diff options
Diffstat (limited to 'src/arch/i386/core/start16.S')
-rw-r--r-- | src/arch/i386/core/start16.S | 285 |
1 files changed, 0 insertions, 285 deletions
diff --git a/src/arch/i386/core/start16.S b/src/arch/i386/core/start16.S deleted file mode 100644 index 72fcfbfb..00000000 --- a/src/arch/i386/core/start16.S +++ /dev/null @@ -1,285 +0,0 @@ -/***************************************************************************** - * - * THIS FILE IS NOW OBSOLETE. - * - * The functions of this file are now placed in init.S. - * - ***************************************************************************** - */ - -#ifndef PCBIOS -#error "16bit code is only supported with the PCBIOS" -#endif - -#define CODE_SEG 0x08 -#define DATA_SEG 0x10 - -#define EXEC_IN_SITU_MAGIC 0x45524548 /* 'HERE' */ - - .equ CR0_PE, 1 - -#ifdef GAS291 -#define DATA32 data32; -#define ADDR32 addr32; -#define LJMPI(x) ljmp x -#else -#define DATA32 data32 -#define ADDR32 addr32 -/* newer GAS295 require #define LJMPI(x) ljmp *x */ -#define LJMPI(x) ljmp x -#endif - -/***************************************************************************** - * - * start16 : move payload to desired area of memory, set up for exit - * back to prefix, set up for 32-bit code. - * - * Enter (from prefix) with es:di = 0x4552:0x4548 if you want to - * prevent start16 from moving the payload. There are three - * motivations for moving the payload: - * - * 1. It may be in ROM, in which case we need to move it to RAM. - * 2. Whatever loaded us probably didn't know about our memory usage - * beyond the end of the image file. We should claim this memory - * before using it. - * - * Unless the prefix instructs us otherwise we will move the payload to: - * - * An area of memory claimed from the BIOS via 40:13. - * - * We use the main Etherboot stack (within the image target) as our - * stack; we don't rely on the prefix passing us a stack usable for - * anything other than the prefix's return address. The (first 512 - * bytes of the) prefix code segment is copied to a safe archive - * location. - * - * When we return to the prefix (from start32), we copy this code back - * to a new area of memory, restore the prefix's ss:sp and ljmp back - * to the copy of the prefix. The prefix will see a return from - * start16 *but* may be executing at a new location. Code following - * the lcall to start16 must therefore be position-independent and - * must also be within [cs:0000,cs:01ff]. We make absolutely no - * guarantees about the stack contents when the prefix regains - * control. - * - * Trashes just about all registers, including all the segment - * registers. - * - ***************************************************************************** - */ - - .text - .code16 - .arch i386 - .org 0 - .globl _start16 -_start16: - -/***************************************************************************** - * Work out where we are going to place our image (image = optional - * decompressor + runtime). Exit this stage with %ax containing the - * runtime target address divided by 16 (i.e. a real-mode segment - * address). - ***************************************************************************** - */ - movw %es, %ax - cmpw $(EXEC_IN_SITU_MAGIC >> 16), %ax - jne exec_moved - cmpw $(EXEC_IN_SITU_MAGIC & 0xffff), %di - jne exec_moved -exec_in_situ: - /* Prefix has warned us not to move the payload. Simply - * calculate where the image is going to end up, so we can - * work out where to put our stack. - */ - movw %cs, %ax - addw $((payload-_start16)/16), %ax - jmp 99f -exec_moved: - /* Claim an area of base memory from the BIOS and put the - * payload there. arch_relocated_to() will deal with freeing - * up this memory once we've relocated to high memory. - */ - movw $0x40, %ax - movw %ax, %es - movw %es:(0x13), %ax /* FBMS in kb to %ax */ - shlw $6, %ax /* ... in paragraphs */ - subw $__image_size_pgh, %ax /* Subtract space for image */ - shrw $6, %ax /* Round down to nearest kb */ - movw %ax, %es:(0x13) /* ...and claim memory from BIOS */ - shlw $6, %ax -99: - /* At this point %ax contains the segment address for the - * start of the image (image = optional decompressor + runtime). - */ - -/***************************************************************************** - * Set up stack in start32's stack space within the place we're going - * to copy Etherboot to, reserve space for GDT, copy return address - * from prefix stack, store prefix stack address - ***************************************************************************** - */ - popl %esi /* Return address */ - mov %ss, %bx /* %es:di = prefix stack address */ - mov %bx, %es /* (*after* pop of return address) */ - movw %sp, %di - movw $__offset_stack_pgh, %bx /* Set up Etherboot stack */ - addw %ax, %bx - movw %bx, %ss - movw $__stack_size, %sp - subw $(_gdt_end - _gdt), %sp /* Reserve space for GDT */ - movw %sp, %bp /* Record GDT location */ - /* Set up i386_rm_in_call_data_t structure on stack. This is - * the same structure as is set up by rm_in_call. - */ - pushl $0 /* Dummy opcode */ - pushl %esi /* Prefix return address */ - pushfw /* Flags */ - pushw %di /* Prefix %sp */ - pushw %gs /* Segment registers */ - pushw %fs - pushw %es - pushw %ds - pushw %es /* Prefix %ss */ - pushw %cs - /* Stack is now 32-bit aligned */ - - /* %ax still contains image target segment address */ - -/***************************************************************************** - * Calculate image target and prefix code physical addresses, store on stack - * for use in copy routine. - ***************************************************************************** - */ - movzwl %es:-2(%di), %ebx /* Prefix code segment */ - shll $4, %ebx - pushl %ebx /* Prefix code physical address */ - movzwl %ax, %edi /* Image target segment */ - shll $4, %edi - pushl %edi /* Image target physical address */ - -/***************************************************************************** - * Transition to 32-bit protected mode. Set up all segment - * descriptors to use flat physical addresses. - ***************************************************************************** - */ - /* Copy gdt to area reserved on stack - */ - push %cs /* GDT source location -> %ds:%si */ - pop %ds - mov $(_gdt - _start16), %si - push %ss /* GDT target location -> %es:%di */ - pop %es - mov %bp, %di - mov $(_gdt_end - _gdt), %cx - cld - rep movsb /* Copy GDT to stack */ - movl %ss, %eax - shll $4, %eax - movzwl %bp, %ebx - addl %eax, %ebx /* Physical addr of GDT copy -> %ebx */ - movl %ebx, 2(%bp) /* Fill in addr field in GDT */ - - /* Compute the offset I am running at. - */ - movl %cs, %ebx - shll $4, %ebx /* %ebx = offset for start16 symbols */ - - /* Switch to 32bit protected mode. - */ - cli /* Disable interrupts */ - lgdt (%bp) /* Load GDT from stack */ - movl %cr0, %eax /* Set protected mode bit */ - orb $CR0_PE, %al - movl %eax, %cr0 - movl %ss, %eax /* Convert stack pointer to 32bit */ - shll $4, %eax - movzwl %sp, %esp - addl %eax, %esp - movl $DATA_SEG, %eax /* Reload the segment registers */ - movl %eax, %ds - movl %eax, %es - movl %eax, %ss - movl %eax, %fs - movl %eax, %gs - /* Flush prefetch queue, and reload %cs:%eip by effectively ljmping - * to code32_start. Do the jump via pushl and lret because the text - * may not be writable/ - */ - pushl $CODE_SEG - ADDR32 leal (code32_start-_start16)(%ebx), %eax - pushl %eax - DATA32 lret /* DATA32 needed, because we're still in 16-bit mode */ - -_gdt: -gdtarg: - .word _gdt_end - _gdt - 1 /* limit */ - .long 0 /* addr */ - .word 0 -_pmcs: - /* 32 bit protected mode code segment */ - .word 0xffff, 0 - .byte 0, 0x9f, 0xcf, 0 -_pmds: - /* 32 bit protected mode data segment */ - .word 0xffff,0 - .byte 0,0x93,0xcf,0 -_gdt_end: - - .code32 -code32_start: - -/***************************************************************************** - * Copy payload to target location. Do the copy backwards, since if - * there's overlap with a forward copy then it means start16 is going - * to get trashed during the copy anyway... - ***************************************************************************** - */ - popl %edi /* Image target physical address */ - pushl %edi - leal (payload-_start16)(%ebx), %esi /* Image source physical addr */ - movl $__payload_size, %ecx /* Payload size (not image size) */ - addl %ecx, %edi /* Start at last byte (length - 1) */ - decl %edi - addl %ecx, %esi - decl %esi - std /* Backward copy of image */ - rep movsb - cld - popl %edi /* Restore image target physical address */ - leal __decompressor_uncompressed(%edi), %ebx - subl $_text, %ebx /* %ebx = offset for runtime symbols */ - -/***************************************************************************** - * Copy prefix to storage area within Etherboot image. - ***************************************************************************** - */ - popl %esi /* Prefix source physical address */ - pushl %edi - leal _prefix_copy(%ebx), %edi /* Prefix copy phys. addr. */ - leal _eprefix_copy(%ebx), %ecx - subl %edi, %ecx /* Prefix copy size */ - rep movsb /* Forward copy of prefix */ - popl %edi /* Restore image target physical address */ - -/***************************************************************************** - * Record base memory used by Etherboot image - ***************************************************************************** - */ - movl %edi, _prefix_image_basemem (%ebx) - -/***************************************************************************** - * Jump to start of the image (i.e. the decompressor, or start32 if - * non-compressed). - ***************************************************************************** - */ - pushl $0 /* Inform start32 that exit path is 16-bit */ - jmpl *%edi /* Jump to image */ - - .balign 16 - /* Etherboot needs to be 16byte aligned or data that - * is virtually aligned is no longer physically aligned - * which is just nasty in general. 16byte alignment - * should be sufficient though. - */ -payload: |