From ce710bb94ad74a99772d1e3a6f2293808436bb25 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 29 Jun 2014 17:46:55 -0600 Subject: [PATCH] SAMA5 PIO: Add support for secure interrupts; Fix PIO debug output --- arch/arm/src/sama5/sam_pio.c | 88 +++++++++++++++++++++++---------- arch/arm/src/sama5/sam_pio.h | 32 ++++++++---- arch/arm/src/sama5/sam_pioirq.c | 19 +++++++ 3 files changed, 103 insertions(+), 36 deletions(-) diff --git a/arch/arm/src/sama5/sam_pio.c b/arch/arm/src/sama5/sam_pio.c index f063994277..eb336db25f 100644 --- a/arch/arm/src/sama5/sam_pio.c +++ b/arch/arm/src/sama5/sam_pio.c @@ -137,7 +137,7 @@ static inline int sam_piopin(pio_pinset_t cfgset) static inline int sam_configinput(uintptr_t base, uint32_t pin, pio_pinset_t cfgset) { -#if defined(PIO_HAVE_SCHMITT) || defined(PIO_HAVE_DRIVE) +#if defined(PIO_HAVE_SCHMITT) || defined(PIO_HAVE_DRIVE) || defined(SAM_PIO_ISLR_OFFSET) uint32_t regval; #endif #if defined(PIO_HAVE_DRIVE) @@ -151,6 +151,14 @@ static inline int sam_configinput(uintptr_t base, uint32_t pin, putreg32(pin, base + SAM_PIO_IDR_OFFSET); +#if defined(SAM_PIO_ISLR_OFFSET) + /* Assume unsecure */ + + regval = getreg32(base + SAM_PIO_ISLR_OFFSET); + regval |= pin; + putreg32(regval, base + SAM_PIO_ISLR_OFFSET); +#endif + /* Enable/disable the pull-up as requested */ if ((cfgset & PIO_CFG_PULLUP) != 0) @@ -248,10 +256,22 @@ static inline int sam_configinput(uintptr_t base, uint32_t pin, static inline int sam_configoutput(uintptr_t base, uint32_t pin, pio_pinset_t cfgset) { +#if defined(SAM_PIO_ISLR_OFFSET) + uint32_t regval; +#endif + /* Disable interrupts on the pin */ putreg32(pin, base + SAM_PIO_IDR_OFFSET); +#if defined(SAM_PIO_ISLR_OFFSET) + /* Assume unsecure */ + + regval = getreg32(base + SAM_PIO_ISLR_OFFSET); + regval |= pin; + putreg32(regval, base + SAM_PIO_ISLR_OFFSET); +#endif + /* Enable/disable the pull-up as requested */ if ((cfgset & PIO_CFG_PULLUP) != 0) @@ -323,6 +343,14 @@ static inline int sam_configperiph(uintptr_t base, uint32_t pin, putreg32(pin, base + SAM_PIO_IDR_OFFSET); +#if defined(SAM_PIO_ISLR_OFFSET) + /* Assume unsecure */ + + regval = getreg32(base + SAM_PIO_ISLR_OFFSET); + regval |= pin; + putreg32(regval, base + SAM_PIO_ISLR_OFFSET); +#endif + /* Enable/disable the pull-up as requested */ if ((cfgset & PIO_CFG_PULLUP) != 0) @@ -548,45 +576,53 @@ int sam_dumppio(uint32_t pinset, const char *msg) { irqstate_t flags; uintptr_t base; - unsigned int pin; unsigned int port; /* Get the base address associated with the PIO port */ - pin = sam_piopin(pinset); port = (pinset & PIO_PORT_MASK) >> PIO_PORT_SHIFT; - base = SAM_PION_BASE(port); + base = SAM_PION_VBASE(port); /* The following requires exclusive access to the PIO registers */ flags = irqsave(); lldbg("PIO%c pinset: %08x base: %08x -- %s\n", g_portchar[port], pinset, base, msg); - lldbg(" PSR: %08x OSR: %08x IFSR: %08x ODSR: %08x\n", + +#ifdef SAM_PIO_ISLR_OFFSET + lldbg(" PSR: %08x ISLR: %08x OSR: %08x IFSR: %08x\n", + getreg32(base + SAM_PIO_PSR_OFFSET), getreg32(base + SAM_PIO_ISLR_OFFSET), + getreg32(base + SAM_PIO_OSR_OFFSET), getreg32(base + SAM_PIO_IFSR_OFFSET)); +#else + lldbg(" PSR: %08x OSR: %08x IFSR: %08x\n", getreg32(base + SAM_PIO_PSR_OFFSET), getreg32(base + SAM_PIO_OSR_OFFSET), - getreg32(base + SAM_PIO_IFSR_OFFSET), getreg32(base + SAM_PIO_ODSR_OFFSET)); - lldbg(" PDSR: %08x IMR: %08x ISR: %08x MDSR: %08x\n", - getreg32(base + SAM_PIO_PDSR_OFFSET), getreg32(base + SAM_PIO_IMR_OFFSET), - getreg32(base + SAM_PIO_ISR_OFFSET), getreg32(base + SAM_PIO_MDSR_OFFSET)); - lldbg(" ABCDSR: %08x %08x IFSCSR: %08x PPDSR: %08x\n", - getreg32(base + SAM_PIO_ABCDSR1_OFFSET), getreg32(base + SAM_PIO_ABCDSR2_OFFSET), - getreg32(base + SAM_PIO_IFSCSR_OFFSET), getreg32(base + SAM_PIOC_PPDSR)); - lldbg(" PUSR: %08x SCDR: %08x OWSR: %08x AIMMR: %08x\n", - getreg32(base + SAM_PIO_PUSR_OFFSET), getreg32(base + SAM_PIO_SCDR_OFFSET), - getreg32(base + SAM_PIO_OWSR_OFFSET), getreg32(base + SAM_PIO_AIMMR_OFFSET)); - lldbg(" ESR: %08x LSR: %08x ELSR: %08x FELLSR: %08x\n", - getreg32(base + SAM_PIO_ESR_OFFSET), getreg32(base + SAM_PIO_LSR_OFFSET), - getreg32(base + SAM_PIO_ELSR_OFFSET), getreg32(base + SAM_PIO_FELLSR_OFFSET)); - lldbg(" FRLHSR: %08x LOCKSR: %08x WPMR: %08x WPSR: %08x\n", - getreg32(base + SAM_PIO_FRLHSR_OFFSET), getreg32(base + SAM_PIO_LOCKSR_OFFSET), + getreg32(base + SAM_PIO_IFSR_OFFSET)); +#endif + lldbg(" ODSR: %08x PDSR: %08x IMR: %08x ISR: %08x\n", + getreg32(base + SAM_PIO_ODSR_OFFSET), getreg32(base + SAM_PIO_PDSR_OFFSET), + getreg32(base + SAM_PIO_IMR_OFFSET), getreg32(base + SAM_PIO_ISR_OFFSET)); + lldbg(" MDSR: %08x PUSR: %08x ABDCSR: %08x %08x\n", + getreg32(base + SAM_PIO_MDSR_OFFSET), getreg32(base + SAM_PIO_PUSR_OFFSET), + getreg32(base + SAM_PIO_ABCDSR1_OFFSET), getreg32(base + SAM_PIO_ABCDSR2_OFFSET)); + lldbg(" IFSCSR: %08x SCDR: %08x PPDSR: %08x OWSR: %08x\n", + getreg32(base + SAM_PIO_IFSCSR_OFFSET), getreg32(base + SAM_PIO_SCDR_OFFSET), + getreg32(base + SAM_PIO_PPDSR_OFFSET), getreg32(base + SAM_PIO_OWSR_OFFSET)); +#ifdef SAM_PIO_LOCKSR_OFFSET + lldbg(" AIMMR: %08x ELSR: %08x FRLHSR: %08x LOCKSR: %08x\n", + getreg32(base + SAM_PIO_AIMMR_OFFSET), getreg32(base + SAM_PIO_ELSR_OFFSET), + getreg32(base + SAM_PIO_FRLHSR_OFFSET), getreg32(base + SAM_PIO_LOCKSR_OFFSET)); +#else + lldbg(" AIMMR: %08x ELSR: %08x FRLHSR: %08x\n", + getreg32(base + SAM_PIO_AIMMR_OFFSET), getreg32(base + SAM_PIO_ELSR_OFFSET), + getreg32(base + SAM_PIO_FRLHSR_OFFSET)); +#endif + lldbg("SCHMITT: %08x DRIVER: %08x %08x\n", + getreg32(base + SAM_PIO_SCHMITT_OFFSET), getreg32(base + SAM_PIO_DRIVER1_OFFSET), + getreg32(base + SAM_PIO_DRIVER2_OFFSET)); + lldbg(" WPMR: %08x WPSR: %08x\n", getreg32(base + SAM_PIO_WPMR_OFFSET), getreg32(base + SAM_PIO_WPSR_OFFSET)); - lldbg(" PCMR: %08x PCIMR: %08x PCISR: %08x PCRHR: %08x\n", - getreg32(base + SAM_PIO_PCMR_OFFSET), getreg32(base + SAM_PIO_PCIMR_OFFSET), - getreg32(base + SAM_PIO_PCISR_OFFSET), getreg32(base + SAM_PIO_PCRHR_OFFSET)); - lldbg("SCHMITT: %08x\n", - getreg32(base + SAM_PIO_SCHMITT_OFFSET)); + irqrestore(flags); return OK; } #endif - diff --git a/arch/arm/src/sama5/sam_pio.h b/arch/arm/src/sama5/sam_pio.h index d70a1bd46a..abaa6b2d05 100644 --- a/arch/arm/src/sama5/sam_pio.h +++ b/arch/arm/src/sama5/sam_pio.h @@ -73,15 +73,15 @@ /* 32-bit Encoding: * - * .... .... ..MM MCCC CCDD IIIV PPPB BBBB + * .... .... .MMM CCCC CDDI IISV PPPB BBBB */ /* Input/Output mode: * - * .... .... ..MM M... .... .... .... .... + * .... .... .MMM .... .... .... .... .... */ -#define PIO_MODE_SHIFT (19) /* Bits 19-21: PIO mode */ +#define PIO_MODE_SHIFT (20) /* Bits 20-22: PIO mode */ #define PIO_MODE_MASK (7 << PIO_MODE_SHIFT) # define PIO_INPUT (0 << PIO_MODE_SHIFT) /* Input */ # define PIO_OUTPUT (1 << PIO_MODE_SHIFT) /* Output */ @@ -93,10 +93,10 @@ /* These bits set the configuration of the pin: * NOTE: No definitions for parallel capture mode * - * .... .... .... .CCC CC.. .... .... .... + * .... .... .... CCCC C... .... .... .... */ -#define PIO_CFG_SHIFT (14) /* Bits 14-18: PIO configuration bits */ +#define PIO_CFG_SHIFT (15) /* Bits 15-19: PIO configuration bits */ #define PIO_CFG_MASK (31 << PIO_CFG_SHIFT) # define PIO_CFG_DEFAULT (0 << PIO_CFG_SHIFT) /* Default, no attribute */ # define PIO_CFG_PULLUP (1 << PIO_CFG_SHIFT) /* Bit 11: Internal pull-up */ @@ -107,10 +107,10 @@ /* Drive Strength: * - * .... .... .... .... ..DD .... .... .... + * .... .... .... .... .DD. .... .... .... */ -#define PIO_DRIVE_SHIFT (12) /* Bits 12-13: Drive strength */ +#define PIO_DRIVE_SHIFT (13) /* Bits 13-14: Drive strength */ #define PIO_DRIVE_MASK (7 << PIO_DRIVE_SHIFT) # define PIO_DRIVE_LOW (0 << PIO_DRIVE_SHIFT) # define PIO_DRIVE_MEDIUM (2 << PIO_DRIVE_SHIFT) @@ -118,10 +118,10 @@ /* Additional interrupt modes: * - * .... .... .... .... .... III. .... .... + * .... .... .... .... ...I II.. .... .... */ -#define PIO_INT_SHIFT (9) /* Bits 9-11: PIO interrupt bits */ +#define PIO_INT_SHIFT (10) /* Bits 9-12: PIO interrupt bits */ #define PIO_INT_MASK (7 << PIO_INT_SHIFT) # define _PIO_INT_AIM (1 << 10) /* Bit 10: Additional Interrupt modes */ # define _PIO_INT_LEVEL (1 << 9) /* Bit 9: Level detection interrupt */ @@ -135,12 +135,24 @@ # define PIO_INT_FALLING (_PIO_INT_AIM | _PIO_INT_EDGE | _PIO_INT_FL) # define PIO_INT_BOTHEDGES (0) +/* If the pin is an interrupt, then this determines if the pin is a secure interrupt: + * + * .... .... .... .... .... ..S. .... .... + */ + +#ifdef SAMA5_SAIC +# define PIO_INT_SECURE (1 << 9) /* Bit 9: Secure interrupt */ +#else +# define PIO_INT_SECURE (0) +#endif +#define PIO_INT_UNSECURE (0) + /* If the pin is an PIO output, then this identifies the initial output value: * * .... .... .... .... .... ...V .... .... */ -#define PIO_OUTPUT_SET (1 << 8) /* Bit 8: Inital value of output */ +#define PIO_OUTPUT_SET (1 << 8) /* Bit 8: Initial value of output */ #define PIO_OUTPUT_CLEAR (0) /* This identifies the PIO port: diff --git a/arch/arm/src/sama5/sam_pioirq.c b/arch/arm/src/sama5/sam_pioirq.c index f80dcdc56e..0d9269a465 100644 --- a/arch/arm/src/sama5/sam_pioirq.c +++ b/arch/arm/src/sama5/sam_pioirq.c @@ -378,6 +378,21 @@ void sam_pioirq(pio_pinset_t pinset) uint32_t base = sam_piobase(pinset); int pin = sam_piopin(pinset); + /* Enable writing to PIO registers */ + + putreg32(PIO_WPMR_WPKEY, base + SAM_PIO_WPMR_OFFSET); + +#if defined(SAMA5_SAIC) && defined(SAM_PIO_ISLR_OFFSET) + /* Is the interrupt secure? */ + + if ((pinset & PIO_INT_SECURE) != 0) + { + uint32_t regval = getreg32(base + SAM_PIO_ISLR_OFFSET); + regval &= ~pin; + putreg32(regval, base + SAM_PIO_ISLR_OFFSET); + } +#endif + /* Are any additional interrupt modes selected? */ if ((pinset & _PIO_INT_AIM) != 0) @@ -414,6 +429,10 @@ void sam_pioirq(pio_pinset_t pinset) putreg32(pin, base + SAM_PIO_AIMDR_OFFSET); } + + /* Disable writing to PIO registers */ + + putreg32(PIO_WPMR_WPEN | PIO_WPMR_WPKEY, base + SAM_PIO_WPMR_OFFSET); } /************************************************************************************