aboutsummaryrefslogtreecommitdiff
path: root/target-microblaze
diff options
context:
space:
mode:
Diffstat (limited to 'target-microblaze')
-rw-r--r--target-microblaze/cpu.h12
-rw-r--r--target-microblaze/helper.h3
-rw-r--r--target-microblaze/microblaze-decode.h3
-rw-r--r--target-microblaze/op_helper.c41
-rw-r--r--target-microblaze/translate.c44
5 files changed, 95 insertions, 8 deletions
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index 14d4d42730..536222e4b8 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -79,6 +79,8 @@ struct CPUMBState;
#define ESR_DIZ (1<<11) /* Zone Protection */
#define ESR_S (1<<10) /* Store instruction */
+#define ESR_ESS_FSL_OFFSET 5
+
#define ESR_EC_FSL 0
#define ESR_EC_UNALIGNED_DATA 1
#define ESR_EC_ILLEGAL_OP 2
@@ -91,6 +93,7 @@ struct CPUMBState;
#define ESR_EC_INSN_STORAGE 9
#define ESR_EC_DATA_TLB 10
#define ESR_EC_INSN_TLB 11
+#define ESR_EC_MASK 31
/* Floating Point Status Register (FSR) Bits */
#define FSR_IO (1<<4) /* Invalid operation */
@@ -194,7 +197,7 @@ struct CPUMBState;
#define PVR11_MMU_ITLB_SIZE 0x38000000
#define PVR11_MMU_DTLB_SIZE 0x07000000
#define PVR11_MMU_TLB_ACCESS 0x00C00000
-#define PVR11_MMU_ZONES 0x003C0000
+#define PVR11_MMU_ZONES 0x003E0000
/* MSR Reset value PVR mask */
#define PVR11_MSR_RESET_VALUE_MASK 0x000007FF
@@ -211,6 +214,13 @@ struct CPUMBState;
#define CC_EQ 0
#define NB_MMU_MODES 3
+
+#define STREAM_EXCEPTION (1 << 0)
+#define STREAM_ATOMIC (1 << 1)
+#define STREAM_TEST (1 << 2)
+#define STREAM_CONTROL (1 << 3)
+#define STREAM_NONBLOCK (1 << 4)
+
typedef struct CPUMBState {
uint32_t debug;
uint32_t btaken;
diff --git a/target-microblaze/helper.h b/target-microblaze/helper.h
index 1696b885b6..b92aa34d05 100644
--- a/target-microblaze/helper.h
+++ b/target-microblaze/helper.h
@@ -33,4 +33,7 @@ DEF_HELPER_2(mmu_write, void, i32, i32)
DEF_HELPER_4(memalign, void, i32, i32, i32, i32)
+DEF_HELPER_2(get, i32, i32, i32)
+DEF_HELPER_3(put, void, i32, i32, i32)
+
#include "def-helper.h"
diff --git a/target-microblaze/microblaze-decode.h b/target-microblaze/microblaze-decode.h
index 4a274768d3..401319ed46 100644
--- a/target-microblaze/microblaze-decode.h
+++ b/target-microblaze/microblaze-decode.h
@@ -50,3 +50,6 @@
#define DEC_BR {B8(00100110), B8(00110111)}
#define DEC_BCC {B8(00100111), B8(00110111)}
#define DEC_RTS {B8(00101101), B8(00111111)}
+
+#define DEC_STREAM {B8(00010011), B8(00110111)}
+
diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
index d75a53cc54..c7b2f97d96 100644
--- a/target-microblaze/op_helper.c
+++ b/target-microblaze/op_helper.c
@@ -60,7 +60,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
if (tb) {
/* the PC is inside the translated code. It means that we have
a virtual CPU fault */
- cpu_restore_state(tb, env, pc, NULL);
+ cpu_restore_state(tb, env, pc);
}
}
cpu_loop_exit();
@@ -69,6 +69,41 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
}
#endif
+void helper_put(uint32_t id, uint32_t ctrl, uint32_t data)
+{
+ int test = ctrl & STREAM_TEST;
+ int atomic = ctrl & STREAM_ATOMIC;
+ int control = ctrl & STREAM_CONTROL;
+ int nonblock = ctrl & STREAM_NONBLOCK;
+ int exception = ctrl & STREAM_EXCEPTION;
+
+ qemu_log("Unhandled stream put to stream-id=%d data=%x %s%s%s%s%s\n",
+ id, data,
+ test ? "t" : "",
+ nonblock ? "n" : "",
+ exception ? "e" : "",
+ control ? "c" : "",
+ atomic ? "a" : "");
+}
+
+uint32_t helper_get(uint32_t id, uint32_t ctrl)
+{
+ int test = ctrl & STREAM_TEST;
+ int atomic = ctrl & STREAM_ATOMIC;
+ int control = ctrl & STREAM_CONTROL;
+ int nonblock = ctrl & STREAM_NONBLOCK;
+ int exception = ctrl & STREAM_EXCEPTION;
+
+ qemu_log("Unhandled stream get from stream-id=%d %s%s%s%s%s\n",
+ id,
+ test ? "t" : "",
+ nonblock ? "n" : "",
+ exception ? "e" : "",
+ control ? "c" : "",
+ atomic ? "a" : "");
+ return 0xdead0000 | id;
+}
+
void helper_raise_exception(uint32_t index)
{
env->exception_index = index;
@@ -303,7 +338,7 @@ uint32_t helper_fcmp_eq(uint32_t a, uint32_t b)
set_float_exception_flags(0, &env->fp_status);
fa.l = a;
fb.l = b;
- r = float32_eq(fa.f, fb.f, &env->fp_status);
+ r = float32_eq_quiet(fa.f, fb.f, &env->fp_status);
flags = get_float_exception_flags(&env->fp_status);
update_fpu_flags(flags & float_flag_invalid);
@@ -349,7 +384,7 @@ uint32_t helper_fcmp_ne(uint32_t a, uint32_t b)
fa.l = a;
fb.l = b;
set_float_exception_flags(0, &env->fp_status);
- r = !float32_eq(fa.f, fb.f, &env->fp_status);
+ r = !float32_eq_quiet(fa.f, fb.f, &env->fp_status);
flags = get_float_exception_flags(&env->fp_status);
update_fpu_flags(flags & float_flag_invalid);
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index fdb2b40df9..b47b92e909 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -146,7 +146,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
tcg_gen_goto_tb(n);
tcg_gen_movi_tl(cpu_SR[SR_PC], dest);
- tcg_gen_exit_tb((long)tb + n);
+ tcg_gen_exit_tb((tcg_target_long)tb + n);
} else {
tcg_gen_movi_tl(cpu_SR[SR_PC], dest);
tcg_gen_exit_tb(0);
@@ -923,7 +923,7 @@ static void dec_load(DisasContext *dc)
/*
* When doing reverse accesses we need to do two things.
*
- * 1. Reverse the address wrt endianess.
+ * 1. Reverse the address wrt endianness.
* 2. Byteswap the data lanes on the way back into the CPU core.
*/
if (rev && size != 4) {
@@ -1476,6 +1476,42 @@ static void dec_null(DisasContext *dc)
dc->abort_at_next_insn = 1;
}
+/* Insns connected to FSL or AXI stream attached devices. */
+static void dec_stream(DisasContext *dc)
+{
+ int mem_index = cpu_mmu_index(dc->env);
+ TCGv_i32 t_id, t_ctrl;
+ int ctrl;
+
+ LOG_DIS("%s%s imm=%x\n", dc->rd ? "get" : "put",
+ dc->type_b ? "" : "d", dc->imm);
+
+ if ((dc->tb_flags & MSR_EE_FLAG) && (mem_index == MMU_USER_IDX)) {
+ tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+ t_gen_raise_exception(dc, EXCP_HW_EXCP);
+ return;
+ }
+
+ t_id = tcg_temp_new();
+ if (dc->type_b) {
+ tcg_gen_movi_tl(t_id, dc->imm & 0xf);
+ ctrl = dc->imm >> 10;
+ } else {
+ tcg_gen_andi_tl(t_id, cpu_R[dc->rb], 0xf);
+ ctrl = dc->imm >> 5;
+ }
+
+ t_ctrl = tcg_const_tl(ctrl);
+
+ if (dc->rd == 0) {
+ gen_helper_put(t_id, t_ctrl, cpu_R[dc->ra]);
+ } else {
+ gen_helper_get(cpu_R[dc->rd], t_id, t_ctrl);
+ }
+ tcg_temp_free(t_id);
+ tcg_temp_free(t_ctrl);
+}
+
static struct decoder_info {
struct {
uint32_t bits;
@@ -1500,6 +1536,7 @@ static struct decoder_info {
{DEC_MUL, dec_mul},
{DEC_DIV, dec_div},
{DEC_MSR, dec_msr},
+ {DEC_STREAM, dec_stream},
{{0, 0}, dec_null}
};
@@ -1903,8 +1940,7 @@ void cpu_reset (CPUState *env)
#endif
}
-void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
- unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
{
env->sregs[SR_PC] = gen_opc_pc[pc_pos];
}