driver/rtc: RTC ticker at 1024Hz

This commit is contained in:
Edgaru089 2021-11-07 23:07:47 +08:00
parent 312703104d
commit 3d43ab3d61
4 changed files with 95 additions and 0 deletions

View 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

View 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
View 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
View 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