1 1.9 thorpej /* $NetBSD: machdep.c,v 1.9 2024/03/05 14:15:30 thorpej Exp $ */ 2 1.1 bouyer 3 1.1 bouyer /* 4 1.1 bouyer * Copyright 2001, 2002 Wasabi Systems, Inc. 5 1.1 bouyer * All rights reserved. 6 1.1 bouyer * 7 1.1 bouyer * Written by Jason R. Thorpe and Simon Burge for Wasabi Systems, Inc. 8 1.1 bouyer * 9 1.1 bouyer * Redistribution and use in source and binary forms, with or without 10 1.1 bouyer * modification, are permitted provided that the following conditions 11 1.1 bouyer * are met: 12 1.1 bouyer * 1. Redistributions of source code must retain the above copyright 13 1.1 bouyer * notice, this list of conditions and the following disclaimer. 14 1.1 bouyer * 2. Redistributions in binary form must reproduce the above copyright 15 1.1 bouyer * notice, this list of conditions and the following disclaimer in the 16 1.1 bouyer * documentation and/or other materials provided with the distribution. 17 1.1 bouyer * 3. All advertising materials mentioning features or use of this software 18 1.1 bouyer * must display the following acknowledgement: 19 1.1 bouyer * This product includes software developed for the NetBSD Project by 20 1.1 bouyer * Wasabi Systems, Inc. 21 1.1 bouyer * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 1.1 bouyer * or promote products derived from this software without specific prior 23 1.1 bouyer * written permission. 24 1.1 bouyer * 25 1.1 bouyer * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 1.1 bouyer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 1.1 bouyer * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 1.1 bouyer * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 1.1 bouyer * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 1.1 bouyer * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 1.1 bouyer * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 1.1 bouyer * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 1.1 bouyer * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 1.1 bouyer * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 1.1 bouyer * POSSIBILITY OF SUCH DAMAGE. 36 1.1 bouyer */ 37 1.1 bouyer 38 1.1 bouyer /* 39 1.1 bouyer * Copyright (c) 1988 University of Utah. 40 1.1 bouyer * Copyright (c) 1992, 1993 41 1.1 bouyer * The Regents of the University of California. All rights reserved. 42 1.1 bouyer * 43 1.1 bouyer * This code is derived from software contributed to Berkeley by 44 1.1 bouyer * the Systems Programming Group of the University of Utah Computer 45 1.1 bouyer * Science Department, The Mach Operating System project at 46 1.1 bouyer * Carnegie-Mellon University and Ralph Campbell. 47 1.1 bouyer * 48 1.1 bouyer * Redistribution and use in source and binary forms, with or without 49 1.1 bouyer * modification, are permitted provided that the following conditions 50 1.1 bouyer * are met: 51 1.1 bouyer * 1. Redistributions of source code must retain the above copyright 52 1.1 bouyer * notice, this list of conditions and the following disclaimer. 53 1.1 bouyer * 2. Redistributions in binary form must reproduce the above copyright 54 1.1 bouyer * notice, this list of conditions and the following disclaimer in the 55 1.1 bouyer * documentation and/or other materials provided with the distribution. 56 1.1 bouyer * 3. Neither the name of the University nor the names of its contributors 57 1.1 bouyer * may be used to endorse or promote products derived from this software 58 1.1 bouyer * without specific prior written permission. 59 1.1 bouyer * 60 1.1 bouyer * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 61 1.1 bouyer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 62 1.1 bouyer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 63 1.1 bouyer * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 64 1.1 bouyer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 65 1.1 bouyer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 66 1.1 bouyer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 67 1.1 bouyer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 68 1.1 bouyer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 69 1.1 bouyer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 70 1.1 bouyer * SUCH DAMAGE. 71 1.1 bouyer * 72 1.1 bouyer * @(#)machdep.c 8.3 (Berkeley) 1/12/94 73 1.1 bouyer * from: Utah Hdr: machdep.c 1.63 91/04/24 74 1.1 bouyer */ 75 1.1 bouyer 76 1.1 bouyer /* 77 1.1 bouyer * Copyright (c) 2009, 2010 Miodrag Vallat. 78 1.1 bouyer * 79 1.1 bouyer * Permission to use, copy, modify, and distribute this software for any 80 1.1 bouyer * purpose with or without fee is hereby granted, provided that the above 81 1.1 bouyer * copyright notice and this permission notice appear in all copies. 82 1.1 bouyer * 83 1.1 bouyer * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 84 1.1 bouyer * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 85 1.1 bouyer * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 86 1.1 bouyer * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 87 1.1 bouyer * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 88 1.1 bouyer * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 89 1.1 bouyer * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 90 1.1 bouyer */ 91 1.1 bouyer 92 1.1 bouyer #include <sys/cdefs.h> 93 1.9 thorpej __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.9 2024/03/05 14:15:30 thorpej Exp $"); 94 1.1 bouyer 95 1.1 bouyer #include "opt_ddb.h" 96 1.1 bouyer #include "opt_execfmt.h" 97 1.1 bouyer #include "opt_modular.h" 98 1.1 bouyer 99 1.1 bouyer #define _MIPS_BUS_DMA_PRIVATE 100 1.1 bouyer 101 1.1 bouyer #include <sys/param.h> 102 1.1 bouyer #include <sys/systm.h> 103 1.1 bouyer #include <sys/kernel.h> 104 1.1 bouyer #include <sys/buf.h> 105 1.1 bouyer #include <sys/reboot.h> 106 1.1 bouyer #include <sys/mount.h> 107 1.1 bouyer #include <sys/kcore.h> 108 1.1 bouyer #include <sys/boot_flag.h> 109 1.1 bouyer #include <sys/termios.h> 110 1.1 bouyer #include <sys/ksyms.h> 111 1.1 bouyer #include <sys/device.h> 112 1.6 christos #include <sys/cpu.h> 113 1.1 bouyer 114 1.1 bouyer #include <uvm/uvm_extern.h> 115 1.1 bouyer 116 1.1 bouyer #include <dev/cons.h> 117 1.1 bouyer 118 1.1 bouyer #include "ksyms.h" 119 1.1 bouyer 120 1.1 bouyer #if NKSYMS || defined(DDB) || defined(MODULAR) 121 1.1 bouyer #include <machine/db_machdep.h> 122 1.1 bouyer #include <ddb/db_extern.h> 123 1.1 bouyer #include <sys/exec_elf.h> 124 1.1 bouyer #endif 125 1.1 bouyer 126 1.1 bouyer #include <evbmips/loongson/autoconf.h> 127 1.1 bouyer #include <evbmips/loongson/loongson_intr.h> 128 1.1 bouyer #include <evbmips/loongson/loongson_bus_defs.h> 129 1.1 bouyer #include <machine/cpu.h> 130 1.1 bouyer #include <machine/psl.h> 131 1.1 bouyer 132 1.1 bouyer #include <mips/locore.h> 133 1.1 bouyer 134 1.1 bouyer #include <mips/bonito/bonitoreg.h> 135 1.1 bouyer #include <mips/bonito/bonitovar.h> 136 1.1 bouyer #include <mips/pmon/pmon.h> 137 1.4 nonaka 138 1.4 nonaka #include "sisfb.h" 139 1.4 nonaka #if NSISFB > 0 140 1.1 bouyer #include <dev/pci/sisfb.h> 141 1.4 nonaka #endif 142 1.4 nonaka 143 1.4 nonaka #include "lynxfb.h" 144 1.4 nonaka #if NLYNXFB > 0 145 1.4 nonaka #include <dev/pci/lynxfbvar.h> 146 1.4 nonaka #endif 147 1.4 nonaka 148 1.4 nonaka #include "pckbc.h" 149 1.4 nonaka #if NPCKBC > 0 150 1.4 nonaka #include <dev/isa/isareg.h> 151 1.4 nonaka #include <dev/ic/i8042reg.h> 152 1.4 nonaka #include <dev/ic/pckbcvar.h> 153 1.4 nonaka #endif 154 1.4 nonaka #include "pckbd.h" 155 1.4 nonaka #include "ukbd.h" 156 1.4 nonaka #if NUKBD > 0 157 1.4 nonaka #include <dev/usb/ukbdvar.h> 158 1.4 nonaka #endif 159 1.4 nonaka #if NPCKBD > 0 || NUKBD > 0 160 1.4 nonaka #include <dev/wscons/wskbdvar.h> 161 1.4 nonaka #endif 162 1.1 bouyer 163 1.1 bouyer #include "com.h" 164 1.1 bouyer #if NCOM > 0 165 1.1 bouyer #include <dev/ic/comreg.h> 166 1.1 bouyer #include <dev/ic/comvar.h> 167 1.1 bouyer 168 1.2 macallan bus_space_tag_t comconsiot; 169 1.2 macallan bus_addr_t comconsaddr; 170 1.2 macallan int comconsrate = 0; 171 1.2 macallan #endif /* NCOM > 0 */ 172 1.2 macallan 173 1.1 bouyer #ifdef LOW_DEBUG 174 1.1 bouyer #define DPRINTF(x) printf x 175 1.1 bouyer #define DPPRINTF(x) pmon_printf x 176 1.1 bouyer #else 177 1.1 bouyer #define DPRINTF(x) 178 1.1 bouyer #define DPPRINTF(x) 179 1.1 bouyer #endif 180 1.1 bouyer 181 1.1 bouyer 182 1.1 bouyer int ex_mallocsafe = 0; 183 1.1 bouyer struct extent *loongson_io_ex = NULL; 184 1.1 bouyer struct extent *loongson_mem_ex = NULL; 185 1.1 bouyer struct mips_bus_space bonito_iot; 186 1.1 bouyer struct mips_bus_space bonito_memt; 187 1.1 bouyer struct mips_bus_dma_tag bonito_dmat; 188 1.1 bouyer struct mips_pci_chipset bonito_pc; 189 1.1 bouyer 190 1.1 bouyer uint loongson_ver; 191 1.1 bouyer 192 1.1 bouyer const struct platform *sys_platform; 193 1.1 bouyer struct bonito_flavour { 194 1.1 bouyer const char *prefix; 195 1.1 bouyer const struct platform *platform; 196 1.1 bouyer }; 197 1.1 bouyer 198 1.1 bouyer extern const struct platform fuloong_platform; 199 1.1 bouyer extern const struct platform gdium_platform; 200 1.1 bouyer extern const struct platform generic2e_platform; 201 1.1 bouyer extern const struct platform lynloong_platform; 202 1.1 bouyer extern const struct platform yeeloong_platform; 203 1.1 bouyer 204 1.1 bouyer const struct bonito_flavour bonito_flavours[] = { 205 1.1 bouyer /* Lemote Fuloong 2F mini-PC */ 206 1.1 bouyer { "LM6002", &fuloong_platform }, /* dual Ethernet, no prefix */ 207 1.1 bouyer { "LM6003", &fuloong_platform }, 208 1.1 bouyer { "LM6004", &fuloong_platform }, 209 1.1 bouyer /* EMTEC Gdium Liberty 1000 */ 210 1.1 bouyer { "Gdium", &gdium_platform }, 211 1.1 bouyer /* Lemote Yeeloong 8.9" netbook */ 212 1.1 bouyer { "LM8089", &yeeloong_platform }, 213 1.1 bouyer /* supposedly Lemote Yeeloong 10.1" netbook, but those found so far 214 1.1 bouyer report themselves as LM8089 */ 215 1.1 bouyer { "LM8101", &yeeloong_platform }, 216 1.1 bouyer /* Lemote Lynloong all-in-one computer */ 217 1.1 bouyer { "LM9001", &lynloong_platform }, 218 1.1 bouyer { NULL } 219 1.1 bouyer }; 220 1.1 bouyer 221 1.1 bouyer /* Maps for VM objects. */ 222 1.1 bouyer struct vm_map *phys_map = NULL; 223 1.1 bouyer 224 1.1 bouyer int netboot; /* Are we netbooting? */ 225 1.1 bouyer 226 1.1 bouyer phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 227 1.1 bouyer int mem_cluster_cnt; 228 1.1 bouyer 229 1.1 bouyer void mach_init(int, int32_t, int32_t, int32_t, char *); 230 1.1 bouyer 231 1.1 bouyer static int pmoncngetc(dev_t); 232 1.1 bouyer static void pmoncnputc(dev_t, int); 233 1.1 bouyer 234 1.1 bouyer struct consdev pmoncons = { 235 1.1 bouyer NULL, /* probe */ 236 1.1 bouyer NULL, /* init */ 237 1.1 bouyer pmoncngetc, /* getc */ 238 1.1 bouyer pmoncnputc, /* putc */ 239 1.1 bouyer nullcnpollc, /* poolc */ 240 1.1 bouyer NULL, /* BELL */ 241 1.1 bouyer makedev(0, 0), 242 1.1 bouyer CN_DEAD 243 1.1 bouyer }; 244 1.1 bouyer 245 1.8 simonb /* The LOONGSON kernels only support little endian */ 246 1.8 simonb CTASSERT(_BYTE_ORDER == _LITTLE_ENDIAN); 247 1.8 simonb 248 1.1 bouyer /* 249 1.1 bouyer * Do all the stuff that locore normally does before calling main(). 250 1.1 bouyer */ 251 1.1 bouyer void 252 1.1 bouyer mach_init(int32_t argc, int32_t argva, int32_t enva, int32_t callvec, 253 1.1 bouyer char *boot_esym) 254 1.1 bouyer { 255 1.1 bouyer void *kernend; 256 1.1 bouyer #ifdef NOTYET 257 1.1 bouyer int howto; 258 1.1 bouyer #endif 259 1.1 bouyer const char *env; 260 1.1 bouyer int i; 261 1.1 bouyer psize_t memlo, memhi; 262 1.1 bouyer const struct bonito_flavour *f; 263 1.1 bouyer char *ssym = NULL, *esym = NULL; 264 1.1 bouyer pcireg_t reg; 265 1.1 bouyer pcitag_t pcitag; 266 1.1 bouyer 267 1.1 bouyer extern char edata[], end[]; 268 1.1 bouyer 269 1.1 bouyer /* 270 1.1 bouyer * Clear the BSS segment. 271 1.1 bouyer */ 272 1.1 bouyer memset(edata, 0, (char *)end - edata); 273 1.1 bouyer 274 1.1 bouyer pmon_init(argc, argva, enva, callvec); 275 1.1 bouyer DPPRINTF(("pmon hello\n")); 276 1.1 bouyer 277 1.1 bouyer cn_tab = &pmoncons; 278 1.1 bouyer 279 1.1 bouyer DPRINTF(("hello 0x%x %d 0x%x 0x%x %p stack %p\n", pmon_callvec, argc, argva, enva, boot_esym, &i)); 280 1.1 bouyer 281 1.1 bouyer /* 282 1.1 bouyer * Reserve space for the symbol table, if it exists. 283 1.1 bouyer */ 284 1.1 bouyer 285 1.1 bouyer #if NKSYMS || defined(DDB) || defined(MODULAR) 286 1.1 bouyer /* Attempt to locate ELF header and symbol table after kernel. */ 287 1.1 bouyer if (end[0] == ELFMAG0 && end[1] == ELFMAG1 && 288 1.1 bouyer end[2] == ELFMAG2 && end[3] == ELFMAG3) { 289 1.1 bouyer /* ELF header exists directly after kernel. */ 290 1.1 bouyer ssym = end; 291 1.1 bouyer esym = boot_esym; 292 1.1 bouyer kernend = (void *)mips_round_page(esym); 293 1.1 bouyer } else { 294 1.1 bouyer ssym = (char *)(vaddr_t)*(int32_t *)end; 295 1.1 bouyer if (((long)ssym - (long)end) >= 0 && 296 1.1 bouyer ((long)ssym - (long)end) <= 0x1000 && 297 1.1 bouyer ssym[0] == ELFMAG0 && ssym[1] == ELFMAG1 && 298 1.1 bouyer ssym[2] == ELFMAG2 && ssym[3] == ELFMAG3) { 299 1.1 bouyer /* Pointers exist directly after kernel. */ 300 1.1 bouyer esym = (char *)(vaddr_t)*((int32_t *)end + 1); 301 1.1 bouyer kernend = (void *)mips_round_page(esym); 302 1.1 bouyer } else { 303 1.1 bouyer /* Pointers aren't setup either... */ 304 1.1 bouyer ssym = NULL; 305 1.1 bouyer esym = NULL; 306 1.1 bouyer kernend = (void *)mips_round_page(end); 307 1.1 bouyer } 308 1.1 bouyer } 309 1.1 bouyer DPRINTF(("ssym %p esym %p\n", ssym, esym)); 310 1.1 bouyer #endif 311 1.1 bouyer 312 1.1 bouyer /* 313 1.1 bouyer * Set up the exception vectors and CPU-specific function 314 1.1 bouyer * vectors early on. We need the wbflush() vector set up 315 1.1 bouyer * before comcnattach() is called (or at least before the 316 1.1 bouyer * first printf() after that is called). 317 1.1 bouyer * Also clears the I+D caches. 318 1.1 bouyer */ 319 1.1 bouyer DPRINTF(("mips_vector_init ")); 320 1.1 bouyer mips_vector_init(NULL, false); 321 1.1 bouyer 322 1.7 cherry DPRINTF(("uvm_md_init\n")); 323 1.7 cherry uvm_md_init(); 324 1.1 bouyer #if NKSYMS || defined(DDB) || defined(MODULAR) 325 1.1 bouyer //ksyms_addsyms_elf((vaddr_t)esym - (vaddr_t)ssym, ssym, esym); 326 1.1 bouyer #endif 327 1.1 bouyer 328 1.1 bouyer /* 329 1.1 bouyer * Try and figure out what kind of hardware we are. 330 1.1 bouyer */ 331 1.1 bouyer 332 1.1 bouyer env = pmon_getenv("systype"); 333 1.1 bouyer if (env == NULL) { 334 1.1 bouyer printf("Unable to figure out system type!\n"); 335 1.1 bouyer goto unsupported; 336 1.1 bouyer } 337 1.1 bouyer if (strcmp(env, "Bonito") != 0) { 338 1.1 bouyer printf("This kernel doesn't support system type \"%s\".\n", 339 1.1 bouyer env); 340 1.1 bouyer goto unsupported; 341 1.1 bouyer } 342 1.1 bouyer 343 1.1 bouyer /* 344 1.1 bouyer * While the kernel supports other processor types than Loongson, 345 1.1 bouyer * we are not expecting a Bonito-based system with a different 346 1.1 bouyer * processor. Just to be on the safe side, refuse to run on 347 1.1 bouyer * non Loongson2 processors for now. 348 1.1 bouyer */ 349 1.1 bouyer 350 1.1 bouyer switch ((mips_options.mips_cpu_id >> 8) & 0xff) { 351 1.1 bouyer case MIPS_LOONGSON2: 352 1.1 bouyer switch (mips_options.mips_cpu_id & 0xff) { 353 1.1 bouyer case 0x00: 354 1.1 bouyer loongson_ver = 0x2c; 355 1.1 bouyer break; 356 1.1 bouyer case 0x02: 357 1.1 bouyer loongson_ver = 0x2e; 358 1.1 bouyer break; 359 1.1 bouyer case 0x03: 360 1.1 bouyer loongson_ver = 0x2f; 361 1.1 bouyer break; 362 1.1 bouyer case 0x05: 363 1.1 bouyer loongson_ver = 0x3a; 364 1.1 bouyer break; 365 1.1 bouyer } 366 1.1 bouyer if (loongson_ver == 0x2e || loongson_ver == 0x2f) 367 1.1 bouyer break; 368 1.1 bouyer /* FALLTHROUGH */ 369 1.1 bouyer default: 370 1.1 bouyer printf("This kernel doesn't support processor type 0x%x" 371 1.1 bouyer ", version %d.%d.\n", 372 1.1 bouyer (mips_options.mips_cpu_id >> 8) & 0xff, 373 1.1 bouyer (mips_options.mips_cpu_id >> 4) & 0x0f, 374 1.1 bouyer mips_options.mips_cpu_id & 0x0f); 375 1.1 bouyer goto unsupported; 376 1.1 bouyer } 377 1.1 bouyer 378 1.1 bouyer /* 379 1.1 bouyer * Try to figure out what particular machine we run on, depending 380 1.1 bouyer * on the PMON version information. 381 1.1 bouyer */ 382 1.1 bouyer 383 1.1 bouyer env = pmon_getenv("Version"); 384 1.1 bouyer if (env == NULL) { 385 1.1 bouyer /* 386 1.1 bouyer * If this is a 2E system, use the generic code and hope 387 1.1 bouyer * for the best. 388 1.1 bouyer */ 389 1.1 bouyer if (loongson_ver == 0x2e) { 390 1.1 bouyer sys_platform = &generic2e_platform; 391 1.1 bouyer } else { 392 1.1 bouyer printf("Unable to figure out model!\n"); 393 1.1 bouyer goto unsupported; 394 1.1 bouyer } 395 1.1 bouyer } else { 396 1.1 bouyer for (f = bonito_flavours; f->prefix != NULL; f++) 397 1.1 bouyer if (strncmp(env, f->prefix, strlen(f->prefix)) == 398 1.1 bouyer 0) { 399 1.1 bouyer sys_platform = f->platform; 400 1.1 bouyer break; 401 1.1 bouyer } 402 1.1 bouyer 403 1.1 bouyer if (sys_platform == NULL) { 404 1.1 bouyer /* 405 1.1 bouyer * Early Lemote designs shipped without a model prefix. 406 1.1 bouyer * Hopefully these well be close enough to the first 407 1.1 bouyer * generation Fuloong 2F design (LM6002); let's warn 408 1.1 bouyer * the user and try this if version is 1.2.something 409 1.1 bouyer * (1.3 onwards are expected to have a model prefix, 410 1.1 bouyer * and there are currently no reports of 1.1 and 411 1.1 bouyer * below being 2F systems). 412 1.1 bouyer * 413 1.1 bouyer * Note that this could be handled by adding a 414 1.1 bouyer * "1.2." machine type entry to the flavours table, 415 1.1 bouyer * but I prefer have it stand out. 416 1.1 bouyer * LM6002 users are encouraged to add the system 417 1.1 bouyer * model prefix to the `Version' variable. 418 1.1 bouyer */ 419 1.1 bouyer if (strncmp(env, "1.2.", 4) == 0) { 420 1.1 bouyer printf("No model prefix in version" 421 1.1 bouyer " string \"%s\".\n" 422 1.1 bouyer "Attempting to match as Lemote Fuloong\n", 423 1.1 bouyer env); 424 1.1 bouyer sys_platform = &fuloong_platform; 425 1.1 bouyer } 426 1.1 bouyer } 427 1.1 bouyer 428 1.1 bouyer if (sys_platform == NULL) { 429 1.1 bouyer printf("This kernel doesn't support model \"%s\"." 430 1.1 bouyer "\n", env); 431 1.1 bouyer goto unsupported; 432 1.1 bouyer } 433 1.1 bouyer } 434 1.1 bouyer 435 1.6 christos cpu_setmodel("%s %s", sys_platform->vendor, sys_platform->product); 436 1.6 christos DPRINTF(("Found %s, setting up.\n", cpu_getmodel())); 437 1.1 bouyer 438 1.1 bouyer /* 439 1.1 bouyer * Figure out memory information. 440 1.1 bouyer * PMON reports it in two chunks, the memory under the 256MB 441 1.1 bouyer * CKSEG limit, and memory above that limit. We need to do the 442 1.1 bouyer * math ourselves. 443 1.1 bouyer */ 444 1.1 bouyer 445 1.1 bouyer env = pmon_getenv("memsize"); 446 1.1 bouyer if (env == NULL) { 447 1.1 bouyer printf("Could not get memory information" 448 1.1 bouyer " from the firmware\n"); 449 1.1 bouyer goto unsupported; 450 1.1 bouyer } 451 1.1 bouyer memlo = strtoul(env, NULL, 10); /* size in MB */ 452 1.1 bouyer DPRINTF(("memlo %" PRIdPSIZE, memlo)); 453 1.1 bouyer if (memlo < 0 || memlo > 256) { 454 1.1 bouyer printf("Incorrect low memory size `%s'\n", env); 455 1.1 bouyer goto unsupported; 456 1.1 bouyer } 457 1.1 bouyer 458 1.1 bouyer /* 3A PMON only reports up to 240MB as low memory */ 459 1.1 bouyer if (memlo >= 240) { 460 1.1 bouyer env = pmon_getenv("highmemsize"); 461 1.1 bouyer if (env == NULL) 462 1.1 bouyer memhi = 0; 463 1.1 bouyer else 464 1.1 bouyer memhi = strtoul(env, NULL, 10); /* size in MB */ 465 1.1 bouyer if (memhi < 0 || memhi > (64 * 1024) - 256) { 466 1.1 bouyer printf("Incorrect high memory size `%s'\n", 467 1.1 bouyer env); 468 1.1 bouyer /* better expose the problem than limit to 256MB */ 469 1.1 bouyer goto unsupported; 470 1.1 bouyer } 471 1.1 bouyer } else 472 1.1 bouyer memhi = 0; 473 1.1 bouyer 474 1.1 bouyer DPRINTF(("memhi %" PRIdPSIZE "\n", memhi)); 475 1.1 bouyer memlo = memlo * 1024 * 1024; 476 1.1 bouyer memhi = memhi * 1024 * 1024; 477 1.1 bouyer 478 1.1 bouyer switch (loongson_ver) { 479 1.1 bouyer case 0x2e: 480 1.1 bouyer loongson2e_setup(memlo, memhi, 481 1.1 bouyer MIPS_KSEG0_START, (vaddr_t)kernend, &bonito_dmat); 482 1.1 bouyer break; 483 1.1 bouyer default: 484 1.1 bouyer case 0x2f: 485 1.1 bouyer case 0x3a: 486 1.1 bouyer loongson2f_setup(memlo, memhi, 487 1.1 bouyer MIPS_KSEG0_START, (vaddr_t)kernend, &bonito_dmat); 488 1.1 bouyer break; 489 1.1 bouyer } 490 1.1 bouyer 491 1.1 bouyer DPRINTF(("bonito_pci_init ")); 492 1.1 bouyer bonito_pci_init(&bonito_pc, sys_platform->bonito_config); 493 1.1 bouyer bonito_pc.pc_intr_v = __UNCONST(sys_platform->bonito_config); 494 1.1 bouyer bonito_pc.pc_intr_map = loongson_pci_intr_map; 495 1.1 bouyer bonito_pc.pc_intr_string = loongson_pci_intr_string; 496 1.1 bouyer bonito_pc.pc_intr_evcnt = loongson_pci_intr_evcnt; 497 1.1 bouyer bonito_pc.pc_intr_establish = loongson_pci_intr_establish; 498 1.1 bouyer bonito_pc.pc_intr_disestablish = loongson_pci_intr_disestablish; 499 1.1 bouyer bonito_pc.pc_conf_interrupt = loongson_pci_conf_interrupt; 500 1.1 bouyer bonito_pc.pc_pciide_compat_intr_establish = 501 1.1 bouyer loongson_pciide_compat_intr_establish; 502 1.1 bouyer DPRINTF(("bonito_bus_io_init ")); 503 1.1 bouyer bonito_bus_io_init(&bonito_iot, NULL); 504 1.4 nonaka /* override mapping function */ 505 1.4 nonaka bonito_iot.bs_map = bonito_bus_io_legacy_map; 506 1.1 bouyer DPRINTF(("bonito_bus_mem_init\n")); 507 1.1 bouyer bonito_bus_mem_init(&bonito_memt, NULL); 508 1.1 bouyer 509 1.1 bouyer bonito_dmat._cookie = __UNCONST(sys_platform); 510 1.1 bouyer bonito_dmat._dmamap_ops = mips_bus_dmamap_ops; 511 1.1 bouyer bonito_dmat._dmamem_ops = mips_bus_dmamem_ops; 512 1.1 bouyer bonito_dmat._dmatag_ops = mips_bus_dmatag_ops; 513 1.1 bouyer 514 1.1 bouyer DPRINTF(("sys_platform->setup %p\n", sys_platform->setup)); 515 1.1 bouyer if (sys_platform->setup != NULL) 516 1.1 bouyer (*(sys_platform->setup))(); 517 1.1 bouyer 518 1.1 bouyer #if NCOM > 0 519 1.1 bouyer DPRINTF(("comconsrate %d\n", comconsrate)); 520 1.1 bouyer if (comconsrate > 0) { 521 1.1 bouyer if (comcnattach(comconsiot, comconsaddr, comconsrate, 522 1.1 bouyer COM_FREQ, COM_TYPE_NORMAL, 523 1.1 bouyer (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8) != 0) 524 1.1 bouyer panic("unable to initialize serial console"); 525 1.1 bouyer } 526 1.1 bouyer #endif /* NCOM > 0 */ 527 1.1 bouyer 528 1.1 bouyer for (i = 0; i < 32 - 0x11; i++) { 529 1.1 bouyer pcitag = pci_make_tag(&bonito_pc, 0, i, 0); 530 1.1 bouyer reg = pci_conf_read(&bonito_pc, pcitag, PCI_CLASS_REG); 531 1.1 bouyer DPRINTF(("dev %d class 0x%x", i, reg)); 532 1.1 bouyer reg = pci_conf_read(&bonito_pc, pcitag, PCI_ID_REG); 533 1.1 bouyer DPRINTF((" id 0x%x; ", reg)); 534 1.1 bouyer #if NSISFB > 0 535 1.1 bouyer if (cn_tab == &pmoncons) 536 1.4 nonaka sisfb_cnattach(&bonito_memt, &bonito_iot, &bonito_pc, 537 1.4 nonaka pcitag, reg); 538 1.4 nonaka #endif 539 1.4 nonaka #if NLYNXFB > 0 540 1.4 nonaka if (cn_tab == &pmoncons) 541 1.4 nonaka lynxfb_cnattach(&bonito_memt, &bonito_iot, &bonito_pc, 542 1.1 bouyer pcitag, reg); 543 1.1 bouyer #endif 544 1.3 macallan if (cn_tab == &pmoncons) 545 1.4 nonaka gdium_cnattach(&bonito_memt, &bonito_iot, &bonito_pc, 546 1.3 macallan pcitag, reg); 547 1.4 nonaka if (cn_tab != &pmoncons) 548 1.4 nonaka break; 549 1.1 bouyer } 550 1.4 nonaka #if NPCKBC > 0 || NUKBD > 0 551 1.4 nonaka if (cn_tab != &pmoncons) { 552 1.4 nonaka int rc = ENXIO; 553 1.4 nonaka #if NPCKBC > 0 554 1.4 nonaka if (rc != 0) 555 1.5 jdc rc = pckbc_cnattach(&bonito_iot, IO_KBD, KBCMDP, 0, 0); 556 1.4 nonaka #endif 557 1.4 nonaka #if NUKBD > 0 558 1.4 nonaka if (rc != 0) 559 1.4 nonaka rc = ukbd_cnattach(); 560 1.4 nonaka #endif 561 1.4 nonaka } 562 1.4 nonaka #endif /* NPCKBC > 0 || NUKBD > 0 */ 563 1.1 bouyer DPRINTF(("\n")); 564 1.1 bouyer 565 1.1 bouyer /* 566 1.1 bouyer * Get the timer from PMON. 567 1.1 bouyer */ 568 1.1 bouyer DPRINTF(("search cpuclock ")); 569 1.1 bouyer env = pmon_getenv("cpuclock"); 570 1.1 bouyer DPRINTF(("got %s ", env)); 571 1.1 bouyer if (env != NULL) { 572 1.1 bouyer curcpu()->ci_cpu_freq = 573 1.1 bouyer strtoul(env, NULL, 10); 574 1.1 bouyer } 575 1.1 bouyer 576 1.1 bouyer DPRINTF(("cpuclock %ld\n", curcpu()->ci_cpu_freq)); 577 1.1 bouyer 578 1.1 bouyer if (mips_options.mips_cpu_flags & CPU_MIPS_DOUBLE_COUNT) 579 1.1 bouyer curcpu()->ci_cpu_freq /= 2; 580 1.1 bouyer 581 1.1 bouyer 582 1.1 bouyer /* Compute the number of ticks for hz. */ 583 1.1 bouyer curcpu()->ci_cycles_per_hz = (curcpu()->ci_cpu_freq + hz / 2) / hz; 584 1.1 bouyer 585 1.1 bouyer /* Compute the delay divisor. */ 586 1.1 bouyer curcpu()->ci_divisor_delay = 587 1.1 bouyer ((curcpu()->ci_cpu_freq + 500000) / 1000000); 588 1.1 bouyer 589 1.1 bouyer /* 590 1.1 bouyer * Get correct cpu frequency if the CPU runs at twice the 591 1.1 bouyer * external/cp0-count frequency. 592 1.1 bouyer */ 593 1.1 bouyer if (mips_options.mips_cpu_flags & CPU_MIPS_DOUBLE_COUNT) 594 1.1 bouyer curcpu()->ci_cpu_freq *= 2; 595 1.1 bouyer 596 1.1 bouyer #ifdef DEBUG 597 1.1 bouyer printf("Timer calibration: %lu cycles/sec\n", 598 1.1 bouyer curcpu()->ci_cpu_freq); 599 1.1 bouyer #endif 600 1.1 bouyer 601 1.1 bouyer #if NCOM > 0 && 0 602 1.1 bouyer /* 603 1.1 bouyer * Delay to allow firmware putchars to complete. 604 1.1 bouyer * FIFO depth * character time. 605 1.1 bouyer * character time = (1000000 / (defaultrate / 10)) 606 1.1 bouyer */ 607 1.1 bouyer delay(160000000 / comcnrate); 608 1.1 bouyer if (comcnattach(&gc->gc_iot, MALTA_UART0ADR, comcnrate, 609 1.1 bouyer COM_FREQ, COM_TYPE_NORMAL, 610 1.1 bouyer (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8) != 0) 611 1.1 bouyer panic("malta: unable to initialize serial console"); 612 1.1 bouyer #endif /* NCOM > 0 */ 613 1.1 bouyer 614 1.1 bouyer /* 615 1.1 bouyer * XXX: check argv[0] - do something if "gdb"??? 616 1.1 bouyer */ 617 1.1 bouyer 618 1.1 bouyer /* 619 1.1 bouyer * Look at arguments passed to us and compute boothowto. 620 1.1 bouyer */ 621 1.1 bouyer boothowto = RB_AUTOBOOT; 622 1.1 bouyer #ifdef NOTYET 623 1.1 bouyer for (i = 1; i < argc; i++) { 624 1.1 bouyer for (cp = argv[i]; *cp; cp++) { 625 1.1 bouyer /* Ignore superfluous '-', if there is one */ 626 1.1 bouyer if (*cp == '-') 627 1.1 bouyer continue; 628 1.1 bouyer 629 1.1 bouyer howto = 0; 630 1.1 bouyer BOOT_FLAG(*cp, howto); 631 1.1 bouyer if (! howto) 632 1.1 bouyer printf("bootflag '%c' not recognised\n", *cp); 633 1.1 bouyer else 634 1.1 bouyer boothowto |= howto; 635 1.1 bouyer } 636 1.1 bouyer } 637 1.1 bouyer #endif 638 1.1 bouyer 639 1.1 bouyer /* 640 1.1 bouyer * Load the rest of the available pages into the VM system. 641 1.1 bouyer */ 642 1.1 bouyer mips_page_physload(MIPS_KSEG0_START, (vaddr_t)kernend, 643 1.1 bouyer mem_clusters, mem_cluster_cnt, NULL, 0); 644 1.1 bouyer 645 1.1 bouyer /* 646 1.1 bouyer * Initialize error message buffer (at end of core). 647 1.1 bouyer */ 648 1.1 bouyer DPRINTF(("mips_init_msgbuf\n")); 649 1.1 bouyer mips_init_msgbuf(); 650 1.1 bouyer 651 1.1 bouyer DPRINTF(("pmap_bootstrap\n")); 652 1.1 bouyer pmap_bootstrap(); 653 1.1 bouyer 654 1.1 bouyer /* 655 1.1 bouyer * Allocate uarea page for lwp0 and set it. 656 1.1 bouyer */ 657 1.1 bouyer DPRINTF(("curlwp %p ", curlwp)); 658 1.1 bouyer DPRINTF(("curlwp stack %p\n", curlwp->l_addr)); 659 1.1 bouyer mips_init_lwp0_uarea(); 660 1.1 bouyer 661 1.1 bouyer DPRINTF(("curlwp %p ", curlwp)); 662 1.1 bouyer DPRINTF(("curlwp stack %p\n", curlwp->l_addr)); 663 1.1 bouyer 664 1.1 bouyer /* 665 1.1 bouyer * Initialize debuggers, and break into them, if appropriate. 666 1.1 bouyer */ 667 1.1 bouyer #if defined(DDB) 668 1.1 bouyer if (boothowto & RB_KDB) 669 1.1 bouyer Debugger(); 670 1.1 bouyer #endif 671 1.1 bouyer DPRINTF(("return\n")); 672 1.1 bouyer return; 673 1.1 bouyer unsupported: 674 1.1 bouyer panic("unsupported hardware\n"); 675 1.1 bouyer } 676 1.1 bouyer 677 1.1 bouyer void 678 1.1 bouyer consinit(void) 679 1.1 bouyer { 680 1.1 bouyer 681 1.1 bouyer /* 682 1.1 bouyer * Everything related to console initialization is done 683 1.1 bouyer * in mach_init(). 684 1.1 bouyer */ 685 1.1 bouyer } 686 1.1 bouyer 687 1.1 bouyer /* 688 1.1 bouyer * Allocate memory for variable-sized tables, 689 1.1 bouyer */ 690 1.1 bouyer void 691 1.1 bouyer cpu_startup(void) 692 1.1 bouyer { 693 1.1 bouyer /* 694 1.1 bouyer * Do the common startup items. 695 1.1 bouyer */ 696 1.1 bouyer cpu_startup_common(); 697 1.1 bouyer 698 1.1 bouyer /* 699 1.1 bouyer * Virtual memory is bootstrapped -- notify the bus spaces 700 1.1 bouyer * that memory allocation is now safe. 701 1.1 bouyer */ 702 1.1 bouyer ex_mallocsafe = 1; 703 1.1 bouyer } 704 1.1 bouyer 705 1.1 bouyer int waittime = -1; 706 1.1 bouyer 707 1.1 bouyer void 708 1.1 bouyer cpu_reboot(int howto, char *bootstr) 709 1.1 bouyer { 710 1.1 bouyer 711 1.1 bouyer /* Take a snapshot before clobbering any registers. */ 712 1.1 bouyer savectx(curpcb); 713 1.1 bouyer 714 1.1 bouyer if (cold) { 715 1.1 bouyer howto |= RB_HALT; 716 1.1 bouyer goto haltsys; 717 1.1 bouyer } 718 1.1 bouyer 719 1.1 bouyer /* If "always halt" was specified as a boot flag, obey. */ 720 1.1 bouyer if (boothowto & RB_HALT) 721 1.1 bouyer howto |= RB_HALT; 722 1.1 bouyer 723 1.1 bouyer boothowto = howto; 724 1.1 bouyer if ((howto & RB_NOSYNC) == 0 && (waittime < 0)) { 725 1.1 bouyer waittime = 0; 726 1.1 bouyer vfs_shutdown(); 727 1.1 bouyer } 728 1.1 bouyer 729 1.1 bouyer splhigh(); 730 1.1 bouyer 731 1.1 bouyer if (howto & RB_DUMP) 732 1.1 bouyer dumpsys(); 733 1.1 bouyer 734 1.1 bouyer haltsys: 735 1.1 bouyer doshutdownhooks(); 736 1.1 bouyer 737 1.1 bouyer pmf_system_shutdown(boothowto); 738 1.1 bouyer 739 1.1 bouyer if ((howto & RB_POWERDOWN) == RB_POWERDOWN) { 740 1.1 bouyer if (sys_platform->powerdown != NULL) 741 1.1 bouyer sys_platform->powerdown(); 742 1.1 bouyer } 743 1.1 bouyer 744 1.1 bouyer if (howto & RB_HALT) { 745 1.1 bouyer printf("\n"); 746 1.1 bouyer printf("The operating system has halted.\n"); 747 1.1 bouyer printf("Please press any key to reboot.\n\n"); 748 1.1 bouyer cnpollc(1); /* For proper keyboard command handling */ 749 1.1 bouyer cngetc(); 750 1.1 bouyer cnpollc(0); 751 1.1 bouyer } 752 1.1 bouyer 753 1.1 bouyer printf("%s\n\n", ((howto & RB_HALT) != 0) ? "halted." : "rebooting..."); 754 1.1 bouyer 755 1.1 bouyer if (sys_platform->reset != NULL) 756 1.1 bouyer sys_platform->reset(); 757 1.1 bouyer 758 1.1 bouyer __asm__ __volatile__ ( 759 1.1 bouyer "\t.long 0x3c02bfc0\n" 760 1.1 bouyer "\t.long 0x00400008\n" 761 1.1 bouyer ::: "v0"); 762 1.1 bouyer } 763 1.1 bouyer 764 1.1 bouyer /* 765 1.1 bouyer * Early console through pmon routines. 766 1.1 bouyer */ 767 1.1 bouyer 768 1.1 bouyer int 769 1.1 bouyer pmoncngetc(dev_t dev) 770 1.1 bouyer { 771 1.1 bouyer /* 772 1.1 bouyer * PMON does not give us a getc routine. So try to get a whole line 773 1.1 bouyer * and return it char by char, trying not to lose the \n. Kind 774 1.1 bouyer * of ugly but should work. 775 1.1 bouyer * 776 1.1 bouyer * Note that one could theoretically use pmon_read(STDIN, &c, 1) 777 1.1 bouyer * but the value of STDIN within PMON is not a constant and there 778 1.1 bouyer * does not seem to be a way of letting us know which value to use. 779 1.1 bouyer */ 780 1.1 bouyer static char buf[1 + PMON_MAXLN]; 781 1.1 bouyer static char *bufpos = buf; 782 1.1 bouyer int c; 783 1.1 bouyer 784 1.1 bouyer if (*bufpos == '\0') { 785 1.1 bouyer bufpos = buf; 786 1.1 bouyer if (pmon_gets(buf) == NULL) { 787 1.1 bouyer /* either an empty line or EOF. assume the former */ 788 1.1 bouyer return (int)'\n'; 789 1.1 bouyer } else { 790 1.1 bouyer /* put back the \n sign */ 791 1.1 bouyer buf[strlen(buf)] = '\n'; 792 1.1 bouyer } 793 1.1 bouyer } 794 1.1 bouyer 795 1.1 bouyer c = (int)*bufpos++; 796 1.1 bouyer if (bufpos - buf > PMON_MAXLN) { 797 1.1 bouyer bufpos = buf; 798 1.1 bouyer *bufpos = '\0'; 799 1.1 bouyer } 800 1.1 bouyer 801 1.1 bouyer return c; 802 1.1 bouyer } 803 1.1 bouyer 804 1.1 bouyer void 805 1.1 bouyer pmoncnputc(dev_t dev, int c) 806 1.1 bouyer { 807 1.1 bouyer if (c == '\n') 808 1.1 bouyer pmon_printf("\n"); 809 1.1 bouyer else 810 1.1 bouyer pmon_printf("%c", c); 811 1.1 bouyer } 812