1 /* $NetBSD: machdep.c,v 1.37 2025/12/20 10:51:04 skrll Exp $ */ 2 3 /* 4 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 5 * Copyright (C) 1995, 1996 TooLs GmbH. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by TooLs GmbH. 19 * 4. The name of TooLs GmbH may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.37 2025/12/20 10:51:04 skrll Exp $"); 36 37 #include "opt_compat_netbsd.h" 38 #include "opt_mvmeconf.h" 39 #include "opt_ddb.h" 40 41 #include <sys/param.h> 42 #include <sys/buf.h> 43 #include <sys/bus.h> 44 #include <sys/conf.h> 45 #include <sys/device.h> 46 #include <sys/exec.h> 47 #include <sys/extent.h> 48 #include <sys/intr.h> 49 #include <sys/kernel.h> 50 #include <sys/mbuf.h> 51 #include <sys/mount.h> 52 #include <sys/msgbuf.h> 53 #include <sys/proc.h> 54 #include <sys/reboot.h> 55 #include <sys/syscallargs.h> 56 #include <sys/syslog.h> 57 #include <sys/systm.h> 58 #include <sys/sysctl.h> 59 60 #include <machine/autoconf.h> 61 #include <machine/bootinfo.h> 62 #include <machine/platform.h> 63 #include <machine/powerpc.h> 64 65 #include <powerpc/pmap.h> 66 #include <powerpc/trap.h> 67 68 #include <powerpc/oea/bat.h> 69 70 #include <dev/cons.h> 71 72 #if 0 73 #include "vga.h" 74 #if (NVGA > 0) 75 #include <dev/ic/mc6845reg.h> 76 #include <dev/ic/pcdisplayvar.h> 77 #include <dev/ic/vgareg.h> 78 #include <dev/ic/vgavar.h> 79 #endif 80 81 #include "pckbc.h" 82 #if (NPCKBC > 0) 83 #include <dev/isa/isareg.h> 84 #include <dev/ic/i8042reg.h> 85 #include <dev/ic/pckbcvar.h> 86 #endif 87 #endif 88 89 #include "com.h" 90 #if (NCOM > 0) 91 #include <sys/termios.h> 92 #include <dev/ic/comreg.h> 93 #include <dev/ic/comvar.h> 94 #endif 95 96 void initppc(u_long, u_long, void *); 97 98 /* 99 * Global variables used here and there 100 */ 101 struct mvmeppc_bootinfo bootinfo; 102 vaddr_t prep_intr_reg; /* PReP-compatible interrupt vector register */ 103 uint32_t prep_intr_reg_off = INTR_VECTOR_REG; 104 struct mem_region physmemr[2], availmemr[2]; 105 paddr_t avail_end; /* XXX temporary */ 106 struct pic_ops *isa_pic; 107 108 void 109 initppc(u_long startkernel, u_long endkernel, void *btinfo) 110 { 111 /* 112 * Copy bootinfo. 113 */ 114 memcpy(&bootinfo, btinfo, sizeof(bootinfo)); 115 116 /* 117 * Figure out the board family/type. 118 */ 119 ident_platform(); 120 121 if (platform == NULL) { 122 extern void _mvmeppc_unsup_board(const char *, const char *); 123 char msg[80]; 124 125 snprintf(msg, sizeof(msg), "Unsupported model: MVME%04x", 126 bootinfo.bi_modelnumber); 127 _mvmeppc_unsup_board(msg, &msg[strlen(msg)]); 128 /* NOTREACHED */ 129 } 130 131 /* 132 * Set memory region 133 */ 134 physmemr[0].start = 0; 135 physmemr[0].size = bootinfo.bi_memsize & ~PGOFSET; 136 availmemr[0].start = (endkernel + PGOFSET) & ~PGOFSET; 137 availmemr[0].size = bootinfo.bi_memsize - availmemr[0].start; 138 avail_end = physmemr[0].start + physmemr[0].size; /* XXX temporary */ 139 140 /* 141 * Set CPU clock 142 */ 143 { 144 extern u_long ticks_per_sec, ns_per_tick; 145 146 ticks_per_sec = bootinfo.bi_clocktps; 147 ns_per_tick = 1000000000 / ticks_per_sec; 148 } 149 150 prep_initppc(startkernel, endkernel, boothowto, 0); 151 152 (*platform->pic_setup)(); 153 } 154 155 /* 156 * Machine dependent startup code. 157 */ 158 void 159 cpu_startup(void) 160 { 161 char modelbuf[256]; 162 163 /* 164 * Mapping PReP-compatible interrupt vector register. 165 */ 166 prep_intr_reg = (vaddr_t) mapiodev(MVMEPPC_INTR_REG, PAGE_SIZE, false); 167 if (!prep_intr_reg) 168 panic("startup: no room for interrupt register"); 169 170 snprintf(modelbuf, sizeof(modelbuf), 171 "%s\nCore Speed: %dMHz, Bus Speed: %dMHz\n", 172 platform->model, 173 bootinfo.bi_mpuspeed/1000000, 174 bootinfo.bi_busspeed/1000000); 175 oea_startup(modelbuf); 176 177 /* 178 * Now allow hardware interrupts. 179 */ 180 { 181 int msr; 182 183 splraise(-1); 184 __asm volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0" 185 : "=r"(msr) : "K"(PSL_EE)); 186 } 187 188 bus_space_mallocok(); 189 } 190 191 /* 192 * consinit 193 * Initialize system console. 194 */ 195 void 196 consinit(void) 197 { 198 static int initted = 0; 199 200 if (initted) 201 return; 202 initted = 1; 203 204 #if 0 205 206 #if (NPFB > 0) 207 if (!strcmp(consinfo->devname, "fb")) { 208 pfb_cnattach(consinfo->addr); 209 #if (NPCKBC > 0) 210 pckbc_cnattach(&mvmeppc_isa_io_space_tag, IO_KBD, KBCMDP, 211 PCKBC_KBD_SLOT, 0); 212 #endif 213 return; 214 } 215 #endif 216 217 #if (NVGA > 0) || (NGTEN > 0) 218 if (!strcmp(consinfo->devname, "vga")) { 219 #if (NGTEN > 0) 220 if (!gten_cnattach(&mvmeppc_mem_space_tag)) 221 goto dokbd; 222 #endif 223 #if (NVGA > 0) 224 if (!vga_cnattach(&mvmeppc_io_space_tag, &mvmeppc_mem_space_tag, 225 -1, 1)) 226 goto dokbd; 227 #endif 228 dokbd: 229 #if (NPCKBC > 0) 230 pckbc_cnattach(&mvmeppc_isa_io_space_tag, IO_KBD, KBCMDP, 231 PCKBC_KBD_SLOT, 0); 232 #endif 233 return; 234 } 235 #endif /* PC | VGA */ 236 237 #endif 238 239 #if (NCOM > 0) 240 if (!strcmp(bootinfo.bi_consoledev, "PC16550")) { 241 bus_space_tag_t tag = &genppc_isa_io_space_tag; 242 static const bus_addr_t caddr[2] = {0x3f8, 0x2f8}; 243 int rv; 244 rv = comcnattach(tag, caddr[bootinfo.bi_consolechan], 245 bootinfo.bi_consolespeed, COM_FREQ, COM_TYPE_NORMAL, 246 bootinfo.bi_consolecflag); 247 if (rv) 248 panic("can't init serial console"); 249 250 return; 251 } 252 #endif 253 panic("invalid console device %s", bootinfo.bi_consoledev); 254 } 255 256 /* 257 * Halt or reboot the machine after syncing/dumping according to howto. 258 */ 259 void 260 cpu_reboot(int howto, char *what) 261 { 262 static int syncing; 263 264 if (cold) { 265 howto |= RB_HALT; 266 goto halt_sys; 267 } 268 269 boothowto = howto; 270 if ((howto & RB_NOSYNC) == 0 && syncing == 0) { 271 syncing = 1; 272 vfs_shutdown(); /* sync */ 273 } 274 275 /* Disable intr */ 276 splhigh(); 277 278 /* Do dump if requested */ 279 if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 280 oea_dumpsys(); 281 282 halt_sys: 283 doshutdownhooks(); 284 285 pmf_system_shutdown(boothowto); 286 287 if (howto & RB_HALT) { 288 printf("\n"); 289 printf("The operating system has halted.\n"); 290 printf("Please press any key to reboot.\n\n"); 291 cnpollc(true); /* for proper keyboard command handling */ 292 cngetc(); 293 cnpollc(false); 294 } 295 296 printf("rebooting...\n\n"); 297 298 (*platform->reset)(); 299 300 printf("Oops! Board reset failed!\n"); 301 302 for (;;) 303 continue; 304 /* NOTREACHED */ 305 } 306