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

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, Jun 14, 2015 at 8:45 PM, Mihai Carabas <mihai.carabas@gmail.com>
wrote:

> 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?
>
>
I found another issue in regions_to_avail function: end variable is
vm_paddr_t which is typedef at uint32_t. The problem is when having start
at 0x80000000 and the size of the memory 0x80000000 (2G) than the end
variable which is start + size becomes 0 (overflow). Can we shrink down end
by 1? this seems to solve the problem.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CANg1yUtFjDr7AMnOJLc-58umU6eqvox3WEkfJyQ14CRwmb8HPA>