Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Oct 2003 19:13:30 -0800 (PST)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 40926 for review
Message-ID:  <200310310313.h9V3DUKn008335@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=40926

Change 40926 by peter@peter_daintree on 2003/10/30 19:13:27

	rewrite mpboot.s.  There are still a couple of loose ends yet.
	TODO:
	  * set the segment base for %cs/%ds so we can remain relocatable
	  * hook up the pagetables
	  * make it compile (yeah, this would be useful)

Affected files ...

.. //depot/projects/hammer/sys/amd64/amd64/mpboot.s#11 edit

Differences ...

==== //depot/projects/hammer/sys/amd64/amd64/mpboot.s#11 (text+ko) ====

@@ -1,5 +1,5 @@
-/*
- * Copyright (c) 1995, Jack F. Vogel
+/*-
+ * Copyright (c) 2003 Peter Wemm
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -10,16 +10,11 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by Jack F. Vogel
- * 4. The name of the developer may be used to endorse or promote products
- *    derived from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -28,188 +23,160 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * mpboot.s:	FreeBSD machine support for the Intel MP Spec
- *		multiprocessor systems.
- *
  * $FreeBSD: src/sys/i386/i386/mpboot.s,v 1.22 2003/10/30 21:42:44 jhb Exp $
  */
 
 #include <machine/asmacros.h>		/* miscellaneous asm macros */
-#include <machine/apicreg.h>
 #include <machine/specialreg.h>
 
 #include "assym.s"
 
-/*
- * the APs enter here from their trampoline code (bootMP, below)
- */
-	.section .data32
+	.section .bootcode
 	.p2align 4
 
-	.code32
-	.globl	MPentry
-MPentry:
-	movl	%cr4,%eax
-	orl	$CR4_PSE|CR4_PGE|CR4_PAE,%eax	/* Enable features  */
-	movl	%eax,%cr4
-
-	/* Now enable paging mode */
-	movl	IdlePTD32, %eax
-	movl	%eax, %cr3
-	movl	%cr0,%eax
-	orl	$CR0_PE|CR0_PG,%eax		/* enable paging */
-	movl	%eax,%cr0			/* let the games begin! */
-	movl	bootSTK32,%esp			/* boot stack end loc. */
-
-#ifdef SMP_ME_HARDER	/* 64 bit reference in 32 bit code */
-	pushl	$init_secondary			/* jump to high mem */
-#endif
-	ret
-
-	.p2align 4
-
-BOOTMP_start:
-
+	.globl	mptramp_start
+mptramp_start:
 	.code16
-	.globl	bootMP
-bootMP:
-	cli
-	/* First guarantee a 'clean slate' */
-	xorl	%eax, %eax
-	movl	%eax, %ebx
-	movl	%eax, %ecx
- 	movl	%eax, %edx
-	movl	%eax, %esi
-	movl	%eax, %edi
-
-	/* set up data segments */
-	mov	%cs, %ax
-	mov	%ax, %ds
-	mov	%ax, %es
-	mov	%ax, %fs
-	mov	%ax, %gs
+	/*
+	 * The AP enters here in response to the startup IPI.
+	 * We are in real mode. %cs is the only segment register set.
+	 */
+	cli				/* make sure no interrupts */
+	mov	%cs, %ax		/* copy %cs to %ds.  Remember these */
+	mov	%ax, %ds		/* are offsets rather than selectors */
 	mov	%ax, %ss
-	mov	$(boot_stk-bootMP), %esp
 
-	/* Now load the global descriptor table */
-	lgdt	MP_GDTptr-bootMP
+	/*
+	 * Load the descriptor table pointer.  We'll need it when running
+	 * in 16 bit protected mode.
+	 */
+	lgdt	lgdt_desc-mptramp_start
 
 	/* Enable protected mode */
-	movl	%cr0, %eax
-	orl	$CR0_PE, %eax
+	movl	$CR0_PE, %eax
 	movl	%eax, %cr0 
 
 	/*
-	 * make intrasegment jump to flush the processor pipeline and
-	 * reload CS register
+	 * Now execute a far jump to turn on protected mode.  This
+	 * causes the segment registers to turn into selectors and causes
+	 * %cs to be loaded from the gdt.
 	 */
