1 1.17 hgutch /* $NetBSD: Locore.c,v 1.17 2022/05/14 07:11:23 hgutch Exp $ */ 2 1.1 mrg 3 1.1 mrg /* 4 1.1 mrg * Copyright (C) 1995, 1996 Wolfgang Solfrank. 5 1.1 mrg * Copyright (C) 1995, 1996 TooLs GmbH. 6 1.1 mrg * All rights reserved. 7 1.1 mrg * 8 1.1 mrg * Redistribution and use in source and binary forms, with or without 9 1.1 mrg * modification, are permitted provided that the following conditions 10 1.1 mrg * are met: 11 1.1 mrg * 1. Redistributions of source code must retain the above copyright 12 1.1 mrg * notice, this list of conditions and the following disclaimer. 13 1.1 mrg * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 mrg * notice, this list of conditions and the following disclaimer in the 15 1.1 mrg * documentation and/or other materials provided with the distribution. 16 1.1 mrg * 3. All advertising materials mentioning features or use of this software 17 1.1 mrg * must display the following acknowledgement: 18 1.1 mrg * This product includes software developed by TooLs GmbH. 19 1.1 mrg * 4. The name of TooLs GmbH may not be used to endorse or promote products 20 1.1 mrg * derived from this software without specific prior written permission. 21 1.1 mrg * 22 1.1 mrg * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 23 1.1 mrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 1.1 mrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 1.1 mrg * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 1.1 mrg * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 1.1 mrg * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28 1.1 mrg * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 1.1 mrg * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 1.1 mrg * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 1.1 mrg * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 1.1 mrg */ 33 1.1 mrg 34 1.1 mrg #include <lib/libsa/stand.h> 35 1.1 mrg #include "openfirm.h" 36 1.1 mrg 37 1.1 mrg #include <machine/cpu.h> 38 1.16 martin #include <machine/vmparam.h> 39 1.1 mrg 40 1.15 martin /* 41 1.15 martin * We are trying to boot a sparc v9 cpu, so openfirmware has to be 64bit, 42 1.15 martin * and the kernel we load will be dealing with 64bits too (even if it is 43 1.15 martin * a 32bit kernel. 44 1.15 martin * Make sure we picked up the right defines: 45 1.15 martin */ 46 1.15 martin __CTASSERT(sizeof(cell_t)==8); 47 1.15 martin __CTASSERT(sizeof(paddr_t)==8); 48 1.15 martin 49 1.1 mrg extern int openfirmware(void *); 50 1.1 mrg 51 1.1 mrg 52 1.1 mrg __dead void 53 1.7 cdi _rtt(void) 54 1.7 cdi { 55 1.8 uwe 56 1.7 cdi OF_exit(); 57 1.7 cdi } 58 1.7 cdi 59 1.7 cdi void __attribute__((__noreturn__)) 60 1.7 cdi OF_exit(void) 61 1.1 mrg { 62 1.1 mrg struct { 63 1.1 mrg cell_t name; 64 1.1 mrg cell_t nargs; 65 1.1 mrg cell_t nreturns; 66 1.1 mrg } args; 67 1.1 mrg 68 1.1 mrg args.name = ADR2CELL("exit"); 69 1.1 mrg args.nargs = 0; 70 1.1 mrg args.nreturns = 0; 71 1.1 mrg openfirmware(&args); 72 1.7 cdi 73 1.7 cdi printf("OF_exit failed"); 74 1.8 uwe for (;;) 75 1.8 uwe continue; 76 1.1 mrg } 77 1.1 mrg 78 1.1 mrg void 79 1.8 uwe OF_enter(void) 80 1.1 mrg { 81 1.1 mrg struct { 82 1.1 mrg cell_t name; 83 1.1 mrg cell_t nargs; 84 1.1 mrg cell_t nreturns; 85 1.1 mrg } args; 86 1.1 mrg 87 1.1 mrg args.name = ADR2CELL("enter"); 88 1.1 mrg args.nargs = 0; 89 1.1 mrg args.nreturns = 0; 90 1.1 mrg openfirmware(&args); 91 1.1 mrg } 92 1.1 mrg 93 1.1 mrg int 94 1.8 uwe OF_finddevice(const char *name) 95 1.1 mrg { 96 1.1 mrg struct { 97 1.1 mrg cell_t name; 98 1.1 mrg cell_t nargs; 99 1.1 mrg cell_t nreturns; 100 1.1 mrg cell_t device; 101 1.1 mrg cell_t phandle; 102 1.1 mrg } args; 103 1.1 mrg 104 1.1 mrg args.name = ADR2CELL("finddevice"); 105 1.1 mrg args.nargs = 1; 106 1.1 mrg args.nreturns = 1; 107 1.1 mrg args.device = ADR2CELL(name); 108 1.1 mrg if (openfirmware(&args) == -1) 109 1.1 mrg return -1; 110 1.1 mrg return args.phandle; 111 1.1 mrg } 112 1.1 mrg 113 1.1 mrg int 114 1.8 uwe OF_instance_to_package(int ihandle) 115 1.1 mrg { 116 1.1 mrg struct { 117 1.1 mrg cell_t name; 118 1.1 mrg cell_t nargs; 119 1.1 mrg cell_t nreturns; 120 1.1 mrg cell_t ihandle; 121 1.1 mrg cell_t phandle; 122 1.1 mrg } args; 123 1.1 mrg 124 1.1 mrg args.name = ADR2CELL("instance-to-package"); 125 1.1 mrg args.nargs = 1; 126 1.1 mrg args.nreturns = 1; 127 1.1 mrg args.ihandle = HDL2CELL(ihandle); 128 1.1 mrg if (openfirmware(&args) == -1) 129 1.1 mrg return -1; 130 1.1 mrg return args.phandle; 131 1.1 mrg } 132 1.1 mrg 133 1.1 mrg int 134 1.9 martin OF_instance_to_path(int ihandle, char *buf, int buflen) 135 1.9 martin { 136 1.9 martin struct { 137 1.9 martin cell_t name; 138 1.9 martin cell_t nargs; 139 1.9 martin cell_t nreturns; 140 1.9 martin cell_t ihandle; 141 1.9 martin cell_t buf; 142 1.9 martin cell_t buflen; 143 1.9 martin cell_t length; 144 1.9 martin } args; 145 1.9 martin 146 1.9 martin args.name = ADR2CELL("instance-to-path"); 147 1.9 martin args.nargs = 3; 148 1.9 martin args.nreturns = 1; 149 1.9 martin args.ihandle = HDL2CELL(ihandle); 150 1.9 martin args.buf = ADR2CELL(buf); 151 1.9 martin args.buflen = buflen; 152 1.9 martin if (openfirmware(&args) < 0) 153 1.9 martin return -1; 154 1.9 martin return args.length; 155 1.9 martin } 156 1.9 martin 157 1.9 martin int 158 1.16 martin OF_parent(int phandle) 159 1.16 martin { 160 1.16 martin struct { 161 1.16 martin cell_t name; 162 1.16 martin cell_t nargs; 163 1.16 martin cell_t nreturns; 164 1.16 martin cell_t phandle; 165 1.16 martin cell_t parent; 166 1.16 martin } args; 167 1.16 martin 168 1.16 martin args.name = ADR2CELL("parent"); 169 1.16 martin args.nargs = 1; 170 1.16 martin args.nreturns = 1; 171 1.16 martin args.phandle = HDL2CELL(phandle); 172 1.16 martin if (openfirmware(&args) == -1) 173 1.16 martin return 0; 174 1.16 martin return args.parent; 175 1.16 martin } 176 1.16 martin 177 1.16 martin int 178 1.8 uwe OF_getprop(int handle, const char *prop, void *buf, int buflen) 179 1.1 mrg { 180 1.1 mrg struct { 181 1.1 mrg cell_t name; 182 1.1 mrg cell_t nargs; 183 1.1 mrg cell_t nreturns; 184 1.1 mrg cell_t phandle; 185 1.1 mrg cell_t prop; 186 1.1 mrg cell_t buf; 187 1.1 mrg cell_t buflen; 188 1.1 mrg cell_t size; 189 1.1 mrg } args; 190 1.1 mrg 191 1.1 mrg args.name = ADR2CELL("getprop"); 192 1.1 mrg args.nargs = 4; 193 1.1 mrg args.nreturns = 1; 194 1.1 mrg args.phandle = HDL2CELL(handle); 195 1.1 mrg args.prop = ADR2CELL(prop); 196 1.1 mrg args.buf = ADR2CELL(buf); 197 1.1 mrg args.buflen = buflen; 198 1.1 mrg if (openfirmware(&args) == -1) 199 1.1 mrg return -1; 200 1.1 mrg return args.size; 201 1.1 mrg } 202 1.1 mrg 203 1.1 mrg #ifdef __notyet__ /* Has a bug on FirePower */ 204 1.1 mrg int 205 1.8 uwe OF_setprop(u_int handle, char *prop, void *buf, int len) 206 1.1 mrg { 207 1.1 mrg struct { 208 1.1 mrg cell_t name; 209 1.1 mrg cell_t nargs; 210 1.1 mrg cell_t nreturns; 211 1.1 mrg cell_t phandle; 212 1.1 mrg cell_t prop; 213 1.1 mrg cell_t buf; 214 1.1 mrg cell_t len; 215 1.1 mrg cell_t size; 216 1.1 mrg } args; 217 1.1 mrg 218 1.1 mrg args.name = ADR2CELL("setprop"); 219 1.1 mrg args.nargs = 4; 220 1.1 mrg args.nreturns = 1; 221 1.1 mrg args.phandle = HDL2CELL(handle); 222 1.1 mrg args.prop = ADR2CELL(prop); 223 1.1 mrg args.buf = ADR2CELL(buf); 224 1.1 mrg args.len = len; 225 1.1 mrg if (openfirmware(&args) == -1) 226 1.1 mrg return -1; 227 1.1 mrg return args.size; 228 1.1 mrg } 229 1.1 mrg #endif 230 1.1 mrg 231 1.1 mrg int 232 1.16 martin OF_interpret(const char *cmd, int nargs, int nreturns, ...) 233 1.16 martin { 234 1.16 martin va_list ap; 235 1.16 martin struct { 236 1.16 martin cell_t name; 237 1.16 martin cell_t nargs; 238 1.16 martin cell_t nreturns; 239 1.16 martin cell_t slot[16]; 240 1.16 martin } args; 241 1.16 martin cell_t status; 242 1.16 martin int i = 0; 243 1.16 martin 244 1.16 martin args.name = ADR2CELL("interpret"); 245 1.16 martin args.nargs = ++nargs; 246 1.16 martin args.nreturns = ++nreturns; 247 1.16 martin args.slot[i++] = ADR2CELL(cmd); 248 1.16 martin va_start(ap, nreturns); 249 1.16 martin while (i < nargs) { 250 1.16 martin args.slot[i++] = va_arg(ap, cell_t); 251 1.16 martin } 252 1.16 martin if (openfirmware(&args) == -1) { 253 1.16 martin va_end(ap); 254 1.16 martin return (-1); 255 1.16 martin } 256 1.16 martin status = args.slot[i++]; 257 1.16 martin while (i < nargs+nreturns) { 258 1.16 martin *va_arg(ap, cell_t *) = args.slot[i++]; 259 1.16 martin } 260 1.16 martin va_end(ap); 261 1.16 martin 262 1.16 martin return status; 263 1.16 martin } 264 1.16 martin 265 1.16 martin int 266 1.16 martin OF_package_to_path(int phandle, char *buf, int buflen) 267 1.16 martin { 268 1.16 martin struct { 269 1.16 martin cell_t name; 270 1.16 martin cell_t nargs; 271 1.16 martin cell_t nreturns; 272 1.16 martin cell_t phandle; 273 1.16 martin cell_t buf; 274 1.16 martin cell_t buflen; 275 1.16 martin cell_t length; 276 1.16 martin } args; 277 1.16 martin 278 1.16 martin if (buflen > PAGE_SIZE) 279 1.16 martin return -1; 280 1.16 martin args.name = ADR2CELL("package-to-path"); 281 1.16 martin args.nargs = 3; 282 1.16 martin args.nreturns = 1; 283 1.16 martin args.phandle = HDL2CELL(phandle); 284 1.16 martin args.buf = ADR2CELL(buf); 285 1.16 martin args.buflen = buflen; 286 1.16 martin if (openfirmware(&args) < 0) 287 1.16 martin return -1; 288 1.16 martin return args.length; 289 1.16 martin } 290 1.16 martin 291 1.16 martin int 292 1.8 uwe OF_open(const char *dname) 293 1.1 mrg { 294 1.1 mrg struct { 295 1.1 mrg cell_t name; 296 1.1 mrg cell_t nargs; 297 1.1 mrg cell_t nreturns; 298 1.1 mrg cell_t dname; 299 1.1 mrg cell_t handle; 300 1.1 mrg } args; 301 1.1 mrg 302 1.1 mrg args.name = ADR2CELL("open"); 303 1.1 mrg args.nargs = 1; 304 1.1 mrg args.nreturns = 1; 305 1.1 mrg args.dname = ADR2CELL(dname); 306 1.1 mrg if (openfirmware(&args) == -1 || 307 1.1 mrg args.handle == 0) 308 1.1 mrg return -1; 309 1.1 mrg return args.handle; 310 1.1 mrg } 311 1.1 mrg 312 1.1 mrg void 313 1.8 uwe OF_close(int handle) 314 1.1 mrg { 315 1.1 mrg struct { 316 1.1 mrg cell_t name; 317 1.1 mrg cell_t nargs; 318 1.1 mrg cell_t nreturns; 319 1.1 mrg cell_t handle; 320 1.1 mrg } args; 321 1.1 mrg 322 1.1 mrg args.name = ADR2CELL("close"); 323 1.1 mrg args.nargs = 1; 324 1.13 martin args.nreturns = 0; 325 1.1 mrg args.handle = HDL2CELL(handle); 326 1.1 mrg openfirmware(&args); 327 1.1 mrg } 328 1.1 mrg 329 1.1 mrg int 330 1.8 uwe OF_write(int handle, const void *addr, int len) 331 1.1 mrg { 332 1.1 mrg struct { 333 1.1 mrg cell_t name; 334 1.1 mrg cell_t nargs; 335 1.1 mrg cell_t nreturns; 336 1.1 mrg cell_t ihandle; 337 1.1 mrg cell_t addr; 338 1.1 mrg cell_t len; 339 1.1 mrg cell_t actual; 340 1.1 mrg } args; 341 1.1 mrg 342 1.1 mrg args.name = ADR2CELL("write"); 343 1.1 mrg args.nargs = 3; 344 1.1 mrg args.nreturns = 1; 345 1.1 mrg args.ihandle = HDL2CELL(handle); 346 1.1 mrg args.addr = ADR2CELL(addr); 347 1.1 mrg args.len = len; 348 1.1 mrg if (openfirmware(&args) == -1) 349 1.1 mrg return -1; 350 1.1 mrg return args.actual; 351 1.1 mrg } 352 1.1 mrg 353 1.1 mrg int 354 1.8 uwe OF_read(int handle, void *addr, int len) 355 1.1 mrg { 356 1.1 mrg struct { 357 1.1 mrg cell_t name; 358 1.1 mrg cell_t nargs; 359 1.1 mrg cell_t nreturns; 360 1.1 mrg cell_t ihandle; 361 1.1 mrg cell_t addr; 362 1.1 mrg cell_t len; 363 1.1 mrg cell_t actual; 364 1.1 mrg } args; 365 1.1 mrg 366 1.1 mrg args.name = ADR2CELL("read"); 367 1.1 mrg args.nargs = 3; 368 1.1 mrg args.nreturns = 1; 369 1.1 mrg args.ihandle = HDL2CELL(handle); 370 1.1 mrg args.addr = ADR2CELL(addr); 371 1.1 mrg args.len = len; 372 1.1 mrg if (openfirmware(&args) == -1) { 373 1.1 mrg return -1; 374 1.1 mrg } 375 1.1 mrg return args.actual; 376 1.1 mrg } 377 1.1 mrg 378 1.1 mrg int 379 1.8 uwe OF_seek(int handle, u_quad_t pos) 380 1.1 mrg { 381 1.1 mrg struct { 382 1.1 mrg cell_t name; 383 1.1 mrg cell_t nargs; 384 1.1 mrg cell_t nreturns; 385 1.1 mrg cell_t handle; 386 1.1 mrg cell_t poshi; 387 1.1 mrg cell_t poslo; 388 1.1 mrg cell_t status; 389 1.1 mrg } args; 390 1.1 mrg 391 1.1 mrg args.name = ADR2CELL("seek"); 392 1.1 mrg args.nargs = 3; 393 1.1 mrg args.nreturns = 1; 394 1.1 mrg args.handle = HDL2CELL(handle); 395 1.14 nakayama args.poshi = HDQ2CELL_HI(pos); 396 1.14 nakayama args.poslo = HDQ2CELL_LO(pos); 397 1.1 mrg if (openfirmware(&args) == -1) { 398 1.1 mrg return -1; 399 1.1 mrg } 400 1.1 mrg return args.status; 401 1.1 mrg } 402 1.1 mrg 403 1.1 mrg void 404 1.8 uwe OF_release(void *virt, u_int size) 405 1.1 mrg { 406 1.1 mrg struct { 407 1.1 mrg cell_t name; 408 1.1 mrg cell_t nargs; 409 1.1 mrg cell_t nreturns; 410 1.1 mrg cell_t virt; 411 1.1 mrg cell_t size; 412 1.1 mrg } args; 413 1.1 mrg 414 1.1 mrg args.name = ADR2CELL("release"); 415 1.1 mrg args.nargs = 2; 416 1.1 mrg args.nreturns = 0; 417 1.1 mrg args.virt = ADR2CELL(virt); 418 1.1 mrg args.size = size; 419 1.1 mrg openfirmware(&args); 420 1.1 mrg } 421 1.1 mrg 422 1.1 mrg int 423 1.8 uwe OF_milliseconds(void) 424 1.1 mrg { 425 1.1 mrg struct { 426 1.1 mrg cell_t name; 427 1.1 mrg cell_t nargs; 428 1.1 mrg cell_t nreturns; 429 1.1 mrg cell_t ms; 430 1.1 mrg } args; 431 1.1 mrg 432 1.1 mrg args.name = ADR2CELL("milliseconds"); 433 1.1 mrg args.nargs = 0; 434 1.1 mrg args.nreturns = 1; 435 1.1 mrg openfirmware(&args); 436 1.1 mrg return args.ms; 437 1.1 mrg } 438 1.1 mrg 439 1.7 cdi int 440 1.7 cdi OF_peer(int phandle) 441 1.1 mrg { 442 1.1 mrg struct { 443 1.1 mrg cell_t name; 444 1.1 mrg cell_t nargs; 445 1.1 mrg cell_t nreturns; 446 1.7 cdi cell_t phandle; 447 1.7 cdi cell_t sibling; 448 1.1 mrg } args; 449 1.1 mrg 450 1.7 cdi args.name = ADR2CELL("peer"); 451 1.7 cdi args.nargs = 1; 452 1.7 cdi args.nreturns = 1; 453 1.7 cdi args.phandle = HDL2CELL(phandle); 454 1.7 cdi if (openfirmware(&args) == -1) 455 1.7 cdi return 0; 456 1.7 cdi return args.sibling; 457 1.7 cdi } 458 1.7 cdi 459 1.7 cdi int 460 1.7 cdi OF_child(int phandle) 461 1.7 cdi { 462 1.7 cdi struct { 463 1.7 cdi cell_t name; 464 1.7 cdi cell_t nargs; 465 1.7 cdi cell_t nreturns; 466 1.7 cdi cell_t phandle; 467 1.7 cdi cell_t child; 468 1.7 cdi } args; 469 1.1 mrg 470 1.7 cdi args.name = ADR2CELL("child"); 471 1.7 cdi args.nargs = 1; 472 1.7 cdi args.nreturns = 1; 473 1.7 cdi args.phandle = HDL2CELL(phandle); 474 1.7 cdi if (openfirmware(&args) == -1) 475 1.7 cdi return 0; 476 1.7 cdi return args.child; 477 1.1 mrg } 478 1.1 mrg 479 1.1 mrg static u_int mmuh = -1; 480 1.1 mrg static u_int memh = -1; 481 1.1 mrg 482 1.1 mrg void 483 1.7 cdi OF_initialize(void) 484 1.1 mrg { 485 1.1 mrg u_int chosen; 486 1.7 cdi 487 1.7 cdi if ( (chosen = OF_finddevice("/chosen")) == -1) { 488 1.7 cdi OF_exit(); 489 1.7 cdi } 490 1.7 cdi if (OF_getprop(chosen, "mmu", &mmuh, sizeof(mmuh)) != sizeof(mmuh) 491 1.1 mrg || OF_getprop(chosen, "memory", &memh, sizeof(memh)) != sizeof(memh)) 492 1.7 cdi OF_exit(); 493 1.1 mrg } 494 1.1 mrg 495 1.1 mrg /* 496 1.1 mrg * The following need either the handle to memory or the handle to the MMU. 497 1.1 mrg */ 498 1.1 mrg 499 1.1 mrg /* 500 1.1 mrg * Grab some address space from the prom 501 1.1 mrg * 502 1.1 mrg * Only works while the prom is actively mapping us. 503 1.1 mrg */ 504 1.1 mrg vaddr_t 505 1.8 uwe OF_claim_virt(vaddr_t vaddr, int len) 506 1.1 mrg { 507 1.1 mrg struct { 508 1.1 mrg cell_t name; 509 1.1 mrg cell_t nargs; 510 1.1 mrg cell_t nreturns; 511 1.1 mrg cell_t method; 512 1.1 mrg cell_t ihandle; 513 1.1 mrg cell_t align; 514 1.1 mrg cell_t len; 515 1.1 mrg cell_t vaddr; 516 1.1 mrg cell_t status; 517 1.1 mrg cell_t retaddr; 518 1.1 mrg } args; 519 1.1 mrg 520 1.1 mrg #ifdef __notyet 521 1.1 mrg if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) { 522 1.1 mrg OF_printf("OF_claim_virt: cannot get mmuh\r\n"); 523 1.1 mrg return -1LL; 524 1.1 mrg } 525 1.1 mrg #endif 526 1.1 mrg args.name = ADR2CELL("call-method"); 527 1.1 mrg args.nargs = 5; 528 1.1 mrg args.nreturns = 2; 529 1.1 mrg args.method = ADR2CELL("claim"); 530 1.1 mrg args.ihandle = HDL2CELL(mmuh); 531 1.1 mrg args.align = 0; 532 1.1 mrg args.len = len; 533 1.1 mrg args.vaddr = ADR2CELL(vaddr); 534 1.11 nakayama if (openfirmware(&args) != 0) 535 1.1 mrg return -1LL; 536 1.11 nakayama return (vaddr_t)args.retaddr; 537 1.1 mrg } 538 1.1 mrg 539 1.1 mrg /* 540 1.1 mrg * Request some address space from the prom 541 1.1 mrg * 542 1.1 mrg * Only works while the prom is actively mapping us. 543 1.1 mrg */ 544 1.1 mrg vaddr_t 545 1.8 uwe OF_alloc_virt(int len, int align) 546 1.1 mrg { 547 1.1 mrg int retaddr=-1; 548 1.1 mrg struct { 549 1.1 mrg cell_t name; 550 1.1 mrg cell_t nargs; 551 1.1 mrg cell_t nreturns; 552 1.1 mrg cell_t method; 553 1.1 mrg cell_t ihandle; 554 1.1 mrg cell_t align; 555 1.1 mrg cell_t len; 556 1.1 mrg cell_t status; 557 1.1 mrg cell_t retaddr; 558 1.1 mrg } args; 559 1.1 mrg 560 1.1 mrg #ifdef __notyet 561 1.1 mrg if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) { 562 1.1 mrg OF_printf("OF_alloc_virt: cannot get mmuh\r\n"); 563 1.1 mrg return -1LL; 564 1.1 mrg } 565 1.1 mrg #endif 566 1.1 mrg args.name = ADR2CELL("call-method"); 567 1.1 mrg args.nargs = 4; 568 1.1 mrg args.nreturns = 2; 569 1.1 mrg args.method = ADR2CELL("claim"); 570 1.11 nakayama args.ihandle = HDL2CELL(mmuh); 571 1.1 mrg args.align = align; 572 1.1 mrg args.len = len; 573 1.1 mrg args.retaddr = ADR2CELL(&retaddr); 574 1.11 nakayama if (openfirmware(&args) != 0) 575 1.1 mrg return -1LL; 576 1.11 nakayama return (vaddr_t)args.retaddr; 577 1.1 mrg } 578 1.1 mrg 579 1.1 mrg /* 580 1.1 mrg * Release some address space to the prom 581 1.1 mrg * 582 1.1 mrg * Only works while the prom is actively mapping us. 583 1.1 mrg */ 584 1.1 mrg int 585 1.8 uwe OF_free_virt(vaddr_t vaddr, int len) 586 1.1 mrg { 587 1.1 mrg struct { 588 1.1 mrg cell_t name; 589 1.1 mrg cell_t nargs; 590 1.1 mrg cell_t nreturns; 591 1.1 mrg cell_t method; 592 1.1 mrg cell_t ihandle; 593 1.1 mrg cell_t len; 594 1.1 mrg cell_t vaddr; 595 1.1 mrg } args; 596 1.1 mrg 597 1.1 mrg #ifdef __notyet 598 1.1 mrg if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) { 599 1.1 mrg OF_printf("OF_claim_virt: cannot get mmuh\r\n"); 600 1.1 mrg return -1; 601 1.1 mrg } 602 1.1 mrg #endif 603 1.1 mrg args.name = ADR2CELL("call-method"); 604 1.1 mrg args.nargs = 4; 605 1.1 mrg args.nreturns = 0; 606 1.1 mrg args.method = ADR2CELL("release"); 607 1.1 mrg args.ihandle = HDL2CELL(mmuh); 608 1.1 mrg args.vaddr = ADR2CELL(vaddr); 609 1.1 mrg args.len = len; 610 1.1 mrg return openfirmware(&args); 611 1.1 mrg } 612 1.1 mrg 613 1.1 mrg 614 1.1 mrg /* 615 1.1 mrg * Unmap some address space 616 1.1 mrg * 617 1.1 mrg * Only works while the prom is actively mapping us. 618 1.1 mrg */ 619 1.1 mrg int 620 1.8 uwe OF_unmap_virt(vaddr_t vaddr, int len) 621 1.1 mrg { 622 1.1 mrg struct { 623 1.1 mrg cell_t name; 624 1.1 mrg cell_t nargs; 625 1.1 mrg cell_t nreturns; 626 1.1 mrg cell_t method; 627 1.1 mrg cell_t ihandle; 628 1.1 mrg cell_t len; 629 1.1 mrg cell_t vaddr; 630 1.1 mrg } args; 631 1.1 mrg 632 1.1 mrg #ifdef __notyet 633 1.1 mrg if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) { 634 1.1 mrg OF_printf("OF_claim_virt: cannot get mmuh\r\n"); 635 1.1 mrg return -1; 636 1.1 mrg } 637 1.1 mrg #endif 638 1.1 mrg args.name = ADR2CELL("call-method"); 639 1.1 mrg args.nargs = 4; 640 1.1 mrg args.nreturns = 0; 641 1.1 mrg args.method = ADR2CELL("unmap"); 642 1.1 mrg args.ihandle = HDL2CELL(mmuh); 643 1.1 mrg args.vaddr = ADR2CELL(vaddr); 644 1.1 mrg args.len = len; 645 1.1 mrg return openfirmware(&args); 646 1.1 mrg } 647 1.1 mrg 648 1.1 mrg /* 649 1.1 mrg * Have prom map in some memory 650 1.1 mrg * 651 1.1 mrg * Only works while the prom is actively mapping us. 652 1.1 mrg */ 653 1.1 mrg vaddr_t 654 1.8 uwe OF_map_phys(paddr_t paddr, off_t size, vaddr_t vaddr, int mode) 655 1.1 mrg { 656 1.1 mrg struct { 657 1.1 mrg cell_t name; 658 1.1 mrg cell_t nargs; 659 1.1 mrg cell_t nreturns; 660 1.1 mrg cell_t method; 661 1.1 mrg cell_t ihandle; 662 1.1 mrg cell_t mode; 663 1.1 mrg cell_t size; 664 1.1 mrg cell_t vaddr; 665 1.1 mrg cell_t paddr_hi; 666 1.1 mrg cell_t paddr_lo; 667 1.1 mrg } args; 668 1.1 mrg 669 1.1 mrg #ifdef __notyet 670 1.1 mrg if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) { 671 1.1 mrg OF_printf("OF_map_phys: cannot get mmuh\r\n"); 672 1.1 mrg return 0LL; 673 1.1 mrg } 674 1.1 mrg #endif 675 1.1 mrg args.name = ADR2CELL("call-method"); 676 1.1 mrg args.nargs = 7; 677 1.17 hgutch args.nreturns = 0; 678 1.1 mrg args.method = ADR2CELL("map"); 679 1.1 mrg args.ihandle = HDL2CELL(mmuh); 680 1.1 mrg args.mode = mode; 681 1.1 mrg args.size = size; 682 1.1 mrg args.vaddr = ADR2CELL(vaddr); 683 1.11 nakayama args.paddr_hi = HDQ2CELL_HI(paddr); 684 1.11 nakayama args.paddr_lo = HDQ2CELL_LO(paddr); 685 1.1 mrg 686 1.1 mrg if (openfirmware(&args) == -1) 687 1.1 mrg return -1; 688 1.17 hgutch return 0; 689 1.1 mrg } 690 1.1 mrg 691 1.1 mrg 692 1.1 mrg /* 693 1.1 mrg * Request some RAM from the prom 694 1.1 mrg * 695 1.1 mrg * Only works while the prom is actively mapping us. 696 1.1 mrg */ 697 1.1 mrg paddr_t 698 1.8 uwe OF_alloc_phys(int len, int align) 699 1.1 mrg { 700 1.1 mrg struct { 701 1.1 mrg cell_t name; 702 1.1 mrg cell_t nargs; 703 1.1 mrg cell_t nreturns; 704 1.1 mrg cell_t method; 705 1.1 mrg cell_t ihandle; 706 1.1 mrg cell_t align; 707 1.1 mrg cell_t len; 708 1.1 mrg cell_t status; 709 1.1 mrg cell_t phys_hi; 710 1.1 mrg cell_t phys_lo; 711 1.1 mrg } args; 712 1.1 mrg 713 1.1 mrg #ifdef __notyet 714 1.1 mrg if (memh == -1 && ((memh = get_memory_handle()) == -1)) { 715 1.1 mrg OF_printf("OF_alloc_phys: cannot get memh\r\n"); 716 1.1 mrg return -1LL; 717 1.1 mrg } 718 1.1 mrg #endif 719 1.1 mrg args.name = ADR2CELL("call-method"); 720 1.1 mrg args.nargs = 4; 721 1.1 mrg args.nreturns = 3; 722 1.1 mrg args.method = ADR2CELL("claim"); 723 1.1 mrg args.ihandle = HDL2CELL(memh); 724 1.1 mrg args.align = align; 725 1.1 mrg args.len = len; 726 1.11 nakayama if (openfirmware(&args) != 0) 727 1.1 mrg return -1LL; 728 1.11 nakayama return (paddr_t)CELL2HDQ(args.phys_hi, args.phys_lo); 729 1.1 mrg } 730 1.1 mrg 731 1.1 mrg /* 732 1.1 mrg * Request some specific RAM from the prom 733 1.1 mrg * 734 1.1 mrg * Only works while the prom is actively mapping us. 735 1.1 mrg */ 736 1.1 mrg paddr_t 737 1.8 uwe OF_claim_phys(paddr_t phys, int len) 738 1.1 mrg { 739 1.1 mrg struct { 740 1.1 mrg cell_t name; 741 1.1 mrg cell_t nargs; 742 1.1 mrg cell_t nreturns; 743 1.1 mrg cell_t method; 744 1.1 mrg cell_t ihandle; 745 1.1 mrg cell_t align; 746 1.1 mrg cell_t len; 747 1.1 mrg cell_t phys_hi; 748 1.1 mrg cell_t phys_lo; 749 1.1 mrg cell_t status; 750 1.1 mrg cell_t res; 751 1.1 mrg cell_t rphys_hi; 752 1.1 mrg cell_t rphys_lo; 753 1.1 mrg } args; 754 1.1 mrg 755 1.1 mrg #ifdef __notyet 756 1.1 mrg if (memh == -1 && ((memh = get_memory_handle()) == -1)) { 757 1.1 mrg OF_printf("OF_alloc_phys: cannot get memh\r\n"); 758 1.1 mrg return 0LL; 759 1.1 mrg } 760 1.1 mrg #endif 761 1.1 mrg args.name = ADR2CELL("call-method"); 762 1.1 mrg args.nargs = 6; 763 1.1 mrg args.nreturns = 4; 764 1.1 mrg args.method = ADR2CELL("claim"); 765 1.1 mrg args.ihandle = HDL2CELL(memh); 766 1.1 mrg args.align = 0; 767 1.1 mrg args.len = len; 768 1.11 nakayama args.phys_hi = HDQ2CELL_HI(phys); 769 1.11 nakayama args.phys_lo = HDQ2CELL_LO(phys); 770 1.11 nakayama if (openfirmware(&args) != 0) 771 1.1 mrg return 0LL; 772 1.11 nakayama return (paddr_t)CELL2HDQ(args.rphys_hi, args.rphys_lo); 773 1.1 mrg } 774 1.1 mrg 775 1.1 mrg /* 776 1.1 mrg * Free some RAM to prom 777 1.1 mrg * 778 1.1 mrg * Only works while the prom is actively mapping us. 779 1.1 mrg */ 780 1.1 mrg int 781 1.8 uwe OF_free_phys(paddr_t phys, int len) 782 1.1 mrg { 783 1.1 mrg struct { 784 1.1 mrg cell_t name; 785 1.1 mrg cell_t nargs; 786 1.1 mrg cell_t nreturns; 787 1.1 mrg cell_t method; 788 1.1 mrg cell_t ihandle; 789 1.1 mrg cell_t len; 790 1.1 mrg cell_t phys_hi; 791 1.1 mrg cell_t phys_lo; 792 1.1 mrg } args; 793 1.1 mrg 794 1.1 mrg #ifdef __notyet 795 1.1 mrg if (memh == -1 && ((memh = get_memory_handle()) == -1)) { 796 1.1 mrg OF_printf("OF_free_phys: cannot get memh\r\n"); 797 1.1 mrg return -1; 798 1.1 mrg } 799 1.1 mrg #endif 800 1.1 mrg args.name = ADR2CELL("call-method"); 801 1.1 mrg args.nargs = 5; 802 1.1 mrg args.nreturns = 0; 803 1.1 mrg args.method = ADR2CELL("release"); 804 1.1 mrg args.ihandle = HDL2CELL(memh); 805 1.1 mrg args.len = len; 806 1.11 nakayama args.phys_hi = HDQ2CELL_HI(phys); 807 1.11 nakayama args.phys_lo = HDQ2CELL_LO(phys); 808 1.1 mrg return openfirmware(&args); 809 1.1 mrg } 810 1.1 mrg 811 1.1 mrg 812 1.1 mrg /* 813 1.1 mrg * Claim virtual memory -- does not map it in. 814 1.1 mrg */ 815 1.1 mrg 816 1.1 mrg void * 817 1.8 uwe OF_claim(void *virt, u_int size, u_int align) 818 1.1 mrg { 819 1.1 mrg #define SUNVMOF 820 1.1 mrg #ifndef SUNVMOF 821 1.1 mrg struct { 822 1.1 mrg cell_t name; 823 1.1 mrg cell_t nargs; 824 1.1 mrg cell_t nreturns; 825 1.1 mrg cell_t virt; 826 1.1 mrg cell_t size; 827 1.1 mrg cell_t align; 828 1.1 mrg cell_t baseaddr; 829 1.1 mrg } args; 830 1.1 mrg 831 1.1 mrg 832 1.1 mrg args.name = ADR2CELL("claim"); 833 1.1 mrg args.nargs = 3; 834 1.1 mrg args.nreturns = 1; 835 1.1 mrg args.virt = virt; 836 1.1 mrg args.size = size; 837 1.1 mrg args.align = align; 838 1.1 mrg if (openfirmware(&args) == -1) 839 1.1 mrg return (void *)-1; 840 1.1 mrg return args.baseaddr; 841 1.1 mrg #else 842 1.1 mrg /* 843 1.1 mrg * Sun Ultra machines run the firmware with VM enabled, 844 1.1 mrg * so you need to handle allocating and mapping both 845 1.1 mrg * virtual and physical memory. Ugh. 846 1.1 mrg */ 847 1.1 mrg 848 1.1 mrg paddr_t paddr; 849 1.1 mrg void* newvirt = NULL; 850 1.1 mrg 851 1.1 mrg if (virt == NULL) { 852 1.1 mrg if ((virt = (void*)OF_alloc_virt(size, align)) == (void*)-1) { 853 1.12 tsutsui printf("OF_alloc_virt(%d,%d) failed w/%p\n", size, align, virt); 854 1.1 mrg return (void *)-1; 855 1.1 mrg } 856 1.1 mrg } else { 857 1.1 mrg if ((newvirt = (void*)OF_claim_virt((vaddr_t)virt, size)) == (void*)-1) { 858 1.12 tsutsui printf("OF_claim_virt(%p,%d) failed w/%p\n", virt, size, newvirt); 859 1.1 mrg return (void *)-1; 860 1.1 mrg } 861 1.1 mrg } 862 1.11 nakayama if ((paddr = OF_alloc_phys(size, align)) == (paddr_t)-1) { 863 1.1 mrg printf("OF_alloc_phys(%d,%d) failed\n", size, align); 864 1.1 mrg OF_free_virt((vaddr_t)virt, size); 865 1.1 mrg return (void *)-1; 866 1.1 mrg } 867 1.1 mrg if (OF_map_phys(paddr, size, (vaddr_t)virt, -1) == -1) { 868 1.12 tsutsui printf("OF_map_phys(0x%lx,%d,%p,%d) failed\n", 869 1.12 tsutsui (u_long)paddr, size, virt, -1); 870 1.1 mrg OF_free_phys((paddr_t)paddr, size); 871 1.1 mrg OF_free_virt((vaddr_t)virt, size); 872 1.1 mrg return (void *)-1; 873 1.1 mrg } 874 1.1 mrg return (void *)virt; 875 1.1 mrg #endif 876 1.1 mrg } 877