Skip to contentSkip to conversation

arm: Tegra2: add support for A9 CPU init

PATCH Superseded Tom Warren 3 participants 7 messages Mar 18, 2011 – Mar 25, 2011

Subsystems (3)

v2 of 5 Superseded Latest is v5 →

lore
Share & tools
lore

Tom Warren

author
#0 lore raw

PATCH v2 1/1 arm: Tegra2: add support for A9 CPU init

---
Changes for V2:
- Remove returns in void functions
- Move inline assembly code to .S file
- Simplify some if/else code, break out common code
- Minimize the use of local vars
- Inline some single-instance functions
- Remove TRUE/FALSE define, use 1/0 instead
- Replace memset of mem-mapped regs w/loop of writel's

 arch/arm/cpu/armv7/start.S                 |   12 +
 arch/arm/cpu/armv7/tegra2/Makefile         |    2 +-
 arch/arm/cpu/armv7/tegra2/ap20.c           |  366 ++++++++++++++++++++++++++++
 arch/arm/cpu/armv7/tegra2/ap20.h           |  105 ++++++++
 arch/arm/cpu/armv7/tegra2/lowlevel_init.S  |   70 ++++++
 arch/arm/include/asm/arch-tegra2/clk_rst.h |   27 ++
 arch/arm/include/asm/arch-tegra2/pmc.h     |    8 +
 arch/arm/include/asm/arch-tegra2/scu.h     |   43 ++++
 arch/arm/include/asm/arch-tegra2/tegra2.h  |    5 +
 board/nvidia/common/board.c                |   10 +
 board/nvidia/common/board.h                |   29 +++
 include/configs/harmony.h                  |    1 +
 include/configs/seaboard.h                 |    3 +-
 include/configs/tegra2-common.h            |    2 +
 14 files changed, 681 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/tegra2/ap20.c
 create mode 100644 arch/arm/cpu/armv7/tegra2/ap20.h
 create mode 100644 arch/arm/include/asm/arch-tegra2/scu.h
 create mode 100644 board/nvidia/common/board.h
arch/arm/cpu/armv7/start.S +12 -0
index cb4f92f..4b36693 100644
@@ -70,6 +70,18 @@ _end_vect:
 _TEXT_BASE:
 	.word	CONFIG_SYS_TEXT_BASE
 
+#ifdef CONFIG_TEGRA2
+/*
+ * Tegra2 uses 2 separate CPUs - the AVP (ARM7TDMI) and the CPU (dual A9s).
+ * U-Boot runs on the AVP first, setting things up for the CPU (PLLs,
+ * muxes, clocks, clamps, etc.). Then the AVP halts, and expects the CPU
+ * to pick up its reset vector, which points here.
+ */
+.globl _armboot_start
+_armboot_start:
+        .word _start
+#endif
+
 /*
  * These are defined in the board-specific linker script.
  */
arch/arm/cpu/armv7/tegra2/Makefile +1 -1
index 687c887..f1ea915 100644
@@ -28,7 +28,7 @@ include $(TOPDIR)/config.mk
 LIB	=  $(obj)lib$(SOC).o
 
 SOBJS	:= lowlevel_init.o
-COBJS	:= board.o sys_info.o timer.o
+COBJS	:= ap20.o board.o sys_info.o timer.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
arch/arm/cpu/armv7/tegra2/ap20.c new file +366 -0

366 lines not on this page · raw message

arch/arm/cpu/armv7/tegra2/ap20.h new file +105 -0

105 lines not on this page · raw message

arch/arm/cpu/armv7/tegra2/lowlevel_init.S +70 -0

82 lines not on this page · raw message

arch/arm/include/asm/arch-tegra2/clk_rst.h +27 -0
index 6d573bf..d67a5d7 100644
@@ -149,6 +149,9 @@ struct clk_rst_ctlr {
 	uint crc_clk_src_csite;		/*_CSITE_0,		0x1D4 */
 	uint crc_reserved19[9];		/*			0x1D8-1F8 */
 	uint crc_clk_src_osc;		/*_OSC_0,		0x1FC */
+	uint crc_reserved20[80];	/*			0x200-33C */
+	uint crc_cpu_cmplx_set;		/* _CPU_CMPLX_SET_0,	0x340 */
+	uint crc_cpu_cmplx_clr;		/* _CPU_CMPLX_CLR_0,	0x344 */
 };
 
 #define PLL_BYPASS		(1 << 31)
