xref: /openbsd-src/sys/arch/landisk/landisk/machdep.c (revision 01802d2cc63d886227ab3b39e923ff13cf516166)
1 /*	$OpenBSD: machdep.c,v 1.48 2020/05/31 06:23:57 dlg Exp $	*/
2 /*	$NetBSD: machdep.c,v 1.1 2006/09/01 21:26:18 uwe Exp $	*/
3 
4 /*-
5  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
10  * Simulation Facility, NASA Ames Research Center.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*-
35  * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
36  * All rights reserved.
37  *
38  * This code is derived from software contributed to Berkeley by
39  * William Jolitz.
40  *
41  * Redistribution and use in source and binary forms, with or without
42  * modification, are permitted provided that the following conditions
43  * are met:
44  * 1. Redistributions of source code must retain the above copyright
45  *    notice, this list of conditions and the following disclaimer.
46  * 2. Redistributions in binary form must reproduce the above copyright
47  *    notice, this list of conditions and the following disclaimer in the
48  *    documentation and/or other materials provided with the distribution.
49  * 3. Neither the name of the University nor the names of its contributors
50  *    may be used to endorse or promote products derived from this software
51  *    without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63  * SUCH DAMAGE.
64  *
65  *	@(#)machdep.c	7.4 (Berkeley) 6/3/91
66  */
67 
68 #include "ksyms.h"
69 
70 #include <sys/param.h>
71 #include <sys/systm.h>
72 #include <sys/kernel.h>
73 #include <sys/proc.h>
74 #include <sys/mount.h>
75 #include <sys/reboot.h>
76 #include <sys/sysctl.h>
77 #include <sys/exec.h>
78 #include <sys/core.h>
79 #include <sys/kcore.h>
80 
81 #include <net/if.h>
82 
83 #include <uvm/uvm_extern.h>
84 
85 #include <dev/cons.h>
86 
87 #include <sh/bscreg.h>
88 #include <sh/cpgreg.h>
89 #include <sh/trap.h>
90 
91 #include <sh/cache.h>
92 #include <sh/cache_sh4.h>
93 #include <sh/mmu_sh4.h>
94 
95 #include <machine/cpu.h>
96 #include <machine/kcore.h>
97 #include <machine/pcb.h>
98 
99 #include <landisk/landisk/landiskreg.h>
100 
101 #ifdef DDB
102 #include <machine/db_machdep.h>
103 #include <ddb/db_extern.h>
104 #include <ddb/db_interface.h>
105 #endif
106 
107 /* the following is used externally (sysctl_hw) */
108 char machine[] = MACHINE;		/* landisk */
109 
110 __dead void landisk_startup(int, char *);
111 __dead void main(void);
112 void	cpu_init_kcore_hdr(void);
113 void	blink_led(void *);
114 
115 int	led_blink;
116 
117 extern u_int32_t getramsize(void);
118 
119 struct uvm_constraint_range  dma_constraint = { 0x0, (paddr_t)-1 };
120 struct uvm_constraint_range *uvm_md_constraints[] = { NULL };
121 
122 /*
123  * safepri is a safe priority for sleep to set for a spin-wait
124  * during autoconfiguration or after a panic.
125  */
126 int   safepri = 0;
127 
128 void
cpu_startup(void)129 cpu_startup(void)
130 {
131 	extern char cpu_model[120];
132 
133 	strlcpy(cpu_model, "SH4 SH7751R", sizeof cpu_model);
134 
135         sh_startup();
136 }
137 
138 vaddr_t kernend;	/* used by /dev/mem too */
139 char *esym;
140 
141 __dead void
landisk_startup(int howto,char * _esym)142 landisk_startup(int howto, char *_esym)
143 {
144 	u_int32_t ramsize;
145 
146 	/* Start to determine heap area */
147 	esym = _esym;
148 	kernend = (vaddr_t)round_page((vaddr_t)esym);
149 
150 	boothowto = howto;
151 
152 	ramsize = getramsize();
153 
154 	/* Initialize CPU ops. */
155 	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7751R);
156 
157 	/* Initialize early console */
158 	consinit();
159 
160 	/* Load memory to UVM */
161 	if (ramsize == 0 || ramsize > 512 * 1024 * 1024)
162 		ramsize = IOM_RAM_SIZE;
163 	physmem = atop(ramsize);
164 	kernend = atop(round_page(SH3_P1SEG_TO_PHYS(kernend)));
165 	uvm_page_physload(atop(IOM_RAM_BEGIN),
166 	    atop(IOM_RAM_BEGIN + ramsize), kernend,
167 	    atop(IOM_RAM_BEGIN + ramsize), 0);
168 	cpu_init_kcore_hdr();	/* need to be done before pmap_bootstrap */
169 
170 	/* Initialize proc0 u-area */
171 	sh_proc0_init();
172 
173 	/* Initialize pmap and start to address translation */
174 	pmap_bootstrap();
175 
176 #if defined(DDB)
177 	db_machine_init();
178 	ddb_init();
179 	if (boothowto & RB_KDB) {
180 		db_enter();
181 	}
182 #endif
183 
184 	/* Jump to main */
185 	__asm volatile(
186 		"jmp	@%0\n\t"
187 		" mov	%1, sp"
188 		:: "r" (main), "r" (proc0.p_md.md_pcb->pcb_sf.sf_r7_bank));
189 	for (;;)
190 		continue;
191 	/* NOTREACHED */
192 }
193 
194 __dead void
boot(int howto)195 boot(int howto)
196 {
197 	if ((howto & RB_RESET) != 0)
198 		goto doreset;
199 
200 	if (cold) {
201 		if ((howto & RB_USERREQ) == 0)
202 			howto |= RB_HALT;
203 		goto haltsys;
204 	}
205 
206 	boothowto = howto;
207 	if ((howto & RB_NOSYNC) == 0) {
208 		vfs_shutdown(curproc);
209 
210 		if ((howto & RB_TIMEBAD) == 0) {
211 			resettodr();
212 		} else {
213 			printf("WARNING: not updating battery clock\n");
214 		}
215 	}
216 	if_downall();
217 
218 	uvm_shutdown();
219 	splhigh();
220 	cold = 1;
221 
222 	if ((howto & RB_DUMP) != 0)
223 		dumpsys();
224 
225 haltsys:
226 	config_suspend_all(DVACT_POWERDOWN);
227 
228 	if ((howto & RB_POWERDOWN) != 0) {
229 		_reg_write_1(LANDISK_PWRMNG, PWRMNG_POWEROFF);
230 		delay(1 * 1000 * 1000);
231 		printf("POWEROFF FAILED!\n");
232 		howto |= RB_HALT;
233 	}
234 
235 	if ((howto & RB_HALT) != 0) {
236 		printf("\n");
237 		printf("The operating system has halted.\n");
238 		printf("Please press any key to reboot.\n\n");
239 		cnpollc(1);
240 		cngetc();
241 		cnpollc(0);
242 	}
243 
244 doreset:
245 	printf("rebooting...\n");
246 	machine_reset();
247 
248 	for (;;)
249 		continue;
250 	/* NOTREACHED */
251 }
252 
253 void
machine_reset(void)254 machine_reset(void)
255 {
256 	_cpu_exception_suspend();
257 	_reg_write_4(SH_(EXPEVT), EXPEVT_RESET_MANUAL);
258 	(void)*(volatile uint32_t *)0x80000001;	/* CPU shutdown */
259 
260 	/*NOTREACHED*/
261 	for (;;) {
262 		continue;
263 	}
264 }
265 
266 #if !defined(DONT_INIT_BSC)
267 /*
268  * InitializeBsc
269  * : BSC(Bus State Controller)
270  */
271 void InitializeBsc(void);
272 
273 void
InitializeBsc(void)274 InitializeBsc(void)
275 {
276 
277 	/*
278 	 * Drive RAS,CAS in stand by mode and bus release mode
279 	 * Area0 = Normal memory, Area5,6=Normal(no burst)
280 	 * Area2 = Normal memory, Area3 = SDRAM, Area5 = Normal memory
281 	 * Area4 = Normal Memory
282 	 * Area6 = Normal memory
283 	 */
284 	_reg_write_4(SH4_BCR1, BSC_BCR1_VAL);
285 
286 	/*
287 	 * Bus Width
288 	 * Area4: Bus width = 16bit
289 	 * Area6,5 = 16bit
290 	 * Area1 = 8bit
291 	 * Area2,3: Bus width = 32bit
292 	 */
293 	_reg_write_2(SH4_BCR2, BSC_BCR2_VAL);
294 
295 #if defined(SH4) && defined(SH7751R)
296 	if (cpu_product == CPU_PRODUCT_7751R) {
297 #ifdef BSC_BCR3_VAL
298 		_reg_write_2(SH4_BCR3, BSC_BCR3_VAL);
299 #endif
300 #ifdef BSC_BCR4_VAL
301 		_reg_write_4(SH4_BCR4, BSC_BCR4_VAL);
302 #endif
303 	}
304 #endif	/* SH4 && SH7751R */
305 
306 	/*
307 	 * Idle cycle number in transition area and read to write
308 	 * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3
309 	 * Area1 = 3, Area0 = 3
310 	 */
311 	_reg_write_4(SH4_WCR1, BSC_WCR1_VAL);
312 
313 	/*
314 	 * Wait cycle
315 	 * Area 6 = 6
316 	 * Area 5 = 2
317 	 * Area 4 = 10
318 	 * Area 3 = 3
319 	 * Area 2,1 = 3
320 	 * Area 0 = 6
321 	 */
322 	_reg_write_4(SH4_WCR2, BSC_WCR2_VAL);
323 
324 #ifdef BSC_WCR3_VAL
325 	_reg_write_4(SH4_WCR3, BSC_WCR3_VAL);
326 #endif
327 
328 	/*
329 	 * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle,
330 	 * write pre-charge=1cycle
331 	 * CAS before RAS refresh RAS assert time = 3 cycle
332 	 * Disable burst, Bus size=32bit, Column Address=10bit, Refresh ON
333 	 * CAS before RAS refresh ON, EDO DRAM
334 	 */
335 	_reg_write_4(SH4_MCR, BSC_MCR_VAL);
336 
337 #ifdef BSC_SDMR2_VAL
338 	_reg_write_1(BSC_SDMR2_VAL, 0);
339 #endif
340 
341 #ifdef BSC_SDMR3_VAL
342 	_reg_write_1(BSC_SDMR3_VAL, 0);
343 #endif /* BSC_SDMR3_VAL */
344 
345 	/*
346 	 * PCMCIA Control Register
347 	 * OE/WE assert delay 3.5 cycle
348 	 * OE/WE negate-address delay 3.5 cycle
349 	 */
350 #ifdef BSC_PCR_VAL
351 	_reg_write_2(SH4_PCR, BSC_PCR_VAL);
352 #endif
353 
354 	/*
355 	 * Refresh Timer Control/Status Register
356 	 * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt
357 	 * Count Limit = 1024
358 	 * In following statement, the reason why high byte = 0xa5(a4 in RFCR)
359 	 * is the rule of SH3 in writing these register.
360 	 */
361 	_reg_write_2(SH4_RTCSR, BSC_RTCSR_VAL);
362 
363 	/*
364 	 * Refresh Timer Counter
365 	 * Initialize to 0
366 	 */
367 #ifdef BSC_RTCNT_VAL
368 	_reg_write_2(SH4_RTCNT, BSC_RTCNT_VAL);
369 #endif
370 
371 	/* set Refresh Time Constant Register */
372 	_reg_write_2(SH4_RTCOR, BSC_RTCOR_VAL);
373 
374 	/* init Refresh Count Register */
375 #ifdef BSC_RFCR_VAL
376 	_reg_write_2(SH4_RFCR, BSC_RFCR_VAL);
377 #endif
378 
379 	/*
380 	 * Clock Pulse Generator
381 	 */
382 	/* Set Clock mode (make internal clock double speed) */
383 	_reg_write_2(SH4_FRQCR, FRQCR_VAL);
384 }
385 #endif /* !DONT_INIT_BSC */
386 
387 /*
388  * Dump the machine-dependent dump header.
389  */
390 u_int
cpu_dump(int (* dump)(dev_t,daddr_t,caddr_t,size_t),daddr_t * blknop)391 cpu_dump(int (*dump)(dev_t, daddr_t, caddr_t, size_t), daddr_t *blknop)
392 {
393 	extern cpu_kcore_hdr_t cpu_kcore_hdr;
394 	char buf[dbtob(1)];
395 	cpu_kcore_hdr_t *h;
396 	kcore_seg_t *kseg;
397 	int rc;
398 
399 #ifdef DIAGNOSTIC
400 	if (cpu_dumpsize() > btodb(sizeof buf)) {
401 		printf("buffer too small in cpu_dump, ");
402 		return (EINVAL);	/* "aborted" */
403 	}
404 #endif
405 
406 	bzero(buf, sizeof buf);
407 	kseg = (kcore_seg_t *)buf;
408 	h = (cpu_kcore_hdr_t *)(buf + ALIGN(sizeof(kcore_seg_t)));
409 
410 	/* Create the segment header */
411 	CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
412 	kseg->c_size = dbtob(1) - ALIGN(sizeof(kcore_seg_t));
413 
414 	bcopy(&cpu_kcore_hdr, h, sizeof(*h));
415 	/* We can now fill kptp in the header... */
416 	h->kcore_kptp = SH3_P1SEG_TO_PHYS((vaddr_t)pmap_kernel()->pm_ptp);
417 
418 	rc = (*dump)(dumpdev, *blknop, buf, sizeof buf);
419 	*blknop += btodb(sizeof buf);
420 	return (rc);
421 }
422 
423 /*
424  * Return the size of the machine-dependent dump header, in disk blocks.
425  */
426 u_int
cpu_dumpsize(void)427 cpu_dumpsize(void)
428 {
429 	u_int size;
430 
431 	size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t));
432 	return (btodb(roundup(size, dbtob(1))));
433 }
434 
435 /*
436  * Fill the machine-dependent dump header.
437  */
438 void
cpu_init_kcore_hdr(void)439 cpu_init_kcore_hdr(void)
440 {
441 	extern cpu_kcore_hdr_t cpu_kcore_hdr;
442 	cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
443 	phys_ram_seg_t *seg = cpu_kcore_hdr.kcore_segs;
444 	struct vm_physseg *physseg = vm_physmem;
445 	u_int i;
446 
447 	bzero(h, sizeof(*h));
448 
449 	h->kcore_nsegs = min(NPHYS_RAM_SEGS, (u_int)vm_nphysseg);
450 	for (i = h->kcore_nsegs; i != 0; i--) {
451 		seg->start = ptoa(physseg->start);
452 		seg->size = (psize_t)ptoa(physseg->end - physseg->start);
453 		seg++;
454 		physseg++;
455 	}
456 }
457 
458 int
cpu_sysctl(int * name,u_int namelen,void * oldp,size_t * oldlenp,void * newp,size_t newlen,struct proc * p)459 cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
460     size_t newlen, struct proc *p)
461 {
462 	int oldval, ret;
463 
464 	/* all sysctl names at this level are terminal */
465 	if (namelen != 1)
466 		return (ENOTDIR);		/* overloaded */
467 
468 	switch (name[0]) {
469 	case CPU_CONSDEV: {
470 		dev_t consdev;
471 		if (cn_tab != NULL)
472 			consdev = cn_tab->cn_dev;
473 		else
474 			consdev = NODEV;
475 		return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
476 		    sizeof consdev));
477 	}
478 
479 	case CPU_LED_BLINK:
480 		oldval = led_blink;
481 		ret = sysctl_int(oldp, oldlenp, newp, newlen, &led_blink);
482 		if (oldval != led_blink)
483 			blink_led(NULL);
484 		return (ret);
485 
486 	default:
487 		return (EOPNOTSUPP);
488 	}
489 	/* NOTREACHED */
490 }
491 
492 void
blink_led(void * whatever)493 blink_led(void *whatever)
494 {
495 	static struct timeout blink_tmo;
496 	u_int8_t ledctrl;
497 
498 	if (led_blink == 0) {
499 		_reg_write_1(LANDISK_LEDCTRL,
500 		    LED_POWER_CHANGE | LED_POWER_VALUE);
501 		return;
502 	}
503 
504 	ledctrl = (u_int8_t)_reg_read_1(LANDISK_LEDCTRL) & LED_POWER_VALUE;
505 	ledctrl ^= (LED_POWER_CHANGE | LED_POWER_VALUE);
506 	_reg_write_1(LANDISK_LEDCTRL, ledctrl);
507 
508 	timeout_set(&blink_tmo, blink_led, NULL);
509 	timeout_add(&blink_tmo,
510 	    ((averunnable.ldavg[0] + FSCALE) * hz) >> FSHIFT);
511 }
512 
513 unsigned int
cpu_rnd_messybits(void)514 cpu_rnd_messybits(void)
515 {
516 	struct timespec ts;
517 
518 	nanotime(&ts);
519 	return (ts.tv_nsec ^ (ts.tv_sec << 20));
520 }
521