static paddr_t getphysmem(u_long size) { struct memarr *pmemarr; /* physical memory regions */ int npmemarr; /* number of entries in pmemarr */ struct memarr *mp; int i; extern char start[]; /* top of stack (see srt0.S) */ /* * Find the physical memory area that's in use by the boot loader. * Our stack grows down from label `start'; assume we need no more * than 16K of stack space. * The top of the boot loader is the next 4MB boundary. */ if (pmap_extract((vaddr_t)start - (16*1024), &bstart) != 0) return ((paddr_t)-1); bend = roundup(bstart, 0x400000); /* * Get available physical memory from the prom. */ npmemarr = prom_makememarr(NULL, 0, MEMARR_AVAILPHYS); pmemarr = alloc(npmemarr*sizeof(struct memarr)); if (pmemarr == NULL) return ((paddr_t)-1); npmemarr = prom_makememarr(pmemarr, npmemarr, MEMARR_AVAILPHYS); /* * Find a suitable loading address. */ for (mp = pmemarr, i = npmemarr; --i >= 0; mp++) { paddr_t pa = (paddr_t)pmemarr[i].addr; u_long len = (u_long)pmemarr[i].len; /* Check whether it will fit in front of us */ if (pa < bstart && len >= size && (bstart - pa) >= size) return (pa); /* Skip the boot program memory */ if (pa < bend) { if (len < bend - pa) /* Not large enough */ continue; /* Shrink this segment */ len -= bend - pa; pa = bend; } /* Does it fit in the remainder of this segment? */ if (len >= size) return (pa); } return ((paddr_t)-1); }
static paddr_t getphysmem(u_long size) { struct memarr *pmemarr; /* physical memory regions */ u_int npmemarr; /* number of entries in pmemarr */ struct memarr *mp; int i; #ifdef DEBUG static int arrdpy; #endif /* * Get available physical memory from the prom. */ npmemarr = prom_makememarr(NULL, 0, MEMARR_AVAILPHYS); pmemarr = alloc(npmemarr*sizeof(struct memarr)); if (pmemarr == NULL) return ((paddr_t)-1); npmemarr = prom_makememarr(pmemarr, npmemarr, MEMARR_AVAILPHYS); #ifdef DEBUG if (arrdpy == 0) { arrdpy = 1; printf("Available physical memory:\n"); for (mp = pmemarr, i = (int)npmemarr; --i >= 0; mp++) { uint64_t addr; addr = pmemarr[i].addr_hi; addr <<= 32; addr |= pmemarr[i].addr_lo; printf("%p at 0x%llx\n", pmemarr[i].len, addr); } } #endif /* * Find a suitable loading address. */ for (mp = pmemarr, i = (int)npmemarr; --i >= 0; mp++) { paddr_t pa; u_long len; /* Skip memory ranges the kernel can't use yet on sun4d */ if (pmemarr[i].addr_hi != 0) continue; pa = (paddr_t)pmemarr[i].addr_lo; if (pa >= 0x80000000) continue; len = (u_long)pmemarr[i].len; if (len >= 0x80000000) len = 0x80000000; if (pa + len > 0x80000000) len = 0x80000000 - pa; if (len < size) continue; /* Check whether it will fit in front of us */ if (pa < bstart && len >= size && (bstart - pa) >= size) return (pa); /* Skip the boot program memory */ if (pa < bend) { if (len < bend - pa) /* Not large enough */ continue; /* Shrink this segment */ len -= bend - pa; pa = bend; } /* Does it fit in the remainder of this segment? */ if (len >= size) return (pa); } return ((paddr_t)-1); }