1 /* $NetBSD: kloader_machdep.c,v 1.3 2009/03/15 02:23:52 nonaka Exp $ */ 2 3 /*- 4 * Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: kloader_machdep.c,v 1.3 2009/03/15 02:23:52 nonaka Exp $"); 31 32 #include "debug_kloader.h" 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/disklabel.h> 37 38 #include <machine/kloader.h> 39 #include <machine/pmap.h> 40 41 #include <arm/cpufunc.h> 42 #include <arm/xscale/pxa2x0reg.h> 43 44 #include <zaurus/zaurus/zaurus_var.h> 45 46 #ifndef KERNEL_BASE 47 #define KERNEL_BASE 0xc0000000 48 #endif 49 50 kloader_jumpfunc_t kloader_zaurus_jump __attribute__((__noreturn__)); 51 kloader_bootfunc_t kloader_zaurus_boot __attribute__((__noreturn__)); 52 void kloader_zaurus_reset(void); 53 54 struct kloader_ops kloader_zaurus_ops = { 55 .jump = kloader_zaurus_jump, 56 .boot = kloader_zaurus_boot, 57 .reset = kloader_zaurus_reset, 58 }; 59 60 void 61 kloader_reboot_setup(const char *filename) 62 { 63 64 __kloader_reboot_setup(&kloader_zaurus_ops, filename); 65 } 66 67 void 68 kloader_zaurus_reset(void) 69 { 70 71 zaurus_restart(); 72 /*NOTREACHED*/ 73 } 74 75 void 76 kloader_zaurus_jump(kloader_bootfunc_t func, vaddr_t sp, 77 struct kloader_bootinfo *kbi, struct kloader_page_tag *tag) 78 { 79 extern int kloader_howto; 80 void (*bootinfop)(void *, void *) = (void *)(0xc0200000 - PAGE_SIZE); 81 uint32_t *bootmagicp = (uint32_t *)(0xc0200000 - BOOTARGS_BUFSIZ); 82 vaddr_t top, ptr; 83 struct bootinfo *bootinfo; 84 struct btinfo_howto *bi_howto; 85 struct btinfo_rootdevice *bi_rootdv; 86 87 disable_interrupts(I32_bit|F32_bit); 88 89 /* copy 2nd boot-loader to va=pa page */ 90 memmove(bootinfop, func, PAGE_SIZE); 91 92 /* 93 * make bootinfo 94 */ 95 memset(bootmagicp, 0, BOOTARGS_BUFSIZ); 96 bootinfo = (struct bootinfo *)(bootmagicp + 1); 97 bootinfo->nentries = 0; 98 top = ptr = (vaddr_t)bootinfo->info; 99 100 /* pass to howto for new kernel */ 101 bi_howto = (struct btinfo_howto *)ptr; 102 bi_howto->common.len = sizeof(struct btinfo_howto); 103 bi_howto->common.type = BTINFO_HOWTO; 104 bi_howto->howto = kloader_howto; 105 bootinfo->nentries++; 106 ptr += bi_howto->common.len; 107 108 /* set previous root device for new boot device */ 109 if (root_device != NULL 110 && device_class(root_device) == DV_DISK 111 && !device_is_a(root_device, "dk")) { 112 bi_rootdv = (struct btinfo_rootdevice *)ptr; 113 bi_rootdv->common.len = sizeof(struct btinfo_rootdevice); 114 bi_rootdv->common.type = BTINFO_ROOTDEVICE; 115 snprintf(bi_rootdv->devname, sizeof(bi_rootdv->devname), "%s%c", 116 device_xname(root_device), (int)DISKPART(rootdev) + 'a'); 117 bootinfo->nentries++; 118 ptr += bi_rootdv->common.len; 119 } 120 121 if (bootinfo->nentries > 0) 122 *bootmagicp = BOOTARGS_MAGIC; 123 cpu_idcache_wbinv_all(); 124 125 /* jump to 2nd boot-loader */ 126 (*bootinfop)(kbi, tag); 127 128 /*NOTREACHED*/ 129 for (;;) 130 continue; 131 } 132 133 /* 134 * Physcal address to virtual address 135 */ 136 vaddr_t 137 kloader_phystov(paddr_t pa) 138 { 139 vaddr_t va; 140 int error; 141 142 va = KERNEL_BASE + pa - 0xa0000000UL; 143 error = pmap_enter(pmap_kernel(), va, pa, VM_PROT_ALL, 0); 144 if (error) { 145 printf("%s: map failed: pa=0x%lx, va=0x%lx, error=%d\n", 146 __func__, pa, va, error); 147 } 148 return va; 149 } 150