- Created src/e3c509.h: full windowed register model (8 windows), command codes, status/interrupt bits, RX filter, transceiver types, device struct and API declarations - Created src/e3c509.c: full driver implementation with PIO TX/RX, window selection, 10base-T (RJ45) transceiver config, MAC address read from Window 2, FIFO-based packet send/receive, IRQ handler, devicefs char device registration as 'eth' class - Probe uses manufacturer ID check (0x6D50 at Window 0) - Only 10base-T supported per design requirements - Wired IRQ 10 (vector 42) handler into isr.c - QEMU does not emulate 3C509 ISA, so driver correctly probes 'not found' in QEMU; tested alongside NE2000 without issues
101 lines
2.4 KiB
C
101 lines
2.4 KiB
C
#include "isr.h"
|
|
#include "pic.h"
|
|
#include "process.h"
|
|
#include "syscall.h"
|
|
#include "keyboard.h"
|
|
#include "floppy.h"
|
|
#include "ne2000.h"
|
|
#include "e3c509.h"
|
|
#include <stdint.h>
|
|
|
|
/* Forward declaration for kernel panic or similar */
|
|
void offset_print(const char *str);
|
|
void print_hex(uint32_t val);
|
|
|
|
/* Exception messages */
|
|
char *exception_messages[] = {
|
|
"Division By Zero",
|
|
"Debug",
|
|
"Non Maskable Interrupt",
|
|
"Breakpoint",
|
|
"Into Detected Overflow",
|
|
"Out of Bounds",
|
|
"Invalid Opcode",
|
|
"No Coprocessor",
|
|
"Double Fault",
|
|
"Coprocessor Segment Overrun",
|
|
"Bad TSS",
|
|
"Segment Not Present",
|
|
"Stack Fault",
|
|
"General Protection Fault",
|
|
"Page Fault",
|
|
"Unknown Interrupt",
|
|
"Coprocessor Fault",
|
|
"Alignment Check",
|
|
"Machine Check",
|
|
"Reserved",
|
|
"Reserved",
|
|
"Reserved",
|
|
"Reserved",
|
|
"Reserved",
|
|
"Reserved",
|
|
"Reserved",
|
|
"Reserved",
|
|
"Reserved",
|
|
"Reserved",
|
|
"Reserved",
|
|
"Reserved",
|
|
"Reserved"
|
|
};
|
|
|
|
void isr_handler(registers_t *regs)
|
|
{
|
|
/* System call (INT 0x80) */
|
|
if (regs->int_no == 0x80) {
|
|
syscall_handler(regs);
|
|
return;
|
|
}
|
|
|
|
/* Hardware interrupts (IRQs 0-15, mapped to vectors 32-47) */
|
|
if (regs->int_no >= 32 && regs->int_no < 48) {
|
|
/* Send EOI to PIC (IRQ number 0-15) */
|
|
pic_send_eoi(regs->int_no - 32);
|
|
|
|
if (regs->int_no == 32) {
|
|
/* Timer tick - invoke scheduler */
|
|
schedule_tick(regs);
|
|
} else if (regs->int_no == 33) {
|
|
/* Keyboard IRQ */
|
|
keyboard_irq(regs);
|
|
} else if (regs->int_no == 38) {
|
|
/* Floppy IRQ */
|
|
floppy_irq();
|
|
} else if (regs->int_no == 41) {
|
|
/* NE2000 Ethernet IRQ (IRQ 9, vector 41) */
|
|
ne2k_irq();
|
|
} else if (regs->int_no == 42) {
|
|
/* 3C509B Ethernet IRQ (IRQ 10, vector 42) */
|
|
e3c509_irq();
|
|
}
|
|
return;
|
|
}
|
|
|
|
/* CPU exceptions (vectors 0-31) */
|
|
offset_print("received interrupt: ");
|
|
print_hex(regs->int_no);
|
|
offset_print("\n");
|
|
|
|
if (regs->int_no < 32)
|
|
{
|
|
offset_print(exception_messages[regs->int_no]);
|
|
offset_print(" Exception. System Halted!\n");
|
|
offset_print(" EIP: ");
|
|
print_hex(regs->eip);
|
|
offset_print(" CS: ");
|
|
print_hex(regs->cs);
|
|
offset_print(" ERR: ");
|
|
print_hex(regs->err_code);
|
|
for (;;) ;
|
|
}
|
|
}
|