#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.389 2026/06/13 15:28:09 thorpej Exp $");
#include "opt_adb.h"
#include "opt_copy_symtab.h"
#include "opt_ddb.h"
#include "opt_ddbparam.h"
#include "opt_kgdb.h"
#include "opt_mac68k.h"
#include "opt_modular.h"
#include "akbd.h"
#include "audio.h"
#include "genfb.h"
#include "macfb.h"
#include "zsc.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/conf.h>
#include <sys/core.h>
#include <sys/exec.h>
#include <sys/extent.h>
#include <sys/file.h>
#include <sys/kcore.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mount.h>
#include <sys/msgbuf.h>
#include <sys/pool.h>
#include <sys/proc.h>
#include <sys/queue.h>
#include <sys/reboot.h>
#include <sys/signalvar.h>
#include <sys/syscallargs.h>
#include <sys/vnode.h>
#include <sys/ksyms.h>
#include <sys/module.h>
#ifdef KGDB
#include <sys/kgdb.h>
#endif
#include <sys/exec_elf.h>
#include <sys/device.h>
#include <sys/cpu.h>
#include <m68k/cacheops.h>
#include <m68k/mmu_40.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 <machine/kcore.h>
#include <machine/video.h>
#define MAXMEM 64*1024
#include <uvm/uvm_extern.h>
#include <sys/sysctl.h>
#include <dev/cons.h>
#include <dev/mm.h>
#include <machine/iopreg.h>
#include <machine/psc.h>
#include <machine/viareg.h>
#include <mac68k/mac68k/macrom.h>
#include <mac68k/dev/adbvar.h>
#if NAKBD > 0
#include <mac68k/dev/akbdvar.h>
#endif
#if NMACFB > 0
#include <mac68k/dev/macfbvar.h>
#endif
#include <mac68k/dev/pm_direct.h>
#include <mac68k/dev/zs_cons.h>
#include "ksyms.h"
int symsize, end, *ssym, *esym;
struct mac68k_machine_S mac68k_machine;
volatile u_char *Via1Base, *Via2Base, *PSCBase = NULL;
u_long NuBusBase = NBBASE;
u_long IOBase;
vaddr_t SCSIBase;
int numranges;
u_long low[8];
u_long high[8];
u_long last_page;
vaddr_t newvideoaddr;
int vidlen;
extern paddr_t avail_start, avail_end;
extern int machineid;
#define NBMAXRANGES 16
int nbnumranges;
u_long nbphys[NBMAXRANGES];
u_long nblog[NBMAXRANGES];
long nblen[NBMAXRANGES];
struct mac68k_video mac68k_video;
int (*mac68k_bell_callback)(void *, int, int, int);
void * mac68k_bell_cookie;
int maxmem;
static long iomem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)];
struct extent *iomem_ex;
int iomem_malloc_safe;
static u_long get_physical(u_int, u_long *);
void initcpu(void);
int cpu_dumpsize(void);
int cpu_dump(int (*)(dev_t, daddr_t, void *, size_t), daddr_t *);
void cpu_init_kcore_hdr(void);
void getenvvars(u_long, char *);
static long getenv(const char *);
void dumpsys(void);
void machine_init(paddr_t);
void nmihand(struct frame);
cpu_kcore_hdr_t cpu_kcore_hdr;
volatile unsigned char *sccA = 0;
void
machine_init(paddr_t nextpa)
{
int i;
for (i = 0; i < numranges; i++) {
if (low[i] <= avail_start && avail_start < high[i])
uvm_page_physload(atop(avail_start), atop(high[i]),
atop(avail_start), atop(high[i]),
VM_FREELIST_DEFAULT);
else
uvm_page_physload(atop(low[i]), atop(high[i]),
atop(low[i]), atop(high[i]),
VM_FREELIST_DEFAULT);
}
#ifdef __HAVE_NEW_PMAP_68K
extern char start[], etext[];
pmap_protect(pmap_kernel(), m68k_round_page((vaddr_t)start),
m68k_trunc_page((vaddr_t)etext),
UVM_PROT_READ | UVM_PROT_EXEC);
pmap_update(pmap_kernel());
#endif
iomem_ex = extent_create("iomem", 0x0, 0xffffffff,
(void *)iomem_ex_storage, sizeof(iomem_ex_storage),
EX_NOCOALESCE|EX_NOWAIT);
intr_init();
iop_init(1);
for (i = 0; i < btoc(MSGBUFSIZE); i++)
pmap_enter(pmap_kernel(), (vaddr_t)msgbufaddr + i * PAGE_SIZE,
high[numranges - 1] + i * PAGE_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE));
pmap_update(pmap_kernel());
}
void
consinit(void)
{
static int init;
if (!init) {
cninit();
init = 1;
} else {
#if NAKBD > 0 && (NMACFB + NGENFB) > 0
if (mac68k_machine.serial_console == 0) {
void maccninit(struct consdev *);
maccninit(NULL);
}
#endif
mac68k_calibrate_delay();
#if NZSC > 0 && defined(KGDB)
zs_kgdb_init();
#endif
#if NKSYMS || defined(DDB) || defined(MODULAR)
ksyms_addsyms_elf(symsize, ssym, esym);
#endif
if (boothowto & RB_KDB) {
#ifdef KGDB
kgdb_connect(1);
#else
#ifdef DDB
Debugger();
#endif
#endif
}
}
}
#define CURRENTBOOTERVER 111
void
cpu_startup(void)
{
int vers;
int xdelay;
cpu_init_kcore_hdr();
cpu_startup_common();
vers = mac68k_machine.booter_version;
if (vers < CURRENTBOOTERVER) {
if (vers < 100)
vers += 99;
printf("\nYou booted with booter version %d.%d.\n",
vers / 100, vers % 100);
printf("Booter version %d.%d is necessary to fully support\n",
CURRENTBOOTERVER / 100, CURRENTBOOTERVER % 100);
printf("this kernel.\n\n");
for (xdelay = 0; xdelay < 1000000; xdelay++);
}
extern u_int delay_factor;
printf("cpu: delay factor %d\n", delay_factor);
initcpu();
iomem_malloc_safe = 1;
}
void
initcpu(void)
{
DCIS();
}
void doboot(void) __attribute__((__noreturn__));
struct pcb dumppcb;
void
machine_powerdown(void)
{
via_powerdown();
#ifndef MRG_ADB
adb_poweroff();
#endif
pm_poweroff();
}
void
machine_reboot(int howto, char *bootstr)
{
extern u_long last_page;
pmap_enter(pmap_kernel(), (vaddr_t)last_page, (vaddr_t)last_page,
VM_PROT_ALL, VM_PROT_ALL|PMAP_WIRED);
pmap_update(pmap_kernel());
doboot();
}
void
cpu_init_kcore_hdr(void)
{
phys_ram_seg_t *ram_segs = pmap_init_kcore_hdr(&cpu_kcore_hdr);
int i;
for (i = 0; i < numranges; i++) {
ram_segs[i].start = low[i];
ram_segs[i].size = high[i] - low[i];
}
}
#define CHDRSIZE (ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)))
#define MDHDRSIZE roundup(CHDRSIZE, dbtob(1))
int
cpu_dumpsize(void)
{
return btodb(MDHDRSIZE);
}
int
cpu_dump(int (*dump)(dev_t, daddr_t, void *, size_t), daddr_t *blknop)
{
int buf[MDHDRSIZE / sizeof(int)];
cpu_kcore_hdr_t *chdr;
kcore_seg_t *kseg;
int error;
kseg = (kcore_seg_t *)buf;
chdr = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(kcore_seg_t)) /
sizeof(int)];
CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
kseg->c_size = MDHDRSIZE - ALIGN(sizeof(kcore_seg_t));
memcpy(chdr, &cpu_kcore_hdr, sizeof(cpu_kcore_hdr_t));
error = (*dump)(dumpdev, *blknop, (void *)buf, sizeof(buf));
*blknop += btodb(sizeof(buf));
return (error);
}
u_int32_t dumpmag = 0x8fca0101;
int dumpsize = 0;
long dumplo = 0;
void
cpu_dumpconf(void)
{
cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
struct m68k_kcore_hdr *m = &h->un._m68k;
int chdrsize;
int nblks;
int i;
if (dumpdev == NODEV)
return;
nblks = bdev_size(dumpdev);
chdrsize = cpu_dumpsize();
dumpsize = 0;
for (i = 0; i < M68K_NPHYS_RAM_SEGS && m->ram_segs[i].size; i++)
dumpsize += btoc(m->ram_segs[i].size);
if (nblks < (ctod(dumpsize) + chdrsize + ctod(1))) {
dumpsize = 0;
dumplo = -1;
return;
}
dumplo = (nblks - 1) - ctod(dumpsize) - chdrsize;
}
void
dumpsys(void)
{
cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
struct m68k_kcore_hdr *m = &h->un._m68k;
const struct bdevsw *bdev;
daddr_t blkno;
int (*dump)(dev_t, daddr_t, void *, size_t);
int pg;
paddr_t maddr;
int seg;
int error;
seg = 0;
maddr = m->ram_segs[seg].start;
pg = 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) {
printf("\ndump to dev %u,%u not possible\n",
major(dumpdev), minor(dumpdev));
return;
}
dump = bdev->d_dump;
blkno = dumplo;
printf("\ndumping to dev %u,%u offset %ld\n",
major(dumpdev), minor(dumpdev), dumplo);
printf("dump ");
error = cpu_dump(dump, &blkno);
if (error)
goto bad;
for (pg = 0; pg < dumpsize; pg++) {
#define NPGMB (1024*1024/PAGE_SIZE)
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;
goto bad;
}
maddr = m->ram_segs[seg].start;
}
pmap_enter(pmap_kernel(), (vaddr_t)vmmap, maddr,
VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
pmap_update(pmap_kernel());
error = (*dump)(dumpdev, blkno, vmmap, PAGE_SIZE);
bad:
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");
}
void nmihand(struct frame);
void
nmihand(struct frame frame)
{
static int nmihanddeep = 0;
if (nmihanddeep++)
return;
#ifdef DDB
printf("Panic switch: PC is 0x%x.\n", frame.f_pc);
Debugger();
#endif
nmihanddeep = 0;
}
int get_top_of_ram(void);
int
get_top_of_ram(void)
{
return ((mac68k_machine.mach_memsize * (1024 * 1024)) - PAGE_SIZE);
}
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);
}
static char *envbuf = NULL;
void
getenvvars(u_long flag, char *buf)
{
extern u_long bootdev;
extern u_long macos_boottime, MacOSROMBase;
extern long macos_gmtbias;
int root_scsi_id;
u_long root_ata_dev;
int i;
Elf_Ehdr *ehdr;
Elf_Shdr *shp;
vaddr_t minsym;
if ((flag & 0x80000000) == 0) {
} else
envbuf = buf;
mac68k_video.mv_kvaddr = getenv("VIDEO_ADDR");
mac68k_video.mv_stride = getenv("ROW_BYTES");
mac68k_video.mv_depth = getenv("SCREEN_DEPTH");
mac68k_video.mv_width = getenv("DIMENSIONS") & 0xffff;
mac68k_video.mv_height = (getenv("DIMENSIONS") >> 16) & 0xffff;
mac68k_machine.machineid = machineid = getenv("MACHINEID");
mac68k_machine.mach_processor = getenv("PROCESSOR");
#ifndef MAC68K_MEMSIZE
mac68k_machine.mach_memsize = getenv("MEMSIZE");
#else
mac68k_machine.mach_memsize = MAC68K_MEMSIZE;
#endif
mac68k_machine.do_graybars = getenv("GRAYBARS");
mac68k_machine.serial_boot_echo = getenv("SERIALECHO");
mac68k_machine.serial_console = getenv("SERIALCONSOLE");
mac68k_machine.modem_flags = getenv("SERIAL_MODEM_FLAGS");
mac68k_machine.modem_cts_clk = getenv("SERIAL_MODEM_HSKICLK");
mac68k_machine.modem_dcd_clk = getenv("SERIAL_MODEM_GPICLK");
mac68k_machine.modem_d_speed = getenv("SERIAL_MODEM_DSPEED");
mac68k_machine.print_flags = getenv("SERIAL_PRINT_FLAGS");
mac68k_machine.print_cts_clk = getenv("SERIAL_PRINT_HSKICLK");
mac68k_machine.print_dcd_clk = getenv("SERIAL_PRINT_GPICLK");
mac68k_machine.print_d_speed = getenv("SERIAL_PRINT_DSPEED");
mac68k_machine.booter_version = getenv("BOOTERVER");
root_scsi_id = getenv("ROOT_SCSI_ID");
root_ata_dev = getenv("ROOT_ATA_DEV");
if (((mac68k_machine.booter_version < CURRENTBOOTERVER) ||
(flag & 0x40000)) && bootdev == 0) {
if (root_ata_dev) {
switch (root_ata_dev) {
default:
case 0xffffffe0:
case 0x20:
case 0x21:
bootdev = MAKEBOOTDEV(22, 0, 0, 0, 0);
break;
case 0xffffffe1:
bootdev = MAKEBOOTDEV(22, 0, 0, 1, 0);
break;
}
} else {
bootdev = MAKEBOOTDEV(4, 0, 0, root_scsi_id, 0);
}
}
boothowto = getenv("BOOTHOWTO");
if (boothowto == 0)
boothowto = getenv("SINGLE_USER");
esym = (int *)getenv("END_SYM");
#ifndef makeoptions_COPY_SYMTAB
if (esym == (int *)0)
#endif
esym = (int *)&end;
macos_boottime = getenv("BOOTTIME");
macos_gmtbias = getenv("GMTBIAS");
ROMBase = (void *)getenv("ROMBASE");
if (ROMBase == (void *)0) {
ROMBase = (void *)ROMBASE;
}
MacOSROMBase = (unsigned long)ROMBase;
TimeDBRA = getenv("TIMEDBRA");
ADBDelay = (u_short)getenv("ADBDELAY");
HwCfgFlags = getenv("HWCFGFLAGS");
HwCfgFlags2 = getenv("HWCFGFLAG2");
HwCfgFlags3 = getenv("HWCFGFLAG3");
ADBReInit_JTBL = getenv("ADBREINIT_JTBL");
mrg_ADBIntrPtr = (void *)getenv("ADBINTERRUPT");
ehdr = (void *)getenv("MARK_SYM");
if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0 ||
ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
return;
}
minsym = ~0;
shp = (Elf_Shdr *)(end + ehdr->e_shoff);
for (i = 0; i < ehdr->e_shnum; i++) {
if (shp[i].sh_type != SHT_SYMTAB &&
shp[i].sh_type != SHT_STRTAB) {
continue;
}
minsym = MIN(minsym, (vaddr_t)end + shp[i].sh_offset);
}
symsize = 1;
ssym = (int *)ehdr;
}
static long
getenv(const char *str)
{
char *s;
const char *s1;
int val, base;
s = envbuf;
while (1) {
for (s1 = str; *s1 && *s && *s != '='; s1++, s++) {
if (toupper(*s1) != toupper(*s)) {
break;
}
}
if (*s1) {
while (*s) {
s++;
}
s++;
if (*s == '\0') {
return 0;
}
continue;
}
if (*s == '=') {
s++;
val = 0;
base = 10;
if (*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')) {
base = 16;
s += 2;
} else
if (*s == '0') {
base = 8;
}
while (*s) {
if (toupper(*s) >= 'A' && toupper(*s) <= 'F') {
val = val * base + toupper(*s) - 'A' + 10;
} else {
val = val * base + (*s - '0');
}
s++;
}
return val;
} else {
return 1;
}
}
}
static romvec_t romvecs[] =
{
{
"Mac II class ROMs",
(void *)0x40807002,
(void *)0x0,
(void *)0x4080a4d8,
(void *)0x40807778,
(void *)0x40807792,
(void *)0x408077be,
(void *)0x408077c4,
(void *)0x40807704,
(void *)0x408072fa,
(void *)0x0,
(void *)0x4080d6d0,
(void *)0x4080d6fa,
(void *)0x4080dbe8,
(void *)0x4080dd78,
(void *)0x4080dd82,
(void *)0x4080ddd6,
(void *)0x0,
(void *)0x0,
(void *)0x0,
(void *)0x0,
(void *)0x0,
(void *)0x40814c58,
(void *)0x40814b64,
},
{
"Powerbook class ROMs",
(void *)0x4088ae5e,
(void *)0x408885ec,
(void *)0x4088ae0e,
(void *)0x4080a360,
(void *)0x4080a37a,
(void *)0x4080a3a6,
(void *)0x4080a3ac,
(void *)0x4080a752,
(void *)0x4080a3dc,
(void *)0x408888ec,
(void *)0x4080c05c,
(void *)0x4080c086,
(void *)0x4080c5cc,
(void *)0x4080b186,
(void *)0x4080b190,
(void *)0x4080b1e4,
(void *)0x4080a818,
(void *)0x40814800,
(void *)0x408147c4,
(void *)0x0,
(void *)0x4087eb90,
(void *)0x4081c406,
(void *)0x4081c312,
},
{
"Mac IIsi class ROMs",
(void *)0x40814912,
(void *)0x0,
(void *)0x408150f0,
(void *)0x4080a360,
(void *)0x4080a37a,
(void *)0x4080a3a6,
(void *)0x4080a3ac,
(void *)0x4080a752,
(void *)0x4080a3dc,
(void *)0x0,
(void *)0x4080c05c,
(void *)0x4080c086,
(void *)0x4080c5cc,
(void *)0x4080b186,
(void *)0x4080b190,
(void *)0x4080b1e4,
(void *)0x4080a818,
(void *)0x40814800,
(void *)0x408147c4,
(void *)0x0,
(void *)0x4087eb90,
(void *)0x4081c406,
(void *)0x4081c312,
},
{
"Mac Classic II ROMs",
(void *)0x40a14912,
(void *)0x0,
(void *)0x40a150f0,
(void *)0x40a0a360,
(void *)0x40a0a37a,
(void *)0x40a0a3a6,
(void *)0x40a0a3ac,
(void *)0x40a0a752,
(void *)0x40a0a3dc,
(void *)0x0,
(void *)0x40a0c05c,
(void *)0x40a0c086,
(void *)0x40a0c5cc,
(void *)0x40a0b186,
(void *)0x40a0b190,
(void *)0x40a0b1e4,
(void *)0x40a0a818,
(void *)0x40a14800,
(void *)0x40a147c4,
(void *)0x40a03ba6,
(void *)0x40a7eb90,
(void *)0x40a1c406,
(void *)0x40a1c312,
},
{
"Mac IIci/Q700 ROMs",
(void *)0x4080a700,
(void *)0x0,
(void *)0x4080a5aa,
(void *)0x4080a360,
(void *)0x4080a37a,
(void *)0x4080a3a6,
(void *)0x4080a3ac,
(void *)0x4080a752,
(void *)0x4080a3dc,
(void *)0x0,
(void *)0x4080c05c,
(void *)0x4080c086,
(void *)0x4080c5cc,
(void *)0x4080b186,
(void *)0x4080b190,
(void *)0x4080b1e4,
(void *)0x4080a818,
(void *)0x0,
(void *)0x408147c4,
(void *)0x0,
(void *)0x4087eb90,
(void *)0x4081c406,
(void *)0x4081c312,
},
{
"2nd Powerbook class ROMs",
(void *)0x408b2eec,
(void *)0x408885ec,
(void *)0x408b2e76,
(void *)0x4080a360,
(void *)0x4080a37a,
(void *)0x4080a3a6,
(void *)0x4080a3ac,
(void *)0x4080a752,
(void *)0x4080a3dc,
(void *)0x408888ec,
(void *)0x4080c05c,
(void *)0x4080c086,
(void *)0x4080c5cc,
(void *)0x4080b186,
(void *)0x4080b190,
(void *)0x408b39b2,
(void *)0x4080a818,
(void *)0x40814800,
(void *)0x40888400,
(void *)0x408cce28,
(void *)0x4087eb90,
(void *)0x4081c406,
(void *)0x4081c312,
},
{
"Quadra/Centris ROMs",
(void *)0x408b2dea,
(void *)0x0,
(void *)0x408b2c72,
(void *)0x4080a360,
(void *)0x4080a37a,
(void *)0x4080a3a6,
(void *)0x4080a3ac,
(void *)0x4080a752,
(void *)0x4080a3dc,
(void *)0x40809ae6,
(void *)0x4080c05c,
(void *)0x4080c086,
(void *)0x4080c5cc,
(void *)0x4080b186,
(void *)0x4080b190,
(void *)0x408b39b6,
(void *)0x4080a818,
(void *)0x40814800,
(void *)0x408147c4,
(void *)0x408d2b64,
(void *)0x4087eb90,
(void *)0x4081c406,
(void *)0x4081c312,
},
{
"Quadra AV ROMs",
(void *)0x4080cac6,
(void *)0x0,
(void *)0x40805cd4,
(void *)0x40839600,
(void *)0x4083961a,
(void *)0x40839646,
(void *)0x4083964c,
(void *)0x408397b8,
(void *)0x4083967c,
(void *)0x0,
(void *)0x4081141c,
(void *)0x4081144e,
(void *)0x40811930,
(void *)0x4080b624,
(void *)0x4080b62e,
(void *)0x40806884,
(void *)0x408398c2,
(void *)0x4080cada,
(void *)0x4080de14,
(void *)0x408143b8,
(void *)0x409bdb60,
(void *)0x4083b3d8,
(void *)0x4083b2e4,
},
{
"68040 PowerBook ROMs",
(void *)0x400b2efc,
(void *)0x400d8e66,
(void *)0x400b2e86,
(void *)0x4000a360,
(void *)0x4000a37a,
(void *)0x4000a3a6,
(void *)0x4000a3ac,
(void *)0x4000a752,
(void *)0x4000a3dc,
(void *)0x400d9302,
(void *)0x4000c05c,
(void *)0x4000c086,
(void *)0x4000c5cc,
(void *)0x4000b186,
(void *)0x4000b190,
(void *)0x400b3c08,
(void *)0x4000a818,
(void *)0x40009ae6,
(void *)0x400147c4,
(void *)0x400a7a5c,
(void *)0x4007eb90,
(void *)0x4001c406,
(void *)0x4001c312,
},
{
"Quadra/Centris 605 ROMs",
(void *)0x408a9b56,
(void *)0x0,
(void *)0x408b2f94,
(void *)0x4080a360,
(void *)0x4080a37a,
(void *)0x4080a3a6,
(void *)0x4080a3ac,
(void *)0x4080a752,
(void *)0x4080a3dc,
(void *)0x0,
(void *)0x4080c05c,
(void *)0x4080c086,
(void *)0x4080c5cc,
(void *)0x4080b186,
(void *)0x4080b190,
(void *)0x408b3bf8,
(void *)0x4080a818,
(void *)0x408a99c0,
(void *)0x408147c4,
(void *)0x408a82c0,
(void *)0x4087eb90,
(void *)0x4081c406,
(void *)0x4081c312,
},
{
"Duo 270C ROMs",
(void *)0x408b2efc,
(void *)0x408885ec,
(void *)0x408b2e86,
(void *)0x4080a360,
(void *)0x4080a37a,
(void *)0x4080a3a6,
(void *)0x4080a3ac,
(void *)0x4080a752,
(void *)0x4080a3dc,
(void *)0x408888ec,
(void *)0x4080c05c,
(void *)0x4080c086,
(void *)0x4080c5cc,
(void *)0x4080b186,
(void *)0x4080b190,
(void *)0x408b3bf8,
(void *)0x4080a818,
(void *)0x40814800,
(void *)0x408147c4,
(void *)0x0,
(void *)0x4087eb90,
(void *)0x4081c406,
(void *)0x4081c312,
},
{
"P/LC 550 ROMs",
(void *)0x408d16d6,
(void *)0x0,
(void *)0x408b2f84,
(void *)0x4080a360,
(void *)0x4080a37a,
(void *)0x4080a3a6,
(void *)0x4080a3ac,
(void *)0x4080a752,
(void *)0x4080a3dc,
(void *)0x0,
(void *)0x4080c05c,
(void *)0x4080c086,
(void *)0x4080c5cc,
(void *)0x4080b186,
(void *)0x4080b190,
(void *)0x408b3c04,
(void *)0x4080a818,
(void *)0x408d1450,
(void *)0x408147c4,
(void *)0x408d24a4,
(void *)0x4087eb90,
(void *)0x4081c406,
(void *)0x4081c312,
},
{
"MacTV ROMs",
(void *)0x40acfed6,
(void *)0x0,
(void *)0x40ab2f84,
(void *)0x40a0a360,
(void *)0x40a0a37a,
(void *)0x40a0a3a6,
(void *)0x40a0a3ac,
(void *)0x40a0a752,
(void *)0x40a0a3dc,
(void *)0x0,
(void *)0x40a0c05c,
(void *)0x40a0c086,
(void *)0x40a0c5cc,
(void *)0x40a0b186,
(void *)0x40a0b190,
(void *)0x40ab3bf4,
(void *)0x40a0a818,
(void *)0x40acfd40,
(void *)0x40a147c4,
(void *)0x40a038a0,
(void *)0x40a7eb90,
(void *)0x40a1c406,
(void *)0x40a1c312,
},
{
"Quadra630 ROMs",
(void *)0x408a9bd2,
(void *)0x0,
(void *)0x408b2f94,
(void *)0x4080a360,
(void *)0x4080a37a,
(void *)0x4080a3a6,
(void *)0x4080a3ac,
(void *)0x4080a752,
(void *)0x4080a3dc,
(void *)0,
(void *)0x4080c05c,
(void *)0x4080c086,
(void *)0x4080c5cc,
(void *)0x4080b186,
(void *)0x4080b190,
(void *)0x408b39f4,
(void *)0x4080a818,
(void *)0x408a99c0,
(void *)0x408147c8,
(void *)0x408a7ef8,
(void *)0x4087eb90,
(void *)0x4081c406,
(void *)0x4081c312,
},
{
"LC III ROMs",
(void *)0x40814912,
(void *)0x0,
(void *)0x408b2f94,
(void *)0x4080a360,
(void *)0x4080a37a,
(void *)0x4080a3a6,
(void *)0x4080a3ac,
(void *)0x4080a752,
(void *)0x4080a3dc,
(void *)0x0,
(void *)0x4080c05c,
(void *)0x4080c086,
(void *)0x4080c5cc,
(void *)0x4080b186,
(void *)0x4080b190,
(void *)0x408b39b6,
(void *)0x4080a818,
(void *)0x40814800,
(void *)0x408147c4,
(void *)0x408d2918,
(void *)0x4087eb90,
(void *)0x4081c406,
(void *)0x4081c312,
},
{
"MacLC520 ROMs",
(void *)0x408d16d6,
(void *)0x0,
(void *)0x408b2f84,
(void *)0x4080a360,
(void *)0x4080a37a,
(void *)0x4080a3a6,
(void *)0x4080a3ac,
(void *)0x4080a752,
(void *)0x4080a3dc,
(void *)0x0,
(void *)0x4080c05c,
(void *)0x4080c086,
(void *)0x4080c5cc,
(void *)0x4080b186,
(void *)0x4080b190,
(void *)0x408b3c04,
(void *)0x4080a818,
(void *)0x408d1450,
(void *)0x408147c4,
(void *)0x408d2460,
(void *)0x4087eb90,
(void *)0x4081c406,
(void *)0x4081c312,
},
{
"MacLC575 ROMs",
(void *)0x408a9b56,
(void *)0x0,
(void *)0x408b2f94,
(void *)0x4080a360,
(void *)0x4080a37a,
(void *)0x4080a3a6,
(void *)0x4080a3ac,
(void *)0x4080a752,
(void *)0x4080a3dc,
(void *)0x0,
(void *)0x4080c05c,
(void *)0x4080c086,
(void *)0x4080c5cc,
(void *)0x4080b186,
(void *)0x4080b190,
(void *)0x408b3bf8,
(void *)0x4080a818,
(void *)0x408a99c0,
(void *)0x408147c4,
(void *)0x408a81a0,
(void *)0x4087eb90,
(void *)0x4081c406,
(void *)0x4081c312,
},
{
"Quadra950 class ROMs",
(void *)0x40814912,
(void *)0x0,
(void *)0x4080a4d8,
(void *)0x4080a360,
(void *)0x4080a37a,
(void *)0x4080a3a6,
(void *)0x4080a3ac,
(void *)0x4080a752,
(void *)0x4080a3dc,
(void *)0x0,
(void *)0x4080c05c,
(void *)0x4080c086,
(void *)0x4080c5cc,
(void *)0x4080b186,
(void *)0x4080b190,
(void *)0x4080b1e4,
(void *)0x4080a818,
(void *)0x40814800,
(void *)0x408147c4,
(void *)0x408038bc,
(void *)0x4087eb90,
(void *)0x4081c406,
(void *)0x4081c312,
},
{
"Mac IIfx ROMs",
(void *)0x40809f4a,
(void *)0x0,
(void *)0x4080a4d8,
(void *)0x4080a360,
(void *)0x4080a37a,
(void *)0x4080a3a6,
(void *)0x4080a3ac,
(void *)0x4080a752,
(void *)0x4080a3dc,
(void *)0x0,
(void *)0x4080c05c,
(void *)0x4080c086,
(void *)0x4080c5cc,
(void *)0x4080b186,
(void *)0x4080b190,
(void *)0x4080b1e4,
(void *)0x4080a818,
(void *)0x0,
(void *)0x0,
(void *)0x408037c0,
(void *)0x4087eb90,
(void *)0x4081c406,
(void *)0x4081c312,
},
{
"Performa 580 ROMs",
(void *) 0x4089a8be,
(void *) 0x0,
(void *) 0x408b2f94,
(void *) 0x4080a360,
(void *) 0x4080a37a,
(void *) 0x4080a3a6,
(void *) 0x4080a3ac,
(void *) 0x4080a752,
(void *) 0x4080a3dc,
(void *) 0x0,
(void *) 0x4080c05c,
(void *) 0x4080c086,
(void *) 0x4080c5cc,
(void *) 0x4080b186,
(void *) 0x4080b190,
(void *) 0x408b3bf4,
(void *) 0x4080a818,
(void *) 0x408a99c0,
(void *) 0x408147c8,
(void *) 0x408a7f74,
(void *) 0x4087eb90,
(void *) 0x4081c406,
(void *) 0x4081c312,
},
};
struct cpu_model_info cpu_models[] = {
{MACH_MACII, "II ", "", MACH_CLASSII, &romvecs[0]},
{MACH_MACIIX, "IIx ", "", MACH_CLASSII, &romvecs[0]},
{MACH_MACIICX, "IIcx ", "", MACH_CLASSII, &romvecs[0]},
{MACH_MACSE30, "SE/30 ", "", MACH_CLASSII, &romvecs[0]},
{MACH_MACIICI, "IIci ", "", MACH_CLASSIIci, &romvecs[4]},
{MACH_MACIISI, "IIsi ", "", MACH_CLASSIIsi, &romvecs[2]},
{MACH_MACIIVI, "IIvi ", "", MACH_CLASSIIvx, &romvecs[2]},
{MACH_MACIIVX, "IIvx ", "", MACH_CLASSIIvx, &romvecs[2]},
{MACH_MACIIFX, "IIfx ", "", MACH_CLASSIIfx, &romvecs[18]},
{MACH_MACQ700, "Quadra", " 700 ", MACH_CLASSQ, &romvecs[4]},
{MACH_MACQ900, "Quadra", " 900 ", MACH_CLASSQ, &romvecs[6]},
{MACH_MACQ950, "Quadra", " 950 ", MACH_CLASSQ, &romvecs[17]},
{MACH_MACQ800, "Quadra", " 800 ", MACH_CLASSQ, &romvecs[6]},
{MACH_MACQ650, "Quadra", " 650 ", MACH_CLASSQ, &romvecs[6]},
{MACH_MACC650, "Centris", " 650 ", MACH_CLASSQ, &romvecs[6]},
{MACH_MACQ605, "Quadra", " 605 ", MACH_CLASSQ, &romvecs[9]},
{MACH_MACQ605_33, "Quadra", " 605/33 ", MACH_CLASSQ, &romvecs[9]},
{MACH_MACC610, "Centris", " 610 ", MACH_CLASSQ, &romvecs[6]},
{MACH_MACQ610, "Quadra", " 610 ", MACH_CLASSQ, &romvecs[6]},
{MACH_MACQ630, "Quadra", " 630 ", MACH_CLASSQ2, &romvecs[13]},
{MACH_MACC660AV, "Centris", " 660AV ", MACH_CLASSAV, &romvecs[7]},
{MACH_MACQ840AV, "Quadra", " 840AV ", MACH_CLASSAV, &romvecs[7]},
{MACH_MACPB100, "PowerBook", " 100 ", MACH_CLASSPB, &romvecs[1]},
{MACH_MACPB140, "PowerBook", " 140 ", MACH_CLASSPB, &romvecs[1]},
{MACH_MACPB145, "PowerBook", " 145 ", MACH_CLASSPB, &romvecs[1]},
{MACH_MACPB150, "PowerBook", " 150 ", MACH_CLASSDUO, &romvecs[10]},
{MACH_MACPB160, "PowerBook", " 160 ", MACH_CLASSPB, &romvecs[5]},
{MACH_MACPB165, "PowerBook", " 165 ", MACH_CLASSPB, &romvecs[5]},
{MACH_MACPB165C, "PowerBook", " 165c ", MACH_CLASSPB, &romvecs[5]},
{MACH_MACPB170, "PowerBook", " 170 ", MACH_CLASSPB, &romvecs[1]},
{MACH_MACPB180, "PowerBook", " 180 ", MACH_CLASSPB, &romvecs[5]},
{MACH_MACPB180C, "PowerBook", " 180c ", MACH_CLASSPB, &romvecs[5]},
{MACH_MACPB190, "PowerBook", " 190 ", MACH_CLASSPB, &romvecs[8]},
{MACH_MACPB190CS, "PowerBook", " 190cs ", MACH_CLASSPB, &romvecs[8]},
{MACH_MACPB500, "PowerBook", " 500 ", MACH_CLASSPB, &romvecs[8]},
{MACH_MACPB210, "PowerBook Duo", " 210 ", MACH_CLASSDUO, &romvecs[5]},
{MACH_MACPB230, "PowerBook Duo", " 230 ", MACH_CLASSDUO, &romvecs[5]},
{MACH_MACPB250, "PowerBook Duo", " 250 ", MACH_CLASSDUO, &romvecs[5]},
{MACH_MACPB270, "PowerBook Duo", " 270C ", MACH_CLASSDUO, &romvecs[5]},
{MACH_MACPB280, "PowerBook Duo", " 280 ", MACH_CLASSDUO, &romvecs[5]},
{MACH_MACPB280C, "PowerBook Duo", " 280C ", MACH_CLASSDUO, &romvecs[5]},
{MACH_MACP600, "Performa", " 600 ", MACH_CLASSIIvx, &romvecs[2]},
{MACH_MACP460, "Performa", " 460 ", MACH_CLASSLC, &romvecs[14]},
{MACH_MACP550, "Performa", " 550 ", MACH_CLASSLC, &romvecs[11]},
{MACH_MACP580, "Performa", " 580 ", MACH_CLASSQ2, &romvecs[19]},
{MACH_MACTV, "TV ", "", MACH_CLASSLC, &romvecs[12]},
{MACH_MACLCII, "LC", " II ", MACH_CLASSLC, &romvecs[3]},
{MACH_MACLCIII, "LC", " III ", MACH_CLASSLC, &romvecs[14]},
{MACH_MACLC475, "LC", " 475 ", MACH_CLASSQ, &romvecs[9]},
{MACH_MACLC475_33, "LC", " 475/33 ", MACH_CLASSQ, &romvecs[9]},
{MACH_MACLC520, "LC", " 520 ", MACH_CLASSLC, &romvecs[15]},
{MACH_MACLC575, "LC", " 575 ", MACH_CLASSQ2, &romvecs[16]},
{MACH_MACCCLASSIC, "Color Classic ", "", MACH_CLASSLC, &romvecs[3]},
{MACH_MACCCLASSICII, "Color Classic"," II ", MACH_CLASSLC, &romvecs[3]},
{MACH_MACCLASSICII, "Classic", " II ", MACH_CLASSLC, &romvecs[3]},
{0, "Unknown", "", MACH_CLASSII, NULL},
{0, NULL, NULL, 0, NULL},
};
struct intvid_info_t {
int machineid;
u_long fbbase;
u_long fbmask;
u_long fblen;
} intvid_info[] = {
{ MACH_MACCLASSICII, 0x009f9a80, 0x0, 21888 },
{ MACH_MACPB140, 0xfee08000, 0x0, 32 * 1024 },
{ MACH_MACPB145, 0xfee08000, 0x0, 32 * 1024 },
{ MACH_MACPB170, 0xfee08000, 0x0, 32 * 1024 },
{ MACH_MACPB150, 0x60000000, 0x0, 128 * 1024 },
{ MACH_MACPB160, 0x60000000, 0x0ffe0000, 128 * 1024 },
{ MACH_MACPB165, 0x60000000, 0x0ffe0000, 128 * 1024 },
{ MACH_MACPB180, 0x60000000, 0x0ffe0000, 128 * 1024 },
{ MACH_MACPB210, 0x60000000, 0x0, 128 * 1024 },
{ MACH_MACPB230, 0x60000000, 0x0, 128 * 1024 },
{ MACH_MACPB250, 0x60000000, 0x0, 128 * 1024 },
{ MACH_MACPB270, 0x60000000, 0x0, 128 * 1024 },
{ MACH_MACPB280, 0x60000000, 0x0, 128 * 1024 },
{ MACH_MACPB280C, 0x60000000, 0x0, 128 * 1024 },
{ MACH_MACIICI, 0x0, 0x0, 320 * 1024 },
{ MACH_MACIISI, 0x0, 0x0, 320 * 1024 },
{ MACH_MACCCLASSIC, 0x50f40000, 0x0, 512 * 1024 },
{ MACH_MACLCII, 0x50f40000, 0x0, 512 * 1024 },
{ MACH_MACPB165C, 0xfc040000, 0x0, 512 * 1024 },
{ MACH_MACPB180C, 0xfc040000, 0x0, 512 * 1024 },
{ MACH_MACPB190, 0x60000000, 0x0, 512 * 1024 },
{ MACH_MACPB190CS, 0x60000000, 0x0, 512 * 1024 },
{ MACH_MACPB500, 0x60000000, 0x0, 512 * 1024 },
{ MACH_MACLCIII, 0x60b00000, 0x0, 768 * 1024 },
{ MACH_MACLC520, 0x60000000, 0x0, 1024 * 1024 },
{ MACH_MACP550, 0x60000000, 0x0, 1024 * 1024 },
{ MACH_MACTV, 0x60000000, 0x0, 1024 * 1024 },
{ MACH_MACLC475, 0xf9000000, 0x0, 1024 * 1024 },
{ MACH_MACLC475_33, 0xf9000000, 0x0, 1024 * 1024 },
{ MACH_MACLC575, 0xf9000000, 0x0, 1024 * 1024 },
{ MACH_MACC610, 0xf9000000, 0x0, 1024 * 1024 },
{ MACH_MACC650, 0xf9000000, 0x0, 1024 * 1024 },
{ MACH_MACP580, 0xf9000000, 0x0, 1024 * 1024 },
{ MACH_MACQ605, 0xf9000000, 0x0, 1024 * 1024 },
{ MACH_MACQ605_33, 0xf9000000, 0x0, 1024 * 1024 },
{ MACH_MACQ610, 0xf9000000, 0x0, 1024 * 1024 },
{ MACH_MACQ630, 0xf9000000, 0x0, 1024 * 1024 },
{ MACH_MACQ650, 0xf9000000, 0x0, 1024 * 1024 },
{ MACH_MACC660AV, 0x50100000, 0x0, 1024 * 1024 },
{ MACH_MACQ700, 0xf9000000, 0x0, 1024 * 1024 },
{ MACH_MACQ800, 0xf9000000, 0x0, 1024 * 1024 },
{ MACH_MACQ900, 0xf9000000, 0x0, 1024 * 1024 },
{ MACH_MACQ950, 0xf9000000, 0x0, 1024 * 1024 },
{ MACH_MACQ840AV, 0x50100000, 0x0, 2048 * 1024 },
{ 0, 0x0, 0x0, 0 },
};
int mach_cputype(void);
int
mach_cputype(void)
{
return (mac68k_machine.mach_processor);
}
void
machine_set_model(void)
{
cpu_setmodel("Apple Macintosh %s%s",
cpu_models[mac68k_machine.cpu_model_index].model_major,
cpu_models[mac68k_machine.cpu_model_index].model_minor);
}
static void get_machine_info(void);
static void
get_machine_info(void)
{
int i;
for (i = 0; cpu_models[i].model_major; i++)
if (mac68k_machine.machineid == cpu_models[i].machineid)
break;
if (cpu_models[i].model_major == NULL)
i--;
mac68k_machine.cpu_model_index = i;
}
struct cpu_model_info *current_mac_model;
romvec_t *mrg_MacOSROMVectors = 0;
void setmachdep(void);
void
setmachdep(void)
{
struct cpu_model_info *cpui;
get_machine_info();
load_addr = 0;
cpui = &(cpu_models[mac68k_machine.cpu_model_index]);
current_mac_model = cpui;
mac68k_machine.via1_ipl = 1;
mac68k_machine.via2_ipl = 2;
mac68k_machine.aux_interrupts = 0;
switch (cpui->class) {
case MACH_CLASSII:
VIA2 = VIA2OFF;
IOBase = 0x50f00000;
Via1Base = (volatile u_char *)IOBase;
mac68k_machine.scsi80 = 1;
mac68k_machine.zs_chip = 0;
via_reg(VIA1, vIER) = 0x7f;
via_reg(VIA2, vIER) = 0x7f;
break;
case MACH_CLASSPB:
VIA2 = VIA2OFF;
IOBase = 0x50f00000;
Via1Base = (volatile u_char *)IOBase;
mac68k_machine.scsi80 = 1;
mac68k_machine.zs_chip = 0;
via_reg(VIA1, vIER) = 0x6f;
via_reg(VIA2, vIER) = 0x7f;
if (cputype == CPU_68040)
mac68k_machine.sonic = 1;
break;
case MACH_CLASSDUO:
VIA2 = RBVOFF;
IOBase = 0x50f00000;
Via1Base = (volatile u_char *)IOBase;
mac68k_machine.scsi80 = 1;
mac68k_machine.zs_chip = 0;
via_reg(VIA1, vIER) = 0x6f;
via_reg(VIA2, rIER) = 0x7f;
break;
case MACH_CLASSQ:
case MACH_CLASSQ2:
VIA2 = VIA2OFF;
IOBase = 0x50f00000;
Via1Base = (volatile u_char *)IOBase;
mac68k_machine.sonic = 1;
mac68k_machine.scsi96 = 1;
mac68k_machine.zs_chip = 0;
via_reg(VIA1, vIER) = 0x7f;
via_reg(VIA2, vIER) = 0x7f;
#if 1
switch (current_mac_model->machineid) {
default:
mac68k_machine.aux_interrupts = 1;
via_reg(VIA1, vBufB) &= (0xff ^ DB1O_AuxIntEnb);
via_reg(VIA1, vDirB) |= DB1O_AuxIntEnb;
mac68k_machine.via1_ipl = 6;
mac68k_machine.via2_ipl = 2;
break;
}
#endif
break;
case MACH_CLASSAV:
case MACH_CLASSP580:
VIA2 = VIA2OFF;
IOBase = 0x50f00000;
Via1Base = (volatile u_char *)IOBase;
mac68k_machine.scsi96 = 1;
mac68k_machine.zs_chip = 0;
via_reg(VIA1, vIER) = 0x7f;
via_reg(VIA2, vIER) = 0x7f;
break;
case MACH_CLASSIIci:
VIA2 = RBVOFF;
IOBase = 0x50f00000;
Via1Base = (volatile u_char *)IOBase;
mac68k_machine.scsi80 = 1;
mac68k_machine.zs_chip = 0;
via_reg(VIA1, vIER) = 0x7f;
via_reg(VIA2, rIER) = 0x7f;
break;
case MACH_CLASSIIsi:
VIA2 = RBVOFF;
IOBase = 0x50f00000;
Via1Base = (volatile u_char *)IOBase;
mac68k_machine.scsi80 = 1;
mac68k_machine.zs_chip = 0;
via_reg(VIA1, vIER) = 0x7f;
via_reg(VIA2, rIER) = 0x7f;
break;
case MACH_CLASSIIvx:
VIA2 = RBVOFF;
IOBase = 0x50f00000;
Via1Base = (volatile u_char *)IOBase;
mac68k_machine.scsi80 = 1;
mac68k_machine.zs_chip = 0;
via_reg(VIA1, vIER) = 0x7f;
via_reg(VIA2, rIER) = 0x7f;
break;
case MACH_CLASSLC:
VIA2 = RBVOFF;
IOBase = 0x50f00000;
Via1Base = (volatile u_char *)IOBase;
mac68k_machine.scsi80 = 1;
mac68k_machine.zs_chip = 0;
via_reg(VIA1, vIER) = 0x7f;
via_reg(VIA2, rIER) = 0x7f;
break;
case MACH_CLASSIIfx:
VIA2 = OSSOFF;
IOBase = 0x50f00000;
Via1Base = (volatile u_char *)IOBase;
mac68k_machine.scsi80 = 1;
mac68k_machine.zs_chip = 0;
via_reg(VIA1, vIER) = 0x7f;
break;
default:
case MACH_CLASSH:
break;
}
mrg_MacOSROMVectors = cpui->rom_vectors;
}
void
mac68k_set_io_offsets(vaddr_t base)
{
Via1Base = (volatile u_char *)base;
Via2Base = Via1Base + 0x2000 * VIA2;
switch (current_mac_model->class) {
case MACH_CLASSQ:
switch (current_mac_model->machineid) {
case MACH_MACQ900:
case MACH_MACQ950:
sccA = (volatile u_char *)base + 0xc020;
SCSIBase = base + 0xf000;
mac68k_machine.scsi96_2 = 1;
iop_init(0);
break;
case MACH_MACQ800:
sccA = (volatile u_char *)base + 0xc020;
SCSIBase = base + 0x10000;
break;
case MACH_MACQ700:
sccA = (volatile u_char *)base + 0xc000;
SCSIBase = base + 0xf000;
break;
default:
sccA = (volatile u_char *)base + 0xc000;
SCSIBase = base + 0x10000;
break;
}
break;
case MACH_CLASSQ2:
sccA = (volatile u_char *)base + 0xc020;
SCSIBase = base + 0x10000;
break;
case MACH_CLASSP580:
sccA = (volatile u_char *)base + 0xc020;
SCSIBase = base;
break;
case MACH_CLASSAV:
sccA = (volatile u_char *)base + 0x4000;
SCSIBase = base + 0x18000;
PSCBase = (volatile u_char *)base + 0x31000;
break;
case MACH_CLASSII:
case MACH_CLASSPB:
case MACH_CLASSDUO:
case MACH_CLASSIIci:
case MACH_CLASSIIsi:
case MACH_CLASSIIvx:
case MACH_CLASSLC:
sccA = (volatile u_char *)base + 0x4000;
SCSIBase = base;
break;
case MACH_CLASSIIfx:
sccA = (volatile u_char *)base + 0x4020;
SCSIBase = base;
iop_init(0);
break;
default:
case MACH_CLASSH:
panic("Unknown/unsupported machine class (%d).",
current_mac_model->class);
break;
}
}
#if GRAYBARS
static u_long gray_nextaddr = 0;
void
gray_bar(void)
{
static int i = 0;
static int flag = 0;
__asm volatile (
" movl %a0,%sp@-;"
" movl %a1,%sp@-;"
" movl %d0,%sp@-;"
" movl %d1,%sp@-");
if (mac68k_machine.do_graybars) {
for (i = 0; i < 10 * mac68k_video.mv_stride / 4; i++)
((u_long *)mac68k_video.mv_kvaddr)
[gray_nextaddr++] = 0xaaaaaaaa;
for (i = 0; i < 2 * mac68k_video.mv_stride / 4; i++)
((u_long *)mac68k_video.mv_kvaddr)
[gray_nextaddr++] = 0x00000000;
}
__asm volatile (
" movl %sp@+,%d1;"
" movl %sp@+,%d0;"
" movl %sp@+,%a1;"
" movl %sp@+,%a0");
}
#endif
extern u_long ptest040(void *, u_int);
extern u_long plpar060(void *, u_int);
extern int get_pte(u_int, u_long *, u_short *);
static u_long
get_physical(u_int addr, u_long * phys)
{
extern u_int macos_tc;
u_long pte[2], ph, mask;
u_short psr;
int i, numbits;
if (cputype == CPU_68060) {
ph = plpar060((void *)addr, FC_SUPERD);
if (ph == (u_long)-1) {
ph = plpar060((void *)addr, FC_USERD);
if (ph == (u_long)-1) {
return 0;
}
}
*phys = ph;
return 1;
} else if (mmutype == MMU_68040) {
ph = ptest040((void *)addr, FC_SUPERD);
if ((ph & MMUSR40_R) == 0) {
ph = ptest040((void *)addr, FC_USERD);
if ((ph & MMUSR40_R) == 0)
return 0;
}
if ((ph & MMUSR40_T) != 0)
ph = addr;
mask = (macos_tc & TCR40_P) ? 0x00001fff : 0x00000fff;
ph &= (~mask);
} else {
switch (get_pte(addr, pte, &psr)) {
case (-1):
return 0;
case 0:
ph = pte[0] & 0xFFFFFF00;
break;
case 1:
ph = pte[1] & 0xFFFFFF00;
break;
default:
panic("get_physical(): bad get_pte()");
}
numbits = 0;
psr &= 0x0007;
for (i = 0; i < psr; i++)
numbits += (macos_tc >> (12 - i * 4)) & 0x0f;
mask = (1 << (32 - numbits)) - 1;
}
*phys = ph + (addr & mask);
return 1;
}
static void check_video(const char *, u_long, u_long);
static void
check_video(const char *id, u_long limit, u_long maxm)
{
u_long addr, phys;
if (!get_physical(mac68k_video.mv_kvaddr, &phys)) {
if (mac68k_machine.do_graybars)
printf("get_mapping(): %s. False start.\n", id);
} else {
mac68k_video.mv_log = mac68k_video.mv_kvaddr;
mac68k_video.mv_phys = phys;
mac68k_video.mv_len = 32768;
addr = mac68k_video.mv_kvaddr + 32768;
while (get_physical(addr, &phys)) {
if ((phys - mac68k_video.mv_phys)
!= mac68k_video.mv_len)
break;
if (mac68k_video.mv_len + 32768 > limit) {
if (mac68k_machine.do_graybars) {
printf("mapping: %s. Does it never end?\n",
id);
printf(" Forcing VRAM size ");
printf("to a conservative %ldK.\n",
maxm/1024);
}
mac68k_video.mv_len = maxm;
break;
}
mac68k_video.mv_len += 32768;
addr += 32768;
}
if (mac68k_machine.do_graybars) {
printf(" %s internal video at addr %p (phys %p), ",
id, (void *)mac68k_video.mv_log,
(void *)mac68k_video.mv_phys);
printf("len 0x%x.\n", mac68k_video.mv_len);
}
}
}
u_int
get_mapping(void)
{
struct intvid_info_t *iip;
u_long addr, lastpage, phys, len, limit;
int i, last, same;
numranges = 0;
for (i = 0; i < 8; i++) {
low[i] = 0;
high[i] = 0;
}
lastpage = get_top_of_ram();
get_physical(0, &load_addr);
if (mac68k_machine.do_graybars)
printf("Loaded at 0x%0lx\n", load_addr);
last = 0;
for (addr = 0; addr <= lastpage && get_physical(addr, &phys);
addr += PAGE_SIZE) {
if (numranges > 0 && phys != high[last]) {
for (i = 0; i < numranges; i++) {
if (low[i] <= phys && phys <= high[i]) {
last = i;
break;
}
}
if (i >= numranges)
last = numranges - 1;
if (low[last] <= phys && phys < high[last])
continue;
}
if (numranges > 0 && phys == high[last]) {
high[last] += PAGE_SIZE;
} else {
for (last = 0; last < numranges; last++)
if (phys < low[last])
break;
if (last < numranges && phys < low[last]) {
for (i = numranges; i > last; i--) {
low[i] = low[i - 1];
high[i] = high[i - 1];
}
}
numranges++;
low[last] = phys;
high[last] = phys + PAGE_SIZE;
}
if (last < (numranges - 1) && high[last] == low[last + 1] &&
low[last + 1] != load_addr) {
high[last] = high[last + 1];
for (i = last + 1; i < numranges; i++) {
low[i] = low[i + 1];
high[i] = high[i + 1];
}
--numranges;
}
}
if (mac68k_machine.do_graybars) {
printf("System RAM: %ld bytes in %ld pages.\n",
addr, addr / PAGE_SIZE);
for (i = 0; i < numranges; i++) {
printf(" Low = 0x%lx, high = 0x%lx\n",
low[i], high[i]);
}
}
if (!get_physical(mac68k_video.mv_kvaddr, &phys))
phys = mac68k_video.mv_kvaddr;
for (iip = intvid_info; iip->machineid; iip++)
if (mac68k_machine.machineid == iip->machineid)
break;
if (mac68k_machine.machineid == iip->machineid &&
(phys & ~iip->fbmask) >= iip->fbbase &&
(phys & ~iip->fbmask) < (iip->fbbase + iip->fblen)) {
mac68k_video.mv_phys = phys & ~iip->fbmask;
mac68k_video.mv_len = 32768 - (phys & 0x7fff);
limit = iip->fbbase + iip->fblen - mac68k_video.mv_phys;
if (mac68k_video.mv_len > limit) {
mac68k_video.mv_len = limit;
} else {
addr = mac68k_video.mv_kvaddr + mac68k_video.mv_len;
while (get_physical(addr, &phys)) {
phys &= ~iip->fbmask;
if ((phys - mac68k_video.mv_phys) !=
mac68k_video.mv_len)
break;
if ((mac68k_video.mv_phys + 32768) > limit) {
mac68k_video.mv_len = limit;
break;
}
mac68k_video.mv_len += 32768;
addr += 32768;
}
}
}
if (mac68k_video.mv_len > 0) {
if (mac68k_machine.do_graybars)
printf("On-board video at addr %p (phys %p), "
"len 0x%x.\n",
(void *)mac68k_video.mv_kvaddr,
(void *)mac68k_video.mv_phys,
mac68k_video.mv_len);
} else {
nbnumranges = 0;
for (i = 0; i < NBMAXRANGES; i++) {
nbphys[i] = 0;
nblog[i] = 0;
nblen[i] = 0;
}
same = 0;
for (addr = 0xF9000000; addr < 0xFF000000; addr += 32768) {
if (!get_physical(addr, &phys)) {
continue;
}
len = nbnumranges == 0 ? 0 : nblen[nbnumranges - 1];
#ifdef __debug_mondo_verbose__
if (mac68k_machine.do_graybars)
printf ("0x%lx --> 0x%lx\n", addr, phys);
#endif
if (nbnumranges > 0
&& addr == nblog[nbnumranges - 1] + len
&& phys == nbphys[nbnumranges - 1]) {
nblen[nbnumranges - 1] += 32768;
same = 1;
} else {
if ((nbnumranges > 0)
&& !same
&& (addr == nblog[nbnumranges - 1] + len)
&& (phys == nbphys[nbnumranges - 1] + len))
nblen[nbnumranges - 1] += 32768;
else {
if (same &&
nbnumranges > 0 ) {
nblen[nbnumranges - 1] = -len;
same = 0;
}
if (nbnumranges == NBMAXRANGES) {
if (mac68k_machine.do_graybars)
printf("get_mapping(): Too many NuBus ranges.\n");
break;
}
nbnumranges++;
nblog[nbnumranges - 1] = addr;
nbphys[nbnumranges - 1] = phys;
nblen[nbnumranges - 1] = 32768;
}
}
}
if (same) {
nblen[nbnumranges - 1] = -nblen[nbnumranges - 1];
same = 0;
}
if (mac68k_machine.do_graybars) {
printf("Non-system RAM (nubus, etc.):\n");
for (i = 0; i < nbnumranges; i++) {
printf(" Log = 0x%lx, Phys = 0x%lx, Len = 0x%lx (%lu)\n",
nblog[i], nbphys[i], nblen[i], nblen[i]);
}
}
for (i = 0; i < nbnumranges; i++) {
if (nblen[i] > 0
&& nbphys[i] <= 32768
&& 32768 <= nbphys[i] + nblen[i]) {
mac68k_video.mv_log = nblog[i] - nbphys[i];
mac68k_video.mv_len = nblen[i] + nbphys[i];
mac68k_video.mv_phys = 0;
break;
}
}
if (i == nbnumranges) {
if (0x60000000 <= mac68k_video.mv_kvaddr
&& mac68k_video.mv_kvaddr < 0x70000000) {
if (mac68k_machine.do_graybars)
printf("Checking for Internal Video ");
check_video("PB/IIvx (0x60?00000)",
1 * 1024 * 1024, 1 * 1024 * 1024);
} else if (0x50F40000 <= mac68k_video.mv_kvaddr
&& mac68k_video.mv_kvaddr < 0x50FBFFFF) {
check_video("LC video (0x50f40000)",
512 * 1024, 512 * 1024);
} else if (0x50100100 <= mac68k_video.mv_kvaddr
&& mac68k_video.mv_kvaddr < 0x50400000) {
check_video("AV video (0x50100100)",
1 * 1024 * 1024, 1 * 1024 * 1024);
} else {
if (mac68k_machine.do_graybars)
printf(" no internal video at "
"address 0 -- "
"mac68k_video.mv_kvaddr is "
"0x%lx.\n",
mac68k_video.mv_kvaddr);
}
} else if (mac68k_machine.do_graybars) {
printf(" Video address = %p\n",
(void *)mac68k_video.mv_kvaddr);
printf(" Int video starts at %p\n",
(void *)mac68k_video.mv_log);
printf(" Length = 0x%x (%d) bytes\n",
mac68k_video.mv_len, mac68k_video.mv_len);
}
}
int reqsize = mac68k_video.mv_height * mac68k_video.mv_stride;
if (mac68k_video.mv_len < reqsize)
mac68k_video.mv_len = reqsize;
return load_addr;
}
void printstar(void);
void
printstar(void)
{
__asm volatile (
" movl %a0,%sp@-;"
" movl %a1,%sp@-;"
" movl %d0,%sp@-;"
" movl %d1,%sp@-");
__asm volatile (
" movl %sp@+,%d1;"
" movl %sp@+,%d0;"
" movl %sp@+,%a1;"
" movl %sp@+,%a0");
}
void
mac68k_set_bell_callback(int (*callback)(void *, int, int, int), void *cookie)
{
mac68k_bell_callback = callback;
mac68k_bell_cookie = (void *)cookie;
}
int
mac68k_ring_bell(int freq, int length, int volume)
{
if (mac68k_bell_callback)
return ((*mac68k_bell_callback)(mac68k_bell_cookie,
freq, length, volume));
else
return (ENXIO);
}
int
mm_md_physacc(paddr_t pa, vm_prot_t prot)
{
extern u_long last_page;
return (pa < last_page) ? 0 : EFAULT;
}
void __attribute__((no_instrument_function))
pmap_machine_check_bootstrap_allocations(paddr_t nextpa, paddr_t firstpa)
{
int i;
for (i = 0; i < numranges; i++) {
if (low[i] <= firstpa && firstpa < high[i]) {
break;
}
}
if (i >= numranges || nextpa > high[i]) {
if (mac68k_machine.do_graybars) {
printf("Failure in NetBSD boot; ");
if (i < numranges) {
printf("nextpa=0x%lx, high[%d]=0x%lx.\n",
nextpa, i, high[i]);
} else {
printf("can't find kernel RAM segment.\n");
}
printf("You're hosed! Try booting with 32-bit ");
printf("addressing enabled in the memory control ");
printf("panel.\n");
printf("Older machines may need Mode32 to get that ");
printf("option.\n");
}
panic("Cannot work with the current memory mappings.");
}
}
#define PMBM_IOBase 0
#define PMBM_ROMBase 1
#define PMBM_VIDBase 2
struct pmap_bootmap machine_bootmap[] = {
{ .pmbm_vaddr = 0,
.pmbm_paddr = 0,
.pmbm_size = m68k_ptob(IIOMAPSIZE),
.pmbm_flags = PMBM_F_FIXEDVA | PMBM_F_CI },
{ .pmbm_vaddr_ptr = (vaddr_t *)&ROMBase,
.pmbm_paddr = 0,
.pmbm_size = m68k_ptob(ROMMAPSIZE),
.pmbm_flags = PMBM_F_RO },
{ .pmbm_vaddr_ptr = &newvideoaddr,
.pmbm_paddr = 0,
.pmbm_size = 0,
.pmbm_flags = PMBM_F_CI },
{ .pmbm_vaddr = -1 },
};
paddr_t bootstrap_mac68k(int);
paddr_t __attribute__((no_instrument_function))
bootstrap_mac68k(int tc)
{
#if NZSC > 0
extern int zsinited;
extern void zs_init(void);
#endif
extern int *esym;
paddr_t nextpa;
void *oldROMBase;
char use_bootmem = 0;
int i;
#ifdef DJMEMCMAX
if(mac68k_machine.machineid == MACH_MACC650 ||
mac68k_machine.machineid == MACH_MACQ650 ||
mac68k_machine.machineid == MACH_MACQ610 ||
mac68k_machine.machineid == MACH_MACC610 ||
mac68k_machine.machineid == MACH_MACQ800) {
use_bootmem = 1;
}
#endif
if (mac68k_machine.do_graybars)
printf("Bootstrapping NetBSD/mac68k.\n");
oldROMBase = ROMBase;
mac68k_video.mv_phys = mac68k_video.mv_kvaddr;
if ((!use_bootmem) && (((tc & 0x80000000) && (mmutype == MMU_68030)) ||
((tc & 0x8000) && (mmutype == MMU_68040)))) {
if (mac68k_machine.do_graybars)
printf("Getting mapping from MMU.\n");
(void) get_mapping();
if (mac68k_machine.do_graybars)
printf("Done.\n");
} else {
numranges = 1;
low[0] = 0;
high[0] = mac68k_machine.mach_memsize * (1024 * 1024);
if (mac68k_machine.do_graybars)
printf("Faked range to byte 0x%lx.\n", high[0]);
}
nextpa = load_addr + m68k_round_page(esym);
if (mac68k_machine.do_graybars)
printf("Bootstrapping the pmap system.\n");
vidlen = m68k_round_page(mac68k_video.mv_height *
mac68k_video.mv_stride + m68k_page_offset(mac68k_video.mv_phys));
vsize_t mem_size = 0;
for (i = 0; i < numranges; i++)
mem_size += high[i] - low[i];
physmem = m68k_btop(mem_size);
#ifdef __HAVE_NEW_PMAP_68K
machine_bootmap[PMBM_IOBase].pmbm_vaddr = (vaddr_t)IOBase;
machine_bootmap[PMBM_IOBase].pmbm_paddr = (paddr_t)IOBase;
machine_bootmap[PMBM_ROMBase].pmbm_paddr = (paddr_t)ROMBase;
machine_bootmap[PMBM_VIDBase].pmbm_paddr =
m68k_trunc_page(mac68k_video.mv_phys);
machine_bootmap[PMBM_VIDBase].pmbm_size = vidlen;
#endif
nextpa = pmap_bootstrap1(nextpa, load_addr);
#ifdef __HAVE_NEW_PMAP_68K
if (vidlen) {
newvideoaddr += m68k_page_offset(mac68k_video.mv_phys);
}
#endif
avail_start = m68k_round_page(nextpa);
last_page = high[numranges - 1] - m68k_ptob(1);
#if NAUDIO > 0
high[numranges - 1] -= (m68k_round_page(MSGBUFSIZE) + m68k_ptob(8));
#else
high[numranges - 1] -= (m68k_round_page(MSGBUFSIZE) + m68k_ptob(1));
#endif
avail_end = high[numranges - 1];
if (mac68k_machine.do_graybars)
printf("Pmap bootstrapped.\n");
if (!vidlen)
panic("Don't know how to relocate video!");
if (mac68k_machine.do_graybars)
printf("Moving ROMBase from %p to %p.\n", oldROMBase, ROMBase);
mrg_fixupROMBase(oldROMBase, ROMBase);
if (mac68k_machine.do_graybars)
printf("Video address %p -> %p.\n",
(void *)mac68k_video.mv_kvaddr, (void *)newvideoaddr);
mac68k_set_io_offsets(IOBase);
#if NZSC > 0
if (zsinited != 0)
zs_init();
#endif
mac68k_video.mv_kvaddr = newvideoaddr;
return nextpa;
}