1/* $NetBSD: boot.c,v 1.2 2025/11/16 22:37:49 jmcneill Exp $ */
2
3/*-
4 * Copyright (c) 2025 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <lib/libsa/stand.h>
30#include <lib/libsa/loadfile.h>
31
32#include <powerpc/include/psl.h>
33#include <powerpc/include/spr.h>
34
35#include <machine/pio.h>
36
37#include "cache.h"
38#include "console.h"
39#include "gpio.h"
40#include "miniipc.h"
41#include "sdmmc.h"
42#include "timer.h"
43
44#define PI_INTERRUPT_CAUSE	0x0c003000
45#define  RESET_SWITCH_STATE	__BIT(16)
46
47#define HW_BASE			0x0d800000
48#define HW_RESETS		(HW_BASE + 0x194)
49#define  RSTBINB		__BIT(0)
50
51static const char * const names[] = {
52	"netbsd", "netbsd.gz",
53	"onetbsd", "onetbsd.gz",
54	"netbsd.old", "onetbsd.old.gz",
55};
56#define NUMNAMES	__arraycount(names)
57
58static int	exec_netbsd(const char *);
59
60int
61main(void)
62{
63	extern uint8_t edata[], end[];
64	int curname;
65
66	memset(&edata, 0, end - edata);	/* clear BSS */
67
68	gpio_enable_int(GPIO_EJECT_BTN);
69	gpio_ack_int(GPIO_EJECT_BTN);
70
71	console_init();
72
73	gpio_set(GPIO_SLOT_LED);
74
75	if (!miniipc_probe()) {
76		panic("MINI IPC not found!");
77	}
78
79	sdmmc_init();
80
81	curname = gpio_get_int(GPIO_EJECT_BTN) ? 2 : 0;
82	gpio_disable_int(GPIO_EJECT_BTN);
83	gpio_ack_int(GPIO_EJECT_BTN);
84
85	for (; curname < NUMNAMES; curname++) {
86		printf("booting %s ", names[curname]);
87		exec_netbsd(names[curname]);
88	}
89
90	panic("No bootable kernel found");
91
92	return 0;
93}
94
95static int
96exec_netbsd(const char *fname)
97{
98	u_long marks[MARK_MAX];
99	void (*entry)(void);
100	int fd;
101
102	memset(marks, 0, sizeof(marks));
103	fd = loadfile(fname, marks, LOAD_KERNEL);
104	if (fd == -1) {
105		return -1;
106	}
107
108	gpio_clear(GPIO_SLOT_LED);
109
110	entry = (void *)marks[MARK_ENTRY];
111	cache_dcbf((void *)marks[MARK_START],
112		   marks[MARK_END] - marks[MARK_START]);
113	cache_icbi((void *)marks[MARK_START],
114		   marks[MARK_END] - marks[MARK_START]);
115
116	entry();
117	panic("Unexpected return from kernel");
118}
119
120__dead void
121_rtt(void)
122{
123	int led = 0;
124	for (;;) {
125		if (led) {
126			gpio_set(GPIO_SLOT_LED);
127		} else {
128			gpio_clear(GPIO_SLOT_LED);
129		}
130		for (int i = 0; i < 1000; i++) {
131			if ((in32(PI_INTERRUPT_CAUSE) & RESET_SWITCH_STATE) == 0) {
132				out32(HW_RESETS, in32(HW_RESETS) & ~RSTBINB);
133			}
134			timer_udelay(1000);
135		}
136		led ^= 1;
137	}
138}
139