@@ -162,4 +165,28 @@ struct clk_rst_ctlr {
 #define SWR_UARTA_RST		(1 << 6)
 #define CLK_ENB_UARTA		(1 << 6)
 
+#define SWR_CPU_RST		(1 << 0)
+#define CLK_ENB_CPU		(1 << 0)
+#define SWR_CSITE_RST		(1 << 9)
+#define CLK_ENB_CSITE		(1 << 9)
+
+#define SET_CPURESET0		(1 << 0)
+#define SET_DERESET0		(1 << 4)
+#define SET_DBGRESET0		(1 << 12)
+
+#define SET_CPURESET1		(1 << 1)
+#define SET_DERESET1		(1 << 5)
+#define SET_DBGRESET1		(1 << 13)
+
+#define CLR_CPURESET0		(1 << 0)
+#define CLR_DERESET0		(1 << 4)
+#define CLR_DBGRESET0		(1 << 12)
+
+#define CLR_CPURESET1		(1 << 1)
+#define CLR_DERESET1		(1 << 5)
+#define CLR_DBGRESET1		(1 << 13)
+
+#define CPU0_CLK_STP		(1 << 8)
+#define CPU1_CLK_STP		(1 << 9)
+
 #endif	/* CLK_RST_H */
arch/arm/include/asm/arch-tegra2/pmc.h +8 -0
index 7ec9eeb..b1d47cd 100644
@@ -121,4 +121,12 @@ struct pmc_ctlr {
 	uint pmc_gate;			/* _GATE_0, offset 15C */
 };
 
+#define CPU_PWRED	1
+#define CPU_CLMP	1
+
+#define PARTID_CP	0xFFFFFFF8
+#define START_CP	(1 << 8)
+
+#define CPUPWRREQ_OE	(1 << 16)
+
 #endif	/* PMC_H */
arch/arm/include/asm/arch-tegra2/scu.h new file +43 -0

43 lines not on this page · raw message

arch/arm/include/asm/arch-tegra2/tegra2.h +5 -0
index 9001b68..5813cd9 100644
@@ -25,8 +25,12 @@
 #define _TEGRA2_H_
 
 #define NV_PA_SDRAM_BASE	0x00000000
+#define NV_PA_ARM_PERIPHBASE	0x50040000
+#define NV_PA_PG_UP_BASE	0x60000000
 #define NV_PA_TMRUS_BASE	0x60005010
 #define NV_PA_CLK_RST_BASE	0x60006000
+#define NV_PA_FLOW_BASE		0x60007000
+#define NV_PA_EVP_BASE		0x6000F000
 #define NV_PA_APB_MISC_BASE	0x70000000
 #define NV_PA_APB_UARTA_BASE	(NV_PA_APB_MISC_BASE + 0x6000)
 #define NV_PA_APB_UARTB_BASE	(NV_PA_APB_MISC_BASE + 0x6040)
@@ -34,6 +38,7 @@
 #define NV_PA_APB_UARTD_BASE	(NV_PA_APB_MISC_BASE + 0x6300)
 #define NV_PA_APB_UARTE_BASE	(NV_PA_APB_MISC_BASE + 0x6400)
 #define NV_PA_PMC_BASE		0x7000E400
+#define NV_PA_CSITE_BASE	0x70040000
 
 #define TEGRA2_SDRC_CS0		NV_PA_SDRAM_BASE
 #define LOW_LEVEL_SRAM_STACK	0x4000FFFC
board/nvidia/common/board.c +10 -0
index b2c412c..078547b 100644
@@ -30,6 +30,7 @@
 #include <asm/arch/clk_rst.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/uart.h>
+#include "board.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -37,6 +38,15 @@ const struct tegra2_sysinfo sysinfo = {
 	CONFIG_TEGRA2_BOARD_STRING
 };
 
