@@ -34,6 +34,11 @@
#include "op_helper.h"
#include "cpu_helper.h"
#include "translate.h"
+#ifndef CONFIG_USER_ONLY
+#include "hex_mmu.h"
+#include "hw/intc/l2vic.h"
+#include "hex_interrupts.h"
+#endif
#define SF_BIAS 127
#define SF_MANTBITS 23
@@ -1338,9 +1343,36 @@ void HELPER(vwhist128qm)(CPUHexagonState *env, int32_t uiV)
}
#ifndef CONFIG_USER_ONLY
+static void hexagon_set_vid(CPUHexagonState *env, uint32_t offset, int val)
+{
+ g_assert((offset == L2VIC_VID_0) || (offset == L2VIC_VID_1));
+ CPUState *cs = env_cpu(env);
+ HexagonCPU *cpu = HEXAGON_CPU(cs);
+ const hwaddr pend_mem = cpu->l2vic_base_addr + offset;
+ cpu_physical_memory_write(pend_mem, &val, sizeof(val));
+}
+
+static void hexagon_clear_last_irq(CPUHexagonState *env, uint32_t offset)
+{
+ /*
+ * currently only l2vic is the only attached it uses vid0, remove
+ * the assert below if anther is added
+ */
+ hexagon_set_vid(env, offset, L2VIC_CIAD_INSTRUCTION);
+}
+
void HELPER(ciad)(CPUHexagonState *env, uint32_t mask)
{
- g_assert_not_reached();
+ uint32_t ipendad;
+ uint32_t iad;
+
+ BQL_LOCK_GUARD();
+ ipendad = READ_SREG(HEX_SREG_IPENDAD);
+ iad = fGET_FIELD(ipendad, IPENDAD_IAD);
+ fSET_FIELD(ipendad, IPENDAD_IAD, iad & ~(mask));
+ arch_set_system_reg(env, HEX_SREG_IPENDAD, ipendad);
+ hexagon_clear_last_irq(env, L2VIC_VID_0);
+ hex_interrupt_update(env);
}
void HELPER(siad)(CPUHexagonState *env, uint32_t mask)
@@ -1416,11 +1448,6 @@ static void modify_syscfg(CPUHexagonState *env, uint32_t val)
g_assert_not_reached();
}
-static void hexagon_set_vid(CPUHexagonState *env, uint32_t offset, int val)
-{
- g_assert_not_reached();
-}
-
static uint32_t hexagon_find_last_irq(CPUHexagonState *env, uint32_t vid)
{
g_assert_not_reached();