/* Get devtree details and create exclude_range array * Also create usablemem_ranges for KEXEC_ON_CRASH */ static int get_devtree_details(unsigned long kexec_flags) { unsigned long long rmo_base; unsigned long long tce_base; unsigned int tce_size; unsigned long long htab_base, htab_size; unsigned long long kernel_end; unsigned long long initrd_start, initrd_end; char buf[MAXBYTES]; char device_tree[256] = "/proc/device-tree/"; char fname[256]; DIR *dir, *cdir; FILE *file; struct dirent *dentry; struct stat fstat; int n, i = 0; if ((dir = opendir(device_tree)) == NULL) { perror(device_tree); return -1; } while ((dentry = readdir(dir)) != NULL) { if (strncmp(dentry->d_name, "chosen", 6) && strncmp(dentry->d_name, "memory@", 7) && strcmp(dentry->d_name, "memory") && strncmp(dentry->d_name, "pci@", 4) && strncmp(dentry->d_name, "rtas", 4)) continue; strcpy(fname, device_tree); strcat(fname, dentry->d_name); if ((cdir = opendir(fname)) == NULL) { perror(fname); goto error_opendir; } if (strncmp(dentry->d_name, "chosen", 6) == 0) { strcat(fname, "/linux,kernel-end"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if (fread(&kernel_end, sizeof(uint64_t), 1, file) != 1) { perror(fname); goto error_openfile; } fclose(file); /* Add kernel memory to exclude_range */ exclude_range[i].start = 0x0UL; exclude_range[i].end = kernel_end; i++; if (kexec_flags & KEXEC_ON_CRASH) { memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry->d_name); strcat(fname, "/linux,crashkernel-base"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if (fread(&crash_base, sizeof(uint64_t), 1, file) != 1) { perror(fname); goto error_openfile; } fclose(file); memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry->d_name); strcat(fname, "/linux,crashkernel-size"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if (fread(&crash_size, sizeof(uint64_t), 1, file) != 1) { perror(fname); goto error_openfile; } if (crash_base > mem_min) mem_min = crash_base; if (crash_base + crash_size < mem_max) mem_max = crash_base + crash_size; add_usable_mem_rgns(0, crash_base + crash_size); reserve(KDUMP_BACKUP_LIMIT, crash_base-KDUMP_BACKUP_LIMIT); } memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry->d_name); strcat(fname, "/linux,htab-base"); if ((file = fopen(fname, "r")) == NULL) { closedir(cdir); if (errno == ENOENT) { /* Non LPAR */ errno = 0; continue; } perror(fname); goto error_opendir; } if (fread(&htab_base, sizeof(uint64_t), 1, file) != 1) { perror(fname); goto error_openfile; } memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry->d_name); strcat(fname, "/linux,htab-size"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if (fread(&htab_size, sizeof(uint64_t), 1, file) != 1) { perror(fname); goto error_openfile; } /* Add htab address to exclude_range - NON-LPAR only */ exclude_range[i].start = htab_base; exclude_range[i].end = htab_base + htab_size; i++; /* reserve the initrd_start and end locations. */ if (reuse_initrd) { memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry->d_name); strcat(fname, "/linux,initrd-start"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } /* check for 4 and 8 byte initrd offset sizes */ if (stat(fname, &fstat) != 0) { perror(fname); goto error_openfile; } if (fread(&initrd_start, fstat.st_size, 1, file) != 1) { perror(fname); goto error_openfile; } fclose(file); memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry->d_name); strcat(fname, "/linux,initrd-end"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } /* check for 4 and 8 byte initrd offset sizes */ if (stat(fname, &fstat) != 0) { perror(fname); goto error_openfile; } if (fread(&initrd_end, fstat.st_size, 1, file) != 1) { perror(fname); goto error_openfile; } fclose(file); /* Add initrd address to exclude_range */ exclude_range[i].start = initrd_start; exclude_range[i].end = initrd_end; i++; } } /* chosen */ if (strncmp(dentry->d_name, "rtas", 4) == 0) { strcat(fname, "/linux,rtas-base"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if (fread(&rtas_base, sizeof(unsigned int), 1, file) != 1) { perror(fname); goto error_openfile; } memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry->d_name); strcat(fname, "/rtas-size"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if (fread(&rtas_size, sizeof(unsigned int), 1, file) != 1) { perror(fname); goto error_openfile; } closedir(cdir); /* Add rtas to exclude_range */ exclude_range[i].start = rtas_base; exclude_range[i].end = rtas_base + rtas_size; i++; if (kexec_flags & KEXEC_ON_CRASH) add_usable_mem_rgns(rtas_base, rtas_size); } /* rtas */ if (!strncmp(dentry->d_name, "memory@", 7) || !strcmp(dentry->d_name, "memory")) { strcat(fname, "/reg"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if ((n = fread(buf, 1, MAXBYTES, file)) < 0) { perror(fname); goto error_openfile; } rmo_base = ((unsigned long long *)buf)[0]; rmo_top = rmo_base + ((unsigned long long *)buf)[1]; if (rmo_top > 0x30000000UL) rmo_top = 0x30000000UL; fclose(file); closedir(cdir); } /* memory */ if (strncmp(dentry->d_name, "pci@", 4) == 0) { strcat(fname, "/linux,tce-base"); if ((file = fopen(fname, "r")) == NULL) { closedir(cdir); if (errno == ENOENT) { /* Non LPAR */ errno = 0; continue; } perror(fname); goto error_opendir; } if (fread(&tce_base, sizeof(uint64_t), 1, file) != 1) { perror(fname); goto error_openfile; return -1; } memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry->d_name); strcat(fname, "/linux,tce-size"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if (fread(&tce_size, sizeof(unsigned int), 1, file) != 1) { perror(fname); goto error_openfile; } /* Add tce to exclude_range - NON-LPAR only */ exclude_range[i].start = tce_base; exclude_range[i].end = tce_base + tce_size; i++; if (kexec_flags & KEXEC_ON_CRASH) add_usable_mem_rgns(tce_base, tce_size); closedir(cdir); } /* pci */ } closedir(dir); nr_exclude_ranges = i; sort_ranges(); #ifdef DEBUG int k; for (k = 0; k < i; k++) fprintf(stderr, "exclude_range sorted exclude_range[%d] " "start:%llx, end:%llx\n", k, exclude_range[k].start, exclude_range[k].end); #endif return 0; error_openfile: fclose(file); error_opencdir: closedir(cdir); error_opendir: closedir(dir); return -1; }
/* Get devtree details and create exclude_range array * Also create usablemem_ranges for KEXEC_ON_CRASH */ static int get_devtree_details(unsigned long kexec_flags) { uint64_t rmo_base; uint64_t tce_base; unsigned int tce_size; uint64_t htab_base, htab_size; uint64_t kernel_end; uint64_t initrd_start, initrd_end; char buf[MAXBYTES]; char device_tree[256] = "/proc/device-tree/"; char fname[256]; DIR *dir, *cdir; FILE *file; struct dirent *dentry; struct stat fstat; int n, i = 0; if ((dir = opendir(device_tree)) == NULL) { perror(device_tree); return -1; } while ((dentry = readdir(dir)) != NULL) { if (strncmp(dentry->d_name, "chosen", 6) && strncmp(dentry->d_name, "memory@", 7) && strcmp(dentry->d_name, "memory") && strncmp(dentry->d_name, "pci@", 4) && strncmp(dentry->d_name, "rtas", 4)) continue; strcpy(fname, device_tree); strcat(fname, dentry->d_name); if ((cdir = opendir(fname)) == NULL) { perror(fname); goto error_opendir; } if (strncmp(dentry->d_name, "chosen", 6) == 0) { strcat(fname, "/linux,kernel-end"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if (fread(&kernel_end, sizeof(uint64_t), 1, file) != 1) { perror(fname); goto error_openfile; } fclose(file); kernel_end = be64_to_cpu(kernel_end); /* Add kernel memory to exclude_range */ exclude_range[i].start = 0x0UL; exclude_range[i].end = kernel_end; i++; if (i >= max_memory_ranges) realloc_memory_ranges(); if (kexec_flags & KEXEC_ON_CRASH) { memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry->d_name); strcat(fname, "/linux,crashkernel-base"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if (fread(&crash_base, sizeof(uint64_t), 1, file) != 1) { perror(fname); goto error_openfile; } fclose(file); crash_base = be64_to_cpu(crash_base); memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry->d_name); strcat(fname, "/linux,crashkernel-size"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if (fread(&crash_size, sizeof(uint64_t), 1, file) != 1) { perror(fname); goto error_openfile; } fclose(file); crash_size = be64_to_cpu(crash_size); if (crash_base > mem_min) mem_min = crash_base; if (crash_base + crash_size < mem_max) mem_max = crash_base + crash_size; add_usable_mem_rgns(0, crash_base + crash_size); reserve(KDUMP_BACKUP_LIMIT, crash_base-KDUMP_BACKUP_LIMIT); } /* * Read the first kernel's memory limit. * If the first kernel is booted with mem= option then * it would export "linux,memory-limit" file * reflecting value for the same. */ memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry->d_name); strcat(fname, "/linux,memory-limit"); if ((file = fopen(fname, "r")) == NULL) { if (errno != ENOENT) { perror(fname); goto error_opencdir; } errno = 0; /* * File not present. * fall through. On older kernel this file * is not present. */ } else { if (fread(&memory_limit, sizeof(uint64_t), 1, file) != 1) { perror(fname); goto error_openfile; } fclose(file); memory_limit = be64_to_cpu(memory_limit); } memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry->d_name); strcat(fname, "/linux,htab-base"); if ((file = fopen(fname, "r")) == NULL) { closedir(cdir); if (errno == ENOENT) { /* Non LPAR */ errno = 0; continue; } perror(fname); goto error_opendir; } if (fread(&htab_base, sizeof(uint64_t), 1, file) != 1) { perror(fname); goto error_openfile; } fclose(file); htab_base = be64_to_cpu(htab_base); memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry->d_name); strcat(fname, "/linux,htab-size"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if (fread(&htab_size, sizeof(uint64_t), 1, file) != 1) { perror(fname); goto error_openfile; } fclose(file); htab_size = be64_to_cpu(htab_size); /* Add htab address to exclude_range - NON-LPAR only */ exclude_range[i].start = htab_base; exclude_range[i].end = htab_base + htab_size; i++; if (i >= max_memory_ranges) realloc_memory_ranges(); /* reserve the initrd_start and end locations. */ if (reuse_initrd) { memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry->d_name); strcat(fname, "/linux,initrd-start"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } /* check for 4 and 8 byte initrd offset sizes */ if (stat(fname, &fstat) != 0) { perror(fname); goto error_openfile; } if (fread(&initrd_start, fstat.st_size, 1, file) != 1) { perror(fname); goto error_openfile; } initrd_start = be64_to_cpu(initrd_start); fclose(file); memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry->d_name); strcat(fname, "/linux,initrd-end"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } /* check for 4 and 8 byte initrd offset sizes */ if (stat(fname, &fstat) != 0) { perror(fname); goto error_openfile; } if (fread(&initrd_end, fstat.st_size, 1, file) != 1) { perror(fname); goto error_openfile; } initrd_end = be64_to_cpu(initrd_end); fclose(file); /* Add initrd address to exclude_range */ exclude_range[i].start = initrd_start; exclude_range[i].end = initrd_end; i++; if (i >= max_memory_ranges) realloc_memory_ranges(); } } /* chosen */ if (strncmp(dentry->d_name, "rtas", 4) == 0) { strcat(fname, "/linux,rtas-base"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if (fread(&rtas_base, sizeof(unsigned int), 1, file) != 1) { perror(fname); goto error_openfile; } fclose(file); rtas_base = be32_to_cpu(rtas_base); memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry->d_name); strcat(fname, "/rtas-size"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if (fread(&rtas_size, sizeof(unsigned int), 1, file) != 1) { perror(fname); goto error_openfile; } fclose(file); closedir(cdir); rtas_size = be32_to_cpu(rtas_size); /* Add rtas to exclude_range */ exclude_range[i].start = rtas_base; exclude_range[i].end = rtas_base + rtas_size; i++; if (i >= max_memory_ranges) realloc_memory_ranges(); if (kexec_flags & KEXEC_ON_CRASH) add_usable_mem_rgns(rtas_base, rtas_size); } /* rtas */ if (!strncmp(dentry->d_name, "memory@", 7) || !strcmp(dentry->d_name, "memory")) { strcat(fname, "/reg"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if ((n = fread(buf, 1, MAXBYTES, file)) < 0) { perror(fname); goto error_openfile; } rmo_base = be64_to_cpu(((uint64_t *)buf)[0]); rmo_top = rmo_base + be64_to_cpu(((uint64_t *)buf)[1]); if (rmo_top > 0x30000000UL) rmo_top = 0x30000000UL; fclose(file); closedir(cdir); } /* memory */ if (strncmp(dentry->d_name, "pci@", 4) == 0) { strcat(fname, "/linux,tce-base"); if ((file = fopen(fname, "r")) == NULL) { closedir(cdir); if (errno == ENOENT) { /* Non LPAR */ errno = 0; continue; } perror(fname); goto error_opendir; } if (fread(&tce_base, sizeof(uint64_t), 1, file) != 1) { perror(fname); goto error_openfile; } fclose(file); tce_base = be64_to_cpu(tce_base); memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry->d_name); strcat(fname, "/linux,tce-size"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if (fread(&tce_size, sizeof(unsigned int), 1, file) != 1) { perror(fname); goto error_openfile; } fclose(file); tce_size = be32_to_cpu(tce_size); /* Add tce to exclude_range - NON-LPAR only */ exclude_range[i].start = tce_base; exclude_range[i].end = tce_base + tce_size; i++; if (i >= max_memory_ranges) realloc_memory_ranges(); if (kexec_flags & KEXEC_ON_CRASH) add_usable_mem_rgns(tce_base, tce_size); closedir(cdir); } /* pci */ } closedir(dir); nr_exclude_ranges = i; sort_ranges(); int k; for (k = 0; k < i; k++) dbgprintf("exclude_range sorted exclude_range[%d] " "start:%llx, end:%llx\n", k, exclude_range[k].start, exclude_range[k].end); return 0; error_openfile: fclose(file); error_opencdir: closedir(cdir); error_opendir: closedir(dir); return -1; }
/* Get devtree details and create exclude_range array * Also create usablemem_ranges for KEXEC_ON_CRASH */ static int get_devtree_details(unsigned long kexec_flags) { uint64_t rmo_base; unsigned long long tce_base; unsigned int tce_size; unsigned long long htab_base, htab_size; unsigned long long kernel_end; unsigned long long initrd_start, initrd_end; char buf[MAXBYTES]; char device_tree[256] = "/proc/device-tree/"; char fname[256]; DIR *dir, *cdir; FILE *file; struct dirent *dentry; int n, i = 0; if ((dir = opendir(device_tree)) == NULL) { perror(device_tree); return -1; } while ((dentry = readdir(dir)) != NULL) { if (strncmp(dentry->d_name, "chosen", 6) && strncmp(dentry->d_name, "memory@", 7) && strncmp(dentry->d_name, "memory", 6) && strncmp(dentry->d_name, "pci@", 4) && strncmp(dentry->d_name, "rtas", 4)) continue; strcpy(fname, device_tree); strcat(fname, dentry->d_name); if ((cdir = opendir(fname)) == NULL) { perror(fname); goto error_opendir; } if (strncmp(dentry->d_name, "chosen", 6) == 0) { /* only reserve kernel region if we are doing a crash kernel */ if (kexec_flags & KEXEC_ON_CRASH) { strcat(fname, "/linux,kernel-end"); file = fopen(fname, "r"); if (!file) { perror(fname); goto error_opencdir; } if ((n = fread(buf, 1, MAXBYTES, file)) < 0) { perror(fname); goto error_openfile; } if (n == sizeof(uint32_t)) { kernel_end = ((uint32_t *)buf)[0]; } else if (n == sizeof(uint64_t)) { kernel_end = ((uint64_t *)buf)[0]; } else { fprintf(stderr, "%s node has invalid size: %d\n", fname, n); goto error_openfile; } fclose(file); /* Add kernel memory to exclude_range */ exclude_range[i].start = 0x0UL; exclude_range[i].end = kernel_end; i++; if (i >= max_memory_ranges) realloc_memory_ranges(); memset(fname, 0, sizeof(fname)); sprintf(fname, "%s%s%s", device_tree, dentry->d_name, "/linux,crashkernel-base"); file = fopen(fname, "r"); if (!file) { perror(fname); goto error_opencdir; } if ((n = fread(buf, 1, MAXBYTES, file)) < 0) { perror(fname); goto error_openfile; } if (n == sizeof(uint32_t)) { crash_base = ((uint32_t *)buf)[0]; } else if (n == sizeof(uint64_t)) { crash_base = ((uint64_t *)buf)[0]; } else { fprintf(stderr, "%s node has invalid size: %d\n", fname, n); goto error_openfile; } fclose(file); memset(fname, 0, sizeof(fname)); sprintf(fname, "%s%s%s", device_tree, dentry->d_name, "/linux,crashkernel-size"); file = fopen(fname, "r"); if (!file) { perror(fname); goto error_opencdir; } if ((n = fread(buf, 1, MAXBYTES, file)) < 0) { perror(fname); goto error_openfile; } if (n == sizeof(uint32_t)) { crash_size = ((uint32_t *)buf)[0]; } else if (n == sizeof(uint64_t)) { crash_size = ((uint64_t *)buf)[0]; } else { fprintf(stderr, "%s node has invalid size: %d\n", fname, n); goto error_openfile; } fclose(file); if (crash_base > mem_min) mem_min = crash_base; if (crash_base + crash_size < mem_max) mem_max = crash_base + crash_size; #ifndef CONFIG_BOOKE add_usable_mem_rgns(0, crash_base + crash_size); /* Reserve the region (KDUMP_BACKUP_LIMIT,crash_base) */ reserve(KDUMP_BACKUP_LIMIT, crash_base-KDUMP_BACKUP_LIMIT); #else add_usable_mem_rgns(crash_base, crash_size); #endif } /* reserve the initrd_start and end locations. */ memset(fname, 0, sizeof(fname)); sprintf(fname, "%s%s%s", device_tree, dentry->d_name, "/linux,initrd-start"); file = fopen(fname, "r"); if (!file) { errno = 0; initrd_start = 0; } else { if ((n = fread(buf, 1, MAXBYTES, file)) < 0) { perror(fname); goto error_openfile; } if (n == sizeof(uint32_t)) { initrd_start = ((uint32_t *)buf)[0]; } else if (n == sizeof(uint64_t)) { initrd_start = ((uint64_t *)buf)[0]; } else { fprintf(stderr, "%s node has invalid size: %d\n", fname, n); goto error_openfile; } fclose(file); } memset(fname, 0, sizeof(fname)); sprintf(fname, "%s%s%s", device_tree, dentry->d_name, "/linux,initrd-end"); file = fopen(fname, "r"); if (!file) { errno = 0; initrd_end = 0; } else { if ((n = fread(buf, 1, MAXBYTES, file)) < 0) { perror(fname); goto error_openfile; } if (n == sizeof(uint32_t)) { initrd_end = ((uint32_t *)buf)[0]; } else if (n == sizeof(uint64_t)) { initrd_end = ((uint64_t *)buf)[0]; } else { fprintf(stderr, "%s node has invalid size: %d\n", fname, n); goto error_openfile; } fclose(file); } if ((initrd_end - initrd_start) != 0 ) { initrd_base = initrd_start; initrd_size = initrd_end - initrd_start; } if (reuse_initrd) { /* Add initrd address to exclude_range */ exclude_range[i].start = initrd_start; exclude_range[i].end = initrd_end; i++; if (i >= max_memory_ranges) realloc_memory_ranges(); } /* HTAB */ memset(fname, 0, sizeof(fname)); sprintf(fname, "%s%s%s", device_tree, dentry->d_name, "/linux,htab-base"); file = fopen(fname, "r"); if (!file) { closedir(cdir); if (errno == ENOENT) { /* Non LPAR */ errno = 0; continue; } perror(fname); goto error_opendir; } if (fread(&htab_base, sizeof(unsigned long), 1, file) != 1) { perror(fname); goto error_openfile; } memset(fname, 0, sizeof(fname)); sprintf(fname, "%s%s%s", device_tree, dentry->d_name, "/linux,htab-size"); file = fopen(fname, "r"); if (!file) { perror(fname); goto error_opencdir; } if (fread(&htab_size, sizeof(unsigned long), 1, file) != 1) { perror(fname); goto error_openfile; } /* Add htab address to exclude_range - NON-LPAR only */ exclude_range[i].start = htab_base; exclude_range[i].end = htab_base + htab_size; i++; if (i >= max_memory_ranges) realloc_memory_ranges(); } /* chosen */ if (strncmp(dentry->d_name, "rtas", 4) == 0) { strcat(fname, "/linux,rtas-base"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if (fread(&rtas_base, sizeof(unsigned int), 1, file) != 1) { perror(fname); goto error_openfile; } memset(fname, 0, sizeof(fname)); sprintf(fname, "%s%s%s", device_tree, dentry->d_name, "/linux,rtas-size"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; } if (fread(&rtas_size, sizeof(unsigned int), 1, file) != 1) { perror(fname); goto error_openfile; } closedir(cdir); /* Add rtas to exclude_range */ exclude_range[i].start = rtas_base; exclude_range[i].end = rtas_base + rtas_size; i++; if (kexec_flags & KEXEC_ON_CRASH) add_usable_mem_rgns(rtas_base, rtas_size); } /* rtas */ if (!strncmp(dentry->d_name, "memory@", 7) || !strcmp(dentry->d_name, "memory")) { int fd; strcat(fname, "/reg"); if ((fd = open(fname, O_RDONLY)) < 0) { perror(fname); goto error_opencdir; } if (read_memory_region_limits(fd, &rmo_base, &rmo_top) != 0) goto error_openfile; if (rmo_top > 0x30000000UL) rmo_top = 0x30000000UL; close(fd); closedir(cdir); } /* memory */ if (strncmp(dentry->d_name, "pci@", 4) == 0) { strcat(fname, "/linux,tce-base"); file = fopen(fname, "r"); if (!file) { closedir(cdir); if (errno == ENOENT) { /* Non LPAR */ errno = 0; continue; } perror(fname); goto error_opendir; } if (fread(&tce_base, sizeof(unsigned long), 1, file) != 1) { perror(fname); goto error_openfile; return -1; } memset(fname, 0, sizeof(fname)); sprintf(fname, "%s%s%s", device_tree, dentry->d_name, "/linux,tce-size"); file = fopen(fname, "r"); if (!file) { perror(fname); goto error_opencdir; } if (fread(&tce_size, sizeof(unsigned int), 1, file) != 1) { perror(fname); goto error_openfile; } /* Add tce to exclude_range - NON-LPAR only */ exclude_range[i].start = tce_base; exclude_range[i].end = tce_base + tce_size; i++; if (kexec_flags & KEXEC_ON_CRASH) add_usable_mem_rgns(tce_base, tce_size); closedir(cdir); } /* pci */ } closedir(dir); nr_exclude_ranges = i; sort_ranges(); #ifdef DEBUG int k; for (k = 0; k < i; k++) fprintf(stderr, "exclude_range sorted exclude_range[%d] " "start:%llx, end:%llx\n", k, exclude_range[k].start, exclude_range[k].end); #endif return 0; error_openfile: fclose(file); error_opencdir: closedir(cdir); error_opendir: closedir(dir); return -1; }