* In pseudo code, this implementation does the following:\r
*\r
* for each node {\r
- * have_device_type = false\r
- * have_reg = false\r
+ * have_device_type = false\r
+ * have_reg = false\r
*\r
- * for each property {\r
- * if property value == 'memory' {\r
- * if property name == 'device_type' {\r
- * have_device_type = true\r
- * }\r
- * } else {\r
- * if property name == 'reg' {\r
- * have_reg = true\r
- * membase = property value[0]\r
- * memsize = property value[1]\r
- * }\r
- * }\r
- * }\r
- * if have_device_type and have_reg {\r
- * return membase and memsize\r
- * }\r
+ * for each property {\r
+ * if property value == 'memory' {\r
+ * if property name == 'device_type' {\r
+ * have_device_type = true\r
+ * }\r
+ * } else {\r
+ * if property name == 'reg' {\r
+ * have_reg = true\r
+ * membase = property value[0]\r
+ * memsize = property value[1]\r
+ * }\r
+ * }\r
+ * }\r
+ * if have_device_type and have_reg {\r
+ * return membase and memsize\r
+ * }\r
* }\r
* return NOT_FOUND\r
*/\r
\r
-#define FDT_MAGIC 0xedfe0dd0\r
+#define FDT_MAGIC 0xedfe0dd0\r
\r
-#define FDT_BEGIN_NODE 0x1\r
-#define FDT_END_NODE 0x2\r
-#define FDT_PROP 0x3\r
-#define FDT_END 0x9\r
+#define FDT_BEGIN_NODE 0x1\r
+#define FDT_END_NODE 0x2\r
+#define FDT_PROP 0x3\r
+#define FDT_END 0x9\r
\r
- xMEMSIZE .req x0 // recorded system RAM size\r
- xMEMBASE .req x1 // recorded system RAM base\r
+ xMEMSIZE .req x0 // recorded system RAM size\r
+ xMEMBASE .req x1 // recorded system RAM base\r
\r
- xLR .req x8 // our preserved link register\r
- xDTP .req x9 // pointer to traverse the DT structure\r
- xSTRTAB .req x10 // pointer to the DTB string table\r
- xMEMNODE .req x11 // bit field to record found properties\r
+ xLR .req x8 // our preserved link register\r
+ xDTP .req x9 // pointer to traverse the DT structure\r
+ xSTRTAB .req x10 // pointer to the DTB string table\r
+ xMEMNODE .req x11 // bit field to record found properties\r
\r
-#define HAVE_REG 0x1\r
-#define HAVE_DEVICE_TYPE 0x2\r
+#define HAVE_REG 0x1\r
+#define HAVE_DEVICE_TYPE 0x2\r
\r
- .text\r
- .align 3\r
+ .text\r
+ .align 3\r
_memory:\r
- .asciz "memory"\r
+ .asciz "memory"\r
_reg:\r
- .asciz "reg"\r
+ .asciz "reg"\r
_device_type:\r
- .asciz "device_type"\r
+ .asciz "device_type"\r
\r
- /*\r
- * Compare strings in x4 and x5, return in w7\r
- */\r
- .align 3\r
+ /*\r
+ * Compare strings in x4 and x5, return in w7\r
+ */\r
+ .align 3\r
strcmp:\r
- ldrb w2, [x4], #1\r
- ldrb w3, [x5], #1\r
- subs w7, w2, w3\r
- cbz w2, 0f\r
- cbz w3, 0f\r
- beq strcmp\r
-0: ret\r
-\r
- .globl find_memnode\r
+ ldrb w2, [x4], #1\r
+ ldrb w3, [x5], #1\r
+ subs w7, w2, w3\r
+ cbz w2, 0f\r
+ cbz w3, 0f\r
+ beq strcmp\r
+0: ret\r
+\r
+ .globl find_memnode\r
find_memnode:\r
- // preserve link register\r
- mov xLR, x30\r
- mov xDTP, x0\r
-\r
- /*\r
- * Check the DTB magic at offset 0\r
- */\r
- movz w4, #:abs_g0_nc:FDT_MAGIC\r
- movk w4, #:abs_g1:FDT_MAGIC\r
- ldr w5, [xDTP]\r
- cmp w4, w5\r
- bne err_invalid_magic\r
-\r
- /*\r
- * Read the string offset and store it for later use\r
- */\r
- ldr w4, [xDTP, #12]\r
- rev w4, w4\r
- add xSTRTAB, xDTP, x4\r
-\r
- /*\r
- * Read the struct offset and add it to the DT pointer\r
- */\r
- ldr w5, [xDTP, #8]\r
- rev w5, w5\r
- add xDTP, xDTP, x5\r
-\r
- /*\r
- * Check current tag for FDT_BEGIN_NODE\r
- */\r
- ldr w5, [xDTP]\r
- rev w5, w5\r
- cmp w5, #FDT_BEGIN_NODE\r
- bne err_unexpected_begin_tag\r
+ // preserve link register\r
+ mov xLR, x30\r
+ mov xDTP, x0\r
+\r
+ /*\r
+ * Check the DTB magic at offset 0\r
+ */\r
+ movz w4, #:abs_g0_nc:FDT_MAGIC\r
+ movk w4, #:abs_g1:FDT_MAGIC\r
+ ldr w5, [xDTP]\r
+ cmp w4, w5\r
+ bne err_invalid_magic\r
+\r
+ /*\r
+ * Read the string offset and store it for later use\r
+ */\r
+ ldr w4, [xDTP, #12]\r
+ rev w4, w4\r
+ add xSTRTAB, xDTP, x4\r
+\r
+ /*\r
+ * Read the struct offset and add it to the DT pointer\r
+ */\r
+ ldr w5, [xDTP, #8]\r
+ rev w5, w5\r
+ add xDTP, xDTP, x5\r
+\r
+ /*\r
+ * Check current tag for FDT_BEGIN_NODE\r
+ */\r
+ ldr w5, [xDTP]\r
+ rev w5, w5\r
+ cmp w5, #FDT_BEGIN_NODE\r
+ bne err_unexpected_begin_tag\r
\r
begin_node:\r
- mov xMEMNODE, #0\r
- add xDTP, xDTP, #4\r
+ mov xMEMNODE, #0\r
+ add xDTP, xDTP, #4\r
\r
- /*\r
- * Advance xDTP past NULL terminated string\r
- */\r
-0: ldrb w4, [xDTP], #1\r
- cbnz w4, 0b\r
+ /*\r
+ * Advance xDTP past NULL terminated string\r
+ */\r
+0: ldrb w4, [xDTP], #1\r
+ cbnz w4, 0b\r
\r
next_tag:\r
- /*\r
- * Align the DT pointer xDTP to the next 32-bit boundary\r
- */\r
- add xDTP, xDTP, #3\r
- and xDTP, xDTP, #~3\r
-\r
- /*\r
- * Read the next tag, could be BEGIN_NODE, END_NODE, PROP, END\r
- */\r
- ldr w5, [xDTP]\r
- rev w5, w5\r
- cmp w5, #FDT_BEGIN_NODE\r
- beq begin_node\r
- cmp w5, #FDT_END_NODE\r
- beq end_node\r
- cmp w5, #FDT_PROP\r
- beq prop_node\r
- cmp w5, #FDT_END\r
- beq err_end_of_fdt\r
- b err_unexpected_tag\r
+ /*\r
+ * Align the DT pointer xDTP to the next 32-bit boundary\r
+ */\r
+ add xDTP, xDTP, #3\r
+ and xDTP, xDTP, #~3\r
+\r
+ /*\r
+ * Read the next tag, could be BEGIN_NODE, END_NODE, PROP, END\r
+ */\r
+ ldr w5, [xDTP]\r
+ rev w5, w5\r
+ cmp w5, #FDT_BEGIN_NODE\r
+ beq begin_node\r
+ cmp w5, #FDT_END_NODE\r
+ beq end_node\r
+ cmp w5, #FDT_PROP\r
+ beq prop_node\r
+ cmp w5, #FDT_END\r
+ beq err_end_of_fdt\r
+ b err_unexpected_tag\r
\r
prop_node:\r
- /*\r
- * If propname == 'reg', record as membase and memsize\r
- * If propname == 'device_type' and value == 'memory',\r
- * set the 'is_memnode' flag for this node\r
- */\r
- ldr w6, [xDTP, #4]\r
- add xDTP, xDTP, #12\r
- rev w6, w6\r
- mov x5, xDTP\r
- adr x4, _memory\r
- bl strcmp\r
-\r
- /*\r
- * Get handle to property name\r
- */\r
- ldr w5, [xDTP, #-4]\r
- rev w5, w5\r
- add x5, xSTRTAB, x5\r
-\r
- cbz w7, check_device_type\r
-\r
- /*\r
- * Check for 'reg' property\r
- */\r
- adr x4, _reg\r
- bl strcmp\r
- cbnz w7, inc_and_next_tag\r
-\r
- /*\r
- * Extract two 64-bit quantities from the 'reg' property. These values\r
- * will only be used if the node also turns out to have a device_type\r
- * property with a value of 'memory'.\r
- *\r
- * NOTE: xDTP is only guaranteed to be 32 bit aligned, and we are most\r
- * likely executing with the MMU off, so we cannot use 64 bit\r
- * wide accesses here.\r
- */\r
- ldp w4, w5, [xDTP]\r
- orr xMEMBASE, x4, x5, lsl #32\r
- ldp w4, w5, [xDTP, #8]\r
- orr xMEMSIZE, x4, x5, lsl #32\r
- rev xMEMBASE, xMEMBASE\r
- rev xMEMSIZE, xMEMSIZE\r
- orr xMEMNODE, xMEMNODE, #HAVE_REG\r
- b inc_and_next_tag\r
+ /*\r
+ * If propname == 'reg', record as membase and memsize\r
+ * If propname == 'device_type' and value == 'memory',\r
+ * set the 'is_memnode' flag for this node\r
+ */\r
+ ldr w6, [xDTP, #4]\r
+ add xDTP, xDTP, #12\r
+ rev w6, w6\r
+ mov x5, xDTP\r
+ adr x4, _memory\r
+ bl strcmp\r
+\r
+ /*\r
+ * Get handle to property name\r
+ */\r
+ ldr w5, [xDTP, #-4]\r
+ rev w5, w5\r
+ add x5, xSTRTAB, x5\r
+\r
+ cbz w7, check_device_type\r
+\r
+ /*\r
+ * Check for 'reg' property\r
+ */\r
+ adr x4, _reg\r
+ bl strcmp\r
+ cbnz w7, inc_and_next_tag\r
+\r
+ /*\r
+ * Extract two 64-bit quantities from the 'reg' property. These values\r
+ * will only be used if the node also turns out to have a device_type\r
+ * property with a value of 'memory'.\r
+ *\r
+ * NOTE: xDTP is only guaranteed to be 32 bit aligned, and we are most\r
+ * likely executing with the MMU off, so we cannot use 64 bit\r
+ * wide accesses here.\r
+ */\r
+ ldp w4, w5, [xDTP]\r
+ orr xMEMBASE, x4, x5, lsl #32\r
+ ldp w4, w5, [xDTP, #8]\r
+ orr xMEMSIZE, x4, x5, lsl #32\r
+ rev xMEMBASE, xMEMBASE\r
+ rev xMEMSIZE, xMEMSIZE\r
+ orr xMEMNODE, xMEMNODE, #HAVE_REG\r
+ b inc_and_next_tag\r
\r
check_device_type:\r
- /*\r
- * Check whether the current property's name is 'device_type'\r
- */\r
- adr x4, _device_type\r
- bl strcmp\r
- cbnz w7, inc_and_next_tag\r
- orr xMEMNODE, xMEMNODE, #HAVE_DEVICE_TYPE\r
+ /*\r
+ * Check whether the current property's name is 'device_type'\r
+ */\r
+ adr x4, _device_type\r
+ bl strcmp\r
+ cbnz w7, inc_and_next_tag\r
+ orr xMEMNODE, xMEMNODE, #HAVE_DEVICE_TYPE\r
\r
inc_and_next_tag:\r
- add xDTP, xDTP, x6\r
- b next_tag\r
+ add xDTP, xDTP, x6\r
+ b next_tag\r
\r
end_node:\r
- /*\r
- * Check for device_type = memory and reg = xxxx\r
- * If we have both, we are done\r
- */\r
- add xDTP, xDTP, #4\r
- cmp xMEMNODE, #(HAVE_REG | HAVE_DEVICE_TYPE)\r
- bne next_tag\r
+ /*\r
+ * Check for device_type = memory and reg = xxxx\r
+ * If we have both, we are done\r
+ */\r
+ add xDTP, xDTP, #4\r
+ cmp xMEMNODE, #(HAVE_REG | HAVE_DEVICE_TYPE)\r
+ bne next_tag\r
\r
- ret xLR\r
+ ret xLR\r
\r
err_invalid_magic:\r
err_unexpected_begin_tag:\r
err_unexpected_tag:\r
err_end_of_fdt:\r
- wfi\r
+ wfi\r