http://gimel.esc.cam.ac.uk/james/rpld/src/rpld-1.2.tar.gz
[rpld.git] / nics / dm9102 / dmfix.S
1 ! Davicom Bootloader fixup, switches off the DAVICOM fast ethernet chip
2 ! before transfering control to the RPL'd image, so that the chip
3 ! doesn't scribble all over it while it relocates
4 !
5 ! This image needs 2k of memory, and can be loaded anywhere, after
6 ! it does its stuff it does jmp 0x9020:0x0
7 !
8
9 !
10 ! $Id: dmfix.S,v 1.1 2000/07/16 13:16:40 root Exp $ll rights reserved
11 !
12 !  Copyright (c) 1999, James McKenzie.
13 !                       All rights reserved
14 !  Copyright (c) 1999, Christopher Lightfoot.
15 !                       All rights reserved
16
17 !  By using this file, you agree to the terms and conditions set
18 !  forth in the LICENCE file which can be found at the top level of
19 !  the rpld distribution.
20
21 !  DAVICOM is a trademark of DAVICOM semiconductor inc.
22
23 !
24 !
25 ! $Log: dmfix.S,v $
26 ! Revision 1.1  2000/07/16 13:16:40  root
27 ! #
28 !
29 ! Revision 1.4  1999/09/14 17:18:27  root
30 ! #
31 !
32 ! Revision 1.3  1999/09/13 12:32:26  root
33 ! #
34 !
35 ! Revision 1.2  1999/09/12 05:07:29  root
36 ! *** empty log message ***
37 !
38 !
39
40 ! Offsets into the PCI config space
41 #define PCI_VENDOR_ID                   0x00
42 #define PCI_DEVICE_ID                   0x02
43 #define PCI_HEADER_TYPE                 0x0e
44 #define PCI_BASE_ADDRESS_0              0x10
45
46 !PCI constants
47 #define PCI_BASE_ADDRESS_IO_MASK        0xfffc
48 #define PCI_VENDOR_ID_DAVICOM           0x1282
49 #define PCI_DEVICE_ID_DAVICOM_9102      0x9102
50
51
52 .globl begtext, begdata, begbss, endtext, enddata, endbss
53 .text
54 begtext:
55 .data
56 begdata:
57 .bss
58 begbss:
59 .text
60
61 entry start
62 start:
63         mov ax,cs
64         mov es,ax
65         mov ds,ax
66         mov ss,ax
67
68 ! Put the stack at us+2k
69         mov di,#0x800-12
70         mov sp,di
71
72 ! Say hello
73         lea si,hello
74         call prtstr
75         call print_nl
76
77         lea si,top
78         call prtstr
79         call print_nl
80
81 ! Scan the pci bus
82         mov byte (devfn),#0
83
84 dev_loop:
85                 mov bh, byte (devfn)            !Device number
86                 mov bl,#PCI_VENDOR_ID           !Offset into config space
87                 mov cl, byte (bus)              !Bus number
88                 call pci_read_config_word
89
90                 cmp ax,#0xffff
91                 beq dull
92                 cmp ax,#0x0000
93                 beq dull
94
95                         mov (vid),ax
96
97                         xor dh,dh       
98                         mov dl,byte (bus)
99         
100                         call print_2hex
101                         call print_sp   
102         
103                         mov dl, byte (devfn)
104                         sar dl,#3
105                         and dx,#0x1f
106         
107                         call print_2hex
108                         call print_sp
109         
110                         mov dl, byte (devfn)
111                         and dl,#7
112         
113                         call print_2hex
114                         call print_sp
115                 
116                         mov dx,(vid)
117                         call print_hex
118                         call print_sp
119         
120                         mov bh, byte (devfn)    !Device number
121                         mov bl,#PCI_DEVICE_ID   !Offset into config space
122                         mov cl,byte (bus)       !Bus number
123                         call pci_read_config_word
124         
125                         mov (did),ax
126                 
127                         mov dx,ax
128                         call print_hex
129                         call print_sp
130         
131                         mov bh, byte (devfn)  !Device number
132                         mov bl,#PCI_BASE_ADDRESS_0 !Offset into config space
133                         mov cl, byte (bus)      !Bus number
134                         call pci_read_config_word
135         
136                         and ax,#PCI_BASE_ADDRESS_IO_MASK
137                         mov (dad),ax
138         
139                         mov dx,ax
140                         call print_hex
141                         call print_sp
142         
143         
144                         cmp (vid),#PCI_VENDOR_ID_DAVICOM
145                         bne skipfix
146                         cmp (did),#PCI_DEVICE_ID_DAVICOM_9102
147                         bne skipfix
148         
149                                 mov dx,(dad) !Hit the Reset bit
150                                 in eax,dx
151                                 or eax,#1
152                                 out dx,eax
153                 
154                                 lea si,fixed
155                                 call prtstr
156         
157 skipfix:
158         
159         
160                         mov bh, byte (devfn)    !Device number
161                         mov bl,#PCI_HEADER_TYPE !Offset into config space
162                         mov cl,byte (bus)       !Bus number
163                         call pci_read_config_byte
164         
165                         and al,#0x80
166                         cmp al,#0x80
167                         beq multi
168                                 inc byte (devfn)
169                                 inc byte (devfn)
170                                 inc byte (devfn)
171                                 inc byte (devfn)
172                                 inc byte (devfn)
173                                 inc byte (devfn)
174                                 inc byte (devfn)
175 multi:
176
177                         call print_nl
178
179 dull:
180
181
182                 inc byte (devfn)
183                 mov dl, byte (devfn)
184                 cmp dl,#0
185                 beq dev_loop_skip
186                         br dev_loop
187 dev_loop_skip:
188
189         lea si,done
190         call prtstr
191         call print_nl
192
193 ! Hand over control to the linux 2ndary boot loader
194         jmp 0x9020:0x0
195
196
197 ! bh contains device_fn
198 ! bl conatins offset
199 ! cl contains the bus number
200
201
202 pci_read_config_word: 
203         push bx
204         and bl,#0xfc
205         mov ch,#0x80
206
207         mov (controldword),bx
208         mov (controldword+2),cx
209
210         mov eax,(controldword)
211         mov dx,#0xcf8
212         out dx,eax
213
214         pop dx
215         and dx,#0x2
216         add dx,#0xcfc
217
218         in ax,dx
219         ret
220
221 pci_read_config_byte: 
222         push bx
223         and bl,#0xfc
224         mov ch,#0x80
225
226         mov (controldword),bx
227         mov (controldword+2),cx
228
229         mov eax,(controldword)
230         mov dx,#0xcf8
231         out dx,eax
232
233         pop dx
234         and dx,#0x3
235         add dx,#0xcfc
236
237         in al,dx
238         ret
239
240
241 prtstr: 
242                 lodsb
243                 and     al,al
244                 jz      fin
245                 call    prtchr
246         jmp     prtstr
247 fin:    ret
248
249 prtchr: push    ax
250         push    cx
251         xor     bh,bh
252         mov     cx,#0x01
253         mov     ah,#0x0e
254         int     0x10
255         pop     cx
256         pop     ax
257         ret
258
259 print_hex:
260         mov     cx, #4          ! 4 hex digits
261 print_digit:
262         rol     dx, #4          ! rotate so that lowest 4 bits are used
263         mov     ax, #0xe0f      ! ah = request, al = mask for nybble
264         and     al, dl
265         add     al, #0x90       ! convert al to ascii hex (four instructions)
266         daa
267         adc     al, #0x40
268         daa
269         int     0x10
270         loop    print_digit
271         ret
272
273 print_2hex:
274         mov     cx, #2          ! 2 hex digits
275 print_2digit:
276         rol     dx, #4          ! rotate so that lowest 4 bits are used
277         mov     ax, #0xe0f      ! ah = request, al = mask for nybble
278         and     al, dl
279         add     al, #0x90       ! convert al to ascii hex (four instructions)
280         daa
281         adc     al, #0x40
282         daa
283         int     0x10
284         loop    print_2digit
285         ret
286
287 print_sp:
288         mov     ax, #0xe20      ! SP
289         int     0x10
290         ret
291
292 print_nl:
293         mov     ax, #0xe0d      ! CR
294         int     0x10
295         mov     al, #0xa        ! LF
296         int     0x10
297         ret
298
299 davicom_base:
300         .word   0x0
301 bus:
302         .byte   0x0
303 devfn:
304         .byte   0x0
305
306 controldword:
307         .word 0
308         .word 0
309 vid:
310         .word 0
311 did:
312         .word 0
313 dad:    
314         .word 0
315
316 hello:    .ascii  "DAVICOM killer (c) 1999 James McKenzie <james@fishsoup.dhs.org>"
317                 db      0x00
318
319 top:    .ascii "Bs Sl Fn VID  DID  Window 0 base"
320         db 0x00
321 fixed:  .ascii "- FIXED"
322         db 0x00
323
324 done:   .ascii "Transfering control to linux secondary boot loader"
325         db 0x00
326
327 .text
328 endtext:
329 .data
330 enddata:
331 .bss
332 endbss:
333