From 57d5eaa5fb7d43684af2514aee14c7f2356fa5cb Mon Sep 17 00:00:00 2001 From: Atish Patra <atish.patra@wdc.com> Date: Wed, 9 Jan 2019 00:47:14 -0800 Subject: platform: Rename fdt.c to tinyfdt.c Libfdt already have fdt.c and fdt.h. Rename both fdt.* present in openSBI to tinyfdt.* Signed-off-by: Atish Patra <atish.patra@wdc.com> --- platform/common/fdt.c | 314 --------------------------------- platform/common/include/plat/fdt.h | 73 -------- platform/common/include/plat/tinyfdt.h | 73 ++++++++ platform/common/irqchip/plic.c | 2 +- platform/common/objects.mk | 2 +- platform/common/tinyfdt.c | 314 +++++++++++++++++++++++++++++++++ 6 files changed, 389 insertions(+), 389 deletions(-) delete mode 100644 platform/common/fdt.c delete mode 100644 platform/common/include/plat/fdt.h create mode 100644 platform/common/include/plat/tinyfdt.h create mode 100644 platform/common/tinyfdt.c diff --git a/platform/common/fdt.c b/platform/common/fdt.c deleted file mode 100644 index 4f6017c..0000000 --- a/platform/common/fdt.c +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Copyright (c) 2018 Western Digital Corporation or its affiliates. - * - * Authors: - * Anup Patel <anup.patel@wdc.com> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include <plat/fdt.h> - -#define FDT_MAGIC 0xd00dfeed -#define FDT_VERSION 17 - -struct fdt_header { - u32 magic; - u32 totalsize; - u32 off_dt_struct; - u32 off_dt_strings; - u32 off_mem_rsvmap; - u32 version; - u32 last_comp_version; /* <= 17 */ - u32 boot_cpuid_phys; - u32 size_dt_strings; - u32 size_dt_struct; -} __attribute__((packed)); - -#define FDT_BEGIN_NODE 1 -#define FDT_END_NODE 2 -#define FDT_PROP 3 -#define FDT_NOP 4 -#define FDT_END 9 - -u32 fdt_rev32(u32 v) -{ - return ((v & 0x000000FF) << 24) | - ((v & 0x0000FF00) << 8) | - ((v & 0x00FF0000) >> 8) | - ((v & 0xFF000000) >> 24); -} - -ulong fdt_strlen(const char *str) -{ - ulong ret = 0; - - while (*str != '\0') { - ret++; - str++; - } - - return ret; -} - -int fdt_strcmp(const char *a, const char *b) -{ - /* search first diff or end of string */ - for (; *a == *b && *a != '\0'; a++, b++); - return *a - *b; -} - -int fdt_prop_string_index(const struct fdt_prop *prop, - const char *str) -{ - int i; - ulong l = 0; - const char *p, *end; - - p = prop->value; - end = p + prop->len; - - for (i = 0; p < end; i++, p += l) { - l = fdt_strlen(p) + 1; - if (p + l > end) - return -1; - if (fdt_strcmp(str, p) == 0) - return i; /* Found it; return index */ - } - - return -1; -} - -struct recursive_iter_info { - void (*fn)(const struct fdt_node *node, - const struct fdt_prop *prop, - void *priv); - void *fn_priv; - const char *str; -}; - -#define DATA32(ptr) fdt_rev32(*((u32*)ptr)) - -static void recursive_iter(char **data, struct recursive_iter_info *info, - const struct fdt_node *parent) -{ - struct fdt_node node; - struct fdt_prop prop; - - if (DATA32(*data) != FDT_BEGIN_NODE) - return; - - node.data = *data; - - (*data) += sizeof(u32); - - node.parent = parent; - node.name = *data; - - *data += fdt_strlen(*data) + 1; - while ((ulong)(*data) % sizeof(u32) != 0) - (*data)++; - - node.depth = (parent) ? (parent->depth + 1) : 1; - - /* Default cell counts, as per the FDT spec */ - node.address_cells = 2; - node.size_cells = 1; - - info->fn(&node, NULL, info->fn_priv); - - while (DATA32(*data) != FDT_END_NODE) { - switch (DATA32(*data)) { - case FDT_PROP: - prop.node = &node; - *data += sizeof(u32); - prop.len = DATA32(*data); - *data += sizeof(u32); - prop.name = &info->str[DATA32(*data)]; - *data += sizeof(u32); - prop.value = *data; - *data += prop.len; - while ((ulong)(*data) % sizeof(u32) != 0) - (*data)++; - info->fn(&node, &prop, info->fn_priv); - break; - case FDT_NOP: - *data += sizeof(u32); - break; - case FDT_BEGIN_NODE: - recursive_iter(data, info, &node); - break; - default: - return; - }; - } - - *data += sizeof(u32); -} - -struct match_iter_info { - int (*match)(const struct fdt_node *node, - const struct fdt_prop *prop, - void *priv); - void *match_priv; - void (*fn)(const struct fdt_node *node, - const struct fdt_prop *prop, - void *priv); - void *fn_priv; - const char *str; -}; - -static void match_iter(const struct fdt_node *node, - const struct fdt_prop *prop, - void *priv) -{ - char *data; - struct match_iter_info *minfo = priv; - struct fdt_prop nprop; - - /* Do nothing if node+prop dont match */ - if (!minfo->match(node, prop, minfo->match_priv)) - return; - - /* Call function for node */ - if (minfo->fn) - minfo->fn(node, NULL, minfo->fn_priv); - - /* Convert node to character stream */ - data = node->data; - data += sizeof(u32); - - /* Skip node name */ - data += fdt_strlen(data) + 1; - while ((ulong)(data) % sizeof(u32) != 0) - data++; - - /* Find node property and its value */ - while (DATA32(data) == FDT_PROP) { - nprop.node = node; - data += sizeof(u32); - nprop.len = DATA32(data); - data += sizeof(u32); - nprop.name = &minfo->str[DATA32(data)]; - data += sizeof(u32); - nprop.value = data; - data += nprop.len; - while ((ulong)(data) % sizeof(u32) != 0) - (data)++; - /* Call function for every property */ - if (minfo->fn) - minfo->fn(node, &nprop, minfo->fn_priv); - } -} - -int fdt_match_node_prop(void *fdt, - int (*match)(const struct fdt_node *node, - const struct fdt_prop *prop, - void *priv), - void *match_priv, - void (*fn)(const struct fdt_node *node, - const struct fdt_prop *prop, - void *priv), - void *fn_priv) -{ - char *data; - u32 string_offset, data_offset; - struct fdt_header *header; - struct match_iter_info minfo; - struct recursive_iter_info rinfo; - - if (!fdt || !match) - return -1; - - header = fdt; - if (fdt_rev32(header->magic) != FDT_MAGIC || - fdt_rev32(header->last_comp_version) > FDT_VERSION) - return -1; - string_offset = fdt_rev32(header->off_dt_strings); - data_offset = fdt_rev32(header->off_dt_struct); - - minfo.match = match; - minfo.match_priv = match_priv; - minfo.fn = fn; - minfo.fn_priv = fn_priv; - minfo.str = (const char *)(fdt + string_offset); - - rinfo.fn = match_iter; - rinfo.fn_priv = &minfo; - rinfo.str = minfo.str; - - data = (char *)(fdt + data_offset); - recursive_iter(&data, &rinfo, NULL); - - return 0; -} - -struct match_compat_info { - const char *compat; -}; - -static int match_compat(const struct fdt_node *node, - const struct fdt_prop *prop, - void *priv) -{ - struct match_compat_info *cinfo = priv; - - if (!prop) - return 0; - - if (fdt_strcmp(prop->name, "compatible")) - return 0; - - if (fdt_prop_string_index(prop, cinfo->compat) < 0) - return 0; - - return 1; -} - -int fdt_compat_node_prop(void *fdt, - const char *compat, - void (*fn)(const struct fdt_node *node, - const struct fdt_prop *prop, - void *priv), - void *fn_priv) -{ - struct match_compat_info cinfo = { .compat = compat }; - - return fdt_match_node_prop(fdt, match_compat, &cinfo, - fn, fn_priv); -} - -static int match_walk(const struct fdt_node *node, - const struct fdt_prop *prop, - void *priv) -{ - if (!prop) - return 1; - - return 0; -} - -int fdt_walk(void *fdt, - void (*fn)(const struct fdt_node *node, - const struct fdt_prop *prop, - void *priv), - void *fn_priv) -{ - return fdt_match_node_prop(fdt, match_walk, NULL, - fn, fn_priv); -} - -u32 fdt_size(void *fdt) -{ - struct fdt_header *header; - - if (!fdt) - return 0; - - header = fdt; - if (fdt_rev32(header->magic) != FDT_MAGIC || - fdt_rev32(header->last_comp_version) > FDT_VERSION) - return 0; - - return fdt_rev32(header->totalsize); -} diff --git a/platform/common/include/plat/fdt.h b/platform/common/include/plat/fdt.h deleted file mode 100644 index 246243f..0000000 --- a/platform/common/include/plat/fdt.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2018 Western Digital Corporation or its affiliates. - * - * Authors: - * Anup Patel <anup.patel@wdc.com> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#ifndef __FDT_H__ -#define __FDT_H__ - -#include <sbi/sbi_types.h> - -struct fdt_node { - char *data; - const struct fdt_node *parent; - const char *name; - int depth; - int address_cells; - int size_cells; -}; - -struct fdt_prop { - const struct fdt_node *node; - const char *name; - void *value; - u32 len; -}; - -/* Reverse byte-order of 32bit number */ -u32 fdt_rev32(u32 v); - -/* Length of a string */ -ulong fdt_strlen(const char *str); - -/* Compate two strings */ -int fdt_strcmp(const char *a, const char *b); - -/* Find index of matching string from a list of strings */ -int fdt_prop_string_index(const struct fdt_prop *prop, - const char *str); - -/* Iterate over each property of matching node */ -int fdt_match_node_prop(void *fdt, - int (*match)(const struct fdt_node *node, - const struct fdt_prop *prop, - void *priv), - void *match_priv, - void (*fn)(const struct fdt_node *node, - const struct fdt_prop *prop, - void *priv), - void *fn_priv); - -/* Iterate over each property of compatible node */ -int fdt_compat_node_prop(void *fdt, - const char *compat, - void (*fn)(const struct fdt_node *node, - const struct fdt_prop *prop, - void *priv), - void *fn_priv); - -/* Iterate over each node and property */ -int fdt_walk(void *fdt, - void (*fn)(const struct fdt_node *node, - const struct fdt_prop *prop, - void *priv), - void *fn_priv); - -/* Get size of FDT */ -u32 fdt_size(void *fdt); - -#endif diff --git a/platform/common/include/plat/tinyfdt.h b/platform/common/include/plat/tinyfdt.h new file mode 100644 index 0000000..246243f --- /dev/null +++ b/platform/common/include/plat/tinyfdt.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2018 Western Digital Corporation or its affiliates. + * + * Authors: + * Anup Patel <anup.patel@wdc.com> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef __FDT_H__ +#define __FDT_H__ + +#include <sbi/sbi_types.h> + +struct fdt_node { + char *data; + const struct fdt_node *parent; + const char *name; + int depth; + int address_cells; + int size_cells; +}; + +struct fdt_prop { + const struct fdt_node *node; + const char *name; + void *value; + u32 len; +}; + +/* Reverse byte-order of 32bit number */ +u32 fdt_rev32(u32 v); + +/* Length of a string */ +ulong fdt_strlen(const char *str); + +/* Compate two strings */ +int fdt_strcmp(const char *a, const char *b); + +/* Find index of matching string from a list of strings */ +int fdt_prop_string_index(const struct fdt_prop *prop, + const char *str); + +/* Iterate over each property of matching node */ +int fdt_match_node_prop(void *fdt, + int (*match)(const struct fdt_node *node, + const struct fdt_prop *prop, + void *priv), + void *match_priv, + void (*fn)(const struct fdt_node *node, + const struct fdt_prop *prop, + void *priv), + void *fn_priv); + +/* Iterate over each property of compatible node */ +int fdt_compat_node_prop(void *fdt, + const char *compat, + void (*fn)(const struct fdt_node *node, + const struct fdt_prop *prop, + void *priv), + void *fn_priv); + +/* Iterate over each node and property */ +int fdt_walk(void *fdt, + void (*fn)(const struct fdt_node *node, + const struct fdt_prop *prop, + void *priv), + void *fn_priv); + +/* Get size of FDT */ +u32 fdt_size(void *fdt); + +#endif diff --git a/platform/common/irqchip/plic.c b/platform/common/irqchip/plic.c index 61a6bd0..8a1e08e 100644 --- a/platform/common/irqchip/plic.c +++ b/platform/common/irqchip/plic.c @@ -8,7 +8,7 @@ */ #include <sbi/riscv_io.h> -#include <plat/fdt.h> +#include <plat/tinyfdt.h> #include <plat/irqchip/plic.h> #define PLIC_PRIORITY_BASE 0x0 diff --git a/platform/common/objects.mk b/platform/common/objects.mk index 712e950..b3e06fd 100644 --- a/platform/common/objects.mk +++ b/platform/common/objects.mk @@ -7,4 +7,4 @@ # SPDX-License-Identifier: BSD-2-Clause # -platform-common-objs-y += fdt.o +platform-common-objs-y += tinyfdt.o diff --git a/platform/common/tinyfdt.c b/platform/common/tinyfdt.c new file mode 100644 index 0000000..4f6017c --- /dev/null +++ b/platform/common/tinyfdt.c @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2018 Western Digital Corporation or its affiliates. + * + * Authors: + * Anup Patel <anup.patel@wdc.com> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <plat/fdt.h> + +#define FDT_MAGIC 0xd00dfeed +#define FDT_VERSION 17 + +struct fdt_header { + u32 magic; + u32 totalsize; + u32 off_dt_struct; + u32 off_dt_strings; + u32 off_mem_rsvmap; + u32 version; + u32 last_comp_version; /* <= 17 */ + u32 boot_cpuid_phys; + u32 size_dt_strings; + u32 size_dt_struct; +} __attribute__((packed)); + +#define FDT_BEGIN_NODE 1 +#define FDT_END_NODE 2 +#define FDT_PROP 3 +#define FDT_NOP 4 +#define FDT_END 9 + +u32 fdt_rev32(u32 v) +{ + return ((v & 0x000000FF) << 24) | + ((v & 0x0000FF00) << 8) | + ((v & 0x00FF0000) >> 8) | + ((v & 0xFF000000) >> 24); +} + +ulong fdt_strlen(const char *str) +{ + ulong ret = 0; + + while (*str != '\0') { + ret++; + str++; + } + + return ret; +} + +int fdt_strcmp(const char *a, const char *b) +{ + /* search first diff or end of string */ + for (; *a == *b && *a != '\0'; a++, b++); + return *a - *b; +} + +int fdt_prop_string_index(const struct fdt_prop *prop, + const char *str) +{ + int i; + ulong l = 0; + const char *p, *end; + + p = prop->value; + end = p + prop->len; + + for (i = 0; p < end; i++, p += l) { + l = fdt_strlen(p) + 1; + if (p + l > end) + return -1; + if (fdt_strcmp(str, p) == 0) + return i; /* Found it; return index */ + } + + return -1; +} + +struct recursive_iter_info { + void (*fn)(const struct fdt_node *node, + const struct fdt_prop *prop, + void *priv); + void *fn_priv; + const char *str; +}; + +#define DATA32(ptr) fdt_rev32(*((u32*)ptr)) + +static void recursive_iter(char **data, struct recursive_iter_info *info, + const struct fdt_node *parent) +{ + struct fdt_node node; + struct fdt_prop prop; + + if (DATA32(*data) != FDT_BEGIN_NODE) + return; + + node.data = *data; + + (*data) += sizeof(u32); + + node.parent = parent; + node.name = *data; + + *data += fdt_strlen(*data) + 1; + while ((ulong)(*data) % sizeof(u32) != 0) + (*data)++; + + node.depth = (parent) ? (parent->depth + 1) : 1; + + /* Default cell counts, as per the FDT spec */ + node.address_cells = 2; + node.size_cells = 1; + + info->fn(&node, NULL, info->fn_priv); + + while (DATA32(*data) != FDT_END_NODE) { + switch (DATA32(*data)) { + case FDT_PROP: + prop.node = &node; + *data += sizeof(u32); + prop.len = DATA32(*data); + *data += sizeof(u32); + prop.name = &info->str[DATA32(*data)]; + *data += sizeof(u32); + prop.value = *data; + *data += prop.len; + while ((ulong)(*data) % sizeof(u32) != 0) + (*data)++; + info->fn(&node, &prop, info->fn_priv); + break; + case FDT_NOP: + *data += sizeof(u32); + break; + case FDT_BEGIN_NODE: + recursive_iter(data, info, &node); + break; + default: + return; + }; + } + + *data += sizeof(u32); +} + +struct match_iter_info { + int (*match)(const struct fdt_node *node, + const struct fdt_prop *prop, + void *priv); + void *match_priv; + void (*fn)(const struct fdt_node *node, + const struct fdt_prop *prop, + void *priv); + void *fn_priv; + const char *str; +}; + +static void match_iter(const struct fdt_node *node, + const struct fdt_prop *prop, + void *priv) +{ + char *data; + struct match_iter_info *minfo = priv; + struct fdt_prop nprop; + + /* Do nothing if node+prop dont match */ + if (!minfo->match(node, prop, minfo->match_priv)) + return; + + /* Call function for node */ + if (minfo->fn) + minfo->fn(node, NULL, minfo->fn_priv); + + /* Convert node to character stream */ + data = node->data; + data += sizeof(u32); + + /* Skip node name */ + data += fdt_strlen(data) + 1; + while ((ulong)(data) % sizeof(u32) != 0) + data++; + + /* Find node property and its value */ + while (DATA32(data) == FDT_PROP) { + nprop.node = node; + data += sizeof(u32); + nprop.len = DATA32(data); + data += sizeof(u32); + nprop.name = &minfo->str[DATA32(data)]; + data += sizeof(u32); + nprop.value = data; + data += nprop.len; + while ((ulong)(data) % sizeof(u32) != 0) + (data)++; + /* Call function for every property */ + if (minfo->fn) + minfo->fn(node, &nprop, minfo->fn_priv); + } +} + +int fdt_match_node_prop(void *fdt, + int (*match)(const struct fdt_node *node, + const struct fdt_prop *prop, + void *priv), + void *match_priv, + void (*fn)(const struct fdt_node *node, + const struct fdt_prop *prop, + void *priv), + void *fn_priv) +{ + char *data; + u32 string_offset, data_offset; + struct fdt_header *header; + struct match_iter_info minfo; + struct recursive_iter_info rinfo; + + if (!fdt || !match) + return -1; + + header = fdt; + if (fdt_rev32(header->magic) != FDT_MAGIC || + fdt_rev32(header->last_comp_version) > FDT_VERSION) + return -1; + string_offset = fdt_rev32(header->off_dt_strings); + data_offset = fdt_rev32(header->off_dt_struct); + + minfo.match = match; + minfo.match_priv = match_priv; + minfo.fn = fn; + minfo.fn_priv = fn_priv; + minfo.str = (const char *)(fdt + string_offset); + + rinfo.fn = match_iter; + rinfo.fn_priv = &minfo; + rinfo.str = minfo.str; + + data = (char *)(fdt + data_offset); + recursive_iter(&data, &rinfo, NULL); + + return 0; +} + +struct match_compat_info { + const char *compat; +}; + +static int match_compat(const struct fdt_node *node, + const struct fdt_prop *prop, + void *priv) +{ + struct match_compat_info *cinfo = priv; + + if (!prop) + return 0; + + if (fdt_strcmp(prop->name, "compatible")) + return 0; + + if (fdt_prop_string_index(prop, cinfo->compat) < 0) + return 0; + + return 1; +} + +int fdt_compat_node_prop(void *fdt, + const char *compat, + void (*fn)(const struct fdt_node *node, + const struct fdt_prop *prop, + void *priv), + void *fn_priv) +{ + struct match_compat_info cinfo = { .compat = compat }; + + return fdt_match_node_prop(fdt, match_compat, &cinfo, + fn, fn_priv); +} + +static int match_walk(const struct fdt_node *node, + const struct fdt_prop *prop, + void *priv) +{ + if (!prop) + return 1; + + return 0; +} + +int fdt_walk(void *fdt, + void (*fn)(const struct fdt_node *node, + const struct fdt_prop *prop, + void *priv), + void *fn_priv) +{ + return fdt_match_node_prop(fdt, match_walk, NULL, + fn, fn_priv); +} + +u32 fdt_size(void *fdt) +{ + struct fdt_header *header; + + if (!fdt) + return 0; + + header = fdt; + if (fdt_rev32(header->magic) != FDT_MAGIC || + fdt_rev32(header->last_comp_version) > FDT_VERSION) + return 0; + + return fdt_rev32(header->totalsize); +} -- cgit v1.2.3