Skip to contentSkip to conversation

Add ARMv7M STM32F1 and STM3210E-EVAL board support

PATCH Superseded Matt Porter 3 participants 16 messages Apr 21, 2015

Subsystems (3)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

v2 cover Add ARMv7M STM32F1 and STM3210E-EVAL board support

This series adds support for the STM32F1 SoC family and the STM3210E-EVAL board on top of the STM32F4 SoC family support [1].

Since this board has no DRAM the first patch fixes the build when CONFIG_NR_DRAM_BANKS is not set. A patch is also required to force the processor to stay in Thumb mode when 'go'ing to an application.

As the STM32F1 differs greatly from STM32F4 in flash and clock layout, there's a separate subdirectory for the STM32F1 family. The gpio and serial drivers are shared as these peripherals are mostly similar with only the pinmux bits being significantly different in the gpio driver.

The STM3210E-EVAL board is supported with 1MiB Flash and 96KiB of SRAM on the STM32F103ZGT6, USART1 for console, and four user LEDs.

[1] http://lists.denx.de/pipermail/u-boot/2015-March/206640.html

Matt Porter (6):
image: fix build when CONFIG_NR_DRAM_BANKS is disabled on ARM common/cmd_boot: keep ARM v7M in thumb mode during do_go_exec()
ARMv7M: add STM32F1 support
gpio: stm32: add stm32f1 support
serial: stm32: add stm32f1 support
board: add stm3210e-eval board support

 arch/arm/Kconfig                          |   5 +
 arch/arm/cpu/armv7m/Makefile              |   1 +
 arch/arm/cpu/armv7m/stm32f1/Makefile      |  13 ++
 arch/arm/cpu/armv7m/stm32f1/clock.c       | 195 ++++++++++++++++++++++++++++++
 arch/arm/cpu/armv7m/stm32f1/flash.c       | 179 +++++++++++++++++++++++++++
 arch/arm/cpu/armv7m/stm32f1/soc.c         |  35 ++++++
 arch/arm/cpu/armv7m/stm32f1/timer.c       | 120 ++++++++++++++++++
 arch/arm/include/asm/arch-stm32f1/gpio.h  | 117 ++++++++++++++++++
 arch/arm/include/asm/arch-stm32f1/stm32.h | 115 ++++++++++++++++++
 board/st/stm3210e-eval/Kconfig            |  19 +++
 board/st/stm3210e-eval/MAINTAINERS        |   5 +
 board/st/stm3210e-eval/Makefile           |  13 ++
 board/st/stm3210e-eval/stm3210e-eval.c    |  85 +++++++++++++
 common/cmd_boot.c                         |   4 +
 common/image.c                            |   2 +-
 configs/stm3210e-eval_defconfig           |   3 +
 drivers/gpio/stm32_gpio.c                 | 109 ++++++++++++++++-
 drivers/serial/serial_stm32.c             |   9 ++
 include/configs/stm3210e-eval.h           | 117 ++++++++++++++++++
 include/flash.h                           |   1 +
 20 files changed, 1145 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/cpu/armv7m/stm32f1/Makefile
 create mode 100644 arch/arm/cpu/armv7m/stm32f1/clock.c
 create mode 100644 arch/arm/cpu/armv7m/stm32f1/flash.c
 create mode 100644 arch/arm/cpu/armv7m/stm32f1/soc.c
 create mode 100644 arch/arm/cpu/armv7m/stm32f1/timer.c
 create mode 100644 arch/arm/include/asm/arch-stm32f1/gpio.h
 create mode 100644 arch/arm/include/asm/arch-stm32f1/stm32.h
 create mode 100644 board/st/stm3210e-eval/Kconfig
 create mode 100644 board/st/stm3210e-eval/MAINTAINERS
 create mode 100644 board/st/stm3210e-eval/Makefile
 create mode 100644 board/st/stm3210e-eval/stm3210e-eval.c
 create mode 100644 configs/stm3210e-eval_defconfig
 create mode 100644 include/configs/stm3210e-eval.h
Signature · 1 line
2.1.0
#1 lore raw

PATCH v2 1/6 image: fix build when CONFIG_NR_DRAM_BANKS is disabled on ARM

common/image.c currently implicitly depends on CONFIG_NR_DRAM_BANKS when CONFIG_ARM is enabled. Make this requirement explicit.

---
 common/image.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
common/image.c +1 -1
index 162b682..73c24f5 100644
@@ -461,7 +461,7 @@ phys_size_t getenv_bootm_size(void)
 		tmp = 0;
 
 
-#if defined(CONFIG_ARM)
+#if defined(CONFIG_ARM) && defined(CONFIG_NR_DRAM_BANKS)
 	return gd->bd->bi_dram[0].size - tmp;
 #else
 	return gd->bd->bi_memsize - tmp;
Signature · 1 line
2.1.0
#2 lore raw

PATCH v2 2/6 common/cmd_boot: keep ARM v7M in thumb mode during do_go_exec()

In reply to Matt Porter

On ARM v7M, the processor will return to ARM mode when executing a blx instruction with bit 0 of the address == 0. Always set it to 1 to stay in thumb mode.

---
 common/cmd_boot.c | 4 ++++
 1 file changed, 4 insertions(+)
common/cmd_boot.c +4 -0
index 8f2e070..20ce652 100644
@@ -38,6 +38,10 @@ static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	 * pass address parameter as argv[0] (aka command name),
 	 * and all remaining args
 	 */
