Message ID | 20230801161409.25905-3-dpsmith@apertussolutions.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Rebranding dom0less to hyperlaunch part 1 | expand |
Hi Daniel, > -----Original Message----- > Subject: [PATCH 2/2] fdt: make fdt handling reusable across arch > > This refactors reusable code from Arm's bootfdt.c and device-tree.h that is > general fdt handling code. The Kconfig parameter CORE_DEVICE_TREE is > introduced for when the ability of parsing DTB files is needed by a capability > such as hyperlaunch. > > Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com> > --- > MAINTAINERS | 2 + > xen/arch/arm/bootfdt.c | 141 +------------------------------ > xen/common/Kconfig | 4 + > xen/common/Makefile | 3 +- > xen/common/fdt.c | 153 ++++++++++++++++++++++++++++++++++ > xen/include/xen/device_tree.h | 50 +---------- > xen/include/xen/fdt.h | 79 ++++++++++++++++++ > 7 files changed, 242 insertions(+), 190 deletions(-) > create mode 100644 xen/common/fdt.c > create mode 100644 xen/include/xen/fdt.h > > +void __init device_tree_get_reg( > + const __be32 **cell, uint32_t address_cells, uint32_t size_cells, > + paddr_t *start, paddr_t *size) > +{ > + uint64_t dt_start, dt_size; > + > + /* > + * dt_next_cell will return uint64_t whereas paddr_t may not be 64-bit. > + * Thus, there is an implicit cast from uint64_t to paddr_t. > + */ > + dt_start = dt_next_cell(address_cells, cell); > + dt_size = dt_next_cell(size_cells, cell); > + > + if ( dt_start != (paddr_t)dt_start ) > + { > + printk("Physical address greater than max width supported\n"); > + WARN(); > + } > + > + if ( dt_size != (paddr_t)dt_size ) > + { > + printk("Physical size greater than max width supported\n"); > + WARN(); > + } > + > + /* > + * Xen will truncate the address/size if it is greater than the maximum > + * supported width and it will give an appropriate warning. > + */ > + *start = dt_start; > + *size = dt_size; > +} > + > +u32 __init device_tree_get_u32( > + const void *fdt, int node, const char *prop_name, u32 dflt) > +{ > + const struct fdt_property *prop; > + > + prop = fdt_get_property(fdt, node, prop_name, NULL); > + if ( !prop || prop->len < sizeof(u32) ) > + return dflt; > + > + return fdt32_to_cpu(*(uint32_t*)prop->data); > +} When I tested this patch by our internal CI (I applied this patch on top of today's staging: c2026b88b5 xen/arm/IRQ: uniform irq_set_affinity() with x86 version), there are some build errors as below: aarch64-linux-gnu-gcc -MMD -MP -MF ./.asm-offsets.s.d -DBUILD_ID -fno-strict-aliasing -std=gnu99 -Wall -Wstrict-prototypes -Wdeclaration-after-statement -Wno-unused-but-set-variable -Wno-unused-local-typedefs -O2 -fomit-frame-pointer -nostdinc -fno-builtin -fno-common -Werror -Wredundant-decls -Wno-pointer-arith -Wvla -pipe -D__XEN__ -include /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/config.h -mcpu=generic -mgeneral-regs-only -mno-outline-atomics -I./include -I./arch/arm/include -I/jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include -I/jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/include -fno-pie -fno-stack-protector -fno-exceptions -fno-asynchronous-unwind-tables -Wnested-externs -S -g0 -o asm-offsets.s.new -MQ asm-offsets.s /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/arm64/asm-offsets.c In file included from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/arm64/asm-offsets.c:13: /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/include/asm/setup.h:162:6: error: redundant redeclaration of 'device_tree_get_reg' [-Werror=redundant-decls] 162 | void device_tree_get_reg(const __be32 **cell, uint32_t address_cells, | ^~~~~~~~~~~~~~~~~~~ In file included from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/device_tree.h:17, from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/include/asm/smp.h:6, from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/smp.h:4, from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/rwlock.h:6, from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/sched.h:7, from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/arm64/asm-offsets.c:9: /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/fdt.h:64:13: note: previous declaration of 'device_tree_get_reg' with type 'void(const __be32 **, u32, u32, u64 *, u64 *)' {aka 'void(const unsigned int **, unsigned int, unsigned int, long unsigned int *, long unsigned int *)'} 64 | void __init device_tree_get_reg( | ^~~~~~~~~~~~~~~~~~~ In file included from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/arm64/asm-offsets.c:13: /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/include/asm/setup.h:165:5: error: redundant redeclaration of 'device_tree_get_u32' [-Werror=redundant-decls] 165 | u32 device_tree_get_u32(const void *fdt, int node, | ^~~~~~~~~~~~~~~~~~~ In file included from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/device_tree.h:17, from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/include/asm/smp.h:6, from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/smp.h:4, from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/rwlock.h:6, from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/sched.h:7, from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/arm64/asm-offsets.c:9: /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/fdt.h:68:12: note: previous declaration of 'device_tree_get_u32' with type 'u32(const void *, int, const char *, u32)' {aka 'unsigned int(const void *, int, const char *, unsigned int)'} 68 | u32 __init device_tree_get_u32( | ^~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors make[2]: *** [/jenkins/workspace/ais-xenbits-xen/layers/xen/xen/./build.mk:45: asm-offsets.s] Error 1 make[1]: *** [/jenkins/workspace/ais-xenbits-xen/layers/xen/xen/Makefile:597: xen] Error 2 make[1]: Leaving directory '/jenkins/workspace/ais-xenbits-xen/build/xen-fvp-base' make: *** [Makefile:183: __sub-make] Error 2 make: Leaving directory '/jenkins/workspace/ais-xenbits-xen/layers/xen/xen' The staging itself passed the CI check. Did I miss some context to make this patch works? Could you please provide some hints? Thanks in advance! Kind regards, Henry
On 01.08.2023 18:14, Daniel P. Smith wrote: > This refactors reusable code from Arm's bootfdt.c and device-tree.h that is > general fdt handling code. The Kconfig parameter CORE_DEVICE_TREE is > introduced for when the ability of parsing DTB files is needed by a capability > such as hyperlaunch. > > Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com> > --- > MAINTAINERS | 2 + > xen/arch/arm/bootfdt.c | 141 +------------------------------ > xen/common/Kconfig | 4 + > xen/common/Makefile | 3 +- > xen/common/fdt.c | 153 ++++++++++++++++++++++++++++++++++ > xen/include/xen/device_tree.h | 50 +---------- > xen/include/xen/fdt.h | 79 ++++++++++++++++++ > 7 files changed, 242 insertions(+), 190 deletions(-) > create mode 100644 xen/common/fdt.c > create mode 100644 xen/include/xen/fdt.h The filename here ... > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -303,7 +303,9 @@ F: xen/common/libfdt/ > F: xen/common/device_tree.c > F: xen/include/xen/libfdt/ > F: xen/include/xen/device_tree.h > +F: include/xen/fdt.h > F: xen/drivers/passthrough/device_tree.c > +F: common/fdt.c ... don't match the additions here. Also please insert in alphabetically sorted order, ignoring the previously misplaced final entry (entries), unless you want to take the opportunity and get things properly sorted again in this section. Jan
On 8/2/23 02:13, Henry Wang wrote: > Hi Daniel, Hey Henry! >> -----Original Message----- >> Subject: [PATCH 2/2] fdt: make fdt handling reusable across arch >> >> This refactors reusable code from Arm's bootfdt.c and device-tree.h that is >> general fdt handling code. The Kconfig parameter CORE_DEVICE_TREE is >> introduced for when the ability of parsing DTB files is needed by a capability >> such as hyperlaunch. >> >> Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com> >> --- >> MAINTAINERS | 2 + >> xen/arch/arm/bootfdt.c | 141 +------------------------------ >> xen/common/Kconfig | 4 + >> xen/common/Makefile | 3 +- >> xen/common/fdt.c | 153 ++++++++++++++++++++++++++++++++++ >> xen/include/xen/device_tree.h | 50 +---------- >> xen/include/xen/fdt.h | 79 ++++++++++++++++++ >> 7 files changed, 242 insertions(+), 190 deletions(-) >> create mode 100644 xen/common/fdt.c >> create mode 100644 xen/include/xen/fdt.h >> >> +void __init device_tree_get_reg( >> + const __be32 **cell, uint32_t address_cells, uint32_t size_cells, >> + paddr_t *start, paddr_t *size) >> +{ >> + uint64_t dt_start, dt_size; >> + >> + /* >> + * dt_next_cell will return uint64_t whereas paddr_t may not be 64-bit. >> + * Thus, there is an implicit cast from uint64_t to paddr_t. >> + */ >> + dt_start = dt_next_cell(address_cells, cell); >> + dt_size = dt_next_cell(size_cells, cell); >> + >> + if ( dt_start != (paddr_t)dt_start ) >> + { >> + printk("Physical address greater than max width supported\n"); >> + WARN(); >> + } >> + >> + if ( dt_size != (paddr_t)dt_size ) >> + { >> + printk("Physical size greater than max width supported\n"); >> + WARN(); >> + } >> + >> + /* >> + * Xen will truncate the address/size if it is greater than the maximum >> + * supported width and it will give an appropriate warning. >> + */ >> + *start = dt_start; >> + *size = dt_size; >> +} >> + >> +u32 __init device_tree_get_u32( >> + const void *fdt, int node, const char *prop_name, u32 dflt) >> +{ >> + const struct fdt_property *prop; >> + >> + prop = fdt_get_property(fdt, node, prop_name, NULL); >> + if ( !prop || prop->len < sizeof(u32) ) >> + return dflt; >> + >> + return fdt32_to_cpu(*(uint32_t*)prop->data); >> +} > > When I tested this patch by our internal CI (I applied this patch on top > of today's staging: > c2026b88b5 xen/arm/IRQ: uniform irq_set_affinity() with x86 version), > there are some build errors as below: > > aarch64-linux-gnu-gcc -MMD -MP -MF ./.asm-offsets.s.d -DBUILD_ID -fno-strict-aliasing -std=gnu99 -Wall -Wstrict-prototypes -Wdeclaration-after-statement -Wno-unused-but-set-variable -Wno-unused-local-typedefs -O2 -fomit-frame-pointer -nostdinc -fno-builtin -fno-common -Werror -Wredundant-decls -Wno-pointer-arith -Wvla -pipe -D__XEN__ -include /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/config.h -mcpu=generic -mgeneral-regs-only -mno-outline-atomics -I./include -I./arch/arm/include -I/jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include -I/jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/include -fno-pie -fno-stack-protector -fno-exceptions -fno-asynchronous-unwind-tables -Wnested-externs -S -g0 -o asm-offsets.s.new -MQ asm-offsets.s /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/arm64/asm-offsets.c > In file included from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/arm64/asm-offsets.c:13: > /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/include/asm/setup.h:162:6: error: redundant redeclaration of 'device_tree_get_reg' [-Werror=redundant-decls] > 162 | void device_tree_get_reg(const __be32 **cell, uint32_t address_cells, > | ^~~~~~~~~~~~~~~~~~~ > In file included from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/device_tree.h:17, > from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/include/asm/smp.h:6, > from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/smp.h:4, > from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/rwlock.h:6, > from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/sched.h:7, > from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/arm64/asm-offsets.c:9: > /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/fdt.h:64:13: note: previous declaration of 'device_tree_get_reg' with type 'void(const __be32 **, u32, u32, u64 *, u64 *)' {aka 'void(const unsigned int **, unsigned int, unsigned int, long unsigned int *, long unsigned int *)'} > 64 | void __init device_tree_get_reg( > | ^~~~~~~~~~~~~~~~~~~ > In file included from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/arm64/asm-offsets.c:13: > /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/include/asm/setup.h:165:5: error: redundant redeclaration of 'device_tree_get_u32' [-Werror=redundant-decls] > 165 | u32 device_tree_get_u32(const void *fdt, int node, > | ^~~~~~~~~~~~~~~~~~~ > In file included from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/device_tree.h:17, > from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/include/asm/smp.h:6, > from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/smp.h:4, > from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/rwlock.h:6, > from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/sched.h:7, > from /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/arch/arm/arm64/asm-offsets.c:9: > /jenkins/workspace/ais-xenbits-xen/layers/xen/xen/include/xen/fdt.h:68:12: note: previous declaration of 'device_tree_get_u32' with type 'u32(const void *, int, const char *, u32)' {aka 'unsigned int(const void *, int, const char *, unsigned int)'} > 68 | u32 __init device_tree_get_u32( > | ^~~~~~~~~~~~~~~~~~~ > cc1: all warnings being treated as errors > make[2]: *** [/jenkins/workspace/ais-xenbits-xen/layers/xen/xen/./build.mk:45: asm-offsets.s] Error 1 > make[1]: *** [/jenkins/workspace/ais-xenbits-xen/layers/xen/xen/Makefile:597: xen] Error 2 > make[1]: Leaving directory '/jenkins/workspace/ais-xenbits-xen/build/xen-fvp-base' > make: *** [Makefile:183: __sub-make] Error 2 > make: Leaving directory '/jenkins/workspace/ais-xenbits-xen/layers/xen/xen' > > The staging itself passed the CI check. Did I miss some context to make > this patch works? Could you please provide some hints? Thanks in advance! Nope you are correct, I now need to go back and look if I sent patches out of the wrong branch or if I really did miss cleaning up the original declarations in the Arm tree. I fairly confident I made sure gitlab-ci passed before I cut the patches for sending, but since I had three different series in flight, I may have gotten jumbled. Apologies for the unnecessary churn here. V/r, Daniel P. Smith
On 8/2/23 03:27, Jan Beulich wrote: > On 01.08.2023 18:14, Daniel P. Smith wrote: >> This refactors reusable code from Arm's bootfdt.c and device-tree.h that is >> general fdt handling code. The Kconfig parameter CORE_DEVICE_TREE is >> introduced for when the ability of parsing DTB files is needed by a capability >> such as hyperlaunch. >> >> Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com> >> --- >> MAINTAINERS | 2 + >> xen/arch/arm/bootfdt.c | 141 +------------------------------ >> xen/common/Kconfig | 4 + >> xen/common/Makefile | 3 +- >> xen/common/fdt.c | 153 ++++++++++++++++++++++++++++++++++ >> xen/include/xen/device_tree.h | 50 +---------- >> xen/include/xen/fdt.h | 79 ++++++++++++++++++ >> 7 files changed, 242 insertions(+), 190 deletions(-) >> create mode 100644 xen/common/fdt.c >> create mode 100644 xen/include/xen/fdt.h > > The filename here ... > >> --- a/MAINTAINERS >> +++ b/MAINTAINERS >> @@ -303,7 +303,9 @@ F: xen/common/libfdt/ >> F: xen/common/device_tree.c >> F: xen/include/xen/libfdt/ >> F: xen/include/xen/device_tree.h >> +F: include/xen/fdt.h >> F: xen/drivers/passthrough/device_tree.c >> +F: common/fdt.c > > ... don't match the additions here. Also please insert in alphabetically > sorted order, ignoring the previously misplaced final entry (entries), > unless you want to take the opportunity and get things properly sorted > again in this section. Ack, will fix along with ensuring they are properly sorted. v/r, dps
Hi Daniel, > -----Original Message----- > Subject: Re: [PATCH 2/2] fdt: make fdt handling reusable across arch > > make: *** [Makefile:183: __sub-make] Error 2 > > make: Leaving directory '/jenkins/workspace/ais-xenbits- > xen/layers/xen/xen' > > > > The staging itself passed the CI check. Did I miss some context to make > > this patch works? Could you please provide some hints? Thanks in advance! > > Nope you are correct, I now need to go back and look if I sent patches > out of the wrong branch or if I really did miss cleaning up the original > declarations in the Arm tree. I fairly confident I made sure gitlab-ci > passed before I cut the patches for sending, I think so, as I saw something related to the Gitlab-CI runners discussion in IRC yesterday. > but since I had three > different series in flight, I may have gotten jumbled. Apologies for the > unnecessary churn here. No problem at all, I am more than happy to do the test for your v2 series once it is in the mailing list :)) Kind regards, Henry > > V/r, > Daniel P. Smith
On 8/2/23 21:40, Henry Wang wrote: > Hi Daniel, > >> -----Original Message----- >> Subject: Re: [PATCH 2/2] fdt: make fdt handling reusable across arch >>> make: *** [Makefile:183: __sub-make] Error 2 >>> make: Leaving directory '/jenkins/workspace/ais-xenbits- >> xen/layers/xen/xen' >>> >>> The staging itself passed the CI check. Did I miss some context to make >>> this patch works? Could you please provide some hints? Thanks in advance! >> >> Nope you are correct, I now need to go back and look if I sent patches >> out of the wrong branch or if I really did miss cleaning up the original >> declarations in the Arm tree. I fairly confident I made sure gitlab-ci >> passed before I cut the patches for sending, > > I think so, as I saw something related to the Gitlab-CI runners discussion > in IRC yesterday. > >> but since I had three >> different series in flight, I may have gotten jumbled. Apologies for the >> unnecessary churn here. > > No problem at all, I am more than happy to do the test for your > v2 series once it is in the mailing list :)) Great! Thank you! v/r, dps
diff --git a/MAINTAINERS b/MAINTAINERS index 694412a961..b7fc3ed805 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -303,7 +303,9 @@ F: xen/common/libfdt/ F: xen/common/device_tree.c F: xen/include/xen/libfdt/ F: xen/include/xen/device_tree.h +F: include/xen/fdt.h F: xen/drivers/passthrough/device_tree.c +F: common/fdt.c ECLAIR R: Simone Ballarin <simone.ballarin@bugseng.com> diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c index 2673ad17a1..cdf4f17789 100644 --- a/xen/arch/arm/bootfdt.c +++ b/xen/arch/arm/bootfdt.c @@ -12,79 +12,11 @@ #include <xen/device_tree.h> #include <xen/lib.h> #include <xen/libfdt/libfdt-xen.h> +#include <xen/fdt.h> #include <xen/sort.h> #include <xsm/xsm.h> #include <asm/setup.h> -static bool __init device_tree_node_matches(const void *fdt, int node, - const char *match) -{ - const char *name; - size_t match_len; - - name = fdt_get_name(fdt, node, NULL); - match_len = strlen(match); - - /* Match both "match" and "match@..." patterns but not - "match-foo". */ - return strncmp(name, match, match_len) == 0 - && (name[match_len] == '@' || name[match_len] == '\0'); -} - -static bool __init device_tree_node_compatible(const void *fdt, int node, - const char *match) -{ - int len, l; - const void *prop; - - prop = fdt_getprop(fdt, node, "compatible", &len); - if ( prop == NULL ) - return false; - - while ( len > 0 ) { - if ( !dt_compat_cmp(prop, match) ) - return true; - l = strlen(prop) + 1; - prop += l; - len -= l; - } - - return false; -} - -void __init device_tree_get_reg(const __be32 **cell, uint32_t address_cells, - uint32_t size_cells, paddr_t *start, - paddr_t *size) -{ - uint64_t dt_start, dt_size; - - /* - * dt_next_cell will return uint64_t whereas paddr_t may not be 64-bit. - * Thus, there is an implicit cast from uint64_t to paddr_t. - */ - dt_start = dt_next_cell(address_cells, cell); - dt_size = dt_next_cell(size_cells, cell); - - if ( dt_start != (paddr_t)dt_start ) - { - printk("Physical address greater than max width supported\n"); - WARN(); - } - - if ( dt_size != (paddr_t)dt_size ) - { - printk("Physical size greater than max width supported\n"); - WARN(); - } - - /* - * Xen will truncate the address/size if it is greater than the maximum - * supported width and it will give an appropriate warning. - */ - *start = dt_start; - *size = dt_size; -} - static int __init device_tree_get_meminfo(const void *fdt, int node, const char *prop_name, u32 address_cells, u32 size_cells, @@ -135,77 +67,6 @@ static int __init device_tree_get_meminfo(const void *fdt, int node, return 0; } -u32 __init device_tree_get_u32(const void *fdt, int node, - const char *prop_name, u32 dflt) -{ - const struct fdt_property *prop; - - prop = fdt_get_property(fdt, node, prop_name, NULL); - if ( !prop || prop->len < sizeof(u32) ) - return dflt; - - return fdt32_to_cpu(*(uint32_t*)prop->data); -} - -/** - * device_tree_for_each_node - iterate over all device tree sub-nodes - * @fdt: flat device tree. - * @node: parent node to start the search from - * @func: function to call for each sub-node. - * @data: data to pass to @func. - * - * Any nodes nested at DEVICE_TREE_MAX_DEPTH or deeper are ignored. - * - * Returns 0 if all nodes were iterated over successfully. If @func - * returns a value different from 0, that value is returned immediately. - */ -int __init device_tree_for_each_node(const void *fdt, int node, - device_tree_node_func func, - void *data) -{ - /* - * We only care about relative depth increments, assume depth of - * node is 0 for simplicity. - */ - int depth = 0; - const int first_node = node; - u32 address_cells[DEVICE_TREE_MAX_DEPTH]; - u32 size_cells[DEVICE_TREE_MAX_DEPTH]; - int ret; - - do { - const char *name = fdt_get_name(fdt, node, NULL); - u32 as, ss; - - if ( depth >= DEVICE_TREE_MAX_DEPTH ) - { - printk("Warning: device tree node `%s' is nested too deep\n", - name); - continue; - } - - as = depth > 0 ? address_cells[depth-1] : DT_ROOT_NODE_ADDR_CELLS_DEFAULT; - ss = depth > 0 ? size_cells[depth-1] : DT_ROOT_NODE_SIZE_CELLS_DEFAULT; - - address_cells[depth] = device_tree_get_u32(fdt, node, - "#address-cells", as); - size_cells[depth] = device_tree_get_u32(fdt, node, - "#size-cells", ss); - - /* skip the first node */ - if ( node != first_node ) - { - ret = func(fdt, node, name, depth, as, ss, data); - if ( ret != 0 ) - return ret; - } - - node = fdt_next_node(fdt, node, &depth); - } while ( node >= 0 && depth > 0 ); - - return 0; -} - static int __init process_memory_node(const void *fdt, int node, const char *name, int depth, u32 address_cells, u32 size_cells, diff --git a/xen/common/Kconfig b/xen/common/Kconfig index 0d248ab941..e2fdb3cbc3 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -38,8 +38,12 @@ config HAS_ALTERNATIVE config HAS_COMPAT bool +config CORE_DEVICE_TREE + bool + config HAS_DEVICE_TREE bool + select CORE_DEVICE_TREE config HAS_EX_TABLE bool diff --git a/xen/common/Makefile b/xen/common/Makefile index 46049eac35..fd3769e1c6 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -11,6 +11,7 @@ obj-y += domain.o obj-y += event_2l.o obj-y += event_channel.o obj-y += event_fifo.o +obj-$(CONFIG_CORE_DEVICE_TREE) += fdt.o obj-$(CONFIG_CRASH_DEBUG) += gdbstub.o obj-$(CONFIG_GRANT_TABLE) += grant_table.o obj-y += guestcopy.o @@ -75,7 +76,7 @@ obj-y += sched/ obj-$(CONFIG_UBSAN) += ubsan/ obj-$(CONFIG_NEEDS_LIBELF) += libelf/ -obj-$(CONFIG_HAS_DEVICE_TREE) += libfdt/ +obj-$(CONFIG_CORE_DEVICE_TREE) += libfdt/ CONF_FILE := $(if $(patsubst /%,,$(KCONFIG_CONFIG)),$(objtree)/)$(KCONFIG_CONFIG) $(obj)/config.gz: $(CONF_FILE) diff --git a/xen/common/fdt.c b/xen/common/fdt.c new file mode 100644 index 0000000000..8d7acaaa43 --- /dev/null +++ b/xen/common/fdt.c @@ -0,0 +1,153 @@ +/* + * Flattened Device Tree + * + * Copyright (C) 2012-2014 Citrix Systems, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <xen/fdt.h> +#include <xen/init.h> +#include <xen/lib.h> +#include <xen/libfdt/libfdt.h> +#include <xen/types.h> + +bool __init device_tree_node_matches( + const void *fdt, int node, const char *match) +{ + const char *name; + size_t match_len; + + name = fdt_get_name(fdt, node, NULL); + match_len = strlen(match); + + /* Match both "match" and "match@..." patterns but not + "match-foo". */ + return strncmp(name, match, match_len) == 0 + && (name[match_len] == '@' || name[match_len] == '\0'); +} + +bool __init device_tree_node_compatible( + const void *fdt, int node, const char *match) +{ + int len, l; + const void *prop; + + prop = fdt_getprop(fdt, node, "compatible", &len); + if ( prop == NULL ) + return false; + + while ( len > 0 ) { + if ( !dt_compat_cmp(prop, match) ) + return true; + l = strlen(prop) + 1; + prop += l; + len -= l; + } + + return false; +} + +void __init device_tree_get_reg( + const __be32 **cell, uint32_t address_cells, uint32_t size_cells, + paddr_t *start, paddr_t *size) +{ + uint64_t dt_start, dt_size; + + /* + * dt_next_cell will return uint64_t whereas paddr_t may not be 64-bit. + * Thus, there is an implicit cast from uint64_t to paddr_t. + */ + dt_start = dt_next_cell(address_cells, cell); + dt_size = dt_next_cell(size_cells, cell); + + if ( dt_start != (paddr_t)dt_start ) + { + printk("Physical address greater than max width supported\n"); + WARN(); + } + + if ( dt_size != (paddr_t)dt_size ) + { + printk("Physical size greater than max width supported\n"); + WARN(); + } + + /* + * Xen will truncate the address/size if it is greater than the maximum + * supported width and it will give an appropriate warning. + */ + *start = dt_start; + *size = dt_size; +} + +u32 __init device_tree_get_u32( + const void *fdt, int node, const char *prop_name, u32 dflt) +{ + const struct fdt_property *prop; + + prop = fdt_get_property(fdt, node, prop_name, NULL); + if ( !prop || prop->len < sizeof(u32) ) + return dflt; + + return fdt32_to_cpu(*(uint32_t*)prop->data); +} + +/** + * device_tree_for_each_node - iterate over all device tree sub-nodes + * @fdt: flat device tree. + * @node: parent node to start the search from + * @func: function to call for each sub-node. + * @data: data to pass to @func. + * + * Any nodes nested at DEVICE_TREE_MAX_DEPTH or deeper are ignored. + * + * Returns 0 if all nodes were iterated over successfully. If @func + * returns a value different from 0, that value is returned immediately. + */ +int __init device_tree_for_each_node( + const void *fdt, int node, device_tree_node_func func, void *data) +{ + /* + * We only care about relative depth increments, assume depth of + * node is 0 for simplicity. + */ + int depth = 0; + const int first_node = node; + u32 address_cells[DEVICE_TREE_MAX_DEPTH]; + u32 size_cells[DEVICE_TREE_MAX_DEPTH]; + int ret; + + do { + const char *name = fdt_get_name(fdt, node, NULL); + u32 as, ss; + + if ( depth >= DEVICE_TREE_MAX_DEPTH ) + { + printk("Warning: device tree node `%s' is nested too deep\n", + name); + continue; + } + + as = depth > 0 ? address_cells[depth-1] : DT_ROOT_NODE_ADDR_CELLS_DEFAULT; + ss = depth > 0 ? size_cells[depth-1] : DT_ROOT_NODE_SIZE_CELLS_DEFAULT; + + address_cells[depth] = device_tree_get_u32(fdt, node, + "#address-cells", as); + size_cells[depth] = device_tree_get_u32(fdt, node, + "#size-cells", ss); + + /* skip the first node */ + if ( node != first_node ) + { + ret = func(fdt, node, name, depth, as, ss, data); + if ( ret != 0 ) + return ret; + } + + node = fdt_next_node(fdt, node, &depth); + } while ( node >= 0 && depth > 0 ); + + return 0; +} diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h index c2eada7489..f59aa54423 100644 --- a/xen/include/xen/device_tree.h +++ b/xen/include/xen/device_tree.h @@ -14,13 +14,12 @@ #include <asm/device.h> #include <public/xen.h> #include <public/device_tree_defs.h> +#include <xen/fdt.h> #include <xen/kernel.h> #include <xen/string.h> #include <xen/types.h> #include <xen/list.h> -#define DEVICE_TREE_MAX_DEPTH 16 - /* * Struct used for matching a device */ @@ -159,17 +158,8 @@ struct dt_raw_irq { u32 specifier[DT_MAX_IRQ_SPEC]; }; -typedef int (*device_tree_node_func)(const void *fdt, - int node, const char *name, int depth, - u32 address_cells, u32 size_cells, - void *data); - extern const void *device_tree_flattened; -int device_tree_for_each_node(const void *fdt, int node, - device_tree_node_func func, - void *data); - /** * dt_unflatten_host_device_tree - Unflatten the host device tree * @@ -214,14 +204,6 @@ extern const struct dt_device_node *dt_interrupt_controller; struct dt_device_node * dt_find_interrupt_controller(const struct dt_device_match *matches); -#define dt_prop_cmp(s1, s2) strcmp((s1), (s2)) -#define dt_node_cmp(s1, s2) strcasecmp((s1), (s2)) -#define dt_compat_cmp(s1, s2) strcasecmp((s1), (s2)) - -/* Default #address and #size cells */ -#define DT_ROOT_NODE_ADDR_CELLS_DEFAULT 2 -#define DT_ROOT_NODE_SIZE_CELLS_DEFAULT 1 - #define dt_for_each_property_node(dn, pp) \ for ( pp = (dn)->properties; (pp) != NULL; pp = (pp)->next ) @@ -231,16 +213,6 @@ dt_find_interrupt_controller(const struct dt_device_match *matches); #define dt_for_each_child_node(dt, dn) \ for ( dn = (dt)->child; (dn) != NULL; dn = (dn)->sibling ) -/* Helper to read a big number; size is in cells (not bytes) */ -static inline u64 dt_read_number(const __be32 *cell, int size) -{ - u64 r = 0; - - while ( size-- ) - r = (r << 32) | be32_to_cpu(*(cell++)); - return r; -} - /* Wrapper for dt_read_number() to return paddr_t (instead of uint64_t) */ static inline paddr_t dt_read_paddr(const __be32 *cell, int size) { @@ -268,26 +240,6 @@ static inline paddr_t dt_read_paddr(const __be32 *cell, int size) return r; } -/* Helper to convert a number of cells to bytes */ -static inline int dt_cells_to_size(int size) -{ - return (size * sizeof (u32)); -} - -/* Helper to convert a number of bytes to cells, rounds down */ -static inline int dt_size_to_cells(int bytes) -{ - return (bytes / sizeof(u32)); -} - -static inline u64 dt_next_cell(int s, const __be32 **cellp) -{ - const __be32 *p = *cellp; - - *cellp = p + s; - return dt_read_number(p, s); -} - static inline const char *dt_node_full_name(const struct dt_device_node *np) { return (np && np->full_name) ? np->full_name : "<no-node>"; diff --git a/xen/include/xen/fdt.h b/xen/include/xen/fdt.h new file mode 100644 index 0000000000..00f9f3792f --- /dev/null +++ b/xen/include/xen/fdt.h @@ -0,0 +1,79 @@ +/* + * Flattened Device Tree + * + * Copyright (C) 2012 Citrix Systems, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __XEN_FDT_H__ +#define __XEN_FDT_H__ + +#include <xen/init.h> +#include <xen/libfdt/libfdt.h> +#include <xen/types.h> + +#define DEVICE_TREE_MAX_DEPTH 16 + +/* Default #address and #size cells */ +#define DT_ROOT_NODE_ADDR_CELLS_DEFAULT 2 +#define DT_ROOT_NODE_SIZE_CELLS_DEFAULT 1 + +#define dt_prop_cmp(s1, s2) strcmp((s1), (s2)) +#define dt_node_cmp(s1, s2) strcasecmp((s1), (s2)) +#define dt_compat_cmp(s1, s2) strcasecmp((s1), (s2)) + +/* Helper to read a big number; size is in cells (not bytes) */ +static inline u64 dt_read_number(const __be32 *cell, int size) +{ + u64 r = 0; + + while ( size-- ) + r = (r << 32) | be32_to_cpu(*(cell++)); + return r; +} + +/* Helper to convert a number of cells to bytes */ +static inline int dt_cells_to_size(int size) +{ + return (size * sizeof (u32)); +} + +/* Helper to convert a number of bytes to cells, rounds down */ +static inline int dt_size_to_cells(int bytes) +{ + return (bytes / sizeof(u32)); +} + +static inline u64 dt_next_cell(int s, const __be32 **cellp) +{ + const __be32 *p = *cellp; + + *cellp = p + s; + return dt_read_number(p, s); +} + + +bool __init device_tree_node_matches( + const void *fdt, int node, const char *match); + +bool __init device_tree_node_compatible( + const void *fdt, int node, const char *match); + +void __init device_tree_get_reg( + const __be32 **cell, u32 address_cells, u32 size_cells, u64 *start, + u64 *size); + +u32 __init device_tree_get_u32( + const void *fdt, int node, const char *prop_name, u32 dflt); + +typedef int (*device_tree_node_func)( + const void *fdt, int node, const char *name, int depth, u32 address_cells, + u32 size_cells, void *data); + +int device_tree_for_each_node( + const void *fdt, int node, device_tree_node_func func, void *data); + + +#endif /* __XEN_FDT_H__ */
This refactors reusable code from Arm's bootfdt.c and device-tree.h that is general fdt handling code. The Kconfig parameter CORE_DEVICE_TREE is introduced for when the ability of parsing DTB files is needed by a capability such as hyperlaunch. Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com> --- MAINTAINERS | 2 + xen/arch/arm/bootfdt.c | 141 +------------------------------ xen/common/Kconfig | 4 + xen/common/Makefile | 3 +- xen/common/fdt.c | 153 ++++++++++++++++++++++++++++++++++ xen/include/xen/device_tree.h | 50 +---------- xen/include/xen/fdt.h | 79 ++++++++++++++++++ 7 files changed, 242 insertions(+), 190 deletions(-) create mode 100644 xen/common/fdt.c create mode 100644 xen/include/xen/fdt.h