+#ifdef CONFIG_BOARD_EARLY_INIT_F
+int board_early_init_f(void)
+{
+	debug("Board Early Init\n");
+	tegra2_start();
+	return 0;
+}
+#endif	/* EARLY_INIT */
+
 /*
  * Routine: timer_init
  * Description: init the timestamp and lastinc value
board/nvidia/common/board.h new file +29 -0
new file mode 100644
index 0000000..47c7885
@@ -0,0 +1,29 @@
+/*
+ *  (C) Copyright 2010,2011
+ *  NVIDIA Corporation <www.nvidia.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+void tegra2_start(void);
+
+#endif	/* BOARD_H */
include/configs/harmony.h +1 -0
index d004f31..34bd899 100644
@@ -46,4 +46,5 @@
 #define CONFIG_MACH_TYPE		MACH_TYPE_HARMONY
 #define CONFIG_SYS_BOARD_ODMDATA	0x300d8011 /* lp1, 1GB */
 
+#define CONFIG_BOARD_EARLY_INIT_F
 #endif /* __CONFIG_H */
include/configs/seaboard.h +2 -1
index fd87560..06ce3e2 100644
@@ -37,7 +37,8 @@
 #define CONFIG_TEGRA2_ENABLE_UARTD
 #define CONFIG_SYS_NS16550_COM1		NV_PA_APB_UARTD_BASE
 
-#define CONFIG_MACH_TYPE		MACH_TYPE_TEGRA_SEABOARD
+#define CONFIG_MACH_TYPE		MACH_TYPE_SEABOARD
 #define CONFIG_SYS_BOARD_ODMDATA	0x300d8011 /* lp1, 1GB */
 
+#define CONFIG_BOARD_EARLY_INIT_F
 #endif /* __CONFIG_H */
include/configs/tegra2-common.h +2 -0
index 4f4374a..2924325 100644
@@ -33,6 +33,8 @@
 #define CONFIG_MACH_TEGRA_GENERIC	/* which is a Tegra generic machine */
 #define CONFIG_L2_OFF			/* No L2 cache */
 
+#define CONFIG_ENABLE_CORTEXA9		/* enable CPU (A9 complex) */
+
 #include <asm/arch/tegra2.h>		/* get chip and board defs */
 
 /*
Signature · 1 line
1.7.4.1
#1 lore raw

PATCH v2 1/1 arm: Tegra2: add support for A9 CPU init

Hi Tom,
Things look pretty good. Minor comments/questions below.

<snip>

Quoted 25 lines
arch/arm/cpu/armv7/tegra2/ap20.c new file +25 -0
+/*
+ * TBD: Move cold_boot() to assembly file.
+ * Values/offsets of the table vars make this difficult.
+ */
+
+void cold_boot(void)
+{
+	asm volatile(
+		"msr	cpsr_c, #0xD3	\n"
+		/*
+		* Check current processor: CPU or AVP?
+		* If CPU, go to CPU boot code, else continue on AVP path.
+		*/
+		"mov	r0, %0		\n"
+		"ldrb	r2, [r0, %1]	\n"
+		/* are we the CPU? */
+		"cmp	r2, %2		\n"
+		"mov	sp, %3		\n"
+		/*  yep, we are the CPU */
+		"bxeq	%4		\n"
+
+		/* AVP initialization follows this path */
+		"mov	sp, %5		\n"
+		/* Init and start CPU */
+		"b	startup_cpu	\n"

arch/arm/cpu/armv7/tegra2/ap20.c line 366

Quoted 10 lines
arch/arm/cpu/armv7/tegra2/ap20.c new file +10 -0
+		:
+		: "i"(NV_PA_PG_UP_BASE),
+		"i"(PG_UP_TAG_0),
+		"r"(proc_tag),
+		"r"(cpu_boot_stack),
+		"r"(_armboot_start),
+		"r"(avp_boot_stack)
+		: "r0", "r2", "cc", "lr"
+	);
+}

What errors did you encounter when this was in the assembly file? It'd be nice to put it there now. Likely it will never get fixed if it doesn't implemented correctly off the bat. If you post the errors perhaps someone on the list can provide insight.

<snip>

Quoted 9 lines

+.globl startup_cpu

arch/arm/cpu/armv7/tegra2/lowlevel_init.S +8 -0
+startup_cpu:
+	@ Initialize the AVP, clocks, and memory controller
+	@ SDRAM is guaranteed to be on at this point
+
+	ldr     r0, =cold_boot			@ R0 = reset vector for CPU
+	bl      start_cpu			@ start the CPU
+
+	@ Transfer control to the AVP code */

arch/arm/cpu/armv7/tegra2/lowlevel_init.S lowlevel_init: · line 81

