|
@@ -175,13 +175,14 @@ print_hex_nibble:
|
175
|
175
|
#ifndef KEEP_IT_REAL
|
176
|
176
|
|
177
|
177
|
/* GDT for protected-mode calls */
|
178
|
|
- .section ".data16"
|
|
178
|
+ .section ".prefix.lib"
|
179
|
179
|
.align 16
|
|
180
|
+pm_call_vars:
|
180
|
181
|
gdt:
|
181
|
182
|
gdt_limit: .word gdt_length - 1
|
182
|
183
|
gdt_base: .long 0
|
183
|
184
|
.word 0 /* padding */
|
184
|
|
-pm_cs: /* 16-bit protected-mode code segment */
|
|
185
|
+pm_cs: /* 16-bit protected-mode code segment */
|
185
|
186
|
.equ PM_CS, pm_cs - gdt
|
186
|
187
|
.word 0xffff, 0
|
187
|
188
|
.byte 0, 0x9b, 0x00, 0
|
|
@@ -197,18 +198,24 @@ gdt_end:
|
197
|
198
|
.equ gdt_length, . - gdt
|
198
|
199
|
.size gdt, . - gdt
|
199
|
200
|
|
200
|
|
- .section ".data16"
|
|
201
|
+ .section ".prefix.lib"
|
201
|
202
|
.align 16
|
202
|
203
|
pm_saved_gdt:
|
203
|
204
|
.long 0, 0
|
204
|
205
|
.size pm_saved_gdt, . - pm_saved_gdt
|
205
|
206
|
|
|
207
|
+ .equ pm_call_vars_size, . - pm_call_vars
|
|
208
|
+#define PM_CALL_VAR(x) ( -pm_call_vars_size + ( (x) - pm_call_vars ) )
|
|
209
|
+
|
206
|
210
|
.section ".prefix.lib"
|
207
|
211
|
.code16
|
208
|
212
|
pm_call:
|
209
|
|
- /* Preserve registers, flags, GDT, and RM return point */
|
|
213
|
+ /* Preserve registers, flags, and RM return point */
|
|
214
|
+ pushw %bp
|
|
215
|
+ movw %sp, %bp
|
|
216
|
+ subw $pm_call_vars_size, %sp
|
|
217
|
+ andw $0xfff0, %sp
|
210
|
218
|
pushfl
|
211
|
|
- sgdt pm_saved_gdt
|
212
|
219
|
pushw %gs
|
213
|
220
|
pushw %fs
|
214
|
221
|
pushw %es
|
|
@@ -217,27 +224,43 @@ pm_call:
|
217
|
224
|
pushw %cs
|
218
|
225
|
pushw $99f
|
219
|
226
|
|
|
227
|
+ /* Set up local variable block, and preserve GDT */
|
|
228
|
+ pushw %cx
|
|
229
|
+ pushw %si
|
|
230
|
+ pushw %di
|
|
231
|
+ pushw %ss
|
|
232
|
+ popw %es
|
|
233
|
+ movw $pm_call_vars, %si
|
|
234
|
+ leaw PM_CALL_VAR(pm_call_vars)(%bp), %di
|
|
235
|
+ movw $pm_call_vars_size, %cx
|
|
236
|
+ cs rep movsb
|
|
237
|
+ popw %di
|
|
238
|
+ popw %si
|
|
239
|
+ popw %cx
|
|
240
|
+ sgdt PM_CALL_VAR(pm_saved_gdt)(%bp)
|
|
241
|
+
|
220
|
242
|
/* Set up GDT bases */
|
221
|
243
|
pushl %eax
|
222
|
|
- pushw %bx
|
|
244
|
+ pushl %edi
|
223
|
245
|
xorl %eax, %eax
|
224
|
|
- movw %ds, %ax
|
|
246
|
+ movw %ss, %ax
|
225
|
247
|
shll $4, %eax
|
226
|
|
- addl $gdt, %eax
|
227
|
|
- movl %eax, gdt_base
|
|
248
|
+ movzwl %bp, %edi
|
|
249
|
+ leal PM_CALL_VAR(gdt)(%eax, %edi), %eax
|
|
250
|
+ movl %eax, PM_CALL_VAR(gdt_base)(%bp)
|
228
|
251
|
movw %cs, %ax
|
229
|
|
- movw $pm_cs, %bx
|
|
252
|
+ movw $PM_CALL_VAR(pm_cs), %di
|
230
|
253
|
call set_seg_base
|
231
|
254
|
movw %ss, %ax
|
232
|
|
- movw $pm_ss, %bx
|
|
255
|
+ movw $PM_CALL_VAR(pm_ss), %di
|
233
|
256
|
call set_seg_base
|
234
|
|
- popw %bx
|
|
257
|
+ popl %edi
|
235
|
258
|
popl %eax
|
236
|
259
|
|
237
|
260
|
/* Switch CPU to protected mode and load up segment registers */
|
238
|
261
|
pushl %eax
|
239
|
262
|
cli
|
240
|
|
- lgdt gdt
|
|
263
|
+ lgdt PM_CALL_VAR(gdt)(%bp)
|
241
|
264
|
movl %cr0, %eax
|
242
|
265
|
orb $CR0_PE, %al
|
243
|
266
|
movl %eax, %cr0
|
|
@@ -273,18 +296,19 @@ pm_call:
|
273
|
296
|
popw %es
|
274
|
297
|
popw %fs
|
275
|
298
|
popw %gs
|
276
|
|
- lgdt pm_saved_gdt
|
|
299
|
+ lgdt PM_CALL_VAR(pm_saved_gdt)(%bp)
|
277
|
300
|
popfl
|
278
|
|
-
|
|
301
|
+ movw %bp, %sp
|
|
302
|
+ popw %bp
|
279
|
303
|
ret
|
280
|
304
|
.size pm_call, . - pm_call
|
281
|
305
|
|
282
|
306
|
set_seg_base:
|
283
|
307
|
rolw $4, %ax
|
284
|
|
- movw %ax, 2(%bx)
|
285
|
|
- andw $0xfff0, 2(%bx)
|
286
|
|
- movb %al, 4(%bx)
|
287
|
|
- andb $0x0f, 4(%bx)
|
|
308
|
+ movw %ax, 2(%bp,%di)
|
|
309
|
+ andw $0xfff0, 2(%bp,%di)
|
|
310
|
+ movb %al, 4(%bp,%di)
|
|
311
|
+ andb $0x0f, 4(%bp,%di)
|
288
|
312
|
ret
|
289
|
313
|
.size set_seg_base, . - set_seg_base
|
290
|
314
|
|
|
@@ -301,7 +325,7 @@ set_seg_base:
|
301
|
325
|
* %ecx : length
|
302
|
326
|
* Returns:
|
303
|
327
|
* %ds:esi : next source address
|
304
|
|
- * %ds:esi : next destination address
|
|
328
|
+ * %es:edi : next destination address
|
305
|
329
|
* Corrupts:
|
306
|
330
|
* None
|
307
|
331
|
****************************************************************************
|
|
@@ -316,27 +340,57 @@ copy_bytes:
|
316
|
340
|
.size copy_bytes, . - copy_bytes
|
317
|
341
|
|
318
|
342
|
/****************************************************************************
|
319
|
|
- * install_block (real-mode or 16-bit protected-mode near call)
|
|
343
|
+ * install_block (real-mode near call)
|
320
|
344
|
*
|
321
|
345
|
* Install block to specified address
|
322
|
346
|
*
|
323
|
347
|
* Parameters:
|
324
|
|
- * %ds:esi : source address (must be a multiple of 16)
|
325
|
|
- * %es:edi : destination address
|
|
348
|
+ * %esi : source physical address (must be a multiple of 16)
|
|
349
|
+ * %edi : destination physical address (must be a multiple of 16)
|
326
|
350
|
* %ecx : length of (decompressed) data
|
327
|
351
|
* %edx : total length of block (including any uninitialised data portion)
|
328
|
352
|
* Returns:
|
329
|
|
- * %ds:esi : next source address (will be a multiple of 16)
|
|
353
|
+ * %esi : next source physical address (will be a multiple of 16)
|
330
|
354
|
* Corrupts:
|
331
|
|
- * %ecx, %edx
|
|
355
|
+ * none
|
332
|
356
|
****************************************************************************
|
333
|
357
|
*/
|
334
|
358
|
.section ".prefix.lib"
|
335
|
359
|
.code16
|
336
|
360
|
install_block:
|
|
361
|
+
|
|
362
|
+#ifdef KEEP_IT_REAL
|
|
363
|
+
|
|
364
|
+ /* Preserve registers */
|
|
365
|
+ pushw %ds
|
|
366
|
+ pushw %es
|
|
367
|
+ pushl %ecx
|
|
368
|
+ pushl %edi
|
|
369
|
+
|
|
370
|
+ /* Convert %esi and %edi to segment registers */
|
|
371
|
+ shrl $4, %esi
|
|
372
|
+ movw %si, %ds
|
|
373
|
+ xorw %si, %si
|
|
374
|
+ shrl $4, %edi
|
|
375
|
+ movw %di, %es
|
|
376
|
+ xorw %di, %di
|
|
377
|
+
|
|
378
|
+#else /* KEEP_IT_REAL */
|
|
379
|
+
|
|
380
|
+ /* Call self in protected mode */
|
|
381
|
+ pushw %ax
|
|
382
|
+ movw $1f, %ax
|
|
383
|
+ call pm_call
|
|
384
|
+ popw %ax
|
|
385
|
+ ret
|
|
386
|
+1:
|
337
|
387
|
/* Preserve registers */
|
|
388
|
+ pushl %ecx
|
338
|
389
|
pushl %edi
|
339
|
390
|
|
|
391
|
+#endif /* KEEP_IT_REAL */
|
|
392
|
+
|
|
393
|
+
|
340
|
394
|
#if COMPRESS
|
341
|
395
|
/* Decompress source to destination */
|
342
|
396
|
call decompress16
|
|
@@ -357,8 +411,28 @@ install_block:
|
357
|
411
|
addl $0xf, %esi
|
358
|
412
|
andl $~0xf, %esi
|
359
|
413
|
|
360
|
|
- /* Restore registers and return */
|
|
414
|
+
|
|
415
|
+#ifdef KEEP_IT_REAL
|
|
416
|
+
|
|
417
|
+ /* Convert %ds:esi back to a physical address */
|
|
418
|
+ movzwl %ds, %cx
|
|
419
|
+ shll $4, %ecx
|
|
420
|
+ addl %ecx, %esi
|
|
421
|
+
|
|
422
|
+ /* Restore registers */
|
361
|
423
|
popl %edi
|
|
424
|
+ popl %ecx
|
|
425
|
+ popw %es
|
|
426
|
+ popw %ds
|
|
427
|
+
|
|
428
|
+#else /* KEEP_IT_REAL */
|
|
429
|
+
|
|
430
|
+ /* Restore registers */
|
|
431
|
+ popl %edi
|
|
432
|
+ popl %ecx
|
|
433
|
+
|
|
434
|
+#endif
|
|
435
|
+
|
362
|
436
|
ret
|
363
|
437
|
.size install_block, . - install_block
|
364
|
438
|
|
|
@@ -406,87 +480,6 @@ alloc_basemem:
|
406
|
480
|
ret
|
407
|
481
|
.size alloc_basemem, . - alloc_basemem
|
408
|
482
|
|
409
|
|
-/****************************************************************************
|
410
|
|
- * install_basemem (real-mode near call)
|
411
|
|
- *
|
412
|
|
- * Install source block into base memory
|
413
|
|
- *
|
414
|
|
- * Parameters:
|
415
|
|
- * %esi : source physical address (must be a multiple of 16)
|
416
|
|
- * %es : destination segment address
|
417
|
|
- * %cx : length of (decompressed) data
|
418
|
|
- * %dx : total length of block (including any uninitialised data portion)
|
419
|
|
- * Returns:
|
420
|
|
- * %esi : next source physical address (will be a multiple of 16)
|
421
|
|
- * Corrupts:
|
422
|
|
- * %ecx, %edx
|
423
|
|
- ****************************************************************************
|
424
|
|
- */
|
425
|
|
- .section ".prefix.lib"
|
426
|
|
- .code16
|
427
|
|
-install_basemem:
|
428
|
|
- /* Preserve registers */
|
429
|
|
- pushl %edi
|
430
|
|
- pushw %ds
|
431
|
|
-
|
432
|
|
- /* Preserve original %esi */
|
433
|
|
- pushl %esi
|
434
|
|
-
|
435
|
|
- /* Install to specified address */
|
436
|
|
- shrl $4, %esi
|
437
|
|
- movw %si, %ds
|
438
|
|
- xorw %si, %si
|
439
|
|
- xorl %edi, %edi
|
440
|
|
- movzwl %cx, %ecx
|
441
|
|
- movzwl %dx, %edx
|
442
|
|
- call install_block
|
443
|
|
-
|
444
|
|
- /* Fix up %esi for return */
|
445
|
|
- popl %ecx
|
446
|
|
- addl %ecx, %esi
|
447
|
|
-
|
448
|
|
- /* Restore registers */
|
449
|
|
- popw %ds
|
450
|
|
- popl %edi
|
451
|
|
- ret
|
452
|
|
- .size install_basemem, . - install_basemem
|
453
|
|
-
|
454
|
|
-/****************************************************************************
|
455
|
|
- * install_highmem (real-mode near call)
|
456
|
|
- *
|
457
|
|
- * Install source block into high memory
|
458
|
|
- *
|
459
|
|
- * Parameters:
|
460
|
|
- * %esi : source physical address (must be a multiple of 16)
|
461
|
|
- * %edi : destination physical address
|
462
|
|
- * %ecx : length of (decompressed) data
|
463
|
|
- * %edx : total length of block (including any uninitialised data portion)
|
464
|
|
- * Returns:
|
465
|
|
- * %esi : next source physical address (will be a multiple of 16)
|
466
|
|
- * Corrupts:
|
467
|
|
- * %ecx, %edx
|
468
|
|
- ****************************************************************************
|
469
|
|
- */
|
470
|
|
-
|
471
|
|
-#ifndef KEEP_IT_REAL
|
472
|
|
-
|
473
|
|
- .section ".prefix.lib"
|
474
|
|
- .code16
|
475
|
|
-install_highmem:
|
476
|
|
- /* Preserve registers */
|
477
|
|
- pushw %ax
|
478
|
|
-
|
479
|
|
- /* Install to specified address */
|
480
|
|
- movw $install_block, %ax
|
481
|
|
- call pm_call
|
482
|
|
-
|
483
|
|
- /* Restore registers */
|
484
|
|
- popw %ax
|
485
|
|
- ret
|
486
|
|
- .size install_highmem, . - install_highmem
|
487
|
|
-
|
488
|
|
-#endif /* KEEP_IT_REAL */
|
489
|
|
-
|
490
|
483
|
/****************************************************************************
|
491
|
484
|
* install (real-mode near call)
|
492
|
485
|
*
|
|
@@ -555,17 +548,19 @@ install_prealloc:
|
555
|
548
|
shll $4, %esi
|
556
|
549
|
1: addl $_payload_offset, %esi
|
557
|
550
|
|
558
|
|
- /* Install .text16 */
|
559
|
|
- movw %ax, %es
|
560
|
|
- movw $_text16_size, %cx
|
561
|
|
- movw %cx, %dx
|
562
|
|
- call install_basemem
|
563
|
|
-
|
564
|
|
- /* Install .data16 */
|
565
|
|
- movw %bx, %es
|
566
|
|
- movw $_data16_progbits_size, %cx
|
567
|
|
- movw $_data16_size, %dx
|
568
|
|
- call install_basemem
|
|
551
|
+ /* Install .text16 and .data16 */
|
|
552
|
+ pushl %edi
|
|
553
|
+ movzwl %ax, %edi
|
|
554
|
+ shll $4, %edi
|
|
555
|
+ movl $_text16_size, %ecx
|
|
556
|
+ movl %ecx, %edx
|
|
557
|
+ call install_block /* .text16 */
|
|
558
|
+ movzwl %bx, %edi
|
|
559
|
+ shll $4, %edi
|
|
560
|
+ movl $_data16_progbits_size, %ecx
|
|
561
|
+ movl $_data16_size, %edx
|
|
562
|
+ call install_block /* .data16 */
|
|
563
|
+ popl %edi
|
569
|
564
|
|
570
|
565
|
/* Set up %ds for access to .data16 */
|
571
|
566
|
movw %bx, %ds
|
|
@@ -581,9 +576,7 @@ install_prealloc:
|
581
|
576
|
*/
|
582
|
577
|
movl $_textdata_progbits_size, %ecx
|
583
|
578
|
movl $_textdata_size, %edx
|
584
|
|
- pushl %edi
|
585
|
|
- call install_highmem
|
586
|
|
- popl %edi
|
|
579
|
+ call install_block
|
587
|
580
|
|
588
|
581
|
/* Initialise librm at current location */
|
589
|
582
|
movw %ax, (init_librm_vector+2)
|