allocate 128KB (as opposed to 64KB) per-cpu, and place the interrupt

stack, cpu_info structure, panicstack, idle uarea and normal kernel
stack in here.  the idle uarea and kernel stack are in the 2nd 64KB
page.  the interrupt stack and cpu_info structure are as the same
place in the 1st 64KB page, and the panicstack grows down from the
top of this page.  update comments in param.h to suit (XXX: a lot
of these constants should move to a header file that will not pollute
the name space so much.)  map these pages identically between
cpu_initialise() and cpu_mp_startup(), and deal with the two 64KB
pages in pmap_extract().  keep an unmapped 64KB page between them.

don't initialise the unused "ci_eintstack" member of the cpu_info
structure

use constants to initialise many addresses in the cpu_info structure,
consolidating these assignments from cpu0 and cpu>0

delete u0/estack0/panicstack from locore.s

clean up some wrong comments in locore.s

fix a 32bit-only bug in cpu_mp_startup().

delete 'u0' entirely.


this fixes recent random lossage seen on port-sparc64: processes
stuck in RUN state, data faults, and hangs.
This commit is contained in:
mrg 2006-10-17 22:26:05 +00:00
parent f3366866dc
commit d7ad3f5fab
4 changed files with 82 additions and 102 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: param.h,v 1.36 2006/08/28 13:43:35 yamt Exp $ */
/* $NetBSD: param.h,v 1.37 2006/10/17 22:26:05 mrg Exp $ */
/*
* Copyright (c) 1992, 1993
@ -165,10 +165,15 @@ extern int nbpg, pgofset, pgshift;
* KERNEND+0x02000: Auxreg_va (unused?)
* KERNEND+0x04000: TMPMAP_VA (unused?)
* KERNEND+0x06000: message buffer.
* KERNEND+0x010000: 64K locked TTE -- different for each CPU
* Contains interrupt stack, cpu_info structure,
* and 32KB kernel TSB.
* KERNEND+0x020000: IODEV_BASE -- begin mapping IO devices here.
* KERNEND+0x010000: INTSTACK -- per-cpu 64K locked TTE
* Contains interrupt stack (32KB), cpu_info structure
* and panicstack (32KB)
* KERNEND+0x018000: CPUINFO_VA -- cpu_info structure
* KERNEND+0x020000: unmapped space (top of panicstack)
* KERNEND+0x030000: IDLE_U_VA -- per-cpu 64K locked TTE
* u area and bottom of kernel stack
* KERNEND+0x040000: INITSTACK_VA -- initial kernel stack pointer
* KERNEND+0x040000: IODEV_BASE -- begin mapping IO devices here.
* 0x00000000fe000000: IODEV_END -- end of device mapping space.
*
*/
@ -176,7 +181,7 @@ extern int nbpg, pgofset, pgshift;
#define KERNEND 0x0e0000000 /* end of kernel virtual space */
#define VM_MAX_KERNEL_BUF ((KERNEND-KERNBASE)/4)
#define _MAXNBPG 8192 /* fixed VAs, independent of actual NBPG */
#define _MAXNBPG 8192 /* fixed VAs, independent of actual NBPG */
#define AUXREG_VA ( KERNEND + _MAXNBPG) /* 1 page REDZONE */
#define TMPMAP_VA ( AUXREG_VA + _MAXNBPG)
@ -184,10 +189,14 @@ extern int nbpg, pgofset, pgshift;
/*
* Here's the location of the interrupt stack and CPU structure.
*/
#define INTSTACK ( KERNEND + 8*_MAXNBPG)/* 64K after kernel end */
#define EINTSTACK ( INTSTACK + 2*USPACE) /* 32KB */
#define CPUINFO_VA ( EINTSTACK)
#define IODEV_BASE ( CPUINFO_VA + 8*_MAXNBPG)/* 64K long */
#define INTSTACK ( KERNEND + 8*_MAXNBPG)
#define EINTSTACK ( INTSTACK + 4*_MAXNBPG)
#define CPUINFO_VA ( EINTSTACK )
#define PANICSTACK ( INTSTACK + 8*_MAXNBPG)
#define IDLE_U_VA ( INTSTACK + 16*_MAXNBPG)
#define KSTACK_VA ( INTSTACK + 16*_MAXNBPG) /* make this 16 to have a redzone */
#define INITSTACK_VA ( KSTACK_VA + 8*_MAXNBPG)
#define IODEV_BASE ( INITSTACK_VA + 0*_MAXNBPG)
#define IODEV_END 0x0f0000000UL /* 16 MB of iospace */
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.c,v 1.54 2006/10/03 21:05:22 mrg Exp $ */
/* $NetBSD: cpu.c,v 1.55 2006/10/17 22:26:06 mrg Exp $ */
/*
* Copyright (c) 1996
@ -52,7 +52,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.54 2006/10/03 21:05:22 mrg Exp $");
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.55 2006/10/17 22:26:06 mrg Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -107,7 +107,7 @@ alloc_cpuinfo(u_int cpu_node)
{
paddr_t pa0, pa;
vaddr_t va, va0;
vsize_t sz = 8 * PAGE_SIZE;
vsize_t sz = 16 * PAGE_SIZE;
int portid;
struct cpu_info *cpi, *ci;
extern paddr_t cpu0paddr;
@ -123,7 +123,7 @@ alloc_cpuinfo(u_int cpu_node)
return cpi;
/* Allocate the aligned VA and determine the size. */
va = uvm_km_alloc(kernel_map, sz, sz, UVM_KMF_VAONLY);
va = uvm_km_alloc(kernel_map, sz, 8 * PAGE_SIZE, UVM_KMF_VAONLY);
if (!va)
panic("alloc_cpuinfo: no virtual space");
va0 = va;
@ -152,10 +152,9 @@ alloc_cpuinfo(u_int cpu_node)
cpi->ci_upaid = portid;
cpi->ci_fplwp = NULL;
cpi->ci_spinup = NULL; /* XXX */
cpi->ci_eintstack = (void *)EINTSTACK; /* XXX */
cpi->ci_idle_u = (struct pcb *)(CPUINFO_VA + 2 * PAGE_SIZE); /* XXX */
cpi->ci_cpcb = cpi->ci_idle_u; /* XXX */
cpi->ci_initstack = (void *)((vaddr_t)cpi->ci_idle_u + 2 * PAGE_SIZE); /* XXX */
cpi->ci_idle_u = (struct pcb *)IDLE_U_VA;
cpi->ci_cpcb = cpi->ci_idle_u;
cpi->ci_initstack = (void *)INITSTACK_VA;
cpi->ci_paddr = pa0;
cpi->ci_self = cpi;
cpi->ci_node = cpu_node;

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.229 2006/10/04 05:00:39 mrg Exp $ */
/* $NetBSD: locore.s,v 1.230 2006/10/17 22:26:06 mrg Exp $ */
/*
* Copyright (c) 1996-2002 Eduardo Horvath
@ -393,15 +393,6 @@ _C_LABEL(data_start): ! Start of data segment
_C_LABEL(__idle_u):
.space USPACE
/*
* Process 0's u.
*
* This must be aligned on an 8 byte boundary.
*/
.globl _C_LABEL(u0)
_C_LABEL(u0): POINTER 0
estack0: POINTER 0
#ifdef KGDB
/*
* Another item that must be aligned, easiest to put it here.
@ -412,7 +403,7 @@ _C_LABEL(kgdb_stack):
.space KGDB_STACK_SIZE ! hope this is enough
#endif
#ifdef DEBUG
#ifdef NOTDEF_DEBUG
/*
* This stack is used when we detect kernel stack corruption.
*/
@ -2369,13 +2360,9 @@ winfixspill:
wrpr %g0, 0, %otherwin
or %lo(2f), %o0, %o0
wrpr %g0, WSTATE_KERN, %wstate
#ifdef DEBUG
set panicstack-CC64FSZ-STKB, %sp ! Use panic stack.
#else
set estack0, %sp
LDPTR [%sp], %sp
add %sp, -CC64FSZ-STKB, %sp ! Overwrite proc 0's stack.
#endif
sethi %hi(PANICSTACK), %sp
LDPTR [%sp + %lo(PANICSTACK)], %sp
add %sp, -CC64FSZ-STKB, %sp
ta 1; nop ! This helps out traptrace.
call _C_LABEL(panic) ! This needs to be fixed properly but we should panic here
mov %g1, %o1
@ -3120,13 +3107,9 @@ slowtrap:
cmp %g7, WSTATE_KERN
bnz,pt %icc, 1f ! User stack -- we'll blow it away
nop
#ifdef DEBUG
set panicstack, %sp ! Kernel stack corrupt -- use panicstack
#else
set estack0, %sp
LDPTR [%sp], %sp
add %sp, -CC64FSZ-STKB, %sp ! Overwrite proc 0's stack.
#endif
sethi %hi(PANICSTACK), %sp
LDPTR [%sp + %lo(PANICSTACK)], %sp
add %sp, -CC64FSZ-STKB, %sp
1:
#endif
rdpr %tt, %g4
@ -4929,21 +4912,12 @@ dostart:
#endif
0:
call _C_LABEL(bootstrap)
clr %g4 ! Clear data segment pointer
/*
* pmap_bootstrap should have allocated a stack for proc 0 and
* stored the start and end in u0 and estack0. Switch to that
* stack now.
*/
/*
* Initialize a CPU. This is used both for bootstrapping the first CPU
* and spinning up each subsequent CPU. Basically:
* Initialize a CPU. Basically:
*
* Establish the 4MB locked mappings for kernel data and text.
* Locate the cpu_info structure for this CPU.
* Establish a locked mapping for interrupt stack.
* Switch to the initial stack.
@ -4953,20 +4927,7 @@ dostart:
_C_LABEL(cpu_initialize):
/*
* Step 5: install the permanent 4MB kernel mapping in both the
* immu and dmmu. We will clear out other mappings later.
*
* Register usage in this section:
*
* %l0 = ktext (also KERNBASE)
* %l1 = ektext
* %l2 = ktextp/TTE Data for text w/o low bits
* %l3 = kdata (also DATA_START)
* %l4 = ekdata
* %l5 = kdatap/TTE Data for data w/o low bits
* %l6 = 4MB
* %l7 = 4MB-1
* %o0-%o5 = tmp
* Step 5: is not more.
*/
/*
@ -5019,6 +4980,16 @@ _C_LABEL(cpu_initialize):
membar #Sync ! We may need more membar #Sync in here
flush %o5
1:
!!
!! Map in idle u area and kernel stack
!!
sethi %hi(KSTACK_VA), %l0
stxa %l0, [%l5] ASI_DMMU ! Make DMMU point to it
membar #Sync
stxa %l2, [%g0] ASI_DMMU_DATA_IN ! Store it
membar #Sync
flush %o5
!!! Make sure our stack's OK.
flushw
sethi %hi(CPUINFO_VA+CI_INITSTACK), %l0
@ -5167,7 +5138,7 @@ ENTRY(cpu_mp_startup)
#endif
!!
!! Now, map in the interrupt stack as context==0
!! Now, map in the interrupt stack & cpu_info as context==0
!!
set TLB_TAG_ACCESS, %l5
set 1f, %o5
@ -5180,9 +5151,9 @@ ENTRY(cpu_mp_startup)
flush %l0
1:
!!
!! Map in cpu_info structure at CPUINFO_VA.
!! Map in idle u area and kernel stack
!!
set CPUINFO_VA, %l0
set KSTACK_VA, %l0
stxa %l0, [%l5] ASI_DMMU ! Make DMMU point to it
membar #Sync
stxa %l2, [%g0] ASI_DMMU_DATA_IN ! Store it
@ -5198,8 +5169,12 @@ ENTRY(cpu_mp_startup)
flush %o5
!!! Make sure our stack's OK.
LDPTR [%g2 + %lo(CBA_INITSTACK)], %l0
add %l0, -CC64FSZ-80-BIAS, %l0
LDPTR [%g2 + CBA_INITSTACK], %l0
add %l0, - CC64FSZ - 80, %l0
#ifdef _LP64
andn %l0, 0x0f, %l0 ! Needs to be 16-byte aligned
sub %l0, BIAS, %l0 ! and biased
#endif
mov %l0, %sp
set 1, %fp
clr %i7
@ -6726,8 +6701,7 @@ ENTRY(cpu_exit)
flushw ! DEBUG
sethi %hi(IDLE_U), %l6
LDPTR [%l6 + %lo(IDLE_U)], %l6
! set _C_LABEL(idle_u), %l6
SET_SP_REDZONE(%l6, %l5)
SET_SP_REDZONE(%l6, %o0)
#endif
wrpr %g0, PSTATE_INTR, %pstate ! and then enable traps
@ -10855,7 +10829,7 @@ _C_LABEL(ssym):
! XXX should it called lwp0paddr
.globl _C_LABEL(proc0paddr)
_C_LABEL(proc0paddr):
POINTER _C_LABEL(u0) ! KVA of proc0 uarea
POINTER 0
#if !defined(MULTIPROCESSOR)
.comm _C_LABEL(curlwp), PTRSZ

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.c,v 1.177 2006/10/15 21:07:45 martin Exp $ */
/* $NetBSD: pmap.c,v 1.178 2006/10/17 22:26:06 mrg Exp $ */
/*
*
* Copyright (C) 1996-1999 Eduardo Horvath.
@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.177 2006/10/15 21:07:45 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.178 2006/10/17 22:26:06 mrg Exp $");
#undef NO_VCACHE /* Don't forget the locked TLB in dostart */
#define HWREF
@ -753,9 +753,9 @@ pmap_bootstrap(u_long kernelstart, u_long kernelend)
#endif
/*
* Allocate a ncpu*64MB page for the cpu_info structure now.
* Allocate a ncpu*128KB page for the cpu_info & stack structure now.
*/
cpu0paddr = prom_alloc_phys(8 * PAGE_SIZE * sparc_ncpus, 8 * PAGE_SIZE);
cpu0paddr = prom_alloc_phys(16 * PAGE_SIZE * sparc_ncpus, 8 * PAGE_SIZE);
if (cpu0paddr == 0) {
prom_printf("Cannot allocate cpu_infos\n");
prom_halt();
@ -1009,22 +1009,18 @@ pmap_bootstrap(u_long kernelstart, u_long kernelend)
/* Let's keep 1 page of redzone after the kernel */
vmmap += PAGE_SIZE;
{
extern vaddr_t u0[2];
extern struct pcb* proc0paddr;
extern struct pcb *proc0paddr;
extern void main(void);
vaddr_t u0va;
paddr_t pa;
/* Initialize all the pointers to u0 */
proc0paddr = (struct pcb *)vmmap;
u0[0] = vmmap;
/* Allocate some VAs for u0 */
u0[1] = vmmap + 2*USPACE;
u0va = vmmap;
BDPRINTF(PDB_BOOT1,
("Inserting stack 0 into pmap_kernel() at %p\n",
vmmap));
while (vmmap < u0[1]) {
while (vmmap < u0va + 2*USPACE) {
int64_t data1;
if (!pmap_get_page(&pa))
@ -1057,9 +1053,9 @@ pmap_bootstrap(u_long kernelstart, u_long kernelend)
BDPRINTF(PDB_BOOT1,
("Inserting cpu_info into pmap_kernel() at %p\n",
cpus));
/* Now map in all 8 pages of interrupt stack/cpu_info */
/* Now map in all 16 pages of interrupt stack/cpu_info */
pa = cpu0paddr;
prom_map_phys(pa, 64*KB, vmmap, -1);
prom_map_phys(pa, 128*KB, vmmap, -1);
/*
* Also map it in as the interrupt stack.
@ -1068,8 +1064,9 @@ pmap_bootstrap(u_long kernelstart, u_long kernelend)
* XXXX locore.s does not flush these mappings
* before installing the locked TTE.
*/
prom_map_phys(pa, 64*KB, CPUINFO_VA, -1);
for (i = 0; i < 8; i++) {
prom_map_phys(pa, 64*KB, INTSTACK, -1);
prom_map_phys(pa + 64*KB, 64*KB, KSTACK_VA, -1);
for (i = 0; i < 16; i++) {
int64_t data1;
data1 = TSB_DATA(0 /* global */,
@ -1088,7 +1085,7 @@ pmap_bootstrap(u_long kernelstart, u_long kernelend)
BDPRINTF(PDB_BOOT1, ("Initializing cpu_info\n"));
/* Initialize our cpu_info structure */
memset((void *)intstk, 0, 8 * PAGE_SIZE);
memset((void *)intstk, 0, 128 * KB);
cpus->ci_self = cpus;
cpus->ci_next = NULL;
cpus->ci_curlwp = &lwp0;
@ -1099,14 +1096,12 @@ pmap_bootstrap(u_long kernelstart, u_long kernelend)
cpus->ci_fplwp = NULL;
cpus->ci_spinup = main; /* Call main when we're running. */
cpus->ci_paddr = cpu0paddr;
cpus->ci_idle_u = (struct pcb *)(CPUINFO_VA + 2 * PAGE_SIZE);
cpus->ci_cpcb = cpus->ci_idle_u;
proc0paddr = (struct pcb *)cpus->ci_idle_u;
cpus->ci_initstack = (void *)((vaddr_t)cpus->ci_idle_u + 2 * PAGE_SIZE);
/* (void *)u0[1]; */
cpus->ci_eintstack = (void *)EINTSTACK;
cpus->ci_idle_u = (struct pcb *)IDLE_U_VA;
cpus->ci_cpcb = (struct pcb *)u0va;
cpus->ci_initstack = (void *)INITSTACK_VA;
proc0paddr = cpus->ci_cpcb;
cpu0paddr += 64 * KB;
cpu0paddr += 128 * KB;
CPUSET_CLEAR(cpus_active);
CPUSET_ADD(cpus_active, 0);
@ -2059,10 +2054,13 @@ pmap_extract(pm, va, pap)
pa = pmap_kextract(va);
DPRINTF(PDB_EXTRACT, ("pmap_extract: va=%lx pa=%llx\n",
(u_long)va, (unsigned long long)pa));
} else if (pm == pmap_kernel() && va >= INTSTACK && va < (INTSTACK + 4*USPACE)) {
/* XXX */
} else if (pm == pmap_kernel() && va >= INTSTACK && va < (INTSTACK + 64*KB)) {
pa = (paddr_t)(curcpu()->ci_paddr - INTSTACK + va);
DPRINTF(PDB_EXTRACT, ("pmap_extract: va=%lx pa=%llx\n",
DPRINTF(PDB_EXTRACT, ("pmap_extract (intstack): va=%lx pa=%llx\n",
(u_long)va, (unsigned long long)pa));
} else if (pm == pmap_kernel() && va >= KSTACK_VA && va < (KSTACK_VA + 64*KB)) {
pa = (paddr_t)(curcpu()->ci_paddr - KSTACK_VA + va);
DPRINTF(PDB_EXTRACT, ("pmap_extract (kstack): va=%lx pa=%llx\n",
(u_long)va, (unsigned long long)pa));
} else {
if (pm != pmap_kernel()) {