Quoted 10 lines
arch/arm/cpu/armv7/tegra2/lowlevel_init.S +10 -0
+	bl      halt_avp
+
+	@ Should never get here
+_loop_forever2:
+	b	_loop_forever2
+
+.globl cache_configure
+cache_configure:
+	stmdb r13!,{r14}
+@	/* invalidate instruction cache */

It looks like there's a combination of comment forms @, @ */, and @ /* */. Is there a reason not to use the normal /* */ universally?

Best,
Peter

author
#2 lore raw

PATCH v2 1/1 arm: Tegra2: add support for A9 CPU init

Peter,

Quoted 37 lines · Peter Tyser

Hi Tom,
Things look pretty good. ?Minor comments/questions below.

<snip>

Quoted 32 lines
(quoted diff) +32 -0
+/*
+ * TBD: Move cold_boot() to assembly file.
+ * Values/offsets of the table vars make this difficult.
+ */
+
+void cold_boot(void)
+{
+ ? ? asm volatile(
+ ? ? ? ? ? ? "msr ? ?cpsr_c, #0xD3 ? \n"
+ ? ? ? ? ? ? /*
+ ? ? ? ? ? ? * Check current processor: CPU or AVP?
+ ? ? ? ? ? ? * If CPU, go to CPU boot code, else continue on AVP path.
+ ? ? ? ? ? ? */
+ ? ? ? ? ? ? "mov ? ?r0, %0 ? ? ? ? ?\n"
+ ? ? ? ? ? ? "ldrb ? r2, [r0, %1] ? ?\n"
+ ? ? ? ? ? ? /* are we the CPU? */
+ ? ? ? ? ? ? "cmp ? ?r2, %2 ? ? ? ? ?\n"
+ ? ? ? ? ? ? "mov ? ?sp, %3 ? ? ? ? ?\n"
+ ? ? ? ? ? ? /* ?yep, we are the CPU */
+ ? ? ? ? ? ? "bxeq ? %4 ? ? ? ? ? ? ?\n"
+
+ ? ? ? ? ? ? /* AVP initialization follows this path */
+ ? ? ? ? ? ? "mov ? ?sp, %5 ? ? ? ? ?\n"
+ ? ? ? ? ? ? /* Init and start CPU */
+ ? ? ? ? ? ? "b ? ? ?startup_cpu ? ? \n"
+ ? ? ? ? ? ? :
+ ? ? ? ? ? ? : "i"(NV_PA_PG_UP_BASE),
+ ? ? ? ? ? ? "i"(PG_UP_TAG_0),
+ ? ? ? ? ? ? "r"(proc_tag),
+ ? ? ? ? ? ? "r"(cpu_boot_stack),
+ ? ? ? ? ? ? "r"(_armboot_start),
+ ? ? ? ? ? ? "r"(avp_boot_stack)
Quoted 8 lines
Quoted 3 lines

+ ? ? ? ? ? ? : "r0", "r2", "cc", "lr"
+ ? ? );
+}

What errors did you encounter when this was in the assembly file? ?It'd be nice to put it there now. ?Likely it will never get fixed if it doesn't implemented correctly off the bat. ?If you post the errors perhaps someone on the list can provide insight.

I didn't capture a log of the errors when I was trying to put the cold_boot code into lowlevel_init.S. But I saw fixup errors and undefined constant errors, all related to the #defines (NV_PG_UP_BASE, avp/cpu_boot_stack, etc.) and how the compiler/assembler references indirect and relative constants.

Note that this code works perfectly as-is, so there's no pressing need to move it to assembly now, except for a cosmetic/procedural one. I'd rather get this accepted into mainline, so I can move on to the eMMC/SPI/USB drivers so people can use the code to boot an OS on our (many) Tegra2 boards coming to market RSN.

If some ARM / gcc assembly wizard wants to attempt moving this code to a .S file, I welcome the help - I may even attack it at a later date, when I've got more bandwidth. But it isn't a priority for me right now, unless someone on the list adamantly opposes the code as-s. But I'd expect anyone with that strong an opinion about to be able to fix it, or at least attempt it and see why I decided to defer moving it to assembly for now.

Quoted 17 lines

<snip>

Quoted 14 lines

+.globl startup_cpu

