forked from PoliEcho-holding-org/kern
Implemented PIT
This commit is contained in:
@@ -10,10 +10,18 @@ TODO
|
|||||||
[x] Virtual MM
|
[x] Virtual MM
|
||||||
[x] Paging
|
[x] Paging
|
||||||
[x] Serial monitor
|
[x] Serial monitor
|
||||||
[ ] Timer interrupts
|
[ ] Make dedicated asm functions like lidt(), sti(), ...
|
||||||
|
[x] PIT
|
||||||
|
[ ] RTC
|
||||||
|
[ ] HPET
|
||||||
|
[ ] System calls
|
||||||
|
[ ] Userspace
|
||||||
|
[ ] Processes
|
||||||
|
[ ] Scheduler
|
||||||
[ ] Task switching
|
[ ] Task switching
|
||||||
[ ] IPC
|
[ ] Inter-process communication
|
||||||
[ ] Graphics
|
[ ] Graphics
|
||||||
|
[ ] Multicore support
|
||||||
[ ] Networking :)
|
[ ] Networking :)
|
||||||
[ ] Finish all the TODOs
|
[ ] Finish all the TODOs
|
||||||
[ ] Run DOOM
|
[ ] Run DOOM
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ struct isr_int_frame {
|
|||||||
typedef void (*isr_handler_ptr)(struct isr_int_frame* iframe);
|
typedef void (*isr_handler_ptr)(struct isr_int_frame* iframe);
|
||||||
|
|
||||||
int isr_init(void);
|
int isr_init(void);
|
||||||
void isr_register_IRQ(uint8_t i, isr_handler_ptr handler);
|
void isr_register(uint8_t i, isr_handler_ptr handler);
|
||||||
int isr_handle_interrupt(struct isr_int_frame iframe);
|
int isr_handle_interrupt(struct isr_int_frame iframe);
|
||||||
|
|
||||||
// Assembly definitions (isr.s)
|
// Assembly definitions (isr.s)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
|
||||||
|
// cpuid
|
||||||
void cpuid(uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx);
|
void cpuid(uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx);
|
||||||
|
|
||||||
// Ports
|
// Ports
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef _TIMER_H
|
||||||
|
#define _TIMER_H
|
||||||
|
|
||||||
|
#include <isr.h>
|
||||||
|
|
||||||
|
#define PIT_DIV 1193180
|
||||||
|
#define PIT_CH0 0x40
|
||||||
|
#define PIT_CH1 0x41
|
||||||
|
#define PIT_CH2 0x42
|
||||||
|
#define PIT_CMD 0x43
|
||||||
|
|
||||||
|
int timer_init(void);
|
||||||
|
void timer_wait(size_t ticks);
|
||||||
|
|
||||||
|
int pit_init(void);
|
||||||
|
void pit_phase(uint8_t ch, uint8_t mode, uint32_t hz);
|
||||||
|
void pit_handler(struct isr_int_frame* iframe);
|
||||||
|
|
||||||
|
// TODO: rtc_init(void);
|
||||||
|
// TODO: hpet_init(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
+7
-9
@@ -75,28 +75,26 @@ int isr_init(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void isr_register_irq(uint8_t i, isr_handler_ptr handler) {
|
void isr_register(uint8_t i, isr_handler_ptr handler) {
|
||||||
|
if (i > 16) return; // Security
|
||||||
irq_handlers[i] = handler;
|
irq_handlers[i] = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
void isr_send_eoi(uint8_t irq) {
|
void isr_send_eoi(uint8_t irq) {
|
||||||
if (irq >= 8) {
|
if (irq >= 8) outb(0xA0, 0x20);
|
||||||
outb(0xa0, 0x20);
|
|
||||||
}
|
|
||||||
outb(0x20, 0x20);
|
outb(0x20, 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Write fault handlers and make this more robust
|
||||||
int isr_handle_interrupt(struct isr_int_frame iframe) {
|
int isr_handle_interrupt(struct isr_int_frame iframe) {
|
||||||
if (iframe.interrupt < 32) {
|
if (iframe.interrupt < 32) {
|
||||||
// ISRs 0-31 - Exceptions
|
// ISRs 0-31 - Exceptions
|
||||||
panic(exceptions[iframe.error]);
|
panic(exceptions[iframe.interrupt]);
|
||||||
} else if (iframe.interrupt >= 32 && iframe.interrupt < 48) {
|
} else if (iframe.interrupt >= 32 && iframe.interrupt < 48) {
|
||||||
// ISRs 32-47 - Hardware interrupts
|
// ISRs 32-47 - Hardware interrupts
|
||||||
uint8_t irq = iframe.interrupt - 32;
|
uint8_t irq = iframe.interrupt - 32;
|
||||||
if (irq_handlers[irq]) {
|
if (irq_handlers[irq]) irq_handlers[irq](&iframe);
|
||||||
irq_handlers[irq](&iframe);
|
isr_send_eoi(irq);
|
||||||
isr_send_eoi(irq);
|
|
||||||
}
|
|
||||||
} else if (iframe.interrupt == 128) {
|
} else if (iframe.interrupt == 128) {
|
||||||
// ISR 128 - System call
|
// ISR 128 - System call
|
||||||
return syscall_handler(&iframe);
|
return syscall_handler(&iframe);
|
||||||
|
|||||||
+7
-2
@@ -2,6 +2,7 @@
|
|||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <paging.h>
|
#include <paging.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
|
#include <timer.h>
|
||||||
#include <gdt.h>
|
#include <gdt.h>
|
||||||
#include <isr.h>
|
#include <isr.h>
|
||||||
#include <pmm.h>
|
#include <pmm.h>
|
||||||
@@ -29,13 +30,17 @@ void kmain(void* ptr, uint32_t magic) {
|
|||||||
if (tty_init() != 0) panic("Failed to initalize TTY driver.");
|
if (tty_init() != 0) panic("Failed to initalize TTY driver.");
|
||||||
tty_puts("kern.\n\n");
|
tty_puts("kern.\n\n");
|
||||||
|
|
||||||
// TODO: Timer
|
// Timer
|
||||||
// TODO: Scheduler
|
if (timer_init() != 0) panic("Failed to initialize timer.");
|
||||||
|
|
||||||
// TODO: Syscalls
|
// TODO: Syscalls
|
||||||
|
// TODO: Scheduler
|
||||||
// TODO: Interprocess communication
|
// TODO: Interprocess communication
|
||||||
// TODO: Tasking
|
// TODO: Tasking
|
||||||
// TODO: Load & run /sbin/init
|
// TODO: Load & run /sbin/init
|
||||||
|
|
||||||
|
while (1);
|
||||||
|
|
||||||
panic("kmain() reached end.");
|
panic("kmain() reached end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#include <kernel.h>
|
||||||
|
#include <system.h>
|
||||||
|
#include <isr.h>
|
||||||
|
#include <tty.h>
|
||||||
|
|
||||||
|
#include <timer.h>
|
||||||
|
|
||||||
|
size_t timer_ticks = 0;
|
||||||
|
|
||||||
|
int timer_init(void) {
|
||||||
|
// TODO: Check what timer we can use and select the best one
|
||||||
|
return pit_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer_wait(size_t t) {
|
||||||
|
size_t req = timer_ticks + t;
|
||||||
|
while (req != timer_ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
int pit_init(void) {
|
||||||
|
isr_register(0, pit_handler);
|
||||||
|
pit_phase(0, 2, 1000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pit_phase(uint8_t ch, uint8_t mode, uint32_t hz) {
|
||||||
|
if (ch > 2 || mode > 7) return;
|
||||||
|
|
||||||
|
__asm__ volatile ("cli");
|
||||||
|
|
||||||
|
outb(PIT_CMD, ((ch << 6) | (3 << 4) | (mode << 1)));
|
||||||
|
|
||||||
|
uint32_t div = PIT_DIV / hz;
|
||||||
|
debugf("[PIT] Setting PIT divisor to %d...\n", div);
|
||||||
|
outb(PIT_CH0 + ch, div & 0xFF);
|
||||||
|
outb(PIT_CH0 + ch, div >> 8);
|
||||||
|
|
||||||
|
__asm__ volatile ("sti");
|
||||||
|
}
|
||||||
|
|
||||||
|
void pit_handler(struct isr_int_frame* iframe) {
|
||||||
|
timer_ticks++;
|
||||||
|
|
||||||
|
if (timer_ticks % 1000 == 0) tty_puts(".");
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user