int teardown(struct ut_suite *suite) { (void) suite; simple_free(ai); simple_free(resCos); simple_free(resSin); simple_free(refCos); simple_free(refSin); return 0; }
void kexec_memory_map(void *fdt, int reserve_initrd) { uint64_t start, size, end; int nodeoffset; int lpar = 0; kexec_map = simple_init(); /* Work out if we are in LPAR mode */ nodeoffset = fdt_path_offset(fdt, "/rtas"); if (nodeoffset >= 0) { if (fdt_getprop(fdt, nodeoffset, "ibm,hypertas-functions", NULL)) lpar = 1; } /* First find our memory */ nodeoffset = fdt_path_offset(fdt, "/"); if (nodeoffset < 0) { fprintf(stderr, "Device tree has no root node\n"); exit(1); } while (1) { const char *type; int len; const fdt64_t *reg; nodeoffset = fdt_next_node(fdt, nodeoffset, NULL); if (nodeoffset < 0) break; type = fdt_getprop(fdt, nodeoffset, "device_type", NULL); if (!type || strcmp(type, "memory")) continue; reg = fdt_getprop(fdt, nodeoffset, "reg", &len); while (len) { start = fdt64_to_cpu(*reg++); size = fdt64_to_cpu(*reg++); len -= 2 * sizeof(uint64_t); if (lpar == 1) { /* Only use the RMA region for LPAR */ if (start == 0) { if (size > MEMORY_CAP) size = MEMORY_CAP; simple_free(kexec_map, 0, size); mem_top = size; } } else { if (start >= MEMORY_CAP) continue; if ((start + size) > MEMORY_CAP) size = MEMORY_CAP - start; simple_free(kexec_map, start, size); if ((start + size) > mem_top) mem_top = start + size; } } } /* Reserve the kernel */ nodeoffset = fdt_path_offset(fdt, "/chosen"); if (nodeoffset < 0) { fprintf(stderr, "Device tree has no chosen node\n"); exit(1); } /* * XXX FIXME: Need to add linux,kernel-start property to the * kernel to handle relocatable kernels. */ start = 0; if (getprop_u64(fdt, nodeoffset, "linux,kernel-end", &end)) { fprintf(stderr, "getprop linux,kernel-end failed\n"); exit(1); } simple_alloc_at(kexec_map, start, end - start); /* Reserve the MMU hashtable in non LPAR mode */ if (lpar == 0) { if (getprop_u64(fdt, nodeoffset, "linux,htab-base", &start) || getprop_u64(fdt, nodeoffset, "linux,htab-size", &size)) { fprintf(stderr, "Could not find linux,htab-base or " "linux,htab-size properties\n"); exit(1); } if (start < mem_top) simple_alloc_at(kexec_map, start, size); } /* XXX FIXME: Reserve TCEs in kexec_map */ if (new_style_reservation(fdt, reserve_initrd)) return; /* Reserve the initrd if requested */ if (reserve_initrd && !getprop_u64(fdt, nodeoffset, "linux,initrd-start", &start) && !getprop_u64(fdt, nodeoffset, "linux,initrd-end", &end)) { if (start < mem_top) simple_alloc_at(kexec_map, start, end - start); } /* Reserve RTAS */ nodeoffset = fdt_path_offset(fdt, "/rtas"); if (nodeoffset > 0) { uint32_t rtas_start, rtas_size; if (getprop_u32(fdt, nodeoffset, "linux,rtas-base", &rtas_start)) { fprintf(stderr, "getprop linux,rtas-base failed\n"); exit(1); } if (getprop_u32(fdt, nodeoffset, "rtas-size", &rtas_size)) { fprintf(stderr, "getprop rtas-size failed\n"); exit(1); } simple_alloc_at(kexec_map, rtas_start, rtas_size); if (fdt_add_mem_rsv(fdt, rtas_start, rtas_size)) perror("fdt_add_mem_rsv"); } nodeoffset = fdt_path_offset(fdt, "/ibm,opal"); if (nodeoffset > 0) { uint64_t opal_start, opal_size; if (getprop_u64(fdt, nodeoffset, "opal-base-address", &opal_start)) { fprintf(stderr, "getprop opal-base-address failed\n"); exit(1); } if (getprop_u64(fdt, nodeoffset, "opal-runtime-size", &opal_size)) { fprintf(stderr, "getprop opal-runtime-size failed\n"); exit(1); } simple_alloc_at(kexec_map, opal_start, opal_size); if (fdt_add_mem_rsv(fdt, opal_start, opal_size)) perror("fdt_add_mem_rsv"); } }