On Mon, Oct 08, 2012 at 02:59:19PM +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. Acked-by: Dave Martin <dave.martin@xxxxxxxxxx> (Commentary below, but the patch looks OK to me.) > > Signed-off-by: Jon Medhurst <tixy@xxxxxxxxxx> > --- > semi_loader.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 57 insertions(+) > > diff --git a/semi_loader.c b/semi_loader.c > index c9750be..b0c064c 100644 > --- a/semi_loader.c > +++ b/semi_loader.c > @@ -242,6 +242,61 @@ 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)) I had a vague memory of something like this already existing somewhere, but I think I may be confusing this with another codebase. > + > +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 */ We may want to be more sophisticated about this at some point, but this is a sensible compromise for now. There is no official CCI binding yet, but this code makes reasonable- looking, minimal assumptions about its final form. > + > + /* 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"); > + 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 { > + /* > + * p[addrcells - 1] is the least significant 32-bits of > + * the address for the CCI. On 32-bit CPUs any additional > + * address bits had better be zero otherwise we can't > + * access it as we don't enable the MMU. > + */ > + init_cci(fdt32_to_cpu(p[addrcells - 1])); > + } > + } > + > + return; > +} > + > static int is_space(char c) > { > return c == ' '; > @@ -598,4 +653,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