Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / arch / i386 / stand / netboot / start_rom.S
blob7b76816aa83f23e912e965390ff0a7a6d34539c2
1 /*      $NetBSD: start_rom.S,v 1.1.4.3 2004/09/21 13:17:18 skrll Exp $  */
2         
3 /*
4  * ROM startup
5  * mostly from freebsd:sys/arch/i396/boot/netboot/start2.S
6  */
8 #include <machine/asm.h>
9 #define addr32  .byte 0x67
11 reloc = RELOC
13 #ifndef BOOTSTACK
14 #define BOOTSTACK 0xfffc
15 #endif
16 bootstack = BOOTSTACK
18         .text
19         .code16
20 textstart:
22 /* At entry, the processor is in 16 bit real mode and the code is being
23  * executed from an address it was not linked to. Code must be pic and
24  * 32 bit sensitive until things are fixed up.
25  */
26         .word   0xaa55                  /* bios extension signature */
27         .byte   0                       /* no. of 512B blocks - set by genprom */
28         jmp     1f                      /* enter from bios here */
29         .byte   0                       /* checksum */
30 #ifdef PCIROM
31         . = 0x18                        /* required offset of pointer */
32         .word   (pcidata - textstart)
33 pcidata:
34         .ascii  "PCIR"
35         .word   PCI_VID
36         .word   PCI_DID
37         .word   0                       /* pointer to vital product data */
38         .word   (pcidataend - pcidata)
39         .long   (0 + (PCI_CLASS << 8))  /* class, revision */
40         .word   0                       /* no. of 512B blocks - set by genprom */
41         .word   0                       /* revision */
42         .byte   0                       /* code type */
43         .byte   0x80                    /* "indicator" - last image */
44         .word   0                       /* reserved */
45 pcidataend:
46 #endif
48         pushl   %eax
49         push    %ds
50         xor     %ax,%ax
51         mov     %ax, %ds
53         /* check signature */
54         mov     0x304, %ax
55         cmp     $0x4d52, %ax            /* $0x4d52  == 'MR' */
56         jz      2f      /* we have been here - don't clobber saved vector */
58         /* save old INT19 vector to a secret location (???) */
59         movw    0x64, %ax
60         movw    %ax, 0x300
61         movw    0x66, %ax
62         movw    %ax, 0x302
64         /* set INT19 vector to our entry */
65         movl    $(_C_LABEL(start)-reloc), %eax
66         movw    %ax, 0x64
67         mov     %cs, %ax
68         movw    %ax, 0x66
70         /* set a signature (is this a safe location?) */
71         movw    $0x4d52, %ax            /* 0x4d52 == 'MR' */
72         movw    %ax, 0x304
74 2:      pop     %ds
75         popl    %eax
77 #ifdef ROMDEBUG
78         push    %ds
79         pushl   %eax
80         mov     %cs, %ax
81         mov     %ax, %ds
82         pop     %ax
83         pushl   %esi
84         movw    $(imesg-textstart), %si
85         call    message
86         popl    %esi
87         pop     %ds
88 #endif
90         lret
92 #ifdef ROMDEBUG
94 imesg:  .asciz "bsd rom installed\r\n"
95 cmesg:  .asciz "bsd rom called\r\n"
96 rmesg:  .asciz "bsd rom relocated\r\n"
97 emesg:  .asciz "bsd rom done\r\n"
100  * message: write the message in %ds:%esi to console
101  */
102 message:
103         pushl   %eax
104         pushl   %ebx
105         pushl   %edx
107 nextb:
108         cld
109         lodsb                   /* load a byte into %al */
110         testb   %al, %al
111         jz      done
113         movb    $0x0e, %ah
114         movw    $0x0001, %bx
115         int     $0x10
117         jmp     nextb
118 done:
120         movb    $0x00, %ah      /* wait for keypress */
121         int     $0x16
123         popl    %edx
124         popl    %ebx
125         popl    %eax
126         ret
128 #endif /* ROMDEBUG */
130 /**************************************************************************
131 START - Where all the fun begins....
132 **************************************************************************/
134 ENTRY(start)
135         .code16
136         cli
137         mov     %cs, %ax
138         mov     %ax, %ds
140 #ifdef ROMDEBUG
141         movw    $(cmesg-textstart), %si
142         call    message
143 #endif
145         cld
147         /* copy to reloc and jump to copy */
148         xor     %si, %si
149         xor     %di, %di
150         movw    $(reloc>>4), %ax
151         mov     %ax, %es
152         movl    $(_C_LABEL(edata)-reloc), %ecx
153         cs
154         rep
155         movsb
156         ljmpl   $(reloc>>4), $1f-reloc          /* Jmp to RELOC:1f */
158         nop
159         mov     %cs, %ax
160         mov     %ax, %ds
161         mov     %ax, %es
162         mov     %ax, %ss
163         movw    $bootstack, %ax
164         mov     %ax, %sp
166         /* clear bss */
167         xor     %ax, %ax
168         movl    $_C_LABEL(edata), %edi
169         movl    $_C_LABEL(end), %ecx
170         subw    %di, %cx
171         cld
172         rep
173         stosb
175 #ifdef ROMDEBUG
176         mov     $(rmesg-textstart), %si
177         call    message
178 #endif
180         calll   _C_LABEL(real_to_prot)
181         .code32
182         call    _C_LABEL(main)
184         .globl  _C_LABEL(exit)
185 _C_LABEL(exit):
186         call    _C_LABEL(prot_to_real)
187         .code16
189 #ifdef ROMDEBUG
190         mov     $(emesg-textstart), %si
191         call    message
192 #endif
194         /* jump to saved vector */
195         xor     %ax, %ax
196         mov     %ax, %ds
197         movw    0x302, %ax
198         push    %ax
199         movw    0x300, %ax
200         push    %ax
201         lret
203 /**************************************************************************
204 GLOBAL DESCRIPTOR TABLE
205 **************************************************************************/
206 #ifdef __ELF__
207         .align  16
208 #else
209         .align  4
210 #endif
211 gdt:
212         .word   0, 0
213         .byte   0, 0x00, 0x00, 0
215 #ifdef SUPPORT_LINUX    /* additional dummy */
216         .word   0, 0
217         .byte   0, 0x00, 0x00, 0
218 #endif
220         /* code segment */
221         .globl flatcodeseg
222 flatcodeseg = . - gdt
223 bootcodeseg = . - gdt
224         .word   0xffff, 0
225         .byte   0, 0x9f, 0xcf, 0
227         /* data segment */
228         .globl flatdataseg
229 flatdataseg = . - gdt
230 bootdataseg = . - gdt
231         .word   0xffff, 0
232         .byte   0, 0x93, 0xcf, 0
234         /* 16 bit real mode */
235 bootrealseg = . - gdt
236         .word   0xffff, 0
237         .byte   0, 0x9f, 0x0f, 0
239         /* limits (etc) for data segment in real mode */
240 bootrealdata = . - gdt
241         .word   0xffff, 0
242         .byte   0, 0x92, 0x00, 0
243 gdtlen = . - gdt
245 #ifdef __ELF__
246         .align  16
247 #else
248         .align  4
249 #endif
250 gdtarg:
251         .word   gdtlen-1                /* limit */
252         .long   gdt                     /* addr */
254 CR0_PE          =       0x1
256 /**************************************************************************
257 REAL_TO_PROT - Go from REAL mode to Protected Mode
258 **************************************************************************/
259 ENTRY(real_to_prot)
260         .code16
261         cli
262         pushl   %eax
264         .code32
265         addr32                          /* don't know the syntax for this! */
266         lgdt    %cs:gdtarg-reloc
267         .code16
269         movl    %cr0, %eax
270         orl     $CR0_PE, %eax
271         mov     %eax, %cr0              /* turn on protected mode */
273         /* jump to relocation, flush prefetch queue, and reload %cs */
274         ljmpl   $bootcodeseg, $1f
276         .code32
277         /* reload other segment registers */
278         movl    $bootdataseg, %eax
279         mov     %ax, %ds
280         mov     %ax, %es
281         mov     %ax, %ss
282         add     $reloc, %esp            /* Fix up stack pointer */
283         movl    4(%esp), %eax           /* Fix up return Address */
284         add     $reloc, %eax
285         movl    %eax, 4(%esp)
286         popl    %eax
287         ret
290 /**************************************************************************
291 PROT_TO_REAL - Go from Protected Mode to REAL Mode
292 **************************************************************************/
293 ENTRY(prot_to_real)
294         .code32
295         pushl   %eax
296         movl    4(%esp), %eax           /* Fix up return Address */
297         sub     $reloc, %eax
298         movl    %eax, 4(%esp)
299         sub     $reloc, %esp            /* Adjust stack pointer */
301         /*
302          * Load the segment registers while still in protected mode.
303          * Otherwise the control bits don't get changed.
304          * The correct values are loaded later.
305          */
306         movw    $bootrealdata, %ax
307         movw    %ax, %ds
308         movw    %ax, %es
309         movw    %ax, %ss
311         ljmp    $bootrealseg, $1f       /* jump to a 16 bit segment */
313         .code16
314         /* clear the PE bit of CR0 */
315         mov     %cr0, %eax
316         andl    $~CR0_PE, %eax
317         mov     %eax, %cr0
319         /* make intersegment jmp to flush the processor pipeline
320          * and reload CS register
321          */
322         ljmpl   $(reloc)>>4, $2f-reloc
324         /* we are in real mode now
325          * set up the real mode segment registers : DS, SS, ES
326          */
327         mov     %cs, %ax
328         mov     %ax, %ds
329         mov     %ax, %es
330         mov     %ax, %ss
331         sti
332         popl    %eax
333         retl
335 ENTRY(pbzero)
336         .code32
337         jmp     _C_LABEL(bzero)
339 ENTRY(vpbcopy)
340 ENTRY(pvbcopy)
341         .code32
342         jmp     _C_LABEL(bcopy)
344 ENTRY(vtophys)
345         .code32
346         movl    4(%esp), %eax
347         ret