machdep.c revision 1.1.2.44 1 1.1.2.35 matt /* machdep.c,v 1.1.2.34 2011/04/29 08:26:18 matt Exp */
2 1.1.2.1 cliff
3 1.1.2.44 matt /*-
4 1.1.2.44 matt * Copyright (c) 2012 The NetBSD Foundation, Inc.
5 1.1.2.1 cliff * All rights reserved.
6 1.1.2.1 cliff *
7 1.1.2.44 matt * This code is derived from software contributed to The NetBSD Foundation
8 1.1.2.44 matt * by Matt Thomas of 3am Software Foundry.
9 1.1.2.1 cliff *
10 1.1.2.1 cliff * Redistribution and use in source and binary forms, with or without
11 1.1.2.1 cliff * modification, are permitted provided that the following conditions
12 1.1.2.1 cliff * are met:
13 1.1.2.1 cliff * 1. Redistributions of source code must retain the above copyright
14 1.1.2.1 cliff * notice, this list of conditions and the following disclaimer.
15 1.1.2.1 cliff * 2. Redistributions in binary form must reproduce the above copyright
16 1.1.2.1 cliff * notice, this list of conditions and the following disclaimer in the
17 1.1.2.1 cliff * documentation and/or other materials provided with the distribution.
18 1.1.2.1 cliff *
19 1.1.2.44 matt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1.2.44 matt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1.2.1 cliff * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1.2.44 matt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1.2.1 cliff * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1.2.1 cliff * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1.2.1 cliff * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1.2.1 cliff * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1.2.1 cliff * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1.2.1 cliff * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1.2.1 cliff * POSSIBILITY OF SUCH DAMAGE.
30 1.1.2.1 cliff */
31 1.1.2.1 cliff
32 1.1.2.1 cliff #include <sys/cdefs.h>
33 1.1.2.35 matt __KERNEL_RCSID(0, "machdep.c,v 1.1.2.34 2011/04/29 08:26:18 matt Exp");
34 1.1.2.25 cliff
35 1.1.2.25 cliff #define __INTR_PRIVATE
36 1.1.2.35 matt #define __MUTEX_PRIVATE
37 1.1.2.39 matt #define _MIPS_BUS_DMA_PRIVATE
38 1.1.2.1 cliff
39 1.1.2.33 cliff #include "opt_multiprocessor.h"
40 1.1.2.1 cliff #include "opt_ddb.h"
41 1.1.2.1 cliff #include "opt_com.h"
42 1.1.2.1 cliff #include "opt_execfmt.h"
43 1.1.2.1 cliff #include "opt_memsize.h"
44 1.1.2.28 cliff #include "rmixl_pcix.h"
45 1.1.2.28 cliff #include "rmixl_pcie.h"
46 1.1.2.1 cliff
47 1.1.2.1 cliff #include <sys/param.h>
48 1.1.2.1 cliff #include <sys/systm.h>
49 1.1.2.1 cliff #include <sys/kernel.h>
50 1.1.2.1 cliff #include <sys/buf.h>
51 1.1.2.1 cliff #include <sys/reboot.h>
52 1.1.2.1 cliff #include <sys/mount.h>
53 1.1.2.1 cliff #include <sys/kcore.h>
54 1.1.2.1 cliff #include <sys/boot_flag.h>
55 1.1.2.1 cliff #include <sys/termios.h>
56 1.1.2.1 cliff #include <sys/ksyms.h>
57 1.1.2.36 matt #include <sys/intr.h>
58 1.1.2.1 cliff #include <sys/bus.h>
59 1.1.2.1 cliff #include <sys/device.h>
60 1.1.2.6 cliff #include <sys/extent.h>
61 1.1.2.6 cliff #include <sys/malloc.h>
62 1.1.2.1 cliff
63 1.1.2.1 cliff #include <uvm/uvm_extern.h>
64 1.1.2.1 cliff
65 1.1.2.1 cliff #include <dev/cons.h>
66 1.1.2.1 cliff
67 1.1.2.1 cliff #include "ksyms.h"
68 1.1.2.1 cliff
69 1.1.2.1 cliff #if NKSYMS || defined(DDB) || defined(LKM)
70 1.1.2.34 matt #include <mips/db_machdep.h>
71 1.1.2.1 cliff #include <ddb/db_extern.h>
72 1.1.2.1 cliff #endif
73 1.1.2.1 cliff
74 1.1.2.34 matt #include <mips/cpu.h>
75 1.1.2.34 matt #include <mips/psl.h>
76 1.1.2.34 matt #include <mips/cache.h>
77 1.1.2.39 matt #include <mips/mipsNN.h>
78 1.1.2.34 matt #include <mips/mips_opcode.h>
79 1.1.2.36 matt #include <mips/pte.h>
80 1.1.2.1 cliff
81 1.1.2.1 cliff #include "com.h"
82 1.1.2.1 cliff #if NCOM == 0
83 1.1.2.1 cliff #error no serial console
84 1.1.2.1 cliff #endif
85 1.1.2.1 cliff
86 1.1.2.1 cliff #include <dev/ic/comreg.h>
87 1.1.2.1 cliff #include <dev/ic/comvar.h>
88 1.1.2.1 cliff
89 1.1.2.39 matt #include <dev/pci/pcireg.h>
90 1.1.2.39 matt #include <dev/pci/pcivar.h>
91 1.1.2.39 matt #include <dev/pci/pciconf.h>
92 1.1.2.39 matt
93 1.1.2.25 cliff #include <mips/rmi/rmixlreg.h>
94 1.1.2.1 cliff #include <mips/rmi/rmixlvar.h>
95 1.1.2.25 cliff #include <mips/rmi/rmixl_intr.h>
96 1.1.2.1 cliff #include <mips/rmi/rmixl_firmware.h>
97 1.1.2.25 cliff #include <mips/rmi/rmixl_comvar.h>
98 1.1.2.26 cliff #include <mips/rmi/rmixl_pcievar.h>
99 1.1.2.28 cliff #include <mips/rmi/rmixl_pcixvar.h>
100 1.1.2.1 cliff
101 1.1.2.39 matt //#define MACHDEP_DEBUG 1
102 1.1.2.6 cliff #ifdef MACHDEP_DEBUG
103 1.1.2.6 cliff int machdep_debug=MACHDEP_DEBUG;
104 1.1.2.39 matt # define DPRINTF(x,...) do { if (machdep_debug) printf(x, ## __VA_ARGS__); } while(0)
105 1.1.2.6 cliff #else
106 1.1.2.39 matt # define DPRINTF(x,...)
107 1.1.2.39 matt #endif
108 1.1.2.39 matt
109 1.1.2.44 matt extern int comcnspeed;
110 1.1.2.1 cliff
111 1.1.2.44 matt void mach_init(int, int32_t *, void *, int64_t);
112 1.1.2.38 matt
113 1.1.2.1 cliff /*
114 1.1.2.1 cliff * Do all the stuff that locore normally does before calling main().
115 1.1.2.1 cliff */
116 1.1.2.1 cliff void
117 1.1.2.7 cliff mach_init(int argc, int32_t *argv, void *envp, int64_t infop)
118 1.1.2.1 cliff {
119 1.1.2.44 matt struct rmixl_config * const rcp = &rmixl_configuration;
120 1.1.2.44 matt vaddr_t kernend;
121 1.1.2.16 cliff uint64_t memsize;
122 1.1.2.1 cliff extern char edata[], end[];
123 1.1.2.39 matt bool uboot_p = false;
124 1.1.2.39 matt
125 1.1.2.39 matt const uint32_t cfg0 = mips3_cp0_config_read();
126 1.1.2.39 matt #if (MIPS64_XLR + MIPS64_XLS) > 0 && (MIPS64_XLP) == 0
127 1.1.2.39 matt const bool is_xlp_p = false /* make sure cfg0 is used */
128 1.1.2.39 matt && MIPSNN_GET(CFG_AR, cfg0) == MIPSNN_CFG_AR_REV2;
129 1.1.2.39 matt KASSERT(MIPSNN_GET(CFG_AR, cfg0) == MIPSNN_CFG_AR_REV1);
130 1.1.2.39 matt #elif (MIPS64_XLR + MIPS64_XLS) == 0 && (MIPS64_XLP) > 0
131 1.1.2.39 matt const bool is_xlp_p = true /* make sure cfg0 is used */
132 1.1.2.39 matt || MIPSNN_GET(CFG_AR, cfg0) == MIPSNN_CFG_AR_REV2;
133 1.1.2.39 matt KASSERT(MIPSNN_GET(CFG_AR, cfg0) == MIPSNN_CFG_AR_REV2);
134 1.1.2.39 matt #else
135 1.1.2.39 matt const bool is_xlp_p = (MIPSNN_GET(CFG_AR, cfg0) == MIPSNN_CFG_AR_REV2);
136 1.1.2.39 matt #endif
137 1.1.2.1 cliff
138 1.1.2.39 matt rmixl_pcr_init_core(is_xlp_p);
139 1.1.2.8 cliff
140 1.1.2.37 matt #ifdef MULTIPROCESSOR
141 1.1.2.37 matt __asm __volatile("dmtc0 %0,$%1,2"
142 1.1.2.37 matt :: "r"(&pmap_tlb0_info.ti_hwlock->mtx_lock),
143 1.1.2.37 matt "n"(MIPS_COP_0_OSSCRATCH));
144 1.1.2.37 matt #endif
145 1.1.2.37 matt
146 1.1.2.1 cliff /*
147 1.1.2.1 cliff * Clear the BSS segment.
148 1.1.2.1 cliff */
149 1.1.2.44 matt kernend = mips_round_page(end);
150 1.1.2.1 cliff memset(edata, 0, (char *)kernend - edata);
151 1.1.2.1 cliff
152 1.1.2.39 matt /*
153 1.1.2.44 matt * Setup a early console for output by mips_vector_init
154 1.1.2.39 matt */
155 1.1.2.44 matt rmixl_init_early_cons(rcp, is_xlp_p);
156 1.1.2.38 matt
157 1.1.2.1 cliff /*
158 1.1.2.1 cliff * Set up the exception vectors and CPU-specific function
159 1.1.2.1 cliff * vectors early on. We need the wbflush() vector set up
160 1.1.2.1 cliff * before comcnattach() is called (or at least before the
161 1.1.2.1 cliff * first printf() after that is called).
162 1.1.2.1 cliff * Also clears the I+D caches.
163 1.1.2.25 cliff *
164 1.1.2.25 cliff * specify chip-specific EIRR/EIMR based spl functions
165 1.1.2.1 cliff */
166 1.1.2.34 matt #ifdef MULTIPROCESSOR
167 1.1.2.34 matt mips_vector_init(&rmixl_splsw, true);
168 1.1.2.34 matt #else
169 1.1.2.34 matt mips_vector_init(&rmixl_splsw, false);
170 1.1.2.34 matt #endif
171 1.1.2.1 cliff
172 1.1.2.39 matt if (argc < 0) {
173 1.1.2.39 matt void *bd = (void *)(intptr_t)argc;
174 1.1.2.39 matt void *imgaddr = argv;
175 1.1.2.39 matt void *consdev = envp;
176 1.1.2.39 matt char *bootargs = (void *)(intptr_t)infop;
177 1.1.2.39 matt printf("%s: u-boot: boardinfo=%p, image-addr=%p, consdev=%p, bootargs=%p <%s>\n",
178 1.1.2.39 matt __func__, bd, imgaddr, consdev, bootargs, bootargs);
179 1.1.2.39 matt uboot_p = true;
180 1.1.2.39 matt printf("%s: u-boot: console baudrate=%d\n", __func__,
181 1.1.2.39 matt *(int *)bd);
182 1.1.2.39 matt if (*(int *)bd % 1200 == 0)
183 1.1.2.39 matt comcnspeed = *(int *)bd;
184 1.1.2.39 matt } else {
185 1.1.2.39 matt DPRINTF("%s: argc=%d, argv=%p, envp=%p, info=%#"PRIx64"\n",
186 1.1.2.39 matt __func__, argc, argv, envp, infop);
187 1.1.2.39 matt }
188 1.1.2.39 matt
189 1.1.2.15 matt /* mips_vector_init initialized mips_options */
190 1.1.2.15 matt strcpy(cpu_model, mips_options.mips_cpu->cpu_name);
191 1.1.2.14 cliff
192 1.1.2.39 matt #if (MIPS64_XLP) > 0
193 1.1.2.44 matt if (is_xlp_p) {
194 1.1.2.44 matt rmixl_mach_xlp_init(rcp);
195 1.1.2.39 matt }
196 1.1.2.44 matt #endif /* MIPS64_XLP */
197 1.1.2.39 matt
198 1.1.2.39 matt /* determine DRAM first */
199 1.1.2.39 matt memsize = rmixl_physaddr_init();
200 1.1.2.39 matt DPRINTF("%s: physaddr init done (memsize=%"PRIu64"MB)!\n",
201 1.1.2.39 matt __func__, memsize >> 20);
202 1.1.2.39 matt
203 1.1.2.39 matt if (!uboot_p) {
204 1.1.2.39 matt /* get system info from firmware */
205 1.1.2.39 matt memsize = rmixlfw_init(infop);
206 1.1.2.39 matt DPRINTF("%s: firmware init done (memsize=%"PRIu64"MB)!\n",
207 1.1.2.39 matt __func__, memsize >> 20);
208 1.1.2.39 matt } else {
209 1.1.2.39 matt rcp->rc_psb_info.userapp_cpu_map = 1;
210 1.1.2.39 matt }
211 1.1.2.1 cliff
212 1.1.2.44 matt #if 0
213 1.1.2.1 cliff /* set the VM page size */
214 1.1.2.1 cliff uvm_setpagesize();
215 1.1.2.1 cliff
216 1.1.2.1 cliff physmem = btoc(memsize);
217 1.1.2.44 matt #endif
218 1.1.2.1 cliff
219 1.1.2.39 matt #if (MIPS64_XLR + MIPS64_XLS) > 0
220 1.1.2.44 matt if (!is_xlp_p) {
221 1.1.2.44 matt rmixl_mach_xlsxlr_init(rcp);
222 1.1.2.39 matt }
223 1.1.2.44 matt #endif /* (MIPS64_XLR + MIPS64_XLS) > 0 */
224 1.1.2.1 cliff
225 1.1.2.14 cliff #if defined(MULTIPROCESSOR) && defined(MACHDEP_DEBUG)
226 1.1.2.39 matt if (!uboot_p) {
227 1.1.2.39 matt rmixl_wakeup_info_print(rcp->rc_cpu_wakeup_info);
228 1.1.2.39 matt rmixl_wakeup_info_print(rcp->rc_cpu_wakeup_info + 1);
229 1.1.2.39 matt printf("cpu_wakeup_info %p, cpu_wakeup_end %p\n",
230 1.1.2.39 matt rcp->rc_cpu_wakeup_info,
231 1.1.2.39 matt rcp->rc_cpu_wakeup_end);
232 1.1.2.39 matt printf("userapp_cpu_map: %#"PRIx64"\n",
233 1.1.2.39 matt rcp->rc_psb_info.userapp_cpu_map);
234 1.1.2.39 matt printf("wakeup: %#"PRIx64"\n", rcp->rc_psb_info.wakeup);
235 1.1.2.39 matt }
236 1.1.2.14 cliff #endif
237 1.1.2.14 cliff
238 1.1.2.1 cliff /*
239 1.1.2.1 cliff * Obtain the cpu frequency
240 1.1.2.1 cliff */
241 1.1.2.44 matt rmixl_mach_freq_init(rcp, uboot_p, is_xlp_p);
242 1.1.2.1 cliff
243 1.1.2.1 cliff /*
244 1.1.2.1 cliff * Look at arguments passed to us and compute boothowto.
245 1.1.2.1 cliff * - rmixl firmware gives us a 32 bit argv[i], so adapt
246 1.1.2.1 cliff * by forcing sign extension in cast to (char *)
247 1.1.2.1 cliff */
248 1.1.2.1 cliff boothowto = RB_AUTOBOOT;
249 1.1.2.39 matt // boothowto |= AB_VERBOSE;
250 1.1.2.42 matt // boothowto |= AB_DEBUG;
251 1.1.2.39 matt if (!uboot_p) {
252 1.1.2.44 matt rmixl_mach_init_parse_args(argc, (void *)(intptr_t)argv);
253 1.1.2.1 cliff }
254 1.1.2.6 cliff #ifdef DIAGNOSTIC
255 1.1.2.1 cliff printf("boothowto %#x\n", boothowto);
256 1.1.2.6 cliff #endif
257 1.1.2.1 cliff
258 1.1.2.1 cliff /*
259 1.1.2.44 matt * Now do the common rmixl dependent initialization.
260 1.1.2.6 cliff */
261 1.1.2.44 matt rmixl_mach_init_common(rcp, kernend, memsize, uboot_p, is_xlp_p);
262 1.1.2.1 cliff }
263