From dddc5bbf2d91f20e6fb62edd105975a63a9c5058 Mon Sep 17 00:00:00 2001 From: "Mihail Semenyako (mike.dld)" Date: Sat, 3 Mar 2007 17:47:01 +0000 Subject: [PATCH] Updated gfx_kernel to revision #383 git-svn-id: svn://kolibrios.org@385 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../gfx_kernel/network/eth_drv/ethernet.inc | 1780 +++-------------- 1 file changed, 266 insertions(+), 1514 deletions(-) diff --git a/kernel/branches/gfx_kernel/network/eth_drv/ethernet.inc b/kernel/branches/gfx_kernel/network/eth_drv/ethernet.inc index 6d6dc10629..32686464e9 100644 --- a/kernel/branches/gfx_kernel/network/eth_drv/ethernet.inc +++ b/kernel/branches/gfx_kernel/network/eth_drv/ethernet.inc @@ -36,6 +36,22 @@ ; ;******************************************************************** +ETHER_IP equ 0x0008 ; Reversed from 0800 for intel +ETHER_ARP equ 0x0608 ; Reversed from 0806 for intel +ETHER_RARP equ 0x3580 + +struc ETH_FRAME +{ .DstMAC dp ? ;destination MAC-address [6 bytes] + .SrcMAC dp ? ;source MAC-address [6 bytes] + .Type dw ? ;type of the upper-layer protocol [2 bytes] + .Data db ? ;data [46-1500 bytes] +} + +virtual at Ether_buffer + ETH_FRAME ETH_FRAME +end virtual + + ; Some useful information on data structures ; Ethernet Packet - ARP Request example @@ -75,18 +91,14 @@ ; Include individual drivers source files at this point. ; If you create a new driver, include it below. -include "rtl8029.inc" -include "i8255x.inc" -include "rtl8139.inc" -include "3c59x.inc" -include "sis900.inc" -include "pcnet32.inc" - -; DEBUGGING_STATE enables or disables output of received and transmitted -; data over the serial port -DEBUGGING_ENABLED equ 1 -DEBUGGING_DISABLED equ 0 -DEBUGGING_STATE equ DEBUGGING_ENABLED +include "drivers/rtl8029.inc" +include "drivers/i8255x.inc" +include "drivers/rtl8139.inc" +include "drivers/3c59x.inc" +include "drivers/sis900.inc" +include "drivers/pcnet32.inc" +;include "drivers/mtd80x.inc" +include "drivers/rtl8169.inc" ; PCICards ; ======== @@ -100,167 +112,251 @@ DEBUGGING_STATE equ DEBUGGING_ENABLED ; be several lines which refer to the same functions. ; The first driver found on the PCI bus will be the one used. -PCICARDS_ENTRY_SIZE equ 20 ; Size of each PCICARDS entry +PCICARDS_ENTRY_SIZE equ 24 ; Size of each PCICARDS entry iglobal PCICards: -dd 0x12098086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit -dd 0x10298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit -dd 0x12298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit -dd 0x10308086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit -dd 0x24498086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit -dd 0x802910ec, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit -dd 0x12111113, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit -dd 0x813910ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -; /+/ Новые вендоры сетевых карт на базе rtl8139 -dd 0x813810ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -dd 0x12111113, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -dd 0x13601500, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -dd 0x13604033, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -dd 0x13001186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -dd 0x13401186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -dd 0xab0613d1, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -dd 0xa1171259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -dd 0xa11e1259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -dd 0xab0614ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -dd 0xab0714ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -dd 0x123411db, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -dd 0x91301432, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -dd 0x101202ac, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -dd 0x0106018a, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -dd 0x1211126c, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -dd 0x81391743, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -dd 0x8139021b, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit -; /-/ -dd 0x590010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x592010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x597010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x595010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x595110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x595210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x900010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x900110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x900410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x900510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x900610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x900A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x905010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x905110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x905510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x905810b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x905A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x920010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x980010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x980510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x764610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x505510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x605510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x605610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x5b5710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x505710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x515710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x525710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x656010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x656210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x656410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x450010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit -dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit -dd 0x20001022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit -dd 0x26251022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit -dd 0x20011022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit -; following card is untested -dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit -dd 0,0,0,0,0 ; end of list marker, do not remove +dd 0x12098086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 +dd 0x10298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 +dd 0x12298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 +dd 0x10308086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 +dd 0x24498086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 +dd 0x802910ec, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit, 0 +dd 0x12111113, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit, 0 + +dd 0x813910ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x813810ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x12111113, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x13601500, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x13604033, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x13001186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x13401186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0xab0613d1, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0xa1171259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0xa11e1259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0xab0614ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0xab0714ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x123411db, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x91301432, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x101202ac, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x0106018a, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x1211126c, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x81391743, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x8139021b, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable + +dd 0x816810ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 +dd 0x816910ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 +dd 0x011616ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 +dd 0x43001186, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 + +dd 0x590010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x592010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x597010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x595010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x595110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x595210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x900010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x900110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x900410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x900510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x900610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x900A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x905010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x905110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x905510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x905810b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x905A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x920010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x980010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x980510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x764610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x505510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x605510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x605610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x5b5710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x505710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x515710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x525710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x656010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x656210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x656410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 +dd 0x450010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 + +dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit, 0 + +dd 0x20001022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0 +dd 0x26251022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0 +dd 0x20011022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0 + +;dd 0x08031516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable + +; following cards are untested +dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit, 0 +;dd 0x08001516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable +;dd 0x08911516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable + +rb PCICARDS_ENTRY_SIZE ; end of list marker, do not remove endg -; PCI Bus defines -PCI_HEADER_TYPE equ 0x0e ;8 bit -PCI_BASE_ADDRESS_0 equ 0x10 ;32 bit -PCI_BASE_ADDRESS_5 equ 0x24 ;32 bits -PCI_BASE_ADDRESS_SPACE_IO equ 0x01 -PCI_VENDOR_ID equ 0x00 ;16 bit -PCI_BASE_ADDRESS_IO_MASK equ 0xFFFFFFFC - -ETHER_IP equ 0x0008 ; Reversed from 0800 for intel -ETHER_ARP equ 0x0608 ; Reversed from 0806 for intel -ETHER_RARP equ 0x3580 -ARP_REQ_OPCODE equ 0x0100 -ARP_REP_OPCODE equ 0x0200 - uglobal - arp_rx_count: dd 0 - ip_rx_count: dd 0 - dumped_rx_count: dd 0 - ip_tx_count: dd 0 - node_addr: db 0,0,0,0,0,0 +;Net-stack's interface's settings + node_addr: db 0,0,0,0,0,0 + gateway_ip: dd 0 + dns_ip: dd 0 + eth_rx_data_len: dw 0 - eth_status: dd 0 - io_addr: dd 0 - hdrtype: db 0 + eth_status: dd 0 + io_addr: dd 0 + hdrtype: db 0 vendor_device: dd 0 - pci_data: dd 0 - pci_dev: dd 0 - pci_bus: dd 0 + pci_data: dd 0 + pci_dev: dd 0 + pci_bus: dd 0 ; These will hold pointers to the selected driver functions - drvr_probe: dd 0 - drvr_reset: dd 0 - drvr_poll: dd 0 + drvr_probe: dd 0 + drvr_reset: dd 0 + drvr_poll: dd 0 drvr_transmit: dd 0 + drvr_cable: dd 0 - ; These hold the destination Host identity for ARP responses - remote_ip_add: dd 0 - remote_hw_add: db 0, 0, 0, 0, 0, 0 endg iglobal broadcast_add: db 0xff,0xff,0xff,0xff,0xff,0xff - subnet_mask: dd 0x00ffffff + subnet_mask: dd 0x00ffffff ; 255.255.255.0 endg -uglobal - ; This is used by getMACfromIP - MACAddress: db 0,0,0,0,0,0 - gateway_ip: db 0, 0, 0, 0 - dns_ip: dd 0 -endg +include "arp.inc" ;arp-protocol functions +include "pci.inc" ;PCI bus access functions -; The follow is the ARP Table. -; This table must be manually updated and the kernel recompilied if -; changes are made to it. -; ARP_TABLE_SIZE defines the size of the table -; ARP_TABLE_ENTRIES defines the number of entries in the table -; Each entry is 10 bytes: 4 Byte IP address, 6 byte MAC Address, -; 2 bytes status, 2 bytes TTL ( in seconds ) -; Empty entries are filled with zeros -; The TTL field is decremented every second, and is deleted when it -; reaches 0. It is refreshed every time a packet is received -; If the TTL field is 0xFFFF it is a permanent entry and is never deleted -; The status field can be the following values -; 0x0000 entry not used -; 0x0001 entry holds a valid mapping -; 0x0002 entry contains an IP address, awaiting ARP response -; 0x0003 No response received to ARP request. -; The last status value is provided to allow the network layer to delete -; a packet that is queued awaiting an ARP response -ARP_NO_ENTRY equ 0 -ARP_VALID_MAPPING equ 1 -ARP_AWAITING_RESPONSE equ 2 -ARP_RESPONSE_TIMEOUT equ 3 +;*************************************************************************** +; Function +; eth_tx +; +; Description +; Looks at the NET1OUT_QUEUE for data to send. +; Stores that destination IP in a location used by the tx routine +; Looks up the MAC address in the ARP table; stores that where +; the tx routine can get it +; Get the length of the data. Store that where the tx routine wants it +; Call tx +; Places buffer on empty queue when the tx routine finished +; +;*************************************************************************** +proc eth_tx stdcall uses ebx esi edi +local MACAddress dp ? ;allocate 6 bytes in the stack -ARP_ENTRY_SIZE equ 14 ; Number of bytes per entry -ARP_TABLE_SIZE equ 20 ; Size of table -ARP_TABLE_ENTRIES equ 0 ; Inital, hardcoded entries + ; Look for a buffer to tx + mov eax, NET1OUT_QUEUE + call dequeue + cmp ax, NO_BUFFER + je .exit ; Exit if no buffer available -uglobal - ARPTable: - times ( ARP_TABLE_SIZE - ARP_TABLE_ENTRIES ) * ARP_ENTRY_SIZE db 0 -endg + push eax ;save buffer number -iglobal - NumARP: db ARP_TABLE_ENTRIES -endg + ; convert buffer pointer eax to the absolute address + imul eax, IPBUFFSIZE + add eax, IPbuffs + + ; Extract the destination IP + ; find the destination IP in the ARP table, get MAC + ; store this MAC in 'MACAddress' + mov ebx, eax ; Save buffer address + mov edx, [ebx + 16] ; get destination address + + ; If the destination address is 255.255.255.255, + ; set the MACAddress to all ones ( broadcast ) + cld + mov esi, broadcast_add + lea edi, [MACAddress] + movsd + movsw + cmp edx, 0xffffffff + je .send ; If it is broadcast, just send + + lea eax, [MACAddress] ;cause this is local variable + stdcall arp_table_manager, ARP_TABLE_IP_TO_MAC, edx, eax ;opcode,IP,MAC_ptr - Get the MAC address. + + cmp eax, ARP_VALID_MAPPING + je .send + + ; No valid entry. Has the request been sent, but timed out? + cmp eax, ARP_RESPONSE_TIMEOUT + je .freebuf + + .wait_response: ;we wait arp-response + ; Re-queue the packet, and exit + pop ebx + mov eax, NET1OUT_QUEUE + call queue ; Get the buffer back + jmp .exit + + .send: ;if ARP_VALID_MAPPING then send the packet + lea edi, [MACAddress] ; Pointer to 48 bit destination address + movzx ecx, word[ebx+2] ; Size of IP packet to send + xchg ch, cl ; because mirror byte-order + mov esi, ebx ; Pointer to packet data + mov bx, ETHER_IP ; Type of packet + call dword [drvr_transmit] ; Call the drivers transmit function + + ; OK, we have sent a packet, so increment the count + inc dword [ip_tx_count] + + ; And finally, return the buffer to the free queue + .freebuf: + pop eax + call freeBuff + + .exit: + ret +endp + +;*************************************************************************** +; Function +; ether_IP_handler +; +; Description +; Called when an IP ethernet packet is received on the ethernet +; Header + Data is in Ether_buffer[] +; We just need to get a buffer from the 'free' queue, and +; store the packet in it, then insert the packet number into the +; IPRX queue. +; If no queue entry is available, the packet is silently discarded +; All registers may be destroyed +; +;*************************************************************************** +ether_IP_handler: + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je eiph00x + + ; convert buffer pointer eax to the absolute address + push eax + mov ecx, IPBUFFSIZE + mul ecx + add eax, IPbuffs + + mov edi, eax + + ; get a pointer to the start of the DATA + mov esi, ETH_FRAME.Data + + ; Now store it all away + mov ecx, IPBUFFSIZE / 4 ; Copy all of the available + ; data across - worse case + cld + rep movsd + + ; And finally, place the buffer in the IPRX queue + pop ebx + mov eax, IPIN_QUEUE + call queue + +eiph00x: + ret ;*************************************************************************** ; Function @@ -276,14 +372,14 @@ endg ;*************************************************************************** eth_probe: ; Find a card on the PCI bus, and get it's address - call scan_bus ; Find the ethernet cards PIC address + call scan_bus ; Find the ethernet cards PIC address xor eax, eax cmp [io_addr], eax - je ep_00x ; Return 0 in eax if no cards found + je ep_00x ; Return 0 in eax if no cards found - call dword [drvr_probe] ; Call the drivers probe function + call dword [drvr_probe] ; Call the drivers probe function - mov eax, [io_addr] ; return a non zero value + mov eax, [io_addr] ; return a non zero value ep_00x: ret @@ -300,7 +396,7 @@ ep_00x: ethernet_driver: ; Do nothing if the driver is inactive cmp [ethernet_active], byte 0 - je eth_exit + je eth_exit call eth_rx call eth_tx @@ -323,1379 +419,35 @@ eth_exit: eth_rx: xor ax, ax mov [eth_rx_data_len], ax - call dword [drvr_poll] ; Call the drivers poll function + call dword [drvr_poll] ; Call the drivers poll function mov ax, [eth_rx_data_len] cmp ax, 0 - je erx_exit + je .exit -if DEBUGGING_STATE = DEBUGGING_ENABLED - pusha - mov eax, 0 ;Indicate that this is a received packet - mov cx, [eth_rx_data_len] - mov esi, Ether_buffer - cmp word [esi + 12], ETHER_IP - jnz erxd_done -; cmp byte [esi + 14 + 9], 0x06 ; TCP -; jnz erxd_done - call eth_dump -erxd_done: - popa -end if ; Check the protocol. Call appropriate handler - mov eax, Ether_buffer - add eax, 12 ; The address of the protocol word - mov ax, [eax] - - cmp ax, ETHER_ARP - je erx_001 ; It is ARP + mov ax, [ETH_FRAME.Type] ; The address of the protocol word cmp ax, ETHER_IP - je erx_002 ; It's IP + je .is_ip ; It's IP -; inc dword [dumped_rx_count] + cmp ax, ETHER_ARP + je .is_arp ; It is ARP - jmp erx_exit ; If not IP or ARP, ignore + jmp .exit ; If not IP or ARP, ignore -erx_001: - mov eax, [arp_rx_count] - inc eax - mov [arp_rx_count], eax + .is_ip: + DEBUGF 1,"K : eth_rx - IP packet\n" + inc dword [ip_rx_count] + call ether_IP_handler + jmp .exit + .is_arp: + DEBUGF 1,"K : eth_rx - ARP packet\n" ; At this point, the packet is still in the Ether_buffer call arp_handler - jmp erx_exit - -erx_002: - mov eax, [ip_rx_count] - inc eax - mov [ip_rx_count], eax - - ; Check to see if the MAC address is in our arp table - ; refresh the arp ttl if so - - mov esi, Ether_buffer - add esi, 6 - - call refreshARP - - call ether_IP_handler - - jmp erx_exit - -erx_exit: + .exit: ret - -;*************************************************************************** -; Function -; eth_tx -; -; Description -; Looks at the NET1OUT_QUEUE for data to send. -; Stores that destination IP in a location used by the tx routine -; Looks up the MAC address in the ARP table; stores that where -; the tx routine can get it -; Get the length of the data. Store that where the tx routine wants it -; Call tx -; Places buffer on empty queue when the tx routine finished -; -;*************************************************************************** -eth_tx: - ; Look for a buffer to tx - mov eax, NET1OUT_QUEUE - call dequeue - cmp ax, NO_BUFFER - je eth_exit ; Exit if no buffer available - - push eax - - ; convert buffer pointer eax to the absolute address - mov ecx, IPBUFFSIZE - mul ecx - add eax, IPbuffs - - ; Extract the destination IP - ; find the destination IP in the ARP table, get MAC - ; store this MAC in 'MACAddress' - mov ebx, eax ; Save buffer address - mov edx, [ebx + 16] ; get destination address - - ; If the destination address is 255.255.255.255, - ; set the MACAddress to all ones ( broadcast ) - mov [MACAddress], dword 0xffffffff - mov [MACAddress + 4], word 0xffff - cmp edx, 0xffffffff - je etx_send ; If it is broadcast, just send - - call getMACfromIP ; Get the MAC address. - - cmp eax, ARP_VALID_MAPPING - jz etx_send - - ; No valid entry. Are we waiting for a response? - cmp eax, ARP_AWAITING_RESPONSE - jne etx_001 - - ; Re-queue the packet, and exit - pop ebx - mov eax, NET1OUT_QUEUE - call queue - jmp etx_exit - -etx_001: - ; HAs the request been sent, but timed out? - cmp eax, ARP_RESPONSE_TIMEOUT - jne etx_002 - - pop eax - call freeBuff - jmp etx_exit - -etx_002: - ; There is no entry. Re queue the request, and ask ARP to send a request - - ; IP address is in edx - push edx - call arp_request - pop ebx - - ; Add an entry in the ARP table, awaiting response - - cmp byte [NumARP], ARP_TABLE_SIZE - je etx_003 ; We cannot add a new entry in the table - - inc byte [NumARP] - - movzx eax, byte [NumARP] - mov ecx, ARP_ENTRY_SIZE - mul ecx - sub eax, ARP_ENTRY_SIZE - - mov [eax + ARPTable], ebx - xor ebx, ebx - mov [eax + ARPTable + 4], ebx - mov [eax + ARPTable + 8], bx - - ; set the status field up - awaiting response - mov cl, 0x00 - mov [eax + ARPTable + 10], cl - mov cl, 0x02 - mov [eax + ARPTable + 11], cl - - ; Initialise the time to live field - 10s - mov cx, 0x000A - mov [eax + ARPTable + 12], cx - -etx_003: - pop ebx ; Get the buffer back - mov eax, NET1OUT_QUEUE - call queue - jmp etx_exit - -etx_send: - xor ecx, ecx - mov ch, [ebx+2] - mov cl, [ebx+3] ; ; Size of IP packet to send - - mov esi, ebx - - mov edi, MACAddress - -if DEBUGGING_STATE = DEBUGGING_ENABLED - pusha - mov cx, 42 - mov eax, 1 ; Indicate that this is a tx packet - call eth_dump - popa -end if - - mov bx, ETHER_IP - call dword [drvr_transmit] ; Call the drivers transmit function - - ; OK, we have sent a packet, so increment the count - inc dword [ip_tx_count] - - ; And finally, return the buffer to the free queue - pop eax - call freeBuff - -etx_exit: - ret - -;*************************************************************************** -; Function -; ether_IP_handler -; -; Description -; Called when an IP ethernet packet is received on the ethernet -; Header + Data is in Ether_buffer[] -; We just need to get a buffer from the 'free' queue, and -; store the packet in it, then insert the packet number into the -; IPRX queue. -; If no queue entry is available, the packet is silently discarded -; All registers may be destroyed -; -;*************************************************************************** -ether_IP_handler: - mov eax, EMPTY_QUEUE - call dequeue - cmp ax, NO_BUFFER - je eiph00x - - ; convert buffer pointer eax to the absolute address - push eax - mov ecx, IPBUFFSIZE - mul ecx - add eax, IPbuffs - - mov edi, eax - - ; get a pointer to the start of the DATA - mov esi, Ether_buffer + 14 - - ; Now store it all away - mov ecx, IPBUFFSIZE / 4 ; Copy all of the available - ; data across - worse case - cld - rep movsd - - ; And finally, place the buffer in the IPRX queue - pop ebx - mov eax, IPIN_QUEUE - call queue - -eiph00x: - ret - -;*************************************************************************** -; -; ARP CODE FOLLOWS -; -; The ARP code is used by ethernet drivers to translate an destination -; IP address into an ethernet hardware address. Functions to broadcast -; requests and handle response are (or will be) here. -; The IP layer has no knowledge of ARP, as this is a network interface -; issue -; -;*************************************************************************** - -;*************************************************************************** -; Function -; arp_timer -; -; Description -; Called every 1s -; It is responsible for removing expired routes -; All registers may be destroyed -; -;*************************************************************************** -arp_timer: - ; loop through all the ARP entries, decrementing each one - ; that doesn't have a TTL of 0xFFFF - movzx eax, byte [NumARP] - -arp_001: - cmp eax, 0 - je arp_003 - - push eax - dec eax - mov ecx, ARP_ENTRY_SIZE - mul ecx - cmp word [ eax + ARPTable + 12], 0xFFFF - je arp_002 - - cmp word [ eax + ARPTable + 12], 0 - je arp_002 - - dec word [eax + ARPTable + 12] - -arp_002: - pop eax - dec eax - jmp arp_001 - - ; Now, look for entries with a TTL of 0 - ; Valid entries and response timeout entries get removed - ; awaiting response gets converted into a response timeout, with a - ; short life time - this allows queued packets to be flushed -arp_003: - movzx edx, byte [NumARP] - cmp edx, 0 - je arp_exit - - ; EDX holds the # of entries to search through - mov eax, 0 - -arp_005: - cmp word [ eax + ARPTable + 12], 0 - jne arp_004 - - ; If it's status code is 0001 or 0003, delete the entry - cmp word [eax + ARPTable + 10], 0x0100 - je arp_007 - cmp word [eax + ARPTable + 10], 0x0300 - je arp_007 - - ; The only other valid code is 0002 - indicating a - ; timeout while waiting for a response. Change the - ; entry to response timed out - - mov [eax + ARPTable + 10], word 0x0300 - mov [eax + ARPTable + 12], word 0x000A - jmp arp_004 - -arp_007: - ; Delete this entry - mov edi, ARPTable - add edi, eax - mov esi, edi - add esi, ARP_ENTRY_SIZE - - mov ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE - sub ecx, eax - - rep movsb - - dec byte [NumARP] - jmp arp_006 - -arp_004: - add eax, ARP_ENTRY_SIZE -arp_006: - dec edx - cmp edx, 0 - jne arp_005 - -arp_exit: - ret - -;*************************************************************************** -; Function -; arp_request -; -; Description -; Sends an ARP request on the ethernet -; The requested IP address is in edx -; All registers may be destroyed -; -;*************************************************************************** -arp_request: - mov ebx, Ether_buffer - mov ax, 0x0100 - mov [ebx], ax - add ebx, 2 - - mov ax, 0x0008 - mov [ebx], ax - add ebx, 2 - - mov ax, 0x0406 - mov [ebx], ax - add ebx, 2 - - mov ax, 0x0100 - mov [ebx], ax - add ebx, 2 - - mov ecx, node_addr - mov eax, [ecx] - mov [ebx], eax - add ecx, 4 - add ebx, 4 - mov ax, [ecx] - mov [ebx], ax - add ebx, 2 - mov eax, [stack_ip] - mov [ebx], eax - add ebx, 4 - - xor eax, eax - mov [ebx], eax - add ebx, 4 - mov [ebx], ax - - add ebx, 2 - mov [ebx], edx - - ; Now, send it! - - ; Pointer to 48 bit destination address in edi - ; Type of packet in bx - ; size of packet in ecx - ; pointer to packet data in esi - mov edi, broadcast_add - -;if DEBUGGING_STATE = DEBUGGING_ENABLED -; pusha -; mov eax, 1 ; Indicate that this is a tx packet -; mov ecx, 28 -; mov esi, Ether_buffer -; call eth_dump -; popa -;end if - - mov bx, ETHER_ARP - mov ecx, 28 - mov esi, Ether_buffer - call dword [drvr_transmit] ; Call the drivers transmit function - ret - -;*************************************************************************** -; Function -; arp_handler -; -; Description -; Called when an ARP packet is received on the ethernet -; Header + Data is in Ether_buffer[] -; It looks to see if the packet is a request to resolve this Hosts -; IP address. If it is, send the ARP reply packet. -; This Hosts IP address is in dword [stack_ip] ( in network format ) -; This Hosts MAC address is in node_addr[6] -; All registers may be destroyed -; -;*************************************************************************** -arp_handler: - ; Is this a REQUEST? - ; Is this a request for My Host IP - ; Yes - So construct a response message. - ; Send this message to the ethernet card for transmission - - mov ebx, Ether_buffer - - mov edx, ebx - add edx, 20 - mov ax, [edx] - cmp ax, ARP_REQ_OPCODE ; Is this a request packet? - jne arph_resp ; No - so test for response - - mov edx, ebx - add edx, 38 - mov eax, [edx] - - cmp eax, [stack_ip] ; Is it looking for my IP address? - jne arph_exit ; No - so quit now - - ; OK, it is a request for my MAC address. Build the frame and send it - - ; Save the important data from the original packet - ; remote MAC address first - mov ecx, remote_hw_add - mov edx, ebx - add edx, 22 ; edx points to Source h/w address - mov eax, [edx] - mov [ecx], eax - add edx, 4 - add ecx, 4 - mov ax, [edx] - mov [ecx],ax - - ; and also the remote IP address - add edx, 2 - mov eax,[edx] - mov [remote_ip_add], eax - - ; So now we can reuse the packet. ebx still holds the address of - ; the header + packet - ; We dont need the header ( first 14 bytes ) - - mov edx, ebx - add edx, 20 - mov ax, ARP_REP_OPCODE - mov [edx], ax - add edx, 2 - - mov ecx, node_addr - mov eax, [ecx] - mov [edx], eax - add ecx, 4 - add edx, 4 - mov ax, [ecx] - mov [edx], ax - add edx, 2 - mov eax, [stack_ip] - mov [edx], eax - add edx, 4 - mov ecx, remote_hw_add - mov eax, [ecx] - mov [edx], eax - add ecx, 4 - add edx, 4 - mov ax, [ecx] - mov [edx], ax - - add edx, 2 - mov eax, [remote_ip_add] - mov [edx], eax - - ; Now, send it! - - ; Pointer to 48 bit destination address in edi - ; Type of packet in bx - ; size of packet in ecx - ; pointer to packet data in esi - mov edi, remote_hw_add - -;if DEBUGGING_STATE = DEBUGGING_ENABLED -; pusha -; mov eax, 1 ; Indicate that this is a tx packet -; mov ecx, 28 -; mov esi, Ether_buffer + 14 - ; call eth_dump -; popa -;end if - - mov bx, ETHER_ARP - mov ecx, 28 - mov esi, Ether_buffer + 14 - call dword [drvr_transmit] ; Call the drivers transmit function - jmp arph_exit - -arph_resp: - cmp ax, ARP_REP_OPCODE ; Is this a replypacket? - jne arph_resp ; No - so quit - - ; This was a reply, probably directed at me. - ; save the remotes MAC & IP - mov ecx, remote_hw_add - mov edx, ebx - add edx, 22 ; edx points to Source h/w address - mov eax, [edx] - mov [ecx], eax - add edx, 4 - add ecx, 4 - mov ax, [edx] - mov [ecx],ax - - ; and also the remote IP address - add edx, 2 - mov eax,[edx] - mov [remote_ip_add], eax - - ; Now, add an entry in the table for this IP address if it doesn't exist - - push eax - movzx eax, byte [NumARP] - mov ecx, ARP_ENTRY_SIZE - mul ecx - pop edx - movzx ecx, byte [NumARP] - cmp ecx, 0 - je arph_002 - -arph_001: - sub eax, ARP_ENTRY_SIZE - cmp [eax + ARPTable], edx - loopnz arph_001 ; Return back if non match - - jnz arph_002 ; None found, add to end - - mov ecx, [remote_hw_add] - mov [eax + ARPTable + 4], ecx - mov cx, [remote_hw_add+4] - mov [eax + ARPTable + 8], cx - - ; specify the type - a valid entry - mov cl, 0x00 - mov [eax + ARPTable + 10], cl - mov cl, 0x01 - mov [eax + ARPTable + 11], cl - - ; Initialise the time to live field - 1 hour - mov cx, 0x0E10 - mov [eax + ARPTable + 12], cx - jmp arph_exit - -arph_002: - - cmp byte [NumARP], ARP_TABLE_SIZE - je arph_exit - - inc byte [NumARP] - - movzx eax, byte [NumARP] - mov ecx, ARP_ENTRY_SIZE - mul ecx - sub eax, ARP_ENTRY_SIZE - - mov ecx, [remote_ip_add] - mov [eax + ARPTable], ecx - mov ecx, [remote_hw_add] - mov [eax + ARPTable + 4], ecx - mov cx, [remote_hw_add+4] - mov [eax + ARPTable + 8], cx - - mov cl, 0x00 - mov [eax + ARPTable + 10], cl - mov cl, 0x01 - mov [eax + ARPTable + 11], cl - - ; Initialise the time to live field - 1 hour - mov cx, 0x0E10 - mov [eax + ARPTable + 12], cx - -arph_exit: - ret - -; pointer to MAC in esi -refreshARP: - mov ebx, [esi] - mov dx, [esi+4] - push edx - movzx eax, byte [NumARP] - mov ecx, ARP_ENTRY_SIZE - mul ecx - pop edx - movzx ecx, byte [NumARP] - cmp ecx, 0 - je rf_exit - -rf_001: - sub eax, ARP_ENTRY_SIZE - cmp [eax + ARPTable+4], ebx - - je rf_002 - loop rf_001 - jmp rf_exit - -rf_002: - cmp [eax + ARPTable+8], dx - je rf_gotone - loop rf_001 - jmp rf_exit - -rf_gotone: - ; Initialise the time to live field - 1 hour - mov cx, 0x0E10 - mov [eax + ARPTable + 12], cx - -rf_exit: - ret - -;*************************************************************************** -; Function -; getMACfromIP -; -; Description -; Takes an IP address in edx and scans the ARP table for -; a matching entry -; If a match is found, it's MAC address is stored in MACAddress. -; Otherwise the value 0 is writen to MACAddress -; eax holds ARP table entry status code ( ARP_ ) -; ebx unchanged -; -;*************************************************************************** -getMACfromIP: - ; first, check destination IP to see if it is on 'this' network. - ; The test is: - ; if ( destIP & subnet_mask == stack_ip & subnet_mask ) - ; desitnation is local - ; else - ; destination is remote, so pass to gateway - - mov eax, edx - and eax, [subnet_mask] - mov ecx, [stack_ip] - and ecx, [subnet_mask] - cmp eax, ecx - je gm0 - - mov edx, [gateway_ip] -gm0: - push edx - xor eax, eax - mov [MACAddress], eax - mov [MACAddress + 4], ax - - movzx eax, byte [NumARP] - mov ecx, ARP_ENTRY_SIZE - mul ecx - - pop edx - - movzx ecx, byte [NumARP] - cmp ecx, 0 - je gm_none -gm1: - sub eax, ARP_ENTRY_SIZE - cmp [eax + ARPTable], edx - loopnz gm1 ; Return back if non match - jnz gm_none ; Quit if none found - - ; eax holds index - mov ecx, [eax + ARPTable + 4] - mov [MACAddress], ecx - mov cx, [eax + ARPTable + 8] - mov [MACAddress+4], cx - - ; Return the entry status in eax - mov ch, [eax + ARPTable + 10] - mov cl, [eax + ARPTable + 11] - movzx eax, cx - jmp gm_exit - -gm_none: - mov eax, ARP_NO_ENTRY - -gm_exit: - ret - -;*************************************************************************** -; -; PCI CODE FOLLOWS -; -; the following functions provide access to the PCI interface. -; These functions are used by scan_bus, and also some ethernet drivers -; -;*************************************************************************** - -;*************************************************************************** -; Function -; config_cmd -; -; Description -; creates a command dword for use with the PCI bus -; bus # in ebx -; devfn in ecx -; where in edx -; -; command dword returned in eax -; Only eax destroyed -;*************************************************************************** -config_cmd: - push ecx - mov eax, ebx - shl eax, 16 - or eax, 0x80000000 - shl ecx, 8 - or eax, ecx - pop ecx - or eax, edx - and eax, 0xFFFFFFFC - ret - -;*************************************************************************** -; Function -; pcibios_read_config_byte -; -; Description -; reads a byte from the PCI config space -; bus # in ebx -; devfn in ecx -; where in edx ( ls 16 bits significant ) -; -; byte returned in al ( rest of eax zero ) -; Only eax/edx destroyed -;*************************************************************************** -pcibios_read_config_byte: - call config_cmd - push dx - mov dx, 0xCF8 - out dx, eax - pop dx - - xor eax, eax - and dx, 0x03 - add dx, 0xCFC -; and dx, 0xFFC - in al, dx - ret - -;*************************************************************************** -; Function -; pcibios_read_config_word -; -; Description -; reads a word from the PCI config space -; bus # in ebx -; devfn in ecx -; where in edx ( ls 16 bits significant ) -; -; word returned in ax ( rest of eax zero ) -; Only eax/edx destroyed -;*************************************************************************** -pcibios_read_config_word: - call config_cmd - push dx - mov dx, 0xCF8 - out dx, eax - pop dx - - xor eax, eax - and dx, 0x02 - add dx, 0xCFC -; and dx, 0xFFC - in ax, dx - ret - -;*************************************************************************** -; Function -; pcibios_read_config_dword -; -; Description -; reads a dword from the PCI config space -; bus # in ebx -; devfn in ecx -; where in edx ( ls 16 bits significant ) -; -; dword returned in eax -; Only eax/edx destroyed -;*************************************************************************** -pcibios_read_config_dword: - push edx - call config_cmd - push dx - mov dx, 0xCF8 - out dx, eax - pop dx - xor eax, eax - mov dx, 0xCFC - in eax, dx - pop edx - ret - -;*************************************************************************** -; Function -; pcibios_write_config_byte -; -; Description -; write a byte in al to the PCI config space -; bus # in ebx -; devfn in ecx -; where in edx ( ls 16 bits significant ) -; -; Only eax/edx destroyed -;*************************************************************************** -pcibios_write_config_byte: - push ax - call config_cmd - push dx - mov dx, 0xCF8 - out dx, eax - pop dx - pop ax - - and dx, 0x03 - add dx, 0xCFC - out dx, al - ret - -;*************************************************************************** -; Function -; pcibios_write_config_word -; -; Description -; write a word in ax to the PCI config space -; bus # in ebx -; devfn in ecx -; where in edx ( ls 16 bits significant ) -; -; Only eax/edx destroyed -;*************************************************************************** -pcibios_write_config_word: - push ax - call config_cmd - push dx - mov dx, 0xCF8 - out dx, eax - pop dx - pop ax - - and dx, 0x02 - add dx, 0xCFC - out dx, ax - ret - -;*************************************************************************** -; Function -; delay_us -; -; Description -; delays for 30 to 60 us -; -; I would prefer this routine to be able to delay for -; a selectable number of microseconds, but this works for now. -; -; If you know a better way to do 2us delay, pleae tell me! -;*************************************************************************** -delay_us: - push eax - push ecx - - mov ecx,2 - - in al,0x61 - and al,0x10 - mov ah,al - cld - -dcnt1: - in al,0x61 - and al,0x10 - cmp al,ah - jz dcnt1 - - mov ah,al - loop dcnt1 - - pop ecx - pop eax - - ret - -;*************************************************************************** -; Function -; scan_bus -; -; Description -; Scans the PCI bus for a supported device -; If a supported device is found, the drvr_ variables are initialised -; to that drivers functions ( as defined in the PCICards table) -; -; io_addr holds card I/O space. 32 bit, but only LS 16 bits valid -; pci_data holds the PCI vendor + device code -; pci_dev holds PCI bus dev # -; pci_bus holds PCI bus # -; -; io_addr will be zero if no card found -; -;*************************************************************************** -scan_bus: - xor eax, eax - mov [hdrtype], al - mov [pci_data], eax - - xor ebx, ebx ; ebx = bus# 0 .. 255 - -sb_bus_loop: - xor ecx, ecx ; ecx = devfn# 0 .. 254 ( not 255? ) - -sb_devf_loop: - mov eax, ecx - and eax, 0x07 - - cmp eax, 0 - jne sb_001 - - mov edx, PCI_HEADER_TYPE - call pcibios_read_config_byte - mov [hdrtype], al - jmp sb_002 - -sb_001: - mov al, [hdrtype] - and al, 0x80 - cmp al, 0x80 - jne sb_inc_devf - -sb_002: - mov edx, PCI_VENDOR_ID - call pcibios_read_config_dword - mov [vendor_device], eax - cmp eax, 0xffffffff - je sb_empty - cmp eax, 0 - jne sb_check_vendor - -sb_empty: - mov [hdrtype], byte 0 - jmp sb_inc_devf - -sb_check_vendor: - ; iterate though PCICards until end or match found - mov esi, PCICards - -sb_check: - cmp [esi], dword 0 - je sb_inc_devf ; Quit if at last entry - cmp eax, [esi] - je sb_got_card - add esi, PCICARDS_ENTRY_SIZE - jmp sb_check - -sb_got_card: - ; indicate that we have found the card - mov [pci_data], eax - mov [pci_dev], ecx - mov [pci_bus], ebx - - ; Define the driver functions - push eax - mov eax, [esi+4] - mov [drvr_probe], eax - mov eax, [esi+8] - mov [drvr_reset], eax - mov eax, [esi+12] - mov [drvr_poll], eax - mov eax, [esi+16] - mov [drvr_transmit], eax - pop eax - - mov edx, PCI_BASE_ADDRESS_0 - -sb_reg_check: - call pcibios_read_config_dword - mov [io_addr], eax - and eax, PCI_BASE_ADDRESS_IO_MASK - cmp eax, 0 - je sb_inc_reg - mov eax, [io_addr] - and eax, PCI_BASE_ADDRESS_SPACE_IO - cmp eax, 0 - je sb_inc_reg - - mov eax, [io_addr] - and eax, PCI_BASE_ADDRESS_IO_MASK - mov [io_addr], eax - -sb_exit1: - ret - -sb_inc_reg: - add edx, 4 - cmp edx, PCI_BASE_ADDRESS_5 - jbe sb_reg_check - -sb_inc_devf: - inc ecx - cmp ecx, 255 - jb sb_devf_loop - inc ebx - cmp ebx, 256 - jb sb_bus_loop - - ; We get here if we didn't find our card - ; set io_addr to 0 as an indication - xor eax, eax - mov [io_addr], eax - -sb_exit2: - ret - -;*************************************************************************** -; -; DEBUGGING CODE FOLLOWS -; -; If debugging data output is not required, ALL code & data below may -; be removed. -; -;*************************************************************************** - -if DEBUGGING_STATE = DEBUGGING_ENABLED - -;*************************************************************************** -; Function -; eth_dump -; -; Description -; Dumps a tx or rx ethernet packet over the rs232 link -; This is a debugging routine that seriously slows down the stack. -; Use with caution. -; -; Baud rate is 57600, 8n1 com1 -; eax : type (0 == rx, 1 == tx ) -; cx : # of bytes in buffer -; esi : address of buffer start -; edi : pointer to MACAddress ( tx only ) -; -;*************************************************************************** -eth_dump: - pusha - - ; Set the port to the desired speed - mov ebx, 0x3f8 ; combase - - mov edx, ebx - add edx, 3 ; data format register - mov al, 0x80 ; enable access to divisor latch - out dx, al - - mov edx, ebx - add edx, 1 ; interrupt enable register - mov al, 0x00 ; No interruts enabled - out dx, al - - mov edx, ebx - mov al, 0x20 / 16 ; set baud rate to 57600 0x10 =115200 - out dx, al - - mov edx, ebx - add edx, 3 ; data format register - mov al, 0x03 ; 8 data bits - out dx, al - - mov edx, ebx - add edx, 4 ; Modem control register - mov al, 0x08 ; out2 enabled. No handshaking. - out dx, al - - mov edx, ebx - add edx, 1 ; interrupt enable register - mov al, 0x01 ; Receive data interrupt enabled, - out dx, al - - popa - - ; First, display the type of the buffer. - ; If it is a tx buffer, display the macaddress - - pusha - - cmp eax, 0 - jne dd001 - - mov bl, 0x0a - call tx_byted - mov bl, 0x0d - call tx_byted - - ; Output "RX:" - mov bl, 'R' - call tx_byted - mov bl, 'X' - call tx_byted - mov bl, ':' - call tx_byted - jmp dump_data - -dd001: - mov bl, 0x0a - call tx_byted - mov bl, 0x0d - call tx_byted - - ; Output TX: xxxxxxxxxxxx - mov bl, 'T' - call tx_byted - mov bl, 'X' - call tx_byted - mov bl, ':' - call tx_byted - mov bl, ' ' - call tx_byted - - ; Display MAC address - xor eax, eax - mov al, [edi] - shr al, 4 - mov bl, [eax + hexchars] - call tx_byted ; byte in bl eax ebx edx destroyed - - xor eax, eax - mov al, [edi] - and al, 0x0f - mov bl, [eax + hexchars] - call tx_byted ; byte in bl eax ebx edx destroyed - - inc edi - xor eax, eax - mov al, [edi] - shr al, 4 - mov bl, [eax + hexchars] - call tx_byted ; byte in bl eax ebx edx destroyed - - xor eax, eax - mov al, [edi] - and al, 0x0f - mov bl, [eax + hexchars] - call tx_byted ; byte in bl eax ebx edx destroyed - - inc edi - xor eax, eax - mov al, [edi] - shr al, 4 - mov bl, [eax + hexchars] - call tx_byted ; byte in bl eax ebx edx destroyed - - xor eax, eax - mov al, [edi] - and al, 0x0f - mov bl, [eax + hexchars] - call tx_byted ; byte in bl eax ebx edx destroyed - - inc edi - xor eax, eax - mov al, [edi] - shr al, 4 - mov bl, [eax + hexchars] - call tx_byted ; byte in bl eax ebx edx destroyed - - xor eax, eax - mov al, [edi] - and al, 0x0f - mov bl, [eax + hexchars] - call tx_byted ; byte in bl eax ebx edx destroyed - - inc edi - xor eax, eax - mov al, [edi] - shr al, 4 - mov bl, [eax + hexchars] - call tx_byted ; byte in bl eax ebx edx destroyed - - xor eax, eax - mov al, [edi] - and al, 0x0f - mov bl, [eax + hexchars] - call tx_byted ; byte in bl eax ebx edx destroyed - - inc edi - xor eax, eax - mov al, [edi] - shr al, 4 - mov bl, [eax + hexchars] - call tx_byted ; byte in bl eax ebx edx destroyed - - xor eax, eax - mov al, [edi] - and al, 0x0f - mov bl, [eax + hexchars] - call tx_byted ; byte in bl eax ebx edx destroyed - -dump_data: - popa - - ; OK, we come in here with - ; cx == number of byte to send - ; esi == buffer start - ; -dd_000: - mov bl, 0x0a - call tx_byted - mov bl, 0x0d - call tx_byted - - mov eax, 16 ; Number of characters on the line - mov edi, esi ; Save first byte position for later - - push ecx - -dd_001: - push eax - - ; Print a byte, and a space - xor eax, eax - mov al, [esi] - shr al, 4 - mov bl, [eax + hexchars] - call tx_byted ; byte in bl eax ebx edx destroyed - - xor eax, eax - mov al, [esi] - and al, 0x0f - mov bl, [eax + hexchars] - call tx_byted ; byte in bl eax ebx edx destroyed - - mov bl, ' ' - call tx_byted - - pop eax - - inc esi - dec ecx - cmp ecx, 0 - je dd_0011 ; Print the ASCII format - - dec eax - - cmp eax, 0 - je dd_002 ; Print the ASCII format - jmp dd_001 ; Print rest of line - -dd_0011: - ; First, complete the 16 bytes of data, by printing spaces - dec eax - cmp eax, 0 - je dd_002 - - push eax - mov bl, ' ' - call tx_byted - mov bl, ' ' - call tx_byted - mov bl, ' ' - call tx_byted - pop eax - jmp dd_0011 - -dd_002: - pop ecx - mov esi, edi ; Go back to the start of the line data - - mov eax, 16 - -outLineAscii: - push eax - - xor eax, eax - mov al, [esi] - mov bl, '.' - - cmp al, 0x1F - jle outAscii - cmp al, 0x7e - jge outAscii - - mov bl, al - -outAscii: - call tx_byted ; byte in bl eax ebx edx destroyed - - pop eax - dec ecx - inc esi - cmp ecx, 0 - je dd_003 - - dec eax - cmp eax, 0 - je dd_003 - jmp outLineAscii - -dd_003: - cmp ecx, 0 - je dd_004 - jmp dd_000 - -dd_004: - ret - -;*************************************************************************** -; Function -; tx_byte -; -; Description -; Send a byte in bl out of the com port 1 -; destroys eax, edx -; -;*************************************************************************** -tx_byted: - push ebx ; Save the byte - - mov ebx, 0x3f8 ; get the com port address - - ; Wait for transmit buffer to empty. This could take 1ms @ 9600baud - - mov edx, ebx - add edx, 5 - -wait_txd: - in al, dx ; read uart serialisation status - and al, 0x40 - cmp al, 0 - jz wait_txd ; loop until free - - mov edx, ebx - pop eax ; restore the byte to send - out dx, al - ret - -iglobal - ; This is used for translating hex to ASCII for display or output - hexchars db '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' -endg -end if -