david/ipxe
david
/
ipxe
Archived
1
0
Fork 0
This repository has been archived on 2020-12-06. You can view files and clone it, but cannot push or open issues or pull requests.
ipxe/src/arch/i386/core/setup.S

159 lines
3.9 KiB
ArmAsm

/****************************************************************************
* This file provides the setup() and setup16() functions. The
* purpose of these functions is to set up the internal environment so
* that C code can execute. This includes setting up the internal
* stack and (where applicable) setting up a GDT for virtual
* addressing.
*
* These functions are designed to be called by the prefix.
*
* The same basic assembly code is used to compile both setup()
* and setup16().
****************************************************************************
*/
.text
.arch i386
#ifdef CODE16
/****************************************************************************
* setup16 (real-mode far call)
*
* This function can be called by a 16-bit prefix in order to set up
* the internal (either 16-bit or 32-bit) environment.
*
* Parameters: none
*
* %cs:0000, %ds:0000 and %es:0000 must point to the start of the
* (decompressed) runtime image.
*
* If KEEP_IT_REAL is defined, then %ds:0000 may instead point to the
* start of the (decompressed) data segment portion of the runtime
* image. If %ds==%cs, then it will be assumed that the data segment
* follows immediately after the code segment.
****************************************************************************
*/
#ifdef KEEP_IT_REAL
#define ENTER_FROM_EXTERNAL call ext_to_kir
#define RETURN_TO_EXTERNAL call kir_to_ext
#define ENTRY_POINT kir_call
#else /* KEEP_IT_REAL */
#define ENTER_FROM_EXTERNAL \
pushw %cs ; \
call real_to_prot ; \
.code32
#define RETURN_TO_EXTERNAL \
call prot_to_real ; \
.code16
#define ENTRY_POINT _prot_call /* _prot_call = OFFSET ( prot_call ) in librm */
#endif /* KEEP_IT_REAL */
#define ENTRY_POINT_REGISTER di
.section ".text16"
.code16
.globl setup16
setup16:
#else /* CODE16 */
/****************************************************************************
* setup (32-bit protected-mode near call)
*
* This function can be called by a 32-bit prefix in order to set up
* the internal 32-bit environment.
*
* Parameters: none
****************************************************************************
*/
#define ENTER_FROM_EXTERNAL call ext_to_int
#define RETURN_TO_EXTERNAL call int_to_ext
#define ENTRY_POINT int_call
#define ENTRY_POINT_REGISTER edi
.section ".text"
.code32
.globl setup
setup:
#endif /* CODE16 */
/* Preserve flags (including interrupt status) */
pushfl
/* Switch to (uninitialised) internal environment. This will
* preserve the external environment for when we call
* RETURN_TO_EXTERNAL.
*/
ENTER_FROM_EXTERNAL
/* NOTE: We may have only four bytes of stack at this point */
#if defined(CODE16) && defined(KEEP_IT_REAL)
/* If %ds == %cs, then the data segment is located immediately
* after the code segment.
*/
pushw %ax
pushw %bx
movw %cs, %ax
movw %ds, %bx
cmpw %ax, %bx
jne 1f
addw $_text_load_size_pgh, %ax
movw %ax, %ds
1: popw %bx
popw %ax
/* Switch to internal stack */
pushw %ds
popw %ss
movl $_estack, %esp
#else /* CODE16 && KEEP_IT_REAL */
/* Work out where we're running */
call 1f
1: popl %ebp
/* Switch to internal pmode stack */
leal (_estack-1b)(%ebp), %esp
/* Set up GDT for virtual addressing */
call run_here
#endif /* CODE16 && KEEP_IT_REAL */
/* Switch back to external environment. This will preserve
* the internal environment ready for the next call.
*/
RETURN_TO_EXTERNAL
/* Pass pointer to entry-point function back to prefix. %es
* may, by now, have been destroyed, so we re-initialise it
* from %cs.
*/
pushw %cs
popw %es
mov $ENTRY_POINT, %ENTRY_POINT_REGISTER
/* Restore flags (including interrupt status) */
popfl
lret
/****************************************************************************
* Internal stack
****************************************************************************
*/
.section ".stack"
.align 8
_stack:
.space 4096
_estack: