Support for Interrupts on ARM-RTOS in the K2 family.
authorJohn Godbey <j-godbey@ti.com>
Mon, 16 Nov 2015 18:30:57 +0000 (13:30 -0500)
committerSam Nelson <sam.nelson@ti.com>
Tue, 17 Nov 2015 03:29:14 +0000 (22:29 -0500)
- Added support for the Interrupt module running on ARM-RTOS.
- Updated Interrupt.c to handle the ARM side.
- Added an entry for hardware semaphore support in Settings.xs.

Signed-off-by:John Godbey <j-godbey@ti.com>

packages/ti/sdo/ipc/family/Settings.xs
packages/ti/sdo/ipc/family/tci663x/Interrupt.c
packages/ti/sdo/ipc/family/tci663x/Interrupt.xs

index 6f9e431d849bf648daa8a2cd78f3dbf7bc01efaf..afb6f0d194a1232849d128d32a4686b2a61c0eef 100644 (file)
@@ -146,7 +146,8 @@ var deviceAliases = {
                            'TMS320TCI6636',
                            'TMS320TCI6638',
                            'Kepler'],
-    'TMS320C66AK2H12'   : ['TCI66AK2G02'],
+    'TMS320C66AK2H12'   : ['TCI66AK2G02',
+                           'TCI6636K2H'],
     'LM3.*'             : ['LM4.*'],
     'Vayu'              : ['DRA7XX']
 }
@@ -293,6 +294,7 @@ var notifySetupDelegates = {
     'TMS320C6472'       : { del: 'ti.sdo.ipc.family.c647x.NotifySetup', },
     'TMS320C6474'       : { del: 'ti.sdo.ipc.family.c647x.NotifySetup', },
     'TMS320TCI6634'     : { del: 'ti.sdo.ipc.family.tci663x.NotifyCircSetup', },
+    'TCI6636K2H'        : { del: 'ti.sdo.ipc.family.tci663x.NotifyCircSetup', },
     'OMAP4430'          : { del: 'ti.sdo.ipc.family.omap4430.NotifySetup', },
     'Arctic'            : { del: 'ti.sdo.ipc.family.arctic.NotifyCircSetup', },
     'LM3.*'             : { del: 'ti.sdo.ipc.notifyDrivers.NotifySetupNull', },
@@ -350,6 +352,8 @@ var interruptDelegates = {
     },
     'ti.catalog.arm.cortexa15' : {
         'Vayu'          : { del: 'ti.sdo.ipc.family.vayu.InterruptHost', },
+        'TCI66AK2G02'   : { del: 'ti.sdo.ipc.family.tci663x.Interrupt', },
+        'TCI6636K2H'    : { del: 'ti.sdo.ipc.family.tci663x.Interrupt', },
     },
     'ti.catalog.c6000' : {
         'OMAP3530'      : { del: 'ti.sdo.ipc.family.omap3530.InterruptDsp', },
@@ -363,6 +367,7 @@ var interruptDelegates = {
         'TMS320C6678'   : { del: 'ti.sdo.ipc.family.c647x.Interrupt', },
         'TMS320C6670'   : { del: 'ti.sdo.ipc.family.c647x.Interrupt', },
         'TMS320TCI6634' : { del: 'ti.sdo.ipc.family.tci663x.Interrupt', },
+        'TCI6636K2H'    : { del: 'ti.sdo.ipc.family.tci663x.Interrupt', },
 
         'OMAP4430'      : { del: 'ti.sdo.ipc.family.omap4430.InterruptDsp', },
         'Arctic'        : { del: 'ti.sdo.ipc.family.arctic.InterruptDsp', },
@@ -488,8 +493,15 @@ var hwSemDelegates = {
             baseAddr:   0x02640100,
             queryAddr:  0x02640200,
             numSems:    32,
-        },
+        }
     },
+    'ti.catalog.arm.cortexa15' : {
+        'TMS320C66AK2H12' : {
+            baseAddr:   0x02640100,
+            queryAddr:  0x02640200,
+            numSems:    32,
+        }
+    }
 }
 for (var family in hwSemDelegates) {
     setDeviceAliases(hwSemDelegates[family], deviceAliases);
index 6989d06ead30d515bcd778ad822c8be72367ed0d..ad6c61ebf026c27ee80e6a0d6b096989e64baec8 100644 (file)
 
 #include "package/internal/Interrupt.xdc.h"
 
-extern volatile cregister UInt DNUM;
+#define ARM_SOURCE_OFFSET 31
+#define ARM_HWI_OFFSET 32
 
+#ifdef _TMS320C6X
+    extern cregister volatile UInt DNUM;
+#else
+    /* ARM does not support DNUM */
+#endif
 
 /*
  *************************************************************************
@@ -92,6 +98,7 @@ Int Interrupt_Module_startup(Int phase)
                 Interrupt_A_hostConfig);
     }
 
+#ifdef _TMS320C6X
     /*  Validate the running executable has been loaded onto the correct
      *  processor. In other words, make sure CORE0 was loaded onto DSP0
      *  (i.e. DNUM == 0), CORE1 loaded onto DSP1, etc.
@@ -102,12 +109,17 @@ Int Interrupt_Module_startup(Int phase)
     if (nameId != DNUM) {
         System_abort("incorrect executable loaded onto processor");
     }
+#else
+    /*  Host doesn't necessarily follow the same naming conventions
+    */
+#endif
 
     if (!Interrupt_enableKick) {
         /* do not unlock the kick registers */
         return (Startup_DONE);
     }
 
+#ifdef _TMS320C6X
     /* only write KICK registers from CORE0 */
     if (DNUM == 0) {
         /* TODO: What if CORE0 is not started, but the others are? */
@@ -120,6 +132,10 @@ Int Interrupt_Module_startup(Int phase)
             *kick1 = 0x95a4f1e0;        /* must be written with this value */
         }
     }
