Skip to content

Commit

Permalink
- MADT
Browse files Browse the repository at this point in the history
  • Loading branch information
fgsoftware1 committed Oct 2, 2024
1 parent 7a3279e commit 456353d
Show file tree
Hide file tree
Showing 14 changed files with 562 additions and 50 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
*.o
*.a
*.bin
*.iso
*.elf
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
====
fgOS
PiriquitOS
====

.. image:: https://app.codacy.com/project/badge/Grade/ed7a424ed40f46b7951a63c882f6fbf6
Expand Down
6 changes: 4 additions & 2 deletions build.ninja
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ build ./build/i386/keyboard.o: gcc ./src/arch/i386/kernel/drivers/keyboard.c
build ./build/i386/fpu.o: gcc ./src/arch/i386/kernel/drivers/fpu.c
build ./build/i386/pit.o: gcc ./src/arch/i386/kernel/drivers/pit.c
build ./build/i386/console.o: gcc ./src/arch/i386/kernel/console.c
build ./build/i386/acpi.o: gcc ./src/arch/i386/kernel/acpi.c
build ./build/i386/madt.o: gcc ./src/arch/i386/kernel/madt.c
build ./build/i386/kernel.o: gcc ./src/arch/i386/kernel/kernel.c

build ./isodir/boot/piriquitOS-i386.bin: ld ./build/libc/string.o ./build/i386/boot.o ./build/i386/gdt.asm.o ./build/i386/gdt.c.o ./build/i386/idt.c.o ./build/i386/idt.asm.o ./build/i386/irq.o ./build/i386/exceptions.o ./build/i386/isr.o ./build/i386/io.o ./build/i386/vga.o ./build/i386/pic.o ./build/i386/cmos.o ./build/i386/keyboard.o ./build/i386/pit.o ./build/i386/console.o ./build/i386/fpu.o ./build/i386/kernel.o
build ./isodir/boot/piriquitOS-i386.bin: ld ./build/i386/acpi.o ./build/i386/madt.o ./build/libc/string.o ./build/i386/boot.o ./build/i386/gdt.asm.o ./build/i386/gdt.c.o ./build/i386/idt.c.o ./build/i386/idt.asm.o ./build/i386/irq.o ./build/i386/exceptions.o ./build/i386/isr.o ./build/i386/io.o ./build/i386/vga.o ./build/i386/pic.o ./build/i386/cmos.o ./build/i386/keyboard.o ./build/i386/pit.o ./build/i386/console.o ./build/i386/fpu.o ./build/i386/kernel.o
build ./build/piriquitOS-i386.iso: iso ./isodir

#phony
build libc: phony ./build/libc/string.o ./libs/libc.a
build i386: phony ./build/libc/string.o ./build/i386/boot.o ./build/i386/gdt.asm.o ./build/i386/idt.asm.o ./build/i386/irq.o ./build/i386/exceptions.o ./build/i386/isr.o ./build/i386/io.o ./build/i386/vga.o ./build/i386/pic.o ./build/i386/cmos.o ./build/i386/keyboard.o ./build/i386/console.o ./build/i386/fpu.o ./build/i386/pit.o ./build/i386/kernel.o ./isodir/boot/piriquitOS-i386.bin ./build/piriquitOS-i386.iso
build i386: phony ./libs/libc.a ./build/i386/acpi.o ./build/i386/madt.o ./build/i386/boot.o ./build/i386/gdt.asm.o ./build/i386/idt.asm.o ./build/i386/irq.o ./build/i386/exceptions.o ./build/i386/isr.o ./build/i386/io.o ./build/i386/vga.o ./build/i386/pic.o ./build/i386/cmos.o ./build/i386/keyboard.o ./build/i386/console.o ./build/i386/fpu.o ./build/i386/pit.o ./build/i386/kernel.o ./isodir/boot/piriquitOS-i386.bin ./build/piriquitOS-i386.iso

default help
83 changes: 83 additions & 0 deletions src/arch/i386/kernel/acpi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#include "include/acpi.h"
#include "libc/include/string.h"
#include "libc/include/stdio.h"

static acpi_rsdp_t *rsdp = NULL;
static acpi_xsdt_t *xsdt = NULL;

static bool validate_table(acpi_sdt_header_t *table_header) {
u8 sum = 0;
for (u32 i = 0; i < table_header->length; i++) {
sum += ((u8 *) table_header)[i];
}
return sum == 0;
}

bool acpi_init(void) {
// Search for the RSDP
for (u8 *addr = (u8 *)0x000E0000; addr < (u8 *)0x00100000; addr += 16) {
if (memcmp(addr, "RSD PTR ", 8) == 0) {
rsdp = (acpi_rsdp_t *)addr;
break;
}
}

if (!rsdp) {
printf("ACPI: RSDP not found\n");
return false;
}

// Validate RSDP checksum
u8 sum = 0;
for (int i = 0; i < sizeof(acpi_rsdp_t); i++) {
sum += ((u8 *)rsdp)[i];
}
if (sum != 0) {
printf("ACPI: RSDP checksum invalid\n");
return false;
}

// Get XSDT
xsdt = (acpi_xsdt_t *)(u32)rsdp->rsdt_address;

if (!validate_table(&xsdt->header)) {
printf("ACPI: XSDT checksum invalid\n");
return false;
}

printf("ACPI: Initialization successful\n");
return true;
}

