1 /* $NetBSD: machdep.c,v 1.32 2021/02/27 01:31:24 thorpej 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.32 2021/02/27 01:31:24 thorpej Exp $"); 36 37 #include "opt_compat_netbsd.h" 38 #include "opt_mvmetype.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/malloc.h> 51 #include <sys/mbuf.h> 52 #include <sys/mount.h> 53 #include <sys/msgbuf.h> 54 #include <sys/proc.h> 55 #include <sys/reboot.h> 56 #include <sys/syscallargs.h> 57 #include <sys/syslog.h> 58 #include <sys/systm.h> 59 #include <sys/sysctl.h> 60 61 #include <machine/autoconf.h> 62 #include <machine/bootinfo.h> 63 #include <machine/platform.h> 64 #include <machine/powerpc.h> 65 66 #include <powerpc/pmap.h> 67 #include <powerpc/trap.h> 68 69 #include <powerpc/oea/bat.h> 70 71 #include <dev/cons.h> 72 73 #if 0 74 #include "vga.h" 75 #if (NVGA > 0) 76 #include <dev/ic/mc6845reg.h> 77 #include <dev/ic/pcdisplayvar.h> 78 #include <dev/ic/vgareg.h> 79 #include <dev/ic/vgavar.h> 80 #endif 81 82 #include "pckbc.h" 83 #if (NPCKBC > 0) 84 #include <dev/isa/isareg.h> 85 #include <dev/ic/i8042reg.h> 86 #include <dev/ic/pckbcvar.h> 87 #endif 88 #endif 89 90 #include "com.h" 91 #if (NCOM > 0) 92 #include <sys/termios.h> 93 #include <dev/ic/comreg.h> 94 #include <dev/ic/comvar.h> 95 #endif 96 97 void initppc(u_long, u_long, void *); 98 99 /* 100 * Global variables used here and there 101 */ 102 struct mvmeppc_bootinfo bootinfo; 103 vaddr_t prep_intr_reg; /* PReP-compatible interrupt vector register */ 104 uint32_t prep_intr_reg_off = INTR_VECTOR_REG; 105 struct mem_region physmemr[2], availmemr[2]; 106 paddr_t avail_end; /* XXX temporary */ 107 struct pic_ops *isa_pic; 108 109 void 110 initppc(u_long startkernel, u_long endkernel, void *btinfo) 111 { 112 /* 113 * Copy bootinfo. 114 */ 115 memcpy(&bootinfo, btinfo, sizeof(bootinfo)); 116 117 /* 118 * Figure out the board family/type. 119 */ 120 ident_platform(); 121 122 if (platform == NULL) { 123 extern void _mvmeppc_unsup_board(const char *, const char *); 124 char msg[80]; 125 126 snprintf(msg, sizeof(msg), "Unsupported model: MVME%04x", 127 bootinfo.bi_modelnumber); 128 _mvmeppc_unsup_board(msg, &msg[strlen(msg)]); 129 /* NOTREACHED */ 130 } 131 132 /* 133 * Set memory region 134 */ 135 physmemr[0].start = 0; 136 physmemr[0].size = bootinfo.bi_memsize & ~PGOFSET; 137 availmemr[0].start = (endkernel + PGOFSET) & ~PGOFSET; 138 availmemr[0].size = bootinfo.bi_memsize - availmemr[0].start; 139 avail_end = physmemr[0].start + physmemr[0].size; /* XXX temporary */ 140 141 /* 142 * Set CPU clock 143 */ 144 { 145 extern u_long ticks_per_sec, ns_per_tick; 146 147 ticks_per_sec = bootinfo.bi_clocktps; 148 ns_per_tick = 1000000000 / ticks_per_sec; 149 } 150 151 prep_initppc(startkernel, endkernel, boothowto, 0); 152 153 (*platform->pic_setup)(); 154 } 155 156 /* 157 * Machine dependent startup code. 158 */ 159 void 160 cpu_startup(void) 161 { 162 char modelbuf[256]; 163 164 /* 165 * Mapping PReP-compatible interrput vector register. 166 */ 167 prep_intr_reg = (vaddr_t) mapiodev(MVMEPPC_INTR_REG, PAGE_SIZE, false); 168 if (!prep_intr_reg) 169 panic("startup: no room for interrupt register"); 170 171 snprintf(modelbuf, sizeof(modelbuf), 172 "%s\nCore Speed: %dMHz, Bus Speed: %dMHz\n", 173 platform->model, 174 bootinfo.bi_mpuspeed/1000000, 175 bootinfo.bi_busspeed/1000000); 176 oea_startup(modelbuf); 177 178 /* 179 * Now allow hardware interrupts. 180 */ 181 { 182 int msr; 183 184 splraise(-1); 185 __asm volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0" 186 : "=r"(msr) : "K"(PSL_EE)); 187 } 188 189 bus_space_mallocok(); 190 } 191 192 /* 193 * consinit 194 * Initialize system console. 195 */ 196 void 197 consinit(void) 198 { 199 static int initted = 0; 200 201 if (initted) 202 return; 203 initted = 1; 204 205 #if 0 206 207 #if (NPFB > 0) 208 if (!strcmp(consinfo->devname, "fb")) { 209 pfb_cnattach(consinfo->addr); 210 #if (NPCKBC > 0) 211 pckbc_cnattach(&mvmeppc_isa_io_space_tag, IO_KBD, KBCMDP, 212 PCKBC_KBD_SLOT, 0); 213 #endif 214 return; 215 } 216 #endif 217 218 #if (NVGA > 0) || (NGTEN > 0) 219 if (!strcmp(consinfo->devname, "vga")) { 220 #if (NGTEN > 0) 221 if (!gten_cnattach(&mvmeppc_mem_space_tag)) 222 goto dokbd; 223 #endif 224 #if (NVGA > 0) 225 if (!vga_cnattach(&mvmeppc_io_space_tag, &mvmeppc_mem_space_tag, 226 -1, 1)) 227 goto dokbd; 228 #endif 229 dokbd: 230 #if (NPCKBC > 0) 231 pckbc_cnattach(&mvmeppc_isa_io_space_tag, IO_KBD, KBCMDP, 232 PCKBC_KBD_SLOT, 0); 233 #endif 234 return; 235 } 236 #endif /* PC | VGA */ 237 238 #endif 239 240 #if (NCOM > 0) 241 if (!strcmp(bootinfo.bi_consoledev, "PC16550")) { 242 bus_space_tag_t tag = &genppc_isa_io_space_tag; 243 static const bus_addr_t caddr[2] = {0x3f8, 0x2f8}; 244 int rv; 245 rv = comcnattach(tag, caddr[bootinfo.bi_consolechan], 246 bootinfo.bi_consolespeed, COM_FREQ, COM_TYPE_NORMAL, 247 bootinfo.bi_consolecflag); 248 if (rv) 249 panic("can't init serial console"); 250 251 return; 252 } 253 #endif 254 panic("invalid console device %s", bootinfo.bi_consoledev); 255 } 256 257 /* 258 * Halt or reboot the machine after syncing/dumping according to howto. 259 */ 260 void 261 cpu_reboot(int howto, char *what) 262 { 263 static int syncing; 264 265 if (cold) { 266 howto |= RB_HALT; 267 goto halt_sys; 268 } 269 270 boothowto = howto; 271 if ((howto & RB_NOSYNC) == 0 && syncing == 0) { 272 syncing = 1; 273 vfs_shutdown(); /* sync */ 274 resettodr(); /* set wall clock */ 275 } 276 277 /* Disable intr */ 278 splhigh(); 279 280 /* Do dump if requested */ 281 if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 282 oea_dumpsys(); 283 284 halt_sys: 285 doshutdownhooks(); 286 287 pmf_system_shutdown(boothowto); 288 289 if (howto & RB_HALT) { 290 printf("\n"); 291 printf("The operating system has halted.\n"); 292 printf("Please press any key to reboot.\n\n"); 293 cnpollc(1); /* for proper keyboard command handling */ 294 cngetc(); 295 cnpollc(0); 296 } 297 298 printf("rebooting...\n\n"); 299 300 (*platform->reset)(); 301 302 printf("Oops! Board reset failed!\n"); 303 304 for (;;) 305 continue; 306 /* NOTREACHED */ 307 } 308