+#ifdef CONFIG_CPU_V7M
+	/* For ARM V7M, set bit zero to stay in Thumb mode */
+	addr++;
+#endif
 	rc = do_go_exec ((void *)addr, argc - 1, argv + 1);
 	if (rc != 0) rcode = 1;
 
Signature · 1 line
2.1.0
#3 lore raw

PATCH v2 2/6 common/cmd_boot: keep ARM v7M in thumb mode during do_go_exec()

Quoted 2 lines · Matt Porter

On ARM v7M, the processor will return to ARM mode when executing a blx instruction with bit 0 of the address == 0. Always set it

but that's what the 'x' is for, right ? eXchange the CPU mode.

Quoted 12 lines

to 1 to stay in thumb mode.

---
 common/cmd_boot.c | 4 ++++
 1 file changed, 4 insertions(+)
common/cmd_boot.c +0 -0
index 8f2e070..20ce652 100644

common/cmd_boot.c static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) · line 44

Quoted 7 lines
common/cmd_boot.c +4 -0
@@ -38,6 +38,10 @@ static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	 * pass address parameter as argv[0] (aka command name),
 	 * and all remaining args
 	 */
+#ifdef CONFIG_CPU_V7M
+	/* For ARM V7M, set bit zero to stay in Thumb mode */
+	addr++;
+#endif

what if we were in ARM state when we reached this point ? You're now telling CPU to always switch to Thumb. Is this really what we want ?

From ARM's instruction manual:

"
The BX and BLX instructions can change the processor state from ARM to Thumb, or from Thumb to ARM.

BLX label always changes the state.

BX Rm and BLX Rm derive the target state from bit[0] of Rm:

if bit[0] of Rm is 0, the processor changes to, or remains in, ARM state

if bit[0] of Rm is 1, the processor changes to, or remains in, Thumb state.
"

Signature · 8 lines
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150421/a558332d/attachment.sig>
#4 lore raw

PATCH v2 2/6 common/cmd_boot: keep ARM v7M in thumb mode during do_go_exec()

Quoted 39 lines · Felipe Balbi
Quoted 2 lines · Matt Porter

On ARM v7M, the processor will return to ARM mode when executing a blx instruction with bit 0 of the address == 0. Always set it

but that's what the 'x' is for, right ? eXchange the CPU mode.

Quoted 12 lines

to 1 to stay in thumb mode.

---
 common/cmd_boot.c | 4 ++++
 1 file changed, 4 insertions(+)
common/cmd_boot.c +0 -0
index 8f2e070..20ce652 100644

common/cmd_boot.c static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) · line 44

Quoted 7 lines
common/cmd_boot.c +4 -0
@@ -38,6 +38,10 @@ static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	 * pass address parameter as argv[0] (aka command name),
 	 * and all remaining args
 	 */
+#ifdef CONFIG_CPU_V7M
+	/* For ARM V7M, set bit zero to stay in Thumb mode */
+	addr++;
+#endif

what if we were in ARM state when we reached this point ? You're now telling CPU to always switch to Thumb. Is this really what we want ?

From ARM's instruction manual:

"
The BX and BLX instructions can change the processor state from ARM to Thumb, or from Thumb to ARM.

BLX label always changes the state.

Quoted 8 lines

BX Rm and BLX Rm derive the target state from bit[0] of Rm:

if bit[0] of Rm is 0, the processor changes to, or remains in, ARM state

if bit[0] of Rm is 1, the processor changes to, or remains in, Thumb state.
"

oh wait, this is cortex-m, it's supposed to be thumb2 only, why do we even need that bit ?

Signature · 8 lines
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150421/2a2a9977/attachment.sig>
#5 lore raw

PATCH v2 2/6 common/cmd_boot: keep ARM v7M in thumb mode during do_go_exec()

Quoted 45 lines · Felipe Balbi
Quoted 44 lines · Felipe Balbi
Quoted 2 lines · Matt Porter

On ARM v7M, the processor will return to ARM mode when executing a blx instruction with bit 0 of the address == 0. Always set it

but that's what the 'x' is for, right ? eXchange the CPU mode.

Quoted 12 lines

to 1 to stay in thumb mode.

---
 common/cmd_boot.c | 4 ++++
 1 file changed, 4 insertions(+)
common/cmd_boot.c +0 -0
index 8f2e070..20ce652 100644

common/cmd_boot.c static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) · line 44

Quoted 7 lines
common/cmd_boot.c +4 -0
@@ -38,6 +38,10 @@ static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	 * pass address parameter as argv[0] (aka command name),
 	 * and all remaining args
 	 */
+#ifdef CONFIG_CPU_V7M
+	/* For ARM V7M, set bit zero to stay in Thumb mode */
+	addr++;
+#endif

what if we were in ARM state when we reached this point ? You're now telling CPU to always switch to Thumb. Is this really what we want ?

From ARM's instruction manual:

"
The BX and BLX instructions can change the processor state from ARM to Thumb, or from Thumb to ARM.

BLX label always changes the state.

BX Rm and BLX Rm derive the target state from bit[0] of Rm:

if bit[0] of Rm is 0, the processor changes to, or remains in, ARM state

Quoted 6 lines
Quoted 3 lines

if bit[0] of Rm is 1, the processor changes to, or remains in, Thumb state.
"

oh wait, this is cortex-m, it's supposed to be thumb2 only, why do we even need that bit ?

seems like it must be set for cortex-m, but then shouldn't this be done by GCC ? Are we, perhaps, using wrong GCC arguments when building for cortex-m ?

Signature · 8 lines
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150421/a9ebc26e/attachment.sig>
#6 lore raw

