- Make MACHINE_NEW_NONCONTIG non-optional.

- Make initialization of the message buffer a little less magic-looking.
- Maintain two copies of the number and size of physical memory segments.
  One copy, mem_clusters[], contains _all_ of physical RAM, for crash dumps.
  The other copy, phys_seg_list[], starts out with all of physical RAM (and
  is used to initialize mem_clusters[]), but is adjusted to be the memory
  actually managed by the VM system.
- Fix crash dumps with regard to multiple memory segments.
This commit is contained in:
thorpej 1998-03-18 07:11:22 +00:00
parent c0cfbf8d7d
commit c718c9e278
1 changed files with 150 additions and 117 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.34 1998/02/21 19:03:26 scw Exp $ */
/* $NetBSD: machdep.c,v 1.35 1998/03/18 07:11:22 thorpej Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -98,9 +98,7 @@
#include <machine/kcore.h> /* XXX should be pulled in by sys/kcore.h */
#ifdef MACHINE_NEW_NONCONTIG
#include <mvme68k/mvme68k/seglist.h>
#endif
#define MAXMEM 64*1024*CLSIZE /* XXX - from cmap.h */
@ -135,9 +133,11 @@ int bufpages = BUFPAGES;
#else
int bufpages = 0;
#endif
caddr_t msgbufaddr;
caddr_t msgbufaddr; /* KVA of message buffer */
vm_offset_t msgbufpa; /* PA of message buffer */
int maxmem; /* max memory per process */
int physmem = MAXMEM; /* max supported memory, changes to actual */
int physmem; /* size of physical memory */
/*
* safepri is a safe priority for sleep to set for a spin-wait
@ -169,6 +169,20 @@ void cpu_init_kcore_hdr __P((void));
*/
cpu_kcore_hdr_t cpu_kcore_hdr;
/*
* Memory segments initialized in locore, which are eventually loaded
* as managed VM pages.
*/
phys_seg_list_t phys_seg_list[VM_PHYSSEG_MAX];
/*
* Memory segments to dump. This is initialized from the phys_seg_list
* before pages are stolen from it for VM system overhead. I.e. this
* covers the entire range of physical memory.
*/
phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX];
int mem_cluster_cnt;
/*
* On the 68020/68030, the value of delay_divisor is roughly
* 2048 / cpuspeed (where cpuspeed is in MHz).
@ -206,8 +220,13 @@ mvme68k_init()
/*
* Tell the VM system about available physical memory.
*/
#ifdef MACHINE_NEW_NONCONTIG
for (i = 0; i < MAX_PHYS_SEGS && phys_seg_list[i].ps_start; i++)
for (i = 0; i < mem_cluster_cnt; i++) {
if (phys_seg_list[i].ps_start == phys_seg_list[i].ps_end) {
/*
* Segment has been completely gobbled up.
*/
continue;
}
#if defined(UVM)
uvm_page_physload(atop(phys_seg_list[i].ps_start),
atop(phys_seg_list[i].ps_end),
@ -219,7 +238,7 @@ mvme68k_init()
atop(phys_seg_list[i].ps_start),
atop(phys_seg_list[i].ps_end));
#endif
#endif
}
/* Initialize interrupt handlers. */
isrinit();
@ -246,19 +265,11 @@ mvme68k_init()
/*
* Initialize error message buffer (at end of core).
* avail_end was pre-decremented in pmap_bootstrap to compensate.
*/
#ifdef MACHINE_NEW_NONCONTIG
#define MVME_MSG_BUF_START phys_seg_list[0].ps_end
#else
#define MVME_MSG_BUF_START avail_end
#endif
for (i = 0; i < btoc(MSGBUFSIZE); i++)
for (i = 0; i < btoc(round_page(MSGBUFSIZE)); i++)
pmap_enter(pmap_kernel(), (vm_offset_t)msgbufaddr + i * NBPG,
MVME_MSG_BUF_START + i * NBPG, VM_PROT_ALL, TRUE);
msgbufpa + i * NBPG, VM_PROT_ALL, TRUE);
initmsgbuf(msgbufaddr, round_page(MSGBUFSIZE));
#undef MVME_MSG_BUF_START
}
#ifdef MVME147
@ -351,6 +362,7 @@ cpu_startup()
register unsigned i;
register caddr_t v;
int base, residual;
u_quad_t vmememsize;
vm_offset_t minaddr, maxaddr;
vm_size_t size;
#ifdef DEBUG
@ -371,15 +383,12 @@ cpu_startup()
printf(version);
identifycpu();
printf("real mem = %d", ctob(physmem));
#ifdef MACHINE_NEW_NONCONTIG
maxaddr = 0;
for (i = 1; i < MAX_PHYS_SEGS && phys_seg_list[i].ps_start; i++)
maxaddr += phys_seg_list[i].ps_end - phys_seg_list[i].ps_start;
if ( maxaddr )
printf(" (of which %d is offboard)", maxaddr);
#endif
for (vmememsize = 0, i = 1; i < mem_cluster_cnt; i++)
vmememsize += mem_clusters[i].size;
if (vmememsize != 0)
printf(" (%qu on-board, %qu VMEbus)",
mem_clusters[0].size, vmememsize);
printf("\n");
@ -891,6 +900,7 @@ cpu_init_kcore_hdr()
{
cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
struct m68k_kcore_hdr *m = &h->un._m68k;
int i;
extern char end[];
bzero(&cpu_kcore_hdr, sizeof(cpu_kcore_hdr));
@ -942,12 +952,11 @@ cpu_init_kcore_hdr()
/*
* The mvme68k has one or two memory segments.
*
* XXX Dump routines need to be fixed to handle multiple
* XXX segments (VME memory cards).
*/
m->ram_segs[0].start = lowram;
m->ram_segs[0].size = ctob(physmem);
for (i = 0; i < mem_cluster_cnt; i++) {
m->ram_segs[i].start = mem_clusters[i].start;
m->ram_segs[i].size = mem_clusters[i].size;
}
}
/*
@ -963,6 +972,20 @@ cpu_dumpsize()
return (btodb(roundup(size, dbtob(1))));
}
/*
* Calculate size of RAM (in pages) to be dumped.
*/
u_long
cpu_dump_mempagecnt()
{
u_long i, n;
n = 0;
for (i = 0; i < mem_cluster_cnt; i++)
n += atop(mem_clusters[i].size);
return (n);
}
/*
* Called by dumpsys() to dump the machine-dependent header.
*/
@ -1003,143 +1026,153 @@ long dumplo = 0; /* blocks */
* in case there might be a disk label stored there.
* If there is extra space, put dump at the end to
* reduce the chance that swapping trashes it.
*
* XXX This routine will need to change when we support
* XXX VME memory cards.
*/
void
cpu_dumpconf()
{
int chdrsize; /* size of the dump header */
int nblks; /* size of the dump area */
int nblks, dumpblks; /* size of dump area */
int maj;
if (dumpdev == NODEV)
return;
goto bad;
maj = major(dumpdev);
if (maj < 0 || maj >= nblkdev)
panic("dumpconf: bad dumpdev=0x%x", dumpdev);
if (bdevsw[maj].d_psize == NULL)
return;
goto bad;
nblks = (*bdevsw[maj].d_psize)(dumpdev);
chdrsize = cpu_dumpsize();
if (nblks <= ctod(1))
goto bad;
dumpsize = btoc(cpu_kcore_hdr.un._m68k.ram_segs[0].size);
dumpblks = cpu_dumpsize();
if (dumpblks < 0)
goto bad;
dumpblks += ctod(cpu_dump_mempagecnt());
/*
* Check do see if we will fit. Note we always skip the
* first CLBYTES in case there is a disk label there.
*/
if (nblks < (ctod(dumpsize) + chdrsize + ctod(1))) {
dumpsize = 0;
dumplo = -1;
return;
}
/* If dump won't fit (incl. room for possible label), punt. */
if (dumpblks > (nblks - ctod(1)))
goto bad;
/*
* Put dump at the end of the partition.
*/
dumplo = (nblks - 1) - ctod(dumpsize) - chdrsize;
/* Put dump at end of partition */
dumplo = nblks - dumpblks;
/* dumpsize is in page units, and doesn't include headers. */
dumpsize = cpu_dump_mempagecnt();
return;
bad:
dumpsize = 0;
}
/*
* Dump physical memory onto the dump device. Called by cpu_reboot().
*
* XXX This routine will have to change when we support
* XXX VME memory cards.
*/
void
dumpsys()
{
daddr_t blkno; /* current block to write */
/* dump routine */
u_long totalbytesleft, bytes, i, n, memcl;
u_long maddr;
int psize;
daddr_t blkno;
int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
int pg; /* page being dumped */
vm_offset_t maddr; /* PA being dumped */
int error; /* error code from (*dump)() */
int error;
/* XXX initialized here because of gcc lossage */
maddr = lowram;
pg = 0;
/* XXX Should save registers. */
/* Don't put dump messages in msgbuf. */
msgbufenabled = 0;
/* Make sure dump device is valid. */
msgbufenabled = 0; /* don't record dump msgs in msgbuf */
if (dumpdev == NODEV)
return;
/*
* XXX When we support VME memory cards, we'll want to initialize
* XXX the kcore header and call cpu_dumpconf() again here.
* For dumps during autoconfiguration,
* if dump device has already configured...
*/
if (dumpsize == 0) {
if (dumpsize == 0)
cpu_dumpconf();
if (dumpsize == 0)
return;
}
if (dumplo <= 0) {
printf("\ndump to dev %u,%u not possible\n", major(dumpdev),
minor(dumpdev));
return;
}
dump = bdevsw[major(dumpdev)].d_dump;
blkno = dumplo;
printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev),
minor(dumpdev), dumplo);
psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
printf("dump ");
if (psize == -1) {
printf("area unavailable\n");
return;
}
/* Write the dump header. */
error = cpu_dump(dump, &blkno);
if (error)
goto bad;
/* XXX should purge all outstanding keystrokes. */
for (pg = 0; pg < dumpsize; pg++) {
#define NPGMB (1024*1024/NBPG)
/* print out how many MBs we have dumped */
if (pg && (pg % NPGMB) == 0)
printf("%d ", pg / NPGMB);
#undef NPGMB
pmap_enter(pmap_kernel(), (vm_offset_t)vmmap, maddr,
VM_PROT_READ, TRUE);
dump = bdevsw[major(dumpdev)].d_dump;
blkno = dumplo;
error = (*dump)(dumpdev, blkno, vmmap, NBPG);
bad:
switch (error) {
case 0:
maddr += NBPG;
blkno += btodb(NBPG);
break;
if ((error = cpu_dump(dump, &blkno)) != 0)
goto err;
case ENXIO:
printf("device bad\n");
return;
totalbytesleft = ptoa(cpu_dump_mempagecnt());
case EFAULT:
printf("device not ready\n");
return;
for (memcl = 0; memcl < mem_cluster_cnt; memcl++) {
maddr = mem_clusters[memcl].start;
bytes = mem_clusters[memcl].size;
case EINVAL:
printf("area improper\n");
return;
for (i = 0; i < bytes; i += n, totalbytesleft -= n) {
case EIO:
printf("i/o error\n");
return;
/* Print out how many MBs we have left to go. */
if ((totalbytesleft % (1024*1024)) == 0)
printf("%d ", totalbytesleft / (1024 * 1024));
case EINTR:
printf("aborted from console\n");
return;
/* Limit size for next transfer. */
n = bytes - i;
if (n > NBPG)
n = NBPG;
default:
printf("error %d\n", error);
return;
pmap_enter(pmap_kernel(), (vm_offset_t)vmmap, maddr,
VM_PROT_READ, TRUE);
error = (*dump)(dumpdev, blkno, vmmap, n);
if (error)
goto err;
maddr += n;
blkno += btodb(n);
}
}
printf("succeeded\n");
err:
switch (error) {
case ENXIO:
printf("device bad\n");
break;
case EFAULT:
printf("device not ready\n");
break;
case EINVAL:
printf("area improper\n");
break;
case EIO:
printf("i/o error\n");
break;
case EINTR:
printf("aborted from console\n");
break;
case 0:
printf("succeeded\n");
break;
default:
printf("error %d\n", error);
break;
}
printf("\n\n");
delay(5000);
}
void