void *acpi_find_table(const char *signature) {
u32 entries = (xsdt->header.length - sizeof(acpi_sdt_header_t)) / sizeof(u64);

for (u32 i = 0; i < entries; i++) {
acpi_sdt_header_t *header = (acpi_sdt_header_t *)(u32)xsdt->entry[i];
if (memcmp(header->signature, signature, 4) == 0) {
if (validate_table(header)) {
return header;
} else {
printf("ACPI: Found table %.4s but checksum invalid\n", signature);
return NULL;
}
}
}

printf("ACPI: Table %.4s not found\n", signature);
return NULL;
}

void probe_acpi(void) {
printf("ACPI: Probing tables\n");
printf("ACPI: RSDP found at 0x%x\n", (u32)rsdp);
printf("ACPI: XSDT found at 0x%x\n", (u32)xsdt);

u32 entries = (xsdt->header.length - sizeof(acpi_sdt_header_t)) / sizeof(u64);
printf("ACPI: XSDT contains %d entries\n", entries);

for (u32 i = 0; i < entries; i++) {
acpi_sdt_header_t *header = (acpi_sdt_header_t *)(u32)xsdt->entry[i];
printf("ACPI: Found table %.4s at 0x%x\n", header->signature, (u32)header);
}
}
39 changes: 35 additions & 4 deletions src/arch/i386/kernel/drivers/cmos.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#include "../include/drivers/cmos.h"
#include "../include/drivers/pic.h"
#include "../include/console.h"
#include "../include/isr.h"
#include "../include/io.h"

void rtc_handler(struct registers_t *r) {
void rtc_handler(struct registers_t *r)
{
u8 seconds = cmos_read(RTC_SECONDS);
u8 minutes = cmos_read(RTC_MINUTES);
u8 hours = cmos_read(RTC_HOURS);
Expand All @@ -14,18 +16,47 @@ void rtc_handler(struct registers_t *r) {
pic_eoi(IRQ_CMOS);
}

void init_cmos(){
void init_cmos()
{
printf("Initiating CMOS...\n");
isr_register_interrupt_handler(IRQ_CMOS, rtc_handler);
cmos_self_test();
unmask(IRQ_CMOS - IRQ_BASE);
cmos_write(0x0A, cmos_read(0x0A) | 0x40);
}

u8 cmos_read(u8 reg) {
void cmos_self_test()
{
printf("Performing CMOS self-test...\n");

u8 test_address = 0x10;
u8 test_value = 0xAA;
u8 original_value = cmos_read(test_address);

cmos_write(test_address, test_value);

u8 read_value = cmos_read(test_address);

if (read_value == test_value)
{
printf("CMOS self-test passed.\n");
}
else
{
printf("CMOS self-test failed.\n");
}

cmos_write(test_address, original_value);
}

u8 cmos_read(u8 reg)
{
outportb(CMOS_ADDR_REG, reg);
return inportb(CMOS_DATA_REG);
}

void cmos_write(u8 reg, u8 val) {
void cmos_write(u8 reg, u8 val)
{
outportb(CMOS_ADDR_REG, reg);
outportb(CMOS_DATA_REG, val);
}
71 changes: 69 additions & 2 deletions src/arch/i386/kernel/drivers/keyboard.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "../include/drivers/keyboard.h"
#include "../include/drivers/pic.h"
#include "../include/console.h"
#include "../include/console.h"
#include "../include/idt.h"
#include "../include/io.h"
Expand All @@ -16,8 +18,7 @@ char g_scan_code_chars[128] = {
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0,
'\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ',
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0
};
0, 0, 0, 0, 0, 0, 0, 0, 0};

static int get_scancode()
{
Expand Down Expand Up @@ -153,12 +154,78 @@ void keyboard_handler(registers_t *r)
break;
}
}

pic_eoi(IRQ_KEYBOARD);
}

static void wait_for_keyboard_controller(void){
while (inportb(KEYBOARD_STATUS_PORT) & 0x02)
;
}

static void keyboard_send_command(u8 command){
wait_for_keyboard_controller();
outportb(KEYBOARD_COMMAND_PORT, command);
}

static void keyboard_send_data(u8 data){
wait_for_keyboard_controller();
outportb(KEYBOARD_DATA_PORT, data);
}

void init_keyboard()
{
printf("Initiating keyboard...\n");
flush_keyboard_buffer();
isr_register_interrupt_handler(IRQ_KEYBOARD, keyboard_handler);
keyboard_self_test();
unmask(IRQ_KEYBOARD - IRQ_BASE);
}

void flush_keyboard_buffer(void){
while (inportb(KEYBOARD_STATUS_PORT) & 0x01)
{
inportb(KEYBOARD_DATA_PORT);
}
}

void keyboard_self_test(){
printf("Performing keyboard self-test...\n");

// disable keyboard
keyboard_send_command(0xAD);

// Flush the keyboard buffer
flush_keyboard_buffer();

// Perform keyboard controller self-test
keyboard_send_command(0xAA);
if (inportb(KEYBOARD_DATA_PORT) != 0x55)
{
printf("Keyboard controller self-test failed\n");
return;
}

// Perform keyboard interface test
keyboard_send_command(0xAB);
if (inportb(KEYBOARD_DATA_PORT) != 0x00)
{
printf("Keyboard interface test failed\n");
return;
}

// Enable keyboard
keyboard_send_command(0xAE);

// Reset keyboard
keyboard_send_data(0xFF);
if (inportb(KEYBOARD_DATA_PORT) != 0xFA)
{
printf("Keyboard reset failed\n");
return;
}

printf("If no errors where printed above keyboard self-test passed.\n");
}

char kb_getchar()
Expand Down
7 changes: 3 additions & 4 deletions src/arch/i386/kernel/drivers/pic.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ void init_pic()
outportb(PIC_SLAVE_DATA, a2);

//! MASKING ALL INTERRUPTS
//outportb(PIC_MASTER_DATA, 0xFF);
//outportb(PIC_SLAVE_DATA, 0xFF);
pic_disable();
}

void pic_disable()
Expand Down Expand Up @@ -56,7 +55,7 @@ void mask(u8 irq)
port = PIC_SLAVE_DATA;
irq -= 8;
}
value = inportb(port) &~ (1 << irq);
value = inportb(port) | (1 << irq);
outportb(port, value);
}

