Port-arm archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: LG Nexus 5



Good day, folks.

After much whittling away of the "fun" that led up to being able to get a PID 1 going, attached is a patch. This patch is _not_ intended as a worthy submission to the code-base. It's merely evidence that the LG Nexus 5 is approachable.

Known issues:

1. The hack to simplefb to support 24-bit color isn't quite right. It appears to result in green text (unless that's always true?) and there is some kind of glitch in which text from the bottom might become interleaved with text near the top, or even interleaved with such text from a previous boot of the device. (When I used some framebuffer code from 'tinyfont' and it used 24 bits per pixel, it was fine.)

2. The macro-names for the CPU probably warrant criticism.

3. The macros for the CPU probably aren't the right combination of specificity.

4. The injection of the CPU into "someone else's" section isn't right and there should probably be a new section, instead.

5. I haven't yet figured out how to provide a /dev/console. Any suggestions would be most welcome.

6. The "platform" naming isn't quite right, but having not developed for NetBSD before, I'm uncertain as to the conventions. SoC? Precise phone-model? Less-precise phone-model? Whimsical choice?

7. The "NEXUSTROUBLEXXX" lines are merely descriptive. The use of an 'if' to block out a "problematic" line warrants further pursuit of understanding before even deciding upon a correct strategy, whether #ifdef or something else.

8. The organization of the configuration-files probably isn't right. If the device was fully supported, I suppose it'd probably get added into evbarm GENERIC, at such a time... or elsewhere.

9. Thanks to Nick Hudson for direction towards callout(9). I'm not sure that xxx_platform_device_register is where it belongs; probably not.

10. Magical numbers everywhere, including an arbitrary choice for the framebuffer VA space.

11. The last time I checked, some of the low RAM is forfeited; likely due to the FDT not covering enough detail.

A build of this should work on the "D820(E) 16GB" model if loaded at PA 0x68FF8040 with the correct FDT.

Feedback welcome, of course.

- Shao Miller
diff --git a/arch/arm/arm/cpufunc.c b/arch/arm/arm/cpufunc.c
index 35ccdec4..1359278d 100644
--- a/arch/arm/arm/cpufunc.c
+++ b/arch/arm/arm/cpufunc.c
@@ -1949,7 +1949,7 @@ set_cpufuncs(void)
 	}
 #endif /* CPU_XSCALE_IXP425 */
 #if defined(CPU_CORTEX)
