diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2009-11-19 06:06:52 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2009-11-19 06:06:52 +0000 |
commit | 8b778e3e285501cf3fe074b5a02dab393ba888bb (patch) | |
tree | 061797d5fd87d964d50d83dc04eaa9951e0bc6ac /sys/arch/sgi | |
parent | ef5876e7f6c56e72432d77336b585efcdacdcd2c (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.c | 69 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip30_machdep.c | 43 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip32_machdep.c | 48 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/machdep.c | 15 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/sginode.c | 143 |
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 */ |