PATCH v2 2/6 common/cmd_boot: keep ARM v7M in thumb mode during do_go_exec()

Quoted 50 lines · Felipe Balbi
Quoted 49 lines · Felipe Balbi
Quoted 47 lines · Felipe Balbi
Quoted 2 lines · Matt Porter

On ARM v7M, the processor will return to ARM mode when executing a blx instruction with bit 0 of the address == 0. Always set it

but that's what the 'x' is for, right ? eXchange the CPU mode.

Quoted 12 lines

to 1 to stay in thumb mode.

---
 common/cmd_boot.c | 4 ++++
 1 file changed, 4 insertions(+)
common/cmd_boot.c +0 -0
index 8f2e070..20ce652 100644

common/cmd_boot.c static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) · line 44

Quoted 7 lines
common/cmd_boot.c +4 -0
@@ -38,6 +38,10 @@ static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	 * pass address parameter as argv[0] (aka command name),
 	 * and all remaining args
 	 */
+#ifdef CONFIG_CPU_V7M
+	/* For ARM V7M, set bit zero to stay in Thumb mode */
+	addr++;
+#endif

what if we were in ARM state when we reached this point ? You're now telling CPU to always switch to Thumb. Is this really what we want ?

From ARM's instruction manual:

"
The BX and BLX instructions can change the processor state from ARM to Thumb, or from Thumb to ARM.

BLX label always changes the state.

BX Rm and BLX Rm derive the target state from bit[0] of Rm:

if bit[0] of Rm is 0, the processor changes to, or remains in, ARM state

if bit[0] of Rm is 1, the processor changes to, or remains in, Thumb state.
"

Quoted 6 lines
Quoted 2 lines

oh wait, this is cortex-m, it's supposed to be thumb2 only, why do we even need that bit ?

seems like it must be set for cortex-m, but then shouldn't this be done by GCC ? Are we, perhaps, using wrong GCC arguments when building for cortex-m ?

From "make V=1":

	... -march=armv7-m -mthumb ...
$ arm-none-eabi-gcc -v
...
gcc version 4.8.3 20140913 (release) (4.8.3-11ubuntu1+11)

-Matt
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150421/15e57079/attachment.sig>

#7 lore raw

PATCH v2 2/6 common/cmd_boot: keep ARM v7M in thumb mode during do_go_exec()

In reply to Felipe Balbi
Quoted 5 lines · Felipe Balbi
Quoted 2 lines · Matt Porter

On ARM v7M, the processor will return to ARM mode when executing a blx instruction with bit 0 of the address == 0. Always set it

but that's what the 'x' is for, right ? eXchange the CPU mode.

Yes.

Quoted 7 lines
Quoted 7 lines

to 1 to stay in thumb mode.

---
 common/cmd_boot.c | 4 ++++
 1 file changed, 4 insertions(+)
Quoted 15 lines

common/cmd_boot.c static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) · line 44

Quoted 12 lines
common/cmd_boot.c +4 -0
index 8f2e070..20ce652 100644
@@ -38,6 +38,10 @@ static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	 * pass address parameter as argv[0] (aka command name),
 	 * and all remaining args
 	 */
+#ifdef CONFIG_CPU_V7M
+	/* For ARM V7M, set bit zero to stay in Thumb mode */
+	addr++;
+#endif

what if we were in ARM state when we reached this point ? You're now telling CPU to always switch to Thumb. Is this really what we want ?

We have no ARM state on this core so that's not possible.

Quoted 10 lines

From ARM's instruction manual:

"
The BX and BLX instructions can change the processor state from ARM to Thumb, or from Thumb to ARM.

BLX label always changes the state.

Quoted 7 lines

BX Rm and BLX Rm derive the target state from bit[0] of Rm:

if bit[0] of Rm is 0, the processor changes to, or remains in, ARM state

if bit[0] of Rm is 1, the processor changes to, or remains in, Thumb state.

Correct. The last statement is why this patch exists. There is no ARM mode on M3, we immediately fault. Having bit[0]=0 for BX/BLX is not permitted on V7M...something not covered in the generic description of these instructions.

Incidentally, I forgot to update this with Kamil's comment that it should be implemented as |1 and will address that now.

-Matt
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150421/58245ca2/attachment.sig>

#8 lore raw

PATCH v2 2/6 common/cmd_boot: keep ARM v7M in thumb mode during do_go_exec()

Quoted 49 lines · Matt Porter
Quoted 5 lines · Felipe Balbi
Quoted 2 lines · Matt Porter

On ARM v7M, the processor will return to ARM mode when executing a blx instruction with bit 0 of the address == 0. Always set it

but that's what the 'x' is for, right ? eXchange the CPU mode.

Yes.

Quoted 7 lines
Quoted 7 lines

to 1 to stay in thumb mode.

---
 common/cmd_boot.c | 4 ++++
 1 file changed, 4 insertions(+)
Quoted 15 lines

common/cmd_boot.c static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) · line 44

Quoted 12 lines
common/cmd_boot.c +4 -0
index 8f2e070..20ce652 100644
@@ -38,6 +38,10 @@ static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	 * pass address parameter as argv[0] (aka command name),
 	 * and all remaining args
 	 */
+#ifdef CONFIG_CPU_V7M
+	/* For ARM V7M, set bit zero to stay in Thumb mode */
+	addr++;
+#endif

what if we were in ARM state when we reached this point ? You're now telling CPU to always switch to Thumb. Is this really what we want ?

We have no ARM state on this core so that's not possible.

