Forum Discussion
Altera_Forum
Honored Contributor
9 years agoOn further debugging, I observed that the parsing of "ranges' property fails at this point:
To give the sequence: altera_pcie_probe() -> altera_pcie_parse_request_of_pci_ranges() -> of_pci_get_host_bridge_resources() In of_pci_get_host_bridge_resources(), there is a call to of_pci_range_parser_init(), and then a loop for_each_of_pci_range(&parser, &range), as below: /* Check for ranges property */ err = of_pci_range_parser_init(&parser, dev); if (err) goto parse_failed; pr_debug("Parsing ranges property...\n"); for_each_of_pci_range(&parser, &range) { pr_info("inside for_each_of_pci_range...\n"); /* Read next ranges element */ if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO) snprintf(range_type, 4, " IO"); else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM) snprintf(range_type, 4, "MEM"); else snprintf(range_type, 4, "err"); pr_info(" %s %#010llx..%#010llx -> %#010llx\n", range_type, range.cpu_addr, range.cpu_addr + range.size - 1, range.pci_addr); /* some code goes here */ } What I observed is, the loop is not entered at all, which means the previous function of_pci_range_parser_init() hasn't done it's job properly. Let me paste a portion of my DTS file again below: sopc0: sopc@0 { device_type = "soc"; ranges; # address-cells = <1>; # size-cells = <1>; compatible = "ALTR,avalon", "simple-bus"; bus-frequency = <0>; test_subsys_pcie: pcie@0x000000000 { compatible = "altera, my-pcie"; reg = <0xc0000000 0x00001000>, <0xc0001000 0x00010000>, <0xff200000 0x00010000>; reg-names = "axi_slave_1", "axi_slave_2", "axi_slave_3"; interrupt-parent = <&HPS_arm_gic_0>; interrupts = <0 19 4>; clocks = <&test_subsys_clk_125M>; device_type = "pci"; bus-range = <0x00000000 0x000000ff>; # address-cells = <1>; # size-cells = <1>; ranges = <0x00000000 0xc0000000 0x00001000>; }; //end unknown@0x000000000 (test_subsys_pcie) I expect the of_pci_range_parser_init() function to figure out the ranges correctly in the DTS. Is there anything wrong with the way I've declared the "ranges" in DTS ? If the parsing by of_pci_range_parser_init() is wrong, it should've returned an error, but it didn't; It succeeded; But the loop for_each_of_pci_range(&parser, &range) fails to take off ! Inside of_pci_range_parser_init(), I printed the the foll.: parser->range=c1ff789c, parser->end=c1ff78a8, len=12 The difference between 0x c1ff789c and 0x c1ff78a8 is 12 i.e. 12 bytes. But what does this length indicate?? The parser structure is defined in linux/of_address.h as follows: struct of_pci_range_parser { struct device_node *node; const __be32 *range; const __be32 *end; int np; int pna; }; What does the range and end mean here? I want to understand this w.r.to the ranges I've declared ranges = <0x00000000 0xc0000000 0x00001000>. In the loop for_each_of_pci_range(&parser, &range), the 2nd argument is a pointer to the foll. Structure: struct of_pci_range { u32 pci_space; u64 pci_addr; u64 cpu_addr; u64 size; u32 flags; }; Similary I want to understand the of_pci_range structure w.r.to the "ranges" property in DTS. What is the link among struct of_pci_range_parser, struct of_pci_range, and "ranges" property in DTS? Going through the code is pretty confusing. Can someone explain?