machdep.c revision 1.31
1/*	$OpenBSD: machdep.c,v 1.31 2014/04/14 07:36:12 mpi 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) */
108char machine[] = MACHINE;		/* landisk */
109
110__dead void landisk_startup(int, char *);
111__dead void main(void);
112void	cpu_init_kcore_hdr(void);
113void	blink_led(void *);
114
115int	led_blink;
116
117extern u_int32_t getramsize(void);
118
119struct uvm_constraint_range  dma_constraint = { 0x0, (paddr_t)-1 };
120struct 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 */
126int   safepri = 0;
127
128void
129cpu_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
138vaddr_t kernend;	/* used by /dev/mem too */
139char *esym;
140
141__dead void
142landisk_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		Debugger();
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	/* NOTREACHED */
190	for (;;) ;
191}
192
193void
194boot(int howto)
195{
196	struct device *mainbus;
197
198	if (cold) {
199		if ((howto & RB_USERREQ) == 0)
200			howto |= RB_HALT;
201		goto haltsys;
202	}
203
204	boothowto = howto;
205	if ((howto & RB_NOSYNC) == 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		if ((howto & RB_TIMEBAD) == 0)
212			resettodr();
213		else
214			printf("WARNING: not updating battery clock\n");
215	}
216	if_downall();
217
218	uvm_shutdown();
219	splhigh();		/* Disable interrupts. */
220
221	/* Do a dump if requested. */
222	if (howto & RB_DUMP)
223		dumpsys();
224
225haltsys:
226	doshutdownhooks();
227	mainbus = device_mainbus();
228	if (mainbus != NULL)
229		config_suspend(mainbus, DVACT_POWERDOWN);
230
231	if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
232		_reg_write_1(LANDISK_PWRMNG, PWRMNG_POWEROFF);
233		delay(1 * 1000 * 1000);
234		printf("POWEROFF FAILED!\n");
235		howto |= RB_HALT;
236	}
237
238	if (howto & RB_HALT) {
239		printf("\n");
240		printf("The operating system has halted.\n");
241		printf("Please press any key to reboot.\n\n");
242		cnpollc(1);
243		cngetc();
244		cnpollc(0);
245	}
246
247	printf("rebooting...\n");
248	machine_reset();
249
250	/*NOTREACHED*/
251	for (;;) {
252		continue;
253	}
254}
255
256void
257machine_reset(void)
258{
259	_cpu_exception_suspend();
260	_reg_write_4(SH_(EXPEVT), EXPEVT_RESET_MANUAL);
261	(void)*(volatile uint32_t *)0x80000001;	/* CPU shutdown */
262
263	/*NOTREACHED*/
264	for (;;) {
265		continue;
266	}
267}
268
269#if !defined(DONT_INIT_BSC)
270/*
271 * InitializeBsc
272 * : BSC(Bus State Controller)
273 */
274void InitializeBsc(void);
275
276void
277InitializeBsc(void)
278{
279
280	/*
281	 * Drive RAS,CAS in stand by mode and bus release mode
282	 * Area0 = Normal memory, Area5,6=Normal(no burst)
283	 * Area2 = Normal memory, Area3 = SDRAM, Area5 = Normal memory
284	 * Area4 = Normal Memory
285	 * Area6 = Normal memory
286	 */
287	_reg_write_4(SH4_BCR1, BSC_BCR1_VAL);
288
289	/*
290	 * Bus Width
291	 * Area4: Bus width = 16bit
292	 * Area6,5 = 16bit
293	 * Area1 = 8bit
294	 * Area2,3: Bus width = 32bit
295	 */
296	_reg_write_2(SH4_BCR2, BSC_BCR2_VAL);
297
298#if defined(SH4) && defined(SH7751R)
299	if (cpu_product == CPU_PRODUCT_7751R) {
300#ifdef BSC_BCR3_VAL
301		_reg_write_2(SH4_BCR3, BSC_BCR3_VAL);
302#endif
303#ifdef BSC_BCR4_VAL
304		_reg_write_4(SH4_BCR4, BSC_BCR4_VAL);
305#endif
306	}
307#endif	/* SH4 && SH7751R */
308
309	/*
310	 * Idle cycle number in transition area and read to write
311	 * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3
312	 * Area1 = 3, Area0 = 3
313	 */
314	_reg_write_4(SH4_WCR1, BSC_WCR1_VAL);
315
316	/*
317	 * Wait cycle
318	 * Area 6 = 6
319	 * Area 5 = 2
320	 * Area 4 = 10
321	 * Area 3 = 3
322	 * Area 2,1 = 3
323	 * Area 0 = 6
324	 */
325	_reg_write_4(SH4_WCR2, BSC_WCR2_VAL);
326
327#ifdef BSC_WCR3_VAL
328	_reg_write_4(SH4_WCR3, BSC_WCR3_VAL);
329#endif
330
331	/*
332	 * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle,
333	 * write pre-charge=1cycle
334	 * CAS before RAS refresh RAS assert time = 3 cycle
335	 * Disable burst, Bus size=32bit, Column Address=10bit, Refresh ON
336	 * CAS before RAS refresh ON, EDO DRAM
337	 */
338	_reg_write_4(SH4_MCR, BSC_MCR_VAL);
339
340#ifdef BSC_SDMR2_VAL
341	_reg_write_1(BSC_SDMR2_VAL, 0);
342#endif
343
344#ifdef BSC_SDMR3_VAL
345	_reg_write_1(BSC_SDMR3_VAL, 0);
346#endif /* BSC_SDMR3_VAL */
347
348	/*
349	 * PCMCIA Control Register
350	 * OE/WE assert delay 3.5 cycle
351	 * OE/WE negate-address delay 3.5 cycle
352	 */
353#ifdef BSC_PCR_VAL
354	_reg_write_2(SH4_PCR, BSC_PCR_VAL);
355#endif
356
357	/*
358	 * Refresh Timer Control/Status Register
359	 * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt
360	 * Count Limit = 1024
361	 * In following statement, the reason why high byte = 0xa5(a4 in RFCR)
362	 * is the rule of SH3 in writing these register.
363	 */
364	_reg_write_2(SH4_RTCSR, BSC_RTCSR_VAL);
365
366	/*
367	 * Refresh Timer Counter
368	 * Initialize to 0
369	 */
370#ifdef BSC_RTCNT_VAL
371	_reg_write_2(SH4_RTCNT, BSC_RTCNT_VAL);
372#endif
373
374	/* set Refresh Time Constant Register */
375	_reg_write_2(SH4_RTCOR, BSC_RTCOR_VAL);
376
377	/* init Refresh Count Register */
378#ifdef BSC_RFCR_VAL
379	_reg_write_2(SH4_RFCR, BSC_RFCR_VAL);
380#endif
381
382	/*
383	 * Clock Pulse Generator
384	 */
385	/* Set Clock mode (make internal clock double speed) */
386	_reg_write_2(SH4_FRQCR, FRQCR_VAL);
387}
388#endif /* !DONT_INIT_BSC */
389
390/*
391 * Dump the machine-dependent dump header.
392 */
393u_int
394cpu_dump(int (*dump)(dev_t, daddr_t, caddr_t, size_t), daddr_t *blknop)
395{
396	extern cpu_kcore_hdr_t cpu_kcore_hdr;
397	char buf[dbtob(1)];
398	cpu_kcore_hdr_t *h;
399	kcore_seg_t *kseg;
400	int rc;
401
402#ifdef DIAGNOSTIC
403	if (cpu_dumpsize() > btodb(sizeof buf)) {
404		printf("buffer too small in cpu_dump, ");
405		return (EINVAL);	/* "aborted" */
406	}
407#endif
408
409	bzero(buf, sizeof buf);
410	kseg = (kcore_seg_t *)buf;
411	h = (cpu_kcore_hdr_t *)(buf + ALIGN(sizeof(kcore_seg_t)));
412
413	/* Create the segment header */
414	CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
415	kseg->c_size = dbtob(1) - ALIGN(sizeof(kcore_seg_t));
416
417	bcopy(&cpu_kcore_hdr, h, sizeof(*h));
418	/* We can now fill kptp in the header... */
419	h->kcore_kptp = SH3_P1SEG_TO_PHYS((vaddr_t)pmap_kernel()->pm_ptp);
420
421	rc = (*dump)(dumpdev, *blknop, buf, sizeof buf);
422	*blknop += btodb(sizeof buf);
423	return (rc);
424}
425
426/*
427 * Return the size of the machine-dependent dump header, in disk blocks.
428 */
429u_int
430cpu_dumpsize()
431{
432	u_int size;
433
434	size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t));
435	return (btodb(roundup(size, dbtob(1))));
436}
437
438/*
439 * Fill the machine-dependent dump header.
440 */
441void
442cpu_init_kcore_hdr()
443{
444	extern cpu_kcore_hdr_t cpu_kcore_hdr;
445	cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
446	phys_ram_seg_t *seg = cpu_kcore_hdr.kcore_segs;
447	struct vm_physseg *physseg = vm_physmem;
448	u_int i;
449
450	bzero(h, sizeof(*h));
451
452	h->kcore_nsegs = min(NPHYS_RAM_SEGS, (u_int)vm_nphysseg);
453	for (i = h->kcore_nsegs; i != 0; i--) {
454		seg->start = ptoa(physseg->start);
455		seg->size = (psize_t)ptoa(physseg->end - physseg->start);
456		seg++;
457		physseg++;
458	}
459}
460
461int
462cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
463    size_t newlen, struct proc *p)
464{
465	int oldval, ret;
466
467	/* all sysctl names at this level are terminal */
468	if (namelen != 1)
469		return (ENOTDIR);		/* overloaded */
470
471	switch (name[0]) {
472	case CPU_CONSDEV: {
473		dev_t consdev;
474		if (cn_tab != NULL)
475			consdev = cn_tab->cn_dev;
476		else
477			consdev = NODEV;
478		return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
479		    sizeof consdev));
480	}
481
482	case CPU_LED_BLINK:
483		oldval = led_blink;
484		ret = sysctl_int(oldp, oldlenp, newp, newlen, &led_blink);
485		if (oldval != led_blink)
486			blink_led(NULL);
487		return (ret);
488
489	default:
490		return (EOPNOTSUPP);
491	}
492	/* NOTREACHED */
493}
494
495void
496blink_led(void *whatever)
497{
498	static struct timeout blink_tmo;
499	u_int8_t ledctrl;
500
501	if (led_blink == 0) {
502		_reg_write_1(LANDISK_LEDCTRL,
503		    LED_POWER_CHANGE | LED_POWER_VALUE);
504		return;
505	}
506
507	ledctrl = (u_int8_t)_reg_read_1(LANDISK_LEDCTRL) & LED_POWER_VALUE;
508	ledctrl ^= (LED_POWER_CHANGE | LED_POWER_VALUE);
509	_reg_write_1(LANDISK_LEDCTRL, ledctrl);
510
511	timeout_set(&blink_tmo, blink_led, NULL);
512	timeout_add(&blink_tmo,
513	    ((averunnable.ldavg[0] + FSCALE) * hz) >> FSHIFT);
514}
515