Revert "fdt: translate address if #size-cells = <0>"
This reverts commit d64b9cdcd4
.
As pointed by [1] and [2], the reverted patch made every DT 'reg'
property translatable. What the patch was trying to fix was fixed in a
different way from previously submitted patches which instead of
correcting the generic address translation function fixed the issue with
appropriate platform code.
[1] https://patchwork.ozlabs.org/project/uboot/patch/1614324949-61314-1-git-send-email-bmeng.cn@gmail.com/
[2] https://lore.kernel.org/linux-clk/20210402192054.7934-1-dariobin@libero.it/T/
Signed-off-by: Dario Binacchi <dariobin@libero.it>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
This commit is contained in:
parent
5a6caf916c
commit
a47abd7bf4
|
@ -45,7 +45,6 @@
|
||||||
fdt-dummy1 = "/translation-test@8000/dev@1,100";
|
fdt-dummy1 = "/translation-test@8000/dev@1,100";
|
||||||
fdt-dummy2 = "/translation-test@8000/dev@2,200";
|
fdt-dummy2 = "/translation-test@8000/dev@2,200";
|
||||||
fdt-dummy3 = "/translation-test@8000/noxlatebus@3,300/dev@42";
|
fdt-dummy3 = "/translation-test@8000/noxlatebus@3,300/dev@42";
|
||||||
fdt-dummy4 = "/translation-test@8000/xlatebus@4,400/devs/dev@19";
|
|
||||||
usb0 = &usb_0;
|
usb0 = &usb_0;
|
||||||
usb1 = &usb_1;
|
usb1 = &usb_1;
|
||||||
usb2 = &usb_2;
|
usb2 = &usb_2;
|
||||||
|
@ -1270,7 +1269,6 @@
|
||||||
1 0x100 0x9000 0x1000
|
1 0x100 0x9000 0x1000
|
||||||
2 0x200 0xA000 0x1000
|
2 0x200 0xA000 0x1000
|
||||||
3 0x300 0xB000 0x1000
|
3 0x300 0xB000 0x1000
|
||||||
4 0x400 0xC000 0x1000
|
|
||||||
>;
|
>;
|
||||||
|
|
||||||
dma-ranges = <0 0x000 0x10000000 0x1000
|
dma-ranges = <0 0x000 0x10000000 0x1000
|
||||||
|
@ -1307,25 +1305,6 @@
|
||||||
reg = <0x42>;
|
reg = <0x42>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
xlatebus@4,400 {
|
|
||||||
compatible = "sandbox,zero-size-cells-bus";
|
|
||||||
reg = <4 0x400 0x1000>;
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
ranges = <0 4 0x400 0x1000>;
|
|
||||||
|
|
||||||
devs {
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
|
|
||||||
dev@19 {
|
|
||||||
compatible = "denx,u-boot-fdt-dummy";
|
|
||||||
reg = <0x19>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
osd {
|
osd {
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
#include <exports.h>
|
#include <exports.h>
|
||||||
#include <fdtdec.h>
|
#include <fdtdec.h>
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fdt_getprop_u32_default_node - Return a node's property or a default
|
* fdt_getprop_u32_default_node - Return a node's property or a default
|
||||||
*
|
*
|
||||||
|
@ -1001,8 +999,8 @@ void fdt_del_node_and_alias(void *blob, const char *alias)
|
||||||
/* Max address size we deal with */
|
/* Max address size we deal with */
|
||||||
#define OF_MAX_ADDR_CELLS 4
|
#define OF_MAX_ADDR_CELLS 4
|
||||||
#define OF_BAD_ADDR FDT_ADDR_T_NONE
|
#define OF_BAD_ADDR FDT_ADDR_T_NONE
|
||||||
#define OF_CHECK_COUNTS(na, ns) (((na) > 0 && (na) <= OF_MAX_ADDR_CELLS) && \
|
#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
|
||||||
((ns) > 0 || gd_size_cells_0()))
|
(ns) > 0)
|
||||||
|
|
||||||
/* Debug utility */
|
/* Debug utility */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
|
@ -271,18 +271,6 @@ config OF_TRANSLATE
|
||||||
used for the address translation. This function is faster and
|
used for the address translation. This function is faster and
|
||||||
smaller in size than fdt_translate_address().
|
smaller in size than fdt_translate_address().
|
||||||
|
|
||||||
config OF_TRANSLATE_ZERO_SIZE_CELLS
|
|
||||||
bool "Enable translation for zero size cells"
|
|
||||||
depends on OF_TRANSLATE
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
The routine used to translate an FDT address into a physical CPU
|
|
||||||
address was developed by IBM. It considers that crossing any level
|
|
||||||
with #size-cells = <0> makes translation impossible, even if it is
|
|
||||||
not the way it was specified.
|
|
||||||
Enabling this option makes translation possible even in the case
|
|
||||||
of crossing levels with #size-cells = <0>.
|
|
||||||
|
|
||||||
config SPL_OF_TRANSLATE
|
config SPL_OF_TRANSLATE
|
||||||
bool "Translate addresses using fdt_translate_address in SPL"
|
bool "Translate addresses using fdt_translate_address in SPL"
|
||||||
depends on SPL_DM && SPL_OF_CONTROL
|
depends on SPL_DM && SPL_OF_CONTROL
|
||||||
|
|
|
@ -50,7 +50,7 @@ fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index)
|
||||||
|
|
||||||
reg += index * (na + ns);
|
reg += index * (na + ns);
|
||||||
|
|
||||||
if (ns || gd_size_cells_0()) {
|
if (ns) {
|
||||||
/*
|
/*
|
||||||
* Use the full-fledged translate function for complex
|
* Use the full-fledged translate function for complex
|
||||||
* bus setups.
|
* bus setups.
|
||||||
|
|
|
@ -18,8 +18,7 @@
|
||||||
/* Max address size we deal with */
|
/* Max address size we deal with */
|
||||||
#define OF_MAX_ADDR_CELLS 4
|
#define OF_MAX_ADDR_CELLS 4
|
||||||
#define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
|
#define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
|
||||||
#define OF_CHECK_COUNTS(na, ns) (OF_CHECK_ADDR_COUNT(na) && \
|
#define OF_CHECK_COUNTS(na, ns) (OF_CHECK_ADDR_COUNT(na) && (ns) > 0)
|
||||||
((ns) > 0 || gd_size_cells_0()))
|
|
||||||
|
|
||||||
static struct of_bus *of_match_bus(struct device_node *np);
|
static struct of_bus *of_match_bus(struct device_node *np);
|
||||||
|
|
||||||
|
@ -163,6 +162,11 @@ const __be32 *of_get_address(const struct device_node *dev, int index,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(of_get_address);
|
EXPORT_SYMBOL(of_get_address);
|
||||||
|
|
||||||
|
static int of_empty_ranges_quirk(const struct device_node *np)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int of_translate_one(const struct device_node *parent,
|
static int of_translate_one(const struct device_node *parent,
|
||||||
struct of_bus *bus, struct of_bus *pbus,
|
struct of_bus *bus, struct of_bus *pbus,
|
||||||
__be32 *addr, int na, int ns, int pna,
|
__be32 *addr, int na, int ns, int pna,
|
||||||
|
@ -189,8 +193,11 @@ static int of_translate_one(const struct device_node *parent,
|
||||||
* As far as we know, this damage only exists on Apple machines, so
|
* As far as we know, this damage only exists on Apple machines, so
|
||||||
* This code is only enabled on powerpc. --gcl
|
* This code is only enabled on powerpc. --gcl
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ranges = of_get_property(parent, rprop, &rlen);
|
ranges = of_get_property(parent, rprop, &rlen);
|
||||||
|
if (ranges == NULL && !of_empty_ranges_quirk(parent)) {
|
||||||
|
debug("no ranges; cannot translate\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (ranges == NULL || rlen == 0) {
|
if (ranges == NULL || rlen == 0) {
|
||||||
offset = of_read_number(addr, na);
|
offset = of_read_number(addr, na);
|
||||||
memset(addr, 0, pna * 4);
|
memset(addr, 0, pna * 4);
|
||||||
|
|
|
@ -319,8 +319,7 @@ fdt_addr_t ofnode_get_addr_size_index(ofnode node, int index, fdt_size_t *size)
|
||||||
|
|
||||||
ns = of_n_size_cells(ofnode_to_np(node));
|
ns = of_n_size_cells(ofnode_to_np(node));
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_OF_TRANSLATE) &&
|
if (IS_ENABLED(CONFIG_OF_TRANSLATE) && ns > 0) {
|
||||||
(ns > 0 || gd_size_cells_0())) {
|
|
||||||
return of_translate_address(ofnode_to_np(node), prop_val);
|
return of_translate_address(ofnode_to_np(node), prop_val);
|
||||||
} else {
|
} else {
|
||||||
na = of_n_addr_cells(ofnode_to_np(node));
|
na = of_n_addr_cells(ofnode_to_np(node));
|
||||||
|
@ -703,10 +702,8 @@ fdt_addr_t ofnode_get_addr_size(ofnode node, const char *property,
|
||||||
ns = of_n_size_cells(np);
|
ns = of_n_size_cells(np);
|
||||||
*sizep = of_read_number(prop + na, ns);
|
*sizep = of_read_number(prop + na, ns);
|
||||||
|
|
||||||
if (CONFIG_IS_ENABLED(OF_TRANSLATE) &&
|
if (CONFIG_IS_ENABLED(OF_TRANSLATE) && ns > 0)
|
||||||
(ns > 0 || gd_size_cells_0())) {
|
|
||||||
return of_translate_address(np, prop);
|
return of_translate_address(np, prop);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
return of_read_number(prop, na);
|
return of_read_number(prop, na);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -164,9 +164,6 @@ int dm_init(bool of_live)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_OF_TRANSLATE_ZERO_SIZE_CELLS))
|
|
||||||
gd->dm_flags |= GD_DM_FLG_SIZE_CELLS_0;
|
|
||||||
|
|
||||||
if (gd->dm_root) {
|
if (gd->dm_root) {
|
||||||
dm_warn("Virtual root driver already exists!\n");
|
dm_warn("Virtual root driver already exists!\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -183,12 +183,6 @@ struct global_data {
|
||||||
struct global_data *new_gd;
|
struct global_data *new_gd;
|
||||||
|
|
||||||
#ifdef CONFIG_DM
|
#ifdef CONFIG_DM
|
||||||
/**
|
|
||||||
* @dm_flags: additional flags for Driver Model
|
|
||||||
*
|
|
||||||
* See &enum gd_dm_flags
|
|
||||||
*/
|
|
||||||
unsigned long dm_flags;
|
|
||||||
/**
|
/**
|
||||||
* @dm_root: root instance for Driver Model
|
* @dm_root: root instance for Driver Model
|
||||||
*/
|
*/
|
||||||
|
@ -519,12 +513,6 @@ struct global_data {
|
||||||
#define gd_acpi_ctx() NULL
|
#define gd_acpi_ctx() NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_IS_ENABLED(DM)
|
|
||||||
#define gd_size_cells_0() (gd->dm_flags & GD_DM_FLG_SIZE_CELLS_0)
|
|
||||||
#else
|
|
||||||
#define gd_size_cells_0() (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum gd_flags - global data flags
|
* enum gd_flags - global data flags
|
||||||
*
|
*
|
||||||
|
@ -609,18 +597,6 @@ enum gd_flags {
|
||||||
GD_FLG_SMP_READY = 0x40000,
|
GD_FLG_SMP_READY = 0x40000,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* enum gd_dm_flags - global data flags for Driver Model
|
|
||||||
*
|
|
||||||
* See field dm_flags of &struct global_data.
|
|
||||||
*/
|
|
||||||
enum gd_dm_flags {
|
|
||||||
/**
|
|
||||||
* @GD_DM_FLG_SIZE_CELLS_0: Enable #size-cells=<0> translation
|
|
||||||
*/
|
|
||||||
GD_DM_FLG_SIZE_CELLS_0 = 0x00001,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#endif /* __ASM_GENERIC_GBL_DATA_H */
|
#endif /* __ASM_GENERIC_GBL_DATA_H */
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <dm/device_compat.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fdtdec.h>
|
#include <fdtdec.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
|
@ -551,64 +550,6 @@ U_BOOT_DRIVER(fdt_dummy_drv) = {
|
||||||
.id = UCLASS_TEST_DUMMY,
|
.id = UCLASS_TEST_DUMMY,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int zero_size_cells_bus_bind(struct udevice *dev)
|
|
||||||
{
|
|
||||||
ofnode child;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
ofnode_for_each_subnode(child, dev_ofnode(dev)) {
|
|
||||||
if (ofnode_get_property(child, "compatible", NULL))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
err = device_bind_driver_to_node(dev,
|
|
||||||
"zero_size_cells_bus_child_drv",
|
|
||||||
"zero_size_cells_bus_child",
|
|
||||||
child, NULL);
|
|
||||||
if (err) {
|
|
||||||
dev_err(dev, "%s: failed to bind %s\n", __func__,
|
|
||||||
ofnode_get_name(child));
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct udevice_id zero_size_cells_bus_ids[] = {
|
|
||||||
{ .compatible = "sandbox,zero-size-cells-bus" },
|
|
||||||
{ }
|
|
||||||
};
|
|
||||||
|
|
||||||
U_BOOT_DRIVER(zero_size_cells_bus) = {
|
|
||||||
.name = "zero_size_cells_bus_drv",
|
|
||||||
.id = UCLASS_TEST_DUMMY,
|
|
||||||
.of_match = zero_size_cells_bus_ids,
|
|
||||||
.bind = zero_size_cells_bus_bind,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int zero_size_cells_bus_child_bind(struct udevice *dev)
|
|
||||||
{
|
|
||||||
ofnode child;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
ofnode_for_each_subnode(child, dev_ofnode(dev)) {
|
|
||||||
err = lists_bind_fdt(dev, child, NULL, false);
|
|
||||||
if (err) {
|
|
||||||
dev_err(dev, "%s: lists_bind_fdt, err=%d\n",
|
|
||||||
__func__, err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
U_BOOT_DRIVER(zero_size_cells_bus_child_drv) = {
|
|
||||||
.name = "zero_size_cells_bus_child_drv",
|
|
||||||
.id = UCLASS_TEST_DUMMY,
|
|
||||||
.bind = zero_size_cells_bus_child_bind,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int dm_test_fdt_translation(struct unit_test_state *uts)
|
static int dm_test_fdt_translation(struct unit_test_state *uts)
|
||||||
{
|
{
|
||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
|
@ -630,17 +571,8 @@ static int dm_test_fdt_translation(struct unit_test_state *uts)
|
||||||
/* No translation for busses with #size-cells == 0 */
|
/* No translation for busses with #size-cells == 0 */
|
||||||
ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 3, &dev));
|
ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 3, &dev));
|
||||||
ut_asserteq_str("dev@42", dev->name);
|
ut_asserteq_str("dev@42", dev->name);
|
||||||
/* No translation for busses with #size-cells == 0 */
|
|
||||||
ut_asserteq(0x42, dev_read_addr(dev));
|
ut_asserteq(0x42, dev_read_addr(dev));
|
||||||
|
|
||||||
/* Translation for busses with #size-cells == 0 */
|
|
||||||
gd->dm_flags |= GD_DM_FLG_SIZE_CELLS_0;
|
|
||||||
ut_asserteq(0x8042, dev_read_addr(dev));
|
|
||||||
ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 4, &dev));
|
|
||||||
ut_asserteq_str("dev@19", dev->name);
|
|
||||||
ut_asserteq(0xc019, dev_read_addr(dev));
|
|
||||||
gd->dm_flags &= ~GD_DM_FLG_SIZE_CELLS_0;
|
|
||||||
|
|
||||||
/* dma address translation */
|
/* dma address translation */
|
||||||
ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, &dev));
|
ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, &dev));
|
||||||
dma_addr[0] = cpu_to_be32(0);
|
dma_addr[0] = cpu_to_be32(0);
|
||||||
|
|
Loading…
Reference in New Issue