Quoted 15 lines

From ARM's instruction manual:

"
The BX and BLX instructions can change the processor state from ARM to Thumb, or from Thumb to ARM.

BLX label always changes the state.

BX Rm and BLX Rm derive the target state from bit[0] of Rm:

if bit[0] of Rm is 0, the processor changes to, or remains in, ARM state

Quoted 7 lines
Quoted 2 lines

if bit[0] of Rm is 1, the processor changes to, or remains in, Thumb state.

Correct. The last statement is why this patch exists. There is no ARM mode on M3, we immediately fault. Having bit[0]=0 for BX/BLX is not permitted on V7M...something not covered in the generic description of these instructions.

it just seems weird that bit0 wouldn't just be assume 1 by the core itself. I suppose as a consequence we can't use blx label with v7m either ? :-s

cheers

Signature · 8 lines
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150421/6da24df5/attachment.sig>
#9 lore raw

PATCH v2 2/6 common/cmd_boot: keep ARM v7M in thumb mode during do_go_exec()

Quoted 53 lines · Felipe Balbi
Quoted 52 lines · Matt Porter
Quoted 5 lines · Felipe Balbi
Quoted 2 lines · Matt Porter

On ARM v7M, the processor will return to ARM mode when executing a blx instruction with bit 0 of the address == 0. Always set it

but that's what the 'x' is for, right ? eXchange the CPU mode.

Yes.

Quoted 7 lines
Quoted 7 lines

to 1 to stay in thumb mode.

---
 common/cmd_boot.c | 4 ++++
 1 file changed, 4 insertions(+)
Quoted 15 lines

common/cmd_boot.c static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) · line 44

Quoted 12 lines
common/cmd_boot.c +4 -0
index 8f2e070..20ce652 100644
@@ -38,6 +38,10 @@ static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	 * pass address parameter as argv[0] (aka command name),
 	 * and all remaining args
 	 */
+#ifdef CONFIG_CPU_V7M
+	/* For ARM V7M, set bit zero to stay in Thumb mode */
+	addr++;
+#endif

what if we were in ARM state when we reached this point ? You're now telling CPU to always switch to Thumb. Is this really what we want ?

We have no ARM state on this core so that's not possible.

Quoted 17 lines

From ARM's instruction manual:

"
The BX and BLX instructions can change the processor state from ARM to Thumb, or from Thumb to ARM.

BLX label always changes the state.

BX Rm and BLX Rm derive the target state from bit[0] of Rm:

if bit[0] of Rm is 0, the processor changes to, or remains in, ARM state

if bit[0] of Rm is 1, the processor changes to, or remains in, Thumb state.

Quoted 8 lines
Quoted 4 lines

Correct. The last statement is why this patch exists. There is no ARM mode on M3, we immediately fault. Having bit[0]=0 for BX/BLX is not permitted on V7M...something not covered in the generic description of these instructions.

it just seems weird that bit0 wouldn't just be assume 1 by the core itself. I suppose as a consequence we can't use blx label with v7m either ? :-s

It also seems weird to me that it wouldn't just be ignored on anything armv7-m. Yes, blx label would be "very bad" which is why it is not supported on ARMv7-m :)

And to clarify for those listening at home... From The ARMv7-M Instruction Set Appendix A4.1.1:

"
Thumb interworking is held as bit [0] of an interworking address. Interworking addresses are used in the following instructions:
? BX or BLX
? an LDR or LDM that loads the PC.
ARMv7-M only supports the Thumb instruction execution state, therefore the value of address bit [0] must be 1 in interworking instructions, otherwise a fault occurs. All instructions ignore bit [0] and write bits [31:1]:?0? when updating the PC.
"

Also:

"
A7.7.19 BLX (register)
Branch with Link and Exchange calls a subroutine at an address and instruction set specified by a register.
ARMv7-M only supports the Thumb instruction set. An attempt to change the instruction execution state
causes the processor to take an exception on the instruction at the target address.
"

-Matt
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150421/ad0869f1/attachment.sig>

#10 lore raw

PATCH v2 2/6 common/cmd_boot: keep ARM v7M in thumb mode during do_go_exec()

In reply to Felipe Balbi
Quoted 53 lines · Felipe Balbi
Quoted 52 lines · Matt Porter
Quoted 5 lines · Felipe Balbi
Quoted 2 lines · Matt Porter

On ARM v7M, the processor will return to ARM mode when executing a blx instruction with bit 0 of the address == 0. Always set it

but that's what the 'x' is for, right ? eXchange the CPU mode.

Yes.

Quoted 7 lines
Quoted 7 lines

to 1 to stay in thumb mode.

---
 common/cmd_boot.c | 4 ++++
 1 file changed, 4 insertions(+)
Quoted 15 lines

common/cmd_boot.c static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) · line 44

Quoted 12 lines
common/cmd_boot.c +4 -0
index 8f2e070..20ce652 100644
@@ -38,6 +38,10 @@ static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	 * pass address parameter as argv[0] (aka command name),
 	 * and all remaining args
 	 */
+#ifdef CONFIG_CPU_V7M
+	/* For ARM V7M, set bit zero to stay in Thumb mode */
+	addr++;
+#endif

what if we were in ARM state when we reached this point ? You're now telling CPU to always switch to Thumb. Is this really what we want ?

We have no ARM state on this core so that's not possible.

Quoted 17 lines

From ARM's instruction manual:

"
The BX and BLX instructions can change the processor state from ARM to Thumb, or from Thumb to ARM.

BLX label always changes the state.

