Start reorganizing the kernel for MULTIPROCESSOR support.
This commit is contained in:
parent
65bca8bde2
commit
fb0404cc75
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cpu.h,v 1.18 2000/06/12 05:29:43 mrg Exp $ */
|
||||
/* $NetBSD: cpu.h,v 1.19 2000/06/12 23:32:46 eeh Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -74,14 +74,35 @@
|
||||
#include <sparc64/sparc64/intreg.h>
|
||||
|
||||
#include <sys/sched.h>
|
||||
/*
|
||||
* The cpu_info structure is part of a 64KB structure mapped both the kernel
|
||||
* pmap and a single locked TTE a CPUINFO_VA for that particular processor.
|
||||
* Each processor's cpu_info is accessible at CPUINFO_VA only for that
|
||||
* processor. Other processors can access that through an additional mapping
|
||||
* in the kernel pmap.
|
||||
*
|
||||
* The 64KB page contains:
|
||||
*
|
||||
* cpu_info
|
||||
* interrupt stack (all remaining space)
|
||||
* idle PCB
|
||||
* idle stack (STACKSPACE - sizeof(PCB))
|
||||
* 32KB TSB
|
||||
*/
|
||||
|
||||
struct cpu_info {
|
||||
struct proc *ci_curproc;
|
||||
struct pcb *ci_cpcb;
|
||||
struct cpu_info *ci_next;
|
||||
int ci_number;
|
||||
struct schedstate_percpu ci_schedstate; /* scheduler state */
|
||||
#if defined(DIAGNOSTIC) || defined(LOCKDEBUG)
|
||||
u_long ci_spin_locks; /* # of spin locks held */
|
||||
u_long ci_simple_locks; /* # of simple locks held */
|
||||
u_long ci_spin_locks; /* # of spin locks held */
|
||||
u_long ci_simple_locks;/* # of simple locks held */
|
||||
#endif
|
||||
};
|
||||
|
||||
extern struct cpu_info *cpus;
|
||||
extern struct cpu_info cpu_info_store;
|
||||
|
||||
#define curcpu() (&cpu_info_store)
|
||||
@ -93,7 +114,7 @@ extern struct cpu_info cpu_info_store;
|
||||
#define cpu_swapin(p) /* nothing */
|
||||
#define cpu_swapout(p) /* nothing */
|
||||
#define cpu_wait(p) /* nothing */
|
||||
#define cpu_number() 0
|
||||
#define cpu_number() (curcpu()->ci_number)
|
||||
|
||||
/*
|
||||
* Arguments to hardclock, softclock and gatherstats encapsulate the
|
||||
@ -188,6 +209,8 @@ extern struct intrhand *intrlev[MAXINTNUM];
|
||||
|
||||
void intr_establish __P((int level, struct intrhand *));
|
||||
|
||||
/* cpu.c */
|
||||
u_int64_t cpu_start __P((int));
|
||||
/* disksubr.c */
|
||||
struct dkbad;
|
||||
int isbad __P((struct dkbad *bt, int, int, int));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: param.h,v 1.17 2000/05/22 02:35:24 mrg Exp $ */
|
||||
/* $NetBSD: param.h,v 1.18 2000/06/12 23:32:46 eeh Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -120,8 +120,8 @@
|
||||
extern int nbpg, pgofset, pgshift;
|
||||
#endif
|
||||
|
||||
#define KERNBASE 0xf1000000 /* start of kernel virtual space */
|
||||
#define KERNEND 0xfe000000 /* start of kernel virtual space */
|
||||
#define KERNBASE 0x0f1000000 /* start of kernel virtual space */
|
||||
#define KERNEND 0x0fe000000 /* end of kernel virtual space */
|
||||
#define VM_MAX_KERNEL_BUF ((KERNEND-KERNBASE)/4)
|
||||
|
||||
#define DEV_BSIZE 512
|
||||
@ -131,12 +131,18 @@ extern int nbpg, pgofset, pgshift;
|
||||
|
||||
#ifdef __arch64__
|
||||
/* We get stack overflows w/8K stacks in 64-bit mode */
|
||||
#define SSIZE 2 /* initial stack size in pages */
|
||||
#define SSIZE 1 /* initial stack size in pages */
|
||||
#else
|
||||
#define SSIZE 1
|
||||
#endif
|
||||
#define USPACE (SSIZE*8192)
|
||||
|
||||
/*
|
||||
* Here's the location of the interrupt stack and CPU structure.
|
||||
*/
|
||||
#define INTSTACK (KERNEND)
|
||||
#define EINTSTACK (INTSTACK+USPACE
|
||||
|
||||
/*
|
||||
* Constants related to network buffer management.
|
||||
* MCLBYTES must be no larger than NBPG (the software page size), and,
|
||||
@ -202,6 +208,7 @@ extern int nbpg, pgofset, pgshift;
|
||||
*/
|
||||
#ifdef _KERNEL
|
||||
#ifndef _LOCORE
|
||||
#if 0
|
||||
extern vaddr_t dvma_base;
|
||||
extern vaddr_t dvma_end;
|
||||
extern struct map *dvmamap;
|
||||
@ -215,6 +222,7 @@ extern struct map *dvmamap;
|
||||
extern caddr_t kdvma_mapin __P((caddr_t, int, int));
|
||||
extern caddr_t dvma_malloc __P((size_t, void *, int));
|
||||
extern void dvma_free __P((caddr_t, size_t, void *));
|
||||
#endif
|
||||
|
||||
extern void delay __P((unsigned int));
|
||||
#define DELAY(n) delay(n)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cpu.c,v 1.5 1999/11/06 20:18:13 eeh Exp $ */
|
||||
/* $NetBSD: cpu.c,v 1.6 2000/06/12 23:32:47 eeh Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
@ -56,6 +56,7 @@
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_kern.h>
|
||||
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/cpu.h>
|
||||
@ -69,6 +70,12 @@
|
||||
/* This is declared here so that you must include a CPU for the cache code. */
|
||||
struct cacheinfo cacheinfo;
|
||||
|
||||
/* Our exported CPU info; we have only one for now. */
|
||||
struct cpu_info cpu_info_store;
|
||||
|
||||
/* Linked list of all CPUs in system. */
|
||||
struct cpu_info *cpus = NULL;
|
||||
|
||||
/* The following are used externally (sysctl_hw). */
|
||||
char machine[] = MACHINE; /* from <machine/param.h> */
|
||||
char machine_arch[] = MACHINE_ARCH; /* from <machine/param.h> */
|
||||
@ -118,18 +125,85 @@ static char *iu_vendor[16] = {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 4/110 comment: the 4/110 chops off the top 4 bits of an OBIO address.
|
||||
* this confuses autoconf. for example, if you try and map
|
||||
* 0xfe000000 in obio space on a 4/110 it actually maps 0x0e000000.
|
||||
* this is easy to verify with the PROM. this causes problems
|
||||
* with devices like "esp0 at obio0 addr 0xfa000000" because the
|
||||
* 4/110 treats it as esp0 at obio0 addr 0x0a000000" which is the
|
||||
* address of the 4/110's "sw0" scsi chip. the same thing happens
|
||||
* between zs1 and zs2. since the sun4 line is "closed" and
|
||||
* we know all the "obio" devices that will ever be on it we just
|
||||
* put in some special case "if"'s in the match routines of esp,
|
||||
* dma, and zs.
|
||||
* Overhead involved in firing up a new CPU:
|
||||
*
|
||||
* Allocate a cpuinfo/interrupt stack
|
||||
* Map that into the kernel
|
||||
* Initialize the cpuinfo
|
||||
* Return the TLB entry for the cpuinfo.
|
||||
*/
|
||||
u_int64_t
|
||||
cpu_start(cpu_num)
|
||||
int cpu_num;
|
||||
{
|
||||
struct cpu_info *ci;
|
||||
u_int64_t pagesize;
|
||||
u_int64_t pte;
|
||||
vm_page_t m;
|
||||
paddr_t pa;
|
||||
psize_t size;
|
||||
vaddr_t va;
|
||||
struct pglist mlist;
|
||||
int error;
|
||||
|
||||
size = NBPG; /* XXXX 8K, 64K, 512K, or 4MB */
|
||||
TAILQ_INIT(&mlist);
|
||||
if ((error = uvm_pglistalloc((psize_t)size, (paddr_t)0, (paddr_t)-1,
|
||||
(paddr_t)size, (paddr_t)0, &mlist, 1, 0)) != 0)
|
||||
panic("cpu_start: no memory, error %d", error);
|
||||
|
||||
va = uvm_km_valloc(kernel_map, size);
|
||||
if (va == 0)
|
||||
panic("cpu_start: no memory");
|
||||
|
||||
m = TAILQ_FIRST(&mlist);
|
||||
pa = VM_PAGE_TO_PHYS(m);
|
||||
pte = TSB_DATA(0 /* global */,
|
||||
pagesize,
|
||||
pa,
|
||||
1 /* priv */,
|
||||
1 /* Write */,
|
||||
1 /* Cacheable */,
|
||||
1 /* ALIAS -- Disable D$ */,
|
||||
1 /* valid */,
|
||||
0 /* IE */);
|
||||
|
||||
/* Map the pages */
|
||||
for (; m != NULL; m = TAILQ_NEXT(m,pageq)) {
|
||||
pa = VM_PAGE_TO_PHYS(m);
|
||||
pmap_zero_page(pa);
|
||||
pmap_enter(pmap_kernel(), va, pa | PMAP_NVC,
|
||||
VM_PROT_READ|VM_PROT_WRITE,
|
||||
VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
|
||||
va += NBPG;
|
||||
}
|
||||
if (!cpus) cpus = (struct cpu_info *)va;
|
||||
else {
|
||||
for (ci = cpus; ci->ci_next; ci=ci->ci_next);
|
||||
ci->ci_next = (struct cpu_info *)va;
|
||||
}
|
||||
|
||||
switch (size) {
|
||||
#define K *1024
|
||||
case 8 K:
|
||||
pagesize = TLB_8K;
|
||||
break;
|
||||
case 64 K:
|
||||
pagesize = TLB_64K;
|
||||
break;
|
||||
case 512 K:
|
||||
pagesize = TLB_512K;
|
||||
break;
|
||||
case 4 K K:
|
||||
pagesize = TLB_4M;
|
||||
break;
|
||||
default:
|
||||
panic("cpu_start: stack size %x not a machine page size\n",
|
||||
size);
|
||||
}
|
||||
return (pte|TLB_L);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
cpu_match(parent, cf, aux)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: intreg.h,v 1.2 2000/03/16 02:36:59 eeh Exp $ */
|
||||
/* $NetBSD: intreg.h,v 1.3 2000/06/12 23:32:47 eeh Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -73,71 +73,5 @@
|
||||
#ifndef _LOCORE
|
||||
struct intrhand; /* This is in cpu.h if you need it. */
|
||||
void send_softint __P((int cpu, int level, struct intrhand *ih));
|
||||
#if 0
|
||||
void ienab_bis __P((int bis)); /* set given bits */
|
||||
void ienab_bic __P((int bic)); /* clear given bits */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if defined(SUN4M)
|
||||
#ifdef notyet
|
||||
#define IENAB_SYS ((_MAXNBPG * _MAXNCPU) + 0xc)
|
||||
#define IENAB_P0 0x0008
|
||||
#define IENAB_P1 0x1008
|
||||
#define IENAB_P2 0x2008
|
||||
#define IENAB_P3 0x3008
|
||||
#endif /* notyet */
|
||||
#endif
|
||||
|
||||
#if defined(SUN4M)
|
||||
/*
|
||||
* Interrupt Control Registers, located in IO space.
|
||||
* (mapped to `locore' for now..)
|
||||
* There are two sets of interrupt registers called `Processor Interrupts'
|
||||
* and `System Interrupts'. The `Processor' set corresponds to the 15
|
||||
* interrupt levels as seen by the CPU. The `System' set corresponds to
|
||||
* a set of devices supported by the implementing chip-set.
|
||||
*
|
||||
* Briefly, the ICR_PI_* are per-processor interrupts; the ICR_SI_* are
|
||||
* system-wide interrupts, and the ICR_ITR selects the processor to get
|
||||
* the system's interrupts.
|
||||
*/
|
||||
#define ICR_PI_PEND (PI_INTR_VA + 0x0)
|
||||
#define ICR_PI_CLR (PI_INTR_VA + 0x4)
|
||||
#define ICR_PI_SET (PI_INTR_VA + 0x8)
|
||||
#define ICR_SI_PEND (SI_INTR_VA)
|
||||
#define ICR_SI_MASK (SI_INTR_VA + 0x4)
|
||||
#define ICR_SI_CLR (SI_INTR_VA + 0x8)
|
||||
#define ICR_SI_SET (SI_INTR_VA + 0xc)
|
||||
#define ICR_ITR (SI_INTR_VA + 0x10)
|
||||
|
||||
/*
|
||||
* Bits in interrupt registers. Software interrupt requests must
|
||||
* be cleared in software. This is done in locore.s.
|
||||
* There are separate registers for reading pending interrupts and
|
||||
* setting/clearing (software) interrupts.
|
||||
*/
|
||||
#define PINTR_SINTRLEV(n) (1 << (16 + (n)))
|
||||
#define PINTR_IC 0x8000 /* Level 15 clear */
|
||||
|
||||
#define SINTR_MA 0x80000000 /* Mask All interrupts */
|
||||
#define SINTR_ME 0x40000000 /* Module Error (async) */
|
||||
#define SINTR_I 0x20000000 /* MSI (MBus-SBus) */
|
||||
#define SINTR_M 0x10000000 /* ECC Memory controller */
|
||||
#define SINTR_RSVD2 0x0f800000
|
||||
#define SINTR_F 0x00400000 /* Floppy */
|
||||
#define SINTR_RSVD3 0x00200000
|
||||
#define SINTR_V 0x00100000 /* Video (Supersparc only) */
|
||||
#define SINTR_T 0x00080000 /* Level 10 counter */
|
||||
#define SINTR_SC 0x00040000 /* SCSI */
|
||||
#define SINTR_RSVD4 0x00020000
|
||||
#define SINTR_E 0x00010000 /* Ethernet */
|
||||
#define SINTR_S 0x00008000 /* Serial port */
|
||||
#define SINTR_K 0x00004000 /* Keyboard/mouse */
|
||||
#define SINTR_SBUSMASK 0x00003f80 /* SBus */
|
||||
#define SINTR_SBUS(n) (((n) << 7) & 0x00003f80)
|
||||
#define SINTR_RSVD5 0x0000007f
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: locore.s,v 1.60 2000/05/31 05:09:19 thorpej Exp $ */
|
||||
/* $NetBSD: locore.s,v 1.61 2000/06/12 23:32:47 eeh Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1996-1999 Eduardo Horvath
|
||||
* Copyright (c) 1996 Paul Kranenburg
|
||||
@ -289,9 +289,15 @@ _C_LABEL(idle_u):
|
||||
*
|
||||
* This must be aligned on an 8 byte boundary.
|
||||
*/
|
||||
#if 0
|
||||
.globl _C_LABEL(u0)
|
||||
_C_LABEL(u0): .space (2*USPACE)
|
||||
estack0:
|
||||
#else
|
||||
.globl _C_LABEL(u0)
|
||||
_C_LABEL(u0): POINTER 0
|
||||
estack0: POINTER 0
|
||||
#endif
|
||||
|
||||
#ifdef KGDB
|
||||
/*
|
||||
@ -1424,8 +1430,8 @@ traceit:
|
||||
brnz,pn %g4, 1f
|
||||
lduw [%g2+TRACEPTR], %g3
|
||||
rdpr %tl, %g4
|
||||
set _C_LABEL(curproc), %g6
|
||||
rdpr %tt, %g5
|
||||
set _C_LABEL(curproc), %g6
|
||||
cmp %g4, 1
|
||||
sllx %g4, 13, %g4
|
||||
bnz,a,pt %icc, 3f
|
||||
@ -1454,8 +1460,8 @@ traceit:
|
||||
or %g6, %g4, %g4
|
||||
2:
|
||||
|
||||
rdpr %tstate, %g6
|
||||
movnz %icc, %g0, %g3 ! Wrap buffer if needed
|
||||
rdpr %tstate, %g6
|
||||
rdpr %tpc, %g7
|
||||
sth %g4, [%g2+%g3]
|
||||
inc 2, %g3
|
||||
@ -1780,13 +1786,13 @@ intr_setup_msg:
|
||||
stx %i5, [%sp + CC64FSZ + BIAS + TF_O + (5*8)]; \
|
||||
stx %i6, [%sp + CC64FSZ + BIAS + TF_O + (6*8)]; \
|
||||
stx %i6, [%sp + CC64FSZ + BIAS + TF_G + (0*8)]; /* Save fp in clockframe->cf_fp */ \
|
||||
stx %i7, [%sp + CC64FSZ + BIAS + TF_O + (7*8)]; \
|
||||
rdpr %wstate, %g7; /* Find if we're from user mode */ \
|
||||
stx %i7, [%sp + CC64FSZ + BIAS + TF_O + (7*8)]; \
|
||||
cmp %g7, WSTATE_KERN; /* Compare & leave in register */ \
|
||||
be,pn %icc, 1f; /* If we were in kernel mode start saving globals */ \
|
||||
/* came from user mode -- switch to kernel mode stack */ \
|
||||
rdpr %otherwin, %g5; /* Has this already been done? */ \
|
||||
/* tst %g5; tnz %xcc, 1; nop; /* DEBUG -- this should _NEVER_ happen */ \
|
||||
/* mov %g5, %g5; tst %g5; tnz %xcc, 1; nop; /* DEBUG -- this should _NEVER_ happen */ \
|
||||
brnz,pn %g5, 1f; /* Don't set this twice */ \
|
||||
rdpr %canrestore, %g5; /* Fixup register window state registers */ \
|
||||
wrpr %g0, 0, %canrestore; \
|
||||
@ -1912,8 +1918,8 @@ intr_setup_msg:
|
||||
stx %i5, [%sp + CC64FSZ + STKB + TF_O + (5*8)]; \
|
||||
stx %i6, [%sp + CC64FSZ + STKB + TF_O + (6*8)]; \
|
||||
stx %i6, [%sp + CC64FSZ + STKB + TF_G + (0*8)]; /* Save fp in clockframe->cf_fp */ \
|
||||
stx %i7, [%sp + CC64FSZ + STKB + TF_O + (7*8)]; \
|
||||
rdpr %wstate, %g7; /* Find if we're from user mode */ \
|
||||
stx %i7, [%sp + CC64FSZ + STKB + TF_O + (7*8)]; \
|
||||
cmp %g7, WSTATE_KERN; /* Compare & leave in register */ \
|
||||
be,pn %icc, 1f; /* If we were in kernel mode start saving globals */ \
|
||||
/* came from user mode -- switch to kernel mode stack */ \
|
||||
@ -2561,9 +2567,11 @@ winfixspill:
|
||||
or %lo(2f), %o0, %o0
|
||||
wrpr %g0, WSTATE_KERN, %wstate
|
||||
#ifdef DEBUG
|
||||
set panicstack-CC64FSZ, %sp ! Use panic stack.
|
||||
set panicstack-CC64FSZ-STKB, %sp ! Use panic stack.
|
||||
#else
|
||||
set estack0-CC64FSZ, %sp ! Overwrite proc 0's stack.
|
||||
set estack0, %sp
|
||||
LDPTR [%sp], %sp
|
||||
add %sp, -CC64FSZ-STKB, %sp ! Overwrite proc 0's stack.
|
||||
#endif
|
||||
ta 1; nop ! This helps out traptrace.
|
||||
call _C_LABEL(panic) ! This needs to be fixed properly but we should panic here
|
||||
@ -2824,6 +2832,7 @@ winfixsave:
|
||||
* We should re-execute the trapping save.
|
||||
*/
|
||||
rdpr %wstate, %g3
|
||||
mov %g3, %g3
|
||||
cmp %g3, WSTATE_KERN
|
||||
bne,pt %icc, 1f
|
||||
nop
|
||||
@ -3277,7 +3286,9 @@ slowtrap:
|
||||
#ifdef DEBUG
|
||||
set panicstack, %sp ! Kernel stack corrupt -- use panicstack
|
||||
#else
|
||||
set estack0, %sp ! Kernel stack corrupt -- use estack0
|
||||
set estack0, %sp
|
||||
LDPTR [%sp], %sp
|
||||
add %sp, -CC64FSZ-STKB, %sp ! Overwrite proc 0's stack.
|
||||
#endif
|
||||
1:
|
||||
rdpr %tt, %g4
|
||||
@ -3860,11 +3871,11 @@ setup_sparcintr:
|
||||
DLFLUSH(%g1, %g2)
|
||||
mov %g5, %g2
|
||||
CASPTR [%g1] ASI_N, %g0, %g2 ! Try a slot -- MPU safe
|
||||
brz,pt %g2, 4f ! Available?
|
||||
brz,pt %g2, 5f ! Available?
|
||||
#else
|
||||
DLFLUSH(%g1, %g2)
|
||||
LDPTR [%g1], %g2 ! Try a slog
|
||||
brz,a %g2, 4f ! Available?
|
||||
brz,a %g2, 5f ! Available?
|
||||
STPTR %g5, [%g1] ! Grab it
|
||||
#endif
|
||||
dec %g7
|
||||
@ -3874,7 +3885,7 @@ setup_sparcintr:
|
||||
!! If we get here we have a problem.
|
||||
!! There were no available slots and the interrupt was lost.
|
||||
!! We'll resort to polling in this case.
|
||||
4:
|
||||
5:
|
||||
DLFLUSH(%g1, %g1) ! Prevent D$ pollution
|
||||
#endif
|
||||
set 1, %g7
|
||||
@ -4098,7 +4109,25 @@ _C_LABEL(sparc_interrupt):
|
||||
brz,pn %o3, 0f
|
||||
LDPTR [%l2 + IH_ARG], %o0 ! ih->ih_arg
|
||||
stx %g0, [%o3] ! Clear intr source
|
||||
0:
|
||||
#ifdef DEBUG
|
||||
set _C_LABEL(intrdebug), %o3
|
||||
ld [%o3], %o3
|
||||
btst INTRDEBUG_FUNC, %o3
|
||||
bz,a,pt %icc, 0f
|
||||
nop
|
||||
|
||||
save %sp, -CC64FSZ, %sp
|
||||
set 9f, %o0
|
||||
mov %i0, %o2 ! arg
|
||||
mov %i6, %o3 ! sp
|
||||
GLOBTOLOC
|
||||
call prom_printf
|
||||
mov %i1, %o1 ! fun
|
||||
LOCTOGLOB
|
||||
restore
|
||||
0:
|
||||
#endif
|
||||
jmpl %o1, %o7 ! handled = (*ih->ih_fun)(...)
|
||||
movrz %o0, %o2, %o0 ! arg = (arg == 0) ? arg : tf
|
||||
inc %l5
|
||||
@ -4466,8 +4495,8 @@ rft_kernel:
|
||||
sllx %g6, 9, %g6
|
||||
or %g6, %g4, %g4
|
||||
|
||||
rdpr %tstate, %g6
|
||||
movnz %icc, %g0, %g3 ! Wrap if needed
|
||||
rdpr %tstate, %g6
|
||||
rdpr %tpc, %g7
|
||||
sth %g4, [%g2+%g3]
|
||||
inc 2, %g3
|
||||
@ -4810,8 +4839,8 @@ badregs:
|
||||
sllx %g6, 9, %g6
|
||||
or %g6, %g4, %g4
|
||||
|
||||
rdpr %tstate, %g6
|
||||
movnz %icc, %g0, %g3 ! Wrap if needed
|
||||
rdpr %tstate, %g6
|
||||
rdpr %tpc, %g7
|
||||
sth %g4, [%g2+%g3]
|
||||
inc 2, %g3
|
||||
@ -5069,23 +5098,21 @@ dostart:
|
||||
STPTR %o4, [%o5] ! It's initialized data, I hope
|
||||
|
||||
/*
|
||||
* Step 2: Set up a v8-like stack
|
||||
* Step 2: Set up a v8-like stack if we need to
|
||||
*/
|
||||
|
||||
!!! Make sure our stack's OK.
|
||||
#define SAVE save %sp, -CC64FSZ, %sp
|
||||
SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE
|
||||
restore;restore;restore;restore;restore;restore;restore;restore;restore;restore
|
||||
set estack0 - CC64FSZ - 80, %l0 ! via syscall(boot_me_up) or somesuch
|
||||
#ifdef _LP64
|
||||
andn %l0, 0x0f, %l0 ! Needs to be 16-byte aligned
|
||||
sub %l0, BIAS, %l0 ! and biased
|
||||
btst 1, %sp
|
||||
bnz,pt %icc, 0f
|
||||
nop
|
||||
add %sp, -BIAS, %sp
|
||||
#else
|
||||
btst 1, %sp
|
||||
bz,pt %icc, 0f
|
||||
nop
|
||||
add %sp, BIAS, %sp
|
||||
#endif
|
||||
save %g0, %l0, %sp
|
||||
!!! Make sure our stack's OK.
|
||||
SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE
|
||||
restore;restore;restore;restore;restore;restore;restore;restore;restore;restore
|
||||
|
||||
0:
|
||||
/*
|
||||
* Step 3: clear BSS. This may just be paranoia; the boot
|
||||
* loader might already do it for us; but what the hell.
|
||||
@ -5129,6 +5156,26 @@ dostart:
|
||||
call _C_LABEL(bootstrap)
|
||||
inc %o0 ! and add 1 to discover maxctx
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
set _C_LABEL(main), %o0
|
||||
/*
|
||||
* Initialize a CPU. This is used both for bootstrapping the first CPU
|
||||
* and spinning up each subsequent CPU. Basically:
|
||||
*
|
||||
* Establish the 4MB locked mappings for kernel data and text.
|
||||
* Establish a locked mapping for interrupt stack.
|
||||
* Switch to interrupt stack.
|
||||
* Call the routine passed in in %o0
|
||||
*/
|
||||
|
||||
|
||||
_C_LABEL(cpu_init):
|
||||
mov %o0, %l7 ! Save the routine we jump to
|
||||
/*
|
||||
* Step 3: install the permanent 4MB kernel mapping in both the
|
||||
* immu and dmmu. We will clear out other mappings later.
|
||||
@ -5142,7 +5189,7 @@ dostart:
|
||||
* %l4 = tmp
|
||||
* %l5 = tmp && TLB_TAG_ACCESS
|
||||
* %l6 = tmp && CTX_PRIMARY
|
||||
* %l7 = tmp && demap address
|
||||
* %l7 = routine to jump to
|
||||
*/
|
||||
wrpr %g0, 0, %tl ! Make sure we're not in NUCLEUS mode
|
||||
sethi %hi(KERNBASE), %l0 ! Find our xlation
|
||||
@ -5205,12 +5252,12 @@ dostart:
|
||||
#else
|
||||
or %l1, TTE_L|TTE_CP|TTE_CV|TTE_P|TTE_W, %l2 ! And low bits: L=1|CP=1|CV=1|E=0|P=1|W=1(ugh)|G=0
|
||||
#endif
|
||||
set 1f, %l7
|
||||
set 1f, %o5
|
||||
stxa %l0, [%l5] ASI_DMMU ! Same for DMMU
|
||||
membar #Sync ! We may need more membar #Sync in here
|
||||
stxa %l2, [%g0] ASI_DMMU_DATA_IN ! Same for DMMU
|
||||
membar #Sync ! We may need more membar #Sync in here
|
||||
flush %l7 ! Make IMMU see this too
|
||||
flush %o5 ! Make IMMU see this too
|
||||
1:
|
||||
#ifdef NODEF_DEBUG
|
||||
set 1f, %o0 ! Debug printf
|
||||
@ -5233,7 +5280,7 @@ dostart:
|
||||
set TLB_TAG_ACCESS, %l5
|
||||
or %l1, TTE_CP|TTE_P|TTE_W, %l2 ! And low bits: L=0|CP=1|CV=0|E=0|P=1|W=1(ugh)|G=0
|
||||
or %l0, 1, %l4 ! Context = 1
|
||||
set 1f, %l7
|
||||
set 1f, %o5
|
||||
stxa %l4, [%l5] ASI_DMMU ! Make DMMU point to it
|
||||
membar #Sync ! We may need more membar #Sync in here
|
||||
stxa %l2, [%g0] ASI_DMMU_DATA_IN ! Store it
|
||||
@ -5243,17 +5290,17 @@ dostart:
|
||||
flush %l0 ! Make IMMU see this too
|
||||
stxa %l2, [%g0] ASI_IMMU_DATA_IN ! Store it
|
||||
membar #Sync ! We may need more membar #Sync in here
|
||||
flush %l7 ! Make IMMU see this too
|
||||
flush %o5 ! Make IMMU see this too
|
||||
1:
|
||||
!!
|
||||
!! Now load 1 as primary context
|
||||
!!
|
||||
mov 1, %l4
|
||||
mov CTX_PRIMARY, %l6
|
||||
set 1f, %l7
|
||||
set 1f, %o5
|
||||
stxa %l4, [%l6] ASI_DMMU
|
||||
membar #Sync ! This probably should be a flush, but it works
|
||||
flush %l7 ! This should be KERNBASE
|
||||
flush %o5 ! This should be KERNBASE
|
||||
1:
|
||||
|
||||
!!
|
||||
@ -5266,7 +5313,7 @@ dostart:
|
||||
0:
|
||||
stxa %l5, [%l5] ASI_IMMU_DEMAP ! Demap it
|
||||
membar #Sync
|
||||
flush %l7 ! Assume low bits are benign
|
||||
flush %o5 ! Assume low bits are benign
|
||||
cmp %l5, %l3
|
||||
bleu 0b ! Next page
|
||||
add %l5, %l4, %l5
|
||||
@ -5281,21 +5328,21 @@ dostart:
|
||||
#else
|
||||
or %l1, TTE_L|TTE_CP|TTE_CV|TTE_P|TTE_W, %l2 ! And low bits: L=1|CP=1|CV=1|E=0|P=1|W=1(ugh)|G=0
|
||||
#endif
|
||||
set 1f, %l7
|
||||
set 1f, %o5
|
||||
stxa %l0, [%l5] ASI_IMMU ! Make IMMU point to it
|
||||
membar #Sync ! We may need more membar #Sync in here
|
||||
stxa %l2, [%g0] ASI_IMMU_DATA_IN ! Store it
|
||||
membar #Sync ! We may need more membar #Sync in here
|
||||
flush %l7
|
||||
flush %o5
|
||||
1:
|
||||
!!
|
||||
!! Restore 0 as primary context
|
||||
!!
|
||||
mov CTX_PRIMARY, %l6
|
||||
set 1f, %l7
|
||||
set 1f, %o5
|
||||
stxa %g0, [%l6] ASI_DMMU
|
||||
membar #Sync ! No real reason for this XXXX
|
||||
flush %l7
|
||||
flush %o5
|
||||
1:
|
||||
!!
|
||||
!! Now demap context 1
|
||||
@ -5314,7 +5361,43 @@ dostart:
|
||||
stxa %g0, [%l6] ASI_DMMU
|
||||
membar #Sync
|
||||
flush %l0
|
||||
|
||||
/*
|
||||
* Get pointer to our cpu_info struct
|
||||
*/
|
||||
set _C_LABEL(cpu0paddr), %o0
|
||||
LDPTR [%o0], %o0
|
||||
|
||||
!!
|
||||
!! Now, map in the kernel as context==0
|
||||
!!
|
||||
set TLB_TAG_ACCESS, %l5
|
||||
sethi %hi(INTSTACK), %l0
|
||||
set 1f, %o5
|
||||
stxa %l0, [%l5] ASI_IMMU ! Make IMMU point to it
|
||||
membar #Sync ! We may need more membar #Sync in here
|
||||
stxa %o0, [%g0] ASI_IMMU_DATA_IN ! Store it
|
||||
membar #Sync ! We may need more membar #Sync in here
|
||||
flush %o5
|
||||
1:
|
||||
|
||||
!!! Make sure our stack's OK.
|
||||
#define SAVE save %sp, -CC64FSZ, %sp
|
||||
SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE
|
||||
restore;restore;restore;restore;restore;restore;restore;restore;restore;restore
|
||||
set _C_LABEL(estack0), %l0
|
||||
LDPTR [%l0], %l0
|
||||
add %l0, - CC64FSZ - 80, %l0 ! via syscall(boot_me_up) or somesuch
|
||||
#ifdef _LP64
|
||||
andn %l0, 0x0f, %l0 ! Needs to be 16-byte aligned
|
||||
sub %l0, BIAS, %l0 ! and biased
|
||||
#endif
|
||||
save %g0, %l0, %sp
|
||||
!!! Make sure our stack's OK.
|
||||
SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE
|
||||
restore;restore;restore;restore;restore;restore;restore;restore;restore;restore
|
||||
|
||||
|
||||
#if 1
|
||||
/*
|
||||
* This should be handled in the CPU probe code
|
||||
@ -5383,6 +5466,7 @@ dostart:
|
||||
* user space. (If the exec fails, main() does not return.)
|
||||
*/
|
||||
call _C_LABEL(main)
|
||||
! call %l7 ! Call routine
|
||||
clr %o0 ! our frame arg is ignored
|
||||
NOTREACHED
|
||||
|
||||
@ -5488,7 +5572,7 @@ _C_LABEL(openfirmware):
|
||||
mov %g6, %l6
|
||||
mov %g7, %l7
|
||||
jmpl %o1, %o7
|
||||
#if defined(_LP64) || defined(TRAPTRACE)
|
||||
#if !defined(_LP64) || defined(TRAPTRACE)
|
||||
wrpr %g0, PSTATE_PROM, %pstate ! Enable 64-bit addresses for the prom
|
||||
#else
|
||||
wrpr %g0, PSTATE_PROM|PSTATE_IE, %pstate ! Enable 64-bit addresses for the prom
|
||||
@ -5750,7 +5834,7 @@ _C_LABEL(sigcode):
|
||||
andn %l0, BLOCK_ALIGN, %l0 ! do a block store
|
||||
stda %f0, [%l0] ASI_BLK_P
|
||||
inc BLOCK_SIZE, %l0
|
||||
stda %f16, [%l0] ASI_BLK_COMMIT_P
|
||||
stda %f16, [%l0] ASI_BLK_P
|
||||
1:
|
||||
bz,pt %icc, 2f
|
||||
rd %y, %l1 ! in any case, save %y
|
||||
@ -5759,8 +5843,9 @@ _C_LABEL(sigcode):
|
||||
add %l0, 2*BLOCK_SIZE, %l0 ! and skip what we already stored
|
||||
stda %f32, [%l0] ASI_BLK_P
|
||||
inc BLOCK_SIZE, %l0
|
||||
stda %f48, [%l0] ASI_BLK_COMMIT_P
|
||||
stda %f48, [%l0] ASI_BLK_P
|
||||
2:
|
||||
membar #StoreLoad
|
||||
lduw [%fp + BIAS + CC64FSZ], %o0 ! sig
|
||||
lduw [%fp + BIAS + CC64FSZ + 4], %o1 ! code
|
||||
call %g1 ! (*sa->sa_handler)(sig,code,scp)
|
||||
@ -9868,16 +9953,16 @@ Lfp_finish:
|
||||
add %o2, 128, %o2 ! Skip a block
|
||||
|
||||
|
||||
stda %f0, [%o2] ASI_BLK_P ! f->fs_f0 = etc;
|
||||
stda %f0, [%o2] ASI_BLK_COMMIT_P ! f->fs_f0 = etc;
|
||||
inc BLOCK_SIZE, %o2
|
||||
stda %f16, [%o2] ASI_BLK_P
|
||||
stda %f16, [%o2] ASI_BLK_COMMIT_P
|
||||
inc BLOCK_SIZE, %o2
|
||||
1:
|
||||
btst FPRS_DU, %o5 ! Upper FPU clean?
|
||||
bz,pt %icc, 2f ! Then skip it
|
||||
nop
|
||||
|
||||
stda %f32, [%o2] ASI_BLK_P
|
||||
stda %f32, [%o2] ASI_BLK_COMMIT_P
|
||||
inc BLOCK_SIZE, %o2
|
||||
stda %f48, [%o2] ASI_BLK_COMMIT_P
|
||||
2:
|
||||
@ -10333,6 +10418,7 @@ ENTRY(delay) ! %o0 = n
|
||||
add %g1, %g2, %g2
|
||||
! add %o5, %g2, %g2 ! But this gets complicated
|
||||
rdpr %tick, %g1 ! Top of next itr
|
||||
mov %g1, %g1 ! Erratum 50
|
||||
1:
|
||||
cmp %g1, %g2
|
||||
bl,a,pn %xcc, 1b ! Done?
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: machdep.c,v 1.65 2000/06/12 05:31:30 mrg Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.66 2000/06/12 23:32:48 eeh Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
|
||||
@ -129,8 +129,6 @@
|
||||
|
||||
/* #include "fb.h" */
|
||||
|
||||
/* Our exported CPU info; we have only one for now. */
|
||||
struct cpu_info cpu_info_store;
|
||||
int bus_space_debug = 0; /* This may be used by macros elsewhere. */
|
||||
#ifdef DEBUG
|
||||
#define DPRINTF(l, s) do { if (bus_space_debug & l) printf s; } while (0)
|
||||
|
@ -1,8 +1,8 @@
|
||||
/* $NetBSD: pmap.c,v 1.53 2000/05/17 09:12:10 mrg Exp $ */
|
||||
/* $NetBSD: pmap.c,v 1.54 2000/06/12 23:32:48 eeh Exp $ */
|
||||
#undef NO_VCACHE /* Don't forget the locked TLB in dostart */
|
||||
#define HWREF 1
|
||||
#undef BOOT_DEBUG
|
||||
#undef BOOT1_DEBUG
|
||||
#undef BOOT_DEBUG
|
||||
#undef BOOT1_DEBUG
|
||||
/*
|
||||
*
|
||||
* Copyright (C) 1996-1999 Eduardo Horvath.
|
||||
@ -37,6 +37,7 @@
|
||||
#include <sys/systm.h>
|
||||
#include <sys/msgbuf.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/pool.h>
|
||||
#include <sys/exec.h>
|
||||
#include <sys/core.h>
|
||||
#include <sys/kcore.h>
|
||||
@ -68,6 +69,8 @@
|
||||
#define db_printf printf
|
||||
#endif
|
||||
|
||||
paddr_t cpu0paddr;/* XXXXXXXXXXXXXXXX */
|
||||
|
||||
/*
|
||||
* Support for big page sizes. This maps the page size to the
|
||||
* page bits. That is: these are the bits between 8K pages and
|
||||
@ -189,6 +192,7 @@ typedef struct pv_entry {
|
||||
#define PV_SETVA(pv,va) ((pv)->pv_va = (((va)&PV_VAMASK)|(((pv)->pv_va)&PV_MASK)))
|
||||
|
||||
pv_entry_t pv_table; /* array of entries, one per page */
|
||||
static struct pool pv_pool;
|
||||
extern void pmap_remove_pv __P((struct pmap *pm, vaddr_t va, paddr_t pa));
|
||||
extern void pmap_enter_pv __P((struct pmap *pm, vaddr_t va, paddr_t pa));
|
||||
extern void pmap_page_cache __P((paddr_t pa, int mode));
|
||||
@ -212,15 +216,6 @@ int tsbsize; /* tsbents = 512 * 2^^tsbsize */
|
||||
#define TSBENTS (512<<tsbsize)
|
||||
#define TSBSIZE (TSBENTS * 16)
|
||||
|
||||
/*
|
||||
* And here's the IOMMU TSB stuff, also allocated in pmap_bootstrap.
|
||||
*/
|
||||
int64_t *iotsb;
|
||||
paddr_t iotsbp;
|
||||
int iotsbsize; /* tsbents = 1024 * 2 ^^ tsbsize */
|
||||
#define IOTSBENTS (1024<<iotsbsize)
|
||||
#define IOTSBSIZE (IOTSBENTS * 8)
|
||||
|
||||
struct pmap kernel_pmap_;
|
||||
|
||||
int physmem;
|
||||
@ -554,6 +549,15 @@ pmap_bootstrap(kernelstart, kernelend, maxctx)
|
||||
/* Make sure all 4MB are mapped */
|
||||
prom_map_phys(ksegp, 4*MEG, kernelstart, -1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a 64MB page for the cpu_info structure now.
|
||||
*/
|
||||
if ((cpu0paddr = prom_alloc_phys(8*NBPG, 8*NBPG)) == 0 ) {
|
||||
prom_printf("Cannot allocate new cpu_info\r\n");
|
||||
OF_exit();
|
||||
}
|
||||
|
||||
/*
|
||||
* Find out how much RAM we have installed.
|
||||
*/
|
||||
@ -717,23 +721,17 @@ pmap_bootstrap(kernelstart, kernelend, maxctx)
|
||||
prom_printf("TSB allocated at %p size %08x\r\n", (void*)tsb,
|
||||
(int)TSBSIZE);
|
||||
#endif
|
||||
/*
|
||||
* Allocate a single IOMMU TSB so they're all mapped coherently.
|
||||
*/
|
||||
iotsbsize = 0; /* We will only allocate an 8K TSB now */
|
||||
valloc(iotsb, int64_t, IOTSBSIZE);
|
||||
iotsbp = ((vaddr_t)iotsb) - kernelstart + ksegp;
|
||||
bzero(iotsb, IOTSBSIZE); /* Invalidate all entries */
|
||||
|
||||
|
||||
/* initialize pv_list stuff */
|
||||
first_phys_addr = mem->start;
|
||||
#if 0
|
||||
valloc(pv_table, struct pv_entry, sizeof(struct pv_entry)*physmem);
|
||||
bzero((caddr_t)pv_table, sizeof(struct pv_entry)*physmem);
|
||||
#ifdef BOOT1_DEBUG
|
||||
prom_printf("Allocating pv_table at %lx,%lx\r\n", (u_long)pv_table,
|
||||
(u_long)sizeof(struct pv_entry)*physmem);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef BOOT1_DEBUG
|
||||
prom_printf("firstaddr after pmap=%08lx\r\n", (u_long)firstaddr);
|
||||
@ -1025,7 +1023,67 @@ pmap_bootstrap(kernelstart, kernelend, maxctx)
|
||||
prom_printf("Done inserting PROM mappings into pmap_kernel()\r\n");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Fix up start of kernel heap.
|
||||
*/
|
||||
vmmap = (caddr_t)(ksegv + 4*MEG); /* Start after our locked TLB entry */
|
||||
/* Let's keep 1 page of redzone after the kernel */
|
||||
vmmap += NBPG;
|
||||
/* Allocate some VAs for u0 */
|
||||
{
|
||||
extern vaddr_t u0[2];
|
||||
paddr_t pa;
|
||||
|
||||
u0[0] = vmmap;
|
||||
u0[1] = vmmap + 2*USPACE;
|
||||
|
||||
while (vmmap < u0[1]) {
|
||||
pte_t tte;
|
||||
vaddr_t va = (vaddr_t)vmmap;
|
||||
paddr_t newp;
|
||||
|
||||
pmap_get_page(&pa);
|
||||
prom_map_phys(phys_msgbuf, NBPG, va, -1);
|
||||
#ifdef NO_VCACHE
|
||||
tte.data.data = TSB_DATA(0 /* global */,
|
||||
TLB_8K,
|
||||
phys_msgbuf,
|
||||
1 /* priv */,
|
||||
1 /* Write */,
|
||||
1 /* Cacheable */,
|
||||
1 /* ALIAS -- Disable D$ */,
|
||||
1 /* valid */,
|
||||
0 /* IE */);
|
||||
#else
|
||||
tte.data.data = TSB_DATA(0 /* global */,
|
||||
TLB_8K,
|
||||
phys_msgbuf,
|
||||
1 /* priv */,
|
||||
1 /* Write */,
|
||||
1 /* Cacheable */,
|
||||
0 /* No ALIAS */,
|
||||
1 /* valid */,
|
||||
0 /* IE */);
|
||||
#endif
|
||||
newp = NULL;
|
||||
while (pseg_set(pmap_kernel(), va, tte.data.data, newp)
|
||||
!= NULL) {
|
||||
pmap_get_page(&newp);
|
||||
pmap_zero_page(newp);
|
||||
#ifdef DEBUG
|
||||
enter_stats.ptpneeded ++;
|
||||
#endif
|
||||
#ifdef BOOT1_DEBUG
|
||||
prom_printf(
|
||||
"pseg_set: pm=%p va=%p data=%lx newp %lx\r\n",
|
||||
pmap_kernel(), va, (long)tte.data.
|
||||
data, (long)newp);
|
||||
{int i; for (i=0; i<140000000; i++) ;}
|
||||
#endif
|
||||
}
|
||||
vmmap += NBPG;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Set up bounds of allocatable memory for vmstat et al.
|
||||
*/
|
||||
@ -1036,6 +1094,7 @@ pmap_bootstrap(kernelstart, kernelend, maxctx)
|
||||
#ifdef DEBUG
|
||||
pmapdebug = opmapdebug;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1045,13 +1104,94 @@ pmap_bootstrap(kernelstart, kernelend, maxctx)
|
||||
void
|
||||
pmap_init()
|
||||
{
|
||||
u_int64_t pagesize;
|
||||
u_int64_t pte;
|
||||
vm_page_t m;
|
||||
paddr_t pa;
|
||||
psize_t size;
|
||||
vaddr_t va;
|
||||
struct pglist mlist;
|
||||
|
||||
#ifdef NOTDEF_DEBUG
|
||||
prom_printf("pmap_init()\r\n");
|
||||
#endif
|
||||
if (PAGE_SIZE != NBPG)
|
||||
panic("pmap_init: CLSIZE!=1");
|
||||
|
||||
size = sizeof(struct pv_entry) * physmem;
|
||||
TAILQ_INIT(&mlist);
|
||||
if (uvm_pglistalloc((psize_t)size, (paddr_t)0, (paddr_t)-1,
|
||||
(paddr_t)NBPG, (paddr_t)0, &mlist, 1, 0) != 0)
|
||||
panic("cpu_start: no memory");
|
||||
|
||||
va = uvm_km_valloc(kernel_map, size);
|
||||
if (va == 0)
|
||||
panic("cpu_start: no memory");
|
||||
|
||||
pv_table = va;
|
||||
m = TAILQ_FIRST(&mlist);
|
||||
pa = VM_PAGE_TO_PHYS(m);
|
||||
pte = TSB_DATA(0 /* global */,
|
||||
pagesize,
|
||||
pa,
|
||||
1 /* priv */,
|
||||
1 /* Write */,
|
||||
1 /* Cacheable */,
|
||||
1 /* ALIAS -- Disable D$ */,
|
||||
1 /* valid */,
|
||||
0 /* IE */);
|
||||
|
||||
/* Map the pages */
|
||||
for (; m != NULL; m = TAILQ_NEXT(m,pageq)) {
|
||||
paddr_t newp;
|
||||
u_int64_t data;
|
||||
|
||||
pa = VM_PAGE_TO_PHYS(m);
|
||||
pmap_zero_page(pa);
|
||||
#ifdef NO_VCACHE
|
||||
data = TSB_DATA(0 /* global */,
|
||||
TLB_8K,
|
||||
pa,
|
||||
1 /* priv */,
|
||||
1 /* Write */,
|
||||
1 /* Cacheable */,
|
||||
1 /* ALIAS -- Disable D$ */,
|
||||
1 /* valid */,
|
||||
0 /* IE */);
|
||||
#else
|
||||
data = TSB_DATA(0 /* global */,
|
||||
TLB_8K,
|
||||
pa,
|
||||
1 /* priv */,
|
||||
1 /* Write */,
|
||||
1 /* Cacheable */,
|
||||
0 /* No ALIAS */,
|
||||
1 /* valid */,
|
||||
0 /* IE */);
|
||||
#endif
|
||||
newp = NULL;
|
||||
while (pseg_set(pmap_kernel(), va, data, newp)
|
||||
!= NULL) {
|
||||
pmap_get_page(&newp);
|
||||
pmap_zero_page(newp);
|
||||
#ifdef DEBUG
|
||||
enter_stats.ptpneeded ++;
|
||||
#endif
|
||||
#ifdef BOOT1_DEBUG
|
||||
prom_printf(
|
||||
"pseg_set: pm=%p va=%p data=%lx newp %lx\r\n",
|
||||
pmap_kernel(), va, (long)data, (long)newp);
|
||||
{int i; for (i=0; i<140000000; i++) ;}
|
||||
#endif
|
||||
}
|
||||
va += NBPG;
|
||||
}
|
||||
pmap_initialized = 1;
|
||||
|
||||
/* Setup a pool for additional pvlist structures */
|
||||
pool_init(&pv_pool, sizeof(struct pv_entry), 0, 0, 0, "pv_entry", 0,
|
||||
NULL, NULL, 0);
|
||||
|
||||
vm_first_phys = avail_start;
|
||||
vm_num_phys = avail_end - avail_start;
|
||||
}
|
||||
@ -1066,11 +1206,6 @@ pmap_virtual_space(start, end)
|
||||
/*
|
||||
* Reserve one segment for kernel virtual memory
|
||||
*/
|
||||
vmmap = (caddr_t)(ksegv + 4*MEG); /* Start after our locked TLB entry */
|
||||
#ifdef DIAGNOSTIC
|
||||
/* Let's keep 1 page of redzone after the kernel */
|
||||
vmmap += NBPG;
|
||||
#endif
|
||||
/* Reserve two pages for pmap_copy_page && /dev/mem */
|
||||
*start = (vaddr_t)(vmmap + 2*NBPG);
|
||||
*end = VM_MAX_KERNEL_ADDRESS;
|
||||
@ -1802,8 +1937,7 @@ pmap_enter(pm, va, pa, prot, flags)
|
||||
pm, va);
|
||||
#endif
|
||||
/* can this cause us to recurse forever? */
|
||||
npv = (pv_entry_t)
|
||||
malloc(sizeof *npv, M_VMPVENT, M_WAITOK);
|
||||
npv = pool_get(&pv_pool, PR_WAITOK);
|
||||
PV_SETVA(npv,va);
|
||||
npv->pv_pmap = pm;
|
||||
npv->pv_next = pv->pv_next;
|
||||
@ -2972,7 +3106,7 @@ pmap_page_protect(pg, prot)
|
||||
|
||||
/* free the pv */
|
||||
pv->pv_next = npv->pv_next;
|
||||
free((caddr_t)npv, M_VMPVENT);
|
||||
pool_put(&pv_pool, npv);
|
||||
}
|
||||
|
||||
pv = firstpv;
|
||||
@ -3029,7 +3163,7 @@ pmap_page_protect(pg, prot)
|
||||
/* First save mod/ref bits */
|
||||
npv->pv_va |= (pv->pv_va&PV_MASK);
|
||||
*pv = *npv;
|
||||
free((caddr_t)npv, M_VMPVENT);
|
||||
pool_put(&pv_pool, npv);
|
||||
} else {
|
||||
pv->pv_pmap = NULL;
|
||||
pv->pv_next = NULL;
|
||||
@ -3249,8 +3383,7 @@ pmap_enter_pv(pmap, va, pa)
|
||||
pmap, va);
|
||||
#endif
|
||||
/* can this cause us to recurse forever? */
|
||||
npv = (pv_entry_t)
|
||||
malloc(sizeof *npv, M_VMPVENT, M_NOWAIT);
|
||||
npv = pool_get(&pv_pool, PR_NOWAIT);
|
||||
if (npv == NULL)
|
||||
panic("pmap_enter: new pv malloc() failed");
|
||||
PV_SETVA(npv, va);
|
||||
@ -3311,7 +3444,7 @@ pmap_remove_pv(pmap, va, pa)
|
||||
/* First save mod/ref bits */
|
||||
npv->pv_va |= (pv->pv_va&PV_MASK);
|
||||
*pv = *npv;
|
||||
free((caddr_t)npv, M_VMPVENT);
|
||||
pool_put(&pv_pool, npv);
|
||||
} else {
|
||||
pv->pv_pmap = NULL;
|
||||
pv->pv_next = NULL;
|
||||
@ -3352,7 +3485,7 @@ pmap_remove_pv(pmap, va, pa)
|
||||
* alias that may have occurred. However, that's a complicated
|
||||
* operation involving multiple scans of the pv list.
|
||||
*/
|
||||
free((caddr_t)npv, M_VMPVENT);
|
||||
pool_put(&pv_pool, npv);
|
||||
}
|
||||
|
||||
/* Save ref/mod info */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vaddrs.h,v 1.3 1998/09/05 23:57:29 eeh Exp $ */
|
||||
/* $NetBSD: vaddrs.h,v 1.4 2000/06/12 23:32:48 eeh Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
@ -69,66 +69,18 @@
|
||||
*/
|
||||
|
||||
#ifndef IODEV_0
|
||||
#define IODEV_0 0x0fe000000L /* must match VM_MAX_KERNEL_ADDRESS */
|
||||
#define IODEV_0 0x0fe000000UL /* must match VM_MAX_KERNEL_ADDRESS */
|
||||
|
||||
#define _MAXNBPG 8192 /* fixed VAs, independent of actual NBPG */
|
||||
#define _MAXNCPU 4 /* fixed VA allocation allows 4 CPUs */
|
||||
#define _MAXNCPU 64
|
||||
|
||||
/* [4m:] interrupt and counter registers take (1 + NCPU) pages. */
|
||||
|
||||
#define TIMERREG_VA (IODEV_0)
|
||||
#define COUNTERREG_VA ( TIMERREG_VA + _MAXNBPG*_MAXNCPU) /* [4m] */
|
||||
#define ZS0_VA (COUNTERREG_VA + _MAXNBPG)
|
||||
#define ZS1_VA ( ZS0_VA + _MAXNBPG)
|
||||
#define AUXREG_VA ( ZS1_VA + _MAXNBPG)
|
||||
#define CPUINFO_VA ( INTSTACK)
|
||||
#define AUXREG_VA ( EINTSTACK)
|
||||
#define TMPMAP_VA ( AUXREG_VA + _MAXNBPG)
|
||||
#define MSGBUF_VA ( TMPMAP_VA + _MAXNBPG)
|
||||
#define PI_INTR_VA ( MSGBUF_VA + _MAXNBPG) /* [4m] */
|
||||
#define SI_INTR_VA ( PI_INTR_VA + _MAXNBPG*_MAXNCPU) /* [4m] */
|
||||
#define IODEV_BASE ( SI_INTR_VA + _MAXNBPG)
|
||||
#define IODEV_END 0x0ff000000L /* 16 MB of iospace */
|
||||
|
||||
/*
|
||||
* The next constant defines the amount of reserved DVMA space on the
|
||||
* Sun4m. The amount of space *must* be a multiple of 16MB, and thus
|
||||
* (((u_int)0) - DVMA4M_BASE) must be divisible by 16*1024*1024!
|
||||
* Note that pagetables must be allocated at a cost of 1k per MB of DVMA
|
||||
* space, plus severe alignment restrictions. So don't make DVMA4M_BASE too
|
||||
* low (max space = 2G).
|
||||
*
|
||||
* Since DVMA space overlaps with normal kernel address space (notably
|
||||
* the device mappings and the PROM), we don't want to put any DVMA
|
||||
* mappings where any of this useful stuff is (i.e. if we dvma_malloc
|
||||
* a buffer, we want to still have a SRMMU mapping to it, and we can't
|
||||
* have that if its on top of kernel code). Thus the last two
|
||||
* constants define the actual DVMA addresses used. These can be anything
|
||||
* as long as they are within the bounds setup by the first 2 constants.
|
||||
* This is especially important on MP systems with cache coherency: to
|
||||
* avoid consistency problems, DVMA addresses must map to the same place
|
||||
* in both processor and IOMMU space.
|
||||
*/
|
||||
/*
|
||||
* Actually, I don't know how much of this is really relevant to sun4u
|
||||
* machines. I do know that IOMMU TSBs using 8K pages can map the
|
||||
* following size segments:
|
||||
*
|
||||
* VA size VA base TSB size
|
||||
* -------- -------- ---------
|
||||
* 8MB ff800000 8K
|
||||
* 16MB ff000000 16K
|
||||
* 32MB fe000000 32K
|
||||
* 64MB fc000000 64K
|
||||
* 128MB f8000000 128K
|
||||
* 256MB f0000000 256K
|
||||
* 512MB e0000000 512K
|
||||
* 1GB c0000000 1MB
|
||||
*
|
||||
* We will use the 8MB size for now.
|
||||
*/
|
||||
|
||||
#define DVMA_BASE 0x0ff800000L /* can change subject to above rule */
|
||||
#define DVMA_TOP 0x0ffffffffL /* do not modify */
|
||||
#define DVMA_START 0x0ff800000L /* 8M of DVMA */
|
||||
#define DVMA_END 0x0fff00000L /* XXX is this enough? */
|
||||
#define IODEV_BASE ( MSGBUF_VA + _MAXNBPG)
|
||||
#define IODEV_END 0x0ff000000UL /* 16 MB of iospace */
|
||||
|
||||
#endif /* IODEV_0 */
|
||||
|
Loading…
Reference in New Issue
Block a user