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@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
kloader_reboot_setup(const char * filename)59 kloader_reboot_setup(const char *filename)
60 {
61 
62 	__kloader_reboot_setup(&kloader_zaurus_ops, filename);
63 }
64 
65 void
kloader_zaurus_reset(void)66 kloader_zaurus_reset(void)
67 {
68 
69 	zaurus_restart();
70 	/*NOTREACHED*/
71 }
72 
73 void
kloader_zaurus_jump(kloader_bootfunc_t func,vaddr_t sp,struct kloader_bootinfo * kbi,struct kloader_page_tag * tag)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
kloader_phystov(paddr_t pa)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