svn commit: r195982 - in projects/ppc64/sys: conf powerpc/aim
powerpc/aim64 powerpc/include
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Thu Jul 30 21:51:07 UTC 2009
Author: nwhitehorn
Date: Thu Jul 30 21:51:07 2009
New Revision: 195982
URL: http://svn.freebsd.org/changeset/base/195982
Log:
The kernel now tries (and fails, since there isn't one) to start init
after some more hacking with TOC pointers and with setfault().
More irritatingly, to deal with certain broken implementations of this
architecture (I'm looking at you, Cell) that only implement a 65-bit
virtual address space, I've had to reduce the accessible effective
address range to 45 bits. This needs a lot of reexamination, and fixing
it properly will probably involve some kind of global VSID hash table.
Deleted:
projects/ppc64/sys/powerpc/aim64/copyinout.c
Modified:
projects/ppc64/sys/conf/files.powerpc64
projects/ppc64/sys/powerpc/aim/copyinout.c
projects/ppc64/sys/powerpc/aim/trap.c
projects/ppc64/sys/powerpc/aim/vm_machdep.c
projects/ppc64/sys/powerpc/aim64/locore.S
projects/ppc64/sys/powerpc/aim64/machdep.c
projects/ppc64/sys/powerpc/aim64/mmu_oea64.c
projects/ppc64/sys/powerpc/aim64/trap_subr.S
projects/ppc64/sys/powerpc/include/frame.h
projects/ppc64/sys/powerpc/include/pcb.h
Modified: projects/ppc64/sys/conf/files.powerpc64
==============================================================================
--- projects/ppc64/sys/conf/files.powerpc64 Thu Jul 30 21:00:20 2009 (r195981)
+++ projects/ppc64/sys/conf/files.powerpc64 Thu Jul 30 21:51:07 2009 (r195982)
@@ -54,6 +54,7 @@ libkern/flsl.c standard
libkern/memmove.c standard
libkern/memset.c standard
powerpc/aim/clock.c optional aim
+powerpc/aim/copyinout.c optional aim
powerpc/aim/interrupt.c optional aim
powerpc/aim/mp_cpudep.c optional aim smp
powerpc/aim/nexus.c optional aim
@@ -63,7 +64,6 @@ powerpc/aim/platform_chrp.c optional aim
powerpc/aim/trap.c optional aim
powerpc/aim/uma_machdep.c optional aim
powerpc/aim/vm_machdep.c optional aim
-powerpc/aim64/copyinout.c optional aim
powerpc/aim64/locore.S optional aim no-obj
powerpc/aim64/machdep.c optional aim
powerpc/aim64/mmu_oea64.c optional aim
Modified: projects/ppc64/sys/powerpc/aim/copyinout.c
==============================================================================
--- projects/ppc64/sys/powerpc/aim/copyinout.c Thu Jul 30 21:00:20 2009 (r195981)
+++ projects/ppc64/sys/powerpc/aim/copyinout.c Thu Jul 30 21:51:07 2009 (r195982)
@@ -72,6 +72,33 @@ int setfault(faultbuf); /* defined in lo
/*
* Makes sure that the right segment of userspace is mapped in.
*/
+static __inline register_t
+va_to_vsid(pmap_t pm, const volatile void *va)
+{
+ #ifdef __powerpc64__
+ return (((uint64_t)pm->pm_context << 17) |
+ ((uintptr_t)va >> ADDR_SR_SHFT));
+ #else
+ return ((pm->pm_sr[(uintptr_t)va >> ADDR_SR_SHFT]) & SR_VSID_MASK);
+ #endif
+}
+
+#ifdef __powerpc64__
+static __inline void
+set_user_sr(register_t vsid)
+{
+ register_t esid, slb1, slb2;
+
+ esid = USER_SR;
+
+ slb1 = vsid << 12;
+ slb2 = (((esid << 1) | 1UL) << 27) | USER_SR;
+
+ __asm __volatile ("slbie %0; slbmte %1, %2" :: "r"(esid << 28),
+ "r"(slb1), "r"(slb2));
+ isync();
+}
+#else
static __inline void
set_user_sr(register_t vsid)
{
@@ -80,6 +107,7 @@ set_user_sr(register_t vsid)
__asm __volatile ("mtsr %0,%1" :: "n"(USER_SR), "r"(vsid));
isync();
}
+#endif
int
copyout(const void *kaddr, void *udaddr, size_t len)
@@ -103,13 +131,13 @@ copyout(const void *kaddr, void *udaddr,
up = udaddr;
while (len > 0) {
- p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
+ p = (char *)USER_ADDR + ((uintptr_t)up & ~SEGMENT_MASK);
l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
if (l > len)
l = len;
- set_user_sr(pm->pm_sr[(u_int)up >> ADDR_SR_SHFT]);
+ set_user_sr(va_to_vsid(pm,up));
bcopy(kp, p, l);
@@ -144,13 +172,13 @@ copyin(const void *udaddr, void *kaddr,
up = udaddr;
while (len > 0) {
- p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
+ p = (char *)USER_ADDR + ((uintptr_t)up & ~SEGMENT_MASK);
l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
if (l > len)
l = len;
- set_user_sr(pm->pm_sr[(u_int)up >> ADDR_SR_SHFT]);
+ set_user_sr(va_to_vsid(pm,up));
bcopy(p, kp, l);
@@ -218,14 +246,14 @@ subyte(void *addr, int byte)
td = PCPU_GET(curthread);
pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (char *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
+ p = (char *)((uintptr_t)USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
if (setfault(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
- set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
+ set_user_sr(va_to_vsid(pm,addr));
*p = (char)byte;
@@ -233,6 +261,33 @@ subyte(void *addr, int byte)
return (0);
}
+#ifdef __powerpc64__
+int
+suword32(void *addr, int word)
+{
+ struct thread *td;
+ pmap_t pm;
+ faultbuf env;
+ int *p;
+
+ td = PCPU_GET(curthread);
+ pm = &td->td_proc->p_vmspace->vm_pmap;
+ p = (int *)((uintptr_t)USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
+
+ if (setfault(env)) {
+ td->td_pcb->pcb_onfault = NULL;
+ return (-1);
+ }
+
+ set_user_sr(pm->pm_sr[(uintptr_t)addr >> ADDR_SR_SHFT]);
+
+ *p = word;
+
+ td->td_pcb->pcb_onfault = NULL;
+ return (0);
+}
+#endif
+
int
suword(void *addr, long word)
{
@@ -243,14 +298,14 @@ suword(void *addr, long word)
td = PCPU_GET(curthread);
pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (long *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
+ p = (long *)((uintptr_t)USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
if (setfault(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
- set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
+ set_user_sr(va_to_vsid(pm,addr));
*p = word;
@@ -258,12 +313,19 @@ suword(void *addr, long word)
return (0);
}
+#ifdef __powerpc64__
+int
+suword64(void *addr, int64_t word)
+{
+ return (suword(addr, (long)word));
+}
+#else
int
suword32(void *addr, int32_t word)
{
return (suword(addr, (long)word));
}
-
+#endif
int
fubyte(const void *addr)
@@ -276,14 +338,15 @@ fubyte(const void *addr)
td = PCPU_GET(curthread);
pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (u_char *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
+ p = (u_char *)((uintptr_t)USER_ADDR +
+ ((uintptr_t)addr & ~SEGMENT_MASK));
if (setfault(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
- set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
+ set_user_sr(va_to_vsid(pm,addr));
val = *p;
@@ -301,14 +364,14 @@ fuword(const void *addr)
td = PCPU_GET(curthread);
pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (long *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
+ p = (long *)((uintptr_t)USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
if (setfault(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
- set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
+ set_user_sr(va_to_vsid(pm,addr));
val = *p;
@@ -338,9 +401,10 @@ casuword(volatile u_long *addr, u_long o
td = PCPU_GET(curthread);
pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (u_long *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
+ p = (u_long *)((uintptr_t)USER_ADDR +
+ ((uintptr_t)addr & ~SEGMENT_MASK));
- set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
+ set_user_sr(va_to_vsid(pm,addr));
if (setfault(env)) {
td->td_pcb->pcb_onfault = NULL;
Modified: projects/ppc64/sys/powerpc/aim/trap.c
==============================================================================
--- projects/ppc64/sys/powerpc/aim/trap.c Thu Jul 30 21:00:20 2009 (r195981)
+++ projects/ppc64/sys/powerpc/aim/trap.c Thu Jul 30 21:51:07 2009 (r195982)
@@ -105,7 +105,9 @@ static struct powerpc_exception powerpc_
{ 0x0100, "system reset" },
{ 0x0200, "machine check" },
{ 0x0300, "data storage interrupt" },
+ { 0x0380, "data segment exception" },
{ 0x0400, "instruction storage interrupt" },
+ { 0x0480, "instruction segment exception" },
{ 0x0500, "external interrupt" },
{ 0x0600, "alignment" },
{ 0x0700, "program" },
@@ -493,7 +495,7 @@ trap_pfault(struct trapframe *frame, int
vm_map_t map;
vm_prot_t ftype;
int rv;
- u_int user_sr;
+ register_t user_sr;
td = curthread;
p = td->td_proc;
@@ -515,9 +517,16 @@ trap_pfault(struct trapframe *frame, int
if (p->p_vmspace == NULL)
return (SIGSEGV);
+ #ifdef __powerpc64__
+ user_sr = 0;
+ __asm ("slbmfev %0, %1"
+ : "=r"(user_sr)
+ : "r"(USER_SR));
+ #else
__asm ("mfsr %0, %1"
: "=r"(user_sr)
: "K"(USER_SR));
+ #endif
eva &= ADDR_PIDX | ADDR_POFF;
eva |= user_sr << ADDR_SR_SHFT;
map = &p->p_vmspace->vm_map;
Modified: projects/ppc64/sys/powerpc/aim/vm_machdep.c
==============================================================================
--- projects/ppc64/sys/powerpc/aim/vm_machdep.c Thu Jul 30 21:00:20 2009 (r195981)
+++ projects/ppc64/sys/powerpc/aim/vm_machdep.c Thu Jul 30 21:51:07 2009 (r195982)
@@ -129,6 +129,10 @@ static u_int sf_buf_alloc_want;
*/
static struct mtx sf_buf_lock;
+#ifdef __powerpc64__
+extern uintptr_t tocbase;
+#endif
+
/*
* Finish a fork operation, with process p2 nearly set up.
@@ -177,6 +181,9 @@ cpu_fork(struct thread *td1, struct proc
cf = (struct callframe *)tf - 1;
memset(cf, 0, sizeof(struct callframe));
+ #ifdef __powerpc64__
+ cf->cf_toc = tocbase;
+ #endif
cf->cf_func = (register_t)fork_return;
cf->cf_arg0 = (register_t)td2;
cf->cf_arg1 = (register_t)tf;
@@ -455,7 +462,12 @@ cpu_set_upcall(struct thread *td, struct
cf->cf_arg1 = (register_t)tf;
pcb2->pcb_sp = (register_t)cf;
+ #ifdef __powerpc64__
+ pcb2->pcb_lr = ((register_t *)fork_trampoline)[0];
+ pcb2->pcb_toc = ((register_t *)fork_trampoline)[1];
+ #else
pcb2->pcb_lr = (register_t)fork_trampoline;
+ #endif
pcb2->pcb_cpu.aim.usr_vsid = 0;
pcb2->pcb_cpu.aim.usr_esid = 0;
Modified: projects/ppc64/sys/powerpc/aim64/locore.S
==============================================================================
--- projects/ppc64/sys/powerpc/aim64/locore.S Thu Jul 30 21:00:20 2009 (r195981)
+++ projects/ppc64/sys/powerpc/aim64/locore.S Thu Jul 30 21:51:07 2009 (r195982)
@@ -191,6 +191,7 @@ ASENTRY(__start)
*/
.align 3
+ .globl tocbase
tocbase:
.llong .TOC. at tocbase
@@ -200,19 +201,19 @@ tocbase:
ASENTRY(ofw_real_mode_entry)
mflr 0
- lis 31,openfirmware_entry at ha
- ld 31,openfirmware_entry at l(31) /* read client interface handler */
+ lis 4,openfirmware_entry at ha
+ ld 4,openfirmware_entry at l(4) /* read client interface handler */
- mfmsr 30
- mtsprg3 30
- andi. 30, 30, ~(PSL_DR | PSL_IR | PSL_EE)@l
- mtmsrd 30
+ mfmsr 5
+ mtsprg3 5
+ andi. 5, 5, ~(PSL_DR | PSL_IR | PSL_EE)@l
+ mtmsrd 5
- mtctr 31
+ mtctr 4
bctrl
- mfsprg3 30
- mtmsrd 30
+ mfsprg3 5
+ mtmsrd 5
mtlr 0
blr
@@ -228,13 +229,34 @@ ASENTRY(setfault)
mflr 0
mfcr 12
mfsprg 4,0
- lwz 4,PC_CURTHREAD(4)
- lwz 4,TD_PCB(4)
- stw 3,PCB_ONFAULT(4)
- stw 0,0(3)
- stw 1,4(3)
- stw 2,8(3)
- stmw 12,12(3)
+ ld 4,PC_CURTHREAD(4)
+ ld 4,TD_PCB(4)
+ std 3,PCB_ONFAULT(4)
+ std 0,0(3)
+ std 1,8(3)
+ std 2,16(3)
+
+ std %r12,24(%r3) /* Save the non-volatile GP regs. */
+ std %r13,24+1*8(%r3)
+ std %r14,24+2*8(%r3)
+ std %r15,24+3*8(%r3)
+ std %r16,24+4*8(%r3)
+ std %r17,24+5*8(%r3)
+ std %r18,24+6*8(%r3)
+ std %r19,24+7*8(%r3)
+ std %r20,24+8*8(%r3)
+ std %r21,24+9*8(%r3)
+ std %r22,24+10*8(%r3)
+ std %r23,24+11*8(%r3)
+ std %r24,24+12*8(%r3)
+ std %r25,24+13*8(%r3)
+ std %r26,24+14*8(%r3)
+ std %r27,24+15*8(%r3)
+ std %r28,24+16*8(%r3)
+ std %r29,24+17*8(%r3)
+ std %r30,24+18*8(%r3)
+ std %r31,24+19*8(%r3)
+
xor 3,3,3
blr
Modified: projects/ppc64/sys/powerpc/aim64/machdep.c
==============================================================================
--- projects/ppc64/sys/powerpc/aim64/machdep.c Thu Jul 30 21:00:20 2009 (r195981)
+++ projects/ppc64/sys/powerpc/aim64/machdep.c Thu Jul 30 21:51:07 2009 (r195982)
@@ -394,9 +394,9 @@ powerpc_init(u_int startkernel, u_int en
bcopy(&trapcode, (void *)EXC_TRC, (size_t)&trapsize);
bcopy(&trapcode, (void *)EXC_BPT, (size_t)&trapsize);
#endif
- bcopy(&dsitrap, (void *)(EXC_DSI), (size_t)&dsisize);
+ bcopy(&dsitrap, (void *)EXC_DSI, (size_t)&dsisize);
bcopy(&trapcode, (void *)EXC_DSE, (size_t)&trapsize);
- bcopy(&alitrap, (void *)(EXC_ALI), (size_t)&alisize);
+ bcopy(&alitrap, (void *)EXC_ALI, (size_t)&alisize);
bcopy(&trapcode, (void *)EXC_ISI, (size_t)&trapsize);
bcopy(&trapcode, (void *)EXC_ISE, (size_t)&trapsize);
bcopy(&trapcode, (void *)EXC_EXI, (size_t)&trapsize);
Modified: projects/ppc64/sys/powerpc/aim64/mmu_oea64.c
==============================================================================
--- projects/ppc64/sys/powerpc/aim64/mmu_oea64.c Thu Jul 30 21:00:20 2009 (r195981)
+++ projects/ppc64/sys/powerpc/aim64/mmu_oea64.c Thu Jul 30 21:51:07 2009 (r195982)
@@ -171,7 +171,7 @@ static __inline uint64_t
va_to_vsid(pmap_t pm, vm_offset_t va)
{
#ifdef __powerpc64__
- return (((uint64_t)pm->pm_context << 36) |
+ return (((uint64_t)pm->pm_context << 17) |
((uintptr_t)va >> ADDR_SR_SHFT));
#else
return ((pm->pm_sr[(uintptr_t)va >> ADDR_SR_SHFT]) & SR_VSID_MASK);
@@ -742,7 +742,7 @@ moea64_bridge_cpu_bootstrap(mmu_t mmup,
continue;
/* The right-most bit is a validity bit */
- slb1 = ((register_t)kernel_pmap->pm_context << 36) |
+ slb1 = ((register_t)kernel_pmap->pm_context << 17) |
(kernel_pmap->pm_sr[i] >> 1);
slb1 <<= 12;
slb2 = kernel_pmap->pm_sr[i] << 27 | i;
@@ -926,7 +926,7 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_o
/*
* Initialize the kernel pmap (which is statically allocated).
*/
- kernel_pmap->pm_context = 0;
+ kernel_pmap->pm_context = 0xfffff;
#ifdef __powerpc64__
for (i = 0; i < 16; i++)
kernel_pmap->pm_sr[i] = (i << 1) | 1;
@@ -979,8 +979,6 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_o
*/
moea64_pinit(mmup, &ofw_pmap);
- ofw_pmap.pm_sr[KERNEL_SR] = kernel_pmap->pm_sr[KERNEL_SR];
- ofw_pmap.pm_sr[KERNEL2_SR] = kernel_pmap->pm_sr[KERNEL2_SR];
if ((chosen = OF_finddevice("/chosen")) == -1)
panic("moea64_bootstrap: can't find /chosen");
@@ -1841,6 +1839,7 @@ moea64_pinit(mmu_t mmu, pmap_t pmap)
moea64_vsid_bitmap[n] |= mask;
#ifdef __powerpc64__
+printf("Assigning new context: %#x, hash %#x\n",moea64_vsidcontext,hash);
pmap->pm_context = hash;
for (i = 0; i < NSEGS; i++)
pmap->pm_sr[i] = 0;
Modified: projects/ppc64/sys/powerpc/aim64/trap_subr.S
==============================================================================
--- projects/ppc64/sys/powerpc/aim64/trap_subr.S Thu Jul 30 21:00:20 2009 (r195981)
+++ projects/ppc64/sys/powerpc/aim64/trap_subr.S Thu Jul 30 21:51:07 2009 (r195982)
@@ -55,7 +55,7 @@ restoresrs:
mr %r28, %r27
lwz %r27, PM_CONTEXT(%r27);
instslb:
- li %r30, 31;
+ li %r30, 12;
sld %r30, %r27, %r30;
ld %r31, PM_SR(%r28);
@@ -554,7 +554,7 @@ dbtrap:
or. %r3,%r3,%r3
bne dbleave
/* This wasn't for KDB, so switch to real trap: */
- ld %r3,FRAME_EXC+8(%r1) /* save exception */
+ ld %r3,FRAME_EXC+16(%r1) /* save exception */
GET_CPUINFO(%r4)
std %r3,(PC_DBSAVE+CPUSAVE_R31)(%r4)
FRAME_LEAVE(PC_DBSAVE)
Modified: projects/ppc64/sys/powerpc/include/frame.h
==============================================================================
--- projects/ppc64/sys/powerpc/include/frame.h Thu Jul 30 21:00:20 2009 (r195981)
+++ projects/ppc64/sys/powerpc/include/frame.h Thu Jul 30 21:51:07 2009 (r195982)
@@ -79,6 +79,19 @@ struct trapframe {
/*
* Call frame for PowerPC used during fork.
*/
+#ifdef __powerpc64__
+struct callframe {
+ register_t cf_dummy_fp; /* dummy frame pointer */
+ register_t cf_cr;
+ register_t cf_lr;
+ register_t cf_compiler;
+ register_t cf_linkeditor;
+ register_t cf_toc;
+ register_t cf_func;
+ register_t cf_arg0;
+ register_t cf_arg1;
+};
+#else
struct callframe {
register_t cf_dummy_fp; /* dummy frame pointer */
register_t cf_lr; /* space for link register save */
@@ -86,6 +99,10 @@ struct callframe {
register_t cf_arg0;
register_t cf_arg1;
};
+#endif
+
+/* Definitions for syscalls */
+#define FIRSTARG 3 /* first arg in reg 3 */
/* Definitions for syscalls */
#define FIRSTARG 3 /* first arg in reg 3 */
Modified: projects/ppc64/sys/powerpc/include/pcb.h
==============================================================================
--- projects/ppc64/sys/powerpc/include/pcb.h Thu Jul 30 21:00:20 2009 (r195981)
+++ projects/ppc64/sys/powerpc/include/pcb.h Thu Jul 30 21:51:07 2009 (r195982)
@@ -35,7 +35,7 @@
#ifndef _MACHINE_PCB_H_
#define _MACHINE_PCB_H_
-typedef int faultbuf[25];
+typedef register_t faultbuf[25];
struct pcb {
register_t pcb_context[20]; /* non-volatile r14-r31 */
More information about the svn-src-projects
mailing list