summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2007-11-10 10:47:00 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2007-11-10 10:47:00 +0000
commit07f3d5d8f6d929c17a675b8013993aec0a099a5f (patch)
treeb4805ce70ee14bdf4afac166c782404411e1dd64
parenteead99fe98563320f169af5712a4141ac0718db1 (diff)
Remove a fair amount of duplicated code by making cpu_mp_startup call
cpu_initialize.
-rw-r--r--sys/arch/sparc64/sparc64/locore.s411
1 files changed, 12 insertions, 399 deletions
diff --git a/sys/arch/sparc64/sparc64/locore.s b/sys/arch/sparc64/sparc64/locore.s
index 16bf74b22ff..145124854df 100644
--- a/sys/arch/sparc64/sparc64/locore.s
+++ b/sys/arch/sparc64/sparc64/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.102 2007/11/09 16:15:28 kettenis Exp $ */
+/* $OpenBSD: locore.s,v 1.103 2007/11/10 10:46:59 kettenis Exp $ */
/* $NetBSD: locore.s,v 1.137 2001/08/13 06:10:10 jdolecek Exp $ */
/*
@@ -4061,7 +4061,7 @@ dostart:
*/
wrpr %g0, 13, %pil
wrpr %g0, PSTATE_INTR|PSTATE_PEF, %pstate
- wr %o0, FPRS_FEF, %fprs ! Turn on FPU
+ wr %g0, FPRS_FEF, %fprs ! Turn on FPU
#if defined(DDB) || NKSYMS > 0
/*
@@ -4125,6 +4125,10 @@ dostart:
* stack now.
*/
+ sethi %hi(_C_LABEL(cpus)), %g2
+ ldx [%g2 + %lo(_C_LABEL(cpus))], %g2
+ ldx [%g2 + CI_PADDR], %g2 ! Load the interrupt stack's PA
+
/*
* Initialize a CPU. This is used both for bootstrapping the first CPU
* and spinning up each subsequent CPU. Basically:
@@ -4436,26 +4440,11 @@ dlflush2:
#endif /* DEBUG */
/*
- * Step 6: hunt through cpus list and find the one that
- * matches our UPAID.
- */
- sethi %hi(_C_LABEL(cpus)), %l1
- ldxa [%g0] ASI_MID_REG, %l2
- ldx [%l1 + %lo(_C_LABEL(cpus))], %l1
- srax %l2, 17, %l2 ! Isolate UPAID from CPU reg
- and %l2, 0x1f, %l2
-0:
- ld [%l1 + CI_UPAID], %l3 ! Load UPAID
- cmp %l3, %l2 ! Does it match?
- bne,a,pt %icc, 0b ! no
- ldx [%l1 + CI_NEXT], %l1 ! Load next cpu_info pointer
-
-
- /*
- * Get pointer to our cpu_info struct
+ * Step 6: map cpu_info struct and interrupt stack and
+ * switch to our initial stack.
*/
- ldx [%l1 + CI_PADDR], %l1 ! Load the interrupt stack's PA
+ mov %g2, %l1 ! Load the interrupt stack's PA
sethi %hi(0xa0000000), %l2 ! V=1|SZ=01|NFO=0|IE=0
sllx %l2, 32, %l2 ! Shift it into place
@@ -4563,387 +4552,14 @@ dlflush2:
#ifdef MULTIPROCESSOR
ENTRY(cpu_mp_startup)
mov %o0, %g2
+
wrpr %g0, 0, %cleanwin
wrpr %g0, 13, %pil
wrpr %g0, PSTATE_INTR|PSTATE_PEF, %pstate
- wr %o0, FPRS_FEF, %fprs ! Turn on FPU
-
- wrpr %g0, 0, %tl ! Make sure we're not in NUCLEUS mode
-
- flushw
-
-#if 0
- /*
- * Disable the DCACHE entirely for debug.
- */
- ldxa [%g0] ASI_MCCR, %o1
- andn %o1, MCCR_DCACHE_EN, %o1
- stxa %o1, [%g0] ASI_MCCR
- membar #Sync
-#endif /* 0 */
-
- sethi %hi(KERNBASE), %l0 ! Find our xlation
- sethi %hi(DATA_START), %l3
-
- set _C_LABEL(ktextp), %l2 ! Find phys addr
- ldx [%l2], %l2 ! The following gets ugly: We need to load the following mask
- set _C_LABEL(kdatap), %l5
- ldx [%l5], %l5
-
- set _C_LABEL(ektext), %l1 ! And the ends...
- ldx [%l1], %l1
- set _C_LABEL(ekdata), %l4
- ldx [%l4], %l4
-
- sethi %hi(0xe0000000), %o0 ! V=1|SZ=11|NFO=0|IE=0
- sllx %o0, 32, %o0 ! Shift it into place
-
- sethi %hi(0x400000), %l6 ! Create a 4MB mask
- add %l6, -1, %l7
-
- mov -1, %o1 ! Create a nice mask
- sllx %o1, 41, %o1 ! Mask off high bits
- or %o1, 0xfff, %o1 ! We can just load this in 12 (of 13) bits
-
- andn %l2, %o1, %l2 ! Mask the phys page number
- andn %l5, %o1, %l5 ! Mask the phys page number
-
- or %l2, %o0, %l2 ! Now take care of the high bits
- or %l5, %o0, %l5 ! Now take care of the high bits
-
- wrpr %g0, PSTATE_KERN, %pstate ! Disable interrupts
-
-#ifdef DEBUG
- set 1f, %o0 ! Debug printf for TEXT page
- srlx %l0, 32, %o1
- srl %l0, 0, %o2
- or %l2, TLB_L|TLB_CP|TLB_CV|TLB_P, %o4 ! And low bits: L=1|CP=1|CV=1|E=0|P=1|W=1(ugh)|G=0
- srlx %o4, 32, %o3
- call _C_LABEL(prom_printf)
- srl %o4, 0, %o4
-
- set 1f, %o0 ! Debug printf for DATA page
- srlx %l3, 32, %o1
- srl %l3, 0, %o2
- or %l5, TLB_L|TLB_CP|TLB_CV|TLB_P|TLB_W, %o4 ! And low bits: L=1|CP=1|CV=1|E=0|P=1|W=1(ugh)|G=0
- srlx %o4, 32, %o3
- call _C_LABEL(prom_printf)
- srl %o4, 0, %o4
- .data
-1:
- .asciz "Setting DTLB entry %08x %08x data %08x %08x\r\n"
- _ALIGN
- .text
-#endif /* DEBUG */
- mov %l0, %o0 ! Demap all of kernel dmmu text segment
- mov %l3, %o1
- set 0x2000, %o2 ! 8K page size
- add %l1, %l7, %o5 ! Extend to 4MB boundary
- andn %o5, %l7, %o5
-0:
- stxa %o0, [%o0] ASI_DMMU_DEMAP ! Demap text segment
- membar #Sync
- cmp %o0, %o5
- bleu 0b
- add %o0, %o2, %o0
-
- add %l4, %l7, %o5 ! Extend to 4MB boundary
- andn %o5, %l7, %o5
-0:
- stxa %o1, [%o1] ASI_DMMU_DEMAP ! Demap data segment
- membar #Sync
- cmp %o1, %o5
- bleu 0b
- add %o1, %o2, %o1
-
- set (1<<14)-8, %o0 ! Clear out DCACHE
-1:
-dlflush2a:
- stxa %g0, [%o0] ASI_DCACHE_TAG ! clear DCACHE line
- membar #Sync
- brnz,pt %o0, 1b
- dec 8, %o0
-
- /*
- * First map data segment into the DMMU.
- */
- set TLB_TAG_ACCESS, %o0 ! Now map it back in with a locked TTE
- mov %l3, %o1
-#ifdef NO_VCACHE
- ! And low bits: L=1|CP=1|CV=0(ugh)|E=0|P=1|W=1|G=0
- or %l5, TLB_L|TLB_CP|TLB_P|TLB_W, %o2
-#else /* NO_VCACHE */
- ! And low bits: L=1|CP=1|CV=1|E=0|P=1|W=1|G=0
- or %l5, TLB_L|TLB_CP|TLB_CV|TLB_P|TLB_W, %o2
-#endif /* NO_VCACHE */
- set 1f, %o5
-2:
- stxa %o1, [%o0] ASI_DMMU ! Set VA for DSEG
- membar #Sync ! We may need more membar #Sync in here
- stxa %o2, [%g0] ASI_DMMU_DATA_IN ! Store TTE for DSEG
- membar #Sync ! We may need more membar #Sync in here
- flush %o5 ! Make IMMU see this too
-1:
- add %o1, %l6, %o1 ! increment VA
- cmp %o1, %l4 ! Next 4MB mapping....
- blu,pt %xcc, 2b
- add %o2, %l6, %o2 ! Increment tag
-
- /*
- * Next map the text segment into the DMMU so we can get at RODATA.
- */
- mov %l0, %o1
-#ifdef NO_VCACHE
- ! And low bits: L=1|CP=1|CV=0(ugh)|E=0|P=1|W=0|G=0
- or %l2, TLB_L|TLB_CP|TLB_P, %o2
-#else /* NO_VCACHE */
- ! And low bits: L=1|CP=1|CV=1|E=0|P=1|W=0|G=0
- or %l2, TLB_L|TLB_CP|TLB_CV|TLB_P, %o2
-#endif /* NO_VCACHE */
-2:
- stxa %o1, [%o0] ASI_DMMU ! Set VA for DSEG
- membar #Sync ! We may need more membar #Sync in here
- stxa %o2, [%g0] ASI_DMMU_DATA_IN ! Store TTE for DSEG
- membar #Sync ! We may need more membar #Sync in here
- flush %o5 ! Make IMMU see this too
- add %o1, %l6, %o1 ! increment VA
- cmp %o1, %l1 ! Next 4MB mapping....
- blu,pt %xcc, 2b
- add %o2, %l6, %o2 ! Increment tag
-
-#ifdef DEBUG
- set 1f, %o0 ! Debug printf
- srlx %l0, 32, %o1
- srl %l0, 0, %o2
- or %l2, TLB_L|TLB_CP|TLB_CV|TLB_P, %o4
- srlx %o4, 32, %o3
- call _C_LABEL(prom_printf)
- srl %o4, 0, %o4
- .data
-1:
- .asciz "Setting ITLB entry %08x %08x data %08x %08x\r\n"
- _ALIGN
- .text
-#endif /* DEBUG */
- /*
- * Finished the DMMU, now we need to do the IMMU which is more
- * difficult because we're execting instructions through the IMMU
- * while we're flushing it. We need to remap the entire kernel
- * to a new context, flush the entire context 0 IMMU, map it back
- * into context 0, switch to context 0, and flush context 1.
- *
- * Another interesting issue is that the flush instructions are
- * translated through the DMMU, therefore we need to enter the
- * mappings both in the IMMU and the DMMU so we can flush them
- * correctly.
- *
- * Start by mapping in the kernel text as context==1
- */
- set TLB_TAG_ACCESS, %o0
- or %l0, 1, %o1 ! Context = 1
- or %l2, TLB_CP|TLB_P, %o2 ! And low bits: L=0|CP=1|CV=0|E=0|P=1|G=0
-2:
- stxa %o1, [%o0] ASI_DMMU ! Make DMMU point to it
- membar #Sync ! We may need more membar #Sync in here
- stxa %o2, [%g0] ASI_DMMU_DATA_IN ! Store it
- membar #Sync ! We may need more membar #Sync in here
- stxa %o1, [%o0] ASI_IMMU ! Make IMMU point to it
- membar #Sync ! We may need more membar #Sync in here
- flush %o1-1 ! Make IMMU see this too
- stxa %o2, [%g0] ASI_IMMU_DATA_IN ! Store it
- membar #Sync ! We may need more membar #Sync in here
- flush %o5 ! Make IMMU see this too
- add %o1, %l6, %o1 ! increment VA
- cmp %o1, %l1 ! Next 4MB mapping....
- blu,pt %xcc, 2b
- add %o2, %l6, %o2 ! Increment tag
-
- !!
- !! Load 1 as primary context
- !!
- mov 1, %o0
- mov CTX_PRIMARY, %o1
- stxa %o0, [%o1] ASI_DMMU
- wrpr %g0, 0, %tl ! Make SURE we're nucleus mode
- membar #Sync ! This probably should be a flush, but it works
- flush %o5 ! This should be KERNBASE
-
- !!
- !! Demap entire context 0 kernel
- !!
- or %l0, DEMAP_PAGE_NUCLEUS, %o0 ! Context = Nucleus
- add %l1, %l7, %o1 ! Demap all of kernel text seg
- andn %o1, %l7, %o1 ! rounded up to 4MB.
- set 0x2000, %o2 ! 8K page size
-0:
- stxa %o0, [%o0] ASI_IMMU_DEMAP ! Demap it
- membar #Sync
- flush %o5 ! Assume low bits are benign
- cmp %o0, %o1
- bleu,pt %xcc, 0b ! Next page
- add %o0, %o2, %o0
-
- or %l3, DEMAP_PAGE_NUCLEUS, %o0 ! Context = Nucleus
- add %l4, %l7, %o1 ! Demap all of kernel data seg
- andn %o1, %l7, %o1 ! rounded up to 4MB.
-0:
- stxa %o0, [%o0] ASI_IMMU_DEMAP ! Demap it
- membar #Sync
- flush %o5 ! Assume low bits are benign
- cmp %o0, %o1
- bleu,pt %xcc, 0b ! Next page
- add %o0, %o2, %o0
+ wr %g0, FPRS_FEF, %fprs ! Turn on FPU
- !!
- !! Now, map in the kernel text as context==0
- !!
- set TLB_TAG_ACCESS, %o0
- mov %l0, %o1 ! Context = 0
-#ifdef NO_VCACHE
- ! And low bits: L=1|CP=1|CV=0(ugh)|E=0|P=1|W=1|G=0
- or %l2, TLB_L|TLB_CP|TLB_P, %o2
-#else /* NO_VCACHE */
- ! And low bits: L=1|CP=1|CV=1|E=0|P=1|W=1|G=0
- or %l2, TLB_L|TLB_CP|TLB_CV|TLB_P, %o2
-#endif /* NO_VCACHE */
-2:
- stxa %o1, [%o0] ASI_IMMU ! Make IMMU point to it
- membar #Sync ! We may need more membar #Sync in here
- stxa %o2, [%g0] ASI_IMMU_DATA_IN ! Store it
- membar #Sync ! We may need more membar #Sync in here
- flush %o5 ! Make IMMU see this too
- add %o1, %l6, %o1 ! increment VA
- cmp %o1, %l1 ! Next 4MB mapping....
- blu,pt %xcc, 2b
- add %o2, %l6, %o2 ! Increment tag
-
- !!
- !! Restore 0 as primary context
- !!
- mov CTX_PRIMARY, %o0
- stxa %g0, [%o0] ASI_DMMU
- membar #Sync ! No real reason for this XXXX
- flush %o5
-
- !!
- !! Demap context 1
- !!
- mov 1, %o1
- mov CTX_SECONDARY, %o0
- stxa %o1, [%o0] ASI_DMMU
- membar #Sync ! This probably should be a flush, but it works
- flush %l0
- mov DEMAP_CTX_SECONDARY, %o4
- stxa %o4, [%o4] ASI_DMMU_DEMAP
- membar #Sync
- stxa %o4, [%o4] ASI_IMMU_DEMAP
- membar #Sync
- flush %l0
- stxa %g0, [%o0] ASI_DMMU
- membar #Sync
- flush %l0
-
-#ifdef DEBUG
- set 1f, %o0 ! Debug printf
- call _C_LABEL(prom_printf)
- .data
-1:
- .asciz "Setting CPUINFO mappings...\r\n"
- _ALIGN
- .text
-#endif /* DEBUG */
-
- /*
- * Get pointer to our cpu_info struct
- */
-
- mov %g2, %l1 ! Load the interrupt stack's PA
-
- sethi %hi(0xa0000000), %l2 ! V=1|SZ=01|NFO=0|IE=0
- sllx %l2, 32, %l2 ! Shift it into place
-
- mov -1, %l3 ! Create a nice mask
- sllx %l3, 41, %l4 ! Mask off high bits
- or %l4, 0xfff, %l4 ! We can just load this in 12 (of 13) bits
-
- andn %l1, %l4, %l1 ! Mask the phys page number
-
- or %l2, %l1, %l1 ! Now take care of the high bits
-#ifdef NO_VCACHE
- or %l1, TLB_L|TLB_CP|TLB_P|TLB_W, %l2 ! And low bits: L=1|CP=1|CV=0|E=0|P=1|W=0|G=0
-#else /* NO_VCACHE */
- or %l1, TLB_L|TLB_CP|TLB_CV|TLB_P|TLB_W, %l2 ! And low bits: L=1|CP=1|CV=1|E=0|P=1|W=0|G=0
-#endif /* NO_VCACHE */
-
- !!
- !! Now, map in the interrupt stack as context==0
- !!
- set TLB_TAG_ACCESS, %l5
- sethi %hi(INTSTACK), %l0
- stxa %l0, [%l5] ASI_DMMU ! Make DMMU point to it
- membar #Sync ! We may need more membar #Sync in here
- stxa %l2, [%g0] ASI_DMMU_DATA_IN ! Store it
- membar #Sync ! We may need more membar #Sync in here
- flush %o5
-
- !!
- !! Set 0 as primary context XXX
- !!
- mov CTX_PRIMARY, %o0
- stxa %g0, [%o0] ASI_DMMU
- flush %o5
-
-!!! Make sure our stack's OK.
- sethi %hi(CPUINFO_VA+CI_INITSTACK), %l0
- ldx [%l0 + %lo(CPUINFO_VA+CI_INITSTACK)], %l0
- add %l0, - CC64FSZ - 80, %l0
- andn %l0, 0x0f, %l0 ! Needs to be 16-byte aligned
- sub %l0, BIAS, %l0 ! and biased
- mov %l0, %sp
- set 1, %fp
- clr %i7
-
- /*
- * Step 7: change the trap base register, and install our TSBs
- */
-
- /* Set the dmmu tsb */
- sethi %hi(0x1fff), %l2
- set _C_LABEL(tsb_dmmu), %l0
- ldx [%l0], %l0
- set _C_LABEL(tsbsize), %l1
- or %l2, %lo(0x1fff), %l2
- ld [%l1], %l1
- andn %l0, %l2, %l0 ! Mask off size and split bits
- or %l0, %l1, %l0 ! Make a TSB pointer
- set TSB, %l2
- stxa %l0, [%l2] ASI_DMMU ! Install data TSB pointer
- membar #Sync
-
-
- /* Set the immu tsb */
- sethi %hi(0x1fff), %l2
- set _C_LABEL(tsb_immu), %l0
- ldx [%l0], %l0
- set _C_LABEL(tsbsize), %l1
- or %l2, %lo(0x1fff), %l2
- ld [%l1], %l1
- andn %l0, %l2, %l0 ! Mask off size and split bits
- or %l0, %l1, %l0 ! Make a TSB pointer
- set TSB, %l2
- stxa %l0, [%l2] ASI_IMMU ! Install instruction TSB pointer
- membar #Sync ! We may need more membar #Sync in here
-
- /* Change the trap base register */
- set _C_LABEL(trapbase), %l1
- call _C_LABEL(prom_set_trap_table) ! Now we should be running 100% from our handlers
- mov %l1, %o0
- wrpr %l1, 0, %tba ! Make sure the PROM didn't foul up.
- wrpr %g0, WSTATE_KERN, %wstate
-
- call _C_LABEL(cpu_hatch)
+ ba cpu_initialize
nop
- NOTREACHED
#endif
/*
@@ -9445,9 +9061,6 @@ _C_LABEL(proc0paddr):
_C_LABEL(dlflush_start):
.xword dlflush1
.xword dlflush2
-#ifdef MULTIPROCESSOR
- .xword dlflush2a
-#endif
.xword dlflush3
.xword dlflush4
.xword dlflush5