예제 #1
0
static void lb_dump_memory_ranges(struct lb_memory *mem)
{
	int entries;
	int i;
	entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);

	printk(BIOS_DEBUG, "coreboot memory table:\n");
	for(i = 0; i < entries; i++) {
		uint64_t entry_start = unpack_lb64(mem->map[i].start);
		uint64_t entry_size = unpack_lb64(mem->map[i].size);
		const char *entry_type;

		switch (mem->map[i].type) {
		case LB_MEM_RAM: entry_type="RAM"; break;
		case LB_MEM_RESERVED: entry_type="RESERVED"; break;
		case LB_MEM_ACPI: entry_type="ACPI"; break;
		case LB_MEM_NVS: entry_type="NVS"; break;
		case LB_MEM_UNUSABLE: entry_type="UNUSABLE"; break;
		case LB_MEM_VENDOR_RSVD: entry_type="VENDOR RESERVED"; break;
		case LB_MEM_TABLE: entry_type="CONFIGURATION TABLES"; break;
		default: entry_type="UNKNOWN!"; break;
		}

		printk(BIOS_DEBUG, "%2d. %016llx-%016llx: %s\n",
			i, entry_start, entry_start+entry_size-1, entry_type);

	}
}
예제 #2
0
static void lb_reserve_table_memory(struct lb_header *head)
{
/* Dynamic cbmem has already reserved the memory where the coreboot tables
 * reside. Therefore, there is nothing to fix up. */
#if !CONFIG_DYNAMIC_CBMEM
	struct lb_record *last_rec;
	struct lb_memory *mem;
	uint64_t start;
	uint64_t end;
	int i, entries;

	last_rec = lb_last_record(head);
	mem = get_lb_mem();
	start = (unsigned long)head;
	end = (unsigned long)last_rec;
	entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
	/* Resize the right two memory areas so this table is in
	 * a reserved area of memory.  Everything has been carefully
	 * setup so that is all we need to do.
	 */
	for(i = 0; i < entries; i++ ) {
		uint64_t map_start = unpack_lb64(mem->map[i].start);
		uint64_t map_end = map_start + unpack_lb64(mem->map[i].size);
		/* Does this area need to be expanded? */
		if (map_end == start) {
			mem->map[i].size = pack_lb64(end - map_start);
		}
		/* Does this area need to be contracted? */
		else if (map_start == start) {
			mem->map[i].start = pack_lb64(end);
			mem->map[i].size = pack_lb64(map_end - end);
		}
	}
#endif
}
예제 #3
0
/****************************************************************************
 * memory_print_fn
 *
 * Display function for 'memory' item of coreboot table.
 ****************************************************************************/
static void memory_print_fn(const struct lb_record *rec)
{
	char start_str[19], end_str[19], size_str[19];
	const struct lb_memory *p;
	const char *mem_type;
	const struct lb_memory_range *ranges;
	uint64_t size, start, end;
	int i, entries;

	p = (const struct lb_memory *)rec;
	entries = (p->size - sizeof(*p)) / sizeof(p->map[0]);
	ranges = p->map;

	if (entries == 0) {
		printf("No memory ranges were found.\n");
		return;
	}

	for (i = 0;;) {
		switch (ranges[i].type) {
		case LB_MEM_RAM:
			mem_type = "AVAILABLE";
			break;

		case LB_MEM_RESERVED:
			mem_type = "RESERVED";
			break;

		case LB_MEM_TABLE:
			mem_type = "CONFIG_TABLE";
			break;

		default:
			mem_type = "UNKNOWN";
			break;
		}

		size = unpack_lb64(ranges[i].size);
		start = unpack_lb64(ranges[i].start);
		end = start + size - 1;
		uint64_to_hex_string(start_str, start);
		uint64_to_hex_string(end_str, end);
		uint64_to_hex_string(size_str, size);
		printf("%s memory:\n"
		       "    from physical addresses %s to %s\n"
		       "    size is %s bytes (%lld in decimal)\n",
		       mem_type, start_str, end_str, size_str,
		       (unsigned long long)size);

		if (++i >= entries)
			break;

		printf("\n");
	}
}
예제 #4
0
파일: lbtable.c 프로젝트: 0ida/coreboot
/****************************************************************************
 * memory_print_fn
 *
 * Display function for 'memory' item of coreboot table.
 ****************************************************************************/
