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