BX Rm and BLX Rm derive the target state from bit[0] of Rm:

if bit[0] of Rm is 0, the processor changes to, or remains in, ARM state

if bit[0] of Rm is 1, the processor changes to, or remains in, Thumb state.

Quoted 8 lines
Quoted 4 lines

Correct. The last statement is why this patch exists. There is no ARM mode on M3, we immediately fault. Having bit[0]=0 for BX/BLX is not permitted on V7M...something not covered in the generic description of these instructions.

it just seems weird that bit0 wouldn't just be assume 1 by the core itself. I suppose as a consequence we can't use blx label with v7m either ? :-s

At issue is that the code really reads like this (expanding the functions a little bit:
printf ("## Starting application at 0x%08lX ...\n", addr); rc = (void *)addr(argc - 1, argv + 1);

So the compiler translates this as "do what I say" and generates a branch to whatever addr is.

If people really feel strongly about it being too wierd to do "addr |= 1" in the common code, do_go_exec is a weak function and we can put something into arch/arm/lib/ (new file) that provides a do_go_exec for Cortex-M and that ensures that we have the right bit set for the branch instruction that will be generated.

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150421/d84da01c/attachment.sig>
#11 lore raw

PATCH v2 2/6 common/cmd_boot: keep ARM v7M in thumb mode during do_go_exec()

Hi,

Quoted 63 lines · Tom Rini
Quoted 53 lines · Felipe Balbi
Quoted 52 lines · Matt Porter
Quoted 5 lines · Felipe Balbi
Quoted 2 lines · Matt Porter

On ARM v7M, the processor will return to ARM mode when executing a blx instruction with bit 0 of the address == 0. Always set it

but that's what the 'x' is for, right ? eXchange the CPU mode.

Yes.

Quoted 7 lines
Quoted 7 lines

to 1 to stay in thumb mode.

---
 common/cmd_boot.c | 4 ++++
 1 file changed, 4 insertions(+)
Quoted 15 lines

common/cmd_boot.c static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) · line 44

Quoted 12 lines
common/cmd_boot.c +4 -0
index 8f2e070..20ce652 100644
@@ -38,6 +38,10 @@ static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	 * pass address parameter as argv[0] (aka command name),
 	 * and all remaining args
 	 */
+#ifdef CONFIG_CPU_V7M
+	/* For ARM V7M, set bit zero to stay in Thumb mode */
+	addr++;
+#endif

what if we were in ARM state when we reached this point ? You're now telling CPU to always switch to Thumb. Is this really what we want ?

We have no ARM state on this core so that's not possible.

Quoted 17 lines

From ARM's instruction manual:

"
The BX and BLX instructions can change the processor state from ARM to Thumb, or from Thumb to ARM.

BLX label always changes the state.

BX Rm and BLX Rm derive the target state from bit[0] of Rm:

if bit[0] of Rm is 0, the processor changes to, or remains in, ARM state

if bit[0] of Rm is 1, the processor changes to, or remains in, Thumb state.

Quoted 8 lines
Quoted 4 lines

Correct. The last statement is why this patch exists. There is no ARM mode on M3, we immediately fault. Having bit[0]=0 for BX/BLX is not permitted on V7M...something not covered in the generic description of these instructions.

it just seems weird that bit0 wouldn't just be assume 1 by the core itself. I suppose as a consequence we can't use blx label with v7m either ? :-s

Quoted 7 lines

