Refactor PowerPC (especially AIM) init sequence to be less baroque.

MFC after:	2 months
This commit is contained in:
Nathan Whitehorn 2015-01-18 18:32:43 +00:00
parent e751d176f3
commit bb80825435
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=277334
11 changed files with 92 additions and 178 deletions

View File

@ -11,6 +11,7 @@ SECTIONS
/* Read-only sections, merged into text segment: */
. = kernbase + SIZEOF_HEADERS;
PROVIDE (begin = . - SIZEOF_HEADERS);
.text :
{

View File

@ -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

View File

@ -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

View File

@ -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,89 +105,51 @@ 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()
*

View File

@ -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);

View File

@ -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

View File

@ -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>

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;