[coreboot] Multiboot bugfix #2 (coreboot-v3)

Jordan Crouse jordan.crouse at amd.com
Sat Oct 18 00:50:33 CEST 2008


On 28/09/08 00:13 +0200, Robert Millan wrote:
> 
> Hi,
> 
> I noticed that free regions provided by search_global_resources() don't have
> the reserved regions substracted from them.  This patch introduces a check
> to weed them out, splitting when necessary.
> 
> -- 
> Robert Millan
> 
>   The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
>   how) you may access your data; but nobody's threatening your freedom: we
>   still allow you to remove your data and not access it at all."

> 
> Signed-off-by: Robert Millan <rmh at aybabtu.com>
 
Acked-by: Jordan Crouse <jordan.crouse at amd.com>
> Index: arch/x86/multiboot.c
> ===================================================================
> --- arch/x86/multiboot.c	(revision 870)
> +++ arch/x86/multiboot.c	(working copy)
> @@ -25,42 +25,83 @@
>  
>  static struct multiboot_mmap_entry *mb_mem;
>  
> -static void build_mb_mem_range(void *gp, struct device *dev, struct resource *res)
> +static struct {
> +	u64 addr;
> +	u64 len;
> +} reserved_mem[2];
> +
> +static void build_mb_mem_range_nooverlap(u64 addr, u64 len)
>  {
> -	mb_mem->addr = res->base;
> -	mb_mem->len = res->size;
> +	int i;
> +	for (i = 0; i < sizeof(reserved_mem) / sizeof(reserved_mem[0]); i++) {
> +		/* free region fully contained in reserved region, abort */
> +		if (addr >= reserved_mem[i].addr && addr + len <= reserved_mem[i].addr + reserved_mem[i].len)
> +			return;
> +		/* reserved region splits free region */
> +		if (addr < reserved_mem[i].addr && addr + len > reserved_mem[i].addr + reserved_mem[i].len) {
> +			build_mb_mem_range_nooverlap(addr, reserved_mem[i].addr - addr);
> +			build_mb_mem_range_nooverlap(reserved_mem[i].addr + reserved_mem[i].len, (addr + len) - (reserved_mem[i].addr + reserved_mem[i].len));
> +			return;
> +		}
> +		/* left overlap */
> +		if (addr < reserved_mem[i].addr + reserved_mem[i].len && addr + len > reserved_mem[i].addr + reserved_mem[i].len) {
> +			len += addr;
> +			addr = reserved_mem[i].addr + reserved_mem[i].len;
> +			len -= addr;
> +			/* len += addr - old_addr */
> +			continue;
> +		}
> +		/* right overlap */
> +		if (addr < reserved_mem[i].addr && addr + len > reserved_mem[i].addr) {
> +			len = reserved_mem[i].addr - addr;
> +			continue;
> +		}
> +		/* none of the above, just add it */
> +	}
> +
> +	mb_mem->addr = addr;
> +	mb_mem->len = len;
>  	mb_mem->type = 1;
>  	mb_mem->size = sizeof(*mb_mem) - sizeof(mb_mem->size);
>  	mb_mem++;
>  }
>  
> +static void build_mb_mem_range(void *gp, struct device *dev, struct resource *res)
> +{
> +	build_mb_mem_range_nooverlap(res->base, res->size);
> +}
> +
>  unsigned long write_multiboot_info(
>  	unsigned long low_table_start, unsigned long low_table_end,
>  	unsigned long rom_table_start, unsigned long rom_table_end)
>  {
> -	struct multiboot_info *mbi = rom_table_end;
> +	struct multiboot_info *mbi;
> +	int i;
> +
> +	mbi = rom_table_end;
>  	memset(mbi, 0, sizeof(*mbi));
>  	rom_table_end += sizeof(*mbi);
>  
>  	mbi->mmap_addr = (u32) rom_table_end;
>  	mb_mem = rom_table_end;
>  
> +	/* reserved regions */
> +	reserved_mem[0].addr = low_table_start;
> +	reserved_mem[0].len = low_table_end - low_table_start;
> +	reserved_mem[1].addr = rom_table_start;
> +	reserved_mem[1].len = rom_table_end - rom_table_start;
> +	for (i = 0; i < sizeof(reserved_mem) / sizeof(reserved_mem[0]); i++) {
> +		mb_mem->addr = reserved_mem[i].addr;
> +		mb_mem->len = reserved_mem[i].len;
> +		mb_mem->type = 2;
> +		mb_mem->size = sizeof(*mb_mem) - sizeof(mb_mem->size);
> +		mb_mem++;
> +	}
> +
>  	/* free regions */
>  	search_global_resources( IORESOURCE_MEM | IORESOURCE_CACHEABLE,
>  		IORESOURCE_MEM | IORESOURCE_CACHEABLE, build_mb_mem_range, NULL);
>  
> -	/* reserved regions */
> -	mb_mem->addr = low_table_start;
> -	mb_mem->len = low_table_end - low_table_start;
> -	mb_mem->type = 2;
> -	mb_mem->size = sizeof(*mb_mem) - sizeof(mb_mem->size);
> -	mb_mem++;
> -	mb_mem->addr = rom_table_start;
> -	mb_mem->len = rom_table_end - rom_table_start;
> -	mb_mem->type = 2;
> -	mb_mem->size = sizeof(*mb_mem) - sizeof(mb_mem->size);
> -	mb_mem++;
> -
>  	mbi->mmap_length = ((u32) mb_mem) - mbi->mmap_addr;
>  	mbi->flags |= MB_INFO_MEM_MAP;
>  

> --
> coreboot mailing list: coreboot at coreboot.org
> http://www.coreboot.org/mailman/listinfo/coreboot


-- 
Jordan Crouse
Systems Software Development Engineer 
Advanced Micro Devices, Inc.





More information about the coreboot mailing list