xref: /netbsd-src/sys/arch/evbmips/rasoc/machdep.c (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
1 /*	$NetBSD: machdep.c,v 1.5 2011/08/16 06:59:19 matt Exp $	*/
2 /*-
3  * Copyright (c) 2011 CradlePoint Technology, Inc.
4  * All rights reserved.
5  *
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 CRADLEPOINT TECHNOLOGY, INC. AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
30 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.5 2011/08/16 06:59:19 matt Exp $");
31 
32 #include <sys/param.h>
33 #include <sys/boot_flag.h>
34 #include <sys/buf.h>
35 #include <sys/device.h>
36 #include <sys/mount.h>
37 #include <sys/kcore.h>
38 #include <sys/reboot.h>
39 #include <sys/systm.h>
40 #include <sys/kernel.h>
41 #include <sys/termios.h>
42 
43 #include <uvm/uvm_extern.h>
44 
45 #include <dev/cons.h>
46 
47 #include <mips/cache.h>
48 #include <mips/locore.h>
49 #include <mips/cpuregs.h>
50 
51 #include <mips/ralink/ralink_reg.h>
52 #include <mips/ralink/ralink_var.h>
53 
54 /* structures we define/alloc for other files in the kernel */
55 struct vm_map *mb_map = NULL;
56 struct vm_map *phys_map = NULL;
57 struct cpu_info cpu_info_store;
58 int physmem;		/* # pages of physical memory */
59 int mem_cluster_cnt = 0;
60 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX];
61 
62 /* structures others define for us */
63 extern struct user *proc0paddr;
64 
65 void mach_init(void);
66 
67 static inline uint32_t
68 sysctl_read(u_int offset)
69 {
70 	return *RA_IOREG_VADDR(RA_SYSCTL_BASE, offset);
71 }
72 
73 static inline void
74 sysctl_write(u_int offset, uint32_t val)
75 {
76 	*RA_IOREG_VADDR(RA_SYSCTL_BASE, offset) = val;
77 }
78 
79 static void
80 cal_timer(void)
81 {
82 	uint32_t cntfreq;
83 
84 	cntfreq = curcpu()->ci_cpu_freq = RA_CLOCK_RATE;
85 
86 	/* MIPS 4Kc CP0 counts every other clock */
87 	if (mips_options.mips_cpu_flags & CPU_MIPS_DOUBLE_COUNT)
88 		cntfreq /= 2;
89 
90 	curcpu()->ci_cycles_per_hz = (cntfreq + hz / 2) / hz;
91 
92 	/* Compute number of cycles per 1us (1/MHz). 0.5MHz is for roundup. */
93 	curcpu()->ci_divisor_delay = ((cntfreq + 500000) / 1000000);
94 }
95 
96 void
97 mach_init(void)
98 {
99 	vaddr_t kernend;
100 	psize_t memsize;
101 
102 	extern char kernel_text[];
103 	extern char edata[], end[];	/* From Linker */
104 
105 	/* clear the BSS segment */
106 	kernend = mips_round_page(end);
107 
108 	memset(edata, 0, kernend - (vaddr_t)edata);
109 
110 #ifdef RA_CONSOLE_EARLY
111 	/*
112 	 * set up early console
113 	 *  cannot printf until sometime (?) in mips_vector_init
114 	 *  meanwhile can use the ra_console_putc primitive if necessary
115 	 */
116 	ra_console_early();
117 #endif
118 
119 	/* set CPU model info for sysctl_hw */
120 	uint32_t tmp;
121 	tmp = sysctl_read(RA_SYSCTL_ID0);
122 	memcpy(&cpu_model[0], &tmp, 4);
123 	tmp = sysctl_read(RA_SYSCTL_ID1);
124 	memcpy(&cpu_model[4], &tmp, 4);
125 	cpu_model[9] = 0;
126 
127 	/*
128 	 * Set up the exception vectors and CPU-specific function
129 	 * vectors early on.  We need the wbflush() vector set up
130 	 * before comcnattach() is called (or at least before the
131 	 * first printf() after that is called).
132 	 * Sets up mips_cpu_flags that may be queried by other
133 	 * functions called during startup.
134 	 * Also clears the I+D caches.
135 	 */
136 	mips_vector_init(NULL, false);
137 
138 	/*
139 	 * Calibrate timers.
140 	 */
141 	cal_timer();
142 
143 	/*
144 	 * Set the VM page size.
145 	 */
146 	uvm_setpagesize();
147 
148 	/*
149 	 * Look at arguments passed to us and compute boothowto.
150 	 */
151 	boothowto = RB_AUTOBOOT;
152 #ifdef KADB
153 	boothowto |= RB_KDB;
154 #endif
155 
156 	/*
157 	 * Determine the memory size.
158 	 */
159 	memsize = *(volatile uint32_t *)
160 	    MIPS_PHYS_TO_KSEG1(RA_SYSCTL_BASE + RA_SYSCTL_CFG0);
161 	memsize = __SHIFTOUT(memsize, SYSCTL_CFG0_DRAM_SIZE);
162 	if (__predict_false(memsize == 0)) {
163 		memsize = 2 << 20;
164 	} else {
165 		memsize = 4 << (20 + memsize);
166 	}
167 
168 	physmem = btoc(memsize);
169 
170 	mem_clusters[mem_cluster_cnt].start = 0;
171 	mem_clusters[mem_cluster_cnt].size = memsize;
172 	mem_cluster_cnt++;
173 
174 	/*
175 	 * Load the memory into the VM system
176 	 */
177 	mips_page_physload((vaddr_t)kernel_text, kernend,
178 	    mem_clusters, mem_cluster_cnt,
179 	    NULL, 0);
180 
181 	/*
182 	 * Initialize message buffer (at end of core).
183 	 */
184 	mips_init_msgbuf();
185 
186 	/*
187 	 * Initialize the virtual memory system.
188 	 */
189 	pmap_bootstrap();
190 
191 	/*
192 	 * Init mapping for u page(s) for proc0.
193 	 */
194 	mips_init_lwp0_uarea();
195 
196 	/*
197 	 * Initialize busses.
198 	 */
199 	ra_bus_init();
200 
201 #ifdef DDB
202 	if (boothowto & RB_KDB)
203 		Debugger();
204 #endif
205 }
206 
207 void
208 cpu_startup(void)
209 {
210 #ifdef DEBUG
211 	extern int pmapdebug;
212 	const int opmapdebug = pmapdebug;
213 	pmapdebug = 0;		/* Shut up pmap debug during bootstrap */
214 #endif
215 
216 	cpu_startup_common();
217 
218 #ifdef DEBUG
219 	pmapdebug = opmapdebug;
220 #endif
221 }
222 
223 void
224 cpu_reboot(int howto, char *bootstr)
225 {
226 	static int waittime = -1;
227 
228 	/* Take a snapshot before clobbering any registers. */
229 	savectx(lwp_getpcb(curlwp));
230 
231 	/* If "always halt" was specified as a boot flag, obey. */
232 	if (boothowto & RB_HALT)
233 		howto |= RB_HALT;
234 
235 	boothowto = howto;
236 
237 	/* If system is cold, just halt. */
238 	if (cold) {
239 		boothowto |= RB_HALT;
240 		goto haltsys;
241 	}
242 
243 	if ((boothowto & RB_NOSYNC) == 0 && waittime < 0) {
244 		waittime = 0;
245 
246 		/*
247 		 * Synchronize the disks....
248 		 */
249 		vfs_shutdown();
250 
251 		/*
252 		 * If we've been adjusting the clock, the todr
253 		 * will be out of synch; adjust it now.
254 		 */
255 		resettodr();
256 	}
257 
258 	/* Disable interrupts. */
259 	splhigh();
260 
261 	if (boothowto & RB_DUMP)
262 		dumpsys();
263 
264  haltsys:
265 	/* Run any shutdown hooks. */
266 	doshutdownhooks();
267 
268 	pmf_system_shutdown(boothowto);
269 
270 	/*
271 	 * Firmware may autoboot (depending on settings), and we cannot pass
272 	 * flags to it (at least I haven't figured out how to yet), so
273 	 * we "pseudo-halt" now.
274 	 */
275 	if (boothowto & RB_HALT) {
276 		printf("\n");
277 		printf("The operating system has halted.\n");
278 		printf("Please press any key to reboot.\n\n");
279 		cnpollc(1);	/* For proper keyboard command handling */
280 		cngetc();
281 		cnpollc(0);
282 	}
283 
284 	printf("reseting board...\n\n");
285 	mips_icache_sync_all();
286 	mips_dcache_wbinv_all();
287 
288 	sysctl_write(RA_SYSCTL_RST, 1);  /* SoC Reset */
289 	sysctl_write(RA_SYSCTL_RST, 0);
290 
291 #if 0
292 	__asm volatile("jr	%0" :: "r"(MIPS_RESET_EXC_VEC));
293 #endif
294 	printf("Oops, back from reset\n\nSpinning...");
295 	for (;;)
296 		/* spin forever */ ;	/* XXX */
297 	/*NOTREACHED*/
298 }
299 
300 #define NO_SECURITY_MAGIC	0x27051958
301 #define SERIAL_MAGIC		0x100000
302 int
303 ra_check_memo_reg(int key)
304 {
305 	uint32_t magic;
306 
307 	/*
308 	 * These registers may be overwritten.  Keep the value around in case
309 	 * it is used later.  Bitmask 1 == security, 2 = serial
310 	 */
311 	static int keyvalue;
312 
313 	switch (key) {
314 	case NO_SECURITY:
315 		magic = sysctl_read(RA_SYSCTL_MEMO0);
316 		if ((NO_SECURITY_MAGIC == magic) || ((keyvalue & 1) != 0)) {
317 			keyvalue |= 1;
318 			return 1;
319 		}
320 		return 0;
321 		break;
322 
323 	case SERIAL_CONSOLE:
324 		magic = sysctl_read(RA_SYSCTL_MEMO1);
325 		if (((SERIAL_MAGIC & magic) != 0) || ((keyvalue & 2) != 0)) {
326 			keyvalue |= 2;
327 			return 1;
328 		}
329 		return 0;
330 		break;
331 
332 	default:
333 		return 0;
334 	}
335 
336 }
337