Kernel crash dumps now work on the sun3. (Yea!)
This commit is contained in:
parent
99d2ff44d8
commit
4f0e481bc3
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue