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