3e6cd2d02a3f246db785ed88848f00be78d8a555
[people/holger/gpxe.git] / src / arch / i386 / prefix / romprefix.S
1 /* At entry, the processor is in 16 bit real mode and the code is being
2  * executed from an address it was not linked to. Code must be pic and
3  * 32 bit sensitive until things are fixed up.
4  *
5  * Also be very careful as the stack is at the rear end of the interrupt
6  * table so using a noticeable amount of stack space is a no-no.
7  */
8
9         .text
10         .code16
11         .arch i386
12         .section ".prefix", "ax", @progbits
13         
14         .org    0x00
15 romheader:
16         .word   0xAA55                  /* BIOS extension signature */
17 romheader_size: .byte   _rom_size       /* Size in 512-byte blocks */
18         jmp     init_vector             /* Initialisation vector */
19         .org    0x16
20         .word   undiheader
21         .org    0x18
22         .word   pciheader
23         .org    0x1a
24         .word   pnpheader
25         .size romheader, . - romheader
26
27 pciheader:
28         .ascii  "PCIR"                  /* Signature */
29         .word   pci_vendor_id           /* Vendor ID */ 
30         .word   pci_device_id           /* Device ID */
31         .word   0x0000                  /* pointer to vital product data */
32         .word   pciheader_len           /* PCI data structure length */
33         .byte   0x00                    /* PCI data structure revision */
34         .byte   0x02                    /* Device Base Type code */
35         .byte   0x00                    /* Device Sub-Type code */
36         .byte   0x00                    /* Device Interface Type code */
37 pciheader_size: .word   _rom_size       /* Image length same as offset 02h */
38         .word   0x0001                  /* revision level of code/data */
39         .byte   0x00                    /* code type */
40         .byte   0x80                    /* Flags (last PCI data structure) */
41         .word   0x0000                  /* reserved */
42         .equ pciheader_len, . - pciheader
43         .size pciheader, . - pciheader
44
45 pnpheader:
46         .ascii  "$PnP"                  /* Signature */
47         .byte   0x01                    /* Structure revision */
48         .byte   ( pnpheader_len / 16 )  /* Length (in 16 byte increments) */
49         .word   0x0000                  /* Offset of next header */
50         .byte   0x00                    /* Reserved */
51         .byte   0x00                    /* Checksum */
52         .long   0x00000000              /* Device identifier */
53         .word   mfgstr                  /* Manufacturer string */
54         .word   prodstr                 /* Product name */
55         .byte   0x02                    /* Device base type code */
56         .byte   0x00                    /* Device sub-type code */
57         .byte   0x00                    /* Device interface type code */
58         .byte   0x54                    /* Device indicator */
59         .word   0x0000                  /* Boot connection vector */
60         .word   0x0000                  /* Disconnect vector */
61         .word   exec_vector             /* Boot execution vector */
62         .word   0x0000                  /* Reserved */
63         .word   0x0000                  /* Static resource information vector*/
64         .equ pnpheader_len, . - pnpheader
65         .size pnpheader, . - pnpheader
66
67 mfgstr:
68         .asciz  "http://etherboot.org"
69         .size mfgstr, . - mfgstr
70 prodstr:
71         .asciz  "Etherboot"
72         .size prodstr, . - prodstr
73         
74 undiheader:
75         .ascii  "UNDI"                  /* Signature */
76         .byte   undiheader_len          /* Length of structure */
77         .byte   0                       /* Checksum */
78         .byte   0                       /* Structure revision */
79         .byte   0,1,2                   /* PXE version: 2.1.0 */
80         .word   undiloader              /* Offset to loader routine */
81         .word   _data16_size            /* Stack segment size */
82         .word   _data16_size            /* Data segment size */
83         .word   _text16_size            /* Code segment size */
84         .equ undiheader_len, . - undiheader
85         .size undiheader, . - undiheader
86
87 /* Initialisation vector
88  *
89  * Determine whether or not this is a PnP system via a signature
90  * check.  If it is PnP, return to the PnP BIOS indicating that we are
91  * a boot-capable device; the BIOS will call our boot execution vector
92  * if it wants to boot us.  If it is not PnP, hook INT 19.
93  */
94 init_vector:
95         pushw   %si
96         cmpw    $'$'+'P'*256, %es:0(%di)
97         jne     notpnp
98         cmpw    $'n'+'P'*256, %es:2(%di)
99         jne     notpnp
100 ispnp:
101         movw    $ispnp_message, %si
102         jmp     99f
103 notpnp:
104         pushw   %ds
105         pushw   $0
106         popw    %ds
107         pushw   %cs
108         pushw   $exec_vector
109         popl    ( 0x19 * 4 )
110         popw    %ds
111         movw    $notpnp_message, %si
112 99:
113         call    print_message
114         movw    $0x20, %ax
115         popw    %si
116         lret
117         .size init_vector, . - init_vector
118
119 ispnp_message:
120         .asciz  "Etherboot detected PnP BIOS\r\n"
121         .size ispnp_message, . - ispnp_message
122 notpnp_message:
123         .asciz  "Etherboot detected non-PnP BIOS\r\n"
124         .size notpnp_message, . - notpnp_message
125
126 /* Boot execution vector
127  *
128  * Called by the PnP BIOS when it wants to boot us, or via the hooked
129  * INT 19 if we detected a non-PnP BIOS.
130  */     
131 exec_vector:
132         /* Obtain a reasonably-sized stack */
133         xorw    %ax, %ax
134         movw    %ax, %ss
135         movw    $0x7c00, %sp
136         
137         movw    $exec_message, %si
138         call    print_message
139
140         call    install
141
142         /* Set up real-mode stack */
143         movw    %bx, %ss
144         movw    $_estack16, %sp
145
146         /* Jump to .text16 segment */
147         pushw   %ax
148         pushw   $1f
149         lret
150         .section ".text16", "awx", @progbits
151 1:
152         pushl   $main
153         pushw   %cs
154         call    prot_call
155         popl    %eax /* discard */
156
157         /* Boot next device */
158         int     $0x18
159         .previous
160
161 exec_message:
162         .asciz  "Etherboot starting boot\r\n"
163         .size exec_message, . - exec_message
164
165 /* UNDI loader
166  *
167  * Called by an external program to load our PXE stack.
168  */
169 undiloader:
170         /* Save registers */
171         pushl   %edi
172         pushw   %es
173         pushw   %bx
174         /* UNDI loader parameter structure address into %es:%di */
175         movw    %sp, %bx
176         movw    %ss:12(%bx), %di
177         movw    %ss:14(%bx), %es
178         /* Install to specified real-mode addresses */
179         pushw   %di
180         movw    %es:12(%di), %bx
181         movw    %es:14(%di), %ax
182         call    install_prealloc
183         popw    %di
184         /* Call UNDI loader C code */
185         pushl   $pxe_loader_call
186         pushw   %cs
187         pushw   $1f
188         pushw   %ax
189         pushw   $prot_call
190         lret
191 1:      popw    %bx     /* discard */
192         popw    %bx     /* discard */
193         /* Restore registers and return */
194         popw    %bx
195         popw    %es
196         popl    %edi
197         lret
198         .size undiloader, . - undiloader
199                                 
200 /* Utility function: print string
201  */
202 print_message:
203         pushw   %ax
204         pushw   %bx
205         pushw   %bp
206         movw    $0x0007, %bx
207 1:      cs lodsb
208         testb   %al, %al
209         je      2f
210         movb    $0x0e, %ah              /* write char, tty mode */
211         int     $0x10
212         jmp     1b
213 2:      popw    %bp
214         popw    %bx
215         popw    %ax
216         ret
217         .size print_message, . - print_message
218
219
220         /* Data update information for the compressor */
221         .section ".zinfo.fixup", "a"
222         .ascii  "SUBB"
223         .long   romheader_size
224         .long   512
225         .long   0
226         .ascii  "SUBW"
227         .long   pciheader_size
228         .long   512
229         .long   0