Subversion Repositories Kolibri OS

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;;  ETHERNET.INC                                                   ;;
  4. ;;                                                                 ;;
  5. ;;  Ethernet network layer for Menuet OS                           ;;
  6. ;;                                                                 ;;
  7. ;;  Version 0.4  22 September 2003                                 ;;
  8. ;;                                                                 ;;
  9. ;;  This file contains the following:                              ;;
  10. ;;      PCI bus scanning for valid devices                         ;;
  11. ;;      Table of supported ethernet drivers                        ;;
  12. ;;      Code to identify and activate a supported driver           ;;
  13. ;;      ARP handler                                                ;;
  14. ;;      Driver interface to the IP layer                           ;;
  15. ;;      Gateway support                                            ;;
  16. ;;                                                                 ;;
  17. ;;  Individual driver files are included here                      ;;
  18. ;;                                                                 ;;
  19. ;;  The PCI bus scanning code was ported from the etherboot        ;;
  20. ;;  5.0.6 project. The copyright statement for that code is        ;;
  21. ;;                                                                 ;;
  22. ;;          GNU GENERAL PUBLIC LICENSE                             ;;
  23. ;;             Version 2, June 1991                                ;;
  24. ;;                                                                 ;;
  25. ;;  remaining parts Copyright 2002 Mike Hibbett                    ;;
  26. ;;   mikeh@oceanfree.net                                           ;;
  27. ;;                                                                 ;;
  28. ;;  See file COPYING for details                                   ;;
  29. ;;                                                                 ;;
  30. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  31.  
  32. ;********************************************************************
  33. ;   Interface
  34. ;      ethernet_driver   called by stack_handler in stack.inc
  35. ;      eth_probe         called by app_stack_handler in stack.inc
  36. ;
  37. ;********************************************************************
  38.  
  39. ; Some useful information on data structures
  40.  
  41. ;     Ethernet Packet - ARP Request example
  42. ;
  43. ;   0                   1                   2                   3
  44. ;   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  45. ;
  46. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  47. ;   |       Dest   H/W Address                                      |
  48. ;   |                    ( 14 byte header )                         |
  49. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  50. ;   |                               |     Source     H/W Address    |
  51. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  52. ;   |                                                               |
  53. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  54. ;   |    Protocol - ARP 08  06      |
  55. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  56.  
  57. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  58. ;   |  H/W Type  00           01    |  Protocol Type   08 00        |
  59. ;   |                   ( ARP Request packet )                      |
  60. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  61. ;   | HLen    0x06  | PLen    0x04  |    OpCode        00   01      |
  62. ;   |               ( 0001 for request, 0002 for reply )            |
  63. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  64. ;   | Source Hardware Address ( MAC Address )                       |
  65. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  66. ;   |                               |  Source IP Address            |
  67. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  68. ;   |                               | Destination Hardware Address  |
  69. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  70. ;   |                                                               |
  71. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  72. ;   | Destination IP Address                                        |
  73. ;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  74.  
  75. ; Include individual drivers source files at this point.
  76. ; If you create a new driver, include it below.
  77.  
  78. include "rtl8029.inc"
  79. include "i8255x.inc"
  80. include "rtl8139.inc"
  81. include "3c59x.inc"
  82. include "sis900.inc"
  83. include "pcnet32.inc"
  84.  
  85. ; DEBUGGING_STATE enables or disables output of received and transmitted
  86. ; data over the serial port
  87. DEBUGGING_ENABLED           equ     1
  88. DEBUGGING_DISABLED         equ     0
  89. DEBUGGING_STATE             equ     DEBUGGING_DISABLED
  90.  
  91. ; PCICards
  92. ; ========
  93. ; PCI vendor and hardware types for hardware supported by the above drivers
  94. ; If you add a driver, ensure you update this datastructure, otherwise the
  95. ; card will not be probed.
  96. ; Each driver is defined by 4 double words. These are
  97. ;   PCIVendorDevice  probeFunction ResetFunction PollFunction transmitFunction
  98. ; The last entry must be kept at all zeros, to indicate the end of the list
  99. ; As a PCI driver may support more than one hardware implementation, there may
  100. ; be several lines which refer to the same functions.
  101. ; The first driver found on the PCI bus will be the one used.
  102.  
  103. PCICARDS_ENTRY_SIZE         equ     20    ; Size of each PCICARDS entry
  104.  
  105. iglobal
  106. PCICards:
  107. dd  0x12098086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
  108. dd  0x10298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
  109. dd  0x12298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
  110. dd  0x10308086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
  111. dd  0x24498086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
  112. dd  0x802910ec, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit
  113. dd  0x12111113, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit
  114. dd  0x813910ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  115. ; /+/ ═ют√х тхэфюЁ√ ёхЄхт√ї ърЁЄ эр срчх rtl8139
  116. dd  0x813810ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  117. dd  0x12111113, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  118. dd  0x13601500, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  119. dd  0x13604033, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  120. dd  0x13001186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  121. dd  0x13401186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  122. dd  0xab0613d1, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  123. dd  0xa1171259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  124. dd  0xa11e1259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  125. dd  0xab0614ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  126. dd  0xab0714ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  127. dd  0x123411db, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  128. dd  0x91301432, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  129. dd  0x101202ac, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  130. dd  0x0106018a, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  131. dd  0x1211126c, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  132. dd  0x81391743, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  133. dd  0x8139021b, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
  134. ; /-/
  135. dd  0x590010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  136. dd  0x592010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  137. dd  0x597010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  138. dd  0x595010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  139. dd  0x595110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  140. dd  0x595210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  141. dd  0x900010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  142. dd  0x900110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  143. dd  0x900410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  144. dd  0x900510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  145. dd  0x900610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  146. dd  0x900A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  147. dd  0x905010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  148. dd  0x905110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  149. dd  0x905510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  150. dd  0x905810b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  151. dd  0x905A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  152. dd  0x920010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  153. dd  0x980010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  154. dd  0x980510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  155. dd  0x764610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  156. dd  0x505510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  157. dd  0x605510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  158. dd  0x605610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  159. dd  0x5b5710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  160. dd  0x505710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  161. dd  0x515710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  162. dd  0x525710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  163. dd  0x656010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  164. dd  0x656210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  165. dd  0x656410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  166. dd  0x450010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
  167. dd  0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit
  168. dd  0x20001022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit
  169. dd  0x26251022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit
  170. dd  0x20011022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit
  171. ; following card is untested
  172. dd  0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit
  173. dd  0,0,0,0,0  ; end of list marker, do not remove
  174. endg
  175.  
  176. ; PCI Bus defines
  177. PCI_HEADER_TYPE             equ     0x0e  ;8 bit
  178. PCI_BASE_ADDRESS_0         equ     0x10  ;32 bit
  179. PCI_BASE_ADDRESS_5         equ     0x24  ;32 bits
  180. PCI_BASE_ADDRESS_SPACE_IO   equ     0x01
  181. PCI_VENDOR_ID               equ     0x00  ;16 bit
  182. PCI_BASE_ADDRESS_IO_MASK   equ     0xFFFFFFFC
  183.  
  184. ETHER_IP                   equ     0x0008      ; Reversed from 0800 for intel
  185. ETHER_ARP                   equ     0x0608      ; Reversed from 0806 for intel
  186. ETHER_RARP                 equ     0x3580
  187. ARP_REQ_OPCODE             equ     0x0100
  188. ARP_REP_OPCODE             equ     0x0200
  189.  
  190. uglobal
  191.   arp_rx_count:       dd  0
  192.   ip_rx_count:        dd  0
  193.   dumped_rx_count:    dd  0
  194.   ip_tx_count:        dd  0
  195.   node_addr:          db  0,0,0,0,0,0
  196.   eth_rx_data_len:    dw  0
  197.   eth_status:         dd  0
  198.   io_addr:            dd  0
  199.   hdrtype:            db  0
  200.   vendor_device:      dd  0
  201.   pci_data:           dd  0
  202.   pci_dev:            dd  0
  203.   pci_bus:            dd  0
  204.  
  205.   ; These will hold pointers to the selected driver functions
  206.   drvr_probe:         dd  0
  207.   drvr_reset:         dd  0
  208.   drvr_poll:          dd  0
  209.   drvr_transmit:      dd  0
  210.  
  211.   ; These hold the destination Host identity for ARP responses
  212.   remote_ip_add:      dd  0
  213.   remote_hw_add:      db  0, 0, 0, 0, 0, 0
  214. endg
  215.  
  216. iglobal
  217.   broadcast_add:      db  0xff,0xff,0xff,0xff,0xff,0xff
  218.   subnet_mask:        dd  0x00ffffff
  219. endg
  220.  
  221. uglobal
  222.   ; This is used by getMACfromIP
  223.   MACAddress:         db  0,0,0,0,0,0
  224.   gateway_ip:         db  0, 0, 0, 0
  225.   dns_ip:             dd  0
  226. endg
  227.  
  228. ; The follow is the ARP Table.
  229. ; This table must be manually updated and the kernel recompilied if
  230. ; changes are made to it.
  231. ; ARP_TABLE_SIZE defines the size of the table
  232. ; ARP_TABLE_ENTRIES defines the number of entries in the table
  233. ; Each entry is 10 bytes: 4 Byte IP address, 6 byte MAC Address,
  234. ;                         2 bytes status, 2 bytes TTL ( in seconds )
  235. ; Empty entries are filled with zeros
  236. ; The TTL field is decremented every second, and is deleted when it
  237. ; reaches 0. It is refreshed every time a packet is received
  238. ; If the TTL field is 0xFFFF it is a permanent entry and is never deleted
  239. ; The status field can be the following values
  240. ; 0x0000  entry not used
  241. ; 0x0001  entry holds a valid mapping
  242. ; 0x0002  entry contains an IP address, awaiting ARP response
  243. ; 0x0003  No response received to ARP request.
  244. ; The last status value is provided to allow the network layer to delete
  245. ; a packet that is queued awaiting an ARP response
  246.  
  247. ARP_NO_ENTRY               equ 0
  248. ARP_VALID_MAPPING           equ 1
  249. ARP_AWAITING_RESPONSE       equ 2
  250. ARP_RESPONSE_TIMEOUT       equ 3
  251.  
  252. ARP_ENTRY_SIZE             equ     14          ; Number of bytes per entry
  253. ARP_TABLE_SIZE             equ     20          ; Size of table
  254. ARP_TABLE_ENTRIES           equ     0           ; Inital, hardcoded entries
  255.  
  256. uglobal
  257.   ARPTable:
  258.   times ( ARP_TABLE_SIZE - ARP_TABLE_ENTRIES ) * ARP_ENTRY_SIZE  db 0
  259. endg
  260.  
  261. iglobal
  262.   NumARP:        db    ARP_TABLE_ENTRIES
  263. endg
  264.  
  265. ;***************************************************************************
  266. ;   Function
  267. ;      eth_probe
  268. ;   Description
  269. ;      Searches for an ethernet card. If found, the card is enabled and
  270. ;      the ethernet -> IP link established
  271. ;
  272. ;      This function scans the PCI bus looking for a supported device.
  273. ;      ISA bus is currently not supported.
  274. ;
  275. ;        eax is 0 if no hardware found
  276. ;***************************************************************************
  277. eth_probe:
  278.     ; Find a card on the PCI bus, and get it's address
  279.     call    scan_bus                    ; Find the ethernet cards PIC address
  280.     xor     eax, eax
  281.     cmp     [io_addr], eax
  282.     je      ep_00x                      ; Return 0 in eax if no cards found
  283.  
  284.     call    dword [drvr_probe]          ; Call the drivers probe function
  285.  
  286.     mov     eax, [io_addr]              ; return a non zero value
  287.  
  288. ep_00x:
  289.     ret
  290.  
  291. ;***************************************************************************
  292. ;   Function
  293. ;      ethernet_driver
  294. ;
  295. ;   Description
  296. ;       The ethernet RX and TX handler
  297. ;       This is a kernel function, called by stack_handler
  298. ;
  299. ;***************************************************************************
  300. ethernet_driver:
  301.     ; Do nothing if the driver is inactive
  302.     cmp     [ethernet_active], byte 0
  303.     je      eth_exit
  304.  
  305.     call    eth_rx
  306.     call    eth_tx
  307.  
  308. eth_exit:
  309.     ret
  310.  
  311. ;***************************************************************************
  312. ;   Function
  313. ;      eth_rx
  314. ;
  315. ;   Description
  316. ;      Polls the ethernet card for received data. Extracts if present
  317. ;       Depending on the Protocol within the packet:
  318. ;         ARP : Pass to ARP_handler. This may result in an ARP reply
  319. ;               being tx'ed
  320. ;         IP  : Store in an IP buffer
  321. ;
  322. ;***************************************************************************
  323. eth_rx:
  324.     xor     ax, ax
  325.     mov     [eth_rx_data_len], ax
  326.     call    dword [drvr_poll]       ; Call the drivers poll function
  327.  
  328.     mov     ax, [eth_rx_data_len]
  329.     cmp     ax, 0
  330.     je      erx_exit
  331.  
  332. if DEBUGGING_STATE = DEBUGGING_ENABLED
  333.     pusha
  334.     mov     eax, 0                    ;Indicate that this is a received packet
  335.     mov     cx, [eth_rx_data_len]
  336.     mov     esi, Ether_buffer
  337.     cmp     word [esi + 12], ETHER_IP
  338.     jnz     erxd_done
  339. ;    cmp     byte [esi + 14 + 9], 0x06  ; TCP
  340. ;    jnz     erxd_done
  341.     call    eth_dump
  342. erxd_done:
  343.     popa
  344. end if
  345.  
  346.     ; Check the protocol. Call appropriate handler
  347.     mov     eax, Ether_buffer
  348.     add     eax, 12                  ; The address of the protocol word
  349.  
  350.     mov     ax, [eax]
  351.  
  352.     cmp     ax, ETHER_ARP
  353.     je      erx_001                  ; It is ARP
  354.  
  355.     cmp     ax, ETHER_IP
  356.     je      erx_002                  ; It's IP
  357.  
  358. ;    inc     dword [dumped_rx_count]
  359.  
  360.     jmp     erx_exit               ; If not IP or ARP, ignore
  361.  
  362. erx_001:
  363.     mov     eax, [arp_rx_count]
  364.     inc     eax
  365.     mov     [arp_rx_count], eax
  366.  
  367.     ; At this point, the packet is still in the Ether_buffer
  368.     call    arp_handler
  369.  
  370.     jmp     erx_exit
  371.  
  372. erx_002:
  373.     mov     eax, [ip_rx_count]
  374.     inc     eax
  375.     mov     [ip_rx_count], eax
  376.  
  377.     ; Check to see if the MAC address is in our arp table
  378.     ; refresh the arp ttl if so
  379.  
  380.     mov     esi, Ether_buffer
  381.     add     esi, 6
  382.  
  383.     call    refreshARP
  384.  
  385.     call    ether_IP_handler
  386.  
  387.     jmp     erx_exit
  388.  
  389. erx_exit:
  390.     ret
  391.  
  392. ;***************************************************************************
  393. ;   Function
  394. ;      eth_tx
  395. ;
  396. ;   Description
  397. ;      Looks at the NET1OUT_QUEUE for data to send.
  398. ;      Stores that destination IP in a location used by the tx routine
  399. ;      Looks up the MAC address in the ARP table; stores that where
  400. ;      the tx routine can get it
  401. ;      Get the length of the data. Store that where the tx routine wants it
  402. ;      Call tx
  403. ;      Places buffer on empty queue when the tx routine finished
  404. ;
  405. ;***************************************************************************
  406. eth_tx:
  407.     ; Look for a buffer to tx
  408.     mov     eax, NET1OUT_QUEUE
  409.     call    dequeue
  410.     cmp     ax, NO_BUFFER
  411.     je      eth_exit            ; Exit if no buffer available
  412.  
  413.     push    eax
  414.  
  415.     ; convert buffer pointer eax to the absolute address
  416.     mov     ecx, IPBUFFSIZE
  417.     mul     ecx
  418.     add     eax, IPbuffs
  419.  
  420.     ; Extract the destination IP
  421.     ; find the destination IP in the ARP table, get MAC
  422.     ; store this MAC in 'MACAddress'
  423.     mov     ebx, eax               ; Save buffer address
  424.     mov     edx, [ebx + 16]        ; get destination address
  425.  
  426.     ; If the destination address is 255.255.255.255,
  427.     ; set the MACAddress to all ones ( broadcast )
  428.     mov     [MACAddress], dword 0xffffffff
  429.     mov     [MACAddress + 4], word 0xffff
  430.     cmp     edx, 0xffffffff
  431.     je      etx_send                ; If it is broadcast, just send
  432.  
  433.     call    getMACfromIP           ; Get the MAC address.
  434.  
  435.     cmp     eax, ARP_VALID_MAPPING
  436.     jz      etx_send
  437.  
  438.     ; No valid entry. Are we waiting for a response?
  439.     cmp     eax, ARP_AWAITING_RESPONSE
  440.     jne     etx_001
  441.  
  442.     ; Re-queue the packet, and exit
  443.     pop     ebx
  444.     mov     eax, NET1OUT_QUEUE
  445.     call    queue
  446.     jmp     etx_exit
  447.  
  448. etx_001:
  449.     ; HAs the request been sent, but timed out?
  450.     cmp     eax, ARP_RESPONSE_TIMEOUT
  451.     jne     etx_002
  452.  
  453.     pop     eax
  454.     call    freeBuff
  455.     jmp     etx_exit
  456.  
  457. etx_002:
  458.     ; There is no entry. Re queue the request, and ask ARP to send a request
  459.  
  460.     ; IP address is in edx
  461.     push    edx
  462.     call    arp_request
  463.     pop     ebx
  464.  
  465.     ; Add an entry in the ARP table, awaiting response
  466.  
  467.     cmp     byte [NumARP], ARP_TABLE_SIZE
  468.     je      etx_003            ; We cannot add a new entry in the table
  469.  
  470.     inc     byte [NumARP]
  471.  
  472.     movzx   eax, byte [NumARP]
  473.     mov     ecx, ARP_ENTRY_SIZE
  474.     mul     ecx
  475.     sub     eax, ARP_ENTRY_SIZE
  476.  
  477.     mov     [eax + ARPTable], ebx
  478.     xor     ebx, ebx
  479.     mov     [eax + ARPTable + 4], ebx
  480.     mov     [eax + ARPTable + 8], bx
  481.  
  482.     ; set the status field up - awaiting response
  483.     mov     cl, 0x00
  484.     mov     [eax + ARPTable + 10], cl
  485.     mov     cl, 0x02
  486.     mov     [eax + ARPTable + 11], cl
  487.  
  488.     ; Initialise the time to live field - 10s
  489.     mov     cx, 0x000A
  490.     mov     [eax + ARPTable + 12], cx
  491.  
  492. etx_003:
  493.     pop     ebx                        ; Get the buffer back
  494.     mov     eax, NET1OUT_QUEUE
  495.     call    queue
  496.     jmp     etx_exit
  497.  
  498. etx_send:
  499.     xor     ecx, ecx
  500.     mov     ch, [ebx+2]
  501.     mov     cl, [ebx+3]          ; ; Size of IP packet to send
  502.  
  503.     mov     esi, ebx
  504.  
  505.     mov     edi, MACAddress
  506.  
  507. if DEBUGGING_STATE = DEBUGGING_ENABLED
  508.     pusha
  509.     mov     cx, 42
  510.     mov     eax, 1                    ; Indicate that this is a tx packet
  511.     call    eth_dump
  512.     popa
  513. end if
  514.  
  515.     mov     bx, ETHER_IP
  516.     call    dword [drvr_transmit]       ; Call the drivers transmit function
  517.  
  518.     ; OK, we have sent a packet, so increment the count
  519.     inc     dword [ip_tx_count]
  520.  
  521.     ; And finally, return the buffer to the free queue
  522.     pop     eax
  523.     call    freeBuff
  524.  
  525. etx_exit:
  526.     ret
  527.  
  528. ;***************************************************************************
  529. ;   Function
  530. ;      ether_IP_handler
  531. ;
  532. ;   Description
  533. ;      Called when an IP ethernet packet is received on the ethernet
  534. ;      Header + Data is in Ether_buffer[]
  535. ;      We just need to get a buffer from the 'free' queue, and
  536. ;      store the packet in it, then insert the packet number into the
  537. ;      IPRX queue.
  538. ;      If no queue entry is available, the packet is silently discarded
  539. ;      All registers may be destroyed
  540. ;
  541. ;***************************************************************************
  542. ether_IP_handler:
  543.     mov     eax, EMPTY_QUEUE
  544.     call    dequeue
  545.     cmp     ax, NO_BUFFER
  546.     je      eiph00x
  547.  
  548.     ; convert buffer pointer eax to the absolute address
  549.     push    eax
  550.     mov     ecx, IPBUFFSIZE
  551.     mul     ecx
  552.     add     eax, IPbuffs
  553.  
  554.     mov     edi, eax
  555.  
  556.     ; get a pointer to the start of the DATA
  557.     mov     esi, Ether_buffer + 14
  558.  
  559.     ; Now store it all away
  560.     mov     ecx, IPBUFFSIZE / 4     ; Copy all of the available
  561.                               ; data across - worse case
  562.     cld
  563.     rep     movsd
  564.  
  565.     ; And finally, place the buffer in the IPRX queue
  566.     pop     ebx
  567.     mov     eax, IPIN_QUEUE
  568.     call    queue
  569.  
  570. eiph00x:
  571.     ret
  572.  
  573. ;***************************************************************************
  574. ;
  575. ;  ARP CODE FOLLOWS
  576. ;
  577. ;  The ARP code is used by ethernet drivers to translate an destination
  578. ;  IP address into an ethernet hardware address. Functions to broadcast
  579. ;  requests and handle response are (or will be) here.
  580. ;  The IP layer has no knowledge of ARP, as this is a network interface
  581. ;  issue
  582. ;
  583. ;***************************************************************************
  584.  
  585. ;***************************************************************************
  586. ;   Function
  587. ;      arp_timer
  588. ;
  589. ;   Description
  590. ;      Called every 1s
  591. ;      It is responsible for removing expired routes
  592. ;      All registers may be destroyed
  593. ;
  594. ;***************************************************************************
  595. arp_timer:
  596.     ; loop through all the ARP entries, decrementing each one
  597.     ; that doesn't have a TTL of 0xFFFF
  598.     movzx   eax, byte [NumARP]
  599.  
  600. arp_001:
  601.     cmp     eax, 0
  602.     je      arp_003
  603.  
  604.     push    eax
  605.     dec     eax
  606.     mov     ecx, ARP_ENTRY_SIZE
  607.     mul     ecx
  608.     cmp     word [ eax + ARPTable + 12], 0xFFFF
  609.     je      arp_002
  610.  
  611.     cmp     word [ eax + ARPTable + 12], 0
  612.     je      arp_002
  613.  
  614.     dec     word [eax + ARPTable + 12]
  615.  
  616. arp_002:
  617.     pop     eax
  618.     dec     eax
  619.     jmp     arp_001
  620.  
  621.     ; Now, look for entries with a TTL of 0
  622.     ; Valid entries and response timeout entries get removed
  623.     ; awaiting response gets converted into a response timeout, with a
  624.     ; short life time - this allows queued packets to be flushed
  625. arp_003:
  626.     movzx   edx, byte [NumARP]
  627.     cmp     edx, 0
  628.     je      arp_exit
  629.  
  630.     ; EDX holds the # of entries to search through
  631.     mov     eax, 0
  632.  
  633. arp_005:
  634.     cmp     word [ eax + ARPTable + 12], 0
  635.     jne     arp_004
  636.  
  637.     ; If it's status code is 0001 or 0003, delete the entry
  638.     cmp     word [eax + ARPTable + 10], 0x0100
  639.     je      arp_007
  640.     cmp     word [eax + ARPTable + 10], 0x0300
  641.     je      arp_007
  642.  
  643.     ; The only other valid code is 0002 - indicating a
  644.     ; timeout while waiting for a response. Change the
  645.     ; entry to response timed out
  646.  
  647.     mov     [eax + ARPTable + 10], word 0x0300
  648.     mov     [eax + ARPTable + 12], word 0x000A
  649.     jmp     arp_004
  650.  
  651. arp_007:
  652.     ; Delete this entry
  653.     mov     edi, ARPTable
  654.     add     edi, eax
  655.     mov     esi, edi
  656.     add     esi, ARP_ENTRY_SIZE
  657.  
  658.     mov     ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE
  659.     sub     ecx, eax
  660.  
  661.     rep     movsb
  662.  
  663.     dec     byte [NumARP]
  664.     jmp     arp_006
  665.  
  666. arp_004:
  667.     add     eax, ARP_ENTRY_SIZE
  668. arp_006:
  669.     dec     edx
  670.     cmp     edx, 0
  671.     jne     arp_005
  672.  
  673. arp_exit:
  674.     ret
  675.  
  676. ;***************************************************************************
  677. ;   Function
  678. ;      arp_request
  679. ;
  680. ;   Description
  681. ;      Sends an ARP request on the ethernet
  682. ;        The requested IP address is in edx
  683. ;      All registers may be destroyed
  684. ;
  685. ;***************************************************************************
  686. arp_request:
  687.     mov     ebx, Ether_buffer
  688.     mov     ax, 0x0100
  689.     mov     [ebx], ax
  690.     add     ebx, 2
  691.  
  692.     mov     ax, 0x0008
  693.     mov     [ebx], ax
  694.     add     ebx, 2
  695.  
  696.     mov     ax, 0x0406
  697.     mov     [ebx], ax
  698.     add     ebx, 2
  699.  
  700.     mov     ax, 0x0100
  701.     mov     [ebx], ax
  702.     add     ebx, 2
  703.  
  704.     mov     ecx, node_addr
  705.     mov     eax, [ecx]
  706.     mov     [ebx], eax
  707.     add     ecx, 4
  708.     add     ebx, 4
  709.     mov     ax, [ecx]
  710.     mov     [ebx], ax
  711.     add     ebx, 2
  712.     mov     eax, [stack_ip]
  713.     mov     [ebx], eax
  714.     add     ebx, 4
  715.  
  716.     xor     eax, eax
  717.     mov     [ebx], eax
  718.     add     ebx, 4
  719.     mov     [ebx], ax
  720.  
  721.     add     ebx, 2
  722.     mov     [ebx], edx
  723.  
  724.     ; Now, send it!
  725.  
  726.     ; Pointer to 48 bit destination address in edi
  727.     ; Type of packet in bx
  728.     ; size of packet in ecx
  729.     ; pointer to packet data in esi
  730.     mov      edi, broadcast_add
  731.  
  732. ;if DEBUGGING_STATE = DEBUGGING_ENABLED
  733. ;    pusha
  734. ;    mov     eax, 1                    ; Indicate that this is a tx packet
  735. ;    mov     ecx, 28
  736. ;   mov      esi, Ether_buffer
  737. ;    call    eth_dump
  738. ;    popa
  739. ;end if
  740.  
  741.     mov     bx, ETHER_ARP
  742.     mov     ecx, 28
  743.     mov     esi, Ether_buffer
  744.     call    dword [drvr_transmit]       ; Call the drivers transmit function
  745.     ret
  746.  
  747. ;***************************************************************************
  748. ;   Function
  749. ;      arp_handler
  750. ;
  751. ;   Description
  752. ;      Called when an ARP packet is received on the ethernet
  753. ;      Header + Data is in Ether_buffer[]
  754. ;       It looks to see if the packet is a request to resolve this Hosts
  755. ;       IP address. If it is, send the ARP reply packet.
  756. ;      This Hosts IP address is in dword [stack_ip]  ( in network format )
  757. ;       This Hosts MAC address is in node_addr[6]
  758. ;      All registers may be destroyed
  759. ;
  760. ;***************************************************************************
  761. arp_handler:
  762.     ; Is this a REQUEST?
  763.     ; Is this a request for My Host IP
  764.     ; Yes - So construct a response message.
  765.     ; Send this message to the ethernet card for transmission
  766.  
  767.     mov     ebx, Ether_buffer
  768.  
  769.     mov     edx, ebx
  770.     add     edx, 20
  771.     mov     ax, [edx]
  772.     cmp     ax, ARP_REQ_OPCODE      ; Is this a request packet?
  773.     jne     arph_resp            ; No - so test for response
  774.  
  775.     mov     edx, ebx
  776.     add     edx, 38
  777.     mov     eax, [edx]
  778.  
  779.     cmp     eax, [stack_ip]         ; Is it looking for my IP address?
  780.     jne     arph_exit            ; No - so quit now
  781.  
  782.     ; OK, it is a request for my MAC address. Build the frame and send it
  783.  
  784.     ; Save the important data from the original packet
  785.     ; remote MAC address first
  786.     mov     ecx, remote_hw_add
  787.     mov     edx, ebx
  788.     add     edx, 22               ; edx points to Source h/w address
  789.     mov     eax, [edx]
  790.     mov     [ecx], eax
  791.     add     edx, 4
  792.     add     ecx, 4
  793.     mov     ax, [edx]
  794.     mov     [ecx],ax
  795.  
  796.     ; and also the remote IP address
  797.     add     edx, 2
  798.     mov     eax,[edx]
  799.     mov     [remote_ip_add], eax
  800.  
  801.     ; So now we can reuse the packet. ebx still holds the address of
  802.     ; the header + packet
  803.     ; We dont need the header ( first 14 bytes )
  804.  
  805.     mov     edx, ebx
  806.     add     edx, 20
  807.     mov     ax, ARP_REP_OPCODE
  808.     mov     [edx], ax
  809.     add     edx, 2
  810.  
  811.     mov     ecx, node_addr
  812.     mov     eax, [ecx]
  813.     mov     [edx], eax
  814.     add     ecx, 4
  815.     add     edx, 4
  816.     mov     ax, [ecx]
  817.     mov     [edx], ax
  818.     add     edx, 2
  819.     mov     eax, [stack_ip]
  820.     mov     [edx], eax
  821.     add     edx, 4
  822.     mov     ecx, remote_hw_add
  823.     mov     eax, [ecx]
  824.     mov     [edx], eax
  825.     add     ecx, 4
  826.     add     edx, 4
  827.     mov     ax, [ecx]
  828.     mov     [edx], ax
  829.  
  830.     add     edx, 2
  831.     mov     eax, [remote_ip_add]
  832.     mov     [edx], eax
  833.  
  834.     ; Now, send it!
  835.  
  836.     ; Pointer to 48 bit destination address in edi
  837.     ; Type of packet in bx
  838.     ; size of packet in ecx
  839.     ; pointer to packet data in esi
  840.     mov     edi, remote_hw_add
  841.  
  842. ;if DEBUGGING_STATE = DEBUGGING_ENABLED
  843. ;    pusha
  844. ;    mov     eax, 1                    ; Indicate that this is a tx packet
  845. ;    mov     ecx, 28
  846. ;   mov      esi, Ether_buffer + 14
  847.  ;   call    eth_dump
  848. ;    popa
  849. ;end if
  850.  
  851.     mov     bx, ETHER_ARP
  852.     mov     ecx, 28
  853.     mov     esi, Ether_buffer + 14
  854.     call    dword [drvr_transmit]       ; Call the drivers transmit function
  855.     jmp     arph_exit
  856.  
  857. arph_resp:
  858.     cmp     ax, ARP_REP_OPCODE      ; Is this a replypacket?
  859.     jne     arph_resp            ; No - so quit
  860.  
  861.     ; This was a reply, probably directed at me.
  862.     ; save the remotes MAC & IP
  863.     mov     ecx, remote_hw_add
  864.     mov     edx, ebx
  865.     add     edx, 22               ; edx points to Source h/w address
  866.     mov     eax, [edx]
  867.     mov     [ecx], eax
  868.     add     edx, 4
  869.     add     ecx, 4
  870.     mov     ax, [edx]
  871.     mov     [ecx],ax
  872.  
  873.     ; and also the remote IP address
  874.     add     edx, 2
  875.     mov     eax,[edx]
  876.     mov     [remote_ip_add], eax
  877.  
  878.     ; Now, add an entry in the table for this IP address if it doesn't exist
  879.  
  880.     push    eax
  881.     movzx   eax, byte [NumARP]
  882.     mov     ecx, ARP_ENTRY_SIZE
  883.     mul     ecx
  884.     pop     edx
  885.     movzx   ecx, byte [NumARP]
  886.     cmp     ecx, 0
  887.     je      arph_002
  888.  
  889. arph_001:
  890.     sub     eax, ARP_ENTRY_SIZE
  891.     cmp     [eax + ARPTable], edx
  892.     loopnz  arph_001                      ; Return back if non match
  893.  
  894.     jnz     arph_002                   ; None found, add to end
  895.  
  896.     mov     ecx, [remote_hw_add]
  897.     mov     [eax + ARPTable + 4], ecx
  898.     mov     cx, [remote_hw_add+4]
  899.     mov     [eax + ARPTable + 8], cx
  900.  
  901.     ; specify the type - a valid entry
  902.     mov     cl, 0x00
  903.     mov     [eax + ARPTable + 10], cl
  904.     mov     cl, 0x01
  905.     mov     [eax + ARPTable + 11], cl
  906.  
  907.     ; Initialise the time to live field - 1 hour
  908.     mov     cx, 0x0E10
  909.     mov     [eax + ARPTable + 12], cx
  910.     jmp     arph_exit
  911.  
  912. arph_002:
  913.  
  914.     cmp     byte [NumARP], ARP_TABLE_SIZE
  915.     je      arph_exit
  916.  
  917.     inc     byte [NumARP]
  918.  
  919.     movzx   eax, byte [NumARP]
  920.     mov     ecx, ARP_ENTRY_SIZE
  921.     mul     ecx
  922.     sub     eax, ARP_ENTRY_SIZE
  923.  
  924.     mov     ecx, [remote_ip_add]
  925.     mov     [eax + ARPTable], ecx
  926.     mov     ecx, [remote_hw_add]
  927.     mov     [eax + ARPTable + 4], ecx
  928.     mov     cx, [remote_hw_add+4]
  929.     mov     [eax + ARPTable + 8], cx
  930.  
  931.     mov     cl, 0x00
  932.     mov     [eax + ARPTable + 10], cl
  933.     mov     cl, 0x01
  934.     mov     [eax + ARPTable + 11], cl
  935.  
  936.     ; Initialise the time to live field - 1 hour
  937.     mov     cx, 0x0E10
  938.     mov     [eax + ARPTable + 12], cx
  939.  
  940. arph_exit:
  941.     ret
  942.  
  943. ; pointer to MAC in esi
  944. refreshARP:
  945.     mov     ebx, [esi]
  946.     mov     dx, [esi+4]
  947.     push    edx
  948.     movzx   eax, byte [NumARP]
  949.     mov     ecx, ARP_ENTRY_SIZE
  950.     mul     ecx
  951.     pop     edx
  952.     movzx   ecx, byte [NumARP]
  953.     cmp     ecx, 0
  954.     je      rf_exit
  955.  
  956. rf_001:
  957.     sub     eax, ARP_ENTRY_SIZE
  958.     cmp     [eax + ARPTable+4], ebx
  959.  
  960.     je      rf_002
  961.     loop    rf_001
  962.     jmp     rf_exit
  963.  
  964. rf_002:
  965.     cmp     [eax + ARPTable+8], dx
  966.     je      rf_gotone
  967.     loop    rf_001
  968.     jmp     rf_exit
  969.  
  970. rf_gotone:
  971.     ; Initialise the time to live field - 1 hour
  972.     mov     cx, 0x0E10
  973.     mov     [eax + ARPTable + 12], cx
  974.  
  975. rf_exit:
  976.     ret
  977.  
  978. ;***************************************************************************
  979. ;   Function
  980. ;      getMACfromIP
  981. ;
  982. ;   Description
  983. ;       Takes an IP address in edx and scans the ARP table for
  984. ;        a matching entry
  985. ;       If a match is found, it's MAC address is stored in MACAddress.
  986. ;      Otherwise the value 0 is writen to MACAddress
  987. ;      eax holds ARP table entry status code ( ARP_ )
  988. ;      ebx unchanged
  989. ;
  990. ;***************************************************************************
  991. getMACfromIP:
  992.     ; first, check destination IP to see if it is on 'this' network.
  993.     ; The test is:
  994.     ; if ( destIP & subnet_mask == stack_ip & subnet_mask )
  995.     ;   desitnation is local
  996.     ; else
  997.     ;  destination is remote, so pass to gateway
  998.  
  999.     mov     eax, edx
  1000.     and     eax, [subnet_mask]
  1001.     mov     ecx, [stack_ip]
  1002.     and     ecx, [subnet_mask]
  1003.     cmp     eax, ecx
  1004.     je      gm0
  1005.  
  1006.     mov     edx, [gateway_ip]
  1007. gm0:
  1008.     push    edx
  1009.     xor     eax, eax
  1010.     mov     [MACAddress], eax
  1011.     mov     [MACAddress + 4], ax
  1012.  
  1013.     movzx   eax, byte [NumARP]
  1014.     mov     ecx, ARP_ENTRY_SIZE
  1015.     mul     ecx
  1016.  
  1017.     pop     edx
  1018.  
  1019.     movzx   ecx, byte [NumARP]
  1020.     cmp     ecx, 0
  1021.     je      gm_none
  1022. gm1:
  1023.     sub     eax, ARP_ENTRY_SIZE
  1024.     cmp     [eax + ARPTable], edx
  1025.     loopnz  gm1                      ; Return back if non match
  1026.     jnz     gm_none                   ; Quit if none found
  1027.  
  1028.     ; eax holds index
  1029.     mov     ecx, [eax + ARPTable + 4]
  1030.     mov     [MACAddress], ecx
  1031.     mov     cx, [eax + ARPTable + 8]
  1032.     mov     [MACAddress+4], cx
  1033.  
  1034.     ; Return the entry status in eax
  1035.     mov     ch, [eax + ARPTable + 10]
  1036.     mov     cl, [eax + ARPTable + 11]
  1037.     movzx   eax, cx
  1038.     jmp     gm_exit
  1039.  
  1040. gm_none:
  1041.     mov     eax, ARP_NO_ENTRY
  1042.  
  1043. gm_exit:
  1044.     ret
  1045.  
  1046. ;***************************************************************************
  1047. ;
  1048. ;  PCI CODE FOLLOWS
  1049. ;
  1050. ;  the following functions provide access to the PCI interface.
  1051. ;  These functions are used by scan_bus, and also some ethernet drivers
  1052. ;
  1053. ;***************************************************************************
  1054.  
  1055. ;***************************************************************************
  1056. ;   Function
  1057. ;      config_cmd
  1058. ;
  1059. ;   Description
  1060. ;       creates a command dword  for use with the PCI bus
  1061. ;       bus # in ebx
  1062. ;      devfn in ecx
  1063. ;       where in edx
  1064. ;
  1065. ;      command dword returned in eax
  1066. ;       Only eax destroyed
  1067. ;***************************************************************************
  1068. config_cmd:
  1069.     push    ecx
  1070.     mov     eax, ebx
  1071.     shl     eax, 16
  1072.     or      eax, 0x80000000
  1073.     shl     ecx, 8
  1074.     or      eax, ecx
  1075.     pop     ecx
  1076.     or      eax, edx
  1077.     and     eax, 0xFFFFFFFC
  1078.     ret
  1079.  
  1080. ;***************************************************************************
  1081. ;   Function
  1082. ;      pcibios_read_config_byte
  1083. ;
  1084. ;   Description
  1085. ;       reads a byte from the PCI config space
  1086. ;       bus # in ebx
  1087. ;      devfn in ecx
  1088. ;       where in edx ( ls 16 bits significant )
  1089. ;
  1090. ;      byte returned in al ( rest of eax zero )
  1091. ;       Only eax/edx destroyed
  1092. ;***************************************************************************
  1093. pcibios_read_config_byte:
  1094.     call    config_cmd
  1095.     push    dx
  1096.     mov     dx, 0xCF8
  1097.     out     dx, eax
  1098.     pop     dx
  1099.  
  1100.     xor     eax, eax
  1101.     and     dx, 0x03
  1102.     add     dx, 0xCFC
  1103. ;   and     dx, 0xFFC
  1104.     in      al, dx
  1105.     ret
  1106.  
  1107. ;***************************************************************************
  1108. ;   Function
  1109. ;      pcibios_read_config_word
  1110. ;
  1111. ;   Description
  1112. ;       reads a word from the PCI config space
  1113. ;       bus # in ebx
  1114. ;      devfn in ecx
  1115. ;       where in edx ( ls 16 bits significant )
  1116. ;
  1117. ;      word returned in ax ( rest of eax zero )
  1118. ;       Only eax/edx destroyed
  1119. ;***************************************************************************
  1120. pcibios_read_config_word:
  1121.     call    config_cmd
  1122.     push    dx
  1123.     mov     dx, 0xCF8
  1124.     out     dx, eax
  1125.     pop     dx
  1126.  
  1127.     xor     eax, eax
  1128.     and     dx, 0x02
  1129.     add     dx, 0xCFC
  1130. ;   and     dx, 0xFFC
  1131.     in      ax, dx
  1132.     ret
  1133.  
  1134. ;***************************************************************************
  1135. ;   Function
  1136. ;      pcibios_read_config_dword
  1137. ;
  1138. ;   Description
  1139. ;       reads a dword from the PCI config space
  1140. ;       bus # in ebx
  1141. ;      devfn in ecx
  1142. ;       where in edx ( ls 16 bits significant )
  1143. ;
  1144. ;      dword returned in eax
  1145. ;       Only eax/edx destroyed
  1146. ;***************************************************************************
  1147. pcibios_read_config_dword:
  1148.     push    edx
  1149.     call    config_cmd
  1150.     push    dx
  1151.     mov     dx, 0xCF8
  1152.     out     dx, eax
  1153.     pop     dx
  1154.     xor     eax, eax
  1155.     mov     dx, 0xCFC
  1156.     in      eax, dx
  1157.     pop     edx
  1158.     ret
  1159.  
  1160. ;***************************************************************************
  1161. ;   Function
  1162. ;      pcibios_write_config_byte
  1163. ;
  1164. ;   Description
  1165. ;       write a byte in al to the PCI config space
  1166. ;       bus # in ebx
  1167. ;      devfn in ecx
  1168. ;       where in edx ( ls 16 bits significant )
  1169. ;
  1170. ;       Only eax/edx destroyed
  1171. ;***************************************************************************
  1172. pcibios_write_config_byte:
  1173.     push    ax
  1174.     call    config_cmd
  1175.     push    dx
  1176.     mov     dx, 0xCF8
  1177.     out     dx, eax
  1178.     pop     dx
  1179.     pop     ax
  1180.  
  1181.     and     dx, 0x03
  1182.     add     dx, 0xCFC
  1183.     out     dx, al
  1184.     ret
  1185.  
  1186. ;***************************************************************************
  1187. ;   Function
  1188. ;      pcibios_write_config_word
  1189. ;
  1190. ;   Description
  1191. ;       write a word in ax to the PCI config space
  1192. ;       bus # in ebx
  1193. ;      devfn in ecx
  1194. ;       where in edx ( ls 16 bits significant )
  1195. ;
  1196. ;       Only eax/edx destroyed
  1197. ;***************************************************************************
  1198. pcibios_write_config_word:
  1199.     push    ax
  1200.     call    config_cmd
  1201.     push    dx
  1202.     mov     dx, 0xCF8
  1203.     out     dx, eax
  1204.     pop     dx
  1205.     pop     ax
  1206.  
  1207.     and     dx, 0x02
  1208.     add     dx, 0xCFC
  1209.     out     dx, ax
  1210.     ret
  1211.  
  1212. ;***************************************************************************
  1213. ;   Function
  1214. ;      delay_us
  1215. ;
  1216. ;   Description
  1217. ;       delays for 30 to 60 us
  1218. ;
  1219. ;        I would prefer this routine to be able to delay for
  1220. ;       a selectable number of microseconds, but this works for now.
  1221. ;
  1222. ;       If you know a better way to do 2us delay, pleae tell me!
  1223. ;***************************************************************************
  1224. delay_us:
  1225.     push    eax
  1226.     push    ecx
  1227.  
  1228.     mov     ecx,2
  1229.  
  1230.     in      al,0x61
  1231.     and     al,0x10
  1232.     mov     ah,al
  1233.     cld
  1234.  
  1235. dcnt1:
  1236.     in      al,0x61
  1237.     and     al,0x10
  1238.     cmp     al,ah
  1239.     jz      dcnt1
  1240.  
  1241.     mov     ah,al
  1242.     loop    dcnt1
  1243.  
  1244.     pop     ecx
  1245.     pop     eax
  1246.  
  1247.     ret
  1248.  
  1249. ;***************************************************************************
  1250. ;   Function
  1251. ;      scan_bus
  1252. ;
  1253. ;   Description
  1254. ;       Scans the PCI bus for a supported device
  1255. ;        If a supported device is found, the drvr_ variables are initialised
  1256. ;       to that drivers functions ( as defined in the PCICards table)
  1257. ;
  1258. ;        io_addr   holds card I/O space. 32 bit, but only LS 16 bits valid
  1259. ;        pci_data  holds the PCI vendor + device code
  1260. ;       pci_dev   holds PCI bus dev #
  1261. ;       pci_bus   holds PCI bus #
  1262. ;
  1263. ;        io_addr will be zero if no card found
  1264. ;
  1265. ;***************************************************************************
  1266. scan_bus:
  1267.     xor     eax, eax
  1268.     mov     [hdrtype], al
  1269.     mov     [pci_data], eax
  1270.  
  1271.     xor     ebx, ebx         ; ebx = bus# 0 .. 255
  1272.  
  1273. sb_bus_loop:
  1274.     xor     ecx, ecx         ; ecx = devfn# 0 .. 254  ( not 255? )
  1275.  
  1276. sb_devf_loop:
  1277.     mov     eax, ecx
  1278.     and     eax, 0x07
  1279.  
  1280.     cmp     eax, 0
  1281.     jne     sb_001
  1282.  
  1283.     mov     edx, PCI_HEADER_TYPE
  1284.     call    pcibios_read_config_byte
  1285.     mov     [hdrtype], al
  1286.     jmp     sb_002
  1287.  
  1288. sb_001:
  1289.     mov     al, [hdrtype]
  1290.     and     al, 0x80
  1291.     cmp     al, 0x80
  1292.     jne     sb_inc_devf
  1293.  
  1294. sb_002:
  1295.     mov     edx, PCI_VENDOR_ID
  1296.     call    pcibios_read_config_dword
  1297.     mov     [vendor_device], eax
  1298.     cmp     eax, 0xffffffff
  1299.     je      sb_empty
  1300.     cmp     eax, 0
  1301.     jne     sb_check_vendor
  1302.  
  1303. sb_empty:
  1304.     mov     [hdrtype], byte 0
  1305.     jmp     sb_inc_devf
  1306.  
  1307. sb_check_vendor:
  1308.     ; iterate though PCICards until end or match found
  1309.     mov     esi, PCICards
  1310.  
  1311. sb_check:
  1312.     cmp     [esi], dword 0
  1313.     je      sb_inc_devf                ; Quit if at last entry
  1314.     cmp     eax, [esi]
  1315.     je      sb_got_card
  1316.     add     esi, PCICARDS_ENTRY_SIZE
  1317.     jmp     sb_check
  1318.  
  1319. sb_got_card:
  1320.     ; indicate that we have found the card
  1321.     mov     [pci_data], eax
  1322.     mov     [pci_dev], ecx
  1323.     mov     [pci_bus], ebx
  1324.  
  1325.     ; Define the driver functions
  1326.     push    eax
  1327.     mov     eax, [esi+4]
  1328.     mov     [drvr_probe], eax
  1329.     mov     eax, [esi+8]
  1330.     mov     [drvr_reset], eax
  1331.     mov     eax, [esi+12]
  1332.     mov     [drvr_poll], eax
  1333.     mov     eax, [esi+16]
  1334.     mov     [drvr_transmit], eax
  1335.     pop     eax
  1336.  
  1337.     mov     edx, PCI_BASE_ADDRESS_0
  1338.  
  1339. sb_reg_check:
  1340.     call    pcibios_read_config_dword
  1341.     mov     [io_addr], eax
  1342.     and     eax, PCI_BASE_ADDRESS_IO_MASK
  1343.     cmp     eax, 0
  1344.     je      sb_inc_reg
  1345.     mov     eax, [io_addr]
  1346.     and     eax, PCI_BASE_ADDRESS_SPACE_IO
  1347.     cmp     eax, 0
  1348.     je      sb_inc_reg
  1349.  
  1350.     mov     eax, [io_addr]
  1351.     and     eax, PCI_BASE_ADDRESS_IO_MASK
  1352.     mov     [io_addr], eax
  1353.  
  1354. sb_exit1:
  1355.     ret
  1356.  
  1357. sb_inc_reg:
  1358.     add     edx, 4
  1359.     cmp     edx, PCI_BASE_ADDRESS_5
  1360.     jbe     sb_reg_check
  1361.  
  1362. sb_inc_devf:
  1363.     inc     ecx
  1364.     cmp     ecx, 255
  1365.     jb      sb_devf_loop
  1366.     inc     ebx
  1367.     cmp     ebx, 256
  1368.     jb      sb_bus_loop
  1369.  
  1370.     ; We get here if we didn't find our card
  1371.     ; set io_addr to 0 as an indication
  1372.     xor     eax, eax
  1373.     mov     [io_addr], eax
  1374.  
  1375. sb_exit2:
  1376.     ret
  1377.  
  1378. ;***************************************************************************
  1379. ;
  1380. ;  DEBUGGING CODE FOLLOWS
  1381. ;
  1382. ;  If debugging data output is not required, ALL code & data below may
  1383. ;  be removed.
  1384. ;
  1385. ;***************************************************************************
  1386.  
  1387. if DEBUGGING_STATE = DEBUGGING_ENABLED
  1388.  
  1389. ;***************************************************************************
  1390. ;   Function
  1391. ;      eth_dump
  1392. ;
  1393. ;   Description
  1394. ;       Dumps a tx or rx ethernet packet over the rs232 link
  1395. ;       This is a debugging routine that seriously slows down the stack.
  1396. ;       Use with caution.
  1397. ;
  1398. ;       Baud rate is 57600, 8n1  com1
  1399. ;         eax : type (0 == rx, 1 == tx )
  1400. ;          cx : # of bytes in buffer
  1401. ;         esi : address of buffer start
  1402. ;         edi : pointer to MACAddress ( tx only )
  1403. ;
  1404. ;***************************************************************************
  1405. eth_dump:
  1406.     pusha
  1407.  
  1408.     ; Set the port to the desired speed
  1409.     mov     ebx, 0x3f8                     ; combase
  1410.  
  1411.     mov     edx, ebx
  1412.     add     edx, 3                        ; data format register
  1413.     mov     al, 0x80                    ; enable access to divisor latch
  1414.     out     dx, al
  1415.  
  1416.     mov     edx, ebx
  1417.     add     edx, 1                        ; interrupt enable register
  1418.     mov     al, 0x00                    ; No interruts enabled
  1419.     out     dx, al
  1420.  
  1421.     mov     edx, ebx
  1422.     mov     al, 0x20 / 16                ; set baud rate to 57600 0x10 =115200
  1423.     out     dx, al
  1424.  
  1425.     mov     edx, ebx
  1426.     add     edx, 3                        ; data format register
  1427.     mov     al, 0x03                    ; 8 data bits
  1428.     out     dx, al
  1429.  
  1430.     mov     edx, ebx
  1431.     add     edx, 4                        ; Modem control register
  1432.     mov     al, 0x08                    ; out2 enabled. No handshaking.
  1433.     out     dx, al
  1434.  
  1435.     mov     edx, ebx
  1436.     add     edx, 1                        ; interrupt enable register
  1437.     mov     al, 0x01                    ; Receive data interrupt enabled,
  1438.     out     dx, al
  1439.  
  1440.     popa
  1441.  
  1442.     ; First, display the type of the buffer.
  1443.     ; If it is a tx buffer, display the macaddress
  1444.  
  1445.     pusha
  1446.  
  1447.     cmp     eax, 0
  1448.     jne     dd001
  1449.  
  1450.     mov     bl, 0x0a
  1451.     call    tx_byted
  1452.     mov     bl, 0x0d
  1453.     call    tx_byted
  1454.  
  1455.     ; Output "RX:"
  1456.     mov     bl, 'R'
  1457.     call    tx_byted
  1458.     mov     bl, 'X'
  1459.     call    tx_byted
  1460.     mov     bl, ':'
  1461.     call    tx_byted
  1462.     jmp     dump_data
  1463.  
  1464. dd001:
  1465.     mov     bl, 0x0a
  1466.     call    tx_byted
  1467.     mov     bl, 0x0d
  1468.     call    tx_byted
  1469.  
  1470.     ; Output TX: xxxxxxxxxxxx
  1471.     mov     bl, 'T'
  1472.     call    tx_byted
  1473.     mov     bl, 'X'
  1474.     call    tx_byted
  1475.     mov     bl, ':'
  1476.     call    tx_byted
  1477.     mov     bl, ' '
  1478.     call    tx_byted
  1479.  
  1480.     ; Display MAC address
  1481.     xor     eax, eax
  1482.     mov     al, [edi]
  1483.     shr     al, 4
  1484.     mov     bl, [eax + hexchars]
  1485.     call    tx_byted ; byte in bl eax ebx edx destroyed
  1486.  
  1487.     xor     eax, eax
  1488.     mov     al, [edi]
  1489.     and     al, 0x0f
  1490.     mov     bl, [eax + hexchars]
  1491.     call    tx_byted ; byte in bl eax ebx edx destroyed
  1492.  
  1493.     inc     edi
  1494.     xor     eax, eax
  1495.     mov     al, [edi]
  1496.     shr     al, 4
  1497.     mov     bl, [eax + hexchars]
  1498.     call    tx_byted ; byte in bl eax ebx edx destroyed
  1499.  
  1500.     xor     eax, eax
  1501.     mov     al, [edi]
  1502.     and     al, 0x0f
  1503.     mov     bl, [eax + hexchars]
  1504.     call    tx_byted ; byte in bl eax ebx edx destroyed
  1505.  
  1506.     inc     edi
  1507.     xor     eax, eax
  1508.     mov     al, [edi]
  1509.     shr     al, 4
  1510.     mov     bl, [eax + hexchars]
  1511.     call    tx_byted ; byte in bl eax ebx edx destroyed
  1512.  
  1513.     xor     eax, eax
  1514.     mov     al, [edi]
  1515.     and     al, 0x0f
  1516.     mov     bl, [eax + hexchars]
  1517.     call    tx_byted ; byte in bl eax ebx edx destroyed
  1518.  
  1519.     inc     edi
  1520.     xor     eax, eax
  1521.     mov     al, [edi]
  1522.     shr     al, 4
  1523.     mov     bl, [eax + hexchars]
  1524.     call    tx_byted ; byte in bl eax ebx edx destroyed
  1525.  
  1526.     xor     eax, eax
  1527.     mov     al, [edi]
  1528.     and     al, 0x0f
  1529.     mov     bl, [eax + hexchars]
  1530.     call    tx_byted ; byte in bl eax ebx edx destroyed
  1531.  
  1532.     inc     edi
  1533.     xor     eax, eax
  1534.     mov     al, [edi]
  1535.     shr     al, 4
  1536.     mov     bl, [eax + hexchars]
  1537.     call    tx_byted ; byte in bl eax ebx edx destroyed
  1538.  
  1539.     xor     eax, eax
  1540.     mov     al, [edi]
  1541.     and     al, 0x0f
  1542.     mov     bl, [eax + hexchars]
  1543.     call    tx_byted ; byte in bl eax ebx edx destroyed
  1544.  
  1545.     inc     edi
  1546.     xor     eax, eax
  1547.     mov     al, [edi]
  1548.     shr     al, 4
  1549.     mov     bl, [eax + hexchars]
  1550.     call    tx_byted ; byte in bl eax ebx edx destroyed
  1551.  
  1552.     xor     eax, eax
  1553.     mov     al, [edi]
  1554.     and     al, 0x0f
  1555.     mov     bl, [eax + hexchars]
  1556.     call    tx_byted ; byte in bl eax ebx edx destroyed
  1557.  
  1558. dump_data:
  1559.     popa
  1560.  
  1561.     ; OK, we come in here with
  1562.     ; cx == number of byte to send
  1563.     ; esi == buffer start
  1564.     ;
  1565. dd_000:
  1566.     mov     bl, 0x0a
  1567.     call    tx_byted
  1568.     mov     bl, 0x0d
  1569.     call    tx_byted
  1570.  
  1571.     mov     eax, 16        ; Number of characters on the line
  1572.     mov     edi, esi    ; Save first byte position for later
  1573.  
  1574.     push    ecx
  1575.  
  1576. dd_001:
  1577.     push    eax
  1578.  
  1579.     ; Print a byte, and a space
  1580.     xor     eax, eax
  1581.     mov     al, [esi]
  1582.     shr     al, 4
  1583.     mov     bl, [eax + hexchars]
  1584.     call    tx_byted ; byte in bl eax ebx edx destroyed
  1585.  
  1586.     xor     eax, eax
  1587.     mov     al, [esi]
  1588.     and     al, 0x0f
  1589.     mov     bl, [eax + hexchars]
  1590.     call    tx_byted ; byte in bl eax ebx edx destroyed
  1591.  
  1592.     mov     bl, ' '
  1593.     call    tx_byted
  1594.  
  1595.     pop     eax
  1596.  
  1597.     inc     esi
  1598.     dec     ecx
  1599.     cmp     ecx, 0
  1600.     je      dd_0011            ; Print the ASCII format
  1601.  
  1602.     dec     eax
  1603.  
  1604.     cmp     eax, 0
  1605.     je      dd_002            ; Print the ASCII format
  1606.     jmp     dd_001            ; Print rest of line
  1607.  
  1608. dd_0011:
  1609.     ; First, complete the 16 bytes of data, by printing spaces
  1610.     dec     eax
  1611.     cmp     eax, 0
  1612.     je      dd_002
  1613.  
  1614.     push    eax
  1615.     mov     bl, ' '
  1616.     call    tx_byted
  1617.     mov     bl, ' '
  1618.     call    tx_byted
  1619.     mov     bl, ' '
  1620.     call    tx_byted
  1621.     pop     eax
  1622.     jmp     dd_0011
  1623.  
  1624. dd_002:
  1625.     pop     ecx
  1626.     mov     esi, edi        ; Go back to the start of the line data
  1627.  
  1628.     mov     eax, 16
  1629.  
  1630. outLineAscii:
  1631.     push    eax
  1632.  
  1633.     xor     eax, eax
  1634.     mov     al, [esi]
  1635.     mov     bl, '.'
  1636.  
  1637.     cmp     al, 0x1F
  1638.     jle     outAscii
  1639.     cmp     al, 0x7e
  1640.     jge     outAscii
  1641.  
  1642.     mov     bl, al
  1643.  
  1644. outAscii:
  1645.     call    tx_byted ; byte in bl eax ebx edx destroyed
  1646.  
  1647.     pop     eax
  1648.     dec     ecx
  1649.     inc     esi
  1650.     cmp     ecx, 0
  1651.     je      dd_003
  1652.  
  1653.     dec     eax
  1654.     cmp     eax, 0
  1655.     je      dd_003
  1656.     jmp     outLineAscii
  1657.  
  1658. dd_003:
  1659.     cmp     ecx, 0
  1660.     je      dd_004
  1661.     jmp     dd_000
  1662.  
  1663. dd_004:
  1664.     ret
  1665.  
  1666. ;***************************************************************************
  1667. ;   Function
  1668. ;      tx_byte
  1669. ;
  1670. ;   Description
  1671. ;       Send a byte in bl out of the com port 1
  1672. ;       destroys eax, edx
  1673. ;
  1674. ;***************************************************************************
  1675. tx_byted:
  1676.     push    ebx                     ; Save the byte
  1677.  
  1678.     mov     ebx, 0x3f8            ; get the com port address
  1679.  
  1680.     ; Wait for transmit buffer to empty. This could take 1ms @ 9600baud
  1681.  
  1682.     mov     edx, ebx
  1683.     add     edx, 5
  1684.  
  1685. wait_txd:
  1686.     in      al, dx                   ; read uart serialisation status
  1687.     and     al, 0x40
  1688.     cmp     al, 0
  1689.     jz      wait_txd                  ; loop until free
  1690.  
  1691.     mov     edx, ebx
  1692.     pop     eax                     ; restore the byte to send
  1693.     out     dx, al
  1694.     ret
  1695.  
  1696. iglobal
  1697.   ; This is used for translating hex to ASCII for display or output
  1698.   hexchars    db '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
  1699. endg
  1700. end if
  1701.  
  1702.