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

[Minios-devel] [PATCH v2 34/47] arm: parse out the address/size for gicd/gicc



This patch parses out the address/size for gicd/gicc.

Signed-off-by: Huang Shijie <shijie.huang@xxxxxxx>
---
 arch/arm/gic.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 71 insertions(+), 15 deletions(-)

diff --git a/arch/arm/gic.c b/arch/arm/gic.c
index 1e37cdc..687f242 100644
--- a/arch/arm/gic.c
+++ b/arch/arm/gic.c
@@ -177,6 +177,72 @@ static void gic_handler(void) {
     gic_eoir(&gic, irq);
 }
 
+/*
+ * Parse the "reg" property.
+ *
+ * Note: *regp will increase.
+ */
+static uint64_t parse_reg(const uint32_t **regp, uint32_t cell)
+{
+    uint32_t i;
+    uint32_t buf[2];
+    uint64_t *buf64 = (uint64_t *)buf;
+    uint32_t *reg = (uint32_t *)(*regp);
+
+    if (cell > 2)
+        BUG();
+
+    for (i = 0; i < cell; i++)
+    {
+        buf[i] = reg[i];
+    }
+    *regp = reg + cell;
+    return fdt64_to_cpu(buf64[0]);
+}
+
+/*
+ * Parse out the address/size for gicd/gicc.
+ *
+ * Return 0 on success; return 1 on error.
+ */
+static int gic_parse(int node, uint64_t *gicd_addr, uint64_t *gicd_size,
+                               uint64_t *gicc_addr, uint64_t *gicc_size)
+{
+    uint32_t addr_cells = 2, size_cells = 1; /* The default, refer to Spec. */
+    const uint32_t *reg32;
+    int pnode;
+
+    pnode = fdt_parent_offset(device_tree, node);
+    if (pnode < 0)
+         return 1;
+
+    reg32 = fdt_getprop(device_tree, pnode, "#address-cells", NULL);
+    if (reg32)
+         addr_cells = fdt32_to_cpu(reg32[0]);
+
+    reg32 = fdt_getprop(device_tree, pnode, "#size-cells", NULL);
+    if (reg32)
+         size_cells = fdt32_to_cpu(reg32[0]);
+
+    if (addr_cells > 2 || size_cells > 2)
+    {
+         printk("Unsupported #address-cells: %d, #size-cells: %d\n",
+                addr_cells, size_cells);
+        return 1;
+    }
+
+    reg32 = fdt_getprop(device_tree, node, "reg", NULL);
+    if (reg32)
+    {
+         *gicd_addr = parse_reg(&reg32, addr_cells);
+         *gicd_size = parse_reg(&reg32, size_cells);
+         *gicc_addr = parse_reg(&reg32, addr_cells);
+         *gicc_size = parse_reg(&reg32, size_cells);
+    }
+
+    return 0;
+}
+
 void gic_init(void) {
     gic.gicd_base = NULL;
     int node = 0;
@@ -188,7 +254,7 @@ void gic_init(void) {
             break;
 
         if (fdt_getprop(device_tree, node, "interrupt-controller", NULL)) {
-            int len = 0;
+            uint64_t gicd_addr, gicd_size, gicc_addr, gicc_size;
 
             if (fdt_node_check_compatible(device_tree, node, 
"arm,cortex-a15-gic") &&
                 fdt_node_check_compatible(device_tree, node, 
"arm,cortex-a7-gic")) {
@@ -196,21 +262,11 @@ void gic_init(void) {
                 continue;
             }
 
-            const uint64_t *reg = fdt_getprop(device_tree, node, "reg", &len);
-
-            /* We have two registers (GICC and GICD), each of which contains
-             * two parts (an address and a size), each of which is a 64-bit
-             * value (8 bytes), so we expect a length of 2 * 2 * 8 = 32.
-             * If any extra values are passed in future, we ignore them. */
-            if (reg == NULL || len < 32) {
-                printk("Bad 'reg' property: %p %d\n", reg, len);
-                continue;
-            }
+            if (gic_parse(node, &gicd_addr, &gicd_size, &gicc_addr, 
&gicc_size))
+                   continue;
 
-            gic.gicd_base = ioremap((unsigned long) fdt64_to_cpu(reg[0]),
-                                    (unsigned long) fdt64_to_cpu(reg[1]));
-            gic.gicc_base = ioremap((unsigned long) fdt64_to_cpu(reg[2]),
-                                    (unsigned long) fdt64_to_cpu(reg[3]));
+            gic.gicd_base = ioremap(gicd_addr, gicd_size);
+            gic.gicc_base = ioremap(gicc_addr, gicc_size);
             printk("Found GIC: gicd_base = %p, gicc_base = %p\n", 
gic.gicd_base, gic.gicc_base);
             break;
         }
-- 
2.7.4


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.