Allocate a private PCB, kernel stack and interrupt stack for each processor.

As a result, the stack setup code in locore.s changes slightly in
the MULTIPROCESSOR case. Also, make the stack redzone barrier (for
debugging only) a per-CPU entity.
This commit is contained in:
pk 1998-10-11 14:46:45 +00:00
parent cae1a093d5
commit b9d844a520
4 changed files with 127 additions and 20 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.c,v 1.78 1998/10/09 10:08:52 pk Exp $ */
/* $NetBSD: cpu.c,v 1.79 1998/10/11 14:46:46 pk Exp $ */
/*
* Copyright (c) 1996
@ -130,6 +130,7 @@ alloc_cpuinfo()
vaddr_t low, high;
vm_page_t m;
struct pglist mlist;
struct cpu_info *cpi;
/*
* Allocate aligned KVA. `cpuinfo' resides at a fixed virtual
@ -142,8 +143,13 @@ alloc_cpuinfo()
/* Assumes `c_totalsize' is power of two */
align = CACHEINFO.c_totalsize;
/* While we're here, allocate a pre-CPU kernel stack as well? */
sz = sizeof(struct cpu_info)/* + USPACE*/;
/*
* While we're here, allocate a per-CPU idle PCB and
* interrupt stack as well.
*/
sz = sizeof(struct cpu_info);
sz += USPACE; /* `idle' u-area for this CPU */
sz += INT_STACK_SIZE; /* interrupt stack for this CPU */
sz = (sz + NBPG - 1) & -NBPG;
esz = sz + align - NBPG;
@ -166,7 +172,7 @@ alloc_cpuinfo()
if (uvm_pglistalloc(sz, low, high, NBPG, 0, &mlist, 1, 0) != 0)
panic("alloc_cpuinfo: no pages");
sva = va; /* re-use sva */
cpi = (struct cpu_info *)va;
/* Map the pages */
for (m = TAILQ_FIRST(&mlist); m != NULL; m = TAILQ_NEXT(m,pageq)) {
@ -176,11 +182,12 @@ alloc_cpuinfo()
va += NBPG;
}
bzero((void *)sva, sizeof(struct cpu_info));
#if 0
((struct cpu_info *)sva)->stack = sva + sz - USPACE;
#endif
return ((struct cpu_info *)sva);
bzero((void *)cpi, sizeof(struct cpu_info));
cpi->eintstack = (void *)(sva + sz);
cpi->idle_u = (void *)(sva + sz - INT_STACK_SIZE - USPACE);
return (cpi);
}
#ifdef notdef
@ -258,15 +265,22 @@ static int cpu_number;
*/
mid = getpropint(node, "mid", 0);
if (bootcpu == NULL) {
extern struct pcb idle_u[];
bootcpu = sc;
cpus = malloc(ncpu * sizeof(cpi), M_DEVBUF, M_NOWAIT);
bzero(cpus, ncpu * sizeof(cpi));
cpi = sc->sc_cpuinfo = (struct cpu_info *)CPUINFO_VA;
cpi->master = 1;
cpi->eintstack = eintstack;
cpi->idle_u = idle_u;
} else {
cpi = sc->sc_cpuinfo = alloc_cpuinfo();
}
#ifdef DEBUG
cpi->redzone = (void *)((long)cpi->idle_u + REDSIZE);
#endif
cpus[cpu_number] = cpi;
cpi->cpu_no = cpu_number++;
cpi->mid = mid;

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpuvar.h,v 1.15 1998/10/08 22:25:42 pk Exp $ */
/* $NetBSD: cpuvar.h,v 1.16 1998/10/11 14:46:45 pk Exp $ */
/*
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -195,11 +195,20 @@ struct cpu_info {
* The following pointers point to processes that are somehow
* associated with this CPU--running on it, using its FPU,
* etc.
*
* XXXMP: much more needs to go here
*/
struct proc *curproc; /* CPU owner */
struct proc *fpproc; /* FPU owner */
/*
* Idle PCB and Interrupt stack;
*/
void *eintstack; /* End of interrupt stack */
#define INT_STACK_SIZE (128 * 128) /* 128 128-byte stack frames */
struct pcb *idle_u;
void *redzone; /* DEBUG: stack red zone */
#define REDSIZE (8*96) /* some room for bouncing */
/*
* The following are function pointers to do interesting CPU-dependent
* things without having to do type-tests all the time

View File

@ -1,4 +1,4 @@
# $NetBSD: genassym.cf,v 1.13 1998/09/24 20:37:17 pk Exp $
# $NetBSD: genassym.cf,v 1.14 1998/10/11 14:46:46 pk Exp $
#
# Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -150,6 +150,10 @@ define CPUINFO_GETASYNCFLT offsetof(struct cpu_info, get_asyncflt)
define CPUINFO_PURE_VCACHE_FLS offsetof(struct cpu_info, pure_vcache_flush)
define CPUINFO_SYNCFLTDUMP offsetof(struct cpu_info, syncfltdump)
define CPUINFO_INTREG offsetof(struct cpu_info, intreg_4m)
define CPUINFO_EINTSTACK offsetof(struct cpu_info, eintstack)
define INT_STACK_SIZE INT_STACK_SIZE
define CPUINFO_REDZONE offsetof(struct cpu_info, redzone)
define REDSIZE REDSIZE
# PTE bits and related information
define PG_W PG_W

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.96 1998/09/23 11:07:28 pk Exp $ */
/* $NetBSD: locore.s,v 1.97 1998/10/11 14:46:46 pk Exp $ */
/*
* Copyright (c) 1996 Paul Kranenburg
@ -53,6 +53,7 @@
#include "opt_ddb.h"
#include "opt_uvm.h"
#include "opt_compat_svr4.h"
#include "opt_multiprocessor.h"
#include "assym.h"
#include <machine/param.h>
@ -1140,17 +1141,17 @@ trapbase_sun4m:
.skip 4096
#endif
#ifdef DEBUG
/*#ifdef DEBUG*/
/*
* A hardware red zone is impossible. We simulate one in software by
* keeping a `red zone' pointer; if %sp becomes less than this, we panic.
* This is expensive and is only enabled when debugging.
*/
#define REDSIZE (8*96) /* some room for bouncing */
#define REDSTACK 2048 /* size of `panic: stack overflow' region */
/* `redzone' is located in the per-CPU information zone */
_redzone = CPUINFO_VA + CPUINFO_REDZONE
.data
_redzone:
.word _idle_u + REDSIZE
#define REDSTACK 2048 /* size of `panic: stack overflow' region */
_redstack:
.skip REDSTACK
.text
@ -1170,6 +1171,14 @@ Lpanic_red:
sethi %hi(_redzone), tmp2; \
st tmp1, [tmp2 + %lo(_redzone)]
/* variant with a variable & offset */
#define SET_SP_REDZONE_VAR(var, offset, tmp1, tmp2) \
sethi %hi(var), tmp1; \
ld [tmp1 + %lo(var)], tmp1; \
sethi %hi(offset), tmp2; \
add tmp1, tmp2, tmp1; \
SET_SP_REDZONE(tmp1, tmp2)
/* check stack pointer against redzone (uses two temps) */
#define CHECK_SP_REDZONE(t1, t2) \
sethi %hi(_redzone), t1; \
@ -1193,12 +1202,15 @@ Lpanic_red:
call _panic; or %o0, %lo(Lpanic_red), %o0; \
7:
#define XDEBUG
#ifdef XDEBUG
#else
#define SET_SP_REDZONE(base, tmp)
#define SET_SP_REDZONE_CONST(const, t1, t2)
#define SET_SP_REDZONE_VAR(base, t1, t2)
#define CHECK_SP_REDZONE(t1, t2)
#endif
#endif /* DEBUG */
/*
* The window code must verify user stack addresses before using them.
@ -1478,6 +1490,56 @@ wmask: .skip 32 ! u_char wmask[0..31];
* go to the interrupt stack if (a) we came from user mode or (b) we
* came from kernel mode on the kernel stack.
*/
#ifdef MULTIPROCESSOR
_EINTSTACK = CPUINFO_VA + CPUINFO_EINTSTACK
#define INTR_SETUP(stackspace) \
rd %wim, %l4; \
mov 1, %l5; \
sll %l5, %l0, %l5; \
btst PSR_PS, %l0; \
bz 1f; \
btst %l5, %l4; \
/* came from kernel mode; cond codes still indicate trap window */ \
bz,a 0f; \
sethi %hi(_EINTSTACK), %l7; \
CALL_CLEAN_TRAP_WINDOW; \
sethi %hi(_EINTSTACK), %l7; \
0: /* now if not intstack > %fp >= eintstack, we were on the kernel stack */ \
ld [%l7 + %lo(_EINTSTACK)], %l7; \
cmp %fp, %l7; \
bge,a 3f; /* %fp >= eintstack */ \
add %l7, stackspace, %sp; /* so switch to intstack */ \
sethi %hi(INT_STACK_SIZE), %l6; \
sub %l7, %l6, %l7; \
cmp %fp, %l7; \
blu,a 3f; /* %fp < intstack */ \
add %l7, stackspace, %sp; /* so switch to intstack */ \
b 4f; \
add %fp, stackspace, %sp; /* else stay on intstack */ \
1: \
/* came from user mode: compute pcb_nw */ \
sethi %hi(_cpcb), %l6; \
ld [%l6 + %lo(_cpcb)], %l6; \
ld [%l6 + PCB_WIM], %l5; \
and %l0, 31, %l4; \
sub %l4, %l5, %l5; \
set uwtab, %l4; \
ldub [%l4 + %l5], %l5; \
st %l5, [%l6 + PCB_UW]; \
/* cond codes still indicate whether in trap window */ \
bz,a 2f; \
sethi %hi(_EINTSTACK), %l7; \
/* yes, in trap window; must save regs */ \
CALL_CLEAN_TRAP_WINDOW; \
sethi %hi(_EINTSTACK), %l7; \
2: \
ld [%l7 + %lo(_EINTSTACK)], %l7; \
add %l7, stackspace, %sp; \
3: \
SET_SP_REDZONE_VAR(_EINTSTACK, -INT_STACK_SIZE, %l6, %l5); \
4: \
CHECK_SP_REDZONE(%l6, %l5)
#else /* MULTIPROCESSOR */
#define INTR_SETUP(stackspace) \
rd %wim, %l4; \
mov 1, %l5; \
@ -1518,6 +1580,7 @@ wmask: .skip 32 ! u_char wmask[0..31];
SET_SP_REDZONE_CONST(_intstack, %l6, %l5); \
4: \
CHECK_SP_REDZONE(%l6, %l5)
#endif /* MULTIPROCESSOR */
/*
* Handler for making the trap window shiny clean.
@ -2043,10 +2106,27 @@ Lslowtrap_reenter:
* Lslowtrap_reenter above, but maybe after switching stacks....
*/
softtrap:
#ifdef MULTIPROCESSOR
/*
* The interrupt stack is not at a fixed location
* and %sp must be checked against both ends.
*/
sethi %hi(_EINTSTACK), %l7
ld [%l7 + %lo(_EINTSTACK)], %l7
cmp %sp, %l7
bge Lslowtrap_reenter
EMPTY
set INT_STACK_SIZE, %l6
sub %l7, %l6, %l7
cmp %sp, %l7
blu Lslowtrap_reenter
EMPTY
#else
sethi %hi(_eintstack), %l7
cmp %sp, %l7
bge Lslowtrap_reenter
EMPTY
#endif
sethi %hi(_cpcb), %l6
ld [%l6 + %lo(_cpcb)], %l6
set USPACE-CCFSZ-80, %l5