1 /* $NetBSD: machdep.c,v 1.110 2024/03/05 14:15:29 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.110 2024/03/05 14:15:29 thorpej Exp $"); 36 37 #include "opt_compat_netbsd.h" 38 #include "opt_ddb.h" 39 40 #define _POWERPC_BUS_DMA_PRIVATE 41 42 #include <sys/param.h> 43 #include <sys/bus.h> 44 #include <sys/conf.h> 45 #include <sys/device.h> 46 #include <sys/kernel.h> 47 #include <sys/mount.h> 48 #include <sys/reboot.h> 49 #include <sys/systm.h> 50 #include <sys/vnode.h> 51 52 #include <uvm/uvm_extern.h> 53 54 #include <machine/bebox.h> 55 #include <machine/autoconf.h> 56 #include <machine/bootinfo.h> 57 #include <machine/powerpc.h> 58 59 #include <powerpc/bat.h> 60 #include <powerpc/pic/picvar.h> 61 #include <powerpc/pio.h> 62 #include <powerpc/prep_bus.h> 63 #include <powerpc/psl.h> 64 65 #include <dev/cons.h> 66 67 #include "vga.h" 68 #if (NVGA > 0) 69 #include <dev/ic/mc6845reg.h> 70 #include <dev/ic/pcdisplayvar.h> 71 #include <dev/ic/vgareg.h> 72 #include <dev/ic/vgavar.h> 73 #endif 74 75 #include "pckbc.h" 76 #if (NPCKBC > 0) 77 #include <dev/isa/isareg.h> 78 #include <dev/ic/i8042reg.h> 79 #include <dev/ic/pckbcvar.h> 80 #include <dev/pckbport/pckbportvar.h> 81 #endif 82 83 #include "com.h" 84 #if (NCOM > 0) 85 #include <sys/termios.h> 86 #include <dev/ic/comreg.h> 87 #include <dev/ic/comvar.h> 88 #endif 89 90 /* 91 * Global variables used here and there 92 */ 93 char bootinfo[BOOTINFO_MAXSIZE]; 94 #define MEMREGIONS 2 95 struct mem_region physmemr[MEMREGIONS], availmemr[MEMREGIONS]; 96 char bootpath[256]; 97 struct pic_ops *isa_pic; 98 extern int primary_pic; 99 void initppc(u_long, u_long, u_int, void *); 100 static void disable_device(const char *); 101 void setup_bebox_intr(void); 102 103 extern void *startsym, *endsym; 104 105 void 106 initppc(u_long startkernel, u_long endkernel, u_int args, void *btinfo) 107 { 108 /* 109 * copy bootinfo 110 */ 111 memcpy(bootinfo, btinfo, sizeof (bootinfo)); 112 113 /* 114 * BeBox memory region set 115 */ 116 { 117 struct btinfo_memory *meminfo; 118 119 meminfo = 120 (struct btinfo_memory *)lookup_bootinfo(BTINFO_MEMORY); 121 if (!meminfo) 122 panic("not found memory information in bootinfo"); 123 physmemr[0].start = 0; 124 physmemr[0].size = meminfo->memsize & ~PGOFSET; 125 availmemr[0].start = (endkernel + PGOFSET) & ~PGOFSET; 126 availmemr[0].size = meminfo->memsize - availmemr[0].start; 127 } 128 129 /* 130 * Get CPU clock 131 */ 132 { 133 struct btinfo_clock *clockinfo; 134 extern u_long ticks_per_sec, ns_per_tick; 135 136 clockinfo = 137 (struct btinfo_clock *)lookup_bootinfo(BTINFO_CLOCK); 138 if (!clockinfo) 139 panic("not found clock information in bootinfo"); 140 ticks_per_sec = clockinfo->ticks_per_sec; 141 ns_per_tick = 1000000000 / ticks_per_sec; 142 } 143 144 prep_initppc(startkernel, endkernel, args, 145 /* BeBox mainboard registers */ 146 0x7ffff000, BAT_BL_8M, /* XXX magic number */ 147 0); 148 } 149 150 /* 151 * Machine dependent startup code. 152 */ 153 void 154 cpu_startup(void) 155 { 156 157 /* 158 * Do common VM initialization 159 */ 160 oea_startup(NULL); 161 162 pic_init(); 163 isa_pic = setup_i8259(); 164 setup_bebox_intr(); 165 primary_pic = 1; 166 167 /* 168 * set up i8259 as a cascade on BeInterruptController irq 26. 169 */ 170 intr_establish(16 + 26, IST_LEVEL, IPL_HIGH, pic_handle_intr, isa_pic); 171 172 oea_install_extint(pic_ext_intr); 173 174 /* 175 * Now that we have VM, malloc's are OK in bus_space. 176 */ 177 bus_space_mallocok(); 178 } 179 180 /* 181 * lookup_bootinfo: 182 * Look up information in bootinfo of boot loader. 183 */ 184 void * 185 lookup_bootinfo(int type) 186 { 187 struct btinfo_common *bt; 188 struct btinfo_common *help = (struct btinfo_common *)bootinfo; 189 190 do { 191 bt = help; 192 if (bt->type == type) 193 return (help); 194 help = (struct btinfo_common *)((char*)help + bt->next); 195 } while (bt->next && 196 (size_t)help < (size_t)bootinfo + sizeof (bootinfo)); 197 198 return (NULL); 199 } 200 201 static void 202 disable_device(const char *name) 203 { 204 extern struct cfdata cfdata[]; 205 int i; 206 207 for (i = 0; cfdata[i].cf_name != NULL; i++) 208 if (strcmp(cfdata[i].cf_name, name) == 0) { 209 if (cfdata[i].cf_fstate == FSTATE_NOTFOUND) 210 cfdata[i].cf_fstate = FSTATE_DNOTFOUND; 211 else if (cfdata[i].cf_fstate == FSTATE_STAR) 212 cfdata[i].cf_fstate = FSTATE_DSTAR; 213 } 214 } 215 216 /* 217 * consinit 218 * Initialize system console. 219 */ 220 void 221 consinit(void) 222 { 223 struct btinfo_console *consinfo; 224 static int initted; 225 226 if (initted) 227 return; 228 initted = 1; 229 230 consinfo = (struct btinfo_console *)lookup_bootinfo(BTINFO_CONSOLE); 231 if (!consinfo) 232 panic("not found console information in bootinfo"); 233 234 /* 235 * We need to disable genfb or vga, because foo_match() return 236 * the same value. 237 */ 238 if (!strcmp(consinfo->devname, "be")) { 239 /* 240 * We use Framebuffer for initialized by BootROM of BeBox. 241 * In this case, our console will be attached more late. 242 */ 243 #if (NPCKBC > 0) 244 pckbc_cnattach(&genppc_isa_io_space_tag, IO_KBD, KBCMDP, 245 PCKBC_KBD_SLOT, 0); 246 #endif 247 disable_device("vga"); 248 return; 249 } 250 251 disable_device("genfb"); 252 253 #if (NVGA > 0) 254 if (!strcmp(consinfo->devname, "vga")) { 255 vga_cnattach(&prep_io_space_tag, &prep_mem_space_tag, -1, 1); 256 #if (NPCKBC > 0) 257 pckbc_cnattach(&genppc_isa_io_space_tag, IO_KBD, KBCMDP, 258 PCKBC_KBD_SLOT, 0); 259 #endif 260 return; 261 } 262 #endif 263 264 #if (NCOM > 0) 265 if (!strcmp(consinfo->devname, "com")) { 266 bus_space_tag_t tag = &genppc_isa_io_space_tag; 267 268 if(comcnattach(tag, consinfo->addr, consinfo->speed, 269 COM_FREQ, COM_TYPE_NORMAL, 270 ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8))) 271 panic("can't init serial console"); 272 return; 273 } 274 #endif 275 panic("invalid console device %s", consinfo->devname); 276 } 277 278 /* 279 * Halt or reboot the machine after syncing/dumping according to howto. 280 */ 281 void 282 cpu_reboot(int howto, char *what) 283 { 284 static int syncing; 285 static char str[256]; 286 char *ap = str, *ap1 = ap; 287 288 boothowto = howto; 289 if (!cold && !(howto & RB_NOSYNC) && !syncing) { 290 syncing = 1; 291 vfs_shutdown(); /* sync */ 292 } 293 splhigh(); 294 if (howto & RB_HALT) { 295 doshutdownhooks(); 296 pmf_system_shutdown(boothowto); 297 printf("halted\n\n"); 298 299 } 300 if (!cold && (howto & RB_DUMP)) 301 oea_dumpsys(); 302 doshutdownhooks(); 303 pmf_system_shutdown(boothowto); 304 printf("rebooting\n\n"); 305 if (what && *what) { 306 if (strlen(what) > sizeof str - 5) 307 printf("boot string too large, ignored\n"); 308 else { 309 strcpy(str, what); 310 ap1 = ap = str + strlen(str); 311 *ap++ = ' '; 312 } 313 } 314 *ap++ = '-'; 315 if (howto & RB_SINGLE) 316 *ap++ = 's'; 317 if (howto & RB_KDB) 318 *ap++ = 'd'; 319 *ap++ = 0; 320 if (ap[-2] == '-') 321 *ap1 = 0; 322 323 /* Left and Right LED on. Max 15 for both LED. */ 324 #define LEFT_LED(x) (((x) & 0xf) << 4) 325 #define RIGHT_LED(x) (((x) & 0xf)) 326 327 outb(PREP_BUS_SPACE_IO + 0x0c00, LEFT_LED(15) | RIGHT_LED(15)); 328 329 while (1); 330 } 331