Openrisc Features and Fixes for qemu 2.10
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJZCnjJAAoJEMOzHC1eZifkjegP/ieGXCOfRQxLkr7SzWvigjWx HYUCqZ55Qt2nlirKV30Y7sSxuWnHKthgAvp/9/E/d1UGuFjvao9iia0Aet3elh4B bq8BM3LTBTnwknHc2tgHaNyP7VHsNZkCmMsESSEO6NexjnmXIoWxqbdAQ8FdYXpN evzz2pa1uTLju1gu7gDe3gIUBJjqiIOTmsjIkzIj7v9IqHOYKdGlJQSnZ+AHbQJn nRs+uqxN8sKaAILHmteXTEL1v1xhMJGKSY212m0OnUImlJrNgjAFGHKjSD4p8+6h /k4msQXCjdNo5NKu/0S3N8MKYaWTdcHohe4fnevV2fgdUpljLLm0RBNwP0wWi8Gp SZZ4GgeKGioCuqew1OdrhUNEQ+je3o4wdNYH243vVx3AIxXKS/EVIYhjNqDQLJ9M HGD+zcjcplpUlZ9dOXgWXK6yff2GUORPZJw8BLnDeRxjJA0xTefaK3qA5gWqJXrY HahUi0G4fJNZeROaBemcQ4+nPXfz55Ti4jp4Y3l5QqzvRidSZkdEoRfrnyMYP3/C 6RmR/iRQLjEGStKEqeqGMqhJ9Gn2aAkU+l+h4394fzS6CQulPOFZEkjobcAd2/5O lxXilhQOrAVlW8OIQzuGfIbuLdSFh55vurq8bwrMi8leeJ/AIbColun8PnO5E6Zd +1m4x+gT7IIv4QfMoerL =zXGN -----END PGP SIGNATURE----- Merge remote-tracking branch 'shorne/tags/pull-or-20170504' into staging Openrisc Features and Fixes for qemu 2.10 # gpg: Signature made Thu 04 May 2017 01:41:45 AM BST # gpg: using RSA key 0xC3B31C2D5E6627E4 # gpg: Good signature from "Stafford Horne <shorne@gmail.com>" # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: D9C4 7354 AEF8 6C10 3A25 EFF1 C3B3 1C2D 5E66 27E4 * shorne/tags/pull-or-20170504: target/openrisc: Support non-busy idle state using PMR SPR target/openrisc: Remove duplicate features property target/openrisc: Implement full vmstate serialization migration: Add VMSTATE_STRUCT_2DARRAY() target/openrisc: implement shadow registers migration: Add VMSTATE_UINTTL_2DARRAY() target/openrisc: add numcores and coreid support target/openrisc: Fixes for memory debugging target/openrisc: Implement EPH bit target/openrisc: Implement EVBAR register MAINTAINERS: Add myself as openrisc maintainer Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
		
						commit
						317134bb54
					
				| 
						 | 
					@ -196,8 +196,8 @@ F: hw/nios2/
 | 
				
			||||||
F: disas/nios2.c
 | 
					F: disas/nios2.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OpenRISC
 | 
					OpenRISC
 | 
				
			||||||
M: Jia Liu <proljc@gmail.com>
 | 
					M: Stafford Horne <shorne@gmail.com>
 | 
				
			||||||
S: Maintained
 | 
					S: Odd Fixes
 | 
				
			||||||
F: target/openrisc/
 | 
					F: target/openrisc/
 | 
				
			||||||
F: hw/openrisc/
 | 
					F: hw/openrisc/
 | 
				
			||||||
F: tests/tcg/openrisc/
 | 
					F: tests/tcg/openrisc/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,6 +61,7 @@ void cpu_openrisc_timer_update(OpenRISCCPU *cpu)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    next = now + (uint64_t)wait * TIMER_PERIOD;
 | 
					    next = now + (uint64_t)wait * TIMER_PERIOD;
 | 
				
			||||||
    timer_mod(cpu->env.timer, next);
 | 
					    timer_mod(cpu->env.timer, next);
 | 
				
			||||||
 | 
					    qemu_cpu_kick(CPU(cpu));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cpu_openrisc_count_start(OpenRISCCPU *cpu)
 | 
					void cpu_openrisc_count_start(OpenRISCCPU *cpu)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,8 @@
 | 
				
			||||||
    VMSTATE_UINT64_EQUAL_V(_f, _s, _v)
 | 
					    VMSTATE_UINT64_EQUAL_V(_f, _s, _v)
 | 
				
			||||||
#define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v)                        \
 | 
					#define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v)                        \
 | 
				
			||||||
    VMSTATE_UINT64_ARRAY_V(_f, _s, _n, _v)
 | 
					    VMSTATE_UINT64_ARRAY_V(_f, _s, _n, _v)
 | 
				
			||||||
 | 
					#define VMSTATE_UINTTL_2DARRAY_V(_f, _s, _n1, _n2, _v)                \
 | 
				
			||||||
 | 
					    VMSTATE_UINT64_2DARRAY_V(_f, _s, _n1, _n2, _v)
 | 
				
			||||||
#define VMSTATE_UINTTL_TEST(_f, _s, _t)                               \
 | 
					#define VMSTATE_UINTTL_TEST(_f, _s, _t)                               \
 | 
				
			||||||
    VMSTATE_UINT64_TEST(_f, _s, _t)
 | 
					    VMSTATE_UINT64_TEST(_f, _s, _t)
 | 
				
			||||||
#define vmstate_info_uinttl vmstate_info_uint64
 | 
					#define vmstate_info_uinttl vmstate_info_uint64
 | 
				
			||||||
| 
						 | 
					@ -37,6 +39,8 @@
 | 
				
			||||||
    VMSTATE_UINT32_EQUAL_V(_f, _s, _v)
 | 
					    VMSTATE_UINT32_EQUAL_V(_f, _s, _v)
 | 
				
			||||||
#define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v)                        \
 | 
					#define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v)                        \
 | 
				
			||||||
    VMSTATE_UINT32_ARRAY_V(_f, _s, _n, _v)
 | 
					    VMSTATE_UINT32_ARRAY_V(_f, _s, _n, _v)
 | 
				
			||||||
 | 
					#define VMSTATE_UINTTL_2DARRAY_V(_f, _s, _n1, _n2, _v)                \
 | 
				
			||||||
 | 
					    VMSTATE_UINT32_2DARRAY_V(_f, _s, _n1, _n2, _v)
 | 
				
			||||||
