summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/ao.h1
-rw-r--r--src/core/ao_task.c6
-rw-r--r--src/megametrum-v0.1/Makefile10
-rw-r--r--src/megametrum-v0.1/ao_megametrum.c7
-rw-r--r--src/stm-bringup/Makefile2
-rw-r--r--src/stm-bringup/ao.h18
-rw-r--r--src/stm/ao_interrupt.c3
-rw-r--r--src/stm/ao_mpu.h29
-rw-r--r--src/stm/ao_mpu_stm.c149
-rw-r--r--src/stm/registers.ld2
-rw-r--r--src/stm/stm32l.h64
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