mirror of
https://github.com/xcat2/xNBA.git
synced 2024-12-15 15:51:44 +00:00
159 lines
3.9 KiB
ArmAsm
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:
|