Home | History | Annotate | Line # | Download | only in zaurus
      1 /*	$NetBSD: kloader_machdep.c,v 1.8 2021/08/17 22:00:31 andvar Exp $	*/
      2 
      3 /*-
      4  * Copyright (C) 2009-2012 NONAKA Kimihiro <nonaka (at) 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #include <sys/cdefs.h>
     29 __KERNEL_RCSID(0, "$NetBSD: kloader_machdep.c,v 1.8 2021/08/17 22:00:31 andvar Exp $");
     30 
     31 #include "debug_kloader.h"
     32 
     33 #include <sys/param.h>
     34 #include <sys/systm.h>
     35 #include <sys/device.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 #define	KERNEL_TEXT_BASE	((vaddr_t)&KERNEL_BASE_virt)
     47 
     48 kloader_jumpfunc_t kloader_zaurus_jump __attribute__((__noreturn__));
     49 kloader_bootfunc_t kloader_zaurus_boot __attribute__((__noreturn__));
     50 void kloader_zaurus_reset(void);
     51 
     52 struct kloader_ops kloader_zaurus_ops = {
     53 	.jump = kloader_zaurus_jump,
     54 	.boot = kloader_zaurus_boot,
     55 	.reset = kloader_zaurus_reset,
     56 };
     57 
     58 void
     59 kloader_reboot_setup(const char *filename)
     60 {
     61 
     62 	__kloader_reboot_setup(&kloader_zaurus_ops, filename);
     63 }
     64 
     65 void
     66 kloader_zaurus_reset(void)
     67 {
     68 
     69 	zaurus_restart();
     70 	/*NOTREACHED*/
     71 }
     72 
     73 void
     74 kloader_zaurus_jump(kloader_bootfunc_t func, vaddr_t sp,
     75     struct kloader_bootinfo *kbi, struct kloader_page_tag *tag)
     76 {
     77 	extern int kloader_howto;
     78 	extern char KERNEL_BASE_virt[];
     79 	void (*bootinfop)(void *, void *);
     80 	uint32_t *bootmagicp;
     81 	vaddr_t ptr;
     82 	struct bootinfo *bootinfo;
     83 	struct btinfo_howto *bi_howto;
     84 	struct btinfo_rootdevice *bi_rootdv;
     85 
     86 	disable_interrupts(I32_bit|F32_bit);
     87 
     88 	/* copy 2nd boot-loader to va=pa page */
     89 	bootinfop = (void *)(KERNEL_TEXT_BASE - PAGE_SIZE);
     90 	memmove(bootinfop, func, PAGE_SIZE);
     91 
     92 	/*
     93 	 * make bootinfo
     94 	 */
     95 	bootmagicp = (uint32_t *)(KERNEL_TEXT_BASE - BOOTARGS_BUFSIZ);
     96 	memset(bootmagicp, 0, BOOTARGS_BUFSIZ);
     97 	bootinfo = (struct bootinfo *)(bootmagicp + 1);
     98 	bootinfo->nentries = 0;
     99 	ptr = (vaddr_t)bootinfo->info;
    100 
    101 	/* pass to howto for new kernel */
    102 	bi_howto = (struct btinfo_howto *)ptr;
    103 	bi_howto->common.len = sizeof(struct btinfo_howto);
    104 	bi_howto->common.type = BTINFO_HOWTO;
    105 	bi_howto->howto = kloader_howto;
    106 	bootinfo->nentries++;
    107 	ptr += bi_howto->common.len;
    108 
    109 	/* set previous root device for new boot device */
    110 	if (root_device != NULL
    111 	 && device_class(root_device) == DV_DISK
    112 	 && !device_is_a(root_device, "dk")) {
    113 		bi_rootdv = (struct btinfo_rootdevice *)ptr;
    114 		bi_rootdv->common.len = sizeof(struct btinfo_rootdevice);
    115 		bi_rootdv->common.type = BTINFO_ROOTDEVICE;
    116 		snprintf(bi_rootdv->devname, sizeof(bi_rootdv->devname), "%s%c",
    117 		    device_xname(root_device), (int)DISKPART(rootdev) + 'a');
    118 		bootinfo->nentries++;
    119 		ptr += bi_rootdv->common.len;
    120 	}
    121 
    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  * Physical 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 - PXA2X0_SDRAM0_START;
    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