summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/sparc64/include/autoconf.h6
-rw-r--r--sys/arch/sparc64/include/bootinfo.h134
-rw-r--r--sys/arch/sparc64/include/cpu.h30
-rw-r--r--sys/arch/sparc64/include/loadfile_machdep.h73
-rw-r--r--sys/arch/sparc64/include/pmap.h8
-rw-r--r--sys/arch/sparc64/include/vmparam.h10
-rw-r--r--sys/arch/sparc64/sparc64/autoconf.c128
-rw-r--r--sys/arch/sparc64/sparc64/cpu.c65
-rw-r--r--sys/arch/sparc64/sparc64/db_interface.c9
-rw-r--r--sys/arch/sparc64/sparc64/genassym.cf7
-rw-r--r--sys/arch/sparc64/sparc64/locore.s673
-rw-r--r--sys/arch/sparc64/sparc64/machdep.c14
-rw-r--r--sys/arch/sparc64/sparc64/pmap.c705
13 files changed, 768 insertions, 1094 deletions
diff --git a/sys/arch/sparc64/include/autoconf.h b/sys/arch/sparc64/include/autoconf.h
index da30063446d..dbcb1474a0f 100644
--- a/sys/arch/sparc64/include/autoconf.h
+++ b/sys/arch/sparc64/include/autoconf.h
@@ -1,4 +1,4 @@
-/* $NetBSD: autoconf.h,v 1.23 2005/12/11 12:19:10 christos Exp $ */
+/* $NetBSD: autoconf.h,v 1.24 2006/01/27 18:37:49 cdi Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -157,6 +157,8 @@ struct device *parsedisk __P((char *, int, int, dev_t *));
void mountroot_hook_establish __P((void (*) __P((struct device *)),
struct device *));
-void bootstrap __P((int));
+/* Kernel initialization routine. */
+void bootstrap(void *, void *, void *, void *, void *);
+
struct device *getdevunit __P((const char *, int));
int romgetcursoraddr __P((int **, int **));
diff --git a/sys/arch/sparc64/include/bootinfo.h b/sys/arch/sparc64/include/bootinfo.h
index 8147ddf2b11..bc63f4a704a 100644
--- a/sys/arch/sparc64/include/bootinfo.h
+++ b/sys/arch/sparc64/include/bootinfo.h
@@ -1,3 +1,135 @@
-/* $NetBSD: bootinfo.h,v 1.1 2002/07/20 11:52:21 mrg Exp $ */
+/* $NetBSD: bootinfo.h,v 1.2 2006/01/27 18:37:49 cdi Exp $ */
+/*-
+ * Copyright (c) 2005 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _BOOTINFO_H_
+#define _BOOTINFO_H_
+
+#include <machine/param.h>
#include <sparc/bootinfo.h>
+
+/*
+ * The bootloader v1.9 and higher makes a call into a kernel with the following
+ * arguments:
+ *
+ * %o0 OpenFirmware entry point, to keep Sun's updaters happy
+ * %o1 Address of boot information vector (see below)
+ * %o2 Length of the vector, in bytes
+ * %o3 OpenFirmware entry point, to mimic Sun bootloader behavior
+ * %o4 OpenFirmware entry point, to meet earlier NetBSD kernels
+ * expectations
+ *
+ * All parameters are of void* type except for vector length which is of
+ * integer type.
+ *
+ * The boot information vector format was dictated by earlier kernels and
+ * starting from ofwboot v1.9 has four entries:
+ *
+ * +-------------------------------------+
+ * #0 | NetBSD boot magic number ('DDB2') |
+ * +-------------------------------------+
+ * #1 | ksyms' table end address |
+ * +-------------------------------------+
+ * #2 | ksyms' table start address |
+ * +-------------------------------------+
+ * #3 | Pointer to a bootinfo binary object |
+ * +-------------------------------------+
+ *
+ * Kernels written for pre-v1.8 ofwboot require first three cells to present
+ * in this particular order, those that rely on v1.9 and higher won't work if
+ * the last pointer is not in the table; therefore, the vector cannot be
+ * shorter than 4 * sizeof(u_int32_t) or 4 * sizeof(u_int64_t) for 32-bit and
+ * 64-bit boot loader, respectively.
+ *
+ * As of ofwboot v1.9, bootinfo binary object is placed right after the kernel
+ * data segment end, i.e. in the permanently locked 4MB page. There is no order
+ * for the data located in bootinfo binary object. The kernel however expects
+ * at least following parameters to exist in there:
+ *
+ * - Symbol information (size, start, end; see struct btinfo_symtab)
+ * - Kernel end address, calculated as true kernel end address plus size of
+ * space reserved for bootinfo binary object (struct btinfo_kernend)
+ * - Number of text segment pages (struct btinfo_count)
+ * - Number of data segment pages (struct btinfo_count)
+ * - Array of text pages VA/PA (struct btinfo_tlb)
+ * - Array of data pages VA/PA (struct btinfo_tlb)
+ *
+ * The last four data structures fully describe kernel mappings. ofwboot v1.9
+ * and higher map the kernel with 4MB permanent pages and this is the only
+ * way to let kernel know how exactly it was mapped.
+ */
+
+/* Boot magic number */
+#define SPARC_MACHINE_OPENFIRMWARE 0x44444230
+
+#ifdef BOOTINFO_SIZE
+#undef BOOTINFO_SIZE
+#endif
+
+#define BOOTINFO_SIZE NBPG
+
+#define BTINFO_DTLB_SLOTS 100
+#define BTINFO_ITLB_SLOTS 101
+#define BTINFO_DTLB 102
+#define BTINFO_ITLB 103
+#define BTINFO_KERNEND 104
+
+#define LOOKUP_BOOTINFO(btp, info) \
+do { \
+ if ( ((btp) = lookup_bootinfo(info)) == NULL) { \
+ panic("lookup_bootinfo: No " #info " found.\n"); \
+ } \
+} while (0)
+
+struct tlb_entry {
+ uint64_t te_pa;
+ uint64_t te_va;
+};
+
+struct btinfo_count {
+ struct btinfo_common common;
+ int count;
+};
+
+struct btinfo_tlb {
+ struct btinfo_common common;
+ struct tlb_entry tlb[1];
+};
+
+struct btinfo_kernend {
+ struct btinfo_common common;
+ uint64_t addr;
+};
+
+#endif /* _BOOTINFO_H_ */
diff --git a/sys/arch/sparc64/include/cpu.h b/sys/arch/sparc64/include/cpu.h
index 7480a2e53e4..cf20c1ca140 100644
--- a/sys/arch/sparc64/include/cpu.h
+++ b/sys/arch/sparc64/include/cpu.h
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.50 2005/12/24 20:07:37 perry Exp $ */
+/* $NetBSD: cpu.h,v 1.51 2006/01/27 18:37:49 cdi Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -109,11 +109,19 @@ struct cpu_info {
/* Most important fields first */
struct lwp *ci_curlwp;
- struct cpu_data ci_data; /* MI per-cpu data */
struct pcb *ci_cpcb;
struct cpu_info *ci_next;
struct lwp *ci_fplwp;
+
+ void *ci_eintstack;
+ struct pcb *ci_idle_u;
+
+ /* Spinning up the CPU */
+ void (*ci_spinup) __P((void));
+ void *ci_initstack;
+ paddr_t ci_paddr;
+
int ci_number;
int ci_upaid;
int ci_cpuid;
@@ -123,11 +131,6 @@ struct cpu_info {
*/
struct cc_microtime_state ci_cc;
- /* Spinning up the CPU */
- void (*ci_spinup) __P((void));
- void *ci_initstack;
- paddr_t ci_paddr;
-
/* CPU PROM information. */
u_int ci_node;
@@ -135,8 +138,7 @@ struct cpu_info {
int ci_want_ast;
int ci_want_resched;
- void *ci_eintstack;
- struct pcb *ci_idle_u;
+ struct cpu_data ci_data; /* MI per-cpu data */
};
#define CPUF_PRIMARY 1
@@ -191,7 +193,15 @@ extern struct cpu_info *cpus;
void cpu_proc_fork(struct proc *, struct proc *);
#if defined(MULTIPROCESSOR)
-void cpu_mp_startup __P((void));
+extern vaddr_t cpu_spinup_trampoline;
+
+extern char *mp_tramp_code;
+extern u_long mp_tramp_code_len;
+extern u_long mp_tramp_tlb_slots;
+extern u_long mp_tramp_func;
+extern u_long mp_tramp_ci;
+
+void cpu_hatch __P((void));
void cpu_boot_secondary_processors __P((void));
#endif
diff --git a/sys/arch/sparc64/include/loadfile_machdep.h b/sys/arch/sparc64/include/loadfile_machdep.h
index 0b117662c3a..75bd4089f05 100644
--- a/sys/arch/sparc64/include/loadfile_machdep.h
+++ b/sys/arch/sparc64/include/loadfile_machdep.h
@@ -1,3 +1,72 @@
-/* $NetBSD: loadfile_machdep.h,v 1.1 2000/08/16 08:17:50 mrg Exp $ */
+/* $NetBSD: loadfile_machdep.h,v 1.2 2006/01/27 18:37:49 cdi Exp $ */
-#include <sparc/loadfile_machdep.h>
+/*-
+ * Copyright (c) 2005 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOAD_KERNEL LOAD_ALL
+#define COUNT_KERNEL COUNT_ALL
+
+#ifdef _STANDALONE
+#define LOADADDR(a) ((long)(a))
+#define ALIGNENTRY(a) ((u_long)(a))
+#define READ(f, b, c) sparc64_read((f), (void *)LOADADDR(b), (c))
+#define BCOPY(s, d, c) sparc64_memcpy((void *)LOADADDR(d), \
+ (void *)(s), (c))
+#define BZERO(d, c) sparc64_memset((void *)LOADADDR(d), 0, (c))
+#define WARN(a) (void)(printf a, \
+ printf((errno ? ": %s\n" : "\n"), \
+ strerror(errno)))
+#define PROGRESS(a) (void) printf a
+#define ALLOC(a) alloc(a)
+#define DEALLOC(a, b) dealloc(a, b)
+#define OKMAGIC(a) ((a) == OMAGIC)
+
+extern ssize_t sparc64_read(int, void *, size_t);
+extern void* sparc64_memcpy(void *, const void *, size_t);
+extern void* sparc64_memset(void *, int, size_t);
+
+#else
+#define LOADADDR(a) (((u_long)(a)) + (u_long)offset)
+#define ALIGNENTRY(a) ((u_long)(a))
+#define READ(f, b, c) read((f), (void *)LOADADDR(b), (c))
+#define BCOPY(s, d, c) memcpy((void *)LOADADDR(d), (void *)(s), (c))
+#define BZERO(d, c) memset((void *)LOADADDR(d), 0, (c))
+#define WARN(a) warn a
+#define PROGRESS(a) /* nothing */
+#define ALLOC(a) malloc(a)
+#define FREE(a, b) free(a)
+#define OKMAGIC(a) ((a) == OMAGIC)
+#endif
diff --git a/sys/arch/sparc64/include/pmap.h b/sys/arch/sparc64/include/pmap.h
index f19454f9078..dfd7933b92a 100644
--- a/sys/arch/sparc64/include/pmap.h
+++ b/sys/arch/sparc64/include/pmap.h
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.h,v 1.34 2005/12/11 12:19:10 christos Exp $ */
+/* $NetBSD: pmap.h,v 1.35 2006/01/27 18:37:49 cdi Exp $ */
/*-
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -173,7 +173,7 @@ int pmap_count_wired __P((struct pmap *));
void pmap_activate_pmap(struct pmap *);
void pmap_update(struct pmap *);
-void pmap_bootstrap __P((u_long kernelstart, u_long kernelend, u_int numctx));
+void pmap_bootstrap __P((u_long, u_long));
/* make sure all page mappings are modulo 16K to prevent d$ aliasing */
#define PMAP_PREFER(pa, va, sz, td) (*(va)+=(((*(va))^(pa))&(1<<(PGSHIFT))))
@@ -194,6 +194,10 @@ void pmap_kprotect(vaddr_t, vm_prot_t);
int ctx_alloc __P((struct pmap *));
void ctx_free __P((struct pmap *));
+/* Installed physical memory, as discovered during bootstrap. */
+extern int phys_installed_size;
+extern struct mem_region *phys_installed;
+
#endif /* _KERNEL */
#endif /* _LOCORE */
diff --git a/sys/arch/sparc64/include/vmparam.h b/sys/arch/sparc64/include/vmparam.h
index 0d2a704c830..d800806a6bc 100644
--- a/sys/arch/sparc64/include/vmparam.h
+++ b/sys/arch/sparc64/include/vmparam.h
@@ -1,4 +1,4 @@
-/* $NetBSD: vmparam.h,v 1.28 2005/12/11 12:19:10 christos Exp $ */
+/* $NetBSD: vmparam.h,v 1.29 2006/01/27 18:37:49 cdi Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -56,6 +56,14 @@
#define PAGE_MASK (PAGE_SIZE - 1)
/*
+ * The kernel itself is mapped by the boot loader with 4Mb locked VM pages,
+ * so let's keep 4Mb definitions here as well.
+ */
+#define PAGE_SHIFT_4M 22
+#define PAGE_SIZE_4M (1UL<<PAGE_SHIFT_4M)
+#define PAGE_MASK_4M (PAGE_SIZE_4M-1)
+
+/*
* USRSTACK is the top (end) of the user stack.
*/
#define USRSTACK32 0xffffe000L
diff --git a/sys/arch/sparc64/sparc64/autoconf.c b/sys/arch/sparc64/sparc64/autoconf.c
index 8dacc0ef2e9..30034f5b11d 100644
--- a/sys/arch/sparc64/sparc64/autoconf.c
+++ b/sys/arch/sparc64/sparc64/autoconf.c
@@ -1,4 +1,4 @@
-/* $NetBSD: autoconf.c,v 1.106 2005/12/24 20:07:37 perry Exp $ */
+/* $NetBSD: autoconf.c,v 1.107 2006/01/27 18:37:49 cdi Exp $ */
/*
* Copyright (c) 1996
@@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.106 2005/12/24 20:07:37 perry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.107 2006/01/27 18:37:49 cdi Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@@ -81,6 +81,7 @@ __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.106 2005/12/24 20:07:37 perry Exp $")
#include <machine/sparc64.h>
#include <machine/cpu.h>
#include <machine/pmap.h>
+#include <machine/bootinfo.h>
#include <sparc64/sparc64/timerreg.h>
#include <dev/ata/atavar.h>
@@ -119,6 +120,7 @@ struct evcnt intr_evcnts[] = {
};
int printspl = 0;
+void *bootinfo = 0;
#ifdef KGDB
extern int kgdb_debug_panic;
@@ -140,6 +142,12 @@ int nbootpath;
static void bootpath_build __P((void));
static void bootpath_print __P((struct bootpath *));
+/*
+ * Kernel 4MB mappings.
+ */
+struct tlb_entry *kernel_tlbs;
+int kernel_tlb_slots;
+
/* Global interrupt mappings for all device types. Match against the OBP
* 'device_type' property.
*/
@@ -229,40 +237,107 @@ get_ncpus()
}
/*
+ * lookup_bootinfo:
+ * Look up information in bootinfo of boot loader.
+ */
+void *
+lookup_bootinfo(type)
+ int type;
+{
+ struct btinfo_common *bt;
+ char *help = bootinfo;
+
+ /* Check for a bootinfo record first. */
+ if (help == NULL)
+ return (NULL);
+
+ do {
+ bt = (struct btinfo_common *)help;
+ if (bt->type == type)
+ return ((void *)help);
+ help += bt->next;
+ } while (bt->next != 0 &&
+ (size_t)help < (size_t)bootinfo + BOOTINFO_SIZE);
+
+ return (NULL);
+}
+
+/*
* locore.s code calls bootstrap() just before calling main().
*
* What we try to do is as follows:
+ * - Initialize PROM and the console
+ * - Read in part of information provided by a bootloader and find out
+ * kernel load and end addresses
+ * - Initialize ksyms
+ * - Find out number of active CPUs
+ * - Finalize the bootstrap by calling pmap_bootstrap()
*
- * 1) We will try to re-allocate the old message buffer.
- *
- * 2) We will then get the list of the total and available
- * physical memory and available virtual memory from the
- * prom.
- *
- * 3) We will pass the list to pmap_bootstrap to manage them.
- *
- * We will try to run out of the prom until we get to cpu_init().
+ * We will try to run out of the prom until we get out of pmap_bootstrap().
*/
void
-bootstrap(nctx)
- int nctx;
+bootstrap(void *o0, void *bootargs, void *bootsize, void *o3, void *ofw)
{
- extern int end; /* End of kernel */
-#if (NKSYMS || defined(DDB) || defined(LKM))
- extern void *ssym, *esym;
-#endif
-#if !defined(__arch64__) && defined(DDB)
- /* Assembly glue for the PROM */
- extern void OF_sym2val32 __P((void *));
- extern void OF_val2sym32 __P((void *));
-#endif
+ void *bi;
+ long bmagic;
+
+ struct btinfo_symtab *bi_sym;
+ struct btinfo_count *bi_count;
+ struct btinfo_kernend *bi_kend;
+ struct btinfo_tlb *bi_tlb;
+
+ extern void *romtba;
+ extern void* get_romtba(void);
+ extern void OF_val2sym32(void *);
+ extern void OF_sym2val32(void *);
+
+ /* Save OpenFrimware entry point */
+ romp = ofw;
+ romtba = get_romtba();
prom_init();
/* Initialize the PROM console so printf will not panic */
(*cn_tab->cn_init)(cn_tab);
+
+ printf("sparc64_init(%p, %p, %p, %p, %p)\n", o0, bootargs, bootsize,
+ o3, ofw);
+
+ /* Extract bootinfo pointer */
+ if ((long)bootsize >= (4 * sizeof(u_int64_t))) {
+ /* Loaded by 64-bit bootloader */
+ bi = (void*)(u_long)(((u_int64_t*)bootargs)[3]);
+ bmagic = (long)(((u_int64_t*)bootargs)[0]);
+ } else if ((long)bootsize >= (4 * sizeof(u_int32_t))) {
+ /* Loaded by 32-bit bootloader */
+ bi = (void*)(u_long)(((u_int32_t*)bootargs)[3]);
+ bmagic = (long)(((u_int32_t*)bootargs)[0]);
+ } else {
+ printf("Bad bootinfo size.\n"
+ "This kernel requires NetBSD boot loader.\n");
+ panic("sparc64_init.");
+ }
+
+ printf("sparc64_init: bmagic=%lx, bi=%p\n", bmagic, bi);
+
+ /* Read in the information provided by NetBSD boot loader */
+ if (SPARC_MACHINE_OPENFIRMWARE != bmagic) {
+ printf("No bootinfo information.\n"
+ "This kernel requires NetBSD boot loader.\n");
+ panic("sparc64_init.");
+ }
+
+ bootinfo = (void*)(u_long)((u_int64_t*)bi)[1];
+ LOOKUP_BOOTINFO(bi_kend, BTINFO_KERNEND);
+
+ if (bi_kend->addr == (vaddr_t)0) {
+ panic("Kernel end address is not found in bootinfo.\n");
+ }
+
#if NKSYMS || defined(DDB) || defined(LKM)
- ksyms_init((int)((caddr_t)esym - (caddr_t)ssym), ssym, esym);
+ LOOKUP_BOOTINFO(bi_sym, BTINFO_SYMTAB);
+ ksyms_init(bi_sym->nsym, (int *)(u_long)bi_sym->ssym,
+ (int *)(u_long)bi_sym->esym);
#ifdef DDB
#ifdef __arch64__
/* This can only be installed on an 64-bit system cause otherwise our stack is screwed */
@@ -273,8 +348,13 @@ bootstrap(nctx)
#endif
#endif
+ LOOKUP_BOOTINFO(bi_count, BTINFO_DTLB_SLOTS);
+ kernel_tlb_slots = bi_count->count;
+ LOOKUP_BOOTINFO(bi_tlb, BTINFO_DTLB);
+ kernel_tlbs = &bi_tlb->tlb[0];
+
get_ncpus();
- pmap_bootstrap(KERNBASE, (u_long)&end, nctx);
+ pmap_bootstrap(KERNBASE, bi_kend->addr);
}
/*
diff --git a/sys/arch/sparc64/sparc64/cpu.c b/sys/arch/sparc64/sparc64/cpu.c
index a7b61bd4e77..fedc119c889 100644
--- a/sys/arch/sparc64/sparc64/cpu.c
+++ b/sys/arch/sparc64/sparc64/cpu.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.43 2005/12/24 20:07:37 perry Exp $ */
+/* $NetBSD: cpu.c,v 1.44 2006/01/27 18:37:49 cdi Exp $ */
/*
* Copyright (c) 1996
@@ -52,7 +52,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.43 2005/12/24 20:07:37 perry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.44 2006/01/27 18:37:49 cdi Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -82,7 +82,6 @@ volatile cpuset_t cpus_active;/* set of active cpus */
struct cpu_bootargs *cpu_args; /* allocated very early in pmap_bootstrap. */
static struct cpu_info *alloc_cpuinfo(u_int);
-void mp_main(void);
/* The following are used externally (sysctl_hw). */
char machine[] = MACHINE; /* from <machine/param.h> */
@@ -338,55 +337,21 @@ cpu_attach(parent, dev, aux)
}
#if defined(MULTIPROCESSOR)
+vaddr_t cpu_spinup_trampoline;
+
+u_long dump_rtf_info = 0;
+
/*
* Start secondary processors in motion.
*/
-extern vaddr_t ktext;
-extern paddr_t ktextp;
-extern vaddr_t ektext;
-extern vaddr_t kdata;
-extern paddr_t kdatap;
-extern vaddr_t ekdata;
-
-extern void cpu_mp_startup_end(void *);
-
void
cpu_boot_secondary_processors()
{
- int pstate;
+ int i, pstate;
struct cpu_info *ci;
- int i;
- vaddr_t mp_start;
- int mp_start_size;
sparc64_ipi_init();
- cpu_args->cb_ktext = ktext;
- cpu_args->cb_ktextp = ktextp;
- cpu_args->cb_ektext = ektext;
-
- cpu_args->cb_kdata = kdata;
- cpu_args->cb_kdatap = kdatap;
- cpu_args->cb_ekdata = ekdata;
-
- mp_start = ((vaddr_t)cpu_args + sizeof(*cpu_args)+ 0x0f) & ~0x0f;
- mp_start_size = (vaddr_t)cpu_mp_startup_end - (vaddr_t)cpu_mp_startup;
- memcpy((void *)mp_start, cpu_mp_startup, mp_start_size);
-
- mp_start_size = mp_start_size >> 3;
- for (i = 0; i < mp_start_size; i++)
- flush(mp_start + (i << 3));
-
-#ifdef DEBUG
- printf("cpu_args @ %p\n", cpu_args);
- printf("ktext %lx, ktextp %lx, ektext %lx\n",
- cpu_args->cb_ktext, cpu_args->cb_ktextp,cpu_args->cb_ektext);
- printf("kdata %lx, kdatap %lx, ekdata %lx\n",
- cpu_args->cb_kdata, cpu_args->cb_kdatap, cpu_args->cb_ekdata);
- printf("mp_start %lx, mp_start_size 0x%x\n",
- mp_start, mp_start_size);
-#endif
-
printf("cpu0: booting secondary processors:\n");
for (ci = cpus; ci != NULL; ci = ci->ci_next) {
@@ -408,7 +373,8 @@ cpu_boot_secondary_processors()
pstate = getpstate();
setpstate(PSTATE_KERN);
- prom_startcpu(ci->ci_node, (void *)mp_start, 0);
+ printf("mp_tramp: %p\n", (void*)cpu_spinup_trampoline);
+ prom_startcpu(ci->ci_node, (void *)cpu_spinup_trampoline, 0);
for (i = 0; i < 2000; i++) {
membar_sync();
@@ -429,10 +395,21 @@ cpu_boot_secondary_processors()
}
void
-mp_main()
+cpu_hatch()
{
+ int i;
+ char *v = (char*)CPUINFO_VA;
+
+ for (i = 0; i < 4*PAGE_SIZE; i += sizeof(long))
+ flush(v + i);
+ dump_rtf_info = 1;
+
+ printf("cpu%d fired up.\n", cpu_number());
CPUSET_ADD(cpus_active, cpu_number());
+ for (i = 0; i < 5000000; i++)
+ ;
+ printf("cpu%d enters idle loop.\n", cpu_number());
membar_sync();
spl0();
}
diff --git a/sys/arch/sparc64/sparc64/db_interface.c b/sys/arch/sparc64/sparc64/db_interface.c
index 699c23d9756..cd0478a5b44 100644
--- a/sys/arch/sparc64/sparc64/db_interface.c
+++ b/sys/arch/sparc64/sparc64/db_interface.c
@@ -1,4 +1,4 @@
-/* $NetBSD: db_interface.c,v 1.83 2005/12/24 22:45:39 perry Exp $ */
+/* $NetBSD: db_interface.c,v 1.84 2006/01/27 18:37:49 cdi Exp $ */
/*
* Copyright (c) 1996-2002 Eduardo Horvath. All rights reserved.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.83 2005/12/24 22:45:39 perry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.84 2006/01/27 18:37:49 cdi Exp $");
#include "opt_ddb.h"
@@ -414,8 +414,7 @@ db_write_bytes(addr, size, data)
register const char *data;
{
register char *dst;
- extern vaddr_t ktext;
- extern paddr_t ktextp;
+ extern paddr_t pmap_kextract(vaddr_t va);
dst = (char *)addr;
while (size-- > 0) {
@@ -424,7 +423,7 @@ db_write_bytes(addr, size, data)
else if ((dst >= (char *)VM_MIN_KERNEL_ADDRESS) &&
(dst < (char *)VM_MIN_KERNEL_ADDRESS+0x400000))
/* Read Only mapping -- need to do a bypass access */
- stba((u_long)dst - ktext + ktextp, ASI_PHYS_CACHED, *data);
+ stba(pmap_kextract((vaddr_t)dst), ASI_PHYS_CACHED, *data);
else
subyte(dst, *data);
dst++, data++;
diff --git a/sys/arch/sparc64/sparc64/genassym.cf b/sys/arch/sparc64/sparc64/genassym.cf
index a826308e974..4bc3ea6ab89 100644
--- a/sys/arch/sparc64/sparc64/genassym.cf
+++ b/sys/arch/sparc64/sparc64/genassym.cf
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.39 2005/12/11 12:19:14 christos Exp $
+# $NetBSD: genassym.cf,v 1.40 2006/01/27 18:37:49 cdi Exp $
#
# Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -301,3 +301,8 @@ endif
# TLB IPI handler arguments.
define ITA_VADDR offsetof(struct ipi_tlb_args, ita_vaddr)
define ITA_CTX offsetof(struct ipi_tlb_args, ita_ctx)
+
+# pte_t structure.
+define TTE_VPN offsetof(pte_t, tag)
+define TTE_DATA offsetof(pte_t, data)
+define PTE_SIZE sizeof(pte_t)
diff --git a/sys/arch/sparc64/sparc64/locore.s b/sys/arch/sparc64/sparc64/locore.s
index 247dfc478c2..6c5fa4303a9 100644
--- a/sys/arch/sparc64/sparc64/locore.s
+++ b/sys/arch/sparc64/sparc64/locore.s
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.s,v 1.208 2006/01/12 17:58:39 cdi Exp $ */
+/* $NetBSD: locore.s,v 1.209 2006/01/27 18:37:49 cdi Exp $ */
/*
* Copyright (c) 1996-2002 Eduardo Horvath
@@ -742,8 +742,8 @@ label: \
TA32
.globl start, _C_LABEL(kernel_text)
- _C_LABEL(kernel_text) = start ! for kvm_mkdb(8)
-start:
+ _C_LABEL(kernel_text) = kernel_start ! for kvm_mkdb(8)
+kernel_start:
/* Traps from TL=0 -- traps from user mode */
#ifdef __STDC__
#define TABLE(name) user_ ## name
@@ -4217,6 +4217,63 @@ ENTRY(sparc64_ipi_flush_all)
ba,a ret_from_intr_vector
nop
+
+/*
+ * Secondary CPU bootstrap code.
+ */
+ .text
+ .align 32
+1: rd %pc, %l0
+ ldx [%l0 + (4f-1b)], %l1
+ add %l0, (6f-1b), %l2
+ clr %l3
+2: cmp %l3, %l1
+ be %xcc, 3f
+ nop
+ ldx [%l2 + TTE_VPN], %l4
+ ldx [%l2 + TTE_DATA], %l5
+ wr %g0, ASI_DMMU, %asi
+ stxa %l4, [%g0 + TLB_TAG_ACCESS] %asi
+ stxa %l5, [%g0] ASI_DMMU_DATA_IN
+ wr %g0, ASI_IMMU, %asi
+ stxa %l4, [%g0 + TLB_TAG_ACCESS] %asi
+ stxa %l5, [%g0] ASI_IMMU_DATA_IN
+ membar #Sync
+ flush %l4
+ add %l2, PTE_SIZE, %l2
+ add %l3, 1, %l3
+ ba %xcc, 2b
+ nop
+3: ldx [%l0 + (5f-1b)], %l1
+ ldx [%l0 + (7f-1b)], %g2 ! Load cpu_info address.
+ jmpl %l1, %g0
+ nop
+
+ .align 8
+4: .xword 0x0
+5: .xword 0x0
+7: .xword 0x0
+6:
+
+#define DATA(name) \
+ .data ; \
+ .align 8 ; \
+ .globl name ; \
+name:
+
+DATA(mp_tramp_code)
+ .xword 1b
+DATA(mp_tramp_code_len)
+ .xword 6b-1b
+DATA(mp_tramp_tlb_slots)
+ .xword 4b-1b
+DATA(mp_tramp_func)
+ .xword 5b-1b
+DATA(mp_tramp_ci)
+ .xword 7b-1b
+
+ .text
+ .align 32
#endif /* MULTIPROCESSOR */
/*
@@ -5240,7 +5297,19 @@ ENTRY_NOPROFILE(print_itlb)
#endif
#endif
+/*
+ * Kernel entry point.
+ *
+ * The contract between bootloader and kernel is:
+ *
+ * %o0 OpenFirmware entry point, to keep Sun's updaters happy
+ * %o1 Address of boot information vector (see bootinfo.h)
+ * %o2 Length of the vector, in bytes
+ * %o3 OpenFirmware entry point, to mimic Sun bootloader behavior
+ * %o4 OpenFirmware, to meet earlier NetBSD kernels expectations
+ */
.align 8
+start:
dostart:
wrpr %g0, 0, %tick ! XXXXXXX clear %tick register for now
mov 1, %g1
@@ -5276,79 +5345,6 @@ dostart:
wrpr %g0, 13, %pil
wrpr %g0, PSTATE_INTR|PSTATE_PEF, %pstate
wr %g0, FPRS_FEF, %fprs ! Turn on FPU
-#if NKSYMS || defined(DDB) || defined(LKM)
- /*
- * First, check for DDB arguments. A pointer to an argument
- * is passed in %o1 who's length is passed in %o2. Our
- * bootloader passes in a magic number as the first argument,
- * followed by esym as argument 2, so check that %o2 == 8,
- * then extract esym and check the magic number.
- *
- * Oh, yeah, start of elf symtab is arg 3.
- */
- cmp %o2, 8
- blt 1f ! Not enuff args
-
- /*
- * First we'll see if we were loaded by a 64-bit bootloader
- */
- btst 0x7, %o1 ! Check alignment
- bne 0f
- set 0x44444230, %l3
-
- ldx [%o1], %l4
- cmp %l3, %l4 ! chk magic
- bne %xcc, 0f
- nop
-
- ldx [%o1+8], %l4
- sethi %hi(_C_LABEL(esym)), %l3 ! store _esym
- STPTR %l4, [%l3 + %lo(_C_LABEL(esym))]
-
- cmp %o2, 12
- blt 1f
- nop
-
- ldx [%o1+16], %l4
- sethi %hi(_C_LABEL(ssym)), %l3 ! store _esym
- ba 1f
- STPTR %l4, [%l3 + %lo(_C_LABEL(ssym))]
-0:
- /*
- * Now we can try again with for a 32-bit bootloader
- */
- cmp %o2, 8
- blt 1f ! Not enuff args
-
- set 0x44444230, %l3
- ld [%o1], %l4
- cmp %l3, %l4 ! chk magic
- bne 1f
- nop
-
- ld [%o1+4], %l4
- sethi %hi(_C_LABEL(esym)), %l3 ! store _esym
- STPTR %l4, [%l3 + %lo(_C_LABEL(esym))]
-
- cmp %o2, 12
- blt 1f
- nop
-
- ld [%o1+8], %l4
- sethi %hi(_C_LABEL(ssym)), %l3 ! store _esym
- STPTR %l4, [%l3 + %lo(_C_LABEL(ssym))]
-1:
-#endif
- /*
- * Step 1: Save rom entry pointer and prom tba
- */
-
- set romp, %o5
- STPTR %o4, [%o5] ! It's initialized data, I hope
-
- rdpr %tba, %o4
- set romtba, %o5
- STPTR %o4, [%o5]
/*
* Step 2: Set up a v8-like stack if we need to
@@ -5366,30 +5362,10 @@ dostart:
add %sp, BIAS, %sp
#endif
0:
- /*
- * Step 3: clear BSS. This may just be paranoia; the boot
- * loader might already do it for us; but what the hell.
- */
- set _C_LABEL(edata), %o0 ! memset(edata, 0, end - edata)
- set _C_LABEL(end), %o2
- clr %o1
- call _C_LABEL(memset)
- sub %o2, %o0, %o2
- /*
- * Ready to run C code; finish bootstrap.
- */
- set CTX_SECONDARY, %o1 ! Store -1 in the context register
- mov -1, %o2
- stxa %o2, [%o1] ASI_DMMU
- membar #Sync
- ldxa [%o1] ASI_DMMU, %o0 ! then read it back
- membar #Sync
- stxa %g0, [%o1] ASI_DMMU
- membar #Sync
- clr %g4 ! Clear data segment pointer
+
call _C_LABEL(bootstrap)
- inc %o0 ! and add 1 to discover maxctx
+ clr %g4 ! Clear data segment pointer
/*
* pmap_bootstrap should have allocated a stack for proc 0 and
@@ -5426,325 +5402,6 @@ _C_LABEL(cpu_initialize):
* %l7 = 4MB-1
* %o0-%o5 = tmp
*/
-
-#ifdef NO_VCACHE
- !! Turn off D$ in LSU
- ldxa [%g0] ASI_LSU_CONTROL_REGISTER, %g1
- bclr MCCR_DCACHE_EN, %g1
- stxa %g1, [%g0] ASI_LSU_CONTROL_REGISTER
- membar #Sync
-#endif
-
- wrpr %g0, 0, %tl ! Make sure we're not in NUCLEUS mode
- sethi %hi(KERNBASE), %l0 ! Find our xlation
- sethi %hi(DATA_START), %l3
-
- set _C_LABEL(ktextp), %l2 ! Find phys addr
- ldx [%l2], %l2 ! The following gets ugly: We need to load the following mask
- set _C_LABEL(kdatap), %l5
- ldx [%l5], %l5
-
- set _C_LABEL(ektext), %l1 ! And the ends...
- LDPTR [%l1], %l1
- set _C_LABEL(ekdata), %l4
- LDPTR [%l4], %l4
-
- sethi %hi(0xe0000000), %o0 ! V=1|SZ=11|NFO=0|IE=0
- sllx %o0, 32, %o0 ! Shift it into place
-
- sethi %hi(0x400000), %l6 ! Create a 4MB mask
- add %l6, -1, %l7
-
- mov -1, %o1 ! Create a nice mask
- sllx %o1, 41, %o1 ! Mask off high bits
- or %o1, 0xfff, %o1 ! We can just load this in 12 (of 13) bits
-
- andn %l2, %o1, %l2 ! Mask the phys page number
- andn %l5, %o1, %l5 ! Mask the phys page number
-
- or %l2, %o0, %l2 ! Now take care of the high bits
- or %l5, %o0, %l5 ! Now take care of the high bits
-
- wrpr %g0, PSTATE_KERN, %pstate ! Disable interrupts
-
-#ifdef DEBUG
- set _C_LABEL(pmapdebug), %o1
- ld [%o1], %o1
- sethi %hi(0x40000), %o2
- btst %o2, %o1
- bz 0f
-
- set 1f, %o0 ! Debug printf for TEXT page
- srlx %l0, 32, %o1
- srl %l0, 0, %o2
- or %l2, TTE_L|TTE_CP|TTE_CV|TTE_P, %o4 ! And low bits: L=1|CP=1|CV=1|E=0|P=1|W=1(ugh)|G=0
- srlx %o4, 32, %o3
- call _C_LABEL(prom_printf)
- srl %o4, 0, %o4
-
- set 1f, %o0 ! Debug printf for DATA page
- srlx %l3, 32, %o1
- srl %l3, 0, %o2
- or %l5, TTE_L|TTE_CP|TTE_CV|TTE_P|TTE_W, %o4 ! And low bits: L=1|CP=1|CV=1|E=0|P=1|W=1(ugh)|G=0
- srlx %o4, 32, %o3
- call _C_LABEL(prom_printf)
- srl %o4, 0, %o4
- .data
-1:
- .asciz "Setting DTLB entry %08x %08x data %08x %08x\r\n"
- _ALIGN
- .text
-0:
-#endif
- mov %l0, %o0 ! Demap all of kernel dmmu text segment
- mov %l3, %o1
- set 0x2000, %o2 ! 8K page size
- add %l1, %l7, %o5 ! Extend to 4MB boundary
- andn %o5, %l7, %o5
-0:
- stxa %o0, [%o0] ASI_DMMU_DEMAP ! Demap text segment
- membar #Sync
- cmp %o0, %o5
- bleu 0b
- add %o0, %o2, %o0
-
- add %l4, %l7, %o5 ! Extend to 4MB boundary
- andn %o5, %l7, %o5
-0:
- stxa %o1, [%o1] ASI_DMMU_DEMAP ! Demap data segment
- membar #Sync
- cmp %o1, %o5
- bleu 0b
- add %o1, %o2, %o1
-
- set (1<<14)-8, %o0 ! Clear out DCACHE
-1:
- stxa %g0, [%o0] ASI_DCACHE_TAG ! clear DCACHE line
- membar #Sync
- brnz,pt %o0, 1b
- dec 8, %o0
-
- /*
- * First map data segment into the DMMU.
- */
- set TLB_TAG_ACCESS, %o0 ! Now map it back in with a locked TTE
- mov %l3, %o1
-#ifdef NO_VCACHE
- ! And low bits: L=1|CP=1|CV=0(ugh)|E=0|P=1|W=1|G=0
- or %l5, TTE_L|TTE_CP|TTE_P|TTE_W, %o2
-#else
- ! And low bits: L=1|CP=1|CV=1|E=0|P=1|W=1|G=0
- or %l5, TTE_L|TTE_CP|TTE_CV|TTE_P|TTE_W, %o2
-#endif
- set 1f, %o5
-2:
- stxa %o1, [%o0] ASI_DMMU ! Set VA for DSEG
- membar #Sync ! We may need more membar #Sync in here
- stxa %o2, [%g0] ASI_DMMU_DATA_IN ! Store TTE for DSEG
- membar #Sync ! We may need more membar #Sync in here
- flush %o5 ! Make IMMU see this too
-1:
- add %o1, %l6, %o1 ! increment VA
- cmp %o1, %l4 ! Next 4MB mapping....
- blu,pt %xcc, 2b
- add %o2, %l6, %o2 ! Increment tag
-
- /*
- * Next map the text segment into the DMMU so we can get at RODATA.
- */
- mov %l0, %o1
-#ifdef NO_VCACHE
- ! And low bits: L=1|CP=1|CV=0(ugh)|E=0|P=1|W=0|G=0
- or %l2, TTE_L|TTE_CP|TTE_P, %o2
-#else
- ! And low bits: L=1|CP=1|CV=1|E=0|P=1|W=0|G=0
- or %l2, TTE_L|TTE_CP|TTE_CV|TTE_P, %o2
-#endif
-2:
- stxa %o1, [%o0] ASI_DMMU ! Set VA for DSEG
- membar #Sync ! We may need more membar #Sync in here
- stxa %o2, [%g0] ASI_DMMU_DATA_IN ! Store TTE for DSEG
- membar #Sync ! We may need more membar #Sync in here
- flush %o5 ! Make IMMU see this too
- add %o1, %l6, %o1 ! increment VA
- cmp %o1, %l1 ! Next 4MB mapping....
- blu,pt %xcc, 2b
- add %o2, %l6, %o2 ! Increment tag
-
-#ifdef DEBUG
- set _C_LABEL(pmapdebug), %o1
- ld [%o1], %o1
- sethi %hi(0x40000), %o2
- btst %o2, %o1
- bz 0f
-
- set 1f, %o0 ! Debug printf
- srlx %l0, 32, %o1
- srl %l0, 0, %o2
- or %l2, TTE_L|TTE_CP|TTE_CV|TTE_P, %o4
- srlx %o4, 32, %o3
- call _C_LABEL(prom_printf)
- srl %o4, 0, %o4
- .data
-1:
- .asciz "Setting ITLB entry %08x %08x data %08x %08x\r\n"
- _ALIGN
- .text
-0:
-#endif
- /*
- * Finished the DMMU, now we need to do the IMMU which is more
- * difficult because we're execting instructions through the IMMU
- * while we're flushing it. We need to remap the entire kernel
- * to a new context, flush the entire context 0 IMMU, map it back
- * into context 0, switch to context 0, and flush context 1.
- *
- * Another interesting issue is that the flush instructions are
- * translated through the DMMU, therefore we need to enter the
- * mappings both in the IMMU and the DMMU so we can flush them
- * correctly.
- *
- * Start by mapping in the kernel text as context==1
- */
- set TLB_TAG_ACCESS, %o0
- or %l0, 1, %o1 ! Context = 1
- or %l2, TTE_CP|TTE_P, %o2 ! And low bits: L=0|CP=1|CV=0|E=0|P=1|G=0
- set 1f, %o5
-2:
- stxa %o1, [%o0] ASI_DMMU ! Make DMMU point to it
- membar #Sync ! We may need more membar #Sync in here
- stxa %o2, [%g0] ASI_DMMU_DATA_IN ! Store it
- membar #Sync ! We may need more membar #Sync in here
- stxa %o1, [%o0] ASI_IMMU ! Make IMMU point to it
- membar #Sync ! We may need more membar #Sync in here
- flush %o1-1 ! Make IMMU see this too
- stxa %o2, [%g0] ASI_IMMU_DATA_IN ! Store it
- membar #Sync ! We may need more membar #Sync in here
- flush %o5 ! Make IMMU see this too
-1:
- add %o1, %l6, %o1 ! increment VA
- cmp %o1, %l1 ! Next 4MB mapping....
- blu,pt %xcc, 2b
- add %o2, %l6, %o2 ! Increment tag
-
- !!
- !! Load 1 as primary context
- !!
- mov 1, %o0
- mov CTX_PRIMARY, %o1
- stxa %o0, [%o1] ASI_DMMU
- wrpr %g0, 0, %tl ! Make SURE we're nucleus mode
- membar #Sync ! This probably should be a flush, but it works
- flush %o5 ! This should be KERNBASE
-
- !!
- !! Demap entire context 0 kernel
- !!
- or %l0, DEMAP_PAGE_NUCLEUS, %o0 ! Context = Nucleus
- add %l1, %l7, %o1 ! Demap all of kernel text seg
- andn %o1, %l7, %o1 ! rounded up to 4MB.
- set 0x2000, %o2 ! 8K page size
-0:
- stxa %o0, [%o0] ASI_IMMU_DEMAP ! Demap it
- membar #Sync
- flush %o5 ! Assume low bits are benign
- cmp %o0, %o1
- bleu,pt %xcc, 0b ! Next page
- add %o0, %o2, %o0
-
- or %l3, DEMAP_PAGE_NUCLEUS, %o0 ! Context = Nucleus
- add %l4, %l7, %o1 ! Demap all of kernel data seg
- andn %o1, %l7, %o1 ! rounded up to 4MB.
-0:
- stxa %o0, [%o0] ASI_IMMU_DEMAP ! Demap it
- membar #Sync
- flush %o5 ! Assume low bits are benign
- cmp %o0, %o1
- bleu,pt %xcc, 0b ! Next page
- add %o0, %o2, %o0
-
- !!
- !! Now, map in the kernel text as context==0
- !!
- set TLB_TAG_ACCESS, %o0
- mov %l0, %o1 ! Context = 0
-#ifdef NO_VCACHE
- ! And low bits: L=1|CP=1|CV=0(ugh)|E=0|P=1|W=1|G=0
- or %l2, TTE_L|TTE_CP|TTE_P, %o2
-#else
- ! And low bits: L=1|CP=1|CV=1|E=0|P=1|W=1|G=0
- or %l2, TTE_L|TTE_CP|TTE_CV|TTE_P, %o2
-#endif
-2:
- stxa %o1, [%o0] ASI_IMMU ! Make IMMU point to it
- membar #Sync ! We may need more membar #Sync in here
- stxa %o2, [%g0] ASI_IMMU_DATA_IN ! Store it
- membar #Sync ! We may need more membar #Sync in here
- flush %o5 ! Make IMMU see this too
- add %o1, %l6, %o1 ! increment VA
- cmp %o1, %l1 ! Next 4MB mapping....
- blu,pt %xcc, 2b
- add %o2, %l6, %o2 ! Increment tag
-
- !!
- !! Restore 0 as primary context
- !!
- mov CTX_PRIMARY, %o0
- stxa %g0, [%o0] ASI_DMMU
- flush %o5
-
- !!
- !! Demap context 1
- !!
-#ifdef SPITFIRE
- mov 1, %o1
- mov CTX_SECONDARY, %o0
- stxa %o1, [%o0] ASI_DMMU
- membar #Sync ! This probably should be a flush, but it works
- flush %l0
- mov DEMAP_CTX_SECONDARY, %o4
- stxa %o4, [%o4] ASI_DMMU_DEMAP
- membar #Sync
- stxa %o4, [%o4] ASI_IMMU_DEMAP
- membar #Sync
- flush %l0
- stxa %g0, [%o0] ASI_DMMU
- membar #Sync
- flush %l0
-#else
- mov 1, %o1
- wrpr %g0, 1, %tl ! Enter nucleus context
- mov CTX_PRIMARY, %o0
- stxa %o1, [%o0] ASI_DMMU
- membar #Sync ! This probably should be a flush, but it works
- flush %l0
- mov DEMAP_CTX_PRIMARY, %o4
- stxa %o4, [%o4] ASI_DMMU_DEMAP
- membar #Sync
- stxa %o4, [%o4] ASI_IMMU_DEMAP
- membar #Sync
- flush %l0
- stxa %g0, [%o0] ASI_DMMU
- membar #Sync
- flush %l0
- wrpr %g0, 0, %tl ! Exit nucleus context
-#endif
-#ifdef DEBUG
- set _C_LABEL(pmapdebug), %o1
- ld [%o1], %o1
- sethi %hi(0x40000), %o2
- btst %o2, %o1
- bz 0f
-
- set 1f, %o0 ! Debug printf
- call _C_LABEL(prom_printf)
- .data
-1:
- .asciz "Setting CPUINFO mappings...\r\n"
- _ALIGN
- .text
-0:
-#endif
/*
* Step 6: hunt through cpus list and find the one that
@@ -5926,139 +5583,6 @@ ENTRY(cpu_mp_startup)
flushw
/*
- * This code copied to preallocated 'claimed' memory 2-page block.
- * cpu_args are at the beginning of that block
- */
- rd %pc, %g2 ! cpu_args are at the beginning of this page
- andn %g2, 0xfff, %g2 ! they should be smaller the half page
-
- /* map kernel text, data and cpuinfo_va, all locked*/
- sethi %hi(KERNBASE), %l0 ! Find our xlation
- sethi %hi(DATA_START), %l3
-
- ldx [%g2 + CBA_KTEXTP], %l2
- ldx [%g2 + CBA_KDATAP], %l5
-
- LDPTR [%g2 + CBA_EKTEXT], %l1
- LDPTR [%g2 + CBA_EKDATA], %l4
-
- sethi %hi(0xe0000000), %o0 ! V=1|SZ=11|NFO=0|IE=0
- sllx %o0, 32, %o0 ! Shift it into place
-
- sethi %hi(0x400000), %l6 ! Create a 4MB mask
- add %l6, -1, %l7
-
- mov -1, %o1 ! Create a nice mask
- sllx %o1, 41, %o1 ! Mask off high bits
- or %o1, 0xfff, %o1 ! We can just load this in 12 (of 13) bits
-
- andn %l2, %o1, %l2 ! Mask the phys page number
- andn %l5, %o1, %l5 ! Mask the phys page number
-
- or %l2, %o0, %l2 ! Now take care of the high bits
- or %l5, %o0, %l5 ! Now take care of the high bits
-
- /*
- * XXX Demap kernel text/data from DTLB, probably not needed
- */
- mov %l0, %o0 ! Demap all of kernel dmmu text segment
- mov %l3, %o1
- set 0x2000, %o2 ! 8K page size
- add %l1, %l7, %o5 ! Extend to 4MB boundary
- andn %o5, %l7, %o5
-0:
- stxa %o0, [%o0] ASI_DMMU_DEMAP ! Demap text segment
- membar #Sync
- cmp %o0, %o5
- bleu 0b
- add %o0, %o2, %o0
-
- add %l4, %l7, %o5 ! Extend to 4MB boundary
- andn %o5, %l7, %o5
-0:
- stxa %o1, [%o1] ASI_DMMU_DEMAP ! Demap data segment
- membar #Sync
- cmp %o1, %o5
- bleu 0b
- add %o1, %o2, %o1
-
- set (1<<14)-8, %o0 ! Clear out DCACHE
-1:
- stxa %g0, [%o0] ASI_DCACHE_TAG ! clear DCACHE line
- membar #Sync
- brnz,pt %o0, 1b
- dec 8, %o0
-
- /*
- * Now map kernel text/data, first map data segment into the DMMU.
- */
- set TLB_TAG_ACCESS, %o0 ! Now map it back in with a locked TTE
- mov %l3, %o1
-#ifdef NO_VCACHE
- ! And low bits: L=1|CP=1|CV=0(ugh)|E=0|P=1|W=1|G=0
- or %l5, TTE_L|TTE_CP|TTE_P|TTE_W, %o2
-#else
- ! And low bits: L=1|CP=1|CV=1|E=0|P=1|W=1|G=0
- or %l5, TTE_L|TTE_CP|TTE_CV|TTE_P|TTE_W, %o2
-#endif
- set 1f, %o5
-2:
- stxa %o1, [%o0] ASI_DMMU ! Set VA for DSEG
- membar #Sync ! We may need more membar #Sync in here
- stxa %o2, [%g0] ASI_DMMU_DATA_IN ! Store TTE for DSEG
- membar #Sync ! We may need more membar #Sync in here
-1:
- add %o1, %l6, %o1 ! increment VA
- cmp %o1, %l4 ! Next 4MB mapping....
- blu,pt %xcc, 2b
- add %o2, %l6, %o2 ! Increment tag
-
- /*
- * Next map the text segment into the DMMU so we can get at RODATA.
- */
- mov %l0, %o1
-#ifdef NO_VCACHE
- ! And low bits: L=1|CP=1|CV=0(ugh)|E=0|P=1|W=0|G=0
- or %l2, TTE_L|TTE_CP|TTE_P, %o2
-#else
- ! And low bits: L=1|CP=1|CV=1|E=0|P=1|W=0|G=0
- or %l2, TTE_L|TTE_CP|TTE_CV|TTE_P, %o2
-#endif
-2:
- stxa %o1, [%o0] ASI_DMMU ! Set VA for DSEG
- membar #Sync ! We may need more membar #Sync in here
- stxa %o2, [%g0] ASI_DMMU_DATA_IN ! Store TTE for DSEG
- membar #Sync ! We may need more membar #Sync in here
- flush %o5 ! Make IMMU see this too
- add %o1, %l6, %o1 ! increment VA
- cmp %o1, %l1 ! Next 4MB mapping....
- blu,pt %xcc, 2b
- add %o2, %l6, %o2 ! Increment tag
-
- !!
- !! Now, map in the kernel text as context==0
- !!
- set TLB_TAG_ACCESS, %o0
- mov %l0, %o1 ! Context = 0
-#ifdef NO_VCACHE
- ! And low bits: L=1|CP=1|CV=0(ugh)|E=0|P=1|W=1|G=0
- or %l2, TTE_L|TTE_CP|TTE_P, %o2
-#else
- ! And low bits: L=1|CP=1|CV=1|E=0|P=1|W=1|G=0
- or %l2, TTE_L|TTE_CP|TTE_CV|TTE_P, %o2
-#endif
-2:
- stxa %o1, [%o0] ASI_IMMU ! Make IMMU point to it
- membar #Sync ! We may need more membar #Sync in here
- stxa %o2, [%g0] ASI_IMMU_DATA_IN ! Store it
- membar #Sync ! We may need more membar #Sync in here
- flush %o5 ! Make IMMU see this too
- add %o1, %l6, %o1 ! increment VA
- cmp %o1, %l1 ! Next 4MB mapping....
- blu,pt %xcc, 2b
- add %o2, %l6, %o2 ! Increment tag
-
- /*
* Get pointer to our cpu_info struct
*/
ldx [%g2 + CBA_CPUINFO], %l1 ! Load the interrupt stack's PA
@@ -6088,6 +5612,16 @@ ENTRY(cpu_mp_startup)
flush %o5
flush %l0
1:
+ !!
+ !! Map in cpu_info structure at CPUINFO_VA.
+ !!
+ set CPUINFO_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
+ flush %l0
!!
!! Set 0 as primary context XXX
@@ -6136,9 +5670,13 @@ ENTRY(cpu_mp_startup)
jmpl %l0, %o7
mov %l1, %o0
wrpr %l1, 0, %tba ! Make sure the PROM didn't foul up.
+
+ /*
+ * Switch to the kernel mode and run away.
+ */
wrpr %g0, WSTATE_KERN, %wstate
- set _C_LABEL(mp_main), %l1
+ set _C_LABEL(cpu_hatch), %l1
jmpl %l1, %o7
clr %g4
@@ -6146,12 +5684,14 @@ ENTRY(cpu_mp_startup)
set _C_LABEL(sched_lock_idle), %l1 ! Acquire sched_lock
jmpl %l1, %o7
nop
+
sethi %hi(_C_LABEL(sched_whichqs)), %l2
sethi %hi(CURLWP), %l7
set _C_LABEL(idle), %l1
jmpl %l1, %g0
- nop
+ clr %l4
+/* nop*/
NOTREACHED
@@ -6159,6 +5699,29 @@ ENTRY(cpu_mp_startup)
cpu_mp_startup_end:
#endif
+ .align 8
+ENTRY(get_romtba)
+ retl
+ rdpr %tba, %o0
+/*
+ * int get_maxctx(void)
+ *
+ * Get number of available contexts.
+ *
+ */
+ .align 8
+ENTRY(get_maxctx)
+ set CTX_SECONDARY, %o1 ! Store -1 in the context register
+ mov -1, %o2
+ stxa %o2, [%o1] ASI_DMMU
+ membar #Sync
+ ldxa [%o1] ASI_DMMU, %o0 ! then read it back
+ membar #Sync
+ stxa %g0, [%o1] ASI_DMMU
+ membar #Sync
+ retl
+ inc %o0
+
/*
* openfirmware(cell* param);
*
@@ -7884,6 +7447,8 @@ Lsw_scan:
cmp %l3, %o5 ! if (p == q)
be,pn %icc, Lsw_panic_rq ! panic("switch rq");
EMPTY
+
+Lcpu_ok:
LDPTR [%l3], %o0 ! tmp0 = p->p_forw;
STPTR %o0, [%o5] ! q->ph_link = tmp0;
STPTR %o5, [%o0 + PTRSZ] ! tmp0->p_back = q;
@@ -7950,8 +7515,10 @@ cpu_loadproc:
STPTR %l4, [%l7 + %lo(CURLWP)] ! restore old proc so we can save it
cmp %l3, %l4 ! new lwp == curlwp?
+#if !defined(MULTIPROCESSOR)
be,a,pt %xcc, Lsw_sameproc ! yes, go return 0
clr %i0
+#endif
mov 1, %i0
/*
@@ -8010,6 +7577,7 @@ Lsw_load:
_ALIGN
.text
#endif
+
/* set new cpcb */
STPTR %l3, [%l7 + %lo(CURLWP)] ! curlwp = p;
STPTR %l1, [%l6 + %lo(CPCB)] ! cpcb = newpcb;
@@ -8235,6 +7803,7 @@ swtchdelay:
Debugger();
2:
#endif
+
! wrpr %g0, 0, %cleanwin ! DEBUG
clr %g4 ! This needs to point to the base of the data segment
wr %g0, ASI_PRIMARY_NOFAULT, %asi ! Restore default ASI
diff --git a/sys/arch/sparc64/sparc64/machdep.c b/sys/arch/sparc64/sparc64/machdep.c
index bd24c5995eb..43d43f9e9c1 100644
--- a/sys/arch/sparc64/sparc64/machdep.c
+++ b/sys/arch/sparc64/sparc64/machdep.c
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.183 2005/12/11 12:19:15 christos Exp $ */
+/* $NetBSD: machdep.c,v 1.184 2006/01/27 18:37:49 cdi Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -78,7 +78,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.183 2005/12/11 12:19:15 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.184 2006/01/27 18:37:49 cdi Exp $");
#include "opt_ddb.h"
#include "opt_compat_netbsd.h"
@@ -757,10 +757,9 @@ dumpsys()
register int psize;
daddr_t blkno;
register int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
- int error = 0;
+ int j, error = 0;
unsigned long todo;
register struct mem_region *mp;
- extern struct mem_region *mem;
/* copy registers to memory */
snapshot(curpcb);
@@ -803,10 +802,11 @@ dumpsys()
blkno += pmap_dumpsize();
/* calculate total size of dump */
- for (todo = 0, mp = mem; mp->size; mp++)
- todo += mp->size;
+ for (todo = 0, j = 0; j < phys_installed_size; j++)
+ todo += phys_installed[j].size;
- for (mp = mem; mp->size; mp++) {
+ for (mp = &phys_installed[0], j = 0; j < phys_installed_size;
+ j++, mp = &phys_installed[j]) {
unsigned i = 0, n;
paddr_t maddr = mp->start;
diff --git a/sys/arch/sparc64/sparc64/pmap.c b/sys/arch/sparc64/sparc64/pmap.c
index dd11427fded..ddbe64e7b5a 100644
--- a/sys/arch/sparc64/sparc64/pmap.c
+++ b/sys/arch/sparc64/sparc64/pmap.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.167 2006/01/12 18:04:09 cdi Exp $ */
+/* $NetBSD: pmap.c,v 1.168 2006/01/27 18:37:50 cdi Exp $ */
/*
*
* Copyright (C) 1996-1999 Eduardo Horvath.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.167 2006/01/12 18:04:09 cdi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.168 2006/01/27 18:37:50 cdi Exp $");
#undef NO_VCACHE /* Don't forget the locked TLB in dostart */
#define HWREF
@@ -53,6 +53,7 @@ __KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.167 2006/01/12 18:04:09 cdi Exp $");
#include <machine/promlib.h>
#include <machine/kcore.h>
#include <machine/cpu.h>
+#include <machine/bootinfo.h>
#include "cache.h"
@@ -159,16 +160,19 @@ paddr_t kdatap;
vaddr_t ekdata;
paddr_t ekdatap;
+/*
+ * Kernel 4MB pages.
+ */
+extern struct tlb_entry *kernel_tlbs;
+extern int kernel_tlb_slots;
+
static int npgs;
static u_int nextavail;
-static struct mem_region memlist[32]; /* Pick a random size here */
vaddr_t vmmap; /* one reserved MI vpage for /dev/mem */
-struct mem_region *mem, *avail, *orig;
-int memsize;
-
-static int memh = 0, vmemh = 0; /* Handles to OBP devices */
+int phys_installed_size; /* Installed physical memory */
+struct mem_region *phys_installed;
paddr_t avail_start, avail_end; /* These are used by ps & family */
@@ -405,6 +409,157 @@ static void pmap_alloc_bootargs(void)
cpu_args->cb_initstack = v + 2*PAGE_SIZE;
}
+#if defined(MULTIPROCESSOR)
+static void pmap_mp_init(void);
+
+static void
+pmap_mp_init(void)
+{
+ pte_t *tp;
+ char *v;
+ int i;
+
+ extern void cpu_mp_startup(void);
+
+ if ( (v = OF_claim(NULL, PAGE_SIZE, PAGE_SIZE)) == NULL) {
+ panic("pmap_mp_init: Cannot claim a page.");
+ }
+
+ bcopy(mp_tramp_code, v, mp_tramp_code_len);
+ *(u_long *)(v + mp_tramp_tlb_slots) = kernel_tlb_slots;
+ *(u_long *)(v + mp_tramp_func) = (u_long)cpu_mp_startup;
+ *(u_long *)(v + mp_tramp_ci) = (u_long)cpu_args;
+ tp = (pte_t *)(v + mp_tramp_code_len);
+ for (i = 0; i < kernel_tlb_slots; i++) {
+ tp[i].tag = kernel_tlbs[i].te_va;
+ tp[i].data = TSB_DATA(0, /* g */
+ PGSZ_4M, /* sz */
+ kernel_tlbs[i].te_pa, /* pa */
+ 1, /* priv */
+ 1, /* write */
+ 1, /* cache */
+ 1, /* aliased */
+ 1, /* valid */
+ 0 /* ie */);
+ tp[i].data |= TLB_L | TLB_CV;
+ printf("xtlb[%d]: Tag: %p Data: %p\n",
+ i, (void*)tp[i].tag, (void*)tp[i].data);
+ }
+
+ for (i = 0; i < PAGE_SIZE; i += sizeof(long))
+ flush(v + i);
+
+ cpu_spinup_trampoline = (vaddr_t)v;
+}
+#else
+#define pmap_mp_init() ((void)0)
+#endif
+
+paddr_t pmap_kextract(vaddr_t va);
+
+paddr_t
+pmap_kextract(vaddr_t va)
+{
+ int i;
+ paddr_t paddr = (paddr_t)-1;
+
+ for (i = 0; i < kernel_tlb_slots; i++) {
+ if ((va & ~PAGE_MASK_4M) == kernel_tlbs[i].te_va) {
+ paddr = kernel_tlbs[i].te_pa +
+ (paddr_t)(va & PAGE_MASK_4M);
+ break;
+ }
+ }
+
+ if (i == kernel_tlb_slots) {
+ panic("pmap_kextract: Address %p is not from kernel space.\n"
+ "Data segment is too small?\n", (void*)va);
+ }
+
+ return (paddr);
+}
+
+/*
+ * Bootstrap kernel allocator, allocates from unused space in 4MB kernel
+ * data segment meaning that
+ *
+ * - Access to allocated memory will never generate a trap
+ * - Allocated chunks are never reclaimed or freed
+ * - Allocation calls do not change PROM memlists
+ */
+static struct mem_region kdata_mem_pool;
+
+static void
+kdata_alloc_init(vaddr_t va_start, vaddr_t va_end)
+{
+ vsize_t va_size = va_end - va_start;
+
+ kdata_mem_pool.start = va_start;
+ kdata_mem_pool.size = va_size;
+
+ BDPRINTF(PDB_BOOT, ("kdata_alloc_init(): %d bytes @%p.\n", va_size,
+ va_start));
+}
+
+static vaddr_t
+kdata_alloc(vsize_t size, vsize_t align)
+{
+ vaddr_t va;
+ vsize_t asize;
+
+ asize = roundup(kdata_mem_pool.start, align) - kdata_mem_pool.start;
+
+ kdata_mem_pool.start += asize;
+ kdata_mem_pool.size -= asize;
+
+ if (kdata_mem_pool.size < size) {
+ panic("kdata_alloc(): Data segment is too small.\n");
+ }
+
+ va = kdata_mem_pool.start;
+ kdata_mem_pool.start += size;
+ kdata_mem_pool.size -= size;
+
+ BDPRINTF(PDB_BOOT, ("kdata_alloc(): Allocated %d@%p, %d free.\n",
+ size, (void*)va, kdata_mem_pool.size));
+
+ return (va);
+}
+
+/*
+ * Unified routine for reading PROM properties.
+ */
+static void
+pmap_read_memlist(const char *device, const char *property, void **ml,
+ int *ml_size, vaddr_t (* ml_alloc)(vsize_t, vsize_t))
+{
+ void *va;
+ int size, handle;
+
+ if ( (handle = prom_finddevice(device)) == 0) {
+ prom_printf("pmap_read_memlist(): No %s device found.\n",
+ device);
+ prom_halt();
+ }
+ if ( (size = OF_getproplen(handle, property)) < 0) {
+ prom_printf("pmap_read_memlist(): %s/%s has no length.\n",
+ device, property);
+ prom_halt();
+ }
+ if ( (va = (void*)(* ml_alloc)(size, sizeof(u_int64_t))) == NULL) {
+ prom_printf("pmap_read_memlist(): Cannot allocate memlist.\n");
+ prom_halt();
+ }
+ if (OF_getprop(handle, property, va, size) <= 0) {
+ prom_printf("pmap_read_memlist(): Cannot read %s/%s.\n",
+ device, property);
+ prom_halt();
+ }
+
+ *ml = va;
+ *ml_size = size;
+}
+
/*
* This is called during bootstrap, before the system is really initialized.
*
@@ -426,31 +581,53 @@ static void pmap_alloc_bootargs(void)
*/
void
-pmap_bootstrap(kernelstart, kernelend, maxctx)
+pmap_bootstrap(kernelstart, kernelend)
u_long kernelstart, kernelend;
- u_int maxctx;
{
- extern int data_start[], end[]; /* start of data segment */
+ extern int etext, data_start[]; /* start of data segment */
extern int msgbufmapped;
- struct mem_region *mp, *mp1;
- int msgbufsiz;
- int pcnt;
+ struct mem_region *mp, *mp1, *avail, *orig;
+ int i, j, pcnt, msgbufsiz;
size_t s, sz;
- int i, j;
int64_t data;
- vaddr_t va;
+ vaddr_t va, intstk;
u_int64_t phys_msgbuf;
- paddr_t newp, newkp;
- vaddr_t newkv, firstaddr, intstk;
- vsize_t kdsize, ktsize;
+ paddr_t newp;
+
+ void *prom_memlist;
+ int prom_memlist_size;
+
+ extern int get_maxctx(void);
+
+ BDPRINTF(PDB_BOOT, ("Entered pmap_bootstrap.\n"));
+
+ /*
+ * Calculate kernel size.
+ */
+ ktext = kernelstart;
+ ktextp = pmap_kextract(ktext);
+ ektext = roundup((vaddr_t)&etext, PAGE_SIZE_4M);
+ ektextp = pmap_kextract(ektext);
+
+ kdata = (vaddr_t)data_start;
+ kdatap = pmap_kextract(kdata);
+ ekdata = roundup(kernelend, PAGE_SIZE_4M);
+ ekdatap = roundup(pmap_kextract(kernelend), PAGE_SIZE_4M);
+
+ BDPRINTF(PDB_BOOT, ("Virtual layout: text %lx-%lx, data %lx-%lx.\n",
+ ktext, ektext, kdata, ekdata));
+ BDPRINTF(PDB_BOOT, ("Physical layout: text %lx-%lx, data %lx-%lx.\n",
+ ktextp, ektextp, kdatap, ekdatap));
+
+ /* Initialize bootstrap allocator. */
+ kdata_alloc_init(kernelend + 1 * 1024 * 1024, ekdata);
#ifdef DEBUG
pmap_bootdebug();
#endif
- BDPRINTF(PDB_BOOT, ("Entered pmap_bootstrap.\n"));
-
pmap_alloc_bootargs();
+ pmap_mp_init();
/*
* set machine page size
@@ -460,32 +637,6 @@ pmap_bootstrap(kernelstart, kernelend, maxctx)
uvm_setpagesize();
/*
- * Find out how big the kernel's virtual address
- * space is. The *$#@$ prom loses this info
- */
- if ((vmemh = prom_finddevice("/virtual-memory")) == 0) {
- prom_printf("no virtual-memory?");
- prom_halt();
- }
- memset(memlist, 0, sizeof(memlist));
- if (OF_getprop(vmemh, "available", memlist, sizeof(memlist)) <= 0) {
- prom_printf("no vmemory avail?");
- prom_halt();
- }
-
-#ifdef DEBUG
- if (pmapdebug & PDB_BOOT) {
- /* print out mem list */
- prom_printf("Available virtual memory:\n");
- for (mp = memlist; mp->size; mp++) {
- prom_printf("memlist start %p size %lx\n",
- (void *)(u_long)mp->start,
- (u_long)mp->size);
- }
- prom_printf("End of available virtual memory\n");
- }
-#endif
- /*
* Get hold or the message buffer.
*/
msgbufp = (struct kern_msgbuf *)(vaddr_t)MSGBUF_VA;
@@ -512,191 +663,32 @@ pmap_bootstrap(kernelstart, kernelend, maxctx)
initmsgbuf((caddr_t)msgbufp, msgbufsiz);
/*
- * Record kernel mapping -- we will map these with a permanent 4MB
- * TLB entry when we initialize the CPU later.
- */
- BDPRINTF(PDB_BOOT, ("translating kernelstart %p\n",
- (void *)kernelstart));
- ktext = kernelstart;
- ktextp = prom_vtop(kernelstart);
-
- kdata = (vaddr_t)data_start;
- kdatap = prom_vtop(kdata);
- ekdata = (vaddr_t)end;
-
- /*
- * Find the real size of the kernel. Locate the smallest starting
- * address > kernelstart.
- */
- for (mp1 = mp = memlist; mp->size; mp++) {
- /*
- * Check whether this region is at the end of the kernel.
- */
- if (mp->start >= ekdata && (mp1->start < ekdata ||
- mp1->start > mp->start))
- mp1 = mp;
- }
- if (mp1->start < kdata)
- prom_printf("Kernel at end of vmem???\n");
-
- BDPRINTF(PDB_BOOT1,
- ("Kernel data is mapped at %lx, next free seg: %lx, %lx\n",
- (long)kdata, (u_long)mp1->start, (u_long)mp1->size));
-
- /*
- * We save where we can start allocating memory.
- */
- firstaddr = (ekdata + 07) & ~ 07; /* Longword align */
-
- /*
- * We reserve 100K to grow.
- */
- ekdata += 100*KB;
-
- /*
- * And set the end of the data segment to the end of what our
- * bootloader allocated for us, if we still fit in there.
- */
- if (ekdata < mp1->start)
- ekdata = mp1->start;
-
-#define valloc(name, type, sz) do { \
- (name) = (type *)firstaddr; \
- firstaddr += (sz); \
- firstaddr = (firstaddr + 0xf) & ~0xf; \
-} while (0)
-
- /*
- * Since we can't always give the loader the hint to align us on a 4MB
- * boundary, we will need to do the alignment ourselves. First
- * allocate a new 4MB aligned segment for the kernel, then map it
- * in, copy the kernel over, swap mappings, then finally, free the
- * old kernel. Then we can continue with this.
- *
- * We'll do the data segment up here since we know how big it is.
- * We'll do the text segment after we've read in the PROM translations
- * so we can figure out its size.
- *
- * The ctxbusy table takes about 64KB, the TSB up to 32KB, and the
- * rest should be less than 1K, so 100KB extra should be plenty.
- */
- kdsize = round_page(ekdata - kdata);
- BDPRINTF(PDB_BOOT1, ("Kernel data size is %lx\n", (long)kdsize));
-
- if ((kdatap & (4*MEG-1)) == 0) {
- /* We were at a 4MB boundary -- claim the rest */
- psize_t szdiff = (4*MEG - kdsize) & (4*MEG - 1);
-
- BDPRINTF(PDB_BOOT1, ("Need to extend dseg by %lx\n",
- (long)szdiff));
- if (szdiff) {
- /* Claim the rest of the physical page. */
- newkp = kdatap + kdsize;
- newkv = kdata + kdsize;
- if (newkp != prom_claim_phys(newkp, szdiff)) {
- prom_printf("pmap_bootstrap: could not claim "
- "physical dseg extension "
- "at %lx size %lx\n",
- newkp, szdiff);
- goto remap_data;
- }
-
- /* And the rest of the virtual page. */
- if (prom_claim_virt(newkv, szdiff) != newkv)
- prom_printf("pmap_bootstrap: could not claim "
- "virtual dseg extension "
- "at size %lx\n", newkv, szdiff);
-
- /* Make sure all 4MB are mapped */
- prom_map_phys(newkp, szdiff, newkv, -1);
- }
- } else {
- psize_t sz1;
-remap_data:
- /*
- * Either we're not at a 4MB boundary or we can't get the rest
- * of the 4MB extension. We need to move the data segment.
- * Leave 1MB of extra fiddle space in the calculations.
- */
-
- sz1 = (kdsize + 4*MEG - 1) & ~(4*MEG-1);
- BDPRINTF(PDB_BOOT1,
- ("Allocating new %lx kernel data at 4MB boundary\n",
- (u_long)sz1));
- if ((newkp = prom_alloc_phys(sz1, 4*MEG)) == (paddr_t)-1 ) {
- prom_printf("Cannot allocate new kernel\n");
- prom_halt();
- }
- BDPRINTF(PDB_BOOT1, ("Allocating new va for buffer at %llx\n",
- (u_int64_t)newkp));
- if ((newkv = (vaddr_t)prom_alloc_virt(sz1, 8)) ==
- (vaddr_t)-1) {
- prom_printf("Cannot allocate new kernel va\n");
- prom_halt();
- }
- BDPRINTF(PDB_BOOT1, ("Mapping in buffer %llx at %llx\n",
- (u_int64_t)newkp, (u_int64_t)newkv));
- prom_map_phys(newkp, sz1, (vaddr_t)newkv, -1);
- BDPRINTF(PDB_BOOT1, ("Copying %ld bytes kernel data...",
- kdsize));
- memset((void*)newkv, 0, sz1);
- memcpy((void*)newkv, (void*)kdata, kdsize);
- BDPRINTF(PDB_BOOT1, ("done. Swapping maps..unmap new\n"));
- prom_unmap_virt((vaddr_t)newkv, sz1);
- BDPRINTF(PDB_BOOT, ("remap old "));
-#if 0
- /*
- * calling the prom will probably require reading part of the
- * data segment so we can't do this. */
- prom_unmap_virt((vaddr_t)kdatap, kdsize);
-#endif
- prom_map_phys(newkp, sz1, kdata, -1);
- /*
- * we will map in 4MB, more than we allocated, to allow
- * further allocation
- */
- BDPRINTF(PDB_BOOT1, ("free old\n"));
- prom_free_phys(kdatap, kdsize);
- kdatap = newkp;
- BDPRINTF(PDB_BOOT1,
- ("pmap_bootstrap: firstaddr is %lx virt (%lx phys)"
- "avail for kernel\n", (u_long)firstaddr,
- (u_long)prom_vtop(firstaddr)));
- }
-
- /*
* Find out how much RAM we have installed.
*/
BDPRINTF(PDB_BOOT, ("pmap_bootstrap: getting phys installed\n"));
- if ((memh = prom_finddevice("/memory")) == 0) {
- prom_printf("no memory?");
- prom_halt();
- }
- memsize = OF_getproplen(memh, "reg") + 2 * sizeof(struct mem_region);
- valloc(mem, struct mem_region, memsize);
- memset(mem, 0, memsize);
- if (OF_getprop(memh, "reg", mem, memsize) <= 0) {
- prom_printf("no memory installed?");
- prom_halt();
- }
- memsize /= sizeof(struct mem_region);
+ pmap_read_memlist("/memory", "reg", &prom_memlist, &prom_memlist_size,
+ kdata_alloc);
+ phys_installed = prom_memlist;
+ phys_installed_size = prom_memlist_size / sizeof(*phys_installed);
#ifdef DEBUG
if (pmapdebug & PDB_BOOT1) {
/* print out mem list */
prom_printf("Installed physical memory:\n");
- for (mp = mem; mp->size; mp++) {
+ for (i = 0; i < phys_installed_size; i++) {
prom_printf("memlist start %lx size %lx\n",
- (u_long)mp->start, (u_long)mp->size);
+ (u_long)phys_installed[i].start,
+ (u_long)phys_installed[i].size);
}
}
#endif
- BDPRINTF(PDB_BOOT1, ("Calculating physmem:"));
- for (mp = mem; mp->size; mp++)
- physmem += btoc(mp->size);
+ BDPRINTF(PDB_BOOT1, ("Calculating physmem:"));
+ for (i = 0; i < phys_installed_size; i++)
+ physmem += btoc(phys_installed[i].size);
BDPRINTF(PDB_BOOT1, (" result %x or %d pages\n",
(int)physmem, (int)physmem));
+
/*
* Calculate approx TSB size. This probably needs tweaking.
*/
@@ -710,13 +702,11 @@ remap_data:
/*
* Save the prom translations
*/
- sz = OF_getproplen(vmemh, "translations");
- valloc(prom_map, struct prom_map, sz);
- if (OF_getprop(vmemh, "translations", (void*)prom_map, sz) <= 0) {
- prom_printf("no translations installed?");
- prom_halt();
- }
- prom_map_size = sz / sizeof(struct prom_map);
+ pmap_read_memlist("/virtual-memory", "translations", &prom_memlist,
+ &prom_memlist_size, kdata_alloc);
+ prom_map = prom_memlist;
+ prom_map_size = prom_memlist_size / sizeof(struct prom_map);
+
#ifdef DEBUG
if (pmapdebug & PDB_BOOT) {
/* print out mem list */
@@ -730,111 +720,13 @@ remap_data:
prom_printf("End of prom xlations\n");
}
#endif
- /*
- * Hunt for the kernel text segment and figure out it size and
- * alignment.
- */
- for (i = 0; i < prom_map_size; i++)
- if (prom_map[i].vstart == ktext)
- break;
- if (i == prom_map_size)
- panic("No kernel text segment!");
- ktsize = prom_map[i].vsize;
- ektext = ktext + ktsize;
-
- if (ktextp & (4*MEG-1)) {
- /* Kernel text is not 4MB aligned -- need to fix that */
- BDPRINTF(PDB_BOOT1,
- ("Allocating new %lx kernel text at 4MB boundary\n",
- (u_long)ktsize));
- if ((newkp = prom_alloc_phys(ktsize, 4*MEG)) == 0 ) {
- prom_printf("Cannot allocate new kernel text\n");
- prom_halt();
- }
- BDPRINTF(PDB_BOOT1, ("Allocating new va for buffer at %llx\n",
- (u_int64_t)newkp));
- if ((newkv = (vaddr_t)prom_alloc_virt(ktsize, 8)) ==
- (vaddr_t)-1) {
- prom_printf("Cannot allocate new kernel text VA\n");
- prom_halt();
- }
- BDPRINTF(PDB_BOOT1, ("Mapping in buffer %lx at %lx\n",
- (u_long)newkp, (u_long)newkv));
- prom_map_phys(newkp, ktsize, (vaddr_t)newkv, -1);
- BDPRINTF(PDB_BOOT1, ("Copying %ld bytes kernel text...",
- ktsize));
- memcpy((void *)newkv, (void *)ktext,
- ktsize);
- BDPRINTF(PDB_BOOT1, ("done. Swapping maps..unmap new\n"));
- prom_unmap_virt((vaddr_t)newkv, 4*MEG);
- BDPRINTF(PDB_BOOT, ("remap old "));
-#if 0
- /*
- * calling the prom will probably require reading part of the
- * text segment so we can't do this.
- */
- prom_unmap_virt((vaddr_t)ktextp, ktsize);
-#endif
- prom_map_phys(newkp, ktsize, ktext, -1);
- /*
- * we will map in 4MB, more than we allocated, to allow
- * further allocation
- */
- BDPRINTF(PDB_BOOT1, ("free old\n"));
- prom_free_phys(ktextp, ktsize);
- ktextp = newkp;
-
- BDPRINTF(PDB_BOOT1,
- ("pmap_bootstrap: firstaddr is %lx virt (%lx phys)"
- "avail for kernel\n", (u_long)firstaddr,
- (u_long)prom_vtop(firstaddr)));
-
- /*
- * Re-fetch translations -- they've certainly changed.
- */
- if (OF_getprop(vmemh, "translations", (void*)prom_map, sz) <=
- 0) {
- prom_printf("no translations installed?");
- prom_halt();
- }
-#ifdef DEBUG
- if (pmapdebug & PDB_BOOT) {
- /* print out mem list */
- prom_printf("New prom xlations:\n");
- for (i = 0; i < prom_map_size; i++) {
- prom_printf("start %016lx size %016lx tte %016lx\n",
- (u_long)prom_map[i].vstart,
- (u_long)prom_map[i].vsize,
- (u_long)prom_map[i].tte);
- }
- prom_printf("End of prom xlations\n");
- }
-#endif
- }
- ektextp = ktextp + ktsize;
/*
* Here's a quick in-lined reverse bubble sort. It gets rid of
* any translations inside the kernel data VA range.
*/
for(i = 0; i < prom_map_size; i++) {
- if (prom_map[i].vstart >= kdata &&
- prom_map[i].vstart <= firstaddr) {
- prom_map[i].vstart = 0;
- prom_map[i].vsize = 0;
- }
- if (prom_map[i].vstart >= ktext &&
- prom_map[i].vstart <= ektext) {
- prom_map[i].vstart = 0;
- prom_map[i].vsize = 0;
- }
for(j = i; j < prom_map_size; j++) {
- if (prom_map[j].vstart >= kdata &&
- prom_map[j].vstart <= firstaddr)
- continue; /* this is inside the kernel */
- if (prom_map[j].vstart >= ktext &&
- prom_map[j].vstart <= ektext)
- continue; /* this is inside the kernel */
if (prom_map[j].vstart > prom_map[i].vstart) {
struct prom_map tmp;
tmp = prom_map[i];
@@ -869,37 +761,27 @@ remap_data:
* Now the kernel text segment is in its final location we can try to
* find out how much memory really is free.
*/
- sz = OF_getproplen(memh, "available") + sizeof(struct mem_region);
- valloc(orig, struct mem_region, sz);
- memset(orig, 0, sz);
- if (OF_getprop(memh, "available", orig, sz) <= 0) {
- prom_printf("no available RAM?");
- prom_halt();
- }
-#ifdef DEBUG
- if (pmapdebug & PDB_BOOT1) {
- /* print out mem list */
- prom_printf("Available physical memory:\n");
- for (mp = orig; mp->size; mp++) {
- prom_printf("memlist start %lx size %lx\n",
- (u_long)mp->start, (u_long)mp->size);
- }
- prom_printf("End of available physical memory\n");
- }
-#endif
- valloc(avail, struct mem_region, sz);
- memset(avail, 0, sz);
- for (pcnt = 0, mp = orig, mp1 = avail; (mp1->size = mp->size);
- mp++, mp1++) {
- mp1->start = mp->start;
- pcnt++;
+ pmap_read_memlist("/memory", "available", &prom_memlist,
+ &prom_memlist_size, kdata_alloc);
+ orig = prom_memlist;
+ sz = prom_memlist_size;
+ pcnt = prom_memlist_size / sizeof(*orig);
+
+ BDPRINTF(PDB_BOOT1, ("Available physical memory:\n"));
+ avail = (struct mem_region*)kdata_alloc(sz, sizeof(u_int64_t));
+ for (i = 0; i < pcnt; i++) {
+ avail[i] = orig[i];
+ BDPRINTF(PDB_BOOT1, ("memlist start %lx size %lx\n",
+ (u_long)orig[i].start,
+ (u_long)orig[i].size));
}
+ BDPRINTF(PDB_BOOT1, ("End of available physical memory\n"));
/*
* Allocate and initialize a context table
*/
- numctx = maxctx;
- valloc(ctxbusy, paddr_t, CTXSIZE);
+ numctx = get_maxctx();
+ ctxbusy = (paddr_t *)kdata_alloc(CTXSIZE, sizeof(u_int64_t));
memset(ctxbusy, 0, CTXSIZE);
LIST_INIT(&pmap_ctxlist);
@@ -908,61 +790,29 @@ remap_data:
*
* We will use the left over space to flesh out the kernel pmap.
*/
- BDPRINTF(PDB_BOOT1, ("firstaddr before TSB=%lx\n",
- (u_long)firstaddr));
- firstaddr = ((firstaddr + TSBSIZE - 1) & ~(TSBSIZE - 1));
-#ifdef DEBUG
- /* First, page align */
- i = (firstaddr + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
- if ((int)firstaddr < i) {
- prom_printf("TSB alloc fixup failed\n");
- prom_printf("frobbed i, firstaddr before TSB=%x, %lx\n",
- (int)i, (u_long)firstaddr);
- panic("TSB alloc");
- prom_halt();
- }
-#endif
- BDPRINTF(PDB_BOOT, ("frobbed i, firstaddr before TSB=%x, %lx\n",
- (int)i, (u_long)firstaddr));
- valloc(tsb_dmmu, pte_t, TSBSIZE);
+ tsb_dmmu = (pte_t *)kdata_alloc(TSBSIZE, TSBSIZE);
memset(tsb_dmmu, 0, TSBSIZE);
- valloc(tsb_immu, pte_t, TSBSIZE);
+ tsb_immu = (pte_t *)kdata_alloc(TSBSIZE, TSBSIZE);
memset(tsb_immu, 0, TSBSIZE);
- BDPRINTF(PDB_BOOT1, ("firstaddr after TSB=%lx\n", (u_long)firstaddr));
BDPRINTF(PDB_BOOT1, ("TSB allocated at %p/%p size %08x\n",
tsb_dmmu, tsb_immu, TSBSIZE));
- /*
- * Page align all regions.
- * Non-page memory isn't very interesting to us.
- * Also, sort the entries for ascending addresses.
- *
- * And convert from virtual to physical addresses.
- */
-
- BDPRINTF(PDB_BOOT, ("kernel virtual size %08lx - %08lx\n",
- (u_long)kernelstart, (u_long)firstaddr));
- kdata = kdata & ~PGOFSET;
- ekdata = firstaddr;
- ekdata = (ekdata + PGOFSET) & ~PGOFSET;
- BDPRINTF(PDB_BOOT1, ("kernel virtual size %08lx - %08lx\n",
- (u_long)kernelstart, (u_long)kernelend));
- ekdatap = ekdata - kdata + kdatap;
- /* Switch from vaddrs to paddrs */
- if(ekdatap > (kdatap + 4*MEG)) {
- prom_printf("Kernel size exceeds 4MB\n");
- }
-
+ BDPRINTF(PDB_BOOT, ("ktext %08lx[%08lx] - %08lx[%08lx] : "
+ "kdata %08lx[%08lx] - %08lx[%08lx]\n",
+ (u_long)ktext, (u_long)ktextp,
+ (u_long)ektext, (u_long)ektextp,
+ (u_long)kdata, (u_long)kdatap,
+ (u_long)ekdata, (u_long)ekdatap));
#ifdef DEBUG
if (pmapdebug & PDB_BOOT1) {
/* print out mem list */
prom_printf("Available %lx physical memory before cleanup:\n",
(u_long)avail);
- for (mp = avail; mp->size; mp++) {
+ for (i = 0; i < pcnt; i++) {
prom_printf("memlist start %lx size %lx\n",
- (u_long)mp->start,
- (u_long)mp->size);
+ (u_long)avail[i].start,
+ (u_long)avail[i].size);
}
prom_printf("End of available physical memory before cleanup\n");
prom_printf("kernel physical text size %08lx - %08lx\n",
@@ -996,34 +846,7 @@ remap_data:
* memory lists. (NB: we may have already alloc'ed the entire space).
*/
npgs = 0;
- for (mp = avail; mp->size; mp++) {
- /*
- * Check whether this region holds all of the kernel.
- */
- s = mp->start + mp->size;
- if (mp->start < kdatap && s > roundup(ekdatap, 4*MEG)) {
- avail[pcnt].start = roundup(ekdatap, 4*MEG);
- avail[pcnt++].size = s - kdatap;
- mp->size = kdatap - mp->start;
- }
- /*
- * Look whether this regions starts within the kernel.
- */
- if (mp->start >= kdatap &&
- mp->start < roundup(ekdatap, 4*MEG)) {
- s = ekdatap - mp->start;
- if (mp->size > s)
- mp->size -= s;
- else
- mp->size = 0;
- mp->start = roundup(ekdatap, 4*MEG);
- }
- /*
- * Now look whether this region ends within the kernel.
- */
- s = mp->start + mp->size;
- if (s > kdatap && s < roundup(ekdatap, 4*MEG))
- mp->size -= s - kdatap;
+ for (mp = avail, i = 0; i < pcnt; i++, mp = &avail[i]) {
/*
* Now page align the start of the region.
*/
@@ -1078,6 +901,9 @@ remap_data:
* In future we should be able to specify both allocated
* and free.
*/
+ BDPRINTF(PDB_BOOT1, ("uvm_page_physload(%lx, %lx)\n",
+ (long)mp->start,
+ (long)(mp->start + mp->size)));
uvm_page_physload(
atop(mp->start),
atop(mp->start+mp->size),
@@ -1086,25 +912,13 @@ remap_data:
VM_FREELIST_DEFAULT);
}
-#if 0
- /* finally, free up any space that valloc did not use */
- prom_unmap_virt((vaddr_t)ekdata, roundup(ekdata, 4*MEG) - ekdata);
- if (ekdatap < roundup(kdatap, 4*MEG)) {
- uvm_page_physload(atop(ekdatap),
- atop(roundup(ekdatap, (4*MEG))),
- atop(ekdatap),
- atop(roundup(ekdatap, (4*MEG))),
- VM_FREELIST_DEFAULT);
- }
-#endif
-
#ifdef DEBUG
if (pmapdebug & PDB_BOOT) {
/* print out mem list */
prom_printf("Available physical memory after cleanup:\n");
- for (mp = avail; mp->size; mp++) {
+ for (i = 0; i < pcnt; i++) {
prom_printf("avail start %lx size %lx\n",
- (long)mp->start, (long)mp->size);
+ (long)avail[i].start, (long)avail[i].size);
}
prom_printf("End of available physical memory after cleanup\n");
}
@@ -1307,6 +1121,8 @@ remap_data:
avail_end = mp->start+mp->size;
BDPRINTF(PDB_BOOT1, ("Finished pmap_bootstrap()\n"));
+ BDPRINTF(PDB_BOOT, ("left kdata: %" PRId64 " @%" PRIx64 ".\n",
+ kdata_mem_pool.size, kdata_mem_pool.start));
}
/*
@@ -2227,12 +2043,12 @@ pmap_extract(pm, va, pap)
if (pm == pmap_kernel() && va >= kdata && va < roundup(ekdata, 4*MEG)) {
/* Need to deal w/locked TLB entry specially. */
- pa = (paddr_t)(kdatap - kdata + va);
+ 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 >= ktext && va < ektext) {
/* Need to deal w/locked TLB entry specially. */
- pa = (paddr_t)(ktextp - ktext + va);
+ pa = pmap_kextract(va);
DPRINTF(PDB_EXTRACT, ("pmap_extract: va=%lx pa=%llx\n",
(u_long)va, (unsigned long long)pa));
} else {
@@ -2318,7 +2134,7 @@ pmap_dumpsize()
int sz;
sz = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t));
- sz += memsize * sizeof(phys_ram_seg_t);
+ sz += phys_installed_size * sizeof(phys_ram_seg_t);
return btodb(sz + DEV_BSIZE - 1);
}
@@ -2333,7 +2149,7 @@ pmap_dumpsize()
*
* kcore_seg_t MI header defined in <sys/kcore.h>)
* cpu_kcore_hdr_t MD header defined in <machine/kcore.h>)
- * phys_ram_seg_t[memsize] physical memory segments
+ * phys_ram_seg_t[phys_installed_size] physical memory segments
*/
int
pmap_dumpmmu(dump, blkno)
@@ -2391,7 +2207,7 @@ pmap_dumpmmu(dump, blkno)
kcpu->kdatasz = (u_int64_t)ekdatap - kdatap;
/* Now the memsegs */
- kcpu->nmemseg = memsize;
+ kcpu->nmemseg = phys_installed_size;
kcpu->memsegoffset = memsegoffset = ALIGN(sizeof(cpu_kcore_hdr_t));
/* Now we need to point this at our kernel pmap. */
@@ -2401,9 +2217,9 @@ pmap_dumpmmu(dump, blkno)
/* Note: we have assumed everything fits in buffer[] so far... */
bp = (int *)((long)kcpu + ALIGN(sizeof(cpu_kcore_hdr_t)));
- for (i = 0; i < memsize; i++) {
- memseg.start = mem[i].start;
- memseg.size = mem[i].size;
+ for (i = 0; i < phys_installed_size; i++) {
+ memseg.start = phys_installed[i].start;
+ memseg.size = phys_installed[i].size;
EXPEDITE(&memseg, sizeof(phys_ram_seg_t));
}
@@ -2420,12 +2236,15 @@ int
pmap_pa_exists(pa)
paddr_t pa;
{
- struct mem_region *mp;
+ int i;
/* Just go through physical memory list & see if we're there */
- for (mp = mem; mp->size && mp->start <= pa; mp++)
- if (mp->start <= pa && mp->start + mp->size >= pa)
+ for (i = 0; i < phys_installed_size; i++) {
+ if ((phys_installed[i].start <= pa) &&
+ (phys_installed[i].start +
+ phys_installed[i].size >= pa))
return 1;
+ }
return 0;
}