(quoted diff) +13 -0
+startup_cpu:
+ ? ? @ Initialize the AVP, clocks, and memory controller
+ ? ? @ SDRAM is guaranteed to be on at this point
+
+ ? ? ldr ? ? r0, =cold_boot ? ? ? ? ? ? ? ? ?@ R0 = reset vector for CPU
+ ? ? bl ? ? ?start_cpu ? ? ? ? ? ? ? ? ? ? ? @ start the CPU
+
+ ? ? @ Transfer control to the AVP code */
+ ? ? bl ? ? ?halt_avp
+
+ ? ? @ Should never get here
+_loop_forever2:
+ ? ? b ? ? ? _loop_forever2
Quoted 8 lines

arch/arm/cpu/armv7/tegra2/lowlevel_init.S lowlevel_init:

Quoted 5 lines
arch/arm/cpu/armv7/tegra2/lowlevel_init.S +5 -0
+
+.globl cache_configure
+cache_configure:
+ ? ? stmdb r13!,{r14}
+@ ? ?/* invalidate instruction cache */

It looks like there's a combination of comment forms @, @ */, and @ /* */. ?Is there a reason not to use the normal /* */ universally?

No, just dross left over from moving the inline assembly from .c to .S. The rest of lowlevel_init.S uses @ for comments, so I tried to stick with that. I'l fix it, thanks.

Quoted 5 lines

Best,
Peter

Thanks,
Tom

#3 lore raw

PATCH v2 1/1 arm: Tegra2: add support for A9 CPU init

Quoted 60 lines · Tom Warren

Peter,

Quoted 37 lines · Peter Tyser

Hi Tom,
Things look pretty good. Minor comments/questions below.

<snip>

Quoted 32 lines
arch/arm/cpu/armv7/tegra2/ap20.c new file +32 -0
+/*
+ * TBD: Move cold_boot() to assembly file.
+ * Values/offsets of the table vars make this difficult.
+ */
+
+void cold_boot(void)
+{
+     asm volatile(
+             "msr    cpsr_c, #0xD3   \n"
+             /*
+             * Check current processor: CPU or AVP?
+             * If CPU, go to CPU boot code, else continue on AVP path.
+             */
+             "mov    r0, %0          \n"
+             "ldrb   r2, [r0, %1]    \n"
+             /* are we the CPU? */
+             "cmp    r2, %2          \n"
+             "mov    sp, %3          \n"
+             /*  yep, we are the CPU */
+             "bxeq   %4              \n"
+
+             /* AVP initialization follows this path */
+             "mov    sp, %5          \n"
+             /* Init and start CPU */
+             "b      startup_cpu     \n"
+             :
+             : "i"(NV_PA_PG_UP_BASE),
+             "i"(PG_UP_TAG_0),
+             "r"(proc_tag),
+             "r"(cpu_boot_stack),
+             "r"(_armboot_start),
+             "r"(avp_boot_stack)
Quoted 8 lines

arch/arm/cpu/armv7/tegra2/ap20.c line 366

Quoted 3 lines
arch/arm/cpu/armv7/tegra2/ap20.c new file +3 -0
+             : "r0", "r2", "cc", "lr"
+     );
+}

What errors did you encounter when this was in the assembly file? It'd be nice to put it there now. Likely it will never get fixed if it doesn't implemented correctly off the bat. If you post the errors perhaps someone on the list can provide insight.

I didn't capture a log of the errors when I was trying to put the cold_boot code into lowlevel_init.S. But I saw fixup errors and undefined constant errors, all related to the #defines (NV_PG_UP_BASE, avp/cpu_boot_stack, etc.) and how the compiler/assembler references indirect and relative constants.

Note that this code works perfectly as-is, so there's no pressing need to move it to assembly now, except for a cosmetic/procedural one. I'd rather get this accepted into mainline, so I can move on to the eMMC/SPI/USB drivers so people can use the code to boot an OS on our (many) Tegra2 boards coming to market RSN.

Quoted 7 lines

If some ARM / gcc assembly wizard wants to attempt moving this code to a .S file, I welcome the help - I may even attack it at a later date, when I've got more bandwidth. But it isn't a priority for me right now, unless someone on the list adamantly opposes the code as-s. But I'd expect anyone with that strong an opinion about to be able to fix it, or at least attempt it and see why I decided to defer moving it to assembly for now.

