From ecc30b1784493c5de270b70aaccec350d16c5c9b Mon Sep 17 00:00:00 2001 From: itohy Date: Tue, 1 Sep 1998 19:55:32 +0000 Subject: [PATCH] New boot program. Load and execute NetBSD/x68k kernel from Human68k. --- sys/arch/x68k/stand/loadbsd/Makefile | 36 ++ sys/arch/x68k/stand/loadbsd/loadbsd.8 | 135 ++++++ sys/arch/x68k/stand/loadbsd/loadbsd.c | 592 +++++++++++++++++++++++ sys/arch/x68k/stand/loadbsd/trampoline.S | 69 +++ sys/arch/x68k/stand/loadbsd/trampoline.h | 33 ++ 5 files changed, 865 insertions(+) create mode 100644 sys/arch/x68k/stand/loadbsd/Makefile create mode 100644 sys/arch/x68k/stand/loadbsd/loadbsd.8 create mode 100644 sys/arch/x68k/stand/loadbsd/loadbsd.c create mode 100644 sys/arch/x68k/stand/loadbsd/trampoline.S create mode 100644 sys/arch/x68k/stand/loadbsd/trampoline.h diff --git a/sys/arch/x68k/stand/loadbsd/Makefile b/sys/arch/x68k/stand/loadbsd/Makefile new file mode 100644 index 000000000000..eb8af94d8920 --- /dev/null +++ b/sys/arch/x68k/stand/loadbsd/Makefile @@ -0,0 +1,36 @@ +# $NetBSD: Makefile,v 1.1 1998/09/01 19:55:32 itohy Exp $ + +BASE= loadbsd +PROG= ${BASE}.x # Human68k ".x" executable +STRIPFLAG= # not an a.out +BINMODE=444 # not to be run on NetBSD +SRCS= start.S loadbsd.c xprintf.c trampoline.S +MAN= ${BASE}.8 + +BINDIR= /usr/mdec +MANSUBDIR= /${MACHINE} + +.PATH: ${.CURDIR}/../common + +AOUT2HUX!=cd ${.CURDIR}/../aout2hux; echo `${MAKE} print-objdir`/aout2hux +LIBDOS!=cd ${.CURDIR}/../libdos; ${MAKE} print-objdir +LIBIOCS!=cd ${.CURDIR}/../libiocs; ${MAKE} print-objdir + +CPPFLAGS= -W -Wall -O -fomit-frame-pointer +CPPFLAGS+= -m68000 -Wa,-mc68000 +CPPFLAGS+= -I${.CURDIR}/../libdos -I${.CURDIR}/../libiocs +LDFLAGS= -nostdlib -static -N +LDLIBS= -L${LIBDOS} -ldos -L${LIBIOCS} -liocs -lc +DPADD+= ${AOUT2HUX} + +CLEANFILES+= ${BASE}1 ${BASE}2 + +${PROG}: ${BASE}1 ${BASE}2 + ${AOUT2HUX} -o ${.TARGET} ${BASE}1 11000 ${BASE}2 22000 + +.include + +.for i in 1 2 +${BASE}${i}: ${OBJS} ${LIBDOS}/libdos.a ${LIBIOCS}/libiocs.a + ${CC} -o ${.TARGET} ${LDFLAGS} -Wl,-T${i}${i}000 ${OBJS} ${LDLIBS} +.endfor diff --git a/sys/arch/x68k/stand/loadbsd/loadbsd.8 b/sys/arch/x68k/stand/loadbsd/loadbsd.8 new file mode 100644 index 000000000000..bca7030805f3 --- /dev/null +++ b/sys/arch/x68k/stand/loadbsd/loadbsd.8 @@ -0,0 +1,135 @@ +.\" $NetBSD: loadbsd.8,v 1.1 1998/09/01 19:55:33 itohy Exp $ +.Dd Aug 13, 1998 +.Dt LOADBSD 8 x68k +.Os NetBSD +.Sh NAME +.Nm loadbsd +.Nd load and boot NetBSD/x68k kernel from Human68k +.Sh SYNOPSIS +.Nm loadbsd.x +.Op Fl hvV +.Op Fl abDs +.Op Fl r Ar root_device +.Ar kernel_file +.Sh DESCRIPTION +.Nm +is a program runs on Human68k. +It loads and executes the specified +.Nx Ns Tn /x68k +kernel. +.Pp +The options (for +.Nm +itself) are as follows: +.Bl -tag -width flag +.It Fl h +Show help and exit. +.It Fl v +Enable verbose mode. +.It Fl V +Print version of +.Nm +and exit. +.El +.Pp +The options for +.Nx +kernel are as follows: +.Bl -tag -width flag +.It Fl a +Auto (multi-user) boot. +This disables +.Fl s +flag. +.It Fl b +Ask boot device during boot. +Pass +.Dv RB_ASKNAME +boot flag to the kernel. +.It Fl d +Use compiled-in rootdev. +Pass +.Dv RB_DFLTROOT +boot flag to the kernel. +.It Fl D +Enter kernel debugger. +Pass +.Dv RB_KDB +boot flag to the kernel. +.It Fl r Ar root_device +Specify boot device, which shall be mounted as root device. +The default device is +.Sq Li sd@0,0:a . +Note that the boot device name is +.Em not +the same as that of +.Nx . +See +.Sx BOOT DEVICE NAMES +below. +.It Fl s +Single user boot. +Pass +.Dv RB_SINGLE +boot flag to the kernel. +This disables +.Fl a +flag. +This flag is set by default. +.El +.Pp +Although listed separately, the options may be in any order. +.Sh BOOT DEVICE NAMES +The format of boot device names is: +.Pp +.Dl "[/interface/]dev@unit[,lun][:partition]" +.Pp +.Bl -tag -width Fl +.It interface +SCSI interface type. +One of: +.Sq Li spc@0 , +.Sq Li spc@1 , +.Sq Li mha@0 . +If the dev is a SCSI device, and interface is omitted, +the current boot interface is used. +.It dev +Device type. +One of: +.Sq Li fd +(floppy disk drive), +.Sq Li sd +(SCSI disk), +.Sq Li cd +(SCSI CD-ROM), +.Sq Li md +(Memory disk). +.It unit +Device unit #. +You must specify the target SCSI ID if dev is a SCSI device. +.It lun +SCSI LUN #. +0 is assumed if omitted. +.It partition +Partition letter of device. +Partition +.Sq Li a +is used if omitted. +.El +.Sh FILES +.Bl -tag -width /usr/mdec/loadbsd.xxxx -compact +.It Pa /usr/mdec/loadbsd.x +You will find this program here. +.El +.Sh SEE ALSO +.Xr reboot 2 , +.Xr boot 8 +.Sh BUGS +.Nm +reads the entire kernel image at once, +and requires enough free area on the main memory. +.Sh HISTORY +The +.Nm +utility first appeared in +.Nx 1.4 . diff --git a/sys/arch/x68k/stand/loadbsd/loadbsd.c b/sys/arch/x68k/stand/loadbsd/loadbsd.c new file mode 100644 index 000000000000..d26daaa903f9 --- /dev/null +++ b/sys/arch/x68k/stand/loadbsd/loadbsd.c @@ -0,0 +1,592 @@ +/* + * Load and boot NetBSD kernel on Human68k + * + * written by Yasha (ITOH Yasufumi) + * public domain + * + * loadbsd [-hvV] [-abDs] [-r root_device] netbsd + * + * loadbsd options: + * -h help + * -v verbose + * -V print version and exit + * + * kernel options: + * -a auto boot, opposite of -s + * -s single user boot (default) + * -D enter kernel debugger + * -b ask root device + * -d use compiled-in rootdev + * -r specify root device + * + * $NetBSD: loadbsd.c,v 1.1 1998/09/01 19:55:33 itohy Exp $ + */ + +#include + +__RCSID("$NetBSD: loadbsd.c,v 1.1 1998/09/01 19:55:33 itohy Exp $"); +#define VERSION "$Revision: 1.1 $ $Date: 1998/09/01 19:55:33 $" + +#include /* ntohl */ +#include +#include /* ALIGN, ALIGNBYTES */ +#include +#include +#include + +#include +#include +#include "../common/xprintf.h" +#include "trampoline.h" + +#define DEFAULT_ROOTDEVNAME "sd@0,0:a" + +#define ISDIGIT(c) ((c) >= '0' && (c) <= '9') + +#define GETDECIMAL(var, str) \ + do { var *= 10; var += *str++ - '0'; } while (ISDIGIT(*str)) + +static const char *lookupif __P((const char *name, + unsigned *pif, unsigned *punit)); +static void get_current_scsi_interface __P((unsigned *pif, unsigned *punit)); +static int bootdev __P((const char *devstr)); +static struct tramparg *read_kernel __P((const char *fn)); +static int chkmpu __P((void)); +static __dead void usage __P((int status, const char *msg)) + __attribute__((noreturn)); + +int main __P((int argc, char *argv[])); + +int opt_v; +int opt_N; + +const struct hatbl { + char name[4]; + unsigned short id; +} hatable[] = { + X68K_BOOT_SCSIIF_LIST +}; + +/* + * parse interface name + * returns the next position + */ +static const char * +lookupif(name, pif, punit) + const char *name; + unsigned *pif, *punit; +{ + unsigned u, unit; + const char *p; + + for (u = 0; u < sizeof hatable / sizeof hatable[0]; u++) { + const char *n; + + for (n = hatable[u].name, p = name; *n && *n == *p; n++, p++) + ; + if (!*n) + goto found; + } + /* not found */ + return (char *) 0; + +found: + if (*p == '@') + p++; + + /* get unit # */ + if (!ISDIGIT(*p)) + return (char *) 0; + + unit = 0; + GETDECIMAL(unit, p); + + *pif = hatable[u].id; + *punit = unit; + + return p; +} + +/* + * if the SCSI interface is not specified, use the current one + */ +static void +get_current_scsi_interface(pif, punit) + unsigned *pif, *punit; +{ + unsigned binf; + char *bootrom; + int bus_err_buf; + + binf = (unsigned) IOCS_BOOTINF(); + if (binf < 0x00fc0000) + return; /* not booted from SCSI */ + + bootrom = (char *) (binf & 0x00ffffe0); + if (IOCS_B_LPEEK(bootrom + 0x24) == 0x53435349 && /* 'SCSI' */ + IOCS_B_WPEEK(bootrom + 0x28) == 0x494E) { /* 'IN' */ + /* spc0 */ + *pif = X68K_BOOT_SCSIIF_SPC; + *punit = 0; + } else if (DOS_BUS_ERR(&bus_err_buf, (void *)EXSPC_BDID, 1)) { + /* mha0 */ + *pif = X68K_BOOT_SCSIIF_MHA; + *punit = 0; + } else { + /* spc1 */ + *pif = X68K_BOOT_SCSIIF_SPC; + *punit = 1; + } +} + +/* + * parse device name + * + * [/@/]@[,][:] + * + * must be target SCSI ID if is a SCSI device + * + * full form: + * /spc@0/sd@1,2:e + * + * partial form: + * /mha@0/sd@1 = /mha@0/sd@1,0,:a + * sd@1:e = /current_device/sd@1,0e + * sd@1,2:e = /current_device/sd@1,2:e + */ + +const struct devtbl { + char name[3]; + u_char major; +} devtable[] = { + X68K_BOOT_DEV_LIST +}; + +static int +bootdev(devstr) + const char *devstr; +{ + unsigned u; + unsigned major, unit, lun, partition; + int dev; + const char *s = devstr; + unsigned interface = 0, unit_if = 0; + + if (*s == '/') { + /* + * //" + * "/spc@1/sd@2,3:e" + */ + while (*++s == '/') /* skip slashes */ + ; + if (!strchr(s, '/')) + xerrx(1, "%s: bad format", devstr); + + if (!(s = lookupif(s, &interface, &unit_if))) + xerrx(1, "%s: unknown interface", devstr); + + while (*s == '/') /* skip slashes */ + s++; + } else { + /* make lint happy */ + interface = 0; + unit_if = 0; + } + + /* allow r at the top */ + if (*s == 'r') + s++; + + for (u = 0; u < sizeof devtable / sizeof devtable[0]; u++) + if (s[0] == devtable[u].name[0] && s[1] == devtable[u].name[1]) + goto found; + + /* not found */ + xerrx(1, "%s: unknown device", devstr); + +found: major = devtable[u].major; + + /* + * @unit[,lun][:part] + * "sd@1,3:a" + */ + + /* get device unit # */ + s += 2; + if (*s == '@') + s++; + if (!*s) + xerrx(1, "%s: missing unit number", devstr); + if (!ISDIGIT(*s)) + xerrx(1, "%s: wrong device", devstr); + + unit = 0; + GETDECIMAL(unit, s); + + lun = 0; + if (*s == ',') { + s++; + if (!ISDIGIT(*s)) + xerrx(1, "%s: wrong device", devstr); + GETDECIMAL(lun, s); + } + + /* get device partition */ + if (*s == ':') + s++; + if (!*s) + partition = 0; /* no partition letter -- assuming 'a' */ + else if (!s[1]) + partition = *s - 'a'; + else + xerrx(1, "%s: wrong partition letter", devstr); + + /* + * sanity check + */ + if (unit_if >= 16) + xerrx(1, "%s: interface unit # too large", devstr); + if (unit >= 16) + xerrx(1, "%s: device unit # too large", devstr); + if (lun >= 8) + xerrx(1, "%s: SCSI LUN >= 8 is not supported yet", devstr); + if (partition >= 16) + xerrx(1, "%s: unsupported partition", devstr); + + /* + * encode device to be passed to kernel + */ + if (X68K_BOOT_DEV_IS_SCSI(major)) { + /* + * encode SCSI device + */ + if (interface == 0) + get_current_scsi_interface(&interface, &unit_if); + + dev = X68K_MAKESCSIBOOTDEV(major, interface, unit_if, + unit, lun, partition); + } else { + /* encode non-SCSI device */ + dev = X68K_MAKEBOOTDEV(major, unit, partition); + } + + if (opt_v) + xwarnx("%s: major %u, if %u, un_if %u, unit %u, lun %u, partition %u; bootdev 0x%x", + devstr, major, interface, unit_if, unit, lun, partition, dev); + + return dev; +} + +/* + * read kernel and create trampoline + * + * |----------------------| <- allocated buf addr + * | kernel image | + * ~ (header is excluded) ~ + * | | + * |----------------------| <- return value (entry addr of trampoline) + * | struct tramparg | + * | (trampoline args) | + * |----------------------| + * | trampoline code | + * | (in assembly) | + * |----------------------| + */ +static struct tramparg * +read_kernel(fn) + const char *fn; +{ + int fd; + union dos_fcb *fcb; + size_t filesize, nread; + void *buf; + struct exec hdr; + int i; + struct tramparg *arg; + size_t size_tramp = end_trampoline - trampoline; + + if ((fd = DOS_OPEN(fn, 0x20)) < 0) /* RO, share READ */ + xerr(1, "%s: open", fn); + + if ((int)(fcb = DOS_GET_FCB_ADR(fd)) < 0) + xerr(1, "%s: get_fcb_adr", fn); + + /* + * XXX FCB is in supervisor area + */ + /*if (fcb->blk.mode != 0)*/ + if (IOCS_B_BPEEK((char *)fcb + 1) & 0x80) + xerrx(1, "%s: Not a regular file", fn); + + /*filesize = fcb->blk.size;*/ + filesize = IOCS_B_LPEEK(&fcb->blk.size); + + /* + * read a.out header + */ + if ((nread = DOS_READ(fd, (void *) &hdr, sizeof hdr)) != sizeof hdr) { + if ((int)nread < 0) + xerr(1, "%s: read header", fn); + else + xerrx(1, "%s: Not an a.out", fn); + } + /* + * check header + */ + if (N_GETMAGIC(hdr) != NMAGIC) + xerrx(1, "%s: Bad magic number", fn); + if ((i = N_GETMID(hdr)) != MID_M68K) + xerrx(1, "%s: Wrong architecture (mid %d)", fn, i); + + if (opt_v) + xwarnx("%s: %u bytes; text %u, data %u, bss %u, sym %u", + fn, filesize, hdr.a_text, hdr.a_data, + hdr.a_bss, hdr.a_syms); + + /* + * then, read entire body + */ + if ((int)(buf = DOS_MALLOC(filesize + ALIGNBYTES - sizeof hdr + + sizeof(struct tramparg) + + size_tramp + SIZE_TMPSTACK)) < 0) + xerr(1, "read_kernel"); + + if ((nread = DOS_READ(fd, buf, filesize - sizeof hdr)) + != filesize - sizeof hdr) { + if ((int)nread < 0) + xerr(1, "%s: read", fn); + else + xerrx(1, "%s: short read", fn); + } + + if (DOS_CLOSE(fd) < 0) + xerr(1, "%s: close", fn); + + /* + * create argument for trampoline code + */ + arg = (struct tramparg *) ALIGN(buf + nread); + + if (opt_v) + xwarnx("trampoline arg at %p", arg); + + arg->bsr_inst = TRAMP_BSR + sizeof(struct tramparg) - 4; + arg->tmp_stack = (char *) arg + sizeof(struct tramparg) + + size_tramp + SIZE_TMPSTACK; + arg->mpu_type = IOCS_MPU_STAT() & 0xff; + arg->xk.image_top = buf; + arg->xk.load_addr = 0x00000000; /* XXX should not be a fixed addr */ + arg->xk.text_size = hdr.a_text; + arg->xk.data_size = hdr.a_data; + arg->xk.bss_size = hdr.a_bss; + arg->xk.symbol_size = hdr.a_syms; + arg->xk.d5 = IOCS_BOOTINF(); /* unused for now */ +#if 0 + /* filled afterwards */ + arg->xk.rootdev = + arg->xk.boothowto = +#endif + arg->xk.entry_addr = hdr.a_entry; + + if (opt_v) + xwarnx("args: mpu %d, image %p, load 0x%x, entry 0x%x", + arg->mpu_type, arg->xk.image_top, arg->xk.load_addr, + arg->xk.entry_addr); + + /* + * copy trampoline code + */ + if (opt_v) + xwarnx("trampoline code at %p (%u bytes)", + (char *) arg + sizeof(struct tramparg), size_tramp); + + memcpy((char *) arg + sizeof(struct tramparg), trampoline, size_tramp); + + return arg; +} + +/* + * MC68000/010 -> return zero + * MC68020 and later -> return nonzero + */ +static int +chkmpu() +{ + register int ret asm("d0"); + + asm("| %0 <- this must be d0\n\ + moveq #1,d0\n\ + .long 0x103B02FF | foo: moveb pc@((foo+1)-foo-2:B,d0:W:2),d0\n\ + | ^ ^\n\ + | d0.b = 0x02 (68000/010)\n\ + | = 0xff (68020 and later)\n\ + bmis 1f\n\ + moveq #0,d0 | 68000/010\n\ +1:" : "=d" (ret)); + + return ret; +} + +static __dead void +usage(status, msg) + int status; + const char *msg; +{ + extern const char *const __progname; + + if (msg) + xwarnx("%s", msg); + + xerrprintf("\ +%s [-hvV] [-abDs] [-r root_device] netbsd\n\ +\n\ +loadbsd options:\n\ +\t-h help\n\ +\t-v verbose\n\ +\t-V print version and exit\n\ +\n\ +kernel options:\n\ +\t-a auto boot, opposite of -s\n\ +\t-s single user boot (default)\n\ +\t-D enter kernel debugger\n\ +\t-b ask root device\n\ +\t-d use compiled-in rootdev\n\ +\t-r specify root device (default %s)\n\ +\t format: [/interface/]device@unit[,lun][:partition]\n\ +\t interface: one of spc@0, spc@1, mha@0\n\ +\t (current boot interface if omitted)\n\ +\t device: one of fd, sd, cd, md\n\ +\t unit: device unit number (SCSI ID for SCSI device)\n\ +\t lun: SCSI LUN # (0 if omitted)\n\ +\t partition: partition letter ('a' if omitted)\n\ +", __progname, DEFAULT_ROOTDEVNAME); + + DOS_EXIT2(status); +} + +int +main(argc, argv) + int argc; + char *argv[]; +{ + char *rootdevname = 0; + int rootdev; + u_long boothowto = RB_SINGLE; + const char *kernel; + char *p, **flg, **arg; + struct tramparg *tramp; + struct dos_dregs regs; /* unused... */ + int i; + + /* parse options */ + for (arg = flg = argv + 1; (p = *flg) && *p == '-'; ) { + int c; + + while ((c = *++p)) + switch (c) { + case 'h': + usage(0, (char *) 0); + /* NOTREACHED */ + break; + case 'N': /* don't actually execute kernel */ + opt_N = 1; + break; + case 'v': + opt_v = 1; + break; + case 'V': + xprintf("loadbsd %s\n", VERSION); + return 0; + + /* + * kernel boot flags + */ + case 'r': + if (rootdevname) + usage(1, "multiple -r flags"); + else if (!*++arg) + usage(1, "-r requires device name"); + else + rootdevname = *arg; + break; + case 'd': + boothowto |= RB_DFLTROOT; + break; + case 'b': + boothowto |= RB_ASKNAME; + break; + case 'a': + boothowto &= ~RB_SINGLE; + break; + case 's': + boothowto |= RB_SINGLE; + break; + case 'D': + boothowto |= RB_KDB; + break; + + default: + usage(1, (char *) 0); + /* NOTREACHED */ + break; + } + flg = ++arg; + } + + /* check MPU */ + if (chkmpu() == 0) + xerrx(1, "Can't boot NetBSD on 68000/010"); + + argc -= arg - argv; + argv = arg; + + if (argc != 1) + usage(1, (char *) 0); + + kernel = *argv; + + rootdev = bootdev(rootdevname ? rootdevname : DEFAULT_ROOTDEVNAME); + + if (opt_v) + xwarnx("boothowto 0x%x", boothowto); + + tramp = read_kernel(kernel); + + tramp->xk.rootdev = rootdev; + tramp->xk.boothowto = boothowto; + + /* + * we never returns, and make sure the disk cache + * be flushed (if write-back cache is enabled) + */ + if (opt_v) + xwarnx("flush disk cache..."); + + i = DOS_FFLUSH_SET(1); /* enable fflush */ + DOS_FFLUSH(); /* then, issue fflush */ + (void) DOS_FFLUSH_SET(i); /* restore old mode just in case */ + + /* + * the program assumes the MPU caches off + */ + if (opt_v) + xwarnx("flush and disable MPU caches..."); + + IOCS_CACHE_MD(-1); /* flush */ + if (!opt_N) + IOCS_CACHE_MD(0); /* disable both caches */ + + if (opt_v) + xwarnx("Jumping to the kernel. Good Luck!"); + + if (opt_N) + xerrx(0, "But don't actually do it."); + + DOS_SUPER_JSR((void (*) __P((void))) tramp, ®s, ®s); + + /* NOTREACHED */ + + xwarnx("??? return from kernel"); + + return 1; +} diff --git a/sys/arch/x68k/stand/loadbsd/trampoline.S b/sys/arch/x68k/stand/loadbsd/trampoline.S new file mode 100644 index 000000000000..4dfc8f0984f1 --- /dev/null +++ b/sys/arch/x68k/stand/loadbsd/trampoline.S @@ -0,0 +1,69 @@ +| +| copy binary image and execute +| +| written by Yasha (ITOH Yasufumi) +| public domain +| +| $NetBSD: trampoline.S,v 1.1 1998/09/01 19:55:33 itohy Exp $ + +#include +#include "trampoline.h" + +| arg+0 bsr trampoline +| +4 a3+0 temporary stack address +| +8 a3+4 processor type +| +12 a3+8 struct execkern_arg +| +52 trampoline + +ENTRY_NOPROFILE(trampoline) + oriw #0x0700,sr | keep out interrupts + + moveal sp@+,a3 + moveal a3@+,sp | set temporary stack + + movel a3@+,d2 | MPU type + + | + | turn off MMU + | + moveq #MPU_68030,d0 + cmpl d2,d0 + bccs Lmmu030 + | 040/060 + moveq #0,d0 + .long 0x4E7B0003 | movec d0,tc + .long 0x4E7B0004 | movec d0,itt0 + .long 0x4E7B0005 | movec d0,itt1 + .long 0x4E7B0006 | movec d0,dtt0 + .long 0x4E7B0007 | movec d0,dtt1 + .long 0x4E7B0806 | movec d0,urp + .long 0x4E7B0807 | movec d0,srp + bras Lmmudone +Lmmu030: + | 020/030 + clrl sp@- + .long 0xF0174000 | pmove sp@,tc + cmpl d0,d2 + bnes Lmmu020 | 68851 has no tt regs + .long 0xF0170800 | pmove sp@,tt0 + .long 0xF0170C00 | pmove sp@,tt1 +Lmmu020: + movel #0x7fff0001,sp@- | null root pointer + .long 0xF0174C00 | pmove sp@,crp + .long 0xF0174800 | pmove sp@,srp + addql #8,sp +Lmmudone: + + | minimize supervisor protection + clrb AREA_SET_REG + + | reset VBR (for compatibility) + subal a1,a1 + .long 0x4E7B9801 | movec a1,vbr + + | then transfer and exec kernel + +#define XK_NO_C_INTERFACE /* pass arg with a3 */ +#include "../common/execkern.S" + +GLOBAL(end_trampoline) diff --git a/sys/arch/x68k/stand/loadbsd/trampoline.h b/sys/arch/x68k/stand/loadbsd/trampoline.h new file mode 100644 index 000000000000..612f5c3fe716 --- /dev/null +++ b/sys/arch/x68k/stand/loadbsd/trampoline.h @@ -0,0 +1,33 @@ +/* + * definitions for trampoline code + * + * written by Yasha (ITOH Yasufumi) + * public domain + * + * $NetBSD: trampoline.h,v 1.1 1998/09/01 19:55:33 itohy Exp $ + */ + +#define MPU_68030 3 +#define MPU_68040 4 +#define MPU_68060 6 + +#define AREA_SET_REG 0x00E86001 /* (B) supervisor protection reg */ + +#define EXSPC 0x00EA0000 /* external SCSI board */ +#define EXSPC_BDID (EXSPC + 1) /* (B) SCSI board bdid reg */ + +#define SIZE_TMPSTACK 8192 + +#ifndef __ASSEMBLER__ +#include "../common/execkern.h" + +struct tramparg { + unsigned bsr_inst; +#define TRAMP_BSR 0x61000000 /* bsr xxx */ + void *tmp_stack; + int mpu_type; + struct execkern_arg xk; +}; + +extern char trampoline[], end_trampoline[]; +#endif