# i82595.S86 - Routines for supporting network cards with i82595 chip # # Copyright (C) 2003 Gero Kuhlmann # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # $Id: i82595.S86,v 1.1 2003/03/09 00:43:09 gkminix Exp $ # #==================================================================== # #include "common.i86" #include "flash.i86" .file "i82595.S86" .line 30 # #==================================================================== # # Some definitions which are local to this module # ROM_WINSIZE .equ 16384 # ROM address space window size ROM_WINBITS .equ 14 # number of bits in ROM window size # Internal ID numbers for different network cards LAN595 .equ 0 # Generic 82595-based network card LAN595TX .equ 1 # EtherExpress Pro/10 ISA LAN595FX .equ 2 # EtherExpress Pro/10+ ISA LAN595FX_10ISA .equ 3 # EtherExpress 10 ISA # 82595 on-chip registers CMD_REG .equ H'0000 # command register (same for all banks) CMD_BANK0_SEL .equ H'00 # command to select register bank 0 CMD_BANK1_SEL .equ H'40 # command to select register bank 1 CMD_BANK2_SEL .equ H'80 # command to select register bank 2 ID_REG .equ H'0002 # ID register ID_ID_MASK .equ H'2C # mask to isolate chip ID ID_CNT_MASK .equ H'C0 # mask for ID register counter ID_SIGNATURE .equ H'24 # ID for all 82595 chips ROM_WIN_REG .equ H'0002 # register for ROM decode window ROM_WIN_MASK .equ H'70 # mask to select ROM decode window ROM_PAGE_REG .equ H'000C # register for ROM page select ROM_PAGE_MASK .equ H'CF # mask for ROM page select ROM_WRITE_MASK .equ H'30 # mask for ROM write enable ROM_WRITE_ON .equ H'10 # value to enable ROM write ROM_WRITE_OFF .equ H'20 # value to disable ROM write # Definitions to access the serial EEPROM EEPROM_REG_PRO .equ H'000A # EEPROM access register for Pro series EEPROM_REG_10 .equ H'000B # EEPROM access register for 10 series EEPROM_SK .equ B'00000001 # SK bit mask (clock signal) EEPROM_CS .equ B'00000010 # CS bit mask (chip select) EEPROM_DI .equ B'00000100 # DI bit mask (data in) EEPROM_DO .equ B'00001000 # DO bit mask (data out) EEPROM_MAX .equ 18 # number of words to read from EEPROM EEPROM_SIZE .equ 64 # number of words stored within EEPROM EEPROM_WAIT .equ 40 # number of microseconds to wait EEPROM_RDCMD .equ H'0180 # EEPROM read command EEPROM_ADDR0 .equ 4 # offset to first station address word EEPROM_ADDR1 .equ 3 # offset to seconds station address word EEPROM_ADDR2 .equ 2 # offset to third station address word EEPROM_PROADDR .equ H'00AA # first station address word on TX EEPROM_SETUP0 .equ 0 # offset to first setup word EEPROM_SETUP1 .equ 1 # offset to second setup word EEPROM_PROM .equ H'0200 # mask for PROM installation flag EEPROM_IRQMAP .equ 7 # offset to IRQ mapping value EEPROM_FXIRQ .equ H'1EB8 # only allowed IRQ mapping on FX .line 96 # #==================================================================== # # Define some external routines # \(.text) .extern amd_readid # read Flash EPROM ID .extern amd_erase # erase area of Flash EPROM .extern amd_doprog # program a byte into Flash EPROM .extern intel_readid # read Flash EPROM ID .extern intel_erase # erase area of Flash EPROM .extern intel_doprog # program a byte into Flash EPROM .extern fndpnp # find PnP identifier .extern wait_usec # wait for some microseconds .extern gen_verify # generic verification routine # #==================================================================== # # Detect Flash EPROM interface # Input: FS:SI - Pointer to bootrom image # Output: EDI - Start offset into Flash EPROM for bootrom image # ECX - Size of Flash EPROM available for bootrom image # EAX - Linear address of Flash EPROM (zero if N/A) # DX - Offset to Flash EPROM info structure # Carry set if interface not found # Changed registers: EAX, EBX, ECX, EDX, EDI # ifdetect: push esi # First check if the bootrom image is really for us. For this reason, # we grab the PnP ID of the bootrom image and check it against a list # of possible IDs. mov bx,offset nic_list call fndpnp jc detec8 mov [chipid],bx mov [pnpid],edx # Now try to find a 82595 chip in the system. We scan a couple of I/O # port addresses until we find the signature emitted by the chip. Then # we read the ROM window decode register and compute the segment of the # Flash EPROM window. If its invalid, we have to continue scanning. xor bx,bx mov si,offset ldports detec7: push ds mov ax,cs mov ds,ax call ldscan # use the loader scan routine pop ds or dx,dx jz detec8 mov al,CMD_BANK1_SEL out dx,al # change to register bank 1 add dx,ROM_WIN_REG in al,dx # read ROM window address mov bl,al sub dx,ROM_WIN_REG mov al,CMD_BANK0_SEL out dx,al # switch back to register bank 0 and bx,ROM_WIN_MASK jz detec7 # check if ROM enabled shl bx,6 # compute segment address add bx,0xC000 mov [romseg],bx # save ROM segment mov [ioaddr],dx # save the I/O base address # This is some magic to determine if we have a EtherExpress 10 ISA # card, which has a different EEPROM register offset. We first set # the offset to the normal value, and then try to read the first # word of the station address out of the EEPROM. If it is invalid, # we do have a EtherExpress 10 ISA, and have to use a different # EEPROM access port. add dx,EEPROM_REG_PRO mov [ioeeprom],dx mov si,EEPROM_ADDR2 call read_eeprom # read third word of station address or ax,ax # invalid if zero jz detec1 cmp ax,0xFFFF # invalid if -1 jne detec2 detec1: add word ptr [ioeeprom],EEPROM_REG_10 - EEPROM_REG_PRO cmp word ptr [chipid],LAN595FX_10ISA jne detec8 # is it what the bootrom says? # Read the serial EEPROM to get configuration data, and determine the type # of NIC we have. detec2: xor si,si mov di,offset eeprom mov cx,EEPROM_MAX detec3: call read_eeprom # read value from serial EEPROM mov [di],ax # save value into temp storage add di,2 inc si loop detec3 mov bx,[chipid] cmp bx,LAN595FX_10ISA # we have checked for this already je detec6 cmp word ptr [eeprom + EEPROM_IRQMAP * 2],EEPROM_FXIRQ jne detec4 # check if FX IRQ mapping cmp bx,LAN595FX # we have a FX, check if the bootrom jne detec8 # thinks the same jmp detec6 detec4: cmp word ptr [eeprom + EEPROM_ADDR0 * 2],EEPROM_PROADDR jne detec5 # check if address starts with TX value cmp bx,LAN595TX # we have a TX, check if the bootrom jne detec8 # thinks the same jmp detec6 detec5: cmp bx,LAN595 # nothing found so far, so it has to jne detec8 # be a generic 595-based card detec6: shl bx,1 mov ax,name_list[bx] # set name of network card mov [istruct_i82595 + ISTRUCT_ID],ax # We have set all internal variables so far, so we can try finding a supported # Flash EPROM chip and return all relevant parameters. It is possible to use # a single-voltage (AMD-type) Flash EPROM with a i82595. If you are brave # enough you can simply put such a Flash EPROM into the socket on the network # board and hope that no-one will ever activate the Vpp pin (which would fry # the chip with 12 volts). Otherwise you can turn pin 1 of the AMD-type Flash # EPROM chip upwards so that it doesnt sit in the socket anymore, and connect # it with a small wire to ground. Then it is pretty safe. Because of this # possibility, we also do an AMD check here. However, the standard would be # to use a 12 volt Intel-type Flash EPROM. Those can be plugged in without # any doubt. call ifinit # setup Flash EPROM access mov dword ptr [romsize],0 mov word ptr [flasherase],offset amd_erase mov word ptr [flashprog],offset amd_doprog mov word ptr [flashsetup],offset ifdummy mov word ptr [flashcleanup],offset ifdummy mov bx,offset istruct_i82595 call amd_readid # read ID from Flash EPROM or si,si jnz detecA mov word ptr [flasherase],offset intel_erase mov word ptr [flashprog],offset intel_doprog mov word ptr [flashsetup],offset intel_setup mov word ptr [flashcleanup],offset intel_cleanup mov bx,offset istruct_i82595 call intel_readid # read ID from Flash EPROM detecA: call ifclean # turn Flash EPROM access off or si,si jz detec8 mov ecx,[si + FSTRUCT_ROMSIZE] cmp ecx,ROM_WINSIZE # check that the Flash EPROM size is jb detec8 # within the window size mov [romsize],ecx # save physical size of Flash EPROM movzx32 eax,word ptr [romseg] shl eax,4 xor edi,edi # return without error mov dx,si jmp detec9 detec8: stc # return with error detec9: pop esi ret # #==================================================================== # # Dummy routine # Input: none # Output: none # Changed registers: none # ifdummy: clc ret # #==================================================================== # # Read one byte from Flash EPROM. This routine assumes that the NIC chip # has been set to register window 1 already. It will also switch the # ROM bank, but doesnt switch it back. # Input: EDI - Offset into Flash EPROM # Output: AL - Byte value # Changed registers: AL # ifread: push ebx push dx push es xor al,al mov ebx,[romsize] # if romsize is zero we are still in or ebx,ebx # ROM detection mode jz read1 cmp edi,ebx # check if valid offset jae read9 read1: mov bx,[romseg] # set segment to access ROM page mov es,bx mov dx,[ioaddr] # set I/O address to ROM page register add dx,ROM_PAGE_REG mov ebx,edi shr ebx,ROM_WINBITS # compute page number into BL mov al,bl shl al,2 and al,0xC0 and bl,0x0F # adjust the page number to the or bl,al # register format in al,dx and al,ROM_WRITE_MASK # dont change the write-enable bits or al,bl out dx,al # select new page mov ebx,edi and bx,ROM_WINSIZE - 1 # compute offset into ROM window mov al,es:[bx] # read byte from ROM read9: pop es pop dx pop ebx ret # #==================================================================== # # Write one byte into Flash EPROM. This routine assumes that the NIC chip # has been set to register window 1 already. It will also switch the # ROM bank, but doesnt switch it back. # Input: EDI - Offset into Flash EPROM # AL - Byte value # Output: none # Changed registers: none # ifwrite: push ebx push dx push es mov ebx,[romsize] # if romsize is zero we are still in or ebx,ebx # ROM detection mode jz write1 cmp edi,ebx # check if valid offset jae write9 write1: push ax mov bx,[romseg] # set segment to access ROM page mov es,bx mov dx,[ioaddr] # set I/O address to ROM page register add dx,ROM_PAGE_REG mov ebx,edi shr ebx,ROM_WINBITS # compute page number into BL mov al,bl shl al,2 and al,0xC0 and bl,0x0F # adjust the page number to the or bl,al # register format in al,dx and al,ROM_WRITE_MASK # dont change the write-enable bits or al,bl out dx,al # select new page pop ax mov ebx,edi and bx,ROM_WINSIZE - 1 # compute offset into ROM window mov es:[bx],al # write byte into ROM write9: pop es pop dx pop ebx ret # #==================================================================== # # Initialize NIC for programming. This sets the register bank to 1. # Input: none # Output: none # Changed registers: AX # ifinit: push dx mov dx,[ioaddr] # get I/O address mov al,CMD_BANK1_SEL out dx,al # change to register bank 1 pop dx clc ret # #==================================================================== # # Terminate programming. This restores the register bank to 0 and switches # the ROM page back to 0. It assumes that bank 1 is still active when being # called. # Input: none # Output: none # Changed registers: AX # ifclean: push dx mov dx,[ioaddr] # get I/O address add dx,ROM_PAGE_REG in al,dx and al,ROM_WRITE_MASK # dont change the write-enable bits out dx,al # select page 0 sub dx,ROM_PAGE_REG mov al,CMD_BANK0_SEL out dx,al # switch back to register bank 0 pop dx clc ret # #==================================================================== # # Turn programming voltage VPP on. This routine assumes that bank 1 is # still active. # Input: none # Output: none # Changed registers: AL # ifvppon: push dx cmp word ptr [flashprog],offset intel_doprog jne vppon9 mov dx,[ioaddr] # get I/O address add dx,ROM_PAGE_REG in al,dx and al,ROM_PAGE_MASK # dont change the page bits or al,ROM_WRITE_ON out dx,al # turn Vpp on vppon9: pop dx clc ret # #==================================================================== # # Turn programming voltage VPP off. This routine assumes that bank 1 is # still active. # Input: none # Output: none # Changed registers: AL # ifvppoff: push dx cmp word ptr [flashprog],offset intel_doprog jne vppof9 mov dx,[ioaddr] # get I/O address add dx,ROM_PAGE_REG in al,dx and al,ROM_PAGE_MASK # dont change the page bits or al,ROM_WRITE_OFF out dx,al # turn Vpp off vppof9: pop dx clc ret # #==================================================================== # # Erase the Flash EPROM area occupied by the rom image. We simply call # the routine for the Flash EPROM chip. # Input: EDI - Offset to rom image block within EPROM # ECX - Number of bytes to erase # Output: carry flag set if error # Registers changed: EAX # iferase: push bx mov bx,offset istruct_i82595 call [flashsetup] # setup Flash EPROM access jc erase9 call [flasherase] # call chip erasure routine pushf # save carry flag call [flashcleanup] # cleanup Flash EPROM access jnc erase8 pop ax # remove carry flag from stack jmp erase9 # return with carry set erase8: popf # restore carry flag erase9: pop bx ret # #==================================================================== # # Program a memory area into the Flash EPROM. # Input: FS:SI - Pointer to memory area with source data # ECX - Number of bytes to program # EDI - Offset to rom image block within EPROM # Output: carry flag set if error # Registers changed: EAX # ifprog: push bx push ecx push edi push si push fs mov bx,offset istruct_i82595 call [flashsetup] # setup Flash EPROM access jc prog9 prog1: mov al,fs:[si] call [flashprog] # program one byte into Flash EPROM jc prog7 inc si # increment source pointer test si,0x8000 jz prog2 # avoid source pointer overflow mov ax,fs add ax,0x0800 mov fs,ax and si,0x7FFF prog2: inc edi # increment offset into Flash EPROM data32 loop prog1 # continue with next byte clc prog7: pushf # save carry flag call [flashcleanup] # cleanup Flash EPROM access jnc prog8 pop ax # remove carry flag from stack jmp prog9 # return with carry prog8: popf # restore carry flag prog9: pop fs pop si pop edi pop ecx pop bx ret # #==================================================================== # # Verify a memory area against the contents of the Flash EPROM. # Input: FS:SI - Pointer to memory area with source data # ECX - Number of bytes to verify # EDI - Offset to rom image block within EPROM # Output: carry flag set if error # Registers changed: EAX # ifverify: push bx mov bx,offset istruct_i82595 call gen_verify # call generic routine pop bx ret # #==================================================================== # # Read one word from NIC serial EEPROM. This is quite horrible, because # the CPU has to generate all the timings. This code has been partially # taken from the Linux source. # Input: SI - Offset into serial EEPROM # Output: AX - Word read from serial EEPROM # Changed registers: AX # read_eeprom: push bx push cx push dx mov dx,[ioaddr] mov al,CMD_BANK1_SEL out dx,al inc dx # this is black magic: write a 0 xor al,al # into register 1 of bank 1, then out dx,al # switch to bank 2 dec dx mov al,CMD_BANK2_SEL out dx,al mov dx,[ioeeprom] mov al,EEPROM_CS out dx,al # set EEPROM chip select mov bx,si and bx,EEPROM_SIZE - 1 or bx,EEPROM_RDCMD # setup EEPROM read command mov cx,9 # number of bits to shift out eerd1: jcxz eerd3 dec cx # prepare current bit number mov ax,0x0001 shl ax,cl test bx,ax # check if bit set jz eerd2 mov al,EEPROM_DI # set output bit eerd2: or al,EEPROM_CS mov ah,al out dx,al # drive output pin or al,EEPROM_SK out dx,al # drive clock pin push ax mov ax,EEPROM_WAIT call wait_usec # wait 40 microseconds pop ax mov al,ah out dx,al # reset clock pin mov ax,EEPROM_WAIT call wait_usec # wait another 40 microseconds jmp eerd1 eerd3: mov al,EEPROM_CS out dx,al # reset output pin xor bx,bx mov cx,16 # set number of bit to read eerd4: mov al,EEPROM_CS or al,EEPROM_SK out dx,al # drive clock pin mov ax,EEPROM_WAIT call wait_usec # wait 40 microseconds shl bx,1 in al,dx # read input pin test al,EEPROM_DO jz eerd5 or bx,0x0001 # set bit in input word eerd5: mov al,EEPROM_CS out dx,al # reset clock pin mov ax,EEPROM_WAIT call wait_usec # wait another 40 microseconds loop eerd4 # continue with all other bits mov al,EEPROM_SK out dx,al # one clock pulse without chip select mov ax,EEPROM_WAIT call wait_usec # wait 40 microseconds xor al,al out dx,al # reset clock and chip select pins mov ax,EEPROM_WAIT call wait_usec # wait another 40 microseconds mov dx,[ioaddr] mov al,CMD_BANK0_SEL # switch back to bank 0 out dx,al mov ax,bx # prepare return value pop dx pop cx pop bx ret # #==================================================================== # # The following code is the bootrom loader for the 82595. Since this chip # only maps 16kB of the Flash EPROM into the processors address space at # one time, in order to access the whole bootrom it is necessary to switch # the ROM pages during bootrom startup. For this, the initial bootrom loader # and the following code get copied into the first Flash EPROM page, and the # compressed remainder of the bootrom get burned into the remaining pages. # Then when the bootrom starts up, it has to decompress the main parts # (kernel and UNDI). To do this it will call a reading routine, which is # coded below, for every compressed byte to be read. This reading routine # will then switch the Flash EPROM page on the 82595 chip as necessary. # The following code is therefore not only used by the Flash EPROM programmer # code above, but also by the bootrom at a different starting offset. Thats # the reason why the following code as to be strictly position independent. # It has to be able to run at any arbitrary offset. Jumps and calls are # relative on the iA32 platform, so those are not a problem (as long as they # happen within +/- 32kB). But data accesses have to use absolute addresses. # To make data values position independent we are using the BX register, which # always contains the difference between the offset the assembler is generating # and the offset the code expects when running within the bootrom context. # # These routines assume that they get called by a near call, and the DS is # set to CS. # #==================================================================== # # Initialize the bootrom loader. This routine gets only called by the # bootrom, and it has to find an 82595-based network card and setup all # required data values. It returns the absolute offset to the Flash EPROM # reading routine. This routine has to be at the very beginning of the # whole loader code. # Input: BX - PCI PFA of network card # DX - PnP CSN of network card # CS:SI - Pointer to DWORD which contains the size of the bootrom # Output: AX - Offset to Flash EPROM reading routine (0 means error) # DI - Offset to first byte following loader code # Changed registers: EAX, BX, CX, DX, SI, DI # ldinit: jmp ldini0 .word 0 # receives size of flash image loader ldini0: push bx call ldini1 ldini1: pop bx sub bx,offset ldini1 # compute offset difference pop cx # get PCI PFA from stack - not needed push es # First check to see that we are running within RAM. For this we read # the compressed bootrom image size and write it into its assigned # variable. If it is not the same, we are running within a ROM, and # when switching the Flash EPROM page, the results are unpredictable. mov eax,cs:[si] # read size of compressed image mov ldrdsize[bx],eax cmp ldrdsize[bx],eax # check if we could store the variable jne ldini8 mov word ptr ldrdaddr[bx],WINID_LEN mov word ptr ldrdpage[bx],1 # Find a 82595 chip and determine the segment of the Flash EPROM access # window. Finally try to read the signature at the beginning of the compressed # code to check if we can really switch the ROM page. lea si,ldports[bx] ldini2: call ldscan # scan I/O space for 82595 chip or dx,dx jz ldini8 # couldnt find one mov ldioaddr[bx],dx # save base I/O address mov al,CMD_BANK1_SEL out dx,al # change to register bank 1 add dx,ROM_WIN_REG in al,dx # read ROM window address and ax,ROM_WIN_MASK jnz ldini3 # check if ROM enabled sub dx,ROM_WIN_REG mov al,CMD_BANK0_SEL # in case of error switch register out dx,al # bank back to 0 jmp ldini2 ldini3: shl ax,6 # compute segment address add ax,0xC000 mov ldromseg[bx],ax mov es,ax add dx,ROM_PAGE_REG - ROM_WIN_REG in al,dx mov ah,al # save old page number for later and al,ROM_WRITE_MASK # select page 1 or al,0x01 out dx,al lea si,ldsig[bx] xor di,di mov cx,WINID_LEN cld repe cmpsb # compare both strings pushf # save zero flag mov al,ah out dx,al # reset to previous page sub dx,ROM_PAGE_REG mov al,CMD_BANK0_SEL out dx,al # reset to register bank 0 popf # restore zero flag jne ldini8 lea ax,[bx + ldread] # return without error lea di,[bx + ldend + 0x000F] and di,0xFFF0 # adjust to paragraph boundary jmp ldini9 ldini8: xor ax,ax # return with error ldini9: pop es ret # #==================================================================== # # Read one byte from the Flash EPROM by switching the Flash EPROM page # within the 82595 controller. Since we have to switch the page, this # code is not allowed to be run directly from within the Flash EPROM! # Input: none # Output: AL - Byte read from Flash EPROM # Zero flag set if at end of compressed bootrom contents # Changed registers: AX # ldread: push bx call ldrd1 ldrd1: pop bx sub bx,offset ldrd1 # compute offset difference # First check if we are at the end of the file mov ax,word ptr ldrdsize[bx + 0] or ax,word ptr ldrdsize[bx + 2] jz ldrd9 # Now select the proper Flash EPROM page, read the requested byte # and switch back to page 0. We have to do this switching everytime # because we never know if the decompression routine terminates # with an error. In that case, if we would have set the register # bank and flash page permanently, they would never get reset. push dx push es push si mov dx,ldioaddr[bx] # get I/O address mov al,CMD_BANK1_SEL # select proper register bank out dx,al mov ax,ldromseg[bx] # set segment to access ROM page mov es,ax add dx,ROM_PAGE_REG mov si,ldrdpage[bx] # get current page number mov ax,si shl ax,2 and ax,0x00C0 # adjust the page number to the and si,0x000F # register format or si,ax in al,dx mov ah,al # remember old page in AH and al,ROM_WRITE_MASK # dont change the write-enable bits or ax,si out dx,al # select new page mov si,ldrdaddr[bx] # get load address mov al,es:[si] # read the requested byte xchg al,ah out dx,al # restore old Flash EPROM page sub dx,ROM_PAGE_REG mov al,CMD_BANK0_SEL out dx,al # switch back to register page 0 xchg al,ah # move result into AL dec dword ptr ldrdsize[bx] # decrement number of bytes inc word ptr ldrdaddr[bx] # increment read address cmp word ptr ldrdaddr[bx],ROM_WINSIZE jb ldrd2 mov word ptr ldrdaddr[bx],0 inc word ptr ldrdpage[bx] # increment read ptr to next page ldrd2: or dx,dx # clear zero flag pop si pop es pop dx ldrd9: pop bx ret # #==================================================================== # # Scan various I/O port addresses and try to find a 82595 chip. # Input: BX - Offset difference to access variables # SI - Pointer to list of port addresses to scan # Output: DX - Base port address, zero if no chip found # SI - Pointer to next port address to scan # Changed registers: AX, DX, SI # ldscan: mov dx,[si] # get next port address or dx,dx jz ldscn9 add si,2 add dx,ID_REG # read ID register in al,dx mov ah,al and al,ID_ID_MASK cmp al,ID_SIGNATURE # is it our required signature? jne ldscan and ah,ID_CNT_MASK in al,dx # read in the counter and al,ID_CNT_MASK add ah,0x40 cmp al,ah # check if counter increased jne ldscan sub dx,ID_REG # return base port address ldscn9: ret # #==================================================================== # # Variables used by the loader code. It is not nice to have variables within # the code segment, but there is no way to avoid this with the Flash EPROM # loader. # # Variable to hold the I/O address of the 82595 chip. This variable will only # be used by the Flash EPROM loader. The I/O address might be different at # loader runtime and at the time when we run the Flash EPROM programmer (for # example the user might have reconfigured the network card in the meantime). ldioaddr: .word 0 # Segment of Flash EPROM access window ldromseg: .word 0 # Current page in the Flash EPROM. The compressed bootrom code always # starts at page 1. ldrdpage: .word 0 # Current read address offset starting at the beginning of page 1 in the # Flash EPROM ldrdaddr: .word 0 # Size of image to read from Flash EPROM ldrdsize: .long 0 # Signature at the beginning of the compressed ROM code ldsig: .ascii "\&WINID_MAGIC" # I/O ports to be checked during 82595 scan ldports: .word 0x0300 .word 0x0210 .word 0x0240 .word 0x0280 .word 0x02C0 .word 0x0200 .word 0x0320 .word 0x0340 .word 0x0360 .word 0 # The loader code ends here. All the code from label ldinit up to here # gets copied into the bootrom lateron. ldend: # #==================================================================== # # String and constants definitions # \(.data) .global istruct_i82595 # NIC list nic_list: .ascii "PNP828A" .ascii "INT1030" .ascii "INT1031" .ascii "INT1100" .byte 0 # NIC names name_lan595: .asciz "Intel 82595-based network card" name_lan595tx: .asciz "Intel EtherExpress Pro/10 ISA" name_lan595fx: .asciz "Intel EtherExpress Pro/10+ ISA/PnP" name_lan595isa: .asciz "Intel EtherExpress 10 ISA" name_list: .word name_lan595 .word name_lan595tx .word name_lan595fx .word name_lan595isa # Interface definition istruct_i82595: .word 0 # pointer to interface name .word IDEVTYPE_ISA # interface device type .word nic_list # pointer to PnP ID list .word ifdetect # pointer to detection routine .word ifread # pointer to byte read routine .word ifwrite # pointer to byte write routine .word ifvppon # pointer to VPP-on routine .word ifvppoff # pointer to VPP-off routine .word ifinit # pointer to initialization routine .word ifclean # pointer to cleanup routine .word iferase # pointer to erase routine .word ifprog # pointer to programming routine .word ifverify # pointer to verify routine .word ifload # pointer to loader structure .word IFLAGS_NEEDMEM # interface needs direct memory access # Loader definition ifload: .word ldinit # pointer to start of loader code .word ldend # pointer to end of loader code .long ROM_WINSIZE # ROM address space window size # #==================================================================== # # Variable definitions # \(.bss) .lcomm chipid,2 # type of chip installed .lcomm pnpid,4 # PnP vendor and device ID .lcomm ioaddr,2 # I/O address for register access .lcomm romseg,2 # segment of Flash ROM window .lcomm romsize,4 # size of physical Flash ROM .lcomm flasherase,2 # pointer to erase routine .lcomm flashprog,2 # pointer to programming routine .lcomm flashsetup,2 # pointer to Flash setup routine .lcomm flashcleanup,2 # pointer to Flash cleanup routine .lcomm ioeeprom,2 # EEPROM access I/O port address .lcomm eeprom,EEPROM_MAX * 2 # area to save EEPROM values # #==================================================================== # .end