feat: added basic ACPI support using LAI
This commit is contained in:
@@ -9,12 +9,9 @@
|
||||
#include <myke/cpu/idt.h>
|
||||
#include <myke/cpu/pic.h>
|
||||
#include <myke/cpu/syscall_handler.h>
|
||||
#include <myke/drivers/ports.h>
|
||||
#include <myke/libk/libk.h>
|
||||
#include <myke/tasks/task.h>
|
||||
|
||||
#define PIC_END_OF_INTERRUPT 0x20
|
||||
|
||||
isr_t interrupt_handlers[256];
|
||||
|
||||
void isr_install() {
|
||||
@@ -52,8 +49,7 @@ void isr_install() {
|
||||
set_idt_gate(31, (uint32_t) isr31);
|
||||
|
||||
// Remap the PIC
|
||||
// todo make readable
|
||||
pic_init();
|
||||
pic_init(IRQ0);
|
||||
|
||||
// Install the IRQs
|
||||
set_idt_gate(32, (uint32_t) irq0); // 0x20
|
||||
@@ -73,6 +69,7 @@ void isr_install() {
|
||||
set_idt_gate(46, (uint32_t) irq14);
|
||||
set_idt_gate(47, (uint32_t) irq15);
|
||||
|
||||
// 0x80 SYSCALL
|
||||
set_idt_gate(128, (uint32_t) isr128);
|
||||
|
||||
set_idt(); // Load with ASM
|
||||
@@ -116,7 +113,7 @@ char *exception_messages[] = {
|
||||
"Reserved"
|
||||
};
|
||||
|
||||
void isr_handler(isr_registers_t r) {
|
||||
void att_used isr_handler(isr_registers_t r) {
|
||||
char msg[256];
|
||||
if (r.int_no == 128) {
|
||||
syscall_handle(&r);
|
||||
@@ -131,11 +128,10 @@ void register_interrupt_handler(uint8_t n, isr_t handler) {
|
||||
interrupt_handlers[n] = handler;
|
||||
}
|
||||
|
||||
void irq_handler(isr_registers_t r) {
|
||||
void att_used irq_handler(isr_registers_t r) {
|
||||
/* After every interrupt we need to send an EOI to the PICs
|
||||
* or they will not send another interrupt again */
|
||||
if (r.int_no >= 40) port_byte_out(PORT_PIC_SLAVE_COMMAND, PIC_END_OF_INTERRUPT); /* slave */
|
||||
port_byte_out(PORT_PIC_MASTER_COMMAND, PIC_END_OF_INTERRUPT); /* master */
|
||||
pic_eoi(r.int_no >= IRQ8);
|
||||
|
||||
if (r.int_no >= IRQ0 && r.int_no < IRQ15) {
|
||||
task_notify_irq(r.int_no - IRQ0);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//
|
||||
// Created by rick on 22-08-21.
|
||||
//
|
||||
#include <stdbool.h>
|
||||
#include <myke/cpu/pic.h>
|
||||
#include <myke/drivers/ports.h>
|
||||
|
||||
@@ -17,15 +18,17 @@
|
||||
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
|
||||
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
|
||||
|
||||
void pic_init() {
|
||||
#define PIC_END_OF_INTERRUPT 0x20
|
||||
|
||||
void pic_init(uint8_t isr_offset) {
|
||||
// init both master and slave pic's
|
||||
port_byte_out(PORT_PIC_MASTER_COMMAND, ICW1_INIT | ICW1_ICW4);
|
||||
port_byte_out(PORT_PIC_SLAVE_COMMAND, ICW1_INIT | ICW1_ICW4);
|
||||
|
||||
// master with ICW4 offset 20, Slave on IRQ2, 8086 mode,
|
||||
// master with ICW4 offset isr_offset, Slave on IRQ2, 8086 mode,
|
||||
// ICW2
|
||||
port_byte_out(PORT_PIC_MASTER_DATA, 0x20); // offset master
|
||||
port_byte_out(PORT_PIC_SLAVE_DATA, 0x28); // offset slave
|
||||
port_byte_out(PORT_PIC_MASTER_DATA, isr_offset); // offset master
|
||||
port_byte_out(PORT_PIC_SLAVE_DATA, isr_offset + 8); // offset slave
|
||||
// ICW3
|
||||
port_byte_out(PORT_PIC_MASTER_DATA, 0x04); // slave PIC at IRQ2
|
||||
port_byte_out(PORT_PIC_SLAVE_DATA, 0x02); // cascade identity
|
||||
@@ -39,5 +42,10 @@ void pic_init() {
|
||||
|
||||
void pic_set_mask(uint16_t mask) {
|
||||
port_byte_out(PORT_PIC_MASTER_DATA, mask & 0xFF);
|
||||
port_byte_out(PORT_PIC_SLAVE_DATA, mask << 8);
|
||||
port_byte_out(PORT_PIC_SLAVE_DATA, mask >> 8);
|
||||
}
|
||||
|
||||
void pic_eoi(bool slave) {
|
||||
if (slave) port_byte_out(PORT_PIC_SLAVE_COMMAND, PIC_END_OF_INTERRUPT); /* slave */
|
||||
port_byte_out(PORT_PIC_MASTER_COMMAND, PIC_END_OF_INTERRUPT); /* master */
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <myke/cpu/timer.h>
|
||||
#include <myke/cpu/pit.h>
|
||||
#include <myke/drivers/ports.h>
|
||||
#include <myke/cpu/isr.h>
|
||||
#include <myke/libk/libk.h>
|
||||
@@ -33,19 +33,37 @@
|
||||
#define PIT_CHANNEL_1 (0b01 << 6)
|
||||
#define PIT_CHANNEL_2 (0b10 << 6)
|
||||
#define PIT_CHANNEL_READ_BACK (0b11 << 6)
|
||||
#define PIT_RB_LATCH_COUNT (0)
|
||||
#define PIT_RB_LATCH_NO_COUNT (1 << 5)
|
||||
#define PIT_RB_LATCH_STATUS (0)
|
||||
#define PIT_RB_LATCH_NO_STATUS (1 << 4)
|
||||
#define PIT_RB_CHANNEL_2 (1 << 3)
|
||||
#define PIT_RB_CHANNEL_1 (1 << 2)
|
||||
#define PIT_RB_CHANNEL_0 (1 << 1)
|
||||
#define PIT_STATUS_OUTPUT_STATE (1 << 7)
|
||||
#define PIT_STATUS_NULL_COUNT (1 << 6)
|
||||
#define PIT_STATUS_ACCESS_MODE (0b11 >> 4)
|
||||
#define PIT_STATUS_OPERATING_MODE (0b111 < 1)
|
||||
#define PIT_STATUS_BCD_BIN (1)
|
||||
|
||||
#define PIT_FREQUENCY 1193182 /*Hz*/
|
||||
uint32_t tick = 0;
|
||||
|
||||
static void timer_callback(isr_registers_t *regs) {
|
||||
uint32_t pit_ms_to_div(uint32_t ms) {
|
||||
uint32_t divisor = PIT_FREQUENCY / ms;
|
||||
return divisor;
|
||||
}
|
||||
|
||||
static void pit_callback(isr_registers_t *regs) {
|
||||
tick++;
|
||||
task_switch_next();
|
||||
}
|
||||
|
||||
uint32_t timer_get_tick() {
|
||||
uint32_t pit_get_tick() {
|
||||
return tick;
|
||||
}
|
||||
|
||||
void sleep(uint32_t milliseconds) {
|
||||
void pit_sleep(uint32_t milliseconds) {
|
||||
uint32_t done = tick + milliseconds;
|
||||
while (tick != done) {
|
||||
k_wait_for_interrupt();
|
||||
@@ -60,10 +78,10 @@ void print_current_tick() {
|
||||
kprint("\n");
|
||||
}
|
||||
|
||||
int init_timer(uint32_t freq) {
|
||||
register_interrupt_handler(IRQ0, timer_callback);
|
||||
int pit_init(uint32_t freq) {
|
||||
register_interrupt_handler(IRQ0, pit_callback);
|
||||
|
||||
uint32_t divisor = 1193180 / freq;
|
||||
uint32_t divisor = PIT_FREQUENCY / freq;
|
||||
uint8_t low = (uint8_t) (divisor & 0xFF);
|
||||
uint8_t high = (uint8_t) ((divisor >> 8) & 0xFF);
|
||||
port_byte_out(PORT_PIT_COMMAND,
|
||||
@@ -72,3 +90,21 @@ int init_timer(uint32_t freq) {
|
||||
port_byte_out(PORT_PIT_DATA_0, high);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// pit_sleep without interrupts
|
||||
void pit_sleep_ms(const uint32_t sleep) {
|
||||
// todo locking
|
||||
uint32_t divider = pit_ms_to_div(sleep);
|
||||
if (divider > UINT16_MAX) {
|
||||
k_panics("Sleep for to long");
|
||||
}
|
||||
port_byte_out(PORT_PIT_COMMAND,
|
||||
PIT_MODE_BIN | PIT_MODE_INTERRUPT_ON_TERMINAL_COUNT | PIT_ACCESS_MODE_LH | PIT_CHANNEL_0);
|
||||
port_byte_out(PORT_PIT_DATA_0, divider & 0xFF);
|
||||
port_byte_out(PORT_PIT_DATA_0, divider >> 8);
|
||||
do {
|
||||
__builtin_ia32_pause();
|
||||
port_byte_out(PORT_PIT_COMMAND,
|
||||
PIT_CHANNEL_READ_BACK | PIT_RB_CHANNEL_0 | PIT_RB_LATCH_NO_COUNT | PIT_RB_LATCH_STATUS);
|
||||
} while (port_byte_in(PORT_PIT_DATA_0) & PIT_STATUS_OUTPUT_STATE);
|
||||
}
|
||||
Reference in New Issue
Block a user