diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2007-03-20 20:59:55 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2007-03-20 20:59:55 +0000 |
commit | edb06578c73fe05fb3c9ab52a47e1d0a34eca656 (patch) | |
tree | 0c292f80e38cc053d22638c7a85f354f2a842154 /sys | |
parent | c0b399741b60996c0b30aaa0dc02061dc731634c (diff) |
Move macppc to __HAVE_CPUINFO, and make locore.S and trap.c suitable for
MULTIPROCESSOR. From now on sprg0 holds a pointer to struct cpuinfo, which
is used to spill registers to during trap instead of the globals we used to
use for that purpose. Bits and pieces from NetBSD. Help from drahn@ and art@.
Tested by xsa@, thib@, miod@, gwk@, deraadt@.
ok drahn@, gwk@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/macppc/dev/macintr.c | 38 | ||||
-rw-r--r-- | sys/arch/macppc/dev/openpic.c | 38 | ||||
-rw-r--r-- | sys/arch/macppc/include/lock.h | 3 | ||||
-rw-r--r-- | sys/arch/macppc/macppc/clock.c | 4 | ||||
-rw-r--r-- | sys/arch/macppc/macppc/cpu.c | 10 | ||||
-rw-r--r-- | sys/arch/macppc/macppc/genassym.cf | 18 | ||||
-rw-r--r-- | sys/arch/macppc/macppc/locore.S | 257 | ||||
-rw-r--r-- | sys/arch/macppc/macppc/machdep.c | 7 | ||||
-rw-r--r-- | sys/arch/powerpc/include/_types.h | 5 | ||||
-rw-r--r-- | sys/arch/powerpc/include/cpu.h | 101 | ||||
-rw-r--r-- | sys/arch/powerpc/include/intr.h | 26 | ||||
-rw-r--r-- | sys/arch/powerpc/include/lock.h | 112 | ||||
-rw-r--r-- | sys/arch/powerpc/include/pcb.h | 4 | ||||
-rw-r--r-- | sys/arch/powerpc/powerpc/fpu.c | 16 | ||||
-rw-r--r-- | sys/arch/powerpc/powerpc/process_machdep.c | 22 | ||||
-rw-r--r-- | sys/arch/powerpc/powerpc/trap.c | 69 | ||||
-rw-r--r-- | sys/arch/powerpc/powerpc/vm_machdep.c | 20 |
17 files changed, 537 insertions, 213 deletions
diff --git a/sys/arch/macppc/dev/macintr.c b/sys/arch/macppc/dev/macintr.c index 0d3848b5dde..1f0c819281b 100644 --- a/sys/arch/macppc/dev/macintr.c +++ b/sys/arch/macppc/dev/macintr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: macintr.c,v 1.31 2007/03/01 15:00:57 mickey Exp $ */ +/* $OpenBSD: macintr.c,v 1.32 2007/03/20 20:59:53 kettenis Exp $ */ /*- * Copyright (c) 1995 Per Fogelstrom @@ -500,10 +500,11 @@ mac_ext_intr() int irq = 0; int o_imen, r_imen; int pcpl; + struct cpu_info *ci = curcpu(); struct intrhand *ih; volatile unsigned long int_state; - pcpl = cpl; /* Turn off all */ + pcpl = ci->ci_cpl; /* Turn off all */ int_state = read_irq(); if (int_state == 0) @@ -515,8 +516,9 @@ start: o_imen = imen_m; r_imen = 1 << irq; - if ((cpl & r_imen) != 0) { - ipending |= r_imen; /* Masked! Mark this as pending */ + if ((ci->ci_cpl & r_imen) != 0) { + /* Masked! Mark this as pending. */ + ci->ci_ipending |= r_imen; imen_m |= r_imen; enable_irq(~imen_m); } else { @@ -542,21 +544,21 @@ out: void mac_intr_do_pending_int() { + struct cpu_info *ci = curcpu(); struct intrhand *ih; int irq; int pcpl; int hwpend; int s; - static int processing; - if (processing) + if (ci->ci_iactive) return; - processing = 1; + ci->ci_iactive = 1; pcpl = splhigh(); /* Turn off all */ s = ppc_intr_disable(); - hwpend = ipending & ~pcpl; /* Do now unmasked pendings */ + hwpend = ci->ci_ipending & ~pcpl; /* Do now unmasked pendings */ imen_m &= ~hwpend; enable_irq(~imen_m); hwpend &= HWIRQ_MASK; @@ -574,26 +576,26 @@ mac_intr_do_pending_int() /*out32rb(INT_ENABLE_REG, ~imen_m);*/ do { - if((ipending & SINT_CLOCK) & ~pcpl) { - ipending &= ~SINT_CLOCK; + if((ci->ci_ipending & SINT_CLOCK) & ~pcpl) { + ci->ci_ipending &= ~SINT_CLOCK; softclock(); } - if((ipending & SINT_NET) & ~pcpl) { + if((ci->ci_ipending & SINT_NET) & ~pcpl) { extern int netisr; int pisr = netisr; netisr = 0; - ipending &= ~SINT_NET; + ci->ci_ipending &= ~SINT_NET; softnet(pisr); } - if((ipending & SINT_TTY) & ~pcpl) { - ipending &= ~SINT_TTY; + if((ci->ci_ipending & SINT_TTY) & ~pcpl) { + ci->ci_ipending &= ~SINT_TTY; softtty(); } - } while (ipending & (SINT_NET|SINT_CLOCK|SINT_TTY) & ~pcpl); - ipending &= pcpl; - cpl = pcpl; /* Don't use splx... we are here already! */ + } while ((ci->ci_ipending & SINT_MASK) & ~pcpl); + ci->ci_ipending &= pcpl; + ci->ci_cpl = pcpl; /* Don't use splx... we are here already! */ ppc_intr_enable(s); - processing = 0; + ci->ci_iactive = 0; } static int diff --git a/sys/arch/macppc/dev/openpic.c b/sys/arch/macppc/dev/openpic.c index 95d73abdd3b..3b788409152 100644 --- a/sys/arch/macppc/dev/openpic.c +++ b/sys/arch/macppc/dev/openpic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: openpic.c,v 1.36 2007/03/01 15:00:57 mickey Exp $ */ +/* $OpenBSD: openpic.c,v 1.37 2007/03/20 20:59:53 kettenis Exp $ */ /*- * Copyright (c) 1995 Per Fogelstrom @@ -451,21 +451,21 @@ cntlzw(int x) void openpic_do_pending_int() { + struct cpu_info *ci = curcpu(); struct intrhand *ih; int irq; int pcpl; int hwpend; int s; - static int processing; - if (processing) + if (ci->ci_iactive) return; - processing = 1; + ci->ci_iactive = 1; pcpl = splhigh(); /* Turn off all */ s = ppc_intr_disable(); - hwpend = ipending & ~pcpl; /* Do now unmasked pendings */ + hwpend = ci->ci_ipending & ~pcpl; /* Do now unmasked pendings */ imen_o &= ~hwpend; openpic_enable_irq_mask(~imen_o); hwpend &= HWIRQ_MASK; @@ -488,26 +488,26 @@ openpic_do_pending_int() /*out32rb(INT_ENABLE_REG, ~imen_o);*/ do { - if((ipending & SINT_CLOCK) & ~pcpl) { - ipending &= ~SINT_CLOCK; + if((ci->ci_ipending & SINT_CLOCK) & ~pcpl) { + ci->ci_ipending &= ~SINT_CLOCK; softclock(); } - if((ipending & SINT_NET) & ~pcpl) { + if((ci->ci_ipending & SINT_NET) & ~pcpl) { extern int netisr; int pisr = netisr; netisr = 0; - ipending &= ~SINT_NET; + ci->ci_ipending &= ~SINT_NET; softnet(pisr); } - if((ipending & SINT_TTY) & ~pcpl) { - ipending &= ~SINT_TTY; + if((ci->ci_ipending & SINT_TTY) & ~pcpl) { + ci->ci_ipending &= ~SINT_TTY; softtty(); } - } while (ipending & (SINT_NET|SINT_CLOCK|SINT_TTY) & ~pcpl); - ipending &= pcpl; - cpl = pcpl; /* Don't use splx... we are here already! */ + } while ((ci->ci_ipending & SINT_MASK) & ~pcpl); + ci->ci_ipending &= pcpl; + ci->ci_cpl = pcpl; /* Don't use splx... we are here already! */ ppc_intr_enable(s); - processing = 0; + ci->ci_iactive = 0; } u_int @@ -602,12 +602,13 @@ openpic_eoi(int cpu) void ext_intr_openpic() { + struct cpu_info *ci = curcpu(); int irq, realirq; int r_imen; int pcpl, ocpl; struct intrhand *ih; - pcpl = cpl; + pcpl = ci->ci_cpl; realirq = openpic_read_irq(0); @@ -619,7 +620,8 @@ ext_intr_openpic() r_imen = 1 << irq; if ((pcpl & r_imen) != 0) { - ipending |= r_imen; /* Masked! Mark this as pending */ + /* Masked! Mark this as pending. */ + ci->ci_ipending |= r_imen; openpic_disable_irq(realirq); openpic_eoi(0); } else { @@ -640,7 +642,7 @@ ext_intr_openpic() uvmexp.intrs++; __asm__ volatile("":::"memory"); /* don't reorder.... */ - cpl = ocpl; + ci->ci_cpl = ocpl; __asm__ volatile("":::"memory"); /* don't reorder.... */ openpic_enable_irq(realirq); } diff --git a/sys/arch/macppc/include/lock.h b/sys/arch/macppc/include/lock.h new file mode 100644 index 00000000000..3d6062974ab --- /dev/null +++ b/sys/arch/macppc/include/lock.h @@ -0,0 +1,3 @@ +/* $OpenBSD: lock.h,v 1.1 2007/03/20 20:59:53 kettenis Exp $ */ + +#include <powerpc/lock.h> diff --git a/sys/arch/macppc/macppc/clock.c b/sys/arch/macppc/macppc/clock.c index 6ab7c529907..71cdb2f332b 100644 --- a/sys/arch/macppc/macppc/clock.c +++ b/sys/arch/macppc/macppc/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.17 2006/06/19 15:13:35 deraadt Exp $ */ +/* $OpenBSD: clock.c,v 1.18 2007/03/20 20:59:54 kettenis Exp $ */ /* $NetBSD: clock.c,v 1.1 1996/09/30 16:34:40 ws Exp $ */ /* @@ -209,7 +209,7 @@ decr_intr(struct clockframe *frame) */ ppc_mtdec(nextevent - tb); - if (cpl & SPL_CLOCK) { + if (curcpu()->ci_cpl & SPL_CLOCK) { statspending += nstats; } else { nstats += statspending; diff --git a/sys/arch/macppc/macppc/cpu.c b/sys/arch/macppc/macppc/cpu.c index c0a5f3bb8db..7654f6aa20f 100644 --- a/sys/arch/macppc/macppc/cpu.c +++ b/sys/arch/macppc/macppc/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.38 2006/12/12 23:14:27 dim Exp $ */ +/* $OpenBSD: cpu.c,v 1.39 2007/03/20 20:59:54 kettenis Exp $ */ /* * Copyright (c) 1997 Per Fogelstrom @@ -74,6 +74,8 @@ #define PSR_FREQ_MASK 0x0300000000000000LL #define PSR_FREQ_HALF 0x0100000000000000LL +struct cpu_info cpu_info[PPC_MAXPROCS]; + char cpu_model[80]; char machine[] = MACHINE; /* cpu architecture */ @@ -234,6 +236,12 @@ cpuattach(struct device *parent, struct device *dev, void *aux) char name[32]; int qhandle, phandle; u_int32_t clock_freq = 0; + struct cpu_info *ci; + + ci = &cpu_info[dev->dv_unit]; + ci->ci_cpuid = dev->dv_unit; + ci->ci_intrdepth = -1; + ci->ci_dev = dev; pvr = ppc_mfpvr(); cpu = pvr >> 16; diff --git a/sys/arch/macppc/macppc/genassym.cf b/sys/arch/macppc/macppc/genassym.cf index 3ad86d58929..3a3735aaae2 100644 --- a/sys/arch/macppc/macppc/genassym.cf +++ b/sys/arch/macppc/macppc/genassym.cf @@ -1,4 +1,4 @@ -# $OpenBSD: genassym.cf,v 1.12 2005/08/02 21:02:48 drahn Exp $ +# $OpenBSD: genassym.cf,v 1.13 2007/03/20 20:59:54 kettenis Exp $ # # Copyright (c) 1982, 1990 The Regents of the University of California. # All rights reserved. @@ -37,6 +37,7 @@ include <uvm/uvm_extern.h> include <machine/pcb.h> include <machine/pmap.h> +include <machine/cpu.h> export FRAMELEN struct trapframe FRAME_ @@ -72,6 +73,7 @@ member p_forw member p_back member p_addr member p_stat +member p_cpu struct sigframe member sf_sc @@ -79,3 +81,17 @@ member sf_sc struct fpsig export SONPROC + +struct cpu_info +member ci_curproc +member ci_curpcb +member ci_curpm +member ci_idle_pcb +member ci_astpending +member ci_want_resched +member ci_cpl +member ci_intrdepth +member ci_intstk +member ci_tempsave +member ci_ddbsave +member ci_disisave diff --git a/sys/arch/macppc/macppc/locore.S b/sys/arch/macppc/macppc/locore.S index 050b114ea2d..b2658a7fd48 100644 --- a/sys/arch/macppc/macppc/locore.S +++ b/sys/arch/macppc/macppc/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.31 2007/01/21 23:01:45 kettenis Exp $ */ +/* $OpenBSD: locore.S,v 1.32 2007/03/20 20:59:54 kettenis Exp $ */ /* $NetBSD: locore.S,v 1.2 1996/10/16 19:33:09 ws Exp $ */ /* @@ -42,6 +42,10 @@ #include <machine/psl.h> #include <machine/trap.h> +#define GET_CPUINFO(r) mfsprg r,0 + +#define INTSTK (8*1024) /* 8K interrupt stack */ + /* * Globals */ @@ -51,7 +55,6 @@ .data _C_LABEL(esym): .long 0 /* end of symbol table */ _C_LABEL(proc0paddr): .long 0 /* proc0 p_addr */ -idle_u: .long 0 /* fake uarea during idle after exit */ fwargsave: .long 0 @@ -102,9 +105,15 @@ start: li %r9,PGOFSET add %r8,%r8,%r9 andc %r8,%r8,%r9 - lis %r9,idle_u@ha - stw %r8,idle_u@l(%r9) + lis %r9,_C_LABEL(cpu_info)@ha + addi %r9,%r9,_C_LABEL(cpu_info)@l + mtsprg 0,%r9 + addi %r8,%r8,INTSTK + stw %r8,CI_INTSTK(%r9) + stw %r8,CI_IDLE_PCB(%r9) addi %r8,%r8,USPACE /* space for idle_u */ + li %r0,-1 + stw %r0,CI_INTRDEPTH(%r9) lis %r9,_C_LABEL(proc0paddr)@ha stw %r8,_C_LABEL(proc0paddr)@l(%r9) addi %r1,%r8,USPACE-FRAMELEN /* stackpointer for proc0 */ @@ -119,6 +128,16 @@ start: bl _C_LABEL(main) b _C_LABEL(OF_exit) +#ifdef MULTIPROCESSOR +_ENTRY(_C_LABEL(cpu_spinup_trampoline)) + lis %r3,_C_LABEL(cpu_hatch_stack)@ha + lwz %r1,_C_LABEL(cpu_hatch_stack)@l(%r3) + + bl _C_LABEL(cpu_hatch) + bl _C_LABEL(sched_lock_idle) + li %r30,0 + b _C_LABEL(idle) +#endif /* * No processes are runnable, so loop waiting for one. * Separate label here for accounting purposes. @@ -137,6 +156,10 @@ _C_LABEL(idle): or. %r9,%r9,%r9 bne- _C_LABEL(sw1) /* at least one queue non-empty */ +#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) + bl _C_LABEL(sched_unlock_idle) +#endif + ori %r3,%r3,PSL_EE /* reenable ints again */ mtmsr %r3 isync @@ -149,6 +172,9 @@ _C_LABEL(idle): /* May do some power saving here? */ +#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) + bl _C_LABEL(sched_lock_idle) +#endif b _C_LABEL(idle) /* @@ -157,10 +183,9 @@ _C_LABEL(idle): */ _ENTRY(_C_LABEL(switchexit)) /* First switch to the idle pcb/kernel stack */ - lis %r6,idle_u@ha - lwz %r6,idle_u@l(%r6) - lis %r7,_C_LABEL(curpcb)@ha - stw %r6,_C_LABEL(curpcb)@l(%r7) + GET_CPUINFO(%r7) + lwz %r6,CI_IDLE_PCB(%r7) + stw %r6,CI_CURPCB(%r7) addi %r1,%r6,USPACE-16 /* 16 bytes are reserved at stack top */ /* * Schedule the vmspace and stack to be freed (the proc arg is @@ -185,12 +210,11 @@ _ENTRY(_C_LABEL(cpu_switch)) stw %r30,8(%r1) mr %r30,%r3 - lis %r3,_C_LABEL(curproc)@ha + GET_CPUINFO(%r3) li %r31,0 /* Zero to not accumulate cpu time */ - stw %r31,_C_LABEL(curproc)@l(%r3) - lis %r3,_C_LABEL(curpcb)@ha - lwz %r31,_C_LABEL(curpcb)@l(%r3) + stw %r31,CI_CURPROC(%r3) + lwz %r31,CI_CURPCB(%r3) li %r3,0 bl _C_LABEL(lcsplx) @@ -231,13 +255,16 @@ _C_LABEL(sw1): 1: /* just did this resched thing, clear resched */ li %r3,0 - lis %r4,_C_LABEL(want_resched)@ha - stw %r3,_C_LABEL(want_resched)@l(%r4) + GET_CPUINFO(%r4) + stw %r3,CI_WANT_RESCHED(%r4) stw %r3,P_BACK(%r31) /* probably superfluous */ - lis %r4,_C_LABEL(curproc)@ha - stw %r31,_C_LABEL(curproc)@l(%r4) /* record new process */ +#ifdef MULTIPROCESSOR + stw %r4,P_CPU(%r31) +#endif + + stw %r31,CI_CURPROC(%r4) /* record new process */ li %r3,SONPROC stb %r3,P_STAT(%r31) @@ -267,14 +294,14 @@ switch_exited: mtmsr %r3 lwz %r4,P_ADDR(%r31) - lis %r5,_C_LABEL(curpcb)@ha - stw %r4,_C_LABEL(curpcb)@l(%r5) /* indicate new pcb */ + GET_CPUINFO(%r5) + stw %r4,CI_CURPCB(%r5) /* indicate new pcb */ lwz %r5,PCB_PMR(%r4) /* save real pmap pointer for spill fill */ - lis %r6,_C_LABEL(curpm)@ha - stwu %r5,_C_LABEL(curpm)@l(%r6) + GET_CPUINFO(%r6) + stwu %r5,CI_CURPM(%r6) stwcx. %r5,%r0,%r6 /* clear possible reservation */ addic. %r5,%r5,64 @@ -298,6 +325,10 @@ switch_return: lwz %r3,PCB_SPL(%r4) bl _C_LABEL(lcsplx) +#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) + bl _C_LABEL(sched_unlock_idle) +#endif + mr %r3,%r30 /* curproc for special fork returns */ lwz %r31,12(%r1) @@ -311,15 +342,8 @@ switch_return: /* * Data used during primary/secondary traps/interrupts */ -#define tempsave 0x2e0 /* primary save area for trap handling */ -#define disisave 0x3e0 /* primary save area for dsi/isi traps */ -#define INTSTK (8*1024) /* 8K interrupt stack */ + .data -intstk: .space INTSTK /* interrupt stack */ - .global _C_LABEL(intr_depth) - .type _C_LABEL(intr_depth),@object -_C_LABEL(intr_depth): - .long -1 /* in-use marker */ #define SPILLSTK 1024 /* 1K spill stack */ .lcomm spillstk,SPILLSTK,8 @@ -338,16 +362,18 @@ nop32_1s: clrldi %r1,%r1,1 mtmsrd %r1 nop32_1e: - stmw %r28,tempsave(%r0) /* free r28-r31 */ + GET_CPUINFO(%r1) + stmw %r28,CI_TEMPSAVE(%r1) /* free r28-r31 */ mflr %r28 /* save LR */ mfcr %r29 /* save CR */ + mfsprg %r1,1 /* restore SP */ /* Test whether we already had PR set */ mfsrr1 %r31 mtcr %r31 bc 4,17,1f /* branch if PSL_PR is clear */ - lis %r1,_C_LABEL(curpcb)@ha - lwz %r1,_C_LABEL(curpcb)@l(%r1) + GET_CPUINFO(%r1) + lwz %r1,CI_CURPCB(%r1) addi %r1,%r1,USPACE /* stack is top of user struct */ 1: bla s_trap @@ -363,21 +389,22 @@ nop32_2s: mfmsr %r1 clrldi %r1,%r1,1 mtmsrd %r1 - mfsprg %r1,1 /* restore SP */ nop32_2e: - stmw %r28,tempsave(0) /* free r28-r31 */ + GET_CPUINFO(%r1) + stmw %r28,CI_TEMPSAVE(%r1) /* free r28-r31 */ mfdar %r30 mfdsisr %r31 - stmw %r30,tempsave+16(0) + stmw %r30,CI_TEMPSAVE+16(%r1) mflr %r28 /* save LR */ mfcr %r29 /* save CR */ + mfsprg %r1,1 /* restore SP */ /* Test whether we already had PR set */ mfsrr1 %r31 mtcr %r31 bc 4,17,1f /* branch if PSL_PR is clear */ - lis %r1,_C_LABEL(curpcb)@ha - lwz %r1,_C_LABEL(curpcb)@l(%r1) + GET_CPUINFO(%r1) + lwz %r1,CI_CURPCB(%r1) addi %r1,%r1,USPACE /* stack is top of user struct */ 1: bla s_trap @@ -392,12 +419,15 @@ _C_LABEL(alisize) = .-_C_LABEL(alitrap) .type _C_LABEL(dsitrap),@function .type _C_LABEL(dsisize),@object _C_LABEL(dsitrap): - stmw %r28,disisave(0) /* free r28-r31 */ + mtsprg 1,%r1 + GET_CPUINFO(%r1) + stmw %r28,CI_DISISAVE(%r1) /* free r28-r31 */ nop32_3s: mfmsr %r28 clrldi %r28,%r28,1 mtmsrd %r28 nop32_3e: + mfsprg %r1,1 mfcr %r29 /* save CR */ mfxer %r30 /* save XER */ mtsprg 2,%r30 /* in SPRG2 */ @@ -426,7 +456,10 @@ nop64_1s: mfsprg %r30,2 /* restore XER */ mtxer %r30 mtcr %r29 /* restore CR */ - lmw %r28,disisave(0) /* restore r28-r31 */ + mtsprg 1,%r1 + GET_CPUINFO(%r1) + lmw %r28,CI_DISISAVE(%r1) /* restore r28-r31 */ + mfsprg 1,%r1 rfi /* return to trapped code */ 1: nop64_1e: @@ -441,17 +474,18 @@ _C_LABEL(dsisize) = .-_C_LABEL(dsitrap) .type _C_LABEL(isitrap),@function .type _C_LABEL(isisize),@object _C_LABEL(isitrap): + mtsprg 1,%r1 /* save SP */ nop32_4s: - mtsprg 1,%r1 /* save SP */ mfmsr %r1 clrldi %r1,%r1,1 mtmsrd %r1 - mfsprg %r1,1 /* restore SP */ nop32_4e: - stmw %r28,disisave(0) /* free r28-r31 */ + GET_CPUINFO(%r1) + stmw %r28,CI_DISISAVE(%r1) /* free r28-r31 */ mflr %r28 /* save LR */ mfcr %r29 /* save CR */ mfsrr1 %r31 /* test kernel mode */ + mfsprg %r1,1 /* restore SP */ nop64_2s: mtcr %r31 bc 12,17,1f /* branch if PSL_PR is set */ @@ -465,7 +499,10 @@ nop64_2s: lwz %r30,_C_LABEL(battable)+4@l(%r31) /* get batl */ mtibatl 3,%r30 mtcr %r29 /* restore CR */ - lmw %r28,disisave(0) /* restore r28-r31 */ + mtsprg 1,%r1 + GET_CPUINFO(%r1) + lmw %r28,CI_DISISAVE(%r1) /* restore r28-r31 */ + mfsprg %r1,1 rfi /* return to trapped code */ 1: nop64_2e: @@ -485,15 +522,15 @@ nop32_5s: clrldi %r1,%r1,1 mtmsrd %r1 nop32_5e: - stmw %r28,tempsave(0) /* free r28-r31 */ + GET_CPUINFO(%r1) + stmw %r28,CI_TEMPSAVE(%r1) /* free r28-r31 */ mflr %r28 /* save LR */ mfcr %r29 /* save CR */ mfxer %r30 /* save XER */ - lis %r1,intstk+INTSTK@ha /* get interrupt stack */ - addi %r1,%r1,intstk+INTSTK@l - lwz %r31,0(%r1) /* were we already running on intstk? */ + lwz %r31,CI_INTRDEPTH(%r1) /* were we already running on intstk? */ addic. %r31,%r31,1 - stw %r31,0(%r1) + stw %r31,CI_INTRDEPTH(%r1) + lwz %r1,CI_INTSTK(%r1) /* get interrupt stack */ beq 1f mfsprg %r1,1 /* yes, get old SP */ 1: @@ -513,15 +550,15 @@ nop32_6s: clrldi %r1,%r1,1 mtmsrd %r1 nop32_6e: - stmw %r28,tempsave(0) /* free r28-r31 */ + GET_CPUINFO(%r1) + stmw %r28,CI_TEMPSAVE(%r1) /* free r28-r31 */ mflr %r28 /* save LR */ mfcr %r29 /* save CR */ mfxer %r30 /* save XER */ - lis %r1,intstk+INTSTK@ha /* get interrupt stack */ - addi %r1,%r1,intstk+INTSTK@l - lwz %r31,0(%r1) /* were we already running on intstk? */ + lwz %r31,CI_INTRDEPTH(%r1) /* were we already running on intstk? */ addic. %r31,%r31,1 - stw %r31,0(%r1) + stw %r31,CI_INTRDEPTH(%r1) + lwz %r1,CI_INTSTK(%r1) /* get interrupt stack */ beq 1f mfsprg %r1,1 /* yes, get old SP */ 1: @@ -732,7 +769,6 @@ _C_LABEL(tlbdsmiss): _C_LABEL(tlbdsmsize) = .-_C_LABEL(tlbdsmiss) #ifdef DDB -#define ddbsave 0xde0 /* primary save area for DDB */ /* * In case of DDB we want a separate trap catcher for it */ @@ -747,7 +783,8 @@ nop32_7s: clrldi %r1,%r1,1 mtmsrd %r1 nop32_7e: - stmw %r28,ddbsave(0) /* free r28-r31 */ + GET_CPUINFO(%r1) + stmw %r28,CI_DDBSAVE(%r1) /* free r28-r31 */ mflr %r28 /* save LR */ mfcr %r29 /* save CR */ lis %r1,ddbstk+INTSTK@ha /* get new SP */ @@ -769,9 +806,11 @@ _C_LABEL(ddbsize) = .-_C_LABEL(ddblow) */ #define FRAME_SETUP(savearea) \ /* Have to enable translation to allow access of kernel stack: */ \ + GET_CPUINFO(%r31); \ mfsrr0 %r30; \ - mfsrr1 %r31; \ - stmw %r30,savearea+24(0); \ + stw %r30,savearea+24(%r31); \ + mfsrr1 %r30; \ + stw %r30,savearea+28(%r31); \ /* load all kernel segment registers. */ \ lis %r31,_C_LABEL(kernel_pmap_)@ha; \ addi %r31,%r31,_C_LABEL(kernel_pmap_)@l; \ @@ -799,11 +838,13 @@ _C_LABEL(ddbsize) = .-_C_LABEL(ddblow) stwu %r31,-FRAMELEN(%r1); \ stw %r0,FRAME_0+8(%r1); \ stw %r31,FRAME_1+8(%r1); \ + stw %r2,FRAME_2+8(%r1); \ stw %r28,FRAME_LR+8(%r1); \ stw %r29,FRAME_CR+8(%r1); \ - lmw %r28,savearea(0); \ - stmw %r2,FRAME_2+8(%r1); \ - lmw %r28,savearea+16(0); \ + GET_CPUINFO(%r2); \ + lmw %r28,savearea(%r2); \ + stmw %r3,FRAME_3+8(%r1); \ + lmw %r28,savearea+16(%r2); \ mfxer %r3; \ mfctr %r4; \ mflr %r5; \ @@ -823,9 +864,10 @@ _C_LABEL(ddbsize) = .-_C_LABEL(ddblow) lwz %r4,FRAME_CTR+8(%r1); \ lwz %r5,FRAME_XER+8(%r1); \ lwz %r6,FRAME_LR+8(%r1); \ + GET_CPUINFO(%r7); \ + stw %r2,savearea(%r7); \ + stw %r3,savearea+4(%r7); \ lwz %r7,FRAME_CR+8(%r1); \ - stw %r2,savearea(0); \ - stw %r3,savearea+4(0); \ mtctr %r4; \ mtxer %r5; \ mtlr %r6; \ @@ -843,12 +885,12 @@ _C_LABEL(ddbsize) = .-_C_LABEL(ddblow) mtmsr %r2; \ isync; \ /* Decide whether we return to user mode: */ \ - lwz %r3,savearea+4(0); \ + GET_CPUINFO(%r2); \ + lwz %r3,savearea+4(%r2); \ mtcr %r3; \ bc 4,17,1f; /* branch if PSL_PR is false */ \ /* Restore user & kernel access SR: */ \ - lis %r2,_C_LABEL(curpm)@ha; /* get real address of pmap */ \ - lwz %r2,_C_LABEL(curpm)@l(2); \ + lwz %r2,CI_CURPM(%r2); /* get real address of pmap */ \ lwz %r3,0(%r2); mtsr 0,%r3; \ lwz %r3,4(%r2); mtsr 1,%r3; \ lwz %r3,8(%r2); mtsr 2,%r3; \ @@ -867,9 +909,10 @@ _C_LABEL(ddbsize) = .-_C_LABEL(ddblow) lwz %r3,60(%r2); mtsr 15,%r3; \ 1: mfsprg %r2,1; /* restore cr */ \ mtcr %r2; \ - lwz %r2,savearea(0); \ - lwz %r3,savearea+4(0); \ - mtsrr0 %r2; \ + GET_CPUINFO(%r2); \ + lwz %r3,savearea(%r2); \ + mtsrr0 %r3; \ + lwz %r3,savearea+4(%r2); \ mtsrr1 %r3; \ mfsprg %r2,2; /* restore r2 & r3 */ \ mfsprg %r3,3 @@ -878,13 +921,14 @@ _C_LABEL(ddbsize) = .-_C_LABEL(ddblow) * Preamble code for DSI/ISI traps */ disitrap: - lmw %r30,disisave(0) - stmw %r30,tempsave(0) - lmw %r30,disisave+8(0) - stmw %r30,tempsave+8(0) + GET_CPUINFO(%r1) + lmw %r30,CI_DISISAVE(%r1) + stmw %r30,CI_TEMPSAVE(%r1) + lmw %r30,CI_DISISAVE+8(%r1) + stmw %r30,CI_TEMPSAVE+8(%r1) mfdar %r30 mfdsisr %r31 - stmw %r30,tempsave+16(0) + stmw %r30,CI_TEMPSAVE+16(%r1) realtrap: /* Test whether we already had PR set */ mfsrr1 %r1 @@ -892,14 +936,14 @@ realtrap: /* restore SP (might have been overwritten) */ mfsprg %r1,1 bc 4,17,s_trap /* branch if PSL_PR is false */ - lis %r1,_C_LABEL(curpcb)@ha - lwz %r1,_C_LABEL(curpcb)@l(%r1) + GET_CPUINFO(%r1) + lwz %r1,CI_CURPCB(%r1) addi %r1,%r1,USPACE /* stack is top of user struct */ /* * Now the common trap catching code. */ s_trap: - FRAME_SETUP(tempsave) + FRAME_SETUP(CI_TEMPSAVE) /* Now we can recover interrupts again: */ mfmsr %r7 mfsrr1 %r31 @@ -921,15 +965,15 @@ trapexit: lwz %r5,FRAME_SRR1+8(%r1) mtcr %r5 bc 4,17,1f /* branch if PSL_PR is false */ - lis %r3,_C_LABEL(astpending)@ha - lwz %r4,_C_LABEL(astpending)@l(%r3) + GET_CPUINFO(%r3) + lwz %r4,CI_ASTPENDING(%r3) andi. %r4,%r4,1 beq 1f li %r6,EXC_AST stw %r6,FRAME_EXC+8(%r1) b trapagain 1: - FRAME_LEAVE(tempsave) + FRAME_LEAVE(CI_TEMPSAVE) rfi1: rfi /* @@ -939,6 +983,9 @@ rfi1: rfi .globl _C_LABEL(fork_trampoline) .type _C_LABEL(fork_trampoline),@function _C_LABEL(fork_trampoline): +#ifdef MULTIPROCESSOR + bl _C_LABEL(proc_trampoline_mp) +#endif li %r3,0 bl _C_LABEL(lcsplx) mtlr %r31 @@ -1000,10 +1047,11 @@ s_pte_spill: lwz %r3,44(%r1) lwz %r0,48(%r1) beq disitrap - mfsprg %r1,1 /* restore SP */ mtcr %r29 /* restore CR */ mtlr %r28 /* restore LR */ - lmw %r28,disisave(0) /* restore r28-r31 */ + GET_CPUINFO(%r1) + lmw %r28,CI_DISISAVE(%r1) /* restore r28-r31 */ + mfsprg %r1,1 /* restore SP */ rfi2: rfi /* return to trapped code */ /* @@ -1060,10 +1108,10 @@ s_isitrap: stw %r28,40(%r1); /* saved LR */ \ stw %r29,36(%r1); /* saved CR */ \ stw %r30,32(%r1); /* saved XER */ \ - lmw %r28,tempsave(0); /* restore r28-r31 */ \ + GET_CPUINFO(%r4); \ + lmw %r28,CI_TEMPSAVE(%r4); /* restore r28-r31 */ \ mfctr %r6; \ - lis %r5,_C_LABEL(intr_depth)@ha; \ - lwz %r5,_C_LABEL(intr_depth)@l(%r5); \ + lwz %r5,CI_INTRDEPTH(%r4); \ mfsrr0 %r4; \ mfsrr1 %r3; \ stw %r6,28(%r1); \ @@ -1122,11 +1170,16 @@ intr_exit: mtsrr0 %r5 mtctr %r4 mtxer %r3 + + GET_CPUINFO(%r5) + lwz %r4,CI_INTRDEPTH(%r5) + addi %r4,%r4,-1 /* adjust reentrancy count */ + stw %r4,CI_INTRDEPTH(%r5) + /* Returning to user mode? */ mtcr %r6 /* saved SRR1 */ bc 4,17,1f /* branch if PSL_PR is false */ - lis %r3,_C_LABEL(curpm)@ha /* get current pmap real address */ - lwz %r3,_C_LABEL(curpm)@l(%r3) + lwz %r3,CI_CURPM(%r5) /* get current pmap real address */ /* reload all segment registers. */ lwz %r4,0(3); mtsr 0,%r4; lwz %r4,4(3); mtsr 1,%r4; @@ -1144,15 +1197,14 @@ intr_exit: lwz %r4,52(3); mtsr 13,%r4; lwz %r4,56(3); mtsr 14,%r4; lwz %r4,60(3); mtsr 15,%r4; - lis %r3,_C_LABEL(astpending)@ha /* Test AST pending */ - lwz %r4,_C_LABEL(astpending)@l(%r3) + lwz %r4,CI_ASTPENDING(%r5) /* Test AST pending */ andi. %r4,%r4,1 beq 1f /* Setup for entry to realtrap: */ lwz %r3,0(%r1) /* get saved SP */ mtsprg 1,%r3 li %r6,EXC_AST - stmw %r28,tempsave(0) /* establish tempsave again */ + stmw %r28,CI_TEMPSAVE(%r5) /* establish tempsave again */ mtlr %r6 lwz %r28,40(%r1) /* saved LR */ lwz %r29,36(%r1) /* saved CR */ @@ -1161,10 +1213,6 @@ intr_exit: lwz %r4,76(%r1) lwz %r3,80(%r1) lwz %r0,84(%r1) - lis %r30,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */ - lwz %r31,_C_LABEL(intr_depth)@l(%r30) - addi %r31,%r31,-1 - stw %r31,_C_LABEL(intr_depth)@l(%r30) b realtrap 1: /* Here is the normal exit of extintr: */ @@ -1174,10 +1222,6 @@ intr_exit: mtlr %r6 lwz %r6,68(%r1) lwz %r5,72(%r1) - lis %r3,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */ - lwz %r4,_C_LABEL(intr_depth)@l(%r3) - addi %r4,%r4,-1 - stw %r4,_C_LABEL(intr_depth)@l(%r3) lwz %r4,76(%r1) lwz %r3,80(%r1) lwz %r0,84(%r1) @@ -1208,8 +1252,8 @@ _C_LABEL(setfault): mflr %r0 mfcr %r12 mfmsr %r2 - lis %r4,_C_LABEL(curpcb)@ha - lwz %r4,_C_LABEL(curpcb)@l(%r4) + GET_CPUINFO(%r4) + lwz %r4,CI_CURPCB(%r4) stw %r3,PCB_FAULT(%r4) stw %r0,0(%r3) stw %r2,4(%r3) @@ -1286,7 +1330,8 @@ _C_LABEL(ddb_trap): andi. %r3,%r3,~(PSL_EE|PSL_ME)@l mtmsr %r3 /* disable interrupts */ isync - stmw %r28,ddbsave(0) + GET_CPUINFO(%r3) + stmw %r28,CI_DDBSAVE(%r3) mflr %r28 li %r29,EXC_BPT mtlr %r29 @@ -1297,7 +1342,7 @@ _C_LABEL(ddb_trap): * Now the ddb trap catching code. */ ddbtrap: - FRAME_SETUP(ddbsave) + FRAME_SETUP(CI_DDBSAVE) /* Call C trap code: */ addi %r3,%r1,8 bl _C_LABEL(ddb_trap_glue) @@ -1305,17 +1350,19 @@ ddbtrap: bne ddbleave /* This wasn't for DDB, so switch to real trap: */ lwz %r3,FRAME_EXC+8(%r1) /* save exception */ - stw %r3,ddbsave+8(0) - FRAME_LEAVE(ddbsave) + GET_CPUINFO(%r4) + stw %r3,CI_DDBSAVE+8(%r4) + FRAME_LEAVE(CI_DDBSAVE) mtsprg 1,%r1 /* prepare for entrance to realtrap */ - stmw %r28,tempsave(0) + GET_CPUINFO(%r1) + stmw %r28,CI_TEMPSAVE(%r1) mflr %r28 mfcr %r29 - lwz %r31,ddbsave+8(0) + lwz %r31,CI_DDBSAVE+8(%r1) mtlr %r31 b realtrap ddbleave: - FRAME_LEAVE(ddbsave) + FRAME_LEAVE(CI_DDBSAVE) rfi4: rfi #endif /* DDB */ diff --git a/sys/arch/macppc/macppc/machdep.c b/sys/arch/macppc/macppc/machdep.c index 973f3c0f4ba..40b765da52e 100644 --- a/sys/arch/macppc/macppc/machdep.c +++ b/sys/arch/macppc/macppc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.88 2007/03/17 21:11:58 kettenis Exp $ */ +/* $OpenBSD: machdep.c,v 1.89 2007/03/20 20:59:54 kettenis Exp $ */ /* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */ /* @@ -90,9 +90,6 @@ /* * Global variables used here and there */ -struct pcb *curpcb; -struct pmap *curpm; - extern struct user *proc0paddr; struct pool ppc_vecpl; @@ -202,6 +199,7 @@ initppc(startkernel, endkernel, args) extern void *msgbuf_addr; int exc, scratch; + proc0.p_cpu = &cpu_info[0]; proc0.p_addr = proc0paddr; bzero(proc0.p_addr, sizeof *proc0.p_addr); @@ -939,7 +937,6 @@ dumpsys() } -volatile int cpl, ipending, astpending; int imask[IPL_NUM]; /* diff --git a/sys/arch/powerpc/include/_types.h b/sys/arch/powerpc/include/_types.h index 1529aa9cdfb..d8cc81d4506 100644 --- a/sys/arch/powerpc/include/_types.h +++ b/sys/arch/powerpc/include/_types.h @@ -1,4 +1,4 @@ -/* $OpenBSD: _types.h,v 1.2 2006/01/13 17:50:06 millert Exp $ */ +/* $OpenBSD: _types.h,v 1.3 2007/03/20 20:59:53 kettenis Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -115,4 +115,7 @@ typedef int __rune_t; typedef void * __wctrans_t; typedef void * __wctype_t; +/* Feature test macros */ +#define __HAVE_CPUINFO + #endif /* _POWERPC__TYPES_H_ */ diff --git a/sys/arch/powerpc/include/cpu.h b/sys/arch/powerpc/include/cpu.h index d89ed88c158..fe4151fa6be 100644 --- a/sys/arch/powerpc/include/cpu.h +++ b/sys/arch/powerpc/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.29 2007/03/15 10:22:29 art Exp $ */ +/* $OpenBSD: cpu.h,v 1.30 2007/03/20 20:59:53 kettenis Exp $ */ /* $NetBSD: cpu.h,v 1.1 1996/09/30 16:34:21 ws Exp $ */ /* @@ -36,7 +36,85 @@ #include <machine/frame.h> -#include <machine/psl.h> +#include <sys/device.h> +#include <sys/lock.h> +#include <sys/sched.h> + +struct cpu_info { + struct device *ci_dev; /* our device */ + struct schedstate_percpu ci_schedstate; /* scheduler state */ + + struct proc *ci_curproc; + + struct pcb *ci_curpcb; + struct pmap *ci_curpm; + struct proc *ci_fpuproc; + struct proc *ci_vecproc; + struct pcb *ci_idle_pcb; /* PA of our idle pcb */ + int ci_cpuid; + + volatile int ci_astpending; + volatile int ci_want_resched; + volatile int ci_cpl; + volatile int ci_iactive; + volatile int ci_ipending; + int ci_intrdepth; + char *ci_intstk; +#define CPUSAVE_LEN 8 + register_t ci_tempsave[CPUSAVE_LEN]; + register_t ci_ddbsave[CPUSAVE_LEN]; +#define DISISAVE_LEN 4 + register_t ci_disisave[DISISAVE_LEN]; +}; + +static __inline struct cpu_info * +curcpu(void) +{ + struct cpu_info *ci; + + __asm volatile ("mfsprg %0,0" : "=r"(ci)); + return ci; +} + +#define curpcb (curcpu()->ci_curpcb) +#define curpm (curcpu()->ci_curpm) + +#define CPU_INFO_UNIT(ci) ((ci)->ci_dev->dv_unit) + +#ifdef MULTIPROCESSOR + +#define PPC_MAXPROCS 4 + +static __inline int +cpu_number(void) +{ + int pir; + + __asm ("mfspr %0,1023" : "=r"(pir)); + return pir; +} + +void cpu_boot_secondary_processors(void); + +#define CPU_IS_PRIMARY(ci) ((ci)->ci_cpuid == 0) +#define CPU_INFO_ITERATOR int +#define CPU_INFO_FOREACH(cii, ci) \ + for (cii = 0, ci = &cpu_info[0]; cii < PPC_MAXPROCS; cii++, ci++) + +#else + +#define PPC_MAXPROCS 1 + +#define cpu_number() 0 + +#define CPU_IS_PRIMARY(ci) 1 +#define CPU_INFO_ITERATOR int +#define CPU_INFO_FOREACH(cii, ci) \ + for (cii = 0, ci = curcpu(); ci != NULL; ci = NULL) + +#endif + +extern struct cpu_info cpu_info[PPC_MAXPROCS]; #define CLKF_USERMODE(frame) (((frame)->srr1 & PSL_PR) != 0) #define CLKF_PC(frame) ((frame)->srr0) @@ -47,12 +125,9 @@ void delay(unsigned); #define DELAY(n) delay(n) -extern volatile int want_resched; -extern volatile int astpending; - -#define need_resched(ci) (want_resched = 1, astpending = 1) -#define need_proftick(p) do { astpending = 1; } while (0) -#define signotify(p) (astpending = 1) +#define need_resched(ci) (ci->ci_want_resched = 1, ci->ci_astpending = 1) +#define need_proftick(p) do { curcpu()->ci_astpending = 1; } while (0) +#define signotify(p) (curcpu()->ci_astpending = 1) extern char *bootpath; @@ -200,6 +275,8 @@ void ppc64_mtscomc(u_int64_t); u_int64_t ppc64_mfscomd(void); void ppc_mtscomd(u_int32_t); +#include <machine/psl.h> + /* * General functions to enable and disable interrupts * without having inlined assembly code in many functions. @@ -250,4 +327,12 @@ extern int ppc_proc_is_64b; #define PPC_CPU_MPC7455 0x8001 #define PPC_CPU_MPC7457 0x8002 +/* + * This needs to be included late since it relies on definitions higher + * up in this file. + */ +#if defined(MULTIPROCESSOR) && defined(_KERNEL) +#include <sys/mplock.h> +#endif + #endif /* _POWERPC_CPU_H_ */ diff --git a/sys/arch/powerpc/include/intr.h b/sys/arch/powerpc/include/intr.h index fc328c7d342..aad653eeb87 100644 --- a/sys/arch/powerpc/include/intr.h +++ b/sys/arch/powerpc/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.31 2006/03/12 02:55:58 brad Exp $ */ +/* $OpenBSD: intr.h,v 1.32 2007/03/20 20:59:53 kettenis Exp $ */ /* * Copyright (c) 1997 Per Fogelstrom, Opsycon AB and RTMX Inc, USA. @@ -68,7 +68,6 @@ int splsoftnet(void); void do_pending_int(void); -volatile extern int cpl, ipending, astpending; extern int imask[IPL_NUM]; /* SPL asserts */ @@ -82,11 +81,12 @@ extern int imask[IPL_NUM]; volatile static __inline int splraise(int newcpl) { + struct cpu_info *ci = curcpu(); int oldcpl; __asm__ volatile("":::"memory"); /* don't reorder.... */ - oldcpl = cpl; - cpl = oldcpl | newcpl; + oldcpl = ci->ci_cpl; + ci->ci_cpl = oldcpl | newcpl; __asm__ volatile("":::"memory"); /* don't reorder.... */ return(oldcpl); } @@ -94,9 +94,11 @@ splraise(int newcpl) volatile static __inline void splx(int newcpl) { + struct cpu_info *ci = curcpu(); + __asm__ volatile("":::"memory"); /* reorder protect */ - cpl = newcpl; - if(ipending & ~newcpl) + ci->ci_cpl = newcpl; + if(ci->ci_ipending & ~newcpl) do_pending_int(); __asm__ volatile("":::"memory"); /* reorder protect */ } @@ -104,12 +106,13 @@ splx(int newcpl) volatile static __inline int spllower(int newcpl) { + struct cpu_info *ci = curcpu(); int oldcpl; __asm__ volatile("":::"memory"); /* reorder protect */ - oldcpl = cpl; - cpl = newcpl; - if(ipending & ~newcpl) + oldcpl = ci->ci_cpl; + ci->ci_cpl = newcpl; + if(ci->ci_ipending & ~newcpl) do_pending_int(); __asm__ volatile("":::"memory"); /* reorder protect */ return(oldcpl); @@ -120,11 +123,12 @@ spllower(int newcpl) static __inline void set_sint(int pending) { + struct cpu_info *ci = curcpu(); int msrsave; __asm__ ("mfmsr %0" : "=r"(msrsave)); __asm__ volatile ("mtmsr %0" :: "r"(msrsave & ~PSL_EE)); - ipending |= pending; + ci->ci_ipending |= pending; __asm__ volatile ("mtmsr %0" :: "r"(msrsave)); } @@ -140,6 +144,8 @@ set_sint(int pending) #define splaudio() splraise(imask[IPL_AUDIO]) #define splclock() splraise(imask[IPL_CLOCK]) #define splvm() splraise(imask[IPL_VM]) +#define splsched() splhigh() +#define spllock() splhigh() #define splstatclock() splhigh() #define splsoftclock() splraise(SINT_CLOCK) #define splsoftnet() splraise(SINT_NET|SINT_CLOCK) diff --git a/sys/arch/powerpc/include/lock.h b/sys/arch/powerpc/include/lock.h new file mode 100644 index 00000000000..a9b64118c5d --- /dev/null +++ b/sys/arch/powerpc/include/lock.h @@ -0,0 +1,112 @@ +/* $OpenBSD: lock.h,v 1.1 2007/03/20 20:59:53 kettenis Exp $ */ +/* $NetBSD: lock.h,v 1.8 2005/12/28 19:09:29 perry Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Machine-dependent spin lock operations. + */ + +#ifndef _POWERPC_LOCK_H_ +#define _POWERPC_LOCK_H_ + +typedef __volatile int __cpu_simple_lock_t; + +#define __SIMPLELOCK_LOCKED 1 +#define __SIMPLELOCK_UNLOCKED 0 + +static __inline void +__cpu_simple_lock_init(__cpu_simple_lock_t *alp) +{ + *alp = __SIMPLELOCK_UNLOCKED; + __asm volatile ("sync"); +} + +static __inline void +__cpu_simple_lock(__cpu_simple_lock_t *alp) +{ + int old; + + __asm volatile (" \ + \n\ +1: lwarx %0,0,%1 \n\ + cmpwi %0,%2 \n\ + beq+ 3f \n\ +2: lwzx %0,0,%1 \n\ + cmpwi %0,%2 \n\ + beq+ 1b \n\ + b 2b \n\ +3: stwcx. %3,0,%1 \n\ + bne- 1b \n\ + isync \n\ + \n" + : "=&r"(old) + : "r"(alp), "I"(__SIMPLELOCK_UNLOCKED), "r"(__SIMPLELOCK_LOCKED) + : "memory"); +} + +static __inline int +__cpu_simple_lock_try(__cpu_simple_lock_t *alp) +{ + int old, dummy; + + __asm volatile (" \ + \n\ +1: lwarx %0,0,%1 \n\ + cmpwi %0,%2 \n\ + bne 2f \n\ + stwcx. %3,0,%1 \n\ + bne- 1b \n\ +2: stwcx. %3,0,%4 \n\ + isync \n\ + \n" + : "=&r"(old) + : "r"(alp), "I"(__SIMPLELOCK_UNLOCKED), "r"(__SIMPLELOCK_LOCKED), + "r"(&dummy) + : "memory"); + + return (old == __SIMPLELOCK_UNLOCKED); +} + +static __inline void +__cpu_simple_unlock(__cpu_simple_lock_t *alp) +{ + __asm volatile ("sync"); + *alp = __SIMPLELOCK_UNLOCKED; +} + +#endif /* _POWERPC_LOCK_H_ */ diff --git a/sys/arch/powerpc/include/pcb.h b/sys/arch/powerpc/include/pcb.h index bd356bd1891..a49d03f1488 100644 --- a/sys/arch/powerpc/include/pcb.h +++ b/sys/arch/powerpc/include/pcb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pcb.h,v 1.9 2003/02/26 21:54:44 drahn Exp $ */ +/* $OpenBSD: pcb.h,v 1.10 2007/03/20 20:59:53 kettenis Exp $ */ /* $NetBSD: pcb.h,v 1.1 1996/09/30 16:34:29 ws Exp $ */ /*- @@ -65,8 +65,6 @@ struct md_coredump { }; #ifdef _KERNEL -extern struct pcb *curpcb; -extern struct pmap *curpm; extern struct proc *fpuproc; int setfault(faultbuf *env); #endif diff --git a/sys/arch/powerpc/powerpc/fpu.c b/sys/arch/powerpc/powerpc/fpu.c index c5672584c62..7b40ea97df6 100644 --- a/sys/arch/powerpc/powerpc/fpu.c +++ b/sys/arch/powerpc/powerpc/fpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fpu.c,v 1.9 2005/10/09 14:52:12 drahn Exp $ */ +/* $OpenBSD: fpu.c,v 1.10 2007/03/20 20:59:53 kettenis Exp $ */ /* $NetBSD: fpu.c,v 1.1 1996/09/30 16:34:44 ws Exp $ */ /* @@ -41,9 +41,10 @@ void enable_fpu(struct proc *p) { - int msr; + struct cpu_info *ci = curcpu(); struct pcb *pcb = &p->p_addr->u_pcb; struct trapframe *tf = trapframe(p); + int msr; if (!(pcb->pcb_flags & PCB_FPU)) { bzero(&pcb->pcb_fpu, sizeof pcb->pcb_fpu); @@ -86,7 +87,7 @@ enable_fpu(struct proc *p) "lfd 29,232(%0);" "lfd 30,240(%0);" "lfd 31,248(%0)" :: "b"(&pcb->pcb_fpu.fpr[0])); - fpuproc = p; + ci->ci_fpuproc = p; tf->srr1 |= PSL_FP; ppc_mtmsr(msr); __asm volatile("isync"); @@ -95,15 +96,16 @@ enable_fpu(struct proc *p) void save_fpu() { - int msr; + struct cpu_info *ci = curcpu(); struct pcb *pcb; struct proc *p; struct trapframe *tf; + int msr; msr = ppc_mfmsr(); ppc_mtmsr((msr & ~PSL_EE) | PSL_FP); - p = fpuproc; + p = ci->ci_fpuproc; if (p == NULL) { ppc_mtmsr(msr); @@ -149,9 +151,9 @@ save_fpu() asm volatile ("mffs 0; stfd 0,0(%0)" :: "b"(&pcb->pcb_fpu.fpcsr)); asm ("lfd 0,0(%0);" :: "b"(&pcb->pcb_fpu.fpr[0])); - tf = trapframe(fpuproc); + tf = trapframe(ci->ci_fpuproc); tf->srr1 &= ~PSL_FP; - fpuproc = NULL; + ci->ci_fpuproc = NULL; ppc_mtmsr(msr); __asm volatile("isync"); diff --git a/sys/arch/powerpc/powerpc/process_machdep.c b/sys/arch/powerpc/powerpc/process_machdep.c index bdba319e20f..4004c4dd9cf 100644 --- a/sys/arch/powerpc/powerpc/process_machdep.c +++ b/sys/arch/powerpc/powerpc/process_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: process_machdep.c,v 1.11 2006/05/15 21:02:44 kettenis Exp $ */ +/* $OpenBSD: process_machdep.c,v 1.12 2007/03/20 20:59:53 kettenis Exp $ */ /* $NetBSD: process_machdep.c,v 1.1 1996/09/30 16:34:53 ws Exp $ */ /* @@ -45,6 +45,7 @@ int process_read_regs(struct proc *p, struct reg *regs) { + struct cpu_info *ci = curcpu(); struct trapframe *tf = trapframe(p); struct pcb *pcb = &p->p_addr->u_pcb; @@ -53,7 +54,8 @@ process_read_regs(struct proc *p, struct reg *regs) if (!(pcb->pcb_flags & PCB_FPU)) { bzero(regs->fpr, sizeof(regs->fpr)); } else { - if (p == fpuproc) + /* XXX What if the state is on the other cpu? */ + if (p == ci->ci_fpuproc) save_fpu(); bcopy(pcb->pcb_fpu.fpr, regs->fpr, sizeof(regs->fpr)); } @@ -72,13 +74,15 @@ process_read_regs(struct proc *p, struct reg *regs) int process_read_fpregs(struct proc *p, struct fpreg *regs) { + struct cpu_info *ci = curcpu(); struct pcb *pcb = &p->p_addr->u_pcb; if (!(pcb->pcb_flags & PCB_FPU)) { bzero(regs->fpr, sizeof(regs->fpr)); regs->fpscr = 0; } else { - if (p == fpuproc) + /* XXX What if the state is on the other cpu? */ + if (p == ci->ci_fpuproc) save_fpu(); bcopy(pcb->pcb_fpu.fpr, regs->fpr, sizeof(regs->fpr)); regs->fpscr = *(u_int64_t *)&pcb->pcb_fpu.fpcsr; @@ -116,14 +120,16 @@ process_sstep(struct proc *p, int sstep) int process_write_regs(struct proc *p, struct reg *regs) { + struct cpu_info *ci = curcpu(); struct trapframe *tf = trapframe(p); struct pcb *pcb = &p->p_addr->u_pcb; bcopy(regs->gpr, tf->fixreg, sizeof(regs->gpr)); - if (p == fpuproc) { /* release the fpu */ + /* XXX What if the state is on the other cpu? */ + if (p == ci->ci_fpuproc) { /* release the fpu */ save_fpu(); - fpuproc = NULL; + ci->ci_fpuproc = NULL; } bcopy(regs->fpr, pcb->pcb_fpu.fpr, sizeof(regs->fpr)); @@ -146,12 +152,14 @@ process_write_regs(struct proc *p, struct reg *regs) int process_write_fpregs(struct proc *p, struct fpreg *regs) { + struct cpu_info *ci = curcpu(); struct pcb *pcb = &p->p_addr->u_pcb; u_int64_t fpscr = regs->fpscr; - if (p == fpuproc) { /* release the fpu */ + /* XXX What if the state is on the other cpu? */ + if (p == ci->ci_fpuproc) { /* release the fpu */ save_fpu(); - fpuproc = NULL; + ci->ci_fpuproc = NULL; } bcopy(regs->fpr, pcb->pcb_fpu.fpr, sizeof(regs->fpr)); diff --git a/sys/arch/powerpc/powerpc/trap.c b/sys/arch/powerpc/powerpc/trap.c index c5c67b3f456..378730ba6ae 100644 --- a/sys/arch/powerpc/powerpc/trap.c +++ b/sys/arch/powerpc/powerpc/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.74 2007/03/15 10:22:29 art Exp $ */ +/* $OpenBSD: trap.c,v 1.75 2007/03/20 20:59:53 kettenis Exp $ */ /* $NetBSD: trap.c,v 1.3 1996/10/13 03:31:37 christos Exp $ */ /* @@ -71,10 +71,6 @@ void trap(struct trapframe *frame); #define NARGREG 8 /* 8 args are in registers */ #define MOREARGS(sp) ((caddr_t)((int)(sp) + 8)) /* more args go here */ -volatile int want_resched; -struct proc *ppc_vecproc; -struct proc *fpuproc; - #ifdef DDB void ppc_dumpbt(struct trapframe *frame); @@ -261,12 +257,13 @@ userret(struct proc *p, int pc, u_quad_t oticks) addupc_task(p, pc, (int)(p->p_sticks - oticks) * psratio); } - curpriority = p->p_priority; + curcpu()->ci_schedstate.spc_curpriority = p->p_priority; } void trap(struct trapframe *frame) { + struct cpu_info *ci = curcpu(); struct proc *p = curproc; int type = frame->exc; u_quad_t sticks; @@ -283,7 +280,9 @@ trap(struct trapframe *frame) case EXC_TRC|EXC_USER: { sv.sival_int = frame->srr0; + KERNEL_PROC_LOCK(p); trapsignal(p, SIGTRAP, type, TRAP_TRACE, sv); + KERNEL_PROC_UNLOCK(p); } break; @@ -353,6 +352,7 @@ printf("kern dsi on addr %x iar %x\n", frame->dar, frame->srr0); frame->dar, frame->dsisr, 0)) break; + KERNEL_PROC_LOCK(p); if (frame->dsisr & DSISR_STORE) { ftype = VM_PROT_READ | VM_PROT_WRITE; vftype = VM_PROT_WRITE; @@ -361,6 +361,7 @@ printf("kern dsi on addr %x iar %x\n", frame->dar, frame->srr0); if (uvm_fault(&p->p_vmspace->vm_map, trunc_page(frame->dar), 0, ftype) == 0) { uvm_grow(p, trunc_page(frame->dar)); + KERNEL_PROC_UNLOCK(p); break; } @@ -372,6 +373,7 @@ printf("dsi on addr %x iar %x lr %x\n", frame->dar, frame->srr0,frame->lr); */ sv.sival_int = frame->dar; trapsignal(p, SIGSEGV, vftype, SEGV_MAPERR, sv); + KERNEL_PROC_UNLOCK(p); } break; case EXC_ISI|EXC_USER: @@ -383,12 +385,15 @@ printf("dsi on addr %x iar %x lr %x\n", frame->dar, frame->srr0,frame->lr); frame->srr0, 0, 1)) break; + KERNEL_PROC_LOCK(p); ftype = VM_PROT_READ | VM_PROT_EXECUTE; if (uvm_fault(&p->p_vmspace->vm_map, trunc_page(frame->srr0), 0, ftype) == 0) { uvm_grow(p, trunc_page(frame->srr0)); + KERNEL_PROC_UNLOCK(p); break; } + KERNEL_PROC_UNLOCK(p); } #if 0 printf("isi iar %x lr %x\n", frame->srr0, frame->lr); @@ -398,7 +403,9 @@ printf("isi iar %x lr %x\n", frame->srr0, frame->lr); /* XXX Likely that returning from this trap is bogus... */ /* XXX Have to make sure that sigreturn does the right thing. */ sv.sival_int = frame->srr0; + KERNEL_PROC_LOCK(p); trapsignal(p, SIGSEGV, VM_PROT_EXECUTE, SEGV_MAPERR, sv); + KERNEL_PROC_UNLOCK(p); break; case EXC_SC|EXC_USER: { @@ -461,6 +468,8 @@ printf("isi iar %x lr %x\n", frame->srr0, frame->lr); } params = args; } + + KERNEL_PROC_LOCK(p); #ifdef KTRACE if (KTRPOINT(p, KTR_SYSCALL)) ktrsyscall(p, code, argsize, params); @@ -480,6 +489,7 @@ printf("isi iar %x lr %x\n", frame->srr0, frame->lr); else #endif error = (*callp->sy_call)(p, params, rval); + KERNEL_PROC_UNLOCK(p); switch (error) { case 0: frame->fixreg[0] = error; @@ -507,17 +517,22 @@ syscall_bad: break; } #ifdef SYSCALL_DEBUG - scdebug_ret(p, code, error, rval); + KERNEL_PROC_LOCK(p); + scdebug_ret(p, code, error, rval); + KERNEL_PROC_UNLOCK(p); #endif #ifdef KTRACE - if (KTRPOINT(p, KTR_SYSRET)) + if (KTRPOINT(p, KTR_SYSRET)) { + KERNEL_PROC_LOCK(p); ktrsysret(p, code, error, rval[0]); + KERNEL_PROC_UNLOCK(p); + } #endif } break; case EXC_FPU|EXC_USER: - if (fpuproc) + if (ci->ci_fpuproc) save_fpu(); uvmexp.fpswtch++; enable_fpu(p); @@ -533,8 +548,10 @@ syscall_bad: frame->srr0 += 4; else { sv.sival_int = frame->srr0; + KERNEL_PROC_LOCK(p); trapsignal(p, SIGSEGV, VM_PROT_EXECUTE, SEGV_MAPERR, sv); + KERNEL_PROC_UNLOCK(p); } break; @@ -588,7 +605,9 @@ mpc_print_pci_stat(); errnum++; #endif sv.sival_int = frame->srr0; + KERNEL_PROC_LOCK(p); trapsignal(p, SIGTRAP, type, TRAP_BRKPT, sv); + KERNEL_PROC_UNLOCK(p); break; } #if 0 @@ -607,7 +626,9 @@ for (i = 0; i < errnum; i++) { } #endif sv.sival_int = frame->srr0; + KERNEL_PROC_LOCK(p); trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv); + KERNEL_PROC_UNLOCK(p); break; } case EXC_PGM: @@ -628,25 +649,29 @@ for (i = 0; i < errnum; i++) { case EXC_PERF|EXC_USER: #ifdef ALTIVEC case EXC_VEC|EXC_USER: - if (ppc_vecproc) - save_vec(ppc_vecproc); + if (ci->ci_vecproc) + save_vec(ci->ci_vecproc); - ppc_vecproc = p; + ci->ci_vecproc = p; enable_vec(p); break; #else /* ALTIVEC */ sv.sival_int = frame->srr0; + KERNEL_PROC_LOCK(p); trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv); + KERNEL_PROC_UNLOCK(p); break; #endif case EXC_AST|EXC_USER: uvmexp.softs++; - astpending = 0; /* we are about to do it */ + ci->ci_astpending = 0; /* we are about to do it */ if (p->p_flag & P_OWEUPC) { + KERNEL_PROC_LOCK(p); ADDUPROF(p); + KERNEL_PROC_UNLOCK(p); } - if (want_resched) + if (ci->ci_want_resched) preempt(NULL); break; } @@ -656,7 +681,7 @@ for (i = 0; i < errnum; i++) { /* * If someone stole the fpu while we were away, disable it */ - if (p != fpuproc) + if (p != ci->ci_fpuproc) frame->srr1 &= ~PSL_FP; else if (p->p_addr->u_pcb.pcb_flags & PCB_FPU) frame->srr1 |= PSL_FP; @@ -665,7 +690,7 @@ for (i = 0; i < errnum; i++) { /* * If someone stole the vector unit while we were away, disable it */ - if (p == ppc_vecproc) + if (p == ci->ci_vecproc) frame->srr1 |= PSL_VEC; else frame->srr1 &= ~PSL_VEC; @@ -685,12 +710,17 @@ child_return(void *arg) /* Disable FPU, VECT, as we can't be fpuproc */ tf->srr1 &= ~(PSL_FP|PSL_VEC); + KERNEL_PROC_UNLOCK(p); + userret(p, tf->srr0, 0); #ifdef KTRACE - if (KTRPOINT(p, KTR_SYSRET)) + if (KTRPOINT(p, KTR_SYSRET)) { + KERNEL_PROC_LOCK(p); ktrsysret(p, (p->p_flag & P_PPWAIT) ? SYS_vfork : SYS_fork, 0, 0); + KERNEL_PROC_UNLOCK(p); + } #endif } @@ -733,6 +763,7 @@ static int fix_unaligned(struct proc *p, struct trapframe *frame) { int indicator = EXC_ALI_OPCODE_INDICATOR(frame->dsisr); + struct cpu_info *ci = curcpu(); switch (indicator) { case EXC_ALI_LFD: @@ -745,8 +776,8 @@ fix_unaligned(struct proc *p, struct trapframe *frame) * the FPRs, and that their current state is in * the PCB. */ - if (fpuproc != p) { - if (fpuproc) + if (ci->ci_fpuproc != p) { + if (ci->ci_fpuproc) save_fpu(); enable_fpu(p); } diff --git a/sys/arch/powerpc/powerpc/vm_machdep.c b/sys/arch/powerpc/powerpc/vm_machdep.c index d21d46bd283..78cf2d0c1e0 100644 --- a/sys/arch/powerpc/powerpc/vm_machdep.c +++ b/sys/arch/powerpc/powerpc/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.41 2006/11/29 12:26:14 miod Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.42 2007/03/20 20:59:53 kettenis Exp $ */ /* $NetBSD: vm_machdep.c,v 1.1 1996/09/30 16:34:57 ws Exp $ */ /* @@ -59,14 +59,15 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, caddr_t stktop1, stktop2; extern void fork_trampoline(void); struct pcb *pcb = &p2->p_addr->u_pcb; + struct cpu_info *ci = curcpu(); - if (p1 == fpuproc) + if (p1 == ci->ci_fpuproc) save_fpu(); *pcb = p1->p_addr->u_pcb; #ifdef ALTIVEC if (p1->p_addr->u_pcb.pcb_vr != NULL) { - if (p1 == ppc_vecproc) + if (p1 == ci->ci_vecproc) save_vec(p1); pcb->pcb_vr = pool_get(&ppc_vecpl, PR_WAITOK); *pcb->pcb_vr = *p1->p_addr->u_pcb.pcb_vr; @@ -157,21 +158,24 @@ pagemove(caddr_t from, caddr_t to, size_t size) void cpu_exit(struct proc *p) { + struct cpu_info *ci = curcpu(); #ifdef ALTIVEC struct pcb *pcb = &p->p_addr->u_pcb; #endif /* ALTIVEC */ - if (p == fpuproc) /* release the fpu */ - fpuproc = NULL; + /* XXX What if the state is on the other cpu? */ + if (p == ci->ci_fpuproc) /* release the fpu */ + ci->ci_fpuproc = NULL; #ifdef ALTIVEC - if (p == ppc_vecproc) - ppc_vecproc = NULL; /* release the Altivec Unit */ + /* XXX What if the state is on the other cpu? */ + if (p == ci->ci_vecproc) + ci->ci_vecproc = NULL; /* release the Altivec Unit */ if (pcb->pcb_vr != NULL) pool_put(&ppc_vecpl, pcb->pcb_vr); #endif /* ALTIVEC */ - (void)splhigh(); + (void)splsched(); switchexit(p); } |