I understand your perspective, but why not spend the extra 30 minutes and do it the right way? Passing the buck to someone else who cares about maintaining high quality code isn't the right thing to do in my opinion. This patch isn't going to make it into the upcoming release, so it won't gate the other eMMC/SPI/USB drivers you want to add. The bar to get code into open source project generally is higher than "it works" - it has to adhere to the project's design principles and guidelines. U-Boot already needs cleanup as is without adding more cruft. Solving this small issue now results in cleaner code, less headache down the road, and shouldn't take long. As usual, I'm not the maintainer, so its just my $0.02.

Best,
Peter

author
#4 lore raw

PATCH v2 1/1 arm: Tegra2: add support for A9 CPU init

Peter,

Quoted 69 lines · Peter Tyser
Quoted 60 lines · Tom Warren

Peter,

Quoted 37 lines · Peter Tyser

Hi Tom,
Things look pretty good. ?Minor comments/questions below.

<snip>

Quoted 32 lines
(quoted diff) +32 -0
+/*
+ * TBD: Move cold_boot() to assembly file.
+ * Values/offsets of the table vars make this difficult.
+ */
+
+void cold_boot(void)
+{
+ ? ? asm volatile(
+ ? ? ? ? ? ? "msr ? ?cpsr_c, #0xD3 ? \n"
+ ? ? ? ? ? ? /*
+ ? ? ? ? ? ? * Check current processor: CPU or AVP?
+ ? ? ? ? ? ? * If CPU, go to CPU boot code, else continue on AVP path.
+ ? ? ? ? ? ? */
+ ? ? ? ? ? ? "mov ? ?r0, %0 ? ? ? ? ?\n"
+ ? ? ? ? ? ? "ldrb ? r2, [r0, %1] ? ?\n"
+ ? ? ? ? ? ? /* are we the CPU? */
+ ? ? ? ? ? ? "cmp ? ?r2, %2 ? ? ? ? ?\n"
+ ? ? ? ? ? ? "mov ? ?sp, %3 ? ? ? ? ?\n"
+ ? ? ? ? ? ? /* ?yep, we are the CPU */
+ ? ? ? ? ? ? "bxeq ? %4 ? ? ? ? ? ? ?\n"
+
+ ? ? ? ? ? ? /* AVP initialization follows this path */
+ ? ? ? ? ? ? "mov ? ?sp, %5 ? ? ? ? ?\n"
+ ? ? ? ? ? ? /* Init and start CPU */
+ ? ? ? ? ? ? "b ? ? ?startup_cpu ? ? \n"
+ ? ? ? ? ? ? :
+ ? ? ? ? ? ? : "i"(NV_PA_PG_UP_BASE),
+ ? ? ? ? ? ? "i"(PG_UP_TAG_0),
+ ? ? ? ? ? ? "r"(proc_tag),
+ ? ? ? ? ? ? "r"(cpu_boot_stack),
+ ? ? ? ? ? ? "r"(_armboot_start),
+ ? ? ? ? ? ? "r"(avp_boot_stack)
Quoted 8 lines
Quoted 3 lines

+ ? ? ? ? ? ? : "r0", "r2", "cc", "lr"
+ ? ? );
+}

What errors did you encounter when this was in the assembly file? ?It'd be nice to put it there now. ?Likely it will never get fixed if it doesn't implemented correctly off the bat. ?If you post the errors perhaps someone on the list can provide insight.

I didn't capture a log of the errors when I was trying to put the cold_boot code into lowlevel_init.S. But I saw fixup errors and undefined constant errors, all related to the #defines (NV_PG_UP_BASE, avp/cpu_boot_stack, etc.) and how the compiler/assembler references indirect and relative constants.

Note that this code works perfectly as-is, so there's no pressing need to move it to assembly now, except for a cosmetic/procedural one. I'd rather get this accepted into mainline, so I can move on to the eMMC/SPI/USB drivers so people can use the code to boot an OS on our (many) Tegra2 boards coming to market RSN.

Quoted 7 lines

If some ARM / gcc assembly wizard wants to attempt moving this code to a .S file, I welcome the help - I may even attack it at a later date, when I've got more bandwidth. But it isn't a priority for me right now, unless someone on the list adamantly opposes the code as-s. But I'd expect anyone with that strong an opinion about to be able to fix it, or at least attempt it and see why I decided to defer moving it to assembly for now.

