void * bkmem_alloc(size_t size) { /* allocate from boot scratch memory */ void *addr; if (_kmem_ready) return (kobj_alloc(size, 0)); addr = BOP_ALLOC(ops, 0, size, 0); #ifdef DEBUG if (scratch_max < (uintptr_t)addr + size) scratch_max = (uintptr_t)addr + size; #endif return (addr); }
/* * Boot time wrappers for memory allocators. Called for both permanent * and temporary boot memory allocations. We have to track which allocator * (boot or kmem) was used so that we know how to free. */ void * bkmem_alloc(size_t size) { /* allocate from boot scratch memory */ void *addr; if (_kmem_ready) return (kobj_alloc(size, 0)); /* * Remember the highest BOP_ALLOC allocated address and don't free * anything below it. */ addr = BOP_ALLOC(ops, 0, size, 0); if (scratch_max < (uintptr_t)addr + size) scratch_max = (uintptr_t)addr + size; return (addr); }
/* * Get pages from boot and hash them into the kernel's vp. * Used after page structs have been allocated, but before segkmem is ready. */ void * boot_alloc(void *inaddr, size_t size, uint_t align) { caddr_t addr = inaddr; if (bootops == NULL) prom_panic("boot_alloc: attempt to allocate memory after " "BOP_GONE"); size = ptob(btopr(size)); #ifdef __sparc if (bop_alloc_chunk(addr, size, align) != (caddr_t)addr) panic("boot_alloc: bop_alloc_chunk failed"); #else if (BOP_ALLOC(bootops, addr, size, align) != addr) panic("boot_alloc: BOP_ALLOC failed"); #endif boot_mapin((caddr_t)addr, size); return (addr); }
/* * Copy the memlist from boot to kernel, each list is an {addr, size} array * with addr and size of 64-bit (u_longlong_t). The returned length for each * array is 2*the number of array elements. * */ void copy_boot_memlists(u_longlong_t **physinstalled, size_t *physinstalled_len, u_longlong_t **physavail, size_t *physavail_len, u_longlong_t **virtavail, size_t *virtavail_len) { int align = BO_ALIGN_L3; size_t len; struct bootmem_props *tmp = bootmem_props; tryagain: for (tmp = bootmem_props; tmp->name != NULL; tmp++) { len = BOP_GETPROPLEN(bootops, tmp->name); if (len == 0) { panic("cannot get length of \"%s\" property", tmp->name); } tmp->nelems = len / sizeof (u_longlong_t); len = roundup(len, PAGESIZE); if (len <= tmp->bufsize) continue; /* need to allocate more */ if (tmp->ptr) { BOP_FREE(bootops, (caddr_t)tmp->ptr, tmp->bufsize); tmp->ptr = NULL; tmp->bufsize = 0; } tmp->bufsize = len; tmp->ptr = (void *)BOP_ALLOC(bootops, 0, tmp->bufsize, align); if (tmp->ptr == NULL) panic("cannot allocate %lu bytes for \"%s\" property", tmp->bufsize, tmp->name); } /* * take the most current snapshot we can by calling mem-update */ if (BOP_GETPROPLEN(bootops, "memory-update") == 0) (void) BOP_GETPROP(bootops, "memory-update", NULL); /* did the sizes change? */ for (tmp = bootmem_props; tmp->name != NULL; tmp++) { len = BOP_GETPROPLEN(bootops, tmp->name); tmp->nelems = len / sizeof (u_longlong_t); len = roundup(len, PAGESIZE); if (len > tmp->bufsize) { /* ick. Free them all and try again */ for (tmp = bootmem_props; tmp->name != NULL; tmp++) { BOP_FREE(bootops, (caddr_t)tmp->ptr, tmp->bufsize); tmp->ptr = NULL; tmp->bufsize = 0; } goto tryagain; } } /* now we can retrieve the properties */ for (tmp = bootmem_props; tmp->name != NULL; tmp++) { if (BOP_GETPROP(bootops, tmp->name, tmp->ptr) == -1) { panic("cannot retrieve \"%s\" property", tmp->name); } } *physinstalled = bootmem_props[PHYSINSTALLED].ptr; *physinstalled_len = bootmem_props[PHYSINSTALLED].nelems; *physavail = bootmem_props[PHYSAVAIL].ptr; *physavail_len = bootmem_props[PHYSAVAIL].nelems; *virtavail = bootmem_props[VIRTAVAIL].ptr; *virtavail_len = bootmem_props[VIRTAVAIL].nelems; }