summaryrefslogtreecommitdiffstats
path: root/pk/std/std_irq_config.h
diff options
context:
space:
mode:
authorGlenn Miles <milesg@us.ibm.com>2015-02-27 13:33:34 -0600
committerGlenn R. Miles <milesg@us.ibm.com>2015-03-09 12:10:05 -0500
commitf08700ec353ff65467239241558fcdf1a87e377f (patch)
treee31a9c6655634e3c59f9a509c4ace8daeca09487 /pk/std/std_irq_config.h
parent69207c6c1750b4051b9be1dd9bdd984dd7d3db3d (diff)
downloadtalos-sbe-f08700ec353ff65467239241558fcdf1a87e377f.tar.gz
talos-sbe-f08700ec353ff65467239241558fcdf1a87e377f.zip
Add external interrupt support for standard PPE's
Change-Id: I5ac49d4a9aace2dfbe3cdebf0dd7942c1e22da4e Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/16240 Reviewed-by: Glenn R. Miles <milesg@us.ibm.com> Tested-by: Glenn R. Miles <milesg@us.ibm.com>
Diffstat (limited to 'pk/std/std_irq_config.h')
-rw-r--r--pk/std/std_irq_config.h141
1 files changed, 141 insertions, 0 deletions
diff --git a/pk/std/std_irq_config.h b/pk/std/std_irq_config.h
new file mode 100644
index 00000000..a3d9426e
--- /dev/null
+++ b/pk/std/std_irq_config.h
@@ -0,0 +1,141 @@
+#ifndef __STD_IRQ_CONFIG_H__
+#define __STD_IRQ_CONFIG_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2015
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file std_irq_config.h
+/// \brief Contains data and macros pertaining to external interrupt
+/// configuration for a standard PPE.
+///
+
+/// This constant is used to define the size of the table of interrupt handler
+/// structures as well as a limit for error checking.
+#define EXTERNAL_IRQS 64
+
+// Standard interrupt type values (level or edge)
+#define STD_IRQ_TYPE_LEVEL 0
+#define STD_IRQ_TYPE_EDGE 1
+
+// Standard interrupt polarity values (high or low, rising falling)
+#define STD_IRQ_POLARITY_LO 0
+#define STD_IRQ_POLARITY_FALLING 0
+#define STD_IRQ_POLARITY_HI 1
+#define STD_IRQ_POLARITY_RISING 1
+
+// Standard interrupt mask values (masked or enabled)
+#define STD_IRQ_MASKED 0
+#define STD_IRQ_ENABLED 1
+
+// Fail to compile if the application does not define this
+#ifndef APPCFG_EXT_IRQS_CONFIG
+#error "APPCFG_EXT_IRQS_CONFIG must be defined in pk_app_cfg.h"
+#endif
+
+// Fail to compile if the application does not define this
+#ifndef APPCFG_IRQ_INVALID_MASK
+#error "APPCFG_IRQ_INVALID_MASK must be defined in pk_app_cfg.h"
+#endif
+
+#ifndef __ASSEMBLER__
+
+/// This expression recognizes only those IRQ numbers that have named
+/// (non-reserved) interrupts in the standard PPE interrupt controller.
+#define STD_IRQ_VALID(irq) \
+ ({unsigned __irq = (unsigned)(irq); \
+ ((__irq < EXTERNAL_IRQS) && \
+ ((STD_IRQ_MASK64(__irq) & \
+ APPCFG_IRQ_INVALID_MASK) == 0));})
+
+/// This is a 64-bit mask, with big-endian bit 'irq' set.
+#define STD_IRQ_MASK64(irq) (0x8000000000000000ull >> (irq))
+
+#else
+
+//Untyped assembler version of STD_IRQ_MASK64
+#define STD_IRQ_MASK64(irq) (0x8000000000000000 >> (irq))
+
+#endif /* __ASSEMBLER__ */
+
+#ifndef __ASSEMBLER__
+/// These globals are statically initialized elsewhere
+extern uint64_t g_ext_irqs_type;
+extern uint64_t g_ext_irqs_valid;
+extern uint64_t g_ext_irqs_polarity;
+extern uint64_t g_ext_irqs_enable;
+#endif
+
+#ifdef __ASSEMBLER__
+/// These macros aid in the initialization of the external interrupt globals. I would
+/// prefer to use CPP macros, but they don't support recursive macros which I use to
+/// convert the variable number of interrupts that a processor can control into static
+/// bitmaps used by __hwmacro_setup() at runtime.
+
+
+ //helper macro for setting up the irq configuration bitmaps for a standard PPE
+ .macro .std_irq_config irq_num=-1 irq_type=-1 irq_polarity=-1 irq_mask=-1 parms:vararg
+ .if (( \irq_num == -1 ) && ( \irq_type == -1 ) && ( \irq_polarity == -1 ) && ( \irq_mask == -1 ))
+#.if ( .ext_irqs_defd != .ext_irqs_valid )
+#.error "###### .std_irq_config: Missing configuration for one or more interrupts ######"
+#.endif
+
+ .section .sdata
+ .align 3
+ .global g_ext_irqs_type
+ .global g_ext_irqs_polarity
+ .global g_ext_irqs_enable
+ g_ext_irqs_polarity:
+ .quad .ext_irqs_polarity
+ g_ext_irqs_type:
+ .quad .ext_irqs_type
+ g_ext_irqs_enable:
+ .quad .ext_irqs_enable
+ .else
+ .if (( \irq_num < 0 ) || ( \irq_num > (EXTERNAL_IRQS - 1)))
+ .error "###### .std_irq_config: invalid irq number \irq_num ######"
+ .elseif ((.ext_irqs_valid & (1 << ( EXTERNAL_IRQS - 1 - \irq_num ))) == 0 )
+ .error "###### .std_irq_config: Attempt to configure invalid irq number \irq_num ######"
+ .elseif (.ext_irqs_defd & (1 << ( EXTERNAL_IRQS - 1 - \irq_num )))
+ .error "###### .std_irq_config: duplicate definition for irq \irq_num ######"
+ .else
+ .ext_irqs_defd = .ext_irqs_defd | (1 << ( EXTERNAL_IRQS - 1 - \irq_num ))
+ .endif
+
+ .if (( \irq_type < 0 ) || ( \irq_type > 1 ))
+ .error "###### .std_irq_config: invalid/unspecified irq type \irq_type for irq \irq_num ######"
+ .else
+ .ext_irqs_type = .ext_irqs_type | ( \irq_type << ( EXTERNAL_IRQS - 1 - \irq_num ))
+ .endif
+
+ .if (( \irq_polarity < 0 ) || ( \irq_polarity > 1 ))
+ .error "###### .std_irq_config: invalid/unspecified irq polarity ( \irq_polarity ) for irq \irq_num ######"
+ .else
+ .ext_irqs_polarity = .ext_irqs_polarity | ( \irq_polarity << ( EXTERNAL_IRQS - 1 - \irq_num ))
+ .endif
+
+ .if (( \irq_mask < 0 ) || ( \irq_mask > 1 ))
+ .error "###### .std_irq_config: invalid/unspecified irq mask ( \irq_mask ) for irq \irq_num ######"
+ .else
+ .ext_irqs_enable = .ext_irqs_enable | ( \irq_mask << ( EXTERNAL_IRQS - 1 - \irq_num ))
+ .endif
+
+ .std_irq_config \parms
+ .endif
+ .endm
+
+ //Top level macro for generating interrupt configuration globals for a standard PPE
+ .macro .std_irq_cfg_bitmaps
+ .ext_irqs_valid = ~(APPCFG_IRQ_INVALID_MASK)
+ .ext_irqs_type = 0
+ .ext_irqs_polarity = 0
+ .ext_irqs_enable = 0
+ .irq_mask = 0
+ .ext_irqs_defd = 0
+ .std_irq_config APPCFG_EXT_IRQS_CONFIG
+ .endm
+
+#endif /*__ASSEMBLER__*/
+
+#endif /*__STD_IRQ_CONFIG_H__*/
OpenPOWER on IntegriCloud