diff --git a/sys/arch/mvme68k/stand/bootst/Makefile b/sys/arch/mvme68k/stand/bootst/Makefile new file mode 100644 index 000000000000..9e35d6f8e05b --- /dev/null +++ b/sys/arch/mvme68k/stand/bootst/Makefile @@ -0,0 +1,39 @@ +# from: @(#)Makefile 8.1 (Berkeley) 6/10/93 +# $OpenBSD$ + +RELOC=0x3F0000 + +S= ${.CURDIR}/../../../.. +DEFS= +INCPATH=-I${.CURDIR} -I${.CURDIR}/../libsa -I${.CURDIR}/../libbug \ + -I${.CURDIR}/../../include -I${S} -I${S}/lib/libsa +CFLAGS= -O2 ${INCPATH} ${DEFS} ${COPTS} +CLEANFILES+=stboot bootst bootst.bug + +.include "${S}/arch/${MACHINE}/stand/libsa/Makefile.inc" +.include "${S}/arch/${MACHINE}/stand/libbug/Makefile.inc" +.include "${S}/arch/${MACHINE}/stand/bugcrt/Makefile.inc" +.include "${S}/arch/${MACHINE}/stand/wrtvid/Makefile.inc" + +SRCS= bootst.c + +LIBS= ${LIBSA} ${LIBBUG} + +OBJS= ${SRCS:N*.h:R:S/$/.o/g} + +BOOTS= bootst stboot +ALL= ${BOOTS} + +all: ${ALL} + +bootst.bug: ${OBJS} ${BUGCRT} ${LIBS} + ${LD} -s -N -T ${RELOC} ${BUGCRT} ${OBJS} ${LIBS} -o $@ + @size bootst.bug + +bootst stboot: bootst.bug ${WRTVID} + ${WRTVID} bootst.bug + +install: + install -c -m 555 -g bin -o bin ${BOOTS} ${DESTDIR}${MDEC_DIR} + +.include diff --git a/sys/arch/mvme68k/stand/bootst/bootst.c b/sys/arch/mvme68k/stand/bootst/bootst.c new file mode 100644 index 000000000000..66a38c9bad30 --- /dev/null +++ b/sys/arch/mvme68k/stand/bootst/bootst.c @@ -0,0 +1,315 @@ +/* $OpenBSD$ */ + +#include +#include +#include +#include +#include + +#include "stand.h" +#include "libsa.h" + +int load_kern(); +int read_tape_block __P((short ctrl, short dev, short *status, + void *addr, int *cnt, int blk_num, u_char *flags, int verbose)); + +struct kernel { + void *entry; + void *symtab; + void *esym; + int bflags; + int bdev; + char *kname; + void *smini; + void *emini; + u_int end_loaded; +} kernel; + +typedef(*kernel_entry) __P((struct mvmeprom_args *, struct kernel *)); + +int +main() +{ + kernel_entry addr; + struct mvmeprom_args *pbugargs; + + pbugargs = &bugargs; + /* + print_bugargs(pbugargs); + print_time(); + print_brdid(); + print_memory(); + */ + parse_args(&kernel.kname, &kernel.bflags); + if (load_kern(pbugargs) == 1) { + printf("unsuccessful in loading kernel\n"); + } else { + addr = kernel.entry; + +#if 0 + printf("kernel loaded at %x\n", addr); + printf("kernel.entry %x\n", kernel.entry); + printf("kernel.symtab %x\n", kernel.symtab); + printf("kernel.esym %x\n", kernel.esym); + printf("kernel.bflags %x\n", kernel.bflags); + printf("kernel.bdev %x\n", kernel.bdev); + if (kernel.kname) + printf("kernel.kname <%s>\n", kernel.kname); + else + printf("kernel.kname \n"); + printf("kernel.end_loaded %x\n", kernel.end_loaded); +#endif + + if (kernel.bflags & RB_MINIROOT) + loadmini(kernel.end_loaded, pbugargs); + +#if 0 + printf("kernel.smini %x\n", kernel.smini); + printf("kernel.emini %x\n", kernel.emini); + printf("kernel.end_loaded %x\n", kernel.end_loaded); +#endif + if (kernel.bflags & RB_HALT) + _rtt(); + if (((u_long)addr &0xf) == 0x2) { + (addr)(pbugargs, &kernel); + } else { + /* is type fixing anything like price fixing? */ + typedef (* kernel_start) __P((int, int, void *,void *, void *)); + kernel_start addr1; + addr1 = (void *)addr; + (addr1)(kernel.bflags, 0, kernel.esym, kernel.smini, kernel.emini + ); + } + + } + return (0); +} + +#define MVMEPROM_SCALE (512/MVMEPROM_BLOCK_SIZE) + +int +read_tape_block(ctrl, dev, status, addr, cnt, blk_num, flags, verbose) + short ctrl; + short dev; + short *status; + void *addr; + int *cnt; + int blk_num; + u_char *flags; + int verbose; +{ + struct mvmeprom_dskio dio; + int ret; + + dio.ctrl_lun = ctrl; + dio.dev_lun = dev; + dio.status = *status; + dio.pbuffer = addr; + dio.blk_num = blk_num; + dio.blk_cnt = *cnt / (512 / MVMEPROM_SCALE); + dio.flag = *flags; + dio.addr_mod = 0; + + if (verbose) + printf("saddr %x eaddr %x", dio.pbuffer, + (int) dio.pbuffer + (dio.blk_cnt * MVMEPROM_BLOCK_SIZE)); + ret = mvmeprom_diskrd(&dio); + + *status = dio.status; + *cnt = (dio.blk_cnt / MVMEPROM_SCALE) * 512; + if (verbose) { + printf("status %x ret %d ", *status, ret); + printf("flags %x blocks read %x cnt %x\n", + *flags, dio.blk_cnt, *cnt); + } + return (ret); +} +#ifdef DEBUG +int verbose = 1; +#else +int verbose = 0; +#endif + +int +load_kern(pbugargs) + struct mvmeprom_args *pbugargs; +{ + int ret; + char *addr; + u_char flags; + short status = 0; + int blk_num; + struct exec *pexec; + int magic; + int *esym; + int *symtab; + int cnt, len; + char buf[512]; + + blk_num = 2; + /* flags = IGNORE_FILENUM; */ + flags = 0; + cnt = 512; + ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun, &status, + buf, &cnt, blk_num, &flags, verbose); + if (ret != 0) { + printf("unable to load kernel 1 status %x\n", status); + return (1); + } + pexec = (struct exec *) buf; + if (N_GETMID(*pexec) != MID_M68K && + N_GETMID(*pexec) != MID_M68K4K) { + printf("invalid mid on kernel\n"); + return (1); + } + + magic = N_GETMAGIC(*pexec); + switch (magic) { + case ZMAGIC: + break; + case NMAGIC: + printf("NMAGIC not yet supported"); + case OMAGIC: + case QMAGIC: + default: + printf("Unknown or unsupported magic type <%x>\n", magic); + return (1); + } + if (magic == ZMAGIC) { + status = 0; + addr = (char *) (pexec->a_entry & ~0x0FFF); + + bcopy(&buf, addr, 512); + /* 2nd block of exe */ + addr += 512; + + printf("text 0x%x data 0x%x bss 0x%x\n", + pexec->a_text, pexec->a_data, pexec->a_bss); + + len = (pexec->a_text - 512); /* XXX */ + len += (pexec->a_data); + + printf("loading [ %x + %x ", pexec->a_text, pexec->a_data); + + cnt = len; + flags = IGNORE_FILENUM; + ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun, + &status, addr, &cnt, blk_num, &flags, verbose); + if (ret != 0 || cnt != len) { + printf("unable to load kernel 2 status %x\n", status); + return 1; + } + addr += len; + + /* Skip over text and data and zero bss. */ + len = pexec->a_bss; + printf("+ %x", len); +#ifdef DEBUG + printf("bss %x - %x\n", addr, addr + pexec->a_bss); +#endif + bzero(addr, pexec->a_bss); + addr += len; + + if (pexec->a_syms != 0 && !(kernel.bflags & RB_NOSYM)) { + printf(" + [ %x", pexec->a_syms); + addr += 4; /* skip over _end symbol */ + symtab = (void *) pexec->a_syms; + len = pexec->a_syms; + cnt = ((len + (512 - 1)) / 512) * 512; + flags = IGNORE_FILENUM; + ret = read_tape_block(pbugargs->ctrl_lun, + pbugargs->dev_lun, &status, addr, + &cnt, blk_num, &flags, verbose); + if (ret != 0 || cnt != ((len + (512 - 1)) / 512) * 512) { + printf("unable to load kernel 3\n"); + return 1; + } + /* this value should have already been loaded XXX */ + esym = (void *) ((u_int) addr + pexec->a_syms); + if ((int) addr + cnt <= (int) esym) { + printf("missed loading count of symbols\n"); + return 1; + } + addr += cnt; + + + len = *esym; +#if 0 + printf("start load %x end load %x %x\n", addr, + len, addr + len); + printf("esym %x *esym %x\n", esym, len); +#endif + /* dont load tail of already loaded */ + len -= (u_int) addr - (u_int) esym; + + if (len > 0) { + printf(" + %x", *esym); + esym = (void *) (addr + len); + cnt = ((len + (512 - 1)) / 512) * 512; + flags = IGNORE_FILENUM; + ret = read_tape_block(pbugargs->ctrl_lun, + pbugargs->dev_lun, &status, addr, + &cnt, blk_num, &flags, verbose); + if (ret != 0 || cnt != ((len + (512-1)) / 512)*512) { + printf("unable to load kernel 4\n"); + return (1); + } + addr += len; + printf(" ]"); + } else { + printf("+ %x ]", *esym); + } + esym = (int *) (((int) esym) + *esym); + + kernel.symtab = symtab; + kernel.esym = esym; + } else { + kernel.symtab = 0; + kernel.esym = 0; + } + kernel.end_loaded = (int) addr; + flags = IGNORE_FILENUM | END_OF_FILE; + cnt = 8192; + printf("removing pad ["); + ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun, + &status, addr, &cnt, blk_num, &flags, verbose); + if (ret != 0) { + printf("unable to load kernel 5\n"); + return (1); + } + printf(" %d ]", cnt); + + printf("]\n"); + } + kernel.entry = (void *) pexec->a_entry; + return (0); +} + +int +loadmini(addr, pbugargs) + u_int addr; + struct mvmeprom_args *pbugargs; +{ + int cnt, ret, blk_num = 3; + short status = 0; + u_char flags; + + /* align addr to some boundary */ +#define ALIGN_F 0x4 + addr = (u_int) ((((int) addr + ALIGN_F - 1) / ALIGN_F) * ALIGN_F); +#undef ALIGN_F + flags = END_OF_FILE; + cnt = 6144 * 512; /* some abserdly large value. (3meg) */ + printf("loading miniroot[ "); + ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun, + &status, (void *) addr, &cnt, blk_num, &flags, verbose); + if (ret != 0) { + printf("unable to load miniroot\n"); + return (1); + } + kernel.smini = (void *)addr; + printf("%d ]\n", cnt); + kernel.emini = (void *) ((u_int) addr + cnt); + kernel.end_loaded = (u_int) kernel.emini; + return (0); +}