svn commit: r297284 - in head/sys/arm: arm at91 conf include
Michal Meloun
mmel at FreeBSD.org
Sat Mar 26 06:55:57 UTC 2016
Author: mmel
Date: Sat Mar 26 06:55:55 2016
New Revision: 297284
URL: https://svnweb.freebsd.org/changeset/base/297284
Log:
ARM: Teach LINUX_BOOT_ABI to recognize DT blob.
This allow us to boot FreeBSD kernel (using uImage encapsulation) directly
from U-boot using 'bootm' command or by Android fastboot loader.
For now, kernel uImage must be marked as Linux, but we can add support for
FreeBSD into U-Boot later.
Modified:
head/sys/arm/arm/machdep.c
head/sys/arm/at91/board_tsc4370.c
head/sys/arm/conf/TEGRA124
head/sys/arm/include/machdep.h
Modified: head/sys/arm/arm/machdep.c
==============================================================================
--- head/sys/arm/arm/machdep.c Sat Mar 26 03:46:12 2016 (r297283)
+++ head/sys/arm/arm/machdep.c Sat Mar 26 06:55:55 2016 (r297284)
@@ -115,6 +115,7 @@ __FBSDID("$FreeBSD$");
#include <machine/sysarch.h>
#ifdef FDT
+#include <contrib/libfdt/libfdt.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#endif
@@ -959,7 +960,8 @@ makectx(struct trapframe *tf, struct pcb
* Fake up a boot descriptor table
*/
vm_offset_t
-fake_preload_metadata(struct arm_boot_params *abp __unused)
+fake_preload_metadata(struct arm_boot_params *abp __unused, void *dtb_ptr,
+ size_t dtb_size)
{
#ifdef DDB
vm_offset_t zstart = 0, zend = 0;
@@ -997,6 +999,16 @@ fake_preload_metadata(struct arm_boot_pa
} else
#endif
lastaddr = (vm_offset_t)&end;
+ if (dtb_ptr != NULL) {
+ /* Copy DTB to KVA space and insert it into module chain. */
+ lastaddr = roundup(lastaddr, sizeof(int));
+ fake_preload[i++] = MODINFO_METADATA | MODINFOMD_DTBP;
+ fake_preload[i++] = sizeof(uint32_t);
+ fake_preload[i++] = (uint32_t)lastaddr;
+ memmove((void *)lastaddr, dtb_ptr, dtb_size);
+ lastaddr += dtb_size;
+ lastaddr = roundup(lastaddr, sizeof(int));
+ }
fake_preload[i++] = 0;
fake_preload[i] = 0;
preload_metadata = (void *)fake_preload;
@@ -1023,20 +1035,35 @@ linux_parse_boot_param(struct arm_boot_p
struct arm_lbabi_tag *walker;
uint32_t revision;
uint64_t serial;
+#ifdef FDT
+ struct fdt_header *dtb_ptr;
+ uint32_t dtb_size;
+#endif
/*
* Linux boot ABI: r0 = 0, r1 is the board type (!= 0) and r2
* is atags or dtb pointer. If all of these aren't satisfied,
- * then punt.
+ * then punt. Unfortunately, it looks like DT enabled kernels
+ * doesn't uses board type and U-Boot delivers 0 in r1 for them.
*/
- if (!(abp->abp_r0 == 0 && abp->abp_r1 != 0 && abp->abp_r2 != 0))
- return 0;
+ if (abp->abp_r0 != 0 || abp->abp_r2 == 0)
+ return (0);
+#ifdef FDT
+ /* Test if r2 point to valid DTB. */
+ dtb_ptr = (struct fdt_header *)abp->abp_r2;
+ if (fdt_check_header(dtb_ptr) == 0) {
+ dtb_size = fdt_totalsize(dtb_ptr);
+ return (fake_preload_metadata(abp, dtb_ptr, dtb_size));
+ }
+#endif
+ /* Old, ATAG based boot must have board type set. */
+ if (abp->abp_r1 == 0)
+ return (0);
board_id = abp->abp_r1;
walker = (struct arm_lbabi_tag *)
(abp->abp_r2 + KERNVIRTADDR - abp->abp_physaddr);
- /* xxx - Need to also look for binary device tree */
if (ATAG_TAG(walker) != ATAG_CORE)
return 0;
@@ -1077,7 +1104,7 @@ linux_parse_boot_param(struct arm_boot_p
init_static_kenv(NULL, 0);
- return fake_preload_metadata(abp);
+ return fake_preload_metadata(abp, NULL, 0);
}
#endif
@@ -1135,7 +1162,7 @@ default_parse_boot_param(struct arm_boot
return lastaddr;
#endif
/* Fall back to hardcoded metadata. */
- lastaddr = fake_preload_metadata(abp);
+ lastaddr = fake_preload_metadata(abp, NULL, 0);
return lastaddr;
}
Modified: head/sys/arm/at91/board_tsc4370.c
==============================================================================
--- head/sys/arm/at91/board_tsc4370.c Sat Mar 26 03:46:12 2016 (r297283)
+++ head/sys/arm/at91/board_tsc4370.c Sat Mar 26 06:55:55 2016 (r297284)
@@ -601,7 +601,7 @@ parse_boot_param(struct arm_boot_params
inkernel_bootinfo = *(struct tsc_bootinfo *)(abp->abp_r1);
}
- return fake_preload_metadata(abp);
+ return fake_preload_metadata(abp, NULL, 0);
}
ARM_BOARD(NONE, "TSC4370 Controller Board");
Modified: head/sys/arm/conf/TEGRA124
==============================================================================
--- head/sys/arm/conf/TEGRA124 Sat Mar 26 03:46:12 2016 (r297283)
+++ head/sys/arm/conf/TEGRA124 Sat Mar 26 06:55:55 2016 (r297284)
@@ -28,6 +28,7 @@ options SCHED_ULE # ULE scheduler
options PLATFORM # Platform based SoC
options PLATFORM_SMP
options SMP # Enable multiple cores
+options LINUX_BOOT_ABI
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
Modified: head/sys/arm/include/machdep.h
==============================================================================
--- head/sys/arm/include/machdep.h Sat Mar 26 03:46:12 2016 (r297283)
+++ head/sys/arm/include/machdep.h Sat Mar 26 06:55:55 2016 (r297284)
@@ -37,7 +37,8 @@ struct arm_boot_params;
vm_offset_t default_parse_boot_param(struct arm_boot_params *abp);
vm_offset_t freebsd_parse_boot_param(struct arm_boot_params *abp);
vm_offset_t linux_parse_boot_param(struct arm_boot_params *abp);
-vm_offset_t fake_preload_metadata(struct arm_boot_params *abp);
+vm_offset_t fake_preload_metadata(struct arm_boot_params *abp,
+ void *dtb_ptr, size_t dtb_size);
vm_offset_t parse_boot_param(struct arm_boot_params *abp);
void arm_generic_initclocks(void);
More information about the svn-src-all
mailing list