-	if (CPU_ID_CORTEX_P(cputype)) {
+	if (CPU_ID_CORTEX_P(cputype) || CPU_ID_KRAIT_400_P(cputype)) {
 		cpufuncs = armv7_cpufuncs;
 		set_cpufuncs_mpfixup();
 		cpu_do_powersave = 1;			/* Enable powersave */
diff --git a/arch/arm/arm/cpufunc_asm_armv7.S b/arch/arm/arm/cpufunc_asm_armv7.S
index 1d9c11d6..1e9983bd 100644
--- a/arch/arm/arm/cpufunc_asm_armv7.S
+++ b/arch/arm/arm/cpufunc_asm_armv7.S
@@ -138,6 +138,13 @@ STRONG_ALIAS(armv7mp_tlb_flushI, armv7mp_tlb_flushID)
 ENTRY(armv7mp_tlb_flushID)
 	dsb
 	mov	r0, #0
+	/*
+	 * Line NEXUSTROUBLE002 will hang the system if reached after line
+	 * NEXUSTROUBLE001.  If NEXUSTROUBLE002 is removed instead of
+	 * NEXUSTROUBLE001, then NEXUSTROUBLE003 will eventually hang the
+	 * system.
+	 */
+	/* The next line is NEXUSTROUBLE002 */
 	mcr	p15, 0, r0, c8, c3, 0	@ flush entire I+D tlb, IS
 	mcr	p15, 0, r0, c7, c1, 6	@ branch predictor invalidate, IS
 	dsb				@ data synchronization barrier
diff --git a/arch/arm/arm32/arm32_kvminit.c b/arch/arm/arm32/arm32_kvminit.c
index 9bb6a262..28e05b6e 100644
--- a/arch/arm/arm32/arm32_kvminit.c
+++ b/arch/arm/arm32/arm32_kvminit.c
@@ -992,6 +992,12 @@ arm32_kernel_vm_init(vaddr_t kernel_vm_base, vaddr_t vectors, vaddr_t iovbase,
 	/*
 	 * Disable lookups via TTBR0 until there is an activated pmap.
 	 */
+	/*
+	 * See arch/arm/arm/cpufunc_asm_armv7.S for notes about line
+	 * NEXUSTROUBLE001
+	 */
+	if (0)
+	/* The next line is NEXUSTROUBLE001 */
 	armreg_ttbcr_write(armreg_ttbcr_read() | TTBCR_S_PD0);
 	cpu_setttb(l1pt_pa, KERNEL_PID);
 	arm_isb();
diff --git a/arch/arm/cortex/gic.c b/arch/arm/cortex/gic.c
index 47fb8665..90ef0006 100644
--- a/arch/arm/cortex/gic.c
+++ b/arch/arm/cortex/gic.c
@@ -575,6 +575,8 @@ armgic_match(device_t parent, cfdata_t cf, void *aux)
 
 	if (strcmp(cf->cf_name, mpcaa->mpcaa_name) != 0)
 		return 0;
+	if (CPU_ID_KRAIT_400_P(cputype))
+		return 1;
 	if (!CPU_ID_CORTEX_P(cputype) || CPU_ID_CORTEX_A8_P(cputype))
 		return 0;
 
diff --git a/arch/arm/fdt/gic_fdt.c b/arch/arm/fdt/gic_fdt.c
index fa2be9f5..90afb179 100644
--- a/arch/arm/fdt/gic_fdt.c
+++ b/arch/arm/fdt/gic_fdt.c
@@ -113,6 +113,7 @@ static int
 gic_fdt_match(device_t parent, cfdata_t cf, void *aux)
 {
 	const char * const compatible[] = {
+		"qcom,msm-qgic2",
 		"arm,gic-400",
 		"arm,cortex-a15-gic",
 		"arm,cortex-a9-gic",
diff --git a/arch/arm/hammerhead/files.hammerhead b/arch/arm/hammerhead/files.hammerhead
new file mode 100644
index 00000000..4b53acce
--- /dev/null
+++ b/arch/arm/hammerhead/files.hammerhead
@@ -0,0 +1,6 @@
+#	$NetBSD: files.hammerhead,v 0.1 2022/11/23 10:22:25 smiller Exp $
+#
+# Initial support for LG Nexus 5
+#
+
+file	arch/arm/hammerhead/hammerhead_platform.c
diff --git a/arch/arm/hammerhead/hammerhead_platform.c b/arch/arm/hammerhead/hammerhead_platform.c
new file mode 100644
index 00000000..b19d0a9c
--- /dev/null
+++ b/arch/arm/hammerhead/hammerhead_platform.c
@@ -0,0 +1,167 @@
+/* $NetBSD: hammerhead_platform.c,v 0.1 2022/11/23 10:22:25 smiller Exp $ */
+
+/*-
+ * Copyright (c) 2022 Shao Miller <netbsd%sha0.net@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/kernel.h>
+#include <sys/param.h>
+#include <dev/fdt/fdtvar.h>
+#include <arm/fdt/arm_fdtvar.h>
+#include <uvm/uvm_extern.h>
+#include <arm/hammerhead/hammerhead_platform.h>
+
+extern struct bus_space arm_generic_a4x_bs_tag;
+extern struct bus_space arm_generic_bs_tag;
+extern struct arm32_bus_dma_tag arm_generic_dma_tag;
+
+static void hammerhead_platform_bootstrap(void);
+static uint64_t hammerhead_platform_clock(void);
+static void hammerhead_platform_framebuffer_refresh(void *);
+static void hammerhead_platform_device_register(device_t self, void *aux);
+static const struct pmap_devmap * hammerhead_platform_devmap(void);
+static void hammerhead_platform_init_attach_args(struct fdt_attach_args *faa);
+
+static callout_t hammerhead_platform_framebuffer_refresh_callout;
+
+static void
+hammerhead_platform_bootstrap(void)
+{
+	arm_fdt_cpu_bootstrap();
+}
+
+static uint64_t
+hammerhead_platform_clock(void)
+{
+	uint32_t bottom;
+	uint64_t clock;
+	uint32_t new_top;
+	uint32_t old_top;
+
+	do
+	{
+		old_top = *(volatile uint32_t *) 0xF9021004;
+		bottom = *(volatile uint32_t *) 0xF9021000;
+		new_top = *(volatile uint32_t *) 0xF9021004;
+	} while(old_top != new_top);
+	clock = new_top;
+	clock <<= sizeof new_top * CHAR_BIT;
+	clock |= bottom;
+	return clock;
+}
+
+void
+hammerhead_platform_delay(u_int n)
+{
+	uint64_t now;
+	uint64_t return_time;
+	uint64_t start_time;
+
+	start_time = hammerhead_platform_clock();
+	return_time = start_time + (n * (19200000 / 1000000));
+	if (return_time < start_time)
+	{
+		/* Wrap-around happened */
+		do
+		{
+			now = hammerhead_platform_clock();
+		}
+		while (now > start_time);
+	}
+	do
+	{
+		now = hammerhead_platform_clock();
+	}
+	while (now < return_time);
+}
+
+static void
+hammerhead_platform_framebuffer_refresh(void * unused)
+{
+	(void) unused;
+	*(volatile uint32_t *) 0xFD90061C = 0x1;
+	callout_reset(&hammerhead_platform_framebuffer_refresh_callout, 21, hammerhead_platform_framebuffer_refresh, NULL);
+}
+
+static void
+hammerhead_platform_device_register(device_t self, void *aux)
+{
+	callout_init(&hammerhead_platform_framebuffer_refresh_callout, CALLOUT_MPSAFE);
+	callout_reset(&hammerhead_platform_framebuffer_refresh_callout, 21, hammerhead_platform_framebuffer_refresh, NULL);
+}
+
+static const struct pmap_devmap *
+hammerhead_platform_devmap(void)
+{
+	static const struct pmap_devmap devmap[] = {
+		DEVMAP_ENTRY(0xED200000,
+			     0x0D200000,
+			     1080 * 1920 * 3),
+		DEVMAP_ENTRY(0xF0000000,
+			     0xF0000000,
+			     0x10000000),
+		DEVMAP_ENTRY_END
+	};
+
+	return devmap;
+}
+
+static void
+hammerhead_platform_init_attach_args(struct fdt_attach_args *faa)
+{
+	faa->faa_a4x_bst = &arm_generic_a4x_bs_tag;
+	faa->faa_bst = &arm_generic_bs_tag;
+	faa->faa_dmat = &arm_generic_dma_tag;
+}
+
+void
+hammerhead_platform_reset(void)
+{
+	*(volatile uint32_t *) 0xFE80565C = 0x77665500;
+	*(volatile uint32_t *) 0xFC4CF804 = 0x00;
+	*(volatile int32_t *) 0xFC4CF810 = -1;
+	*(volatile uint32_t *) 0xFC4CF800 = 0x85B0;
+	hammerhead_platform_delay(300000);
+	*(volatile uint32_t *) 0xFC4CF804 = 0x00;
+	*(volatile uint32_t *) 0xFC4CF810 = 0x01;
+	*(volatile uint32_t *) 0xFC4CF800 = 0x85A0;
+	*(volatile uint32_t *) 0xFC4CF804 = 0x00;
+	*(volatile uint32_t *) 0xFC4CF810 = 0x80;
+	*(volatile uint32_t *) 0xFC4CF800 = 0x85B0;
+	*(volatile uint32_t *) 0xFC4AB000 = 0x00;
+}
+
+static const struct arm_platform hammerhead_platform = {
+	.ap_devmap = hammerhead_platform_devmap,
+	.ap_bootstrap = hammerhead_platform_bootstrap,
+	.ap_init_attach_args = hammerhead_platform_init_attach_args,
+	.ap_device_register = hammerhead_platform_device_register,
+	.ap_reset = hammerhead_platform_reset,
+	.ap_delay = hammerhead_platform_delay,
+	.ap_uart_freq = NULL,
+	.ap_mpstart = arm_fdt_cpu_mpstart,
+};
+
+ARM_PLATFORM(hammerhead, "lge,hammerhead", &hammerhead_platform);
diff --git a/arch/arm/hammerhead/hammerhead_platform.h b/arch/arm/hammerhead/hammerhead_platform.h
new file mode 100644
index 00000000..20d76871
--- /dev/null
+++ b/arch/arm/hammerhead/hammerhead_platform.h
@@ -0,0 +1,35 @@
+/* $NetBSD: hammerhead_platform.h,v 0.1 2022/11/23 10:22:25 smiller Exp $ */
+
+/*-
+ * Copyright (c) 2022 Shao Miller <netbsd%sha0.net@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef HAMMERHEAD_PLATFORM_H_
+#define HAMMERHEAD_PLATFORM_H_ 1
+
+extern void hammerhead_platform_delay(u_int n);
+extern void hammerhead_platform_reset(void);
+
+#endif /* HAMMERHEAD_PLATFORM_H_ */
diff --git a/arch/arm/include/cputypes.h b/arch/arm/include/cputypes.h
index 0d92a2d7..7b88d232 100644
--- a/arch/arm/include/cputypes.h
+++ b/arch/arm/include/cputypes.h
@@ -195,6 +195,8 @@
 #define CPU_ID_CORTEX_A76AE_P(n) ((n & 0xff0ff0f0) == 0x410fd0e0)
 #define CPU_ID_CORTEX_A77_P(n)	((n & 0xff0ff0f0) == 0x410fd0f0)
 
+#define CPU_ID_KRAIT_400_P(n)	((n) == CPU_ID_KRAIT_400)
+
 #define CPU_ID_THUNDERXRX	0x43000a10
 #define CPU_ID_THUNDERXP1d0	0x43000a10
 #define CPU_ID_THUNDERXP1d1	0x43000a11
@@ -206,6 +208,7 @@
 #define CPU_ID_SA110		0x4401a100
 #define CPU_ID_SA1100		0x4401a110
 #define CPU_ID_EMAG8180		0x503f0002
+#define CPU_ID_KRAIT_400	0x512F06F0
 #define CPU_ID_TI925T		0x54029250
 #define CPU_ID_MV88FR571_VD	0x56155710
 #define CPU_ID_MV88SV131	0x56251310
diff --git a/arch/evbarm/conf/HAMMERHEAD b/arch/evbarm/conf/HAMMERHEAD
new file mode 100644
index 00000000..aa61356d
--- /dev/null
+++ b/arch/evbarm/conf/HAMMERHEAD
@@ -0,0 +1,20 @@
+#	$NetBSD: HAMMERHEAD,v 0.1 2022/11/23 10:22:25 smiller Exp $
+#
+# Initial support for LG Nexus 5
+#
+
+include	"arch/evbarm/conf/GENERIC"
+include "arch/arm/hammerhead/files.hammerhead"
+
+options		MEMORY_DISK_HOOKS
+options		MEMORY_DISK_ROOT_SIZE=10000
+options		MEMORY_DISK_IS_ROOT
+options		MEMORY_DISK_SERVER=1
+
+pseudo-device	md	1
+
+options 	DIAGNOSTIC
+options 	DEBUG
+options 	PMAP_DEBUG
+
+options 	VERBOSE_INIT_ARM
diff --git a/arch/evbarm/fdt/fdt_machdep.c b/arch/evbarm/fdt/fdt_machdep.c
index ec4800a2..0c25742d 100644
--- a/arch/evbarm/fdt/fdt_machdep.c
+++ b/arch/evbarm/fdt/fdt_machdep.c
@@ -488,7 +488,7 @@ initarm(void *arg)
 	uint64_t memory_start, memory_end;
 
 	/* set temporally to work printf()/panic() even before consinit() */
-	cn_tab = &earlycons;
+	(void) earlycons;
 
 	/* Load FDT */
 	int error = fdt_check_header(fdt_addr_r);
diff --git a/dev/fdt/simplefb.c b/dev/fdt/simplefb.c
index d766538e..a11d1616 100644
--- a/dev/fdt/simplefb.c
+++ b/dev/fdt/simplefb.c
@@ -159,6 +159,8 @@ simplefb_attach_genfb(struct simplefb_softc *sc)
 		depth = 32;
 	} else if (strcmp(format, "r5g6b5") == 0) {
 		depth = 16;
+	} else if (strcmp(format, "r8g8b8") == 0) {
+		depth = 24;
 	} else {
 		aprint_error(": unsupported format '%s'\n", format);
 		return ENXIO;
diff --git a/external/gpl2/dts/dist/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts b/external/gpl2/dts/dist/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
index b3b04736..2587cd01 100644
--- a/external/gpl2/dts/dist/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
+++ b/external/gpl2/dts/dist/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
@@ -7,6 +7,8 @@
 #include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
 
 / {
+	qcom,msm-id = <0x7e 0x96 0x20002 0x2b>;
+
 	model = "LGE MSM 8974 HAMMERHEAD";
 	compatible = "lge,hammerhead", "qcom,msm8974";
 
@@ -15,7 +17,17 @@
 	};
 
 	chosen {
-		stdout-path = "serial0:115200n8";
+		stdout-path = "/chosen/framebuffer";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		framebuffer0: framebuffer@d200000 {
+		    compatible = "simple-framebuffer";
+		    reg = <0x0D200000 6220800>;
+		    width = <1080>;
+		    height = <1920>;
+		    stride = <3240>;
+		    format = "r8g8b8";
+		};
 	};
 
 	smd {
diff --git a/kern/init_main.c b/kern/init_main.c
index 5604495e..64527644 100644
--- a/kern/init_main.c
+++ b/kern/init_main.c
@@ -933,6 +933,7 @@ check_console(struct lwp *l)
 	if (error == 0) {
 		vrele(vp);
 	} else if (error == ENOENT) {
+printf("%s: ENOENT\n", __func__);
 		if (boothowto & (AB_VERBOSE|AB_DEBUG))
 			printf("warning: no /dev/console\n");
 	} else {
diff --git a/uvm/uvm_page.c b/uvm/uvm_page.c
index 8edf2ed8..bb4783d7 100644
--- a/uvm/uvm_page.c
+++ b/uvm/uvm_page.c
@@ -424,6 +424,11 @@ uvm_page_init(vaddr_t *kvm_startp, vaddr_t *kvm_endp)
 		    (cpuarray + (lcv * uvmexp.ncolors));
 		uvm_page_init_buckets(&uvm.cpus[0]->page_free[lcv]);
 	}
+	/*
+	 * See arch/arm/arm/cpufunc_asm_armv7.S for notes about line
+         * NEXUSTROUBLE003
+	 */
+	/* The next line is NEXUSTROUBLE003 */
 	memset(pagearray, 0, pagecount * sizeof(struct vm_page));
 
 	/*


Home | Main Index | Thread Index | Old Index