-	pushl	$0x18
-	pushl	$(protmode-bootMP)
-	lretl
+	.byte	0xea			/* opcode for far jump */
+	.word	protmode-mptramp_start	/* offset in segment */
+	.word	bootcode-gdt		/* index in gdt for 16 bit code */
 
-       .code32		
+	/*
+	 * At this point, we are running in 32 bit legacy protected mode.
+	 * However, we have a non-zero base address in our segment registers
+	 * so that we can remain relocatable.
+	 */
+	.code32
 protmode:
+	mov	$bootdata-gdt, %eax
+	mov	%ax, %ds
+	mov	%ax, %ss
+
+	/* Turn on the PAE, PSE and PGE bits for when paging is enabled */
+	mov	%cr4, %eax
+	orl	$(CR4_PAE | CR4_PSE | CR4_PGE), %eax
+	mov	%eax, %cr4
 
 	/*
-	 * we are NOW running for the first time with %eip
-	 * having the full physical address, BUT we still
-	 * are using a segment descriptor with the origin
-	 * not matching the booting kernel.
-	 *
- 	 * SO NOW... for the BIG Jump into kernel's segment
-	 * and physical text above 1 Meg.
+	 * Point to the embedded page tables for startup.  Note that this
+	 * only gets accessed after we're actually in 64 bit mode, however
+	 * we can only set the bottom 32 bits of %cr3 in this state.  This
+	 * means we are required to use a temporary page table that is below
+	 * the 4GB limit.
 	 */
-	mov	$0x10, %ebx
-	movw	%bx, %ds
-	movw	%bx, %es
-	movw	%bx, %fs
-	movw	%bx, %gs
-	movw	%bx, %ss
+	movl	$pagetables, %eax	XXX
+	mov	%eax, %cr3
 
-	.globl	bigJump
-bigJump:
-	/* this will be modified by mpInstallTramp() */
-	ljmp	$0x08, $0			/* far jmp to MPentry() */
-	
-/*
- * MP boot strap Global Descriptor Table
- */
-	.p2align 4
-	.globl	MP_GDT
-	.globl	bootCodeSeg
-	.globl	bootDataSeg
-MP_GDT:
+	/*
+	 * Enable EFER.LME so that we get long mode when all the prereqs are
+	 * in place.  In this case, it turns on when CR0_PG is finally enabled.
+	 */
+	movl	$MSR_EFER, %ecx
+	rdmsr
+	orl	$EFER_LME, %eax
+	wrmsr
 
-nulldesc:		/* offset = 0x0 */
+	/*
+	 * Finally, switch to 64 bit mode by enabling paging.  We have
+	 * to be very careful here because all the segmentation disappears
+	 * out from underneath us.  The spec says we can depend on the
+	 * subsequent pipelined long jump to execute.  This is Magic.
+	 */
+	mov	%cr0, %eax
+	orl	$CR0_PG, %eax
+	mov	%eax, %cr3
 
-	.word	0x0	
-	.word	0x0	
-	.byte	0x0	
-	.byte	0x0	
-	.byte	0x0	
-	.byte	0x0	
+	.byte	0xea		/* opcode for far jump */
+	.long	entry_64	/* 64 bit flat address */
+	.word	kernelcode-gdt	/* selector offset */
 
-kernelcode:		/* offset = 0x08 */
+	.p2align 4,0
+gdt:
+	/*
+	 * All segment descriptor tables start with a null descriptor */
+	 */
+	.long	0x00000000
+	.long	0x00000000
 
-	.word	0xffff	/* segment limit 0..15 */
-	.word	0x0000	/* segment base 0..15 */
-	.byte	0x0	/* segment base 16..23; set for 0K */
-	.byte	0x9f	/* flags; Type	*/
-	.byte	0xcf	/* flags; Limit	*/
-	.byte	0x0	/* segment base 24..32 */
+	/*
+	 * This is the 64 bit long mode code descriptor.  There is no
+	 * 64 bit data descriptor.
+	 */
+kernelcode:
+	.long	0x00000000
+	.long	0x00209800
 
