[Feature]Upload Modem source code
Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/driver/devdrv/cirq/md97/src/GCC/mips_vic_entry.S b/mcu/driver/devdrv/cirq/md97/src/GCC/mips_vic_entry.S
new file mode 100644
index 0000000..636a141
--- /dev/null
+++ b/mcu/driver/devdrv/cirq/md97/src/GCC/mips_vic_entry.S
@@ -0,0 +1,69 @@
+#include "drv_mdcirq_reg.h"
+
+.text
+.section "INTERRUPT_VECTOR", "ax"
+.set push
+.set nomips16
+.set noreorder
+interrupt_vector:
+.globl interrupt_vector
+.ent interrupt_vector
+ IRQ0_VEC:
+ li $k0, 0
+ la $k1, irq_handler
+ jr $k1
+
+ .align 5
+ IRQ1_VEC:
+ li $k0, 1
+ la $k1, irq_handler
+ jr $k1
+
+ .align 5
+ IRQ2_VEC:
+ li $k0, 2
+ la $k1, irq_handler
+ jr $k1
+
+ .align 5
+ IRQ3_VEC:
+ li $k0, 3
+ la $k1, irq_handler
+ jr $k1
+
+ .align 5
+ IRQ4_VEC:
+ li $k0, 4
+ la $k1, irq_handler
+ jr $k1
+
+ .align 5
+ IRQ5_VEC:
+ li $k0, 5
+#if defined(__MDCIRQ_OSIPI_SPECIAL_FLOW__)
+ la $k1, ipi_handler
+ jr $k1
+#else
+ la $k1, irq_handler
+ jr $k1
+#endif
+
+ .align 5
+ IRQ6_VEC:
+ li $k0, 6
+ la $k1, irq_handler
+ jr $k1
+
+ .align 5
+ IRQ7_VEC:
+ li $k0, 7
+ la $k1, irq_handler
+ jr $k1
+
+.size interrupt_vector,.-interrupt_vector
+.set reorder
+.end interrupt_vector
+.set pop
+
+
+
diff --git a/mcu/driver/devdrv/cirq/md97/src/drv_mdcirq.c b/mcu/driver/devdrv/cirq/md97/src/drv_mdcirq.c
new file mode 100644
index 0000000..c416f4f
--- /dev/null
+++ b/mcu/driver/devdrv/cirq/md97/src/drv_mdcirq.c
@@ -0,0 +1,2445 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * drv_mdcirq.c
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * Low level interrupt controller driver
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ * ==========================================================================
+ * $Log$
+ *
+ * 07 07 2020 jacky-sh.wang
+ * [MOLY00543671] [Gen97][Palmer] MDCIRQ driver porting
+ * 1. Palmer call for check-in
+ * 2. Add IRQ pending status query API
+ *
+ * 04 16 2020 chia-han.wu
+ * [MOLY00477218] [Gen97][MDCIRQ][System Service] MDCIRQ driver development
+ * 1. Enable MDCIRQ New Architecture
+ * 2. Back-to-back IRQ speedup flow
+ * 3. SW workaround for MDCIRQ broadcast issue
+ *
+ * 02 11 2020 chia-han.wu
+ * [MOLY00499118] [ALPS04987882][Margaux] debug patch for IRQ178 unexpectedly masked issue
+ * record caller and frc which masked/unmasked IRQ178
+ *
+ * 09 23 2019 chia-han.wu
+ * [MOLY00423169] [Gen97][MDCIRQ][System Service] MDCIRQ driver development
+ * 1. Disable shrink DI duration logging mode
+ * 2. Disable nested DI/EI check
+ * 3. Add debug variable for IE sampling, IE status, dormant state
+ * 4. Fix VPE_STATUS_HISR_TASK_LOWEST
+ * 5. Add group 24 for NR IRQs
+ *
+ * 09 18 2019 chia-han.wu
+ * [MOLY00437875] Dynamic Affinity Change & Equally Dispatch
+ * Roll back equally dispatch
+ *
+ * 09 06 2019 chia-han.wu
+ * [MOLY00437875] Dynamic Affinity Change & Equally Dispatch
+ * LTE Rx tick dynamic affinity change & Equally dispatch
+ *
+ * 07 31 2019 chia-han.wu
+ * [MOLY00423169] [Gen97][MDCIRQ][System Service] MDCIRQ driver development
+ * 1. IRQ timing record API
+ * 2. remove MO_Sync in Set/Clear OSIPI
+ *
+ * 07 12 2019 chia-han.wu
+ * [MOLY00421608] [MDCIRQ][System Service] Remove IRQ_Register_LISR() and IRQSensitivity() for ISR Centralization
+ * .
+ *
+ * 06 25 2019 chia-han.wu
+ * [MOLY00396869] [MODIS HW Copro] Work on making Modis to run with ESL HW models and Uplane with ESL
+ * Merge MASE ESL modifications back to VMOLY Trunk
+ *
+ * 06 17 2019 chia-han.wu
+ * [MOLY00409637] [Gen97][MDCIRQ][System Service] MDCIRQ driver development
+ * rollback debug assert modifications for hard to detect bugs
+ *
+ * 05 20 2019 chia-han.wu
+ * [MOLY00406573] [MOLY00405204] [Gen97][MDCIRQ][System Service] MDCIRQ driver development
+ * runtime change NR IRQ affinity
+ *
+ * 05 10 2019 chia-han.wu
+ * [MOLY00405655] [Gen97][MDCIRQ][System Service] replace assert with debug_assert for SMO
+ * .
+ *
+ * 05 09 2019 chia-han.wu
+ * [MOLY00405020] [SystemService][ESL] Patch Modification for L1 Performance Evaluation Framework
+ * Modification for Gen97 ESL
+ *
+ * 05 09 2019 chia-han.wu
+ * [MOLY00405204] [Gen97][MDCIRQ][System Service] MDCIRQ driver development
+ * remove L1_ASSERT_BYPASS
+ *
+ * 05 09 2019 chia-han.wu
+ * [MOLY00405204] [Gen97][MDCIRQ][System Service] MDCIRQ driver development
+ * 1. CHRT domain DI not allowed check
+ * 2. Optimize activate/deavtivate LISR by using light weight ITC lock
+ * 3. remove L1_ASSERT_BYPASS
+ *
+ * 04 19 2019 chia-han.wu
+ * [MOLY00400628] [Gen97][MDCIRQ][System Service] fix build warning
+ * fix NLWCTG_SAP_CUSTOM build error
+ *
+ * 04 11 2019 chia-han.wu
+ * [MOLY00398536] [System Service][MOLY Kernel Internal Request] SST: bi-weekly release WK15
+ * backup some cirq status registers after CTI to decrease CTI delay
+ *
+ * 03 18 2019 chia-han.wu
+ * [MOLY00378746] [System Service] [KAL Config] ISR Centraliztion Framework.
+ * Optimize IRQ sensitivity config for ISR Centralization
+ *
+ * 02 18 2019 chia-han.wu
+ * [MOLY00378459] [MT6297][Phone Call][NSA FullStack][Keysight] Assert fail: lhrt_check.c 134 - (LISR)PHY LTMR Inst2
+ * SW workaround for Shaolin HW bug (Ticket:118884)
+ *
+ * 02 15 2019 panu.peisa
+ * [MOLY00384803] [Gen97][SystemService][Change Request] KAL Refactoring Phase-in
+ *
+ * Added changes to swrd part.
+ *
+ * 02 15 2019 chia-han.wu
+ * [MOLY00384599] [MT6297][APOLLO]Update Bus driver for PWB bypass AWID check
+ * Revert SW workaround for CIRQ wait issue since foud root cause by PWB missetting
+ *
+ * 01 22 2019 chia-han.wu
+ * [MOLY00379054] [Gen97][idletask]: disable busy loop
+ * SW workaround for CIRQ wait issue
+ * (IRQ pending in CIRQ due to IE status is unexpectedly disabled)
+ *
+ * 01 21 2019 chia-han.wu
+ * [MOLY00378746] [System Service] [KAL Config] ISR Centraliztion Framework.
+ * Centralize Gen97 IRQ configurations
+ *
+ * 12 24 2018 chia-han.wu
+ * [MOLY00372791] [Gen97][MDCIRQ][System Service] enable CIRQ time history function to record IRQ 0x26's FRC
+ * enable irq0x26 time history
+ *
+ * 11 07 2018 chia-han.wu
+ * [MOLY00351302] [Gen97][MDCIRQ][System Service] MDCIRQ driver development
+ * 1. Reduce IRQ numbers from 372 to 368
+ * 2. Reduce YQ signals from 7 to 6
+ * 3. Define CRT Registers for Gen97
+ * 4. Raise TC priority in MIN_SAVE and reset TC priority according to IRQ priority in isrC_Main
+ * 5. Remove kal_if_hrt_domain and kal_if_chrt_domain and use kal_get_current_domain instead
+ * 6. Create drv_mdcirq_per_VPE_domain_type array to save all VPE's domain type
+ * 7. Reinitialize di_tc in interrupt_preinit
+ * 8. drv_mdcirq.c driver code modification
+ * 9. IRQ Configuration Settings according to Gen97_MDCIRQ_IRQ_Affinity_UserGuide
+ * 10. Remove redundant code
+ * 11. Bus monitor Runtime configure IRQ configuration settings
+ *
+ * 10 08 2018 chia-han.wu
+ * [MOLY00351302] [Gen97][MDCIRQ][System Service] MDCIRQ driver development
+ * Set R_MDCIRQ_RETREAT_BY_ALLOW_CNT to 32?d40 in MDCIRQ init code
+ *
+ * 08 16 2018 chia-han.wu
+ * [MOLY00345091] [MT6297][APOLLO]Update idle service flow for sleep
+ * Modify irq_handler flow for MT6297-VPE2?s Idle_Service_Handler_Wait()
+ *
+ * 08 13 2018 chia-han.wu
+ * [MOLY00345672] [Gen97][MDCIRQ][System Service] Merge code from UMOLYE.GEN97.DEV to VMOLY.TRUNK
+ * .
+ *
+ * 06 27 2018 chia-han.wu
+ * [MOLY00334727] [SystemService][Gen97][ESL] Merge ESL Modification to 97 DEV for L1 ESL bring-up modification
+ * .
+ *
+ * 06 05 2018 chia-han.wu
+ * [MOLY00331372] [Gen97][MDCIRQ][System Service] rename dormant related driver API
+ * rename drv_mdcirq_DCM_EI() to drv_mdcirq_Idletask_EI(), and drv_mdcirq_DCM_DI() to drv_mdcirq_Idletask_DI()
+ *
+ * 05 08 2018 yen-chun.liu
+ * [MOLY00302569] [Gen97][MDCIRQ][System Service] MDCIRQ driver development
+ * check-in MDCIRQ driver for Gen97.
+ *
+ * 05 08 2018 yen-chun.liu
+ * [MOLY00302569] [Gen97][MDCIRQ][System Service] MDCIRQ driver development
+ * check-in MDCIRQ driver for Gen97.
+ *
+ * 04 16 2018 gway.lo
+ * [MOLY00311118] [GEN97] bring-up owner related code check-in
+ * mdcirq makr code for boot to idle
+ *
+ * 03 13 2018 yen-chun.liu
+ * [MOLY00302569] [Gen97][MDCIRQ][System Service] MDCIRQ driver development
+ * fix priority ack part.
+ *
+ ****************************************************************************/
+/******************************************************************************
+ * Include header files
+ ******************************************************************************/
+#include "kal_iram_section_defs.h"
+#include "kal_public_api.h"
+#include "kal_internal_api.h"
+#include "kal_hrt_api.h"
+#include "kal_itc.h"
+#include "intrCtrl.h"
+#include "drv_comm.h"
+#include "drv_mdcirq.h"
+#include "sync_data.h"
+#include "ex_public.h"
+#include "init_comm.h"
+#include "SST_intrCtrl.h"
+#include "drv_vpe_irq.h"
+#include "ex_public.h"
+#include "syscomp_config.h"
+
+/******************************************************************************
+ * Define global data
+ ******************************************************************************/
+kal_uint32 IRQMaskStatus[NUM_IRQ_SOURCES/32 + 1];
+kal_uint32 IRQStatus[NUM_IRQ_SOURCES/32 + 1];
+kal_uint32 IRQ_B_NMI_B_MaskStatus;
+kal_uint32 IRQ_B_NMI_B_Status;
+kal_uint32 VPE_IE_Status;
+kal_uint32 VPE_IE_Sampling_Status;
+kal_uint32 VPE_Dormant_Status;
+kal_uint32 drv_mdcirq_NMI_ready[MDCIRQ_TOTAL_VPE_NUM] = {KAL_FALSE};
+kal_uint32 drv_mdcirq_NMI_trigger[MDCIRQ_TOTAL_VPE_NUM];
+kal_uint32 drv_mdcirq_deadlock_processing;
+kal_uint32 drv_mdcirq_irq_ack_exception;
+__MCURW_HWRO_C_ALIGNED_ZI_WB(32) kal_uint32 drv_mdcirq_activate_lisr_lock[8];
+kal_uint32 runtime_change_NRIRQ_affinity_NSA_timing_record[MDCIRQ_TOTAL_VPE_NUM];
+kal_uint32 runtime_change_NRIRQ_affinity_SA_timing_record[MDCIRQ_TOTAL_VPE_NUM];
+kal_uint32 runtime_change_LTEIRQ_affinity_ENDC_timing_record[MDCIRQ_TOTAL_VPE_NUM];
+kal_uint32 runtime_change_LTEIRQ_affinity_LTEONLY_timing_record[MDCIRQ_TOTAL_VPE_NUM];
+/* Array with domain type of every vpe. Needed since kal_get_current_domain() can only read the domain type for current vpe*/
+kal_uint32 drv_mdcirq_per_VPE_domain_type[MDCIRQ_TOTAL_VPE_NUM];
+
+
+extern kal_uint32 sst_ex_irq_mask_duration[];
+extern kal_uint32 sst_irq_mask_caller[];
+extern kal_uint32 IRQMaskCounter[];
+extern kal_uint32 sst_hrt_qbit_caller[];
+extern kal_uint32 HRTQbitCounter[];
+extern kal_uint32 kal_hrt_SaveAndSetIRQMask_NoCheck(void);
+extern void kal_hrt_RestoreIRQMask_NoCheck(kal_uint32 irq);
+extern void IRQMaskDurationHandler(kal_uint32 duration, kal_uint32 retaddr, kal_uint32 vpe_num);
+extern kal_bool MDCIRQ_IRQSensitivity_Status(kal_uint16 HWIRQCode);
+
+
+#if defined(__ENABLE_SW_TRIGGER_INTERRUPT__)
+kal_uint32 SW_INT_Counter[NUM_IRQ_SOURCES];
+#endif /* __ENABLE_SW_TRIGGER_INTERRUPT__ */
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ZI(4) kal_uint16 HWIRQCode2SWIRQCode[MDCIRQ_MAX_ISR_NUM];
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_RW(4) kal_uint16 SWIRQCode2HWIRQCode[MDCIRQ_MAX_ISR_NUM] =
+{
+ #define IRQ_PRIORITY_CONST(a) a,
+ #include "irqPriority.h"
+ #undef IRQ_PRIORITY_CONST
+};
+
+/* error checking for two IRQ number definition */
+typedef kal_uint32 irq_priority_boundary_check1[MDCIRQ_MAX_ISR_NUM - NUM_IRQ_SOURCES];
+typedef kal_uint32 irq_priority_boundary_check2[NUM_IRQ_SOURCES - MDCIRQ_MAX_ISR_NUM];
+
+/* error checking for IRQ priority not exceed the number of IRQs*/
+typedef kal_uint32 irq_priority_boundary_check1[MDCIRQ_MAX_ISR_NUM - IRQ_PRIORITY_END];
+typedef kal_uint32 irq_priority_boundary_check2[IRQ_PRIORITY_END - MDCIRQ_MAX_ISR_NUM];
+
+static const kal_uint16 irq_group_map2vpe_list[] =
+{
+ INTERRUPT_GROUP_M2V_LIST
+};
+
+const IRQRuntimeConfigStruct irq_runtime_config_table[]=
+{
+ {IRQ_MDINFRA_BUSMON_MATCH_STS_CODE, IRQ_SW_LISR41_CODE, IRQ_MDINFRA_BUSMON_MATCH_STS_CODE_PRIORITY, IRQ_SW_LISR41_CODE_PRIORITY},
+ {IRQ_MDMCU_BUSMON_MATCH_STS_CODE, IRQ_SW_LISR42_CODE, IRQ_MDMCU_BUSMON_MATCH_STS_CODE_PRIORITY, IRQ_SW_LISR42_CODE_PRIORITY},
+};
+
+/* add 1 for the case that MDCIRQ_MAX_ISR_NUM cannot be divied by 32 */
+kal_uint32 broadcastValueArray[MDCIRQ_MAX_ISR_NUM/32 + 1];
+kal_uint32 sensitivityValueArray[MDCIRQ_MAX_ISR_NUM/32 + 1];
+
+#if defined(__MTK_TARGET__)
+/* bb reg dump setting */
+EX_BBREG_DUMP cirq_dump;
+const kal_uint32 cirq_dump_regions[] =
+{
+ MDCIRQ_BASE, MDCIRQ_REG_END - MDCIRQ_BASE, 4, /* CIRQ APB registers*/
+ MDCIRQ_GCR_BASE, MDCIRQ_GCR_REG_END - MDCIRQ_GCR_BASE, 4, /* CIRQ custom GCR registers */
+};
+#endif /* __MTK_TARGET__ */
+
+
+/*****************************************************************************
+ * External function/variables *
+ *****************************************************************************/
+extern const isr_config_s isr_config_tbl[];
+extern void NMI_handler();
+
+/*****************************************************************************
+ * Function Declaration *
+ *****************************************************************************/
+void drv_mdcirq_clr_all_swtr(void);
+
+/*****************************************************************************
+ * Function Implementation - Low Layer *
+ *****************************************************************************/
+
+void drv_mdcirq_unmask_all(void)
+{
+ /* unmask all CIRQ source */
+ kal_int32 i;
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM/32; i++)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_IMCR_BASE, i, 0xFFFFFFFF);
+ }
+ /* For the case that MDCIRQ_MAX_ISR_NUM cannot be divied by 32 */
+ if((MDCIRQ_MAX_ISR_NUM % 32) != 0)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_IMCR_BASE, (MDCIRQ_MAX_ISR_NUM/32), (1 << (MDCIRQ_MAX_ISR_NUM%32)) -1);
+ }
+}
+
+void drv_mdcirq_mask_all(void)
+{
+ kal_int32 i;
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM/32; i++)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_IMSR_BASE, i, 0xFFFFFFFF);
+ }
+ /* For the case that MDCIRQ_MAX_ISR_NUM cannot be divied by 32 */
+ if((MDCIRQ_MAX_ISR_NUM % 32) != 0)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_IMSR_BASE, (MDCIRQ_MAX_ISR_NUM/32), (1 << (MDCIRQ_MAX_ISR_NUM%32)) -1);
+ }
+}
+
+void drv_mdcirq_clr_all_status(void)
+{
+ kal_int32 i;
+#if !defined (__MDCIRQ_NEW_ARCHITECTURE__)
+ /* clear all CIRQ interrupt source */
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM/32; i++)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_ISAR_BASE, i, 0xFFFFFFFF);
+ }
+ /* For the case that MDCIRQ_MAX_ISR_NUM cannot be divied by 32 */
+ if((MDCIRQ_MAX_ISR_NUM % 32) != 0)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_ISAR_BASE, (MDCIRQ_MAX_ISR_NUM/32), (1 << (MDCIRQ_MAX_ISR_NUM%32)) -1);
+ }
+#else
+ /* Clear Status Registers one-by-one*/
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM; i++)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_ISAR_BASE, (i/32), (1 << (i%32)));
+ }
+#endif
+}
+
+void drv_mdcirq_clr_all_swtr(void)
+{
+ kal_int32 i;
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM/32; i++)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_ISTR_BASE, i, 0);
+ }
+ /* For the case that MDCIRQ_MAX_ISR_NUM cannot be divied by 32 */
+ if((MDCIRQ_MAX_ISR_NUM % 32) != 0)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_ISTR_BASE, (MDCIRQ_MAX_ISR_NUM/32), 0);
+ }
+}
+
+void drv_mdcirq_clr_all_pri_stk(void)
+{
+ kal_int32 i;
+ for(i=0; i < MDCIRQ_TOTAL_VPE_NUM; i++)
+ {
+#if defined(__MDCIRQ_GCR_SIGNAL_DISABLE__)
+ DRV_WriteReg32((MDCIRQ_VPE_IRQ_ID_RETURN_BASE + i*4), 0x3FF);
+#else
+ DRV_WriteReg32((MDCIRQ_GCR_VPE_IRQ_ID_RETURN_BASE + i*4), 0x3FF);
+#endif
+ }
+}
+
+void drv_mdcirq_set_irq_group(kal_uint32 HWIRQCode, kal_uint32 GROUP_ID)
+{
+ kal_uint32 reg_value, clear_value, SWIRQCode;
+ SWIRQCode = (kal_uint32)HWIRQCode2SWIRQCode[HWIRQCode];
+ reg_value = (GROUP_ID<<((SWIRQCode%4)*8)) ;
+ clear_value = ~(0xFF<<((SWIRQCode%4)*8));
+ reg_value = (DRV_Reg32(MDCIRQ_IRQ_GROUP_CFG(SWIRQCode)) & clear_value) | reg_value;
+ DRV_WriteReg32(MDCIRQ_IRQ_GROUP_CFG(SWIRQCode), reg_value);
+ MO_Sync();
+}
+
+
+
+void drv_mdcirq_set_Group2VPE(kal_uint32 group, kal_uint32 VPES)
+{
+ DRV_WriteReg32(MDCIRQ_GROUP_M2V_CFG(group), VPES);
+}
+
+void drv_mdcirq_set_Broadcast(kal_uint32 HWIRQCode, kal_bool Type)
+{
+ kal_uint32 SWIRQCode;
+ SWIRQCode = (kal_uint32)HWIRQCode2SWIRQCode[HWIRQCode];
+ if(Type==KAL_TRUE)
+ MDCIRQ_SetRegBit_Vector(MDCIRQ_IBROCAT_BASE,SWIRQCode);
+ else
+ MDCIRQ_ClrRegBit_Vector(MDCIRQ_IBROCAT_BASE,SWIRQCode);
+}
+
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ROCODE void drv_mdcirq_Set_VPE_state(kal_uint32 VPE, kal_uint32 state)
+{
+ DEBUG_ASSERT((VPE < MDCIRQ_TOTAL_VPE_NUM) && (state<=VPE_STATUS_HISR_TASK_LOWEST));
+#if defined(__MDCIRQ_GCR_SIGNAL_DISABLE__)
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_VPE_IRQ_STATE_BASE, VPE, state);
+#else
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_GCR_VPE_IRQ_STATE_BASE, VPE, state);
+#endif
+}
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ROCODE kal_uint32 drv_mdcirq_SaveAndSet_VPE_state(kal_uint32 VPE, kal_uint32 state)
+{
+ kal_uint32 ori_state;
+ DEBUG_ASSERT((VPE < MDCIRQ_TOTAL_VPE_NUM) && (state<=VPE_STATUS_HISR_TASK_LOWEST));
+#if defined(__MDCIRQ_GCR_SIGNAL_DISABLE__)
+ ori_state = MDCIRQ_READ_REG_INDEX(MDCIRQ_VPE_IRQ_STATE_BASE, VPE);
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_VPE_IRQ_STATE_BASE, VPE, state);
+#else
+ ori_state = MDCIRQ_READ_REG_INDEX(MDCIRQ_GCR_VPE_IRQ_STATE_BASE, VPE);
+
+#if 1
+#if !defined (__ESL_MASE_GEN97__)
+ /* SW workaround for Shaolin HW bug (Ticket:118884) */
+ __asm__ __volatile__ (
+ "addiu %0, %0, 0\n"
+ : "+r" (ori_state)
+ :
+ :
+ );
+#endif /* __ESL_MASE_GEN97__ */
+#endif
+
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_GCR_VPE_IRQ_STATE_BASE, VPE, state);
+#endif
+ return ori_state;
+}
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ROCODE void drv_mdcirq_Restore_VPE_state(kal_uint32 VPE, kal_uint32 ori_state)
+{
+ DEBUG_ASSERT((VPE < MDCIRQ_TOTAL_VPE_NUM) && (ori_state<=VPE_STATUS_HISR_TASK_LOWEST));
+#if defined(__MDCIRQ_GCR_SIGNAL_DISABLE__)
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_VPE_IRQ_STATE_BASE, VPE, ori_state);
+#else
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_GCR_VPE_IRQ_STATE_BASE, VPE, ori_state);
+#endif
+}
+
+void drv_mdcirq_set_NMI(kal_uint32 VPEID)
+{
+ DRV_WriteReg32(MDCIRQ_NMI_SET, 1<<VPEID);
+ MO_Sync();
+}
+
+void drv_mdcirq_clear_NMI(kal_uint32 VPEID)
+{
+ DRV_WriteReg32(MDCIRQ_NMI_CLR, 1<<VPEID);
+ MO_Sync();
+}
+
+void drv_mdcirq_clr_all_NMI(void)
+{
+ DRV_WriteReg32(MDCIRQ_NMI_CLR, MDCIRQ_ALL_VPE_MASK);
+ MO_Sync();
+}
+
+void drv_mdcirq_set_NMI_Mask(kal_uint32 VPEID)
+{
+ DRV_WriteReg32(MDCIRQ_NMI_MASK_SET,1<<VPEID);
+ MO_Sync();
+}
+
+void drv_mdcirq_clear_NMI_Mask(kal_uint32 VPEID)
+{
+ DRV_WriteReg32(MDCIRQ_NMI_MASK_CLR,1<<VPEID);
+ MO_Sync();
+}
+
+void drv_mdcirq_mask_NMI_all(void)
+{
+ DRV_WriteReg32(MDCIRQ_NMI_MASK, MDCIRQ_ALL_VPE_MASK);
+ MO_Sync();
+}
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ROCODE void drv_mdcirq_set_YQ_Signal(kal_uint32 CORE, kal_uint32 YQ_num)
+{
+ /* Set specified YQ signal */
+ DEBUG_ASSERT((CORE < MDCIRQ_TOTAL_CORE_NUM) && ((YQ_num % MDCIRQ_YQ_SIGNAL_GCR_START) < MDCIRQ_YQ_SIGNAL_PER_CORE_HALF));
+ if( YQ_num < MDCIRQ_YQ_SIGNAL_GCR_START)
+ {
+ DRV_WriteReg32(MDCIRQ_YQ_SET_REG_BASE+(YQ_num<<2),1<<CORE);
+ }
+ else
+ {
+ DRV_WriteReg32(MDCIRQ_GCR_YQ_SET_REG_BASE+((YQ_num-MDCIRQ_YQ_SIGNAL_GCR_START)<<2),1<<CORE);
+ }
+ MO_Sync();
+}
+
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ROCODE void drv_mdcirq_clear_YQ_Signal(kal_uint32 CORE, kal_uint32 YQ_num)
+{
+ /* Clear specified YQ signal */
+ DEBUG_ASSERT((CORE < MDCIRQ_TOTAL_CORE_NUM) && ((YQ_num % MDCIRQ_YQ_SIGNAL_GCR_START) < MDCIRQ_YQ_SIGNAL_PER_CORE_HALF));
+ if( YQ_num < MDCIRQ_YQ_SIGNAL_GCR_START)
+ {
+ DRV_WriteReg32(MDCIRQ_YQ_CLEAR_REG_BASE+(YQ_num<<2),1<<CORE);
+ }
+ else
+ {
+ DRV_WriteReg32(MDCIRQ_GCR_YQ_CLEAR_REG_BASE+((YQ_num-MDCIRQ_YQ_SIGNAL_GCR_START)<<2),1<<CORE);
+ }
+ MO_Sync();
+}
+
+void drv_mdcirq_set_YQ_Mask(kal_uint32 CORE, kal_uint32 YQ_num)
+{
+ /* Mask specified YQ signal */
+ DEBUG_ASSERT((CORE < MDCIRQ_TOTAL_CORE_NUM) && ((YQ_num % MDCIRQ_YQ_SIGNAL_GCR_START) < MDCIRQ_YQ_SIGNAL_PER_CORE_HALF));
+ if( YQ_num < MDCIRQ_YQ_SIGNAL_GCR_START)
+ {
+ DRV_WriteReg32(MDCIRQ_YQ_MASK_SET_REG_BASE+(YQ_num<<2),1<<CORE);
+ }
+ else
+ {
+ DRV_WriteReg32(MDCIRQ_GCR_YQ_MASK_SET_REG_BASE+((YQ_num-MDCIRQ_YQ_SIGNAL_GCR_START)<<2),1<<CORE);
+ }
+ MO_Sync();
+}
+
+void drv_mdcirq_clear_YQ_Mask(kal_uint32 CORE, kal_uint32 YQ_num)
+{
+ /* Unmask specified YQ signal */
+ DEBUG_ASSERT((CORE < MDCIRQ_TOTAL_CORE_NUM) && ((YQ_num % MDCIRQ_YQ_SIGNAL_GCR_START) < MDCIRQ_YQ_SIGNAL_PER_CORE_HALF));
+ if( YQ_num < MDCIRQ_YQ_SIGNAL_GCR_START)
+ {
+ DRV_WriteReg32(MDCIRQ_YQ_MASK_CLEAR_REG_BASE+(YQ_num<<2),1<<CORE);
+ }
+ else
+ {
+ DRV_WriteReg32(MDCIRQ_GCR_YQ_MASK_CLEAR_REG_BASE+((YQ_num-MDCIRQ_YQ_SIGNAL_GCR_START)<<2),1<<CORE);
+ }
+ MO_Sync();
+}
+
+void drv_mdcirq_clear_ALL_YQ_Mask(void)
+{
+ /* claer all YQ mask */
+ kal_int32 i;
+ for(i=0 ; i< MDCIRQ_YQ_SIGNAL_PER_CORE_HALF; i++)
+ {
+ DRV_WriteReg32(MDCIRQ_YQ_MASK_CLEAR_REG_BASE+(i<<2),MDCIRQ_ALL_CORE_MASK);
+ DRV_WriteReg32(MDCIRQ_GCR_YQ_MASK_CLEAR_REG_BASE+(i<<2),MDCIRQ_ALL_CORE_MASK);
+ }
+ MO_Sync();
+}
+
+void drv_mdcirq_set_ALL_YQ_Mask(void)
+{
+ kal_int32 i;
+ for(i=0 ; i< MDCIRQ_YQ_SIGNAL_PER_CORE_HALF; i++)
+ {
+ DRV_WriteReg32(MDCIRQ_YQ_MASK_SET_REG_BASE+(i<<2),MDCIRQ_ALL_CORE_MASK);
+ DRV_WriteReg32(MDCIRQ_GCR_YQ_MASK_SET_REG_BASE+(i<<2),MDCIRQ_ALL_CORE_MASK);
+ }
+ MO_Sync();
+}
+
+void drv_mdcirq_set_OSIPI(kal_uint32 VPEID)
+{
+ DRV_WriteReg32(MDCIRQ_GCR_OSIRQ_STATUS_SET, 1 << VPEID);
+}
+
+void drv_mdcirq_clear_OSIPI(kal_uint32 VPEID)
+{
+ DRV_WriteReg32(MDCIRQ_GCR_OSIRQ_STATUS_CLR, 1 << VPEID);
+}
+
+void drv_mdcirq_set_OSIPI_Mask(kal_uint32 VPEID)
+{
+ DRV_WriteReg32(MDCIRQ_GCR_OSIRQ_MASK_SET, 1 << VPEID);
+ MO_Sync();
+}
+
+void drv_mdcirq_clear_OSIPI_Mask(kal_uint32 VPEID)
+{
+ DRV_WriteReg32(MDCIRQ_GCR_OSIRQ_MASK_CLR, 1 << VPEID);
+ MO_Sync();
+}
+
+void drv_mdcirq_set_Ultra_threshold(kal_uint32 VPE, kal_uint32 PRLV)
+{
+ DEBUG_ASSERT((VPE<MDCIRQ_TOTAL_VPE_NUM)&&(PRLV<=MDCIRQ_LOWEST_PRI));
+ DRV_WriteReg32(MDCIRQ_VPE_ULTRA_PRLV_BASE+(VPE<<2), PRLV);
+ MO_Sync();
+}
+
+void drv_mdcirq_set_PreUltra_threshold(kal_uint32 VPE, kal_uint32 PRLV)
+{
+ DEBUG_ASSERT((VPE<MDCIRQ_TOTAL_VPE_NUM)&&(PRLV<=MDCIRQ_LOWEST_PRI));
+ DRV_WriteReg32(MDCIRQ_VPE_PREULTRA_PRLV_BASE+(VPE<<2), PRLV);
+ MO_Sync();
+}
+
+void drv_mdcirq_set_Ultra_PreUltra_mask_per_vpe(kal_uint32 VPE, kal_uint32 maskValue)
+{
+ DEBUG_ASSERT((VPE<MDCIRQ_TOTAL_VPE_NUM));
+ DRV_WriteReg32(MDCIRQ_ULTRA_MASK_CLR, (0x3 << (VPE * 2)));
+ DRV_WriteReg32(MDCIRQ_ULTRA_MASK_SET, (maskValue << (VPE * 2)));
+ MO_Sync();
+}
+
+void drv_mdcirq_set_Ultra_PreUltra_mask_all(kal_uint32 maskValue)
+{
+ kal_uint32 i, clearValue = 0, regValue = 0;
+ for( i = 0; i < MDCIRQ_TOTAL_VPE_NUM; i++)
+ {
+ clearValue |= (0x3 << (i * 2));
+ regValue |= (maskValue << (i * 2));
+ }
+ DRV_WriteReg32(MDCIRQ_ULTRA_MASK_CLR, clearValue);
+ DRV_WriteReg32(MDCIRQ_ULTRA_MASK_SET, regValue);
+ MO_Sync();
+}
+
+void drv_mdcirq_clear_Ultra_PreUltra_mask_per_vpe(kal_uint32 VPE, kal_uint32 maskValue)
+{
+ DEBUG_ASSERT((VPE<MDCIRQ_TOTAL_VPE_NUM));
+ DRV_WriteReg32(MDCIRQ_ULTRA_MASK_CLR, (maskValue << (VPE * 2)));
+ MO_Sync();
+}
+
+
+void drv_mdcirq_clear_Ultra_PreUltra_mask_all(kal_uint32 maskValue)
+{
+ kal_uint32 i, regValue = 0;
+ for( i = 0; i < MDCIRQ_TOTAL_VPE_NUM; i++)
+ {
+ regValue |= (maskValue << (2 * i));
+ }
+ DRV_WriteReg32(MDCIRQ_ULTRA_MASK_CLR, regValue);
+ MO_Sync();
+}
+
+void drv_mdcirq_set_HRTSignal_threshold(kal_uint32 VPE, kal_uint32 PRLV)
+{
+ DEBUG_ASSERT((VPE<MDCIRQ_TOTAL_VPE_NUM)&&(PRLV<=MDCIRQ_LOWEST_PRI));
+ DRV_WriteReg32(MDCIRQ_VPE_HRT_PRLV_BASE+(VPE<<2), PRLV);
+ MO_Sync();
+}
+
+void drv_mdcirq_set_HRTSignal_mask_per_vpe(kal_uint32 VPE)
+{
+ DEBUG_ASSERT((VPE<MDCIRQ_TOTAL_VPE_NUM));
+ DRV_WriteReg32(MDCIRQ_VPE_HRT_MASK_SET, (1 << VPE));
+ MO_Sync();
+}
+
+void drv_mdcirq_set_HRTSignal_mask_all()
+{
+ DRV_WriteReg32(MDCIRQ_VPE_HRT_MASK_SET, MDCIRQ_ALL_VPE_MASK);
+ MO_Sync();
+}
+
+void drv_mdcirq_clear_HRTSignal_mask_per_vpe(kal_uint32 VPE)
+{
+ DEBUG_ASSERT((VPE<MDCIRQ_TOTAL_VPE_NUM));
+ DRV_WriteReg32(MDCIRQ_VPE_HRT_MASK_CLR, (1 << VPE));
+ MO_Sync();
+}
+
+void drv_mdcirq_clear_HRTSignal_mask_all()
+{
+ DRV_WriteReg32(MDCIRQ_VPE_HRT_MASK_CLR, MDCIRQ_ALL_VPE_MASK);
+ MO_Sync();
+}
+
+void drv_mdcirq_set_EQD_mode(kal_uint32 mode)
+{
+ DEBUG_ASSERT(mode<=0x3);
+ DRV_WriteReg32(MDCIRQ_VPE_CRT_MODE, mode);
+ MO_Sync();
+}
+
+void drv_mdcirq_set_EQDSignal_threshold(kal_uint32 PRLV)
+{
+ DEBUG_ASSERT(PRLV<=MDCIRQ_LOWEST_PRI);
+ DRV_WriteReg32(MDCIRQ_VPE_CRT_PRLV, PRLV);
+ MO_Sync();
+}
+
+void drv_mdcirq_set_EQD_mask_per_vpe(kal_uint32 VPE)
+{
+ DEBUG_ASSERT((VPE<MDCIRQ_TOTAL_VPE_NUM));
+ DRV_WriteReg32(MDCIRQ_VPE_PRLV_CRT_MASK_SET, (1 << VPE));
+ MO_Sync();
+}
+
+void drv_mdcirq_set_EQD_mask_all()
+{
+ DRV_WriteReg32(MDCIRQ_VPE_PRLV_CRT_MASK_SET, MDCIRQ_ALL_VPE_MASK);
+ MO_Sync();
+}
+
+void drv_mdcirq_clear_EQD_mask_per_vpe(kal_uint32 VPE)
+{
+ DEBUG_ASSERT((VPE<MDCIRQ_TOTAL_VPE_NUM));
+ DRV_WriteReg32(MDCIRQ_VPE_PRLV_CRT_MASK_CLR, (1 << VPE));
+ MO_Sync();
+}
+
+void drv_mdcirq_clear_EQD_mask_all()
+{
+ DRV_WriteReg32(MDCIRQ_VPE_PRLV_CRT_MASK_CLR, MDCIRQ_ALL_VPE_MASK);
+ MO_Sync();
+}
+
+void drv_mdcirq_IRQ_mask(kal_uint32 VPE)
+{
+ DEBUG_ASSERT((VPE<MDCIRQ_TOTAL_VPE_NUM));
+ DRV_WriteReg32(MDCIRQ_VPE_INTMASK_SET, 1<<VPE);
+ MO_Sync();
+}
+
+void drv_mdcirq_IRQ_mask_all()
+{
+ DRV_WriteReg32(MDCIRQ_VPE_INTMASK_SET, MDCIRQ_ALL_VPE_MASK);
+ MO_Sync();
+}
+
+
+void drv_mdcirq_IRQ_unmask(kal_uint32 VPE)
+{
+ DEBUG_ASSERT((VPE<MDCIRQ_TOTAL_VPE_NUM));
+ DRV_WriteReg32(MDCIRQ_VPE_INTMASK_CLR, 1<<VPE);
+ MO_Sync();
+}
+
+
+void drv_mdcirq_IRQ_unmask_all()
+{
+ DRV_WriteReg32(MDCIRQ_VPE_INTMASK_CLR, MDCIRQ_ALL_VPE_MASK);
+ MO_Sync();
+}
+
+kal_uint32 drv_mdcirq_get_IRQ_ACK_enable()
+{
+ return (DRV_Reg32(MDCIRQ_CIRQ_GCR_MASK) & DRV_Reg32(MDCIRQ_CIRQ_APB_ACK_MASK));
+}
+
+
+void drv_mdcirq_GCR_enable(kal_bool enable)
+{
+ if(enable)
+ {
+ DRV_WriteReg32(MDCIRQ_CIRQ_GCR_MASK, 0);
+ }
+ else
+ {
+ DRV_WriteReg32(MDCIRQ_CIRQ_GCR_MASK, 1);
+ }
+ MO_Sync();
+}
+
+void drv_mdcirq_APB_enable(kal_bool enable)
+{
+ if(enable)
+ {
+ DRV_WriteReg32(MDCIRQ_CIRQ_APB_ACK_MASK, 0);
+ }
+ else
+ {
+ DRV_WriteReg32(MDCIRQ_CIRQ_APB_ACK_MASK, 1);
+ }
+ MO_Sync();
+}
+
+void drv_mdcirq_IRQ_ACK_enable(kal_bool enable)
+{
+ drv_mdcirq_GCR_enable(enable);
+ drv_mdcirq_APB_enable(enable);
+}
+
+//Enable/Disable Ibit sampling from VPE to MDCIRQ
+void drv_mdcirq_IBit_sampling_enable(kal_uint32 VPE, kal_bool enable)
+{
+ DEBUG_ASSERT((VPE<MDCIRQ_TOTAL_VPE_NUM));
+ if(enable)
+ {
+ DRV_WriteReg32(MDCIRQ_IE_CHECK_EN_SET, 1<<VPE);
+ }
+ else
+ {
+ DRV_WriteReg32(MDCIRQ_IE_CHECK_EN_CLR, 1<<VPE);
+ }
+ MO_Sync();
+}
+
+
+//Enable Ibit sampling from VPE to MDCIRQ
+void drv_mdcirq_IBit_sampling_enable_all(kal_bool enable)
+{
+ if(enable)
+ {
+ DRV_WriteReg32(MDCIRQ_IE_CHECK_EN_SET, MDCIRQ_ALL_VPE_MASK);
+ }
+ else
+ {
+ DRV_WriteReg32(MDCIRQ_IE_CHECK_EN_CLR, MDCIRQ_ALL_VPE_MASK);
+ }
+ MO_Sync();
+}
+
+//Disable Ibit sampling from VPE to MDCIRQ in DCM DI
+kal_uint32 drv_mdcirq_Idletask_DI()
+{
+ kal_uint32 vpe_num, ret;
+
+ Set_EXL();
+ vpe_num = kal_get_current_vpe_id();
+ drv_mdcirq_IBit_sampling_enable(vpe_num, KAL_FALSE);
+ ret = kal_hrt_SaveAndSetIRQMask_NoCheck();
+ Clear_EXL();
+ return ret;
+}
+
+//Enable Ibit sampling from VPE to MDCIRQ in DCM EI
+void drv_mdcirq_Idletask_EI(kal_uint32 ret)
+{
+ kal_uint32 vpe_num;
+
+ Set_EXL();
+ vpe_num = kal_get_current_vpe_id();
+ /* EI earlier than sampling enable to avoid IRQ resend*/
+ kal_hrt_RestoreIRQMask_NoCheck(ret);
+ drv_mdcirq_IBit_sampling_enable(vpe_num, KAL_TRUE);
+ Clear_EXL();
+}
+
+void drv_mdcirq_IBit_Ultra_select(kal_uint32 VPE, kal_uint32 Ultra_level)
+{
+ DEBUG_ASSERT((VPE<MDCIRQ_TOTAL_VPE_NUM) && (Ultra_level<3));
+ DRV_WriteReg32(MDCIRQ_ULTRA_CLR, 0x3 << (VPE*2));
+ DRV_WriteReg32(MDCIRQ_ULTRA_SET, Ultra_level << (VPE*2));
+ MO_Sync();
+}
+
+void drv_mdcirq_Ultra_mask(kal_uint32 VPE, kal_uint32 Ultra_level_mask)
+{
+ DEBUG_ASSERT((VPE<MDCIRQ_TOTAL_VPE_NUM) && (Ultra_level_mask<=3));
+ DRV_WriteReg32(MDCIRQ_ULTRA_MASK_CLR, 0x3 << (VPE*2));
+ DRV_WriteReg32(MDCIRQ_ULTRA_MASK_SET, Ultra_level_mask << (VPE*2));
+ MO_Sync();
+}
+
+void drv_mdcirq_set_dormant_state(kal_uint32 VPE)
+{
+ DEBUG_ASSERT((VPE<MDCIRQ_TOTAL_VPE_NUM));
+ DRV_WriteReg32(MDCIRQ_VPE_DORMANT_STATE_SET, (1 << VPE));
+ MO_Sync();
+}
+
+void drv_mdcirq_set_dormant_state_all()
+{
+ DRV_WriteReg32(MDCIRQ_VPE_DORMANT_STATE_SET, MDCIRQ_ALL_VPE_MASK);
+ MO_Sync();
+}
+
+void drv_mdcirq_clear_dormant_state(kal_uint32 VPE)
+{
+ DEBUG_ASSERT((VPE<MDCIRQ_TOTAL_VPE_NUM));
+ DRV_WriteReg32(MDCIRQ_VPE_DORMANT_STATE_CLEAR, (1 << VPE));
+ MO_Sync();
+}
+
+void drv_mdcirq_clear_dormant_state_all()
+{
+ DRV_WriteReg32(MDCIRQ_VPE_DORMANT_STATE_CLEAR, MDCIRQ_ALL_VPE_MASK);
+ MO_Sync();
+}
+
+void drv_mdcirq_set_vector_priority(kal_uint32 HWIRQCode, kal_uint32 priority)
+{
+ /* config the priority for specified CIRQ ID */
+
+ DEBUG_ASSERT(HWIRQCode < MDCIRQ_MAX_ISR_NUM);
+ DEBUG_ASSERT(priority <= MDCIRQ_LOWEST_PRI);
+
+ kal_uint32 priroty_local, shift_bits;
+
+ shift_bits = (priority % 2) * 16;
+
+ priroty_local = DRV_Reg32(MDCIRQ_PRLV(priority)) & (~(0x1FF << shift_bits));
+
+ priroty_local |= (HWIRQCode << shift_bits);
+
+ DRV_WriteReg32(MDCIRQ_PRLV(priority), priroty_local);
+ MO_Sync();
+
+ HWIRQCode2SWIRQCode[HWIRQCode] = (kal_uint16)priority;
+ SWIRQCode2HWIRQCode[priority] = (kal_uint16)HWIRQCode;
+
+}
+
+void drv_mdcirq_set_min_priority(kal_uint32 VPE, kal_uint32 priority)
+{
+ DEBUG_ASSERT(VPE < MDCIRQ_TOTAL_VPE_NUM);
+ DEBUG_ASSERT(priority <= MDCIRQ_LOWEST_PRI);
+
+#if defined(__MDCIRQ_GCR_SIGNAL_DISABLE__)
+ DRV_WriteReg32(MDCIRQ_VPE_MIN_PRLV_BASE + VPE*4, priority);
+#else
+ DRV_WriteReg32(MDCIRQ_GCR_VPE_MIN_PRLV_BASE + VPE*4, priority);
+#endif
+ MO_Sync();
+
+}
+
+void drv_mdcirq_set_broadcast_type(kal_uint32 HWIRQCode, kal_bool broadcast)
+{
+ /* config the broadcast type for specified CIRQ ID */
+ DEBUG_ASSERT(HWIRQCode < MDCIRQ_MAX_ISR_NUM);
+
+ kal_uint32 SWIRQCode;
+ SWIRQCode = (kal_uint32)HWIRQCode2SWIRQCode[HWIRQCode];
+
+ if(broadcast){
+ /* broadcast is true => set broadcast type register*/
+ MDCIRQ_SetRegBit_Vector( MDCIRQ_IBROCAT_BASE, SWIRQCode);
+ }
+ else{
+ /* broadcast is false => clear broadcast type register*/
+ MDCIRQ_ClrRegBit_Vector( MDCIRQ_IBROCAT_BASE, SWIRQCode);
+ }
+ MO_Sync();
+}
+
+/* This API can only be called after MDCIRQ owner approved */
+void drv_mdcirq_runtime_set_IRQ_config( kal_uint32 HWIRQCode, kal_bool priorityLevel, kal_uint32 group, kal_bool broadcast){
+ /*
+ HWIRQCode: IRQID which caller want to change configuration
+ priorityLevel: 0:low priority, 1: high priority. The value of low/high priority depends on pre-defined table
+ group: affinity group which user want to send IRQ. Refer group macro definition in intrCtrl_MTxxxx.h
+ broadcast: 0: dynamic type, 1: broadcast type
+ */
+ kal_uint32 i = 0, tableSize = sizeof(irq_runtime_config_table)/sizeof(IRQRuntimeConfigStruct);
+ kal_uint32 priority, replaceHWIRQCode, replacePriority;
+ kal_uint32 savedmask;
+ kal_bool sensitivity;
+
+ for( i = 0; i < tableSize; i++){
+ if( irq_runtime_config_table[i].mainVector == HWIRQCode){
+ if(priorityLevel){
+ priority = irq_runtime_config_table[i].highPriority;
+ replacePriority = irq_runtime_config_table[i].lowPriority;
+ }
+ else{
+ priority = irq_runtime_config_table[i].lowPriority;
+ replacePriority = irq_runtime_config_table[i].highPriority;
+ }
+ replaceHWIRQCode = irq_runtime_config_table[i].replaceVector;
+ break;
+ }
+ }
+ if( i == tableSize){
+ /* Someone call API without registration*/
+ EXT_ASSERT(0, HWIRQCode, 0, 0);
+ }
+ savedmask = kal_hrt_SaveAndSetIRQMask();
+
+ IRQMask(HWIRQCode);
+ IRQMask(replaceHWIRQCode);
+
+ sensitivity = MDCIRQ_IRQSensitivity_Status(HWIRQCode);
+
+ drv_mdcirq_set_vector_priority(HWIRQCode, priority);
+ drv_mdcirq_set_vector_priority(replaceHWIRQCode, replacePriority);
+ drv_mdcirq_set_irq_group(HWIRQCode, group);
+ drv_mdcirq_set_broadcast_type(HWIRQCode, broadcast);
+ MDCIRQ_IRQSensitivity(HWIRQCode, sensitivity);
+
+ IRQUnmask(HWIRQCode);
+
+ kal_hrt_RestoreIRQMask(savedmask);
+}
+
+//mode0: IRQ issue after EI
+//mode1: IRQ issue once timing slot is exceeded threshold
+void drv_mdcirq_set_VPE_timing_check_MODE(kal_uint32 VPE, kal_uint32 mode)
+{
+ DEBUG_ASSERT(VPE < MDCIRQ_TOTAL_VPE_NUM);
+ DEBUG_ASSERT(mode < 0x2);
+
+ if(mode == 0)
+ {
+ DRV_WriteReg32(MDCIRQ_IE_CHECK_MODE_CLR,1<<VPE);
+ }
+ else
+ {
+ DRV_WriteReg32(MDCIRQ_IE_CHECK_MODE_SET,1<<VPE);
+ }
+ MO_Sync();
+}
+
+//mode0: IRQ issue after EI
+//mode1: IRQ issue once timing slot is exceeded threshold
+kal_bool drv_mdcirq_VPE_timing_check_MODE(kal_uint32 VPE)
+{
+ DEBUG_ASSERT(VPE < MDCIRQ_TOTAL_VPE_NUM);
+ return (DRV_Reg32(MDCIRQ_IE_CHECK_MODE)&(1<<VPE));
+}
+
+void drv_mdcirq_set_VPE_timing_check_threshold(kal_uint32 VPE, kal_uint32 threshold)
+{
+ /* config the threshold(us) for Qbit check on specified VPE */
+ DEBUG_ASSERT(VPE < MDCIRQ_TOTAL_VPE_NUM);
+ DEBUG_ASSERT(threshold <= 0xFFFFFFFF);
+
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_VPE_TIMECHECK_THRESHOLD_BASE, VPE, threshold);
+
+ MO_Sync();
+}
+
+kal_uint32 drv_mdcirq_get_VPE_timing_check_mask_frc(kal_uint32 VPE)
+{
+ /* get the FRC counter when VPE disable interrupt */
+ DEBUG_ASSERT(VPE < MDCIRQ_TOTAL_VPE_NUM);
+
+ return MDCIRQ_READ_REG_INDEX(MDCIRQ_VPE_TIMECHECK_FRC_COUNTER_MASK_BASE, VPE);
+}
+
+kal_uint32 drv_mdcirq_get_VPE_timing_slot(kal_uint32 VPE)
+{
+ /* get the DI duration when VPE enable interrupt */
+ DEBUG_ASSERT(VPE < MDCIRQ_TOTAL_VPE_NUM);
+
+ return MDCIRQ_READ_REG_INDEX(MDCIRQ_VPE_IE_TIMING_CHK_TIMING_SLOT_BASE, VPE);
+}
+
+kal_uint32 drv_mdcirq_get_VPE_RA_MASK(kal_uint32 VPE)
+{
+ DEBUG_ASSERT(VPE < MDCIRQ_TOTAL_VPE_NUM);
+ return MDCIRQ_READ_REG_INDEX(MDCIRQ_VPE_RA_MASK_BASE, VPE);
+}
+
+kal_uint32 drv_mdcirq_get_VPE_RA_UNMASK(kal_uint32 VPE)
+{
+ DEBUG_ASSERT(VPE < MDCIRQ_TOTAL_VPE_NUM);
+ return MDCIRQ_READ_REG_INDEX(MDCIRQ_VPE_RA_UNMASK_BASE, VPE);
+}
+
+
+void drv_mdcirq_clear_VPE_timing_check_frc_counter(kal_uint32 VPE)
+{
+ /* clear VPE timing check IRQ status*/
+ DEBUG_ASSERT(VPE < MDCIRQ_TOTAL_VPE_NUM);
+
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_VPE_TIMECHECK_FRC_COUNTER_CLEAR_BASE, VPE, 1);
+
+ MO_Sync();
+}
+
+kal_bool drv_mdcirq_get_VPE_timing_check_interrupt_status(kal_uint32 VPE)
+{
+ /* return the VPE is violation timing check or not */
+ DEBUG_ASSERT(VPE < MDCIRQ_TOTAL_VPE_NUM);
+
+ if( DRV_Reg32(MDCIRQ_TIMECHECK_INTERRUPT_STATUS)&(0x1<<VPE) )
+ {
+ return KAL_TRUE;
+ }
+ else
+ {
+ return KAL_FALSE;
+ }
+}
+
+/*************************************************************************
+* FUNCTION
+* drv_mdcirq_IRQ_B_NMI_B_status
+*
+* DESCRIPTION
+* Return whether there is IRQ/NMI pending for service
+*
+* PARAMETERS
+* vpe_id : vpe id
+*
+* RETURNS
+* KAL_TRUE: there is IRQ/NMI pending for service
+* KAL_FALSE: there is no IRQ/NMI pending for service
+*
+*************************************************************************/
+kal_bool drv_mdcirq_IRQ_B_NMI_B_status(kal_uint32 vpe_id)
+{
+ kal_uint32 status=0;
+ DEBUG_ASSERT(vpe_id<MDCIRQ_TOTAL_VPE_NUM);
+ status = DRV_Reg32(MDCIRQ_VPEINT_STATUS);
+ if(((status>>vpe_id)&(0x10001)) != 0x10001)
+ {
+ return KAL_TRUE;
+ }
+ else
+ {
+ return KAL_FALSE;
+ }
+}
+
+/*************************************************************************
+* FUNCTION
+* drv_mdcirq_IRQ_B_status
+*
+* DESCRIPTION
+* Return whether there is IRQ pending for service
+*
+* PARAMETERS
+* vpe_id : vpe id
+*
+* RETURNS
+* KAL_TRUE: there is IRQ pending for service
+* KAL_FALSE: there is no IRQ pending for service
+*
+*************************************************************************/
+kal_bool drv_mdcirq_IRQ_B_status(kal_uint32 vpe_id)
+{
+ kal_uint32 status;
+ DEBUG_ASSERT(vpe_id<MDCIRQ_TOTAL_VPE_NUM);
+ status = DRV_Reg32(MDCIRQ_VPEINT_STATUS);
+ if(((status>>vpe_id)&(0x1)) != 0x1)
+ {
+ return KAL_TRUE;
+ }
+ else
+ {
+ return KAL_FALSE;
+ }
+}
+
+/*************************************************************************
+* FUNCTION
+* drv_mdcirq_OSIPI_status
+*
+* DESCRIPTION
+* Return whether there is IRQ pending for service
+*
+* PARAMETERS
+* vpe_id : vpe id
+*
+* RETURNS
+* KAL_TRUE: there is IRQ pending for service
+* KAL_FALSE: there is no IRQ pending for service
+*
+*************************************************************************/
+kal_bool drv_mdcirq_OSIPI_status(kal_uint32 vpe_id)
+{
+ kal_uint32 status;
+ DEBUG_ASSERT(vpe_id<MDCIRQ_TOTAL_VPE_NUM);
+ status = DRV_Reg32(MDCIRQ_GCR_OSIRQ_STATUS);
+ if(((status>>vpe_id)&(0x1)) != 0x0)
+ {
+ return KAL_TRUE;
+ }
+ else
+ {
+ return KAL_FALSE;
+ }
+}
+
+// Returns whether a IRQ is asserted in first pending
+kal_bool drv_mdcirq_IRQ_pending_status(kal_uint32 HWIRQCode)
+{
+ DEBUG_ASSERT(HWIRQCode < MDCIRQ_MAX_ISR_NUM);
+
+ kal_uint32 SWIRQCode, status;
+ SWIRQCode = (kal_uint32)HWIRQCode2SWIRQCode[HWIRQCode];
+
+ status = MDCIRQ_GetRegBit_Vector(MDCIRQ_ISAR_BASE, SWIRQCode);
+ if (status) {
+ return KAL_TRUE;
+ }
+
+ return KAL_FALSE;
+}
+
+void drv_mdcirq_enable_time_record(kal_uint32 index, kal_uint32 HWIRQCode, kal_bool after_mask)
+{
+ DEBUG_ASSERT(index < 5);
+ DEBUG_ASSERT(HWIRQCode < MDCIRQ_MAX_ISR_NUM);
+
+ DRV_WriteReg32(MDCIRQ_ISAR_REC_EN_SET, 1 << index);
+ if (after_mask == KAL_TRUE) {
+ DRV_WriteReg32(MDCIRQ_ISAR_REC_TYPE_SET, 1 << index);
+ /* After remap and SW mask => fill in IRQ's priority */
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_ISAR_REC_ID_BASE, index, HWIRQCode2SWIRQCode[HWIRQCode]);
+ } else {
+ DRV_WriteReg32(MDCIRQ_ISAR_REC_TYPE_CLR, 1 << index);
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_ISAR_REC_ID_BASE, index, HWIRQCode);
+ }
+
+ MO_Sync();
+}
+
+void drv_mdcirq_disable_time_record(kal_uint32 index)
+{
+ DEBUG_ASSERT(index < 5);
+
+ DRV_WriteReg32(MDCIRQ_ISAR_REC_EN_CLR, 1 << index);
+ MO_Sync();
+}
+
+#if defined (__MDCIRQ_NEW_ARCHITECTURE__)
+void drv_mdcirq_retreat_enable_all()
+{
+ DRV_WriteReg32(MDCIRQ_RETREAT_BY_DI_EN, MDCIRQ_ALL_VPE_MASK);
+ DRV_WriteReg32(MDCIRQ_RETREAT_BY_ALLOW_EN, MDCIRQ_ALL_VPE_MASK);
+ DRV_WriteReg32(MDCIRQ_RETREAT_BY_VPEMASK_EN, MDCIRQ_ALL_VPE_MASK);
+ DRV_WriteReg32(MDCIRQ_RETREAT_BY_DORM_EN, MDCIRQ_ALL_VPE_MASK);
+ DRV_WriteReg32(MDCIRQ_RETREAT_BY_READ_EN, MDCIRQ_ALL_VPE_MASK);
+ MO_Sync();
+}
+
+void drv_mdcirq_retreat_disable_all()
+{
+ DRV_WriteReg32(MDCIRQ_RETREAT_BY_DI_EN, 0x0);
+ DRV_WriteReg32(MDCIRQ_RETREAT_BY_ALLOW_EN, 0x0);
+ DRV_WriteReg32(MDCIRQ_RETREAT_BY_VPEMASK_EN, 0x0);
+ DRV_WriteReg32(MDCIRQ_RETREAT_BY_DORM_EN, 0x0);
+ DRV_WriteReg32(MDCIRQ_RETREAT_BY_READ_EN, 0x0);
+ MO_Sync();
+}
+
+#else // for CIRQ Old Design
+void drv_mdcirq_WAIT_MODE(MDCIRQ_IRQ_DISPATCH_MODE mode)
+{
+ DRV_WriteReg32(MDCIRQ_WAIT_MODE, mode);
+ MO_Sync();
+}
+
+kal_bool drv_mdcirq_get_HW_MASK(kal_uint32 HWIRQCode)
+{
+ DEBUG_ASSERT(HWIRQCode < MDCIRQ_MAX_ISR_NUM);
+ kal_uint32 SWIRQCode;
+ SWIRQCode = (kal_uint32)HWIRQCode2SWIRQCode[HWIRQCode];
+
+ if(MDCIRQ_GetRegBit_Vector(MDCIRQ_HW_IRQ_MASK_BASE, SWIRQCode))
+ {
+ return KAL_TRUE;
+ }
+ else
+ {
+ return KAL_FALSE;
+ }
+}
+
+kal_bool drv_mdcirq_get_VPE_Status(kal_uint32 VPE, kal_uint32 HWIRQCode)
+{
+ DEBUG_ASSERT(VPE < MDCIRQ_TOTAL_VPE_NUM);
+ DEBUG_ASSERT(HWIRQCode < MDCIRQ_MAX_ISR_NUM);
+ kal_uint32 SWIRQCode;
+ SWIRQCode = (kal_uint32)HWIRQCode2SWIRQCode[HWIRQCode];
+
+ if(MDCIRQ_GetRegBit_Vector((MDCIRQ_VPE_ISAR_BASE+(0x30*VPE)), SWIRQCode))
+ {
+ return KAL_TRUE;
+ }
+ else
+ {
+ return KAL_FALSE;
+ }
+}
+#endif
+
+/* Reset as system default */
+void drv_mdcirq_reset(void)
+{
+ kal_int32 i;
+ kal_uint32 combine, temp;
+
+#if defined(__MDCIRQ_NEW_ARCHITECTURE__)
+ /* Enable CIRQ New Architecture*/
+ DRV_WriteReg32(MDCIRQ_NEW_ARCHI_EN, 1);
+#else
+#if defined(__MDCIRQ_WAIT_MODE_ENABLE__)
+ drv_mdcirq_WAIT_MODE(WAIT_MODE_ENABLE);
+#else
+ drv_mdcirq_WAIT_MODE(WAIT_MODE_DISABLE_WITH_ENHANCEMENT);
+#endif
+#endif
+
+#if defined(__MDCIRQ_GCR_SIGNAL_DISABLE__)
+ drv_mdcirq_GCR_enable(KAL_FALSE);
+#endif
+
+ /* Mask All Interrupt Sources */
+ drv_mdcirq_mask_all();
+ MO_Sync();
+
+ /* Set interrupt priority, set interrupt priority mapping should be the first step*/
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM; i++)
+ {
+ HWIRQCode2SWIRQCode[SWIRQCode2HWIRQCode[i]] = (kal_uint16)i;
+ }
+
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM/2; i++)
+ {
+ DRV_WriteReg32(MDCIRQ_PRLV(i<<1), (SWIRQCode2HWIRQCode[2*i]) | (SWIRQCode2HWIRQCode[2*i + 1] << 16));
+ }
+
+ /* Suggest to clear all interrupt source after priority mapping*/
+ /* Clear Status Registers */
+ drv_mdcirq_clr_all_status();
+
+ /* Clear Software Trigger Interrupt*/
+ drv_mdcirq_clr_all_swtr();
+
+ /* Set Interrupt Group */
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM/4; i++)
+ {
+ combine = isr_config_tbl[SWIRQCode2HWIRQCode[4*i]].irq_group | isr_config_tbl[SWIRQCode2HWIRQCode[4*i+1]].irq_group << 8 | isr_config_tbl[SWIRQCode2HWIRQCode[4*i+2]].irq_group << 16 | isr_config_tbl[SWIRQCode2HWIRQCode[4*i+3]].irq_group << 24;
+ DRV_WriteReg32(MDCIRQ_IRQ_GROUP_CFG(i<<2), combine);
+ }
+
+ // Set map2vpe setting of IRQ groups
+ for(i =0; i < MDCIRQ_TOTAL_IRQ_GROUP_NUM; i++)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_GROUP_M2V_CFG_BASE, i, irq_group_map2vpe_list[i]);
+ }
+
+ /* Clear Priority Stack */
+ /* No need to do it after gen93 comment by DE */
+ //drv_mdcirq_clr_all_pri_stk();
+
+ /* Sensitivity */
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM/32; i++)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_ISENR_BASE, i, 0x0);
+ }
+ /* For the case that MDCIRQ_MAX_ISR_NUM cannot be divied by 32 */
+ if((MDCIRQ_MAX_ISR_NUM % 32) != 0)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_ISENR_BASE, (MDCIRQ_MAX_ISR_NUM/32), 0);
+ }
+
+ /* Pre-Sensitivity */
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM/32; i++)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_ISENR_PRE_BASE, i, 0x0);
+ }
+ /* For the case that MDCIRQ_MAX_ISR_NUM cannot be divied by 32 */
+ if((MDCIRQ_MAX_ISR_NUM % 32) != 0)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_ISENR_PRE_BASE, (MDCIRQ_MAX_ISR_NUM/32), 0);
+ }
+
+
+ /* Set interrupt as broadcast/dynamic type */
+ for(i = 0; i < (MDCIRQ_MAX_ISR_NUM/32 + 1); i++)
+ {
+ broadcastValueArray[i] = 0;
+ }
+
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM; i++)
+ {
+ if( isr_config_tbl[i].irq_type == BROADCAST_TYPE )
+ {
+ temp = (kal_uint32)HWIRQCode2SWIRQCode[i];
+ broadcastValueArray[temp / 32] |= (1 << (temp % 32));
+ }
+ }
+
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM/32; i++)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_IBROCAT_BASE, i, broadcastValueArray[i]);
+ }
+ if((MDCIRQ_MAX_ISR_NUM % 32) != 0)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_IBROCAT_BASE, (MDCIRQ_MAX_ISR_NUM/32), broadcastValueArray[MDCIRQ_MAX_ISR_NUM/32]);
+ }
+
+ /* Set Minimal Priority Level to Lowest Priority */
+ for(i = 0; i< MDCIRQ_TOTAL_VPE_NUM; i++)
+ {
+#if defined(__MDCIRQ_GCR_SIGNAL_DISABLE__)
+ DRV_WriteReg32(MDCIRQ_VPE_MIN_PRLV_BASE + i*4, MDCIRQ_LOWEST_PRI);
+#else
+ DRV_WriteReg32(MDCIRQ_GCR_VPE_MIN_PRLV_BASE + i*4, MDCIRQ_LOWEST_PRI);
+#endif
+ }
+
+ for(i = 0; i< MDCIRQ_TOTAL_VPE_NUM; i++)
+ {
+ drv_mdcirq_IBit_Ultra_select(i, MDCIRQ_To_BUS_Normal);
+ drv_mdcirq_set_Ultra_threshold(i, 0x0);
+ drv_mdcirq_set_PreUltra_threshold(i, 0x0);
+ }
+ drv_mdcirq_set_Ultra_PreUltra_mask_all(MDCIRQ_To_BUS_PreUltra|MDCIRQ_To_BUS_Ultra);
+
+
+ /*for(i = 0; i < MDCIRQ_TOTAL_VPE_NUM; i++)
+ {
+ drv_mdcirq_set_HRTSignal_threshold(i, 0x0);
+ }
+ drv_mdcirq_set_HRTSignal_mask_all();*/
+
+ for(i = 0; i< MDCIRQ_TOTAL_VPE_NUM; i++)
+ {
+ drv_mdcirq_Set_VPE_state(i, VPE_STATUS_HISR_TASK_LOWEST);
+ }
+
+ drv_mdcirq_mask_NMI_all();
+ drv_mdcirq_clr_all_NMI();
+
+ //config boot slave address for NMI
+ INT_Set_BootSlave(0, (kal_uint32)&NMI_handler);
+#ifndef __SINGLE_CORE__
+ INT_Set_BootSlave(1, (kal_uint32)&NMI_handler);
+ INT_Set_BootSlave(2, (kal_uint32)&NMI_handler);
+ INT_Set_BootSlave(3, (kal_uint32)&NMI_handler);
+#endif
+
+ for(i = 0; i< MDCIRQ_TOTAL_VPE_NUM; i++)
+ {
+ drv_mdcirq_NMI_ready[i] = KAL_TRUE;
+ }
+
+ /* For SFU configutation */
+ /* Set HRT signal priority threshold. Normal domain: priority above HRT priority threshold, HRT/CHRT domain: all */
+ for( i = 0; i < MDCIRQ_TOTAL_VPE_NUM; i++ )
+ {
+ if(drv_mdcirq_per_VPE_domain_type[i] == KAL_DOMAIN_NORMAL)
+ {
+ /* In register spec, higher or equal to threshold will raise HRT signal */
+ drv_mdcirq_set_HRTSignal_threshold(i, IRQ_HRT_PRIORITY_THRESHOLD - 1);
+ }
+ else
+ {
+ /* In register spec, higher or equal to threshold will raise HRT signal */
+ drv_mdcirq_set_HRTSignal_threshold(i, MDCIRQ_TOTAL_PRI_LEVEL - 1);
+ }
+ }
+ /* Clear HRT signal to SFU mask */
+ drv_mdcirq_clear_HRTSignal_mask_all();
+
+ /* Enable MDCIRQ equally dispatch IRQs */
+ // drv_mdcirq_set_EQD_mode(0x1);
+ // drv_mdcirq_set_EQDSignal_threshold(IRQ_EQUALLY_DISPATCH_PRIORITY_THRESHOLD);
+ // drv_mdcirq_clear_EQD_mask_all();
+
+ //enable IE bit sampling for smart dispatch and timing check
+#if !defined(__ESL_MASE__)
+ drv_mdcirq_IBit_sampling_enable_all(KAL_TRUE);
+#endif
+
+ /* Align Gen95's design, when set min_prlv, MDCIRQ will block all irq for 40T CIRQ cycles */
+ DRV_WriteReg32(MDCIRQ_RETREAT_BY_ALLOW_CNT, 40);
+
+ /* Record IRQ trigger time */
+ drv_mdcirq_enable_time_record(0, IRQ_NR_TIMER_IRQ0_CODE, KAL_FALSE);
+
+ MO_Sync();
+}
+
+/*************************************************************************
+* FUNCTION
+* IRQMask
+*
+* DESCRIPTION
+* Mask certain interrupt source.
+*
+* PARAMETERS
+* Interrupt source to be masked, it is indexed via IRQCode2Line.
+*
+* RETURNS
+*
+*************************************************************************/
+kal_uint32 MASK_CALLER[1024][2] = {0};
+kal_uint32 UNMASK_CALLER[1024][2] = {0};
+kal_uint32 mask_idx = 0;
+kal_uint32 unmask_idx = 0;
+
+void MDCIRQ_IRQMask(kal_uint16 HWIRQCode)
+{
+ kal_uint32 SWIRQCode;
+ if (HWIRQCode == 178){
+ __asm__ __volatile__ (
+ "move %0, $ra\n"
+ : "=r" (MASK_CALLER[mask_idx % 1024][0])
+ :
+ :
+ );
+ MASK_CALLER[mask_idx % 1024][1] = ust_get_current_time();
+ mask_idx++;
+ }
+
+ SWIRQCode = (kal_uint32)HWIRQCode2SWIRQCode[HWIRQCode];
+
+ MDCIRQ_WrSetRegBit_Vector(MDCIRQ_IMSR_BASE, SWIRQCode);
+ MO_Sync();
+}
+
+/*************************************************************************
+* FUNCTION
+* IRQUnmask
+*
+* DESCRIPTION
+* Unmask certain interrupt source.
+*
+* PARAMETERS
+* Interrupt source to be unmasked, it is indexed via IRQCode2Line.
+*
+* RETURNS
+*
+*************************************************************************/
+void MDCIRQ_IRQUnmask(kal_uint16 HWIRQCode)
+{
+ kal_uint32 SWIRQCode;
+
+ if (HWIRQCode == 178){
+ __asm__ __volatile__ (
+ "move %0, $ra\n"
+ : "=r" (UNMASK_CALLER[unmask_idx % 1024][0])
+ :
+ :
+ );
+ UNMASK_CALLER[mask_idx % 1024][1] = ust_get_current_time();
+ unmask_idx++;
+ }
+
+ SWIRQCode = (kal_uint32)HWIRQCode2SWIRQCode[HWIRQCode];
+
+ MDCIRQ_WrClrRegBit_Vector(MDCIRQ_IMCR_BASE, SWIRQCode);
+ MO_Sync();
+}
+
+/*************************************************************************
+* FUNCTION
+* IRQMask_Status
+*
+* DESCRIPTION
+* query the interrupt code status
+*
+* PARAMETERS
+*
+* RETURNS
+*
+*************************************************************************/
+kal_uint32 IRQMask_Status(kal_uint16 HWIRQCode)
+{
+ kal_uint32 SWIRQCode;
+ SWIRQCode = (kal_uint32)HWIRQCode2SWIRQCode[HWIRQCode];
+
+ return (MDCIRQ_READ_REG_INDEX(MDCIRQ_IMKR_BASE, SWIRQCode/32) & (1<<(SWIRQCode%32)));
+
+}
+
+/*************************************************************************
+* FUNCTION
+* IRQDirectMaskAll
+*
+* DESCRIPTION
+* Mask all of the interrupts with direct indexing.
+*
+* IMPORTANT NOTICE
+* Reserved for system service only!
+* used while system error
+* such as fatal error, assertion failure and CPU triggered excetpion.
+*
+* PARAMETERS
+*
+* RETURNS
+*
+*************************************************************************/
+void MDCIRQ_IRQDirectMaskAll(void)
+{
+ drv_mdcirq_mask_all();
+}
+
+/*************************************************************************
+* FUNCTION
+* IRQ_SaveMaskStatus
+*
+* DESCRIPTION
+* Save the current IRQ MASK status when exception
+*
+* PARAMETERS
+*
+* RETURNS
+*
+*************************************************************************/
+void MDCIRQ_IRQ_SaveMaskStatus(void)
+{
+ kal_int32 i;
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM/32; i++)
+ {
+ IRQMaskStatus[i] = MDCIRQ_READ_REG_INDEX( MDCIRQ_IMKR_BASE, i);
+ }
+ /* For the case that MDCIRQ_MAX_ISR_NUM cannot be divied by 32 */
+ if((MDCIRQ_MAX_ISR_NUM % 32) != 0)
+ {
+ IRQMaskStatus[MDCIRQ_MAX_ISR_NUM/32] = MDCIRQ_READ_REG_INDEX( MDCIRQ_IMKR_BASE, (MDCIRQ_MAX_ISR_NUM/32));
+ }
+}
+
+/*************************************************************************
+* FUNCTION
+* MDCIRQ_IRQ_SaveStatus
+*
+* DESCRIPTION
+* Save the current IRQ MASK status when exception
+*
+* PARAMETERS
+*
+* RETURNS
+*
+*************************************************************************/
+void MDCIRQ_IRQ_SaveStatus(void)
+{
+ kal_int32 i;
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM/32; i++)
+ {
+ IRQStatus[i] = MDCIRQ_READ_REG_INDEX( MDCIRQ_ISAR_BASE, i);
+ }
+ /* For the case that MDCIRQ_MAX_ISR_NUM cannot be divied by 32 */
+ if((MDCIRQ_MAX_ISR_NUM % 32) != 0)
+ {
+ IRQStatus[MDCIRQ_MAX_ISR_NUM/32] = MDCIRQ_READ_REG_INDEX( MDCIRQ_ISAR_BASE, (MDCIRQ_MAX_ISR_NUM/32));
+ }
+}
+
+/*************************************************************************
+* FUNCTION
+* MDCIRQ_EX_SaveStatus_beforeCTI
+*
+* DESCRIPTION
+* Save the current IRQ_B/NMI_B status in exception flow before
+* triggering cross core trigger interrupt
+*
+*
+* PARAMETERS
+*
+* RETURNS
+*
+*************************************************************************/
+void MDCIRQ_EX_SaveStatus_beforeCTI(void)
+{
+ IRQ_B_NMI_B_Status = DRV_Reg32(MDCIRQ_VPEINT_STATUS);
+}
+
+/*************************************************************************
+* FUNCTION
+* MDCIRQ_EX_SaveStatus_afterCTI
+*
+* DESCRIPTION
+* Save the current interrupt status and interrupt mask status
+* in exception flow after triggering cross core trigger interrupt
+*
+* PARAMETERS
+*
+* RETURNS
+*
+*************************************************************************/
+void MDCIRQ_EX_SaveStatus_afterCTI(void)
+{
+ IRQ_B_NMI_B_MaskStatus = DRV_Reg32(MDCIRQ_VPE_INTMASK);
+ VPE_IE_Status = DRV_Reg32(MDCIRQ_IE_STATUS);
+ VPE_IE_Sampling_Status = DRV_Reg32(MDCIRQ_IE_CHECK_EN);
+ VPE_Dormant_Status = DRV_Reg32(MDCIRQ_VPE_DORMANT_STATE);
+ MDCIRQ_IRQ_SaveMaskStatus();
+ MDCIRQ_IRQ_SaveStatus();
+#if defined (__MDCIRQ_NEW_ARCHITECTURE__)
+ drv_mdcirq_retreat_disable_all();
+#endif
+}
+
+/*************************************************************************
+* FUNCTION
+* IRQClearInt
+*
+* DESCRIPTION
+* Clear IRQ with plain format interrupt status
+*
+* PARAMETERS
+* Plain format interrupt status
+*
+* RETURNS
+*
+*************************************************************************/
+void MDCIRQ_IRQClearInt(kal_uint16 HWIRQCode)
+{
+
+ kal_uint32 savedmask, savedIRQmask;
+ kal_uint32 SWIRQCode;
+
+ /* Lockout all interrupts */
+ savedmask = kal_hrt_SaveAndSetIRQMask();
+
+ SWIRQCode = (kal_uint32)HWIRQCode2SWIRQCode[HWIRQCode];
+
+ //Since Gen92 MDCIRQ to now
+ //Workaround for WHQA:28291
+ //if target IRQ is pulse trigger, then clear interrupt
+ //if(!(drv_mdcirq_sensitivity[(code/32)]&(1<<(code%32))))
+ {
+ //Workaround for WHQA:28291
+ //backup IRQ mask status
+ savedIRQmask = MDCIRQ_GetRegBit_Vector(MDCIRQ_IMKR_BASE, SWIRQCode);
+
+ //Workaround for WHQA:28291
+ //Mask target IRQ
+ if(!savedIRQmask)
+ MDCIRQ_IRQMask(HWIRQCode);
+
+ MDCIRQ_WrClrRegBit_Vector(MDCIRQ_ISAR_BASE, SWIRQCode);
+
+ //Workaround for WHQA:28291
+ //Restore target IRQ mask
+ if(!savedIRQmask)
+ MDCIRQ_IRQUnmask(HWIRQCode);
+ }
+
+ kal_hrt_RestoreIRQMask(savedmask);
+
+}
+
+
+
+/*************************************************************************
+* FUNCTION
+* IRQSensitivity
+*
+* DESCRIPTION
+* Setting sensitivity of IRQ
+*
+* PARAMETERS
+* code: IRQ number to be set
+* edge: either edge active low or level active low
+*
+* RETURNS
+*
+*************************************************************************/
+void MDCIRQ_IRQSensitivity(kal_uint16 HWIRQCode, kal_bool edge)
+{
+ kal_uint32 SWIRQCode;
+ SWIRQCode = (kal_uint32)HWIRQCode2SWIRQCode[HWIRQCode];
+
+ if( KAL_TRUE == edge )
+ {
+ MDCIRQ_WrSetRegBit_Vector(MDCIRQ_ISENR_CLEAR_PRE_BASE, HWIRQCode);
+ MDCIRQ_WrSetRegBit_Vector(MDCIRQ_ISENR_CLEAR_BASE, SWIRQCode);
+ }
+ else
+ {
+ MDCIRQ_WrSetRegBit_Vector(MDCIRQ_ISENR_SET_PRE_BASE, HWIRQCode);
+ MDCIRQ_WrSetRegBit_Vector(MDCIRQ_ISENR_SET_BASE, SWIRQCode);
+ }
+ MO_Sync();
+}
+
+/*************************************************************************
+* FUNCTION
+* MDCIRQ_IRQSensitivity_Status
+*
+* DESCRIPTION
+* Get sensitivity of IRQ
+*
+* PARAMETERS
+* code: IRQ number to be set
+*
+* RETURNS
+* kal_true: edge
+* kal_false: level
+*
+*************************************************************************/
+kal_bool MDCIRQ_IRQSensitivity_Status(kal_uint16 HWIRQCode)
+{
+ kal_bool sensitivity;
+ sensitivity = MDCIRQ_GetRegBit_Vector(MDCIRQ_ISENR_PRE_BASE, HWIRQCode);
+ return (sensitivity == 0x1)?KAL_FALSE:KAL_TRUE;
+}
+
+/*************************************************************************
+* FUNCTION
+* SYS_endIsr
+*
+* DESCRIPTION
+* Notify the CIRQ current ISR is finished!
+*
+* PARAMETERS
+* Binary coded interrupt status
+*
+* RETURNS
+*
+*************************************************************************/
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ROCODE void MDCIRQ_SYS_endIsr(kal_uint32 vpe_num, kal_uint32 Return_IRQID)
+{
+
+#if defined(__MDCIRQ_GCR_SIGNAL_DISABLE__)
+ DRV_WriteReg32(MDCIRQ_VPE_IRQ_ID_RETURN_BASE + (vpe_num<<2), Return_IRQID);
+#else
+ DRV_WriteReg32(MDCIRQ_GCR_VPE_IRQ_ID_RETURN_BASE + (vpe_num<<2), Return_IRQID);
+#endif
+ MO_Sync();
+
+}
+
+
+/*************************************************************************
+* FUNCTION
+* SYS_ClearInt
+*
+* DESCRIPTION
+* Reserved for system service only!
+* Clear IRQ with plain format interrupt status
+* It is trapped while Interrupt is disabled!
+*
+* PARAMETERS
+* Plain format interrupt status
+*
+* RETURNS
+*
+*************************************************************************/
+void MDCIRQ_SYS_ClearInt(kal_uint32 HWIRQCode)
+{
+ kal_uint32 SWIRQCode;
+
+ DEBUG_ASSERT(HWIRQCode < NUM_IRQ_SOURCES);
+ SWIRQCode = (kal_uint32)HWIRQCode2SWIRQCode[HWIRQCode];
+
+ MDCIRQ_WrClrRegBit_Vector(MDCIRQ_ISAR_BASE, SWIRQCode);
+}
+
+//only exception flow can use this API!
+void MDCIRQ_EX_NMITrigger(kal_uint32 vpe_id)
+{
+ DEBUG_ASSERT(vpe_id<MDCIRQ_TOTAL_VPE_NUM);
+ drv_mdcirq_clear_NMI_Mask(vpe_id);
+ drv_mdcirq_set_NMI(vpe_id);
+ MO_Sync();
+}
+
+//query whether the NMI can be called
+kal_bool MDCIRQ_EX_IsNMIReady(kal_uint32 vpe_id)
+{
+ return drv_mdcirq_NMI_ready[vpe_id];
+}
+
+kal_bool MDCIRQ_EX_WD_Triggered_NMI(kal_uint32 VPEID)
+{
+#if defined(__DEADLOCK_DETECTION__)
+ return drv_mdcirq_NMI_trigger[VPEID];
+#else
+ return KAL_FALSE;
+#endif
+}
+
+void MDCIRQ_EX_MASK_ALL(kal_uint32 VPEID)
+{
+ drv_mdcirq_IRQ_mask(VPEID);
+ drv_vpe_irq_save_and_mask_all(VPEID);
+}
+
+void drv_mdcirq_Deadlock_Detection_Lisr(kal_uint32 irqID)
+{
+ kal_uint32 i;
+ kal_uint32 deadlockVPEID;
+
+ /* Deadlock detection interrupt is broadcast type but only one VPE need to process it */
+ kal_hrt_take_itc_lock(KAL_ITC_CORE012_INT, KAL_INFINITE_WAIT);
+ if( drv_mdcirq_deadlock_processing == KAL_TRUE)
+ {
+ /* Other VPE already start to process it. Just return. */
+ kal_hrt_give_itc_lock(KAL_ITC_CORE012_INT);
+ return;
+ }
+ drv_mdcirq_deadlock_processing = KAL_TRUE;
+ /* Mask self deadlock detection interrupt to avoid nested enter LISR.
+ Mask other deadlock detection for easy handling. */
+ for(i=0; i<MDCIRQ_TOTAL_VPE_NUM; i++)
+ {
+ IRQMask(IRQ_IEBIT_CHECK_IRQ0_CODE + i);
+ }
+ kal_hrt_give_itc_lock(KAL_ITC_CORE012_INT);
+
+ deadlockVPEID = irqID - IRQ_IEBIT_CHECK_IRQ0_CODE;
+ /* Record deadlock VPE for exception and debugging. */
+ drv_mdcirq_NMI_trigger[deadlockVPEID] = KAL_TRUE;
+
+ if( MDCIRQ_EX_IsNMIReady(deadlockVPEID) == KAL_TRUE)
+ {
+ /* If NMI ready, trigger NMI to deadlock VPE and return. */
+ MDCIRQ_EX_NMITrigger(deadlockVPEID);
+ }
+ else
+ {
+ /* If NMI not ready, just assert to trigger exception. */
+ DEBUG_EXT_ASSERT3(0, deadlockVPEID, drv_mdcirq_get_VPE_timing_check_mask_frc(deadlockVPEID), drv_mdcirq_get_VPE_RA_MASK(deadlockVPEID));
+ }
+}
+
+void drv_mdcirq_Deadlock_Detection_Init()
+{
+ kal_uint32 i=0;
+
+ for(i=0; i<MDCIRQ_TOTAL_VPE_NUM; i++)
+ {
+ /* initialize global veriables for deadlock detection */
+ drv_mdcirq_deadlock_processing = KAL_FALSE;
+ drv_mdcirq_NMI_trigger[i] = KAL_FALSE;
+
+ /* Set checking mode to tigger interrupt immediately after violation .
+ Clear counter and set threshold. */
+ drv_mdcirq_set_VPE_timing_check_MODE(i, 0x1);
+ drv_mdcirq_clear_VPE_timing_check_frc_counter(i);
+ if(drv_mdcirq_per_VPE_domain_type[i] == KAL_DOMAIN_NORMAL)
+ {
+ drv_mdcirq_set_VPE_timing_check_threshold(i, SST_HR_DUR_NON_HRT_WD);
+ }
+ else
+ {
+ drv_mdcirq_set_VPE_timing_check_threshold(i, SST_HR_DUR_HRT_WD);
+ }
+
+ IRQUnmask(IRQ_IEBIT_CHECK_IRQ0_CODE + i);
+ }
+}
+
+void drv_mdcirq_Qbit_Violation_Lisr(kal_uint32 v)
+{
+ /* HRT timing violation in normal domain will not enter this LISR because we always use SW timing check for HRT
+ Qbits check in normal domain */
+ kal_uint32 maskDuration, VPEID, returnAddress;
+#if defined(__MTK_INTERNAL__)
+ kal_uint32 maskCaller, maskTime;
+#endif /* __MTK_INTERNAL__ */
+
+ VPEID = kal_get_current_vpe_id();
+
+ /* Avoid driver function call due to performace concern */
+ maskDuration = MDCIRQ_READ_REG_INDEX(MDCIRQ_VPE_IE_TIMING_CHK_TIMING_SLOT_BASE, VPEID);
+ TRANS_TO_QBIT(maskDuration, maskDuration);
+
+ /* Avoid driver function call due to performace concern */
+ returnAddress = MDCIRQ_READ_REG_INDEX(MDCIRQ_VPE_RA_UNMASK_BASE, VPEID);
+
+#if defined(__MTK_INTERNAL__)
+ maskCaller = MDCIRQ_READ_REG_INDEX(MDCIRQ_VPE_RA_MASK_BASE, VPEID);
+ maskTime = MDCIRQ_READ_REG_INDEX(MDCIRQ_VPE_TIMECHECK_FRC_COUNTER_MASK_BASE, VPEID);
+ if(kal_get_current_domain() == KAL_DOMAIN_NORMAL)
+ {
+ /* record normal domain interrupt mask caller and mask time for debugging*/
+ sst_irq_mask_caller[VPEID] = maskCaller;
+ IRQMaskCounter[VPEID] = maskTime;
+ }
+ else if (kal_get_current_domain() == KAL_DOMAIN_HRT)
+ {
+ /* record HRT domain interrupt mask caller and mask time for debugging*/
+ sst_hrt_qbit_caller[VPEID] = maskCaller;
+ HRTQbitCounter[VPEID]= maskTime;
+ }
+ sst_ex_irq_mask_duration[VPEID] = maskDuration;
+
+ if (!INT_QueryExceptionStatus())
+ {
+ if(kal_get_current_domain() == KAL_DOMAIN_NORMAL)
+ {
+ /* Normal domain fatal error code 0xb31 */
+ kal_fatal_error_handler(KAL_ERROR_OVER_QBIT_NORMAL_FAILED, (kal_uint32)returnAddress);
+ }
+ else if (kal_get_current_domain() == KAL_DOMAIN_HRT)
+ {
+ /* HRT domain fatal error code 0xb34 */
+ kal_fatal_error_handler(KAL_ERROR_OVER_QBIT_HRT_FAILED, (kal_uint32)returnAddress);
+ }
+ }
+#else /* __MTK_INTERNAL__ */
+ IRQMaskDurationHandler(maskDuration, (kal_uint32)returnAddress, VPEID);
+#endif /* __MTK_INTERNAL__ */
+
+ /* Re-enable timing check */
+ /* Avoid driver function call due to performace concern */
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_VPE_TIMECHECK_FRC_COUNTER_CLEAR_BASE, VPEID, 1);
+ MO_Sync();
+
+}
+
+void drv_mdcirq_Qbit_Violation_Init()
+{
+ kal_uint32 i=0;
+
+ for(i=0; i<MDCIRQ_TOTAL_VPE_NUM; i++)
+ {
+ /* Set checking mode to tigger interrupt immediately after violation .
+ Clear counter and set threshold. */
+ drv_mdcirq_set_VPE_timing_check_MODE(i, 0x1);
+ drv_mdcirq_clear_VPE_timing_check_frc_counter(i);
+ if(drv_mdcirq_per_VPE_domain_type[i] == KAL_DOMAIN_NORMAL)
+ {
+ drv_mdcirq_set_VPE_timing_check_threshold(i, IRQ_DISABLE_MAX_DURATION_NON_HRT);
+ }
+ else if (drv_mdcirq_per_VPE_domain_type[i] == KAL_DOMAIN_HRT)
+ {
+ drv_mdcirq_set_VPE_timing_check_threshold(i, IRQ_DISABLE_MAX_DURATION_HRT);
+ }
+
+ IRQUnmask(IRQ_IEBIT_CHECK_IRQ0_CODE+i);
+ }
+
+}
+
+void drv_mdcirq_sleep_MaskValueInit(CIRQ_MASK_VALUE_T *sleepMaskPtr)
+{
+ kal_uint32 i;
+ for (i = 0; i < (MDCIRQ_MAX_ISR_NUM/32); i++)
+ {
+ sleepMaskPtr->irq_mask[i] = 0xFFFFFFFF;
+ }
+ /* For the case that MDCIRQ_MAX_ISR_NUM cannot be divied by 32 */
+ if((MDCIRQ_MAX_ISR_NUM % 32) != 0)
+ {
+ sleepMaskPtr->irq_mask[(MDCIRQ_MAX_ISR_NUM/32)] = (1 << (MDCIRQ_MAX_ISR_NUM%32)) - 1;
+ }
+}
+
+void drv_mdcirq_sleep_SetMaskValue(CIRQ_MASK_VALUE_T *sleepMaskPtr, kal_uint32 HWIRQCode)
+{
+ kal_uint32 regIndex, bitIndex, SWIRQCode;
+ SWIRQCode = (kal_uint32)HWIRQCode2SWIRQCode[HWIRQCode];
+ regIndex = SWIRQCode / 32;
+ bitIndex = SWIRQCode % 32;
+ sleepMaskPtr->irq_mask[regIndex] &= ~(1<< bitIndex);
+}
+
+void drv_mdcirq_sleep_MaskAll(CIRQ_MASK_VALUE_T *originalMaskBackupPtr, CIRQ_MASK_VALUE_T *sleepMaskPtr)
+{
+ kal_uint32 i;
+ for (i = 0; i < (MDCIRQ_MAX_ISR_NUM/32); i++)
+ {
+ /* backup current irq mask */
+ originalMaskBackupPtr->irq_mask[i]= MDCIRQ_READ_REG_INDEX(MDCIRQ_IMKR_BASE, i);
+ /* mask all irq mask (except the IRQ bypass by drv_mdcirq_sleep_SetMaskValue() are not masked) */
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_IMSR_BASE, i, (originalMaskBackupPtr->irq_mask[i] | sleepMaskPtr->irq_mask[i]));
+ }
+ /* For the case that MDCIRQ_MAX_ISR_NUM cannot be divied by 32 */
+ if((MDCIRQ_MAX_ISR_NUM % 32) != 0)
+ {
+ /* backup current irq mask */
+ originalMaskBackupPtr->irq_mask[(MDCIRQ_MAX_ISR_NUM/32)]= MDCIRQ_READ_REG_INDEX(MDCIRQ_IMKR_BASE, (MDCIRQ_MAX_ISR_NUM/32));
+ /* mask all irq mask (except the IRQ bypass by drv_mdcirq_sleep_SetMaskValue() are not masked) */
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_IMSR_BASE, (MDCIRQ_MAX_ISR_NUM/32), (originalMaskBackupPtr->irq_mask[(MDCIRQ_MAX_ISR_NUM/32)] | sleepMaskPtr->irq_mask[(MDCIRQ_MAX_ISR_NUM/32)]));
+ }
+ MO_Sync();
+}
+
+void drv_mdcirq_sleep_RestoreAll(CIRQ_MASK_VALUE_T * originalMaskBackupPtr)
+{
+ kal_uint32 i;
+ for (i = 0; i < (MDCIRQ_MAX_ISR_NUM/32); i++)
+ {
+ /*Restore CIRQ based on prevserved value*/
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_IMKR_BASE, i, originalMaskBackupPtr->irq_mask[i]);
+ }
+ /* For the case that MDCIRQ_MAX_ISR_NUM cannot be divied by 32 */
+ if((MDCIRQ_MAX_ISR_NUM % 32) != 0)
+ {
+ /*Restore CIRQ based on prevserved value*/
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_IMKR_BASE, (MDCIRQ_MAX_ISR_NUM/32), originalMaskBackupPtr->irq_mask[(MDCIRQ_MAX_ISR_NUM/32)]);
+ }
+
+ MO_Sync();
+}
+
+#if defined(__ENABLE_SW_TRIGGER_INTERRUPT__)
+
+/*************************************************************************
+* FUNCTION
+* Activate_LISR
+*
+* DESCRIPTION
+* This function activate SW interrupt lisr
+*
+* PARAMETERS
+* handle : handler of software trigger interrupt
+*
+* RETURNS
+* none
+*
+*************************************************************************/
+void MDCIRQ_Activate_LISR(SW_CODE_HANDLE HWIRQCode)
+{
+ DEBUG_ASSERT(HWIRQCode < NUM_IRQ_SOURCES);
+
+ kal_uint32 irq_mask=0, mt_mask=0, ori_prio=0;
+
+#if defined(__MDCIRQ_OSIPI_SPECIAL_FLOW__)
+ KAL_ITC_LOCK_TAKE_DI_DMT_PRIO(drv_mdcirq_activate_lisr_lock[0], irq_mask, mt_mask, ori_prio);
+#else
+ if (HWIRQCode < SW_TRIGGER_CODE53 || HWIRQCode > SW_TRIGGER_CODE64)
+ {
+ KAL_ITC_LOCK_TAKE_DI_DMT_PRIO(drv_mdcirq_activate_lisr_lock[0], irq_mask, mt_mask, ori_prio);
+ }
+#endif
+
+ SW_INT_Counter[HWIRQCode]++;
+ if(SW_INT_Counter[HWIRQCode]==1)
+ {
+ MDCIRQ_WrSetRegBit_Vector(MDCIRQ_ISTR_SET_BASE, HWIRQCode);
+ MO_Sync();
+ }
+
+#if defined(__MDCIRQ_OSIPI_SPECIAL_FLOW__)
+ KAL_ITC_LOCK_GIVE_EI_EMT_PRIO(drv_mdcirq_activate_lisr_lock[0], irq_mask, mt_mask, ori_prio);
+#else
+ if (HWIRQCode < SW_TRIGGER_CODE53 || HWIRQCode > SW_TRIGGER_CODE64)
+ {
+ KAL_ITC_LOCK_GIVE_EI_EMT_PRIO(drv_mdcirq_activate_lisr_lock[0], irq_mask, mt_mask, ori_prio);
+ }
+#endif
+}
+
+// special LISR acivation driver, used for idletask only
+// Cannot take ITC since VPE2 cannot allow disabling interrupt
+void MDCIRQ_Activate_LISR_without_ITC(SW_CODE_HANDLE HWIRQCode)
+{
+ DEBUG_ASSERT(HWIRQCode < NUM_IRQ_SOURCES);
+
+ MDCIRQ_WrSetRegBit_Vector(MDCIRQ_ISTR_SET_BASE, HWIRQCode);
+}
+
+/*************************************************************************
+* FUNCTION
+* Deactivate_LISR
+*
+* DESCRIPTION
+* This function deactivate SW interrupt lisr
+*
+* PARAMETERS
+* handle : handler of software trigger interrupt
+*
+* RETURNS
+* none
+*
+*************************************************************************/
+void MDCIRQ_Deactivate_LISR(SW_CODE_HANDLE HWIRQCode)
+{
+ DEBUG_ASSERT(HWIRQCode < NUM_IRQ_SOURCES);
+
+ kal_uint32 irq_mask=0, mt_mask=0, ori_prio=0;
+
+#if defined(__MDCIRQ_OSIPI_SPECIAL_FLOW__)
+ KAL_ITC_LOCK_TAKE_DI_DMT_PRIO(drv_mdcirq_activate_lisr_lock[0], irq_mask, mt_mask, ori_prio);
+#else
+ if (HWIRQCode < SW_TRIGGER_CODE53 || HWIRQCode > SW_TRIGGER_CODE64)
+ {
+ KAL_ITC_LOCK_TAKE_DI_DMT_PRIO(drv_mdcirq_activate_lisr_lock[0], irq_mask, mt_mask, ori_prio);
+ }
+#endif
+
+ SW_INT_Counter[HWIRQCode]--;
+ if(SW_INT_Counter[HWIRQCode]==0)
+ {
+ MDCIRQ_WrSetRegBit_Vector(MDCIRQ_ISTR_CLEAR_BASE, HWIRQCode);
+ MO_Sync();
+ }
+
+#if defined(__MDCIRQ_OSIPI_SPECIAL_FLOW__)
+ KAL_ITC_LOCK_GIVE_EI_EMT_PRIO(drv_mdcirq_activate_lisr_lock[0], irq_mask, mt_mask, ori_prio);
+#else
+ if (HWIRQCode < SW_TRIGGER_CODE53 || HWIRQCode > SW_TRIGGER_CODE64)
+ {
+ KAL_ITC_LOCK_GIVE_EI_EMT_PRIO(drv_mdcirq_activate_lisr_lock[0], irq_mask, mt_mask, ori_prio);
+ }
+#endif
+}
+
+// special LISR deacivation driver, used for idletask only
+void MDCIRQ_Deactivate_LISR_without_ITC(SW_CODE_HANDLE HWIRQCode)
+{
+ DEBUG_ASSERT(HWIRQCode < NUM_IRQ_SOURCES);
+
+ MDCIRQ_WrSetRegBit_Vector(MDCIRQ_ISTR_CLEAR_BASE, HWIRQCode);
+}
+
+kal_uint32 MDCIRQ_SW_INT_Count(SW_CODE_HANDLE HWIRQCode)
+{
+ DEBUG_ASSERT(HWIRQCode < NUM_IRQ_SOURCES);
+ return SW_INT_Counter[HWIRQCode];
+}
+
+
+#endif /* end of __ENABLE_SW_TRIGGER_INTERRUPT__ */
+
+/*************************************************************************
+* FUNCTION
+* MDCIRQ_Runtime_Change_NRIRQ_Affinity_NSA
+*
+* DESCRIPTION
+* This function changes NRIRQs' affinity settings to NSA settings at runtime
+* HRT NRIRQ: VPE3,4,6,7,9,10(NSA) <-> VPE0,1,2,3,4,6,7,9,10(SA)
+* CHRT NRIRQ: VPE3,4,5,6,7,8,9,10,11(NSA) <-> VPE0,1,2,3,4,5,6,7,8,9,10,11(SA)
+*
+* PARAMETERS
+* none
+*
+* RETURNS
+* none
+*
+*************************************************************************/
+void MDCIRQ_Runtime_Change_NRIRQ_Affinity_NSA() {
+ kal_uint32 vpe_id = kal_get_current_vpe_id();
+ runtime_change_NRIRQ_affinity_NSA_timing_record[vpe_id] = ust_get_current_time();
+ /* HRT NRIRQ: VPE3,4,6,7,9,10 */
+ drv_mdcirq_set_Group2VPE(20, 0x927);
+ /* CHRT NRIRQ: VPE3,4,5,6,7,8,9,10,11 */
+ drv_mdcirq_set_Group2VPE(21, 0x007);
+ MO_Sync();
+}
+
+/*************************************************************************
+* FUNCTION
+* MDCIRQ_Runtime_Change_NRIRQ_Affinity_SA
+*
+* DESCRIPTION
+* This function changes NRIRQs' affinity settings to SA settings at runtime
+* HRT NRIRQ: VPE3,4,6,7,9,10(NSA) <-> VPE0,1,2,3,4,6,7,9,10(SA)
+* CHRT NRIRQ: VPE3,4,5,6,7,8,9,10,11(NSA) <-> VPE0,1,2,3,4,5,6,7,8,9,10,11(SA)
+*
+* PARAMETERS
+* none
+*
+* RETURNS
+* none
+*
+*************************************************************************/
+void MDCIRQ_Runtime_Change_NRIRQ_Affinity_SA() {
+ kal_uint32 vpe_id = kal_get_current_vpe_id();
+ runtime_change_NRIRQ_affinity_SA_timing_record[vpe_id] = ust_get_current_time();
+ /* HRT NRIRQ: VPE0,1,2,3,4,6,7,9,10 */
+ drv_mdcirq_set_Group2VPE(20, 0x920);
+ /* CHRT NRIRQ: VPE0,1,2,3,4,5,6,7,8,9,10,11 */
+ drv_mdcirq_set_Group2VPE(21, 0x000);
+ MO_Sync();
+}
+
+/*************************************************************************
+* FUNCTION
+* MDCIRQ_Runtime_Change_LTEIRQ_Affinity_ENDC
+*
+* DESCRIPTION
+* This function changes LTEIRQs' affinity settings to ENDC settings at runtime
+* HRT LTEIRQ: VPE2(ENDC) <-> VPE3,4,6,7,9,10(LTEONLY)
+*
+* PARAMETERS
+* none
+*
+* RETURNS
+* none
+*
+*************************************************************************/
+void MDCIRQ_Runtime_Change_LTEIRQ_Affinity_ENDC() {
+ kal_uint32 vpe_id = kal_get_current_vpe_id();
+ runtime_change_LTEIRQ_affinity_ENDC_timing_record[vpe_id] = ust_get_current_time();
+ /* HRT LTEIRQ: VPE2 */
+ drv_mdcirq_set_Group2VPE(22, 0xFFB);
+ MO_Sync();
+}
+
+/*************************************************************************
+* FUNCTION
+* MDCIRQ_Runtime_Change_LTEIRQ_Affinity_LTEONLY
+*
+* DESCRIPTION
+* This function changes LTEIRQs' affinity settings to LTEONLY settings at runtime
+* HRT LTEIRQ: VPE2(ENDC) <-> VPE3,4,6,7,9,10(LTEONLY)
+*
+* PARAMETERS
+* none
+*
+* RETURNS
+* none
+*
+*************************************************************************/
+void MDCIRQ_Runtime_Change_LTEIRQ_Affinity_LTEONLY() {
+ kal_uint32 vpe_id = kal_get_current_vpe_id();
+ runtime_change_LTEIRQ_affinity_LTEONLY_timing_record[vpe_id] = ust_get_current_time();
+ /* HRT NRIRQ: VPE3,4,6,7,9,10 */
+ drv_mdcirq_set_Group2VPE(22, 0x927);
+ MO_Sync();
+}
+
+kal_bool drv_mdcirq_bbregdump_callback(void){
+ /* Backup irq_ack enable status before disable it */
+ drv_mdcirq_irq_ack_exception = drv_mdcirq_get_IRQ_ACK_enable();
+ /* Disable irq_ack when read irq_id to avoid MDCIRQ register corruption when bbreg dump*/
+ drv_mdcirq_IRQ_ACK_enable(KAL_FALSE);
+ return KAL_TRUE;
+}
+
+/*************************************************************************
+* FUNCTION
+* drv_mdcirq_IRQ_sensitivity_config
+*
+* DESCRIPTION
+* Init all IRQ sensitivity
+*
+* PARAMETERS
+*
+* RETURNS
+*
+*************************************************************************/
+void drv_mdcirq_IRQ_sensitivity_config(void)
+{
+ kal_uint32 i, temp;
+
+ for(i = 0; i < (MDCIRQ_MAX_ISR_NUM/32 + 1); i++)
+ {
+ sensitivityValueArray[i] = 0;
+ }
+
+ /* Sensitivity: by priority (SWIRQCode) */
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM; i++)
+ {
+ if( isr_config_tbl[i].irq_sensitivity == LEVEL_SENSITIVE )
+ {
+ temp = (kal_uint32)HWIRQCode2SWIRQCode[i];
+ sensitivityValueArray[temp / 32] |= (1 << (temp % 32));
+ }
+ }
+
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM/32; i++)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_ISENR_BASE, i, sensitivityValueArray[i]);
+ }
+ if((MDCIRQ_MAX_ISR_NUM % 32) != 0)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_ISENR_BASE, (MDCIRQ_MAX_ISR_NUM/32), sensitivityValueArray[MDCIRQ_MAX_ISR_NUM/32]);
+ }
+
+ for(i = 0; i < (MDCIRQ_MAX_ISR_NUM/32 + 1); i++)
+ {
+ sensitivityValueArray[i] = 0;
+ }
+
+ /* Pre-sensitivity: by IRQ ID (HWIRQCode) */
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM; i++)
+ {
+ if( isr_config_tbl[i].irq_sensitivity == LEVEL_SENSITIVE )
+ {
+ sensitivityValueArray[i / 32] |= (1 << (i % 32));
+ }
+ }
+
+ for(i = 0; i < MDCIRQ_MAX_ISR_NUM/32; i++)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_ISENR_PRE_BASE, i, sensitivityValueArray[i]);
+ }
+ if((MDCIRQ_MAX_ISR_NUM % 32) != 0)
+ {
+ MDCIRQ_WRITE_REG_INDEX(MDCIRQ_ISENR_PRE_BASE, (MDCIRQ_MAX_ISR_NUM/32), sensitivityValueArray[MDCIRQ_MAX_ISR_NUM/32]);
+ }
+
+ MO_Sync();
+}
+
+/*************************************************************************
+* FUNCTION
+* initINTR
+*
+* DESCRIPTION
+* Interrupt initialization
+*
+* PARAMETERS
+*
+* RETURNS
+*
+*************************************************************************/
+void initINTR(void)
+{
+ kal_uint32 idx;
+
+ drv_mdcirq_reset();
+
+#if defined(__ENABLE_SW_TRIGGER_INTERRUPT__)
+ /* Initialize SW Interrupt Counter*/
+ for(idx=0; idx < NUM_IRQ_SOURCES; idx++)
+ {
+ SW_INT_Counter[idx]=0;
+ }
+#endif
+
+#if defined(__MTK_TARGET__)
+ /* register bb reg dump */
+ cirq_dump.regions = (kal_uint32*)cirq_dump_regions;
+ cirq_dump.num = sizeof(cirq_dump_regions) / (sizeof(kal_uint32) * 3);
+ cirq_dump.bbreg_dump_callback = drv_mdcirq_bbregdump_callback;
+ EX_REGISTER_BBREG_DUMP(&cirq_dump);
+#endif /* __MTK_TARGET__ */
+
+ MDCIRQ_IRQ_LISR_Init();
+
+ /* Should be called after LISR init because the following function will register LISRs */
+#if defined(__DEADLOCK_DETECTION__)
+ drv_mdcirq_Deadlock_Detection_Init();
+#elif defined(__MDCIRQ_TIMING_CHECK_EN__)
+ drv_mdcirq_Qbit_Violation_Init();
+#endif
+
+ /* init all IRQ sensitivity */
+ drv_mdcirq_IRQ_sensitivity_config();
+}
diff --git a/mcu/driver/devdrv/cirq/md97/src/drv_vpe_irq.c b/mcu/driver/devdrv/cirq/md97/src/drv_vpe_irq.c
new file mode 100644
index 0000000..9536d9b
--- /dev/null
+++ b/mcu/driver/devdrv/cirq/md97/src/drv_vpe_irq.c
@@ -0,0 +1,291 @@
+#include "kal_iram_section_defs.h"
+#include "kal_public_api.h"
+#include "kal_hrt_api.h"
+#include "kal_general_types.h"
+#include "kal_internal_api.h"
+#include "cache_sw.h"
+#include "intrCtrl.h"
+#include "drv_comm.h"
+#include "drv_mdcirq_reg.h"
+#include "sync_data.h"
+#include "devdrv_ls.h"
+#include "ex_public.h"
+#include <boot.h>
+#include <mips/mt.h>
+#include "cpu_info.h"
+
+kal_uint32 drv_vpe_irq_mask_exception[SYS_MCU_NUM_VPE];
+
+#define IRQ_CLEAR_EXL() \
+ unsigned int status_reg; \
+ do { \
+ __asm__ __volatile__( \
+ "mfc0 %0, $12\n\t" \
+ "ins %0, $zero, 1, 1\n\t" \
+ "mtc0 %0, $12\n\t" \
+ "ehb\n\t" \
+ : "=&d" (status_reg) \
+ : \
+ ); \
+ } while(0)
+
+#define IRQ_SET_EXL() \
+ unsigned int status_reg; \
+ do { \
+ __asm__ __volatile__( \
+ "mfc0 %0, $12\n\t" \
+ "ori %0, 0x2\n\t" \
+ "mtc0 %0, $12\n\t" \
+ "ehb\n\t" \
+ : "=&d" (status_reg) \
+ : \
+ ); \
+ } while(0)
+
+
+#define IRQ_GET_AND_MASK_INT(ret) \
+ do { \
+ __asm__ __volatile__( \
+ "di %0\n\t" \
+ "ehb\n\t" \
+ : "=d" (ret) \
+ : \
+ ); \
+ } while(0)
+
+#define IRQ_RESTORE_INT(irq) \
+ do { \
+ if((irq&0x1)==1)\
+ {\
+ __asm__ __volatile__( \
+ "ei\n\t" \
+ "ehb\n\t" \
+ ); \
+ }\
+ } while(0)
+
+#define IRQ_ENABLE_INT() \
+ do { \
+ __asm__ __volatile__( \
+ "ei\n\t" \
+ "ehb\n\t" \
+ ); \
+ } while(0)
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ROCODE kal_uint32 LockIRQ()
+{
+ kal_uint32 ret;
+ IRQ_GET_AND_MASK_INT(ret);
+ return ret;
+}
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ROCODE void RestoreIRQ(kal_uint32 irq)
+{
+ IRQ_RESTORE_INT(irq);
+}
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ROCODE void ReEnableIRQ(void)
+{
+ IRQ_ENABLE_INT();
+}
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ROCODE kal_uint32 DisableIRQ()
+{
+ kal_uint32 ret;
+ IRQ_GET_AND_MASK_INT(ret);
+ return ret;
+}
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ROCODE void Set_EXL(void)
+{
+ IRQ_SET_EXL();
+}
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ROCODE void Clear_EXL(void)
+{
+ IRQ_CLEAR_EXL();
+}
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ROCODE kal_uint32 Ibit_Status(void)
+{
+ unsigned int status_reg;
+
+ __asm__ __volatile__(
+ "mfc0 %0, $12\n\t"
+ "andi %0, 0x1\n\t"
+ : "=&d" (status_reg)
+ :
+ );
+
+ return status_reg;
+
+}
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ROCODE void VPE_IRQ_MASK(kal_uint32 code)
+{
+ kal_uint32 mask;
+ ASSERT(code <= VPE_IRQID_END);
+ mask = ~( 1 << (8+code));
+
+ //$12 = C0_STATUS
+ __asm__ __volatile__
+ (
+ "MFC0 $a1, $12\r\n"
+ "AND $a1, %0\r\n"
+ "MTC0 $a1, $12\r\n"
+ "EHB \r\n"
+ :
+ :"d"(mask)
+ :"$a1"
+ );
+}
+
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ROCODE void VPE_IRQ_UNMASK(kal_uint32 code)
+{
+ kal_uint32 umask;
+ ASSERT(code <= VPE_IRQID_END);
+ umask = ( 1 << (8+code));
+
+ //$12 = C0_STATUS
+ __asm__ __volatile__
+ (
+ "MFC0 $a1, $12\r\n"
+ "OR $a1, %0\r\n"
+ "MTC0 $a1, $12\r\n"
+ "EHB \r\n"
+ :
+ :"d"(umask)
+ :"$a1"
+ );
+
+}
+
+void drv_vpe_irq_save_and_mask_all(kal_uint32 VPEID)
+{
+ kal_uint32 interruptMaskAll;
+ /* Get C0_STATUS */
+ __asm__ __volatile__
+ (
+ "MFC0 %0, $12\r\n"
+ :"=&d"(drv_vpe_irq_mask_exception[VPEID])
+ :
+ :
+ );
+ /* Extract IM[15:8] bit from C0_Status */
+ drv_vpe_irq_mask_exception[VPEID] = drv_vpe_irq_mask_exception[VPEID] & 0xFF00;
+
+ interruptMaskAll = ~(0xFF00);
+ /* Set IM[15:8] to mask all interrupt */
+ __asm__ __volatile__
+ (
+ "MFC0 $a1, $12\r\n"
+ "AND $a1, %0\r\n"
+ "MTC0 $a1, $12\r\n"
+ "EHB \r\n"
+ :
+ :"d"(interruptMaskAll)
+ :"$a1"
+ );
+}
+
+void drv_vpe_irq_set_YQMask(kal_uint32 mask)
+{
+ ASSERT(mask <= 0xffff);
+
+ //$1 4= YQMask
+ __asm__ __volatile__(
+ "MFC0 $a1, $1, 4\r\n"
+ "ANDI $a1, 0\r\n"
+ "OR $a1, %0\r\n"
+ "MTC0 $a1, $1, 4\r\n"
+ "EHB"
+ :
+ : "d"(mask)
+ :"$a1"
+ );
+}
+
+void drv_vpe_irq_clear_timer()
+{
+#if !__mips16
+ __asm__ __volatile__(
+ "MTC0 $zero, $9, 0\r\n"
+ "EHB"
+ :
+ :
+ :"$zero"
+ );
+#else
+ __asm__ __volatile__(
+ "LI $a1, 0\r\n"
+ "MTC0 $a1, $9, 0\r\n"
+ "EHB"
+ :
+ :
+ :"$a1"
+ );
+#endif
+}
+
+void drv_vpe_irq_clear_compare()
+{
+#if !__mips16
+ __asm__ __volatile__(
+ "MTC0 $zero, $11, 0\r\n"
+ "EHB"
+ :
+ :
+ :"$zero"
+ );
+#else
+ __asm__ __volatile__(
+ "LI $a1, 0\r\n"
+ "MTC0 $a1, $11, 0\r\n"
+ "EHB"
+ :
+ :
+ :"$a1"
+ );
+#endif
+}
+
+
+void drv_vpe_irq_reset(void)
+{
+ kal_uint32 interrupt_vector_enable=0x800000;
+
+//use special interrupt vector
+ __asm__ __volatile__
+ (
+ "MFC0 $a1, $13\r\n" //$13=C0_CAUSE
+ "OR $a1, %0\r\n"
+ "MTC0 $a1, $13\r\n"
+ "EHB\r\n"
+ :
+ :"r"(interrupt_vector_enable)
+ :"$a1"
+ );
+
+//set vector interrupt offset as 32byte
+ __asm__ __volatile__
+ (
+ "MFC0 $a1, $12,1\r\n" //$12,1 = C0_INTCTL
+ "ORI $a1, 0x20\r\n"
+ "MTC0 $a1, $12,1\r\n"
+ "EHB \r\n"
+ :
+ :
+ :"$a1"
+ );
+
+ VPE_IRQ_UNMASK(VPE_IRQID_MDCIRQ);
+#if defined(__MDCIRQ_OSIPI_SPECIAL_FLOW__)
+ VPE_IRQ_UNMASK(VPE_IRQID_OSIPI);
+#endif
+}
+
+void initVPEIRQ(void)
+{
+ drv_vpe_irq_reset();
+}
diff --git a/mcu/driver/devdrv/cirq/md97/src/isrentry.c b/mcu/driver/devdrv/cirq/md97/src/isrentry.c
new file mode 100644
index 0000000..89af8b7
--- /dev/null
+++ b/mcu/driver/devdrv/cirq/md97/src/isrentry.c
@@ -0,0 +1,753 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * isrentry.c
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ * This Module defines the IRQ service routines for all IRQ sources
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+/*******************************************************************************
+ * Include header files.
+ *******************************************************************************/
+#ifdef __MTK_TARGET__
+#include <mips/mt.h>
+#endif
+#include "reg_base.h"
+#include "isrentry.h"
+#include "intrCtrl.h"
+
+#if defined __MIPS_I7200__
+#include "md97/idle_service.h"
+#include "drv_rstctl.h"
+#endif
+
+#include "kal_hrt_api.h"
+#include "sync_data.h"
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+#include "kal_public_defs.h"
+#include "us_timer.h"
+#include "drv_mdcirq.h"
+#include "drv_mdcirq_reg.h"
+#include "kal_iram_section_defs.h"
+#include "drv_vpe_irq.h"
+#include "kal_cpuinfo.h"
+#include "mips_ia_utils.h"
+#include "drv_vpe_irq.h"
+#include "ex_public.h"
+#include "SST_sla.h"
+#include "swtr.h"
+#include "kal_internal_api.h"
+#include "mddbg_public.h"
+#include "kal_wp_hook.h"
+
+#if defined(__ESL_DBG_UTIL__)
+#include "esl_debug.h"
+#else /* __ESL_DBG_UTIL__ */
+#define esl_printf(donothing...) do {;}while(0)
+#endif /* __ESL_DBG_UTIL__ */
+
+/*************************************************************************
+ * Define function prototypes and data structures.
+ *************************************************************************/
+
+extern void kal_hrt_mt_save(kal_uint32 irqvector, kal_mt_stack_ptr *stack_ptr);
+extern void kal_hrt_mt_restore(kal_uint32 irqvector, kal_mt_stack_ptr *stack_ptr);
+
+#if defined(__DUMMY_L1_ON_TARGET_4G5G__)
+extern void xl1r_vpe_idle_setup_False(void);
+#endif
+
+/*************************************************************************
+ * Define imported global data.
+ *************************************************************************/
+extern kal_uint16 HWIRQCode2SWIRQCode[];
+extern kal_uint16 SWIRQCode2HWIRQCode[];
+
+#if defined(__MDCIRQ_B2B_IRQ_SPEEDUP_FLOW__)
+extern kal_uint32 ECT_VPE_Trigger_Status[];
+#endif
+
+/*************************************************************************
+ * Define global data.
+ *************************************************************************/
+irqlisr_entry lisr_dispatch_tbl[NUM_IRQ_SOURCES];
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ZI(4) void *processing_lisr[MDCIRQ_TOTAL_VPE_NUM];
+#if defined(__MD97_IS_2CORES__)
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_RW(4) kal_uint32 processing_irqx[MDCIRQ_TOTAL_VPE_NUM] = {IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT};
+#else
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_RW(4) kal_uint32 processing_irqx[MDCIRQ_TOTAL_VPE_NUM] = {IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT};
+#endif
+
+#if defined(__MDCIRQ_MPB_PROFILE__)
+__MCURW_HWRO_C_ALIGNED_ZI_WB(32) kal_uint32 processing_hrt_irq_count[8];
+kal_uint32 max_concur_hrt_irq_count = 0; // Include both Running HRT ISRs & Preempted HRT ISRs
+kal_uint32 max_concur_processing_hrt_irqx[MDCIRQ_TOTAL_VPE_NUM] = {IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT, IRQ_NOT_LISR_CONTEXT};
+kal_uint32 max_concur_hrt_irq_frc = 0;
+#endif
+
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ZI(4) kal_uint32 processing_irqCnt[MDCIRQ_TOTAL_VPE_NUM];
+__MCURW_HWRW_C_ALIGNED_L2CACHE_LOCK_ZI(4) kal_uint32 max_processing_irqCnt[MDCIRQ_TOTAL_VPE_NUM];
+
+/* spurious interrupt log */
+#define SPURIOUS_IRQ_LOG_SIZE 20
+kal_uint32 spurious_count[MDCIRQ_TOTAL_VPE_NUM] = {0};
+kal_uint32 spurious_id[MDCIRQ_TOTAL_VPE_NUM][SPURIOUS_IRQ_LOG_SIZE];
+
+/*************************************************************************
+ * Macro Definitions for "CIRQ Dispatch Misbehaviour" SW Workaround *
+ *************************************************************************/
+#define MDCIRQ_DUMMY_DI() \
+do{ \
+ __asm__ __volatile__( \
+ "di\n\t" \
+ "ehb\n\t" \
+ ); \
+} while(0)
+
+#define MDCIRQ_DUMMY_EI() \
+do{ \
+ __asm__ __volatile__( \
+ "ei\n\t" \
+ "ehb\n\t" \
+ ); \
+} while(0)
+
+
+/* Delay cirq_cycle T * 6(Shaolin to CIRQ clock ratio) * 2(dual issue) */
+/* 6T per round => 5 nop + 1 addiu from for loop */
+#define MDCIRQ_DELAY_LOOP(cirq_cycle) \
+do{ \
+ register kal_uint32 _delay_loop; \
+ for(_delay_loop = 0; _delay_loop < cirq_cycle * 2; _delay_loop++) { \
+ __asm__ __volatile__( \
+ "nop\n\t" \
+ "nop\n\t" \
+ "nop\n\t" \
+ "nop\n\t" \
+ "nop\n\t" \
+ ); \
+ } \
+}while(0)
+
+/*************************************************************************
+ * Macro Definitions for "CIRQ Dispatch Misbehaviour" SW Workaround End *
+ *************************************************************************/
+
+/*************************************************************************
+* FUNCTION
+* MDCIRQ_IRQ_Register_LISR
+*
+* DESCRIPTION
+* This function implement method to register IRQ's LISR.
+*
+* CALLS
+*
+* CALL BY
+*
+* PARAMETERS
+* HWIRQID - vector number to register
+* reg_lisr - register LISR's handler
+* description - LISR's description pointer to be saved.
+* Remember, the routine won't duplicate the description,
+* therefore, caller shouldn't free the description.
+*
+* RETURNS
+*
+*************************************************************************/
+void MDCIRQ_IRQ_Register_LISR(kal_uint16 HWIRQCode, void (*reg_lisr)(kal_uint32), char* description)
+{
+ kal_uint32 savedMask, SWIRQCode;
+
+ savedMask = kal_hrt_SaveAndSetIRQMask();
+ SWIRQCode = (kal_uint32)HWIRQCode2SWIRQCode[HWIRQCode];
+ lisr_dispatch_tbl[HWIRQCode].vector = SWIRQCode;
+ lisr_dispatch_tbl[HWIRQCode].lisr_handler = reg_lisr;
+ lisr_dispatch_tbl[HWIRQCode].description = description;
+ kal_hrt_RestoreIRQMask(savedMask);
+}
+
+/*************************************************************************
+* FUNCTION
+* MDCIRQ_IRQ_LISR_Init
+*
+* DESCRIPTION
+* This function implement IRQ's LISR (Low-level Interrupt Service Routine)
+* Table initialization.
+*
+* CALLS
+*
+* CALL BY
+*
+* PARAMETERS
+*
+* RETURNS
+*
+*************************************************************************/
+void MDCIRQ_IRQ_LISR_Init()
+{
+ kal_uint32 i;
+ for (i = NUM_IRQ_SOURCES; i != 0; i--)
+ {
+ MDCIRQ_IRQ_Register_LISR(i - 1, MDCIRQ_IRQ_Default_LISR, "NULL handler");
+ }
+}
+
+/*************************************************************************
+* FUNCTION
+* MDCIRQ_IRQ_Retrieve_LISR
+*
+* DESCRIPTION
+* This function implement to retrieve register LISR handler
+*
+* CALLS
+*
+* CALL BY
+*
+* PARAMETERS
+*
+* RETURNS
+*
+*************************************************************************/
+void* MDCIRQ_IRQ_Retrieve_LISR(kal_uint16 HWIRQCode)
+{
+ return(void*)(lisr_dispatch_tbl[HWIRQCode].lisr_handler);
+}
+
+/*************************************************************************
+* FUNCTION
+* IRQ_Default_LISR
+*
+* DESCRIPTION
+* This function implement default IRQ' LISR
+*
+* CALLS
+*
+* CALL BY
+* IRQ_LISR_Init()
+*
+* PARAMETERS
+*
+* RETURNS
+*
+*************************************************************************/
+void MDCIRQ_IRQ_Default_LISR(kal_uint32 irq_id)
+{
+ kal_fatal_error_handler(KAL_ERROR_NON_REGISTERED_LISR, irq_id);
+}
+
+void INT_Timer_Interrupt(void)
+{
+ kal_timer_interrupt();
+}
+
+void isrC_Main(kal_uint32 vector)
+{
+
+ kal_uint32 vpe_num;
+ kal_uint32 irqx_swcode, irqx_swcode_non_spurious;
+ kal_uint32 irqx_hwcode, irqx_hwcode_non_spurious;
+ void *processing_lisr_backup;
+ kal_uint32 processing_irqx_backup;
+ kal_uint32 ori_vpe_state;
+ kal_mt_stack_ptr mt_stack_ptr_backup = {{NULL}};
+
+ ASSERT_EXL_SAFE(vector == VPE_IRQID_MDCIRQ);
+
+ vpe_num = kal_get_current_vpe_id();
+ processing_lisr_backup = processing_lisr[vpe_num];
+ processing_irqx_backup = processing_irqx[vpe_num];
+
+#if defined(__MDCIRQ_B2B_IRQ_SPEEDUP_FLOW__)
+ do {
+#endif
+
+#if defined(__MDCIRQ_GCR_SIGNAL_DISABLE__)
+ irqx_swcode = DRV_Reg32(MDCIRQ_VPE_IRQ_ID_BASE + (vpe_num<<2));
+#else
+ irqx_swcode = DRV_Reg32(MDCIRQ_GCR_VPE_IRQ_ID_BASE + (vpe_num<<2));
+#endif
+
+ irqx_swcode_non_spurious = irqx_swcode & 0x1ff;
+
+ /* Set&backup VPE IRQ state */
+ ori_vpe_state = drv_mdcirq_SaveAndSet_VPE_state(vpe_num, irqx_swcode_non_spurious);
+
+#if defined __MIPS_I7200__
+ /* Reset TC's priority according IRQ's Priority */
+ register miu_reg32_t tc_priority;
+ if (irqx_swcode < IRQ_HRT_PRIORITY_THRESHOLD) {
+ // HRT IRQs
+ tc_priority = HRT_CONTEXT_GRP;
+#if defined(__MDCIRQ_MPB_PROFILE__)
+ kal_atomic_inc(&processing_hrt_irq_count[0]);
+#endif
+ } else {
+ // Non-HRT IRQs and Spurious IRQs
+ tc_priority = kal_get_current_domain();
+ }
+ miu_mtc0(MIU_C0_TCSCHEDULE, tc_priority << MIU_C0_TCSCHEDULE_PRIO_BITFIELD_BEG);
+
+#else /* MT6297_IA */
+ /* Not set when spurious interrput, so take original read ID result as parameter */
+ if( !kal_if_hrt_domain(vpe_num) )
+ {
+ LISR_RAISE_TC_PRIO(irqx_swcode);
+ }
+#endif
+
+#if defined(__DUMMY_L1_ON_TARGET_4G5G__)
+ /* Record current VPE is not in Idletask for KS IODT FPGA */
+ xl1r_vpe_idle_setup_False();
+#endif
+
+ irqx_hwcode_non_spurious = (kal_uint32)SWIRQCode2HWIRQCode[irqx_swcode_non_spurious];
+ irqx_hwcode = irqx_hwcode_non_spurious | (irqx_swcode&0x200);
+
+ /* Use HW code to do IRQ logging */
+ esl_printf(ESL_SIM_TIME_FLAG|ESL_WALL_TIME_FLAG, "[ISR-%d S]\n", irqx_hwcode);
+
+ /* These global variable will be used by others. The meaning should keep the same as 93*/
+ processing_irqx[vpe_num] = irqx_hwcode_non_spurious;
+ processing_lisr[vpe_num] = (void*)lisr_dispatch_tbl[irqx_hwcode_non_spurious].lisr_handler;
+ processing_irqCnt[vpe_num]++;
+ if(processing_irqCnt[vpe_num]>max_processing_irqCnt[vpe_num])
+ {
+ max_processing_irqCnt[vpe_num] = processing_irqCnt[vpe_num];
+ }
+
+ SLA_LoggingLISR(0xaaaa0000 | ((kal_uint32)irqx_hwcode), vpe_num);
+
+ /************************************************************************************
+ * SW workaround for "CIRQ Dispatch Misbehaviour" *
+ * When low priority IRQ is enterting IRQ handler flow (readID ~ set vpe state), and *
+ * high priority IRQ is choosing best vpe according to vpe state, the high priority *
+ * IRQ will dispatch to the same VPE and preempt low priority IRQ since vpe state *
+ * of the low priority IRQ has not yet been updated to CIRQ. This may cause two *
+ * critical LISRS to run on the same VPE while other VPEs are in IDLE. Therefore, we *
+ * trigger a dummy DI/EI below to force high priority IRQ to be resent to other VPEs.*
+ *************************************************************************************/
+
+#if defined(__MDCIRQ_GCR_SIGNAL_DISABLE__)
+ /* Dummy read APB_VPE_IRQ_STATE to guarantee value has been written to CIRQ */
+ ASSERT_EXL_SAFE(MDCIRQ_READ_REG_INDEX(MDCIRQ_VPE_IRQ_STATE_BASE, vpe_num) == irqx_swcode_non_spurious);
+#else
+ /* Dummy read GCR_VPE_IRQ_STATE to guarantee value has been written to GCR,
+ then wait for 3T CIRQ clock so that the GCR value is synced to CIRQ */
+ ASSERT_EXL_SAFE(MDCIRQ_READ_REG_INDEX(MDCIRQ_GCR_VPE_IRQ_STATE_BASE, vpe_num) == irqx_swcode_non_spurious);
+ MDCIRQ_DELAY_LOOP(3);
+#endif
+
+ /* Dummy DI/EI to force pending IRQs to be resent */
+ MDCIRQ_DUMMY_DI();
+ MDCIRQ_DELAY_LOOP(3);
+ MDCIRQ_DUMMY_EI();
+
+ /************************************************************************************
+ * SW workaround for "CIRQ Dispatch Misbehaviour" End *
+ *************************************************************************************/
+
+ /* Non-Spurious IRQ */
+ if(!(irqx_hwcode&0x200))
+ {
+ kal_hrt_mt_save(irqx_hwcode_non_spurious, &mt_stack_ptr_backup);
+#if defined(__MDCIRQ_OSIPI_SPECIAL_FLOW__)
+ /* Mask OSIPI in the first IRQ LISR (because OSIPI is the lowest priority) */
+ if( processing_irqCnt[vpe_num] == 1 )
+ {
+ VPE_IRQ_MASK(VPE_IRQID_OSIPI);
+ }
+#endif
+#if defined __MIPS_I7200__
+ if((kal_get_current_domain() == KAL_DOMAIN_CHRT) && (processing_irqCnt[vpe_num] == 1))
+ {
+ // enable and kick WDT
+ drv_rstctl_set_check_bit((vpeid_e)vpe_num);
+ drv_rstctl_set_kick_bit((vpeid_e)vpe_num);
+ }
+#endif
+#if !defined(DISABLE_MDDBG_FUNCTION)
+ wp_hook_dispatchLISR_start(vpe_num,irqx_hwcode_non_spurious);
+#endif
+ Clear_EXL();
+
+ lisr_dispatch_tbl[irqx_hwcode_non_spurious].lisr_handler(irqx_hwcode_non_spurious);
+
+ if(Ibit_Status()!=1) //Ibit cannot be disabled after LISR!
+ {
+ kal_fatal_error_handler(KAL_ERROR_INTERRUPT_DISABLED_AFTER_LISR_FAILED, (kal_uint32)processing_lisr[vpe_num]);
+ }
+
+ Set_EXL();
+#if !defined(DISABLE_MDDBG_FUNCTION)
+ wp_hook_dispatchLISR_end(vpe_num,irqx_hwcode_non_spurious);
+#endif
+
+#if defined(__MDCIRQ_B2B_IRQ_SPEEDUP_FLOW__)
+ /* CIRQ timing limitation: "After clearing IRQ source, need to wait for
+ 105T CPU clock before doing priority ACK."
+ => SWLA need to be placed before priority ACK */
+ kal_hrt_mt_restore(irqx_hwcode_non_spurious, &mt_stack_ptr_backup);
+ SLA_LoggingLISR(0xaaaaaaaa, vpe_num);
+ drv_mdcirq_Restore_VPE_state(vpe_num, ori_vpe_state);
+
+ /* In B2B flow, do priority ACK earlier so that next IRQ can be
+ triggered to CPU earlier. */
+ if( processing_irqx_backup == IRQ_NOT_LISR_CONTEXT)
+ MDCIRQ_SYS_endIsr(vpe_num, processing_irqx_backup);
+ else
+ MDCIRQ_SYS_endIsr(vpe_num, (kal_uint32)HWIRQCode2SWIRQCode[processing_irqx_backup]);
+#endif
+
+#if defined(__MDCIRQ_OSIPI_SPECIAL_FLOW__)
+ /* Unmask OSIPI after the first IRQ LISR */
+ if( processing_irqCnt[vpe_num] == 1 )
+ {
+ VPE_IRQ_UNMASK(VPE_IRQID_OSIPI);
+ }
+#endif
+
+#if defined __MIPS_I7200__
+ if((kal_get_current_domain() == KAL_DOMAIN_CHRT) && (processing_irqCnt[vpe_num] == 1))
+ {
+ // disable WDT
+ drv_rstctl_clr_check_bit((vpeid_e)vpe_num);
+ // set wait variable
+ Idle_Service_Prepare_WAIT();
+ }
+#endif
+
+#if !defined(__MDCIRQ_B2B_IRQ_SPEEDUP_FLOW__)
+ kal_hrt_mt_restore(irqx_hwcode_non_spurious, &mt_stack_ptr_backup);
+#endif
+ }
+ else // spurious IRQ
+ {
+ spurious_id[vpe_num][spurious_count[vpe_num]%SPURIOUS_IRQ_LOG_SIZE] = irqx_hwcode;
+ spurious_count[vpe_num]++;
+
+#if defined(__MDCIRQ_B2B_IRQ_SPEEDUP_FLOW__)
+ SLA_LoggingLISR(0xaaaaaaaa, vpe_num);
+ drv_mdcirq_Restore_VPE_state(vpe_num, ori_vpe_state);
+#endif
+ }
+
+#if defined(__MDCIRQ_MPB_PROFILE__)
+ if (processing_hrt_irq_count[0] >= max_concur_hrt_irq_count) {
+ max_concur_hrt_irq_count = processing_hrt_irq_count[0];
+ max_concur_hrt_irq_frc = ust_get_current_time();
+ memcpy(max_concur_processing_hrt_irqx, processing_irqx, sizeof(processing_irqx));
+ }
+ if (irqx_swcode < IRQ_HRT_PRIORITY_THRESHOLD) {
+ kal_atomic_dec(&processing_hrt_irq_count[0]);
+ }
+#endif
+
+ processing_irqx[vpe_num] = processing_irqx_backup;
+ processing_lisr[vpe_num] = processing_lisr_backup;
+ processing_irqCnt[vpe_num]--;
+
+ /* Use HW code to do IRQ logging */
+ esl_printf(ESL_SIM_TIME_FLAG|ESL_WALL_TIME_FLAG, "[ISR-%d E]\n", irqx_hwcode);
+
+#if defined(__MDCIRQ_B2B_IRQ_SPEEDUP_FLOW__)
+ /* CTI interrupt is level-trigger and the source would not be cleared.
+ Therefore, ignore the pending IRQ, let it back to OS and enter exception. */
+ if (ECT_VPE_Trigger_Status[vpe_num] != 0) {
+ break;
+ }
+
+ /* Check if next IRQ is pending */
+ /* IRQ_B <-> SI_INT[4] => IP6 => C0_CAUSE[14] */
+ if (((miu_mfc0(MIU_C0_CAUSE) >> (8 + VPE_IRQID_MDCIRQ)) & 0x1) == 1) {
+ /* Delay 1T CIRQ clock to ensure IRQ ID has been synced to GCR */
+ MDCIRQ_DELAY_LOOP(1);
+
+ /* CIRQ timing limitation: "SW should not DI or set min priority within
+ 50T CPU clock before read ID."
+ => Should not DI or set SPL within 50T before this point */
+ } else {
+ /* No pending IRQ => exit ISR handler loop */
+ break;
+ }
+
+ } while (1);
+#else
+ SLA_LoggingLISR(0xaaaaaaaa, vpe_num);
+ drv_mdcirq_Restore_VPE_state(vpe_num, ori_vpe_state);
+
+ /* Non-Spurious IRQ */
+ if(!(irqx_hwcode&0x200))
+ {
+ /* IRQ idx in SW code view */
+ if( processing_irqx_backup == IRQ_NOT_LISR_CONTEXT)
+ MDCIRQ_SYS_endIsr(vpe_num, processing_irqx_backup);
+ else
+ MDCIRQ_SYS_endIsr(vpe_num, (kal_uint32)HWIRQCode2SWIRQCode[processing_irqx_backup]);
+ }
+#endif
+}
+
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+