Quoted 11 lines

I understand your perspective, but why not spend the extra 30 minutes and do it the right way? ?Passing the buck to someone else who cares about maintaining high quality code isn't the right thing to do in my opinion. ?This patch isn't going to make it into the upcoming release, so it won't gate the other eMMC/SPI/USB drivers you want to add. ?The bar to get code into open source project generally is higher than "it works" - it has to adhere to the project's design principles and guidelines. ?U-Boot already needs cleanup as is without adding more cruft. ?Solving this small issue now results in cleaner code, less headache down the road, and shouldn't take long. ?As usual, I'm not the maintainer, so its just my $0.02.

FWIW, I spent _far_ more than 30 minutes on this .. close to a full day of frustration/banging my head against the wall. I have other priorities besides upstreaming Tegra2 U-Boot support, and I can't justify spending days on this. As I originally stated, I'm no expert in the intricacies of ARM asm programming - my expertise is in x86 CPUs, and hit a wall with this port to assembly.

I'm not passing the buck, and while I agree that this code is not the cleanest I've seen, I don't think I'm pushing low-quality code here. It's 8 lines of embedded assembly, plus a table. Looking at what the C compiler produces in assembly, it's twice as long, pushes some of the tabled values on the stack and then pulls them back into registers, and is, IMHO, harder to understand. I could just cut-and-paste the compiler output into lowlevel_init.S, and add some comments, but is that really any better? Is the goal to get clean, understandable code, or messier, harder to parse code in the right files?

As to adhering to U-Boot's design principles and guidelines, could you point me to the section on embedded assembly in C files? I don't remember seeing a specific section on that topic, don't see it under U-Boot Coding Style, nor in the Linux coding guidelines, and I'd like to reference it for future use.

For now, I'm going to let this percolate, as I have other fish to fry.

Thanks for your input,

Tom

Quoted 5 lines

Best,
Peter

#5 lore raw

PATCH v2 1/1 arm: Tegra2: add support for A9 CPU init

Quoted 83 lines · Tom Warren

Peter,

Quoted 69 lines · Peter Tyser
Quoted 60 lines · Tom Warren

Peter,

Quoted 37 lines · Peter Tyser

Hi Tom,
Things look pretty good. Minor comments/questions below.

<snip>

Quoted 32 lines
arch/arm/cpu/armv7/tegra2/ap20.c new file +32 -0
+/*
+ * TBD: Move cold_boot() to assembly file.
+ * Values/offsets of the table vars make this difficult.
+ */
+
+void cold_boot(void)
+{
+     asm volatile(
+             "msr    cpsr_c, #0xD3   \n"
+             /*
+             * Check current processor: CPU or AVP?
+             * If CPU, go to CPU boot code, else continue on AVP path.
+             */
+             "mov    r0, %0          \n"
+             "ldrb   r2, [r0, %1]    \n"
+             /* are we the CPU? */
+             "cmp    r2, %2          \n"
+             "mov    sp, %3          \n"
+             /*  yep, we are the CPU */
+             "bxeq   %4              \n"
+
+             /* AVP initialization follows this path */
+             "mov    sp, %5          \n"
+             /* Init and start CPU */
+             "b      startup_cpu     \n"
+             :
+             : "i"(NV_PA_PG_UP_BASE),
+             "i"(PG_UP_TAG_0),
+             "r"(proc_tag),
+             "r"(cpu_boot_stack),
+             "r"(_armboot_start),
+             "r"(avp_boot_stack)
Quoted 8 lines

arch/arm/cpu/armv7/tegra2/ap20.c line 366

Quoted 3 lines
arch/arm/cpu/armv7/tegra2/ap20.c new file +3 -0
+             : "r0", "r2", "cc", "lr"
+     );
+}

What errors did you encounter when this was in the assembly file? It'd be nice to put it there now. Likely it will never get fixed if it doesn't implemented correctly off the bat. If you post the errors perhaps someone on the list can provide insight.

I didn't capture a log of the errors when I was trying to put the cold_boot code into lowlevel_init.S. But I saw fixup errors and undefined constant errors, all related to the #defines (NV_PG_UP_BASE, avp/cpu_boot_stack, etc.) and how the compiler/assembler references indirect and relative constants.

