# flashcard.S86 - Routines for supporting FlashCard # # Copyright (C) 2002-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: flashcard.S86,v 1.1 2003/03/09 00:43:09 gkminix Exp $ # #==================================================================== # #include "common.i86" #include "flash.i86" .file "flashcard.S86" .line 30 # #==================================================================== # # Some definitions which are local to this module # MAXSIZE .equ 131072 # max supported EPROM size MINSIZE .equ AMD_MINSIZE # min supported EPROM size SEGLOW .equ H'C800 # lower range for EPROM segment SEGHIGH .equ H'E800 # upper range for EPROM segment SEGBIOS .equ H'F000 # BIOS segment SEGSTEP .equ H'0200 # 8kB steps for EPROM segment SEGCHECK .equ MINSIZE / 16 # 32kB block for RAM check .line 48 # #==================================================================== # # 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 chkram # check for RAM area .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 es push si # Detecting a FlashCard is not as easy as it is with PCI network cards, # since a FlashCard doesnt have any identifying register on board. It simply # maps the Flash EPROM into the ISA address space. Therefore we have to scan # through the whole extension ROM address space at 8kB intervalls, check if # there is ROM within the following 32 kB, and then try to identify a # Flash EPROM chip at that intervall. Of course, this only works, if the BIOS # did NOT copy the Flash EPROM contents into shadow RAM. # As a side effect, this routine will also be able to find any Flash EPROM on # a network card which has not been detected previously. Therefore, this FlasCard # detection routine has to be called last after all other detection routines # havent found anything. mov bx,SEGLOW mov dword ptr [winsize],SEGCHECK * 16 detec1: mov cx,SEGCHECK call chkram # check if this is RAM jnc detec2 and ax,0 - SEGSTEP + 1 # skip the memory which we know mov bx,ax # contains RAM jmp detec3 detec2: push bx and ebx,0x0000FFFF shl ebx,4 # save address of Flash EPROM mov [romaddr],ebx # for calls to ifread mov bx,offset istruct_fc call amd_readid # read ID from Flash EPROM pop bx or si,si # check if Flash EPROM found jnz detec4 detec3: cmp bx,SEGHIGH # dont go into BIOS ROM area jae detec8 add bx,SEGSTEP # continue with next 8kB block jmp detec1 # Determine the size of the Flash EPROM and set an upper limit for the # window size. The FlashCard allows selecting only a portion of the whole # Flash EPROM size to be accessible, starting at the beginning of the # Flash EPROM address space. We call this the window size. It can not # be detected by reading a certain register, as there are no registers # on the FlashCard. However, the window size cant be larger than the # physical Flash EPROM size, and it cant go into the BIOS. detec4: mov [curchip],si mov eax,[si + FSTRUCT_ROMSIZE] mov [romsize],eax # save Flash EPROM size mov ecx,SEGBIOS * 16 sub ecx,[romaddr] cmp eax,ecx # check that the flash EPROM jbe detec5 # doesnt go into the BIOS area mov eax,ecx detec5: cmp eax,MINSIZE # should be at least 32kB jb detec8 cmp eax,MAXSIZE # limit to a maximum of 128kB jbe detec6 mov eax,MAXSIZE detec6: mov [winsize],eax # save maximum window size # Now we know the size of the area which can be accessed at most. There # is no reasonable way to find out about the real window size except # programming into the Flash EPROM. This is not suitable at this point. # We therefore just accept what we found so far. If the real window # size is smaller as what we thought, then all programming above the # real window size wont happen, and we will produce an error upon verify. # However, if the jumpered real window size is smaller than what we # guessed above, there might still be some RAM following the Flash EPROM. # In order to prevent the programming routines to write into that RAM, # we first have to find this RAM, and will then set the window size so # that it is no longer possible to clobber the RAM contents. The following # code will scan through the Flash EPROM and see if it really contains # ROM. mov ebx,[romaddr] shr ebx,4 shr eax,4 mov cx,ax call chkram # check if this is RAM jnc detec7 mov ebx,[romaddr] # we found some RAM, so AX contains the shr ebx,4 # segment where this RAM has been found sub ax,bx shl eax,4 # compute the size of the remaining and eax,0x000FFFF0 # Flash EPROM address space and check cmp eax,MINSIZE # that it is sufficiently large jb detec8 mov [winsize],eax # we use this as our new window size # After all this checking and memory scanning we finally found a FlashCard, # so we can prepare the return values. detec7: mov dx,[curchip] mov ecx,[winsize] mov eax,[romaddr] xor edi,edi clc jmp detec9 # Return to caller. detec8: stc # return with error detec9: pop es pop si ret # #==================================================================== # # Read one byte from Flash EPROM. # Input: EDI - Offset into Flash EPROM # Output: AL - Byte value # Changed registers: AL # ifread: push es push edi xor al,al cmp edi,[winsize] # check if offset is within limits jae read9 push eax add edi,[romaddr] mov eax,edi shr eax,4 # compute pointer to byte mov es,ax and di,0x000F pop eax mov al,es:[di] # get byte from Flash EPROM read9: pop edi pop es ret # #==================================================================== # # Write one byte into Flash EPROM. # Input: EDI - Offset into Flash EPROM # AL - Byte value # Output: none # Changed registers: none # ifwrite: push es push edi cmp edi,[winsize] # check if offset is within limits jae write9 push eax add edi,[romaddr] mov eax,edi shr eax,4 # compute pointer to byte mov es,ax and di,0x000F pop eax mov es:[di],al # put byte into Flash EPROM write9: pop edi pop es ret # #==================================================================== # # Initialize NIC for programming. # Input: none # Output: none # Changed registers: none # ifinit: # fall through # #==================================================================== # # Terminate programming. # Input: none # Output: none # Changed registers: none # ifclean: clc ret # #==================================================================== # # Turn programming voltage VPP on # Input: none # Output: none # Changed registers: none # ifvppon: # fall through # #==================================================================== # # Turn programming voltage VPP off # Input: none # Output: none # Changed registers: none # ifvppoff: stc 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_fc call amd_erase # call chip erasure routine 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_fc prog1: mov al,fs:[si] call amd_doprog # program one byte into Flash EPROM jc prog9 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 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_fc call gen_verify # call generic routine pop bx ret # #==================================================================== # # String and constants definitions # \(.data) .global istruct_fc # Interface definition ifname: .asciz "FlashCard" istruct_fc: .word ifname # pointer to interface name .word IDEVTYPE_NONE # interface device type .word 0 # no device 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 0 # no loader necessary .word IFLAGS_NEEDMEM # interface needs direct memory access # #==================================================================== # # Variable definitions # \(.bss) .lcomm curchip,2 # pointer to chip definition struct .lcomm romaddr,4 # base address of Flash ROM .lcomm romsize,4 # size of Flash ROM .lcomm winsize,4 # size of ROM window # #==================================================================== # .end