caddr_t prom_alloc(caddr_t virthint, size_t size, u_int align) { caddr_t virt = virthint; u_int physaddr; if (align == 0) align = (u_int)1; /* * First, allocate or claim the virtual address space. * In either case, after this code, "virt" is the chosen address. */ if (virthint == 0) { virt = prom_allocate_virt(align, size); if (virt == (caddr_t)-1) return ((caddr_t)0); } else { if (prom_claim_virt(size, virthint) == (caddr_t)-1) return ((caddr_t)0); } /* * Next, allocate the physical address space, at the specified * physical alignment (or 1 byte alignment, if none specified) */ if (prom_allocate_phys(size, align, &physaddr) == -1) { /* * Request failed, free virtual address space and return. */ prom_free_virt(size, virt); return ((caddr_t)0); } /* * Next, create a mapping from the physical to virtual address, * using a default "mode". */ if (prom_map_phys(-1, size, virt, 0, physaddr) == -1) { /* * The call failed; release the physical and virtual * addresses allocated or claimed, and return. */ prom_free_virt(size, virt); prom_free_phys(size, physaddr); return ((caddr_t)0); } return (virt); }
/* * allocate virt and phys space without any mapping; * stores virt and phys addrs at *vap and *pap */ int cb_alloc(size_t size, uint_t align, caddr_t *vap, physaddr_t *pap) { physaddr_t phys; caddr_t virt; virt = prom_allocate_virt(align, (size_t)align); if (virt == (caddr_t)-1) return (ERR); if (prom_allocate_phys(size, align, &phys) == -1) { prom_free_virt(size, virt); return (ERR); } *vap = virt; *pap = phys; return (0); }