static void find_memory_chunks(struct mem_chunk chunk[]) { unsigned long long memsize, rnmax, rzm; unsigned long addr = 0, size; int i = 0, type; rzm = sclp_get_rzm(); rnmax = sclp_get_rnmax(); memsize = rzm * rnmax; if (!rzm) rzm = 1ULL << 17; if (sizeof(long) == 4) { rzm = min(ADDR2G, rzm); memsize = memsize ? min(ADDR2G, memsize) : ADDR2G; } do { size = 0; type = tprot(addr); do { size += rzm; if (memsize && addr + size >= memsize) break; } while (type == tprot(addr + size)); if (type == CHUNK_READ_WRITE || type == CHUNK_READ_ONLY) { chunk[i].addr = addr; chunk[i].size = size; chunk[i].type = type; i++; } addr += size; } while (addr < memsize && i < MEMORY_CHUNKS); }
void __init detect_memory_memblock(void) { unsigned long long memsize, rnmax, rzm; unsigned long addr, size; int type; rzm = sclp_get_rzm(); rnmax = sclp_get_rnmax(); memsize = rzm * rnmax; if (!rzm) rzm = 1ULL << 17; max_physmem_end = memsize; addr = 0; /* keep memblock lists close to the kernel */ memblock_set_bottom_up(true); do { size = 0; type = tprot(addr); do { size += rzm; if (max_physmem_end && addr + size >= max_physmem_end) break; } while (type == tprot(addr + size)); if (type == CHUNK_READ_WRITE || type == CHUNK_READ_ONLY) { if (max_physmem_end && (addr + size > max_physmem_end)) size = max_physmem_end - addr; memblock_physmem_add(addr, size); } addr += size; } while (addr < max_physmem_end); memblock_set_bottom_up(false); if (!max_physmem_end) max_physmem_end = memblock_end_of_DRAM(); }