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