Module Name:    src
Committed By:   jakllsch
Date:           Thu Aug 16 23:40:19 UTC 2012

Modified Files:
        src/sys/arch/evbarm/rpi: rpi_machdep.c rpi_start.S

Log Message:
Get accessible memory quantity and kernel command line via Linux ARM 'A'-tag
interface used by Raspberry Pi's start.elf.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/evbarm/rpi/rpi_machdep.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/evbarm/rpi/rpi_start.S

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/evbarm/rpi/rpi_machdep.c
diff -u src/sys/arch/evbarm/rpi/rpi_machdep.c:1.4 src/sys/arch/evbarm/rpi/rpi_machdep.c:1.5
--- src/sys/arch/evbarm/rpi/rpi_machdep.c:1.4	Thu Aug 16 18:22:46 2012
+++ src/sys/arch/evbarm/rpi/rpi_machdep.c	Thu Aug 16 23:40:19 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: rpi_machdep.c,v 1.4 2012/08/16 18:22:46 matt Exp $	*/
+/*	$NetBSD: rpi_machdep.c,v 1.5 2012/08/16 23:40:19 jakllsch Exp $	*/
 
 /*
  * Copyright (c) 2002, 2003, 2005  Genetec Corporation.  All rights reserved.
@@ -122,7 +122,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rpi_machdep.c,v 1.4 2012/08/16 18:22:46 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rpi_machdep.c,v 1.5 2012/08/16 23:40:19 jakllsch Exp $");
 
 #include "opt_evbarm_boardtype.h"
 #include "opt_broadcom.h"
@@ -227,6 +227,9 @@ int plcomcnmode = PLCONMODE;
 #include <sys/kgdb.h>
 #endif
 
+/* Smallest amount of RAM start.elf could give us. */
+#define RPI_MINIMUM_ARM_RAM_SPLIT (128U * 1024 * 1024)
+
 void
 cpu_reboot(int howto, char *bootstr)
 {
@@ -324,6 +327,65 @@ static const struct pmap_devmap rpi_devm
 #undef  _A
 #undef  _S
 
+#define LINUX_ARM_MACHTYPE_BCM2708 3138
+
+#define LINUX_ATAG_NONE		0x00000000
+struct linux_atag_header {
+	uint32_t size;
+	uint32_t tag;
+} __packed __aligned(4); 
+
+#define LINUX_ATAG_MEM		0x54410002
+struct linux_atag_mem {
+	uint32_t size;
+	uint32_t start;
+} __packed __aligned(4);
+
+#define LINUX_ATAG_CMDLINE	0x54410009
+struct linux_atag_cmdline {
+	char cmdline[1];
+} __packed __aligned(4);
+
+struct linux_atag {
+	struct linux_atag_header	hdr;
+	union {
+		struct linux_atag_mem		mem;
+		struct linux_atag_cmdline	cmdline;
+	} u;
+} __packed __aligned(4);
+
+static void
+parse_linux_atags(void *atag_base)
+{
+	struct linux_atag *atp;
+
+	for (atp = atag_base;
+	    atp->hdr.size >= sizeof(struct linux_atag_header)/sizeof(uint32_t);
+	    atp = (void *)((uintptr_t)atp + sizeof(uint32_t) * atp->hdr.size)) {
+		printf("atag: size %08x tag %08x\n", atp->hdr.size, atp->hdr.tag);
+		if (atp->hdr.tag == LINUX_ATAG_MEM) {
+			if (bootconfig.dramblocks > 1) {
+				printf("Ignoring RAM block 0x%08x-0x%08x\n",
+				    atp->u.mem.start, atp->u.mem.start +
+				    atp->u.mem.size - 1);
+				continue;
+			}
+			physical_end = atp->u.mem.size;
+			physmem = physical_end / PAGE_SIZE;
+			KASSERT(atp->u.mem.start == 0);
+			physical_start = atp->u.mem.start;
+			bootconfig.dram[bootconfig.dramblocks].address = 0x0;
+			bootconfig.dram[bootconfig.dramblocks].pages = physmem;
+			++bootconfig.dramblocks;
+		}
+
+		if (atp->hdr.tag == LINUX_ATAG_CMDLINE) {
+			strncpy(bootargs, atp->u.cmdline.cmdline,
+			    sizeof(bootargs));
+		}
+	}
+}
+
 /*
  * u_int initarm(...)
  *
@@ -364,13 +426,19 @@ initarm(void *arg)
 	printf("initarm: Configuring system ...\n");
 #endif
 
-	bootconfig.dramblocks = 1;
-	physical_end = (MEMSIZE * 1024 * 1024); /* MEMSIZE */
-	physmem = physical_end / PAGE_SIZE;
-	physical_start = 0;
+	extern const uint32_t rpi_boot_regs[4];
+	if (rpi_boot_regs[0] == 0 &&
+	    rpi_boot_regs[1] == LINUX_ARM_MACHTYPE_BCM2708) {
+		parse_linux_atags((void *)KERN_PHYSTOV(rpi_boot_regs[2]));
+	} else {
+		bootconfig.dramblocks = 1;
+		physical_end = RPI_MINIMUM_ARM_RAM_SPLIT;
+		physmem = physical_end / PAGE_SIZE;
+		physical_start = 0;
 
-	bootconfig.dram[0].address = 0x0;
-	bootconfig.dram[0].pages = physmem;
+		bootconfig.dram[0].address = 0x0;
+		bootconfig.dram[0].pages = physmem;
+	}
 
 	/*
 	 * Our kernel is at the beginning of memory, so set our free space to
@@ -500,6 +568,9 @@ initarm(void *arg)
 	md_root_setconf(memory_disk, sizeof memory_disk);
 #endif
 
+	boot_args = bootargs;
+	parse_mi_bootargs(boot_args);
+
 #ifdef BOOTHOWTO
 	boothowto |= BOOTHOWTO;
 #endif

Index: src/sys/arch/evbarm/rpi/rpi_start.S
diff -u src/sys/arch/evbarm/rpi/rpi_start.S:1.3 src/sys/arch/evbarm/rpi/rpi_start.S:1.4
--- src/sys/arch/evbarm/rpi/rpi_start.S:1.3	Thu Aug 16 21:46:18 2012
+++ src/sys/arch/evbarm/rpi/rpi_start.S	Thu Aug 16 23:40:19 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: rpi_start.S,v 1.3 2012/08/16 21:46:18 jakllsch Exp $	*/
+/*	$NetBSD: rpi_start.S,v 1.4 2012/08/16 23:40:19 jakllsch Exp $	*/
 
 /*
  * Copyright (c) 2002, 2003  Genetec Corporation.  All rights reserved.
@@ -88,7 +88,7 @@
 #include <arm/armreg.h>
 #include "assym.h"
 
-RCSID("$NetBSD: rpi_start.S,v 1.3 2012/08/16 21:46:18 jakllsch Exp $")
+RCSID("$NetBSD: rpi_start.S,v 1.4 2012/08/16 23:40:19 jakllsch Exp $")
 
 /* Location (in MiB) to put temporary MMU tables just below. */
 /* Raspberry Pi start.elf will give us anywhere between 128MiB and 240MiB */
@@ -126,6 +126,9 @@ RCSID("$NetBSD: rpi_start.S,v 1.3 2012/0
 
 	.global	_C_LABEL(rpi_start)
 _C_LABEL(rpi_start):
+	adr	r8, rpi_boot_regs
+	stmia	r8!, {r0-r3}
+
 	mrs	r0, cpsr
 	bic	r0, r0, #PSR_MODE
 	orr	r0, r0, #(I32_bit | F32_bit | PSR_SVC32_MODE)
@@ -323,3 +326,7 @@ mmu_init_table:
 
 	/* end of table */
 	MMU_INIT(0, 0, 0, 0)
+
+	.globl	_C_LABEL(rpi_boot_regs)
+rpi_boot_regs:
+	.space 4 * 4

Reply via email to