X-Git-Url: https://git.saurik.com/apple/boot.git/blobdiff_plain/14c7c974991c850bfa0348affbd4bee3223205ee..bba600dda0ea8a76d875db7308f372bfc43f8506:/i386/libsaio/asm.s?ds=sidebyside diff --git a/i386/libsaio/asm.s b/i386/libsaio/asm.s index ede3dfa..a9bbe9d 100644 --- a/i386/libsaio/asm.s +++ b/i386/libsaio/asm.s @@ -1,12 +1,12 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * - * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights + * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights * Reserved. This file contains Original Code and/or Modifications of * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.1 (the "License"). You may not use this file + * Source License Version 2.0 (the "License"). You may not use this file * except in compliance with the License. Please obtain a copy of the * License at http://www.apple.com/publicsource and read it before using * this file. @@ -31,6 +31,49 @@ /* * HISTORY * $Log: asm.s,v $ + * Revision 1.8 2005/06/24 22:47:12 curtisg + * Merging changes for 4159531 to pass data to the kernel in EFI format. + * + * Revision 1.7 2004/05/13 17:58:38 curtisg + * Integrating: + * : (Silent boot) + * : (5 sec boot timeout is too short) + * : (Boot option to display graphics modes) + * : (Default graphics mode should be 32-bit) + * : (Booter should always find a video mode) + * : (Booter displays "0MB" VRAM) + * + * Revision 1.6 2003/11/05 20:51:02 curtisg + * Integrated 3069695,3331770,3370488,3371823 + * + * Revision 1.5.26.1 2003/10/27 23:57:59 curtisg + * Added printing of volume names, better handling of extended + * partitions, and updated Apple license strings. + * New chain booter should work better with foreign operating + * systems. + * + * Revision 1.5 2002/11/05 20:34:26 jliu + * Integrating: + * 3051234 boot shouldnt require Graphics = Yes + * 3091627 Need support for refresh rate adjustment + * + * Revision 1.4 2002/10/02 00:06:18 curtisg + * Integrating PR-3032510. + * + * Revision 1.3.6.1 2002/08/30 21:16:29 curtisg + * KERNBOOTSTRUCT is going away in favor of KernelBootArgs_t in . + * + * Revision 1.3 2002/07/09 14:06:21 jliu + * Merging changes from PR-2954224 branch in boot/i386. + * + * Revision 1.2.30.1 2002/07/05 16:24:51 jliu + * Merged UFS/HFS/HFS+ filesystem support from BootX. + * Moved boot2 load address due to increased size. boot0/boot1 also changed. + * Updated boot graphics and CLUT. + * Added support to chain load foreign booters. + * Fixed param passing bug in network loader. + * Misc cleanup in libsaio. + * * Revision 1.2 2000/05/23 23:01:11 lindak * Merged PR-2309530 into Kodiak (liu i386 booter: does not support label-less * ufs partitions) @@ -59,11 +102,11 @@ * Import of boot-25 (~mwatson) * * Revision 2.1.1.2 90//03//22 17:59:50 rvb - * Added _sp() => where is the stack at. [kupfer] + * Added _sp() => where is the stack at. [kupfer] * * Revision 2.1.1.1 90//02//09 17:25:04 rvb - * Add Intel copyright - * [90//02//09 rvb] + * Add Intel copyright + * [90//02//09 rvb] * */ @@ -86,76 +129,115 @@ .file "asm.s" -BOOTSEG = BASE_SEG +CR0_PE_ON = 0x1 +CR0_PE_OFF = 0x7ffffff0 + +STACK32_BASE = ADDR32(STACK_SEG, 0) +STACK16_SEG = STACK_SEG +CODE32_BASE = ADDR32(BASE_SEG, 0) +CODE16_SEG = BASE_SEG -CR0_PE_ON = 0x1 -CR0_PE_OFF = 0xfffffffe +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Pointer to 6-bytes in memory that contains the base address and the limit +// (size of GDT table in bytes) of the GDT. The LGDT is the only instruction +// that directly loads a linear address (not a segment relative address) and +// a limit in protected mode. .globl _Gdtr .data - .align 2,0x90 + .align 2, 0x90 _Gdtr: - .word 0x2F -// .long _Gdt+4096 + .word GDTLIMIT .long vtop(_Gdt) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Data area for __switch_stack. // -save_sp: .long STACK_ADDR -save_ss: .long 0 - +save_sp: .long STACK_OFS +save_ss: .long STACK_SEG .text // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // real_to_prot() -// transfer from real mode to protected mode. -// preserves all registers except eax +// +// Transfer from real mode to protected mode. +// Preserves all registers except EAX. // LABEL(__real_to_prot) - // guarantee that interrupt is disabled when in prot mode + + // Interrupts are disabled in protected mode. + cli - addr32 // load the gdtr + // Load the Global Descriptor Table Register (GDTR). + + addr32 data32 - lgdt _Gdtr + lgdt OFFSET16(_Gdtr) - // set the PE bit of CR0 to go to protected mode + // Enter protected mode by setting the PE bit in CR0. mov %cr0, %eax data32 or $CR0_PE_ON, %eax - mov %eax, %cr0 + mov %eax, %cr0 - // make intrasegment jump to flush the processor pipeline and - // reload CS register + // Make intrasegment jump to flush the processor pipeline and + // reload CS register. data32 ljmp $0x08, $xprot xprot: // we are in USE32 mode now - // set up the protected mode segment registers : DS, SS, ES + // set up the protected mode segment registers : DS, SS, ES, FS, GS mov $0x10, %eax movw %ax, %ds movw %ax, %ss movw %ax, %es + movw %ax, %fs + movw %ax, %gs + + // Convert STACK_SEG:SP to 32-bit linear stack pointer. - xorl %eax, %eax // clear garbage from upper word of esp - movw %sp, %ax + movzwl %sp, %eax + addl $STACK32_BASE, %eax movl %eax, %esp + // Convert STACK_SEG:BP to 32-bit linear base pointer. + + movzwl %bp, %eax + addl $STACK32_BASE, %eax + movl %eax, %ebp + + // Modify the caller's return address on the stack from + // segment offset to linear address. + + popl %eax + addl $CODE32_BASE, %eax + pushl %eax + ret // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // prot_to_real() -// transfer from protected mode to real mode -// preserves all registers except eax +// +// Transfer from protected mode to real mode. +// Preserves all registers except EAX. // LABEL(__prot_to_real) + // Set up segment registers appropriate for real mode. + + movw $0x30, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + ljmp $0x18, $x16 // change to USE16 mode x16: @@ -168,74 +250,67 @@ x16: // and reload CS register data32 - ljmp $BOOTSEG, $xreal + ljmp $CODE16_SEG, $xreal - CODE32_BASE xreal: // we are in real mode now - // set up the real mode segment registers : DS, SS, ES + // set up the real mode segment registers : DS, DS, ES, FS, GS movw %cs, %ax movw %ax, %ds - movw %ax, %ss movw %ax, %es + movw %ax, %fs + movw %ax, %gs + + // load stack segment register SS. data32 - ret + movl $STACK16_SEG, %eax + movw %ax, %ss -#if defined(DEFINE_INLINE_FUNCTIONS) + // clear top 16-bits of ESP and EBP. -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// outb(port, byte) -// -LABEL(_outb) - push %ebp - mov %esp, %ebp - push %edx + data32 + movzwl %sp, %esp + data32 + movzwl %bp, %ebp - movw 8(%ebp), %dx - movb 12(%ebp), %al - outb %al, %dx + // Modify caller's return address on the stack + // from linear address to segment offset. - pop %edx - pop %ebp - ret + data32 + popl %eax + data32 + movzwl %ax, %eax + data32 + pushl %eax -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// inb(port) -// -LABEL(_inb) - push %ebp - mov %esp, %ebp - push %edx + // Reenable maskable interrupts. - movw 8(%ebp), %dx - subw %ax, %ax - inb %dx, %al + sti - pop %edx - pop %ebp + data32 ret -#endif /* DEFINE_INLINE_FUNCTIONS */ - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // halt() // LABEL(_halt) -// call _getchar - hlt + call _bgetc jmp _halt // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// startprog(phyaddr) -// Start the program on protected mode where phyaddr is the entry point +// startprog(phyaddr, arg) +// Start the program on protected mode where phyaddr is the entry point. +// Passes arg to the program in %eax. // LABEL(_startprog) push %ebp mov %esp, %ebp - mov 0x8(%ebp), %ecx // entry offset - mov $0x28, %ebx // segment + mov 0xc(%ebp), %eax // argument to program + mov 0x8(%ebp), %ecx // entry offset + mov $0x28, %ebx // segment push %ebx push %ecx @@ -255,91 +330,94 @@ LABEL(__sp) ret // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// Returns the current stack pointer. +// Returns the current frame pointer. // LABEL(__bp) mov %ebp, %eax ret -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Switch stack. -# Switches between registers SS:SP and memory save_ss:save_sp. -# Call this function from real mode only!!! -# -# AX, DI, and SI are modified. -# +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// switch_stack() +// +// Switches stack pointer between SS:SP and memory save_ss:save_sp. +// Call this function from real mode only!!! +// +// AX, DI, and SI are clobbered. +// LABEL(__switch_stack) - popl %eax # save return address - popl %edi # discard upper 16-bit - - data32 - addr32 - movl save_ss, %esi # copy new SS to ESI - - data32 - addr32 - movl save_sp, %edi # copy new SP to EDI - - addr32 - mov %ss, save_ss # save current SS - - data32 - addr32 - movl %esp, save_sp # Save current SP - - cli - mov %si, %ss # Perform stack switch - mov %di, %sp - sti - - pushl %eax # push IP of caller onto the new stack - - xorl %eax, %eax - xorl %esi, %esi - xorl %edi, %edi - - ret - -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Issue a request to the network loader. -# + popl %eax # save return address + popl %edi # discard upper 16-bit + + data32 + addr32 + movl OFFSET16(save_ss), %esi # new SS to SI + + data32 + addr32 + movl OFFSET16(save_sp), %edi # new SP to DI + + addr32 + mov %ss, OFFSET16(save_ss) # save current SS to memory + + data32 + addr32 + movl %esp, OFFSET16(save_sp) # save current SP to memory + + cli + mov %si, %ss # switch stack + mov %di, %sp + sti + + pushl %eax # push IP of caller onto the new stack + + xorl %eax, %eax + xorl %esi, %esi + xorl %edi, %edi + + ret + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// loader() +// +// Issue a request to the network loader. +// LABEL(_loader) - enter $0, $0 - pushal + enter $0, $0 + pushal - # - # Pass a far pointer to the command structure - # to the INT call through DI:CX. - # - # The command code is in BX. - # + # + # Pass a far pointer to the command structure + # to the INT call through DX:CX. + # + # The command code is in BX. + # - movw 8(%ebp), %bx # 8[EBP] = command code - movw 12(%ebp), %cx # 12[EBP] = command structure offset - movw 14(%ebp), %di # 14[EBP] = command structure segment + movw 8(%ebp), %bx # 8[EBP] = command code + movw 12(%ebp), %cx # 12[EBP] = command structure offset + movw 14(%ebp), %dx # 14[EBP] = command structure segment - call __prot_to_real # Revert to real mode + call __prot_to_real # Revert to real mode - ###### Real Mode Begin ###### + ###### Real Mode Begin ###### - data32 - call __switch_stack # Switch to NBP stack + data32 + call __switch_stack # Switch to NBP stack - int $0x2b # Call NBP + int $0x2b # Call NBP - data32 - call __switch_stack # Restore stack + data32 + call __switch_stack # Restore stack - data32 - call __real_to_prot # Back to protected mode - - ###### Real Mode End ###### - - popal - leave - ret + data32 + call __real_to_prot # Back to protected mode + + ###### Real Mode End ###### + + popal + leave + ret -#if 0 +#if UNUSED // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // pcpy(src, dst, cnt) // where src is a virtual address and dst is a physical address