diff --git a/sys/arch/hpcsh/conf/GENERIC b/sys/arch/hpcsh/conf/GENERIC index 6f8f323c6a67..c997f09b1952 100644 --- a/sys/arch/hpcsh/conf/GENERIC +++ b/sys/arch/hpcsh/conf/GENERIC @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.14 2001/12/28 12:21:56 martin Exp $ +# $NetBSD: GENERIC,v 1.15 2002/01/27 05:14:33 uch Exp $ # # GENERIC machine description file # @@ -22,21 +22,29 @@ include "arch/hpcsh/conf/std.hpcsh" maxusers 32 # estimated number of users +options KLOADER_KERNEL_PATH="\"/netbsd\"" +options KLOADER_DEBUG +#options INTERRUPT_MONITOR +#options BUS_SPACE_DEBUG +#options PFCKBD_DEBUG +#options HD64461VIDEO_DEBUG +#options HD64461PCMCIA_DEBUG + options SH7709A # 133MHz options SH7709A_BROKEN_IPR options PCLOCK=22000000 # 22MHz options DDB # in-kernel debugger -options DIAGNOSTIC # extra kernel debugging checks -options DEBUG # extra kernel debugging support +#options DIAGNOSTIC # extra kernel debugging checks +#options DEBUG # extra kernel debugging support options KTRACE # system call tracing support options MSGBUFSIZE=65534 # Standard system options options RTC_OFFSET=-540 # hardware clock is this many mins. west of GMT -options SCSIVERBOSE # human readable SCSI error messages -options PCMCIAVERBOSE # verbose PCMCIA configuration messages +#options SCSIVERBOSE # human readable SCSI error messages +#options PCMCIAVERBOSE # verbose PCMCIA configuration messages # Executable format options options EXEC_COFF # 32-bit COFF executables diff --git a/sys/arch/hpcsh/conf/files.hpcsh b/sys/arch/hpcsh/conf/files.hpcsh index e42259fe26ba..08e55f57005d 100644 --- a/sys/arch/hpcsh/conf/files.hpcsh +++ b/sys/arch/hpcsh/conf/files.hpcsh @@ -1,9 +1,15 @@ -# $NetBSD: files.hpcsh,v 1.14 2001/07/02 17:19:09 uch Exp $ +# $NetBSD: files.hpcsh,v 1.15 2002/01/27 05:14:33 uch Exp $ # maxpartitions 8 maxusers 2 16 64 +defflag debug_hpcsh.h BUS_SPACE_DEBUG + KLOADER_DEBUG + PFCKBD_DEBUG + HD64461VIDEO_DEBUG + HD64461PCMCIA_DEBUG + file arch/hpcsh/hpcsh/conf.c file arch/hpcsh/hpcsh/machdep.c file arch/hpcsh/hpcsh/clock.c @@ -11,7 +17,13 @@ file arch/hpcsh/hpcsh/console.c file arch/hpcsh/hpcsh/autoconf.c file arch/hpcsh/hpcsh/bus_space.c file arch/hpcsh/hpcsh/procfs_machdep.c procfs + file arch/hpcsh/hpcsh/debug.c +defflag opt_interrupt_monitor.h INTERRUPT_MONITOR + +file arch/hpcsh/hpcsh/kloader.c +defparam opt_kloader_kernel_path.h KLOADER_KERNEL_PATH + device mainbus { [id = -1] } diff --git a/sys/arch/hpcsh/hpcsh/kloader.c b/sys/arch/hpcsh/hpcsh/kloader.c new file mode 100644 index 000000000000..fac44cbbab36 --- /dev/null +++ b/sys/arch/hpcsh/hpcsh/kloader.c @@ -0,0 +1,532 @@ +/* $NetBSD: kloader.c,v 1.1 2002/01/27 05:14:34 uch Exp $ */ + +/*- + * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "debug_hpcsh.h" + +#include +#include +#include +#include +#include +#include +#define ELFSIZE 32 +#include + +#include + +#include +#include + +#ifdef KLOADER_DEBUG +#define DPRINTF_ENABLE +#define DPRINTF_DEBUG kloader_debug +#endif +#include + +/* XXX-start should be in sh3/include */ +#define SH7709A_CCA 0xf0000000 + +#define SH7709A_CACHE_LINESZ 16 +#define SH7709A_CACHE_ENTRY 256 +#define SH7709A_CACHE_WAY 4 +#define SH7709A_CACHE_SIZE \ + (SH7709A_CACHE_LINESZ * SH7709A_CACHE_ENTRY * SH7709A_CACHE_WAY) + +#define SH7709A_CACHE_ENTRY_SHIFT 4 +#define SH7709A_CACHE_ENTRY_MASK 0x00000ff0 +#define SH7709A_CACHE_WAY_SHIFT 12 +#define SH7709A_CACHE_WAY_MASK 0x00003000 + +#define SH7709A_CACHE_FLUSH() \ +do { \ + u_int32_t __e, __w, __wa, __a; \ + \ + for (__w = 0; __w < SH7709A_CACHE_WAY; __w++) { \ + __wa = SH7709A_CCA | __w << SH7709A_CACHE_WAY_SHIFT; \ + for (__e = 0; __e < SH7709A_CACHE_ENTRY; __e++) { \ + __a = __wa |(__e << SH7709A_CACHE_ENTRY_SHIFT); \ + /* Clear U,V bit */ \ + (*(__volatile__ u_int32_t *)__a) &= ~0x3; \ + } \ + } \ +} while (/*CONSTCOND*/0) +/* XXX-end should be in sh3/include */ + +struct kloader_page_tag { + u_int32_t next; + u_int32_t src; + u_int32_t dst; + u_int32_t sz; +}; +#define BUCKET_SIZE (PAGE_SIZE - sizeof(struct kloader_page_tag)) + +STATIC struct { + struct pglist pg_head; +#define PG_VADDR(pg) SH3_PHYS_TO_P1SEG(VM_PAGE_TO_PHYS(pg)) + struct vm_page *cur_pg; + struct vnode *vp; + struct kloader_page_tag *tagstart; + struct kloader_bootinfo *bootinfo; + vaddr_t loader_sp; + void (*loader)(struct kloader_bootinfo *, struct kloader_page_tag *); + int setuped; +} kloader; + +extern paddr_t avail_start, avail_end; + +STATIC void kloader_boot(struct kloader_bootinfo *, struct kloader_page_tag *); +STATIC int kloader_load(void); +STATIC int kloader_alloc_memory(size_t); +STATIC void kloader_load_segment(vaddr_t, vsize_t, off_t, size_t); +STATIC void kloader_load_segment_end(void); +STATIC void kloader_load_bucket(vaddr_t, off_t, size_t); + +STATIC struct vnode *kloader_open(const char *); +STATIC void kloader_close(void); +STATIC int kloader_read(size_t, size_t, void *); + +#ifdef KLOADER_DEBUG +STATIC void kloader_pagetag_dump(void); +STATIC void kloader_bootinfo_dump(void); +#endif + +#define KLOADER_PROC (&proc0) + +void +kloader_reboot_setup(const char *filename) +{ + + if (kloader.bootinfo == NULL) { + PRINTF("No bootinfo.\n"); + return; + } + + PRINTF("kernel file name: %s\n", filename); + kloader.vp = kloader_open(filename); + if (kloader.vp == NULL) + return; + + if (kloader_load() != 0) + goto end; + + kloader.setuped = 1; +#ifdef KLOADER_DEBUG + kloader_pagetag_dump(); +#endif + end: + kloader_close(); +} + +void +kloader_reboot() +{ + + if (!kloader.setuped) + return; + +#ifdef KLOADER_DEBUG + kloader_bootinfo_dump(); +#endif + PRINTF("Rebooting...\n"); + + SH7709A_CACHE_FLUSH(); + + __asm__ __volatile__( + "mov %0, r4;" + "mov %1, r5;" + "jmp @%2;" + "mov %3, sp" + : : + "r"(kloader.bootinfo), + "r"(kloader.tagstart), + "r"(kloader.loader), + "r"(kloader.loader_sp)); + /* NOTREACHED */ +} + +/* + * 2nd-bootloader. Make sure that PIC and its size is lower than page size. + */ +void +kloader_boot(struct kloader_bootinfo *kbi, struct kloader_page_tag *p) +{ + int tmp; + + /* Disable interrupt. block exception.(TLB exception don't occur) */ + __asm__ __volatile__( + "stc sr, %1;" + "or %0, %1;" + "ldc %1, sr" : : "r"(0x500000f0), "r"(tmp)); + + /* Now I run on P1, TLB flush. and disable. */ + SHREG_MMUCR = MMUCR_TF; + + do { + u_int32_t *dst =(u_int32_t *)p->dst; + u_int32_t *src =(u_int32_t *)p->src; + u_int32_t sz = p->sz / sizeof (int); + while (sz--) + *dst++ = *src++; + } while ((p = (struct kloader_page_tag *)p->next) != 0); + + SH7709A_CACHE_FLUSH(); + + /* jump to kernel entry. */ + __asm__ __volatile__( + "mov %0, r4;" + "mov %1, r5;" + "jmp @%3;" + "mov %2, r6;" + : : + "r"(kbi->argc), + "r"(kbi->argv), + "r"(&kbi->bootinfo), + "r"(kbi->entry)); + /* NOTREACHED */ +} + +int +kloader_load() +{ + Elf_Ehdr eh; + Elf_Phdr ph[16], *p; + Elf_Shdr sh[16]; + vaddr_t kv; + size_t sz; + int i; + + /* read kernel's ELF header */ + kloader_read(0, sizeof(Elf_Ehdr), &eh); + + if (eh.e_ident[EI_MAG0] != ELFMAG0 || + eh.e_ident[EI_MAG1] != ELFMAG1 || + eh.e_ident[EI_MAG2] != ELFMAG2 || + eh.e_ident[EI_MAG3] != ELFMAG3) { + PRINTF("not a ELF file\n"); + return (1); + } + + /* read section header */ + kloader_read(eh.e_shoff, eh.e_shentsize * eh.e_shnum, sh); + + /* read program header */ + kloader_read(eh.e_phoff, eh.e_phentsize * eh.e_phnum, ph); + + /* calcurate memory size */ + DPRINTF("file size: "); + for (sz = 0, i = 0; i < eh.e_phnum; i++) { + if (ph[i].p_type == PT_LOAD) { + size_t filesz = ph[i].p_filesz; + _DPRINTF("+0x%x", filesz); + sz += sh3_round_page(filesz); + } + } + _DPRINTF(" entry: %08x\n", eh.e_entry); + + /* get memory for new kernel */ + if (kloader_alloc_memory(sz) != 0) + return (1); + + /* copy newkernel to memory */ + for (i = 0, p = ph; i < eh.e_phnum; i++, p++) { + if (p->p_type == PT_LOAD) { + size_t filesz = p->p_filesz; + size_t memsz = p->p_memsz; + off_t fileofs = p->p_offset; + kv = p->p_vaddr; + DPRINTF("[%d] vaddr 0x%08lx file size 0x%x" + " mem size 0x%x\n", i, kv, filesz, memsz); + kloader_load_segment(kv, memsz, fileofs, filesz); + kv += memsz; + } + } + /* end tag */ + kloader_load_segment_end(); + + /* copy loader code */ + KDASSERT(kloader.cur_pg); + kloader.loader = (void *)PG_VADDR(kloader.cur_pg); + memcpy(kloader.loader, kloader_boot, PAGE_SIZE); + + /* loader stack */ + kloader.cur_pg = TAILQ_NEXT(kloader.cur_pg, pageq); + KDASSERT(kloader.cur_pg); + kloader.loader_sp = (vaddr_t)PG_VADDR(kloader.cur_pg); + + /* kernel entry point */ + kloader.bootinfo->entry = eh.e_entry; + + DPRINTF("[loader] addr=%p sp=0x%08lx [kernel] addr=0x%08lx\n", + kloader.loader, kloader.loader_sp, kloader.bootinfo->entry); + + return (0); +} + +int +kloader_alloc_memory(size_t sz) +{ + int i, n, error; + + n = (sz + BUCKET_SIZE - 1) / BUCKET_SIZE /* kernel */ + + 1 /* 2nd loader */ + + 1; /* 2nd loader's stack */ + + TAILQ_INIT(&kloader.pg_head); + + for (i = 0; i < n; i++) { + error = uvm_pglistalloc(PAGE_SIZE, avail_start, avail_end, + PAGE_SIZE, PAGE_SIZE, &kloader.pg_head, 0, 0); + if (error) { + uvm_pglistfree(&kloader.pg_head); + PRINTF("can't allocate memory.\n"); + return (1); + } + } + + kloader.cur_pg = TAILQ_FIRST(&kloader.pg_head); + kloader.tagstart = (void *)PG_VADDR(kloader.cur_pg); + + return (0); +} + +void kloader_load_segment(vaddr_t kv, vsize_t memsz, off_t fileofs, + size_t filesz) +{ + int i, n; + + if (filesz == 0) + return; + + n = filesz / BUCKET_SIZE; + for (i = 0; i < n; i ++) { + kloader_load_bucket(kv, fileofs, BUCKET_SIZE); + kv += BUCKET_SIZE; + fileofs += BUCKET_SIZE; + } + + n = filesz % BUCKET_SIZE; + if (n) { + kloader_load_bucket(kv, fileofs, n); + } +} + +void +kloader_load_segment_end() +{ + struct vm_page *pg; + + pg = TAILQ_PREV(kloader.cur_pg, pglist, pageq); + + ((struct kloader_page_tag *)PG_VADDR(pg))->next = 0; +} + +void +kloader_load_bucket(vaddr_t kv, off_t ofs, size_t sz) +{ + struct vm_page *pg = kloader.cur_pg; + vaddr_t addr = PG_VADDR(pg); + struct kloader_page_tag *tag = (void *)addr; + + KDASSERT(pg != NULL); + + tag->src = addr + sizeof(struct kloader_page_tag); + tag->dst = kv; + tag->sz = sz; + + kloader_read(ofs, sz, (void *)tag->src); + + pg = TAILQ_NEXT(pg, pageq); + tag->next = PG_VADDR(pg); + kloader.cur_pg = pg; +} + +/* + * file access + */ +struct vnode * +kloader_open(const char *filename) +{ + struct proc *p = KLOADER_PROC; + struct nameidata nid; + + NDINIT(&nid, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, p); + + if (namei(&nid) != 0) { + PRINTF("namei failed (%s)\n", filename); + return (0); + } + + if (vn_open(&nid, FREAD, 0) != 0) { + PRINTF("%s open failed\n", filename); + return (0); + } + + return (nid.ni_vp); +} + +void +kloader_close() +{ + struct proc *p = KLOADER_PROC; + struct vnode *vp = kloader.vp; + + VOP_UNLOCK(vp, 0); + vn_close(vp, FREAD, p->p_ucred, p); +} + +int +kloader_read(size_t ofs, size_t size, void *buf) +{ + struct proc *p = KLOADER_PROC; + struct vnode *vp = kloader.vp; + size_t resid; + int error; + + error = vn_rdwr(UIO_READ, vp, buf, size, ofs, UIO_SYSSPACE, + IO_NODELOCKED | IO_SYNC, p->p_ucred, &resid, p); + + if (error) + PRINTF("read error.\n"); + + return (error); +} + +/* + * bootinfo + */ +void +kloader_bootinfo_set(struct kloader_bootinfo *kbi, int argc, char *argv[], + struct bootinfo *bi, boolean_t printok) +{ + char *p, *pend, *buf; + int i; + + kloader.bootinfo = kbi; + buf = kbi->_argbuf; + + memcpy(&kbi->bootinfo, bi, sizeof(struct bootinfo)); + kbi->argc = argc; + kbi->argv = (char **)buf; + + p = &buf[argc * sizeof(char **)]; + pend = &buf[KLOADER_KERNELARGS_MAX - 1]; + + for (i = 0; i < argc; i++) { + char *q = argv[i]; + int len = strlen(q) + 1; + if ((p + len) > pend) { + kloader.bootinfo = NULL; + if (printok) + PRINTF("buffer insufficient.\n"); + return; + } + kbi->argv[i] = p; + memcpy(p, q, len); + p += len; + } +#ifdef KLOADER_DEBUG + if (printok) + kloader_bootinfo_dump(); +#endif +} + +/* + * debug + */ +#ifdef KLOADER_DEBUG +void +kloader_bootinfo_dump() +{ + struct kloader_bootinfo *kbi = kloader.bootinfo; + struct bootinfo *bi; + int i; + + if (kbi == NULL) { + PRINTF("no bootinfo available.\n"); + return; + } + bi = &kbi->bootinfo; + + dbg_banner_function(); + printf("[bootinfo] addr=%p\n", kbi); +#define _(m, fmt) printf(" - %-15s= " #fmt "\n", #m, bi->m) + _(length, %d); + _(magic, 0x%08x); + _(fb_addr, %p); + _(fb_line_bytes, %d); + _(fb_width, %d); + _(fb_height, %d); + _(fb_type, %d); + _(bi_cnuse, %d); + _(platid_cpu, 0x%08lx); + _(platid_machine, 0x%08lx); + _(timezone, 0x%08lx); +#undef _ + + printf("[args]\n"); + for (i = 0; i < kbi->argc; i++) { + printf(" - %s\n", kbi->argv[i]); + } + dbg_banner_line(); +} + +void +kloader_pagetag_dump() +{ + struct kloader_page_tag *tag = kloader.tagstart; + struct kloader_page_tag *p, *op; + int i, n; + + p = tag; + i = 0, n = 15; + + dbg_banner_function(); + PRINTF("[page tag chain]\n"); + do { + if (i < n) { + printf("[%2d] next 0x%08x src 0x%08x dst 0x%08x" + " sz 0x%x\n", i, p->next, p->src, p->dst, p->sz); + } else if (i == n) { + printf("[...]\n"); + } + op = p; + i++; + } while ((p = (struct kloader_page_tag *)(p->next)) != 0); + + printf("[%d(last)] next 0x%08x src 0x%08x dst 0x%08x sz 0x%x\n", + i - 1, op->next, op->src, op->dst, op->sz); + dbg_banner_line(); +} +#endif /* KLOADER_DEBUG */ diff --git a/sys/arch/hpcsh/hpcsh/kloader.h b/sys/arch/hpcsh/hpcsh/kloader.h new file mode 100644 index 000000000000..187b6519050e --- /dev/null +++ b/sys/arch/hpcsh/hpcsh/kloader.h @@ -0,0 +1,50 @@ +/* $NetBSD: kloader.h,v 1.1 2002/01/27 05:14:34 uch Exp $ */ + +/*- + * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#define KLOADER_KERNELARGS_MAX 256 + +struct kloader_bootinfo { + char _argbuf[KLOADER_KERNELARGS_MAX]; + + vaddr_t entry; + struct bootinfo bootinfo; + int argc; + char **argv; +} __attribute__((__aligned__(4))); + +void kloader_reboot_setup(const char *); +void kloader_reboot(void); +void kloader_bootinfo_set(struct kloader_bootinfo *, int, char *[], + struct bootinfo *, boolean_t); diff --git a/sys/arch/hpcsh/hpcsh/machdep.c b/sys/arch/hpcsh/hpcsh/machdep.c index 829e9f451b1c..78f0ba037306 100644 --- a/sys/arch/hpcsh/hpcsh/machdep.c +++ b/sys/arch/hpcsh/hpcsh/machdep.c @@ -1,7 +1,7 @@ -/* $NetBSD: machdep.c,v 1.15 2001/11/28 05:55:35 lukem Exp $ */ +/* $NetBSD: machdep.c,v 1.16 2002/01/27 05:14:34 uch Exp $ */ /*- - * Copyright (c) 2001 The NetBSD Foundation, Inc. + * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,6 +40,7 @@ #include "fs_mfs.h" #include "fs_nfs.h" #include "biconsdev.h" +#include "opt_kloader_kernel_path.h" #include #include @@ -73,6 +74,7 @@ #include #include /* makebootdev() */ #include +#include #include @@ -159,7 +161,6 @@ machine_startup(int argc, char *argv[], struct bootinfo *bi) extern char MonTrap100[], MonTrap100_end[]; extern char MonTrap600[], MonTrap600_end[]; extern char tlbmisshandler_stub[], tlbmisshandler_stub_end[]; - static struct bootinfo __bootinfo; vaddr_t proc0_sp; vaddr_t kernend; psize_t sz; @@ -168,6 +169,12 @@ machine_startup(int argc, char *argv[], struct bootinfo *bi) int i; char *p; size_t symbolsize; + /* + * this routines stack is never polluted since stack pointer + * is lower than kernel text segment, and at exiting, stack pointer + * is changed to proc0. + */ + struct kloader_bootinfo kbi; /* symbol table size */ symbolsize = 0; @@ -194,7 +201,7 @@ machine_startup(int argc, char *argv[], struct bootinfo *bi) kernend = (vaddr_t)sh3_round_page(end + symbolsize); /* setup bootinfo */ - bootinfo = &__bootinfo; + bootinfo = &kbi.bootinfo; memcpy(bootinfo, bi, sizeof(struct bootinfo)); /* setup bootstrap options */ @@ -243,14 +250,8 @@ machine_startup(int argc, char *argv[], struct bootinfo *bi) } consinit(); - /* print kernel option */ - for (i = 0; i < argc; i++) - DPRINTF(("option [%d]: %s\n", i, argv[i])); - DPRINTF(("platid(cpu/machine) = %08lx/%08lx\n", - bootinfo->platid_cpu, bootinfo->platid_machine)); - DPRINTF(("display=%dx%d-(%d) %p type=%d \n", - bootinfo->fb_width, bootinfo->fb_height, - bootinfo->fb_line_bytes, bootinfo->fb_addr, bootinfo->fb_type)); + /* copy boot parameter for kloader */ + kloader_bootinfo_set(&kbi, argc, argv, bi, TRUE); uvm_setpagesize(); /* default page size (4KB) */ @@ -423,8 +424,13 @@ cpu_reboot(int howto, char *bootstr) } /* If "always halt" was specified as a boot flag, obey. */ - if ((boothowto & RB_HALT) != 0) + if ((boothowto & RB_HALT) != 0) { howto |= RB_HALT; + } else { +#ifdef KLOADER_KERNEL_PATH + kloader_reboot_setup(KLOADER_KERNEL_PATH); +#endif + } boothowto = howto; if ((howto & RB_NOSYNC) == 0) { @@ -454,7 +460,14 @@ cpu_reboot(int howto, char *bootstr) doshutdownhooks(); /* Finally, halt/reboot the system. */ - printf("%s\n\n", howto & RB_HALT ? "halted." : "rebooting..."); + if (howto & RB_HALT) { + printf("halted.\n"); + } else { +#ifdef KLOADER_KERNEL_PATH + kloader_reboot(); + /* NOTREACHED */ +#endif + } goto *(u_int32_t *)0xa0000000; while (1) @@ -518,6 +531,7 @@ mem_cluster_init(paddr_t addr) DPRINTF(("\n")); #endif /* NARLY_MEMORY_PROBE */ } + DPRINTF(("total memory = %dMbyte\n", (int)(ptoa(npages) >> 20))); return (npages);