Note that this code works perfectly as-is, so there's no pressing need to move it to assembly now, except for a cosmetic/procedural one. I'd rather get this accepted into mainline, so I can move on to the eMMC/SPI/USB drivers so people can use the code to boot an OS on our (many) Tegra2 boards coming to market RSN.

Quoted 7 lines

If some ARM / gcc assembly wizard wants to attempt moving this code to a .S file, I welcome the help - I may even attack it at a later date, when I've got more bandwidth. But it isn't a priority for me right now, unless someone on the list adamantly opposes the code as-s. But I'd expect anyone with that strong an opinion about to be able to fix it, or at least attempt it and see why I decided to defer moving it to assembly for now.

Quoted 11 lines

I understand your perspective, but why not spend the extra 30 minutes and do it the right way? Passing the buck to someone else who cares about maintaining high quality code isn't the right thing to do in my opinion. This patch isn't going to make it into the upcoming release, so it won't gate the other eMMC/SPI/USB drivers you want to add. The bar to get code into open source project generally is higher than "it works" - it has to adhere to the project's design principles and guidelines. U-Boot already needs cleanup as is without adding more cruft. Solving this small issue now results in cleaner code, less headache down the road, and shouldn't take long. As usual, I'm not the maintainer, so its just my $0.02.

Quoted 6 lines

FWIW, I spent _far_ more than 30 minutes on this .. close to a full day of frustration/banging my head against the wall. I have other priorities besides upstreaming Tegra2 U-Boot support, and I can't justify spending days on this. As I originally stated, I'm no expert in the intricacies of ARM asm programming - my expertise is in x86 CPUs, and hit a wall with this port to assembly.

Understood. When situations like that happen its good to ask others for input rather than using a non-optimal solution. Then either
- Someone suggests how to fix the code, and the code improves.
- No one helps, which implies your method isn't easy to improve upon, you gave it a good effort, and so it gets included.

As is, the current patch looks like a non-optimal solution that someone familiar with ARM asm could have quickly helped with.

Quoted 2 lines

I'm not passing the buck, and while I agree that this code is not the cleanest I've seen, I don't think I'm pushing low-quality code here.

Based on the fact that you tried to fix it for a day, it sounds like you are aware its less than ideal implementation, and the "TBD" comment for the function further implies that this function doesn't belong here, and someone should fix it down the road. My guess is that this will likely never happen unless it gets fixed now.

Quoted 8 lines

It's 8 lines of embedded assembly, plus a table. Looking at what the C compiler produces in assembly, it's twice as long, pushes some of the tabled values on the stack and then pulls them back into registers, and is, IMHO, harder to understand. I could just cut-and-paste the compiler output into lowlevel_init.S, and add some comments, but is that really any better? Is the goal to get clean, understandable code, or messier, harder to parse code in the right files?

Quoted 5 lines

As to adhering to U-Boot's design principles and guidelines, could you point me to the section on embedded assembly in C files? I don't remember seeing a specific section on that topic, don't see it under U-Boot Coding Style, nor in the Linux coding guidelines, and I'd like to reference it for future use.

There isn't a specific section about inline assembly, similar to how there isn't documentation other general C rules like what goes in header files, when to split up a file into 2 files, why global variables should be avoided, etc. The general rule is that inline assembly should only be used in when necessary in rare cases like low-level control/access of the CPU, special optimizations in critical paths, etc.

Quoted 1 line

For now, I'm going to let this percolate, as I have other fish to fry.

Sounds good. I understand the schedule vs perfection issue - I'm just voicing my opinions based on how I'd write the code with my infinite free time, which ultimately doesn't carry a whole lot of weight:) Regardless of how it works out its great seeing Nvidia push their code upstream.

Best,
Peter

#6 lore raw

PATCH v2 1/1 arm: Tegra2: add support for A9 CPU init

In reply to Tom Warren
Quoted 2 lines

FWIW, I spent _far_ more than 30 minutes on this .. close to a full day of frustration/banging my head against the wall. [...]

I understand the feeling.

I'm one of those who suggested (but not required) to put full-asm function in .S files for a reason; I personally think the reboot code may remain as it is, given the effort involved. There are minor details that may be better, but since I'm unable to suggest (and at least compile-test) them for lack of time, I'm not even listing them.

Thank you very much for your efforts in following previous suggestions.

/alessandro