1/*	$NetBSD: machdep.c,v 1.47 2024/03/05 14:15:29 thorpej Exp $	*/
2
3/*-
4 * Copyright (c) 1996, 1997, 1998, 2002 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.47 2024/03/05 14:15:29 thorpej Exp $");
69
70#include "opt_ddb.h"
71#include "opt_kgdb.h"
72#include "opt_memsize.h"
73#include "scif.h"
74#include "opt_kloader.h"
75#include "opt_modular.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/module.h>
86#include <sys/cpu.h>
87
88#ifdef KGDB
89#include <sys/kgdb.h>
90#include <sh3/dev/scifvar.h>
91#endif
92#ifdef DDB
93#include <machine/db_machdep.h>
94#include <ddb/db_extern.h>
95#endif
96
97#include <sh3/cpu.h>
98#include <sh3/exception.h>
99#include <sh3/bscreg.h>
100#include <machine/intr.h>
101#include <machine/kloader.h>
102#include <machine/pcb.h>
103
104#include <dev/cons.h>
105
106#include "ksyms.h"
107
108/* the following is used externally (sysctl_hw) */
109char machine[] = MACHINE;		/* dreamcast */
110char machine_arch[] = MACHINE_ARCH;	/* sh3el */
111
112void main(void) __attribute__((__noreturn__));
113void dreamcast_startup(void) __attribute__((__noreturn__));
114
115void
116dreamcast_startup(void)
117{
118	extern char edata[], end[];
119	paddr_t kernend;
120
121	/* Clear bss */
122	memset(edata, 0, end - edata);
123
124	/* Initialize CPU ops. */
125	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7750);
126
127	/* Console */
128	consinit();
129
130	/* Load memory to UVM */
131	physmem = atop(IOM_RAM_SIZE);
132	kernend = atop(round_page(SH3_P1SEG_TO_PHYS(end)));
133	uvm_page_physload(
134		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
135		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
136		VM_FREELIST_DEFAULT);
137
138	/* Initialize proc0 u-area */
139	sh_proc0_init();
140
141	/* Initialize pmap and start to address translation */
142	pmap_bootstrap();
143
144	/* Debugger. */
145#if defined(KGDB) && (NSCIF > 0)
146	if (scif_kgdb_init() == 0) {
147		kgdb_debug_init = 1;
148		kgdb_connect(1);
149	}
150#endif /* KGDB && NSCIF > 0 */
151
152	/* Jump to main */
153	__asm volatile(
154		"jmp	@%0;"
155		"mov	%1, sp"
156		:: "r"(main),"r"(lwp0.l_md.md_pcb->pcb_sf.sf_r7_bank));
157	/* NOTREACHED */
158	while (1)
159		;
160}
161
162void
163consinit(void)
164{
165	static int initted;
166
167	if (initted)
168		return;
169	initted = 1;
170
171	cninit();
172}
173
174void
175cpu_startup(void)
176{
177
178	cpu_setmodel("SEGA Dreamcast");
179
180	sh_startup();
181}
182
183SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
184{
185
186	sysctl_createv(clog, 0, NULL, NULL,
187		       CTLFLAG_PERMANENT,
188		       CTLTYPE_NODE, "machdep", NULL,
189		       NULL, 0, NULL, 0,
190		       CTL_MACHDEP, CTL_EOL);
191
192	sysctl_createv(clog, 0, NULL, NULL,
193		       CTLFLAG_PERMANENT,
194		       CTLTYPE_STRUCT, "console_device", NULL,
195		       sysctl_consdev, 0, NULL, sizeof(dev_t),
196		       CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
197}
198
199void
200cpu_reboot(int howto, char *bootstr)
201{
202#ifdef KLOADER
203	struct kloader_bootinfo kbi;
204#endif
205	static int waittime = -1;
206
207	if (cold) {
208		howto |= RB_HALT;
209		goto haltsys;
210	}
211
212#ifdef KLOADER
213	/* No bootinfo is required. */
214	kloader_bootinfo_set(&kbi, 0, NULL, NULL, true);
215	if ((howto & RB_HALT) == 0) {
216		if ((howto & RB_STRING) && bootstr != NULL) {
217			printf("loading a new kernel: %s\n", bootstr);
218			kloader_reboot_setup(bootstr);
219		}
220	}
221#endif
222
223	boothowto = howto;
224	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
225		waittime = 0;
226		vfs_shutdown();
227	}
228
229	/* Disable interrupts. */
230	splhigh();
231
232	/* Do a dump if requested. */
233	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
234		dumpsys();
235
236 haltsys:
237	doshutdownhooks();
238
239	pmf_system_shutdown(boothowto);
240
241	if (howto & RB_HALT) {
242		printf("\n");
243		printf("The operating system has halted.\n");
244		printf("Please press any key to reboot.\n\n");
245		cngetc();
246	}
247
248#ifdef KLOADER
249	else if ((howto & RB_STRING) && bootstr != NULL) {
250		kloader_reboot();
251		printf("\nFailed to load a new kernel.\n");
252		cngetc();
253	}
254#endif
255
256	printf("rebooting...\n");
257	cpu_reset();
258	for(;;)
259		;
260	/*NOTREACHED*/
261}
262
263void
264intc_intr(int ssr, int spc, int ssp)
265{
266	struct intc_intrhand *ih;
267	int evtcode;
268
269	curcpu()->ci_data.cpu_nintr++;
270
271	evtcode = _reg_read_4(SH4_INTEVT);
272
273	ih = EVTCODE_IH(evtcode);
274	KDASSERT(ih->ih_func);
275	/*
276	 * On entry, all interrupts are disabled, and exception is enabled.
277	 * Enable higher level interrupt here.
278	 */
279	_cpu_intr_resume(ih->ih_level);
280
281	if (evtcode == SH_INTEVT_TMU0_TUNI0) {	/* hardclock */
282		struct clockframe cf;
283		cf.spc = spc;
284		cf.ssr = ssr;
285		cf.ssp = ssp;
286		(*ih->ih_func)(&cf);
287	} else {
288		(*ih->ih_func)(ih->ih_arg);
289	}
290}
291
292#ifdef MODULAR
293/*
294 * Push any modules loaded by the bootloader etc.
295 */
296void
297module_init_md(void)
298{
299}
300#endif
301