| @@ -1,970 +1,970 @@ | | | @@ -1,970 +1,970 @@ |
1 | /* $NetBSD: machdep.c,v 1.135 2011/07/01 18:54:33 dyoung Exp $ */ | | 1 | /* $NetBSD: machdep.c,v 1.136 2011/07/28 04:06:09 uebayasi Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2000 Soren S. Jorvang | | 4 | * Copyright (c) 2000 Soren S. Jorvang |
5 | * Copyright (c) 2001, 2002, 2003 Rafal K. Boni | | 5 | * Copyright (c) 2001, 2002, 2003 Rafal K. Boni |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
15 | * documentation and/or other materials provided with the distribution. | | 15 | * documentation and/or other materials provided with the distribution. |
16 | * 3. All advertising materials mentioning features or use of this software | | 16 | * 3. All advertising materials mentioning features or use of this software |
17 | * must display the following acknowledgement: | | 17 | * must display the following acknowledgement: |
18 | * This product includes software developed for the | | 18 | * This product includes software developed for the |
19 | * NetBSD Project. See http://www.NetBSD.org/ for | | 19 | * NetBSD Project. See http://www.NetBSD.org/ for |
20 | * information about NetBSD. | | 20 | * information about NetBSD. |
21 | * 4. The name of the author may not be used to endorse or promote products | | 21 | * 4. The name of the author may not be used to endorse or promote products |
22 | * derived from this software without specific prior written permission. | | 22 | * derived from this software without specific prior written permission. |
23 | * | | 23 | * |
24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
25 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 25 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
26 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 26 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
27 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 27 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
29 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 29 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
34 | */ | | 34 | */ |
35 | | | 35 | |
36 | #include <sys/cdefs.h> | | 36 | #include <sys/cdefs.h> |
37 | __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.135 2011/07/01 18:54:33 dyoung Exp $"); | | 37 | __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.136 2011/07/28 04:06:09 uebayasi Exp $"); |
38 | | | 38 | |
39 | #include "opt_ddb.h" | | 39 | #include "opt_ddb.h" |
40 | #include "opt_kgdb.h" | | 40 | #include "opt_kgdb.h" |
41 | #include "opt_execfmt.h" | | 41 | #include "opt_execfmt.h" |
42 | #include "opt_cputype.h" | | 42 | #include "opt_cputype.h" |
43 | #include "opt_mips_cache.h" | | 43 | #include "opt_mips_cache.h" |
44 | #include "opt_modular.h" | | 44 | #include "opt_modular.h" |
45 | | | 45 | |
46 | #define __INTR_PRIVATE | | 46 | #define __INTR_PRIVATE |
47 | | | 47 | |
48 | #include <sys/param.h> | | 48 | #include <sys/param.h> |
49 | #include <sys/systm.h> | | 49 | #include <sys/systm.h> |
50 | #include <sys/kernel.h> | | 50 | #include <sys/kernel.h> |
51 | #include <sys/proc.h> | | 51 | #include <sys/proc.h> |
52 | #include <sys/buf.h> | | 52 | #include <sys/buf.h> |
53 | #include <sys/reboot.h> | | 53 | #include <sys/reboot.h> |
54 | #include <sys/conf.h> | | 54 | #include <sys/conf.h> |
55 | #include <sys/file.h> | | 55 | #include <sys/file.h> |
56 | #include <sys/malloc.h> | | 56 | #include <sys/malloc.h> |
57 | #include <sys/mbuf.h> | | 57 | #include <sys/mbuf.h> |
58 | #include <sys/msgbuf.h> | | 58 | #include <sys/msgbuf.h> |
59 | #include <sys/device.h> | | 59 | #include <sys/device.h> |
60 | #include <sys/exec.h> | | 60 | #include <sys/exec.h> |
61 | #include <sys/mount.h> | | 61 | #include <sys/mount.h> |
62 | #include <sys/syscallargs.h> | | 62 | #include <sys/syscallargs.h> |
63 | #include <sys/kcore.h> | | 63 | #include <sys/kcore.h> |
64 | #include <sys/boot_flag.h> | | 64 | #include <sys/boot_flag.h> |
65 | #include <sys/ksyms.h> | | 65 | #include <sys/ksyms.h> |
66 | | | 66 | |
67 | #include <uvm/uvm_extern.h> | | 67 | #include <uvm/uvm_extern.h> |
68 | | | 68 | |
69 | #include <machine/cpu.h> | | 69 | #include <machine/cpu.h> |
70 | #include <machine/reg.h> | | 70 | #include <machine/reg.h> |
71 | #include <machine/psl.h> | | 71 | #include <machine/psl.h> |
72 | #include <machine/pte.h> | | 72 | #include <machine/pte.h> |
73 | #include <machine/autoconf.h> | | 73 | #include <machine/autoconf.h> |
74 | #include <machine/machtype.h> | | 74 | #include <machine/machtype.h> |
75 | #include <machine/sysconf.h> | | 75 | #include <machine/sysconf.h> |
76 | #include <machine/intr.h> | | 76 | #include <machine/intr.h> |
77 | #include <machine/bootinfo.h> | | 77 | #include <machine/bootinfo.h> |
78 | #include <sys/bus.h> | | 78 | #include <sys/bus.h> |
79 | | | 79 | |
80 | #include <mips/locore.h> | | 80 | #include <mips/locore.h> |
81 | #include <mips/cache.h> | | 81 | #include <mips/cache.h> |
82 | #include <mips/cache_r5k.h> | | 82 | #include <mips/cache_r5k.h> |
83 | #ifdef ENABLE_MIPS4_CACHE_R10K | | 83 | #ifdef ENABLE_MIPS4_CACHE_R10K |
84 | #include <mips/cache_r10k.h> | | 84 | #include <mips/cache_r10k.h> |
85 | #endif | | 85 | #endif |
86 | | | 86 | |
87 | #include <sgimips/dev/int2reg.h> | | 87 | #include <sgimips/dev/int2reg.h> |
88 | #include <sgimips/dev/crimevar.h> | | 88 | #include <sgimips/dev/crimevar.h> |
89 | #include <sgimips/sgimips/arcemu.h> | | 89 | #include <sgimips/sgimips/arcemu.h> |
90 | | | 90 | |
91 | #include <dev/arcbios/arcbios.h> | | 91 | #include <dev/arcbios/arcbios.h> |
92 | #include <dev/arcbios/arcbiosvar.h> | | 92 | #include <dev/arcbios/arcbiosvar.h> |
93 | | | 93 | |
94 | #include "ksyms.h" | | 94 | #include "ksyms.h" |
95 | | | 95 | |
96 | #if NKSYMS || defined(DDB) || defined(MODULAR) || defined(KGDB) | | 96 | #if NKSYMS || defined(DDB) || defined(MODULAR) || defined(KGDB) |
97 | #include <machine/db_machdep.h> | | 97 | #include <machine/db_machdep.h> |
98 | #include <ddb/db_access.h> | | 98 | #include <ddb/db_access.h> |
99 | #include <ddb/db_sym.h> | | 99 | #include <ddb/db_sym.h> |
100 | #include <ddb/db_extern.h> | | 100 | #include <ddb/db_extern.h> |
101 | #ifndef DB_ELFSIZE | | 101 | #ifndef DB_ELFSIZE |
102 | #error Must define DB_ELFSIZE! | | 102 | #error Must define DB_ELFSIZE! |
103 | #endif | | 103 | #endif |
104 | #define ELFSIZE DB_ELFSIZE | | 104 | #define ELFSIZE DB_ELFSIZE |
105 | #include <sys/exec_elf.h> | | 105 | #include <sys/exec_elf.h> |
106 | #endif | | 106 | #endif |
107 | | | 107 | |
108 | #include "mcclock_mace.h" | | 108 | #include "mcclock_mace.h" |
109 | #include "crime.h" | | 109 | #include "crime.h" |
110 | | | 110 | |
111 | #if NMCCLOCK_MACE > 0 | | 111 | #if NMCCLOCK_MACE > 0 |
112 | void mcclock_poweroff(void); | | 112 | void mcclock_poweroff(void); |
113 | #endif | | 113 | #endif |
114 | | | 114 | |
115 | struct sgimips_intrhand intrtab[NINTR]; | | 115 | struct sgimips_intrhand intrtab[NINTR]; |
116 | | | 116 | |
117 | /* Our exported CPU info; we can have only one. */ | | 117 | /* Our exported CPU info; we can have only one. */ |
118 | struct cpu_info cpu_info_store; | | 118 | struct cpu_info cpu_info_store; |
119 | | | 119 | |
120 | /* Maps for VM objects. */ | | 120 | /* Maps for VM objects. */ |
121 | struct vm_map *phys_map = NULL; | | 121 | struct vm_map *phys_map = NULL; |
122 | | | 122 | |
123 | int mach_type = 0; /* IPxx type */ | | 123 | int mach_type = 0; /* IPxx type */ |
124 | int mach_subtype = 0; /* subtype: eg., Guinness/Fullhouse for IP22 */ | | 124 | int mach_subtype = 0; /* subtype: eg., Guinness/Fullhouse for IP22 */ |
125 | int mach_boardrev = 0; /* machine board revision, in case it matters */ | | 125 | int mach_boardrev = 0; /* machine board revision, in case it matters */ |
126 | | | 126 | |
127 | int arcsmem; /* Memory used by the ARCS firmware */ | | 127 | int arcsmem; /* Memory used by the ARCS firmware */ |
128 | | | 128 | |
129 | int ncpus; | | 129 | int ncpus; |
130 | | | 130 | |
131 | #define IPL2SPL_TABLE_COMMON \ | | 131 | #define IPL2SPL_TABLE_COMMON \ |
132 | [IPL_NONE] = 0, \ | | 132 | [IPL_NONE] = 0, \ |
133 | [IPL_SOFTCLOCK] = MIPS_SOFT_INT_MASK_0, \ | | 133 | [IPL_SOFTCLOCK] = MIPS_SOFT_INT_MASK_0, \ |
134 | [IPL_SOFTNET] = MIPS_SOFT_INT_MASK, \ | | 134 | [IPL_SOFTNET] = MIPS_SOFT_INT_MASK, \ |
135 | [IPL_DDB] = MIPS_INT_MASK, \ | | 135 | [IPL_DDB] = MIPS_INT_MASK, \ |
136 | [IPL_HIGH] = MIPS_INT_MASK | | 136 | [IPL_HIGH] = MIPS_INT_MASK |
137 | | | 137 | |
138 | /* CPU interrupt sr maps */ | | 138 | /* CPU interrupt sr maps */ |
139 | #if defined(MIPS1) | | 139 | #if defined(MIPS1) |
140 | static const struct ipl_sr_map sgi_ip6_ipl_sr_map = { | | 140 | static const struct ipl_sr_map sgi_ip6_ipl_sr_map = { |
141 | .sr_bits = { | | 141 | .sr_bits = { |
142 | IPL2SPL_TABLE_COMMON, | | 142 | IPL2SPL_TABLE_COMMON, |
143 | [IPL_VM] = MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, | | 143 | [IPL_VM] = MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, |
144 | [IPL_SCHED] = MIPS_INT_MASK_4|MIPS_INT_MASK_2| | | 144 | [IPL_SCHED] = MIPS_INT_MASK_4|MIPS_INT_MASK_2| |
145 | MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, | | 145 | MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, |
146 | }, | | 146 | }, |
147 | }; | | 147 | }; |
148 | static const struct ipl_sr_map sgi_ip12_ipl_sr_map = { | | 148 | static const struct ipl_sr_map sgi_ip12_ipl_sr_map = { |
149 | .sr_bits = { | | 149 | .sr_bits = { |
150 | IPL2SPL_TABLE_COMMON, | | 150 | IPL2SPL_TABLE_COMMON, |
151 | [IPL_VM] = MIPS_INT_MASK_2|MIPS_INT_MASK_1|MIPS_INT_MASK_0| | | 151 | [IPL_VM] = MIPS_INT_MASK_2|MIPS_INT_MASK_1|MIPS_INT_MASK_0| |
152 | MIPS_SOFT_INT_MASK, | | 152 | MIPS_SOFT_INT_MASK, |
153 | [IPL_SCHED] = MIPS_INT_MASK_4|MIPS_INT_MASK_3|MIPS_INT_MASK_2| | | 153 | [IPL_SCHED] = MIPS_INT_MASK_4|MIPS_INT_MASK_3|MIPS_INT_MASK_2| |
154 | MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, | | 154 | MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, |
155 | }, | | 155 | }, |
156 | }; | | 156 | }; |
157 | #endif /* defined(MIPS1) */ | | 157 | #endif /* defined(MIPS1) */ |
158 | | | 158 | |
159 | #if defined(MIPS3) | | 159 | #if defined(MIPS3) |
160 | static const struct ipl_sr_map sgi_ip2x_ipl_sr_map = { | | 160 | static const struct ipl_sr_map sgi_ip2x_ipl_sr_map = { |
161 | .sr_bits = { | | 161 | .sr_bits = { |
162 | IPL2SPL_TABLE_COMMON, | | 162 | IPL2SPL_TABLE_COMMON, |
163 | [IPL_VM] = MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, | | 163 | [IPL_VM] = MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, |
164 | [IPL_SCHED] = MIPS_INT_MASK, | | 164 | [IPL_SCHED] = MIPS_INT_MASK, |
165 | }, | | 165 | }, |
166 | }; | | 166 | }; |
167 | static const struct ipl_sr_map sgi_ip3x_ipl_sr_map = { | | 167 | static const struct ipl_sr_map sgi_ip3x_ipl_sr_map = { |
168 | .sr_bits = { | | 168 | .sr_bits = { |
169 | IPL2SPL_TABLE_COMMON, | | 169 | IPL2SPL_TABLE_COMMON, |
170 | [IPL_VM] = MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, | | 170 | [IPL_VM] = MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, |
171 | [IPL_SCHED] = MIPS_INT_MASK_5|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, | | 171 | [IPL_SCHED] = MIPS_INT_MASK_5|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, |
172 | }, | | 172 | }, |
173 | }; | | 173 | }; |
174 | #endif /* defined(MIPS3) */ | | 174 | #endif /* defined(MIPS3) */ |
175 | | | 175 | |
176 | phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; | | 176 | phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; |
177 | int mem_cluster_cnt; | | 177 | int mem_cluster_cnt; |
178 | | | 178 | |
179 | #if defined(INDY_R4600_CACHE) | | 179 | #if defined(INDY_R4600_CACHE) |
180 | extern void ip22_sdcache_disable(void); | | 180 | extern void ip22_sdcache_disable(void); |
181 | extern void ip22_sdcache_enable(void); | | 181 | extern void ip22_sdcache_enable(void); |
182 | #endif | | 182 | #endif |
183 | | | 183 | |
184 | #if defined(MIPS3) | | 184 | #if defined(MIPS3) |
185 | extern void mips3_clock_intr(vaddr_t, uint32_t, uint32_t); | | 185 | extern void mips3_clock_intr(vaddr_t, uint32_t, uint32_t); |
186 | #endif | | 186 | #endif |
187 | | | 187 | |
188 | void mach_init(int, int32_t *, uintptr_t, int32_t); | | 188 | void mach_init(int, int32_t *, uintptr_t, int32_t); |
189 | | | 189 | |
190 | void sgimips_count_cpus(struct arcbios_component *, | | 190 | void sgimips_count_cpus(struct arcbios_component *, |
191 | struct arcbios_treewalk_context *); | | 191 | struct arcbios_treewalk_context *); |
192 | | | 192 | |
193 | #ifdef KGDB | | 193 | #ifdef KGDB |
194 | void kgdb_port_init(void); | | 194 | void kgdb_port_init(void); |
195 | void kgdb_connect(int); | | 195 | void kgdb_connect(int); |
196 | #endif | | 196 | #endif |
197 | | | 197 | |
198 | void mips_machdep_find_l2cache(struct arcbios_component *comp, struct arcbios_treewalk_context *atc); | | 198 | void mips_machdep_find_l2cache(struct arcbios_component *comp, struct arcbios_treewalk_context *atc); |
199 | | | 199 | |
200 | /* Motherboard or system-specific initialization vector */ | | 200 | /* Motherboard or system-specific initialization vector */ |
201 | static void unimpl_bus_reset(void); | | 201 | static void unimpl_bus_reset(void); |
202 | static void unimpl_cons_init(void); | | 202 | static void unimpl_cons_init(void); |
203 | static void *unimpl_intr_establish(int, int, int (*)(void *), void *); | | 203 | static void *unimpl_intr_establish(int, int, int (*)(void *), void *); |
204 | static void unimpl_intr(vaddr_t, uint32_t, uint32_t); | | 204 | static void unimpl_intr(vaddr_t, uint32_t, uint32_t); |
205 | static unsigned long nulllong(void); | | 205 | static unsigned long nulllong(void); |
206 | static void nullvoid(void); | | 206 | static void nullvoid(void); |
207 | | | 207 | |
208 | void ddb_trap_hook(int where); | | 208 | void ddb_trap_hook(int where); |
209 | | | 209 | |
210 | static int badaddr_workaround(void *, size_t); | | 210 | static int badaddr_workaround(void *, size_t); |
211 | | | 211 | |
212 | struct platform platform = { | | 212 | struct platform platform = { |
213 | .badaddr = badaddr_workaround, | | 213 | .badaddr = badaddr_workaround, |
214 | .bus_reset = unimpl_bus_reset, | | 214 | .bus_reset = unimpl_bus_reset, |
215 | .cons_init = unimpl_cons_init, | | 215 | .cons_init = unimpl_cons_init, |
216 | .intr_establish = unimpl_intr_establish, | | 216 | .intr_establish = unimpl_intr_establish, |
217 | .clkread = nulllong, | | 217 | .clkread = nulllong, |
218 | .watchdog_reset = nullvoid, | | 218 | .watchdog_reset = nullvoid, |
219 | .watchdog_disable = nullvoid, | | 219 | .watchdog_disable = nullvoid, |
220 | .watchdog_enable = nullvoid, | | 220 | .watchdog_enable = nullvoid, |
221 | .intr0 = unimpl_intr, | | 221 | .intr0 = unimpl_intr, |
222 | .intr1 = unimpl_intr, | | 222 | .intr1 = unimpl_intr, |
223 | .intr2 = unimpl_intr, | | 223 | .intr2 = unimpl_intr, |
224 | .intr3 = unimpl_intr, | | 224 | .intr3 = unimpl_intr, |
225 | .intr4 = unimpl_intr, | | 225 | .intr4 = unimpl_intr, |
226 | .intr5 = unimpl_intr | | 226 | .intr5 = unimpl_intr |
227 | }; | | 227 | }; |
228 | | | 228 | |
229 | extern u_int32_t ssir; | | 229 | extern u_int32_t ssir; |
230 | extern char kernel_text[], edata[], end[]; | | 230 | extern char kernel_text[], edata[], end[]; |
231 | | | 231 | |
232 | uint8_t *bootinfo; /* pointer to bootinfo structure */ | | 232 | uint8_t *bootinfo; /* pointer to bootinfo structure */ |
233 | static uint8_t bi_buf[BOOTINFO_SIZE]; /* buffer to store bootinfo data */ | | 233 | static uint8_t bi_buf[BOOTINFO_SIZE]; /* buffer to store bootinfo data */ |
234 | static const char *bootinfo_msg = NULL; | | 234 | static const char *bootinfo_msg = NULL; |
235 | | | 235 | |
236 | #define ARCS_VECTOR MIPS_PHYS_TO_KSEG0(0x00001000) | | 236 | #define ARCS_VECTOR MIPS_PHYS_TO_KSEG0(0x00001000) |
237 | | | 237 | |
238 | /* | | 238 | /* |
239 | * Do all the stuff that locore normally does before calling main(). | | 239 | * Do all the stuff that locore normally does before calling main(). |
240 | * Process arguments passed to us by the ARCS firmware. | | 240 | * Process arguments passed to us by the ARCS firmware. |
241 | */ | | 241 | */ |
242 | void | | 242 | void |
243 | mach_init(int argc, int32_t argv32[], uintptr_t magic, int32_t bip32) | | 243 | mach_init(int argc, int32_t argv32[], uintptr_t magic, int32_t bip32) |
244 | { | | 244 | { |
245 | paddr_t first, last; | | 245 | paddr_t first, last; |
246 | vsize_t size; | | 246 | vsize_t size; |
247 | void *bip = (void *)(intptr_t)bip32; | | 247 | void *bip = (void *)(intptr_t)bip32; |
248 | struct arcbios_mem *mem; | | 248 | struct arcbios_mem *mem; |
249 | const char *cpufreq, *osload; | | 249 | const char *cpufreq, *osload; |
250 | char *bootpath = NULL; | | 250 | char *bootpath = NULL; |
251 | vaddr_t kernend; | | 251 | vaddr_t kernend; |
252 | int kernstartpfn, kernendpfn; | | 252 | int kernstartpfn, kernendpfn; |
253 | u_int i; | | 253 | u_int i; |
254 | int rv; | | 254 | int rv; |
255 | #if NKSYMS > 0 || defined(DDB) || defined(MODULAR) | | 255 | #if NKSYMS > 0 || defined(DDB) || defined(MODULAR) |
256 | int nsym = 0; | | 256 | int nsym = 0; |
257 | char *ssym = NULL; | | 257 | char *ssym = NULL; |
258 | char *esym = NULL; | | 258 | char *esym = NULL; |
259 | struct btinfo_symtab *bi_syms; | | 259 | struct btinfo_symtab *bi_syms; |
260 | #endif | | 260 | #endif |
261 | #ifdef _LP64 | | 261 | #ifdef _LP64 |
262 | char *argv[argc+1]; | | 262 | char *argv[argc+1]; |
263 | | | 263 | |
264 | for (i = 0; i < argc; i++) { | | 264 | for (i = 0; i < argc; i++) { |
265 | argv[i] = (void *)(intptr_t)argv32[i]; | | 265 | argv[i] = (void *)(intptr_t)argv32[i]; |
266 | } | | 266 | } |
267 | #else | | 267 | #else |
268 | char **argv = (void *)argv32; | | 268 | char **argv = (void *)argv32; |
269 | #endif | | 269 | #endif |
270 | | | 270 | |
271 | /* | | 271 | /* |
272 | * Initialize firmware. This will set up the bootstrap console. | | 272 | * Initialize firmware. This will set up the bootstrap console. |
273 | * At this point we do not yet know the machine type, so we | | 273 | * At this point we do not yet know the machine type, so we |
274 | * try to init real arcbios, and if that fails (return value 1), | | 274 | * try to init real arcbios, and if that fails (return value 1), |
275 | * fall back to the emulator. If the latter fails also we | | 275 | * fall back to the emulator. If the latter fails also we |
276 | * don't have much to panic with. | | 276 | * don't have much to panic with. |
277 | * | | 277 | * |
278 | * The third argument (magic) is the environment variable array if | | 278 | * The third argument (magic) is the environment variable array if |
279 | * there's no bootinfo. | | 279 | * there's no bootinfo. |
280 | */ | | 280 | */ |
281 | if (arcbios_init(ARCS_VECTOR) == 1) { | | 281 | if (arcbios_init(ARCS_VECTOR) == 1) { |
282 | #ifdef _LP64 | | 282 | #ifdef _LP64 |
283 | panic("no ARCS firmware"); | | 283 | panic("no ARCS firmware"); |
284 | #else | | 284 | #else |
285 | if (magic == BOOTINFO_MAGIC) | | 285 | if (magic == BOOTINFO_MAGIC) |
286 | arcemu_init(NULL); /* XXX - need some prom env */ | | 286 | arcemu_init(NULL); /* XXX - need some prom env */ |
287 | else | | 287 | else |
288 | arcemu_init((const char **)magic); | | 288 | arcemu_init((const char **)magic); |
289 | #endif | | 289 | #endif |
290 | } | | 290 | } |
291 | | | 291 | |
292 | strcpy(cpu_model, arcbios_system_identifier); | | 292 | strcpy(cpu_model, arcbios_system_identifier); |
293 | | | 293 | |
294 | uvm_setpagesize(); | | 294 | uvm_setpagesize(); |
295 | | | 295 | |
296 | /* set up bootinfo structures */ | | 296 | /* set up bootinfo structures */ |
297 | if (magic == BOOTINFO_MAGIC && bip != NULL) { | | 297 | if (magic == BOOTINFO_MAGIC && bip != NULL) { |
298 | struct btinfo_magic *bi_magic; | | 298 | struct btinfo_magic *bi_magic; |
299 | struct btinfo_bootpath *bi_path; | | 299 | struct btinfo_bootpath *bi_path; |
300 | | | 300 | |
301 | memcpy(bi_buf, bip, BOOTINFO_SIZE); | | 301 | memcpy(bi_buf, bip, BOOTINFO_SIZE); |
302 | bootinfo = bi_buf; | | 302 | bootinfo = bi_buf; |
303 | bi_magic = lookup_bootinfo(BTINFO_MAGIC); | | 303 | bi_magic = lookup_bootinfo(BTINFO_MAGIC); |
304 | if (bi_magic != NULL && bi_magic->magic == BOOTINFO_MAGIC) { | | 304 | if (bi_magic != NULL && bi_magic->magic == BOOTINFO_MAGIC) { |
305 | bootinfo_msg = "bootinfo found.\n"; | | 305 | bootinfo_msg = "bootinfo found.\n"; |
306 | bi_path = lookup_bootinfo(BTINFO_BOOTPATH); | | 306 | bi_path = lookup_bootinfo(BTINFO_BOOTPATH); |
307 | if (bi_path != NULL) | | 307 | if (bi_path != NULL) |
308 | bootpath = bi_path->bootpath; | | 308 | bootpath = bi_path->bootpath; |
309 | } else | | 309 | } else |
310 | bootinfo_msg = | | 310 | bootinfo_msg = |
311 | "invalid magic number in bootinfo structure.\n"; | | 311 | "invalid magic number in bootinfo structure.\n"; |
312 | } else | | 312 | } else |
313 | bootinfo_msg = "no bootinfo found. (old bootblocks?)\n"; | | 313 | bootinfo_msg = "no bootinfo found. (old bootblocks?)\n"; |
314 | | | 314 | |
315 | #if NKSYM > 0 || defined(DDB) || defined(MODULAR) | | 315 | #if NKSYM > 0 || defined(DDB) || defined(MODULAR) |
316 | bi_syms = lookup_bootinfo(BTINFO_SYMTAB); | | 316 | bi_syms = lookup_bootinfo(BTINFO_SYMTAB); |
317 | | | 317 | |
318 | /* check whether there is valid bootinfo symtab info */ | | 318 | /* check whether there is valid bootinfo symtab info */ |
319 | if (bi_syms != NULL) { | | 319 | if (bi_syms != NULL) { |
320 | nsym = bi_syms->nsym; | | 320 | nsym = bi_syms->nsym; |
321 | ssym = (char *)bi_syms->ssym; | | 321 | ssym = (char *)bi_syms->ssym; |
322 | esym = (char *)bi_syms->esym; | | 322 | esym = (char *)bi_syms->esym; |
323 | kernend = mips_round_page(esym); | | 323 | kernend = mips_round_page(esym); |
324 | } else | | 324 | } else |
325 | #endif | | 325 | #endif |
326 | { | | 326 | { |
327 | kernend = mips_round_page(end); | | 327 | kernend = mips_round_page(end); |
328 | } | | 328 | } |
329 | | | 329 | |
330 | /* Leave 1 page before kernel untouched as that's where our initial | | 330 | /* Leave 1 page before kernel untouched as that's where our initial |
331 | * kernel stack is */ | | 331 | * kernel stack is */ |
332 | /* XXX We could free it in cpu_startup() though XXX */ | | 332 | /* XXX We could free it in cpu_startup() though XXX */ |
333 | kernstartpfn = atop(MIPS_KSEG0_TO_PHYS((vaddr_t) kernel_text)) - 1; | | 333 | kernstartpfn = atop(MIPS_KSEG0_TO_PHYS((vaddr_t) kernel_text)) - 1; |
334 | kernendpfn = atop(MIPS_KSEG0_TO_PHYS(kernend)); | | 334 | kernendpfn = atop(MIPS_KSEG0_TO_PHYS(kernend)); |
335 | | | 335 | |
336 | cpufreq = arcbios_GetEnvironmentVariable("cpufreq"); | | 336 | cpufreq = arcbios_GetEnvironmentVariable("cpufreq"); |
337 | | | 337 | |
338 | if (cpufreq == 0) | | 338 | if (cpufreq == 0) |
339 | panic("no $cpufreq"); | | 339 | panic("no $cpufreq"); |
340 | | | 340 | |
341 | /* | | 341 | /* |
342 | * Note initial estimate of CPU speed... If we care enough, we'll | | 342 | * Note initial estimate of CPU speed... If we care enough, we'll |
343 | * use the RTC to get a better estimate later. | | 343 | * use the RTC to get a better estimate later. |
344 | */ | | 344 | */ |
345 | curcpu()->ci_cpu_freq = strtoul(cpufreq, NULL, 10) * 1000000; | | 345 | curcpu()->ci_cpu_freq = strtoul(cpufreq, NULL, 10) * 1000000; |
346 | | | 346 | |
347 | /* | | 347 | /* |
348 | * Check machine (IPn) type. | | 348 | * Check machine (IPn) type. |
349 | * | | 349 | * |
350 | * Note even on IP12 (which doesn't have ARCBIOS), | | 350 | * Note even on IP12 (which doesn't have ARCBIOS), |
351 | * arcbios_system_identifiler[] has been initilialized | | 351 | * arcbios_system_identifiler[] has been initilialized |
352 | * in arcemu_ip12_init(). | | 352 | * in arcemu_ip12_init(). |
353 | */ | | 353 | */ |
354 | for (i = 0; arcbios_system_identifier[i] != '\0'; i++) { | | 354 | for (i = 0; arcbios_system_identifier[i] != '\0'; i++) { |
355 | if (mach_type == 0 && | | 355 | if (mach_type == 0 && |
356 | arcbios_system_identifier[i] >= '0' && | | 356 | arcbios_system_identifier[i] >= '0' && |
357 | arcbios_system_identifier[i] <= '9') { | | 357 | arcbios_system_identifier[i] <= '9') { |
358 | mach_type = strtoul(&arcbios_system_identifier[i], | | 358 | mach_type = strtoul(&arcbios_system_identifier[i], |
359 | NULL, 10); | | 359 | NULL, 10); |
360 | break; | | 360 | break; |
361 | } | | 361 | } |
362 | } | | 362 | } |
363 | if (mach_type <= 0) | | 363 | if (mach_type <= 0) |
364 | panic("invalid architecture"); | | 364 | panic("invalid architecture"); |
365 | | | 365 | |
366 | /* | | 366 | /* |
367 | * Get boot device infomation. | | 367 | * Get boot device infomation. |
368 | */ | | 368 | */ |
369 | | | 369 | |
370 | /* Try to get the boot device information from bootinfo first. */ | | 370 | /* Try to get the boot device information from bootinfo first. */ |
371 | if (bootpath != NULL) | | 371 | if (bootpath != NULL) |
372 | makebootdev(bootpath); | | 372 | makebootdev(bootpath); |
373 | else { | | 373 | else { |
374 | /* | | 374 | /* |
375 | * The old bootloader prior to 5.0 doesn't pass bootinfo. | | 375 | * The old bootloader prior to 5.0 doesn't pass bootinfo. |
376 | * If argv[0] is the bootloader, then argv[1] might be | | 376 | * If argv[0] is the bootloader, then argv[1] might be |
377 | * the kernel that was loaded. | | 377 | * the kernel that was loaded. |
378 | * If argv[1] isn't an environment string, try to use it | | 378 | * If argv[1] isn't an environment string, try to use it |
379 | * to set the boot device. | | 379 | * to set the boot device. |
380 | */ | | 380 | */ |
381 | if (argc > 1 && strchr(argv[1], '=') != 0) | | 381 | if (argc > 1 && strchr(argv[1], '=') != 0) |
382 | makebootdev(argv[1]); | | 382 | makebootdev(argv[1]); |
383 | | | 383 | |
384 | /* | | 384 | /* |
385 | * If we are loaded directly by ARCBIOS, | | 385 | * If we are loaded directly by ARCBIOS, |
386 | * argv[0] is the path of the loaded kernel, | | 386 | * argv[0] is the path of the loaded kernel, |
387 | * but booted_partition could be SGIVOLHDR in such case, | | 387 | * but booted_partition could be SGIVOLHDR in such case, |
388 | * so assume root is partition a. | | 388 | * so assume root is partition a. |
389 | */ | | 389 | */ |
390 | if (argc > 0 && argv[0] != NULL) { | | 390 | if (argc > 0 && argv[0] != NULL) { |
391 | makebootdev(argv[0]); | | 391 | makebootdev(argv[0]); |
392 | booted_partition = 0; | | 392 | booted_partition = 0; |
393 | } | | 393 | } |
394 | } | | 394 | } |
395 | | | 395 | |
396 | /* | | 396 | /* |
397 | * Also try to get the default bootpath from ARCBIOS envronment | | 397 | * Also try to get the default bootpath from ARCBIOS envronment |
398 | * bacause bootpath is not set properly by old bootloaders and | | 398 | * bacause bootpath is not set properly by old bootloaders and |
399 | * argv[0] might be invalid on some machine. | | 399 | * argv[0] might be invalid on some machine. |
400 | */ | | 400 | */ |
401 | osload = arcbios_GetEnvironmentVariable("OSLoadPartition"); | | 401 | osload = arcbios_GetEnvironmentVariable("OSLoadPartition"); |
402 | if (osload != NULL) | | 402 | if (osload != NULL) |
403 | makebootdev(osload); | | 403 | makebootdev(osload); |
404 | | | 404 | |
405 | /* | | 405 | /* |
406 | * The case where the kernel has been loaded by a | | 406 | * The case where the kernel has been loaded by a |
407 | * boot loader will usually have been catched by | | 407 | * boot loader will usually have been catched by |
408 | * the first makebootdev() case earlier on, but | | 408 | * the first makebootdev() case earlier on, but |
409 | * we still use OSLoadPartition to get the preferred | | 409 | * we still use OSLoadPartition to get the preferred |
410 | * root filesystem location, even if it's not | | 410 | * root filesystem location, even if it's not |
411 | * actually the location of the loaded kernel. | | 411 | * actually the location of the loaded kernel. |
412 | */ | | 412 | */ |
413 | for (i = 0; i < argc; i++) { | | 413 | for (i = 0; i < argc; i++) { |
414 | if (strncmp(argv[i], "OSLoadPartition=", 15) == 0) | | 414 | if (strncmp(argv[i], "OSLoadPartition=", 15) == 0) |
415 | makebootdev(argv[i] + 16); | | 415 | makebootdev(argv[i] + 16); |
416 | } | | 416 | } |
417 | | | 417 | |
418 | /* | | 418 | /* |
419 | * When the kernel is loaded directly by the firmware, and | | 419 | * When the kernel is loaded directly by the firmware, and |
420 | * no explicit OSLoadPartition is set, we fall back on | | 420 | * no explicit OSLoadPartition is set, we fall back on |
421 | * SystemPartition for the boot device. | | 421 | * SystemPartition for the boot device. |
422 | */ | | 422 | */ |
423 | for (i = 0; i < argc; i++) { | | 423 | for (i = 0; i < argc; i++) { |
424 | if (strncmp(argv[i], "SystemPartition", 15) == 0) | | 424 | if (strncmp(argv[i], "SystemPartition", 15) == 0) |
425 | makebootdev(argv[i] + 16); | | 425 | makebootdev(argv[i] + 16); |
426 | } | | 426 | } |
427 | | | 427 | |
428 | /* | | 428 | /* |
429 | * Single- or multi-user ('auto' in SGI terms). | | 429 | * Single- or multi-user ('auto' in SGI terms). |
430 | * | | 430 | * |
431 | * Query ARCBIOS first, then default to environment variables. | | 431 | * Query ARCBIOS first, then default to environment variables. |
432 | */ | | 432 | */ |
433 | | | 433 | |
434 | /* Set default to single user. */ | | 434 | /* Set default to single user. */ |
435 | boothowto = RB_SINGLE; | | 435 | boothowto = RB_SINGLE; |
436 | | | 436 | |
437 | osload = arcbios_GetEnvironmentVariable("OSLoadOptions"); | | 437 | osload = arcbios_GetEnvironmentVariable("OSLoadOptions"); |
438 | if (osload != NULL && strcmp(osload, "auto") == 0) | | 438 | if (osload != NULL && strcmp(osload, "auto") == 0) |
439 | boothowto &= ~RB_SINGLE; | | 439 | boothowto &= ~RB_SINGLE; |
440 | | | 440 | |
441 | for (i = 0; i < argc; i++) { | | 441 | for (i = 0; i < argc; i++) { |
442 | if (strcmp(argv[i], "OSLoadOptions=auto") == 0) | | 442 | if (strcmp(argv[i], "OSLoadOptions=auto") == 0) |
443 | boothowto &= ~RB_SINGLE; | | 443 | boothowto &= ~RB_SINGLE; |
444 | } | | 444 | } |
445 | | | 445 | |
446 | /* | | 446 | /* |
447 | * Pass the args again to check for flags -- This is done | | 447 | * Pass the args again to check for flags -- This is done |
448 | * AFTER checking for OSLoadOptions to ensure that "auto" | | 448 | * AFTER checking for OSLoadOptions to ensure that "auto" |
449 | * does not override the "-s" flag. | | 449 | * does not override the "-s" flag. |
450 | */ | | 450 | */ |
451 | | | 451 | |
452 | for (i = 0; i < argc; i++) { | | 452 | for (i = 0; i < argc; i++) { |
453 | /* | | 453 | /* |
454 | * Unfortunately, it appears that IP12's prom passes a '-a' | | 454 | * Unfortunately, it appears that IP12's prom passes a '-a' |
455 | * flag when booting a kernel directly from a disk volume | | 455 | * flag when booting a kernel directly from a disk volume |
456 | * header. This corresponds to RB_ASKNAME in NetBSD, but | | 456 | * header. This corresponds to RB_ASKNAME in NetBSD, but |
457 | * appears to mean 'autoboot' in prehistoric SGI-speak. | | 457 | * appears to mean 'autoboot' in prehistoric SGI-speak. |
458 | */ | | 458 | */ |
459 | if (mach_type < MACH_SGI_IP20 && bootinfo == NULL && | | 459 | if (mach_type < MACH_SGI_IP20 && bootinfo == NULL && |
460 | strcmp(argv[i], "-a") == 0) | | 460 | strcmp(argv[i], "-a") == 0) |
461 | continue; | | 461 | continue; |
462 | | | 462 | |
463 | /* | | 463 | /* |
464 | * Extract out any flags passed for the kernel in the | | 464 | * Extract out any flags passed for the kernel in the |
465 | * argument string. Warn for unknown/invalid flags, | | 465 | * argument string. Warn for unknown/invalid flags, |
466 | * but silently skip non-flag arguments, as they are | | 466 | * but silently skip non-flag arguments, as they are |
467 | * likely PROM environment values (if I knew those | | 467 | * likely PROM environment values (if I knew those |
468 | * would always precede *any* flags, then I'd say we | | 468 | * would always precede *any* flags, then I'd say we |
469 | * should warn about *all* unexpected values, but for | | 469 | * should warn about *all* unexpected values, but for |
470 | * now this should be fine). | | 470 | * now this should be fine). |
471 | * | | 471 | * |
472 | * Use the MI boot-flag extractor since we don't use | | 472 | * Use the MI boot-flag extractor since we don't use |
473 | * any special MD flags and to make sure we're up-to | | 473 | * any special MD flags and to make sure we're up-to |
474 | * date with new MI flags whenever they're added. | | 474 | * date with new MI flags whenever they're added. |
475 | */ | | 475 | */ |
476 | if (argv[i][0] == '-') { | | 476 | if (argv[i][0] == '-') { |
477 | rv = 0; | | 477 | rv = 0; |
478 | BOOT_FLAG(argv[i][1], rv); | | 478 | BOOT_FLAG(argv[i][1], rv); |
479 | | | 479 | |
480 | if (rv == 0) { | | 480 | if (rv == 0) { |
481 | printf("Unexpected option '%s' ignored", | | 481 | printf("Unexpected option '%s' ignored", |
482 | argv[i]); | | 482 | argv[i]); |
483 | } else { | | 483 | } else { |
484 | boothowto |= rv; | | 484 | boothowto |= rv; |
485 | } | | 485 | } |
486 | } | | 486 | } |
487 | } | | 487 | } |
488 | | | 488 | |
489 | #ifdef DEBUG | | 489 | #ifdef DEBUG |
490 | boothowto |= AB_DEBUG; | | 490 | boothowto |= AB_DEBUG; |
491 | #endif | | 491 | #endif |
492 | aprint_debug("argc = %d\n", argc); | | 492 | aprint_debug("argc = %d\n", argc); |
493 | for (i = 0; i < argc; i++) | | 493 | for (i = 0; i < argc; i++) |
494 | aprint_debug("argv[%d] = %s\n", i, argv[i]); | | 494 | aprint_debug("argv[%d] = %s\n", i, argv[i]); |
495 | | | 495 | |
496 | #if NKSYMS || defined(DDB) || defined(MODULAR) | | 496 | #if NKSYMS || defined(DDB) || defined(MODULAR) |
497 | /* init symbols if present */ | | 497 | /* init symbols if present */ |
498 | if (esym) | | 498 | if (esym) |
499 | ksyms_addsyms_elf(nsym, ssym, esym); | | 499 | ksyms_addsyms_elf(nsym, ssym, esym); |
500 | #endif /* NKSYMS || defined(DDB) || defined(MODULAR) */ | | 500 | #endif /* NKSYMS || defined(DDB) || defined(MODULAR) */ |
501 | | | 501 | |
502 | #if defined(KGDB) || defined(DDB) | | 502 | #if defined(KGDB) || defined(DDB) |
503 | /* Set up DDB hook to turn off watchdog on entry */ | | 503 | /* Set up DDB hook to turn off watchdog on entry */ |
504 | db_trap_callback = ddb_trap_hook; | | 504 | db_trap_callback = ddb_trap_hook; |
505 | | | 505 | |
506 | #ifdef DDB | | 506 | #ifdef DDB |
507 | if (boothowto & RB_KDB) | | 507 | if (boothowto & RB_KDB) |
508 | Debugger(); | | 508 | Debugger(); |
509 | #endif | | 509 | #endif |
510 | | | 510 | |
511 | #ifdef KGDB | | 511 | #ifdef KGDB |
512 | kgdb_port_init(); | | 512 | kgdb_port_init(); |
513 | | | 513 | |
514 | if (boothowto & RB_KDB) | | 514 | if (boothowto & RB_KDB) |
515 | kgdb_connect(0); | | 515 | kgdb_connect(0); |
516 | #endif | | 516 | #endif |
517 | #endif | | 517 | #endif |
518 | | | 518 | |
519 | switch (mach_type) { | | 519 | switch (mach_type) { |
520 | #if defined(MIPS1) | | 520 | #if defined(MIPS1) |
521 | case MACH_SGI_IP6 | MACH_SGI_IP10: | | 521 | case MACH_SGI_IP6 | MACH_SGI_IP10: |
522 | platform.intr3 = mips1_fpu_intr; | | 522 | platform.intr3 = mips1_fpu_intr; |
523 | ipl_sr_map = sgi_ip6_ipl_sr_map; | | 523 | ipl_sr_map = sgi_ip6_ipl_sr_map; |
524 | break; | | 524 | break; |
525 | | | 525 | |
526 | case MACH_SGI_IP12: | | 526 | case MACH_SGI_IP12: |
527 | i = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000); | | 527 | i = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000); |
528 | mach_boardrev = (i & 0x7000) >> 12; | | 528 | mach_boardrev = (i & 0x7000) >> 12; |
529 | | | 529 | |
530 | if ((i & 0x8000) == 0) { | | 530 | if ((i & 0x8000) == 0) { |
531 | if (mach_boardrev < 7) | | 531 | if (mach_boardrev < 7) |
532 | mach_subtype = MACH_SGI_IP12_4D_3X; | | 532 | mach_subtype = MACH_SGI_IP12_4D_3X; |
533 | else | | 533 | else |
534 | mach_subtype = MACH_SGI_IP12_VIP12; | | 534 | mach_subtype = MACH_SGI_IP12_VIP12; |
535 | } else { | | 535 | } else { |
536 | if (mach_boardrev < 6) | | 536 | if (mach_boardrev < 6) |
537 | mach_subtype = MACH_SGI_IP12_HP1; | | 537 | mach_subtype = MACH_SGI_IP12_HP1; |
538 | else | | 538 | else |
539 | mach_subtype = MACH_SGI_IP12_HPLC; | | 539 | mach_subtype = MACH_SGI_IP12_HPLC; |
540 | } | | 540 | } |
541 | | | 541 | |
542 | ipl_sr_map = sgi_ip12_ipl_sr_map; | | 542 | ipl_sr_map = sgi_ip12_ipl_sr_map; |
543 | platform.intr0 = mips1_fpu_intr; | | 543 | platform.intr0 = mips1_fpu_intr; |
544 | break; | | 544 | break; |
545 | #endif /* MIPS1 */ | | 545 | #endif /* MIPS1 */ |
546 | | | 546 | |
547 | #if defined(MIPS3) | | 547 | #if defined(MIPS3) |
548 | case MACH_SGI_IP20: | | 548 | case MACH_SGI_IP20: |
549 | i = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000); | | 549 | i = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000); |
550 | mach_boardrev = (i & 0x7000) >> 12; | | 550 | mach_boardrev = (i & 0x7000) >> 12; |
551 | ipl_sr_map = sgi_ip2x_ipl_sr_map; | | 551 | ipl_sr_map = sgi_ip2x_ipl_sr_map; |
552 | platform.intr5 = mips3_clock_intr; | | 552 | platform.intr5 = mips3_clock_intr; |
553 | break; | | 553 | break; |
554 | case MACH_SGI_IP22: | | 554 | case MACH_SGI_IP22: |
555 | ipl_sr_map = sgi_ip2x_ipl_sr_map; | | 555 | ipl_sr_map = sgi_ip2x_ipl_sr_map; |
556 | platform.intr5 = mips3_clock_intr; | | 556 | platform.intr5 = mips3_clock_intr; |
557 | break; | | 557 | break; |
558 | case MACH_SGI_IP30: | | 558 | case MACH_SGI_IP30: |
559 | ipl_sr_map = sgi_ip3x_ipl_sr_map; | | 559 | ipl_sr_map = sgi_ip3x_ipl_sr_map; |
560 | platform.intr5 = mips3_clock_intr; | | 560 | platform.intr5 = mips3_clock_intr; |
561 | break; | | 561 | break; |
562 | case MACH_SGI_IP32: | | 562 | case MACH_SGI_IP32: |
563 | ipl_sr_map = sgi_ip3x_ipl_sr_map; | | 563 | ipl_sr_map = sgi_ip3x_ipl_sr_map; |
564 | platform.intr5 = mips3_clock_intr; | | 564 | platform.intr5 = mips3_clock_intr; |
565 | break; | | 565 | break; |
566 | #endif /* MIPS3 */ | | 566 | #endif /* MIPS3 */ |
567 | default: | | 567 | default: |
568 | panic("IP%d architecture not supported", mach_type); | | 568 | panic("IP%d architecture not supported", mach_type); |
569 | break; | | 569 | break; |
570 | } | | 570 | } |
571 | | | 571 | |
572 | physmem = arcsmem = 0; | | 572 | physmem = arcsmem = 0; |
573 | mem_cluster_cnt = 0; | | 573 | mem_cluster_cnt = 0; |
574 | mem = NULL; | | 574 | mem = NULL; |
575 | | | 575 | |
576 | #ifdef DEBUG | | 576 | #ifdef DEBUG |
577 | i = 0; | | 577 | i = 0; |
578 | mem = NULL; | | 578 | mem = NULL; |
579 | | | 579 | |
580 | do { | | 580 | do { |
581 | if ((mem = arcbios_GetMemoryDescriptor(mem)) != NULL) { | | 581 | if ((mem = arcbios_GetMemoryDescriptor(mem)) != NULL) { |
582 | i++; | | 582 | i++; |
583 | printf("Mem block %d: type %d, " | | 583 | printf("Mem block %d: type %d, " |
584 | "base 0x%04lx, size 0x%04lx\n", | | 584 | "base 0x%04"PRIx32", size 0x%04"PRIx32"\n", |
585 | i, mem->Type, mem->BasePage, mem->PageCount); | | 585 | i, mem->Type, mem->BasePage, mem->PageCount); |
586 | } | | 586 | } |
587 | } while (mem != NULL); | | 587 | } while (mem != NULL); |
588 | #endif | | 588 | #endif |
589 | | | 589 | |
590 | /* | | 590 | /* |
591 | * XXX This code assumes that ARCS provides the memory | | 591 | * XXX This code assumes that ARCS provides the memory |
592 | * XXX sorted in ascending order. | | 592 | * XXX sorted in ascending order. |
593 | */ | | 593 | */ |
594 | mem = NULL; | | 594 | mem = NULL; |
595 | for (i = 0; mem_cluster_cnt < VM_PHYSSEG_MAX; i++) { | | 595 | for (i = 0; mem_cluster_cnt < VM_PHYSSEG_MAX; i++) { |
596 | mem = arcbios_GetMemoryDescriptor(mem); | | 596 | mem = arcbios_GetMemoryDescriptor(mem); |
597 | | | 597 | |
598 | if (mem == NULL) | | 598 | if (mem == NULL) |
599 | break; | | 599 | break; |
600 | | | 600 | |
601 | first = round_page(mem->BasePage * ARCBIOS_PAGESIZE); | | 601 | first = round_page(mem->BasePage * ARCBIOS_PAGESIZE); |
602 | last = trunc_page(first + mem->PageCount * ARCBIOS_PAGESIZE); | | 602 | last = trunc_page(first + mem->PageCount * ARCBIOS_PAGESIZE); |
603 | size = last - first; | | 603 | size = last - first; |
604 | | | 604 | |
605 | switch (mem->Type) { | | 605 | switch (mem->Type) { |
606 | case ARCBIOS_MEM_FreeContiguous: | | 606 | case ARCBIOS_MEM_FreeContiguous: |
607 | case ARCBIOS_MEM_FreeMemory: | | 607 | case ARCBIOS_MEM_FreeMemory: |
608 | case ARCBIOS_MEM_LoadedProgram: | | 608 | case ARCBIOS_MEM_LoadedProgram: |
609 | mem_clusters[mem_cluster_cnt].start = first; | | 609 | mem_clusters[mem_cluster_cnt].start = first; |
610 | mem_clusters[mem_cluster_cnt].size = size; | | 610 | mem_clusters[mem_cluster_cnt].size = size; |
611 | mem_cluster_cnt++; | | 611 | mem_cluster_cnt++; |
612 | break; | | 612 | break; |
613 | | | 613 | |
614 | case ARCBIOS_MEM_FirmwareTemporary: | | 614 | case ARCBIOS_MEM_FirmwareTemporary: |
615 | case ARCBIOS_MEM_FirmwarePermanent: | | 615 | case ARCBIOS_MEM_FirmwarePermanent: |
616 | arcsmem += btoc(size); | | 616 | arcsmem += btoc(size); |
617 | break; | | 617 | break; |
618 | | | 618 | |
619 | case ARCBIOS_MEM_ExceptionBlock: | | 619 | case ARCBIOS_MEM_ExceptionBlock: |
620 | case ARCBIOS_MEM_SystemParameterBlock: | | 620 | case ARCBIOS_MEM_SystemParameterBlock: |
621 | case ARCBIOS_MEM_BadMemory: | | 621 | case ARCBIOS_MEM_BadMemory: |
622 | break; | | 622 | break; |
623 | | | 623 | |
624 | default: | | 624 | default: |
625 | panic("unknown memory descriptor %d type %d", | | 625 | panic("unknown memory descriptor %d type %d", |
626 | i, mem->Type); | | 626 | i, mem->Type); |
627 | } | | 627 | } |
628 | | | 628 | |
629 | physmem += btoc(size); | | 629 | physmem += btoc(size); |
630 | | | 630 | |
631 | } | | 631 | } |
632 | | | 632 | |
633 | if (mem_cluster_cnt == 0) | | 633 | if (mem_cluster_cnt == 0) |
634 | panic("no free memory descriptors found"); | | 634 | panic("no free memory descriptors found"); |
635 | | | 635 | |
636 | mips_page_physload((vaddr_t)kernel_text - PAGE_SIZE, (vaddr_t)kernend, | | 636 | mips_page_physload((vaddr_t)kernel_text - PAGE_SIZE, (vaddr_t)kernend, |
637 | mem_clusters, mem_cluster_cnt, NULL, 0); | | 637 | mem_clusters, mem_cluster_cnt, NULL, 0); |
638 | | | 638 | |
639 | /* We can now no longer use bootinfo. */ | | 639 | /* We can now no longer use bootinfo. */ |
640 | bootinfo = NULL; | | 640 | bootinfo = NULL; |
641 | | | 641 | |
642 | /* | | 642 | /* |
643 | * Initialize mips version-dependent DMA handlers. | | 643 | * Initialize mips version-dependent DMA handlers. |
644 | */ | | 644 | */ |
645 | sgimips_bus_dma_init(); | | 645 | sgimips_bus_dma_init(); |
646 | | | 646 | |
647 | /* | | 647 | /* |
648 | * Walk the component tree and count the number of CPUs | | 648 | * Walk the component tree and count the number of CPUs |
649 | * present in the system. | | 649 | * present in the system. |
650 | */ | | 650 | */ |
651 | arcbios_tree_walk(sgimips_count_cpus, NULL); | | 651 | arcbios_tree_walk(sgimips_count_cpus, NULL); |
652 | | | 652 | |
653 | /* | | 653 | /* |
654 | * Copy exception-dispatch code down to exception vector. | | 654 | * Copy exception-dispatch code down to exception vector. |
655 | * Initialize locore-function vector. | | 655 | * Initialize locore-function vector. |
656 | * Clear out the I and D caches. | | 656 | * Clear out the I and D caches. |
657 | */ | | 657 | */ |
658 | mips_vector_init(NULL, false); | | 658 | mips_vector_init(NULL, false); |
659 | | | 659 | |
660 | /* | | 660 | /* |
661 | * Initialize error message buffer (at end of core). | | 661 | * Initialize error message buffer (at end of core). |
662 | */ | | 662 | */ |
663 | mips_init_msgbuf(); | | 663 | mips_init_msgbuf(); |
664 | | | 664 | |
665 | pmap_bootstrap(); | | 665 | pmap_bootstrap(); |
666 | | | 666 | |
667 | /* | | 667 | /* |
668 | * Allocate uarea for lwp0 and set it. | | 668 | * Allocate uarea for lwp0 and set it. |
669 | */ | | 669 | */ |
670 | mips_init_lwp0_uarea(); | | 670 | mips_init_lwp0_uarea(); |
671 | } | | 671 | } |
672 | | | 672 | |
673 | void | | 673 | void |
674 | sgimips_count_cpus(struct arcbios_component *node, | | 674 | sgimips_count_cpus(struct arcbios_component *node, |
675 | struct arcbios_treewalk_context *atc) | | 675 | struct arcbios_treewalk_context *atc) |
676 | { | | 676 | { |
677 | | | 677 | |
678 | switch (node->Class) { | | 678 | switch (node->Class) { |
679 | case COMPONENT_CLASS_ProcessorClass: | | 679 | case COMPONENT_CLASS_ProcessorClass: |
680 | if (node->Type == COMPONENT_TYPE_CPU) | | 680 | if (node->Type == COMPONENT_TYPE_CPU) |
681 | ncpus++; | | 681 | ncpus++; |
682 | break; | | 682 | break; |
683 | | | 683 | |
684 | default: | | 684 | default: |
685 | break; | | 685 | break; |
686 | } | | 686 | } |
687 | } | | 687 | } |
688 | | | 688 | |
689 | /* | | 689 | /* |
690 | * Allocate memory for variable-sized tables. | | 690 | * Allocate memory for variable-sized tables. |
691 | */ | | 691 | */ |
692 | void | | 692 | void |
693 | cpu_startup(void) | | 693 | cpu_startup(void) |
694 | { | | 694 | { |
695 | vaddr_t minaddr, maxaddr; | | 695 | vaddr_t minaddr, maxaddr; |
696 | char pbuf[9]; | | 696 | char pbuf[9]; |
697 | | | 697 | |
698 | #ifdef BOOTINFO_DEBUG | | 698 | #ifdef BOOTINFO_DEBUG |
699 | if (bootinfo_msg) | | 699 | if (bootinfo_msg) |
700 | printf(bootinfo_msg); | | 700 | printf(bootinfo_msg); |
701 | #endif | | 701 | #endif |
702 | | | 702 | |
703 | printf("%s%s", copyright, version); | | 703 | printf("%s%s", copyright, version); |
704 | | | 704 | |
705 | format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); | | 705 | format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); |
706 | printf("total memory = %s\n", pbuf); | | 706 | printf("total memory = %s\n", pbuf); |
707 | format_bytes(pbuf, sizeof(pbuf), ctob(arcsmem)); | | 707 | format_bytes(pbuf, sizeof(pbuf), ctob(arcsmem)); |
708 | printf("(%s reserved for ARCS)\n", pbuf); | | 708 | printf("(%s reserved for ARCS)\n", pbuf); |
709 | | | 709 | |
710 | minaddr = 0; | | 710 | minaddr = 0; |
711 | /* | | 711 | /* |
712 | * Allocate a submap for physio. | | 712 | * Allocate a submap for physio. |
713 | */ | | 713 | */ |
714 | phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, | | 714 | phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, |
715 | VM_PHYS_SIZE, 0, false, NULL); | | 715 | VM_PHYS_SIZE, 0, false, NULL); |
716 | | | 716 | |
717 | /* | | 717 | /* |
718 | * (No need to allocate an mbuf cluster submap. Mbuf clusters | | 718 | * (No need to allocate an mbuf cluster submap. Mbuf clusters |
719 | * are allocated via the pool allocator, and we use KSEG to | | 719 | * are allocated via the pool allocator, and we use KSEG to |
720 | * map those pages.) | | 720 | * map those pages.) |
721 | */ | | 721 | */ |
722 | format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); | | 722 | format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); |
723 | printf("avail memory = %s\n", pbuf); | | 723 | printf("avail memory = %s\n", pbuf); |
724 | } | | 724 | } |
725 | | | 725 | |
726 | int waittime = -1; | | 726 | int waittime = -1; |
727 | | | 727 | |
728 | void | | 728 | void |
729 | cpu_reboot(int howto, char *bootstr) | | 729 | cpu_reboot(int howto, char *bootstr) |
730 | { | | 730 | { |
731 | /* Take a snapshot before clobbering any registers. */ | | 731 | /* Take a snapshot before clobbering any registers. */ |
732 | savectx(curpcb); | | 732 | savectx(curpcb); |
733 | | | 733 | |
734 | if (cold) { | | 734 | if (cold) { |
735 | howto |= RB_HALT; | | 735 | howto |= RB_HALT; |
736 | goto haltsys; | | 736 | goto haltsys; |
737 | } | | 737 | } |
738 | | | 738 | |
739 | /* If "always halt" was specified as a boot flag, obey. */ | | 739 | /* If "always halt" was specified as a boot flag, obey. */ |
740 | if (boothowto & RB_HALT) | | 740 | if (boothowto & RB_HALT) |
741 | howto |= RB_HALT; | | 741 | howto |= RB_HALT; |
742 | | | 742 | |
743 | boothowto = howto; | | 743 | boothowto = howto; |
744 | if ((howto & RB_NOSYNC) == 0 && (waittime < 0)) { | | 744 | if ((howto & RB_NOSYNC) == 0 && (waittime < 0)) { |
745 | waittime = 0; | | 745 | waittime = 0; |
746 | vfs_shutdown(); | | 746 | vfs_shutdown(); |
747 | | | 747 | |
748 | /* | | 748 | /* |
749 | * If we've been adjusting the clock, the todr | | 749 | * If we've been adjusting the clock, the todr |
750 | * will be out of synch; adjust it now. | | 750 | * will be out of synch; adjust it now. |
751 | */ | | 751 | */ |
752 | resettodr(); | | 752 | resettodr(); |
753 | } | | 753 | } |
754 | | | 754 | |
755 | /* Clear and disable watchdog timer. */ | | 755 | /* Clear and disable watchdog timer. */ |
756 | (void)(*platform.watchdog_disable)(); | | 756 | (void)(*platform.watchdog_disable)(); |
757 | | | 757 | |
758 | splhigh(); | | 758 | splhigh(); |
759 | | | 759 | |
760 | if (howto & RB_DUMP) | | 760 | if (howto & RB_DUMP) |
761 | dumpsys(); | | 761 | dumpsys(); |
762 | | | 762 | |
763 | haltsys: | | 763 | haltsys: |
764 | | | 764 | |
765 | doshutdownhooks(); | | 765 | doshutdownhooks(); |
766 | | | 766 | |
767 | pmf_system_shutdown(boothowto); | | 767 | pmf_system_shutdown(boothowto); |
768 | | | 768 | |
769 | /* | | 769 | /* |
770 | * Calling arcbios_PowerDown() results in a "CP1 unusable trap" | | 770 | * Calling arcbios_PowerDown() results in a "CP1 unusable trap" |
771 | * which lands me back in DDB, at least on my Indy. So, enable | | 771 | * which lands me back in DDB, at least on my Indy. So, enable |
772 | * the FPU before asking the PROM to power down to avoid this.. | | 772 | * the FPU before asking the PROM to power down to avoid this.. |
773 | * It seems to want the FPU to play the `poweroff tune' 8-/ | | 773 | * It seems to want the FPU to play the `poweroff tune' 8-/ |
774 | */ | | 774 | */ |
775 | if ((howto & RB_POWERDOWN) == RB_POWERDOWN) { | | 775 | if ((howto & RB_POWERDOWN) == RB_POWERDOWN) { |
776 | /* Set CP1 usable bit in SR */ | | 776 | /* Set CP1 usable bit in SR */ |
777 | mips_cp0_status_write(mips_cp0_status_read() | | | 777 | mips_cp0_status_write(mips_cp0_status_read() | |
778 | MIPS_SR_COP_1_BIT); | | 778 | MIPS_SR_COP_1_BIT); |
779 | | | 779 | |
780 | printf("powering off...\n\n"); | | 780 | printf("powering off...\n\n"); |
781 | delay(500000); | | 781 | delay(500000); |
782 | #if NMCCLOCK_MACE > 0 | | 782 | #if NMCCLOCK_MACE > 0 |
783 | if (mach_type == MACH_SGI_IP32) { | | 783 | if (mach_type == MACH_SGI_IP32) { |
784 | mcclock_poweroff(); | | 784 | mcclock_poweroff(); |
785 | } else | | 785 | } else |
786 | #endif | | 786 | #endif |
787 | arcbios_PowerDown(); | | 787 | arcbios_PowerDown(); |
788 | printf("WARNING: powerdown failed\n"); | | 788 | printf("WARNING: powerdown failed\n"); |
789 | /* | | 789 | /* |
790 | * RB_POWERDOWN implies RB_HALT... fall into it... | | 790 | * RB_POWERDOWN implies RB_HALT... fall into it... |
791 | */ | | 791 | */ |
792 | } | | 792 | } |
793 | | | 793 | |
794 | if (howto & RB_HALT) { | | 794 | if (howto & RB_HALT) { |
795 | printf("halting...\n\n"); | | 795 | printf("halting...\n\n"); |
796 | arcbios_EnterInteractiveMode(); | | 796 | arcbios_EnterInteractiveMode(); |
797 | } | | 797 | } |
798 | | | 798 | |
799 | printf("rebooting...\n\n"); | | 799 | printf("rebooting...\n\n"); |
800 | #if NCRIME > 0 | | 800 | #if NCRIME > 0 |
801 | if (mach_type == MACH_SGI_IP32) { | | 801 | if (mach_type == MACH_SGI_IP32) { |
802 | crime_reboot(); | | 802 | crime_reboot(); |
803 | } else | | 803 | } else |
804 | #endif | | 804 | #endif |
805 | arcbios_Reboot(); | | 805 | arcbios_Reboot(); |
806 | | | 806 | |
807 | for (;;); | | 807 | for (;;); |
808 | } | | 808 | } |
809 | | | 809 | |
810 | void delay(unsigned long n) | | 810 | void delay(unsigned long n) |
811 | { | | 811 | { |
812 | register int __N = curcpu()->ci_divisor_delay * n; | | 812 | register int __N = curcpu()->ci_divisor_delay * n; |
813 | | | 813 | |
814 | do { | | 814 | do { |
815 | __asm("addiu %0,%1,-1" : "=r" (__N) : "0" (__N)); | | 815 | __asm("addiu %0,%1,-1" : "=r" (__N) : "0" (__N)); |
816 | } while (__N > 0); | | 816 | } while (__N > 0); |
817 | } | | 817 | } |
818 | | | 818 | |
819 | /* | | 819 | /* |
820 | * IP12 appears to be buggy and unable to reliably support badaddr. | | 820 | * IP12 appears to be buggy and unable to reliably support badaddr. |
821 | * Approximately 1.8% of the time a false negative (bad address said to | | 821 | * Approximately 1.8% of the time a false negative (bad address said to |
822 | * be good) is generated and we stomp on invalid registers. Testing has | | 822 | * be good) is generated and we stomp on invalid registers. Testing has |
823 | * not shown false positives, nor consecutive false negatives to occur. | | 823 | * not shown false positives, nor consecutive false negatives to occur. |
824 | */ | | 824 | */ |
825 | static int | | 825 | static int |
826 | badaddr_workaround(void *addr, size_t size) | | 826 | badaddr_workaround(void *addr, size_t size) |
827 | { | | 827 | { |
828 | int i, bad; | | 828 | int i, bad; |
829 | | | 829 | |
830 | for (i = bad = 0; i < 100; i++) { | | 830 | for (i = bad = 0; i < 100; i++) { |
831 | if (badaddr(addr, size)) | | 831 | if (badaddr(addr, size)) |
832 | bad++; | | 832 | bad++; |
833 | } | | 833 | } |
834 | | | 834 | |
835 | /* false positives appear not to occur */ | | 835 | /* false positives appear not to occur */ |
836 | return (bad != 0); | | 836 | return (bad != 0); |
837 | } | | 837 | } |
838 | | | 838 | |
839 | /* | | 839 | /* |
840 | * Ensure all platform vectors are always initialized. | | 840 | * Ensure all platform vectors are always initialized. |
841 | */ | | 841 | */ |
842 | static void | | 842 | static void |
843 | unimpl_bus_reset(void) | | 843 | unimpl_bus_reset(void) |
844 | { | | 844 | { |
845 | | | 845 | |
846 | panic("target init didn't set bus_reset"); | | 846 | panic("target init didn't set bus_reset"); |
847 | } | | 847 | } |
848 | | | 848 | |
849 | static void | | 849 | static void |
850 | unimpl_cons_init(void) | | 850 | unimpl_cons_init(void) |
851 | { | | 851 | { |
852 | | | 852 | |
853 | panic("target init didn't set cons_init"); | | 853 | panic("target init didn't set cons_init"); |
854 | } | | 854 | } |
855 | | | 855 | |
856 | static void * | | 856 | static void * |
857 | unimpl_intr_establish(int level, int ipl, int (*handler) (void *), void *arg) | | 857 | unimpl_intr_establish(int level, int ipl, int (*handler) (void *), void *arg) |
858 | { | | 858 | { |
859 | panic("target init didn't set intr_establish"); | | 859 | panic("target init didn't set intr_establish"); |
860 | return NULL; | | 860 | return NULL; |
861 | } | | 861 | } |
862 | | | 862 | |
863 | static void | | 863 | static void |
864 | unimpl_intr(vaddr_t pc, uint32_t status, uint32_t pending) | | 864 | unimpl_intr(vaddr_t pc, uint32_t status, uint32_t pending) |
865 | { | | 865 | { |
866 | printf("spurious interrupt pending %#x\n", pending); | | 866 | printf("spurious interrupt pending %#x\n", pending); |
867 | } | | 867 | } |
868 | | | 868 | |
869 | static unsigned long | | 869 | static unsigned long |
870 | nulllong(void) | | 870 | nulllong(void) |
871 | { | | 871 | { |
872 | printf("nulllong\n"); | | 872 | printf("nulllong\n"); |
873 | return (0); | | 873 | return (0); |
874 | } | | 874 | } |
875 | | | 875 | |
876 | static void | | 876 | static void |
877 | nullvoid(void) | | 877 | nullvoid(void) |
878 | { | | 878 | { |
879 | printf("nullvoid\n"); | | 879 | printf("nullvoid\n"); |
880 | return; | | 880 | return; |
881 | } | | 881 | } |
882 | | | 882 | |
883 | void * | | 883 | void * |
884 | lookup_bootinfo(int type) | | 884 | lookup_bootinfo(int type) |
885 | { | | 885 | { |
886 | struct btinfo_common *bt; | | 886 | struct btinfo_common *bt; |
887 | uint8_t *bip; | | 887 | uint8_t *bip; |
888 | | | 888 | |
889 | /* check for a bootinfo record first */ | | 889 | /* check for a bootinfo record first */ |
890 | if (bootinfo == NULL) | | 890 | if (bootinfo == NULL) |
891 | return NULL; | | 891 | return NULL; |
892 | | | 892 | |
893 | bip = bootinfo; | | 893 | bip = bootinfo; |
894 | do { | | 894 | do { |
895 | bt = (struct btinfo_common *)bip; | | 895 | bt = (struct btinfo_common *)bip; |
896 | if (bt->type == type) | | 896 | if (bt->type == type) |
897 | return (void *)bt; | | 897 | return (void *)bt; |
898 | bip += bt->next; | | 898 | bip += bt->next; |
899 | } while (bt->next != 0 && | | 899 | } while (bt->next != 0 && |
900 | bt->next < BOOTINFO_SIZE /* sanity */ && | | 900 | bt->next < BOOTINFO_SIZE /* sanity */ && |
901 | (size_t)bip < (size_t)bootinfo + BOOTINFO_SIZE); | | 901 | (size_t)bip < (size_t)bootinfo + BOOTINFO_SIZE); |
902 | | | 902 | |
903 | return NULL; | | 903 | return NULL; |
904 | } | | 904 | } |
905 | | | 905 | |
906 | #if defined(DDB) || defined(KGDB) | | 906 | #if defined(DDB) || defined(KGDB) |
907 | | | 907 | |
908 | void ddb_trap_hook(int where) | | 908 | void ddb_trap_hook(int where) |
909 | { | | 909 | { |
910 | switch (where) { | | 910 | switch (where) { |
911 | case 1: /* Entry to DDB, turn watchdog off */ | | 911 | case 1: /* Entry to DDB, turn watchdog off */ |
912 | (void)(*platform.watchdog_disable)(); | | 912 | (void)(*platform.watchdog_disable)(); |
913 | break; | | 913 | break; |
914 | | | 914 | |
915 | case 0: /* Exit from DDB, turn watchdog back on */ | | 915 | case 0: /* Exit from DDB, turn watchdog back on */ |
916 | (void)(*platform.watchdog_enable)(); | | 916 | (void)(*platform.watchdog_enable)(); |
917 | break; | | 917 | break; |
918 | } | | 918 | } |
919 | } | | 919 | } |
920 | | | 920 | |
921 | #endif | | 921 | #endif |
922 | | | 922 | |
923 | void mips_machdep_cache_config(void) | | 923 | void mips_machdep_cache_config(void) |
924 | { | | 924 | { |
925 | | | 925 | |
926 | arcbios_tree_walk(mips_machdep_find_l2cache, NULL); | | 926 | arcbios_tree_walk(mips_machdep_find_l2cache, NULL); |
927 | | | 927 | |
928 | switch (MIPS_PRID_IMPL(mips_options.mips_cpu_id)) { | | 928 | switch (MIPS_PRID_IMPL(mips_options.mips_cpu_id)) { |
929 | #if defined(INDY_R4600_CACHE) | | 929 | #if defined(INDY_R4600_CACHE) |
930 | case MIPS_R4600: | | 930 | case MIPS_R4600: |
931 | /* | | 931 | /* |
932 | * R4600 is on Indy-class machines only. Disable and | | 932 | * R4600 is on Indy-class machines only. Disable and |
933 | * flush pcache. | | 933 | * flush pcache. |
934 | */ | | 934 | */ |
935 | mips_cache_info.mci_sdcache_size = 0; | | 935 | mips_cache_info.mci_sdcache_size = 0; |
936 | mips_cache_info.mci_sdcache_line_size = 0; | | 936 | mips_cache_info.mci_sdcache_line_size = 0; |
937 | ip22_sdcache_disable(); | | 937 | ip22_sdcache_disable(); |
938 | break; | | 938 | break; |
939 | #endif | | 939 | #endif |
940 | #if defined(MIPS3) | | 940 | #if defined(MIPS3) |
941 | case MIPS_R5000: | | 941 | case MIPS_R5000: |
942 | case MIPS_RM5200: | | 942 | case MIPS_RM5200: |
943 | r5k_enable_sdcache(); | | 943 | r5k_enable_sdcache(); |
944 | break; | | 944 | break; |
945 | #endif | | 945 | #endif |
946 | } | | 946 | } |
947 | } | | 947 | } |
948 | | | 948 | |
949 | void | | 949 | void |
950 | mips_machdep_find_l2cache(struct arcbios_component *comp, struct arcbios_treewalk_context *atc) | | 950 | mips_machdep_find_l2cache(struct arcbios_component *comp, struct arcbios_treewalk_context *atc) |
951 | { | | 951 | { |
952 | struct mips_cache_info * const mci = &mips_cache_info; | | 952 | struct mips_cache_info * const mci = &mips_cache_info; |
953 | device_t self = atc->atc_cookie; | | 953 | device_t self = atc->atc_cookie; |
954 | | | 954 | |
955 | if (comp->Class != COMPONENT_CLASS_CacheClass) | | 955 | if (comp->Class != COMPONENT_CLASS_CacheClass) |
956 | return; | | 956 | return; |
957 | | | 957 | |
958 | switch (comp->Type) { | | 958 | switch (comp->Type) { |
959 | case COMPONENT_TYPE_SecondaryICache: | | 959 | case COMPONENT_TYPE_SecondaryICache: |
960 | panic("%s: split L2 cache", self->dv_xname); | | 960 | panic("%s: split L2 cache", self->dv_xname); |
961 | case COMPONENT_TYPE_SecondaryDCache: | | 961 | case COMPONENT_TYPE_SecondaryDCache: |
962 | case COMPONENT_TYPE_SecondaryCache: | | 962 | case COMPONENT_TYPE_SecondaryCache: |
963 | mci->mci_sdcache_size = COMPONENT_KEY_Cache_CacheSize(comp->Key); | | 963 | mci->mci_sdcache_size = COMPONENT_KEY_Cache_CacheSize(comp->Key); |
964 | mci->mci_sdcache_line_size = | | 964 | mci->mci_sdcache_line_size = |
965 | COMPONENT_KEY_Cache_LineSize(comp->Key); | | 965 | COMPONENT_KEY_Cache_LineSize(comp->Key); |
966 | /* XXX */ | | 966 | /* XXX */ |
967 | mci->mci_sdcache_ways = 1; | | 967 | mci->mci_sdcache_ways = 1; |
968 | break; | | 968 | break; |
969 | } | | 969 | } |
970 | } | | 970 | } |