diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/ao.h | 1 | ||||
| -rw-r--r-- | src/core/ao_task.c | 6 | ||||
| -rw-r--r-- | src/megametrum-v0.1/Makefile | 10 | ||||
| -rw-r--r-- | src/megametrum-v0.1/ao_megametrum.c | 7 | ||||
| -rw-r--r-- | src/stm-bringup/Makefile | 2 | ||||
| -rw-r--r-- | src/stm-bringup/ao.h | 18 | ||||
| -rw-r--r-- | src/stm/ao_interrupt.c | 3 | ||||
| -rw-r--r-- | src/stm/ao_mpu.h | 29 | ||||
| -rw-r--r-- | src/stm/ao_mpu_stm.c | 149 | ||||
| -rw-r--r-- | src/stm/registers.ld | 2 | ||||
| -rw-r--r-- | src/stm/stm32l.h | 64 | 
11 files changed, 286 insertions, 5 deletions
| diff --git a/src/core/ao.h b/src/core/ao.h index 2b375cfd..87e69e19 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -64,6 +64,7 @@  #define AO_PANIC_BT		11	/* Communications with bluetooth device failed */  #define AO_PANIC_STACK		12	/* Stack overflow */  #define AO_PANIC_SPI		13	/* SPI communication failure */ +#define AO_PANIC_CRASH		14	/* Processor crashed */  #define AO_PANIC_SELF_TEST_CC1120	0x40 | 1	/* Self test failure */  #define AO_PANIC_SELF_TEST_HMC5883	0x40 | 2	/* Self test failure */  #define AO_PANIC_SELF_TEST_MPU6000	0x40 | 3	/* Self test failure */ diff --git a/src/core/ao_task.c b/src/core/ao_task.c index c2b1b270..df70b906 100644 --- a/src/core/ao_task.c +++ b/src/core/ao_task.c @@ -20,6 +20,9 @@  #if HAS_SAMPLE_PROFILE  #include <ao_sample_profile.h>  #endif +#if HAS_STACK_GUARD +#include <ao_mpu.h> +#endif  #define AO_NO_TASK_INDEX	0xff @@ -127,6 +130,9 @@ ao_yield(void) ao_arch_naked_define  	ao_cur_task->start = ao_sample_profile_timer_value();  #endif  	} +#if HAS_STACK_GUARD +	ao_mpu_stack_guard(ao_cur_task->stack); +#endif  #if AO_CHECK_STACK  	cli();  	in_yield = 0; diff --git a/src/megametrum-v0.1/Makefile b/src/megametrum-v0.1/Makefile index b100fafc..487a643f 100644 --- a/src/megametrum-v0.1/Makefile +++ b/src/megametrum-v0.1/Makefile @@ -25,11 +25,13 @@ INC = \  	ao_task.h \  	ao_whiten.h \  	ao_sample_profile.h \ +	ao_mpu.h \  	stm32l.h  #  # Common AltOS sources  # +#	ao_hmc5883.c  #PROFILE=ao_profile.c  #PROFILE_DEF=-DAO_PROFILE=1 @@ -38,7 +40,8 @@ SAMPLE_PROFILE=ao_sample_profile.c \  	ao_sample_profile_timer.c  SAMPLE_PROFILE_DEF=-DHAS_SAMPLE_PROFILE=1 -#	ao_hmc5883.c +STACK_GUARD=ao_mpu_stm.c +STACK_GUARD_DEF=-DHAS_STACK_GUARD=1  ALTOS_SRC = \  	ao_interrupt.c \ @@ -87,13 +90,14 @@ ALTOS_SRC = \  	ao_companion.c \  	ao_pyro.c \  	$(PROFILE) \ -	$(SAMPLE_PROFILE) +	$(SAMPLE_PROFILE) \ +	$(STACK_GUARD)  PRODUCT=MegaMetrum-v0.1  PRODUCT_DEF=-DMEGAMETRUM  IDPRODUCT=0x0023 -CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) -Os -g +CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) -Os -g  PROGNAME=megametrum-v0.1  PROG=$(PROGNAME)-$(VERSION).elf diff --git a/src/megametrum-v0.1/ao_megametrum.c b/src/megametrum-v0.1/ao_megametrum.c index 114f144f..43c2292d 100644 --- a/src/megametrum-v0.1/ao_megametrum.c +++ b/src/megametrum-v0.1/ao_megametrum.c @@ -28,12 +28,19 @@  #include <ao_sample_profile.h>  #endif  #include <ao_pyro.h> +#if HAS_STACK_GUARD +#include <ao_mpu.h> +#endif  int  main(void)  {  	ao_clock_init(); +#if HAS_STACK_GUARD +	ao_mpu_init(); +#endif +  	ao_serial_init();  	ao_led_init(LEDS_AVAILABLE);  	ao_led_on(AO_LED_GREEN); diff --git a/src/stm-bringup/Makefile b/src/stm-bringup/Makefile index d45e836d..5cc94bd9 100644 --- a/src/stm-bringup/Makefile +++ b/src/stm-bringup/Makefile @@ -12,7 +12,7 @@ PDCLIB=/home/keithp/sat  C_LIB=$(PDCLIB)/lib/pdclib.a  C_INC=-I$(PDCLIB)/include -DEF_CFLAGS=-g -std=gnu99 -Os -mlittle-endian -mthumb -ffreestanding -nostdlib -I../../src/stm $(C_INC) +DEF_CFLAGS=-g -std=gnu99 -Os -mlittle-endian -mthumb -ffreestanding -nostdlib -I. -I../../src/stm $(C_INC)  # to run from SRAM  LD_FLAGS_RAM=-L../stm -Wl,-Taltos-ram.ld diff --git a/src/stm-bringup/ao.h b/src/stm-bringup/ao.h new file mode 100644 index 00000000..27204fae --- /dev/null +++ b/src/stm-bringup/ao.h @@ -0,0 +1,18 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * 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; version 2 of the License. + * + * 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. + */ + +#define ao_panic(n)	for(;;); diff --git a/src/stm/ao_interrupt.c b/src/stm/ao_interrupt.c index 6b4a9700..a423d8b1 100644 --- a/src/stm/ao_interrupt.c +++ b/src/stm/ao_interrupt.c @@ -15,6 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ +#include <ao.h>  #include "stm32l.h"  #include <string.h> @@ -28,7 +29,7 @@ extern char __bss_start__, __bss_end__;  void stm_halt_isr(void)  { -	for(;;); +	ao_panic(AO_PANIC_CRASH);  }  void stm_ignore_isr(void) diff --git a/src/stm/ao_mpu.h b/src/stm/ao_mpu.h new file mode 100644 index 00000000..cc6132a5 --- /dev/null +++ b/src/stm/ao_mpu.h @@ -0,0 +1,29 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * 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; version 2 of the License. + * + * 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 _AO_MPU_H_ +#define _AO_MPU_H_ + +extern uint32_t	ao_mpu_dregion; + +void +ao_mpu_stack_guard(void *stack); + +void +ao_mpu_init(void); + +#endif /* _AO_MPU_H_ */ diff --git a/src/stm/ao_mpu_stm.c b/src/stm/ao_mpu_stm.c new file mode 100644 index 00000000..969d7446 --- /dev/null +++ b/src/stm/ao_mpu_stm.c @@ -0,0 +1,149 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * 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; version 2 of the License. + * + * 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. + */ + +#include <ao.h> +#include <ao_mpu.h> + +static uint32_t	stm_mpu_dregion; + +void +ao_mpu_init(void) +{ +	uint32_t	region; + +	/* Check to see how many regions we have */ +	stm_mpu_dregion = (stm_mpu.typer >> STM_MPU_TYPER_DREGION) & STM_MPU_TYPER_DREGION_MASK; + +	/* No MPU at all */ +	if (stm_mpu_dregion == 0) +		return; + +	/* Disable MPU */ +	stm_mpu.cr = ((0 << STM_MPU_CR_PRIVDEFENA) | +		      (0 << STM_MPU_CR_HFNMIENA) | +		      (0 << STM_MPU_CR_ENABLE)); + +	/* Disable all regions */ +	for (region = 0; region < stm_mpu_dregion; region++) { +		/* Set the base address and RNR value */ +		stm_mpu.rbar = ((0 & (STM_MPU_RBAR_ADDR_MASK << STM_MPU_RBAR_ADDR)) | +				(1 << STM_MPU_RBAR_VALID) | +				(region << STM_MPU_RBAR_REGION)); + +		/* Disable this region */ +		stm_mpu.rasr = 0; +	} + +	region = 0; + +	/* Flash */ +	/* 0x00000000 - 0x1fffffff */ +	stm_mpu.rbar = (0x0000000 | +			(1 << STM_MPU_RBAR_VALID) | +			(region << STM_MPU_RBAR_REGION)); + +	stm_mpu.rasr = ((0 << STM_MPU_RASR_XN) | +			(STM_MPU_RASR_AP_RO_RO << STM_MPU_RASR_AP) | +			(5 << STM_MPU_RASR_TEX) | +			(0 << STM_MPU_RASR_C) | +			(1 << STM_MPU_RASR_B) | +			(0 << STM_MPU_RASR_S) | +			(0 << STM_MPU_RASR_SRD) | +			(28 << STM_MPU_RASR_SIZE) | +			(1 << STM_MPU_RASR_ENABLE)); +	region++; + +	/* Ram */ +	/* 0x20000000 - 0x3fffffff */ +	stm_mpu.rbar = (0x20000000 | +			(1 << STM_MPU_RBAR_VALID) | +			(region << STM_MPU_RBAR_REGION)); + +	stm_mpu.rasr = ((0 << STM_MPU_RASR_XN) | +			(STM_MPU_RASR_AP_RW_RW << STM_MPU_RASR_AP) | +			(5 << STM_MPU_RASR_TEX) | +			(0 << STM_MPU_RASR_C) | +			(1 << STM_MPU_RASR_B) | +			(0 << STM_MPU_RASR_S) | +			(0 << STM_MPU_RASR_SRD) | +			(28 << STM_MPU_RASR_SIZE) | +			(1 << STM_MPU_RASR_ENABLE)); +	region++; + +	/* Peripherals */ + +	/* 0x4000000 - 0x7ffffff */ +	stm_mpu.rbar = (0x40000000 | +			(1 << STM_MPU_RBAR_VALID) | +			(region << STM_MPU_RBAR_REGION)); + +	stm_mpu.rasr = ((1 << STM_MPU_RASR_XN) | +			(STM_MPU_RASR_AP_RW_RW << STM_MPU_RASR_AP) | +			(2 << STM_MPU_RASR_TEX) | +			(0 << STM_MPU_RASR_C) | +			(0 << STM_MPU_RASR_B) | +			(0 << STM_MPU_RASR_S) | +			(0 << STM_MPU_RASR_SRD) | +			(29 << STM_MPU_RASR_SIZE) | +			(1 << STM_MPU_RASR_ENABLE)); +	region++; + +	/* 0x8000000 - 0xffffffff */ +	stm_mpu.rbar = (0x80000000 | +			(1 << STM_MPU_RBAR_VALID) | +			(region << STM_MPU_RBAR_REGION)); + +	stm_mpu.rasr = ((1 << STM_MPU_RASR_XN) | +			(STM_MPU_RASR_AP_RW_RW << STM_MPU_RASR_AP) | +			(2 << STM_MPU_RASR_TEX) | +			(0 << STM_MPU_RASR_C) | +			(0 << STM_MPU_RASR_B) | +			(0 << STM_MPU_RASR_S) | +			(0 << STM_MPU_RASR_SRD) | +			(30 << STM_MPU_RASR_SIZE) | +			(1 << STM_MPU_RASR_ENABLE)); +	region++; + +	/* Enable MPU */ +	stm_mpu.cr = ((0 << STM_MPU_CR_PRIVDEFENA) | +		      (0 << STM_MPU_CR_HFNMIENA) | +		      (1 << STM_MPU_CR_ENABLE)); +} + +/* + * Protect the base of the stack from CPU access + */ + +void +ao_mpu_stack_guard(void *base) +{ +	uintptr_t	addr = (uintptr_t) base; + +	/* Round up to cover the lowest possible 32-byte region */ +	addr = (addr + ~(STM_MPU_RBAR_ADDR_MASK << STM_MPU_RBAR_ADDR)) & (STM_MPU_RBAR_ADDR_MASK << STM_MPU_RBAR_ADDR); + +	stm_mpu.rbar = addr | (1 << STM_MPU_RBAR_VALID) | (7 << STM_MPU_RBAR_REGION); +	stm_mpu.rasr = ((1 << STM_MPU_RASR_XN) | +			(STM_MPU_RASR_AP_NONE_NONE << STM_MPU_RASR_AP) | +			(5 << STM_MPU_RASR_TEX) | +			(0 << STM_MPU_RASR_C) | +			(1 << STM_MPU_RASR_B) | +			(0 << STM_MPU_RASR_S) | +			(0 << STM_MPU_RASR_SRD) | +			(4 << STM_MPU_RASR_SIZE) | +			(1 << STM_MPU_RASR_ENABLE)); +} diff --git a/src/stm/registers.ld b/src/stm/registers.ld index fd61e486..f8b224a2 100644 --- a/src/stm/registers.ld +++ b/src/stm/registers.ld @@ -46,5 +46,7 @@ stm_tim2   = 0x40000000;  stm_nvic   = 0xe000e100; +stm_mpu    = 0xe000ed90; +  /* calibration data in system memory */  stm_temp_cal = 0x1ff80078; diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h index e950d09b..d953aee4 100644 --- a/src/stm/stm32l.h +++ b/src/stm/stm32l.h @@ -901,6 +901,63 @@ stm_nvic_get_priority(int irq) {  	return (stm_nvic.ipr[IRQ_PRIO_REG(irq)] >> IRQ_PRIO_BIT(irq)) & IRQ_PRIO_MASK(0);  } +struct stm_mpu { +	vuint32_t	typer; +	vuint32_t	cr; +	vuint32_t	rnr; +	vuint32_t	rbar; + +	vuint32_t	rasr; +	vuint32_t	rbar_a1; +	vuint32_t	rasr_a1; +	vuint32_t	rbar_a2; +	vuint32_t	rasr_a2; +	vuint32_t	rbar_a3; +	vuint32_t	rasr_a3; +}; + +extern struct stm_mpu stm_mpu; + +#define STM_MPU_TYPER_IREGION	16 +#define  STM_MPU_TYPER_IREGION_MASK	0xff +#define STM_MPU_TYPER_DREGION	8 +#define  STM_MPU_TYPER_DREGION_MASK	0xff +#define STM_MPU_TYPER_SEPARATE	0 + +#define STM_MPU_CR_PRIVDEFENA	2 +#define STM_MPU_CR_HFNMIENA	1 +#define STM_MPU_CR_ENABLE	0 + +#define STM_MPU_RNR_REGION	0 +#define STM_MPU_RNR_REGION_MASK		0xff + +#define STM_MPU_RBAR_ADDR	5 +#define STM_MPU_RBAR_ADDR_MASK		0x7ffffff + +#define STM_MPU_RBAR_VALID	4 +#define STM_MPU_RBAR_REGION	0 +#define STM_MPU_RBAR_REGION_MASK	0xf + +#define STM_MPU_RASR_XN		28 +#define STM_MPU_RASR_AP		24 +#define  STM_MPU_RASR_AP_NONE_NONE	0 +#define  STM_MPU_RASR_AP_RW_NONE	1 +#define  STM_MPU_RASR_AP_RW_RO		2 +#define  STM_MPU_RASR_AP_RW_RW		3 +#define  STM_MPU_RASR_AP_RO_NONE	5 +#define  STM_MPU_RASR_AP_RO_RO		6 +#define  STM_MPU_RASR_AP_MASK		7 +#define STM_MPU_RASR_TEX	19 +#define  STM_MPU_RASR_TEX_MASK		7 +#define STM_MPU_RASR_S		18 +#define STM_MPU_RASR_C		17 +#define STM_MPU_RASR_B		16 +#define STM_MPU_RASR_SRD	8 +#define  STM_MPU_RASR_SRD_MASK		0xff +#define STM_MPU_RASR_SIZE	1 +#define  STM_MPU_RASR_SIZE_MASK		0x1f +#define STM_MPU_RASR_ENABLE	0 +  #define isr(name) void stm_ ## name ## _isr(void);  isr(nmi) @@ -1568,6 +1625,13 @@ extern struct stm_tim234 stm_tim2, stm_tim3, stm_tim4;  #define STM_TIM234_SR_CC1IF	1  #define STM_TIM234_SR_UIF	0 +#define STM_TIM234_EGR_TG	6 +#define STM_TIM234_EGR_CC4G	4 +#define STM_TIM234_EGR_CC3G	3 +#define STM_TIM234_EGR_CC2G	2 +#define STM_TIM234_EGR_CC1G	1 +#define STM_TIM234_EGR_UG	0 +  #define STM_TIM234_CCMR1_OC2CE	15  #define STM_TIM234_CCMR1_OC2M	12  #define  STM_TIM234_CCMR1_OC2M_FROZEN			0 | 
