1195098Sed/* $NetBSD: Locore.c,v 1.17 2022/05/14 07:11:23 hgutch Exp $ */ 2195098Sed 3195098Sed/* 4195098Sed * Copyright (C) 1995, 1996 Wolfgang Solfrank. 5195098Sed * Copyright (C) 1995, 1996 TooLs GmbH. 6195098Sed * All rights reserved. 7195098Sed * 8195098Sed * Redistribution and use in source and binary forms, with or without 9195098Sed * modification, are permitted provided that the following conditions 10195098Sed * are met: 11198090Srdivacky * 1. Redistributions of source code must retain the above copyright 12198090Srdivacky * notice, this list of conditions and the following disclaimer. 13195098Sed * 2. Redistributions in binary form must reproduce the above copyright 14198090Srdivacky * notice, this list of conditions and the following disclaimer in the 15195340Sed * documentation and/or other materials provided with the distribution. 16198090Srdivacky * 3. All advertising materials mentioning features or use of this software 17198090Srdivacky * must display the following acknowledgement: 18195098Sed * This product includes software developed by TooLs GmbH. 19205407Srdivacky * 4. The name of TooLs GmbH may not be used to endorse or promote products 20202878Srdivacky * derived from this software without specific prior written permission. 21202878Srdivacky * 22198090Srdivacky * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 23198090Srdivacky * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24198090Srdivacky * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25202878Srdivacky * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26195098Sed * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27195098Sed * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28195098Sed * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29195098Sed * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30198090Srdivacky * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31202878Srdivacky * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32198090Srdivacky */ 33205407Srdivacky 34198090Srdivacky#include <lib/libsa/stand.h> 35202878Srdivacky#include "openfirm.h" 36202878Srdivacky 37202878Srdivacky#include <machine/cpu.h> 38203954Srdivacky#include <machine/vmparam.h> 39203954Srdivacky 40203954Srdivacky/* 41203954Srdivacky * We are trying to boot a sparc v9 cpu, so openfirmware has to be 64bit, 42203954Srdivacky * and the kernel we load will be dealing with 64bits too (even if it is 43198090Srdivacky * a 32bit kernel. 44202878Srdivacky * Make sure we picked up the right defines: 45202878Srdivacky */ 46203954Srdivacky__CTASSERT(sizeof(cell_t)==8); 47205218Srdivacky__CTASSERT(sizeof(paddr_t)==8); 48205218Srdivacky 49203954Srdivackyextern int openfirmware(void *); 50203954Srdivacky 51203954Srdivacky 52203954Srdivacky__dead void 53203954Srdivacky_rtt(void) 54198090Srdivacky{ 55195098Sed 56202878Srdivacky OF_exit(); 57203954Srdivacky} 58202878Srdivacky 59202878Srdivackyvoid __attribute__((__noreturn__)) 60202878SrdivackyOF_exit(void) 61202878Srdivacky{ 62202878Srdivacky struct { 63202878Srdivacky cell_t name; 64202878Srdivacky cell_t nargs; 65202878Srdivacky cell_t nreturns; 66202878Srdivacky } args; 67203954Srdivacky 68203954Srdivacky args.name = ADR2CELL("exit"); 69203954Srdivacky args.nargs = 0; 70203954Srdivacky args.nreturns = 0; 71206274Srdivacky openfirmware(&args); 72206274Srdivacky 73206274Srdivacky printf("OF_exit failed"); 74203954Srdivacky for (;;) 75202878Srdivacky continue; 76202878Srdivacky} 77202878Srdivacky 78202878Srdivackyvoid 79202878SrdivackyOF_enter(void) 80203954Srdivacky{ 81203954Srdivacky struct { 82203954Srdivacky cell_t name; 83203954Srdivacky cell_t nargs; 84202878Srdivacky cell_t nreturns; 85202878Srdivacky } args; 86202878Srdivacky 87202878Srdivacky args.name = ADR2CELL("enter"); 88202878Srdivacky args.nargs = 0; 89202878Srdivacky args.nreturns = 0; 90202878Srdivacky openfirmware(&args); 91202878Srdivacky} 92203954Srdivacky 93202878Srdivackyint 94202878SrdivackyOF_finddevice(const char *name) 95202878Srdivacky{ 96202878Srdivacky struct { 97203954Srdivacky cell_t name; 98198090Srdivacky cell_t nargs; 99198090Srdivacky cell_t nreturns; 100195098Sed cell_t device; 101198090Srdivacky cell_t phandle; 102195098Sed } args; 103198090Srdivacky 104195098Sed args.name = ADR2CELL("finddevice"); 105202878Srdivacky args.nargs = 1; 106195098Sed args.nreturns = 1; 107198090Srdivacky args.device = ADR2CELL(name); 108195098Sed if (openfirmware(&args) == -1) 109202878Srdivacky return -1; 110195098Sed return args.phandle; 111198090Srdivacky} 112208599Srdivacky 113208599Srdivackyint 114208599SrdivackyOF_instance_to_package(int ihandle) 115208599Srdivacky{ 116203954Srdivacky struct { 117202878Srdivacky cell_t name; 118198090Srdivacky cell_t nargs; 119195098Sed cell_t nreturns; 120202878Srdivacky cell_t ihandle; 121202878Srdivacky cell_t phandle; 122202878Srdivacky } args; 123202878Srdivacky 124202878Srdivacky args.name = ADR2CELL("instance-to-package"); 125202878Srdivacky args.nargs = 1; 126198090Srdivacky args.nreturns = 1; 127198090Srdivacky args.ihandle = HDL2CELL(ihandle); 128195098Sed if (openfirmware(&args) == -1) 129208599Srdivacky return -1; 130208599Srdivacky return args.phandle; 131208599Srdivacky} 132202878Srdivacky 133195098Sedint 134202878SrdivackyOF_instance_to_path(int ihandle, char *buf, int buflen) 135202878Srdivacky{ 136203954Srdivacky struct { 137203954Srdivacky cell_t name; 138195098Sed cell_t nargs; 139202878Srdivacky cell_t nreturns; 140202878Srdivacky cell_t ihandle; 141202878Srdivacky cell_t buf; 142198090Srdivacky cell_t buflen; 143198090Srdivacky cell_t length; 144198090Srdivacky } args; 145195098Sed 146204642Srdivacky args.name = ADR2CELL("instance-to-path"); 147204642Srdivacky args.nargs = 3; 148204642Srdivacky args.nreturns = 1; 149198090Srdivacky args.ihandle = HDL2CELL(ihandle); 150198090Srdivacky args.buf = ADR2CELL(buf); 151203954Srdivacky args.buflen = buflen; 152203954Srdivacky if (openfirmware(&args) < 0) 153203954Srdivacky return -1; 154203954Srdivacky return args.length; 155203954Srdivacky} 156198090Srdivacky 157206274Srdivackyint 158206274SrdivackyOF_parent(int phandle) 159206274Srdivacky{ 160206274Srdivacky struct { 161206274Srdivacky cell_t name; 162198090Srdivacky cell_t nargs; 163198090Srdivacky cell_t nreturns; 164198090Srdivacky cell_t phandle; 165198090Srdivacky cell_t parent; 166195098Sed } args; 167198090Srdivacky 168195098Sed args.name = ADR2CELL("parent"); 169202878Srdivacky args.nargs = 1; 170202878Srdivacky args.nreturns = 1; 171202878Srdivacky args.phandle = HDL2CELL(phandle); 172202878Srdivacky if (openfirmware(&args) == -1) 173202878Srdivacky return 0; 174202878Srdivacky return args.parent; 175202878Srdivacky} 176202878Srdivacky 177202878Srdivackyint 178202878SrdivackyOF_getprop(int handle, const char *prop, void *buf, int buflen) 179202878Srdivacky{ 180202878Srdivacky struct { 181202878Srdivacky cell_t name; 182202878Srdivacky cell_t nargs; 183202878Srdivacky cell_t nreturns; 184202878Srdivacky cell_t phandle; 185202878Srdivacky cell_t prop; 186202878Srdivacky cell_t buf; 187202878Srdivacky cell_t buflen; 188202878Srdivacky cell_t size; 189202878Srdivacky } args; 190202878Srdivacky 191202878Srdivacky args.name = ADR2CELL("getprop"); 192202878Srdivacky args.nargs = 4; 193202878Srdivacky args.nreturns = 1; 194202878Srdivacky args.phandle = HDL2CELL(handle); 195202878Srdivacky args.prop = ADR2CELL(prop); 196202878Srdivacky args.buf = ADR2CELL(buf); 197202878Srdivacky args.buflen = buflen; 198202878Srdivacky if (openfirmware(&args) == -1) 199202878Srdivacky return -1; 200202878Srdivacky return args.size; 201202878Srdivacky} 202202878Srdivacky 203202878Srdivacky#ifdef __notyet__ /* Has a bug on FirePower */ 204202878Srdivackyint 205202878SrdivackyOF_setprop(u_int handle, char *prop, void *buf, int len) 206202878Srdivacky{ 207202878Srdivacky struct { 208202878Srdivacky cell_t name; 209202878Srdivacky cell_t nargs; 210202878Srdivacky cell_t nreturns; 211202878Srdivacky cell_t phandle; 212195098Sed cell_t prop; 213195098Sed cell_t buf; 214195098Sed cell_t len; 215195098Sed cell_t size; 216195098Sed } args; 217198090Srdivacky 218198090Srdivacky args.name = ADR2CELL("setprop"); 219195098Sed args.nargs = 4; 220195098Sed args.nreturns = 1; 221198090Srdivacky args.phandle = HDL2CELL(handle); 222195098Sed args.prop = ADR2CELL(prop); 223195098Sed args.buf = ADR2CELL(buf); 224195098Sed args.len = len; 225195098Sed if (openfirmware(&args) == -1) 226198090Srdivacky return -1; 227208599Srdivacky return args.size; 228195098Sed} 229195098Sed#endif 230202878Srdivacky 231202878Srdivackyint 232198090SrdivackyOF_interpret(const char *cmd, int nargs, int nreturns, ...) 233195098Sed{ 234195098Sed va_list ap; 235202878Srdivacky struct { 236198090Srdivacky cell_t name; 237198090Srdivacky cell_t nargs; 238202878Srdivacky cell_t nreturns; 239195098Sed cell_t slot[16]; 240202878Srdivacky } args; 241198090Srdivacky cell_t status; 242195098Sed int i = 0; 243198090Srdivacky 244202878Srdivacky args.name = ADR2CELL("interpret"); 245202878Srdivacky args.nargs = ++nargs; 246198396Srdivacky args.nreturns = ++nreturns; 247198396Srdivacky args.slot[i++] = ADR2CELL(cmd); 248208599Srdivacky va_start(ap, nreturns); 249195098Sed while (i < nargs) { 250195098Sed args.slot[i++] = va_arg(ap, cell_t); 251198396Srdivacky } 252202878Srdivacky if (openfirmware(&args) == -1) { 253195098Sed va_end(ap); 254202878Srdivacky return (-1); 255203954Srdivacky } 256203954Srdivacky status = args.slot[i++]; 257203954Srdivacky while (i < nargs+nreturns) { 258203954Srdivacky *va_arg(ap, cell_t *) = args.slot[i++]; 259203954Srdivacky } 260203954Srdivacky va_end(ap); 261203954Srdivacky 262203954Srdivacky return status; 263203954Srdivacky} 264203954Srdivacky 265203954Srdivackyint 266203954SrdivackyOF_package_to_path(int phandle, char *buf, int buflen) 267203954Srdivacky{ 268203954Srdivacky struct { 269203954Srdivacky cell_t name; 270203954Srdivacky cell_t nargs; 271203954Srdivacky cell_t nreturns; 272203954Srdivacky cell_t phandle; 273203954Srdivacky cell_t buf; 274203954Srdivacky cell_t buflen; 275203954Srdivacky cell_t length; 276203954Srdivacky } args; 277203954Srdivacky 278202878Srdivacky if (buflen > PAGE_SIZE) 279202878Srdivacky return -1; 280202878Srdivacky args.name = ADR2CELL("package-to-path"); 281202878Srdivacky args.nargs = 3; 282202878Srdivacky args.nreturns = 1; 283202878Srdivacky args.phandle = HDL2CELL(phandle); 284202878Srdivacky args.buf = ADR2CELL(buf); 285202878Srdivacky args.buflen = buflen; 286202878Srdivacky if (openfirmware(&args) < 0) 287202878Srdivacky return -1; 288202878Srdivacky return args.length; 289202878Srdivacky} 290202878Srdivacky 291195098Sedint 292195098SedOF_open(const char *dname) 293202878Srdivacky{ 294202878Srdivacky struct { 295195098Sed cell_t name; 296195098Sed cell_t nargs; 297198090Srdivacky cell_t nreturns; 298202878Srdivacky cell_t dname; 299202878Srdivacky cell_t handle; 300198090Srdivacky } args; 301198090Srdivacky 302208599Srdivacky args.name = ADR2CELL("open"); 303208599Srdivacky args.nargs = 1; 304208599Srdivacky args.nreturns = 1; 305208599Srdivacky args.dname = ADR2CELL(dname); 306208599Srdivacky if (openfirmware(&args) == -1 || 307208599Srdivacky args.handle == 0) 308208599Srdivacky return -1; 309208599Srdivacky return args.handle; 310208599Srdivacky} 311208599Srdivacky 312208599Srdivackyvoid 313208599SrdivackyOF_close(int handle) 314208599Srdivacky{ 315208599Srdivacky struct { 316208599Srdivacky cell_t name; 317208599Srdivacky cell_t nargs; 318208599Srdivacky cell_t nreturns; 319208599Srdivacky cell_t handle; 320208599Srdivacky } args; 321208599Srdivacky 322203954Srdivacky args.name = ADR2CELL("close"); 323203954Srdivacky args.nargs = 1; 324203954Srdivacky args.nreturns = 0; 325203954Srdivacky args.handle = HDL2CELL(handle); 326203954Srdivacky openfirmware(&args); 327202878Srdivacky} 328198090Srdivacky 329202878Srdivackyint 330203954SrdivackyOF_write(int handle, const void *addr, int len) 331203954Srdivacky{ 332202878Srdivacky struct { 333202878Srdivacky cell_t name; 334202878Srdivacky cell_t nargs; 335202878Srdivacky cell_t nreturns; 336202878Srdivacky cell_t ihandle; 337198090Srdivacky cell_t addr; 338198090Srdivacky cell_t len; 339202878Srdivacky cell_t actual; 340202878Srdivacky } args; 341202878Srdivacky 342202878Srdivacky args.name = ADR2CELL("write"); 343202878Srdivacky args.nargs = 3; 344202878Srdivacky args.nreturns = 1; 345202878Srdivacky args.ihandle = HDL2CELL(handle); 346202878Srdivacky args.addr = ADR2CELL(addr); 347202878Srdivacky args.len = len; 348202878Srdivacky if (openfirmware(&args) == -1) 349198090Srdivacky return -1; 350198090Srdivacky return args.actual; 351198090Srdivacky} 352198090Srdivacky 353198090Srdivackyint 354198090SrdivackyOF_read(int handle, void *addr, int len) 355198090Srdivacky{ 356198090Srdivacky struct { 357198090Srdivacky cell_t name; 358198090Srdivacky cell_t nargs; 359202878Srdivacky cell_t nreturns; 360198090Srdivacky cell_t ihandle; 361198090Srdivacky cell_t addr; 362198090Srdivacky cell_t len; 363202878Srdivacky cell_t actual; 364198090Srdivacky } args; 365198090Srdivacky 366208599Srdivacky args.name = ADR2CELL("read"); 367208599Srdivacky args.nargs = 3; 368208599Srdivacky args.nreturns = 1; 369208599Srdivacky args.ihandle = HDL2CELL(handle); 370208599Srdivacky args.addr = ADR2CELL(addr); 371208599Srdivacky args.len = len; 372208599Srdivacky if (openfirmware(&args) == -1) { 373208599Srdivacky return -1; 374208599Srdivacky } 375208599Srdivacky return args.actual; 376208599Srdivacky} 377208599Srdivacky 378208599Srdivackyint 379208599SrdivackyOF_seek(int handle, u_quad_t pos) 380208599Srdivacky{ 381208599Srdivacky struct { 382208599Srdivacky cell_t name; 383202878Srdivacky cell_t nargs; 384202878Srdivacky cell_t nreturns; 385203954Srdivacky cell_t handle; 386203954Srdivacky cell_t poshi; 387203954Srdivacky cell_t poslo; 388203954Srdivacky cell_t status; 389203954Srdivacky } args; 390203954Srdivacky 391203954Srdivacky args.name = ADR2CELL("seek"); 392203954Srdivacky args.nargs = 3; 393203954Srdivacky args.nreturns = 1; 394203954Srdivacky args.handle = HDL2CELL(handle); 395203954Srdivacky args.poshi = HDQ2CELL_HI(pos); 396203954Srdivacky args.poslo = HDQ2CELL_LO(pos); 397203954Srdivacky if (openfirmware(&args) == -1) { 398203954Srdivacky return -1; 399203954Srdivacky } 400203954Srdivacky return args.status; 401203954Srdivacky} 402203954Srdivacky 403203954Srdivackyvoid 404203954SrdivackyOF_release(void *virt, u_int size) 405203954Srdivacky{ 406203954Srdivacky struct { 407203954Srdivacky cell_t name; 408203954Srdivacky cell_t nargs; 409203954Srdivacky cell_t nreturns; 410203954Srdivacky cell_t virt; 411203954Srdivacky cell_t size; 412203954Srdivacky } args; 413203954Srdivacky 414203954Srdivacky args.name = ADR2CELL("release"); 415203954Srdivacky args.nargs = 2; 416203954Srdivacky args.nreturns = 0; 417203954Srdivacky args.virt = ADR2CELL(virt); 418203954Srdivacky args.size = size; 419202878Srdivacky openfirmware(&args); 420195098Sed} 421202878Srdivacky 422202878Srdivackyint 423202878SrdivackyOF_milliseconds(void) 424202878Srdivacky{ 425202878Srdivacky struct { 426202878Srdivacky cell_t name; 427202878Srdivacky cell_t nargs; 428202878Srdivacky cell_t nreturns; 429202878Srdivacky cell_t ms; 430202878Srdivacky } args; 431202878Srdivacky 432202878Srdivacky args.name = ADR2CELL("milliseconds"); 433202878Srdivacky args.nargs = 0; 434202878Srdivacky args.nreturns = 1; 435202878Srdivacky openfirmware(&args); 436202878Srdivacky return args.ms; 437202878Srdivacky} 438202878Srdivacky 439203954Srdivackyint 440203954SrdivackyOF_peer(int phandle) 441202878Srdivacky{ 442195098Sed struct { 443195098Sed cell_t name; 444202878Srdivacky cell_t nargs; 445202878Srdivacky cell_t nreturns; 446202878Srdivacky cell_t phandle; 447202878Srdivacky cell_t sibling; 448195098Sed } args; 449202878Srdivacky 450195098Sed args.name = ADR2CELL("peer"); 451202878Srdivacky args.nargs = 1; 452202878Srdivacky args.nreturns = 1; 453202878Srdivacky args.phandle = HDL2CELL(phandle); 454202878Srdivacky if (openfirmware(&args) == -1) 455202878Srdivacky return 0; 456202878Srdivacky return args.sibling; 457202878Srdivacky} 458202878Srdivacky 459202878Srdivackyint 460202878SrdivackyOF_child(int phandle) 461202878Srdivacky{ 462202878Srdivacky struct { 463202878Srdivacky cell_t name; 464202878Srdivacky cell_t nargs; 465202878Srdivacky cell_t nreturns; 466202878Srdivacky cell_t phandle; 467195098Sed cell_t child; 468202878Srdivacky } args; 469202878Srdivacky 470202878Srdivacky args.name = ADR2CELL("child"); 471202878Srdivacky args.nargs = 1; 472202878Srdivacky args.nreturns = 1; 473195098Sed args.phandle = HDL2CELL(phandle); 474202878Srdivacky if (openfirmware(&args) == -1) 475202878Srdivacky return 0; 476202878Srdivacky return args.child; 477202878Srdivacky} 478202878Srdivacky 479202878Srdivackystatic u_int mmuh = -1; 480202878Srdivackystatic u_int memh = -1; 481202878Srdivacky 482202878Srdivackyvoid 483202878SrdivackyOF_initialize(void) 484202878Srdivacky{ 485202878Srdivacky u_int chosen; 486202878Srdivacky 487203954Srdivacky if ( (chosen = OF_finddevice("/chosen")) == -1) { 488202878Srdivacky OF_exit(); 489195098Sed } 490195098Sed if (OF_getprop(chosen, "mmu", &mmuh, sizeof(mmuh)) != sizeof(mmuh) 491203954Srdivacky || OF_getprop(chosen, "memory", &memh, sizeof(memh)) != sizeof(memh)) 492203954Srdivacky OF_exit(); 493203954Srdivacky} 494203954Srdivacky 495203954Srdivacky/* 496203954Srdivacky * The following need either the handle to memory or the handle to the MMU. 497203954Srdivacky */ 498202878Srdivacky 499202878Srdivacky/* 500202878Srdivacky * Grab some address space from the prom 501202878Srdivacky * 502202878Srdivacky * Only works while the prom is actively mapping us. 503202878Srdivacky */ 504202878Srdivackyvaddr_t 505202878SrdivackyOF_claim_virt(vaddr_t vaddr, int len) 506202878Srdivacky{ 507202878Srdivacky struct { 508202878Srdivacky cell_t name; 509202878Srdivacky cell_t nargs; 510202878Srdivacky cell_t nreturns; 511202878Srdivacky cell_t method; 512202878Srdivacky cell_t ihandle; 513202878Srdivacky cell_t align; 514202878Srdivacky cell_t len; 515202878Srdivacky cell_t vaddr; 516202878Srdivacky cell_t status; 517195098Sed cell_t retaddr; 518195098Sed } args; 519195098Sed 520198090Srdivacky#ifdef __notyet 521198090Srdivacky if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) { 522198090Srdivacky OF_printf("OF_claim_virt: cannot get mmuh\r\n"); 523198090Srdivacky return -1LL; 524198090Srdivacky } 525198090Srdivacky#endif 526198090Srdivacky args.name = ADR2CELL("call-method"); 527198090Srdivacky args.nargs = 5; 528198090Srdivacky args.nreturns = 2; 529198090Srdivacky args.method = ADR2CELL("claim"); 530198090Srdivacky args.ihandle = HDL2CELL(mmuh); 531198090Srdivacky args.align = 0; 532198090Srdivacky args.len = len; 533198090Srdivacky args.vaddr = ADR2CELL(vaddr); 534198090Srdivacky if (openfirmware(&args) != 0) 535198090Srdivacky return -1LL; 536195098Sed return (vaddr_t)args.retaddr; 537198090Srdivacky} 538198090Srdivacky 539198090Srdivacky/* 540198090Srdivacky * Request some address space from the prom 541198090Srdivacky * 542198090Srdivacky * Only works while the prom is actively mapping us. 543198090Srdivacky */ 544202878Srdivackyvaddr_t 545198090SrdivackyOF_alloc_virt(int len, int align) 546198090Srdivacky{ 547198090Srdivacky int retaddr=-1; 548198090Srdivacky struct { 549198090Srdivacky cell_t name; 550195098Sed cell_t nargs; 551198090Srdivacky cell_t nreturns; 552198090Srdivacky cell_t method; 553198090Srdivacky cell_t ihandle; 554198090Srdivacky cell_t align; 555198090Srdivacky cell_t len; 556195098Sed cell_t status; 557195098Sed cell_t retaddr; 558198090Srdivacky } args; 559195098Sed 560195098Sed#ifdef __notyet 561195098Sed if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) { 562202878Srdivacky OF_printf("OF_alloc_virt: cannot get mmuh\r\n"); 563195098Sed return -1LL; 564195098Sed } 565204642Srdivacky#endif 566204642Srdivacky args.name = ADR2CELL("call-method"); 567204642Srdivacky args.nargs = 4; 568204642Srdivacky args.nreturns = 2; 569204642Srdivacky args.method = ADR2CELL("claim"); 570204642Srdivacky args.ihandle = HDL2CELL(mmuh); 571204642Srdivacky args.align = align; 572198090Srdivacky args.len = len; 573195098Sed args.retaddr = ADR2CELL(&retaddr); 574195098Sed if (openfirmware(&args) != 0) 575202878Srdivacky return -1LL; 576202878Srdivacky return (vaddr_t)args.retaddr; 577195098Sed} 578195098Sed 579198090Srdivacky/* 580203954Srdivacky * Release some address space to the prom 581203954Srdivacky * 582203954Srdivacky * Only works while the prom is actively mapping us. 583203954Srdivacky */ 584203954Srdivackyint 585203954SrdivackyOF_free_virt(vaddr_t vaddr, int len) 586198090Srdivacky{ 587203954Srdivacky struct { 588203954Srdivacky cell_t name; 589203954Srdivacky cell_t nargs; 590203954Srdivacky cell_t nreturns; 591203954Srdivacky cell_t method; 592203954Srdivacky cell_t ihandle; 593203954Srdivacky cell_t len; 594203954Srdivacky cell_t vaddr; 595203954Srdivacky } args; 596203954Srdivacky 597203954Srdivacky#ifdef __notyet 598203954Srdivacky if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) { 599203954Srdivacky OF_printf("OF_claim_virt: cannot get mmuh\r\n"); 600203954Srdivacky return -1; 601203954Srdivacky } 602203954Srdivacky#endif 603203954Srdivacky args.name = ADR2CELL("call-method"); 604203954Srdivacky args.nargs = 4; 605203954Srdivacky args.nreturns = 0; 606203954Srdivacky args.method = ADR2CELL("release"); 607203954Srdivacky args.ihandle = HDL2CELL(mmuh); 608203954Srdivacky args.vaddr = ADR2CELL(vaddr); 609203954Srdivacky args.len = len; 610203954Srdivacky return openfirmware(&args); 611203954Srdivacky} 612203954Srdivacky 613203954Srdivacky 614203954Srdivacky/* 615203954Srdivacky * Unmap some address space 616203954Srdivacky * 617203954Srdivacky * Only works while the prom is actively mapping us. 618203954Srdivacky */ 619203954Srdivackyint 620203954SrdivackyOF_unmap_virt(vaddr_t vaddr, int len) 621203954Srdivacky{ 622203954Srdivacky struct { 623203954Srdivacky cell_t name; 624203954Srdivacky cell_t nargs; 625203954Srdivacky cell_t nreturns; 626203954Srdivacky cell_t method; 627203954Srdivacky cell_t ihandle; 628203954Srdivacky cell_t len; 629203954Srdivacky cell_t vaddr; 630203954Srdivacky } args; 631203954Srdivacky 632203954Srdivacky#ifdef __notyet 633203954Srdivacky if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) { 634203954Srdivacky OF_printf("OF_claim_virt: cannot get mmuh\r\n"); 635203954Srdivacky return -1; 636203954Srdivacky } 637203954Srdivacky#endif 638203954Srdivacky args.name = ADR2CELL("call-method"); 639203954Srdivacky args.nargs = 4; 640198090Srdivacky args.nreturns = 0; 641203954Srdivacky args.method = ADR2CELL("unmap"); 642203954Srdivacky args.ihandle = HDL2CELL(mmuh); 643203954Srdivacky args.vaddr = ADR2CELL(vaddr); 644203954Srdivacky args.len = len; 645203954Srdivacky return openfirmware(&args); 646203954Srdivacky} 647203954Srdivacky 648203954Srdivacky/* 649203954Srdivacky * Have prom map in some memory 650203954Srdivacky * 651203954Srdivacky * Only works while the prom is actively mapping us. 652198090Srdivacky */ 653203954Srdivackyvaddr_t 654203954SrdivackyOF_map_phys(paddr_t paddr, off_t size, vaddr_t vaddr, int mode) 655198090Srdivacky{ 656203954Srdivacky struct { 657203954Srdivacky cell_t name; 658203954Srdivacky cell_t nargs; 659203954Srdivacky cell_t nreturns; 660203954Srdivacky cell_t method; 661195340Sed cell_t ihandle; 662203954Srdivacky cell_t mode; 663198090Srdivacky cell_t size; 664203954Srdivacky cell_t vaddr; 665203954Srdivacky cell_t paddr_hi; 666203954Srdivacky cell_t paddr_lo; 667203954Srdivacky } args; 668203954Srdivacky 669203954Srdivacky#ifdef __notyet 670203954Srdivacky if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) { 671203954Srdivacky OF_printf("OF_map_phys: cannot get mmuh\r\n"); 672208599Srdivacky return 0LL; 673206083Srdivacky } 674208599Srdivacky#endif 675208599Srdivacky args.name = ADR2CELL("call-method"); 676208599Srdivacky args.nargs = 7; 677206083Srdivacky args.nreturns = 0; 678203954Srdivacky args.method = ADR2CELL("map"); 679206274Srdivacky args.ihandle = HDL2CELL(mmuh); 680203954Srdivacky args.mode = mode; 681203954Srdivacky args.size = size; 682202878Srdivacky args.vaddr = ADR2CELL(vaddr); 683195098Sed args.paddr_hi = HDQ2CELL_HI(paddr); 684195098Sed args.paddr_lo = HDQ2CELL_LO(paddr); 685206274Srdivacky 686206274Srdivacky if (openfirmware(&args) == -1) 687206274Srdivacky return -1; 688206274Srdivacky return 0; 689206274Srdivacky} 690206274Srdivacky 691206274Srdivacky 692206274Srdivacky/* 693206274Srdivacky * Request some RAM from the prom 694206274Srdivacky * 695195098Sed * Only works while the prom is actively mapping us. 696195098Sed */ 697195098Sedpaddr_t 698203954SrdivackyOF_alloc_phys(int len, int align) 699202878Srdivacky{ 700202878Srdivacky struct { 701205218Srdivacky cell_t name; 702202878Srdivacky cell_t nargs; 703203954Srdivacky cell_t nreturns; 704205218Srdivacky cell_t method; 705203954Srdivacky cell_t ihandle; 706195098Sed cell_t align; 707 cell_t len; 708 cell_t status; 709 cell_t phys_hi; 710 cell_t phys_lo; 711 } args; 712 713#ifdef __notyet 714 if (memh == -1 && ((memh = get_memory_handle()) == -1)) { 715 OF_printf("OF_alloc_phys: cannot get memh\r\n"); 716 return -1LL; 717 } 718#endif 719 args.name = ADR2CELL("call-method"); 720 args.nargs = 4; 721 args.nreturns = 3; 722 args.method = ADR2CELL("claim"); 723 args.ihandle = HDL2CELL(memh); 724 args.align = align; 725 args.len = len; 726 if (openfirmware(&args) != 0) 727 return -1LL; 728 return (paddr_t)CELL2HDQ(args.phys_hi, args.phys_lo); 729} 730 731/* 732 * Request some specific RAM from the prom 733 * 734 * Only works while the prom is actively mapping us. 735 */ 736paddr_t 737OF_claim_phys(paddr_t phys, int len) 738{ 739 struct { 740 cell_t name; 741 cell_t nargs; 742 cell_t nreturns; 743 cell_t method; 744 cell_t ihandle; 745 cell_t align; 746 cell_t len; 747 cell_t phys_hi; 748 cell_t phys_lo; 749 cell_t status; 750 cell_t res; 751 cell_t rphys_hi; 752 cell_t rphys_lo; 753 } args; 754 755#ifdef __notyet 756 if (memh == -1 && ((memh = get_memory_handle()) == -1)) { 757 OF_printf("OF_alloc_phys: cannot get memh\r\n"); 758 return 0LL; 759 } 760#endif 761 args.name = ADR2CELL("call-method"); 762 args.nargs = 6; 763 args.nreturns = 4; 764 args.method = ADR2CELL("claim"); 765 args.ihandle = HDL2CELL(memh); 766 args.align = 0; 767 args.len = len; 768 args.phys_hi = HDQ2CELL_HI(phys); 769 args.phys_lo = HDQ2CELL_LO(phys); 770 if (openfirmware(&args) != 0) 771 return 0LL; 772 return (paddr_t)CELL2HDQ(args.rphys_hi, args.rphys_lo); 773} 774 775/* 776 * Free some RAM to prom 777 * 778 * Only works while the prom is actively mapping us. 779 */ 780int 781OF_free_phys(paddr_t phys, int len) 782{ 783 struct { 784 cell_t name; 785 cell_t nargs; 786 cell_t nreturns; 787 cell_t method; 788 cell_t ihandle; 789 cell_t len; 790 cell_t phys_hi; 791 cell_t phys_lo; 792 } args; 793 794#ifdef __notyet 795 if (memh == -1 && ((memh = get_memory_handle()) == -1)) { 796 OF_printf("OF_free_phys: cannot get memh\r\n"); 797 return -1; 798 } 799#endif 800 args.name = ADR2CELL("call-method"); 801 args.nargs = 5; 802 args.nreturns = 0; 803 args.method = ADR2CELL("release"); 804 args.ihandle = HDL2CELL(memh); 805 args.len = len; 806 args.phys_hi = HDQ2CELL_HI(phys); 807 args.phys_lo = HDQ2CELL_LO(phys); 808 return openfirmware(&args); 809} 810 811 812/* 813 * Claim virtual memory -- does not map it in. 814 */ 815 816void * 817OF_claim(void *virt, u_int size, u_int align) 818{ 819#define SUNVMOF 820#ifndef SUNVMOF 821 struct { 822 cell_t name; 823 cell_t nargs; 824 cell_t nreturns; 825 cell_t virt; 826 cell_t size; 827 cell_t align; 828 cell_t baseaddr; 829 } args; 830 831 832 args.name = ADR2CELL("claim"); 833 args.nargs = 3; 834 args.nreturns = 1; 835 args.virt = virt; 836 args.size = size; 837 args.align = align; 838 if (openfirmware(&args) == -1) 839 return (void *)-1; 840 return args.baseaddr; 841#else 842/* 843 * Sun Ultra machines run the firmware with VM enabled, 844 * so you need to handle allocating and mapping both 845 * virtual and physical memory. Ugh. 846 */ 847 848 paddr_t paddr; 849 void* newvirt = NULL; 850 851 if (virt == NULL) { 852 if ((virt = (void*)OF_alloc_virt(size, align)) == (void*)-1) { 853 printf("OF_alloc_virt(%d,%d) failed w/%p\n", size, align, virt); 854 return (void *)-1; 855 } 856 } else { 857 if ((newvirt = (void*)OF_claim_virt((vaddr_t)virt, size)) == (void*)-1) { 858 printf("OF_claim_virt(%p,%d) failed w/%p\n", virt, size, newvirt); 859 return (void *)-1; 860 } 861 } 862 if ((paddr = OF_alloc_phys(size, align)) == (paddr_t)-1) { 863 printf("OF_alloc_phys(%d,%d) failed\n", size, align); 864 OF_free_virt((vaddr_t)virt, size); 865 return (void *)-1; 866 } 867 if (OF_map_phys(paddr, size, (vaddr_t)virt, -1) == -1) { 868 printf("OF_map_phys(0x%lx,%d,%p,%d) failed\n", 869 (u_long)paddr, size, virt, -1); 870 OF_free_phys((paddr_t)paddr, size); 871 OF_free_virt((vaddr_t)virt, size); 872 return (void *)-1; 873 } 874 return (void *)virt; 875#endif 876} 877