[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v4 19/32] target-xtensa: implement windowed regi
From: |
Blue Swirl |
Subject: |
Re: [Qemu-devel] [PATCH v4 19/32] target-xtensa: implement windowed registers |
Date: |
Sun, 4 Sep 2011 18:27:19 +0000 |
On Thu, Sep 1, 2011 at 8:45 PM, Max Filippov <address@hidden> wrote:
> See ISA, 4.7.1 for details.
>
> Physical registers and currently visible window are separate fields in
> CPUEnv. Only current window is accessible to TCG. On operations that
> change window base helpers copy current window to and from physical
> registers.
>
> Window overflow check described in 4.7.1.3 is in separate patch.
>
> Signed-off-by: Max Filippov <address@hidden>
> ---
> target-xtensa/cpu.h | 8 ++
> target-xtensa/helper.c | 1 +
> target-xtensa/helpers.h | 8 ++
> target-xtensa/op_helper.c | 185
> +++++++++++++++++++++++++++++++++++++++++++++
> target-xtensa/translate.c | 144 +++++++++++++++++++++++++++++++++--
> 5 files changed, 337 insertions(+), 9 deletions(-)
>
> diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
> index cae6637..7e662f5 100644
> --- a/target-xtensa/cpu.h
> +++ b/target-xtensa/cpu.h
> @@ -108,6 +108,8 @@ enum {
> enum {
> SAR = 3,
> SCOMPARE1 = 12,
> + WINDOW_BASE = 72,
> + WINDOW_START = 73,
> EPC1 = 177,
> DEPC = 192,
> EXCSAVE1 = 209,
> @@ -134,6 +136,8 @@ enum {
>
> #define PS_WOE 0x40000
>
> +#define MAX_NAREG 64
> +
> enum {
> /* Static vectors */
> EXC_RESET,
> @@ -185,6 +189,7 @@ enum {
> typedef struct XtensaConfig {
> const char *name;
> uint64_t options;
> + unsigned nareg;
> int excm_level;
> int ndepc;
> uint32_t exception_vector[EXC_MAX];
> @@ -196,6 +201,7 @@ typedef struct CPUXtensaState {
> uint32_t pc;
> uint32_t sregs[256];
> uint32_t uregs[256];
> + uint32_t phys_regs[MAX_NAREG];
>
> int exception_taken;
>
> @@ -214,6 +220,8 @@ int cpu_xtensa_exec(CPUXtensaState *s);
> void do_interrupt(CPUXtensaState *s);
> int cpu_xtensa_signal_handler(int host_signum, void *pinfo, void *puc);
> void xtensa_cpu_list(FILE *f, fprintf_function cpu_fprintf);
> +void xtensa_sync_window_from_phys(CPUState *env);
> +void xtensa_sync_phys_from_window(CPUState *env);
>
> #define XTENSA_OPTION_BIT(opt) (((uint64_t)1) << (opt))
>
> diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
> index 44ebb9f..4f86934 100644
> --- a/target-xtensa/helper.c
> +++ b/target-xtensa/helper.c
> @@ -45,6 +45,7 @@ static const XtensaConfig core_config[] = {
> {
> .name = "sample-xtensa-core",
> .options = -1,
> + .nareg = 64,
> .ndepc = 1,
> .excm_level = 16,
> .exception_vector = {
> diff --git a/target-xtensa/helpers.h b/target-xtensa/helpers.h
> index 6329c43..0971fde 100644
> --- a/target-xtensa/helpers.h
> +++ b/target-xtensa/helpers.h
> @@ -5,5 +5,13 @@ DEF_HELPER_2(exception_cause, void, i32, i32)
> DEF_HELPER_3(exception_cause_vaddr, void, i32, i32, i32)
> DEF_HELPER_1(nsa, i32, i32)
> DEF_HELPER_1(nsau, i32, i32)
> +DEF_HELPER_1(wsr_windowbase, void, i32)
> +DEF_HELPER_3(entry, void, i32, i32, i32)
> +DEF_HELPER_1(retw, i32, i32)
> +DEF_HELPER_1(rotw, void, i32)
> +DEF_HELPER_2(window_check, void, i32, i32)
> +DEF_HELPER_0(restore_owb, void)
> +DEF_HELPER_1(movsp, void, i32)
> +DEF_HELPER_0(dump_state, void)
>
> #include "def-helper.h"
> diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
> index 794a834..7f75422 100644
> --- a/target-xtensa/op_helper.c
> +++ b/target-xtensa/op_helper.c
> @@ -100,3 +100,188 @@ uint32_t HELPER(nsau)(uint32_t v)
> {
> return v ? clz32(v) : 32;
> }
> +
> +static void copy_window_from_phys(CPUState *env,
> + uint32_t window, uint32_t phys, uint32_t n)
> +{
> + assert(phys < env->config->nareg);
> + if (phys + n <= env->config->nareg) {
> + memcpy(env->regs + window, env->phys_regs + phys,
> + n * sizeof(uint32_t));
> + } else {
> + uint32_t n1 = env->config->nareg - phys;
> + memcpy(env->regs + window, env->phys_regs + phys,
> + n1 * sizeof(uint32_t));
> + memcpy(env->regs + window + n1, env->phys_regs,
> + (n - n1) * sizeof(uint32_t));
> + }
> +}
> +
> +static void copy_phys_from_window(CPUState *env,
> + uint32_t phys, uint32_t window, uint32_t n)
> +{
> + assert(phys < env->config->nareg);
> + if (phys + n <= env->config->nareg) {
> + memcpy(env->phys_regs + phys, env->regs + window,
> + n * sizeof(uint32_t));
> + } else {
> + uint32_t n1 = env->config->nareg - phys;
> + memcpy(env->phys_regs + phys, env->regs + window,
> + n1 * sizeof(uint32_t));
> + memcpy(env->phys_regs, env->regs + window + n1,
> + (n - n1) * sizeof(uint32_t));
> + }
> +}
> +
> +
> +#define WINDOWBASE_BOUND(a) ((a) & (env->config->nareg / 4 - 1))
> +#define WINDOW_BOUND(a) ((a) & (env->config->nareg - 1))
'env' could be a parameter to the macro, though inline functions are
preferred over macros these days.
> +#define WINDOWSTART_BIT(a) (1 << WINDOWBASE_BOUND(a))
> +
> +void xtensa_sync_window_from_phys(CPUState *env)
> +{
> + copy_window_from_phys(env, 0, env->sregs[WINDOW_BASE] * 4, 16);
> +}
> +
> +void xtensa_sync_phys_from_window(CPUState *env)
> +{
> + copy_phys_from_window(env, env->sregs[WINDOW_BASE] * 4, 0, 16);
> +}
> +
> +static void rotate_window_abs(uint32_t position)
> +{
> + xtensa_sync_phys_from_window(env);
> + env->sregs[WINDOW_BASE] = WINDOWBASE_BOUND(position);
> + xtensa_sync_window_from_phys(env);
> +}
> +
> +static void rotate_window(uint32_t delta)
> +{
> + rotate_window_abs(env->sregs[WINDOW_BASE] + delta);
> +}
> +
> +void HELPER(wsr_windowbase)(uint32_t v)
> +{
> + rotate_window_abs(v);
> +}
> +
> +void HELPER(entry)(uint32_t pc, uint32_t s, uint32_t imm)
> +{
> + int callinc = (env->sregs[PS] & PS_CALLINC) >> PS_CALLINC_SHIFT;
> + if (s > 3 || ((env->sregs[PS] & (PS_WOE | PS_EXCM)) ^ PS_WOE) != 0) {
> + qemu_log("Illegal entry instruction(pc = %08x), PS = %08x\n",
> + pc, env->sregs[PS]);
> + HELPER(exception_cause)(pc, ILLEGAL_INSTRUCTION_CAUSE);
> + } else {
> + env->regs[(callinc << 2) | (s & 3)] = env->regs[s] - (imm << 3);
> + rotate_window(callinc);
> + env->sregs[WINDOW_START] |= WINDOWSTART_BIT(env->sregs[WINDOW_BASE]);
> + }
> +}
> +
> +void HELPER(window_check)(uint32_t pc, uint32_t w)
> +{
> + uint32_t windowbase = WINDOWBASE_BOUND(env->sregs[WINDOW_BASE]);
> + uint32_t windowstart = env->sregs[WINDOW_START];
> + uint32_t m, n;
> +
> + if ((env->sregs[PS] & (PS_WOE | PS_EXCM)) ^ PS_WOE) {
> + return;
> + }
> +
> + for (n = 1; ; ++n) {
> + if (n > w) {
> + return;
> + }
> + if (windowstart & WINDOWSTART_BIT(windowbase + n)) {
> + break;
> + }
> + }
> +
> + m = WINDOWBASE_BOUND(windowbase + n);
> + rotate_window(n);
> + env->sregs[PS] = (env->sregs[PS] & ~PS_OWB) |
> + (windowbase << PS_OWB_SHIFT) | PS_EXCM;
> + env->sregs[EPC1] = env->pc = pc;
> +
> + if (windowstart & WINDOWSTART_BIT(m + 1)) {
> + HELPER(exception)(EXC_WINDOW_OVERFLOW4);
> + } else if (windowstart & WINDOWSTART_BIT(m + 2)) {
> + HELPER(exception)(EXC_WINDOW_OVERFLOW8);
> + } else {
> + HELPER(exception)(EXC_WINDOW_OVERFLOW12);
> + }
> +}
> +
> +uint32_t HELPER(retw)(uint32_t pc)
> +{
> + int n = (env->regs[0] >> 30) & 0x3;
> + int m = 0;
> + uint32_t windowbase = WINDOWBASE_BOUND(env->sregs[WINDOW_BASE]);
> + uint32_t windowstart = env->sregs[WINDOW_START];
> + uint32_t ret_pc = 0;
> +
> + if (windowstart & WINDOWSTART_BIT(windowbase - 1)) {
> + m = 1;
> + } else if (windowstart & WINDOWSTART_BIT(windowbase - 2)) {
> + m = 2;
> + } else if (windowstart & WINDOWSTART_BIT(windowbase - 3)) {
> + m = 3;
> + }
> +
> + if (n == 0 || (m != 0 && m != n) ||
> + ((env->sregs[PS] & (PS_WOE | PS_EXCM)) ^ PS_WOE) != 0) {
> + qemu_log("Illegal retw instruction(pc = %08x), "
> + "PS = %08x, m = %d, n = %d\n",
> + pc, env->sregs[PS], m, n);
> + HELPER(exception_cause)(pc, ILLEGAL_INSTRUCTION_CAUSE);
> + } else {
> + int owb = windowbase;
> +
> + ret_pc = (pc & 0xc0000000) | (env->regs[0] & 0x3fffffff);
> +
> + rotate_window(-n);
> + if (windowstart & WINDOWSTART_BIT(env->sregs[WINDOW_BASE])) {
> + env->sregs[WINDOW_START] &= ~WINDOWSTART_BIT(owb);
> + } else {
> + /* window underflow */
> + env->sregs[PS] = (env->sregs[PS] & ~PS_OWB) |
> + (windowbase << PS_OWB_SHIFT) | PS_EXCM;
> + env->sregs[EPC1] = env->pc = pc;
> +
> + if (n == 1) {
> + HELPER(exception)(EXC_WINDOW_UNDERFLOW4);
> + } else if (n == 2) {
> + HELPER(exception)(EXC_WINDOW_UNDERFLOW8);
> + } else if (n == 3) {
> + HELPER(exception)(EXC_WINDOW_UNDERFLOW12);
> + }
> + }
> + }
> + return ret_pc;
> +}
> +
> +void HELPER(rotw)(uint32_t imm4)
> +{
> + rotate_window(imm4);
> +}
> +
> +void HELPER(restore_owb)(void)
> +{
> + rotate_window_abs((env->sregs[PS] & PS_OWB) >> PS_OWB_SHIFT);
> +}
> +
> +void HELPER(movsp)(uint32_t pc)
> +{
> + if ((env->sregs[WINDOW_START] &
> + (WINDOWSTART_BIT(env->sregs[WINDOW_BASE] - 3) |
> + WINDOWSTART_BIT(env->sregs[WINDOW_BASE] - 2) |
> + WINDOWSTART_BIT(env->sregs[WINDOW_BASE] - 1))) == 0) {
> + HELPER(exception_cause)(pc, ALLOCA_CAUSE);
> + }
> +}
> +
> +void HELPER(dump_state)(void)
> +{
> + cpu_dump_state(env, stderr, fprintf, 0);
> +}
> diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
> index de5f947..de393ff 100644
> --- a/target-xtensa/translate.c
> +++ b/target-xtensa/translate.c
> @@ -67,6 +67,8 @@ static TCGv_i32 cpu_UR[256];
> static const char * const sregnames[256] = {
> [SAR] = "SAR",
> [SCOMPARE1] = "SCOMPARE1",
> + [WINDOW_BASE] = "WINDOW_BASE",
> + [WINDOW_START] = "WINDOW_START",
> [EPC1] = "EPC1",
> [DEPC] = "DEPC",
> [EXCSAVE1] = "EXCSAVE1",
> @@ -217,6 +219,34 @@ static void gen_jumpi(DisasContext *dc, uint32_t dest,
> int slot)
> tcg_temp_free(tmp);
> }
>
> +static void gen_callw_slot(DisasContext *dc, int _callinc, TCGv_i32 dest,
> + int slot)
> +{
> + TCGv_i32 callinc = tcg_const_i32(_callinc);
> +
> + tcg_gen_deposit_i32(cpu_SR[PS], cpu_SR[PS],
> + callinc, PS_CALLINC_SHIFT, PS_CALLINC_LEN);
> + tcg_temp_free(callinc);
> + tcg_gen_movi_i32(cpu_R[_callinc << 2],
> + (_callinc << 30) | (dc->next_pc & 0x3fffffff));
> + gen_jump_slot(dc, dest, slot);
> +}
> +
> +static void gen_callw(DisasContext *dc, int callinc, TCGv_i32 dest)
> +{
> + gen_callw_slot(dc, callinc, dest, -1);
> +}
> +
> +static void gen_callwi(DisasContext *dc, int callinc, uint32_t dest, int
> slot)
> +{
> + TCGv_i32 tmp = tcg_const_i32(dest);
> + if (((dc->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
> + slot = -1;
> + }
> + gen_callw_slot(dc, callinc, tmp, slot);
> + tcg_temp_free(tmp);
> +}
> +
> static void gen_brcond(DisasContext *dc, TCGCond cond,
> TCGv_i32 t0, TCGv_i32 t1, uint32_t offset)
> {
> @@ -263,6 +293,11 @@ static void gen_wsr_sar(DisasContext *dc, uint32_t sr,
> TCGv_i32 s)
> dc->sar_m32_5bit = false;
> }
>
> +static void gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v)
> +{
> + gen_helper_wsr_windowbase(v);
> +}
> +
> static void gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v)
> {
> uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB |
> @@ -281,6 +316,7 @@ static void gen_wsr(DisasContext *dc, uint32_t sr,
> TCGv_i32 s)
> static void (* const wsr_handler[256])(DisasContext *dc,
> uint32_t sr, TCGv_i32 v) = {
> [SAR] = gen_wsr_sar,
> + [WINDOW_BASE] = gen_wsr_windowbase,
> [PS] = gen_wsr_ps,
> };
>
> @@ -429,7 +465,12 @@ static void disas_xtensa_insn(DisasContext *dc)
>
> case 1: /*RETWw*/
> HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
> - TBD();
> + {
> + TCGv_i32 tmp = tcg_const_i32(dc->pc);
> + gen_helper_retw(tmp, tmp);
> + gen_jump(dc, tmp);
> + tcg_temp_free(tmp);
> + }
> break;
>
> case 3: /*reserved*/
> @@ -454,7 +495,13 @@ static void disas_xtensa_insn(DisasContext *dc)
> case 2: /*CALLX8w*/
> case 3: /*CALLX12w*/
> HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
> - TBD();
> + {
> + TCGv_i32 tmp = tcg_temp_new_i32();
> +
> + tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]);
> + gen_callw(dc, CALLX_N, tmp);
> + tcg_temp_free(tmp);
> + }
> break;
> }
> break;
> @@ -463,7 +510,12 @@ static void disas_xtensa_insn(DisasContext *dc)
>
> case 1: /*MOVSPw*/
> HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
> - TBD();
> + {
> + TCGv_i32 pc = tcg_const_i32(dc->pc);
> + gen_helper_movsp(pc);
> + tcg_gen_mov_i32(cpu_R[RRR_T], cpu_R[RRR_S]);
> + tcg_temp_free(pc);
> + }
> break;
>
> case 2: /*SYNC*/
> @@ -523,7 +575,27 @@ static void disas_xtensa_insn(DisasContext *dc)
> case 4: /*RFWOw*/
> case 5: /*RFWUw*/
> HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
> - TBD();
> + gen_check_privilege(dc);
> + {
> + TCGv_i32 tmp = tcg_const_i32(1);
> +
> + tcg_gen_andi_i32(
> + cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
> + tcg_gen_shl_i32(tmp, tmp,
> cpu_SR[WINDOW_BASE]);
> +
> + if (RRR_S == 4) {
> + tcg_gen_andc_i32(cpu_SR[WINDOW_START],
> + cpu_SR[WINDOW_START], tmp);
> + } else {
> + tcg_gen_or_i32(cpu_SR[WINDOW_START],
> + cpu_SR[WINDOW_START], tmp);
> + }
> +
> + gen_helper_restore_owb();
> + gen_jump(dc, cpu_SR[EPC1]);
> +
> + tcg_temp_free(tmp);
> + }
> break;
>
> default: /*reserved*/
> @@ -670,7 +742,13 @@ static void disas_xtensa_insn(DisasContext *dc)
>
> case 8: /*ROTWw*/
> HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
> - TBD();
> + gen_check_privilege(dc);
> + {
> + TCGv_i32 tmp = tcg_const_i32(
> + RRR_T | ((RRR_T & 8) ? 0xfffffff0 : 0));
> + gen_helper_rotw(tmp);
> + tcg_temp_free(tmp);
> + }
> break;
>
> case 14: /*NSAu*/
> @@ -1129,7 +1207,35 @@ static void disas_xtensa_insn(DisasContext *dc)
> break;
>
> case 9: /*LSC4*/
> - TBD();
> + switch (OP2) {
> + case 0: /*L32E*/
> + HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
> + gen_check_privilege(dc);
> + {
> + TCGv_i32 addr = tcg_temp_new_i32();
> + tcg_gen_addi_i32(addr, cpu_R[RRR_S],
> + (0xffffffc0 | (RRR_R << 2)));
> + tcg_gen_qemu_ld32u(cpu_R[RRR_T], addr, dc->ring);
> + tcg_temp_free(addr);
> + }
> + break;
> +
> + case 4: /*S32E*/
> + HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
> + gen_check_privilege(dc);
> + {
> + TCGv_i32 addr = tcg_temp_new_i32();
> + tcg_gen_addi_i32(addr, cpu_R[RRR_S],
> + (0xffffffc0 | (RRR_R << 2)));
> + tcg_gen_qemu_st32(cpu_R[RRR_T], addr, dc->ring);
> + tcg_temp_free(addr);
> + }
> + break;
> +
> + default:
> + RESERVED();
> + break;
> + }
> break;
>
> case 10: /*FP0*/
> @@ -1368,7 +1474,8 @@ static void disas_xtensa_insn(DisasContext *dc)
> case 2: /*CALL8w*/
> case 3: /*CALL12w*/
> HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
> - TBD();
> + gen_callwi(dc, CALL_N,
> + (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0);
> break;
> }
> break;
> @@ -1411,7 +1518,15 @@ static void disas_xtensa_insn(DisasContext *dc)
> switch (BRI8_M) {
> case 0: /*ENTRYw*/
> HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
> - TBD();
> + {
> + TCGv_i32 pc = tcg_const_i32(dc->pc);
> + TCGv_i32 s = tcg_const_i32(BRI12_S);
> + TCGv_i32 imm = tcg_const_i32(BRI12_IMM12);
> + gen_helper_entry(pc, s, imm);
> + tcg_temp_free(imm);
> + tcg_temp_free(s);
> + tcg_temp_free(pc);
> + }
> break;
>
> case 1: /*B1*/
> @@ -1576,7 +1691,12 @@ static void disas_xtensa_insn(DisasContext *dc)
>
> case 1: /*RETW.Nn*/
> HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
> - TBD();
> + {
> + TCGv_i32 tmp = tcg_const_i32(dc->pc);
> + gen_helper_retw(tmp, tmp);
> + gen_jump(dc, tmp);
> + tcg_temp_free(tmp);
> + }
> break;
>
> case 2: /*BREAK.Nn*/
> @@ -1747,6 +1867,12 @@ void cpu_dump_state(CPUState *env, FILE *f,
> fprintf_function cpu_fprintf,
> for (i = 0; i < 16; ++i)
> cpu_fprintf(f, "A%02d=%08x%c", i, env->regs[i],
> (i % 4) == 3 ? '\n' : ' ');
> +
> + cpu_fprintf(f, "\n");
> +
> + for (i = 0; i < env->config->nareg; ++i)
Braces.
> + cpu_fprintf(f, "AR%02d=%08x%c", i, env->phys_regs[i],
> + (i % 4) == 3 ? '\n' : ' ');
> }
>
> void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
> --
> 1.7.6
>
>
>
- [Qemu-devel] [PATCH v4 26/32] target-xtensa: implement CPENABLE and PRID SRs, (continued)
- [Qemu-devel] [PATCH v4 26/32] target-xtensa: implement CPENABLE and PRID SRs, Max Filippov, 2011/09/01
- [Qemu-devel] [PATCH v4 16/32] target-xtensa: add PS register and access control, Max Filippov, 2011/09/01
- [Qemu-devel] [PATCH v4 13/32] target-xtensa: mark reserved and TBD opcodes, Max Filippov, 2011/09/01
- [Qemu-devel] [PATCH v4 22/32] target-xtensa: implement unaligned exception option, Max Filippov, 2011/09/01
- [Qemu-devel] [PATCH v4 18/32] target-xtensa: implement RST2 group (32 bit mul/div/rem), Max Filippov, 2011/09/01
- [Qemu-devel] [PATCH v4 31/32] MAINTAINERS: add xtensa maintainer, Max Filippov, 2011/09/01
- [Qemu-devel] [PATCH v4 21/32] target-xtensa: implement extended L32R, Max Filippov, 2011/09/01
- [Qemu-devel] [PATCH v4 23/32] target-xtensa: implement SIMCALL, Max Filippov, 2011/09/01
- [Qemu-devel] [PATCH v4 19/32] target-xtensa: implement windowed registers, Max Filippov, 2011/09/01
- Re: [Qemu-devel] [PATCH v4 19/32] target-xtensa: implement windowed registers,
Blue Swirl <=
- [Qemu-devel] [PATCH v4 27/32] target-xtensa: implement relocatable vectors, Max Filippov, 2011/09/01
- [Qemu-devel] [PATCH v4 17/32] target-xtensa: implement exceptions, Max Filippov, 2011/09/01
- [Qemu-devel] [PATCH v4 25/32] target-xtensa: implement accurate window check, Max Filippov, 2011/09/01
- [Qemu-devel] [PATCH v4 29/32] target-xtensa: implement memory protection options, Max Filippov, 2011/09/01
- [Qemu-devel] [PATCH v4 32/32] target-xtensa: add regression testsuite, Max Filippov, 2011/09/01
- [Qemu-devel] [PATCH v4 24/32] target-xtensa: implement interrupt option, Max Filippov, 2011/09/01
- [Qemu-devel] [PATCH v4 30/32] target-xtensa: add dc232b core and board, Max Filippov, 2011/09/01