Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 14 Jun 2015 20:45:41 +0300
From:      Mihai Carabas <mihai.carabas@gmail.com>
To:        freebsd-arm@freebsd.org
Subject:   Re: porting freebsd-arm on FastModels - CortexA15
Message-ID:  <CANg1yUtFFVM401orwEToTgmN1=HGcWC6fxwSP=er0DcSz46sJQ@mail.gmail.com>
In-Reply-To: <CANg1yUt%2BfaNUyJre66Q4DESPVTemviEPAG8eFCExw=avfdq-TQ@mail.gmail.com>
References:  <CANg1yUt%2BfaNUyJre66Q4DESPVTemviEPAG8eFCExw=avfdq-TQ@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Hello,

On Sat, Jun 13, 2015 at 4:59 PM, Mihai Carabas <mihai.carabas@gmail.com>
wrote:

> Hello,
>
> My name is Mihai Carabas and I am a GSoC student this year on porting
> bhyve over ARM. Right now I'm working on booting FreeBSD ARM on an
> CortexA15 emulated platform running with FastModels.
>
> I have two problems until now:
>
> a) I used the DTS from sys/gnu/dts/arm/vexpress-v2p-ca15-tc1.dts and I
> build the FDT directly in the kernel. I have a problem with the address
> calculated for the serial0 console.
>
> The DTB parser selects the first range from the bus:
> 228 >------->-------ranges = <0 0 0 0x08000000 0x04000000>,
> 229 >------->------->------- <1 0 0 0x14000000 0x04000000>,
> 230 >------->------->------- <2 0 0 0x18000000 0x04000000>,
> 231 >------->------->------- <3 0 0 0x1c000000 0x04000000>,
> 232 >------->------->------- <4 0 0 0x0c000000 0x04000000>,
> 233 >------->------->------- <5 0 0 0x10000000 0x04000000>;
>
> The valid range for this platform is the entry starting with 3 (the
> console is mapped at address 0x1c090000). But the parser ellects the first
> range.
>
> The console is declared like this (as a child to iofpga root node):
>  68 >------->-------iofpga@3,00000000 {
>  69 >------->------->-------compatible = "arm,amba-bus", "simple-bus";
>  70 >------->------->-------#address-cells = <1>;
>  71 >------->------->-------#size-cells = <1>;
>  72 >------->------->-------ranges = <0 3 0 0x200000>;
> ........
> 156 >------->------->-------v2m_serial0: uart@090000 {
> 157 >------->------->------->-------compatible = "arm,pl011",
> "arm,primecell";
> 158 >------->------->------->-------reg = <0x090000 0x1000>;
> 159 >------->------->------->-------interrupts = <5>;
> 160 >------->------->------->-------clocks = <&v2m_oscclk2>, <&smbclk>;
> 161 >------->------->------->-------clock-names = "uartclk", "apb_pclk";
> 162 >------->------->-------};
>
> As you can see the iofgpa selects the chip number 3, which is ok, but the
> final address computed by the FreeBSD parser isn't. Any thoughts on this?
>

I've found the issue with DTS parsing (a bug in the FDT parsing I guess).
The ranges value contains the address of the child node (the first value: 0
in this case), the address of the parent (3 0 - the parent address-cells is
2) and the size of the range for the child node (0x200000).

The problem appears at the parent, because it has two values. If we analyze
the "fdt_get_range" from sys/dev/fdt/fdt_common.c we will see the following
line:
par_bus_addr = fdt_data_get((void *)rangesptr, par_addr_cells);

All seems ok (par_addr_cells is 2), but par_bus_addr is of type u_long,
which means unsigned long and a length of 32bits and can't accomodate the
two values in the parent address space.

415 u_long
416 fdt_data_get(void *data, int cells)
417 {
418
419 >-------if (cells == 1)
420 >------->-------return (fdt32_to_cpu(*((uint32_t *)data)));
421
422 >-------return (fdt64_to_cpu(*((uint64_t *)data)));

If we look at fdt64_to_cpu:
 29 static inline uint64_t fdt64_to_cpu(uint64_t x)
 30 {
 31 >-------return (EXTRACT_BYTE(0) << 56) | (EXTRACT_BYTE(1) << 48) |
(EXTRACT_BYTE(2) << 40) | (EXTRACT_BYTE(3) << 32)
 32 >------->-------| (EXTRACT_BYTE(4) << 24) | (EXTRACT_BYTE(5) << 16) |
(EXTRACT_BYTE(6) << 8) | EXTRACT_BYTE(7);
 33 }

It returns a 64bit variable which doesn't fit in the u_long par_bus_addr
and the compiler selects only the least significant bits, meaning "0". The
"3" is left out and this is why the parsing code doesn't select the third
chip from the bus.

What would be the best resolution for this? Replacing all the u_longs with
uint64_t in the fdt_common?

Thank you,
Mihai



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CANg1yUtFFVM401orwEToTgmN1=HGcWC6fxwSP=er0DcSz46sJQ>