At issue is that the code really reads like this (expanding the functions a little bit:
printf ("## Starting application at 0x%08lX ...\n", addr); rc = (void *)addr(argc - 1, argv + 1);

So the compiler translates this as "do what I say" and generates a branch to whatever addr is.

yeah, you're right. There's nothing the compiler can do. Well, it could refuse from using bx/blx instructions, would a 'bl' do the same thing in this particular case ? (yes, off-topic, sorry)

Quoted 5 lines

If people really feel strongly about it being too wierd to do "addr |= 1" in the common code, do_go_exec is a weak function and we can put something into arch/arm/lib/ (new file) that provides a do_go_exec for Cortex-M and that ensures that we have the right bit set for the branch instruction that will be generated.

I think that's probably a lot clearer, yes.

Signature · 8 lines
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150421/e5d1057e/attachment.sig>
#12 lore raw

PATCH v2 3/6 ARMv7M: add STM32F1 support

In reply to Matt Porter

Add ARMv7M STM32F1 support including clocks, timer, gpio, and flash.

---
 arch/arm/cpu/armv7m/Makefile              |   1 +
 arch/arm/cpu/armv7m/stm32f1/Makefile      |  13 ++
 arch/arm/cpu/armv7m/stm32f1/clock.c       | 195 ++++++++++++++++++++++++++++++
 arch/arm/cpu/armv7m/stm32f1/flash.c       | 179 +++++++++++++++++++++++++++
 arch/arm/cpu/armv7m/stm32f1/soc.c         |  35 ++++++
 arch/arm/cpu/armv7m/stm32f1/timer.c       | 120 ++++++++++++++++++
 arch/arm/include/asm/arch-stm32f1/gpio.h  | 117 ++++++++++++++++++
 arch/arm/include/asm/arch-stm32f1/stm32.h | 115 ++++++++++++++++++
 include/flash.h                           |   1 +
 9 files changed, 776 insertions(+)
 create mode 100644 arch/arm/cpu/armv7m/stm32f1/Makefile
 create mode 100644 arch/arm/cpu/armv7m/stm32f1/clock.c
 create mode 100644 arch/arm/cpu/armv7m/stm32f1/flash.c
 create mode 100644 arch/arm/cpu/armv7m/stm32f1/soc.c
 create mode 100644 arch/arm/cpu/armv7m/stm32f1/timer.c
 create mode 100644 arch/arm/include/asm/arch-stm32f1/gpio.h
 create mode 100644 arch/arm/include/asm/arch-stm32f1/stm32.h
arch/arm/cpu/armv7m/Makefile +1 -0
index b662e03..93a1956 100644
@@ -8,4 +8,5 @@
 extra-y := start.o
 obj-y += cpu.o
 
+obj-$(CONFIG_STM32F1) += stm32f1/
 obj-$(CONFIG_STM32F4) += stm32f4/
arch/arm/cpu/armv7m/stm32f1/Makefile new file +13 -0
new file mode 100644
index 0000000..7b43761
@@ -0,0 +1,13 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# (C) Copyright 2015
+# Kamil Lulko, <[email protected]>
+#
+# Copyright 2015 Konsulko Group, Matt Porter <[email protected]>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y += soc.o clock.o timer.o flash.o
arch/arm/cpu/armv7m/stm32f1/clock.c new file +195 -0

195 lines not on this page · raw message

arch/arm/cpu/armv7m/stm32f1/flash.c new file +179 -0

179 lines not on this page · raw message

arch/arm/cpu/armv7m/stm32f1/soc.c new file +35 -0
new file mode 100644
index 0000000..ecb1269
@@ -0,0 +1,35 @@
+/*
+ * (C) Copyright 2015
+ * Kamil Lulko, <[email protected]>
+ *
+ * Copyright 2015 Konsulko Group, Matt Porter <[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/armv7m.h>
+#include <asm/arch/stm32.h>
+
+u32 get_cpu_rev(void)
+{
+	return 0;
+}
+
+int arch_cpu_init(void)
+{
+	configure_clocks();
+
+	/*
+	 * Configure the memory protection unit (MPU) to allow full access to
+	 * the whole 4GB address space.
+	 */
+	writel(0, &V7M_MPU->rnr);
+	writel(0, &V7M_MPU->rbar);
+	writel((V7M_MPU_RASR_AP_RW_RW | V7M_MPU_RASR_SIZE_4GB
+		| V7M_MPU_RASR_EN), &V7M_MPU->rasr);
+	writel(V7M_MPU_CTRL_ENABLE | V7M_MPU_CTRL_HFNMIENA, &V7M_MPU->ctrl);
+
+	return 0;
+}
arch/arm/cpu/armv7m/stm32f1/timer.c new file +120 -0

120 lines not on this page · raw message

arch/arm/include/asm/arch-stm32f1/gpio.h new file +117 -0

117 lines not on this page · raw message

arch/arm/include/asm/arch-stm32f1/stm32.h new file +115 -0

115 lines not on this page · raw message

include/flash.h +1 -0
index 48aa3a5..5754cf9 100644
@@ -460,6 +460,7 @@ extern flash_info_t *flash_get_info(ulong base);
 #define FLASH_S29GL128N 0x00F1		/* Spansion S29GL128N			*/
 
 #define FLASH_STM32F4	0x00F2		/* STM32F4 Embedded Flash */
+#define FLASH_STM32F1	0x00F3		/* STM32F1 Embedded Flash */
 
 #define FLASH_UNKNOWN	0xFFFF		/* unknown flash type			*/
 
Signature · 1 line
2.1.0
#13 lore raw

PATCH v2 4/6 gpio: stm32: add stm32f1 support

In reply to Matt Porter

Add support for the STM32F1 family to the STM32 gpio driver.

---
Since v1:
- Explicitly check for F4/F1 family and error if not set to a supported STM32 family.

 drivers/gpio/stm32_gpio.c | 109 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 108 insertions(+), 1 deletion(-)
drivers/gpio/stm32_gpio.c +108 -1
index d3497e9..f426727 100644
@@ -5,6 +5,8 @@
  * (C) Copyright 2015
  * Kamil Lulko, <[email protected]>
  *
+ * Copyright 2015 Konsulko Group, Matt Porter <[email protected]>
+ *
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
@@ -16,6 +18,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#if defined(CONFIG_STM32F4)
 #define STM32_GPIOA_BASE	(STM32_AHB1PERIPH_BASE + 0x0000)
 #define STM32_GPIOB_BASE	(STM32_AHB1PERIPH_BASE + 0x0400)
 #define STM32_GPIOC_BASE	(STM32_AHB1PERIPH_BASE + 0x0800)
@@ -90,6 +93,92 @@ int stm32_gpio_config(const struct stm32_gpio_dsc *dsc,
 out:
 	return rv;
 }
