Kernel crash dumps now work on the sun3. (Yea!)

This commit is contained in:
gwr 1996-05-05 06:02:23 +00:00
parent 99d2ff44d8
commit 4f0e481bc3
4 changed files with 274 additions and 82 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore2.c,v 1.51 1996/03/26 15:16:59 gwr Exp $ */
/* $NetBSD: locore2.c,v 1.52 1996/05/05 06:02:37 gwr Exp $ */
/*
* Copyright (c) 1994 Gordon W. Ross
@ -93,6 +93,9 @@ vm_offset_t proc0_user_pa;
struct user *proc0paddr; /* proc[0] pcb address (u-area VA) */
extern struct pcb *curpcb;
extern vm_offset_t dumppage_pa;
extern vm_offset_t dumppage_va;
/*
* Switch to our own interrupt vector table.
*/
@ -396,14 +399,16 @@ void sun3_vm_init(kehp)
/*
* Virtual and physical pages for proc[0] u-area (already mapped)
* XXX - Make these non-cached at their full-time mapping address.
* XXX - Still need to do that? -gwr
*/
proc0paddr = (struct user *) virtual_avail;
proc0_user_pa = avail_start;
virtual_avail += UPAGES*NBPG;
avail_start += UPAGES*NBPG;
/* Make them non-cached. */
avail_start += UPAGES*NBPG;
#if 0
/* Make them non-cached.
* XXX - Make these non-cached at their full-time mapping address.
* XXX - Still need to do that? -gwr
*/
va = (vm_offset_t) proc0paddr;
while (va < virtual_avail) {
pte = get_pte(va);
@ -411,6 +416,15 @@ void sun3_vm_init(kehp)
set_pte(va, pte);
va += NBPG;
}
#endif
/*
* Virtual and physical page used by dumpsys()
*/
dumppage_va = virtual_avail;
dumppage_pa = avail_start;
virtual_avail += NBPG;
avail_start += NBPG;
/*
* XXX - Make sure avail_start is within the low 1M range
@ -749,34 +763,39 @@ char *str;
/*
* Set the PROM vector handler (for g0, g4, etc.)
* and set boothowto from the PROM arg strings.
*
* Note, args are always:
* argv[0] = boot_device (i.e. "sd(0,0,0)")
* argv[1] = options (i.e. "-ds" or NULL)
* argv[2] = NULL
*/
void sun3_monitor_hooks()
{
MachMonBootParam *bpp;
char **argp;
char *p;
int i;
if (romp->romvecVersion >= 2)
*romp->vector_cmd = v_handler;
/* Set boothowto flags from PROM args. */
bpp = *romp->bootParam;
for (i = 0; i < 8; i++) {
p = bpp->argPtr[i];
argp = bpp->argPtr;
/* Null arg? We're done. */
if (p == NULL || *p == '\0')
break;
/* Skip argp[0] (the device string) */
argp++;
/* Have options? */
if (*argp == NULL)
return;
p = *argp;
if (*p == '-') {
/* yes, parse options */
#ifdef DEBUG
mon_printf("arg[%d]=\"%s\"\n", i, p);
mon_printf("boot option: %s\n", p);
#endif
/* Not switches? Skip it. */
if (*p++ != '-')
continue;
while (*p) {
switch (*p++) {
for (++p; *p; p++) {
switch (*p) {
case 'a':
boothowto |= RB_ASKNAME;
break;
@ -788,24 +807,18 @@ void sun3_monitor_hooks()
break;
}
}
argp++;
}
#ifdef DEBUG
mon_printf("boothowto=0x%x\n", boothowto);
/* Have init name? */
if (*argp == NULL)
return;
p = *argp;
mon_printf("boot initpath: %s\n", p);
#endif
}
void set_interrupt_reg(value)
unsigned int value;
{
*interrupt_reg = (unsigned char) value;
}
unsigned int get_interrupt_reg()
{
vm_offset_t pte;
return (unsigned int) *interrupt_reg;
}
/*
* Find mappings for devices that are needed before autoconfiguration.
* First the obio module finds and records useful PROM mappings, then

View File

@ -1,4 +1,5 @@
/* $NetBSD: machdep.c,v 1.71 1996/03/26 15:16:53 gwr Exp $ */
/* $NetBSD: machdep.c,v 1.72 1996/05/05 06:02:23 gwr Exp $ */
/*
* Copyright (c) 1994, 1995 Gordon W. Ross
@ -63,6 +64,8 @@
#include <sys/mount.h>
#include <sys/user.h>
#include <sys/exec.h>
#include <sys/core.h>
#include <sys/kcore.h>
#include <sys/vnode.h>
#include <sys/sysctl.h>
#include <sys/syscallargs.h>
@ -82,6 +85,7 @@
#include <machine/pte.h>
#include <machine/mon.h>
#include <machine/isr.h>
#include <machine/kcore.h>
#include <dev/cons.h>
@ -102,6 +106,7 @@ extern int cold;
int physmem;
int fpu_type;
int msgbufmapped;
/*
* safepri is a safe priority for sleep to set for a spin-wait
@ -764,8 +769,6 @@ static void reboot_sync()
vfs_shutdown();
}
struct pcb dumppcb;
/*
* Common part of the BSD and SunOS reboot system calls.
*/
@ -797,10 +800,8 @@ int reboot2(howto, user_boot_string)
splhigh();
/* Write out a crash dump if asked. */
if (howto & RB_DUMP) {
savectx(&dumppcb);
if (howto & RB_DUMP)
dumpsys();
}
/* run any shutdown hooks */
doshutdownhooks();
@ -862,6 +863,12 @@ u_long dumpmag = 0x8fca0101; /* magic number */
int dumpsize = 0; /* pages */
long dumplo = 0; /* blocks */
/* Our private scratch page for dumping the MMU. */
vm_offset_t dumppage_va;
vm_offset_t dumppage_pa;
#define DUMP_EXTRA 3 /* CPU-dependent extra pages */
/*
* This is called by cpu_startup to set dumplo, dumpsize.
* Dumps always skip the first CLBYTES of disk space
@ -890,37 +897,147 @@ dumpconf()
return;
/* Position dump image near end of space, page aligned. */
dumpsize = physmem; /* pages */
dumpsize = physmem + DUMP_EXTRA; /* pages */
dumplo = nblks - ctod(dumpsize);
dumplo &= ~(ctod(1)-1);
/* If it does not fit, truncate it by moving dumplo. */
/* Note: Must force signed comparison (fixes PR#887) */
/* Note: Must force signed comparison. */
if (dumplo < ((long)ctod(1))) {
dumplo = ctod(1);
dumpsize = dtoc(nblks - dumplo);
}
}
struct pcb dumppcb;
extern vm_offset_t avail_start;
/*
* Write a crash dump.
* Write a crash dump. The format while in swap is:
* kcore_seg_t cpu_hdr;
* cpu_kcore_hdr_t cpu_data;
* padding (NBPG-sizeof(kcore_seg_t))
* pagemap (2*NBPG)
* physical memory...
*/
dumpsys()
{
#if 1
printf("dumping not supported yet :)\n");
#else
struct bdevsw *dsw;
kcore_seg_t *kseg_p;
cpu_kcore_hdr_t *chdr_p;
char *vaddr;
vm_offset_t paddr;
int psize, todo, chunk;
daddr_t blkno;
int error = 0;
msgbufmapped = 0;
if (dumpdev == NODEV)
return;
if (dumpsize == 0) {
if (dumppage_va == 0)
return;
/*
* For dumps during autoconfiguration,
* if dump device has already configured...
*/
if (dumpsize == 0)
dumpconf();
if (dumpsize == 0)
return;
if (dumplo <= 0)
return;
savectx(&dumppcb);
dsw = &bdevsw[major(dumpdev)];
psize = (*(dsw->d_psize))(dumpdev);
if (psize == -1) {
printf("dump area unavailable\n");
return;
}
printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
/* XXX - todo... */
#endif
/*
* Write the dump header, including MMU state.
*/
blkno = dumplo;
todo = dumpsize - DUMP_EXTRA; /* pages */
vaddr = (char*)dumppage_va;
bzero(vaddr, NBPG);
/* kcore header */
kseg_p = (kcore_seg_t *)vaddr;
CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
kseg_p->c_size = (ctob(DUMP_EXTRA) - sizeof(kcore_seg_t));
/* MMU state */
chdr_p = (cpu_kcore_hdr_t *) (kseg_p + 1);
pmap_get_ksegmap(chdr_p->ksegmap);
error = (*dsw->d_dump)(dumpdev, blkno, vaddr, NBPG);
if (error)
goto fail;
blkno += btodb(NBPG);
/* translation RAM (page zero) */
pmap_get_pagemap(vaddr, 0);
error = (*dsw->d_dump)(dumpdev, blkno, vaddr, NBPG);
if (error)
goto fail;
blkno += btodb(NBPG);
/* translation RAM (page one) */
pmap_get_pagemap(vaddr, NBPG);
error = (*dsw->d_dump)(dumpdev, blkno, vaddr, NBPG);
if (error)
goto fail;
blkno += btodb(NBPG);
/*
* Now dump physical memory. Have to do it in two chunks.
* The first chunk is "unmanaged" (by the VM code) and its
* range of physical addresses is not allow in pmap_enter.
* However, that segment is mapped linearly, so we can just
* use the virtual mappings already in place. The second
* chunk is done the normal way, using pmap_enter.
*
* Note that vaddr==(paddr+KERNBASE) for paddr=0 through etext.
*/
/* Do the first chunk (0 <= PA < avail_start) */
paddr = 0;
chunk = btoc(avail_start);
if (chunk > todo)
chunk = todo;
do {
if ((todo & 0xf) == 0)
printf("\r%4d", todo);
vaddr = (char*)(paddr + KERNBASE);
error = (*dsw->d_dump)(dumpdev, blkno, vaddr, NBPG);
if (error)
goto fail;
paddr += NBPG;
blkno += btodb(NBPG);
--todo;
} while (--chunk > 0);
/* Do the second chunk (avail_start <= PA < dumpsize) */
vaddr = (char*)vmmap; /* Borrow /dev/mem VA */
do {
if ((todo & 0xf) == 0)
printf("\r%4d", todo);
pmap_enter(pmap_kernel(), vmmap, paddr | PMAP_NC,
VM_PROT_READ, FALSE);
error = (*dsw->d_dump)(dumpdev, blkno, vaddr, NBPG);
pmap_remove(pmap_kernel(), vmmap, vmmap + NBPG);
if (error)
goto fail;
paddr += NBPG;
blkno += btodb(NBPG);
} while (--todo > 0);
printf("\rdump succeeded\n");
return;
fail:
printf(" dump error=%d\n", error);
}
initcpu()

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.c,v 1.60 1996/02/28 22:51:05 gwr Exp $ */
/* $NetBSD: pmap.c,v 1.61 1996/05/05 06:02:31 gwr Exp $ */
/*
* Copyright (c) 1994, 1995 Gordon W. Ross
@ -3217,6 +3217,55 @@ pmap_prefer(fo, va)
*va += d;
}
/*
* Copy the kernel segmap into the passed buffer (256 bytes).
*/
void
pmap_get_ksegmap(vaddr)
vm_offset_t vaddr;
{
vm_offset_t va;
u_char *cp = (u_char*)vaddr;
va = KERNBASE;
do {
*cp = get_segmap(va);
cp++;
va += NBSG;
} while (va < 0x10000000);
}
/*
* Copy the pagemap RAM into the passed buffer (one page)
* starting at OFF in the pagemap RAM.
*/
void
pmap_get_pagemap(vaddr, off)
vm_offset_t vaddr;
int off;
{
vm_offset_t va, va_end;
int sme, sme_end; /* SegMap Entry numbers */
int *pt;
pt = (int*)vaddr; /* destination */
sme = (off >> 6); /* PMEG to start on */
sme_end = sme + 128; /* where to stop */
va_end = temp_seg_va + NBSG;
do {
set_segmap(temp_seg_va, sme);
va = temp_seg_va;
do {
*pt++ = get_pte(va);
va += NBPG;
} while (va < va_end);
sme++;
} while (sme < sme_end);
set_segmap(temp_seg_va, SEGINV);
}
/*
* Helper functions for changing unloaded PMEGs
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: sun3_startup.c,v 1.51 1996/03/26 15:16:59 gwr Exp $ */
/* $NetBSD: sun3_startup.c,v 1.52 1996/05/05 06:02:37 gwr Exp $ */
/*
* Copyright (c) 1994 Gordon W. Ross
@ -93,6 +93,9 @@ vm_offset_t proc0_user_pa;
struct user *proc0paddr; /* proc[0] pcb address (u-area VA) */
extern struct pcb *curpcb;
extern vm_offset_t dumppage_pa;
extern vm_offset_t dumppage_va;
/*
* Switch to our own interrupt vector table.
*/
@ -396,14 +399,16 @@ void sun3_vm_init(kehp)
/*
* Virtual and physical pages for proc[0] u-area (already mapped)
* XXX - Make these non-cached at their full-time mapping address.
* XXX - Still need to do that? -gwr
*/
proc0paddr = (struct user *) virtual_avail;
proc0_user_pa = avail_start;
virtual_avail += UPAGES*NBPG;
avail_start += UPAGES*NBPG;
/* Make them non-cached. */
avail_start += UPAGES*NBPG;
#if 0
/* Make them non-cached.
* XXX - Make these non-cached at their full-time mapping address.
* XXX - Still need to do that? -gwr
*/
va = (vm_offset_t) proc0paddr;
while (va < virtual_avail) {
pte = get_pte(va);
@ -411,6 +416,15 @@ void sun3_vm_init(kehp)
set_pte(va, pte);
va += NBPG;
}
#endif
/*
* Virtual and physical page used by dumpsys()
*/
dumppage_va = virtual_avail;
dumppage_pa = avail_start;
virtual_avail += NBPG;
avail_start += NBPG;
/*
* XXX - Make sure avail_start is within the low 1M range
@ -749,34 +763,39 @@ char *str;
/*
* Set the PROM vector handler (for g0, g4, etc.)
* and set boothowto from the PROM arg strings.
*
* Note, args are always:
* argv[0] = boot_device (i.e. "sd(0,0,0)")
* argv[1] = options (i.e. "-ds" or NULL)
* argv[2] = NULL
*/
void sun3_monitor_hooks()
{
MachMonBootParam *bpp;
char **argp;
char *p;
int i;
if (romp->romvecVersion >= 2)
*romp->vector_cmd = v_handler;
/* Set boothowto flags from PROM args. */
bpp = *romp->bootParam;
for (i = 0; i < 8; i++) {
p = bpp->argPtr[i];
argp = bpp->argPtr;
/* Null arg? We're done. */
if (p == NULL || *p == '\0')
break;
/* Skip argp[0] (the device string) */
argp++;
/* Have options? */
if (*argp == NULL)
return;
p = *argp;
if (*p == '-') {
/* yes, parse options */
#ifdef DEBUG
mon_printf("arg[%d]=\"%s\"\n", i, p);
mon_printf("boot option: %s\n", p);
#endif
/* Not switches? Skip it. */
if (*p++ != '-')
continue;
while (*p) {
switch (*p++) {
for (++p; *p; p++) {
switch (*p) {
case 'a':
boothowto |= RB_ASKNAME;
break;
@ -788,24 +807,18 @@ void sun3_monitor_hooks()
break;
}
}
argp++;
}
#ifdef DEBUG
mon_printf("boothowto=0x%x\n", boothowto);
/* Have init name? */
if (*argp == NULL)
return;
p = *argp;
mon_printf("boot initpath: %s\n", p);
#endif
}
void set_interrupt_reg(value)
unsigned int value;
{
*interrupt_reg = (unsigned char) value;
}
unsigned int get_interrupt_reg()
{
vm_offset_t pte;
return (unsigned int) *interrupt_reg;
}
/*
* Find mappings for devices that are needed before autoconfiguration.
* First the obio module finds and records useful PROM mappings, then