+#else
+    /*  reserved for RTOS HOST
+    */
+#endif
     return (Startup_DONE);
 }
 
@@ -153,7 +169,11 @@ Void Interrupt_intRegister(UInt16 remoteProcId, IInterrupt_IntInfo *unused,
     UInt key;
     Hwi_Params hwiAttrs;
     UInt16 clusterId;
+#ifdef _TMS320C6X
     volatile UInt32 *ipcar = (volatile UInt32 *)Interrupt_IPCAR0;
+#else
+    volatile UInt32 *ipcarh = (volatile UInt32 *)Interrupt_IPCARH;
+#endif
     UInt32 val;
 
     /* disable global interrupts */
@@ -167,16 +187,28 @@ Void Interrupt_intRegister(UInt16 remoteProcId, IInterrupt_IntInfo *unused,
     /* make sure the interrupt gets plugged only once */
     if (Interrupt_module->numPlugged++ == 0) {
 
+#ifdef _TMS320C6X
         /* clear all pending ipc interrupts */
         val = ipcar[DNUM];
         ipcar[DNUM] = val;
+#else
+        /* Verify that this works for ARM */
+        val = *ipcarh;
+        *ipcarh = val;
+#endif
 
         /* register ipc interrupt */
         Hwi_Params_init(&hwiAttrs);
         hwiAttrs.maskSetting = Hwi_MaskingOption_SELF;
-        hwiAttrs.eventId = Interrupt_INTERDSPINT;
+#ifdef _TMS320C6X
+        hwiAttrs.eventId = Interrupt_INTERDSPINT,
         Interrupt_module->hwi = Hwi_create(Interrupt_ipcIntr, Interrupt_isr,
                 &hwiAttrs, NULL);
+#else
+        Interrupt_module->hwi =
+            Hwi_create(Interrupt_INTERDSPINT + ARM_HWI_OFFSET,
+            Interrupt_isr, &hwiAttrs, NULL);
+#endif
     }
 
     /* restore global interrupts */
@@ -219,12 +251,18 @@ Void Interrupt_intSend(UInt16 procId, IInterrupt_IntInfo *unused, UArg arg)
     int clusterId;
     UInt dnum;
 
+#ifdef _TMS320C6X
     /*  bit 0 is set to generate interrupt.
      *  bits 4-7 is set to specify the interrupt generation source.
      *  The convention is that bit 4 (SRCS0) is used for core 0,
      *  bit 5 (SRCS1) for core 1, etc... .
      */
     val = (1 << (DNUM + Interrupt_SRCSx_SHIFT)) | 1;
+#else
+    /*  Host sets the first bit instead of using DNUM
+    */
+    val = (1 << ARM_SOURCE_OFFSET) | 1;
+#endif
 
     if (procId == MultiProc_getId("HOST")) {
         /* interrupt the host processor,  use IPCGRH register */
@@ -247,15 +285,23 @@ Void Interrupt_intPost(UInt16 srcProcId, IInterrupt_IntInfo *intInfo, UArg arg)
     int clusterId;
     int bit;
     UInt32 val;
+#ifdef _TMS320C6X
     volatile UInt32 *ipcgr = (volatile UInt32 *)Interrupt_IPCGR0;
+#else
+    volatile UInt32 *ipcgrh = (volatile UInt32 *)Interrupt_IPCGRH;
+#endif
 
     /* compute srcsx bit of source processor */
     clusterId = srcProcId - Interrupt_module->baseId;
     bit = Interrupt_module->hwTab[clusterId].srcsx;
     val = (1 << bit) | 1;
 
+#ifdef _TMS320C6X
     /* raise the interrupt to myself */
     ipcgr[DNUM] = val;
+#else
+    *ipcgrh = val;
+#endif
 }
 
 /*
@@ -268,7 +314,11 @@ UInt Interrupt_intClear(UInt16 remoteProcId, IInterrupt_IntInfo *unused)
 {
     int clusterId;
     int pos;
+#ifdef _TMS320C6X
     volatile UInt32 *ipcar = (volatile UInt32 *)Interrupt_IPCAR0;
+#else
+    volatile UInt32 *ipcarh = (volatile UInt32 *)Interrupt_IPCARH;
+#endif
     UInt val;
     UInt stat = 0;
 
@@ -276,12 +326,20 @@ UInt Interrupt_intClear(UInt16 remoteProcId, IInterrupt_IntInfo *unused)
     clusterId = remoteProcId - Interrupt_module->baseId;
     pos = Interrupt_module->hwTab[clusterId].srcsx;
 
+#ifdef _TMS320C6X
     /* read ipcar register to get source bits */
     val = ipcar[DNUM];
+#else
+    val = *ipcarh;
+#endif
 
     if (val & (1 << pos)) {
+#ifdef _TMS320C6X
         /* write ipc acknowledgement register to clear source bit */
         ipcar[DNUM] = (1 << pos);
+#else
+        *ipcarh = (1 << pos);
+#endif
         stat = 1;
     }
 
@@ -301,20 +359,32 @@ Void Interrupt_isr(UArg unused)
 {
     int clId;
     Interrupt_ClientEntry *entry;
+#ifdef _TMS320C6X
     volatile UInt32 *ipcar = (volatile UInt32 *)Interrupt_IPCAR0;
+#else
+    volatile UInt32 *ipcarh = (volatile UInt32 *)Interrupt_IPCARH;
+#endif
     UInt32 val;
     int bit;
 
+#ifdef _TMS320C6X
     /* ipc acknowledgement register value */
     val = ipcar[DNUM];
+#else
+    val = *ipcarh;
+#endif
 
     for (clId = 0; clId < ti_sdo_utils_MultiProc_numProcsInCluster; clId++) {
         bit = Interrupt_module->hwTab[clId].srcsx;
 
         if (val & (1 << bit)) {
 
+#ifdef _TMS320C6X
             /* clear the interrupt source */
             ipcar[DNUM] = (1 << bit);
+#else
+            *ipcarh = (1 << bit);
+#endif
 
             /* invoke the client isr */
             entry = &(Interrupt_module->clientTab[clId]);
index e2da8ffe922a9c2078f28f6e87ab1bd8886cbbe0..75672acd55bc135d2c07719d83782941f9e1398d 100644 (file)
@@ -34,6 +34,7 @@
  *  ======== Interrupt.xs ========
  */
 
+var isaChain = "";
 var deviceSettings = {
     /* all Keystone II devices inherit from TCI6634 */
     'TMS320TCI6634' : {
@@ -43,7 +44,8 @@ var deviceSettings = {
         IPCARH:         0x026202A0,
         KICK0:          0x02620038,
         KICK1:          0x0262003C,
-        INTERDSPINT:    105
+        INTERDSPINT:    105,
+        IPCHOSTINT:     4
     }
 };
 
@@ -62,6 +64,9 @@ function module$meta$init()
         return;
     }
 
+    /* concatinate isa chain into single string for easier matching */
+    isaChain = "#" + Program.build.target.getISAChain().join("#") + "#";
+
     var settings = deviceSettings[Program.cpu.deviceName];
 
     this.IPCGR0         = settings.IPCGR0;
@@ -70,7 +75,12 @@ function module$meta$init()
     this.IPCARH         = settings.IPCARH;
     this.KICK0          = settings.KICK0;
     this.KICK1          = settings.KICK1;
-    this.INTERDSPINT    = settings.INTERDSPINT;
+    if (isaChain.match(/#64P#/)) {
+        this.INTERDSPINT    = settings.INTERDSPINT;
+    }
+    else if (isaChain.match(/#v7A#/)) {
+        this.INTERDSPINT    = settings.IPCHOSTINT;
+    }
 }
 
 /*