|
@@ -8,6 +8,7 @@
|
8
|
8
|
|
9
|
9
|
#define PNP_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'n' << 16 ) + ( 'P' << 24 ) )
|
10
|
10
|
#define PMM_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'M' << 16 ) + ( 'M' << 24 ) )
|
|
11
|
+#define PCI_SIGNATURE ( 'P' + ( 'C' << 8 ) + ( 'I' << 16 ) + ( ' ' << 24 ) )
|
11
|
12
|
#define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) )
|
12
|
13
|
#define PNP_GET_BBS_VERSION 0x60
|
13
|
14
|
|
|
@@ -40,25 +41,31 @@ checksum:
|
40
|
41
|
|
41
|
42
|
pciheader:
|
42
|
43
|
.ascii "PCIR" /* Signature */
|
43
|
|
- .word pci_vendor_id /* Vendor ID */
|
44
|
|
- .word pci_device_id /* Device ID */
|
45
|
|
- .word 0x0000 /* pointer to vital product data */
|
|
44
|
+ .word pci_vendor_id /* Vendor identification */
|
|
45
|
+ .word pci_device_id /* Device identification */
|
|
46
|
+ .word 0x0000 /* Device list pointer */
|
46
|
47
|
.word pciheader_len /* PCI data structure length */
|
47
|
|
- .byte 0x00 /* PCI data structure revision */
|
48
|
|
- .byte 0x02 /* Device Base Type code */
|
49
|
|
- .byte 0x00 /* Device Sub-Type code */
|
50
|
|
- .byte 0x00 /* Device Interface Type code */
|
51
|
|
-pciheader_size: .word _load_size_sect /* Image length same as offset 02h */
|
52
|
|
- .word 0x0001 /* revision level of code/data */
|
53
|
|
- .byte 0x00 /* code type */
|
54
|
|
- .byte 0x80 /* Flags (last PCI data structure) */
|
55
|
|
- .word 0x0000 /* reserved */
|
|
48
|
+ .byte 0x03 /* PCI data structure revision */
|
|
49
|
+ .byte 0x02, 0x00, 0x00 /* Class code */
|
|
50
|
+pciheader_image_length:
|
|
51
|
+ .word _load_size_sect /* Image length */
|
|
52
|
+ .word 0x0001 /* Revision level */
|
|
53
|
+ .byte 0x00 /* Code type */
|
|
54
|
+ .byte 0x80 /* Last image indicator */
|
|
55
|
+pciheader_runtime_length:
|
|
56
|
+ .word _load_size_sect /* Maximum run-time image length */
|
|
57
|
+ .word 0x0000 /* Configuration utility code header */
|
|
58
|
+ .word 0x0000 /* DMTF CLP entry point */
|
56
|
59
|
.equ pciheader_len, . - pciheader
|
57
|
60
|
.size pciheader, . - pciheader
|
58
|
61
|
|
59
|
62
|
.section ".zinfo.fixup", "a" /* Compressor fixup information */
|
60
|
63
|
.ascii "SUBW"
|
61
|
|
- .long pciheader_size
|
|
64
|
+ .long pciheader_image_length
|
|
65
|
+ .long 512
|
|
66
|
+ .long 0
|
|
67
|
+ .ascii "SUBW"
|
|
68
|
+ .long pciheader_runtime_length
|
62
|
69
|
.long 512
|
63
|
70
|
.long 0
|
64
|
71
|
.previous
|
|
@@ -131,22 +138,36 @@ init:
|
131
|
138
|
pushw %ds
|
132
|
139
|
pushw %es
|
133
|
140
|
pushw %fs
|
|
141
|
+ pushw %gs
|
134
|
142
|
cld
|
135
|
143
|
pushw %cs
|
136
|
144
|
popw %ds
|
137
|
145
|
pushw $0x40
|
138
|
146
|
popw %fs
|
|
147
|
+ /* Shuffle some registers around. We need %di available for
|
|
148
|
+ * the print_xxx functions, and in a register that's
|
|
149
|
+ * addressable from %es, so shuffle as follows:
|
|
150
|
+ *
|
|
151
|
+ * %di (pointer to PnP structure) => %bx
|
|
152
|
+ * %bx (runtime segment address, for PCI 3.0) => %gs
|
|
153
|
+ */
|
|
154
|
+ movw %bx, %gs
|
139
|
155
|
movw %di, %bx
|
140
|
|
- xorw %di, %di
|
141
|
156
|
/* Print message as early as possible */
|
142
|
157
|
movw $init_message, %si
|
|
158
|
+ xorw %di, %di
|
143
|
159
|
call print_message
|
144
|
160
|
call print_pci_busdevfn
|
145
|
161
|
/* Fill in product name string, if possible */
|
146
|
162
|
movw $prodstr_pci_id, %di
|
147
|
163
|
call print_pci_busdevfn
|
148
|
164
|
movb $' ', prodstr_separator
|
|
165
|
+ /* Print segment address */
|
|
166
|
+ movb $' ', %al
|
149
|
167
|
xorw %di, %di
|
|
168
|
+ call print_character
|
|
169
|
+ movw %cs, %ax
|
|
170
|
+ call print_hex_word
|
150
|
171
|
/* Check for PnP BIOS */
|
151
|
172
|
testw $0x0f, %bx /* PnP signature must be aligned - bochs */
|
152
|
173
|
jnz hook_int19 /* uses unalignment to indicate 'fake' PnP. */
|
|
@@ -154,6 +175,7 @@ init:
|
154
|
175
|
jne hook_int19
|
155
|
176
|
/* Is PnP: print PnP message */
|
156
|
177
|
movw $init_message_pnp, %si
|
|
178
|
+ xorw %di, %di
|
157
|
179
|
call print_message
|
158
|
180
|
/* Check for BBS */
|
159
|
181
|
pushw %es:0x1b(%bx) /* Real-mode data segment */
|
|
@@ -165,11 +187,13 @@ init:
|
165
|
187
|
testw %ax, %ax
|
166
|
188
|
jne hook_int19
|
167
|
189
|
movw $init_message_bbs, %si
|
|
190
|
+ xorw %di, %di
|
168
|
191
|
call print_message
|
169
|
192
|
jmp hook_bbs
|
170
|
193
|
/* Not BBS-compliant - must hook INT 19 */
|
171
|
194
|
hook_int19:
|
172
|
195
|
movw $init_message_int19, %si
|
|
196
|
+ xorw %di, %di
|
173
|
197
|
call print_message
|
174
|
198
|
xorw %ax, %ax
|
175
|
199
|
movw %ax, %es
|
|
@@ -196,6 +220,7 @@ pmm_scan:
|
196
|
220
|
jnz pmm_scan
|
197
|
221
|
/* PMM found: print PMM message */
|
198
|
222
|
movw $init_message_pmm, %si
|
|
223
|
+ xorw %di, %di
|
199
|
224
|
call print_message
|
200
|
225
|
/* Try to allocate 2MB block via PMM */
|
201
|
226
|
pushw $0x0006 /* Aligned, extended memory */
|
|
@@ -206,8 +231,9 @@ pmm_scan:
|
206
|
231
|
addw $12, %sp
|
207
|
232
|
testw %dx, %dx /* %ax==0 even on success, since align=2MB */
|
208
|
233
|
jnz gotpmm
|
209
|
|
- movw $init_message_pmm_failed, %si
|
210
|
|
- call print_message
|
|
234
|
+ movb $'-', %al
|
|
235
|
+ xorw %di, %di
|
|
236
|
+ call print_character
|
211
|
237
|
jmp no_pmm
|
212
|
238
|
gotpmm: /* PMM allocation succeeded: copy ROM to PMM block */
|
213
|
239
|
pushal /* PMM presence implies 1kB stack */
|
|
@@ -232,8 +258,44 @@ gotpmm: /* PMM allocation succeeded: copy ROM to PMM block */
|
232
|
258
|
loop 1b
|
233
|
259
|
subb %bl, checksum
|
234
|
260
|
popal
|
235
|
|
-no_pmm: /* Prompt for POST-time shell */
|
|
261
|
+no_pmm:
|
|
262
|
+ /* Check for PCI BIOS */
|
|
263
|
+ pushl %edx
|
|
264
|
+ stc
|
|
265
|
+ movw $0xb101, %ax
|
|
266
|
+ int $0x1a
|
|
267
|
+ jc no_pci
|
|
268
|
+ cmpl $PCI_SIGNATURE, %edx
|
|
269
|
+ popl %edx
|
|
270
|
+ jne no_pci
|
|
271
|
+ testb %ah, %ah
|
|
272
|
+ jnz no_pci
|
|
273
|
+ movw $init_message_pci, %si
|
|
274
|
+ xorw %di, %di
|
|
275
|
+ call print_message
|
|
276
|
+ movb %bh, %al
|
|
277
|
+ call print_hex_nibble
|
|
278
|
+ movb $'.', %al
|
|
279
|
+ call print_character
|
|
280
|
+ movb %bl, %al
|
|
281
|
+ call print_hex_byte
|
|
282
|
+ cmpb $3, %bh
|
|
283
|
+ jb no_pci3
|
|
284
|
+ /* Copy self to option ROM space (required for PCI3.0) */
|
|
285
|
+ movb $' ', %al
|
|
286
|
+ xorw %di, %di
|
|
287
|
+ call print_character
|
|
288
|
+ movw %gs, %ax
|
|
289
|
+ call print_hex_word
|
|
290
|
+ movzbw romheader_size, %cx
|
|
291
|
+ shlw $9, %cx
|
|
292
|
+ movw %ax, %es
|
|
293
|
+ rep movsb
|
|
294
|
+no_pci3:
|
|
295
|
+no_pci:
|
|
296
|
+ /* Prompt for POST-time shell */
|
236
|
297
|
movw $init_message_prompt, %si
|
|
298
|
+ xorw %di, %di
|
237
|
299
|
call print_message
|
238
|
300
|
/* Empty the keyboard buffer before waiting for input */
|
239
|
301
|
empty_keyboard_buffer:
|
|
@@ -276,8 +338,10 @@ wait_for_key:
|
276
|
338
|
no_key_pressed:
|
277
|
339
|
/* Print blank lines to terminate messages */
|
278
|
340
|
movw $init_message_end, %si
|
|
341
|
+ xorw %di, %di
|
279
|
342
|
call print_message
|
280
|
343
|
/* Restore registers */
|
|
344
|
+ popw %gs
|
281
|
345
|
popw %fs
|
282
|
346
|
popw %es
|
283
|
347
|
popw %ds
|
|
@@ -290,6 +354,9 @@ no_key_pressed:
|
290
|
354
|
init_message:
|
291
|
355
|
.asciz "gPXE (http://etherboot.org) - PCI "
|
292
|
356
|
.size init_message, . - init_message
|
|
357
|
+init_message_pci:
|
|
358
|
+ .asciz " PCI"
|
|
359
|
+ .size init_message_pci, . - init_message_pci
|
293
|
360
|
init_message_pnp:
|
294
|
361
|
.asciz " PnP"
|
295
|
362
|
.size init_message_pnp, . - init_message_pnp
|
|
@@ -299,9 +366,6 @@ init_message_bbs:
|
299
|
366
|
init_message_pmm:
|
300
|
367
|
.asciz " PMM"
|
301
|
368
|
.size init_message_pmm, . - init_message_pmm
|
302
|
|
-init_message_pmm_failed:
|
303
|
|
- .asciz "(failed)"
|
304
|
|
- .size init_message_pmm_failed, . - init_message_pmm_failed
|
305
|
369
|
init_message_int19:
|
306
|
370
|
.asciz " INT19"
|
307
|
371
|
.size init_message_int19, . - init_message_int19
|