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