11.2Sjmcneill/* $NetBSD: boot.c,v 1.2 2025/11/16 22:37:49 jmcneill Exp $ */ 21.1Sjmcneill 31.1Sjmcneill/*- 41.1Sjmcneill * Copyright (c) 2025 Jared McNeill <jmcneill@invisible.ca> 51.1Sjmcneill * All rights reserved. 61.1Sjmcneill * 71.1Sjmcneill * Redistribution and use in source and binary forms, with or without 81.1Sjmcneill * modification, are permitted provided that the following conditions 91.1Sjmcneill * are met: 101.1Sjmcneill * 1. Redistributions of source code must retain the above copyright 111.1Sjmcneill * notice, this list of conditions and the following disclaimer. 121.1Sjmcneill * 2. Redistributions in binary form must reproduce the above copyright 131.1Sjmcneill * notice, this list of conditions and the following disclaimer in the 141.1Sjmcneill * documentation and/or other materials provided with the distribution. 151.1Sjmcneill * 161.1Sjmcneill * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 171.1Sjmcneill * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 181.1Sjmcneill * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 191.1Sjmcneill * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 201.1Sjmcneill * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 211.1Sjmcneill * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 221.1Sjmcneill * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 231.1Sjmcneill * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 241.1Sjmcneill * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 251.1Sjmcneill * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 261.1Sjmcneill * SUCH DAMAGE. 271.1Sjmcneill */ 281.1Sjmcneill 291.1Sjmcneill#include <lib/libsa/stand.h> 301.1Sjmcneill#include <lib/libsa/loadfile.h> 311.1Sjmcneill 321.1Sjmcneill#include <powerpc/include/psl.h> 331.1Sjmcneill#include <powerpc/include/spr.h> 341.1Sjmcneill 351.2Sjmcneill#include <machine/pio.h> 361.2Sjmcneill 371.1Sjmcneill#include "cache.h" 381.1Sjmcneill#include "console.h" 391.1Sjmcneill#include "gpio.h" 401.1Sjmcneill#include "miniipc.h" 411.1Sjmcneill#include "sdmmc.h" 421.1Sjmcneill#include "timer.h" 431.1Sjmcneill 441.2Sjmcneill#define PI_INTERRUPT_CAUSE 0x0c003000 451.2Sjmcneill#define RESET_SWITCH_STATE __BIT(16) 461.2Sjmcneill 471.2Sjmcneill#define HW_BASE 0x0d800000 481.2Sjmcneill#define HW_RESETS (HW_BASE + 0x194) 491.2Sjmcneill#define RSTBINB __BIT(0) 501.2Sjmcneill 511.1Sjmcneillstatic const char * const names[] = { 521.1Sjmcneill "netbsd", "netbsd.gz", 531.1Sjmcneill "onetbsd", "onetbsd.gz", 541.1Sjmcneill "netbsd.old", "onetbsd.old.gz", 551.1Sjmcneill}; 561.1Sjmcneill#define NUMNAMES __arraycount(names) 571.1Sjmcneill 581.1Sjmcneillstatic int exec_netbsd(const char *); 591.1Sjmcneill 601.1Sjmcneillint 611.1Sjmcneillmain(void) 621.1Sjmcneill{ 631.1Sjmcneill extern uint8_t edata[], end[]; 641.1Sjmcneill int curname; 651.1Sjmcneill 661.1Sjmcneill memset(&edata, 0, end - edata); /* clear BSS */ 671.1Sjmcneill 681.2Sjmcneill gpio_enable_int(GPIO_EJECT_BTN); 691.2Sjmcneill gpio_ack_int(GPIO_EJECT_BTN); 701.2Sjmcneill 711.1Sjmcneill console_init(); 721.1Sjmcneill 731.1Sjmcneill gpio_set(GPIO_SLOT_LED); 741.1Sjmcneill 751.1Sjmcneill if (!miniipc_probe()) { 761.1Sjmcneill panic("MINI IPC not found!"); 771.1Sjmcneill } 781.1Sjmcneill 791.1Sjmcneill sdmmc_init(); 801.1Sjmcneill 811.2Sjmcneill curname = gpio_get_int(GPIO_EJECT_BTN) ? 2 : 0; 821.2Sjmcneill gpio_disable_int(GPIO_EJECT_BTN); 831.2Sjmcneill gpio_ack_int(GPIO_EJECT_BTN); 841.2Sjmcneill 851.2Sjmcneill for (; curname < NUMNAMES; curname++) { 861.1Sjmcneill printf("booting %s ", names[curname]); 871.1Sjmcneill exec_netbsd(names[curname]); 881.1Sjmcneill } 891.1Sjmcneill 901.1Sjmcneill panic("No bootable kernel found"); 911.1Sjmcneill 921.1Sjmcneill return 0; 931.1Sjmcneill} 941.1Sjmcneill 951.1Sjmcneillstatic int 961.1Sjmcneillexec_netbsd(const char *fname) 971.1Sjmcneill{ 981.1Sjmcneill u_long marks[MARK_MAX]; 991.1Sjmcneill void (*entry)(void); 1001.1Sjmcneill int fd; 1011.1Sjmcneill 1021.1Sjmcneill memset(marks, 0, sizeof(marks)); 1031.1Sjmcneill fd = loadfile(fname, marks, LOAD_KERNEL); 1041.1Sjmcneill if (fd == -1) { 1051.1Sjmcneill return -1; 1061.1Sjmcneill } 1071.1Sjmcneill 1081.1Sjmcneill gpio_clear(GPIO_SLOT_LED); 1091.1Sjmcneill 1101.1Sjmcneill entry = (void *)marks[MARK_ENTRY]; 1111.1Sjmcneill cache_dcbf((void *)marks[MARK_START], 1121.1Sjmcneill marks[MARK_END] - marks[MARK_START]); 1131.1Sjmcneill cache_icbi((void *)marks[MARK_START], 1141.1Sjmcneill marks[MARK_END] - marks[MARK_START]); 1151.1Sjmcneill 1161.1Sjmcneill entry(); 1171.1Sjmcneill panic("Unexpected return from kernel"); 1181.1Sjmcneill} 1191.1Sjmcneill 1201.1Sjmcneill__dead void 1211.1Sjmcneill_rtt(void) 1221.1Sjmcneill{ 1231.1Sjmcneill int led = 0; 1241.1Sjmcneill for (;;) { 1251.1Sjmcneill if (led) { 1261.1Sjmcneill gpio_set(GPIO_SLOT_LED); 1271.1Sjmcneill } else { 1281.1Sjmcneill gpio_clear(GPIO_SLOT_LED); 1291.1Sjmcneill } 1301.2Sjmcneill for (int i = 0; i < 1000; i++) { 1311.2Sjmcneill if ((in32(PI_INTERRUPT_CAUSE) & RESET_SWITCH_STATE) == 0) { 1321.2Sjmcneill out32(HW_RESETS, in32(HW_RESETS) & ~RSTBINB); 1331.2Sjmcneill } 1341.2Sjmcneill timer_udelay(1000); 1351.2Sjmcneill } 1361.1Sjmcneill led ^= 1; 1371.1Sjmcneill } 1381.1Sjmcneill} 139