From a2e5cb9c1ece11bd25f867c25e6f34022389125f Mon Sep 17 00:00:00 2001 From: mp Date: Thu, 20 Sep 2001 00:47:17 +0000 Subject: Update PowerPC MD code to compile and do initial bootstrap based on recent changes (KSE and VM requiring physmem to be setup). Reviewed by: benno, jhb, julian --- sys/powerpc/aim/locore.S | 2 +- sys/powerpc/aim/machdep.c | 89 ++++++++++++++++--------- sys/powerpc/aim/mmu_oea.c | 122 ++++++++++++++++++++++++++++++----- sys/powerpc/aim/swtch.S | 6 +- sys/powerpc/aim/vm_machdep.c | 28 ++++---- sys/powerpc/include/cpu.h | 2 +- sys/powerpc/include/frame.h | 3 +- sys/powerpc/include/param.h | 7 +- sys/powerpc/include/pmap.h | 3 +- sys/powerpc/include/reg.h | 2 +- sys/powerpc/powerpc/autoconf.c | 2 +- sys/powerpc/powerpc/genassym.c | 3 +- sys/powerpc/powerpc/locore.S | 2 +- sys/powerpc/powerpc/locore.s | 2 +- sys/powerpc/powerpc/machdep.c | 89 ++++++++++++++++--------- sys/powerpc/powerpc/mmu_oea.c | 122 ++++++++++++++++++++++++++++++----- sys/powerpc/powerpc/pmap.c | 122 ++++++++++++++++++++++++++++++----- sys/powerpc/powerpc/procfs_machdep.c | 64 +++++++++--------- sys/powerpc/powerpc/swtch.S | 6 +- sys/powerpc/powerpc/swtch.s | 6 +- sys/powerpc/powerpc/sys_machdep.c | 2 +- sys/powerpc/powerpc/vm_machdep.c | 28 ++++---- 22 files changed, 519 insertions(+), 193 deletions(-) (limited to 'sys') diff --git a/sys/powerpc/aim/locore.S b/sys/powerpc/aim/locore.S index 4ad6daf..9deb42f 100644 --- a/sys/powerpc/aim/locore.S +++ b/sys/powerpc/aim/locore.S @@ -1351,7 +1351,7 @@ setfault: mfcr 12 mfsprg 4,0 lwz 4,GD_CURPCB(4) - stw 3,PCB_FAULT(4) + stw 3,PCB_ONFAULT(4) stw 0,0(3) stw 1,4(3) stw 2,8(3) diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c index 328a710..205b3d7 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/machdep.c @@ -112,12 +112,14 @@ static const char rcsid[] = #include #include +int physmem = 0; int cold = 1; struct mtx sched_lock; struct mtx Giant; -struct user *proc0paddr; +struct user *proc0uarea; +vm_offset_t proc0kstack; char machine[] = "powerpc"; SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); @@ -146,6 +148,16 @@ void install_extint(void (*)(void)); void osendsig(sig_t, int, sigset_t *, u_long); #endif +static int +sysctl_hw_physmem(SYSCTL_HANDLER_ARGS) +{ + int error = sysctl_handle_int(oidp, 0, ctob(physmem), req); + return (error); +} + +SYSCTL_PROC(_hw, HW_PHYSMEM, physmem, CTLTYPE_INT|CTLFLAG_RD, + 0, 0, sysctl_hw_physmem, "IU", ""); + struct msgbuf *msgbufp = 0; int bootverbose = 0, Maxmem = 0; @@ -155,6 +167,8 @@ vm_offset_t phys_avail[10]; static int chosen; +static struct trapframe proc0_tf; + struct pmap ofw_pmap; extern int ofmsr; @@ -334,8 +348,6 @@ extern ddblow, ddbsize; extern ipkdblow, ipkdbsize; #endif -static struct globaldata tmpglobal; - void powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args) { @@ -382,6 +394,11 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args) * This is here because mem_regions() call needs bat0 set up. */ mem_regions(&allmem, &availmem); + + /* Calculate the physical memory in the machine */ + for (mp = allmem; mp->size; mp++) + physmem += btoc(mp->size); + for (mp = allmem; mp->size; mp++) { vm_offset_t pa = mp->start & 0xf0000000; vm_offset_t end = mp->start + mp->size; @@ -398,10 +415,33 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args) chosen = OF_finddevice("/chosen"); save_ofw_mapping(); - proc0.p_addr = proc0paddr; - bzero(proc0.p_addr, sizeof *proc0.p_addr); + pmap_setavailmem(startkernel, endkernel); + + proc_linkup(&proc0); + + proc0uarea = (struct user *)pmap_steal_memory(UAREA_PAGES * PAGE_SIZE); + proc0kstack = pmap_steal_memory(KSTACK_PAGES * PAGE_SIZE); + proc0.p_uarea = proc0uarea; + thread0 = &proc0.p_thread; + thread0->td_kstack = proc0kstack; + thread0->td_pcb = (struct pcb *) + (thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; + + globalp = pmap_steal_memory(round_page(sizeof(struct globaldata))); + + /* + * XXX: Pass 0 as CPU id. This is bad. We need to work out + * XXX: which CPU we are somehow. + */ + globaldata_init(globalp, 0, sizeof(struct globaldata)); + __asm ("mtsprg 0, %0" :: "r"(globalp)); + + /* setup curproc so the mutexes work */ - LIST_INIT(&proc0.p_contested); + PCPU_SET(curthread, thread0); + PCPU_SET(spinlocks, NULL); + + LIST_INIT(&thread0->td_contested); /* XXX: NetBSDism I _think_. Not sure yet. */ #if 0 @@ -549,25 +589,15 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args) /* * Initialize pmap module. */ - pmap_bootstrap(startkernel, endkernel); + pmap_bootstrap(); restore_ofw_mapping(); - /* - * Setup the global data for the bootstrap cpu. - */ - globalp = (struct globaldata *) &tmpglobal; - - /* - * XXX: Pass 0 as CPU id. This is bad. We need to work out - * XXX: which CPU we are somehow. - */ - globaldata_init(globalp, 0, sizeof(struct globaldata)); - __asm ("mtsprg 0, %0" :: "r"(globalp)); - PCPU_GET(next_asn) = 1; /* 0 used for proc0 pmap */ - PCPU_SET(curproc, &proc0); - PCPU_SET(spinlocks, NULL); + + /* setup proc 0's pcb */ + thread0->td_pcb->pcb_flags = 0; /* XXXKSE */ + thread0->td_frame = &proc0_tf; } static int N_mapping; @@ -695,7 +725,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) #ifdef COMPAT_43 int -osigreturn(struct proc *p, struct osigreturn_args *uap) +osigreturn(struct thread *td, struct osigreturn_args *uap) { /* XXX: To be done */ @@ -704,7 +734,7 @@ osigreturn(struct proc *p, struct osigreturn_args *uap) #endif int -sigreturn(struct proc *p, struct sigreturn_args *uap) +sigreturn(struct thread *td, struct sigreturn_args *uap) { /* XXX: To be done */ @@ -730,13 +760,12 @@ cpu_halt(void) * Set set up registers on exec. */ void -setregs(struct proc *p, u_long entry, u_long stack, u_long ps_strings) +setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) { struct trapframe *tf; struct ps_strings arginfo; - tf = trapframe(p); - + tf = trapframe(td); bzero(tf, sizeof *tf); tf->fixreg[1] = -roundup(-stack + 8, 16); @@ -769,7 +798,7 @@ setregs(struct proc *p, u_long entry, u_long stack, u_long ps_strings) tf->srr0 = entry; tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT; - p->p_addr->u_pcb.pcb_flags = 0; + td->td_pcb->pcb_flags = 0; } extern void *extint, *extsize; @@ -838,7 +867,7 @@ set_fpregs(struct proc *p, struct fpreg *fpregs) } int -ptrace_set_pc(struct proc *p, unsigned long addr) +ptrace_set_pc(struct thread *td, unsigned long addr) { /* XXX: coming soon... */ @@ -846,7 +875,7 @@ ptrace_set_pc(struct proc *p, unsigned long addr) } int -ptrace_single_step(struct proc *p) +ptrace_single_step(struct thread *td) { /* XXX: coming soon... */ @@ -854,7 +883,7 @@ ptrace_single_step(struct proc *p) } int -ptrace_clear_single_step(struct proc *p) +ptrace_clear_single_step(struct thread *td) { /* XXX: coming soon... */ diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c index ad79c602..7b3f3e7 100644 --- a/sys/powerpc/aim/mmu_oea.c +++ b/sys/powerpc/aim/mmu_oea.c @@ -375,7 +375,7 @@ pte_spill(vm_offset_t addr) * This is called during powerpc_init, before the system is really initialized. */ void -pmap_bootstrap(u_int kernelstart, u_int kernelend) +pmap_setavailmem(u_int kernelstart, u_int kernelend) { struct mem_region *mp, *mp1; int cnt, i; @@ -585,6 +585,22 @@ pmap_bootstrap(u_int kernelstart, u_int kernelend) } #endif + nextavail = avail->start; + avail_start = avail->start; + for (mp = avail, i = 0; mp->size; mp++) { + avail_end = mp->start + mp->size; + phys_avail[i++] = mp->start; + phys_avail[i++] = mp->start + mp->size; + } + + +} + +void +pmap_bootstrap() +{ + int i; + /* * Initialize kernel pmap and hardware. */ @@ -632,14 +648,6 @@ pmap_bootstrap(u_int kernelstart, u_int kernelend) tlbia(); - nextavail = avail->start; - avail_start = avail->start; - for (mp = avail, i = 0; mp->size; mp++) { - avail_end = mp->start + mp->size; - phys_avail[i++] = mp->start; - phys_avail[i++] = mp->start + mp->size; - } - virtual_avail = VM_MIN_KERNEL_ADDRESS; virtual_end = VM_MAX_KERNEL_ADDRESS; } @@ -1449,7 +1457,7 @@ pmap_activate(struct thread *td) int psl, i, ksr, seg; pcb = td->td_pcb; - pmap = td->td_pric->p_vmspace->vm_map.pmap; + pmap = vmspace_pmap(td->td_proc->p_vmspace); /* * XXX Normally performed in cpu_fork(). @@ -1664,6 +1672,86 @@ pmap_swapout_proc(struct proc *p) return; } + +/* + * Create the kernel stack (including pcb for i386) for a new thread. + * This routine directly affects the fork perf for a process and + * create performance for a thread. + */ +void +pmap_new_thread(td) + struct thread *td; +{ + /* XXX: coming soon... */ + return; +} + +/* + * Dispose the kernel stack for a thread that has exited. + * This routine directly impacts the exit perf of a process and thread. + */ +void +pmap_dispose_thread(td) + struct thread *td; +{ + /* XXX: coming soon... */ + return; +} + +/* + * Allow the Kernel stack for a thread to be prejudicially paged out. + */ +void +pmap_swapout_thread(td) + struct thread *td; +{ + int i; + vm_object_t ksobj; + vm_offset_t ks; + vm_page_t m; + + ksobj = td->td_kstack_obj; + ks = td->td_kstack; + for (i = 0; i < KSTACK_PAGES; i++) { + m = vm_page_lookup(ksobj, i); + if (m == NULL) + panic("pmap_swapout_thread: kstack already missing?"); + vm_page_dirty(m); + vm_page_unwire(m, 0); + pmap_kremove(ks + i * PAGE_SIZE); + } +} + +/* + * Bring the kernel stack for a specified thread back in. + */ +void +pmap_swapin_thread(td) + struct thread *td; +{ + int i, rv; + vm_object_t ksobj; + vm_offset_t ks; + vm_page_t m; + + ksobj = td->td_kstack_obj; + ks = td->td_kstack; + for (i = 0; i < KSTACK_PAGES; i++) { + m = vm_page_grab(ksobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); + pmap_kenter(ks + i * PAGE_SIZE, VM_PAGE_TO_PHYS(m)); + if (m->valid != VM_PAGE_BITS_ALL) { + rv = vm_pager_get_pages(ksobj, &m, 1, 0); + if (rv != VM_PAGER_OK) + panic("pmap_swapin_thread: cannot get kstack for proc: %d\n", td->td_proc->p_pid); + m = vm_page_lookup(ksobj, i); + m->valid = VM_PAGE_BITS_ALL; + } + vm_page_wire(m); + vm_page_wakeup(m); + vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); + } +} + void pmap_pageable(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, boolean_t pageable) { @@ -1741,7 +1829,7 @@ pmap_steal_memory(vm_size_t size) } /* - * Create the UPAGES for a new process. + * Create the UAREA_PAGES for a new process. * This routine directly affects the fork perf for a process. */ void @@ -1761,20 +1849,20 @@ pmap_new_proc(struct proc *p) */ upobj = p->p_upages_obj; if (upobj == NULL) { - upobj = vm_object_allocate(OBJT_DEFAULT, UPAGES); + upobj = vm_object_allocate(OBJT_DEFAULT, UAREA_PAGES); p->p_upages_obj = upobj; } - /* get a kernel virtual address for the UPAGES for this proc */ - up = p->p_addr; + /* get a kernel virtual address for the UAREA_PAGES for this proc */ + up = (vm_offset_t)p->p_uarea; if (up == 0) { - up = kmem_alloc_nofault(kernel_map, UPAGES * PAGE_SIZE); + up = kmem_alloc_nofault(kernel_map, UAREA_PAGES * PAGE_SIZE); if (up == 0) panic("pmap_new_proc: upage allocation failed"); - p->p_addr = (struct user *)up; + p->p_uarea = (struct user *)up; } - for (i = 0; i < UPAGES; i++) { + for (i = 0; i < UAREA_PAGES; i++) { /* * Get a kernel stack page */ diff --git a/sys/powerpc/aim/swtch.S b/sys/powerpc/aim/swtch.S index af18976..bcdfcae 100644 --- a/sys/powerpc/aim/swtch.S +++ b/sys/powerpc/aim/swtch.S @@ -154,7 +154,7 @@ ENTRY(cpu_switch) stw 3,PCB_SPL(31) /* save spl */ /* Find a new process */ - bl chooseproc + bl choosethread 1: /* record new process */ @@ -172,7 +172,7 @@ ENTRY(cpu_switch) mr 12,2 /* save r2 */ stwu 1,-SFRAMELEN(1) /* still running on old stack */ stmw 10,8(1) - lwz 3,TD_ADDR(30) + lwz 3,TD_PCB(30) stw 1,PCB_SP(3) /* save SP */ switch_exited: @@ -182,7 +182,7 @@ switch_exited: mtmsr 3 /* indicate new pcb */ - lwz 4,TD_ADDR(31) + lwz 4,TD_PCB(31) mfsprg 5,0 stw 4,GD_CURPCB(5) diff --git a/sys/powerpc/aim/vm_machdep.c b/sys/powerpc/aim/vm_machdep.c index 630f9bf..c2110bb 100644 --- a/sys/powerpc/aim/vm_machdep.c +++ b/sys/powerpc/aim/vm_machdep.c @@ -119,8 +119,9 @@ vm_fault_quick(v, prot) * ready to run and return to user mode. */ void -cpu_fork(p1, p2, flags) - register struct proc *p1, *p2; +cpu_fork(td1, p2, flags) + register struct thread *td1; + register struct proc *p2; int flags; { /* XXX: coming soon... */ @@ -133,8 +134,8 @@ cpu_fork(p1, p2, flags) * This is needed to make kernel threads stay in kernel mode. */ void -cpu_set_fork_handler(p, func, arg) - struct proc *p; +cpu_set_fork_handler(td, func, arg) + struct thread *td; void (*func) __P((void *)); void *arg; { @@ -143,8 +144,8 @@ cpu_set_fork_handler(p, func, arg) * 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; + td->p_addr->u_pcb.pcb_context[0] = (u_long) func; + td->p_addr->u_pcb.pcb_context[2] = (u_long) arg; #endif } @@ -156,14 +157,14 @@ cpu_set_fork_handler(p, func, arg) * from proc0. */ void -cpu_exit(p) - register struct proc *p; +cpu_exit(td) + register struct thread *td; { } void -cpu_wait(p) - struct proc *p; +cpu_wait(td) + struct proc *td; { } @@ -180,13 +181,14 @@ cpu_throw(void) * Dump the machine specific header information at the start of a core dump. */ int -cpu_coredump(p, vp, cred) - struct proc *p; +cpu_coredump(td, vp, cred) + struct thread *td; struct vnode *vp; struct ucred *cred; { + struct proc *p = td->td_proc; - return (vn_rdwr(UIO_WRITE, vp, (caddr_t) p->p_addr, ctob(UPAGES), + return (vn_rdwr(UIO_WRITE, vp, (caddr_t)p->p_uarea, ctob(UAREA_PAGES), (off_t)0, UIO_SYSSPACE, IO_UNIT, cred, (int *)NULL, p)); } diff --git a/sys/powerpc/include/cpu.h b/sys/powerpc/include/cpu.h index 37ca02b..a7c70c1 100644 --- a/sys/powerpc/include/cpu.h +++ b/sys/powerpc/include/cpu.h @@ -92,7 +92,7 @@ get_cyclecount(void) return (time); } -#define cpu_getstack(p) ((p)->p_frame->fixreg[1]) +#define cpu_getstack(td) ((td)->td_frame->fixreg[1]) void savectx __P((struct pcb *)); diff --git a/sys/powerpc/include/frame.h b/sys/powerpc/include/frame.h index 927c574..3865de4 100644 --- a/sys/powerpc/include/frame.h +++ b/sys/powerpc/include/frame.h @@ -63,8 +63,7 @@ struct trapframe { * This is to ensure alignment of the stackpointer */ #define FRAMELEN roundup(sizeof(struct trapframe) + 8, 16) -#define trapframe(p) ((struct trapframe *)((char *)(p)->p_addr \ - + USPACE - FRAMELEN + 8)) +#define trapframe(td) ((td)->td_frame) struct switchframe { register_t sp; diff --git a/sys/powerpc/include/param.h b/sys/powerpc/include/param.h index 3ebcd94..3ac5646 100644 --- a/sys/powerpc/include/param.h +++ b/sys/powerpc/include/param.h @@ -112,8 +112,11 @@ #define MAXPHYS (128 * 1024) /* max raw I/O transfer size */ #define MAXDUMPPGS (DFLTPHYS/PAGE_SIZE) -#define UPAGES 2 /* pages of u-area */ -#define USPACE (UPAGES * PAGE_SIZE) /* total size of u-area */ +#ifndef KSTACK_UPAGES +#define KSTACK_PAGES 2 /* includes pcb */ +#endif +#define USPACE (KSTACK_PAGES * PAGE_SIZE) /* total size of pcb */ +#define UAREA_PAGES 1 /* holds struct user WITHOUT PCB */ /* * Constants related to network buffer management. diff --git a/sys/powerpc/include/pmap.h b/sys/powerpc/include/pmap.h index 83adf0d..26c0d6a 100644 --- a/sys/powerpc/include/pmap.h +++ b/sys/powerpc/include/pmap.h @@ -95,7 +95,8 @@ extern vm_offset_t phys_avail[]; extern vm_offset_t virtual_avail; extern vm_offset_t virtual_end; -void pmap_bootstrap __P((u_int kernelstart, u_int kernelend)); +void pmap_bootstrap __P((void)); +void pmap_setavailmem __P((u_int kernelstart, u_int kernelend)); vm_offset_t pmap_steal_memory __P((vm_size_t)); boolean_t ptemodify __P((struct vm_page *, u_int, u_int)); int ptebits __P((struct vm_page *, int)); diff --git a/sys/powerpc/include/reg.h b/sys/powerpc/include/reg.h index dfe9d96..a05e566 100644 --- a/sys/powerpc/include/reg.h +++ b/sys/powerpc/include/reg.h @@ -22,6 +22,6 @@ struct dbreg { unsigned long junk; }; -void setregs(struct proc *, u_long, u_long, u_long); +void setregs(struct thread *, u_long, u_long, u_long); #endif /* _POWERPC_REG_H_ */ diff --git a/sys/powerpc/powerpc/autoconf.c b/sys/powerpc/powerpc/autoconf.c index 400c234..04210cf 100644 --- a/sys/powerpc/powerpc/autoconf.c +++ b/sys/powerpc/powerpc/autoconf.c @@ -38,7 +38,6 @@ static const char rcsid[] = #include #include #include /* for BASE_SLICE, MAX_SLICES */ -#include #include #include #include @@ -49,6 +48,7 @@ static const char rcsid[] = #include #include +#include #include #include diff --git a/sys/powerpc/powerpc/genassym.c b/sys/powerpc/powerpc/genassym.c index 07c972b..34a2612 100644 --- a/sys/powerpc/powerpc/genassym.c +++ b/sys/powerpc/powerpc/genassym.c @@ -95,6 +95,7 @@ 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_ONFAULT, offsetof(struct pcb, pcb_onfault)); ASSYM(TD_PROC, offsetof(struct thread, td_proc)); -ASSYM(TD_ADDR, offsetof(struct thread, td_addr)); +ASSYM(TD_PCB, offsetof(struct thread, td_pcb)); diff --git a/sys/powerpc/powerpc/locore.S b/sys/powerpc/powerpc/locore.S index 4ad6daf..9deb42f 100644 --- a/sys/powerpc/powerpc/locore.S +++ b/sys/powerpc/powerpc/locore.S @@ -1351,7 +1351,7 @@ setfault: mfcr 12 mfsprg 4,0 lwz 4,GD_CURPCB(4) - stw 3,PCB_FAULT(4) + stw 3,PCB_ONFAULT(4) stw 0,0(3) stw 1,4(3) stw 2,8(3) diff --git a/sys/powerpc/powerpc/locore.s b/sys/powerpc/powerpc/locore.s index 4ad6daf..9deb42f 100644 --- a/sys/powerpc/powerpc/locore.s +++ b/sys/powerpc/powerpc/locore.s @@ -1351,7 +1351,7 @@ setfault: mfcr 12 mfsprg 4,0 lwz 4,GD_CURPCB(4) - stw 3,PCB_FAULT(4) + stw 3,PCB_ONFAULT(4) stw 0,0(3) stw 1,4(3) stw 2,8(3) diff --git a/sys/powerpc/powerpc/machdep.c b/sys/powerpc/powerpc/machdep.c index 328a710..205b3d7 100644 --- a/sys/powerpc/powerpc/machdep.c +++ b/sys/powerpc/powerpc/machdep.c @@ -112,12 +112,14 @@ static const char rcsid[] = #include #include +int physmem = 0; int cold = 1; struct mtx sched_lock; struct mtx Giant; -struct user *proc0paddr; +struct user *proc0uarea; +vm_offset_t proc0kstack; char machine[] = "powerpc"; SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); @@ -146,6 +148,16 @@ void install_extint(void (*)(void)); void osendsig(sig_t, int, sigset_t *, u_long); #endif +static int +sysctl_hw_physmem(SYSCTL_HANDLER_ARGS) +{ + int error = sysctl_handle_int(oidp, 0, ctob(physmem), req); + return (error); +} + +SYSCTL_PROC(_hw, HW_PHYSMEM, physmem, CTLTYPE_INT|CTLFLAG_RD, + 0, 0, sysctl_hw_physmem, "IU", ""); + struct msgbuf *msgbufp = 0; int bootverbose = 0, Maxmem = 0; @@ -155,6 +167,8 @@ vm_offset_t phys_avail[10]; static int chosen; +static struct trapframe proc0_tf; + struct pmap ofw_pmap; extern int ofmsr; @@ -334,8 +348,6 @@ extern ddblow, ddbsize; extern ipkdblow, ipkdbsize; #endif -static struct globaldata tmpglobal; - void powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args) { @@ -382,6 +394,11 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args) * This is here because mem_regions() call needs bat0 set up. */ mem_regions(&allmem, &availmem); + + /* Calculate the physical memory in the machine */ + for (mp = allmem; mp->size; mp++) + physmem += btoc(mp->size); + for (mp = allmem; mp->size; mp++) { vm_offset_t pa = mp->start & 0xf0000000; vm_offset_t end = mp->start + mp->size; @@ -398,10 +415,33 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args) chosen = OF_finddevice("/chosen"); save_ofw_mapping(); - proc0.p_addr = proc0paddr; - bzero(proc0.p_addr, sizeof *proc0.p_addr); + pmap_setavailmem(startkernel, endkernel); + + proc_linkup(&proc0); + + proc0uarea = (struct user *)pmap_steal_memory(UAREA_PAGES * PAGE_SIZE); + proc0kstack = pmap_steal_memory(KSTACK_PAGES * PAGE_SIZE); + proc0.p_uarea = proc0uarea; + thread0 = &proc0.p_thread; + thread0->td_kstack = proc0kstack; + thread0->td_pcb = (struct pcb *) + (thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; + + globalp = pmap_steal_memory(round_page(sizeof(struct globaldata))); + + /* + * XXX: Pass 0 as CPU id. This is bad. We need to work out + * XXX: which CPU we are somehow. + */ + globaldata_init(globalp, 0, sizeof(struct globaldata)); + __asm ("mtsprg 0, %0" :: "r"(globalp)); + + /* setup curproc so the mutexes work */ - LIST_INIT(&proc0.p_contested); + PCPU_SET(curthread, thread0); + PCPU_SET(spinlocks, NULL); + + LIST_INIT(&thread0->td_contested); /* XXX: NetBSDism I _think_. Not sure yet. */ #if 0 @@ -549,25 +589,15 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args) /* * Initialize pmap module. */ - pmap_bootstrap(startkernel, endkernel); + pmap_bootstrap(); restore_ofw_mapping(); - /* - * Setup the global data for the bootstrap cpu. - */ - globalp = (struct globaldata *) &tmpglobal; - - /* - * XXX: Pass 0 as CPU id. This is bad. We need to work out - * XXX: which CPU we are somehow. - */ - globaldata_init(globalp, 0, sizeof(struct globaldata)); - __asm ("mtsprg 0, %0" :: "r"(globalp)); - PCPU_GET(next_asn) = 1; /* 0 used for proc0 pmap */ - PCPU_SET(curproc, &proc0); - PCPU_SET(spinlocks, NULL); + + /* setup proc 0's pcb */ + thread0->td_pcb->pcb_flags = 0; /* XXXKSE */ + thread0->td_frame = &proc0_tf; } static int N_mapping; @@ -695,7 +725,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) #ifdef COMPAT_43 int -osigreturn(struct proc *p, struct osigreturn_args *uap) +osigreturn(struct thread *td, struct osigreturn_args *uap) { /* XXX: To be done */ @@ -704,7 +734,7 @@ osigreturn(struct proc *p, struct osigreturn_args *uap) #endif int -sigreturn(struct proc *p, struct sigreturn_args *uap) +sigreturn(struct thread *td, struct sigreturn_args *uap) { /* XXX: To be done */ @@ -730,13 +760,12 @@ cpu_halt(void) * Set set up registers on exec. */ void -setregs(struct proc *p, u_long entry, u_long stack, u_long ps_strings) +setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) { struct trapframe *tf; struct ps_strings arginfo; - tf = trapframe(p); - + tf = trapframe(td); bzero(tf, sizeof *tf); tf->fixreg[1] = -roundup(-stack + 8, 16); @@ -769,7 +798,7 @@ setregs(struct proc *p, u_long entry, u_long stack, u_long ps_strings) tf->srr0 = entry; tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT; - p->p_addr->u_pcb.pcb_flags = 0; + td->td_pcb->pcb_flags = 0; } extern void *extint, *extsize; @@ -838,7 +867,7 @@ set_fpregs(struct proc *p, struct fpreg *fpregs) } int -ptrace_set_pc(struct proc *p, unsigned long addr) +ptrace_set_pc(struct thread *td, unsigned long addr) { /* XXX: coming soon... */ @@ -846,7 +875,7 @@ ptrace_set_pc(struct proc *p, unsigned long addr) } int -ptrace_single_step(struct proc *p) +ptrace_single_step(struct thread *td) { /* XXX: coming soon... */ @@ -854,7 +883,7 @@ ptrace_single_step(struct proc *p) } int -ptrace_clear_single_step(struct proc *p) +ptrace_clear_single_step(struct thread *td) { /* XXX: coming soon... */ diff --git a/sys/powerpc/powerpc/mmu_oea.c b/sys/powerpc/powerpc/mmu_oea.c index ad79c602..7b3f3e7 100644 --- a/sys/powerpc/powerpc/mmu_oea.c +++ b/sys/powerpc/powerpc/mmu_oea.c @@ -375,7 +375,7 @@ pte_spill(vm_offset_t addr) * This is called during powerpc_init, before the system is really initialized. */ void -pmap_bootstrap(u_int kernelstart, u_int kernelend) +pmap_setavailmem(u_int kernelstart, u_int kernelend) { struct mem_region *mp, *mp1; int cnt, i; @@ -585,6 +585,22 @@ pmap_bootstrap(u_int kernelstart, u_int kernelend) } #endif + nextavail = avail->start; + avail_start = avail->start; + for (mp = avail, i = 0; mp->size; mp++) { + avail_end = mp->start + mp->size; + phys_avail[i++] = mp->start; + phys_avail[i++] = mp->start + mp->size; + } + + +} + +void +pmap_bootstrap() +{ + int i; + /* * Initialize kernel pmap and hardware. */ @@ -632,14 +648,6 @@ pmap_bootstrap(u_int kernelstart, u_int kernelend) tlbia(); - nextavail = avail->start; - avail_start = avail->start; - for (mp = avail, i = 0; mp->size; mp++) { - avail_end = mp->start + mp->size; - phys_avail[i++] = mp->start; - phys_avail[i++] = mp->start + mp->size; - } - virtual_avail = VM_MIN_KERNEL_ADDRESS; virtual_end = VM_MAX_KERNEL_ADDRESS; } @@ -1449,7 +1457,7 @@ pmap_activate(struct thread *td) int psl, i, ksr, seg; pcb = td->td_pcb; - pmap = td->td_pric->p_vmspace->vm_map.pmap; + pmap = vmspace_pmap(td->td_proc->p_vmspace); /* * XXX Normally performed in cpu_fork(). @@ -1664,6 +1672,86 @@ pmap_swapout_proc(struct proc *p) return; } + +/* + * Create the kernel stack (including pcb for i386) for a new thread. + * This routine directly affects the fork perf for a process and + * create performance for a thread. + */ +void +pmap_new_thread(td) + struct thread *td; +{ + /* XXX: coming soon... */ + return; +} + +/* + * Dispose the kernel stack for a thread that has exited. + * This routine directly impacts the exit perf of a process and thread. + */ +void +pmap_dispose_thread(td) + struct thread *td; +{ + /* XXX: coming soon... */ + return; +} + +/* + * Allow the Kernel stack for a thread to be prejudicially paged out. + */ +void +pmap_swapout_thread(td) + struct thread *td; +{ + int i; + vm_object_t ksobj; + vm_offset_t ks; + vm_page_t m; + + ksobj = td->td_kstack_obj; + ks = td->td_kstack; + for (i = 0; i < KSTACK_PAGES; i++) { + m = vm_page_lookup(ksobj, i); + if (m == NULL) + panic("pmap_swapout_thread: kstack already missing?"); + vm_page_dirty(m); + vm_page_unwire(m, 0); + pmap_kremove(ks + i * PAGE_SIZE); + } +} + +/* + * Bring the kernel stack for a specified thread back in. + */ +void +pmap_swapin_thread(td) + struct thread *td; +{ + int i, rv; + vm_object_t ksobj; + vm_offset_t ks; + vm_page_t m; + + ksobj = td->td_kstack_obj; + ks = td->td_kstack; + for (i = 0; i < KSTACK_PAGES; i++) { + m = vm_page_grab(ksobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); + pmap_kenter(ks + i * PAGE_SIZE, VM_PAGE_TO_PHYS(m)); + if (m->valid != VM_PAGE_BITS_ALL) { + rv = vm_pager_get_pages(ksobj, &m, 1, 0); + if (rv != VM_PAGER_OK) + panic("pmap_swapin_thread: cannot get kstack for proc: %d\n", td->td_proc->p_pid); + m = vm_page_lookup(ksobj, i); + m->valid = VM_PAGE_BITS_ALL; + } + vm_page_wire(m); + vm_page_wakeup(m); + vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); + } +} + void pmap_pageable(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, boolean_t pageable) { @@ -1741,7 +1829,7 @@ pmap_steal_memory(vm_size_t size) } /* - * Create the UPAGES for a new process. + * Create the UAREA_PAGES for a new process. * This routine directly affects the fork perf for a process. */ void @@ -1761,20 +1849,20 @@ pmap_new_proc(struct proc *p) */ upobj = p->p_upages_obj; if (upobj == NULL) { - upobj = vm_object_allocate(OBJT_DEFAULT, UPAGES); + upobj = vm_object_allocate(OBJT_DEFAULT, UAREA_PAGES); p->p_upages_obj = upobj; } - /* get a kernel virtual address for the UPAGES for this proc */ - up = p->p_addr; + /* get a kernel virtual address for the UAREA_PAGES for this proc */ + up = (vm_offset_t)p->p_uarea; if (up == 0) { - up = kmem_alloc_nofault(kernel_map, UPAGES * PAGE_SIZE); + up = kmem_alloc_nofault(kernel_map, UAREA_PAGES * PAGE_SIZE); if (up == 0) panic("pmap_new_proc: upage allocation failed"); - p->p_addr = (struct user *)up; + p->p_uarea = (struct user *)up; } - for (i = 0; i < UPAGES; i++) { + for (i = 0; i < UAREA_PAGES; i++) { /* * Get a kernel stack page */ diff --git a/sys/powerpc/powerpc/pmap.c b/sys/powerpc/powerpc/pmap.c index ad79c602..7b3f3e7 100644 --- a/sys/powerpc/powerpc/pmap.c +++ b/sys/powerpc/powerpc/pmap.c @@ -375,7 +375,7 @@ pte_spill(vm_offset_t addr) * This is called during powerpc_init, before the system is really initialized. */ void -pmap_bootstrap(u_int kernelstart, u_int kernelend) +pmap_setavailmem(u_int kernelstart, u_int kernelend) { struct mem_region *mp, *mp1; int cnt, i; @@ -585,6 +585,22 @@ pmap_bootstrap(u_int kernelstart, u_int kernelend) } #endif + nextavail = avail->start; + avail_start = avail->start; + for (mp = avail, i = 0; mp->size; mp++) { + avail_end = mp->start + mp->size; + phys_avail[i++] = mp->start; + phys_avail[i++] = mp->start + mp->size; + } + + +} + +void +pmap_bootstrap() +{ + int i; + /* * Initialize kernel pmap and hardware. */ @@ -632,14 +648,6 @@ pmap_bootstrap(u_int kernelstart, u_int kernelend) tlbia(); - nextavail = avail->start; - avail_start = avail->start; - for (mp = avail, i = 0; mp->size; mp++) { - avail_end = mp->start + mp->size; - phys_avail[i++] = mp->start; - phys_avail[i++] = mp->start + mp->size; - } - virtual_avail = VM_MIN_KERNEL_ADDRESS; virtual_end = VM_MAX_KERNEL_ADDRESS; } @@ -1449,7 +1457,7 @@ pmap_activate(struct thread *td) int psl, i, ksr, seg; pcb = td->td_pcb; - pmap = td->td_pric->p_vmspace->vm_map.pmap; + pmap = vmspace_pmap(td->td_proc->p_vmspace); /* * XXX Normally performed in cpu_fork(). @@ -1664,6 +1672,86 @@ pmap_swapout_proc(struct proc *p) return; } + +/* + * Create the kernel stack (including pcb for i386) for a new thread. + * This routine directly affects the fork perf for a process and + * create performance for a thread. + */ +void +pmap_new_thread(td) + struct thread *td; +{ + /* XXX: coming soon... */ + return; +} + +/* + * Dispose the kernel stack for a thread that has exited. + * This routine directly impacts the exit perf of a process and thread. + */ +void +pmap_dispose_thread(td) + struct thread *td; +{ + /* XXX: coming soon... */ + return; +} + +/* + * Allow the Kernel stack for a thread to be prejudicially paged out. + */ +void +pmap_swapout_thread(td) + struct thread *td; +{ + int i; + vm_object_t ksobj; + vm_offset_t ks; + vm_page_t m; + + ksobj = td->td_kstack_obj; + ks = td->td_kstack; + for (i = 0; i < KSTACK_PAGES; i++) { + m = vm_page_lookup(ksobj, i); + if (m == NULL) + panic("pmap_swapout_thread: kstack already missing?"); + vm_page_dirty(m); + vm_page_unwire(m, 0); + pmap_kremove(ks + i * PAGE_SIZE); + } +} + +/* + * Bring the kernel stack for a specified thread back in. + */ +void +pmap_swapin_thread(td) + struct thread *td; +{ + int i, rv; + vm_object_t ksobj; + vm_offset_t ks; + vm_page_t m; + + ksobj = td->td_kstack_obj; + ks = td->td_kstack; + for (i = 0; i < KSTACK_PAGES; i++) { + m = vm_page_grab(ksobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); + pmap_kenter(ks + i * PAGE_SIZE, VM_PAGE_TO_PHYS(m)); + if (m->valid != VM_PAGE_BITS_ALL) { + rv = vm_pager_get_pages(ksobj, &m, 1, 0); + if (rv != VM_PAGER_OK) + panic("pmap_swapin_thread: cannot get kstack for proc: %d\n", td->td_proc->p_pid); + m = vm_page_lookup(ksobj, i); + m->valid = VM_PAGE_BITS_ALL; + } + vm_page_wire(m); + vm_page_wakeup(m); + vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); + } +} + void pmap_pageable(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, boolean_t pageable) { @@ -1741,7 +1829,7 @@ pmap_steal_memory(vm_size_t size) } /* - * Create the UPAGES for a new process. + * Create the UAREA_PAGES for a new process. * This routine directly affects the fork perf for a process. */ void @@ -1761,20 +1849,20 @@ pmap_new_proc(struct proc *p) */ upobj = p->p_upages_obj; if (upobj == NULL) { - upobj = vm_object_allocate(OBJT_DEFAULT, UPAGES); + upobj = vm_object_allocate(OBJT_DEFAULT, UAREA_PAGES); p->p_upages_obj = upobj; } - /* get a kernel virtual address for the UPAGES for this proc */ - up = p->p_addr; + /* get a kernel virtual address for the UAREA_PAGES for this proc */ + up = (vm_offset_t)p->p_uarea; if (up == 0) { - up = kmem_alloc_nofault(kernel_map, UPAGES * PAGE_SIZE); + up = kmem_alloc_nofault(kernel_map, UAREA_PAGES * PAGE_SIZE); if (up == 0) panic("pmap_new_proc: upage allocation failed"); - p->p_addr = (struct user *)up; + p->p_uarea = (struct user *)up; } - for (i = 0; i < UPAGES; i++) { + for (i = 0; i < UAREA_PAGES; i++) { /* * Get a kernel stack page */ diff --git a/sys/powerpc/powerpc/procfs_machdep.c b/sys/powerpc/powerpc/procfs_machdep.c index d6085e8..3ed7a7b 100644 --- a/sys/powerpc/powerpc/procfs_machdep.c +++ b/sys/powerpc/powerpc/procfs_machdep.c @@ -81,28 +81,32 @@ #include +#define PROCFS_ACTION(action) do { \ + int error; \ + \ + mtx_lock_spin(&sched_lock); \ + if ((td->td_proc->p_sflag & PS_INMEM) == 0) \ + error = EIO; \ + else \ + error = (action); \ + mtx_unlock_spin(&sched_lock); \ + return (error); \ +} while(0) + int -procfs_read_regs(p, regs) - struct proc *p; +procfs_read_regs(td, regs) + struct thread *td; struct reg *regs; { - if ((p->p_flag & PS_INMEM) == 0) { - return (EIO); - } - - return (fill_regs(p, regs)); + PROCFS_ACTION(fill_regs(td, regs)); } int -procfs_write_regs(p, regs) - struct proc *p; +procfs_write_regs(td, regs) + struct thread *td; struct reg *regs; { - if ((p->p_flag & PS_INMEM) == 0) { - return (EIO); - } - - return (set_regs(p, regs)); + PROCFS_ACTION(set_regs(td, regs)); } /* @@ -111,32 +115,24 @@ procfs_write_regs(p, regs) */ int -procfs_read_fpregs(p, fpregs) - struct proc *p; +procfs_read_fpregs(td, fpregs) + struct thread *td; struct fpreg *fpregs; { - if ((p->p_flag & PS_INMEM) == 0) { - return (EIO); - } - - return (fill_fpregs(p, fpregs)); + PROCFS_ACTION(fill_fpregs(td, fpregs)); } int -procfs_write_fpregs(p, fpregs) - struct proc *p; +procfs_write_fpregs(td, fpregs) + struct thread *td; struct fpreg *fpregs; { - if ((p->p_flag & PS_INMEM) == 0) { - return (EIO); - } - - return (set_fpregs(p, fpregs)); + PROCFS_ACTION(set_fpregs(td, fpregs)); } int -procfs_sstep(p) - struct proc *p; +procfs_sstep(td) + struct thread *td; { return (EINVAL); } @@ -145,16 +141,16 @@ procfs_sstep(p) * Placeholders */ int -procfs_read_dbregs(p, dbregs) - struct proc *p; +procfs_read_dbregs(td, dbregs) + struct thread *td; struct dbreg *dbregs; { return (EIO); } int -procfs_write_dbregs(p, dbregs) - struct proc *p; +procfs_write_dbregs(td, dbregs) + struct thread *td; struct dbreg *dbregs; { return (EIO); diff --git a/sys/powerpc/powerpc/swtch.S b/sys/powerpc/powerpc/swtch.S index af18976..bcdfcae 100644 --- a/sys/powerpc/powerpc/swtch.S +++ b/sys/powerpc/powerpc/swtch.S @@ -154,7 +154,7 @@ ENTRY(cpu_switch) stw 3,PCB_SPL(31) /* save spl */ /* Find a new process */ - bl chooseproc + bl choosethread 1: /* record new process */ @@ -172,7 +172,7 @@ ENTRY(cpu_switch) mr 12,2 /* save r2 */ stwu 1,-SFRAMELEN(1) /* still running on old stack */ stmw 10,8(1) - lwz 3,TD_ADDR(30) + lwz 3,TD_PCB(30) stw 1,PCB_SP(3) /* save SP */ switch_exited: @@ -182,7 +182,7 @@ switch_exited: mtmsr 3 /* indicate new pcb */ - lwz 4,TD_ADDR(31) + lwz 4,TD_PCB(31) mfsprg 5,0 stw 4,GD_CURPCB(5) diff --git a/sys/powerpc/powerpc/swtch.s b/sys/powerpc/powerpc/swtch.s index af18976..bcdfcae 100644 --- a/sys/powerpc/powerpc/swtch.s +++ b/sys/powerpc/powerpc/swtch.s @@ -154,7 +154,7 @@ ENTRY(cpu_switch) stw 3,PCB_SPL(31) /* save spl */ /* Find a new process */ - bl chooseproc + bl choosethread 1: /* record new process */ @@ -172,7 +172,7 @@ ENTRY(cpu_switch) mr 12,2 /* save r2 */ stwu 1,-SFRAMELEN(1) /* still running on old stack */ stmw 10,8(1) - lwz 3,TD_ADDR(30) + lwz 3,TD_PCB(30) stw 1,PCB_SP(3) /* save SP */ switch_exited: @@ -182,7 +182,7 @@ switch_exited: mtmsr 3 /* indicate new pcb */ - lwz 4,TD_ADDR(31) + lwz 4,TD_PCB(31) mfsprg 5,0 stw 4,GD_CURPCB(5) diff --git a/sys/powerpc/powerpc/sys_machdep.c b/sys/powerpc/powerpc/sys_machdep.c index 3d3157d..e4183f2 100644 --- a/sys/powerpc/powerpc/sys_machdep.c +++ b/sys/powerpc/powerpc/sys_machdep.c @@ -34,7 +34,7 @@ static const char rcsid[] = #include int -sysarch(struct proc *p, struct sysarch_args *uap) +sysarch(struct thread *td, struct sysarch_args *uap) { return (EOPNOTSUPP); diff --git a/sys/powerpc/powerpc/vm_machdep.c b/sys/powerpc/powerpc/vm_machdep.c index 630f9bf..c2110bb 100644 --- a/sys/powerpc/powerpc/vm_machdep.c +++ b/sys/powerpc/powerpc/vm_machdep.c @@ -119,8 +119,9 @@ vm_fault_quick(v, prot) * ready to run and return to user mode. */ void -cpu_fork(p1, p2, flags) - register struct proc *p1, *p2; +cpu_fork(td1, p2, flags) + register struct thread *td1; + register struct proc *p2; int flags; { /* XXX: coming soon... */ @@ -133,8 +134,8 @@ cpu_fork(p1, p2, flags) * This is needed to make kernel threads stay in kernel mode. */ void -cpu_set_fork_handler(p, func, arg) - struct proc *p; +cpu_set_fork_handler(td, func, arg) + struct thread *td; void (*func) __P((void *)); void *arg; { @@ -143,8 +144,8 @@ cpu_set_fork_handler(p, func, arg) * 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; + td->p_addr->u_pcb.pcb_context[0] = (u_long) func; + td->p_addr->u_pcb.pcb_context[2] = (u_long) arg; #endif } @@ -156,14 +157,14 @@ cpu_set_fork_handler(p, func, arg) * from proc0. */ void -cpu_exit(p) - register struct proc *p; +cpu_exit(td) + register struct thread *td; { } void -cpu_wait(p) - struct proc *p; +cpu_wait(td) + struct proc *td; { } @@ -180,13 +181,14 @@ cpu_throw(void) * Dump the machine specific header information at the start of a core dump. */ int -cpu_coredump(p, vp, cred) - struct proc *p; +cpu_coredump(td, vp, cred) + struct thread *td; struct vnode *vp; struct ucred *cred; { + struct proc *p = td->td_proc; - return (vn_rdwr(UIO_WRITE, vp, (caddr_t) p->p_addr, ctob(UPAGES), + return (vn_rdwr(UIO_WRITE, vp, (caddr_t)p->p_uarea, ctob(UAREA_PAGES), (off_t)0, UIO_SYSSPACE, IO_UNIT, cred, (int *)NULL, p)); } -- cgit v1.1