mirror of
https://github.com/AlexAltea/orbital.git
synced 2024-06-16 03:07:58 -04:00
hardware/liverpool: Finished GMC VM translator space
This commit is contained in:
parent
eced42c9a0
commit
2aade82d74
|
@ -13,6 +13,8 @@
|
|||
#include "gmc_7_1_d.h"
|
||||
#include "gmc_7_1_sh_mask.h"
|
||||
|
||||
constexpr auto GMC_VM_COUNT = 16;
|
||||
|
||||
constexpr U64 VM_PTE_VALID = (1ULL << 0);
|
||||
constexpr U64 VM_PTE_SYSTEM = (1ULL << 1);
|
||||
constexpr U64 VM_PTE_SNOOPED = (1ULL << 2);
|
||||
|
@ -21,14 +23,14 @@ constexpr U64 VM_PTE_PROT_X = (1ULL << 4);
|
|||
constexpr U64 VM_PTE_PROT_R = (1ULL << 5);
|
||||
constexpr U64 VM_PTE_PROT_W = (1ULL << 6);
|
||||
|
||||
constexpr U64 VM_MAX_ADDR = 0xFFF'FFFFFFFF;
|
||||
constexpr U64 VM_MAX_ADDR = 0xFF'FFFFFFFF;
|
||||
|
||||
GmcVmSpace::GmcVmSpace(GmcDevice* gmc)
|
||||
: TranslatorSpace(gmc, VM_MAX_ADDR + 1, nullptr), gmc(*gmc) {}
|
||||
GmcVmSpace::GmcVmSpace(Space* gmc_mem)
|
||||
: TranslatorSpace(nullptr, VM_MAX_ADDR + 1, gmc_mem) {
|
||||
}
|
||||
|
||||
TranslatorResult GmcVmSpace::translate(Offset offset) {
|
||||
TranslatorResult res = {};
|
||||
#if 0
|
||||
if (!this->base) {
|
||||
return res;
|
||||
}
|
||||
|
@ -38,9 +40,9 @@ TranslatorResult GmcVmSpace::translate(Offset offset) {
|
|||
pde_base = this->base;
|
||||
pde_index = (offset >> 23) & 0xFFFFF; // TODO: What's the mask?
|
||||
pte_index = (offset >> 12) & 0x7FF;
|
||||
pde = gmc.mem()->read<U64>(pde_base + pde_index * 8);
|
||||
pde = child->read<U64>(pde_base + pde_index * 8);
|
||||
pte_base = pde & ~UINT64_C(0xFF);
|
||||
pte = mem->read<U64>(pte_base + pte_index * 8);
|
||||
pte = child->read<U64>(pte_base + pte_index * 8);
|
||||
|
||||
// Make translation result
|
||||
res.base_pa = offset & ~UINT64_C(0xFFF);
|
||||
|
@ -55,24 +57,36 @@ TranslatorResult GmcVmSpace::translate(Offset offset) {
|
|||
if (pte & VM_PTE_PROT_W) {
|
||||
res.protection |= TranslatorResult::PROT_W;
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
GmcDevice::GmcDevice(Space* mem, const GmcDeviceConfig& config) : Device(nullptr, config) {
|
||||
GmcDevice::GmcDevice(Space* mem, const GmcDeviceConfig& config)
|
||||
: Device(nullptr, config), vm_contexts(GMC_VM_COUNT, { mem }) {
|
||||
reset();
|
||||
}
|
||||
|
||||
void GmcDevice::reset() {
|
||||
vm_invalidate_request = 0;
|
||||
vm_invalidate_response = 0;
|
||||
}
|
||||
|
||||
U32 GmcDevice::mmio_read(U32 index) {
|
||||
U32 value = 0;
|
||||
if (index >= mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR &&
|
||||
index <= mmVM_CONTEXT7_PAGE_TABLE_BASE_ADDR) {
|
||||
const U32 vmid = index - mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR;
|
||||
return vm_contexts[vmid].base >> 12;
|
||||
}
|
||||
if (index >= mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR &&
|
||||
index <= mmVM_CONTEXT15_PAGE_TABLE_BASE_ADDR) {
|
||||
const U32 vmid = 8 + index - mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR;
|
||||
return vm_contexts[vmid].base >> 12;
|
||||
}
|
||||
|
||||
U32 value = 0;
|
||||
switch (index) {
|
||||
// VM
|
||||
case mmVM_INVALIDATE_RESPONSE:
|
||||
value = vm_invalidate_request;
|
||||
value = vm_invalidate_response;
|
||||
break;
|
||||
|
||||
// MC
|
||||
|
@ -89,57 +103,25 @@ U32 GmcDevice::mmio_read(U32 index) {
|
|||
}
|
||||
|
||||
void GmcDevice::mmio_write(U32 index, U32 value) {
|
||||
if (index >= mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR &&
|
||||
index <= mmVM_CONTEXT7_PAGE_TABLE_BASE_ADDR) {
|
||||
const U32 vmid = index - mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR;
|
||||
vm_contexts[vmid].base = value << 12;
|
||||
return;
|
||||
}
|
||||
if (index >= mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR &&
|
||||
index <= mmVM_CONTEXT15_PAGE_TABLE_BASE_ADDR) {
|
||||
const U32 vmid = 8 + index - mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR;
|
||||
vm_contexts[vmid].base = value << 12;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (index) {
|
||||
// VM
|
||||
case mmVM_L2_CG:
|
||||
break;
|
||||
case mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR:
|
||||
vm_context_base[0] = value << 12;
|
||||
break;
|
||||
case mmVM_CONTEXT1_PAGE_TABLE_BASE_ADDR:
|
||||
vm_context_base[1] = value << 12;
|
||||
break;
|
||||
case mmVM_CONTEXT2_PAGE_TABLE_BASE_ADDR:
|
||||
vm_context_base[2] = value << 12;
|
||||
break;
|
||||
case mmVM_CONTEXT3_PAGE_TABLE_BASE_ADDR:
|
||||
vm_context_base[3] = value << 12;
|
||||
break;
|
||||
case mmVM_CONTEXT4_PAGE_TABLE_BASE_ADDR:
|
||||
vm_context_base[4] = value << 12;
|
||||
break;
|
||||
case mmVM_CONTEXT5_PAGE_TABLE_BASE_ADDR:
|
||||
vm_context_base[5] = value << 12;
|
||||
break;
|
||||
case mmVM_CONTEXT6_PAGE_TABLE_BASE_ADDR:
|
||||
vm_context_base[6] = value << 12;
|
||||
break;
|
||||
case mmVM_CONTEXT7_PAGE_TABLE_BASE_ADDR:
|
||||
vm_context_base[7] = value << 12;
|
||||
break;
|
||||
case mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR:
|
||||
vm_context_base[8] = value << 12;
|
||||
break;
|
||||
case mmVM_CONTEXT9_PAGE_TABLE_BASE_ADDR:
|
||||
vm_context_base[9] = value << 12;
|
||||
break;
|
||||
case mmVM_CONTEXT10_PAGE_TABLE_BASE_ADDR:
|
||||
vm_context_base[10] = value << 12;
|
||||
break;
|
||||
case mmVM_CONTEXT11_PAGE_TABLE_BASE_ADDR:
|
||||
vm_context_base[11] = value << 12;
|
||||
break;
|
||||
case mmVM_CONTEXT12_PAGE_TABLE_BASE_ADDR:
|
||||
vm_context_base[12] = value << 12;
|
||||
break;
|
||||
case mmVM_CONTEXT13_PAGE_TABLE_BASE_ADDR:
|
||||
vm_context_base[13] = value << 12;
|
||||
break;
|
||||
case mmVM_CONTEXT14_PAGE_TABLE_BASE_ADDR:
|
||||
vm_context_base[14] = value << 12;
|
||||
break;
|
||||
case mmVM_CONTEXT15_PAGE_TABLE_BASE_ADDR:
|
||||
vm_context_base[15] = value << 12;
|
||||
case mmVM_INVALIDATE_REQUEST:
|
||||
vm_invalidate_response = value;
|
||||
break;
|
||||
|
||||
// MC
|
||||
|
@ -212,3 +194,7 @@ void GmcDevice::mmio_write(U32 index, U32 value) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GmcVmSpace& GmcDevice::get(U32 vmid) {
|
||||
return vm_contexts[vmid];
|
||||
}
|
||||
|
|
|
@ -18,20 +18,18 @@
|
|||
// Forward declarations
|
||||
class GmcDevice;
|
||||
|
||||
constexpr auto GMC_VM_COUNT = 16;
|
||||
|
||||
constexpr auto GMC_MMIO_VM = OffsetRange(0x500, 0x78);
|
||||
constexpr auto GMC_MMIO_MC = OffsetRange(0x800, 0x300);
|
||||
|
||||
class GmcVmSpace : public TranslatorSpace {
|
||||
friend class GmcDevice;
|
||||
public:
|
||||
GmcVmSpace(GmcDevice* gmc);
|
||||
GmcVmSpace(Space* gmc_mem);
|
||||
|
||||
virtual TranslatorResult translate(Offset off) = 0;
|
||||
TranslatorResult translate(Offset off) override;
|
||||
|
||||
private:
|
||||
U64 base = 0;
|
||||
GmcDevice& gmc;
|
||||
};
|
||||
|
||||
struct GmcDeviceConfig : DeviceConfig {
|
||||
|
@ -46,9 +44,10 @@ public:
|
|||
U32 mmio_read(U32 index);
|
||||
void mmio_write(U32 index, U32 value);
|
||||
|
||||
GmcVmSpace& get(U32 vmid);
|
||||
|
||||
private:
|
||||
U32 vm_invalidate_request;
|
||||
U64 vm_context_base[GMC_VM_COUNT];
|
||||
std::vector<GmcVmSpace> vm_contexts;
|
||||
U32 vm_invalidate_response;
|
||||
U32 mc_bist_mismatch_addr;
|
||||
Space* mem;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue