From cd6198fbaf5d167031682681690477db67c0f211 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 27 Jul 2017 14:06:47 +0200 Subject: receiving the first network interrupts --- src/Makefile | 6 ++-- src/drivers/net/rtl8139.c | 78 +++++++++++++++++++++++++-------------------- src/drivers/net/rtl8139.h | 2 ++ src/hardware/interrupts.asm | 1 + src/hardware/interrupts.c | 4 +++ src/hardware/interrupts.h | 1 + 6 files changed, 56 insertions(+), 36 deletions(-) diff --git a/src/Makefile b/src/Makefile index 8d35c45..9222125 100644 --- a/src/Makefile +++ b/src/Makefile @@ -168,14 +168,16 @@ run-qemu-usb: image.bin run-qemu: image.bin qemu-system-i386 -cpu 486 -usb \ - -netdev user,id=net0,net=10.0.0.0/24,host=10.0.0.2,dhcpstart=10.0.0.16 -device rtl8139,netdev=net0 \ + -netdev user,id=net0,net=10.0.0.0/24,host=10.0.0.2,dhcpstart=10.0.0.16,hostfwd=tcp::8080-:80 \ + -device rtl8139,netdev=net0 \ -object filter-dump,id=net0,netdev=net0,file=network.log \ -d guest_errors -m 32 -drive "file=image.bin,if=floppy,format=raw" \ -serial file:serial.log run-qemu-debug: image.bin qemu-system-i386 -cpu 486 -usb \ - -netdev user,id=net0,net=10.0.0.0/24,host=10.0.0.2,dhcpstart=10.0.0.16 -device rtl8139,netdev=net0 \ + -netdev user,id=net0,net=10.0.0.0/24,host=10.0.0.2,dhcpstart=10.0.0.16,hostfwd=tcp::8080-:80 \ + -device rtl8139,netdev=net0 \ -object filter-dump,id=net0,netdev=net0,file=network.log \ -S -s -d guest_errors -m 32 -drive "file=image.bin,if=floppy,format=raw" \ -serial file:serial.log diff --git a/src/drivers/net/rtl8139.c b/src/drivers/net/rtl8139.c index 0f561b2..a24afbe 100644 --- a/src/drivers/net/rtl8139.c +++ b/src/drivers/net/rtl8139.c @@ -27,17 +27,21 @@ static rtl8139_vtable_t const rtl8139_vtable = { // registers #define REG_MAC0 0x00 #define REG_CMD 0x37 +#define REG_IMR 0x3C +#define REG_ISR 0x3E #define REG_TCR 0x40 #define REG_RCR 0x44 -// commands for REG_CMD register +// commands for REG_CMD (command register) #define CMD_RESET 0x10 #define CMD_RECEIVER_ENABLE 0x08 #define CMD_TRANSMITTER_ENABLE 0x04 +// mask for reading the version in from the REG_TCR (transmit configuration register) #define TCR_MODEL_VERSION_AM 0x7C000000 #define TCR_MODEL_VERSION_BM 0x00C00000 +// vendor identifiers received from the REG_TCR (transmit configuration register) #define TCR_MODEL_VERSION_RTL8139 0x60000000 #define TCR_MODEL_VERSION_RTL8139A 0x70000000 #define TCR_MODEL_VERSION_RTL8139B 0x78000000 @@ -49,21 +53,32 @@ static rtl8139_vtable_t const rtl8139_vtable = { #define TCR_MODEL_VERSION_RTL8139CP 0x74800000 #define TCR_MODEL_VERSION_RTL8101 0x74C00000 +// values for REG_TCR (transmit configuration register) #define TCR_IFG_STANDARD 0x03000000 - -/* -#define TCR_IFG_STANDARD (3 << 24) -#define TCR_MXDMA_512 (5 << 8) -#define TCR_MXDMA_1024 (6 << 8) -#define TCR_MXDMA_2048 (7 << 8) - -#define RCR_MXDMA_512 (5 << 8) -#define RCR_MXDMA_1024 (6 << 8) -#define RCR_MXDMA_UNLIMITED (7 << 8) -#define RCR_ACCEPT_BROADCAST (1 << 3) -#define RCR_ACCEPT_MULTICAST (1 << 2) -#define RCR_ACCEPT_PHYS_MATCH (1 << 1) -*/ +#define TCR_MXDMA_2048 0x00000700 + +// values for REG_RCR (receive configuration register) +#define RCR_MXDMA_UNLIMITED 0x00000700 +#define RCR_ACCEPT_BROADCAST 0x00000008 +#define RCR_ACCEPT_PHYS_MATCH 0x00000002 + +// values for REG_IMR/REG_ISR (interrupt mask/status registers) +#define ISR_SYSTEM_ERROR 0x8000 +#define ISR_TIMEOUT 0x4000 +#define ISR_CABLE_LENGTH_CHANGED 0x2000 +#define ISR_RECEIVE_FIFO_OVERFLOW 0x0040 +#define ISR_PACKET_UNDERRUN_LINK_CHANGED 0x0020 +#define ISR_RECEIVE_BUFFER_OVERFLOW 0x0010 +#define ISR_TRANSMIT_ERROR 0x0008 +#define ISR_TRANSMIT_OK 0x0004 +#define ISR_RECEIVE_ERROR 0x0002 +#define ISR_RECEIVE_OK 0x0001 + +#define ISR_ALL \ + ISR_CABLE_LENGTH_CHANGED | ISR_TIMEOUT | ISR_SYSTEM_ERROR | \ + ISR_RECEIVE_FIFO_OVERFLOW | ISR_PACKET_UNDERRUN_LINK_CHANGED | \ + ISR_RECEIVE_BUFFER_OVERFLOW | ISR_TRANSMIT_ERROR | ISR_TRANSMIT_OK | \ + ISR_RECEIVE_ERROR | ISR_RECEIVE_OK void rtl8139_init( rtl8139_t *rtl8139, pci_device_descriptor_t *descriptor, interrupt_t *interrupt, void *context ) { @@ -79,6 +94,8 @@ void rtl8139_init( rtl8139_t *rtl8139, pci_device_descriptor_t *descriptor, inte port8_init( &rtl8139->MAC_port[i], descriptor->port_base + REG_MAC0 + i ); } port8_init( &rtl8139->CMD_port, descriptor->port_base + REG_CMD ); + port16_init( &rtl8139->IMR_port, descriptor->port_base + REG_IMR ); + port16_init( &rtl8139->ISR_port, descriptor->port_base + REG_ISR ); port32_init( &rtl8139->TCR_port, descriptor->port_base + REG_TCR ); port32_init( &rtl8139->RCR_port, descriptor->port_base + REG_RCR ); @@ -107,7 +124,7 @@ void rtl8139_init( rtl8139_t *rtl8139, pci_device_descriptor_t *descriptor, inte rtl8139->model = "RTL8139A"; break; - //case TCR_MODEL_VERSION_RTL8139B: + // case TCR_MODEL_VERSION_RTL8139B: case TCR_MODEL_VERSION_RTL8130: rtl8139->model = "RTL8130/RTL8130B"; break; @@ -138,27 +155,20 @@ void rtl8139_init( rtl8139_t *rtl8139, pci_device_descriptor_t *descriptor, inte break; } -/* TODO: - port32_write( &rtl8139->TCR_port, TCR_IFG_STANDARD ); - - port32_write( &rtl8139->RCR_port, ); - - TCR RCR - - DEBUG_MSG("Inititalisiere RCR/TCR"); - write_register_dword(netcard, REG_RECEIVE_CONFIGURATION, - RCR_MXDMA_UNLIMITED | RCR_ACCEPT_BROADCAST | RCR_ACCEPT_PHYS_MATCH); + // initialize TCR/RCR (take Lowlevel suggestions: TCR = 0x03000700, RCR = 0x0000070a) + port32_write( &rtl8139->TCR_port, TCR_IFG_STANDARD | TCR_MXDMA_2048 ); + port32_write( &rtl8139->RCR_port, RCR_MXDMA_UNLIMITED | RCR_ACCEPT_BROADCAST | RCR_ACCEPT_PHYS_MATCH ); - // DMA burst, 2k is max, what are other operating systems doing? - write_register_dword(netcard, REG_TRANSMIT_CONFIGURATION, - TCR_IFG_STANDARD | TCR_MXDMA_2048); - -*/ - - rtl8139_print_info( rtl8139 ); + // register interrupts we are interested in (we want all and + // filter them in the interrupt handler), read ISR to clear + // the current values (if there are bits set) + port16_write( &rtl8139->IMR_port, ISR_ALL ); + (void)port16_read( &rtl8139->ISR_port ); interrupt_handler_init( &rtl8139->interrupt_handler, IRQ_BASE + descriptor->interrupt, interrupt, rtl8139_handle_interrupt, rtl8139 ); interrupts_register_interrupt_handler( rtl8139->interrupt_handler ); + + rtl8139_print_info( rtl8139 ); ((driver_t *)rtl8139)->vtable = (driver_vtable_t *)&rtl8139_vtable; } @@ -187,7 +197,7 @@ uint32_t rtl8139_handle_interrupt( interrupt_handler_t *handler, uint32_t esp ) rtl8139_t *rtl8139 = (rtl8139_t *)handler->driver; #ifdef DEBUG - printf( "RTL INTERRUPT\n" ); + printf( "RTL8139 INTERRUPT\n" ); #endif return esp; diff --git a/src/drivers/net/rtl8139.h b/src/drivers/net/rtl8139.h index 5743205..66c9a22 100644 --- a/src/drivers/net/rtl8139.h +++ b/src/drivers/net/rtl8139.h @@ -11,6 +11,8 @@ typedef struct { network_t base; port8_t MAC_port[NOF_MAC_REGISTERS]; port8_t CMD_port; + port16_t IMR_port; + port16_t ISR_port; port32_t TCR_port; port32_t RCR_port; pci_device_descriptor_t pci_descriptor; diff --git a/src/hardware/interrupts.asm b/src/hardware/interrupts.asm index 30204e7..95d33f9 100644 --- a/src/hardware/interrupts.asm +++ b/src/hardware/interrupts.asm @@ -60,6 +60,7 @@ interrupts_handle_irq_%1: irq_stub 0x00 irq_stub 0x01 +irq_stub 0x0B irq_stub 0x0C int_entry: diff --git a/src/hardware/interrupts.c b/src/hardware/interrupts.c index bec0896..41433a5 100644 --- a/src/hardware/interrupts.c +++ b/src/hardware/interrupts.c @@ -109,6 +109,10 @@ void interrupts_init( interrupt_t *interrupt, uint16_t gdt_code_segment_selector interrupts_register_interrupt_gate( interrupt, IRQ_BASE + 0x01, gdt_code_segment_selector, &interrupts_handle_irq_0x01, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE ); + // IRQ 11 - PCI, at the moment the RTL8139 + interrupts_register_interrupt_gate( interrupt, IRQ_BASE + 0x0B, gdt_code_segment_selector, + &interrupts_handle_irq_0x0B, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE ); + // IRQ 12 - PS/2 mouse interrupts_register_interrupt_gate( interrupt, IRQ_BASE + 0x0C, gdt_code_segment_selector, &interrupts_handle_irq_0x0C, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE ); diff --git a/src/hardware/interrupts.h b/src/hardware/interrupts.h index 64040cb..f93fa44 100644 --- a/src/hardware/interrupts.h +++ b/src/hardware/interrupts.h @@ -103,6 +103,7 @@ void interrupts_ignore_request( ); void interrupts_handle_exception_0x00( ); void interrupts_handle_irq_0x00( ); void interrupts_handle_irq_0x01( ); +void interrupts_handle_irq_0x0B( ); void interrupts_handle_irq_0x0C( ); // later: tasks and stacks, queues -- cgit v1.2.3-54-g00ecf