ofw_machdep.c revision 199886
150477Speter/*- 233548Sjkh * Copyright (C) 1996 Wolfgang Solfrank. 32893Sdfr * Copyright (C) 1996 TooLs GmbH. 42893Sdfr * All rights reserved. 533548Sjkh * 633548Sjkh * Redistribution and use in source and binary forms, with or without 72893Sdfr * modification, are permitted provided that the following conditions 82893Sdfr * are met: 92893Sdfr * 1. Redistributions of source code must retain the above copyright 102893Sdfr * notice, this list of conditions and the following disclaimer. 112893Sdfr * 2. Redistributions in binary form must reproduce the above copyright 122893Sdfr * notice, this list of conditions and the following disclaimer in the 132893Sdfr * documentation and/or other materials provided with the distribution. 142893Sdfr * 3. All advertising materials mentioning features or use of this software 152893Sdfr * must display the following acknowledgement: 162893Sdfr * This product includes software developed by TooLs GmbH. 172893Sdfr * 4. The name of TooLs GmbH may not be used to endorse or promote products 182893Sdfr * derived from this software without specific prior written permission. 192893Sdfr * 202893Sdfr * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 212893Sdfr * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 222893Sdfr * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 232893Sdfr * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 242893Sdfr * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 252893Sdfr * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 262893Sdfr * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 272893Sdfr * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 282893Sdfr * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 292893Sdfr * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 302893Sdfr * 312893Sdfr * $NetBSD: ofw_machdep.c,v 1.5 2000/05/23 13:25:43 tsubai Exp $ 322893Sdfr */ 332893Sdfr 342893Sdfr#include <sys/cdefs.h> 35139776Simp__FBSDID("$FreeBSD: head/sys/powerpc/aim/ofw_machdep.c 199886 2009-11-28 17:33:19Z nwhitehorn $"); 362893Sdfr 378876Srgrimes#include <sys/param.h> 382893Sdfr#include <sys/bus.h> 392893Sdfr#include <sys/systm.h> 408876Srgrimes#include <sys/conf.h> 412893Sdfr#include <sys/disk.h> 428876Srgrimes#include <sys/fcntl.h> 432893Sdfr#include <sys/malloc.h> 442893Sdfr#include <sys/stat.h> 452893Sdfr 462893Sdfr#include <net/ethernet.h> 478876Srgrimes 482893Sdfr#include <dev/ofw/openfirm.h> 492893Sdfr#include <dev/ofw/ofw_pci.h> 502893Sdfr#include <dev/ofw/ofw_bus.h> 512893Sdfr 522893Sdfr#include <vm/vm.h> 53171754Sbde#include <vm/vm_param.h> 5440651Sbde#include <vm/vm_page.h> 55177785Skib 56171754Sbde#include <machine/bus.h> 57171754Sbde#include <machine/cpu.h> 58171748Sbde#include <machine/md_var.h> 59171754Sbde#include <machine/platform.h> 60171754Sbde#include <machine/ofw_machdep.h> 61171748Sbde 622893Sdfr#define OFMEM_REGIONS 32 63164033Srwatsonstatic struct mem_region OFmem[OFMEM_REGIONS + 1], OFavail[OFMEM_REGIONS + 3]; 642893Sdfrstatic struct mem_region OFfree[OFMEM_REGIONS + 3]; 65171754Sbde 662893Sdfrstruct mem_region64 { 672893Sdfr vm_offset_t mr_start_hi; 68171754Sbde vm_offset_t mr_start_lo; 69171754Sbde vm_size_t mr_size; 70171754Sbde}; 71171754Sbde 7277162Sruextern register_t ofmsr[5]; 7377162Sruextern struct pmap ofw_pmap; 7477162Srustatic int (*ofwcall)(void *); 7577162Srustatic void *fdt; 76171754Sbdeint ofw_real_mode; 772893Sdfr 78172757Sbdestatic int openfirmware(void *args); 79138471Sphk 80172798Sbde/* 81172757Sbde * Saved SPRG0-3 from OpenFirmware. Will be restored prior to the callback. 82172757Sbde */ 83172757Sbderegister_t ofw_sprg0_save; 84172757Sbde 85172757Sbdestatic __inline void 86138471Sphkofw_sprg_prepare(void) 87138471Sphk{ 88138471Sphk /* 8956674Snyan * Assume that interrupt are disabled at this point, or 9056674Snyan * SPRG1-3 could be trashed 9156674Snyan */ 9256674Snyan __asm __volatile("mfsprg0 %0\n\t" 9356674Snyan "mtsprg0 %1\n\t" 9456674Snyan "mtsprg1 %2\n\t" 9556674Snyan "mtsprg2 %3\n\t" 9656674Snyan "mtsprg3 %4\n\t" 9756674Snyan : "=&r"(ofw_sprg0_save) 9856674Snyan : "r"(ofmsr[1]), 9956674Snyan "r"(ofmsr[2]), 100151897Srwatson "r"(ofmsr[3]), 101151897Srwatson "r"(ofmsr[4])); 10230309Sphk} 103171757Sbde 104120492Sfjoestatic __inline void 105138471Sphkofw_sprg_restore(void) 106183754Sattilio{ 107170188Strhodes /* 108138471Sphk * Note that SPRG1-3 contents are irrelevant. They are scratch 109101777Sphk * registers used in the early portion of trap handling when 110101777Sphk * interrupts are disabled. 111101777Sphk * 112101777Sphk * PCPU data cannot be used until this routine is called ! 11312338Sbde */ 114134345Stjr __asm __volatile("mtsprg0 %0" :: "r"(ofw_sprg0_save)); 115134345Stjr} 116134345Stjr 11733548Sjkh/* 118166558Srodrigc * Memory region utilities: determine if two regions overlap, 11933548Sjkh * and merge two overlapping regions into one 12033548Sjkh */ 121138471Sphkstatic int 122138471Sphkmemr_overlap(struct mem_region *r1, struct mem_region *r2) 12333548Sjkh{ 124138471Sphk if ((r1->mr_start + r1->mr_size) < r2->mr_start || 125138471Sphk (r2->mr_start + r2->mr_size) < r1->mr_start) 126138471Sphk return (FALSE); 127138471Sphk 128138471Sphk return (TRUE); 129138471Sphk} 130138471Sphk 131138471Sphkstatic void 132138471Sphkmemr_merge(struct mem_region *from, struct mem_region *to) 133138471Sphk{ 134138471Sphk int end; 135138471Sphk end = imax(to->mr_start + to->mr_size, from->mr_start + from->mr_size); 136138471Sphk to->mr_start = imin(from->mr_start, to->mr_start); 137138471Sphk to->mr_size = end - to->mr_start; 138138471Sphk} 139138471Sphk 140134345Stjr/* 141134345Stjr * This is called during powerpc_init, before the system is really initialized. 142134345Stjr * It shall provide the total and the available regions of RAM. 143134345Stjr * Both lists must have a zero-size entry as terminator. 144134345Stjr * The available regions need not take the kernel into account, but needs 145134345Stjr * to provide space for two additional entry beyond the terminating one. 146134345Stjr */ 147134345Stjrvoid 148134345Stjrofw_mem_regions(struct mem_region **memp, int *memsz, 149134345Stjr struct mem_region **availp, int *availsz) 150138471Sphk{ 151138471Sphk phandle_t phandle; 152138471Sphk int asz, msz, fsz; 153138471Sphk int i, j; 154138471Sphk int still_merging; 155138471Sphk cell_t address_cells; 156138471Sphk 157138471Sphk asz = msz = 0; 158138471Sphk 159138471Sphk /* 160152595Srodrigc * Get #address-cells from root node, defaulting to 1 if it cannot 161152595Srodrigc * be found. 162138471Sphk */ 163138471Sphk phandle = OF_finddevice("/"); 164152595Srodrigc if (OF_getprop(phandle, "#address-cells", &address_cells, 165152595Srodrigc sizeof(address_cells)) < sizeof(address_cells)) 166138471Sphk address_cells = 1; 167138471Sphk 16833548Sjkh /* 169152610Srodrigc * Get memory. 170152610Srodrigc */ 171152610Srodrigc if ((phandle = OF_finddevice("/memory")) == -1 172138471Sphk || (asz = OF_getprop(phandle, "available", 173138471Sphk OFavail, sizeof OFavail[0] * OFMEM_REGIONS)) <= 0) 17433548Sjkh { 17533548Sjkh if (ofw_real_mode) { 17633548Sjkh /* XXX MAMBO */ 17733548Sjkh printf("Physical memory unknown -- guessing 128 MB\n"); 17833548Sjkh 17933548Sjkh /* Leave the first 0xA000000 bytes for the kernel */ 18033548Sjkh OFavail[0].mr_start = 0xA00000; 18133548Sjkh OFavail[0].mr_size = 0x75FFFFF; 18233548Sjkh asz = sizeof(OFavail[0]); 18333548Sjkh } else { 18433548Sjkh panic("no memory?"); 18533548Sjkh } 186144058Sjeff } 187191990Sattilio 18833548Sjkh if (address_cells == 2) { 189171757Sbde struct mem_region64 OFmem64[OFMEM_REGIONS + 1]; 190171757Sbde if ((phandle == -1) || (msz = OF_getprop(phandle, "reg", 19133548Sjkh OFmem64, sizeof OFmem64[0] * OFMEM_REGIONS)) <= 0) { 19233548Sjkh if (ofw_real_mode) { 19333548Sjkh /* XXX MAMBO */ 19433548Sjkh OFmem64[0].mr_start_hi = 0; 19533548Sjkh OFmem64[0].mr_start_lo = 0x0; 19633548Sjkh OFmem64[0].mr_size = 0x7FFFFFF; 197138471Sphk msz = sizeof(OFmem64[0]); 198191990Sattilio } else { 199138471Sphk panic("Physical memory map not found"); 200138471Sphk } 201138471Sphk } 202138471Sphk 203138471Sphk for (i = 0, j = 0; i < msz/sizeof(OFmem64[0]); i++) { 204138471Sphk if (OFmem64[i].mr_start_hi == 0) { 205138471Sphk OFmem[i].mr_start = OFmem64[i].mr_start_lo; 206138471Sphk OFmem[i].mr_size = OFmem64[i].mr_size; 207138471Sphk 208138471Sphk /* 209138471Sphk * Check for memory regions extending above 32-bit 210138471Sphk * memory space, and restrict them to stay there. 211138471Sphk */ 212138471Sphk if (((uint64_t)OFmem[i].mr_start + 213138471Sphk (uint64_t)OFmem[i].mr_size) > 214138471Sphk BUS_SPACE_MAXADDR_32BIT) { 215138471Sphk OFmem[i].mr_size = BUS_SPACE_MAXADDR_32BIT - 216171757Sbde OFmem[i].mr_start; 217171757Sbde } 218171757Sbde j++; 219171757Sbde } 220138471Sphk } 221171757Sbde msz = j*sizeof(OFmem[0]); 222171757Sbde } else { 223171757Sbde if ((msz = OF_getprop(phandle, "reg", 224138471Sphk OFmem, sizeof OFmem[0] * OFMEM_REGIONS)) <= 0) 225138471Sphk panic("Physical memory map not found"); 226138471Sphk } 227138471Sphk 228138471Sphk *memp = OFmem; 229138471Sphk *memsz = msz / sizeof(struct mem_region); 2302893Sdfr 2318876Srgrimes 2322893Sdfr /* 2338876Srgrimes * OFavail may have overlapping regions - collapse these 2342893Sdfr * and copy out remaining regions to OFfree 23512144Sphk */ 236191990Sattilio asz /= sizeof(struct mem_region); 2372893Sdfr do { 2382893Sdfr still_merging = FALSE; 239191990Sattilio for (i = 0; i < asz; i++) { 24033548Sjkh if (OFavail[i].mr_size == 0) 24133548Sjkh continue; 242132902Sphk for (j = i+1; j < asz; j++) { 243138689Sphk if (OFavail[j].mr_size == 0) 244184413Strasz continue; 245138471Sphk if (memr_overlap(&OFavail[j], &OFavail[i])) { 2462893Sdfr memr_merge(&OFavail[j], &OFavail[i]); 247191990Sattilio /* mark inactive */ 248138471Sphk OFavail[j].mr_size = 0; 249138471Sphk still_merging = TRUE; 250138471Sphk } 2512893Sdfr } 25233548Sjkh } 25333548Sjkh } while (still_merging == TRUE); 2542893Sdfr 2552893Sdfr /* evict inactive ranges */ 25633548Sjkh for (i = 0, fsz = 0; i < asz; i++) { 257158924Srodrigc if (OFavail[i].mr_size != 0) { 258165022Srodrigc OFfree[fsz] = OFavail[i]; 259165022Srodrigc fsz++; 260165022Srodrigc } 261165022Srodrigc } 262165022Srodrigc 263165022Srodrigc *availp = OFfree; 264165022Srodrigc *availsz = fsz; 265138689Sphk} 266165022Srodrigc 267138689Sphkvoid 268137036SphkOF_initial_setup(void *fdt_ptr, void *junk, int (*openfirm)(void *)) 269138471Sphk{ 270191990Sattilio if (ofmsr[0] & PSL_DR) 271133287Sphk ofw_real_mode = 0; 272133287Sphk else 2732893Sdfr ofw_real_mode = 1; 2742893Sdfr 2752893Sdfr ofwcall = openfirm; 276132023Salfred fdt = fdt_ptr; 277138471Sphk} 278138471Sphk 279172883Sdelphijboolean_t 280172883SdelphijOF_bootstrap() 281172883Sdelphij{ 282172883Sdelphij boolean_t status = FALSE; 283172883Sdelphij 284172883Sdelphij if (ofwcall != NULL) { 285172883Sdelphij if (ofw_real_mode) 286172883Sdelphij status = OF_install(OFW_STD_REAL, 0); 287172883Sdelphij else 288172883Sdelphij status = OF_install(OFW_STD_DIRECT, 0); 289172883Sdelphij 290172883Sdelphij if (status != TRUE) 291137036Sphk return status; 292137036Sphk 293171551Sbde OF_init(openfirmware); 294137036Sphk } else { 295137036Sphk status = OF_install(OFW_FDT, 0); 296172883Sdelphij 297172883Sdelphij if (status != TRUE) 298171551Sbde return status; 299172883Sdelphij 300171551Sbde OF_init(fdt); 301172883Sdelphij } 302172883Sdelphij 303172883Sdelphij return (status); 304172883Sdelphij} 305172883Sdelphij 306172883Sdelphijstatic int 307172883Sdelphijopenfirmware(void *args) 308172883Sdelphij{ 309172883Sdelphij long oldmsr; 310138471Sphk int result; 311138471Sphk u_int srsave[16]; 31233548Sjkh u_int i; 31333548Sjkh 31433548Sjkh if (pmap_bootstrapped && ofw_real_mode) 31533548Sjkh args = (void *)pmap_kextract((vm_offset_t)args); 316164033Srwatson 317175202Sattilio __asm __volatile( "\t" 318164033Srwatson "sync\n\t" 319171757Sbde "mfmsr %0\n\t" 320164033Srwatson "mtmsr %1\n\t" 321164033Srwatson "isync\n" 322164033Srwatson : "=r" (oldmsr) 323175294Sattilio : "r" (ofmsr[0]) 324164033Srwatson ); 32533548Sjkh 326175294Sattilio ofw_sprg_prepare(); 327137036Sphk 328137036Sphk if (pmap_bootstrapped && !ofw_real_mode) { 329137036Sphk /* 330137036Sphk * Swap the kernel's address space with Open Firmware's 331137036Sphk */ 332137036Sphk for (i = 0; i < 16; i++) { 333137036Sphk srsave[i] = mfsrin(i << ADDR_SR_SHFT); 334123963Sbde mtsrin(i << ADDR_SR_SHFT, ofw_pmap.pm_sr[i]); 335172883Sdelphij } 336172883Sdelphij 337172883Sdelphij /* 338172883Sdelphij * Clear battable[] translations 339172883Sdelphij */ 340165836Srodrigc if (!(cpu_features & PPC_FEATURE_64)) { 341123963Sbde __asm __volatile("mtdbatu 2, %0\n" 342123873Strhodes "mtdbatu 3, %0" : : "r" (0)); 343123873Strhodes } 344172883Sdelphij isync(); 34533548Sjkh } 3462893Sdfr 3472893Sdfr result = ofwcall(args); 34833548Sjkh 349125796Sbde if (pmap_bootstrapped && !ofw_real_mode) { 3502893Sdfr /* 351138471Sphk * Restore the kernel's addr space. The isync() doesn;t 352138471Sphk * work outside the loop unless mtsrin() is open-coded 353149720Sssouhlal * in an asm statement :( 354132902Sphk */ 35533548Sjkh for (i = 0; i < 16; i++) { 35633548Sjkh mtsrin(i << ADDR_SR_SHFT, srsave[i]); 357132902Sphk isync(); 358132902Sphk } 3598876Srgrimes } 36055756Sphk 361149720Sssouhlal ofw_sprg_restore(); 36255756Sphk 3632893Sdfr __asm( "\t" 3642893Sdfr "mtmsr %0\n\t" 36533548Sjkh "isync\n" 36633548Sjkh : : "r" (oldmsr) 3672893Sdfr ); 368184413Strasz 369164033Srwatson return (result); 370184413Strasz} 371184413Strasz 372164033Srwatsonvoid 373164033SrwatsonOF_halt() 374164033Srwatson{ 375164033Srwatson int retval; /* dummy, this may not be needed */ 376164033Srwatson 37733548Sjkh OF_interpret("shut-down", 1, &retval); 37833548Sjkh for (;;); /* just in case */ 379183754Sattilio} 38033548Sjkh 38133548Sjkhvoid 38233548SjkhOF_reboot() 38333548Sjkh{ 3842893Sdfr int retval; /* dummy, this may not be needed */ 38533548Sjkh 3862893Sdfr OF_interpret("reset-all", 1, &retval); 387149720Sssouhlal for (;;); /* just in case */ 3882893Sdfr} 3892893Sdfr 3902893Sdfrvoid 39133548SjkhOF_getetheraddr(device_t dev, u_char *addr) 39233548Sjkh{ 39333548Sjkh phandle_t node; 394138471Sphk 39533548Sjkh node = ofw_bus_get_node(dev); 396134345Stjr OF_getprop(node, "local-mac-address", addr, ETHER_ADDR_LEN); 397191990Sattilio} 3982893Sdfr 3992893Sdfr/* 400171757Sbde * Return a bus handle and bus tag that corresponds to the register 401138471Sphk * numbered regno for the device referenced by the package handle 4022893Sdfr * dev. This function is intended to be used by console drivers in 403138471Sphk * early boot only. It works by mapping the address of the device's 4042893Sdfr * register in the address space of its parent and recursively walk 40533548Sjkh * the device tree upward this way. 4062893Sdfr */ 4072893Sdfrstatic void 40812144SphkOF_get_addr_props(phandle_t node, uint32_t *addrp, uint32_t *sizep, int *pcip) 409183754Sattilio{ 4102893Sdfr char name[16]; 41133548Sjkh uint32_t addr, size; 41233548Sjkh int pci, res; 413189120Sjhb 4142893Sdfr res = OF_getprop(node, "#address-cells", &addr, sizeof(addr)); 4152893Sdfr if (res == -1) 4162893Sdfr addr = 2; 41733548Sjkh res = OF_getprop(node, "#size-cells", &size, sizeof(size)); 41833548Sjkh if (res == -1) 41955188Sbp size = 1; 420171757Sbde pci = 0; 421137036Sphk if (addr == 3 && size == 2) { 422137036Sphk res = OF_getprop(node, "name", name, sizeof(name)); 4232893Sdfr if (res != -1) { 424189120Sjhb name[sizeof(name) - 1] = '\0'; 425189120Sjhb pci = (strcmp(name, "pci") == 0) ? 1 : 0; 426171551Sbde } 427189120Sjhb } 428189120Sjhb if (addrp != NULL) 429189120Sjhb *addrp = addr; 430137036Sphk if (sizep != NULL) 431137036Sphk *sizep = size; 432171551Sbde if (pcip != NULL) 433137036Sphk *pcip = pci; 434137036Sphk} 435175294Sattilio 4363152Sphkint 437189120SjhbOF_decode_addr(phandle_t dev, int regno, bus_space_tag_t *tag, 43833548Sjkh bus_space_handle_t *handle) 439137036Sphk{ 44033548Sjkh uint32_t cell[32]; 4412893Sdfr bus_addr_t addr, raddr, baddr; 44233548Sjkh bus_size_t size, rsize; 44333548Sjkh uint32_t c, nbridge, naddr, nsize; 44456674Snyan phandle_t bridge, parent; 445171408Sbde u_int spc, rspc; 4462893Sdfr int pci, pcib, res; 447171408Sbde 4483152Sphk /* Sanity checking. */ 4492893Sdfr if (dev == 0) 45033548Sjkh return (EINVAL); 45133548Sjkh bridge = OF_parent(dev); 45233548Sjkh if (bridge == 0) 45333548Sjkh return (EINVAL); 454105655Sjhb if (regno < 0) 45533548Sjkh return (EINVAL); 45656674Snyan if (tag == NULL || handle == NULL) 45787068Sjhb return (EINVAL); 45887068Sjhb 45987068Sjhb /* Get the requested register. */ 46087068Sjhb OF_get_addr_props(bridge, &naddr, &nsize, &pci); 46187068Sjhb res = OF_getprop(dev, (pci) ? "assigned-addresses" : "reg", 46256674Snyan cell, sizeof(cell)); 4632893Sdfr if (res == -1) 464111119Simp return (ENXIO); 4652893Sdfr if (res % sizeof(cell[0])) 466137036Sphk return (ENXIO); 467137036Sphk res /= sizeof(cell[0]); 4682893Sdfr regno *= naddr + nsize; 4692893Sdfr if (regno + naddr + nsize > res) 470171551Sbde return (EINVAL); 471173728Smaxim spc = (pci) ? cell[regno] & OFW_PCI_PHYS_HI_SPACEMASK : ~0; 472171551Sbde addr = 0; 473171551Sbde for (c = 0; c < naddr; c++) 474171551Sbde addr = ((uint64_t)addr << 32) | cell[regno++]; 475171551Sbde size = 0; 476171551Sbde for (c = 0; c < nsize; c++) 477171551Sbde size = ((uint64_t)size << 32) | cell[regno++]; 478171551Sbde 479166340Srodrigc /* 480166340Srodrigc * Map the address range in the bridge's decoding window as given 481166340Srodrigc * by the "ranges" property. If a node doesn't have such property 482166340Srodrigc * then no mapping is done. 483166340Srodrigc */ 484166340Srodrigc parent = OF_parent(bridge); 485166340Srodrigc while (parent != 0) { 486166340Srodrigc OF_get_addr_props(parent, &nbridge, NULL, &pcib); 487166340Srodrigc res = OF_getprop(bridge, "ranges", cell, sizeof(cell)); 488166340Srodrigc if (res == -1) 489166340Srodrigc goto next; 490171757Sbde if (res % sizeof(cell[0])) 491166340Srodrigc return (ENXIO); 492166340Srodrigc res /= sizeof(cell[0]); 4932893Sdfr regno = 0; 4942893Sdfr while (regno < res) { 4952893Sdfr rspc = (pci) 4962893Sdfr ? cell[regno] & OFW_PCI_PHYS_HI_SPACEMASK 49733548Sjkh : ~0; 4982893Sdfr if (rspc != spc) { 499113979Sjhb regno += naddr + nbridge + nsize; 500113979Sjhb continue; 501113979Sjhb } 502113979Sjhb raddr = 0; 5032893Sdfr for (c = 0; c < naddr; c++) 5042893Sdfr raddr = ((uint64_t)raddr << 32) | cell[regno++]; 5052893Sdfr rspc = (pcib) 5062893Sdfr ? cell[regno] & OFW_PCI_PHYS_HI_SPACEMASK 5072893Sdfr : ~0; 5082893Sdfr baddr = 0; 5092893Sdfr for (c = 0; c < nbridge; c++) 51033548Sjkh baddr = ((uint64_t)baddr << 32) | cell[regno++]; 5112893Sdfr rsize = 0; 51256674Snyan for (c = 0; c < nsize; c++) 51356674Snyan rsize = ((uint64_t)rsize << 32) | cell[regno++]; 51456674Snyan if (addr < raddr || addr >= raddr + rsize) 515176431Smarcel continue; 516176431Smarcel addr = addr - raddr + baddr; 517176431Smarcel if (rspc != ~0) 518176431Smarcel spc = rspc; 519176431Smarcel } 520176431Smarcel 521176431Smarcel next: 52287068Sjhb bridge = parent; 52387068Sjhb parent = OF_parent(bridge); 52487068Sjhb OF_get_addr_props(bridge, &naddr, &nsize, &pci); 5252893Sdfr } 5262893Sdfr 5272893Sdfr *tag = &bs_le_tag; 5282893Sdfr return (bus_space_map(*tag, addr, size, 0, handle)); 5292893Sdfr} 5302893Sdfr 5312893Sdfrint 5322893Sdfrmem_valid(vm_offset_t addr, int len) 533166340Srodrigc{ 534171757Sbde int i; 535166340Srodrigc 536166340Srodrigc for (i = 0; i < OFMEM_REGIONS; i++) 537166340Srodrigc if ((addr >= OFmem[i].mr_start) 538166340Srodrigc && (addr + len < OFmem[i].mr_start + OFmem[i].mr_size)) 539166340Srodrigc return (0); 540166340Srodrigc 541166340Srodrigc return (EFAULT); 542166340Srodrigc} 543166340Srodrigc 544166340Srodrigc