From d27f1d4c1253db023f670e2f8138c44a6f4a3621 Mon Sep 17 00:00:00 2001 From: Benno Rice Date: Sat, 16 Jun 2001 07:14:07 +0000 Subject: [PATCH] This commit (along with one pending in sys/dev/ofw and one in sys/conf) give us our first minimal glimpse of PowerPC support. With this code we can get to the "mountroot>" prompt on my Apple iMac. We can't get any further due to lack of clock and interrupt handling, among other things. This does however mean that pmap and VM are initialising. We're fairly dependant on OpenFirmware at this point, but I hope to add support for other classes of firmware at a later stage. Reviewed by: obrien, dfr --- sys/powerpc/aim/vm_machdep.c | 112 +++------------------- sys/powerpc/include/atomic.h | 52 ++++++----- sys/powerpc/include/clock.h | 2 + sys/powerpc/include/cpufunc.h | 127 +++++++++++++++++++++++++ sys/powerpc/include/elf.h | 3 + sys/powerpc/include/globaldata.h | 10 +- sys/powerpc/include/globals.h | 21 +++-- sys/powerpc/include/ipl.h | 7 ++ sys/powerpc/include/md_var.h | 18 ---- sys/powerpc/include/mutex.h | 48 +++++----- sys/powerpc/include/param.h | 30 +++++- sys/powerpc/include/pcpu.h | 10 +- sys/powerpc/include/reloc.h | 33 +++++++ sys/powerpc/include/smp.h | 7 ++ sys/powerpc/include/types.h | 14 +-- sys/powerpc/powerpc/atomic.S | 60 +++++++----- sys/powerpc/powerpc/atomic.s | 60 +++++++----- sys/powerpc/powerpc/autoconf.c | 78 ++++++++++++++++ sys/powerpc/powerpc/busdma_machdep.c | 39 ++++++++ sys/powerpc/powerpc/elf_machdep.c | 20 +--- sys/powerpc/powerpc/genassym.c | 133 ++++++--------------------- sys/powerpc/powerpc/mp_machdep.c | 22 ----- sys/powerpc/powerpc/procfs_machdep.c | 34 +++---- sys/powerpc/powerpc/sys_machdep.c | 41 +++++++++ sys/powerpc/powerpc/vm_machdep.c | 112 +++------------------- 25 files changed, 606 insertions(+), 487 deletions(-) create mode 100644 sys/powerpc/include/cpufunc.h create mode 100644 sys/powerpc/include/ipl.h create mode 100644 sys/powerpc/include/reloc.h create mode 100644 sys/powerpc/include/smp.h create mode 100644 sys/powerpc/powerpc/autoconf.c create mode 100644 sys/powerpc/powerpc/busdma_machdep.c create mode 100644 sys/powerpc/powerpc/sys_machdep.c diff --git a/sys/powerpc/aim/vm_machdep.c b/sys/powerpc/aim/vm_machdep.c index 79209e5f2428..11bdf0901a96 100644 --- a/sys/powerpc/aim/vm_machdep.c +++ b/sys/powerpc/aim/vm_machdep.c @@ -84,7 +84,8 @@ #include #include #include -#include + +#include #include #include @@ -122,99 +123,7 @@ cpu_fork(p1, p2, flags) register struct proc *p1, *p2; int flags; { - if ((flags & RFPROC) == 0) - return; - - p2->p_md.md_tf = p1->p_md.md_tf; - p2->p_md.md_flags = p1->p_md.md_flags & (MDP_FPUSED | MDP_UAC_MASK); - - /* - * Cache the physical address of the pcb, so we can - * swap to it easily. - */ - p2->p_md.md_pcbpaddr = (void*)vtophys((vm_offset_t)&p2->p_addr->u_pcb); - - /* - * Copy floating point state from the FP chip to the PCB - * if this process has state stored there. - */ - alpha_fpstate_save(p1, 0); - - /* - * Copy pcb and stack from proc p1 to p2. We do this as - * cheaply as possible, copying only the active part of the - * stack. The stack and pcb need to agree. Make sure that the - * new process has FEN disabled. - */ - p2->p_addr->u_pcb = p1->p_addr->u_pcb; - p2->p_addr->u_pcb.pcb_hw.apcb_usp = alpha_pal_rdusp(); - p2->p_addr->u_pcb.pcb_hw.apcb_flags &= ~ALPHA_PCB_FLAGS_FEN; - - /* - * Set the floating point state. - */ - if ((p2->p_addr->u_pcb.pcb_fp_control & IEEE_INHERIT) == 0) { - p2->p_addr->u_pcb.pcb_fp_control = 0; - p2->p_addr->u_pcb.pcb_fp.fpr_cr = (FPCR_DYN_NORMAL - | FPCR_INVD | FPCR_DZED - | FPCR_OVFD | FPCR_INED - | FPCR_UNFD); - } - - /* - * Arrange for a non-local goto when the new process - * is started, to resume here, returning nonzero from setjmp. - */ -#ifdef DIAGNOSTIC - alpha_fpstate_check(p1); -#endif - - /* - * create the child's kernel stack, from scratch. - */ - { - struct user *up = p2->p_addr; - struct trapframe *p2tf; - - /* - * Pick a stack pointer, leaving room for a trapframe; - * copy trapframe from parent so return to user mode - * will be to right address, with correct registers. - */ - p2tf = p2->p_md.md_tf = (struct trapframe *) - ((char *)p2->p_addr + USPACE - sizeof(struct trapframe)); - bcopy(p1->p_md.md_tf, p2->p_md.md_tf, - sizeof(struct trapframe)); - - /* - * Set up return-value registers as fork() libc stub expects. - */ - p2tf->tf_regs[FRAME_V0] = 0; /* child's pid (linux) */ - p2tf->tf_regs[FRAME_A3] = 0; /* no error */ - p2tf->tf_regs[FRAME_A4] = 1; /* is child (FreeBSD) */ - - /* - * Arrange for continuation at fork_return(), which - * will return to exception_return(). Note that the child - * process doesn't stay in the kernel for long! - * - * This is an inlined version of cpu_set_kpc. - */ - up->u_pcb.pcb_hw.apcb_ksp = (u_int64_t)p2tf; - up->u_pcb.pcb_context[0] = - (u_int64_t)fork_return; /* s0: a0 */ - up->u_pcb.pcb_context[1] = - (u_int64_t)exception_return; /* s1: ra */ - up->u_pcb.pcb_context[2] = (u_long) p2; /* s2: a1 */ - up->u_pcb.pcb_context[7] = - (u_int64_t)fork_trampoline; /* ra: assembly magic */ -#ifdef SMP - /* - * We start off at a nesting level of 1 within the kernel. - */ - p2->p_md.md_kernnest = 1; -#endif - } + /* XXX: coming soon... */ } /* @@ -233,8 +142,10 @@ cpu_set_fork_handler(p, func, arg) * Note that the trap frame follows the args, so the function * is really called like this: func(arg, frame); */ +#if 0 /* XXX */ p->p_addr->u_pcb.pcb_context[0] = (u_long) func; p->p_addr->u_pcb.pcb_context[2] = (u_long) arg; +#endif } /* @@ -248,8 +159,6 @@ void cpu_exit(p) register struct proc *p; { - alpha_fpstate_drop(p); - PROC_LOCK(p); mtx_lock_spin(&sched_lock); mtx_unlock_flags(&Giant, MTX_NOSWITCH); @@ -263,6 +172,7 @@ cpu_exit(p) */ p->p_stat = SZOMB; + mp_fixme("assumption: p_pptr won't change at this time"); wakeup(p->p_pptr); PROC_UNLOCK_NOSWITCH(p); @@ -390,7 +300,7 @@ vunmapbuf(bp) void cpu_reset() { - prom_halt(0); + OF_exit(); } int @@ -456,7 +366,13 @@ vm_page_zero_idle() TAILQ_REMOVE(&vm_page_queues[m->queue].pl, m, pageq); m->queue = PQ_NONE; splx(s); +#if 0 + rel_mplock(); +#endif pmap_zero_page(VM_PAGE_TO_PHYS(m)); +#if 0 + get_mplock(); +#endif (void)splvm(); vm_page_flag_set(m, PG_ZERO); m->queue = PQ_FREE + m->pc; @@ -480,8 +396,10 @@ vm_page_zero_idle() void swi_vm(void *dummy) { +#if 0 /* XXX: Don't have busdma stuff yet */ if (busdma_swi_pending != 0) busdma_swi(); +#endif } /* diff --git a/sys/powerpc/include/atomic.h b/sys/powerpc/include/atomic.h index ebd45ba0c88d..619ca7eeef06 100644 --- a/sys/powerpc/include/atomic.h +++ b/sys/powerpc/include/atomic.h @@ -38,15 +38,15 @@ * of interrupts and SMP safe. */ -void atomic_set_8(volatile u_int8_t *, u_int8_t); -void atomic_clear_8(volatile u_int8_t *, u_int8_t); -void atomic_add_8(volatile u_int8_t *, u_int8_t); -void atomic_subtract_8(volatile u_int8_t *, u_int8_t); +void atomic_set_8(volatile u_int8_t *, u_int8_t); +void atomic_clear_8(volatile u_int8_t *, u_int8_t); +void atomic_add_8(volatile u_int8_t *, u_int8_t); +void atomic_subtract_8(volatile u_int8_t *, u_int8_t); -void atomic_set_16(volatile u_int16_t *, u_int16_t); -void atomic_clear_16(volatile u_int16_t *, u_int16_t); -void atomic_add_16(volatile u_int16_t *, u_int16_t); -void atomic_subtract_16(volatile u_int16_t *, u_int16_t); +void atomic_set_16(volatile u_int16_t *, u_int16_t); +void atomic_clear_16(volatile u_int16_t *, u_int16_t); +void atomic_add_16(volatile u_int16_t *, u_int16_t); +void atomic_subtract_16(volatile u_int16_t *, u_int16_t); static __inline void atomic_set_32(volatile u_int32_t *p, u_int32_t v) @@ -217,7 +217,7 @@ atomic_readandclear_64(volatile u_int64_t *addr) #define atomic_set_long atomic_set_32 #define atomic_clear_long atomic_clear_32 -#define atomic_add_long atomic_add_32 +#define atomic_add_long(p, v) atomic_add_32((u_int32_t *)p, (u_int32_t)v) #define atomic_subtract_long atomic_subtract_32 #define atomic_readandclear_long atomic_readandclear_32 @@ -334,19 +334,21 @@ ATOMIC_STORE_LOAD(int, 32) static __inline u_int32_t atomic_cmpset_32(volatile u_int32_t* p, u_int32_t cmpval, u_int32_t newval) { - u_int32_t ret; + u_int32_t ret; + + ret = 0; __asm __volatile ( - "1:\tlwarx %0, 0, %4\n\t" /* load old value */ - "cmplw 0, %2, %0\n\t" /* compare */ - "bne 2\n\t" /* exit if not equal */ - "mr %0, %3\n\t" /* value to store */ - "stwcx. %0, 0, %1\n\t" /* attempt to store */ - "bne- 1\n\t" /* spin if failed */ + "1:\tlwarx %0, 0, %3\n\t" /* load old value */ + "cmplw 0, %1, %0\n\t" /* compare */ + "bne 2f\n\t" /* exit if not equal */ + "mr %0, %2\n\t" /* value to store */ + "stwcx. %0, 0, %3\n\t" /* attempt to store */ + "bne- 1b\n\t" /* spin if failed */ "eieio\n" /* memory barrier */ "2:\t\n" - : "=&r" (ret), "=r" (*p) - : "r" (cmpval), "r" (newval), "r" (*p) + : "=r" (ret) + : "r" (cmpval), "r" (newval), "r" (p) : "memory"); return ret; @@ -416,7 +418,7 @@ static __inline int atomic_cmpset_acq_ptr(volatile void *dst, void *exp, void *src) { - return (atomic_cmpset_acq_long((volatile u_int32_t *)dst, + return (atomic_cmpset_acq_32((volatile u_int32_t *)dst, (u_int32_t)exp, (u_int32_t)src)); } @@ -424,7 +426,7 @@ static __inline int atomic_cmpset_rel_ptr(volatile void *dst, void *exp, void *src) { - return (atomic_cmpset_rel_long((volatile u_int32_t *)dst, + return (atomic_cmpset_rel_32((volatile u_int32_t *)dst, (u_int32_t)exp, (u_int32_t)src)); } @@ -432,33 +434,33 @@ static __inline void * atomic_load_acq_ptr(volatile void *p) { - return (void *)atomic_load_acq_long((volatile u_int32_t *)p); + return (void *)atomic_load_acq_32((volatile u_int32_t *)p); } static __inline void atomic_store_rel_ptr(volatile void *p, void *v) { - atomic_store_rel_long((volatile u_int32_t *)p, (u_int32_t)v); + atomic_store_rel_32((volatile u_int32_t *)p, (u_int32_t)v); } #define ATOMIC_PTR(NAME) \ static __inline void \ atomic_##NAME##_ptr(volatile void *p, uintptr_t v) \ { \ - atomic_##NAME##_long((volatile u_int32_t *)p, v); \ + atomic_##NAME##_32((volatile u_int32_t *)p, v); \ } \ \ static __inline void \ atomic_##NAME##_acq_ptr(volatile void *p, uintptr_t v) \ { \ - atomic_##NAME##_acq_long((volatile u_int32_t *)p, v); \ + atomic_##NAME##_acq_32((volatile u_int32_t *)p, v); \ } \ \ static __inline void \ atomic_##NAME##_rel_ptr(volatile void *p, uintptr_t v) \ { \ - atomic_##NAME##_rel_long((volatile u_int32_t *)p, v); \ + atomic_##NAME##_rel_32((volatile u_int32_t *)p, v); \ } ATOMIC_PTR(set) diff --git a/sys/powerpc/include/clock.h b/sys/powerpc/include/clock.h index 9e4ad711df53..a7e626373561 100644 --- a/sys/powerpc/include/clock.h +++ b/sys/powerpc/include/clock.h @@ -19,6 +19,8 @@ int sysbeep __P((int pitch, int period)); int acquire_timer2 __P((int mode)); int release_timer2 __P((void)); +void decr_intr(struct clockframe *); + #endif #endif /* !_MACHINE_CLOCK_H_ */ diff --git a/sys/powerpc/include/cpufunc.h b/sys/powerpc/include/cpufunc.h new file mode 100644 index 000000000000..d9ad6ae01063 --- /dev/null +++ b/sys/powerpc/include/cpufunc.h @@ -0,0 +1,127 @@ +/*- + * Copyright (c) 1998 Doug Rabson + * All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_CPUFUNC_H_ +#define _MACHINE_CPUFUNC_H_ + +#ifdef _KERNEL + +#include + +#ifdef __GNUC__ + +static __inline void +breakpoint(void) +{ + return; +} + +#endif + +/* + * Bogus interrupt manipulation + */ +static __inline void +disable_intr(void) +{ + u_int32_t msr; + + msr = 0; + __asm __volatile( + "mfmsr %0\n\t" + "rlwinm %0, %0, 0, 17, 15\n\t" + "mtmsr %0" + : "+r" (msr)); + + return; +} + +static __inline void +enable_intr(void) +{ + u_int32_t msr; + + msr = 0; + __asm __volatile( + "mfmsr %0\n\t" + "ori %0, %0, 0x8000\n\t" + "mtmsr %0" + : "+r" (msr)); + + return; +} + +static __inline u_int +save_intr(void) +{ + u_int msr; + + __asm __volatile("mfmsr %0" : "=r" (msr)); + + return msr; +} + +static __inline critical_t +critical_enter(void) +{ + return ((critical_t)save_intr()); +} + +static __inline void +restore_intr(u_int msr) +{ + __asm __volatile("mtmsr %0" : : "r" (msr)); + + return; +} + +static __inline void +critical_exit(critical_t msr) +{ + return (restore_intr((u_int)msr)); +} + +static __inline void +powerpc_mb(void) +{ + __asm __volatile("eieio;" : : : "memory"); +} + +static __inline void +*powerpc_get_globalp(void) +{ + void *ret; + + __asm __volatile("mfsprg %0, 0" : "=r" (ret)); + + return(ret); +} + +#endif /* _KERNEL */ + +#endif /* !_MACHINE_CPUFUNC_H_ */ diff --git a/sys/powerpc/include/elf.h b/sys/powerpc/include/elf.h index 193565486462..c10dfb46a6ea 100644 --- a/sys/powerpc/include/elf.h +++ b/sys/powerpc/include/elf.h @@ -80,6 +80,9 @@ __ElfType(Auxinfo); #define AT_COUNT 13 /* Count of defined aux entry types. */ +/* Used in John Polstra's testbed stuff. */ +#define AT_DEBUG 14 /* Debugging level. */ + /* * Relocation types. */ diff --git a/sys/powerpc/include/globaldata.h b/sys/powerpc/include/globaldata.h index 4d6d02f60717..de9a1ce1efc4 100644 --- a/sys/powerpc/include/globaldata.h +++ b/sys/powerpc/include/globaldata.h @@ -43,7 +43,6 @@ * point at the globaldata structure. */ struct globaldata { - struct alpha_pcb gd_idlepcb; /* pcb for idling */ struct proc *gd_curproc; /* current process */ struct proc *gd_idleproc; /* idle process */ struct proc *gd_fpcurproc; /* fp state owner */ @@ -52,17 +51,20 @@ struct globaldata { int gd_switchticks; u_int gd_cpuid; /* this cpu number */ u_int gd_other_cpus; /* all other cpus */ - u_int64_t gd_idlepcbphys; /* pa of gd_idlepcb */ - u_int64_t gd_pending_ipis; /* pending IPI events */ + int gd_inside_intr; u_int32_t gd_next_asn; /* next ASN to allocate */ u_int32_t gd_current_asngen; /* ASN rollover check */ + u_int32_t gd_intr_nesting_level; /* interrupt recursion */ + u_int gd_astpending; SLIST_ENTRY(globaldata) gd_allcpu; struct lock_list_entry *gd_spinlocks; #ifdef KTR_PERCPU +#ifdef KTR volatile int gd_ktr_idx; /* Index into trace table */ char *gd_ktr_buf; - char gd_ktr_buf_data[0]; + char gd_ktr_buf_data[KTR_SIZE]; +#endif #endif }; diff --git a/sys/powerpc/include/globals.h b/sys/powerpc/include/globals.h index 10de1b73c4ca..286e5eb69e3d 100644 --- a/sys/powerpc/include/globals.h +++ b/sys/powerpc/include/globals.h @@ -30,23 +30,30 @@ #define _MACHINE_GLOBALS_H_ #ifdef _KERNEL +#include #include -register struct globaldata *globalp __asm__("$8"); - -#if 1 -#define GLOBALP globalp -#else -#define GLOBALP ((struct globaldata *) alpha_pal_rdval()) -#endif +#define GLOBALP ((struct globaldata *) powerpc_get_globalp()) #define PCPU_GET(name) (GLOBALP->gd_##name) #define PCPU_PTR(name) (&GLOBALP->gd_##name) #define PCPU_SET(name,value) (GLOBALP->gd_##name = (value)) +/* + * The following set of macros works for UP kernel as well, but for maximum + * performance we allow the global variables to be accessed directly. On the + * other hand, kernel modules should always use these macros to maintain + * portability between UP and SMP kernels. + */ #define CURPROC PCPU_GET(curproc) #define CURTHD PCPU_GET(curproc) /* temporary */ #define curproc PCPU_GET(curproc) +#define idleproc PCPU_GET(idleproc) +#define curpcb PCPU_GET(curpcb) +#define fpcurproc PCPU_GET(fpcurproc) +#define switchtime PCPU_GET(switchtime) +#define switchticks PCPU_GET(switchticks) +#define witness_spin_check PCPU_GET(witness_spin_check) #endif /* _KERNEL */ diff --git a/sys/powerpc/include/ipl.h b/sys/powerpc/include/ipl.h new file mode 100644 index 000000000000..15ec74ce8f80 --- /dev/null +++ b/sys/powerpc/include/ipl.h @@ -0,0 +1,7 @@ +/* $FreeBSD$ */ + +/* + * An empty file now, + * Although in the times to come, + * More may be found here. + */ diff --git a/sys/powerpc/include/md_var.h b/sys/powerpc/include/md_var.h index bf99dd72c06a..f5df84c1f84a 100644 --- a/sys/powerpc/include/md_var.h +++ b/sys/powerpc/include/md_var.h @@ -55,23 +55,5 @@ int fill_regs __P((struct proc *, struct reg *)); int set_regs __P((struct proc *, struct reg *)); int fill_fpregs __P((struct proc *, struct fpreg *)); int set_fpregs __P((struct proc *, struct fpreg *)); -void alpha_register_pci_scsi __P((int bus, int slot, struct cam_sim *sim)); -#ifdef _SYS_BUS_H_ -struct resource *alpha_platform_alloc_ide_intr(int chan); -int alpha_platform_release_ide_intr(int chan, struct resource *res); -int alpha_platform_setup_ide_intr(struct device *dev, - struct resource *res, - driver_intr_t *fn, void *arg, - void **cookiep); -int alpha_platform_teardown_ide_intr(struct device *dev, - struct resource *res, void *cookie); -int alpha_platform_pci_setup_intr(device_t dev, device_t child, - struct resource *irq, int flags, - driver_intr_t *intr, void *arg, - void **cookiep); -int alpha_platform_pci_teardown_intr(device_t dev, device_t child, - struct resource *irq, void *cookie); -int alpha_pci_route_interrupt(device_t bus, device_t dev, int pin); -#endif #endif /* !_MACHINE_MD_VAR_H_ */ diff --git a/sys/powerpc/include/mutex.h b/sys/powerpc/include/mutex.h index c141d6f017dd..5038f42d5bc0 100644 --- a/sys/powerpc/include/mutex.h +++ b/sys/powerpc/include/mutex.h @@ -36,10 +36,14 @@ #ifdef _KERNEL -/* Global locks */ -extern struct mtx clock_lock; +#define mtx_intr_enable(mutex) do (mutex)->mtx_savecrit |= PSL_EE; while (0) -#define mtx_intr_enable(mutex) do (mutex)->mtx_savecrit = ALPHA_PSL_IPL_0; while (0) +/* + * Assembly macros (for internal use only) + *-------------------------------------------------------------------------- + */ + +#define _V(x) __STRING(x) #endif /* _KERNEL */ @@ -47,29 +51,29 @@ extern struct mtx clock_lock; /* * Simple assembly macros to get and release non-recursive spin locks - * - * XXX: These are presently unused and cannot be used right now. Need to be - * re-written (they are wrong). If you plan to use this and still see - * this message, know not to unless you fix them first! :-) */ #define MTX_ENTER(lck) \ - ldiq a0, ALPHA_PSL_IPL_HIGH; \ - call_pal PAL_OSF1_swpipl; \ -1: ldq_l a0, lck+MTX_LOCK; \ - cmpeq a0, MTX_UNOWNED, a1; \ - beq a1, 1b; \ - ldq a0, PC_CURPROC(globalp); \ - stq_c a0, lck+MTX_LOCK; \ - beq a0, 1b; \ - mb; \ - stl v0, lck+MTX_SAVEINTR + mfmsr r10; \ /* disable interrupts */ + rlwinm r0, r10, 0, 17, 15; \ + mtmsr r0; \ +1: li r11, MTX_LOCK; \ /* MTX_LOCK offset */ + lwarx r0, r11, lck; \ /* load current lock value */ + cmplwi r0, r1, MTX_UNOWNED; \ /* compare with unowned */ + beq 1; \ /* if owned, loop */ + lwz r0, PC_CURPROC(globalp); \ /* load curproc */ + stwcx. r0, r11, lck; \ /* attempt to store */ + beq 1; \ /* loop if failed */ + sync; \ /* sync */ + eieio; \ /* sync */ + stw r10, MTX_SAVEINTR(lck) /* save flags */ #define MTX_EXIT(lck) \ - mb; \ - ldiq a0, MTX_UNOWNED; \ - stq a0, lck+MTX_LOCK; \ - ldl a0, lck+MTX_SAVEINTR; \ - call_pal PAL_OSF1_swpipl + sync; \ /* sync */ + eieio; \ /* sync */ + li r0, MTX_UNOWNED; \ /* load in unowned */ + stw r0, MTX_LOCK(lck); \ /* store to lock */ + lwz r0, MTX_SAVEINTR(lck); \ /* load saved flags */ + mtmsr r0 /* enable interrupts */ #endif /* !LOCORE */ diff --git a/sys/powerpc/include/param.h b/sys/powerpc/include/param.h index ebc67b7b2dd1..3ebcd9454550 100644 --- a/sys/powerpc/include/param.h +++ b/sys/powerpc/include/param.h @@ -74,7 +74,9 @@ #endif #define MID_MACHINE MID_POWERPC +#if !defined(LOCORE) #include +#endif /* * OBJFORMAT_NAMES is a comma-separated list of the object formats @@ -158,18 +160,40 @@ /* * Mach derived conversion macros */ -#define trunc_page(x) ((x) & ~PAGE_MASK) +#define trunc_page(x) ((unsigned long)(x) & ~(PAGE_MASK)) #define round_page(x) (((x) + PAGE_MASK) & ~PAGE_MASK) #define trunc_4mpage(x) ((unsigned)(x) & ~PDRMASK) #define round_4mpage(x) ((((unsigned)(x)) + PDRMASK) & ~PDRMASK) -#define atop(x) ((unsigned)(x) >> PAGE_SHIFT) -#define ptoa(x) ((unsigned)(x) << PAGE_SHIFT) +#define atop(x) ((unsigned long)(x) >> PAGE_SHIFT) +#define ptoa(x) ((unsigned long)(x) << PAGE_SHIFT) #define powerpc_btop(x) ((unsigned)(x) >> PAGE_SHIFT) #define powerpc_ptob(x) ((unsigned)(x) << PAGE_SHIFT) #define pgtok(x) ((x) * (PAGE_SIZE / 1024)) +/* XXX: NetBSD defines that we're using for the moment */ +#define USER_SR 13 +#define KERNEL_SR 14 +#define KERNEL_SEGMENT (0xfffff0 + KERNEL_SR) +#define EMPTY_SEGMENT 0xfffff0 +#define USER_ADDR ((void *)(USER_SR << ADDR_SR_SHFT)) +#define SEGMENT_LENGTH 0x10000000 +#define SEGMENT_MASK 0xf0000000 + +#if !defined(NPMAPS) +#define NPMAPS 32768 +#endif /* !defined(NPMAPS) */ + +#if !defined(MSGBUFSIZE) +#define MSGBUFSIZE PAGE_SIZE +#endif /* !defined(MSGBUFSIZE) */ + +/* + * XXX: Stop NetBSD msgbuf_paddr code from happening. + */ +#define MSGBUFADDR + #endif /* !_MACHINE_PARAM_H_ */ #endif /* !_NO_NAMESPACE_POLLUTION */ diff --git a/sys/powerpc/include/pcpu.h b/sys/powerpc/include/pcpu.h index 4d6d02f60717..de9a1ce1efc4 100644 --- a/sys/powerpc/include/pcpu.h +++ b/sys/powerpc/include/pcpu.h @@ -43,7 +43,6 @@ * point at the globaldata structure. */ struct globaldata { - struct alpha_pcb gd_idlepcb; /* pcb for idling */ struct proc *gd_curproc; /* current process */ struct proc *gd_idleproc; /* idle process */ struct proc *gd_fpcurproc; /* fp state owner */ @@ -52,17 +51,20 @@ struct globaldata { int gd_switchticks; u_int gd_cpuid; /* this cpu number */ u_int gd_other_cpus; /* all other cpus */ - u_int64_t gd_idlepcbphys; /* pa of gd_idlepcb */ - u_int64_t gd_pending_ipis; /* pending IPI events */ + int gd_inside_intr; u_int32_t gd_next_asn; /* next ASN to allocate */ u_int32_t gd_current_asngen; /* ASN rollover check */ + u_int32_t gd_intr_nesting_level; /* interrupt recursion */ + u_int gd_astpending; SLIST_ENTRY(globaldata) gd_allcpu; struct lock_list_entry *gd_spinlocks; #ifdef KTR_PERCPU +#ifdef KTR volatile int gd_ktr_idx; /* Index into trace table */ char *gd_ktr_buf; - char gd_ktr_buf_data[0]; + char gd_ktr_buf_data[KTR_SIZE]; +#endif #endif }; diff --git a/sys/powerpc/include/reloc.h b/sys/powerpc/include/reloc.h new file mode 100644 index 000000000000..a8ce0b106ab0 --- /dev/null +++ b/sys/powerpc/include/reloc.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 1998 John Birrell . + * All rights reserved. + * + * 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 John Birrell. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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 REGENTS 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. + * + * $FreeBSD$ + */ diff --git a/sys/powerpc/include/smp.h b/sys/powerpc/include/smp.h new file mode 100644 index 000000000000..15ec74ce8f80 --- /dev/null +++ b/sys/powerpc/include/smp.h @@ -0,0 +1,7 @@ +/* $FreeBSD$ */ + +/* + * An empty file now, + * Although in the times to come, + * More may be found here. + */ diff --git a/sys/powerpc/include/types.h b/sys/powerpc/include/types.h index 4231ab02c420..8d6b10754b15 100644 --- a/sys/powerpc/include/types.h +++ b/sys/powerpc/include/types.h @@ -49,20 +49,22 @@ typedef struct label_t { } label_t; #endif -typedef unsigned int vm_offset_t; -typedef __int64_t vm_ooffset_t; -typedef unsigned int vm_pindex_t; -typedef unsigned int vm_size_t; +typedef unsigned int vm_offset_t; +typedef __int64_t vm_ooffset_t; +typedef unsigned int vm_pindex_t; +typedef unsigned int vm_size_t; typedef __int32_t register_t; typedef __uint32_t u_register_t; #ifdef _KERNEL -typedef int intfptr_t; -typedef unsigned int uintfptr_t; +typedef int intfptr_t; +typedef unsigned int uintfptr_t; #endif /* Interrupt mask (spl, xxx_imask, etc) */ typedef __uint32_t intrmask_t; +typedef register_t critical_t; + #endif /* _MACHTYPES_H_ */ diff --git a/sys/powerpc/powerpc/atomic.S b/sys/powerpc/powerpc/atomic.S index 8beab01be501..a844f7a6d59f 100644 --- a/sys/powerpc/powerpc/atomic.S +++ b/sys/powerpc/powerpc/atomic.S @@ -77,46 +77,60 @@ ASENTRY(atomic_subtract_8) blr /* return */ ASENTRY(atomic_set_16) -0: lwarx 0, 0, 3 /* load old value */ + li 11, 3 /* mask to test for alignment */ + andc. 11, 3, 11 /* force address to be word-aligned */ +0: lwarx 12, 0, 11 /* load old value */ + bne 1f /* no realignment needed if it's aligned */ slwi 4, 4, 16 /* realign operand */ - or 0, 0, 4 /* calculate new value */ - stwcx. 0, 0, 3 /* attempt to store */ - bne- 0 /* loop if failed */ +1: or 12, 12, 4 /* calculate new value */ + stwcx. 12, 0, 11 /* attempt to store */ + bne- 0b /* loop if failed */ eieio /* synchronise */ sync blr /* return */ ASENTRY(atomic_clear_16) -0: lwarx 0, 0, 3 /* load old value */ + li 11, 3 /* mask to test for alignment */ + andc. 11, 3, 11 /* force address to be word-aligned */ +0: lwarx 12, 0, 11 /* load old value */ + bne 1f /* no realignment needed if it's aligned */ slwi 4, 4, 16 /* realign operand */ - andc 0, 0, 4 /* calculate new value */ - stwcx. 0, 0, 3 /* attempt to store */ - bne- 0 /* loop if failed */ +1: andc 12, 12, 4 /* calculate new value */ + stwcx. 12, 0, 11 /* attempt to store */ + bne- 0b /* loop if failed */ eieio /* synchronise */ sync blr /* return */ ASENTRY(atomic_add_16) -0: lwarx 0, 0, 3 /* load old value */ - srwi 0, 9, 16 /* realign */ - add 0, 4, 0 /* calculate new value */ - slwi 0, 0, 16 /* realign */ - clrlwi 9, 9, 16 /* clear old value */ - or 9, 9, 0 /* copy in new value */ - stwcx. 0, 0, 3 /* attempt to store */ - bne- 0 /* loop if failed */ + li 11, 3 /* mask to test for alignment */ + andc. 11, 3, 11 /* force address to be word-aligned */ +0: lwarx 12, 0, 11 /* load old value */ + bne 1f /* no realignment needed if it's aligned */ + srwi 12, 9, 16 /* realign */ +1: add 12, 4, 12 /* calculate new value */ + bne 2f /* no realignment needed if it's aligned */ + slwi 12, 12, 16 /* realign */ +2: clrlwi 9, 9, 16 /* clear old value */ + or 9, 9, 12 /* copy in new value */ + stwcx. 12, 0, 11 /* attempt to store */ + bne- 0b /* loop if failed */ eieio /* synchronise */ sync blr /* return */ ASENTRY(atomic_subtract_16) -0: lwarx 0, 0, 3 /* load old value */ - srwi 0, 9, 16 /* realign */ - subf 0, 4, 0 /* calculate new value */ - slwi 0, 0, 16 /* realign */ - clrlwi 9, 9, 16 /* clear old value */ - or 9, 9, 0 /* copy in new value */ - stwcx. 0, 0, 3 /* attempt to store */ + li 11, 3 /* mask to test for alignment */ + andc. 11, 3, 11 /* force address to be word-aligned */ +0: lwarx 12, 0, 11 /* load old value */ + bne 1f /* no realignment needed if it's aligned */ + srwi 12, 9, 16 /* realign */ +1: subf 12, 4, 12 /* calculate new value */ + bne 2f /* no realignment needed if it's aligned */ + slwi 12, 12, 16 /* realign */ +2: clrlwi 9, 9, 16 /* clear old value */ + or 9, 9, 12 /* copy in new value */ + stwcx. 12, 0, 11 /* attempt to store */ bne- 0 /* loop if failed */ eieio /* synchronise */ sync diff --git a/sys/powerpc/powerpc/atomic.s b/sys/powerpc/powerpc/atomic.s index 8beab01be501..a844f7a6d59f 100644 --- a/sys/powerpc/powerpc/atomic.s +++ b/sys/powerpc/powerpc/atomic.s @@ -77,46 +77,60 @@ ASENTRY(atomic_subtract_8) blr /* return */ ASENTRY(atomic_set_16) -0: lwarx 0, 0, 3 /* load old value */ + li 11, 3 /* mask to test for alignment */ + andc. 11, 3, 11 /* force address to be word-aligned */ +0: lwarx 12, 0, 11 /* load old value */ + bne 1f /* no realignment needed if it's aligned */ slwi 4, 4, 16 /* realign operand */ - or 0, 0, 4 /* calculate new value */ - stwcx. 0, 0, 3 /* attempt to store */ - bne- 0 /* loop if failed */ +1: or 12, 12, 4 /* calculate new value */ + stwcx. 12, 0, 11 /* attempt to store */ + bne- 0b /* loop if failed */ eieio /* synchronise */ sync blr /* return */ ASENTRY(atomic_clear_16) -0: lwarx 0, 0, 3 /* load old value */ + li 11, 3 /* mask to test for alignment */ + andc. 11, 3, 11 /* force address to be word-aligned */ +0: lwarx 12, 0, 11 /* load old value */ + bne 1f /* no realignment needed if it's aligned */ slwi 4, 4, 16 /* realign operand */ - andc 0, 0, 4 /* calculate new value */ - stwcx. 0, 0, 3 /* attempt to store */ - bne- 0 /* loop if failed */ +1: andc 12, 12, 4 /* calculate new value */ + stwcx. 12, 0, 11 /* attempt to store */ + bne- 0b /* loop if failed */ eieio /* synchronise */ sync blr /* return */ ASENTRY(atomic_add_16) -0: lwarx 0, 0, 3 /* load old value */ - srwi 0, 9, 16 /* realign */ - add 0, 4, 0 /* calculate new value */ - slwi 0, 0, 16 /* realign */ - clrlwi 9, 9, 16 /* clear old value */ - or 9, 9, 0 /* copy in new value */ - stwcx. 0, 0, 3 /* attempt to store */ - bne- 0 /* loop if failed */ + li 11, 3 /* mask to test for alignment */ + andc. 11, 3, 11 /* force address to be word-aligned */ +0: lwarx 12, 0, 11 /* load old value */ + bne 1f /* no realignment needed if it's aligned */ + srwi 12, 9, 16 /* realign */ +1: add 12, 4, 12 /* calculate new value */ + bne 2f /* no realignment needed if it's aligned */ + slwi 12, 12, 16 /* realign */ +2: clrlwi 9, 9, 16 /* clear old value */ + or 9, 9, 12 /* copy in new value */ + stwcx. 12, 0, 11 /* attempt to store */ + bne- 0b /* loop if failed */ eieio /* synchronise */ sync blr /* return */ ASENTRY(atomic_subtract_16) -0: lwarx 0, 0, 3 /* load old value */ - srwi 0, 9, 16 /* realign */ - subf 0, 4, 0 /* calculate new value */ - slwi 0, 0, 16 /* realign */ - clrlwi 9, 9, 16 /* clear old value */ - or 9, 9, 0 /* copy in new value */ - stwcx. 0, 0, 3 /* attempt to store */ + li 11, 3 /* mask to test for alignment */ + andc. 11, 3, 11 /* force address to be word-aligned */ +0: lwarx 12, 0, 11 /* load old value */ + bne 1f /* no realignment needed if it's aligned */ + srwi 12, 9, 16 /* realign */ +1: subf 12, 4, 12 /* calculate new value */ + bne 2f /* no realignment needed if it's aligned */ + slwi 12, 12, 16 /* realign */ +2: clrlwi 9, 9, 16 /* clear old value */ + or 9, 9, 12 /* copy in new value */ + stwcx. 12, 0, 11 /* attempt to store */ bne- 0 /* loop if failed */ eieio /* synchronise */ sync diff --git a/sys/powerpc/powerpc/autoconf.c b/sys/powerpc/powerpc/autoconf.c new file mode 100644 index 000000000000..a3b5721d1c8c --- /dev/null +++ b/sys/powerpc/powerpc/autoconf.c @@ -0,0 +1,78 @@ +/*- + * Copyright (c) 1998 Doug Rabson + * All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif + +#include "opt_bootp.h" +#include "opt_nfs.h" +#include "opt_nfsroot.h" + +#include +#include +#include +#include +#include /* for BASE_SLICE, MAX_SLICES */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +static void configure __P((void *)); +SYSINIT(configure, SI_SUB_CONFIGURE, SI_ORDER_THIRD, configure, NULL) + +extern int nfs_diskless_valid; + +dev_t rootdev = NODEV; +dev_t dumpdev = NODEV; + +/* + * Determine i/o configuration for a machine. + */ +static void +configure(void *dummy) +{ + +#if 0 /* XXX */ + cold = 0; +#endif +} diff --git a/sys/powerpc/powerpc/busdma_machdep.c b/sys/powerpc/powerpc/busdma_machdep.c new file mode 100644 index 000000000000..57cb8f6d8994 --- /dev/null +++ b/sys/powerpc/powerpc/busdma_machdep.c @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2001 Benno Rice. + * All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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 TOOLS GMBH 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. + */ + +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif /* not lint */ + +int busdma_swi_pending; + +void +busdma_swi(void) +{ + + /* XXX: coming soon */ + return; +} diff --git a/sys/powerpc/powerpc/elf_machdep.c b/sys/powerpc/powerpc/elf_machdep.c index 5582fcb1337d..44ea9ef4c468 100644 --- a/sys/powerpc/powerpc/elf_machdep.c +++ b/sys/powerpc/powerpc/elf_machdep.c @@ -67,20 +67,10 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) switch (rtype) { - case R_ALPHA_NONE: + case R_PPC_NONE: break; - case R_ALPHA_REFQUAD: - addr = (Elf_Addr) - linker_file_lookup_symbol(lf, sym, 1); - if (addr == NULL) - return -1; - addr += addend; - if (*where != addr) - *where = addr; - break; - - case R_ALPHA_GLOB_DAT: + case R_PPC_GLOB_DAT: addr = (Elf_Addr) linker_file_lookup_symbol(lf, sym, 1); if (addr == NULL) @@ -90,7 +80,7 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) *where = addr; break; - case R_ALPHA_JMP_SLOT: + case R_PPC_JMP_SLOT: /* No point in lazy binding for kernel modules. */ addr = (Elf_Addr) linker_file_lookup_symbol(lf, sym, 1); @@ -100,13 +90,13 @@ elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) *where = addr; break; - case R_ALPHA_RELATIVE: + case R_PPC_RELATIVE: addr = relocbase + addend + *where; if (*where != addr) *where = addr; break; - case R_ALPHA_COPY: + case R_PPC_COPY: /* * There shouldn't be copy relocations in kernel * objects. diff --git a/sys/powerpc/powerpc/genassym.c b/sys/powerpc/powerpc/genassym.c index 03990ea51b38..d348236ded46 100644 --- a/sys/powerpc/powerpc/genassym.c +++ b/sys/powerpc/powerpc/genassym.c @@ -44,133 +44,58 @@ #include #include #include -#include #include -#include #include #include #include #include #include -#include -#include -#include #include #include #include #include #include -#include #include #include #include #include #include #include +#include +#include ASSYM(GD_CURPROC, offsetof(struct globaldata, gd_curproc)); -ASSYM(GD_FPCURPROC, offsetof(struct globaldata, gd_fpcurproc)); ASSYM(GD_CURPCB, offsetof(struct globaldata, gd_curpcb)); ASSYM(GD_SWITCHTIME, offsetof(struct globaldata, gd_switchtime)); -ASSYM(GD_CPUID, offsetof(struct globaldata, gd_cpuid)); -ASSYM(GD_IDLEPCBPHYS, offsetof(struct globaldata, gd_idlepcbphys)); +ASSYM(GD_ASTPENDING, offsetof(struct globaldata, gd_astpending)); ASSYM(MTX_LOCK, offsetof(struct mtx, mtx_lock)); -ASSYM(MTX_RECURSE, offsetof(struct mtx, mtx_recurse)); +ASSYM(MTX_RECURSECNT, offsetof(struct mtx, mtx_recurse)); ASSYM(MTX_SAVECRIT, offsetof(struct mtx, mtx_savecrit)); -ASSYM(MTX_UNOWNED, MTX_UNOWNED); + +ASSYM(PM_KERNELSR, offsetof(struct pmap, pm_sr[KERNEL_SR])); +ASSYM(PM_USERSR, offsetof(struct pmap, pm_sr[USER_SR])); + +ASSYM(FRAMELEN, FRAMELEN); +ASSYM(FRAME_0, offsetof(struct trapframe, fixreg[0])); +ASSYM(FRAME_1, offsetof(struct trapframe, fixreg[1])); +ASSYM(FRAME_2, offsetof(struct trapframe, fixreg[2])); +ASSYM(FRAME_3, offsetof(struct trapframe, fixreg[3])); +ASSYM(FRAME_LR, offsetof(struct trapframe, lr)); +ASSYM(FRAME_CR, offsetof(struct trapframe, cr)); +ASSYM(FRAME_CTR, offsetof(struct trapframe, ctr)); +ASSYM(FRAME_XER, offsetof(struct trapframe, xer)); +ASSYM(FRAME_SRR0, offsetof(struct trapframe, srr0)); +ASSYM(FRAME_SRR1, offsetof(struct trapframe, srr1)); +ASSYM(FRAME_DAR, offsetof(struct trapframe, dar)); +ASSYM(FRAME_DSISR, offsetof(struct trapframe, dsisr)); +ASSYM(FRAME_EXC, offsetof(struct trapframe, exc)); + +ASSYM(SFRAMELEN, roundup(sizeof(struct switchframe), 16)); + +ASSYM(PCB_PMR, offsetof(struct pcb, pcb_pmreal)); +ASSYM(PCB_SP, offsetof(struct pcb, pcb_sp)); +ASSYM(PCB_SPL, offsetof(struct pcb, pcb_spl)); +ASSYM(PCB_FAULT, offsetof(struct pcb, pcb_onfault)); ASSYM(P_ADDR, offsetof(struct proc, p_addr)); -ASSYM(P_MD_FLAGS, offsetof(struct proc, p_md.md_flags)); -ASSYM(P_MD_PCBPADDR, offsetof(struct proc, p_md.md_pcbpaddr)); -ASSYM(P_MD_HAE, offsetof(struct proc, p_md.md_hae)); -#ifdef SMP -ASSYM(P_MD_KERNNEST, offsetof(struct proc, p_md.md_kernnest)); -#endif -ASSYM(MDP_HAEUSED, MDP_HAEUSED); - -ASSYM(CHIPSET_WRITE_HAE, offsetof(struct alpha_chipset, write_hae)); - -ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS); -ASSYM(PTLEV1I, PTLEV1I); -ASSYM(PTESIZE, PTESIZE); - -ASSYM(U_PCB_ONFAULT, offsetof(struct user, u_pcb.pcb_onfault)); -ASSYM(U_PCB_HWPCB_KSP, offsetof(struct user, u_pcb.pcb_hw.apcb_ksp)); -ASSYM(U_PCB_CONTEXT, offsetof(struct user, u_pcb.pcb_context)); - -ASSYM(PCB_HW, offsetof(struct pcb, pcb_hw)); - -ASSYM(FPREG_FPR_REGS, offsetof(struct fpreg, fpr_regs)); -ASSYM(FPREG_FPR_CR, offsetof(struct fpreg, fpr_cr)); - -ASSYM(EFAULT, EFAULT); -ASSYM(ENAMETOOLONG, ENAMETOOLONG); - -/* Register offsets, for stack frames. */ -ASSYM(FRAME_V0, FRAME_V0); -ASSYM(FRAME_T0, FRAME_T0); -ASSYM(FRAME_T1, FRAME_T1); -ASSYM(FRAME_T2, FRAME_T2); -ASSYM(FRAME_T3, FRAME_T3); -ASSYM(FRAME_T4, FRAME_T4); -ASSYM(FRAME_T5, FRAME_T5); -ASSYM(FRAME_T6, FRAME_T6); -ASSYM(FRAME_T7, FRAME_T7); -ASSYM(FRAME_S0, FRAME_S0); -ASSYM(FRAME_S1, FRAME_S1); -ASSYM(FRAME_S2, FRAME_S2); -ASSYM(FRAME_S3, FRAME_S3); -ASSYM(FRAME_S4, FRAME_S4); -ASSYM(FRAME_S5, FRAME_S5); -ASSYM(FRAME_S6, FRAME_S6); -ASSYM(FRAME_A3, FRAME_A3); -ASSYM(FRAME_A4, FRAME_A4); -ASSYM(FRAME_A5, FRAME_A5); -ASSYM(FRAME_T8, FRAME_T8); -ASSYM(FRAME_T9, FRAME_T9); -ASSYM(FRAME_T10, FRAME_T10); -ASSYM(FRAME_T11, FRAME_T11); -ASSYM(FRAME_RA, FRAME_RA); -ASSYM(FRAME_T12, FRAME_T12); -ASSYM(FRAME_AT, FRAME_AT); -ASSYM(FRAME_SP, FRAME_SP); -ASSYM(FRAME_FLAGS, FRAME_FLAGS); -ASSYM(FRAME_FLAGS_SYSCALL, FRAME_FLAGS_SYSCALL); - -ASSYM(FRAME_SW_SIZE, FRAME_SW_SIZE); - -ASSYM(FRAME_PS, FRAME_PS); -ASSYM(FRAME_PC, FRAME_PC); -ASSYM(FRAME_GP, FRAME_GP); -ASSYM(FRAME_A0, FRAME_A0); -ASSYM(FRAME_A1, FRAME_A1); -ASSYM(FRAME_A2, FRAME_A2); - -ASSYM(FRAME_SIZE, FRAME_SIZE); - -/* bits of the PS register */ -ASSYM(ALPHA_PSL_USERMODE, ALPHA_PSL_USERMODE); -ASSYM(ALPHA_PSL_IPL_MASK, ALPHA_PSL_IPL_MASK); -ASSYM(ALPHA_PSL_IPL_0, ALPHA_PSL_IPL_0); -ASSYM(ALPHA_PSL_IPL_SOFT, ALPHA_PSL_IPL_SOFT); -ASSYM(ALPHA_PSL_IPL_HIGH, ALPHA_PSL_IPL_HIGH); - -/* pte bits */ -ASSYM(ALPHA_L1SHIFT, ALPHA_L1SHIFT); -ASSYM(ALPHA_L2SHIFT, ALPHA_L2SHIFT); -ASSYM(ALPHA_L3SHIFT, ALPHA_L3SHIFT); -ASSYM(ALPHA_K1SEG_BASE, ALPHA_K1SEG_BASE); -ASSYM(ALPHA_PTE_VALID, ALPHA_PTE_VALID); -ASSYM(ALPHA_PTE_ASM, ALPHA_PTE_ASM); -ASSYM(ALPHA_PTE_KR, ALPHA_PTE_KR); -ASSYM(ALPHA_PTE_KW, ALPHA_PTE_KW); - -/* Kernel entries */ -ASSYM(ALPHA_KENTRY_ARITH, ALPHA_KENTRY_ARITH); -ASSYM(ALPHA_KENTRY_MM, ALPHA_KENTRY_MM); - -ASSYM(ALPHA_KENTRY_IF, ALPHA_KENTRY_IF); -ASSYM(ALPHA_KENTRY_UNA, ALPHA_KENTRY_UNA); - -ASSYM(VPTBASE, VPTBASE); diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c index 502abf35a3a9..a8e581961903 100644 --- a/sys/powerpc/powerpc/mp_machdep.c +++ b/sys/powerpc/powerpc/mp_machdep.c @@ -48,28 +48,6 @@ int boot_cpu_id; -/* - * XXX: needs to move to machdep.c - * - * Initialise a struct globaldata. - */ -void -globaldata_init(struct globaldata *globaldata, int cpuno, size_t sz) -{ - - bzero(globaldata, sz); - globaldata->gd_idlepcbphys = vtophys((vm_offset_t) &globaldata->gd_idlepcb); - globaldata->gd_idlepcb.apcb_ksp = (u_int64_t) - ((caddr_t) globaldata + sz - sizeof(struct trapframe)); - globaldata->gd_idlepcb.apcb_ptbr = proc0.p_addr->u_pcb.pcb_hw.apcb_ptbr; - globaldata->gd_cpuno = cpuno; - globaldata->gd_other_cpus = all_cpus & ~(1 << cpuno); - globaldata->gd_next_asn = 0; - globaldata->gd_current_asngen = 1; - globaldata->gd_cpuid = cpuno; - globaldata_register(globaldata); -} - int cpu_mp_probe(void) { diff --git a/sys/powerpc/powerpc/procfs_machdep.c b/sys/powerpc/powerpc/procfs_machdep.c index 96fd0e5aa9e6..d6085e8aea35 100644 --- a/sys/powerpc/powerpc/procfs_machdep.c +++ b/sys/powerpc/powerpc/procfs_machdep.c @@ -36,7 +36,6 @@ * * @(#)procfs_machdep.c 8.3 (Berkeley) 1/27/94 * - * From: * $FreeBSD$ */ @@ -70,7 +69,6 @@ #include #include #include -#include #include #include @@ -81,25 +79,18 @@ #include #include -#define PROCFS_ACTION(action) do { \ - int error; \ - \ - mtx_lock_spin(&sched_lock); \ - if ((p->p_sflag & PS_INMEM) == 0) \ - error = EIO; \ - else \ - error = (action); \ - mtx_unlock_spin(&sched_lock); \ - return (error); \ -} while(0) +#include int procfs_read_regs(p, regs) struct proc *p; struct reg *regs; { + if ((p->p_flag & PS_INMEM) == 0) { + return (EIO); + } - PROCFS_ACTION(fill_regs(p, regs)); + return (fill_regs(p, regs)); } int @@ -107,8 +98,11 @@ procfs_write_regs(p, regs) struct proc *p; struct reg *regs; { + if ((p->p_flag & PS_INMEM) == 0) { + return (EIO); + } - PROCFS_ACTION(set_regs(p, regs)); + return (set_regs(p, regs)); } /* @@ -121,8 +115,11 @@ procfs_read_fpregs(p, fpregs) struct proc *p; struct fpreg *fpregs; { + if ((p->p_flag & PS_INMEM) == 0) { + return (EIO); + } - PROCFS_ACTION(fill_fpregs(p, fpregs)); + return (fill_fpregs(p, fpregs)); } int @@ -130,8 +127,11 @@ procfs_write_fpregs(p, fpregs) struct proc *p; struct fpreg *fpregs; { + if ((p->p_flag & PS_INMEM) == 0) { + return (EIO); + } - PROCFS_ACTION(set_fpregs(p, fpregs)); + return (set_fpregs(p, fpregs)); } int diff --git a/sys/powerpc/powerpc/sys_machdep.c b/sys/powerpc/powerpc/sys_machdep.c new file mode 100644 index 000000000000..3d3157d5ba00 --- /dev/null +++ b/sys/powerpc/powerpc/sys_machdep.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2001 Benno Rice. + * All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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 TOOLS GMBH 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. + */ + +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif /* not lint */ + +#include +#include +#include +#include + +int +sysarch(struct proc *p, struct sysarch_args *uap) +{ + + return (EOPNOTSUPP); +} diff --git a/sys/powerpc/powerpc/vm_machdep.c b/sys/powerpc/powerpc/vm_machdep.c index 79209e5f2428..11bdf0901a96 100644 --- a/sys/powerpc/powerpc/vm_machdep.c +++ b/sys/powerpc/powerpc/vm_machdep.c @@ -84,7 +84,8 @@ #include #include #include -#include + +#include #include #include @@ -122,99 +123,7 @@ cpu_fork(p1, p2, flags) register struct proc *p1, *p2; int flags; { - if ((flags & RFPROC) == 0) - return; - - p2->p_md.md_tf = p1->p_md.md_tf; - p2->p_md.md_flags = p1->p_md.md_flags & (MDP_FPUSED | MDP_UAC_MASK); - - /* - * Cache the physical address of the pcb, so we can - * swap to it easily. - */ - p2->p_md.md_pcbpaddr = (void*)vtophys((vm_offset_t)&p2->p_addr->u_pcb); - - /* - * Copy floating point state from the FP chip to the PCB - * if this process has state stored there. - */ - alpha_fpstate_save(p1, 0); - - /* - * Copy pcb and stack from proc p1 to p2. We do this as - * cheaply as possible, copying only the active part of the - * stack. The stack and pcb need to agree. Make sure that the - * new process has FEN disabled. - */ - p2->p_addr->u_pcb = p1->p_addr->u_pcb; - p2->p_addr->u_pcb.pcb_hw.apcb_usp = alpha_pal_rdusp(); - p2->p_addr->u_pcb.pcb_hw.apcb_flags &= ~ALPHA_PCB_FLAGS_FEN; - - /* - * Set the floating point state. - */ - if ((p2->p_addr->u_pcb.pcb_fp_control & IEEE_INHERIT) == 0) { - p2->p_addr->u_pcb.pcb_fp_control = 0; - p2->p_addr->u_pcb.pcb_fp.fpr_cr = (FPCR_DYN_NORMAL - | FPCR_INVD | FPCR_DZED - | FPCR_OVFD | FPCR_INED - | FPCR_UNFD); - } - - /* - * Arrange for a non-local goto when the new process - * is started, to resume here, returning nonzero from setjmp. - */ -#ifdef DIAGNOSTIC - alpha_fpstate_check(p1); -#endif - - /* - * create the child's kernel stack, from scratch. - */ - { - struct user *up = p2->p_addr; - struct trapframe *p2tf; - - /* - * Pick a stack pointer, leaving room for a trapframe; - * copy trapframe from parent so return to user mode - * will be to right address, with correct registers. - */ - p2tf = p2->p_md.md_tf = (struct trapframe *) - ((char *)p2->p_addr + USPACE - sizeof(struct trapframe)); - bcopy(p1->p_md.md_tf, p2->p_md.md_tf, - sizeof(struct trapframe)); - - /* - * Set up return-value registers as fork() libc stub expects. - */ - p2tf->tf_regs[FRAME_V0] = 0; /* child's pid (linux) */ - p2tf->tf_regs[FRAME_A3] = 0; /* no error */ - p2tf->tf_regs[FRAME_A4] = 1; /* is child (FreeBSD) */ - - /* - * Arrange for continuation at fork_return(), which - * will return to exception_return(). Note that the child - * process doesn't stay in the kernel for long! - * - * This is an inlined version of cpu_set_kpc. - */ - up->u_pcb.pcb_hw.apcb_ksp = (u_int64_t)p2tf; - up->u_pcb.pcb_context[0] = - (u_int64_t)fork_return; /* s0: a0 */ - up->u_pcb.pcb_context[1] = - (u_int64_t)exception_return; /* s1: ra */ - up->u_pcb.pcb_context[2] = (u_long) p2; /* s2: a1 */ - up->u_pcb.pcb_context[7] = - (u_int64_t)fork_trampoline; /* ra: assembly magic */ -#ifdef SMP - /* - * We start off at a nesting level of 1 within the kernel. - */ - p2->p_md.md_kernnest = 1; -#endif - } + /* XXX: coming soon... */ } /* @@ -233,8 +142,10 @@ cpu_set_fork_handler(p, func, arg) * Note that the trap frame follows the args, so the function * is really called like this: func(arg, frame); */ +#if 0 /* XXX */ p->p_addr->u_pcb.pcb_context[0] = (u_long) func; p->p_addr->u_pcb.pcb_context[2] = (u_long) arg; +#endif } /* @@ -248,8 +159,6 @@ void cpu_exit(p) register struct proc *p; { - alpha_fpstate_drop(p); - PROC_LOCK(p); mtx_lock_spin(&sched_lock); mtx_unlock_flags(&Giant, MTX_NOSWITCH); @@ -263,6 +172,7 @@ cpu_exit(p) */ p->p_stat = SZOMB; + mp_fixme("assumption: p_pptr won't change at this time"); wakeup(p->p_pptr); PROC_UNLOCK_NOSWITCH(p); @@ -390,7 +300,7 @@ vunmapbuf(bp) void cpu_reset() { - prom_halt(0); + OF_exit(); } int @@ -456,7 +366,13 @@ vm_page_zero_idle() TAILQ_REMOVE(&vm_page_queues[m->queue].pl, m, pageq); m->queue = PQ_NONE; splx(s); +#if 0 + rel_mplock(); +#endif pmap_zero_page(VM_PAGE_TO_PHYS(m)); +#if 0 + get_mplock(); +#endif (void)splvm(); vm_page_flag_set(m, PG_ZERO); m->queue = PQ_FREE + m->pc; @@ -480,8 +396,10 @@ vm_page_zero_idle() void swi_vm(void *dummy) { +#if 0 /* XXX: Don't have busdma stuff yet */ if (busdma_swi_pending != 0) busdma_swi(); +#endif } /*