summaryrefslogtreecommitdiff
path: root/sys/arch/sgi
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-11-19 06:06:52 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-11-19 06:06:52 +0000
commit8b778e3e285501cf3fe074b5a02dab393ba888bb (patch)
tree061797d5fd87d964d50d83dc04eaa9951e0bc6ac /sys/arch/sgi
parentef5876e7f6c56e72432d77336b585efcdacdcd2c (diff)
Factor triplicated code responsible to add memory information into a
single place.
Diffstat (limited to 'sys/arch/sgi')
-rw-r--r--sys/arch/sgi/sgi/autoconf.c69
-rw-r--r--sys/arch/sgi/sgi/ip30_machdep.c43
-rw-r--r--sys/arch/sgi/sgi/ip32_machdep.c48
-rw-r--r--sys/arch/sgi/sgi/machdep.c15
-rw-r--r--sys/arch/sgi/sgi/sginode.c143
5 files changed, 150 insertions, 168 deletions
diff --git a/sys/arch/sgi/sgi/autoconf.c b/sys/arch/sgi/sgi/autoconf.c
index d031893f350..493a13db8cd 100644
--- a/sys/arch/sgi/sgi/autoconf.c
+++ b/sys/arch/sgi/sgi/autoconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.c,v 1.28 2009/11/07 22:48:37 miod Exp $ */
+/* $OpenBSD: autoconf.c,v 1.29 2009/11/19 06:06:51 miod Exp $ */
/*
* Copyright (c) 2009 Miodrag Vallat.
*
@@ -95,9 +95,13 @@
#include <sys/device.h>
#include <machine/autoconf.h>
+#include <machine/memconf.h>
+
#include <mips64/arcbios.h>
#include <mips64/archtype.h>
+#include <uvm/uvm_extern.h>
+
#include <sgi/xbow/xbow.h>
#include <dev/pci/pcivar.h>
#include <scsi/scsi_all.h>
@@ -154,6 +158,69 @@ diskconf(void)
dumpconf();
}
+/*
+ * Register a memory region.
+ */
+int
+memrange_register(uint64_t startpfn, uint64_t endpfn, uint64_t bmask,
+ unsigned int freelist)
+{
+ struct phys_mem_desc *cur, *m = NULL;
+ int i;
+
+#ifdef DEBUG
+{
+ extern int console_ok;
+
+ if (console_ok)
+ printf("%s: memory from %p to %p\n",
+ __func__, ptoa(startpfn), ptoa(endpfn));
+ else
+ bios_printf("%s: memory from %p to %p\n",
+ __func__, ptoa(startpfn), ptoa(endpfn));
+}
+#endif
+ physmem += endpfn - startpfn;
+
+ /*
+ * Prevent use of memory above 16GB physical, until pmap can support
+ * this.
+ */
+ if (startpfn >= atop(16UL * 1024 * 1024 * 1024))
+ return 0;
+ if (endpfn >= atop(16UL * 1024 * 1024 * 1024))
+ endpfn = atop(16UL * 1024 * 1024 * 1024);
+
+ for (i = 0, cur = mem_layout; i < MAXMEMSEGS; i++, cur++) {
+ if (cur->mem_last_page == 0) {
+ if (m == NULL)
+ m = cur; /* first free segment */
+ continue;
+ }
+ /* merge contiguous areas if on the same freelist */
+ if (cur->mem_freelist == freelist) {
+ if (cur->mem_first_page == endpfn &&
+ ((cur->mem_last_page ^ startpfn) & bmask) == 0) {
+ cur->mem_first_page = startpfn;
+ return 0;
+ }
+ if (cur->mem_last_page == startpfn &&
+ ((cur->mem_first_page ^ endpfn) & bmask) == 0) {
+ cur->mem_last_page = endpfn;
+ return 0;
+ }
+ }
+ }
+
+ if (m == NULL)
+ return ENOMEM;
+
+ m->mem_first_page = startpfn;
+ m->mem_last_page = endpfn;
+ m->mem_freelist = freelist;
+ return 0;
+}
+
static char bootpath_store[sizeof osloadpartition];
static char *bootpath_curpos;
static char *bootpath_lastpos;
diff --git a/sys/arch/sgi/sgi/ip30_machdep.c b/sys/arch/sgi/sgi/ip30_machdep.c
index e03565a7b1e..e415d8d2a3e 100644
--- a/sys/arch/sgi/sgi/ip30_machdep.c
+++ b/sys/arch/sgi/sgi/ip30_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip30_machdep.c,v 1.16 2009/11/18 19:05:51 miod Exp $ */
+/* $OpenBSD: ip30_machdep.c,v 1.17 2009/11/19 06:06:51 miod Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -66,12 +66,10 @@ static int ip30_cpu_exists(int);
void
ip30_setup()
{
-#if 0
paddr_t heart;
int bank;
uint32_t memcfg;
- uint64_t start, count;
-#endif
+ uint64_t start, count, end;
u_long cpuspeed;
/*
@@ -80,17 +78,17 @@ ip30_setup()
*/
uncached_base = PHYS_TO_XKPHYS(0, CCA_NC);
-#if 0
/*
- * Scan for memory. ARCBios reports at least up to 2GB; if
- * memory above 2GB isn't reported, we'll need to re-enable this
- * code and add the unseen areas.
+ * Scan for memory. ARCBios reports up to 1GB of memory as available,
+ * and anything after is reported as reserved.
*/
heart = PHYS_TO_XKPHYS(HEART_PIU_BASE, CCA_NC);
for (bank = 0; bank < 8; bank++) {
- memcfg = *(uint32_t *)
+ memcfg = *(volatile uint32_t *)
(heart + HEART_MEMORY_STATUS + bank * sizeof(uint32_t));
+#ifdef DEBUG
bios_printf("memory bank %d: %08x\n", bank, memcfg);
+#endif
if (!ISSET(memcfg, HEART_MEMORY_VALID))
continue;
@@ -105,11 +103,34 @@ ip30_setup()
/* Physical memory starts at 512MB */
start += IP30_MEMORY_BASE;
+ end = start + count;
+#ifdef DEBUG
bios_printf("memory from %p to %p\n",
- ptoa(start), ptoa(start + count));
- }
+ start, end);
#endif
+ /*
+ * Add memory not obtained through ARCBios.
+ */
+ if (start >= IP30_MEMORY_BASE + IP30_MEMORY_ARCBIOS_LIMIT) {
+ /*
+ * XXX Temporary until there is a way to cope with
+ * XXX xbridge ATE shortage.
+ */
+ if (end > (2UL << 30)) {
+#if 0
+ physmem += atop(end - (2UL << 30));
+#endif
+ end = 2UL << 30;
+ }
+ if (end <= start)
+ continue;
+
+ memrange_register(start, count, 0, VM_FREELIST_DEFAULT);
+ }
+ }
+
+
xbow_widget_base = ip30_widget_short;
xbow_widget_map = ip30_widget_map;
xbow_widget_id = ip30_widget_id;
diff --git a/sys/arch/sgi/sgi/ip32_machdep.c b/sys/arch/sgi/sgi/ip32_machdep.c
index d2bc342e232..492828ef108 100644
--- a/sys/arch/sgi/sgi/ip32_machdep.c
+++ b/sys/arch/sgi/sgi/ip32_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip32_machdep.c,v 1.10 2009/10/26 18:00:06 miod Exp $ */
+/* $OpenBSD: ip32_machdep.c,v 1.11 2009/11/19 06:06:51 miod Exp $ */
/*
* Copyright (c) 2003-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -56,15 +56,18 @@ void crime_configure_memory(void);
void
crime_configure_memory(void)
{
- struct phys_mem_desc *m;
volatile u_int64_t *bank_ctrl;
paddr_t addr;
psize_t size;
u_int64_t ctrl0, ctrl;
- u_int32_t first_page, last_page;
- int bank, i;
+ u_int64_t first_page, last_page;
+ int bank;
+#ifdef DEBUG
+ int i;
+#endif
- bank_ctrl = (void *)PHYS_TO_KSEG1(CRIMEBUS_BASE + CRIME_MEM_BANK0_CONTROL);
+ bank_ctrl =
+ (void *)PHYS_TO_KSEG1(CRIMEBUS_BASE + CRIME_MEM_BANK0_CONTROL);
for (bank = 0; bank < CRIME_MAX_BANKS; bank++) {
ctrl = bank_ctrl[bank];
addr = (ctrl & CRIME_MEM_BANK_ADDR) << 25;
@@ -95,39 +98,16 @@ crime_configure_memory(void)
first_page = atop(addr);
last_page = atop(addr + size);
- /*
- * Try to coalesce with other memory segments if banks are
- * contiguous.
- */
- m = NULL;
- for (i = 0; i < MAXMEMSEGS; i++) {
- if (mem_layout[i].mem_last_page == 0) {
- if (m == NULL)
- m = &mem_layout[i];
- } else if (last_page == mem_layout[i].mem_first_page) {
- m = &mem_layout[i];
- m->mem_first_page = first_page;
- } else if (mem_layout[i].mem_last_page == first_page) {
- m = &mem_layout[i];
- m->mem_last_page = last_page;
- }
- }
- if (m != NULL) {
- if (m->mem_last_page == 0) {
- m->mem_first_page = first_page;
- m->mem_last_page = last_page;
- }
- m->mem_freelist = VM_FREELIST_DEFAULT;
- physmem += atop(size);
- }
+ memrange_register(first_page, last_page, 0,
+ VM_FREELIST_DEFAULT);
}
#ifdef DEBUG
for (i = 0; i < MAXMEMSEGS; i++)
- if (mem_layout[i].mem_first_page)
- bios_printf("MEM %d, 0x%x to 0x%x\n",i,
- ptoa(mem_layout[i].mem_first_page),
- ptoa(mem_layout[i].mem_last_page));
+ if (mem_layout[i].mem_last_page != 0)
+ bios_printf("MEM %d, %p to %p\n", i,
+ ptoa(mem_layout[i].mem_first_page),
+ ptoa(mem_layout[i].mem_last_page));
#endif
}
diff --git a/sys/arch/sgi/sgi/machdep.c b/sys/arch/sgi/sgi/machdep.c
index 2ffbcbd98f7..815ad599b26 100644
--- a/sys/arch/sgi/sgi/machdep.c
+++ b/sys/arch/sgi/sgi/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.87 2009/11/07 18:56:55 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.88 2009/11/19 06:06:51 miod Exp $ */
/*
* Copyright (c) 2003-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -305,9 +305,9 @@ mips_init(int argc, void *argv, caddr_t boot_esym)
uvmexp.pagesize = PAGE_SIZE;
uvm_setpagesize();
- for (i = 0; i < MAXMEMSEGS && mem_layout[i].mem_first_page != 0; i++) {
- u_int32_t fp, lp;
- u_int32_t firstkernpage, lastkernpage;
+ for (i = 0; i < MAXMEMSEGS && mem_layout[i].mem_last_page != 0; i++) {
+ uint64_t fp, lp;
+ uint64_t firstkernpage, lastkernpage;
unsigned int freelist;
paddr_t firstkernpa, lastkernpa;
@@ -341,12 +341,13 @@ mips_init(int argc, void *argv, caddr_t boot_esym)
else if (lp < lastkernpage)
lp = firstkernpage;
else { /* Need to split! */
- u_int32_t xp = firstkernpage;
+ uint64_t xp = firstkernpage;
uvm_page_physload(fp, xp, fp, xp, freelist);
fp = lastkernpage;
}
- if (lp > fp)
+ if (lp > fp) {
uvm_page_physload(fp, lp, fp, lp, freelist);
+ }
}
switch (sys_config.system_type) {
@@ -1042,7 +1043,9 @@ rm7k_perfintr(trapframe)
{
struct proc *p = curproc;
+#ifdef DEBUG
printf("perfintr proc %p!\n", p);
+#endif
cp0_setperfcount(cp0_getperfcount() & 0x7fffffff);
if (p != NULL) {
p->p_md.md_pc_spill++;
diff --git a/sys/arch/sgi/sgi/sginode.c b/sys/arch/sgi/sgi/sginode.c
index 45b13a21049..22feef77553 100644
--- a/sys/arch/sgi/sgi/sginode.c
+++ b/sys/arch/sgi/sgi/sginode.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sginode.c,v 1.14 2009/11/07 14:49:01 miod Exp $ */
+/* $OpenBSD: sginode.c,v 1.15 2009/11/19 06:06:51 miod Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
*
@@ -313,9 +313,8 @@ void
kl_add_memory_ip27(int16_t nasid, int16_t *sizes, unsigned int cnt)
{
paddr_t basepa;
- uint32_t fp, lp, np;
- unsigned int seg, descno, nmeg;
- struct phys_mem_desc *md;
+ uint64_t fp, lp, np;
+ unsigned int seg, nmeg;
/*
* On IP27, access to each DIMM is interleaved, which cause it to
@@ -325,13 +324,6 @@ kl_add_memory_ip27(int16_t nasid, int16_t *sizes, unsigned int cnt)
*/
basepa = (paddr_t)nasid << kl_n_shift;
while (cnt-- != 0) {
- /*
- * XXX Temporary until there is a way to cope with
- * XXX xbridge ATE shortage.
- */
- if (basepa >= (2UL << 30))
- return;
-
nmeg = *sizes++;
for (seg = 0; seg < 4; basepa += (1 << 27), seg++) {
if (nmeg <= 128)
@@ -361,63 +353,27 @@ kl_add_memory_ip27(int16_t nasid, int16_t *sizes, unsigned int cnt)
}
/*
- * Walk the existing segment list to find if we
- * are adjacent to an existing segment, or the
- * next free segment to use if not (unless doing
- * this would cross the 2GB boundary we need for
- * 32 bit DMA memory).
- *
- * Note that since we do not know in which order
- * we'll find our nodes, we have to check for
- * both boundaries, despite adding a given node's
- * memory in increasing pa order.
+ * XXX Temporary until there is a way to cope with
+ * XXX xbridge ATE shortage.
*/
- for (descno = 0, md = mem_layout; descno < MAXMEMSEGS;
- descno++, md++) {
- if (md->mem_first_page == 0)
- break;
-
- /*
- * Do not try to merge segments if they are
- * not covering the same node.
- */
- if ((ptoa(md->mem_first_page) >> kl_n_shift) !=
- nasid)
- continue;
-
- if (md->mem_first_page == lp &&
- lp != atop(2UL << 30)) {
- md->mem_first_page = fp;
- physmem += np;
- md = NULL;
- break;
- }
-
- if (md->mem_last_page == fp &&
- fp != atop(2UL << 30)) {
- md->mem_last_page = lp;
- physmem += np;
- md = NULL;
- break;
- }
- }
- if (descno != MAXMEMSEGS && md != NULL) {
- md->mem_first_page = fp;
- md->mem_last_page = lp;
- md->mem_freelist = lp <= atop(2UL << 30) ?
- VM_FREELIST_DMA32 : VM_FREELIST_DEFAULT;
- physmem += np;
- md = NULL;
+ if (fp >= atop(2UL << 30)) {
+#if 0
+ physmem += lp - fp;
+#endif
+ continue;
}
- if (md != NULL) {
+ if (memrange_register(fp, lp,
+ ~(atop(1UL << kl_n_shift) - 1),
+ lp <= atop(2UL << 30) ?
+ VM_FREELIST_DEFAULT : VM_FREELIST_DMA32) != 0) {
/*
* We could hijack the smallest segment here.
* But is it really worth doing?
*/
bios_printf("%u MB of memory could not be "
"managed, increase MAXMEMSEGS\n",
- atop(np) >> 20);
+ ptoa(np) >> 20);
}
}
}
@@ -428,8 +384,6 @@ kl_add_memory_ip35(int16_t nasid, int16_t *sizes, unsigned int cnt)
{
paddr_t basepa;
uint32_t fp, lp, np;
- unsigned int descno;
- struct phys_mem_desc *md;
/*
* On IP35, the smallest memory DIMMs are 256MB, and the
@@ -438,13 +392,6 @@ kl_add_memory_ip35(int16_t nasid, int16_t *sizes, unsigned int cnt)
basepa = (paddr_t)nasid << kl_n_shift;
while (cnt-- != 0) {
- /*
- * XXX Temporary until there is a way to cope with
- * XXX xbridge ATE shortage.
- */
- if (basepa >= (2UL << 30))
- return;
-
np = *sizes++;
if (np != 0) {
DB_PRF(("IP35 memory from %p to %p (%u MB)\n",
@@ -467,63 +414,27 @@ kl_add_memory_ip35(int16_t nasid, int16_t *sizes, unsigned int cnt)
}
/*
- * Walk the existing segment list to find if we
- * are adjacent to an existing segment, or the
- * next free segment to use if not (unless doing
- * this would cross the 2GB boundary we need for
- * 32 bit DMA memory).
- *
- * Note that since we do not know in which order
- * we'll find our nodes, we have to check for
- * both boundaries, despite adding a given node's
- * memory in increasing pa order.
+ * XXX Temporary until there is a way to cope with
+ * XXX xbridge ATE shortage.
*/
- for (descno = 0, md = mem_layout; descno < MAXMEMSEGS;
- descno++, md++) {
- if (md->mem_first_page == 0)
- break;
-
- /*
- * Do not try to merge segments if they are
- * not covering the same node.
- */
- if ((ptoa(md->mem_first_page) >> kl_n_shift) !=
- nasid)
- continue;
-
- if (md->mem_first_page == lp &&
- lp != atop(2UL << 30)) {
- md->mem_first_page = fp;
- physmem += np;
- md = NULL;
- break;
- }
-
- if (md->mem_last_page == fp &&
- fp != atop(2UL << 30)) {
- md->mem_last_page = lp;
- physmem += np;
- md = NULL;
- break;
- }
- }
- if (descno != MAXMEMSEGS && md != NULL) {
- md->mem_first_page = fp;
- md->mem_last_page = lp;
- md->mem_freelist = lp <= atop(2UL << 30) ?
- VM_FREELIST_DMA32 : VM_FREELIST_DEFAULT;
- physmem += np;
- md = NULL;
+ if (fp >= atop(2UL << 30)) {
+#if 0
+ physmem += lp - fp;
+#endif
+ continue;
}
- if (md != NULL) {
+ if (memrange_register(fp, lp,
+ ~(atop(1UL << kl_n_shift) - 1),
+ lp <= atop(2UL << 30) ?
+ VM_FREELIST_DEFAULT : VM_FREELIST_DMA32) != 0) {
/*
* We could hijack the smallest segment here.
* But is it really worth doing?
*/
bios_printf("%u MB of memory could not be "
"managed, increase MAXMEMSEGS\n",
- atop(np) >> 20);
+ ptoa(np) >> 20);
}
}
basepa += 1UL << 30; /* 1 GB */