diff options
25 files changed, 606 insertions, 487 deletions
diff --git a/sys/powerpc/aim/vm_machdep.c b/sys/powerpc/aim/vm_machdep.c index 79209e5..11bdf09 100644 --- a/sys/powerpc/aim/vm_machdep.c +++ b/sys/powerpc/aim/vm_machdep.c @@ -84,7 +84,8 @@ #include <machine/cpu.h> #include <machine/fpu.h> #include <machine/md_var.h> -#include <machine/prom.h> + +#include <dev/ofw/openfirm.h> #include <vm/vm.h> #include <vm/vm_param.h> @@ -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 ebd45ba..619ca7e 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 9e4ad71..a7e6263 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 0000000..d9ad6ae --- /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 <sys/types.h> + +#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 1935654..c10dfb4 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 4d6d02f..de9a1ce 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 10de1b7..286e5eb 100644 --- a/sys/powerpc/include/globals.h +++ b/sys/powerpc/include/globals.h @@ -30,23 +30,30 @@ #define _MACHINE_GLOBALS_H_ #ifdef _KERNEL +#include <machine/cpufunc.h> #include <machine/globaldata.h> -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 0000000..15ec74c --- /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 bf99dd7..f5df84c 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 c141d6f..5038f42 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 ebc67b7..3ebcd94 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 <machine/cpu.h> +#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 4d6d02f..de9a1ce 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 0000000..a8ce0b1 --- /dev/null +++ b/sys/powerpc/include/reloc.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>. + * 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 0000000..15ec74c --- /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 4231ab0..8d6b107 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 8beab01..a844f7a 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 8beab01..a844f7a 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 0000000..a3b5721 --- /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 <sys/param.h> +#include <sys/systm.h> +#include <sys/conf.h> +#include <sys/disklabel.h> +#include <sys/diskslice.h> /* for BASE_SLICE, MAX_SLICES */ +#include <sys/ipl.h> +#include <sys/reboot.h> +#include <sys/kernel.h> +#include <sys/mount.h> +#include <sys/sysctl.h> +#include <sys/bus.h> +#include <sys/devicestat.h> +#include <sys/cons.h> + +#include <machine/md_var.h> +#include <machine/bootinfo.h> + +#include <cam/cam.h> +#include <cam/cam_ccb.h> +#include <cam/cam_sim.h> +#include <cam/cam_periph.h> +#include <cam/cam_xpt_sim.h> +#include <cam/cam_debug.h> + +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 0000000..57cb8f6 --- /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 5582fcb..44ea9ef 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 03990ea..d348236 100644 --- a/sys/powerpc/powerpc/genassym.c +++ b/sys/powerpc/powerpc/genassym.c @@ -44,133 +44,58 @@ #include <sys/bio.h> #include <sys/buf.h> #include <sys/errno.h> -#include <net/radix.h> #include <sys/socket.h> -#include <sys/proc.h> #include <sys/mount.h> #include <sys/mutex.h> #include <sys/resource.h> #include <sys/resourcevar.h> #include <sys/ktr.h> -#include <machine/frame.h> -#include <machine/chipset.h> -#include <machine/globaldata.h> #include <sys/vmmeter.h> #include <vm/vm.h> #include <vm/vm_param.h> #include <vm/pmap.h> #include <vm/vm_map.h> -#include <sys/user.h> #include <net/if.h> #include <netinet/in.h> #include <nfs/nfsv2.h> #include <nfs/rpcv2.h> #include <nfs/nfs.h> #include <nfs/nfsdiskless.h> +#include <machine/pcb.h> +#include <machine/pmap.h> 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(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(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(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); +ASSYM(P_ADDR, offsetof(struct proc, p_addr)); diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c index 502abf3..a8e5819 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 96fd0e5..d6085e8 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 <sys/mutex.h> #include <sys/proc.h> #include <sys/ptrace.h> -#include <sys/user.h> #include <sys/vnode.h> #include <machine/md_var.h> @@ -81,25 +79,18 @@ #include <vm/pmap.h> #include <vm/vm_map.h> -#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 <sys/user.h> 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 0000000..3d3157d --- /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 <sys/param.h> +#include <sys/systm.h> +#include <sys/errno.h> +#include <sys/sysproto.h> + +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 79209e5..11bdf09 100644 --- a/sys/powerpc/powerpc/vm_machdep.c +++ b/sys/powerpc/powerpc/vm_machdep.c @@ -84,7 +84,8 @@ #include <machine/cpu.h> #include <machine/fpu.h> #include <machine/md_var.h> -#include <machine/prom.h> + +#include <dev/ofw/openfirm.h> #include <vm/vm.h> #include <vm/vm_param.h> @@ -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 } /* |