summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-02-25 11:54:40 +0000
committerPeter Maydell <peter.maydell@linaro.org>2014-02-25 11:54:40 +0000
commit05fd3bf2a1c9fc26414d3cf608732c40d0d9eb23 (patch)
tree89e1d86090aca653216eef7ca1503797fb0a0931
parente7a1d6c52a3ac6e76e5653c830b2545e0a4043d3 (diff)
parent604e1f9cd0602e92ba49a27dd3a46db3d29f882e (diff)
downloadfocaccia-qemu-05fd3bf2a1c9fc26414d3cf608732c40d0d9eb23.tar.gz
focaccia-qemu-05fd3bf2a1c9fc26414d3cf608732c40d0d9eb23.zip
Merge remote-tracking branch 'remotes/xtensa/tags/20140224-xtensa' into staging
Xtensa fixes and improvements queue 2014-02-24:
- add support for ML605 and KC705 FPGA boards;
- flush opencores_eth queue when new RX descriptor is available;
- add basic checks to cache opcodes;
- make core configuration available to tests;
- implement HW config ID special registers.

# gpg: Signature made Mon 24 Feb 2014 00:52:42 GMT using RSA key ID F83FA044
# gpg: Good signature from "Max Filippov <max.filippov@cogentembedded.com>"
# gpg:                 aka "Max Filippov <jcmvbkbc@gmail.com>"

* remotes/xtensa/tags/20140224-xtensa:
  target-xtensa: provide HW confg ID registers
  target-xtensa: refactor standard core configuration
  target-xtensa: add basic tests for cache opcodes
  target-xtensa: allow using core configuration in tests
  target-xtensa: add overridable test_init macro
  target-xtensa: add basic checks to icache opcodes
  target-xtensa: add basic checks to dcache opcodes
  target-xtensa: add RRRI4 opcode format fields
  opencores_eth: flush queue whenever can_receive can go from false to true
  hw/xtensa: add support for ML605 and KC705 FPGA board

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/net/opencores_eth.c33
-rw-r--r--hw/xtensa/xtensa_lx60.c51
-rw-r--r--target-xtensa/core-dc232b.c8
-rw-r--r--target-xtensa/core-dc233c.c8
-rw-r--r--target-xtensa/core-fsf.c8
-rw-r--r--target-xtensa/cpu.c2
-rw-r--r--target-xtensa/cpu.h4
-rw-r--r--target-xtensa/helper.h1
-rw-r--r--target-xtensa/op_helper.c5
-rw-r--r--target-xtensa/overlay_tool.h17
-rw-r--r--target-xtensa/translate.c83
-rw-r--r--tests/tcg/xtensa/Makefile12
-rw-r--r--tests/tcg/xtensa/macros.inc6
-rw-r--r--tests/tcg/xtensa/test_b.S2
-rw-r--r--tests/tcg/xtensa/test_bi.S2
-rw-r--r--tests/tcg/xtensa/test_boolean.S2
-rw-r--r--tests/tcg/xtensa/test_break.S2
-rw-r--r--tests/tcg/xtensa/test_bz.S2
-rw-r--r--tests/tcg/xtensa/test_cache.S97
-rw-r--r--tests/tcg/xtensa/test_clamps.S2
-rw-r--r--tests/tcg/xtensa/test_extui.S2
-rw-r--r--tests/tcg/xtensa/test_fail.S2
-rw-r--r--tests/tcg/xtensa/test_interrupt.S2
-rw-r--r--tests/tcg/xtensa/test_loop.S2
-rw-r--r--tests/tcg/xtensa/test_mac16.S2
-rw-r--r--tests/tcg/xtensa/test_max.S2
-rw-r--r--tests/tcg/xtensa/test_min.S2
-rw-r--r--tests/tcg/xtensa/test_mmu.S6
-rw-r--r--tests/tcg/xtensa/test_mul16.S2
-rw-r--r--tests/tcg/xtensa/test_mul32.S2
-rw-r--r--tests/tcg/xtensa/test_nsa.S2
-rw-r--r--tests/tcg/xtensa/test_pipeline.S2
-rw-r--r--tests/tcg/xtensa/test_quo.S2
-rw-r--r--tests/tcg/xtensa/test_rem.S2
-rw-r--r--tests/tcg/xtensa/test_rst0.S2
-rw-r--r--tests/tcg/xtensa/test_s32c1i.S2
-rw-r--r--tests/tcg/xtensa/test_sar.S2
-rw-r--r--tests/tcg/xtensa/test_sext.S2
-rw-r--r--tests/tcg/xtensa/test_shift.S2
-rw-r--r--tests/tcg/xtensa/test_sr.S2
-rw-r--r--tests/tcg/xtensa/test_timer.S2
-rw-r--r--tests/tcg/xtensa/test_windowed.S2
42 files changed, 332 insertions, 63 deletions
diff --git a/hw/net/opencores_eth.c b/hw/net/opencores_eth.c
index 4118d54ac8..4a443049dd 100644
--- a/hw/net/opencores_eth.c
+++ b/hw/net/opencores_eth.c
@@ -169,6 +169,7 @@ enum {
 };
 
 enum {
+    INT_SOURCE_BUSY = 0x10,
     INT_SOURCE_RXB = 0x4,
     INT_SOURCE_TXB = 0x1,
 };
