[U-Boot] [PATCH v3] dm: core: Enable optional use of fdt_translate_address()

Bin Meng bmeng.cn at gmail.com
Fri Dec 4 07:17:57 CET 2015


Hi,

On Fri, Dec 4, 2015 at 1:31 PM, Bin Meng <bmeng.cn at gmail.com> wrote:
> Hi Stefan,
>
> On Thu, Dec 3, 2015 at 10:12 PM, Stefan Roese <sr at denx.de> wrote:
>> Hi Bin,
>>
>>
>> On 03.12.2015 14:34, Bin Meng wrote:
>>>
>>> Hi Stefan, Simon,
>>>
>>> On Mon, Oct 19, 2015 at 7:16 AM, Simon Glass <sjg at chromium.org> wrote:
>>>>
>>>> On 29 September 2015 at 23:00, Stefan Roese <sr at denx.de> wrote:
>>>>>
>>>>> The current "simple" address translation simple_bus_translate() is not
>>>>> working on some platforms (e.g. MVEBU). As here more complex "ranges"
>>>>> properties are used in many nodes (multiple tuples etc). This patch
>>>>> enables the optional use of the common fdt_translate_address() function
>>>>> which handles this translation correctly.
>>>>>
>>>>> Signed-off-by: Stefan Roese <sr at denx.de>
>>>>> Cc: Simon Glass <sjg at chromium.org>
>>>>> Cc: Bin Meng <bmeng.cn at gmail.com>
>>>>> Cc: Marek Vasut <marex at denx.de>
>>>>> Cc: Masahiro Yamada <yamada.masahiro at socionext.com>
>>>>> Cc: Stephen Warren <swarren at nvidia.com>
>>>>> Cc: Lukasz Majewski <l.majewski at samsung.com>
>>>>> ---
>>>>> v3:
>>>>> - Rebased on current U-Boot version
>>>>> - Added Stephen and Lukasz to Cc
>>>>>
>>>>> v2:
>>>>> - Rework code a bit as suggested by Simon. Also added some comments
>>>>>    to make the use of the code paths more clear.
>>>>>
>>>>>   drivers/core/Kconfig  | 30 ++++++++++++++++++++++++++++++
>>>>>   drivers/core/device.c | 20 ++++++++++++++++++++
>>>>>   2 files changed, 50 insertions(+)
>>>>
>>>>
>>>> Applied to u-boot-dm, thanks!
>>>
>>>
>>> When testing Simon's patch [1], I found PCI UART on Intel Crown Bay no
>>> longer works. git bisect leads to this commit. Somehow I missed this
>>> patch before although I see the commit message get me cc'ed but the
>>> email did not bring to my attention.
>>>
>>> I see this patch introduced OF_TRANSLATE and by default set it to y.
>>> This makes the code logic in dev_get_addr() go through
>>> fdt_translate_address(), which breaks the things.
>>
>>
>> I'm a bit surprised that using the common fdt_translate_address()
>> function instead of the DM internal simple_bus_translate() causes
>> problems on your platform. Are you sure that the ranges are
>> described correctly in your dts? Is the dts a copy from the Linux
>> original one? Ah, probably not, since we're talking about x86
>> which has no DT support in Linux, right?
>>
>
> Is fdt_translate_address() able to handle PCI bus ranges property? PCI
> has special ranges.
>
> The arch/x86/dts/crownbay.dts has something like below:
>
>  90         pci {
>  91                 #address-cells = <3>;
>  92                 #size-cells = <2>;
>  93                 compatible = "pci-x86";
>  94                 u-boot,dm-pre-reloc;
>  95                 ranges = <0x02000000 0x0 0x40000000 0x40000000 0 0x80000000
>  96                           0x42000000 0x0 0xc0000000 0xc0000000 0 0x20000000
>  97                           0x01000000 0x0 0x2000 0x2000 0 0xe000>;
>  98
>  99                 pcie at 17,0 {
> 100                         #address-cells = <3>;
> 101                         #size-cells = <2>;
> 102                         compatible = "pci-bridge";
> 103                         u-boot,dm-pre-reloc;
> 104                         reg = <0x0000b800 0x0 0x0 0x0 0x0>;
>
>>> Should we set
>>> OF_TRANSLATE to n by default? If set to y, this requires dts to have
>>> complete ranges property everywhere.
>>
>>
>> My understanding here is that x86 is a special case. As it doesn't
>> use the full-blown dts sources from Linux. But most likely some
>> "simple" ones, written exactly for U-Boot / DM.
>>
>> I would still prefer to have this OF_TRANSLATE set to y as default.
>> As its needed for at least some platforms. But if we decide to
>> set it to n, I can live with it as well.
>>

Looks like the issue is:

dev_get_addr() return value is of type fdt_addr_t, and if no valid
address found returns FDT_ADDR_T_NONE. But FDT_ADDR_T_NONE is defined
as follows:

#ifdef CONFIG_PHYS_64BIT
#define FDT_ADDR_T_NONE (-1ULL)
#define fdt_addr_to_cpu(reg) be64_to_cpu(reg)
#define fdt_size_to_cpu(reg) be64_to_cpu(reg)
#else
#define FDT_ADDR_T_NONE (-1U)
#define fdt_addr_to_cpu(reg) be32_to_cpu(reg)
#define fdt_size_to_cpu(reg) be32_to_cpu(reg)
#endif

On x86, CONFIG_PHYS_64BIT is not defined, so FDT_ADDR_T_NONE becomes -1U.

In the ns16550 driver, the code logic is:

/* try Processor Local Bus device first */
addr = dev_get_addr(dev);
#ifdef CONFIG_PCI
    if (addr == FDT_ADDR_T_NONE) {
    /* then try pci device */

With OF_TRANSLATE set to y, dev_get_addr() returns OF_BAD_ADDR if no
valid address found, but OF_BAD_ADDR is defined as:

#define OF_BAD_ADDR ((u64)-1)

This creates a size mismatch as FDT_ADDR_T_NONE can be -1U or -1ULL
depending on CONFIG_PHYS_64BIT but OF_BAD_ADDR is always -1ULL.

The patch below fixes this issue:

diff --git a/common/fdt_support.c b/common/fdt_support.c
index f86365e..8930f34 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -16,6 +16,7 @@
 #include <libfdt.h>
 #include <fdt_support.h>
 #include <exports.h>
+#include <fdtdec.h>

 /**
  * fdt_getprop_u32_default_node - Return a node's property or a default
@@ -945,7 +946,7 @@ void fdt_del_node_and_alias(void *blob, const char *alias)

 /* Max address size we deal with */
 #define OF_MAX_ADDR_CELLS      4
-#define OF_BAD_ADDR    ((u64)-1)
+#define OF_BAD_ADDR    FDT_ADDR_T_NONE
 #define OF_CHECK_COUNTS(na, ns)        ((na) > 0 && (na) <=
OF_MAX_ADDR_CELLS && \
                        (ns) > 0)

Regards,
Bin


More information about the U-Boot mailing list