#define VMSTATE_UINTTL_TEST(_f, _s, _t)                               \
 | 
					#define VMSTATE_UINTTL_TEST(_f, _s, _t)                               \
 | 
				
			||||||
    VMSTATE_UINT32_TEST(_f, _s, _t)
 | 
					    VMSTATE_UINT32_TEST(_f, _s, _t)
 | 
				
			||||||
#define vmstate_info_uinttl vmstate_info_uint32
 | 
					#define vmstate_info_uinttl vmstate_info_uint32
 | 
				
			||||||
| 
						 | 
					@ -48,5 +52,8 @@
 | 
				
			||||||
    VMSTATE_UINTTL_EQUAL_V(_f, _s, 0)
 | 
					    VMSTATE_UINTTL_EQUAL_V(_f, _s, 0)
 | 
				
			||||||
#define VMSTATE_UINTTL_ARRAY(_f, _s, _n)                              \
 | 
					#define VMSTATE_UINTTL_ARRAY(_f, _s, _n)                              \
 | 
				
			||||||
    VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, 0)
 | 
					    VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, 0)
 | 
				
			||||||
 | 
					#define VMSTATE_UINTTL_2DARRAY(_f, _s, _n1, _n2)                      \
 | 
				
			||||||
 | 
					    VMSTATE_UINTTL_2DARRAY_V(_f, _s, _n1, _n2, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -500,6 +500,19 @@ extern const VMStateInfo vmstate_info_qtailq;
 | 
				
			||||||
    .offset       = vmstate_offset_array(_state, _field, _type, _num),\
 | 
					    .offset       = vmstate_offset_array(_state, _field, _type, _num),\
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VMSTATE_STRUCT_2DARRAY_TEST(_field, _state, _n1, _n2, _test, \
 | 
				
			||||||
 | 
					                                    _version, _vmsd, _type) {        \
 | 
				
			||||||
 | 
					    .name         = (stringify(_field)),                             \
 | 
				
			||||||
 | 
					    .num          = (_n1) * (_n2),                                   \
 | 
				
			||||||
 | 
					    .field_exists = (_test),                                         \
 | 
				
			||||||
 | 
					    .version_id   = (_version),                                      \
 | 
				
			||||||
 | 
					    .vmsd         = &(_vmsd),                                        \
 | 
				
			||||||
 | 
					    .size         = sizeof(_type),                                   \
 | 
				
			||||||
 | 
					    .flags        = VMS_STRUCT | VMS_ARRAY,                          \
 | 
				
			||||||
 | 
					    .offset       = vmstate_offset_2darray(_state, _field, _type,    \
 | 
				
			||||||
 | 
					                                           _n1, _n2),                \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define VMSTATE_STRUCT_VARRAY_UINT8(_field, _state, _field_num, _version, _vmsd, _type) { \
 | 
					#define VMSTATE_STRUCT_VARRAY_UINT8(_field, _state, _field_num, _version, _vmsd, _type) { \
 | 
				
			||||||
    .name       = (stringify(_field)),                               \
 | 
					    .name       = (stringify(_field)),                               \
 | 
				
			||||||
    .num_offset = vmstate_offset_value(_state, _field_num, uint8_t), \
 | 
					    .num_offset = vmstate_offset_value(_state, _field_num, uint8_t), \
 | 
				
			||||||
| 
						 | 
					@ -747,6 +760,11 @@ extern const VMStateInfo vmstate_info_qtailq;
 | 
				
			||||||
    VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, NULL, _version,   \
 | 
					    VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, NULL, _version,   \
 | 
				
			||||||
            _vmsd, _type)
 | 
					            _vmsd, _type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VMSTATE_STRUCT_2DARRAY(_field, _state, _n1, _n2, _version,    \
 | 
				
			||||||
 | 
					            _vmsd, _type)                                             \
 | 
				
			||||||
 | 
					    VMSTATE_STRUCT_2DARRAY_TEST(_field, _state, _n1, _n2, NULL,       \
 | 
				
			||||||
 | 
					            _version, _vmsd, _type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define VMSTATE_BUFFER_UNSAFE_INFO(_field, _state, _version, _info, _size) \
 | 
					#define VMSTATE_BUFFER_UNSAFE_INFO(_field, _state, _version, _info, _size) \
 | 
				
			||||||
    VMSTATE_BUFFER_UNSAFE_INFO_TEST(_field, _state, NULL, _version, _info, \
 | 
					    VMSTATE_BUFFER_UNSAFE_INFO_TEST(_field, _state, NULL, _version, _info, \
 | 
				
			||||||
            _size)
 | 
					            _size)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1052,7 +1052,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
 | 
				
			||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (i = 0; i < 32; i++) {
 | 
					    for (i = 0; i < 32; i++) {
 | 
				
			||||||
        (*regs)[i] = tswapreg(env->gpr[i]);
 | 
					        (*regs)[i] = tswapreg(cpu_get_gpr(env, i));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    (*regs)[32] = tswapreg(env->pc);
 | 
					    (*regs)[32] = tswapreg(env->pc);
 | 
				
			||||||
    (*regs)[33] = tswapreg(cpu_get_sr(env));
 | 
					    (*regs)[33] = tswapreg(cpu_get_sr(env));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2590,17 +2590,17 @@ void cpu_loop(CPUOpenRISCState *env)
 | 
				
			||||||
        case EXCP_SYSCALL:
 | 
					        case EXCP_SYSCALL:
 | 
				
			||||||
            env->pc += 4;   /* 0xc00; */
 | 
					            env->pc += 4;   /* 0xc00; */
 | 
				
			||||||
            ret = do_syscall(env,
 | 
					            ret = do_syscall(env,
 | 
				
			||||||
                             env->gpr[11], /* return value       */
 | 
					                             cpu_get_gpr(env, 11), /* return value       */
 | 
				
			||||||
                             env->gpr[3],  /* r3 - r7 are params */
 | 
					                             cpu_get_gpr(env, 3),  /* r3 - r7 are params */
 | 
				
			||||||
                             env->gpr[4],
 | 
					                             cpu_get_gpr(env, 4),
 | 
				
			||||||
                             env->gpr[5],
 | 
					                             cpu_get_gpr(env, 5),
 | 
				
			||||||
                             env->gpr[6],
 | 
					                             cpu_get_gpr(env, 6),
 | 
				
			||||||
                             env->gpr[7],
 | 
					                             cpu_get_gpr(env, 7),
 | 
				
			||||||
                             env->gpr[8], 0, 0);
 | 
					                             cpu_get_gpr(env, 8), 0, 0);
 | 
				
			||||||
            if (ret == -TARGET_ERESTARTSYS) {
 | 
					            if (ret == -TARGET_ERESTARTSYS) {
 | 
				
			||||||
                env->pc -= 4;
 | 
					                env->pc -= 4;
 | 
				
			||||||
            } else if (ret != -TARGET_QEMU_ESIGRETURN) {
 | 
					            } else if (ret != -TARGET_QEMU_ESIGRETURN) {
 | 
				
			||||||
                env->gpr[11] = ret;
 | 
					                cpu_set_gpr(env, 11, ret);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case EXCP_DPF:
 | 
					        case EXCP_DPF:
 | 
				
			||||||
| 
						 | 
					@ -4765,7 +4765,7 @@ int main(int argc, char **argv, char **envp)
 | 
				
			||||||
        int i;
 | 
					        int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (i = 0; i < 32; i++) {
 | 
					        for (i = 0; i < 32; i++) {
 | 
				
			||||||
            env->gpr[i] = regs->gpr[i];
 | 
					            cpu_set_gpr(env, i, regs->gpr[i]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        env->pc = regs->pc;
 | 
					        env->pc = regs->pc;
 | 
				
			||||||
        cpu_set_sr(env, regs->sr);
 | 
					        cpu_set_sr(env, regs->sr);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,14 +23,14 @@
 | 
				
			||||||
static inline void cpu_clone_regs(CPUOpenRISCState *env, target_ulong newsp)
 | 
					static inline void cpu_clone_regs(CPUOpenRISCState *env, target_ulong newsp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (newsp) {
 | 
					    if (newsp) {
 | 
				
			||||||
        env->gpr[1] = newsp;
 | 
					        cpu_set_gpr(env, 1, newsp);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    env->gpr[11] = 0;
 | 
					    cpu_set_gpr(env, 11, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void cpu_set_tls(CPUOpenRISCState *env, target_ulong newtls)
 | 
					static inline void cpu_set_tls(CPUOpenRISCState *env, target_ulong newtls)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    env->gpr[10] = newtls;
 | 
					    cpu_set_gpr(env, 10, newtls);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,7 +20,7 @@ typedef struct target_sigaltstack {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline abi_ulong get_sp_from_cpustate(CPUOpenRISCState *state)
 | 
					static inline abi_ulong get_sp_from_cpustate(CPUOpenRISCState *state)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return state->gpr[1];
 | 
					    return cpu_get_gpr(state, 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4411,7 +4411,7 @@ static void setup_sigcontext(struct target_sigcontext *sc,
 | 
				
			||||||
                             CPUOpenRISCState *regs,
 | 
					                             CPUOpenRISCState *regs,
 | 
				
			||||||
                             unsigned long mask)
 | 
					                             unsigned long mask)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    unsigned long usp = regs->gpr[1];
 | 
					    unsigned long usp = cpu_get_gpr(regs, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* copy the regs. they are first in sc so we can use sc directly */
 | 
					    /* copy the regs. they are first in sc so we can use sc directly */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4436,7 +4436,7 @@ static inline abi_ulong get_sigframe(struct target_sigaction *ka,
 | 
				
			||||||
                                     CPUOpenRISCState *regs,
 | 
					                                     CPUOpenRISCState *regs,
 | 
				
			||||||
                                     size_t frame_size)
 | 
					                                     size_t frame_size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    unsigned long sp = regs->gpr[1];
 | 
					    unsigned long sp = cpu_get_gpr(regs, 1);
 | 
				
			||||||
    int onsigstack = on_sig_stack(sp);
 | 
					    int onsigstack = on_sig_stack(sp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* redzone */
 | 
					    /* redzone */
 | 
				
			||||||
| 
						 | 
					@ -4489,7 +4489,8 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
 | 
				
			||||||
    __put_user(0, &frame->uc.tuc_link);
 | 
					    __put_user(0, &frame->uc.tuc_link);
 | 
				
			||||||
    __put_user(target_sigaltstack_used.ss_sp,
 | 
					    __put_user(target_sigaltstack_used.ss_sp,
 | 
				
			||||||
               &frame->uc.tuc_stack.ss_sp);
 | 
					               &frame->uc.tuc_stack.ss_sp);
 | 
				
			||||||
    __put_user(sas_ss_flags(env->gpr[1]), &frame->uc.tuc_stack.ss_flags);
 | 
					    __put_user(sas_ss_flags(cpu_get_gpr(env, 1)),
 | 
				
			||||||
 | 
					               &frame->uc.tuc_stack.ss_flags);
 | 
				
			||||||
    __put_user(target_sigaltstack_used.ss_size,
 | 
					    __put_user(target_sigaltstack_used.ss_size,
 | 
				
			||||||
               &frame->uc.tuc_stack.ss_size);
 | 
					               &frame->uc.tuc_stack.ss_size);
 | 
				
			||||||
    setup_sigcontext(&frame->sc, env, set->sig[0]);
 | 
					    setup_sigcontext(&frame->sc, env, set->sig[0]);
 | 
				
			||||||
| 
						 | 
					@ -4512,13 +4513,13 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Set up registers for signal handler */
 | 
					    /* Set up registers for signal handler */
 | 
				
			||||||
    env->pc = (unsigned long)ka->_sa_handler; /* what we enter NOW */
 | 
					    env->pc = (unsigned long)ka->_sa_handler; /* what we enter NOW */
 | 
				
			||||||
    env->gpr[9] = (unsigned long)return_ip;     /* what we enter LATER */
 | 
					    cpu_set_gpr(env, 9, (unsigned long)return_ip);     /* what we enter LATER */
 | 
				
			||||||
    env->gpr[3] = (unsigned long)sig;           /* arg 1: signo */
 | 
					    cpu_set_gpr(env, 3, (unsigned long)sig);           /* arg 1: signo */
 | 
				
			||||||
    env->gpr[4] = (unsigned long)&frame->info;  /* arg 2: (siginfo_t*) */
 | 
					    cpu_set_gpr(env, 4, (unsigned long)&frame->info);  /* arg 2: (siginfo_t*) */
 | 
				
			||||||
    env->gpr[5] = (unsigned long)&frame->uc;    /* arg 3: ucontext */
 | 
					    cpu_set_gpr(env, 5, (unsigned long)&frame->uc);    /* arg 3: ucontext */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* actually move the usp to reflect the stacked frame */
 | 
					    /* actually move the usp to reflect the stacked frame */
 | 
				
			||||||
    env->gpr[1] = (unsigned long)frame;
 | 
					    cpu_set_gpr(env, 1, (unsigned long)frame);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,8 +51,8 @@ static void openrisc_cpu_reset(CPUState *s)
 | 
				
			||||||
    cpu->env.lock_addr = -1;
 | 
					    cpu->env.lock_addr = -1;
 | 
				
			||||||
    s->exception_index = -1;
 | 
					    s->exception_index = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP;
 | 
					    cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP |
 | 
				
			||||||
    cpu->env.cpucfgr = CPUCFGR_OB32S | CPUCFGR_OF32S;
 | 
					                   UPR_PMP;
 | 
				
			||||||
    cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 << 2)) | (DMMUCFGR_NTS & (6 << 2));
 | 
					    cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 << 2)) | (DMMUCFGR_NTS & (6 << 2));
 | 
				
			||||||
    cpu->env.immucfgr = (IMMUCFGR_NTW & (0 << 2)) | (IMMUCFGR_NTS & (6 << 2));
 | 
					    cpu->env.immucfgr = (IMMUCFGR_NTW & (0 << 2)) | (IMMUCFGR_NTS & (6 << 2));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,12 +65,6 @@ static void openrisc_cpu_reset(CPUState *s)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void set_feature(OpenRISCCPU *cpu, int feature)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    cpu->feature |= feature;
 | 
					 | 
				
			||||||
    cpu->env.cpucfgr = cpu->feature;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void openrisc_cpu_realizefn(DeviceState *dev, Error **errp)
 | 
					static void openrisc_cpu_realizefn(DeviceState *dev, Error **errp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    CPUState *cs = CPU(dev);
 | 
					    CPUState *cs = CPU(dev);
 | 
				
			||||||
| 
						 | 
					@ -132,15 +126,15 @@ static void or1200_initfn(Object *obj)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    OpenRISCCPU *cpu = OPENRISC_CPU(obj);
 | 
					    OpenRISCCPU *cpu = OPENRISC_CPU(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    set_feature(cpu, OPENRISC_FEATURE_OB32S);
 | 
					    cpu->env.cpucfgr = CPUCFGR_NSGF | CPUCFGR_OB32S | CPUCFGR_OF32S |
 | 
				
			||||||
    set_feature(cpu, OPENRISC_FEATURE_OF32S);
 | 
					                       CPUCFGR_EVBARP;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void openrisc_any_initfn(Object *obj)
 | 
					static void openrisc_any_initfn(Object *obj)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    OpenRISCCPU *cpu = OPENRISC_CPU(obj);
 | 
					    OpenRISCCPU *cpu = OPENRISC_CPU(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    set_feature(cpu, OPENRISC_FEATURE_OB32S);
 | 
					    cpu->env.cpucfgr = CPUCFGR_NSGF | CPUCFGR_OB32S | CPUCFGR_EVBARP;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct OpenRISCCPUInfo {
 | 
					typedef struct OpenRISCCPUInfo {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,6 +111,11 @@ enum {
 | 
				
			||||||
    CPUCFGR_OF32S = (1 << 7),
 | 
					    CPUCFGR_OF32S = (1 << 7),
 | 
				
			||||||
    CPUCFGR_OF64S = (1 << 8),
 | 
					    CPUCFGR_OF64S = (1 << 8),
 | 
				
			||||||
    CPUCFGR_OV64S = (1 << 9),
 | 
					    CPUCFGR_OV64S = (1 << 9),
 | 
				
			||||||
 | 
					    /* CPUCFGR_ND = (1 << 10), */
 | 
				
			||||||
 | 
					    /* CPUCFGR_AVRP = (1 << 11), */
 | 
				
			||||||
 | 
					    CPUCFGR_EVBARP = (1 << 12),
 | 
				
			||||||
 | 
					    /* CPUCFGR_ISRP = (1 << 13), */
 | 
				
			||||||
 | 
					    /* CPUCFGR_AECSRP = (1 << 14), */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* DMMU configure register */
 | 
					/* DMMU configure register */
 | 
				
			||||||
| 
						 | 
					@ -135,6 +140,15 @@ enum {
 | 
				
			||||||
    IMMUCFGR_HTR = (1 << 11),
 | 
					    IMMUCFGR_HTR = (1 << 11),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Power management register */
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    PMR_SDF = (15 << 0),
 | 
				
			||||||
 | 
					    PMR_DME = (1 << 4),
 | 
				
			||||||
 | 
					    PMR_SME = (1 << 5),
 | 
				
			||||||
 | 
					    PMR_DCGE = (1 << 6),
 | 
				
			||||||
 | 
					    PMR_SUME = (1 << 7),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Float point control status register */
 | 
					/* Float point control status register */
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
    FPCSR_FPEE = 1,
 | 
					    FPCSR_FPEE = 1,
 | 
				
			||||||
| 
						 | 
					@ -191,17 +205,6 @@ enum {
 | 
				
			||||||
    SR_SCE = (1 << 17),
 | 
					    SR_SCE = (1 << 17),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* OpenRISC Hardware Capabilities */
 | 
					 | 
				
			||||||
enum {
 | 
					 | 
				
			||||||
    OPENRISC_FEATURE_NSGF = (15 << 0),
 | 
					 | 
				
			||||||
    OPENRISC_FEATURE_CGF = (1 << 4),
 | 
					 | 
				
			||||||
    OPENRISC_FEATURE_OB32S = (1 << 5),
 | 
					 | 
				
			||||||
    OPENRISC_FEATURE_OB64S = (1 << 6),
 | 
					 | 
				
			||||||
    OPENRISC_FEATURE_OF32S = (1 << 7),
 | 
					 | 
				
			||||||
    OPENRISC_FEATURE_OF64S = (1 << 8),
 | 
					 | 
				
			||||||
    OPENRISC_FEATURE_OV64S = (1 << 9),
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Tick Timer Mode Register */
 | 
					/* Tick Timer Mode Register */
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
    TTMR_TP = (0xfffffff),
 | 
					    TTMR_TP = (0xfffffff),
 | 
				
			||||||
| 
						 | 
					@ -269,7 +272,8 @@ typedef struct CPUOpenRISCTLBContext {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct CPUOpenRISCState {
 | 
					typedef struct CPUOpenRISCState {
 | 
				
			||||||
    target_ulong gpr[32];     /* General registers */
 | 
					    target_ulong shadow_gpr[16][32]; /* Shadow registers */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    target_ulong pc;          /* Program counter */
 | 
					    target_ulong pc;          /* Program counter */
 | 
				
			||||||
    target_ulong ppc;         /* Prev PC */
 | 
					    target_ulong ppc;         /* Prev PC */
 | 
				
			||||||
    target_ulong jmp_pc;      /* Jump PC */
 | 
					    target_ulong jmp_pc;      /* Jump PC */
 | 
				
			||||||
| 
						 | 
					@ -285,10 +289,11 @@ typedef struct CPUOpenRISCState {
 | 
				
			||||||
    uint32_t sr;              /* Supervisor register, without SR_{F,CY,OV} */
 | 
					    uint32_t sr;              /* Supervisor register, without SR_{F,CY,OV} */
 | 
				
			||||||
    uint32_t vr;              /* Version register */
 | 
					    uint32_t vr;              /* Version register */
 | 
				
			||||||
    uint32_t upr;             /* Unit presence register */
 | 
					    uint32_t upr;             /* Unit presence register */
 | 
				
			||||||
    uint32_t cpucfgr;         /* CPU configure register */
 | 
					 | 
				
			||||||
    uint32_t dmmucfgr;        /* DMMU configure register */
 | 
					    uint32_t dmmucfgr;        /* DMMU configure register */
 | 
				
			||||||
    uint32_t immucfgr;        /* IMMU configure register */
 | 
					    uint32_t immucfgr;        /* IMMU configure register */
 | 
				
			||||||
    uint32_t esr;             /* Exception supervisor register */
 | 
					    uint32_t esr;             /* Exception supervisor register */
 | 
				
			||||||
 | 
					    uint32_t evbar;           /* Exception vector base address register */
 | 
				
			||||||
 | 
					    uint32_t pmr;             /* Power Management Register */
 | 
				
			||||||
    uint32_t fpcsr;           /* Float register */
 | 
					    uint32_t fpcsr;           /* Float register */
 | 
				
			||||||
    float_status fp_status;
 | 
					    float_status fp_status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -303,6 +308,8 @@ typedef struct CPUOpenRISCState {
 | 
				
			||||||
    CPU_COMMON
 | 
					    CPU_COMMON
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Fields from here on are preserved across CPU reset. */
 | 
					    /* Fields from here on are preserved across CPU reset. */
 | 
				
			||||||
 | 
					    uint32_t cpucfgr;         /* CPU configure register */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef CONFIG_USER_ONLY
 | 
					#ifndef CONFIG_USER_ONLY
 | 
				
			||||||
    CPUOpenRISCTLBContext * tlb;
 | 
					    CPUOpenRISCTLBContext * tlb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -329,7 +336,6 @@ typedef struct OpenRISCCPU {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CPUOpenRISCState env;
 | 
					    CPUOpenRISCState env;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uint32_t feature;       /* CPU Capabilities */
 | 
					 | 
				
			||||||
} OpenRISCCPU;
 | 
					} OpenRISCCPU;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline OpenRISCCPU *openrisc_env_get_cpu(CPUOpenRISCState *env)
 | 
					static inline OpenRISCCPU *openrisc_env_get_cpu(CPUOpenRISCState *env)
 | 
				
			||||||
| 
						 | 
					@ -392,6 +398,16 @@ int cpu_openrisc_get_phys_data(OpenRISCCPU *cpu,
 | 
				
			||||||
#define TB_FLAGS_R0_0  2
 | 
					#define TB_FLAGS_R0_0  2
 | 
				
			||||||
#define TB_FLAGS_OVE   SR_OVE
 | 
					#define TB_FLAGS_OVE   SR_OVE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t cpu_get_gpr(const CPUOpenRISCState *env, int i)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return env->shadow_gpr[0][i];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void cpu_set_gpr(CPUOpenRISCState *env, int i, uint32_t val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    env->shadow_gpr[0][i] = val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
 | 
					static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
 | 
				
			||||||
                                        target_ulong *pc,
 | 
					                                        target_ulong *pc,
 | 
				
			||||||
                                        target_ulong *cs_base, uint32_t *flags)
 | 
					                                        target_ulong *cs_base, uint32_t *flags)
 | 
				
			||||||
| 
						 | 
					@ -399,7 +415,7 @@ static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
 | 
				
			||||||
    *pc = env->pc;
 | 
					    *pc = env->pc;
 | 
				
			||||||
    *cs_base = 0;
 | 
					    *cs_base = 0;
 | 
				
			||||||
    *flags = (env->dflag
 | 
					    *flags = (env->dflag
 | 
				
			||||||
              | (env->gpr[0] == 0 ? TB_FLAGS_R0_0 : 0)
 | 
					              | (cpu_get_gpr(env, 0) == 0 ? TB_FLAGS_R0_0 : 0)
 | 
				
			||||||
              | (env->sr & SR_OVE));
 | 
					              | (env->sr & SR_OVE));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,7 @@ int openrisc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
 | 
				
			||||||
    CPUOpenRISCState *env = &cpu->env;
 | 
					    CPUOpenRISCState *env = &cpu->env;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (n < 32) {
 | 
					    if (n < 32) {
 | 
				
			||||||
        return gdb_get_reg32(mem_buf, env->gpr[n]);
 | 
					        return gdb_get_reg32(mem_buf, cpu_get_gpr(env, n));
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        switch (n) {
 | 
					        switch (n) {
 | 
				
			||||||
        case 32:    /* PPC */
 | 
					        case 32:    /* PPC */
 | 
				
			||||||
| 
						 | 
					@ -61,7 +61,7 @@ int openrisc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
 | 
				
			||||||
    tmp = ldl_p(mem_buf);
 | 
					    tmp = ldl_p(mem_buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (n < 32) {
 | 
					    if (n < 32) {
 | 
				
			||||||
        env->gpr[n] = tmp;
 | 
					        cpu_set_gpr(env, n, tmp);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        switch (n) {
 | 
					        switch (n) {
 | 
				
			||||||
        case 32: /* PPC */
 | 
					        case 32: /* PPC */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,12 +60,21 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
 | 
				
			||||||
    env->sr |= SR_SM;
 | 
					    env->sr |= SR_SM;
 | 
				
			||||||
    env->sr &= ~SR_IEE;
 | 
					    env->sr &= ~SR_IEE;
 | 
				
			||||||
    env->sr &= ~SR_TEE;
 | 
					    env->sr &= ~SR_TEE;
 | 
				
			||||||
 | 
					    env->pmr &= ~PMR_DME;
 | 
				
			||||||
 | 
					    env->pmr &= ~PMR_SME;
 | 
				
			||||||
    env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
 | 
					    env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
 | 
				
			||||||
    env->tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;
 | 
					    env->tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;
 | 
				
			||||||
    env->lock_addr = -1;
 | 
					    env->lock_addr = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (cs->exception_index > 0 && cs->exception_index < EXCP_NR) {
 | 
					    if (cs->exception_index > 0 && cs->exception_index < EXCP_NR) {
 | 
				
			||||||
        env->pc = (cs->exception_index << 8);
 | 
					        hwaddr vect_pc = cs->exception_index << 8;
 | 
				
			||||||
 | 
					        if (env->cpucfgr & CPUCFGR_EVBARP) {
 | 
				
			||||||
 | 
					            vect_pc |= env->evbar;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (env->sr & SR_EPH) {
 | 
				
			||||||
 | 
					            vect_pc |= 0xf0000000;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        env->pc = vect_pc;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
 | 
					        cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,6 +24,63 @@
 | 
				
			||||||
#include "hw/boards.h"
 | 
					#include "hw/boards.h"
 | 
				
			||||||
#include "migration/cpu.h"
 | 
					#include "migration/cpu.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int env_post_load(void *opaque, int version_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    CPUOpenRISCState *env = opaque;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Restore MMU handlers */
 | 
				
			||||||
 | 
					    if (env->sr & SR_DME) {
 | 
				
			||||||
 | 
					        env->tlb->cpu_openrisc_map_address_data =
 | 
				
			||||||
 | 
					            &cpu_openrisc_get_phys_data;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        env->tlb->cpu_openrisc_map_address_data =
 | 
				
			||||||
 | 
					            &cpu_openrisc_get_phys_nommu;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (env->sr & SR_IME) {
 | 
				
			||||||
 | 
					        env->tlb->cpu_openrisc_map_address_code =
 | 
				
			||||||
 | 
					            &cpu_openrisc_get_phys_code;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        env->tlb->cpu_openrisc_map_address_code =
 | 
				
			||||||
 | 
					            &cpu_openrisc_get_phys_nommu;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const VMStateDescription vmstate_tlb_entry = {
 | 
				
			||||||
 | 
					    .name = "tlb_entry",
 | 
				
			||||||
 | 
					    .version_id = 1,
 | 
				
			||||||
 | 
					    .minimum_version_id = 1,
 | 
				
			||||||
 | 
					    .minimum_version_id_old = 1,
 | 
				
			||||||
 | 
					    .fields = (VMStateField[]) {
 | 
				
			||||||
 | 
					        VMSTATE_UINTTL(mr, OpenRISCTLBEntry),
 | 
				
			||||||
 | 
					        VMSTATE_UINTTL(tr, OpenRISCTLBEntry),
 | 
				
			||||||
 | 
					        VMSTATE_END_OF_LIST()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const VMStateDescription vmstate_cpu_tlb = {
 | 
				
			||||||
 | 
					    .name = "cpu_tlb",
 | 
				
			||||||
 | 
					    .version_id = 1,
 | 
				
			||||||
 | 
					    .minimum_version_id = 1,
 | 
				
			||||||
 | 
					    .minimum_version_id_old = 1,
 | 
				
			||||||
 | 
					    .fields = (VMStateField[]) {
 | 
				
			||||||
 | 
					        VMSTATE_STRUCT_2DARRAY(itlb, CPUOpenRISCTLBContext,
 | 
				
			||||||
 | 
					                             ITLB_WAYS, ITLB_SIZE, 0,
 | 
				
			||||||
 | 
					                             vmstate_tlb_entry, OpenRISCTLBEntry),
 | 
				
			||||||
 | 
					        VMSTATE_STRUCT_2DARRAY(dtlb, CPUOpenRISCTLBContext,
 | 
				
			||||||
 | 
					                             DTLB_WAYS, DTLB_SIZE, 0,
 | 
				
			||||||
 | 
					                             vmstate_tlb_entry, OpenRISCTLBEntry),
 | 
				
			||||||
 | 
					        VMSTATE_END_OF_LIST()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VMSTATE_CPU_TLB(_f, _s)                             \
 | 
				
			||||||
 | 
					    VMSTATE_STRUCT_POINTER(_f, _s, vmstate_cpu_tlb, CPUOpenRISCTLBContext)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int get_sr(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
 | 
					static int get_sr(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    CPUOpenRISCState *env = opaque;
 | 
					    CPUOpenRISCState *env = opaque;
 | 
				
			||||||
| 
						 | 
					@ -47,10 +104,11 @@ static const VMStateInfo vmstate_sr = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const VMStateDescription vmstate_env = {
 | 
					static const VMStateDescription vmstate_env = {
 | 
				
			||||||
    .name = "env",
 | 
					    .name = "env",
 | 
				
			||||||
    .version_id = 4,
 | 
					    .version_id = 6,
 | 
				
			||||||
    .minimum_version_id = 4,
 | 
					    .minimum_version_id = 6,
 | 
				
			||||||
 | 
					    .post_load = env_post_load,
 | 
				
			||||||
    .fields = (VMStateField[]) {
 | 
					    .fields = (VMStateField[]) {
 | 
				
			||||||
        VMSTATE_UINTTL_ARRAY(gpr, CPUOpenRISCState, 32),
 | 
					        VMSTATE_UINTTL_2DARRAY(shadow_gpr, CPUOpenRISCState, 16, 32),
 | 
				
			||||||
        VMSTATE_UINTTL(pc, CPUOpenRISCState),
 | 
					        VMSTATE_UINTTL(pc, CPUOpenRISCState),
 | 
				
			||||||
        VMSTATE_UINTTL(ppc, CPUOpenRISCState),
 | 
					        VMSTATE_UINTTL(ppc, CPUOpenRISCState),
 | 
				
			||||||
        VMSTATE_UINTTL(jmp_pc, CPUOpenRISCState),
 | 
					        VMSTATE_UINTTL(jmp_pc, CPUOpenRISCState),
 | 
				
			||||||
| 
						 | 
					@ -79,9 +137,21 @@ static const VMStateDescription vmstate_env = {
 | 
				
			||||||
        VMSTATE_UINT32(cpucfgr, CPUOpenRISCState),
 | 
					        VMSTATE_UINT32(cpucfgr, CPUOpenRISCState),
 | 
				
			||||||
        VMSTATE_UINT32(dmmucfgr, CPUOpenRISCState),
 | 
					        VMSTATE_UINT32(dmmucfgr, CPUOpenRISCState),
 | 
				
			||||||
        VMSTATE_UINT32(immucfgr, CPUOpenRISCState),
 | 
					        VMSTATE_UINT32(immucfgr, CPUOpenRISCState),
 | 
				
			||||||
 | 
					        VMSTATE_UINT32(evbar, CPUOpenRISCState),
 | 
				
			||||||
 | 
					        VMSTATE_UINT32(pmr, CPUOpenRISCState),
 | 
				
			||||||
        VMSTATE_UINT32(esr, CPUOpenRISCState),
 | 
					        VMSTATE_UINT32(esr, CPUOpenRISCState),
 | 
				
			||||||
        VMSTATE_UINT32(fpcsr, CPUOpenRISCState),
 | 
					        VMSTATE_UINT32(fpcsr, CPUOpenRISCState),
 | 
				
			||||||
        VMSTATE_UINT64(mac, CPUOpenRISCState),
 | 
					        VMSTATE_UINT64(mac, CPUOpenRISCState),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        VMSTATE_CPU_TLB(tlb, CPUOpenRISCState),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        VMSTATE_TIMER_PTR(timer, CPUOpenRISCState),
 | 
				
			||||||
 | 
					        VMSTATE_UINT32(ttmr, CPUOpenRISCState),
 | 
				
			||||||
 | 
					        VMSTATE_UINT32(ttcr, CPUOpenRISCState),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        VMSTATE_UINT32(picmr, CPUOpenRISCState),
 | 
				
			||||||
 | 
					        VMSTATE_UINT32(picsr, CPUOpenRISCState),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        VMSTATE_END_OF_LIST()
 | 
					        VMSTATE_END_OF_LIST()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -124,7 +124,7 @@ static int cpu_openrisc_get_phys_addr(OpenRISCCPU *cpu,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ret = TLBRET_MATCH;
 | 
					    int ret = TLBRET_MATCH;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (rw == 2) {    /* ITLB */
 | 
					    if (rw == MMU_INST_FETCH) {    /* ITLB */
 | 
				
			||||||
       *physical = 0;
 | 
					       *physical = 0;
 | 
				
			||||||
        ret = cpu->env.tlb->cpu_openrisc_map_address_code(cpu, physical,
 | 
					        ret = cpu->env.tlb->cpu_openrisc_map_address_code(cpu, physical,
 | 
				
			||||||
                                                          prot, address, rw);
 | 
					                                                          prot, address, rw);
 | 
				
			||||||
| 
						 | 
					@ -221,12 +221,28 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 | 
				
			||||||
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
 | 
					    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
 | 
				
			||||||
    hwaddr phys_addr;
 | 
					    hwaddr phys_addr;
 | 
				
			||||||
    int prot;
 | 
					    int prot;
 | 
				
			||||||
 | 
					    int miss;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (cpu_openrisc_get_phys_addr(cpu, &phys_addr, &prot, addr, 0)) {
 | 
					    /* Check memory for any kind of address, since during debug the
 | 
				
			||||||
        return -1;
 | 
					       gdb can ask for anything, check data tlb for address */
 | 
				
			||||||
 | 
					    miss = cpu_openrisc_get_phys_addr(cpu, &phys_addr, &prot, addr, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Check instruction tlb */
 | 
				
			||||||
 | 
					    if (miss) {
 | 
				
			||||||
 | 
					        miss = cpu_openrisc_get_phys_addr(cpu, &phys_addr, &prot, addr,
 | 
				
			||||||
 | 
					                                          MMU_INST_FETCH);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return phys_addr;
 | 
					    /* Last, fall back to a plain address */
 | 
				
			||||||
 | 
					    if (miss) {
 | 
				
			||||||
 | 
					        miss = cpu_openrisc_get_phys_nommu(cpu, &phys_addr, &prot, addr, 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (miss) {
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return phys_addr;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cpu_openrisc_mmu_init(OpenRISCCPU *cpu)
 | 
					void cpu_openrisc_mmu_init(OpenRISCCPU *cpu)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,6 +22,7 @@
 | 
				
			||||||
#include "cpu.h"
 | 
					#include "cpu.h"
 | 
				
			||||||
#include "exec/exec-all.h"
 | 
					#include "exec/exec-all.h"
 | 
				
			||||||
#include "exec/helper-proto.h"
 | 
					#include "exec/helper-proto.h"
 | 
				
			||||||
 | 
					#include "exception.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TO_SPR(group, number) (((group) << 11) + (number))
 | 
					#define TO_SPR(group, number) (((group) << 11) + (number))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,6 +40,10 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
 | 
				
			||||||
        env->vr = rb;
 | 
					        env->vr = rb;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case TO_SPR(0, 11): /* EVBAR */
 | 
				
			||||||
 | 
					        env->evbar = rb;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case TO_SPR(0, 16): /* NPC */
 | 
					    case TO_SPR(0, 16): /* NPC */
 | 
				
			||||||
        cpu_restore_state(cs, GETPC());
 | 
					        cpu_restore_state(cs, GETPC());
 | 
				
			||||||
        /* ??? Mirror or1ksim in not trashing delayed branch state
 | 
					        /* ??? Mirror or1ksim in not trashing delayed branch state
 | 
				
			||||||
| 
						 | 
					@ -88,6 +93,11 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
 | 
				
			||||||
    case TO_SPR(0, 64): /* ESR */
 | 
					    case TO_SPR(0, 64): /* ESR */
 | 
				
			||||||
        env->esr = rb;
 | 
					        env->esr = rb;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case TO_SPR(0, 1024) ... TO_SPR(0, 1024 + (16 * 32)): /* Shadow GPRs */
 | 
				
			||||||
 | 
					        idx = (spr - 1024);
 | 
				
			||||||
 | 
					        env->shadow_gpr[idx / 32][idx % 32] = rb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */
 | 
					    case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */
 | 
				
			||||||
        idx = spr - TO_SPR(1, 512);
 | 
					        idx = spr - TO_SPR(1, 512);
 | 
				
			||||||
        if (!(rb & 1)) {
 | 
					        if (!(rb & 1)) {
 | 
				
			||||||
| 
						 | 
					@ -132,6 +142,15 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
 | 
				
			||||||
    case TO_SPR(5, 2):  /* MACHI */
 | 
					    case TO_SPR(5, 2):  /* MACHI */
 | 
				
			||||||
        env->mac = deposit64(env->mac, 32, 32, rb);
 | 
					        env->mac = deposit64(env->mac, 32, 32, rb);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					    case TO_SPR(8, 0):  /* PMR */
 | 
				
			||||||
 | 
					        env->pmr = rb;
 | 
				
			||||||
 | 
					        if (env->pmr & PMR_DME || env->pmr & PMR_SME) {
 | 
				
			||||||
 | 
					            cpu_restore_state(cs, GETPC());
 | 
				
			||||||
 | 
					            env->pc += 4;
 | 
				
			||||||
 | 
					            cs->halted = 1;
 | 
				
			||||||
 | 
					            raise_exception(cpu, EXCP_HALTED);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    case TO_SPR(9, 0):  /* PICMR */
 | 
					    case TO_SPR(9, 0):  /* PICMR */
 | 
				
			||||||
        env->picmr |= rb;
 | 
					        env->picmr |= rb;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
| 
						 | 
					@ -206,6 +225,9 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
 | 
				
			||||||
    case TO_SPR(0, 4): /* IMMUCFGR */
 | 
					    case TO_SPR(0, 4): /* IMMUCFGR */
 | 
				
			||||||
        return env->immucfgr;
 | 
					        return env->immucfgr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case TO_SPR(0, 11): /* EVBAR */
 | 
				
			||||||
 | 
					        return env->evbar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case TO_SPR(0, 16): /* NPC (equals PC) */
 | 
					    case TO_SPR(0, 16): /* NPC (equals PC) */
 | 
				
			||||||
        cpu_restore_state(cs, GETPC());
 | 
					        cpu_restore_state(cs, GETPC());
 | 
				
			||||||
        return env->pc;
 | 
					        return env->pc;
 | 
				
			||||||
| 
						 | 
					@ -226,6 +248,16 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
 | 
				
			||||||
    case TO_SPR(0, 64): /* ESR */
 | 
					    case TO_SPR(0, 64): /* ESR */
 | 
				
			||||||
        return env->esr;
 | 
					        return env->esr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case TO_SPR(0, 128): /* COREID */
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case TO_SPR(0, 129): /* NUMCORES */
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case TO_SPR(0, 1024) ... TO_SPR(0, 1024 + (16 * 32)): /* Shadow GPRs */
 | 
				
			||||||
 | 
					        idx = (spr - 1024);
 | 
				
			||||||
 | 
					        return env->shadow_gpr[idx / 32][idx % 32];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */
 | 
					    case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */
 | 
				
			||||||
        idx = spr - TO_SPR(1, 512);
 | 
					        idx = spr - TO_SPR(1, 512);
 | 
				
			||||||
        return env->tlb->dtlb[0][idx].mr;
 | 
					        return env->tlb->dtlb[0][idx].mr;
 | 
				
			||||||
| 
						 | 
					@ -265,6 +297,9 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
 | 
				
			||||||
        return env->mac >> 32;
 | 
					        return env->mac >> 32;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case TO_SPR(8, 0):  /* PMR */
 | 
				
			||||||
 | 
					        return env->pmr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case TO_SPR(9, 0):  /* PICMR */
 | 
					    case TO_SPR(9, 0):  /* PICMR */
 | 
				
			||||||
        return env->picmr;
 | 
					        return env->picmr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,7 +107,8 @@ void openrisc_translate_init(void)
 | 
				
			||||||
                                     "mac");
 | 
					                                     "mac");
 | 
				
			||||||
    for (i = 0; i < 32; i++) {
 | 
					    for (i = 0; i < 32; i++) {
 | 
				
			||||||
        cpu_R[i] = tcg_global_mem_new(cpu_env,
 | 
					        cpu_R[i] = tcg_global_mem_new(cpu_env,
 | 
				
			||||||
                                      offsetof(CPUOpenRISCState, gpr[i]),
 | 
					                                      offsetof(CPUOpenRISCState,
 | 
				
			||||||
 | 
					                                               shadow_gpr[0][i]),
 | 
				
			||||||
                                      regnames[i]);
 | 
					                                      regnames[i]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    cpu_R0 = cpu_R[0];
 | 
					    cpu_R0 = cpu_R[0];
 | 
				
			||||||
| 
						 | 
					@ -1662,7 +1663,7 @@ void openrisc_cpu_dump_state(CPUState *cs, FILE *f,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cpu_fprintf(f, "PC=%08x\n", env->pc);
 | 
					    cpu_fprintf(f, "PC=%08x\n", env->pc);
 | 
				
			||||||
    for (i = 0; i < 32; ++i) {
 | 
					    for (i = 0; i < 32; ++i) {
 | 
				
			||||||
        cpu_fprintf(f, "R%02d=%08x%c", i, env->gpr[i],
 | 
					        cpu_fprintf(f, "R%02d=%08x%c", i, cpu_get_gpr(env, i),
 | 
				
			||||||
                    (i % 4) == 3 ? '\n' : ' ');
 | 
					                    (i % 4) == 3 ? '\n' : ' ');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue