Re: [PATCH 3/3] bootwrapper: Initialise CCI device if found in the fdt

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

 



On Thu, Sep 27, 2012 at 07:06:20PM +0100, Jon Medhurst (Tixy) wrote:
> From: Jon Medhurst <tixy@xxxxxxxxxx>
> 
> The A15xA7 models simulate a Cache Coherent Interconnect (CCI) and this
> needs to be initialised correctly for Linux to boot.
> 
> To perform this initiation we add the new function configure_from_fdt()
> which will look in the fdt for devices to initialise. In this first case
> we look for the CCI node and if found then setup this device.
> 
> Signed-off-by: Jon Medhurst <tixy@xxxxxxxxxx>
> ---
>  semi_loader.c |   50 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
> 
> diff --git a/semi_loader.c b/semi_loader.c
> index c9750be..ca70633 100644
> --- a/semi_loader.c
> +++ b/semi_loader.c
> @@ -242,6 +242,54 @@ libfdt_error:
>  	fatal("libfdt: ", fdt_strerror(e), ", while updating device tree\n");
>  }
>  
> +/* For accessing 32-bit device ports */
> +#define io32(p) (*(volatile uint32_t *)(p))
> +
> +static void init_cci(unsigned cci)
> +{
> +	info("Initialising CCI\n");
> +
> +	/*
> +	 * Ideally, the CCI device tree binding would include suitable
> +	 * information so we can correctly configure the CCI, but for
> +	 * now we'll just hard-code settings for the present A15xA7
> +	 * models.
> +	 */
> +
> +	/* Turn on CCI snoops and DVM messages */
> +	io32(cci+0x4000) = 0x3;   /* A15 cluster */
> +	io32(cci+0x5000) = 0x3;   /* A7 cluster */

Ultimately, CCI slave port assignments will be deducible from the DT
topology, but we don't have this yet, so I guess this is OK for now.

For the intergrated switcher work we can have a simple local patch for
this until/unless this (or the switcher) becomes more generic.

> +
> +	/* Wait while change pending bit of status register is set */
> +	while(io32(cci+0xc) & 0x1)
> +		{}
> +}
> +
> +static void configure_from_fdt(struct loader_info *info)
> +{
> +	void *fdt = (void *)info->fdt_start;
> +	uint32_t const *p;
> +	int addrcells, sizecells;
> +	int offset, len;
> +
> +	if(!fdt)
> +		return;
> +
> +	_fdt_address_and_size_cells(fdt, &addrcells, &sizecells);
> +
> +	/* See if there is a CCI device to initialise */
> +	offset = fdt_node_offset_by_compatible(fdt, 0, "arm,cci");

I'm guessing this binding isn't official yet, but it'll do for now...

> +	if (offset >= 0) {
> +		p = fdt_getprop(fdt, offset, "reg", &len);
> +		if(len != (addrcells + sizecells) * 4)
> +			info("Failed parsing device-tree node for CCI\n");
> +		else
> +			init_cci(fdt32_to_cpu(p[addrcells - 1]));

I think this is worth a comment.  I presume you're trying to get the low
32 bits of the address here (and assuming that the high 32 bits are zero).

Cheers
---Dave

> +	}
> +
> +	return;
> +}
> +
>  static int is_space(char c)
>  {
>  	return c == ' ';
> @@ -598,4 +646,6 @@ args_done:
>  	atag_append(&atagp, ATAG_NONE, 0, 0);
>  
>  	update_fdt(&phys, info);
> +
> +	configure_from_fdt(info);
>  }
> -- 
> 1.7.10.4
> 
_______________________________________________
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