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