[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2] xen/arm: gicv2: Export GICv2m register frames to domain0 by device tree
Hi Julien, On 26 April 2016 at 18:49, Julien Grall <julien.grall@xxxxxxx> wrote: > Hello Wei, > > On 25/04/2016 10:39, Wei Chen wrote: >> >> This patch adds v2m extension support in GIC-v2 driver. The GICv2 driver >> detects the MSI frames from device tree and creates corresponding device >> tree nodes in Domain0's DTB. It also provides one hw_ops callback to map > > > NIT: s/Domain0/dom0/ > >> v2m MMIO regions to domain0 and route v2m SPIs to domain0. > > > Ditto. > >> >> With this GICv2m extension support, the domain0 kernel can do GICv2m > > > Ditto > >> frame setup and initialization. >> >> This patch is based on the GICv2m patch of Suravee Suthikulpanit: >> [PATCH 2/2] xen/arm: gicv2: Adding support for GICv2m in Dom0 >> http://lists.xen.org/archives/html/xen-devel/2015-04/msg02613.html >> >> Signed-off-by: Wei Chen <Wei.Chen@xxxxxxxxxx> > > > [...] > >> +static int gicv2_map_hwdown_extra_mappings(struct domain *d) >> +{ >> + const struct v2m_data *v2m_data; >> + >> + /* For the moment, we'll assign all v2m frames to the hardware >> domain. */ >> + list_for_each_entry( v2m_data, &gicv2m_info, entry ) >> + { >> + int ret; >> + u32 spi; >> + >> + printk("GICv2: Mapping v2m frame to d%d: addr=0x%lx size=0x%lx >> spi_base=%u num_spis=%u\n", >> + d->domain_id, v2m_data->addr, v2m_data->size, >> + v2m_data->spi_start, v2m_data->nr_spis); >> + >> + ret = map_mmio_regions(d, paddr_to_pfn(v2m_data->addr), >> + DIV_ROUND_UP(v2m_data->size, PAGE_SIZE), >> + paddr_to_pfn(v2m_data->addr)); >> + if ( ret ) >> + { >> + printk(XENLOG_ERR "GICv2: Map v2m frame to s%d failed.\n", > > > s/s%d/d%d/ > >> + d->domain_id); >> + return ret; >> + } >> + >> + /* >> + * Map all SPIs that are allocated to MSIs for the frame to the >> + * domain. >> + */ >> + for ( spi = v2m_data->spi_start; >> + spi < (v2m_data->spi_start + v2m_data->nr_spis); spi++ ) >> + { >> + /* >> + * MSIs are always edge-triggered. Configure the associated >> SPIs >> + * to be edge-rising. > > > How did you find that SPIs should be configured edge-rising? Before route_irq_to_guest, the SPI must be configured. I found Linux v2m driver set the SPI type to edge-rising, so I set edge-rising as v2m SPI default type here too. > > >> + */ >> + ret = irq_set_spi_type(spi, IRQ_TYPE_EDGE_RISING); >> + if ( ret ) >> + { >> + printk(XENLOG_ERR >> + "GICv2: Failed to set v2m MSI SPI[%d] type.\n", >> spi); >> + return ret; >> + } >> + >> + /* Route a SPI that is allocated to MSI to the domain. */ >> + ret = route_irq_to_guest(d, spi, spi, "v2m"); >> + if ( ret ) >> + { >> + printk(XENLOG_ERR >> + "GICv2: Failed to route v2m MSI SPI[%d] to >> Dom%d.\n", >> + spi, d->domain_id); >> + return ret; >> + } >> + >> + /* Reserve a SPI that is allocated to MSI for the domain. */ >> + if ( !vgic_reserve_virq(d, spi) ) >> + { >> + printk(XENLOG_ERR >> + "GICv2: Failed to reserve v2m MSI SPI[%d] for >> Dom%d.\n", >> + spi, d->domain_id); >> + return -EINVAL; >> + } >> + } >> + } >> + >> + return 0; >> +} >> + >> +/* >> + * Set up gic v2m DT sub-node. >> + * Please refer to the binding document: >> + * >> https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt >> + */ >> +static int gicv2m_make_dt_node(const struct domain *d, >> + const struct dt_device_node *gic, >> + void *fdt) > > > The indentation is still wrong here. > > The start of the second and third lines should be aligned to "const..." on > the first line. I.e > > foo(const > ____const > ____void > > Where _ is the empty space. > > [...] > Thanks for your detailed example! >> +static void gicv2_add_v2m_frame_to_list(paddr_t addr, paddr_t size, >> + u32 spi_start, u32 nr_spis, >> + const struct dt_device_node *v2m) >> +{ >> + struct v2m_data *v2m_data; >> + >> + v2m_data = xzalloc_bytes(sizeof(struct v2m_data)); >> + if ( !v2m_data ) >> + panic("GICv2: Cannot allocate memory for v2m frame"); >> + >> + /* Initialize a new entry to record new frame infomation. */ > > > s/infomation/information/ > > >> + INIT_LIST_HEAD(&v2m_data->entry); >> + v2m_data->addr = addr; >> + v2m_data->size = size; >> + v2m_data->spi_start = spi_start; >> + v2m_data->nr_spis = nr_spis; >> + v2m_data->dt_node = v2m; >> + >> + printk("GICv2m extension register frame:\n" >> + " gic_v2m_addr=%"PRIpaddr"\n" >> + " gic_v2m_size=%"PRIpaddr"\n" >> + " gic_v2m_spi_base=%u\n" >> + " gic_v2m_num_spis=%u\n", >> + v2m_data->addr, v2m_data->size, >> + v2m_data->spi_start, v2m_data->nr_spis); >> + >> + list_add_tail(&v2m_data->entry, &gicv2m_info); >> +} >> + >> +static void gicv2_extension_dt_init(const struct dt_device_node *node) >> +{ >> + int res; >> + u32 spi_start, nr_spis; >> + paddr_t addr, size; >> + const struct dt_device_node *v2m = NULL; >> + >> + /* >> + * Check whether this GIC implements the v2m extension. If so, >> + * add v2m register frames to gicv2m_info. >> + */ >> + dt_for_each_child_node(node, v2m) >> + { >> + if ( !dt_device_is_compatible(v2m, "arm,gic-v2m-frame") ) >> + continue; >> + >> + /* >> + * Check whether DT uses msi-base-spi and msi-num-spis properties >> to >> + * override the hardware setting. >> + */ >> + if ( !dt_property_read_u32(v2m, "arm,msi-base-spi", &spi_start) >> || >> + !dt_property_read_u32(v2m, "arm,msi-num-spis", &nr_spis) ) >> + { >> + u32 msi_typer; >> + void __iomem *base; >> + >> + /* >> + * DT does not override the hardware setting, so we have to >> read >> + * base_spi and num_spis from hardware registers to reserve >> irqs. >> + */ > > > The indentation of the comments if wrong. > > It should be: > > /* > * FOo > * Bar > */ > >> + res = dt_device_get_address(v2m, 0, &addr, &size); >> + if ( res ) >> + panic("GICv2: Cannot find a valid v2m frame address"); >> + >> + base = ioremap_nocache(addr, size); >> + if ( !base ) >> + panic("GICv2: Cannot remap v2m register frame"); >> + >> + msi_typer = readl_relaxed(base + V2M_MSI_TYPER); >> + spi_start = V2M_MSI_TYPER_BASE_SPI(msi_typer); >> + nr_spis = V2M_MSI_TYPER_NUM_SPI(msi_typer); > > > The ACPI code will likely need to read those registers. So this could go in > the new function you have added. > > You could pass pointers to your function to know whether the values are > overridden by the firmware. > I will refine the new function. >> + >> + iounmap(base); >> + } >> + >> + /* Add this v2m frame information to list. */ >> + gicv2_add_v2m_frame_to_list(addr, size, spi_start, nr_spis, v2m); >> + } >> +} >> + > > > Regards, > > -- > Julien Grall _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |