support non-contiguous memory.

patch from Mycroft <root@ihack.net> and uch@netbsd.org.
tested hardware:
	VR4121	IBM WorkPad z50 (48MB, 16MB)
	VR4121	NEC Mobile Gear II MC/R730
	TX3912	Compaq C-series 810 (20MB), 2010c (20MB, 16MB)
	TX3922	Sharp Telios HC-AJ2 (32MB)
This commit is contained in:
shin 2000-02-21 13:46:02 +00:00
parent 74857849d3
commit 26f41e8f13
5 changed files with 180 additions and 117 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.18 2000/02/10 08:34:08 sato Exp $ */
/* $NetBSD: machdep.c,v 1.19 2000/02/21 13:46:02 shin Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -43,7 +43,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.18 2000/02/10 08:34:08 sato Exp $");
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.19 2000/02/21 13:46:02 shin Exp $");
/* from: Utah Hdr: machdep.c 1.63 91/04/24 */
#include "opt_vr41x1.h"
@ -131,7 +131,6 @@ vm_map_t mb_map = NULL;
vm_map_t phys_map = NULL;
int systype; /* mother board type */
int maxmem; /* max memory per process */
int physmem; /* max supported memory, changes to actual */
int mem_cluster_cnt;
phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX];
@ -171,7 +170,7 @@ void unimpl_device_register __P((struct device *, void *));
void unimpl_iointr __P ((void *, u_long));
void unimpl_clockintr __P ((void *));
void unimpl_fb_init __P((caddr_t*));
int unimpl_mem_init __P((caddr_t));
void unimpl_mem_init __P((paddr_t));
void unimpl_reboot __P((int howto, char *bootstr));
struct platform platform = {
@ -208,7 +207,6 @@ mach_init(argc, argv, bi)
char *argv[];
struct bootinfo *bi;
{
u_long first, last;
int i;
caddr_t kernend, v;
unsigned size;
@ -388,28 +386,34 @@ mach_init(argc, argv, bi)
Debugger();
#endif
/*
* Find out how much memory is available and clear memory.
*/
physmem = btoc((paddr_t)kernend - MIPS_KSEG0_START) +
(*platform.mem_init)(kernend);
maxmem = physmem;
/* Find physical memory regions. */
(*platform.mem_init)((paddr_t)kernend - MIPS_KSEG0_START);
/*
* Now that we know how much memory we have, initialize the
* mem cluster array.
*/
mem_clusters[0].start = 0; /* XXX is this correct? */
mem_clusters[0].size = ctob(physmem);
mem_cluster_cnt = 1;
printf("mem_cluster_cnt = %d\n", mem_cluster_cnt);
physmem = 0;
for (i = 0; i < mem_cluster_cnt; i++) {
printf("mem_clusters[%d] = {0x%lx,0x%lx}\n", i,
(paddr_t)mem_clusters[i].start,
(paddr_t)mem_clusters[i].size);
physmem += atop(mem_clusters[i].size);
}
/*
* Load the rest of the available pages into the VM system.
*/
first = round_page(MIPS_KSEG0_TO_PHYS(kernend));
last = mem_clusters[0].start + mem_clusters[0].size;
uvm_page_physload(atop(first), atop(last), atop(first),
atop(last), VM_FREELIST_DEFAULT);
/* Cluster 0 is always the kernel, which doesn't get loaded. */
for (i = 1; i < mem_cluster_cnt; i++) {
paddr_t start, size;
start = (paddr_t)mem_clusters[i].start;
size = (paddr_t)mem_clusters[i].size;
printf("loading 0x%lx,0x%lx\n", start, size);
memset((void *)MIPS_PHYS_TO_KSEG1(start), 0,
size);
uvm_page_physload(atop(start), atop(start + size),
atop(start), atop(start + size),
VM_FREELIST_DEFAULT);
}
/*
* Initialize error message buffer (at end of core).
@ -761,9 +765,9 @@ unimpl_intr(mask, pc, statusreg, causereg)
panic("sysconf.init didnt set intr");
}
int
void
unimpl_mem_init(kernend)
caddr_t kernend;
paddr_t kernend;
{
panic("sysconf.init didnt set memory");
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: sysconf.h,v 1.5 1999/12/04 10:55:18 takemura Exp $ */
/* $NetBSD: sysconf.h,v 1.6 2000/02/21 13:46:04 shin Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
@ -86,7 +86,7 @@ extern struct platform {
void (*iointr) __P((void *, unsigned long));
void (*clockintr) __P((void *));
void (*fb_init) __P((caddr_t*));
int (*mem_init) __P((caddr_t));
void (*mem_init) __P((paddr_t));
#ifdef notyet
void (*mcheck_handler) __P((unsigned long, struct trapframe *,
unsigned long, unsigned long));

View File

@ -1,11 +1,11 @@
/* $NetBSD: vmparam.h,v 1.1.1.1 1999/09/16 12:23:24 takemura Exp $ */
/* $NetBSD: vmparam.h,v 1.2 2000/02/21 13:46:04 shin Exp $ */
#include <mips/vmparam.h>
/*
* hpcmips has one physical memory segment.
*/
#define VM_PHYSSEG_MAX 1
#define VM_PHYSSEG_MAX 5
#define VM_NFREELIST 1
#define VM_FREELIST_DEFAULT 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: tx39.c,v 1.13 2000/02/10 02:15:02 sato Exp $ */
/* $NetBSD: tx39.c,v 1.14 2000/02/21 13:46:04 shin Exp $ */
/*
* Copyright (c) 1999, 2000, by UCHIYAMA Yasushi
@ -33,6 +33,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/kcore.h>
#include <machine/locore.h> /* cpu_id */
#include <machine/bootinfo.h> /* bootinfo */
@ -79,7 +80,6 @@ u_int32_t tx39debugflag;
void tx_init __P((void));
int tx39icu_intr __P((u_int32_t, u_int32_t, u_int32_t, u_int32_t));
int tx39_find_dram __P((u_int32_t, u_int32_t));
void tx39clock_cpuspeed __P((int*, int*));
/* TX39-specific initialization vector */
@ -88,11 +88,15 @@ void tx_bus_reset __P((void));
void tx_cons_init __P((void));
void tx_device_register __P((struct device *, void *));
void tx_fb_init __P((caddr_t*));
int tx_mem_init __P((caddr_t));
void tx_mem_init __P((paddr_t));
void tx_find_dram __P((paddr_t, paddr_t));
void tx_reboot __P((int howto, char *bootstr));
int tx_intr __P((u_int32_t mask, u_int32_t pc, u_int32_t statusReg,
u_int32_t causeReg));
extern phys_ram_seg_t mem_clusters[];
extern int mem_cluster_cnt;
void
tx_init()
{
@ -188,46 +192,71 @@ tx_fb_init(kernend)
#endif /* TX392X */
}
int
void
tx_mem_init(kernend)
caddr_t kernend; /* kseg0 */
paddr_t kernend;
{
u_int32_t startaddr, endaddr;
int npage, xpage, kpage;
startaddr = MIPS_PHYS_TO_KSEG1(
(btoc((u_int32_t)kernend - MIPS_KSEG0_START)) << PGSHIFT);
endaddr = MIPS_PHYS_TO_KSEG1(TX39_SYSADDR_DRAMBANK0CS1 +
TX39_SYSADDR_DRAMBANK_LEN);
kpage = btoc(MIPS_KSEG1_TO_PHYS(startaddr));
/* D-RAM bank0 */
npage = tx39_find_dram(startaddr, endaddr);
printf("DRAM bank0: %d pages (%dMByte) reserved %d pages\n",
npage + 1, ((npage + 1) * NBPG) / 0x100000, kpage + 1);
npage -= kpage; /* exclude kernel area */
/* Clear DRAM area */
memset((void*)startaddr, 0, npage * NBPG);
mem_clusters[0].start = 0;
mem_clusters[0].size = kernend;
mem_cluster_cnt = 1;
/* search DRAM bank 0 */
tx_find_dram(kernend, 0x02000000);
/* D-RAM bank1 XXX find only. not usable yet */
startaddr = MIPS_PHYS_TO_KSEG1(TX39_SYSADDR_DRAMBANK1CS1);
endaddr = MIPS_PHYS_TO_KSEG1(TX39_SYSADDR_DRAMBANK1CS1 +
TX39_SYSADDR_DRAMBANK_LEN);
xpage = tx39_find_dram(startaddr, endaddr);
printf("DRAM bank1: %d pages (%dMByte) ...but not usable yet\n",
xpage + 1, ((xpage + 1) * NBPG) / 0x100000);
/* search DRAM bank 1 */
tx_find_dram(0x02000000, 0x04000000);
/*
* Clear currently unused D-RAM area
* (For reboot Windows CE clearly)
*/
memset((void*)startaddr, 0, npage * NBPG);
memset((void*)(KERNBASE + 0x400), 0,
KERNTEXTOFF - KERNBASE - 0x800);
return npage; /* Return bank0's memory only */
memset((void *)(KERNBASE + 0x400), 0, KERNTEXTOFF -
(KERNBASE + 0x800));
}
void
tx_find_dram(start, end)
paddr_t start, end;
{
caddr_t page, startaddr, endaddr;
startaddr = (void*)MIPS_PHYS_TO_KSEG1(start);
endaddr = (void*)MIPS_PHYS_TO_KSEG1(end);
#define DRAM_MAGIC0 0xac1dcafe
#define DRAM_MAGIC1 0x19700220
page = startaddr;
if (badaddr(page, 4))
return;
*(volatile int *)(page+0) = DRAM_MAGIC0;
*(volatile int *)(page+4) = DRAM_MAGIC1;
wbflush();
if (*(volatile int *)(page+0) != DRAM_MAGIC0 ||
*(volatile int *)(page+4) != DRAM_MAGIC1)
return;
for (page += NBPG; page < endaddr; page += NBPG) {
if (badaddr(page, 4))
return;
if (*(volatile int *)(page+0) == DRAM_MAGIC0 &&
*(volatile int *)(page+4) == DRAM_MAGIC1) {
mem_clusters[mem_cluster_cnt].start = start;
mem_clusters[mem_cluster_cnt].size =
page - startaddr;
/* skip kernel area */
if (mem_cluster_cnt == 1)
mem_clusters[mem_cluster_cnt].size -= start;
mem_cluster_cnt++;
return;
}
}
/* no memory in this bank */
return;
}
void
@ -238,30 +267,6 @@ tx_reboot(howto, bootstr)
goto *(u_int32_t *)MIPS_RESET_EXC_VEC;
}
int
tx39_find_dram(startaddr, endaddr)
u_int32_t startaddr; /* kseg1 */
u_int32_t endaddr; /* kseg1 */
{
#define DRAM_MAGIC0 0xac1dcafe
#define DRAM_MAGIC1 0x19700220
u_int32_t page;
int npage;
page = startaddr;
((volatile int *)page)[0] = DRAM_MAGIC0;
((volatile int *)page)[4] = DRAM_MAGIC1;
page += NBPG;
for (npage = 0; page < endaddr; page += NBPG, npage++) {
if ((((volatile int *)page)[0] == DRAM_MAGIC0 &&
((volatile int *)page)[4] == DRAM_MAGIC1)) {
return npage;
}
}
/* no memory in this bank */
return 0;
}
void
tx_bus_reset()
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: vr.c,v 1.12 2000/02/10 02:15:03 sato Exp $ */
/* $NetBSD: vr.c,v 1.13 2000/02/21 13:46:05 shin Exp $ */
/*-
* Copyright (c) 1999
@ -38,6 +38,7 @@
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/reboot.h>
#include <sys/kcore.h>
#include <machine/cpu.h>
#include <machine/intr.h>
@ -108,7 +109,8 @@ int vr_intr __P((u_int32_t mask, u_int32_t pc, u_int32_t statusReg, u_int32_t ca
void vr_cons_init __P((void));
void vr_device_register __P((struct device *, void *));
void vr_fb_init __P((caddr_t*));
int vr_mem_init __P((caddr_t));
void vr_mem_init __P((paddr_t));
void vr_find_dram __P((paddr_t, paddr_t));
void vr_reboot __P((int howto, char *bootstr));
extern unsigned nullclkread __P((void));
@ -127,6 +129,9 @@ static int (*intr_handler[4]) __P((void*, u_int32_t, u_int32_t)) =
};
static void *intr_arg[4];
extern phys_ram_seg_t mem_clusters[];
extern int mem_cluster_cnt;
void
vr_init()
{
@ -157,33 +162,82 @@ vr_init()
#endif
}
int
void
vr_mem_init(kernend)
caddr_t kernend; /* kseg0 */
paddr_t kernend;
{
u_int32_t startaddr, endaddr, page;
int npage;
#define VR41_SYSADDR_DRAMSTART 0x0
#define VR41_SYSADDR_DRAM_LEN 0x04000000
startaddr = MIPS_PHYS_TO_KSEG1(
(btoc((u_int32_t)kernend - MIPS_KSEG0_START)) << PGSHIFT);
endaddr = MIPS_PHYS_TO_KSEG1(VR41_SYSADDR_DRAMSTART +
VR41_SYSADDR_DRAM_LEN);
for(page = startaddr, npage = 0; page < endaddr;
page+= NBPG, npage++) {
if (badaddr((char*)page, 4))
break;
((volatile int *)page)[0] = 0xa5a5a5a5;
((volatile int *)page)[4] = 0x5a5a5a5a;
wbflush();
if (*(volatile int *)page != 0xa5a5a5a5)
break;
}
/* Clear currently unused D-RAM area (For reboot Windows CE clearly)*/
memset((void*)startaddr, 0, npage * NBPG);
memset((void*)(KERNBASE + 0x400), 0, KERNTEXTOFF - KERNBASE - 0x800);
mem_clusters[0].start = 0;
mem_clusters[0].size = kernend;
mem_cluster_cnt = 1;
vr_find_dram(kernend, 0x02000000);
vr_find_dram(0x02000000, 0x04000000);
vr_find_dram(0x04000000, 0x06000000);
vr_find_dram(0x06000000, 0x08000000);
return npage;
/* Clear currently unused D-RAM area (For reboot Windows CE clearly)*/
memset((void *)(KERNBASE + 0x400), 0, KERNTEXTOFF - (KERNBASE + 0x800));
}
void
vr_find_dram(addr, end)
paddr_t addr, end;
{
int n;
caddr_t page;
#ifdef NARLY_MEMORY_PROBE
int x, i;
#endif
n = mem_cluster_cnt;
for (; addr < end; addr += NBPG) {
page = (void *)MIPS_PHYS_TO_KSEG1(addr);
if (badaddr(page, 4))
goto bad;
*(volatile int *)(page+0) = 0xa5a5a5a5;
*(volatile int *)(page+4) = 0x5a5a5a5a;
wbflush();
if (*(volatile int *)(page+0) != 0xa5a5a5a5)
goto bad;
*(volatile int *)(page+0) = 0x5a5a5a5a;
*(volatile int *)(page+4) = 0xa5a5a5a5;
wbflush();
if (*(volatile int *)(page+0) != 0x5a5a5a5a)
goto bad;
#ifdef NARLY_MEMORY_PROBE
x = random();
for (i = 0; i < NBPG; i += 4)
*(volatile int *)(page+i) = (x ^ i);
wbflush();
for (i = 0; i < NBPG; i += 4)
if (*(volatile int *)(page+i) != (x ^ i))
goto bad;
x = random();
for (i = 0; i < NBPG; i += 4)
*(volatile int *)(page+i) = (x ^ i);
wbflush();
for (i = 0; i < NBPG; i += 4)
if (*(volatile int *)(page+i) != (x ^ i))
goto bad;
#endif
if (!mem_clusters[n].size)
mem_clusters[n].start = addr;
mem_clusters[n].size += NBPG;
continue;
bad:
if (mem_clusters[n].size)
++n;
continue;
}
if (mem_clusters[n].size)
++n;
mem_cluster_cnt = n;
}
void