xref: /netbsd-src/sys/arch/evbsh3/evbsh3/machdep.c (revision 6e3d02bbcd6ad76dfee4cfb9687a4fd87c0e86d6)
1 /*	$NetBSD: machdep.c,v 1.77 2024/02/05 22:08:05 andvar Exp $	*/
2 
3 /*-
4  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
9  * Simulation Facility, NASA Ames Research Center.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*-
34  * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
35  * All rights reserved.
36  *
37  * This code is derived from software contributed to Berkeley by
38  * William Jolitz.
39  *
40  * Redistribution and use in source and binary forms, with or without
41  * modification, are permitted provided that the following conditions
42  * are met:
43  * 1. Redistributions of source code must retain the above copyright
44  *    notice, this list of conditions and the following disclaimer.
45  * 2. Redistributions in binary form must reproduce the above copyright
46  *    notice, this list of conditions and the following disclaimer in the
47  *    documentation and/or other materials provided with the distribution.
48  * 3. Neither the name of the University nor the names of its contributors
49  *    may be used to endorse or promote products derived from this software
50  *    without specific prior written permission.
51  *
52  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62  * SUCH DAMAGE.
63  *
64  *	@(#)machdep.c	7.4 (Berkeley) 6/3/91
65  */
66 
67 #include <sys/cdefs.h>
68 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.77 2024/02/05 22:08:05 andvar Exp $");
69 
70 #include "opt_ddb.h"
71 #include "opt_kgdb.h"
72 #include "opt_memsize.h"
73 #include "opt_initbsc.h"
74 #include "opt_kloader.h"
75 #include "opt_kloader_kernel_path.h"
76 
77 #include <sys/param.h>
78 #include <sys/systm.h>
79 #include <sys/kernel.h>
80 #include <sys/mount.h>
81 #include <sys/reboot.h>
82 #include <sys/sysctl.h>
83 #include <sys/ksyms.h>
84 #include <sys/device.h>
85 #include <sys/bus.h>
86 
87 #include <uvm/uvm_extern.h>
88 
89 #include <dev/cons.h>
90 
91 #include <sh3/bscreg.h>
92 #include <sh3/cpgreg.h>
93 #include <sh3/cache_sh3.h>
94 #include <sh3/cache_sh4.h>
95 #include <sh3/exception.h>
96 
97 #include <machine/intr.h>
98 #include <machine/pcb.h>
99 
100 #ifdef DDB
101 #include <machine/db_machdep.h>
102 #include <ddb/db_extern.h>
103 #endif
104 
105 #ifdef KLOADER
106 #include <machine/kloader.h>
107 #endif
108 
109 #include "ksyms.h"
110 
111 /* the following is used externally (sysctl_hw) */
112 char machine[] = MACHINE;		/* evbsh3 */
113 char machine_arch[] = MACHINE_ARCH;	/* sh3eb or sh3el */
114 
115 #ifdef KLOADER
116 struct kloader_bootinfo kbootinfo;
117 #endif
118 
119 void initSH3(void *);
120 void LoadAndReset(const char *);
121 void XLoadAndReset(char *);
122 
123 /*
124  * Machine-dependent startup code
125  *
126  * This is called from main() in kern/main.c.
127  */
128 void
cpu_startup(void)129 cpu_startup(void)
130 {
131 
132 	sh_startup();
133 }
134 
135 /*
136  * machine dependent system variables.
137  */
138 static int
sysctl_machdep_loadandreset(SYSCTLFN_ARGS)139 sysctl_machdep_loadandreset(SYSCTLFN_ARGS)
140 {
141 	const char *osimage;
142 	int error;
143 
144 	error = sysctl_lookup(SYSCTLFN_CALL(__UNCONST(rnode)));
145 	if (error || newp == NULL)
146 		return (error);
147 
148 	osimage = (const char *)(*(const u_long *)newp);
149 	LoadAndReset(osimage);
150 	/* not reach here */
151 	return (0);
152 }
153 
154 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
155 {
156 
157 	sysctl_createv(clog, 0, NULL, NULL,
158 		       CTLFLAG_PERMANENT,
159 		       CTLTYPE_NODE, "machdep", NULL,
160 		       NULL, 0, NULL, 0,
161 		       CTL_MACHDEP, CTL_EOL);
162 
163 	sysctl_createv(clog, 0, NULL, NULL,
164 		       CTLFLAG_PERMANENT,
165 		       CTLTYPE_STRUCT, "console_device", NULL,
166 		       sysctl_consdev, 0, NULL, sizeof(dev_t),
167 		       CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
168 /*
169 <atatat> okay...your turn to play.
170 <atatat> pick a number.
171 <kjk> 98752.
172 */
173 	sysctl_createv(clog, 0, NULL, NULL,
174 		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
175 		       CTLTYPE_INT, "load_and_reset", NULL,
176 		       sysctl_machdep_loadandreset, 98752, NULL, 0,
177 		       CTL_MACHDEP, CPU_LOADANDRESET, CTL_EOL);
178 }
179 
180 void
cpu_reboot(int howto,char * bootstr)181 cpu_reboot(int howto, char *bootstr)
182 {
183 	static int waittime = -1;
184 
185 	if (cold) {
186 		howto |= RB_HALT;
187 		goto haltsys;
188 	}
189 
190 #ifdef KLOADER
191 	if ((howto & RB_HALT) == 0) {
192 		if ((howto & RB_STRING) && (bootstr != NULL)) {
193 			kloader_reboot_setup(bootstr);
194 		}
195 #ifdef KLOADER_KERNEL_PATH
196 		else {
197 			kloader_reboot_setup(KLOADER_KERNEL_PATH);
198 		}
199 #endif
200 	}
201 #endif
202 
203 	boothowto = howto;
204 	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
205 		waittime = 0;
206 		vfs_shutdown();
207 		/*
208 		 * If we've been adjusting the clock, the todr
209 		 * will be out of synch; adjust it now.
210 		 */
211 		/* resettodr(); */
212 	}
213 
214 	/* Disable interrupts. */
215 	splhigh();
216 
217 	/* Do a dump if requested. */
218 	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
219 		dumpsys();
220 
221 haltsys:
222 	doshutdownhooks();
223 
224 	pmf_system_shutdown(boothowto);
225 
226 	if (howto & RB_HALT) {
227 		printf("\n");
228 		printf("The operating system has halted.\n");
229 		printf("Please press any key to reboot.\n\n");
230 		cngetc();
231 	}
232 #ifdef KLOADER
233 	else {
234 		delay(1 * 1000 * 1000);
235 		kloader_reboot();
236 		printf("\n");
237 		printf("Failed to load a new kernel.\n");
238 		printf("Please press any key to reboot.\n\n");
239 		cngetc();
240 	}
241 #endif
242 
243 	printf("rebooting...\n");
244 	cpu_reset();
245 	for(;;)
246 		continue;
247 	/*NOTREACHED*/
248 }
249 
250 void
initSH3(void * pc)251 initSH3(void *pc)	/* XXX return address */
252 {
253 	extern char edata[], end[];
254 	vaddr_t kernend;
255 
256 	/* Clear bss */
257 	memset(edata, 0, end - edata);
258 
259 	/* Initilize CPU ops. */
260 #if defined(SH3) && defined(SH4)
261 #error "don't define both SH3 and SH4"
262 #elif defined(SH3)
263 #if defined(SH7708)
264 	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708);
265 #elif defined(SH7708S)
266 	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708S);
267 #elif defined(SH7708R)
268 	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708R);
269 #elif defined(SH7709)
270 	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7709);
271 #elif defined(SH7709A)
272 	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7709A);
273 #elif defined(SH7706)
274 	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7706);
275 #else
276 #error "unsupported SH3 variants"
277 #endif
278 #elif defined(SH4)
279 #if defined(SH7750)
280 	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7750);
281 #elif defined(SH7750S)
282 	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7750S);
283 #elif defined(SH7750R)
284 	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7750R);
285 #elif defined(SH7751)
286 	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7751);
287 #elif defined(SH7751R)
288 	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7751R);
289 #elif defined(STX7105)
290 	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_STX7105);
291 #else
292 #error "unsupported SH4 variants"
293 #endif
294 #else
295 #error "define SH3 or SH4"
296 #endif
297 	/* Console */
298 	consinit();
299 
300 #ifdef KLOADER
301 	/* copy boot parameter for kloader */
302 	kloader_bootinfo_set(&kbootinfo, 0, NULL, NULL, true);
303 #endif
304 
305 	/* Load memory to UVM */
306 	kernend = atop(round_page(SH3_P1SEG_TO_PHYS(end)));
307 	physmem = atop(IOM_RAM_SIZE);
308 	uvm_page_physload(
309 		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
310 		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
311 		VM_FREELIST_DEFAULT);
312 
313 	/* Initialize proc0 u-area */
314 	sh_proc0_init();
315 
316 	/* Initialize pmap and start to address translation */
317 	pmap_bootstrap();
318 
319 	/*
320 	 * XXX We can't return here, because we change stack pointer.
321 	 *     So jump to return address directly.
322 	 */
323 	__asm volatile (
324 		"jmp	@%0;"
325 		"mov	%1, r15"
326 		:: "r"(pc),"r"(lwp0.l_md.md_pcb->pcb_sf.sf_r7_bank));
327 }
328 
329 /*
330  * consinit:
331  * initialize the system console.
332  * XXX - shouldn't deal with this initted thing, but then,
333  * it shouldn't be called from init386 either.
334  */
335 void
consinit(void)336 consinit(void)
337 {
338 	static int initted;
339 
340 	if (initted)
341 		return;
342 	initted = 1;
343 
344 	cninit();
345 }
346 
347 #if !defined(DONT_INIT_BSC)
348 /*
349  * InitializeBsc
350  * : BSC(Bus State Controller)
351  */
352 void InitializeBsc(void);
353 
354 void
InitializeBsc(void)355 InitializeBsc(void)
356 {
357 
358 	/*
359 	 * Drive RAS,CAS in stand by mode and bus release mode
360 	 * Area0 = Normal memory, Area5,6=Normal(no burst)
361 	 * Area2 = Normal memory, Area3 = SDRAM, Area5 = Normal memory
362 	 * Area4 = Normal Memory
363 	 * Area6 = Normal memory
364 	 */
365 #if defined(SH3)
366 	_reg_write_2(SH3_BCR1, BSC_BCR1_VAL);
367 #elif defined(SH4)
368 	_reg_write_4(SH4_BCR1, BSC_BCR1_VAL);
369 #endif
370 
371 	/*
372 	 * Bus Width
373 	 * Area4: Bus width = 16bit
374 	 * Area6,5 = 16bit
375 	 * Area1 = 8bit
376 	 * Area2,3: Bus width = 32bit
377 	 */
378 	_reg_write_2(SH_(BCR2), BSC_BCR2_VAL);
379 
380 	/*
381 	 * Idle cycle number in transition area and read to write
382 	 * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3
383 	 * Area1 = 3, Area0 = 3
384 	 */
385 #if defined(SH3)
386 	_reg_write_2(SH3_WCR1, BSC_WCR1_VAL);
387 #elif defined(SH4)
388 	_reg_write_4(SH4_WCR1, BSC_WCR1_VAL);
389 #endif
390 
391 	/*
392 	 * Wait cycle
393 	 * Area 6 = 6
394 	 * Area 5 = 2
395 	 * Area 4 = 10
396 	 * Area 3 = 3
397 	 * Area 2,1 = 3
398 	 * Area 0 = 6
399 	 */
400 #if defined(SH3)
401 	_reg_write_2(SH3_WCR2, BSC_WCR2_VAL);
402 #elif defined(SH4)
403 	_reg_write_4(SH4_WCR2, BSC_WCR2_VAL);
404 #endif
405 
406 #if defined(SH4) && defined(BSC_WCR3_VAL)
407 	_reg_write_4(SH4_WCR3, BSC_WCR3_VAL);
408 #endif
409 
410 	/*
411 	 * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle,
412 	 * write pre-charge=1cycle
413 	 * CAS before RAS refresh RAS assert time = 3 cycle
414 	 * Disable burst, Bus size=32bit, Column Address=10bit, Refresh ON
415 	 * CAS before RAS refresh ON, EDO DRAM
416 	 */
417 #if defined(SH3)
418 	_reg_write_2(SH3_MCR, BSC_MCR_VAL);
419 #elif defined(SH4)
420 	_reg_write_4(SH4_MCR, BSC_MCR_VAL);
421 #endif
422 
423 #if defined(BSC_SDMR2_VAL)
424 	_reg_write_1(BSC_SDMR2_VAL, 0);
425 #endif
426 
427 #if defined(BSC_SDMR3_VAL)
428 #if !(defined(COMPUTEXEVB) && defined(SH7709A))
429 	_reg_write_1(BSC_SDMR3_VAL, 0);
430 #else
431 	_reg_write_2(0x1a000000, 0);	/* ADDSET */
432 	_reg_write_1(BSC_SDMR3_VAL, 0);
433 	_reg_write_2(0x18000000, 0);	/* ADDRST */
434 #endif /* !(COMPUTEXEVB && SH7709A) */
435 #endif /* BSC_SDMR3_VAL */
436 
437 	/*
438 	 * PCMCIA Control Register
439 	 * OE/WE assert delay 3.5 cycle
440 	 * OE/WE negate-address delay 3.5 cycle
441 	 */
442 #ifdef BSC_PCR_VAL
443 	_reg_write_2(SH_(PCR), BSC_PCR_VAL);
444 #endif
445 
446 	/*
447 	 * Refresh Timer Control/Status Register
448 	 * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt
449 	 * Count Limit = 1024
450 	 * In following statement, the reason why high byte = 0xa5(a4 in RFCR)
451 	 * is the rule of SH3 in writing these register.
452 	 */
453 	_reg_write_2(SH_(RTCSR), BSC_RTCSR_VAL);
454 
455 	/*
456 	 * Refresh Timer Counter
457 	 * Initialize to 0
458 	 */
459 #ifdef BSC_RTCNT_VAL
460 	_reg_write_2(SH_(RTCNT), BSC_RTCNT_VAL);
461 #endif
462 
463 	/* set Refresh Time Constant Register */
464 	_reg_write_2(SH_(RTCOR), BSC_RTCOR_VAL);
465 
466 	/* init Refresh Count Register */
467 #ifdef BSC_RFCR_VAL
468 	_reg_write_2(SH_(RFCR), BSC_RFCR_VAL);
469 #endif
470 
471 	/*
472 	 * Clock Pulse Generator
473 	 */
474 	/* Set Clock mode (make internal clock double speed) */
475 	_reg_write_2(SH_(FRQCR), FRQCR_VAL);
476 
477 	/*
478 	 * Cache
479 	 */
480 #ifndef CACHE_DISABLE
481 	/* Cache ON */
482 	_reg_write_4(SH_(CCR), 0x1);
483 #endif
484 }
485 #endif /* !DONT_INIT_BSC */
486 
487 
488  /* XXX This value depends on physical available memory */
489 #define OSIMAGE_BUF_ADDR	(IOM_RAM_BEGIN + 0x00400000)
490 
491 void
LoadAndReset(const char * osimage)492 LoadAndReset(const char *osimage)
493 {
494 	void *buf_addr;
495 	u_long size;
496 	const u_long *src;
497 	u_long *dest;
498 	u_long csum = 0;
499 	u_long csum2 = 0;
500 	u_long size2;
501 
502 	printf("LoadAndReset: copy start\n");
503 	buf_addr = (void *)OSIMAGE_BUF_ADDR;
504 
505 	size = *(const u_long *)osimage;
506 	src = (const u_long *)osimage;
507 	dest = buf_addr;
508 
509 	size = (size + sizeof(u_long) * 2 + 3) >> 2;
510 	size2 = size;
511 
512 	while (size--) {
513 		csum += *src;
514 		*dest++ = *src++;
515 	}
516 
517 	dest = buf_addr;
518 	while (size2--)
519 		csum2 += *dest++;
520 
521 	printf("LoadAndReset: copy end[%lx,%lx]\n", csum, csum2);
522 	printf("start XLoadAndReset\n");
523 
524 	/* mask all externel interrupt (XXX) */
525 
526 	XLoadAndReset(buf_addr);
527 }
528 
529 void
intc_intr(int ssr,int spc,int ssp)530 intc_intr(int ssr, int spc, int ssp)
531 {
532 	struct intc_intrhand *ih;
533 	struct clockframe cf;
534 	int evtcode;
535 
536 	curcpu()->ci_data.cpu_nintr++;
537 
538 	switch (cpu_product) {
539 	case CPU_PRODUCT_7708:
540 	case CPU_PRODUCT_7708S:
541 	case CPU_PRODUCT_7708R:
542 		evtcode = _reg_read_4(SH3_INTEVT);
543 		break;
544 	case CPU_PRODUCT_7709:
545 	case CPU_PRODUCT_7709A:
546 	case CPU_PRODUCT_7706:
547 		evtcode = _reg_read_4(SH7709_INTEVT2);
548 		break;
549 	case CPU_PRODUCT_7750:
550 	case CPU_PRODUCT_7750S:
551 	case CPU_PRODUCT_7750R:
552 	case CPU_PRODUCT_7751:
553 	case CPU_PRODUCT_7751R:
554 		evtcode = _reg_read_4(SH4_INTEVT);
555 		break;
556 	default:
557 #ifdef DIAGNOSTIC
558 		panic("intr_intc: cpu_product %d unhandled!", cpu_product);
559 #endif
560 		return;
561 	}
562 
563 	ih = EVTCODE_IH(evtcode);
564 	KDASSERT(ih->ih_func);
565 	/*
566 	 * On entry, all interrupts are disabled,
567 	 * and exception is enabled for P3 access. (kernel stack is P3,
568 	 * SH3 may or may not cause TLB miss when access stack.)
569 	 * Enable higher level interrupt here.
570 	 */
571 	_cpu_intr_resume(ih->ih_level);
572 
573 	switch (evtcode) {
574 	default:
575 		(*ih->ih_func)(ih->ih_arg);
576 		break;
577 	case SH_INTEVT_TMU0_TUNI0:
578 		cf.spc = spc;
579 		cf.ssr = ssr;
580 		cf.ssp = ssp;
581 		(*ih->ih_func)(&cf);
582 		break;
583 	case SH_INTEVT_NMI:
584 		printf("NMI ignored.\n");
585 		break;
586 	}
587 }
588