-kerneldata:		/* offset = 0x10 */
+	/*
+	 * This is the descriptor for the 32 bit boot code.
+	 * %cs:  +A, +R, -C, DPL=0, +P, +D, +G
+	 * Accessed, Readable, Present, 32 bit, 4G granularity
+	 */
+bootcode:
+	.long	0x0000ffff
+	.long	0x00cf9b00
 
-	.word	0xffff	/* segment limit 0..15 */
-	.word	0x0000	/* segment base 0..15 */
-	.byte	0x0	/* segment base 16..23; set for 0k */
-	.byte	0x93	/* flags; Type  */
-	.byte	0xcf	/* flags; Limit */
-	.byte	0x0	/* segment base 24..32 */
+	/*
+	 * This is the descriptor for the 32 bit boot data.
+	 * We load it into %ds and %ss.  The bits for each selector
+	 * are interpreted slightly differently.
+	 * %ds:  +A, +W, -E, DPL=0, +P, +D, +G
+	 * %ss:  +A, +W, -E, DPL=0, +P, +B, +G
+	 * Accessed, Writeable, Expand up, Present, 32 bit, 4GB 
+	 * For %ds, +D means 'default operand size is 32 bit'.
+	 * For %ss, +B means the stack register is %esp rather than %sp.
+	 */
+bootdata:
+	.long	0x0000ffff
+	.long	0x00cf9300
 
-bootcode:		/* offset = 0x18 */
+gdtend:
 
-	.word	0xffff	/* segment limit 0..15 */
-bootCodeSeg:		/* this will be modified by mpInstallTramp() */
-	.word	0x0000	/* segment base 0..15 */
-	.byte	0x00	/* segment base 16...23; set for 0x000xx000 */
-	.byte	0x9e	/* flags; Type  */
-	.byte	0xcf	/* flags; Limit */
-	.byte	0x0	/*segment base 24..32 */
+	/*
+	 * The pseudo descriptor for lgdt to use.
+	 */
+lgdt_desc:	
+	.word	gdtend - gdt		/* Length */
+	.long	gdt - mptramp_start	/* Offset plus %ds << 4 */
 
-bootdata:		/* offset = 0x20 */
+	.globl	mptramp_end
+mptramp_end:
 
-	.word	0xffff	
-bootDataSeg:		/* this will be modified by mpInstallTramp() */
-	.word	0x0000	/* segment base 0..15 */
-	.byte	0x00	/* segment base 16...23; set for 0x000xx000 */
-	.byte	0x92	
-	.byte	0xcf	
-	.byte	0x0		
 
-/*
- * GDT pointer for the lgdt call
- */
-
-MP_GDTptr:	
-mp_gdtlimit:
-	.word	0x0028		
-	.globl	mp_gdtbase
-mp_gdtbase:		/* this will be modified by mpInstallTramp() */
-	.long	0
-
-	.space	0x100	/* space for boot_stk - 1st temporary stack */
-boot_stk:
-
-	.globl	bootSTK32
-bootSTK32:
-	.long	0
-	.globl	IdlePTD32
-IdlePTD32:
-	.long	0
-
-BOOTMP_end:
-
-	.globl	bootMP_size
-bootMP_size:
-	.long	BOOTMP_end - BOOTMP_start
+	/*
+	 * Yeehar!  We're running in 64 bit mode!  We can mostly ignore our
+	 * segment registers, and get on with it.
+	 * Load a basic stack pointer and jump into the kernel.
+	 * Note that we are running at the correct virtual address, but with
+	 * a 1:1 1GB mirrored mapping over entire address space.  We had better
+	 * switch to a real %cr3 promptly.
+	 */
+	.text
+	.code64
+entry_64:
+	movq	$bootSTK, %rsp
+	pushq	$init_secondary
+	ret



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200310310313.h9V3DUKn008335>