+#elif defined(CONFIG_STM32F1)
+#define STM32_GPIOA_BASE	(STM32_APB2PERIPH_BASE + 0x0800)
+#define STM32_GPIOB_BASE	(STM32_APB2PERIPH_BASE + 0x0C00)
+#define STM32_GPIOC_BASE	(STM32_APB2PERIPH_BASE + 0x1000)
+#define STM32_GPIOD_BASE	(STM32_APB2PERIPH_BASE + 0x1400)
+#define STM32_GPIOE_BASE	(STM32_APB2PERIPH_BASE + 0x1800)
+#define STM32_GPIOF_BASE	(STM32_APB2PERIPH_BASE + 0x1C00)
+#define STM32_GPIOG_BASE	(STM32_APB2PERIPH_BASE + 0x2000)
+
+static const unsigned long io_base[] = {
+	STM32_GPIOA_BASE, STM32_GPIOB_BASE, STM32_GPIOC_BASE,
+	STM32_GPIOD_BASE, STM32_GPIOE_BASE, STM32_GPIOF_BASE,
+	STM32_GPIOG_BASE
+};
+
+#define STM32_GPIO_CR_MODE_MASK		0x3
+#define STM32_GPIO_CR_MODE_SHIFT(p)	(p * 4)
+#define STM32_GPIO_CR_CNF_MASK		0x3
+#define STM32_GPIO_CR_CNF_SHIFT(p)	(p * 4 + 2)
+
+struct stm32_gpio_regs {
+	u32 crl;	/* GPIO port configuration low */
+	u32 crh;	/* GPIO port configuration high */
+	u32 idr;	/* GPIO port input data */
+	u32 odr;	/* GPIO port output data */
+	u32 bsrr;	/* GPIO port bit set/reset */
+	u32 brr;	/* GPIO port bit reset */
+	u32 lckr;	/* GPIO port configuration lock */
+};
+
+#define CHECK_DSC(x)	(!x || x->port > 6 || x->pin > 15)
+#define CHECK_CTL(x)	(!x || x->mode > 3 || x->icnf > 3 || x->ocnf > 3 || \
+			 x->pupd > 1)
+
+int stm32_gpio_config(const struct stm32_gpio_dsc *dsc,
+		const struct stm32_gpio_ctl *ctl)
+{
+	struct stm32_gpio_regs *gpio_regs;
+	u32 *cr;
+	int p, crp;
+	int rv;
+
+	if (CHECK_DSC(dsc)) {
+		rv = -EINVAL;
+		goto out;
+	}
+	if (CHECK_CTL(ctl)) {
+		rv = -EINVAL;
+		goto out;
+	}
+
+	p = dsc->pin;
+
+	gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port];
+
+	/* Enable clock for GPIO port */
+	setbits_le32(&STM32_RCC->apb2enr, 0x04 << dsc->port);
+
+	if (p < 8) {
+		cr = &gpio_regs->crl;
+		crp = p;
+	} else {
+		cr = &gpio_regs->crh;
+		crp = p - 8;
+	}
+
+	clrbits_le32(cr, 0x3 << STM32_GPIO_CR_MODE_SHIFT(crp));
+	setbits_le32(cr, ctl->mode << STM32_GPIO_CR_MODE_SHIFT(crp));
+
+	clrbits_le32(cr, 0x3 << STM32_GPIO_CR_CNF_SHIFT(crp));
+	/* Inputs set the optional pull up / pull down */
+	if (ctl->mode == STM32_GPIO_MODE_IN) {
+		setbits_le32(cr, ctl->icnf << STM32_GPIO_CR_CNF_SHIFT(crp));
+		clrbits_le32(&gpio_regs->odr, 0x1 << p);
+		setbits_le32(&gpio_regs->odr, ctl->pupd << p);
+	} else {
+		setbits_le32(cr, ctl->ocnf << STM32_GPIO_CR_CNF_SHIFT(crp));
+	}
+
+	rv = 0;
+out:
+	return rv;
+}
+#else
+#error STM32 family not supported
+#endif
 
 int stm32_gpout_set(const struct stm32_gpio_dsc *dsc, int state)
 {
@@ -148,10 +237,20 @@ int gpio_direction_input(unsigned gpio)
 
 	dsc.port = stm32_gpio_to_port(gpio);
 	dsc.pin = stm32_gpio_to_pin(gpio);
+#if defined(CONFIG_STM32F4)
 	ctl.af = STM32_GPIO_AF0;
 	ctl.mode = STM32_GPIO_MODE_IN;
+	ctl.otype = STM32_GPIO_OTYPE_PP;
 	ctl.pupd = STM32_GPIO_PUPD_NO;
 	ctl.speed = STM32_GPIO_SPEED_50M;
+#elif defined(CONFIG_STM32F1)
+	ctl.mode = STM32_GPIO_MODE_IN;
+	ctl.icnf = STM32_GPIO_ICNF_IN_FLT;
+	ctl.ocnf = STM32_GPIO_OCNF_GP_PP;	/* ignored for input */
+	ctl.pupd = STM32_GPIO_PUPD_UP;		/* ignored for floating */
+#else
+#error STM32 family not supported
+#endif
 
 	return stm32_gpio_config(&dsc, &ctl);
 }
@@ -164,11 +263,19 @@ int gpio_direction_output(unsigned gpio, int value)
 
 	dsc.port = stm32_gpio_to_port(gpio);
 	dsc.pin = stm32_gpio_to_pin(gpio);
+#if defined(CONFIG_STM32F4)
 	ctl.af = STM32_GPIO_AF0;
 	ctl.mode = STM32_GPIO_MODE_OUT;
-	ctl.otype = STM32_GPIO_OTYPE_PP;
 	ctl.pupd = STM32_GPIO_PUPD_NO;
 	ctl.speed = STM32_GPIO_SPEED_50M;
+#elif defined(CONFIG_STM32F1)
+	ctl.mode = STM32_GPIO_MODE_OUT_50M;
+	ctl.ocnf = STM32_GPIO_OCNF_GP_PP;
+	ctl.icnf = STM32_GPIO_ICNF_IN_FLT;	/* ignored for output */
+	ctl.pupd = STM32_GPIO_PUPD_UP;		/* ignored for output */
+#else
+#error STM32 family not supported
+#endif
 
 	res = stm32_gpio_config(&dsc, &ctl);
 	if (res < 0)
