driver/rtc: RTC ticker at 1024Hz
This commit is contained in:
parent
312703104d
commit
3d43ab3d61
29
driver/irq/pic/rtc/handler.S
Normal file
29
driver/irq/pic/rtc/handler.S
Normal file
@ -0,0 +1,29 @@
|
||||
format elf64
|
||||
|
||||
public __pic_rtc_IRQ8
|
||||
public __pic_rtc_IRQHandler;
|
||||
|
||||
|
||||
section '.bss' writable
|
||||
__pic_rtc_IRQHandler:
|
||||
rq 1
|
||||
|
||||
section '.text' executable
|
||||
__pic_rtc_IRQ8:
|
||||
push rax
|
||||
|
||||
; read the register C byte or the interrupt will block
|
||||
mov al, 0x0c
|
||||
out 0x70, al
|
||||
in al, 0x71
|
||||
|
||||
; tell if the irq handler is NULL
|
||||
mov rax, [__pic_rtc_IRQHandler]
|
||||
test rax, rax
|
||||
pop rax
|
||||
jz .end
|
||||
jmp qword [__pic_rtc_IRQHandler]
|
||||
.end:
|
||||
iret
|
||||
|
||||
|
8
driver/irq/pic/rtc/internal.h
Normal file
8
driver/irq/pic/rtc/internal.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "rtc.h"
|
||||
#include "../../../../main.h"
|
||||
|
||||
|
||||
extern void * __pic_rtc_IRQHandler;
|
||||
SYSV_ABI void __pic_rtc_IRQ8();
|
34
driver/irq/pic/rtc/rtc.c
Normal file
34
driver/irq/pic/rtc/rtc.c
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
#include "rtc.h"
|
||||
#include "internal.h"
|
||||
#include "../pic.h"
|
||||
#include "../internal.h"
|
||||
#include "../../../../main.h"
|
||||
#include "../../../../runtime/panic_assert.h"
|
||||
#include "../../../../interrupt/interrupt.h"
|
||||
|
||||
|
||||
bool pic_rtc_Enabled;
|
||||
|
||||
void pic_rtc_Init() {
|
||||
assert(irq_pic_Enabled && "pic/rtc requires pic to be enabled");
|
||||
|
||||
if (pic_rtc_Enabled)
|
||||
return;
|
||||
INTERRUPT_DISABLE;
|
||||
|
||||
outb(0x70, 0x8b); // select register B, and disable NMI
|
||||
uint8_t prev = inb(0x71); // read the current value of register B
|
||||
outb(0x70, 0x8B); // set the index again (a read will reset the index to register D)
|
||||
outb(0x71, prev | 0x40); // write the previous value ORed with 0x40. This turns on bit 6 of register B
|
||||
|
||||
irq_pic_IRQHandlerRaw[8] = __pic_rtc_IRQ8;
|
||||
irq_pic_Mask(8, false);
|
||||
|
||||
pic_rtc_Enabled = true;
|
||||
INTERRUPT_RESTORE;
|
||||
}
|
||||
|
||||
void pic_rtc_SetHandler(void *handler) {
|
||||
__pic_rtc_IRQHandler = handler;
|
||||
}
|
24
driver/irq/pic/rtc/rtc.h
Normal file
24
driver/irq/pic/rtc/rtc.h
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
extern bool pic_rtc_Enabled;
|
||||
|
||||
// Init installs the required interrupt handlers.
|
||||
void pic_rtc_Init();
|
||||
|
||||
// SetHandler sets the interrupt handler for RTC interrupts.
|
||||
//
|
||||
// The handler is jumped to, so it must use IRET and save registers is uses.
|
||||
void pic_rtc_SetHandler(void *handler);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user