Merge pull request #35 from gbowne1/gbowne1-fixes-interrupts

Fixing interrupts
This commit is contained in:
Gregory Kenneth Bowne 2023-10-30 00:57:11 -07:00 committed by GitHub
commit 5c2e3146a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 201 additions and 197 deletions

View File

@ -8,9 +8,9 @@
], ],
"defines": [], "defines": [],
"compilerPath": "/usr/bin/gcc", "compilerPath": "/usr/bin/gcc",
"cStandard": "c17", "cStandard": "c11",
"cppStandard": "c++20", "cppStandard": "c++11",
"intelliSenseMode": "gcc-x64", "intelliSenseMode": "linux-gcc-x64",
"browse": { "browse": {
"path": [ "path": [
"${workspaceFolder}/**", "${workspaceFolder}/**",

View File

@ -1,12 +0,0 @@
[
{
"directory": "/path/to/project",
"command": "gcc -c -o file1.o file1.c",
"file": "/path/to/project/file1.c"
},
{
"directory": "/path/to/project",
"command": "g++ -c -o file2.o file2.cpp",
"file": "/path/to/project/file2.cpp"
}
]

View File

@ -0,0 +1,8 @@
#ifndef INTERRUPT_UTILS_H
#define INTERRUPT_UTILS_H
#include <stdint.h>
uint32_t read_interrupt_type(void);
#endif /* INTERRUPT_UTILS_H */

View File

@ -1,182 +1,190 @@
#include "isr.h" #include "isr.h"
#include "idt.h" #include "idt.h"
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <signal.h>
enum #include <stdlib.h>
{ #include <unistd.h>
TIMER_INTERRUPT = 0x20,
KEYBOARD_INTERRUPT = 0x21, #include "./interrupt_utils.h"
NETWORK_INTERRUPT = 0x22,
DISK_INTERRUPT = 0x23, void invalid_opcode(void);
SERIAL_PORT_INTERRUPT = 0x24 void general_protection_fault(struct idt_regs *regs);
}; void page_fault(struct idt_regs *regs);
void system_call(struct idt_regs *regs);
void dummy_isr(struct isr_regs *regs)
{ enum
printf("Timer interrupt occurred!\n"); {
} TIMER_INTERRUPT = 0x20,
KEYBOARD_INTERRUPT = 0x21,
// ISR table NETWORK_INTERRUPT = 0x22,
void (*isr_table[256])(struct isr_regs *regs) = {0}; DISK_INTERRUPT = 0x23,
SERIAL_PORT_INTERRUPT = 0x24
// Register an ISR };
extern void isr_register(uint8_t num, void (*handler)(struct isr_regs *regs))
{ void dummy_isr(struct isr_regs *regs)
isr_table[num] = handler; {
} printf("Timer interrupt occurred!\n");
}
// ISR handler
void isr_handler(struct idt_regs *regs) // Register an ISR
{ extern void isr_register(uint8_t num, void (*handler)(struct isr_regs *regs))
switch (regs->int_no) {
{ isr_table[num] = handler;
case 0x00: }
divide_error(regs);
break; // ISR handler
case 0x06: void isr_handler(struct idt_regs *regs)
invalid_opcode(); {
break; switch (regs->int_no)
case 0x0D: {
general_protection_fault(regs); case 0x00:
break; divide_error(regs);
case 0x0E: break;
page_fault(regs); case 0x06:
break; invalid_opcode();
case 0x08: break;
double_fault(); case 0x0D:
break; general_protection_fault(regs);
case 0x80: break;
system_call(regs); case 0x0E:
break; page_fault(regs);
case 0x20: break;
timer(); case 0x08:
break; double_fault();
case 0x21: break;
keyboard(); case 0x80:
break; system_call(regs);
case 0x2F: break;
device(); case 0x20:
break; timer();
case 0x28: break;
network(); case 0x21:
break; keyboard();
case 0x2E: break;
disk(); case 0x2F:
break; device();
case 0x24: break;
serial_port(); case 0x28:
break; network();
default: break;
printf("Unhandled interrupt: %d\n", regs->int_no); case 0x2E:
break; disk();
} break;
} case 0x24:
serial_port();
// Exception handlers break;
void divide_error(struct idt_regs *regs) default:
{ printf("Unhandled interrupt: %d\n", regs->int_no);
printf("Divide by zero error!\n"); break;
// Additional actions can be taken as needed }
} }
void page_fault(struct idt_regs *regs) // Exception handlers
{ void divide_error(struct idt_regs *regs)
uint32_t faulting_address; {
printf("Divide by zero error!\n");
// Read the CR2 register to get the faulting address // Additional actions can be taken as needed
__asm__ volatile("mov %%cr2, %0" : "=r"(faulting_address)); }
// Print an error message with the faulting address void page_fault(struct idt_regs *regs)
printf("Page fault at 0x%x, virtual address 0x%x\n", regs->eip, {
faulting_address); uint32_t faulting_address;
// Additional actions can be taken as needed // Read the CR2 register to get the faulting address
} __asm__ volatile("mov %%cr2, %0" : "=r"(faulting_address));
void general_protection_fault(struct idt_regs *regs) // Print an error message with the faulting address
{ printf("Page fault at 0x%x, virtual address 0x%x\n", regs->eip,
printf("General protection fault occurred!\n"); faulting_address);
// Additional actions can be taken as needed
} // Additional actions can be taken as needed
}
void double_fault()
{ void general_protection_fault(struct idt_regs *regs)
// Handle double fault exception {
} printf("General protection fault occurred!\n");
// Additional actions can be taken as needed
// Interrupt handlers }
void system_call(struct idt_regs *regs)
{ void double_fault()
// Get the system call number from the eax register {
uint32_t syscall_number = regs->eax; // Handle double fault exception
}
// Handle different system call numbers
switch (syscall_number) // Interrupt handlers
{ void system_call(struct idt_regs *regs)
case 1: {
// Handle open() system call // Get the system call number from the eax register
// ... uint32_t syscall_number = regs->eax;
break;
case 2: // Handle different system call numbers
// Handle read() system call switch (syscall_number)
// ... {
break; case 1:
case 3: // Handle open() system call
// Handle write() system call // ...
// ... break;
break; case 2:
case 4: // Handle read() system call
// Handle close() system call // ...
// ... break;
break; case 3:
// Add more cases for other system calls // Handle write() system call
// ...
default: break;
// Unknown system call number case 4:
printf("Unknown system call number: %d\n", syscall_number); // Handle close() system call
break; // ...
} break;
} // Add more cases for other system calls
void timer() default:
{ // Unknown system call number
// Handle timer interrupt printf("Unknown system call number: %d\n", syscall_number);
} break;
}
void keyboard() }
{
// Handle keyboard interrupt void timer()
} {
static int count = 0;
void device() printf ("timer expired %d times\n", ++count);
{ }
// Determine the type of device interrupt
uint32_t interrupt_type = read_interrupt_type(); void keyboard()
{
// Call the appropriate interrupt handler // Handle keyboard interrupt
switch (interrupt_type) }
{
case TIMER_INTERRUPT: void device()
timer(); {
break; // Determine the type of device interrupt
case KEYBOARD_INTERRUPT: uint32_t interrupt_type = read_interrupt_type();
keyboard();
break; // Call the appropriate interrupt handler
case NETWORK_INTERRUPT: switch (interrupt_type)
network(); {
break; case TIMER_INTERRUPT:
case DISK_INTERRUPT: timer();
disk(); break;
break; case KEYBOARD_INTERRUPT:
case SERIAL_PORT_INTERRUPT: keyboard();
serial_port(); break;
break; case NETWORK_INTERRUPT:
// Add more cases for other types of device interrupts network();
break;
default: case DISK_INTERRUPT:
// Unknown interrupt type disk();
printf("Unknown device interrupt type: %d\n", interrupt_type); break;
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;
}
}