Skip to content

Commit

Permalink
init_librm() and prot_call() are now real-mode far calls.
Browse files Browse the repository at this point in the history
install() now calls relocate(), moves the protected-mode code to the new
location, and calls hide_etherboot().
  • Loading branch information
Michael Brown committed May 25, 2006
1 parent 4d81b48 commit 89da833
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 90 deletions.
3 changes: 2 additions & 1 deletion src/arch/i386/interface/pcbios/int13.c
Expand Up @@ -393,7 +393,8 @@ static void hook_int13 ( void ) {
"\nint13_wrapper:\n\t"
"orb $0, %%al\n\t" /* clear CF and OF */
"pushl %0\n\t" /* call int13() */
"data32 call prot_call\n\t"
"pushw %%cs\n\t"
"call prot_call\n\t"
"jo 1f\n\t" /* chain if OF not set */
"pushfw\n\t"
"lcall *%%cs:int13_vector\n\t"
Expand Down
3 changes: 2 additions & 1 deletion src/arch/i386/prefix/dskprefix.S
Expand Up @@ -357,7 +357,8 @@ start_runtime:
.section ".text16", "awx", @progbits
1:
pushl $main
data32 call prot_call
pushw %cs
call prot_call
popl %eax /* discard */

/* Boot next device */
Expand Down
196 changes: 112 additions & 84 deletions src/arch/i386/prefix/libprefix.S
Expand Up @@ -21,6 +21,7 @@

.arch i386
.section ".prefix.lib", "awx", @progbits
.section ".data16", "aw", @progbits

/****************************************************************************
* install_block (real-mode near call)
Expand Down Expand Up @@ -164,6 +165,47 @@ install_basemem:
ret
.size install_basemem, . - install_basemem

/****************************************************************************
* install_highmem (flat real-mode near call)
*
* Install .text and .data into high memory
*
* Parameters:
* %es:edi : address in high memory
* Returns:
* none
* Corrupts:
* none
****************************************************************************
*/

#ifndef KEEP_IT_REAL

.section ".prefix.lib"
.code16
install_highmem:
/* Preserve registers */
pushl %esi
pushl %edi
pushl %ecx
pushl %edx

/* Install .text and .data to specified address */
movl $_textdata_load_offset, %esi
movl $_textdata_progbits_size, %ecx
movl $_textdata_size, %edx
call install_block

/* Restore registers and interrupt status */
popl %edx
popl %ecx
popl %edi
popl %esi
ret
.size install_highmem, . - install_highmem

#endif /* KEEP_IT_REAL */

/****************************************************************************
* GDT for flat real mode
*
Expand All @@ -183,11 +225,6 @@ gdt_limit: .word gdt_length - 1
gdt_base: .long 0
.word 0 /* padding */

real_ds: /* Genuine real mode data segment */
.equ REAL_DS, real_ds - gdt
.word 0xffff, 0
.byte 0, 0x93, 0, 0

flat_ds: /* Flat real mode data segment */
.equ FLAT_DS, flat_ds - gdt
.word 0xffff, 0
Expand All @@ -200,20 +237,20 @@ gdt_end:
#endif /* KEEP_IT_REAL */

/****************************************************************************
* set_segment_limits (real-mode near call)
* flatten_real_mode (real-mode near call)
*
* Sets limits on the data segments %ds and %es.
* Sets 4GB limits on the data segments %ds and %es.
*
* Parameters:
* %cx : Segment limit ($REAL_DS or $FLAT_DS)
* none
****************************************************************************
*/

#ifndef KEEP_IT_REAL

.section ".prefix.lib"
.code16
set_segment_limits:
flatten_real_mode:
/* Preserve real-mode segment values and temporary registers */
pushw %es
pushw %ds
Expand All @@ -227,12 +264,18 @@ set_segment_limits:
movl %eax, %cs:gdt_base
lgdt %cs:gdt

/* Switch to protected mode, set segment limits, switch back */
/* Switch to protected mode */
movl %cr0, %eax
orb $CR0_PE, %al
movl %eax, %cr0
movw %cx, %ds
movw %cx, %es

/* Set flat segment limits */
movw $FLAT_DS, %ax
movw %ax, %ds
movw %ax, %es

/* Switch back to real mode */
movl %cr0, %eax
andb $0!CR0_PE, %al
movl %eax, %cr0

Expand All @@ -241,61 +284,7 @@ set_segment_limits:
popw %ds
popw %es
ret
.size set_segment_limits, . - set_segment_limits

#endif /* KEEP_IT_REAL */

/****************************************************************************
* install_highmem (real-mode near call)
*
* Install .text and .data into high memory
*
* Parameters:
* %edi : physical address in high memory
* Returns:
* none
* Corrupts:
* none
****************************************************************************
*/

#ifndef KEEP_IT_REAL

.section ".prefix.lib"
.code16
install_highmem:
/* Preserve registers and interrupt status */
pushfl
pushl %esi
pushl %edi
pushl %ecx
pushl %edx

/* Disable interrupts and flatten real mode */
cli
movw $FLAT_DS, %cx
call set_segment_limits

/* Install .text and .data to specified address */
xorw %cx, %cx
movw %cx, %es
movl $_textdata_load_offset, %esi
movl $_textdata_progbits_size, %ecx
movl $_textdata_size, %edx
call install_block

/* Unflatten real mode */
movw $REAL_DS, %cx
call set_segment_limits

/* Restore registers and interrupt status */
popl %edx
popl %ecx
popl %edi
popl %esi
popfl
ret
.size install_highmem, . - install_highmem
.size flatten_real_mode, . - flatten_real_mode

#endif /* KEEP_IT_REAL */

Expand Down Expand Up @@ -329,32 +318,71 @@ install_prealloc:
call install_basemem

#ifndef KEEP_IT_REAL
/* Preserve registers and interrupt status, and disable interrupts */
pushfw
pushw %ds
pushw %es
pushl %esi
pushl %ecx
cli

/* Load up %ds and %es, and set up vectors for far calls to .text16 */
movw %bx, %ds
xorw %si, %si
movw %si, %es
movw %ax, (init_librm_vector+2)
movw %ax, (prot_call_vector+2)

/* Install .text and .data to 2MB mark. Use 2MB to avoid
* problems with A20.
*/
call flatten_real_mode
movl $(2<<20), %edi
call install_highmem

/* Continue executing in .text16 segment */
movw %bx, %ds
pushw %cs
pushw $2f
pushw %ax
pushw $1f
lret
.section ".text16", "awx", @progbits
1:
/* Set up protected-mode GDT, call relocate(), reset GDT */
call init_librm
/* Set up initial protected-mode GDT, call relocate().
* relocate() will return with %esi, %edi and %ecx set up
* ready for the copy to the new location.
*/
lcall *init_librm_vector
pushl $relocate
data32 call prot_call
lcall *prot_call_vector
addw $4, %sp
call init_librm

/* Return to executing in .prefix section */
lret
.section ".prefix.lib"
2:
/* Move code to new location, set up new protected-mode GDT */
call flatten_real_mode
pushl %edi
es rep addr32 movsb
popl %edi
lcall *init_librm_vector

/* Hide Etherboot from BIOS memory map. Note that making this
* protected-mode call will also restore normal (non-flat)
* real mode, as part of the protected-to-real transition.
*/
pushl $hide_etherboot
lcall *prot_call_vector
addw $4, %sp

/* Restore registers and interrupt status */
popl %ecx
popl %esi
popw %es
popw %ds
popfw
#endif
ret
.size install_prealloc, . - install_prealloc

#ifndef KEEP_IT_REAL
/* Vectors for far calls to .text16 functions */
.section ".data16"
init_librm_vector:
.word init_librm
.word 0
.size init_librm_vector, . - init_librm_vector
prot_call_vector:
.word prot_call
.word 0
.size prot_call_vector, . - prot_call_vector
#endif
8 changes: 4 additions & 4 deletions src/arch/i386/transitions/librm.S
Expand Up @@ -88,7 +88,7 @@ gdt_end:
.equ gdt_length, gdt_end - gdt

/****************************************************************************
* init_librm (real-mode near call, 16-bit real-mode return address)
* init_librm (real-mode far call, 16-bit real-mode far return address)
*
* Initialise the GDT ready for transitions to protected mode.
*
Expand Down Expand Up @@ -143,7 +143,7 @@ init_librm:
negl %edi
popl %ebx
popl %eax
ret
lret

.section ".text16"
.code16
Expand Down Expand Up @@ -316,7 +316,7 @@ rm_cs: .word 0
rm_ds: .word 0

/****************************************************************************
* prot_call (real-mode near call, 32-bit real-mode return address)
* prot_call (real-mode far call, 16-bit real-mode far return address)
*
* Call a specific C function in the protected-mode code. The
* prototype of the C function must be
Expand Down Expand Up @@ -405,7 +405,7 @@ prot_call:
* zeroes the high word of %esp, and interrupts
* are still disabled at this point. */
popfl
data32 ret
lret

/****************************************************************************
* real_call (protected-mode near call, 32-bit virtual return address)
Expand Down

0 comments on commit 89da833

Please sign in to comment.