]> git.saurik.com Git - apple/boot.git/blobdiff - i386/libsaio/asm.s
boot-132.tar.gz
[apple/boot.git] / i386 / libsaio / asm.s
index ede3dfaa6b440ade58c0433714b2dd12dd082bcd..a9bbe9d10a241e1fff3fe924f43221e6ba2bdf96 100644 (file)
@@ -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@
  * 
  *
  * @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
  * 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.
  * 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.
 /*
  * HISTORY
  * $Log: asm.s,v $
 /*
  * 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:
+ * <rdar://problem/3094680>: (Silent boot)
+ * <rdar://problem/3363893>: (5 sec boot timeout is too short)
+ * <rdar://problem/3533781>: (Boot option to display graphics modes)
+ * <rdar://problem/3545539>: (Default graphics mode should be 32-bit)
+ * <rdar://problem/3643065>: (Booter should always find a video mode)
+ * <rdar://problem/3643815>: (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 <pexpert/i386/boot.h>.
+ *
+ * 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)
  * 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)
  * Import of boot-25 (~mwatson)
  *
  * Revision 2.1.1.2  90//03//22  17:59:50  rvb
  * 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
  * 
  * 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]
  * 
  */
 
  * 
  */
 
 
     .file "asm.s"
 
 
     .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
 
 .globl _Gdtr
     .data
-    .align 2,0x90
+    .align 2, 0x90
 _Gdtr:
 _Gdtr:
-    .word 0x2F
-//  .long _Gdt+4096
+    .word GDTLIMIT
     .long vtop(_Gdt)
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 // Data area for __switch_stack.
 //
     .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()
 
     .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)
 //
 LABEL(__real_to_prot)
-    // guarantee that interrupt is disabled when in prot mode
+
+    // Interrupts are disabled in protected mode.
+
     cli
 
     cli
 
-    addr32                    // load the gdtr
+    // Load the Global Descriptor Table Register (GDTR).
+
+    addr32
     data32
     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     %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
 
     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
 
     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
 
     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()
     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)
 
 // 
 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:
     ljmp    $0x18, $x16       // change to USE16 mode
 
 x16:
@@ -168,74 +250,67 @@ x16:
     // and reload CS register
 
     data32
     // and reload CS register
 
     data32
-    ljmp    $BOOTSEG, $xreal
+    ljmp    $CODE16_SEG, $xreal - CODE32_BASE
 
 xreal:
     // we are in real mode now
 
 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    %cs, %ax
     movw    %ax, %ds
-    movw    %ax, %ss
     movw    %ax, %es
     movw    %ax, %es
+    movw    %ax, %fs
+    movw    %ax, %gs
+
+    // load stack segment register SS.
 
     data32
 
     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
 
     ret
 
-#endif /* DEFINE_INLINE_FUNCTIONS */
-
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 // halt()
 //
 LABEL(_halt)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 // halt()
 //
 LABEL(_halt)
-//  call    _getchar
-    hlt
+    call    _bgetc
     jmp     _halt
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     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
 
 //
 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
 
     push    %ebx
     push    %ecx
 
@@ -255,91 +330,94 @@ LABEL(__sp)
     ret
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     ret
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// Returns the current stack pointer.
+// Returns the current frame pointer.
 //
 LABEL(__bp)
     mov %ebp, %eax
     ret
 
 //
 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)
 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)
 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
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 // pcpy(src, dst, cnt)
 //  where src is a virtual address and dst is a physical address