A64: Implement system register CTR_EL0

This commit is contained in:
MerryMage 2018-02-20 16:44:13 +00:00
parent 58fbb3ff1b
commit 1e15283d00
6 changed files with 22 additions and 0 deletions

View file

@ -103,6 +103,13 @@ struct UserConfig {
/// Executing DC ZVA in this mode will result in zeros being written to memory. /// Executing DC ZVA in this mode will result in zeros being written to memory.
bool hook_data_cache_operations = false; 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<3:0> is log2 of the block size in words
/// DCZID_EL0<4> is 0 if the DC ZVA instruction is permitted. /// DCZID_EL0<4> is 0 if the DC ZVA instruction is permitted.
std::uint32_t dczid_el0 = 4; std::uint32_t dczid_el0 = 4;

View file

@ -472,6 +472,12 @@ void A64EmitX64::EmitA64DataMemoryBarrier(A64EmitContext&, IR::Inst*) {
code.lfence(); 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) { void A64EmitX64::EmitA64GetDCZID(A64EmitContext& ctx, IR::Inst* inst) {
Xbyak::Reg32 result = ctx.reg_alloc.ScratchGpr().cvt32(); Xbyak::Reg32 result = ctx.reg_alloc.ScratchGpr().cvt32();
code.mov(result, conf.dczid_el0); code.mov(result, conf.dczid_el0);

View file

@ -53,6 +53,10 @@ void IREmitter::DataMemoryBarrier() {
Inst(Opcode::A64DataMemoryBarrier); Inst(Opcode::A64DataMemoryBarrier);
} }
IR::U32 IREmitter::GetCTR() {
return Inst<IR::U32>(Opcode::A64GetCTR);
}
IR::U32 IREmitter::GetDCZID() { IR::U32 IREmitter::GetDCZID() {
return Inst<IR::U32>(Opcode::A64GetDCZID); return Inst<IR::U32>(Opcode::A64GetDCZID);
} }

View file

@ -44,6 +44,7 @@ public:
void DataCacheOperationRaised(DataCacheOperation op, const IR::U64& value); void DataCacheOperationRaised(DataCacheOperation op, const IR::U64& value);
void DataSynchronizationBarrier(); void DataSynchronizationBarrier();
void DataMemoryBarrier(); void DataMemoryBarrier();
IR::U32 GetCTR();
IR::U32 GetDCZID(); IR::U32 GetDCZID();
IR::U64 GetTPIDRRO(); IR::U64 GetTPIDRRO();

View file

@ -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 case 0b11'011'0000'0000'111: // DCZID_EL0
X(32, Rt, ir.GetDCZID()); X(32, Rt, ir.GetDCZID());
return true; return true;
case 0b11'011'0000'0000'001: // CTR_EL0
X(32, Rt, ir.GetCTR());
return true;
} }
return InterpretThisInstruction(); return InterpretThisInstruction();
} }

View file

@ -61,6 +61,7 @@ A64OPC(ExceptionRaised, T::Void, T::U64, T::U64
A64OPC(DataCacheOperationRaised, T::Void, T::U64, T::U64 ) A64OPC(DataCacheOperationRaised, T::Void, T::U64, T::U64 )
A64OPC(DataSynchronizationBarrier, T::Void, ) A64OPC(DataSynchronizationBarrier, T::Void, )
A64OPC(DataMemoryBarrier, T::Void, ) A64OPC(DataMemoryBarrier, T::Void, )
A64OPC(GetCTR, T::U32, )
A64OPC(GetDCZID, T::U32, ) A64OPC(GetDCZID, T::U32, )
A64OPC(GetTPIDRRO, T::U64, ) A64OPC(GetTPIDRRO, T::U64, )