@@ -351,8 +352,7 @@ static int open_eth_can_receive(NetClientState *nc)
     OpenEthState *s = qemu_get_nic_opaque(nc);
 
     return GET_REGBIT(s, MODER, RXEN) &&
-        (s->regs[TX_BD_NUM] < 0x80) &&
-        (rx_desc(s)->len_flags & RXD_E);
+        (s->regs[TX_BD_NUM] < 0x80);
 }
 
 static ssize_t open_eth_receive(NetClientState *nc,
@@ -402,6 +402,12 @@ static ssize_t open_eth_receive(NetClientState *nc,
         desc *desc = rx_desc(s);
         size_t copy_size = GET_REGBIT(s, MODER, HUGEN) ? 65536 : maxfl;
 
+        if (!(desc->len_flags & RXD_E)) {
+            open_eth_int_source_write(s,
+                    s->regs[INT_SOURCE] | INT_SOURCE_BUSY);
+            return size;
+        }
+
         desc->len_flags &= ~(RXD_CF | RXD_M | RXD_OR |
                 RXD_IS | RXD_DN | RXD_TL | RXD_SF | RXD_CRC | RXD_LC);
 
@@ -551,6 +557,15 @@ static uint64_t open_eth_reg_read(void *opaque,
     return v;
 }
 
+static void open_eth_notify_can_receive(OpenEthState *s)
+{
+    NetClientState *nc = qemu_get_queue(s->nic);
+
+    if (open_eth_can_receive(nc)) {
+        qemu_flush_queued_packets(nc);
+    }
+}
+
 static void open_eth_ro(OpenEthState *s, uint32_t val)
 {
 }
@@ -567,6 +582,7 @@ static void open_eth_moder_host_write(OpenEthState *s, uint32_t val)
 
     if (set & MODER_RXEN) {
         s->rx_desc = s->regs[TX_BD_NUM];
+        open_eth_notify_can_receive(s);
     }
     if (set & MODER_TXEN) {
         s->tx_desc = 0;
@@ -592,6 +608,18 @@ static void open_eth_int_mask_host_write(OpenEthState *s, uint32_t val)
             s->regs[INT_SOURCE] & s->regs[INT_MASK]);
 }
 
+static void open_eth_tx_bd_num_host_write(OpenEthState *s, uint32_t val)
+{
+    if (val < 0x80) {
+        bool enable = s->regs[TX_BD_NUM] == 0x80;
+
+        s->regs[TX_BD_NUM] = val;
+        if (enable) {
+            open_eth_notify_can_receive(s);
+        }
+    }
+}
+
 static void open_eth_mii_command_host_write(OpenEthState *s, uint32_t val)
 {
     unsigned fiad = GET_REGFIELD(s, MIIADDRESS, FIAD);
@@ -630,6 +658,7 @@ static void open_eth_reg_write(void *opaque,
         [MODER] = open_eth_moder_host_write,
         [INT_SOURCE] = open_eth_int_source_host_write,
         [INT_MASK] = open_eth_int_mask_host_write,
+        [TX_BD_NUM] = open_eth_tx_bd_num_host_write,
         [MIICOMMAND] = open_eth_mii_command_host_write,
         [MIITX_DATA] = open_eth_mii_tx_host_write,
         [MIISTATUS] = open_eth_ro,
diff --git a/hw/xtensa/xtensa_lx60.c b/hw/xtensa/xtensa_lx60.c
index 22e124d9ec..49c58d11a3 100644
--- a/hw/xtensa/xtensa_lx60.c
+++ b/hw/xtensa/xtensa_lx60.c
@@ -40,6 +40,7 @@
 #include "xtensa_bootparam.h"
 
 typedef struct LxBoardDesc {
+    hwaddr flash_base;
     size_t flash_size;
     size_t flash_sector_size;
     size_t sram_size;
@@ -219,7 +220,7 @@ static void lx_init(const LxBoardDesc *board, QEMUMachineInitArgs *args)
 
     dinfo = drive_get(IF_PFLASH, 0, 0);
     if (dinfo) {
-        flash = pflash_cfi01_register(0xf8000000,
+        flash = pflash_cfi01_register(board->flash_base,
                 NULL, "lx60.io.flash", board->flash_size,
                 dinfo->bdrv, board->flash_sector_size,
                 board->flash_size / board->flash_sector_size,
@@ -265,7 +266,9 @@ static void lx_init(const LxBoardDesc *board, QEMUMachineInitArgs *args)
             MemoryRegion *flash_io = g_malloc(sizeof(*flash_io));
 
             memory_region_init_alias(flash_io, NULL, "lx60.flash",
-                    flash_mr, 0, board->flash_size);
+                    flash_mr, 0,
+                    board->flash_size < 0x02000000 ?
+                    board->flash_size : 0x02000000);
             memory_region_add_subregion(system_memory, 0xfe000000,
                     flash_io);
         }
@@ -275,7 +278,8 @@ static void lx_init(const LxBoardDesc *board, QEMUMachineInitArgs *args)
 static void xtensa_lx60_init(QEMUMachineInitArgs *args)
 {
     static const LxBoardDesc lx60_board = {
-        .flash_size = 0x400000,
+        .flash_base = 0xf8000000,
+        .flash_size = 0x00400000,
         .flash_sector_size = 0x10000,
         .sram_size = 0x20000,
     };
@@ -285,13 +289,36 @@ static void xtensa_lx60_init(QEMUMachineInitArgs *args)
 static void xtensa_lx200_init(QEMUMachineInitArgs *args)
 {
     static const LxBoardDesc lx200_board = {
-        .flash_size = 0x1000000,
+        .flash_base = 0xf8000000,
+        .flash_size = 0x01000000,
         .flash_sector_size = 0x20000,
         .sram_size = 0x2000000,
     };
     lx_init(&lx200_board, args);
 }
 
+static void xtensa_ml605_init(QEMUMachineInitArgs *args)
+{
+    static const LxBoardDesc ml605_board = {
+        .flash_base = 0xf8000000,
+        .flash_size = 0x02000000,
+        .flash_sector_size = 0x20000,
+        .sram_size = 0x2000000,
+    };
+    lx_init(&ml605_board, args);
+}
+
+static void xtensa_kc705_init(QEMUMachineInitArgs *args)
+{
+    static const LxBoardDesc kc705_board = {
+        .flash_base = 0xf0000000,
+        .flash_size = 0x08000000,
+        .flash_sector_size = 0x20000,
+        .sram_size = 0x2000000,
+    };
+    lx_init(&kc705_board, args);
+}
+
 static QEMUMachine xtensa_lx60_machine = {
     .name = "lx60",
     .desc = "lx60 EVB (" XTENSA_DEFAULT_CPU_MODEL ")",
@@ -306,10 +333,26 @@ static QEMUMachine xtensa_lx200_machine = {
     .max_cpus = 4,
 };
 
+static QEMUMachine xtensa_ml605_machine = {
+    .name = "ml605",
+    .desc = "ml605 EVB (" XTENSA_DEFAULT_CPU_MODEL ")",
+    .init = xtensa_ml605_init,
+    .max_cpus = 4,
+};
+
+static QEMUMachine xtensa_kc705_machine = {
+    .name = "kc705",
+    .desc = "kc705 EVB (" XTENSA_DEFAULT_CPU_MODEL ")",
+    .init = xtensa_kc705_init,
+    .max_cpus = 4,
+};
+
 static void xtensa_lx_machines_init(void)
 {
     qemu_register_machine(&xtensa_lx60_machine);
     qemu_register_machine(&xtensa_lx200_machine);
+    qemu_register_machine(&xtensa_ml605_machine);
+    qemu_register_machine(&xtensa_kc705_machine);
 }
 
 machine_init(xtensa_lx_machines_init);
diff --git a/target-xtensa/core-dc232b.c b/target-xtensa/core-dc232b.c
index 0bfcf2414c..c51e11e6d7 100644
--- a/target-xtensa/core-dc232b.c
+++ b/target-xtensa/core-dc232b.c
@@ -35,7 +35,6 @@
 
 static const XtensaConfig dc232b = {
     .name = "dc232b",
-    .options = XTENSA_OPTIONS,
     .gdb_regmap = {
         .num_regs = 120,
         .num_core_regs = 52,
@@ -43,13 +42,8 @@ static const XtensaConfig dc232b = {
 #include "core-dc232b/gdb-config.c"
         }
     },
-    .nareg = XCHAL_NUM_AREGS,
-    .ndepc = 1,
-    EXCEPTIONS_SECTION,
-    INTERRUPTS_SECTION,
-    TLB_SECTION,
-    DEBUG_SECTION,
     .clock_freq_khz = 10000,
+    DEFAULT_SECTIONS
 };
 
 REGISTER_CORE(dc232b)
diff --git a/target-xtensa/core-dc233c.c b/target-xtensa/core-dc233c.c
index 738d543e53..42dd64f031 100644
--- a/target-xtensa/core-dc233c.c
+++ b/target-xtensa/core-dc233c.c
@@ -36,7 +36,6 @@
 
 static const XtensaConfig dc233c = {
     .name = "dc233c",
-    .options = XTENSA_OPTIONS,
     .gdb_regmap = {
         .num_regs = 121,
         .num_core_regs = 52,
@@ -44,13 +43,8 @@ static const XtensaConfig dc233c = {
 #include "core-dc233c/gdb-config.c"
         }
     },
-    .nareg = XCHAL_NUM_AREGS,
-    .ndepc = 1,
-    EXCEPTIONS_SECTION,
-    INTERRUPTS_SECTION,
-    TLB_SECTION,
-    DEBUG_SECTION,
     .clock_freq_khz = 10000,
+    DEFAULT_SECTIONS
 };
 
 REGISTER_CORE(dc233c)
diff --git a/target-xtensa/core-fsf.c b/target-xtensa/core-fsf.c
index d4660edde9..6859bee062 100644
--- a/target-xtensa/core-fsf.c
+++ b/target-xtensa/core-fsf.c
@@ -35,15 +35,9 @@
 
 static const XtensaConfig fsf = {
     .name = "fsf",
-    .options = XTENSA_OPTIONS,
     /* GDB for this core is not supported currently */
-    .nareg = XCHAL_NUM_AREGS,
-    .ndepc = 1,
-    EXCEPTIONS_SECTION,
-    INTERRUPTS_SECTION,
-    TLB_SECTION,
-    DEBUG_SECTION,
     .clock_freq_khz = 10000,
+    DEFAULT_SECTIONS
 };
 
 REGISTER_CORE(fsf)
diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index c19d17ad04..749e20580f 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -59,6 +59,8 @@ static void xtensa_cpu_reset(CPUState *s)
     env->sregs[CACHEATTR] = 0x22222222;
     env->sregs[ATOMCTL] = xtensa_option_enabled(env->config,
             XTENSA_OPTION_ATOMCTL) ? 0x28 : 0x15;
+    env->sregs[CONFIGID0] = env->config->configid[0];
+    env->sregs[CONFIGID1] = env->config->configid[1];
 
     env->pending_irq_level = 0;
     reset_mmu(env);
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index 95103e9e87..1cf5ea3aff 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -135,9 +135,11 @@ enum {
     IBREAKA = 128,
     DBREAKA = 144,
     DBREAKC = 160,
+    CONFIGID0 = 176,
     EPC1 = 177,
     DEPC = 192,
     EPS2 = 194,
+    CONFIGID1 = 208,
     EXCSAVE1 = 209,
     CPENABLE = 224,
     INTSET = 226,
@@ -321,6 +323,8 @@ typedef struct XtensaConfig {
     unsigned nibreak;
     unsigned ndbreak;
 
+    uint32_t configid[2];
+
     uint32_t clock_freq_khz;
 
     xtensa_tlb itlb;
diff --git a/target-xtensa/helper.h b/target-xtensa/helper.h
index 38d7157f34..322b04cd0a 100644
--- a/target-xtensa/helper.h
+++ b/target-xtensa/helper.h
@@ -25,6 +25,7 @@ DEF_HELPER_2(advance_ccount, void, env, i32)
 DEF_HELPER_1(check_interrupts, void, env)
 DEF_HELPER_3(check_atomctl, void, env, i32, i32)
 
+DEF_HELPER_2(itlb_hit_test, void, env, i32)
 DEF_HELPER_2(wsr_rasid, void, env, i32)
 DEF_HELPER_FLAGS_3(rtlb0, TCG_CALL_NO_RWG_SE, i32, env, i32, i32)
 DEF_HELPER_FLAGS_3(rtlb1, TCG_CALL_NO_RWG_SE, i32, env, i32, i32)
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index 89a72b5678..509ba49d60 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -415,6 +415,11 @@ void HELPER(check_interrupts)(CPUXtensaState *env)
     check_interrupts(env);
 }
 
+void HELPER(itlb_hit_test)(CPUXtensaState *env, uint32_t vaddr)
+{
+    get_page_addr_code(env, vaddr);
+}
+
 /*!
  * Check vaddr accessibility/cache attributes and raise an exception if
  * specified by the ATOMCTL SR.
diff --git a/target-xtensa/overlay_tool.h b/target-xtensa/overlay_tool.h
index dd4f51a7b7..4c0de7f06a 100644
--- a/target-xtensa/overlay_tool.h
+++ b/target-xtensa/overlay_tool.h
@@ -319,6 +319,23 @@
     .nibreak = XCHAL_NUM_IBREAK, \
     .ndbreak = XCHAL_NUM_DBREAK
 
+#define CONFIG_SECTION \
+    .configid = { \
+        XCHAL_HW_CONFIGID0, \
+        XCHAL_HW_CONFIGID1, \
+    }
+
+#define DEFAULT_SECTIONS \
+    .options = XTENSA_OPTIONS, \
+    .nareg = XCHAL_NUM_AREGS, \
+    .ndepc = (XCHAL_XEA_VERSION >= 2), \
+    EXCEPTIONS_SECTION, \
+    INTERRUPTS_SECTION, \
+    TLB_SECTION, \
+    DEBUG_SECTION, \
+    CONFIG_SECTION
+
+
 #if XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI + 1 <= 2
 #define XCHAL_INTLEVEL2_VECTOR_VADDR 0
 #endif
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 2d2df33115..9f5895e021 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -98,12 +98,15 @@ typedef struct XtensaReg {
 
 #define XTENSA_REG(regname, opt) XTENSA_REG_ACCESS(regname, opt, SR_RWX)
 
-#define XTENSA_REG_BITS(regname, opt) { \
+#define XTENSA_REG_BITS_ACCESS(regname, opt, acc) { \
         .name = (regname), \
         .opt_bits = (opt), \
-        .access = SR_RWX, \
+        .access = (acc), \
     }
 
+#define XTENSA_REG_BITS(regname, opt) \
+    XTENSA_REG_BITS_ACCESS(regname, opt, SR_RWX)
+
 static const XtensaReg sregnames[256] = {
     [LBEG] = XTENSA_REG("LBEG", XTENSA_OPTION_LOOP),
     [LEND] = XTENSA_REG("LEND", XTENSA_OPTION_LOOP),
@@ -134,6 +137,7 @@ static const XtensaReg sregnames[256] = {
     [DBREAKA + 1] = XTENSA_REG("DBREAKA1", XTENSA_OPTION_DEBUG),
     [DBREAKC] = XTENSA_REG("DBREAKC0", XTENSA_OPTION_DEBUG),
     [DBREAKC + 1] = XTENSA_REG("DBREAKC1", XTENSA_OPTION_DEBUG),
+    [CONFIGID0] = XTENSA_REG_BITS_ACCESS("CONFIGID0", XTENSA_OPTION_ALL, SR_R),
     [EPC1] = XTENSA_REG("EPC1", XTENSA_OPTION_EXCEPTION),
     [EPC1 + 1] = XTENSA_REG("EPC2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
     [EPC1 + 2] = XTENSA_REG("EPC3", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
@@ -148,6 +152,7 @@ static const XtensaReg sregnames[256] = {
     [EPS2 + 3] = XTENSA_REG("EPS5", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
     [EPS2 + 4] = XTENSA_REG("EPS6", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
     [EPS2 + 5] = XTENSA_REG("EPS7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [CONFIGID1] = XTENSA_REG_BITS_ACCESS("CONFIGID1", XTENSA_OPTION_ALL, SR_R),
     [EXCSAVE1] = XTENSA_REG("EXCSAVE1", XTENSA_OPTION_EXCEPTION),
     [EXCSAVE1 + 1] = XTENSA_REG("EXCSAVE2",
             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
@@ -922,6 +927,15 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
 #define RRRN_S RRR_S
 #define RRRN_T RRR_T
 
+#define RRI4_R RRR_R
+#define RRI4_S RRR_S
+#define RRI4_T RRR_T
+#ifdef TARGET_WORDS_BIGENDIAN
+#define RRI4_IMM4 ((b2) & 0xf)
+#else
+#define RRI4_IMM4 (((b2) & 0xf0) >> 4)
+#endif
+
 #define RRI8_R RRR_R
 #define RRI8_S RRR_S
 #define RRI8_T RRR_T
@@ -2226,6 +2240,20 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
             gen_load_store(st32, 2);
             break;
 
+#define gen_dcache_hit_test(w, shift) do { \
+            TCGv_i32 addr = tcg_temp_new_i32(); \
+            TCGv_i32 res = tcg_temp_new_i32(); \
+            gen_window_check1(dc, RRI##w##_S); \
+            tcg_gen_addi_i32(addr, cpu_R[RRI##w##_S], \
+                             RRI##w##_IMM##w << shift); \
+            tcg_gen_qemu_ld8u(res, addr, dc->cring); \
+            tcg_temp_free(addr); \
+            tcg_temp_free(res); \
+        } while (0)
+
+#define gen_dcache_hit_test4() gen_dcache_hit_test(4, 4)
+#define gen_dcache_hit_test8() gen_dcache_hit_test(8, 2)
+
         case 7: /*CACHEc*/
             if (RRI8_T < 8) {
                 HAS_OPTION(XTENSA_OPTION_DCACHE);
@@ -2233,49 +2261,69 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
 
             switch (RRI8_T) {
             case 0: /*DPFRc*/
+                gen_window_check1(dc, RRI8_S);
                 break;
 
             case 1: /*DPFWc*/
+                gen_window_check1(dc, RRI8_S);
                 break;
 
             case 2: /*DPFROc*/
+                gen_window_check1(dc, RRI8_S);
                 break;
 
             case 3: /*DPFWOc*/
+                gen_window_check1(dc, RRI8_S);
                 break;
 
             case 4: /*DHWBc*/
+                gen_dcache_hit_test8();
                 break;
 
             case 5: /*DHWBIc*/
+                gen_dcache_hit_test8();
                 break;
 
             case 6: /*DHIc*/
+                gen_check_privilege(dc);
+                gen_dcache_hit_test8();
                 break;
 
             case 7: /*DIIc*/
+                gen_check_privilege(dc);
+                gen_window_check1(dc, RRI8_S);
                 break;
 
             case 8: /*DCEc*/
                 switch (OP1) {
                 case 0: /*DPFLl*/
                     HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
+                    gen_check_privilege(dc);
+                    gen_dcache_hit_test4();
                     break;
 
                 case 2: /*DHUl*/
                     HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
+                    gen_check_privilege(dc);
+                    gen_dcache_hit_test4();
                     break;
 
                 case 3: /*DIUl*/
                     HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
+                    gen_check_privilege(dc);
+                    gen_window_check1(dc, RRI4_S);
                     break;
 
                 case 4: /*DIWBc*/
                     HAS_OPTION(XTENSA_OPTION_DCACHE);
+                    gen_check_privilege(dc);
+                    gen_window_check1(dc, RRI4_S);
                     break;
 
                 case 5: /*DIWBIc*/
                     HAS_OPTION(XTENSA_OPTION_DCACHE);
+                    gen_check_privilege(dc);
+                    gen_window_check1(dc, RRI4_S);
                     break;
 
                 default: /*reserved*/
@@ -2285,22 +2333,46 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
                 }
                 break;
 
+#undef gen_dcache_hit_test
+#undef gen_dcache_hit_test4
+#undef gen_dcache_hit_test8
+
+#define gen_icache_hit_test(w, shift) do { \
+            TCGv_i32 addr = tcg_temp_new_i32(); \
+            gen_window_check1(dc, RRI##w##_S); \
+            tcg_gen_movi_i32(cpu_pc, dc->pc); \
+            tcg_gen_addi_i32(addr, cpu_R[RRI##w##_S], \
+                             RRI##w##_IMM##w << shift); \
+            gen_helper_itlb_hit_test(cpu_env, addr); \
+            tcg_temp_free(addr); \
+        } while (0)
+
+#define gen_icache_hit_test4() gen_icache_hit_test(4, 4)
+#define gen_icache_hit_test8() gen_icache_hit_test(8, 2)
+
             case 12: /*IPFc*/
                 HAS_OPTION(XTENSA_OPTION_ICACHE);
+                gen_window_check1(dc, RRI8_S);
                 break;
 
             case 13: /*ICEc*/
                 switch (OP1) {
                 case 0: /*IPFLl*/
                     HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
+                    gen_check_privilege(dc);
+                    gen_icache_hit_test4();
                     break;
 
                 case 2: /*IHUl*/
                     HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
+                    gen_check_privilege(dc);
+                    gen_icache_hit_test4();
                     break;
 
                 case 3: /*IIUl*/
                     HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
+                    gen_check_privilege(dc);
+                    gen_window_check1(dc, RRI4_S);
                     break;
 
                 default: /*reserved*/
@@ -2311,10 +2383,13 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
 
             case 14: /*IHIc*/
                 HAS_OPTION(XTENSA_OPTION_ICACHE);
+                gen_icache_hit_test8();
                 break;
 
             case 15: /*IIIc*/
                 HAS_OPTION(XTENSA_OPTION_ICACHE);
+                gen_check_privilege(dc);
+                gen_window_check1(dc, RRI8_S);
                 break;
 
             default: /*reserved*/
@@ -2323,6 +2398,10 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
             }
             break;
 
+#undef gen_icache_hit_test
+#undef gen_icache_hit_test4
+#undef gen_icache_hit_test8
+
         case 9: /*L16SI*/
             gen_load_store(ld16s, 1);
             break;
diff --git a/tests/tcg/xtensa/Makefile b/tests/tcg/xtensa/Makefile
index 1b519cae45..a70c92be7e 100644
--- a/tests/tcg/xtensa/Makefile
+++ b/tests/tcg/xtensa/Makefile
@@ -1,10 +1,11 @@
 -include ../../../config-host.mak
 
-CROSS=xtensa-dc232b-elf-
+CORE=dc232b
+CROSS=xtensa-$(CORE)-elf-
 
 ifndef XT
 SIM = ../../../xtensa-softmmu/qemu-system-xtensa
-SIMFLAGS = -M sim -cpu dc232b -nographic -semihosting $(EXTFLAGS) -kernel
+SIMFLAGS = -M sim -cpu $(CORE) -nographic -semihosting $(EXTFLAGS) -kernel
 SIMDEBUG = -s -S
 else
 SIM = xt-run
@@ -17,6 +18,8 @@ AS      = $(CROSS)gcc -x assembler-with-cpp
 LD      = $(CROSS)ld
 
 XTENSA_SRC_PATH = $(SRC_PATH)/tests/tcg/xtensa
+INCLUDE_DIRS = $(XTENSA_SRC_PATH) $(SRC_PATH)/target-xtensa/core-$(CORE)
+XTENSA_INC = $(addprefix -I,$(INCLUDE_DIRS))
 
 LDFLAGS = -T$(XTENSA_SRC_PATH)/linker.ld
 
@@ -27,6 +30,7 @@ TESTCASES += test_bi.tst
 #TESTCASES += test_boolean.tst
 TESTCASES += test_break.tst
 TESTCASES += test_bz.tst
+TESTCASES += test_cache.tst
 TESTCASES += test_clamps.tst
 TESTCASES += test_extui.tst
 TESTCASES += test_fail.tst
@@ -56,10 +60,10 @@ TESTCASES += test_windowed.tst
 all: build
 
 %.o: $(XTENSA_SRC_PATH)/%.c
-	$(CC) -I$(XTENSA_SRC_PATH) $(CFLAGS) -c $< -o $@
+	$(CC) $(XTENSA_INC) $(CFLAGS) -c $< -o $@
 
 %.o: $(XTENSA_SRC_PATH)/%.S
-	$(AS) -Wa,-I,$(XTENSA_SRC_PATH) $(ASFLAGS) -c $< -o $@
+	$(CC) $(XTENSA_INC) $(ASFLAGS) -c $< -o $@
 
 %.tst: %.o $(XTENSA_SRC_PATH)/macros.inc $(CRT) Makefile
 	$(LD) $(LDFLAGS) $(NOSTDFLAGS) $(CRT) $< -o $@
diff --git a/tests/tcg/xtensa/macros.inc b/tests/tcg/xtensa/macros.inc
index c9be1ce516..4ebd30ab86 100644
--- a/tests/tcg/xtensa/macros.inc
+++ b/tests/tcg/xtensa/macros.inc
@@ -1,3 +1,5 @@
+#include "core-isa.h"
+
 .macro test_suite name
 .data
 status: .word result
@@ -43,8 +45,12 @@ main:
     simcall
 .endm
 
+.macro test_init
+.endm
+
 .macro test name
     //print test_\name
+    test_init
 test_\name:
 .global test_\name
 .endm
diff --git a/tests/tcg/xtensa/test_b.S b/tests/tcg/xtensa/test_b.S
index 6cbe5f1fca..8e81f956df 100644
--- a/tests/tcg/xtensa/test_b.S
+++ b/tests/tcg/xtensa/test_b.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite b
 
diff --git a/tests/tcg/xtensa/test_bi.S b/tests/tcg/xtensa/test_bi.S
index 6a5f1dffc9..4f94c0c7e6 100644
--- a/tests/tcg/xtensa/test_bi.S
+++ b/tests/tcg/xtensa/test_bi.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite bi
 
diff --git a/tests/tcg/xtensa/test_boolean.S b/tests/tcg/xtensa/test_boolean.S
index 50e6d2c22a..eac40e0973 100644
--- a/tests/tcg/xtensa/test_boolean.S
+++ b/tests/tcg/xtensa/test_boolean.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite boolean
 
diff --git a/tests/tcg/xtensa/test_break.S b/tests/tcg/xtensa/test_break.S
index 7574cbefc8..775cd7c260 100644
--- a/tests/tcg/xtensa/test_break.S
+++ b/tests/tcg/xtensa/test_break.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 #define debug_level 6
 #define debug_vector level6
diff --git a/tests/tcg/xtensa/test_bz.S b/tests/tcg/xtensa/test_bz.S
index f9ba6e22e8..b68135011e 100644
--- a/tests/tcg/xtensa/test_bz.S
+++ b/tests/tcg/xtensa/test_bz.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite bz
 
diff --git a/tests/tcg/xtensa/test_cache.S b/tests/tcg/xtensa/test_cache.S
new file mode 100644
index 0000000000..6b2df9734b
--- /dev/null
+++ b/tests/tcg/xtensa/test_cache.S
@@ -0,0 +1,97 @@
+#include "macros.inc"
+
+.purgem test_init
+.macro test_init
+    call0   cache_unlock_invalidate
+.endm
+
+test_suite cache
+
+.macro      pf_op op
+    \op     a2, 0
+    \op     a3, 0
+    \op     a4, 0
+.endm
+
+test prefetch
+    movi    a2, 0xd0000000 /* cacheable */
+    movi    a3, 0xd8000000 /* non-cacheable */
+    movi    a4, 0x00001235 /* unmapped */
+
+    pf_op   dpfr
+    pf_op   dpfro
+    pf_op   dpfw
+    pf_op   dpfwo
+    pf_op   ipf
+
+    dpfl    a2, 0
+    ipfl    a2, 0
+test_end
+
+.macro cache_fault op, addr, exc_code
+    set_vector kernel, 2f
+
+    movi    a4, \addr
+1:
+    \op     a4, 0
+    test_fail
+2:
+    rsr     a2, epc1
+    movi    a3, 1b
+    assert  eq, a2, a3
+    rsr     a2, excvaddr
+    assert  eq, a2, a4
+    rsr     a2, exccause
+    movi    a3, \exc_code
+    assert  eq, a2, a3
+.endm
+
+test dpfl_tlb_miss
+    cache_fault dpfl, 0x00002345, 24
+test_end
+
+test dhwb_tlb_miss
+    cache_fault dhwb, 0x00002345, 24
+test_end
+
+test dhwbi_tlb_miss
+    cache_fault dhwbi, 0x00002345, 24
+test_end
+
+test dhi_tlb_miss
+    cache_fault dhi, 0x00002345, 24
+test_end
+
+test dhu_tlb_miss
+    cache_fault dhu, 0x00002345, 24
+test_end
+
+
+test ipfl_tlb_miss
+    cache_fault ipfl, 0x00002345, 16
+test_end
+
+test ihu_tlb_miss
+    cache_fault ihu, 0x00002345, 16
+test_end
+
+test ihi_tlb_miss
+    cache_fault ihi, 0x00002345, 16
+test_end
+
+test_suite_end
+
+.macro cache_all op1, op2, size, linesize
+    movi    a2, 0
+    movi    a3, \size
+1:
+    \op1    a2, 0
+    \op2    a2, 0
+    addi    a2, a2, \linesize
+    bltu    a2, a3, 1b
+.endm
+
+cache_unlock_invalidate:
+    cache_all diu, dii, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE
+    cache_all iiu, iii, XCHAL_ICACHE_SIZE, XCHAL_ICACHE_LINESIZE
+    ret
diff --git a/tests/tcg/xtensa/test_clamps.S b/tests/tcg/xtensa/test_clamps.S
index c186cc98d8..3efabfd9d3 100644
--- a/tests/tcg/xtensa/test_clamps.S
+++ b/tests/tcg/xtensa/test_clamps.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite clamps
 
diff --git a/tests/tcg/xtensa/test_extui.S b/tests/tcg/xtensa/test_extui.S
index 5d55451704..c32bb824df 100644
--- a/tests/tcg/xtensa/test_extui.S
+++ b/tests/tcg/xtensa/test_extui.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite extui
 
diff --git a/tests/tcg/xtensa/test_fail.S b/tests/tcg/xtensa/test_fail.S
index e8d1b425bc..1c26d50790 100644
--- a/tests/tcg/xtensa/test_fail.S
+++ b/tests/tcg/xtensa/test_fail.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite fail
 
diff --git a/tests/tcg/xtensa/test_interrupt.S b/tests/tcg/xtensa/test_interrupt.S
index 68b3ee1492..334ddab287 100644
--- a/tests/tcg/xtensa/test_interrupt.S
+++ b/tests/tcg/xtensa/test_interrupt.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite interrupt
 
diff --git a/tests/tcg/xtensa/test_loop.S b/tests/tcg/xtensa/test_loop.S
index 1c240e8e9b..5755578d01 100644
--- a/tests/tcg/xtensa/test_loop.S
+++ b/tests/tcg/xtensa/test_loop.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite loop
 
diff --git a/tests/tcg/xtensa/test_mac16.S b/tests/tcg/xtensa/test_mac16.S
index 5ddd160ffc..512025d842 100644
--- a/tests/tcg/xtensa/test_mac16.S
+++ b/tests/tcg/xtensa/test_mac16.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite mac16
 
diff --git a/tests/tcg/xtensa/test_max.S b/tests/tcg/xtensa/test_max.S
index 2534c9d90b..3caa207ea5 100644
--- a/tests/tcg/xtensa/test_max.S
+++ b/tests/tcg/xtensa/test_max.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite max
 
diff --git a/tests/tcg/xtensa/test_min.S b/tests/tcg/xtensa/test_min.S
index 6d9ddeb1ac..551cf591e5 100644
--- a/tests/tcg/xtensa/test_min.S
+++ b/tests/tcg/xtensa/test_min.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite min
 
diff --git a/tests/tcg/xtensa/test_mmu.S b/tests/tcg/xtensa/test_mmu.S
index 5d87fbb703..099031fd14 100644
--- a/tests/tcg/xtensa/test_mmu.S
+++ b/tests/tcg/xtensa/test_mmu.S
@@ -1,10 +1,10 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite mmu
 
-.purgem test
+.purgem test_init
 
-.macro test name
+.macro test_init
     movi    a2, 0x00000004
     idtlb   a2
     movi    a2, 0x00100004
diff --git a/tests/tcg/xtensa/test_mul16.S b/tests/tcg/xtensa/test_mul16.S
index bf94376649..98fa7042b5 100644
--- a/tests/tcg/xtensa/test_mul16.S
+++ b/tests/tcg/xtensa/test_mul16.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite mul16
 
diff --git a/tests/tcg/xtensa/test_mul32.S b/tests/tcg/xtensa/test_mul32.S
index fdaf57331b..b288ead9f6 100644
--- a/tests/tcg/xtensa/test_mul32.S
+++ b/tests/tcg/xtensa/test_mul32.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite mul32
 
diff --git a/tests/tcg/xtensa/test_nsa.S b/tests/tcg/xtensa/test_nsa.S
index a5fe5debe4..479b2e2429 100644
--- a/tests/tcg/xtensa/test_nsa.S
+++ b/tests/tcg/xtensa/test_nsa.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite nsa
 
diff --git a/tests/tcg/xtensa/test_pipeline.S b/tests/tcg/xtensa/test_pipeline.S
index 6be6085fc3..f418c11974 100644
--- a/tests/tcg/xtensa/test_pipeline.S
+++ b/tests/tcg/xtensa/test_pipeline.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 .purgem test
 .macro test name
diff --git a/tests/tcg/xtensa/test_quo.S b/tests/tcg/xtensa/test_quo.S
index 12debf1fe0..5b3ae383d0 100644
--- a/tests/tcg/xtensa/test_quo.S
+++ b/tests/tcg/xtensa/test_quo.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite quo
 
diff --git a/tests/tcg/xtensa/test_rem.S b/tests/tcg/xtensa/test_rem.S
index bb0d5fe202..6357e520d9 100644
--- a/tests/tcg/xtensa/test_rem.S
+++ b/tests/tcg/xtensa/test_rem.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite rem
 
diff --git a/tests/tcg/xtensa/test_rst0.S b/tests/tcg/xtensa/test_rst0.S
index 3eda565e8a..a73366b120 100644
--- a/tests/tcg/xtensa/test_rst0.S
+++ b/tests/tcg/xtensa/test_rst0.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite rst0
 
diff --git a/tests/tcg/xtensa/test_s32c1i.S b/tests/tcg/xtensa/test_s32c1i.S
index 4536015a84..93b575db95 100644
--- a/tests/tcg/xtensa/test_s32c1i.S
+++ b/tests/tcg/xtensa/test_s32c1i.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite s32c1i
 
diff --git a/tests/tcg/xtensa/test_sar.S b/tests/tcg/xtensa/test_sar.S
index 40c649ffb8..b615a55767 100644
--- a/tests/tcg/xtensa/test_sar.S
+++ b/tests/tcg/xtensa/test_sar.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite sar
 
diff --git a/tests/tcg/xtensa/test_sext.S b/tests/tcg/xtensa/test_sext.S
index 04dc6500c1..087a6333a4 100644
--- a/tests/tcg/xtensa/test_sext.S
+++ b/tests/tcg/xtensa/test_sext.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite sext
 
diff --git a/tests/tcg/xtensa/test_shift.S b/tests/tcg/xtensa/test_shift.S
index a8e43645b7..5df9ed4b1e 100644
--- a/tests/tcg/xtensa/test_shift.S
+++ b/tests/tcg/xtensa/test_shift.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite shift
 
diff --git a/tests/tcg/xtensa/test_sr.S b/tests/tcg/xtensa/test_sr.S
index 470c03dae2..4fac46e80f 100644
--- a/tests/tcg/xtensa/test_sr.S
+++ b/tests/tcg/xtensa/test_sr.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite sr
 
diff --git a/tests/tcg/xtensa/test_timer.S b/tests/tcg/xtensa/test_timer.S
index 1041cc6658..f8c6f7423a 100644
--- a/tests/tcg/xtensa/test_timer.S
+++ b/tests/tcg/xtensa/test_timer.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite timer
 
diff --git a/tests/tcg/xtensa/test_windowed.S b/tests/tcg/xtensa/test_windowed.S
index cb2d39e1fd..3de6d3763a 100644
--- a/tests/tcg/xtensa/test_windowed.S
+++ b/tests/tcg/xtensa/test_windowed.S
@@ -1,4 +1,4 @@
-.include "macros.inc"
+#include "macros.inc"
 
 test_suite windowed