Re: [PATCH v2] semi_loader: Handle dtbs with 64 bit addresses

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Aug 17, 2012 at 05:39:56PM +0100, Peter Maydell wrote:
> ARM board device tree blobs have moved to specifying addresses and
> sizes as 64 bit values (2 cells) rather than 32 bit (1 cell); update
> bootwrapper so it can handle these rather than stopping with an error.

Assuming that you've tested this, of course:

Acked-by: Dave Martin <dave.martin@xxxxxxxxxx>

> 
> Signed-off-by: Peter Maydell <peter.maydell@xxxxxxxxxx>
> ---
> v1->v2: correct assumption that size-cells == address-cells when
> checking whether existing memory size field is zero
> 
>  semi_loader.c |   37 +++++++++++++++++++++++++++----------
>  1 file changed, 27 insertions(+), 10 deletions(-)
> 
> diff --git a/semi_loader.c b/semi_loader.c
> index 6677527..2a30c5a 100644
> --- a/semi_loader.c
> +++ b/semi_loader.c
> @@ -103,6 +103,7 @@ static void update_fdt(void **dest, struct loader_info *info)
>  	int _chosen;
>  	void *fdt;
>  	uint32_t const *p;
> +	int addrcells, sizecells;
>  
>  	if(!info->fdt_start)
>  		return;
> @@ -113,17 +114,21 @@ static void update_fdt(void **dest, struct loader_info *info)
>  
>  	/*
>  	 * Sanity-check address sizes, since addresses and sizes which do
> -	 * not take up exactly 4 bytes are not supported.
> +	 * not take up exactly 4 or 8 bytes are not supported.
>  	 */
>  	{
>  		if(!(p = fdt_getprop(fdt, 0, "#address-cells", &e)))
>  			goto libfdt_error;
> -		else if(e != 4 || fdt32_to_cpu(*p) != 1)
> +		else if(e != 4)
>  			goto size_error;
> -
> +		addrcells = fdt32_to_cpu(*p);
>  		if(!(p = fdt_getprop(fdt, 0, "#size-cells", &e)))
>  			goto libfdt_error;
> -		else if(e != 4 || fdt32_to_cpu(*p) != 1)
> +		else if(e != 4)
> +			goto size_error;
> +		sizecells = fdt32_to_cpu(*p);
> +		if ((addrcells != 1 && addrcells != 2) ||
> +		    (sizecells != 1 && sizecells != 2))
>  			goto size_error;
>  	}
>  
> @@ -137,7 +142,7 @@ static void update_fdt(void **dest, struct loader_info *info)
>  	{
>  		int offset, depth = 0;
>  		int _memory;
> -		uint32_t reg[2];
> +		uint32_t reg[4];
>  
>  		for(offset = fdt_next_node(fdt, 0, &depth); offset >= 0;
>  				offset = fdt_next_node(fdt, offset, &depth)) {
> @@ -153,7 +158,10 @@ static void update_fdt(void **dest, struct loader_info *info)
>  				if(e < 0)
>  					goto libfdt_error;
>  
> -				if(fdt32_to_cpu(p[1]) != 0)
> +				/* Check whether the <size> part of the <addr>,<size> tuple is nonzero */
> +				if(fdt32_to_cpu(p[addrcells]) != 0)
> +					goto no_add_memory;
> +				if(sizecells == 2 && fdt32_to_cpu(p[addrcells + 1]) != 0)
>  					goto no_add_memory;
>  			}
>  		}
> @@ -162,9 +170,15 @@ static void update_fdt(void **dest, struct loader_info *info)
>  			goto libfdt_error;
>  		_memory = e;
>  
> -		reg[0] = cpu_to_fdt32(PHYS_OFFSET);
> -		reg[1] = cpu_to_fdt32(PHYS_SIZE);
> -		if((e = fdt_setprop(fdt, _memory, "reg", &reg, sizeof reg)) < 0)
> +		/* This assumes PHYS_OFFSET and PHYS_SIZE are 32 bits, though
> +		 * the fdt cells we put them in may not be.
> +		 */
> +		reg[0] = reg[1] = reg[2] = reg[3] = 0;
> +		reg[addrcells - 1] = cpu_to_fdt32(PHYS_OFFSET);
> +		reg[addrcells + sizecells - 1] = cpu_to_fdt32(PHYS_SIZE);
> +		
> +		if((e = fdt_setprop(fdt, _memory, "reg", &reg,
> +				    sizeof(reg[0]) * (addrcells + sizecells))) < 0)
>  			goto libfdt_error;
>  
>  		if((e = fdt_setprop_string(fdt, _memory, "device_type",
> @@ -186,7 +200,10 @@ no_add_memory:
>  
>  	if(info->initrd_start) {
>  		uint32_t initrd_end = info->initrd_start + info->initrd_size;
> -
> +		/* It's not documented whether these cells should honour
> +		 * #address-cells. Currently the kernel accepts them as being
> +		 * addresses of either size, so we leave them as 32 bits for now.
> +		 */
>  		if((e = fdt_setprop_cell(fdt, _chosen, "linux,initrd-start",
>  					info->initrd_start)) < 0)
>  			goto libfdt_error;
> -- 
> 1.7.9.5
> 
_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm


[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux