mirror of https://gitee.com/openkylin/qemu.git
code cleanup, switch to transaction_failed hook
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJc3eUcAAoJEPMMOL0/L748uRwP+QHQ6SUyKPTtopJYpw3drcyz HRQ0uYoJzc/U4oNEA9wb1o3MTREoRrRtl9N3fc2QwF96+55WPqoOVPNmvztpkRIu T51gdg3R5ormDvn7fYlf75tKzj4N2KgblsFcJ2Da++M1tIlvdhT2+JvZ/Pe437Ig GaXAPCO4RwQIhI+CMwd19C+D8jqDFIPi5rs923YMg4/t1+cpm+iYKIb3+s4gLzap hcqiAHEdGX836EKlQYmsHbs01FiSUzRccMGAr3WgelyPHKirSKw/Q752BmvpmidT bV9SYcZ7dGn9mrQ2RfEjD6ATWdjZmGO6jt0W7f1cWXKn1AlhJmOd6LPerschzVHm lTtuN8Dy8YLuwO0X8pjzLYvhsfWy2QD21DrC2biG8DTSXrI1ucFaDPx3twXp5B8H Y/vlEXq3wVcs/vc6kUuNgs8f8EwLmuPnSKMc1qcwH3vjFCAWnpSXbo6HuUqby+UC pfYaD/2reoipekWvdz1u+ptaozvy6pVFO2Mvb+rJA0OhIsFWzGXz92YIXSg97Iyf QtXUTgRo82NKqdA4+6+5XAc0r9o3quSO74beAYlfwvRPagUAvYVH4Q2OLkXNEmYc aq2qmrDCo/2B0j8bw8JTMjnZOPQAuWOy2Hau+VzsxyitEE/LCtUTOd4L4EJ4QIp+ jmFcdhD98HTtQ+OQF3Zm =d7qy -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/vivier/tags/m68k-staging-pull-request' into staging code cleanup, switch to transaction_failed hook # gpg: Signature made Thu 16 May 2019 23:33:00 BST # gpg: using RSA key F30C38BD3F2FBE3C # gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full] # gpg: aka "Laurent Vivier <laurent@vivier.eu>" [full] # gpg: aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full] # Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F 5173 F30C 38BD 3F2F BE3C * remotes/vivier/tags/m68k-staging-pull-request: target/m68k: Optimize rotate_x() using extract_i32() target/m68k: Fix a tcg_temp leak target/m68k: Reduce the l1 TCGLabel scope target/m68k: Switch to transaction_failed hook target/m68k: In get_physical_address() check for memory access failures target/m68k: In dump_address_map() check for memory access failures Signed-off-by: Peter Maydell <peter.maydell@linaro.org> # Conflicts: # target/m68k/cpu.h
This commit is contained in:
commit
b0f9690e78
|
@ -271,7 +271,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
|
|||
cc->gdb_write_register = m68k_cpu_gdb_write_register;
|
||||
cc->tlb_fill = m68k_cpu_tlb_fill;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
cc->do_unassigned_access = m68k_cpu_unassigned_access;
|
||||
cc->do_transaction_failed = m68k_cpu_transaction_failed;
|
||||
cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
|
||||
#endif
|
||||
cc->disas_set_info = m68k_cpu_disas_set_info;
|
||||
|
|
|
@ -545,9 +545,10 @@ static inline int cpu_mmu_index (CPUM68KState *env, bool ifetch)
|
|||
bool m68k_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||
MMUAccessType access_type, int mmu_idx,
|
||||
bool probe, uintptr_t retaddr);
|
||||
void m68k_cpu_unassigned_access(CPUState *cs, hwaddr addr,
|
||||
bool is_write, bool is_exec, int is_asi,
|
||||
unsigned size);
|
||||
void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
|
||||
unsigned size, MMUAccessType access_type,
|
||||
int mmu_idx, MemTxAttrs attrs,
|
||||
MemTxResult response, uintptr_t retaddr);
|
||||
|
||||
#include "exec/cpu-all.h"
|
||||
|
||||
|
|
|
@ -390,6 +390,7 @@ static void dump_address_map(CPUM68KState *env, uint32_t root_pointer)
|
|||
int last_attr = -1, attr = -1;
|
||||
M68kCPU *cpu = m68k_env_get_cpu(env);
|
||||
CPUState *cs = CPU(cpu);
|
||||
MemTxResult txres;
|
||||
|
||||
if (env->mmu.tcr & M68K_TCR_PAGE_8K) {
|
||||
/* 8k page */
|
||||
|
@ -403,22 +404,29 @@ static void dump_address_map(CPUM68KState *env, uint32_t root_pointer)
|
|||
tib_mask = M68K_4K_PAGE_MASK;
|
||||
}
|
||||
for (i = 0; i < M68K_ROOT_POINTER_ENTRIES; i++) {
|
||||
tia = ldl_phys(cs->as, M68K_POINTER_BASE(root_pointer) + i * 4);
|
||||
if (!M68K_UDT_VALID(tia)) {
|
||||
tia = address_space_ldl(cs->as, M68K_POINTER_BASE(root_pointer) + i * 4,
|
||||
MEMTXATTRS_UNSPECIFIED, &txres);
|
||||
if (txres != MEMTX_OK || !M68K_UDT_VALID(tia)) {
|
||||
continue;
|
||||
}
|
||||
for (j = 0; j < M68K_ROOT_POINTER_ENTRIES; j++) {
|
||||
tib = ldl_phys(cs->as, M68K_POINTER_BASE(tia) + j * 4);
|
||||
if (!M68K_UDT_VALID(tib)) {
|
||||
tib = address_space_ldl(cs->as, M68K_POINTER_BASE(tia) + j * 4,
|
||||
MEMTXATTRS_UNSPECIFIED, &txres);
|
||||
if (txres != MEMTX_OK || !M68K_UDT_VALID(tib)) {
|
||||
continue;
|
||||
}
|
||||
for (k = 0; k < tic_size; k++) {
|
||||
tic = ldl_phys(cs->as, (tib & tib_mask) + k * 4);
|
||||
if (!M68K_PDT_VALID(tic)) {
|
||||
tic = address_space_ldl(cs->as, (tib & tib_mask) + k * 4,
|
||||
MEMTXATTRS_UNSPECIFIED, &txres);
|
||||
if (txres != MEMTX_OK || !M68K_PDT_VALID(tic)) {
|
||||
continue;
|
||||
}
|
||||
if (M68K_PDT_INDIRECT(tic)) {
|
||||
tic = ldl_phys(cs->as, M68K_INDIRECT_POINTER(tic));
|
||||
tic = address_space_ldl(cs->as, M68K_INDIRECT_POINTER(tic),
|
||||
MEMTXATTRS_UNSPECIFIED, &txres);
|
||||
if (txres != MEMTX_OK) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
last_logical = logical;
|
||||
|
@ -630,6 +638,7 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical,
|
|||
bool debug = access_type & ACCESS_DEBUG;
|
||||
int page_bits;
|
||||
int i;
|
||||
MemTxResult txres;
|
||||
|
||||
/* Transparent Translation (physical = logical) */
|
||||
for (i = 0; i < M68K_MAX_TTR; i++) {
|
||||
|
@ -659,12 +668,19 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical,
|
|||
/* Root Index */
|
||||
entry = M68K_POINTER_BASE(next) | M68K_ROOT_INDEX(address);
|
||||
|
||||
next = ldl_phys(cs->as, entry);
|
||||
next = address_space_ldl(cs->as, entry, MEMTXATTRS_UNSPECIFIED, &txres);
|
||||
if (txres != MEMTX_OK) {
|
||||
goto txfail;
|
||||
}
|
||||
if (!M68K_UDT_VALID(next)) {
|
||||
return -1;
|
||||
}
|
||||
if (!(next & M68K_DESC_USED) && !debug) {
|
||||
stl_phys(cs->as, entry, next | M68K_DESC_USED);
|
||||
address_space_stl(cs->as, entry, next | M68K_DESC_USED,
|
||||
MEMTXATTRS_UNSPECIFIED, &txres);
|
||||
if (txres != MEMTX_OK) {
|
||||
goto txfail;
|
||||
}
|
||||
}
|
||||
if (next & M68K_DESC_WRITEPROT) {
|
||||
if (access_type & ACCESS_PTEST) {
|
||||
|
@ -679,12 +695,19 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical,
|
|||
/* Pointer Index */
|
||||
entry = M68K_POINTER_BASE(next) | M68K_POINTER_INDEX(address);
|
||||
|
||||
next = ldl_phys(cs->as, entry);
|
||||
next = address_space_ldl(cs->as, entry, MEMTXATTRS_UNSPECIFIED, &txres);
|
||||
if (txres != MEMTX_OK) {
|
||||
goto txfail;
|
||||
}
|
||||
if (!M68K_UDT_VALID(next)) {
|
||||
return -1;
|
||||
}
|
||||
if (!(next & M68K_DESC_USED) && !debug) {
|
||||
stl_phys(cs->as, entry, next | M68K_DESC_USED);
|
||||
address_space_stl(cs->as, entry, next | M68K_DESC_USED,
|
||||
MEMTXATTRS_UNSPECIFIED, &txres);
|
||||
if (txres != MEMTX_OK) {
|
||||
goto txfail;
|
||||
}
|
||||
}
|
||||
if (next & M68K_DESC_WRITEPROT) {
|
||||
if (access_type & ACCESS_PTEST) {
|
||||
|
@ -703,27 +726,46 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical,
|
|||
entry = M68K_4K_PAGE_BASE(next) | M68K_4K_PAGE_INDEX(address);
|
||||
}
|
||||
|
||||
next = ldl_phys(cs->as, entry);
|
||||
next = address_space_ldl(cs->as, entry, MEMTXATTRS_UNSPECIFIED, &txres);
|
||||
if (txres != MEMTX_OK) {
|
||||
goto txfail;
|
||||
}
|
||||
|
||||
if (!M68K_PDT_VALID(next)) {
|
||||
return -1;
|
||||
}
|
||||
if (M68K_PDT_INDIRECT(next)) {
|
||||
next = ldl_phys(cs->as, M68K_INDIRECT_POINTER(next));
|
||||
next = address_space_ldl(cs->as, M68K_INDIRECT_POINTER(next),
|
||||
MEMTXATTRS_UNSPECIFIED, &txres);
|
||||
if (txres != MEMTX_OK) {
|
||||
goto txfail;
|
||||
}
|
||||
}
|
||||
if (access_type & ACCESS_STORE) {
|
||||
if (next & M68K_DESC_WRITEPROT) {
|
||||
if (!(next & M68K_DESC_USED) && !debug) {
|
||||
stl_phys(cs->as, entry, next | M68K_DESC_USED);
|
||||
address_space_stl(cs->as, entry, next | M68K_DESC_USED,
|
||||
MEMTXATTRS_UNSPECIFIED, &txres);
|
||||
if (txres != MEMTX_OK) {
|
||||
goto txfail;
|
||||
}
|
||||
}
|
||||
} else if ((next & (M68K_DESC_MODIFIED | M68K_DESC_USED)) !=
|
||||
(M68K_DESC_MODIFIED | M68K_DESC_USED) && !debug) {
|
||||
stl_phys(cs->as, entry,
|
||||
next | (M68K_DESC_MODIFIED | M68K_DESC_USED));
|
||||
address_space_stl(cs->as, entry,
|
||||
next | (M68K_DESC_MODIFIED | M68K_DESC_USED),
|
||||
MEMTXATTRS_UNSPECIFIED, &txres);
|
||||
if (txres != MEMTX_OK) {
|
||||
goto txfail;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!(next & M68K_DESC_USED) && !debug) {
|
||||
stl_phys(cs->as, entry, next | M68K_DESC_USED);
|
||||
address_space_stl(cs->as, entry, next | M68K_DESC_USED,
|
||||
MEMTXATTRS_UNSPECIFIED, &txres);
|
||||
if (txres != MEMTX_OK) {
|
||||
goto txfail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -755,6 +797,14 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical,
|
|||
}
|
||||
|
||||
return 0;
|
||||
|
||||
txfail:
|
||||
/*
|
||||
* A page table load/store failed. TODO: we should really raise a
|
||||
* suitable guest fault here if this is not a debug access.
|
||||
* For now just return that the translation failed.
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
|
|
|
@ -439,19 +439,15 @@ static inline void do_interrupt_m68k_hardirq(CPUM68KState *env)
|
|||
do_interrupt_all(env, 1);
|
||||
}
|
||||
|
||||
void m68k_cpu_unassigned_access(CPUState *cs, hwaddr addr, bool is_write,
|
||||
bool is_exec, int is_asi, unsigned size)
|
||||
void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
|
||||
unsigned size, MMUAccessType access_type,
|
||||
int mmu_idx, MemTxAttrs attrs,
|
||||
MemTxResult response, uintptr_t retaddr)
|
||||
{
|
||||
M68kCPU *cpu = M68K_CPU(cs);
|
||||
CPUM68KState *env = &cpu->env;
|
||||
#ifdef DEBUG_UNASSIGNED
|
||||
qemu_log_mask(CPU_LOG_INT, "Unassigned " TARGET_FMT_plx " wr=%d exe=%d\n",
|
||||
addr, is_write, is_exec);
|
||||
#endif
|
||||
if (env == NULL) {
|
||||
/* when called from gdb, env is NULL */
|
||||
return;
|
||||
}
|
||||
|
||||
cpu_restore_state(cs, retaddr, true);
|
||||
|
||||
if (m68k_feature(env, M68K_FEATURE_M68040)) {
|
||||
env->mmu.mmusr = 0;
|
||||
|
@ -461,7 +457,7 @@ void m68k_cpu_unassigned_access(CPUState *cs, hwaddr addr, bool is_write,
|
|||
if (env->sr & SR_S) { /* SUPERVISOR */
|
||||
env->mmu.ssw |= M68K_TM_040_SUPER;
|
||||
}
|
||||
if (is_exec) { /* instruction or data */
|
||||
if (access_type == MMU_INST_FETCH) { /* instruction or data */
|
||||
env->mmu.ssw |= M68K_TM_040_CODE;
|
||||
} else {
|
||||
env->mmu.ssw |= M68K_TM_040_DATA;
|
||||
|
@ -479,7 +475,7 @@ void m68k_cpu_unassigned_access(CPUState *cs, hwaddr addr, bool is_write,
|
|||
break;
|
||||
}
|
||||
|
||||
if (!is_write) {
|
||||
if (access_type != MMU_DATA_STORE) {
|
||||
env->mmu.ssw |= M68K_RW_040;
|
||||
}
|
||||
|
||||
|
|
|
@ -2227,6 +2227,7 @@ static TCGv gen_get_sr(DisasContext *s)
|
|||
sr = tcg_temp_new();
|
||||
tcg_gen_andi_i32(sr, QREG_SR, 0xffe0);
|
||||
tcg_gen_or_i32(sr, sr, ccr);
|
||||
tcg_temp_free(ccr);
|
||||
return sr;
|
||||
}
|
||||
|
||||
|
@ -3020,7 +3021,6 @@ DISAS_INSN(branch)
|
|||
int32_t offset;
|
||||
uint32_t base;
|
||||
int op;
|
||||
TCGLabel *l1;
|
||||
|
||||
base = s->pc;
|
||||
op = (insn >> 8) & 0xf;
|
||||
|
@ -3036,7 +3036,7 @@ DISAS_INSN(branch)
|
|||
}
|
||||
if (op > 1) {
|
||||
/* Bcc */
|
||||
l1 = gen_new_label();
|
||||
TCGLabel *l1 = gen_new_label();
|
||||
gen_jmpcc(s, ((insn >> 8) & 0xf) ^ 1, l1);
|
||||
gen_jmp_tb(s, 1, base + offset);
|
||||
gen_set_label(l1);
|
||||
|
@ -3693,6 +3693,7 @@ static TCGv rotate_x(TCGv reg, TCGv shift, int left, int size)
|
|||
tcg_gen_sub_i32(shl, shl, shift); /* shl = size + 1 - shift */
|
||||
tcg_gen_sub_i32(shx, sz, shift); /* shx = size - shift */
|
||||
}
|
||||
tcg_temp_free_i32(sz);
|
||||
|
||||
/* reg = (reg << shl) | (reg >> shr) | (x << shx); */
|
||||
|
||||
|
@ -3708,9 +3709,7 @@ static TCGv rotate_x(TCGv reg, TCGv shift, int left, int size)
|
|||
/* X = (reg >> size) & 1 */
|
||||
|
||||
X = tcg_temp_new();
|
||||
tcg_gen_shr_i32(X, reg, sz);
|
||||
tcg_gen_andi_i32(X, X, 1);
|
||||
tcg_temp_free(sz);
|
||||
tcg_gen_extract_i32(X, reg, size, 1);
|
||||
|
||||
return X;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue