[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH V2 2/3] xen/arm: Add handling of extended regions for Dom0
Hi Stefano [snip] Thank you for the clarification. I need to find device node with non-empty ranges property (and make sure that device_type property is "pci"), after that I need to read the context of ranges property and translate it.You will also need to cover "ranges" that will describe the BARs for the PCIdevices.Good point.Yes, very good point!Could you please clarify how to recognize whether it is a PCIdevice as long as PCI support is not merged? Or just to find any device nodeswith non-empty "ranges" property and retrieve addresses?Normally any bus can have a ranges property with the aperture and possible address translations, including /amba (compatible = "simple-bus"). However, in these cases dt_device_get_address already takes care of it, see xen/common/device_tree.c:dt_device_get_address. The PCI bus is special for 2 reasons: - the ranges property has a different format - the bus is hot-pluggable So I think the only one that we need to treat specially is PCI. As far as I am aware PCI is the only bus (or maybe just the only bus that we support?) where ranges means the aperture. OK, I experimented with that and managed to parse ranges property for PCI host bridge node. I tested on my setup where the host device tree contains two PCI host bridge nodes with the following: pcie@fe000000 { ...ranges = <0x1000000 0x0 0x0 0x0 0xfe100000 0x0 0x100000 0x2000000 0x0 0xfe200000 0x0 0xfe200000 0x0 0x200000 0x2000000 0x0 0x30000000 0x0 0x30000000 0x0 0x8000000 0x42000000 0x0 0x38000000 0x0 0x38000000 0x0 0x8000000>; ... }; pcie@ee800000 { ...ranges = <0x1000000 0x0 0x0 0x0 0xee900000 0x0 0x100000 0x2000000 0x0 0xeea00000 0x0 0xeea00000 0x0 0x200000 0x2000000 0x0 0xc0000000 0x0 0xc0000000 0x0 0x8000000 0x42000000 0x0 0xc8000000 0x0 0xc8000000 0x0 0x8000000>; ... }; So Xen retrieves the *CPU addresses* from the ranges: (XEN) dev /soc/pcie@fe000000 range_size 7 nr_ranges 4 (XEN) 0: addr=fe100000, size=100000 (XEN) 1: addr=fe200000, size=200000 (XEN) 2: addr=30000000, size=8000000 (XEN) 3: addr=38000000, size=8000000 (XEN) dev /soc/pcie@ee800000 range_size 7 nr_ranges 4 (XEN) 0: addr=ee900000, size=100000 (XEN) 1: addr=eea00000, size=200000 (XEN) 2: addr=c0000000, size=8000000 (XEN) 3: addr=c8000000, size=8000000The code below covers ranges property in the context of finding memory holes (to be squashed with current patch): diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index d37156a..7d20c10 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c@@ -834,6 +834,8 @@ static int __init find_memory_holes(struct meminfo *ext_regions) { unsigned int naddr; u64 addr, size; + const __be32 *ranges; + u32 len; naddr = dt_number_of_address(np);@@ -857,6 +859,41 @@ static int __init find_memory_holes(struct meminfo *ext_regions) goto out; } } + + /*+ * Also looking for non-empty ranges property which would likely mean + * that we deal with PCI host bridge device and the property here + * describes the BARs for the PCI devices. + */ + ranges = dt_get_property(np, "ranges", &len); + if ( ranges && len ) + { + unsigned int range_size, nr_ranges; + int na, ns, pna; + + pna = dt_n_addr_cells(np); + na = dt_child_n_addr_cells(np); + ns = dt_child_n_size_cells(np); + range_size = pna + na + ns; + nr_ranges = len / sizeof(__be32) / range_size; + + for ( i = 0; i < nr_ranges; i++, ranges += range_size ) + {+ /* Skip the child address and get the parent (CPU) address */ + addr = dt_read_number(ranges + na, pna); + size = dt_read_number(ranges + na + pna, ns); + + start = addr & PAGE_MASK; + end = PAGE_ALIGN(addr + size); + res = rangeset_remove_range(mem_holes, start, end - 1); + if ( res ) + {+ printk(XENLOG_ERR "Failed to remove: %#"PRIx64"->%#"PRIx64"\n", + start, end); + goto out; + } + } + } } start = 0; -- Regards, Oleksandr Tyshchenko
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |