Changeset View
Changeset View
Standalone View
Standalone View
sys/powerpc/ofw/ofw_machdep.c
Show First 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
#include <dev/ofw/openfirm.h> | #include <dev/ofw/openfirm.h> | ||||
#include <dev/ofw/ofw_pci.h> | #include <dev/ofw/ofw_pci.h> | ||||
#include <dev/ofw/ofw_bus.h> | #include <dev/ofw/ofw_bus.h> | ||||
#include <dev/ofw/ofw_subr.h> | #include <dev/ofw/ofw_subr.h> | ||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/vm_param.h> | #include <vm/vm_param.h> | ||||
#include <vm/vm_page.h> | #include <vm/vm_page.h> | ||||
#include <vm/vm_phys.h> | |||||
#include <machine/bus.h> | #include <machine/bus.h> | ||||
#include <machine/cpu.h> | #include <machine/cpu.h> | ||||
#include <machine/md_var.h> | #include <machine/md_var.h> | ||||
#include <machine/platform.h> | #include <machine/platform.h> | ||||
#include <machine/ofw_machdep.h> | #include <machine/ofw_machdep.h> | ||||
#include <machine/trap.h> | #include <machine/trap.h> | ||||
▲ Show 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | if (((uint64_t)output[j].mr_start + | ||||
(uint64_t)output[j].mr_size - 1) > | (uint64_t)output[j].mr_size - 1) > | ||||
BUS_SPACE_MAXADDR) { | BUS_SPACE_MAXADDR) { | ||||
output[j].mr_size = BUS_SPACE_MAXADDR - | output[j].mr_size = BUS_SPACE_MAXADDR - | ||||
output[j].mr_start + 1; | output[j].mr_start + 1; | ||||
} | } | ||||
j++; | j++; | ||||
} | } | ||||
sz = j*sizeof(output[0]); | |||||
return (sz); | return (j); | ||||
} | } | ||||
static int | |||||
parse_numa_ofw_memory(phandle_t node, const char *prop, | |||||
struct numa_mem_region *output) | |||||
{ | |||||
cell_t address_cells, size_cells; | |||||
cell_t OFmem[4 * PHYS_AVAIL_SZ]; | |||||
int sz, i, j; | |||||
phandle_t phandle; | |||||
sz = 0; | |||||
/* | |||||
* Get #address-cells from root node, defaulting to 1 if it cannot | |||||
* be found. | |||||
*/ | |||||
phandle = OF_finddevice("/"); | |||||
if (OF_getencprop(phandle, "#address-cells", &address_cells, | |||||
sizeof(address_cells)) < (ssize_t)sizeof(address_cells)) | |||||
address_cells = 1; | |||||
if (OF_getencprop(phandle, "#size-cells", &size_cells, | |||||
sizeof(size_cells)) < (ssize_t)sizeof(size_cells)) | |||||
size_cells = 1; | |||||
/* | |||||
* Get memory. | |||||
*/ | |||||
if (node == -1 || (sz = OF_getencprop(node, prop, | |||||
OFmem, sizeof(OFmem))) <= 0) | |||||
panic("Physical memory map not found"); | |||||
i = 0; | |||||
j = 0; | |||||
kib: This looks like a for() loop. | |||||
while (i < sz/sizeof(cell_t)) { | |||||
output[j].mr_start = OFmem[i++]; | |||||
if (address_cells == 2) { | |||||
output[j].mr_start <<= 32; | |||||
output[j].mr_start += OFmem[i++]; | |||||
} | |||||
output[j].mr_size = OFmem[i++]; | |||||
if (size_cells == 2) { | |||||
output[j].mr_size <<= 32; | |||||
output[j].mr_size += OFmem[i++]; | |||||
} | |||||
j++; | |||||
} | |||||
return (j); | |||||
} | |||||
#ifdef FDT | #ifdef FDT | ||||
static int | static int | ||||
excise_reserved_regions(struct mem_region *avail, int asz, | excise_reserved_regions(struct mem_region *avail, int asz, | ||||
struct mem_region *exclude, int esz) | struct mem_region *exclude, int esz) | ||||
{ | { | ||||
int i, j, k; | int i, j, k; | ||||
for (i = 0; i < asz; i++) { | for (i = 0; i < asz; i++) { | ||||
▲ Show 20 Lines • Show All 165 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
/* | /* | ||||
* This is called during powerpc_init, before the system is really initialized. | * This is called during powerpc_init, before the system is really initialized. | ||||
* It shall provide the total and the available regions of RAM. | * It shall provide the total and the available regions of RAM. | ||||
* The available regions need not take the kernel into account. | * The available regions need not take the kernel into account. | ||||
*/ | */ | ||||
void | void | ||||
ofw_numa_mem_regions(struct numa_mem_region *memp, int *memsz) | |||||
{ | |||||
phandle_t phandle; | |||||
int res, count, msz; | |||||
char name[31]; | |||||
cell_t associativity[5]; | |||||
struct numa_mem_region *curmemp; | |||||
msz = 0; | |||||
/* | |||||
* Get memory from all the /memory nodes. | |||||
*/ | |||||
for (phandle = OF_child(OF_peer(0)); phandle != 0; | |||||
phandle = OF_peer(phandle)) { | |||||
if (OF_getprop(phandle, "name", name, sizeof(name)) <= 0) | |||||
continue; | |||||
if (strncmp(name, "memory@", strlen("memory@")) != 0) | |||||
continue; | |||||
count = parse_numa_ofw_memory(phandle, "reg", &memp[msz]); | |||||
if (count == 0) | |||||
continue; | |||||
curmemp = &memp[msz]; | |||||
res = OF_getproplen(phandle, "ibm,associativity"); | |||||
if (res <= 0) | |||||
continue; | |||||
MPASS(count == 1); | |||||
OF_getencprop(phandle, "ibm,associativity", | |||||
associativity, res); | |||||
curmemp->mr_domain = associativity[3] - 1; | |||||
if (bootverbose) | |||||
printf("%s %#lx-%#lx domain(%lu)\n", | |||||
name, curmemp->mr_start, | |||||
curmemp->mr_start + curmemp->mr_size, | |||||
curmemp->mr_domain); | |||||
msz += count; | |||||
} | |||||
*memsz = msz; | |||||
} | |||||
/* | |||||
* This is called during powerpc_init, before the system is really initialized. | |||||
* It shall provide the total and the available regions of RAM. | |||||
* The available regions need not take the kernel into account. | |||||
*/ | |||||
void | |||||
ofw_mem_regions(struct mem_region *memp, int *memsz, | ofw_mem_regions(struct mem_region *memp, int *memsz, | ||||
struct mem_region *availp, int *availsz) | struct mem_region *availp, int *availsz) | ||||
{ | { | ||||
phandle_t phandle; | phandle_t phandle; | ||||
int asz, msz; | int asz, msz; | ||||
int res; | int res; | ||||
char name[31]; | char name[31]; | ||||
asz = msz = 0; | asz = msz = 0; | ||||
/* | /* | ||||
* Get memory from all the /memory nodes. | * Get memory from all the /memory nodes. | ||||
*/ | */ | ||||
for (phandle = OF_child(OF_peer(0)); phandle != 0; | for (phandle = OF_child(OF_peer(0)); phandle != 0; | ||||
phandle = OF_peer(phandle)) { | phandle = OF_peer(phandle)) { | ||||
if (OF_getprop(phandle, "name", name, sizeof(name)) <= 0) | if (OF_getprop(phandle, "name", name, sizeof(name)) <= 0) | ||||
continue; | continue; | ||||
if (strncmp(name, "memory", sizeof(name)) != 0 && | if (strncmp(name, "memory", sizeof(name)) != 0 && | ||||
strncmp(name, "memory@", strlen("memory@")) != 0) | strncmp(name, "memory@", strlen("memory@")) != 0) | ||||
continue; | continue; | ||||
res = parse_ofw_memory(phandle, "reg", &memp[msz]); | res = parse_ofw_memory(phandle, "reg", &memp[msz]); | ||||
msz += res/sizeof(struct mem_region); | msz += res; | ||||
/* | /* | ||||
* On POWER9 Systems we might have both linux,usable-memory and | * On POWER9 Systems we might have both linux,usable-memory and | ||||
* reg properties. 'reg' denotes all available memory, but we | * reg properties. 'reg' denotes all available memory, but we | ||||
* must use 'linux,usable-memory', a subset, as some memory | * must use 'linux,usable-memory', a subset, as some memory | ||||
* regions are reserved for NVLink. | * regions are reserved for NVLink. | ||||
*/ | */ | ||||
if (OF_getproplen(phandle, "linux,usable-memory") >= 0) | if (OF_getproplen(phandle, "linux,usable-memory") >= 0) | ||||
res = parse_ofw_memory(phandle, "linux,usable-memory", | res = parse_ofw_memory(phandle, "linux,usable-memory", | ||||
&availp[asz]); | &availp[asz]); | ||||
else if (OF_getproplen(phandle, "available") >= 0) | else if (OF_getproplen(phandle, "available") >= 0) | ||||
res = parse_ofw_memory(phandle, "available", | res = parse_ofw_memory(phandle, "available", | ||||
&availp[asz]); | &availp[asz]); | ||||
else | else | ||||
res = parse_ofw_memory(phandle, "reg", &availp[asz]); | res = parse_ofw_memory(phandle, "reg", &availp[asz]); | ||||
asz += res/sizeof(struct mem_region); | asz += res; | ||||
} | } | ||||
#ifdef FDT | #ifdef FDT | ||||
phandle = OF_finddevice("/chosen"); | phandle = OF_finddevice("/chosen"); | ||||
if (OF_hasprop(phandle, "fdtmemreserv")) | if (OF_hasprop(phandle, "fdtmemreserv")) | ||||
asz = excise_fdt_reserved(availp, asz); | asz = excise_fdt_reserved(availp, asz); | ||||
/* If the kernel is being loaded through kexec, initrd region is listed | /* If the kernel is being loaded through kexec, initrd region is listed | ||||
▲ Show 20 Lines • Show All 321 Lines • Show Last 20 Lines |
This looks like a for() loop.