#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.94 2026/04/28 03:29:09 thorpej Exp $");
#include "opt_bufcache.h"
#include "opt_ddb.h"
#include "opt_kgdb.h"
#include "opt_sysv.h"
#include "opt_panicbutton.h"
#include "opt_modular.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/callout.h>
#include <sys/conf.h>
#include <sys/exec.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/kernel.h>
#include <sys/mbuf.h>
#include <sys/mount.h>
#include <sys/msgbuf.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/signalvar.h>
#include <sys/syscallargs.h>
#include <sys/tty.h>
#include <sys/vnode.h>
#include <sys/ksyms.h>
#include <sys/module.h>
#include <sys/cpu.h>
#include <sys/kgdb.h>
#include <machine/db_machdep.h>
#include <ddb/db_sym.h>
#include <ddb/db_extern.h>
#include <machine/autoconf.h>
#include <machine/cpu.h>
#include <machine/reg.h>
#include <machine/pcb.h>
#include <machine/psl.h>
#include <machine/pte.h>
#include <m68k/seglist.h>
#define MAXMEM 64*1024
#include <uvm/uvm_extern.h>
#include <sys/sysctl.h>
#include <sys/device.h>
#include <dev/cons.h>
#include <dev/mm.h>
#include <dev/ic/z8530reg.h>
#include <machine/z8530var.h>
#include <cesfic/dev/zsvar.h>
#include "ksyms.h"
extern u_int lowram;
void machine_init(paddr_t);
char *hexstr(int, int);
void dumpsys(void);
void nmihand(struct frame);
int delay_divisor;
extern void sicinit(void*);
struct pmap_bootmap machine_bootmap[] = {
{ .pmbm_vaddr = -1 },
};
void
machine_init(paddr_t nextpa)
{
boothowto = RB_SINGLE;
boothowto |= RB_KDB;
delay_divisor = delay_divisor_est40(25);
phys_seg_list[0].ps_start = lowram;
phys_seg_list[0].ps_end = lowram + m68k_ptob(physmem);
machine_init_common(nextpa);
physaccess((void*)virtual_avail, (void*)0x44000000,
PAGE_SIZE, PG_RW|PG_CI);
sicinit((void*)virtual_avail);
virtual_avail += PAGE_SIZE;
}
int
zs_check_kgdb(struct zs_chanstate *cs, int dev)
{
if((boothowto & RB_KDB) && (dev == makedev(10, 0)))
return (1);
return (0);
}
void zs_kgdb_cnputc(dev_t, int);
void zs_kgdb_cnputc(dev_t dev, int c)
{
zscnputc(dev, c);
}
int zs_kgdb_cngetc(dev_t);
int zs_kgdb_cngetc(dev_t dev)
{
return (zscngetc(dev));
}
extern void sic_enable_int(int, int, int, int, int);
void
consinit(void)
{
physaccess((void*)virtual_avail,
(void*)0x58000000, PAGE_SIZE, PG_RW|PG_CI);
zs_cnattach((void*)virtual_avail);
virtual_avail += PAGE_SIZE;
#ifdef KGDB
kgdb_dev = 1;
kgdb_attach((void*)zscngetc, (void*)zscnputc, (void *)0);
if (boothowto & RB_KDB) {
kgdb_connect(1);
zscons.cn_putc = zs_kgdb_cnputc;
zscons.cn_getc = zs_kgdb_cngetc;
}
#endif
#ifdef DDB
if (boothowto & RB_KDB)
Debugger();
#endif
sic_enable_int(39, 2, 1, 7, 0);
}
void
cpu_startup(void)
{
cpu_startup_common();
printf("delay constant: %d\n", delay_divisor);
}
void
machine_set_model(void)
{
cpu_setmodel("FIC8234");
}
SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
{
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_NODE, "machdep", NULL,
NULL, 0, NULL, 0,
CTL_MACHDEP, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_STRUCT, "console_device", NULL,
sysctl_consdev, 0, NULL, sizeof(dev_t),
CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
}
u_int32_t dumpmag = 0x8fca0101;
int dumpsize = 0;
long dumplo = 0;
void
cpu_dumpconf(void)
{
int nblks;
if (dumpdev == NODEV)
return;
nblks = bdev_size(dumpdev);
if (nblks <= ctod(1))
return;
dumpsize = physmem + 1;
if (dumplo < ctod(1))
dumplo = ctod(1);
if (dumpsize > dtoc(nblks - dumplo))
dumpsize = dtoc(nblks - dumplo);
if (dumplo < nblks - ctod(dumpsize))
dumplo = nblks - ctod(dumpsize);
}
void
dumpsys(void)
{
const struct bdevsw *bdev;
daddr_t blkno;
int (*dump)(dev_t, daddr_t, void *, size_t);
int pg;
vm_offset_t maddr;
int error;
msgbufmapped = 0;
if (dumpdev == NODEV)
return;
bdev = bdevsw_lookup(dumpdev);
if (bdev == NULL)
return;
if (dumpsize == 0) {
cpu_dumpconf();
if (dumpsize == 0)
return;
}
if (dumplo < 0)
return;
dump = bdev->d_dump;
blkno = dumplo;
printf("\ndumping to dev %"PRIx64", offset %ld\n", dumpdev, dumplo);
printf("dump ");
maddr = lowram;
for (pg = 0; pg < dumpsize; pg++) {
#define NPGMB (1024*1024/PAGE_SIZE)
if (pg && (pg % NPGMB) == 0)
printf("%d ", pg / NPGMB);
#undef NPGMB
pmap_enter(pmap_kernel(), (vm_offset_t)vmmap, maddr,
VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
pmap_update(pmap_kernel());
error = (*dump)(dumpdev, blkno, vmmap, PAGE_SIZE);
switch (error) {
case 0:
maddr += PAGE_SIZE;
blkno += btodb(PAGE_SIZE);
break;
case ENXIO:
printf("device bad\n");
return;
case EFAULT:
printf("device not ready\n");
return;
case EINVAL:
printf("area improper\n");
return;
case EIO:
printf("i/o error\n");
return;
case EINTR:
printf("aborted from console\n");
return;
default:
printf("error %d\n", error);
return;
}
}
printf("succeeded\n");
}
#ifdef PANICBUTTON
int panicbutton = 1;
int candbdiv = 2;
void candbtimer(void *);
int crashandburn;
void
candbtimer(void *arg)
{
crashandburn = 0;
}
#endif
static int innmihand;
void
nmihand(struct frame frame)
{
if (innmihand)
return;
innmihand = 1;
printf("NMI\n");
#if defined(DDB) || defined(KGDB)
Debugger();
#endif
innmihand = 0;
}