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:
parent
f3366866dc
commit
d7ad3f5fab
@ -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 */
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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()) {
|
||||
|
Loading…
Reference in New Issue
Block a user