From 4676cfeee23ca89527209d6d2047f22f0197205b Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Mon, 21 Mar 2022 15:04:07 +0100 Subject: [PATCH] Platinum: implement memory controller registers. --- devices/memctrl/platinum.cpp | 86 +++++++++++++++++++++++++++++++++++- devices/memctrl/platinum.h | 29 +++++++++++- 2 files changed, 111 insertions(+), 4 deletions(-) diff --git a/devices/memctrl/platinum.cpp b/devices/memctrl/platinum.cpp index ecd7bb6..4f010a2 100644 --- a/devices/memctrl/platinum.cpp +++ b/devices/memctrl/platinum.cpp @@ -50,6 +50,19 @@ uint32_t PlatinumCtrl::read(uint32_t reg_start, uint32_t offset, int size) switch (offset) { case PlatinumReg::CPU_ID: return this->cpu_id; + case PlatinumReg::DRAM_REFRESH: + return this->dram_refresh; + case PlatinumReg::BANK_0_BASE: + case PlatinumReg::BANK_1_BASE: + case PlatinumReg::BANK_2_BASE: + case PlatinumReg::BANK_3_BASE: + case PlatinumReg::BANK_4_BASE: + case PlatinumReg::BANK_5_BASE: + case PlatinumReg::BANK_6_BASE: + case PlatinumReg::BANK_7_BASE: + return this->bank_base[(offset - PlatinumReg::BANK_0_BASE) >> 4]; + case PlatinumReg::CACHE_CONFIG: + return 0; // report no L2 cache installed default: LOG_F(WARNING, "Platinum: unknown register read at offset 0x%X", offset); } @@ -57,7 +70,76 @@ uint32_t PlatinumCtrl::read(uint32_t reg_start, uint32_t offset, int size) return 0; } -void PlatinumCtrl::write(uint32_t reg_start, uint32_t offset, uint32_t value, int size) +void PlatinumCtrl::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size) { - LOG_F(WARNING, "Platinum: unknown register write at offset 0x%X", offset); + switch (offset) { + case PlatinumReg::ROM_TIMING: + this->rom_timing = value; + break; + case PlatinumReg::DRAM_TIMING: + this->dram_timing = value; + break; + case PlatinumReg::DRAM_REFRESH: + this->dram_refresh = value; + break; + case PlatinumReg::FB_CONFIG_2: + this->fb_config_2 = value; + break; + case PlatinumReg::VRAM_REFRESH: + this->vram_refresh = value; + break; + case PlatinumReg::BANK_0_BASE: + case PlatinumReg::BANK_1_BASE: + case PlatinumReg::BANK_2_BASE: + case PlatinumReg::BANK_3_BASE: + case PlatinumReg::BANK_4_BASE: + case PlatinumReg::BANK_5_BASE: + case PlatinumReg::BANK_6_BASE: + case PlatinumReg::BANK_7_BASE: + this->bank_base[(offset - PlatinumReg::BANK_0_BASE) >> 4] = value; + break; + default: + LOG_F(WARNING, "Platinum: unknown register write at offset 0x%X", offset); + } +} + +void PlatinumCtrl::insert_ram_dimm(int slot_num, uint32_t capacity) +{ + if (slot_num < 0 || slot_num >= 4) { + ABORT_F("Platinum: invalid DIMM slot %d", slot_num); + } + + switch (capacity) { + case DRAM_CAP_2MB: + case DRAM_CAP_4MB: + case DRAM_CAP_8MB: + case DRAM_CAP_16MB: + case DRAM_CAP_32MB: + case DRAM_CAP_64MB: + this->bank_size[slot_num * 2 + 0] = capacity; + break; + case DRAM_CAP_128MB: + this->bank_size[slot_num * 2 + 0] = DRAM_CAP_64MB; + this->bank_size[slot_num * 2 + 1] = DRAM_CAP_64MB; + break; + default: + ABORT_F("Platinum: unsupported DRAM capacity %d", capacity); + } +} + +void PlatinumCtrl::map_phys_ram() +{ + uint32_t total_ram = 0; + + for (int i = 0; i < 8; i++) { + total_ram += this->bank_size[i]; + } + + if (total_ram > DRAM_CAP_64MB) { + ABORT_F("Platinum: RAM bigger than 64MB not supported yet"); + } + + if (!add_ram_region(0x00000000, total_ram)) { + ABORT_F("Platinum: could not allocate RAM storage"); + } } diff --git a/devices/memctrl/platinum.h b/devices/memctrl/platinum.h index eb66891..bab559c 100644 --- a/devices/memctrl/platinum.h +++ b/devices/memctrl/platinum.h @@ -116,7 +116,20 @@ enum PlatinumReg : uint32_t { BANK_6_BASE = 0x0C0, BANK_7_BASE = 0x0D0, GP_SW_SCRATCH = 0x0E0, - PCI_ADDR_MASK = 0x0F0 + PCI_ADDR_MASK = 0x0F0, + FB_CONFIG_1 = 0x140, + FB_CONFIG_2 = 0x150, + VRAM_REFRESH = 0x1B0, +}; + +enum { + DRAM_CAP_2MB = (1 << 21), + DRAM_CAP_4MB = (1 << 22), + DRAM_CAP_8MB = (1 << 23), + DRAM_CAP_16MB = (1 << 24), + DRAM_CAP_32MB = (1 << 25), + DRAM_CAP_64MB = (1 << 26), + DRAM_CAP_128MB = (1 << 27), }; }; // namespace Platinum @@ -132,11 +145,23 @@ public: /* MMIODevice methods */ uint32_t read(uint32_t reg_start, uint32_t offset, int size); - void write(uint32_t reg_start, uint32_t offset, uint32_t value, int size); + void write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size); + + void insert_ram_dimm(int slot_num, uint32_t capacity); + void map_phys_ram(); private: uint32_t cpu_id; uint8_t cpu_type; // 0 - MPC601, 1 - 603/604 CPU + + // memory controller state + uint32_t rom_timing = 0; + uint32_t dram_timing = 0xEFF; + uint32_t dram_refresh = 0x1F4; + uint32_t fb_config_2 = 0x1FFF; + uint32_t vram_refresh = 0x1F4; + uint32_t bank_base[8]; + uint32_t bank_size[8] = { 0 }; }; #endif // PLATINUM_MEMCTRL_H