static void memory_print_fn(const struct lb_record *rec)
{
	const struct lb_memory *p;
	const char *mem_type;
	const struct lb_memory_range *ranges;
	uint64_t size, start, end;
	int i, entries;

	p = (const struct lb_memory *)rec;
	entries = (p->size - sizeof(*p)) / sizeof(p->map[0]);
	ranges = p->map;

	if (entries == 0) {
		printf("No memory ranges were found.\n");
		return;
	}

	for (i = 0;;) {
		switch (ranges[i].type) {
		case LB_MEM_RAM:
			mem_type = "AVAILABLE";
			break;

		case LB_MEM_RESERVED:
			mem_type = "RESERVED";
			break;

		case LB_MEM_TABLE:
			mem_type = "CONFIG_TABLE";
			break;

		default:
			mem_type = "UNKNOWN";
			break;
		}

		size = unpack_lb64(ranges[i].size);
		start = unpack_lb64(ranges[i].start);
		end = start + size - 1;
		printf("%s memory:\n"
		       "    from physical addresses 0x%016" PRIx64
		       " to 0x%016" PRIx64 "\n    size is 0x%016" PRIx64
		       " bytes (%" PRId64 " in decimal)\n",
		       mem_type, start, end, size, size);

		if (++i >= entries)
			break;

		printf("\n");
	}
}
예제 #5
0
static void lb_remove_memory_range(struct lb_memory *mem,
	uint64_t start, uint64_t size)
{
	uint64_t end;
	int entries;
	int i;

	end = start + size;
	entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);

	/* Remove a reserved area from the memory map */
	for(i = 0; i < entries; i++) {
		uint64_t map_start = unpack_lb64(mem->map[i].start);
		uint64_t map_end   = map_start + unpack_lb64(mem->map[i].size);
		if ((start <= map_start) && (end >= map_end)) {
			/* Remove the completely covered range */
			memmove(&mem->map[i], &mem->map[i + 1],
				((entries - i - 1) * sizeof(mem->map[0])));
			mem->size -= sizeof(mem->map[0]);
			entries -= 1;
			/* Since the index will disappear revisit what will appear here */
			i -= 1;
		}
		else if ((start > map_start) && (end < map_end)) {
			/* Split the memory range */
			memmove(&mem->map[i + 1], &mem->map[i],
				((entries - i) * sizeof(mem->map[0])));
			mem->size += sizeof(mem->map[0]);
			entries += 1;
			/* Update the first map entry */
			mem->map[i].size = pack_lb64(start - map_start);
			/* Update the second map entry */
			mem->map[i + 1].start = pack_lb64(end);
			mem->map[i + 1].size  = pack_lb64(map_end - end);
			/* Don't bother with this map entry again */
			i += 1;
		}
		else if ((start <= map_start) && (end > map_start)) {
			/* Shrink the start of the memory range */
			mem->map[i].start = pack_lb64(end);
			mem->map[i].size  = pack_lb64(map_end - end);
		}
		else if ((start < map_end) && (start > map_start)) {
			/* Shrink the end of the memory range */
			mem->map[i].size = pack_lb64(start - map_start);
		}
	}
}
예제 #6
0
static void lb_cleanup_memory_ranges(struct lb_memory *mem)
{
	int entries;
	int i, j;
	entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);

	/* Sort the lb memory ranges */
	for(i = 0; i < entries; i++) {
		uint64_t entry_start = unpack_lb64(mem->map[i].start);
		for(j = i + 1; j < entries; j++) {
			uint64_t temp_start = unpack_lb64(mem->map[j].start);
			if (temp_start < entry_start) {
				struct lb_memory_range tmp;
				tmp = mem->map[i];
				mem->map[i] = mem->map[j];
				mem->map[j] = tmp;
			}
		}
	}

	/* Merge adjacent entries */
	for(i = 0; (i + 1) < entries; i++) {
		uint64_t start, end, nstart, nend;
		if (mem->map[i].type != mem->map[i + 1].type) {
			continue;
		}
		start  = unpack_lb64(mem->map[i].start);
		end    = start + unpack_lb64(mem->map[i].size);
		nstart = unpack_lb64(mem->map[i + 1].start);
		nend   = nstart + unpack_lb64(mem->map[i + 1].size);
		if ((start <= nstart) && (end >= nstart)) {
			if (start > nstart) {
				start = nstart;
			}
			if (end < nend) {
				end = nend;
			}
			/* Record the new region size */
			mem->map[i].start = pack_lb64(start);
			mem->map[i].size  = pack_lb64(end - start);

			/* Delete the entry I have merged with */
			memmove(&mem->map[i + 1], &mem->map[i + 2],
				((entries - i - 2) * sizeof(mem->map[0])));
			mem->size -= sizeof(mem->map[0]);
			entries -= 1;
			/* See if I can merge with the next entry as well */
			i -= 1;
		}
	}
}