diff options
-rw-r--r-- | sys/arch/mac68k/mac68k/machdep.c | 452 |
1 files changed, 170 insertions, 282 deletions
diff --git a/sys/arch/mac68k/mac68k/machdep.c b/sys/arch/mac68k/mac68k/machdep.c index ededf3ffdec..eb476df1cc7 100644 --- a/sys/arch/mac68k/mac68k/machdep.c +++ b/sys/arch/mac68k/mac68k/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.41 1997/05/12 19:59:05 gene Exp $ */ +/* $OpenBSD: machdep.c,v 1.42 1997/05/14 04:41:49 gene Exp $ */ /* $NetBSD: machdep.c,v 1.134 1997/02/14 06:15:30 scottr Exp $ */ /* @@ -86,8 +86,6 @@ #include <sys/proc.h> #include <sys/buf.h> #include <sys/exec.h> -#include <sys/core.h> -#include <sys/kcore.h> #include <sys/vnode.h> #include <sys/reboot.h> #include <sys/conf.h> @@ -124,7 +122,6 @@ #include <machine/psl.h> #include <machine/pte.h> #include <machine/bus.h> -#include <machine/kcore.h> /* XXX should be pulled in by sys/kcore.h */ #include <net/netisr.h> #define MAXMEM 64*1024*CLSIZE /* XXX - from cmap.h */ @@ -243,20 +240,10 @@ static iomem_malloc_safe; static void identifycpu __P((void)); static u_long get_physical __P((u_int, u_long *)); +void dumpsys __P((void)); -int dumpsize __P((void)); -int dump __P((int (*)(dev_t, daddr_t, caddr_t, size_t), daddr_t *)); -void init_kcore_hdr __P((void)); - -void dumpsys __P((void)); - -int bus_mem_add_mapping __P((bus_addr_t, bus_size_t, - int, bus_space_handle_t *)); - -/* - * Machine-dependent crash dump header info. - */ -kcore_hdr_t kcore_hdr; +int bus_mem_add_mapping __P((bus_addr_t, bus_size_t, + int, bus_space_handle_t *)); /* * Console initialization: called early on from main, @@ -305,11 +292,6 @@ cpu_startup(void) int delay; /* - * Initialize the kernel crash dump header. - */ - init_kcore_hdr(); - - /* * Initialize error message buffer (at end of core). * high[numranges-1] was decremented in pmap_bootstrap. */ @@ -606,8 +588,10 @@ boot(howto) splhigh(); /* If rebooting and a dump is requested, do it. */ - if (howto & RB_DUMP) + if (howto & RB_DUMP) { + savectx(&dumppcb); /* XXX this goes away soon */ dumpsys(); + } /* Run any shutdown hooks. */ doshutdownhooks(); @@ -629,9 +613,11 @@ boot(howto) * Map ROM where the MacOS likes it, so we can reboot, * hopefully. */ - pmap_map(MacOSROMBase, MacOSROMBase, MacOSROMBase + 4 * 1024 * 1024, - VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE); + pmap_map(MacOSROMBase, MacOSROMBase, + MacOSROMBase + 4 * 1024 * 1024, + VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE); + printf("rebooting...\n"); DELAY(1000000); doboot(); @@ -639,155 +625,27 @@ boot(howto) } /* - * Initialize the kernel crash dump header. - */ -void -init_kcore_hdr() -{ - kcore_hdr_t *h = &kcore_hdr; - struct m68k_kcore_hdr *m = &h->un._m68k; - int i, j, k; - extern char end[]; - - bzero(&kcore_hdr, sizeof(kcore_hdr)); - - /* - * Initialize the `dispatcher' portion of the header. - */ - strcpy(h->name, machine); - h->page_size = NBPG; - h->kernbase = KERNBASE; - - /* - * Fill in information about our MMU configuration. - */ - m->mmutype = mmutype; - m->sg_v = SG_V; - m->sg_frame = SG_FRAME; - m->sg_ishift = SG_ISHIFT; - m->sg_pmask = SG_PMASK; - m->sg40_shift1 = SG4_SHIFT1; - m->sg40_mask2 = SG4_MASK2; - m->sg40_shift2 = SG4_SHIFT2; - m->sg40_mask3 = SG4_MASK3; - m->sg40_shift3 = SG4_SHIFT3; - m->sg40_addr1 = SG4_ADDR1; - m->sg40_addr2 = SG4_ADDR2; - m->pg_v = PG_V; - m->pg_frame = PG_FRAME; - - /* - * Initialize pointer to kernel segment table. - */ - m->sysseg_pa = (u_int32_t)(pmap_kernel()->pm_stpa); - - /* - * Initialize relocation value such that: - * - * pa = (va - KERNBASE) + reloc - */ - m->reloc = load_addr; - - /* - * Define the end of the relocatable range. - */ - m->relocend = (u_int32_t)end; - - /* - * mac68k has multiple RAM segments on some models. - */ - m->ram_segs[0].start = low[0]; - m->ram_segs[0].size = high[0] - low[0]; - for (i = 1; i < numranges; i++) { - if ((high[i] - low[i]) == 0) - continue; /* shouldn't happen, but be safe */ - - /* - * Sort and coalesce RAM segments, as required by libkvm. - */ - for (j = 0; m->ram_segs[j].size; j++) { - if (low[i] < m->ram_segs[j].start) - break; /* Insert before this segment */ - if (low[i] <= - (m->ram_segs[j].start + m->ram_segs[j].size)) - break; /* Overlapping or adjoining */ - } - - if (m->ram_segs[j].size) { - if (low[i] < m->ram_segs[j].start) { - /* Make room for new segment. */ - for (k = j; m->ram_segs[k].size; k++) - /* counting... */; - for (; k > j; k--) { - m->ram_segs[k].start = - m->ram_segs[k - 1].start; - m->ram_segs[k].size = - m->ram_segs[k - 1].size; - } - } else if (low[i] <= - (m->ram_segs[j].start + m->ram_segs[j].size)) { - /* Coalesce segments. */ - if (high[i] > (m->ram_segs[j].start + - m->ram_segs[j].size)) - m->ram_segs[j].size = - high[i] - m->ram_segs[j].start; - continue; - } - } - - m->ram_segs[j].start = low[i]; - m->ram_segs[j].size = high[i] - low[i]; - } -} - -/* - * Compute the size of the machine-dependent crash dump header. - * Returns size in disk blocks. + * These variables are needed by /sbin/savecore */ -int -dumpsize() -{ - int size; +u_long dumpmag = 0x8fca0101; /* magic number */ +int dumpsize = 0; /* pages */ +long dumplo = 0; /* blocks */ - size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(kcore_hdr_t)); - return (btodb(roundup(size, dbtob(1)))); -} +static int get_max_page __P((void)); -/* - * Called by dumpsys() to dump the machine-dependent header. - */ -int -dump(dump, blknop) - int (*dump) __P((dev_t, daddr_t, caddr_t, size_t)); - daddr_t *blknop; +static int +get_max_page() { - int buf[dbtob(1) / sizeof(int)]; - kcore_hdr_t *chdr; - kcore_seg_t *kseg; - int error; - - kseg = (kcore_seg_t *)buf; - chdr = (kcore_hdr_t *)&buf[ALIGN(sizeof(kcore_seg_t)) / - sizeof(int)]; + int i, max = 0; - /* Create the segment header. */ - CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU); - kseg->c_size = dbtob(1) - ALIGN(sizeof(kcore_seg_t)); - - bcopy(&kcore_hdr, chdr, sizeof(kcore_hdr_t)); - error = (*dump)(dumpdev, *blknop, (caddr_t)buf, sizeof(buf)); - *blknop += btodb(sizeof(buf)); - return (error); + for (i = 0; i < numranges; i++) { + if (high[i] > max) + max = high[i]; + } + return max; } /* - * These variables are needed by /sbin/savecore - */ -u_long dumpmag = 0x8fca0101; /* magic number */ -int dumpsize = 0; /* pages */ -long dumplo = 0; /* blocks */ - -/* * This is called by main to set dumplo and dumpsize. * Dumps always skip the first CLBYTES of disk space in * case there might be a disk label stored there. If there @@ -797,12 +655,8 @@ long dumplo = 0; /* blocks */ void dumpconf() { - kcore_hdr_t *h = &kcore_hdr; - struct m68k_kcore_hdr *m = &h->un._m68k; - int chdrsize; /* size of dump header */ - int nblks; /* size of dump area */ - int maj; - int i; + int nblks; + int maj; if (dumpdev == NODEV) return; @@ -813,141 +667,176 @@ dumpconf() if (bdevsw[maj].d_psize == NULL) return; nblks = (*bdevsw[maj].d_psize) (dumpdev); - chdrsize = dumpsize(); + if (nblks <= ctod(1)) + return; - dumpsize = 0; - for (i = 0; m->ram_segs[i].size && i < M68K_NPHYS_RAM_SEGS; i++) - dumpsize += btoc(m->ram_segs[i].size); + dumpsize = btoc(get_max_page()); - /* - * Check to 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; + /* Always skip the first CLBYTES, in case there is a label there. */ + if (dumplo < ctod(1)) + dumplo = ctod(1); + + /* Put dump at end of partition, and make it fit. */ + if (dumpsize > dtoc(nblks - dumplo)) + dumpsize = dtoc(nblks - dumplo); + if (dumplo < nblks - ctod(dumpsize)) + dumplo = nblks - ctod(dumpsize); +} + +/* + * Doadump comes here after turning off memory management and + * getting on the dump stack, either when called above, or by + * the auto-restart code. + */ +#define BYTES_PER_DUMP NBPG /* Must be a multiple of pagesize XXX small */ +static vm_offset_t dumpspace; + +vm_offset_t reserve_dumppages __P((vm_offset_t)); +static int find_range __P((vm_offset_t)); +static int find_next_range __P((vm_offset_t)); + +vm_offset_t +reserve_dumppages(p) + vm_offset_t p; +{ + dumpspace = p; + return (p + BYTES_PER_DUMP); +} + +static int +find_range(pa) + vm_offset_t pa; +{ + int i; + + for (i = 0; i < numranges; i++) { + if (low[i] <= pa && pa < high[i]) + return i; } + return -1; +} - /* - * Put dump at the end of the partition. - */ - dumplo = (nblks - 1) - ctod(dumpsize) - chdrsize; +static int +find_next_range(pa) + vm_offset_t pa; +{ + int i, near, best, t; + + near = -1; + best = 0x7FFFFFFF; + for (i = 0; i < numranges; i++) { + if (low[i] <= pa && pa < high[i]) + return i; + t = low[i] - pa; + if (t > 0) { + if (t < best) { + near = i; + best = t; + } + } + } + return near; } void dumpsys() { - kcore_hdr_t *h = &kcore_hdr; - struct m68k_kcore_hdr *m = &h->un._m68k; - daddr_t blkno; /* current block to write */ - /* dump routine */ - int (*dump) __P((dev_t, daddr_t, caddr_t, size_t)); - int pg; /* page being dumped */ - vm_offset_t maddr; /* PA being dumped */ - int seg; /* RAM segment being dumped */ - int error; /* error code from (*dump)() */ - - /* XXX initialized here because of gcc lossage */ - seg = 0; - maddr = m->ram_segs[seg].start; - pg = 0; - - /* Don't put dump messages in msgbuf. */ - msgbufmapped = 0; - - /* Make sure dump device is valid. */ + unsigned bytes, i, n; + int range; + int maddr, psize; + daddr_t blkno; + int (*dump) __P((dev_t, daddr_t, caddr_t, size_t)); + int error = 0; + + msgbufmapped = 0; /* don't record dump msgs in msgbuf */ if (dumpdev == NODEV) return; - if (dumpsize == 0) { + + /* + * For dumps during autoconfiguration, + * if dump device has already configured... + */ + if (dumpsize == 0) dumpconf(); - if (dumpsize == 0) - return; - } if (dumplo < 0) return; - dump = bdevsw[major(dumpdev)].d_dump; - blkno = dumplo; - printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo); + psize = (*bdevsw[major(dumpdev)].d_psize) (dumpdev); printf("dump "); - - /* Write the dump header. */ - error = dump(dump, &blkno); - if (error) - goto bad; - - 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 - while (maddr >= - (m->ram_segs[seg].start + m->ram_segs[seg].size)) { - if (++seg >= M68K_NPHYS_RAM_SEGS || - m->ram_segs[seg].size == 0) { - error = EINVAL; /* XXX ?? */ - goto bad; + if (psize == -1) { + printf("area unavailable.\n"); + return; + } + bytes = get_max_page(); + maddr = 0; + range = find_range(0); + blkno = dumplo; + dump = bdevsw[major(dumpdev)].d_dump; + for (i = 0; i < bytes; i += n) { + /* + * Avoid dumping "holes." + */ + if ((range == -1) || (i >= high[range])) { + range = find_next_range(i); + if (range == -1) { + error = EIO; + break; } - maddr = m->ram_segs[seg].start; + n = low[range] - i; + maddr += n; + blkno += btodb(n); + continue; } - pmap_enter(pmap_kernel(), (vm_offset_t)vmmap, maddr, - VM_PROT_READ, TRUE); - - error = (*dump)(dumpdev, blkno, vmmap, NBPG); - bad: - switch (error) { - case 0: - maddr += NBPG; - blkno += btodb(NBPG); + /* Print out how many MBs we have to go. */ + n = bytes - i; + if (n && (n % (1024 * 1024)) == 0) + printf("%d ", n / (1024 * 1024)); + + /* Limit size for next transfer. */ + if (n > BYTES_PER_DUMP) + n = BYTES_PER_DUMP; + + (void) pmap_map(dumpspace, maddr, maddr + n, VM_PROT_READ); + error = (*dump) (dumpdev, blkno, (caddr_t) dumpspace, n); + if (error) break; + maddr += n; + blkno += btodb(n); /* XXX? */ + } - case ENXIO: - printf("device bad\n"); - return; - - case EFAULT: - printf("device not ready\n"); - return; + switch (error) { - case EINVAL: - printf("area improper\n"); - return; + case ENXIO: + printf("device bad\n"); + break; - case EIO: - printf("i/o error\n"); - return; + case EFAULT: + printf("device not ready\n"); + break; - case EINTR: - printf("aborted from console\n"); - return; + case EINVAL: + printf("area improper\n"); + break; - default: - printf("error %d\n", error); - return; - } - } - printf("succeeded\n"); -} + case EIO: + printf("i/o error\n"); + break; -/* - * Doadump comes here after turning off memory management and - * getting on the dump stack, either when called above, or by - * the auto-restart code. - */ -#define BYTES_PER_DUMP NBPG /* Must be a multiple of pagesize XXX small */ -static vm_offset_t dumpspace; + case EINTR: + printf("aborted from console\n"); + break; -vm_offset_t reserve_dumppages __P((vm_offset_t)); + case 0: + printf("succeeded\n"); + break; -vm_offset_t -reserve_dumppages(p) - vm_offset_t p; -{ - dumpspace = p; - return (p + BYTES_PER_DUMP); + default: + printf("error %d\n", error); + break; + } + printf("\n\n"); + delay(5000000); /* 5 seconds */ } /* @@ -1301,10 +1190,9 @@ getenvvars(flag, buf) char *buf; { extern u_long bootdev, videobitdepth, videosize; - extern u_long esym; + extern u_long end, esym; extern u_long macos_boottime, MacOSROMBase; extern long macos_gmtbias; - extern char end[]; int root_scsi_id; /* @@ -1367,7 +1255,7 @@ getenvvars(flag, buf) #ifndef SYMTAB_SPACE if (esym == 0) #endif - esym = (u_int32_t)end; + esym = (long) &end; /* Get MacOS time */ macos_boottime = getenv("BOOTTIME"); |