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>