Expand All @@ -74,7 +73,7 @@ void unmask(u8 irq)
port = PIC_SLAVE_DATA;
irq -= 8;
}
value = inportb(port) | (1 << irq);
value = inportb(port) &~ (1 << irq);
outportb(port, value);
}

Expand Down
38 changes: 16 additions & 22 deletions src/arch/i386/kernel/drivers/pit.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,21 @@
#include "../include/io.h"
#include "../include/isr.h"

u64 ticks;
const u32 freq = 100;
volatile u32 pit_ticks = 0;

void pit_handler(struct registers_t *r) { ticks += 1; }
void pit_handler(struct registers_t *r) { pit_ticks ++; }

void init_pit() {
printf("Initiating PIT...\n");
isr_register_interrupt_handler(IRQ_TIMER, pit_handler);
start_pit_timer();
unmask(IRQ_TIMER - IRQ_BASE);
}

void start_pit_timer() {
if (freq == 0) {
printf("Can't divide by zero!");
return;
}

u16 divisor = 1193180 / freq;

outportb(PIT_COMMAND_PORT, PIT_COMMAND_REGISTER);
outportb(PIT_CH0_DATA_PORT, (u8)(divisor & 0xFF)); // Send the low byte
outportb(PIT_CH0_DATA_PORT, (u8)((divisor >> 8) & 0xFF)); // Send the high byte
void start_pit_timer(u32 frequency) {
u32 divisor = PIT_FREQUENCY / frequency;
outportb(PIT_COMMAND_REGISTER, 0x36); // Set the operating mode to square wave generator
outportb(PIT_CH0_DATA_PORT, divisor & 0xFF); // Set low byte of divisor
outportb(PIT_CH0_DATA_PORT, (divisor >> 8) & 0xFF); // Set high byte of divisor
}

void stop_pit_timer() { outportb(PIT_COMMAND_PORT, 0x30); }
Expand Down Expand Up @@ -73,20 +66,21 @@ void write_pit(u8 channel, u8 value) {
}

void sleep(u32 milliseconds) {
// Calculate the number of PIT ticks needed for the delay
u32 ticks = milliseconds * 1000 / ticks;
u32 ticks = (milliseconds * PIT_FREQUENCY) / 1000;

// Save the current PIT channel 0 count
u8 initialCounter = inportb(PIT_CH0_DATA_PORT);
u8 initialCounterLow = inportb(PIT_CH0_DATA_PORT);
u8 initialCounterHigh = inportb(PIT_CH0_DATA_PORT);

start_pit_timer();
pit_ticks = 0;
start_pit_timer(1000); // Set PIT to 1ms intervals

while (ticks > 0) {
while (pit_ticks < ticks) {
// Wait for PIT interrupt
ticks--;
}

// Restore the initial PIT channel 0 count
outportb(PIT_COMMAND_REGISTER, 0x36); // Set the operating mode to square wave generator
outportb(PIT_CH0_DATA_PORT, initialCounter); // Set the initial counter value
outportb(PIT_CH0_DATA_PORT, initialCounterLow); // Restore low byte of initial counter
outportb(PIT_CH0_DATA_PORT, initialCounterHigh); // Restore high byte of initial counter
}
Loading

0 comments on commit 456353d

Please sign in to comment.