#include #include struct crash_mem_range { uint64_t start, end; }; struct crash_mem { unsigned int max_nr_ranges; unsigned int nr_ranges; struct crash_mem_range ranges[]; }; struct crash_mem cmem = {10, 4, {{0x1000, 0x3fff}, {0x40000, 0x9ffff}, {0xf0000, 0x1ffffff}, {0x2000000, 0x20fffff}}}; int crash_exclude_mem_range(struct crash_mem *mem, unsigned long long mstart, unsigned long long mend) { int i, j; unsigned long long start, end, p_start, p_end; struct crash_mem_range temp_range = {0, 0}; for (i = 0; i < mem->nr_ranges; i++) { start = mem->ranges[i].start; end = mem->ranges[i].end; p_start = mstart; p_end = mend; if (mstart > end || mend < start) continue; /* Truncate any area outside of range */ if (mstart < start) p_start = start; if (mend > end) p_end = end; /* Found completely overlapping range */ if (p_start == start && p_end == end) { mem->ranges[i].start = 0; mem->ranges[i].end = 0; if (i < mem->nr_ranges - 1) { /* Shift rest of the ranges to left */ for (j = i; j < mem->nr_ranges - 1; j++) { mem->ranges[j].start = mem->ranges[j+1].start; mem->ranges[j].end = mem->ranges[j+1].end; } /* * Continue to check if there are another overlapping ranges * from the current position because of shifting the above * mem ranges. */ i--; mem->nr_ranges--; continue; } mem->nr_ranges--; return 0; } if (p_start > start && p_end < end) { /* Split original range */ mem->ranges[i].end = p_start - 1; temp_range.start = p_end + 1; temp_range.end = end; } else if (mstart != start) mem->ranges[i].end = p_start - 1; else mem->ranges[i].start = p_end + 1; break; } /* If a split happened, add the split to array */ if (!temp_range.end) return 0; /* Split happened */ if (i == mem->max_nr_ranges - 1) return -1; /* Location where new range should go */ j = i + 1; if (j < mem->nr_ranges) { /* Move over all ranges one slot towards the end */ for (i = mem->nr_ranges - 1; i >= j; i--) mem->ranges[i + 1] = mem->ranges[i]; } mem->ranges[j].start = temp_range.start; mem->ranges[j].end = temp_range.end; mem->nr_ranges++; return 0; } void print_cmem(struct crash_mem *mem) { int i; for (i = 0; i < mem->nr_ranges; i++) printf("%llx - %llx\n", mem->ranges[i].start, mem->ranges[i].end); } int main(int argc, char **argv) { crash_exclude_mem_range(&cmem, 0, (1<<20) - 1); print_cmem(&cmem); return 0; }