From 1e15283d00739d94ec244e5968185d3d33ca5c7d Mon Sep 17 00:00:00 2001 From: MerryMage Date: Tue, 20 Feb 2018 16:44:13 +0000 Subject: [PATCH] A64: Implement system register CTR_EL0 --- include/dynarmic/A64/config.h | 7 +++++++ src/backend_x64/a64_emit_x64.cpp | 6 ++++++ src/frontend/A64/ir_emitter.cpp | 4 ++++ src/frontend/A64/ir_emitter.h | 1 + src/frontend/A64/translate/impl/system.cpp | 3 +++ src/frontend/ir/opcodes.inc | 1 + 6 files changed, 22 insertions(+) diff --git a/include/dynarmic/A64/config.h b/include/dynarmic/A64/config.h index ffe5aa9b..534f909c 100644 --- a/include/dynarmic/A64/config.h +++ b/include/dynarmic/A64/config.h @@ -103,6 +103,13 @@ struct UserConfig { /// Executing DC ZVA in this mode will result in zeros being written to memory. bool hook_data_cache_operations = false; + /// CTR_EL0<27:24> is log2 of the cache writeback granule in words. + /// CTR_EL0<23:20> is log2 of the exclusives reservation granule in words. + /// CTR_EL0<19:16> is log2 of the smallest data/unifed cacheline in words. + /// CTR_EL0<15:14> is the level 1 instruction cache policy. + /// CTR_EL0<3:0> is log2 of the smallest instruction cacheline in words. + std::uint32_t ctr_el0 = 0x8444c004; + /// DCZID_EL0<3:0> is log2 of the block size in words /// DCZID_EL0<4> is 0 if the DC ZVA instruction is permitted. std::uint32_t dczid_el0 = 4; diff --git a/src/backend_x64/a64_emit_x64.cpp b/src/backend_x64/a64_emit_x64.cpp index 6630fc3a..6a257d90 100644 --- a/src/backend_x64/a64_emit_x64.cpp +++ b/src/backend_x64/a64_emit_x64.cpp @@ -472,6 +472,12 @@ void A64EmitX64::EmitA64DataMemoryBarrier(A64EmitContext&, IR::Inst*) { code.lfence(); } +void A64EmitX64::EmitA64GetCTR(A64EmitContext& ctx, IR::Inst* inst) { + Xbyak::Reg32 result = ctx.reg_alloc.ScratchGpr().cvt32(); + code.mov(result, conf.ctr_el0); + ctx.reg_alloc.DefineValue(inst, result); +} + void A64EmitX64::EmitA64GetDCZID(A64EmitContext& ctx, IR::Inst* inst) { Xbyak::Reg32 result = ctx.reg_alloc.ScratchGpr().cvt32(); code.mov(result, conf.dczid_el0); diff --git a/src/frontend/A64/ir_emitter.cpp b/src/frontend/A64/ir_emitter.cpp index 204d76f1..89894e7e 100644 --- a/src/frontend/A64/ir_emitter.cpp +++ b/src/frontend/A64/ir_emitter.cpp @@ -53,6 +53,10 @@ void IREmitter::DataMemoryBarrier() { Inst(Opcode::A64DataMemoryBarrier); } +IR::U32 IREmitter::GetCTR() { + return Inst(Opcode::A64GetCTR); +} + IR::U32 IREmitter::GetDCZID() { return Inst(Opcode::A64GetDCZID); } diff --git a/src/frontend/A64/ir_emitter.h b/src/frontend/A64/ir_emitter.h index 24d05f1b..d99312e9 100644 --- a/src/frontend/A64/ir_emitter.h +++ b/src/frontend/A64/ir_emitter.h @@ -44,6 +44,7 @@ public: void DataCacheOperationRaised(DataCacheOperation op, const IR::U64& value); void DataSynchronizationBarrier(); void DataMemoryBarrier(); + IR::U32 GetCTR(); IR::U32 GetDCZID(); IR::U64 GetTPIDRRO(); diff --git a/src/frontend/A64/translate/impl/system.cpp b/src/frontend/A64/translate/impl/system.cpp index 2bfa0f82..da644652 100644 --- a/src/frontend/A64/translate/impl/system.cpp +++ b/src/frontend/A64/translate/impl/system.cpp @@ -60,6 +60,9 @@ bool TranslatorVisitor::MRS(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3 case 0b11'011'0000'0000'111: // DCZID_EL0 X(32, Rt, ir.GetDCZID()); return true; + case 0b11'011'0000'0000'001: // CTR_EL0 + X(32, Rt, ir.GetCTR()); + return true; } return InterpretThisInstruction(); } diff --git a/src/frontend/ir/opcodes.inc b/src/frontend/ir/opcodes.inc index c8f007d7..8815423d 100644 --- a/src/frontend/ir/opcodes.inc +++ b/src/frontend/ir/opcodes.inc @@ -61,6 +61,7 @@ A64OPC(ExceptionRaised, T::Void, T::U64, T::U64 A64OPC(DataCacheOperationRaised, T::Void, T::U64, T::U64 ) A64OPC(DataSynchronizationBarrier, T::Void, ) A64OPC(DataMemoryBarrier, T::Void, ) +A64OPC(GetCTR, T::U32, ) A64OPC(GetDCZID, T::U32, ) A64OPC(GetTPIDRRO, T::U64, )