summaryrefslogtreecommitdiff
path: root/gpxe/src/arch/i386/prefix/libprefix.S
diff options
context:
space:
mode:
Diffstat (limited to 'gpxe/src/arch/i386/prefix/libprefix.S')
-rw-r--r--gpxe/src/arch/i386/prefix/libprefix.S168
1 files changed, 141 insertions, 27 deletions
diff --git a/gpxe/src/arch/i386/prefix/libprefix.S b/gpxe/src/arch/i386/prefix/libprefix.S
index ae2a491f..56ca64d9 100644
--- a/gpxe/src/arch/i386/prefix/libprefix.S
+++ b/gpxe/src/arch/i386/prefix/libprefix.S
@@ -199,6 +199,39 @@ print_pci_busdevfn:
ret
.size print_pci_busdevfn, . - print_pci_busdevfn
+/*****************************************************************************
+ * Utility function: clear current line
+ *
+ * Parameters:
+ * %ds:di : output buffer (or %di=0 to print to console)
+ * Returns:
+ * %ds:di : next character in output buffer (if applicable)
+ *****************************************************************************
+ */
+ .section ".prefix.lib"
+ .code16
+ .globl print_kill_line
+print_kill_line:
+ /* Preserve registers */
+ pushw %ax
+ pushw %cx
+ /* Print CR */
+ movb $'\r', %al
+ call print_character
+ /* Print 79 spaces */
+ movb $' ', %al
+ movw $79, %cx
+1: call print_character
+ loop 1b
+ /* Print CR */
+ movb $'\r', %al
+ call print_character
+ /* Restore registers and return */
+ popw %cx
+ popw %ax
+ ret
+ .size print_kill_line, . - print_kill_line
+
/****************************************************************************
* pm_call (real-mode near call)
*
@@ -308,7 +341,7 @@ pm_call:
/* Switch CPU to protected mode and load up segment registers */
pushl %eax
cli
- lgdt PM_CALL_VAR(gdt)(%bp)
+ data32 lgdt PM_CALL_VAR(gdt)(%bp)
movl %cr0, %eax
orb $CR0_PE, %al
movl %eax, %cr0
@@ -344,7 +377,7 @@ pm_call:
popw %es
popw %fs
popw %gs
- lgdt PM_CALL_VAR(pm_saved_gdt)(%bp)
+ data32 lgdt PM_CALL_VAR(pm_saved_gdt)(%bp)
popfl
movw %bp, %sp
popw %bp
@@ -504,31 +537,89 @@ install_block:
.code16
.globl alloc_basemem
alloc_basemem:
+ /* Preserve registers */
+ pushw %fs
+
/* FBMS => %ax as segment address */
- movw $0x40, %ax
- movw %ax, %fs
+ pushw $0x40
+ popw %fs
movw %fs:0x13, %ax
shlw $6, %ax
- /* .data16 segment address */
- subw $_data16_size_pgh, %ax
+ /* Calculate .data16 segment address */
+ subw $_data16_memsz_pgh, %ax
pushw %ax
- /* .text16 segment address */
- subw $_text16_size_pgh, %ax
+ /* Calculate .text16 segment address */
+ subw $_text16_memsz_pgh, %ax
pushw %ax
/* Update FBMS */
shrw $6, %ax
movw %ax, %fs:0x13
- /* Return */
+ /* Retrieve .text16 and .data16 segment addresses */
popw %ax
popw %bx
+
+ /* Restore registers and return */
+ popw %fs
ret
.size alloc_basemem, . - alloc_basemem
/****************************************************************************
+ * free_basemem (real-mode near call)
+ *
+ * Free space allocated with alloc_basemem.
+ *
+ * Parameters:
+ * %ax : .text16 segment address
+ * %bx : .data16 segment address
+ * Returns:
+ * %ax : 0 if successfully freed
+ * Corrupts:
+ * none
+ ****************************************************************************
+ */
+ .section ".text16"
+ .code16
+ .globl free_basemem
+free_basemem:
+ /* Preserve registers */
+ pushw %fs
+
+ /* Check FBMS counter */
+ pushw %ax
+ shrw $6, %ax
+ pushw $0x40
+ popw %fs
+ cmpw %ax, %fs:0x13
+ popw %ax
+ jne 1f
+
+ /* Check hooked interrupt count */
+ cmpw $0, %cs:hooked_bios_interrupts
+ jne 1f
+
+ /* OK to free memory */
+ addw $_text16_memsz_pgh, %ax
+ addw $_data16_memsz_pgh, %ax
+ shrw $6, %ax
+ movw %ax, %fs:0x13
+ xorw %ax, %ax
+
+1: /* Restore registers and return */
+ popw %fs
+ ret
+ .size free_basemem, . - free_basemem
+
+ .section ".text16.data"
+ .globl hooked_bios_interrupts
+hooked_bios_interrupts:
+ .word 0
+ .size hooked_bios_interrupts, . - hooked_bios_interrupts
+
+/****************************************************************************
* install (real-mode near call)
*
* Install all text and data segments.
@@ -594,19 +685,19 @@ install_prealloc:
jnz 1f
movw %cs, %si
shll $4, %esi
-1: addl $_payload_offset, %esi
+1: addl $_payload_lma, %esi
/* Install .text16 and .data16 */
pushl %edi
movzwl %ax, %edi
shll $4, %edi
- movl $_text16_size, %ecx
+ movl $_text16_memsz, %ecx
movl %ecx, %edx
call install_block /* .text16 */
movzwl %bx, %edi
shll $4, %edi
- movl $_data16_progbits_size, %ecx
- movl $_data16_size, %edx
+ movl $_data16_filesz, %ecx
+ movl $_data16_memsz, %edx
call install_block /* .data16 */
popl %edi
@@ -622,8 +713,8 @@ install_prealloc:
* prior to reading the E820 memory map and relocating
* properly.
*/
- movl $_textdata_progbits_size, %ecx
- movl $_textdata_size, %edx
+ movl $_textdata_filesz, %ecx
+ movl $_textdata_memsz, %edx
call install_block
/* Initialise librm at current location */
@@ -676,30 +767,53 @@ prot_call_vector:
.size prot_call_vector, . - prot_call_vector
#endif
+/****************************************************************************
+ * uninstall (real-mode near call)
+ *
+ * Uninstall all text and data segments.
+ *
+ * Parameters:
+ * %ax : .text16 segment address
+ * %bx : .data16 segment address
+ * Returns:
+ * none
+ * Corrupts:
+ * none
+ ****************************************************************************
+ */
+ .section ".text16"
+ .code16
+ .globl uninstall
+uninstall:
+ call free_basemem
+ ret
+ .size uninstall, . - uninstall
+
+
/* File split information for the compressor */
#if COMPRESS
- .section ".zinfo", "a"
+ .section ".zinfo", "a", @progbits
.ascii "COPY"
- .long _prefix_load_offset
- .long _prefix_progbits_size
+ .long _prefix_lma
+ .long _prefix_filesz
.long _max_align
.ascii "PACK"
- .long _text16_load_offset
- .long _text16_progbits_size
+ .long _text16_lma
+ .long _text16_filesz
.long _max_align
.ascii "PACK"
- .long _data16_load_offset
- .long _data16_progbits_size
+ .long _data16_lma
+ .long _data16_filesz
.long _max_align
.ascii "PACK"
- .long _textdata_load_offset
- .long _textdata_progbits_size
+ .long _textdata_lma
+ .long _textdata_filesz
.long _max_align
#else /* COMPRESS */
- .section ".zinfo", "a"
+ .section ".zinfo", "a", @progbits
.ascii "COPY"
- .long _prefix_load_offset
- .long _load_size
+ .long _prefix_lma
+ .long _filesz
.long _max_align
#endif /* COMPRESS */