Made some minor fixes to CMakeLists.tx and working on descriptor tables

This commit is contained in:
2023-09-18 15:18:13 -07:00
parent 0a638989fa
commit 74d12e70ef
55 changed files with 368 additions and 4229 deletions

View File

@@ -3,6 +3,11 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#define MY_DEVICE_VENDOR_ID 0x1234
#define MY_DEVICE_DEVICE_ID 0x5678
#define MY_DEVICE_CLASS_CODE 0x90AB
// EISA bus controller base address
#define EISA_BASE_ADDRESS 0x0000
@@ -46,6 +51,8 @@ void eisa_detect_devices()
// This is my device, configure it
uint32_t config1 = eisa_read_config_dword(address, 4);
uint32_t config2 = eisa_read_config_dword(address, 8);
printf("Config1: %u\n", config1);
printf("Config2: %u\n", config2);
// Do something with the configuration data
}
}
@@ -54,6 +61,44 @@ void eisa_detect_devices()
}
}
// Read a double word (32 bits) from an EISA device's configuration space
uint32_t eisa_read_config_dword(uint32_t address, uint8_t offset)
{
// Set the EISA bus controller base address
eisa_write(EISA_BASE_ADDRESS, address);
// Set the EISA bus controller command port to read configuration data
eisa_write(EISA_COMMAND_PORT, 0x80 | (offset & 0x03));
// Read the double word from the EISA bus controller data port
uint32_t value = 0;
for (int i = 0; i < 4; i++)
{
value |= (eisa_read(EISA_DATA_PORT) << (i * 8));
}
return value;
}
// Read a word (16 bits) from an EISA device's configuration space
uint16_t eisa_read_config_word(uint32_t address, uint8_t offset)
{
// Set the EISA bus controller base address
eisa_write(EISA_BASE_ADDRESS, address);
// Set the EISA bus controller command port to read configuration data
eisa_write(EISA_COMMAND_PORT, 0x80 | (offset & 0x03));
// Read the word from the EISA bus controller data port
uint16_t value = 0;
for (int i = 0; i < 2; i++)
{
value |= (eisa_read(EISA_DATA_PORT) << (i * 8));
}
return value;
}
// Read from an EISA device
uint8_t eisa_read(uint16_t port)
{

View File

@@ -4,6 +4,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
// Initialize the EISA bus
void eisa_init();
@@ -11,6 +12,12 @@ void eisa_init();
// Detect and configure EISA devices
void eisa_detect_devices();
// Read a double word (32 bits) from an EISA device's configuration space
uint32_t eisa_read_config_dword(uint32_t address, uint8_t offset);
// Read a word (16 bits) from an EISA device's configuration space
uint16_t eisa_read_config_word(uint32_t address, uint8_t offset);
// Read from an EISA device
uint8_t eisa_read(uint16_t port);

View File

@@ -7,41 +7,49 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/cdefs.h>
// GDT table
struct gdt_entry *gdt;
// GDT constants
enum GDT_ACCESS
{
GDT_ACCESS_PRESENT = 0x80
};
// GDT base and limit constants
enum GDT_BASE_LIMIT
{
GDT_BASE_MIDDLE_SHIFT = 16,
GDT_BASE_HIGH_SHIFT = 24,
GDT_GRANULARITY_SHIFT = 16,
GDT_GRANULARITY_MASK = 0x0F,
GDT_ACCESS_MASK = 0xF0,
GDT_LIMIT_MASK = 0xFFFF
};
// Initialize a GDT entry
void gdt_set_gate(uint32_t num, uint32_t base, uint32_t limit, uint8_t access,
uint8_t gran)
{
gdt[num].base_low = (base & 0xFFFF);
gdt[num].base_middle = (base >> 16) & 0xFF;
gdt[num].base_high = (base >> 24) & 0xFF;
gdt[num].limit_low = (limit & 0xFFFF);
gdt[num].granularity = (limit >> 16) & 0x0F;
gdt[num].granularity |= gran & 0xF0;
gdt[num].base_low = (base & GDT_LIMIT_MASK);
gdt[num].base_middle = (base >> GDT_BASE_MIDDLE_SHIFT) & 0xFF;
gdt[num].base_high = (base >> GDT_BASE_HIGH_SHIFT) & 0xFF;
gdt[num].limit_low = (limit & GDT_LIMIT_MASK);
gdt[num].granularity =
(limit >> GDT_GRANULARITY_SHIFT) & GDT_GRANULARITY_MASK;
gdt[num].granularity |= gran & GDT_ACCESS_MASK;
gdt[num].access = access;
}
void gdt_init()
{
// Set up GDT pointer
struct gdt_ptr gp;
gp.limit = (sizeof(struct gdt_entry) * 3) - 1;
gdt = (struct gdt_entry *)malloc(sizeof(struct gdt_entry) * 3);
gp.base = (uint32_t)gdt; // Cast gdt to uint32_t
// Clear GDT
memset(gdt, 0, sizeof(struct gdt_entry) * 3);
// Set up code segment
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
// Set up data segment
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
// Load GDT
asm volatile("lgdt %0" : : "m"(gp));
}
// Exception handlers
@@ -57,13 +65,10 @@ extern void keyboard();
extern void device();
// ISR table
void (*isr_table[256])(void);
void (*isr_table[256])(void) = {0};
// Register an ISR
void isr_register(uint8_t num, void (*handler)(void))
{
isr_table[num] = handler;
}
void isr_register(uint8_t num, void (*handler)(struct isr_regs *regs));
// ISR handler
void isr_handler(struct isr_regs *regs)
@@ -80,6 +85,12 @@ void isr_handler(struct isr_regs *regs)
// Initialize the ISR
void isr_init()
{
// Initialize ISR table
for (int i = 0; i < 256; i++)
{
isr_table[i] = NULL;
}
// Register exception handlers
isr_register(0, divide_error);
isr_register(14, page_fault);

View File

@@ -3,6 +3,8 @@
#include <stdint.h>
extern struct gdt_entry *gdt;
// GDT entry structure
struct gdt_entry
{

View File

@@ -6,11 +6,18 @@
#include <stdlib.h>
#include <string.h>
enum
{
GDT_ACCESS_PRESENT = 0x80,
BASE_MIDDLE_SHIFT = 16,
BYTE_MASK = 0xFF
};
// IDT table
struct idt_entry idt[256];
// IDT pointer
struct idt_ptr idtp;
const struct idt_ptr idtp = {sizeof(idt) - 1, idt};
// Exception handlers
extern void divide_error_handler();
@@ -23,13 +30,16 @@ extern void system_call_handler();
extern void timer_handler();
extern void keyboard_handler();
extern void device_handler();
extern void network_handler();
extern void disk_handler();
extern void serial_port_handler();
// Initialize an IDT entry
void idt_set_gate(uint8_t num, void *base, uint16_t sel, uint8_t flags)
{
uint32_t base_addr = (uint32_t)base;
idt[num].base_lo = base_addr & 0xFFFF;
idt[num].base_hi = (base_addr >> 16) & 0xFFFF;
idt[num].base_lo = base_addr & BYTE_MASK;
idt[num].base_hi = (base_addr >> BASE_MIDDLE_SHIFT) & 0xFFFF;
idt[num].sel = sel;
idt[num].always0 = 0;
idt[num].flags = flags;
@@ -38,12 +48,12 @@ void idt_set_gate(uint8_t num, void *base, uint16_t sel, uint8_t flags)
// Initialize the IDT
void idt_init()
{
// Set up IDT pointer
idtp.limit = sizeof(idt) - 1;
idtp.base = &idt[0];
// Clear IDT
memset(&idt, 0, sizeof(idt));
#ifdef __STDC_LIB_EXT1__
memset_s(idt, 0, sizeof(idt));
#else
memset(idt, 0, sizeof(idt));
#endif
// Set up exception handlers
idt_set_gate(0, divide_error_handler, 0x08, 0x8E);
@@ -55,7 +65,9 @@ void idt_init()
idt_set_gate(0x80, system_call_handler, 0x08, 0xEE);
idt_set_gate(0x20, timer_handler, 0x08, 0x8E);
idt_set_gate(0x21, keyboard_handler, 0x08, 0x8E);
idt_set_gate(0x30, device_handler, 0x08, 0x8E);
idt_set_gate(0x22, network_handler, 0x08, 0x8E);
idt_set_gate(0x23, disk_handler, 0x08, 0x8E);
idt_set_gate(0x24, serial_port_handler, 0x08, 0x8E);
// Load IDT
__asm__ volatile("lidt %0" : : "m"(idtp));

View File

@@ -3,6 +3,18 @@
#include <stdint.h>
// Structure for storing register values during an ISR
struct isr_regs
{
uint32_t ds; // Data segment selector
uint32_t edi, esi, ebp, esp, ebx, edx, ecx,
eax; // Pushed by pusha instruction
uint32_t int_no,
err_code; // Interrupt number and error code (if applicable)
uint32_t eip, cs, eflags, useresp,
ss; // Pushed by the processor automatically
};
// IDT entry structure
struct idt_entry
{
@@ -22,15 +34,18 @@ struct idt_ptr
// Exception handlers
void divide_error();
void page_fault();
void general_protection_fault();
void page_fault(struct isr_regs *regs);
void general_protection_fault(struct isr_regs *regs);
void double_fault();
// Interrupt handlers
void system_call();
void system_call(struct isr_regs *regs);
void timer();
void keyboard();
void device();
void network();
void disk();
void serial_port();
// Initialize the IDT
void idt_init();

View File

@@ -2,11 +2,13 @@
#include "idt.h"
#include <stdio.h>
#define TIMER_INTERRUPT 0x20
#define KEYBOARD_INTERRUPT 0x21
#define NETWORK_INTERRUPT 0x22
#define DISK_INTERRUPT 0x23
#define SERIAL_PORT_INTERRUPT 0x24
enum {
TIMER_INTERRUPT = 0x20,
KEYBOARD_INTERRUPT = 0x21,
NETWORK_INTERRUPT = 0x22,
DISK_INTERRUPT = 0x23,
SERIAL_PORT_INTERRUPT = 0x24
};
// ISR table
void (*isr_table[256])(struct isr_regs *regs);
@@ -20,27 +22,23 @@ void isr_register(uint8_t num, void (*handler)(struct isr_regs *regs))
// ISR handler
void isr_handler(struct isr_regs *regs)
{
if (regs->int_no == 0)
{
divide_error();
}
else if (regs->int_no == 13)
{
general_protection_fault(regs);
}
else if (regs->int_no == 14)
{
page_fault(regs);
}
else
{
void (*handler)(struct isr_regs *regs);
handler = isr_table[regs->int_no];
if (handler)
{
handler(regs);
}
switch (regs->int_no) {
case 0:
divide_error();
break;
case 13:
general_protection_fault(regs);
break;
case 14:
page_fault(regs);
break;
default:
void (*handler)(struct isr_regs *regs);
handler = isr_table[regs->int_no];
if (handler) {
handler(regs);
}
break;
}
}
@@ -48,6 +46,7 @@ void isr_handler(struct isr_regs *regs)
void divide_error()
{
printf("Divide by zero error!\n");
// Additional actions can be taken as needed
}
void page_fault(struct isr_regs *regs)
@@ -55,26 +54,19 @@ void page_fault(struct isr_regs *regs)
uint32_t faulting_address;
// Read the CR2 register to get the faulting address
asm volatile("mov %%cr2, %0" : "=r"(faulting_address));
__asm__ volatile("mov %%cr2, %0" : "=r"(faulting_address));
// Print an error message with the faulting address
printf("Page fault at 0x%x, virtual address 0x%x\n", regs->eip,
faulting_address);
// Halt the system
for (;;)
;
// Additional actions can be taken as needed
}
void general_protection_fault(struct isr_regs *regs)
{
// Handle the general protection fault exception
printf("General protection fault occurred!\n");
// Additional actions can be taken as needed
// Halt the system
for (;;)
;
}
void double_fault()
@@ -89,30 +81,29 @@ void system_call(struct isr_regs *regs)
uint32_t syscall_number = regs->eax;
// Handle different system call numbers
switch (syscall_number)
{
case 1:
// Handle open() system call
// ...
break;
case 2:
// Handle read() system call
// ...
break;
case 3:
// Handle write() system call
// ...
break;
case 4:
// Handle close() system call
// ...
break;
switch (syscall_number) {
case 1:
// Handle open() system call
// ...
break;
case 2:
// Handle read() system call
// ...
break;
case 3:
// Handle write() system call
// ...
break;
case 4:
// Handle close() system call
// ...
break;
// Add more cases for other system calls
default:
// Unknown system call number
printf("Unknown system call number: %d\n", syscall_number);
break;
default:
// Unknown system call number
printf("Unknown system call number: %d\n", syscall_number);
break;
}
}
@@ -129,31 +120,30 @@ void keyboard()
void device()
{
// Determine the type of device interrupt
uint32_t interrupt_type = /* Read the interrupt type from the device */;
uint32_t interrupt_type = read_interrupt_type();
// Call the appropriate interrupt handler
switch (interrupt_type)
{
case TIMER_INTERRUPT:
timer();
break;
case KEYBOARD_INTERRUPT:
keyboard();
break;
case NETWORK_INTERRUPT:
network();
break;
case DISK_INTERRUPT:
disk();
break;
case SERIAL_PORT_INTERRUPT:
serial_port();
break;
switch (interrupt_type) {
case TIMER_INTERRUPT:
timer();
break;
case KEYBOARD_INTERRUPT:
keyboard();
break;
case NETWORK_INTERRUPT:
network();
break;
case DISK_INTERRUPT:
disk();
break;
case SERIAL_PORT_INTERRUPT:
serial_port();
break;
// Add more cases for other types of device interrupts
default:
// Unknown interrupt type
printf("Unknown device interrupt type: %d\n", interrupt_type);
break;
default:
// Unknown interrupt type
printf("Unknown device interrupt type: %d\n", interrupt_type);
break;
}
}
}

View File

@@ -6,13 +6,13 @@
// Structure for storing register values during an ISR
struct isr_regs
{
uint32_t ds; // Data segment selector
uint32_t ds; // Data segment selector
uint32_t edi, esi, ebp, esp, ebx, edx, ecx,
eax; // Pushed by pusha instruction
eax; // Pushed by pusha instruction
uint32_t int_no,
err_code; // Interrupt number and error code (if applicable)
uint32_t eip, cs, eflags, useresp,
ss; // Pushed by the processor automatically
ss; // Pushed by the processor automatically
};
// Register an ISR
@@ -21,16 +21,4 @@ void isr_register(uint8_t num, void (*handler)(struct isr_regs *regs));
// ISR handler
void isr_handler(struct isr_regs *regs);
// Exception handlers
void divide_error();
void page_fault();
void general_protection_fault();
void double_fault();
// Interrupt handlers
void system_call();
void timer();
void keyboard();
void device();
#endif
#endif /* ISR_H */

View File

Binary file not shown.

View File

@@ -1,17 +0,0 @@
#include "../include/types.h"
void gdt_set_entry(gdt_entry_t *entry, uint32_t base, uint32_t limit,
uint16_t flags)
{
entry->base = base;
entry->limit = limit;
entry->flags = flags;
}
void idt_set_entry(idt_entry_t *entry, uint32_t base, uint16_t selector,
uint16_t flags)
{
entry->base = base;
entry->selector = selector;
entry->flags = flags;
}