1 /* $NetBSD: machdep.c,v 1.22 2024/03/05 14:15:30 thorpej Exp $ */ 2 3 /* 4 * Copyright 2001, 2002 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Jason R. Thorpe and Simon Burge for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 /* 39 * Copyright (c) 1988 University of Utah. 40 * Copyright (c) 1992, 1993 41 * The Regents of the University of California. All rights reserved. 42 * 43 * This code is derived from software contributed to Berkeley by 44 * the Systems Programming Group of the University of Utah Computer 45 * Science Department, The Mach Operating System project at 46 * Carnegie-Mellon University and Ralph Campbell. 47 * 48 * Redistribution and use in source and binary forms, with or without 49 * modification, are permitted provided that the following conditions 50 * are met: 51 * 1. Redistributions of source code must retain the above copyright 52 * notice, this list of conditions and the following disclaimer. 53 * 2. Redistributions in binary form must reproduce the above copyright 54 * notice, this list of conditions and the following disclaimer in the 55 * documentation and/or other materials provided with the distribution. 56 * 3. Neither the name of the University nor the names of its contributors 57 * may be used to endorse or promote products derived from this software 58 * without specific prior written permission. 59 * 60 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 61 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 62 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 63 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 64 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 65 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 66 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 70 * SUCH DAMAGE. 71 * 72 * @(#)machdep.c 8.3 (Berkeley) 1/12/94 73 * from: Utah Hdr: machdep.c 1.63 91/04/24 74 */ 75 76 #include <sys/cdefs.h> 77 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.22 2024/03/05 14:15:30 thorpej Exp $"); 78 79 #include "opt_ddb.h" 80 #include "opt_execfmt.h" 81 #include "opt_modular.h" 82 83 #include <sys/param.h> 84 #include <sys/boot_flag.h> 85 #include <sys/buf.h> 86 #include <sys/cpu.h> 87 #include <sys/device.h> 88 #include <sys/kcore.h> 89 #include <sys/kernel.h> 90 #include <sys/ksyms.h> 91 #include <sys/mount.h> 92 #include <sys/reboot.h> 93 #include <sys/systm.h> 94 #include <sys/termios.h> 95 96 #include <uvm/uvm_extern.h> 97 98 #include <dev/cons.h> 99 100 #include "ksyms.h" 101 102 #if NKSYMS || defined(DDB) || defined(MODULAR) 103 #include <mips/db_machdep.h> 104 #include <ddb/db_extern.h> 105 #endif 106 107 #include <mips/locore.h> 108 #include <mips/psl.h> 109 110 #include <mips/bonito/bonitoreg.h> 111 #include <evbmips/gdium/gdiumvar.h> 112 113 #include "com.h" 114 #if NCOM > 0 115 #include <dev/ic/comreg.h> 116 #include <dev/ic/comvar.h> 117 118 int comcnrate = 38400; /* XXX should be config option */ 119 #endif /* NCOM > 0 */ 120 121 struct gdium_config gdium_configuration = { 122 .gc_bonito = { 123 .bc_adbase = 11, /* magic */ 124 }, 125 }; 126 127 /* For sysctl_hw. */ 128 129 /* Maps for VM objects. */ 130 struct vm_map *phys_map = NULL; 131 132 int netboot; /* Are we netbooting? */ 133 134 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 135 int mem_cluster_cnt; 136 137 void configure(void); 138 void mach_init(int, char **, char **, void *); 139 140 /* The GDIUM kernels only support little endian */ 141 CTASSERT(_BYTE_ORDER == _LITTLE_ENDIAN); 142 143 /* 144 * For some reason, PMON doesn't assign a real address to the Ralink's BAR. 145 * So we have to do it. 146 */ 147 static void 148 gdium_pci_attach_hook(device_t parent, device_t self, 149 struct pcibus_attach_args *pba) 150 { 151 const pcitag_t high_dev = pci_make_tag(pba->pba_pc, 0, 17, 1); 152 const pcitag_t ralink_dev = pci_make_tag(pba->pba_pc, 0, 13, 0); 153 bus_size_t high_size, ralink_size; 154 pcireg_t v; 155 156 /* 157 * Get the highest PCI addr used from the last PCI dev. 158 */ 159 v = pci_conf_read(pba->pba_pc, high_dev, PCI_MAPREG_START); 160 v &= PCI_MAPREG_MEM_ADDR_MASK; 161 162 /* 163 * Get the sizes of the map registers. 164 */ 165 pci_mapreg_info(pba->pba_pc, high_dev, PCI_MAPREG_START, 166 PCI_MAPREG_MEM_TYPE_32BIT, NULL, &high_size, NULL); 167 pci_mapreg_info(pba->pba_pc, ralink_dev, PCI_MAPREG_START, 168 PCI_MAPREG_MEM_TYPE_32BIT, NULL, &ralink_size, NULL); 169 170 /* 171 * Position the ralink register space after the last device. 172 */ 173 v = (v + high_size + ralink_size - 1) & ~(ralink_size - 1); 174 175 /* 176 * Set the mapreg. 177 */ 178 pci_conf_write(pba->pba_pc, ralink_dev, PCI_MAPREG_START, v); 179 180 #if 0 181 /* 182 * Why does linux do this? 183 */ 184 for (int dev = 15; dev <= 17; dev +=2) { 185 for (int func = 0; func <= 1; func++) { 186 pcitag_t usb_dev = pci_make_tag(pba->pba_pc, 0, dev, func); 187 v = pci_conf_read(pba->pba_pc, usb_dev, 0xe0); 188 v |= 3; 189 pci_conf_write(pba->pba_pc, usb_dev, 0xe0, v); 190 } 191 } 192 #endif 193 } 194 195 /* 196 * Do all the stuff that locore normally does before calling main(). 197 */ 198 void 199 mach_init(int argc, char **argv, char **envp32, void *callvec) 200 { 201 struct gdium_config *gc = &gdium_configuration; 202 void *kernend; 203 #ifdef NOTYET 204 char *cp; 205 int howto; 206 #endif 207 int i; 208 psize_t memsize; 209 char *envp[128]; 210 int32_t *eptrs = (int32_t *)envp32; 211 extern char edata[], end[]; 212 213 /* 214 * Clear the BSS segment. 215 */ 216 kernend = (void *)mips_round_page(end); 217 memset(edata, 0, (char *)kernend - edata); 218 219 /* 220 * the pointer array in envp32 is 32bit - we need to sign extend them 221 * and put them into a list of actual pointers 222 * Only strictly necessary on LP64 but it doesn't hurt in LP32, runs only 223 * once at startup and I'd rather not pollute this file with another 224 * #ifdef orgy 225 */ 226 i = 0; 227 while (i < 128 && eptrs[i] != 0) { 228 envp[i] = (char *)(intptr_t)eptrs[i]; /* sign extend */ 229 i++; 230 } 231 232 /* 233 * Set up the exception vectors and CPU-specific function 234 * vectors early on. We need the wbflush() vector set up 235 * before comcnattach() is called (or at least before the 236 * first printf() after that is called). 237 * Also clears the I+D caches. 238 */ 239 mips_vector_init(NULL, false); 240 241 uvm_md_init(); 242 243 memsize = 256*1024*1024; 244 physmem = btoc(memsize); 245 246 bonito_pci_init(&gc->gc_pc, &gc->gc_bonito); 247 /* 248 * Override the null bonito_pci_attach_hook with our own to we can 249 * fix the ralink (device 13). 250 */ 251 gc->gc_pc.pc_attach_hook = gdium_pci_attach_hook; 252 gdium_bus_io_init(&gc->gc_iot, gc); 253 gdium_bus_mem_init(&gc->gc_memt, gc); 254 gdium_dma_init(gc); 255 gdium_cnattach(gc); 256 257 /* 258 * Disable the 2nd PCI window since we don't need it. 259 */ 260 mips3_sd(MIPS_PHYS_TO_KSEG1(BONITO_REGBASE + 0x158), 0xe); 261 pci_conf_write(&gc->gc_pc, pci_make_tag(&gc->gc_pc, 0, 0, 0), 18, 0); 262 263 /* 264 * Get the timer from PMON. 265 */ 266 for (i = 0; envp[i] != NULL; i++) { 267 if (!strncmp(envp[i], "cpuclock=", 9)) { 268 curcpu()->ci_cpu_freq = 269 strtoul(&envp[i][9], NULL, 10); 270 break; 271 } 272 } 273 274 if (mips_options.mips_cpu_flags & CPU_MIPS_DOUBLE_COUNT) 275 curcpu()->ci_cpu_freq /= 2; 276 277 /* Compute the number of ticks for hz. */ 278 curcpu()->ci_cycles_per_hz = (curcpu()->ci_cpu_freq + hz / 2) / hz; 279 280 /* Compute the delay divisor. */ 281 curcpu()->ci_divisor_delay = 282 ((curcpu()->ci_cpu_freq + 500000) / 1000000); 283 284 /* 285 * Get correct cpu frequency if the CPU runs at twice the 286 * external/cp0-count frequency. 287 */ 288 if (mips_options.mips_cpu_flags & CPU_MIPS_DOUBLE_COUNT) 289 curcpu()->ci_cpu_freq *= 2; 290 291 #ifdef DEBUG 292 printf("Timer calibration: %lu cycles/sec\n", 293 curcpu()->ci_cpu_freq); 294 #endif 295 296 #if NCOM > 0 297 /* 298 * Delay to allow firmware putchars to complete. 299 * FIFO depth * character time. 300 * character time = (1000000 / (defaultrate / 10)) 301 */ 302 delay(160000000 / comcnrate); 303 if (comcnattach(&gc->gc_iot, MALTA_UART0ADR, comcnrate, 304 COM_FREQ, COM_TYPE_NORMAL, 305 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8) != 0) 306 panic("malta: unable to initialize serial console"); 307 #endif /* NCOM > 0 */ 308 309 mem_clusters[0].start = 0; 310 mem_clusters[0].size = ctob(physmem); 311 mem_cluster_cnt = 1; 312 313 cpu_setmodel("Gdium Liberty 1000"); 314 315 /* 316 * XXX: check argv[0] - do something if "gdb"??? 317 */ 318 319 /* 320 * Look at arguments passed to us and compute boothowto. 321 */ 322 boothowto = RB_AUTOBOOT; 323 #ifdef NOTYET 324 for (i = 1; i < argc; i++) { 325 for (cp = argv[i]; *cp; cp++) { 326 /* Ignore superfluous '-', if there is one */ 327 if (*cp == '-') 328 continue; 329 330 howto = 0; 331 BOOT_FLAG(*cp, howto); 332 if (! howto) 333 printf("bootflag '%c' not recognised\n", *cp); 334 else 335 boothowto |= howto; 336 } 337 } 338 #endif 339 340 /* 341 * Load the rest of the available pages into the VM system. 342 */ 343 mips_page_physload(MIPS_KSEG0_START, (vaddr_t)kernend, 344 mem_clusters, mem_cluster_cnt, NULL, 0); 345 346 /* 347 * Initialize error message buffer (at end of core). 348 */ 349 mips_init_msgbuf(); 350 351 pmap_bootstrap(); 352 353 /* 354 * Allocate uarea page for lwp0 and set it. 355 */ 356 mips_init_lwp0_uarea(); 357 358 /* 359 * Initialize debuggers, and break into them, if appropriate. 360 */ 361 #if defined(DDB) 362 if (boothowto & RB_KDB) 363 Debugger(); 364 #endif 365 } 366 367 void 368 consinit(void) 369 { 370 371 /* 372 * Everything related to console initialization is done 373 * in mach_init(). 374 */ 375 } 376 377 /* 378 * Allocate memory for variable-sized tables, 379 */ 380 void 381 cpu_startup(void) 382 { 383 /* 384 * Do the common startup items. 385 */ 386 cpu_startup_common(); 387 388 /* 389 * Virtual memory is bootstrapped -- notify the bus spaces 390 * that memory allocation is now safe. 391 */ 392 gdium_configuration.gc_mallocsafe = 1; 393 394 } 395 396 int waittime = -1; 397 398 void 399 cpu_reboot(int howto, char *bootstr) 400 { 401 402 /* Take a snapshot before clobbering any registers. */ 403 savectx(curpcb); 404 405 if (cold) { 406 howto |= RB_HALT; 407 goto haltsys; 408 } 409 410 /* If "always halt" was specified as a boot flag, obey. */ 411 if (boothowto & RB_HALT) 412 howto |= RB_HALT; 413 414 boothowto = howto; 415 if ((howto & RB_NOSYNC) == 0 && (waittime < 0)) { 416 waittime = 0; 417 vfs_shutdown(); 418 } 419 420 splhigh(); 421 422 if (howto & RB_DUMP) 423 dumpsys(); 424 425 haltsys: 426 doshutdownhooks(); 427 428 pmf_system_shutdown(boothowto); 429 430 if ((howto & RB_POWERDOWN) == RB_POWERDOWN) { 431 /* 432 * Turning on GPIO1 as output will cause a powerdown. 433 */ 434 REGVAL(BONITO_GPIODATA) |= 2; 435 REGVAL(BONITO_GPIOIE) &= ~2; 436 } 437 438 if (howto & RB_HALT) { 439 printf("\n"); 440 printf("The operating system has halted.\n"); 441 printf("Please press any key to reboot.\n\n"); 442 cnpollc(1); /* For proper keyboard command handling */ 443 cngetc(); 444 cnpollc(0); 445 } 446 447 printf("%s\n\n", ((howto & RB_HALT) != 0) ? "halted." : "rebooting..."); 448 449 /* 450 * Turning off GPIO2 as output will cause a reset. 451 */ 452 REGVAL(BONITO_GPIODATA) &= ~4; 453 REGVAL(BONITO_GPIOIE) &= ~4; 454 455 __asm__ __volatile__ ( 456 "\t.long 0x3c02bfc0\n" 457 "\t.long 0x00400008\n" 458 ::: "v0"); 459 } 460