Signature · 1 line
2.1.0
#14 lore raw

PATCH v2 5/6 serial: stm32: add stm32f1 support

In reply to Matt Porter

Add support for the STM32F1 famly to the STM32 serial driver.

---
Since v1:
- Explicitly check for F4/F1 family and error if not set to a supported STM32 family.

 drivers/serial/serial_stm32.c | 9 +++++++++
 1 file changed, 9 insertions(+)
drivers/serial/serial_stm32.c +9 -0
index 3c80096..9b19b68 100644
@@ -2,6 +2,8 @@
  * (C) Copyright 2015
  * Kamil Lulko, <[email protected]>
  *
+ * Copyright 2015 Konsulko Group, Matt Porter <[email protected]>
+ *
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
@@ -10,8 +12,15 @@
 #include <serial.h>
 #include <asm/arch/stm32.h>
 
+#if defined(CONFIG_STM32F4)
 #define STM32_USART1_BASE	(STM32_APB2PERIPH_BASE + 0x1000)
 #define RCC_APB2ENR_USART1EN	(1 << 4)
+#elif defined(CONFIG_STM32F1)
+#define STM32_USART1_BASE	(STM32_APB2PERIPH_BASE + 0x3800)
+#define RCC_APB2ENR_USART1EN	(1 << 14)
+#else
+#error STM32 family not supported
+#endif
 
 #define USART_BASE		STM32_USART1_BASE
 #define RCC_USART_ENABLE	RCC_APB2ENR_USART1EN
Signature · 1 line
2.1.0
#15 lore raw

PATCH v2 6/6 board: add stm3210e-eval board support

In reply to Matt Porter

Add support for the STM32F1-based stm3210e-eval boards from ST. UART, Flash, GPIO, and LEDs are supported.

---
 arch/arm/Kconfig                       |   5 ++
 board/st/stm3210e-eval/Kconfig         |  19 ++++++
 board/st/stm3210e-eval/MAINTAINERS     |   5 ++
 board/st/stm3210e-eval/Makefile        |  13 ++++
 board/st/stm3210e-eval/stm3210e-eval.c |  85 ++++++++++++++++++++++++
 configs/stm3210e-eval_defconfig        |   3 +
 include/configs/stm3210e-eval.h        | 117 +++++++++++++++++++++++++++++++++
 7 files changed, 247 insertions(+)
 create mode 100644 board/st/stm3210e-eval/Kconfig
 create mode 100644 board/st/stm3210e-eval/MAINTAINERS
 create mode 100644 board/st/stm3210e-eval/Makefile
 create mode 100644 board/st/stm3210e-eval/stm3210e-eval.c
 create mode 100644 configs/stm3210e-eval_defconfig
 create mode 100644 include/configs/stm3210e-eval.h
arch/arm/Kconfig +5 -0
index 4eb047c..bcf4e46 100644
@@ -731,6 +731,10 @@ config ARCH_UNIPHIER
 	select SPL
 	select OF_CONTROL
 
+config TARGET_STM3210E_EVAL
+	bool "Support STM3210E-EVAL board"
+	select CPU_V7M
+
 config TARGET_STM32F429_DISCOVERY
 	bool "Support STM32F429 Discovery"
 	select CPU_V7M
@@ -872,6 +876,7 @@ source "board/spear/spear600/Kconfig"
 source "board/spear/x600/Kconfig"
 source "board/st-ericsson/snowball/Kconfig"
 source "board/st-ericsson/u8500/Kconfig"
+source "board/st/stm3210e-eval/Kconfig"
 source "board/st/stm32f429-discovery/Kconfig"
 source "board/st/stv0991/Kconfig"
 source "board/sunxi/Kconfig"
board/st/stm3210e-eval/Kconfig new file +19 -0
new file mode 100644
index 0000000..49bc770
@@ -0,0 +1,19 @@
+if TARGET_STM3210E_EVAL
+
+config SYS_BOARD
+	string
+	default "stm3210e-eval"
+
+config SYS_VENDOR
+	string
+	default "st"
+
+config SYS_SOC
+	string
+	default "stm32f1"
+
+config SYS_CONFIG_NAME
+	string
+	default "stm3210e-eval"
+
+endif
board/st/stm3210e-eval/MAINTAINERS new file +5 -0
new file mode 100644
index 0000000..0f9f31b
@@ -0,0 +1,5 @@
+M:	Matt Porter <[email protected]>
+S:	Maintained
+F:	board/st/stm3210e-eval/
+F:	include/configs/stm3210e-eval.h
+F:	configs/stm3210e-eval_defconfig
board/st/stm3210e-eval/Makefile new file +13 -0
new file mode 100644
index 0000000..b018e08
@@ -0,0 +1,13 @@
+#
+# (C) Copyright 2000-2004
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# (C) Copyright 2015
+# Kamil Lulko, <[email protected]>
+#
+# Copyright 2015 Konsulko Group, Matt Porter <[email protected]>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	:= stm3210e-eval.o
board/st/stm3210e-eval/stm3210e-eval.c new file +85 -0

85 lines not on this page · raw message

configs/stm3210e-eval_defconfig new file +3 -0
new file mode 100644
index 0000000..ac3cad3
@@ -0,0 +1,3 @@
+CONFIG_ARM=y
+CONFIG_TARGET_STM3210E_EVAL=y
+CONFIG_CMD_BOOTM=n
include/configs/stm3210e-eval.h new file +117 -0

117 lines not on this page · raw message

Signature · 1 line
2.1.0