summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2015-01-18 18:32:43 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2015-01-18 18:32:43 +0000
commit3511827a804deda5b4a1e167acbf8c3086c173c7 (patch)
tree4dde9cc1d47683a020399dde86b754943c1621d5
parent1ac50c4c33db8aa0a2923a7f2a0e25cbdee3a40b (diff)
downloadFreeBSD-src-3511827a804deda5b4a1e167acbf8c3086c173c7.zip
FreeBSD-src-3511827a804deda5b4a1e167acbf8c3086c173c7.tar.gz
Refactor PowerPC (especially AIM) init sequence to be less baroque.
MFC after: 2 months
-rw-r--r--sys/conf/ldscript.powerpc1
-rw-r--r--sys/conf/ldscript.powerpc643
-rw-r--r--sys/powerpc/aim/locore32.S56
-rw-r--r--sys/powerpc/aim/locore64.S124
-rw-r--r--sys/powerpc/aim/machdep.c18
-rw-r--r--sys/powerpc/aim/trap_subr64.S15
-rw-r--r--sys/powerpc/booke/locore.S22
-rw-r--r--sys/powerpc/include/trap.h3
-rw-r--r--sys/powerpc/ofw/ofw_machdep.c16
-rw-r--r--sys/powerpc/powerpc/intr_machdep.c5
-rw-r--r--sys/powerpc/powerpc/vm_machdep.c7
11 files changed, 92 insertions, 178 deletions
diff --git a/sys/conf/ldscript.powerpc b/sys/conf/ldscript.powerpc
index efc0dfd..b190dc1 100644
--- a/sys/conf/ldscript.powerpc
+++ b/sys/conf/ldscript.powerpc
@@ -11,6 +11,7 @@ SECTIONS
/* Read-only sections, merged into text segment: */
. = kernbase + SIZEOF_HEADERS;
+ PROVIDE (begin = . - SIZEOF_HEADERS);
.text :
{
diff --git a/sys/conf/ldscript.powerpc64 b/sys/conf/ldscript.powerpc64
index ce23551..dba7455 100644
--- a/sys/conf/ldscript.powerpc64
+++ b/sys/conf/ldscript.powerpc64
@@ -11,6 +11,7 @@ SECTIONS
/* Read-only sections, merged into text segment: */
. = kernbase + SIZEOF_HEADERS;
+ PROVIDE (begin = . - SIZEOF_HEADERS);
.text :
{
@@ -68,7 +69,7 @@ SECTIONS
.toc1 : ALIGN(8) { *(.toc1) }
.opd : ALIGN(8) { KEEP (*(.opd)) }
.branch_lt : ALIGN(8) { *(.branch_lt) }
- .got : ALIGN(8) { *(.got .toc) }
+ .got : ALIGN(8) { __tocbase = .; *(.got .toc) }
.dynamic : { *(.dynamic) }
/* Put .ctors and .dtors next to the .got2 section, so that the pointers
diff --git a/sys/powerpc/aim/locore32.S b/sys/powerpc/aim/locore32.S
index 8cee665..6e462a0 100644
--- a/sys/powerpc/aim/locore32.S
+++ b/sys/powerpc/aim/locore32.S
@@ -76,29 +76,19 @@
.globl kernbase
.set kernbase, KERNBASE
-#define TMPSTKSZ 8192 /* 8K temporary stack */
-
/*
* Globals
*/
.data
+ .align 3
+GLOBAL(__startkernel)
+ .long begin
+GLOBAL(__endkernel)
+ .long end
.align 4
+#define TMPSTKSZ 8192 /* 8K temporary stack */
GLOBAL(tmpstk)
.space TMPSTKSZ
-GLOBAL(esym)
- .long 0 /* end of symbol table */
-
-#define INTRCNT_COUNT 256 /* max(HROWPIC_IRQMAX,OPENPIC_IRQMAX) */
-GLOBAL(intrnames)
- .space INTRCNT_COUNT * (MAXCOMLEN + 1) * 2
-GLOBAL(sintrnames)
- .long INTRCNT_COUNT * (MAXCOMLEN + 1) * 2
-
- .align 4
-GLOBAL(intrcnt)
- .space INTRCNT_COUNT * 4 * 2
-GLOBAL(sintrcnt)
- .long INTRCNT_COUNT * 4 * 2
.text
.globl btext
@@ -142,43 +132,9 @@ __start:
cmplw 8,9
blt 2b
- /* Save the argument pointer and length */
- mr 20,6
- mr 21,7
-
- lis 8,openfirmware_entry@ha
- stw 5,openfirmware_entry@l(8) /* save client interface handler */
-
lis 1,(tmpstk+TMPSTKSZ-16)@ha
addi 1,1,(tmpstk+TMPSTKSZ-16)@l
- mfmsr 0
- lis 9,ofmsr@ha
- stwu 0,ofmsr@l(9)
-
- mfsprg0 0 /* save SPRG0-3 */
- stw 0,4(9) /* ofmsr[1] = sprg0 */
- mfsprg1 0
- stw 0,8(9) /* ofmsr[2] = sprg1 */
- mfsprg2 0
- stw 0,12(9) /* ofmsr[3] = sprg2 */
- mfsprg3 0
- stw 0,16(9) /* ofmsr[4] = sprg3 */
-
- bl OF_initial_setup
-
- lis 3,kernel_text@ha
- addi 3,3,kernel_text@l
-
- lis 4,end@ha
- addi 4,4,end@l
- add 4,4,3
- mr 5,4
-
- /* Restore the argument pointer and length */
- mr 6,20
- mr 7,21
-
bl powerpc_init
mr %r1, %r3
li %r3, 0
diff --git a/sys/powerpc/aim/locore64.S b/sys/powerpc/aim/locore64.S
index 0c26e01..4865e75 100644
--- a/sys/powerpc/aim/locore64.S
+++ b/sys/powerpc/aim/locore64.S
@@ -68,36 +68,28 @@
/* Locate the per-CPU data structure */
#define GET_CPUINFO(r) \
mfsprg0 r
+#define GET_TOCBASE(r) \
+ li r,TRAP_TOCBASE; /* Magic address for TOC */ \
+ ld r,0(r)
-/*
- * Compiled KERNBASE location and the kernel load address
- */
- .globl kernbase
- .set kernbase, KERNBASE
-
-#define TMPSTKSZ 16384 /* 16K temporary stack */
+/* Glue for linker script */
+.globl kernbase
+.set kernbase, KERNBASE
/*
* Globals
*/
.data
+ .align 3
+GLOBAL(__startkernel)
+ .llong begin
+GLOBAL(__endkernel)
+ .llong end
+
.align 4
+#define TMPSTKSZ 16384 /* 16K temporary stack */
GLOBAL(tmpstk)
.space TMPSTKSZ
-GLOBAL(esym)
- .llong 0 /* end of symbol table */
-
-#define INTRCNT_COUNT 256 /* max(HROWPIC_IRQMAX,OPENPIC_IRQMAX) */
-GLOBAL(intrnames)
- .space INTRCNT_COUNT * (MAXCOMLEN + 1) * 2
-GLOBAL(sintrnames)
- .quad INTRCNT_COUNT * (MAXCOMLEN + 1) * 2
-
- .align 4
-GLOBAL(intrcnt)
- .space INTRCNT_COUNT * 4 * 2
-GLOBAL(sintrcnt)
- .quad INTRCNT_COUNT * 4 * 2
.text
.globl btext
@@ -113,90 +105,52 @@ kernel_text:
/*
* Startup entry. Note, this must be the first thing in the text
* segment!
+ *
+ * Calling convention:
+ * r3: Flattened Device Tree pointer (or zero)
+ * r4: ignored
+ * r5: OF client interface pointer (or zero)
+ * r6: Loader metadata pointer (or zero)
*/
.text
ASENTRY_NOPROF(__start)
- li 8,0
- li 9,0x100
- mtctr 9
-1:
- dcbf 0,8
- icbi 0,8
- addi 8,8,0x20
- bdnz 1b
- sync
- isync
-
- /* Save the argument pointer and length */
- mr 20,6
- mr 21,7
-
- lis 8,openfirmware_entry@ha
- std 5,openfirmware_entry@l(8) /* save client interface handler */
+ /* Set up the TOC pointer */
+ b 0f
+ .align 3
+0: nop
+ bl 1f
+ .llong __tocbase + 0x8000
+1: mflr %r2
+ ld %r2,0(%r2)
/* Set up the stack pointer */
- lis 1,(tmpstk+TMPSTKSZ-48)@ha
- addi 1,1,(tmpstk+TMPSTKSZ-48)@l
-
- /* Set up the TOC pointer */
- lis 2,tocbase@ha
- ld 2,tocbase@l(2)
-
- mfmsr 0
- lis 9,ofmsr@ha
- stdu 0,ofmsr@l(9)
-
- mfsprg0 0 /* save SPRG0-3 */
- std 0,8(9) /* ofmsr[1] = sprg0 */
- mfsprg1 0
- std 0,16(9) /* ofmsr[2] = sprg1 */
- mfsprg2 0
- std 0,24(9) /* ofmsr[3] = sprg2 */
- mfsprg3 0
- std 0,32(9) /* ofmsr[4] = sprg3 */
+ lis %r1,(tmpstk+TMPSTKSZ-48)@ha
+ addi %r1,%r1,(tmpstk+TMPSTKSZ-48)@l
/* Switch to 64-bit mode */
- mfmsr 9
- li 8,1
- insrdi 9,8,1,0
- mtmsrd 9
+ mfmsr %r9
+ li %r8,1
+ insrdi %r9,%r8,1,0
+ mtmsrd %r9
isync
- bl OF_initial_setup
- nop
-
- lis 3,kernbase@ha
- addi 3,3,kernbase@l
-
- lis 4,end@ha
- addi 4,4,end@l
- add 4,4,3
- mr 5,4
-
- /* Restore the argument pointer and length */
- mr 6,20
- mr 7,21
-
+ /* Begin CPU init */
+ mr %r4,%r2 /* Replace ignored r4 with tocbase for trap handlers */
bl powerpc_init
nop
+
+ /* Set stack pointer to new value and branch to mi_startup */
mr %r1, %r3
li %r3, 0
std %r3, 0(%r1)
bl mi_startup
nop
+
+ /* If this returns (it won't), go back to firmware */
b OF_exit
nop
/*
- * PPC64 ABI TOC base
- */
-
- .align 3
- .globl tocbase
-tocbase:
- .llong .TOC.@tocbase
-
-/*
* int setfault()
*
* Similar to setjmp to setup for handling faults on accesses to user memory.
diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c
index d1413a2..fdbe48b 100644
--- a/sys/powerpc/aim/machdep.c
+++ b/sys/powerpc/aim/machdep.c
@@ -223,7 +223,7 @@ cpu_startup(void *dummy)
vm_pager_bufferinit();
}
-extern char kernel_text[], _end[];
+extern vm_offset_t __startkernel, __endkernel;
#ifndef __powerpc64__
/* Bits for running on 64-bit systems in 32-bit mode. */
@@ -244,13 +244,12 @@ extern void *dblow, *dbsize;
extern void *imisstrap, *imisssize;
extern void *dlmisstrap, *dlmisssize;
extern void *dsmisstrap, *dsmisssize;
-char save_trap_init[0x2f00]; /* EXC_LAST */
uintptr_t
-powerpc_init(vm_offset_t startkernel, vm_offset_t endkernel,
- vm_offset_t basekernel, void *mdp)
+powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp)
{
struct pcpu *pc;
+ vm_offset_t startkernel, endkernel;
void *generictrap;
size_t trap_offset;
void *kmdp;
@@ -273,8 +272,12 @@ powerpc_init(vm_offset_t startkernel, vm_offset_t endkernel,
trap_offset = 0;
cacheline_warn = 0;
- /* Save trap vectors. */
- ofw_save_trap_vec(save_trap_init);
+ /* Store boot environment state */
+ OF_initial_setup((void *)fdt, NULL, (int (*)(void *))ofentry);
+
+ /* First guess at start/end kernel positions */
+ startkernel = __startkernel;
+ endkernel = __endkernel;
#ifdef WII
/*
@@ -490,6 +493,9 @@ powerpc_init(vm_offset_t startkernel, vm_offset_t endkernel,
#else /* powerpc64 */
cpu_features |= PPC_FEATURE_64;
generictrap = &trapcode;
+
+ /* Set TOC base so that the interrupt code can get at it */
+ *((register_t *)TRAP_TOCBASE) = toc;
#endif
bcopy(&rstcode, (void *)(EXC_RST + trap_offset), (size_t)&rstsize);
diff --git a/sys/powerpc/aim/trap_subr64.S b/sys/powerpc/aim/trap_subr64.S
index 0dc46b3..ec3c925 100644
--- a/sys/powerpc/aim/trap_subr64.S
+++ b/sys/powerpc/aim/trap_subr64.S
@@ -310,8 +310,7 @@ cpu_reset:
lis %r1,(tmpstk+TMPSTKSZ-48)@ha /* get new SP */
addi %r1,%r1,(tmpstk+TMPSTKSZ-48)@l
- lis %r3,tocbase@ha
- ld %r2,tocbase@l(%r3)
+ GET_TOCBASE(%r2)
bl CNAME(cpudep_ap_early_bootstrap) /* Set PCPU */
nop
lis %r3,1@l
@@ -445,8 +444,7 @@ kern_slbtrap:
addi %r1,%r1,PC_SLBSTACK-48+1024
li %r2,~15
and %r1,%r1,%r2
- lis %r3,tocbase@ha
- ld %r2,tocbase@l(%r3)
+ GET_TOCBASE(%r2)
mflr %r3
andi. %r3,%r3,0xff80
mfdar %r4
@@ -683,8 +681,7 @@ k_trap:
FRAME_SETUP(PC_TEMPSAVE)
/* Call C interrupt dispatcher: */
trapagain:
- lis %r3,tocbase@ha
- ld %r2,tocbase@l(%r3)
+ GET_TOCBASE(%r2)
addi %r3,%r1,48
bl CNAME(powerpc_interrupt)
nop
@@ -711,8 +708,7 @@ CNAME(trapexit):
ori %r3,%r3,PSL_EE@l
mtmsr %r3
isync
- lis %r3,tocbase@ha
- ld %r2,tocbase@l(%r3)
+ GET_TOCBASE(%r2)
addi %r3,%r1,48
bl CNAME(ast)
nop
@@ -760,8 +756,7 @@ dbtrap:
FRAME_SETUP(PC_DBSAVE)
/* Call C trap code: */
- lis %r3,tocbase@ha
- ld %r2,tocbase@l(%r3)
+ GET_TOCBASE(%r2)
addi %r3,%r1,48
bl CNAME(db_trap_glue)
nop
diff --git a/sys/powerpc/booke/locore.S b/sys/powerpc/booke/locore.S
index 514afa6..0fcca91 100644
--- a/sys/powerpc/booke/locore.S
+++ b/sys/powerpc/booke/locore.S
@@ -207,7 +207,7 @@ done_mapping:
*/
lis %r1, tmpstack@ha
addi %r1, %r1, tmpstack@l
- addi %r1, %r1, (TMPSTACKSZ - 8)
+ addi %r1, %r1, (TMPSTACKSZ - 16)
/*
* Initialise exception vector offsets
@@ -367,7 +367,7 @@ bp_tlb1_end:
*/
lis %r1, tmpstack@ha
addi %r1, %r1, tmpstack@l
- addi %r1, %r1, (TMPSTACKSZ - 8)
+ addi %r1, %r1, (TMPSTACKSZ - 16)
/*
* Initialise exception vector offsets
@@ -757,6 +757,8 @@ setfault:
.align 4
tmpstack:
.space TMPSTACKSZ
+tmpstackbound:
+ .space 10240 /* XXX: this really should not be necessary */
/*
* Compiled KERNBASE locations
@@ -764,20 +766,4 @@ tmpstack:
.globl kernbase
.set kernbase, KERNBASE
-/*
- * Globals
- */
-#define INTRCNT_COUNT 256 /* max(HROWPIC_IRQMAX,OPENPIC_IRQMAX) */
-
-GLOBAL(intrnames)
- .space INTRCNT_COUNT * (MAXCOMLEN + 1) * 2
-GLOBAL(sintrnames)
- .long INTRCNT_COUNT * (MAXCOMLEN + 1) * 2
-
- .align 4
-GLOBAL(intrcnt)
- .space INTRCNT_COUNT * 4 * 2
-GLOBAL(sintrcnt)
- .long INTRCNT_COUNT * 4 * 2
-
#include <powerpc/booke/trap_subr.S>
diff --git a/sys/powerpc/include/trap.h b/sys/powerpc/include/trap.h
index 211afcf..3b1ade5 100644
--- a/sys/powerpc/include/trap.h
+++ b/sys/powerpc/include/trap.h
@@ -123,6 +123,9 @@
/* DTrace trap opcode. */
#define EXC_DTRACE 0x7c810808
+/* Magic pointer to store TOC base for trap handlers on ppc64 */
+#define TRAP_TOCBASE 0x1f8
+
#ifndef LOCORE
struct trapframe;
struct pcb;
diff --git a/sys/powerpc/ofw/ofw_machdep.c b/sys/powerpc/ofw/ofw_machdep.c
index cc44847..1c02fa3 100644
--- a/sys/powerpc/ofw/ofw_machdep.c
+++ b/sys/powerpc/ofw/ofw_machdep.c
@@ -66,8 +66,8 @@ extern register_t ofmsr[5];
extern void *openfirmware_entry;
static void *fdt;
int ofw_real_mode;
-extern char save_trap_init[0x2f00]; /* EXC_LAST */
-char save_trap_of[0x2f00]; /* EXC_LAST */
+char save_trap_init[0x2f00]; /* EXC_LAST */
+char save_trap_of[0x2f00]; /* EXC_LAST */
int ofwcall(void *);
static int openfirmware(void *args);
@@ -257,18 +257,30 @@ ofw_mem_regions(struct mem_region *memp, int *memsz,
void
OF_initial_setup(void *fdt_ptr, void *junk, int (*openfirm)(void *))
{
+ ofmsr[0] = mfmsr();
+ #ifdef __powerpc64__
+ ofmsr[0] &= ~PSL_SF;
+ #endif
+ __asm __volatile("mfsprg0 %0" : "=&r"(ofmsr[1]));
+ __asm __volatile("mfsprg1 %0" : "=&r"(ofmsr[2]));
+ __asm __volatile("mfsprg2 %0" : "=&r"(ofmsr[3]));
+ __asm __volatile("mfsprg3 %0" : "=&r"(ofmsr[4]));
+
if (ofmsr[0] & PSL_DR)
ofw_real_mode = 0;
else
ofw_real_mode = 1;
fdt = fdt_ptr;
+ openfirmware_entry = openfirm;
#ifdef FDT_DTB_STATIC
/* Check for a statically included blob */
if (fdt == NULL)
fdt = &fdt_static_dtb;
#endif
+
+ ofw_save_trap_vec(save_trap_init);
}
boolean_t
diff --git a/sys/powerpc/powerpc/intr_machdep.c b/sys/powerpc/powerpc/intr_machdep.c
index cc7624f..b481279 100644
--- a/sys/powerpc/powerpc/intr_machdep.c
+++ b/sys/powerpc/powerpc/intr_machdep.c
@@ -127,6 +127,11 @@ static u_int nirqs = 0; /* Allocated IRQs. */
#endif
static u_int stray_count;
+u_long intrcnt[INTR_VECTORS];
+char intrnames[INTR_VECTORS * MAXCOMLEN];
+size_t sintrcnt = sizeof(intrcnt);
+size_t sintrnames = sizeof(intrnames);
+
device_t root_pic;
#ifdef SMP
diff --git a/sys/powerpc/powerpc/vm_machdep.c b/sys/powerpc/powerpc/vm_machdep.c
index d684094..c816e32 100644
--- a/sys/powerpc/powerpc/vm_machdep.c
+++ b/sys/powerpc/powerpc/vm_machdep.c
@@ -99,11 +99,6 @@
#include <vm/vm_map.h>
#include <vm/vm_extern.h>
-#ifdef __powerpc64__
-extern uintptr_t tocbase;
-#endif
-
-
/*
* Finish a fork operation, with process p2 nearly set up.
* Copy and update the pcb, set up the stack so that the child
@@ -149,7 +144,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
cf = (struct callframe *)tf - 1;
memset(cf, 0, sizeof(struct callframe));
#ifdef __powerpc64__
- cf->cf_toc = tocbase;
+ cf->cf_toc = ((register_t *)fork_return)[1];
#endif
cf->cf_func = (register_t)fork_return;
cf->cf_arg0 = (register_t)td2;
OpenPOWER on IntegriCloud