From owner-svn-src-projects@FreeBSD.ORG Thu Jul 30 21:51:07 2009 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A30D3106566C; Thu, 30 Jul 2009 21:51:07 +0000 (UTC) (envelope-from nwhitehorn@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 8F2B28FC12; Thu, 30 Jul 2009 21:51:07 +0000 (UTC) (envelope-from nwhitehorn@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n6ULp7AW046970; Thu, 30 Jul 2009 21:51:07 GMT (envelope-from nwhitehorn@svn.freebsd.org) Received: (from nwhitehorn@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n6ULp7QX046959; Thu, 30 Jul 2009 21:51:07 GMT (envelope-from nwhitehorn@svn.freebsd.org) Message-Id: <200907302151.n6ULp7QX046959@svn.freebsd.org> From: Nathan Whitehorn Date: Thu, 30 Jul 2009 21:51:07 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r195982 - in projects/ppc64/sys: conf powerpc/aim powerpc/aim64 powerpc/include X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Jul 2009 21:51:07 -0000 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.@tocbase @@ -200,19 +201,19 @@ tocbase: ASENTRY(ofw_real_mode_entry) mflr 0 - lis 31,openfirmware_entry@ha - ld 31,openfirmware_entry@l(31) /* read client interface handler */ + lis 4,openfirmware_entry@ha + ld 4,openfirmware_entry@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 */