From 198b918a3c8f6422ad304f43ba5dbc8bb3b742b5 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Mon, 7 Oct 2019 03:21:01 +0200 Subject: [PATCH] MPC106: allocate RAM after software setup. Software will setup MPC106 internal registers and finally set MCCR1[MEMGO] flag. This is the right time for initializing physical RAM. --- devices/mmiodevice.h | 1 + devices/mpc106.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ devices/mpc106.h | 2 ++ main.cpp | 3 +-- 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/devices/mmiodevice.h b/devices/mmiodevice.h index 454d1af..adc6140 100644 --- a/devices/mmiodevice.h +++ b/devices/mmiodevice.h @@ -6,6 +6,7 @@ #define READ_WORD_BE(addr) ((addr)[0] << 16) | (addr)[1] #define READ_DWORD_BE(addr) ((addr)[0] << 24) | ((addr)[1] << 16) | ((addr)[2] << 8) | (addr)[3] +#define READ_DWORD_LE(addr) ((addr)[3] << 24) | ((addr)[2] << 16) | ((addr)[1] << 8) | (addr)[0] /** Abstract class representing a simple, memory-mapped I/O device */ class MMIODevice { diff --git a/devices/mpc106.cpp b/devices/mpc106.cpp index 7c90630..2527b06 100644 --- a/devices/mpc106.cpp +++ b/devices/mpc106.cpp @@ -160,6 +160,13 @@ void MPC106::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size) std::cout << "MPC106 read error: invalid size parameter " << size << std::endl; } + + if (this->my_pci_cfg_hdr[0xF2] & 8) { +#ifdef MPC106_DEBUG + std::cout << "MPC106: MCCR1[MEMGO] was set! " << std::endl; +#endif + setup_ram(); + } } bool MPC106::pci_register_device(int dev_num, PCIDevice *dev_instance) @@ -179,3 +186,38 @@ bool MPC106::pci_register_mmio_region(uint32_t start_addr, uint32_t size, PCIDev // FIXME: add sanity checks! return this->add_mmio_region(start_addr, size, obj); } + +void MPC106::setup_ram() +{ + uint32_t mem_start, mem_end, ext_mem_start, ext_mem_end, bank_start, bank_end; + uint32_t ram_size = 0; + + uint8_t bank_en = this->my_pci_cfg_hdr[0xA0]; + + for (int bank = 0; bank < 8; bank++) { + if (bank_en & (1 << bank)) { + if (bank < 4) { + mem_start = READ_DWORD_LE(&this->my_pci_cfg_hdr[0x80]); + ext_mem_start = READ_DWORD_LE(&this->my_pci_cfg_hdr[0x88]); + mem_end = READ_DWORD_LE(&this->my_pci_cfg_hdr[0x90]); + ext_mem_end = READ_DWORD_LE(&this->my_pci_cfg_hdr[0x98]); + } else { + mem_start = READ_DWORD_LE(&this->my_pci_cfg_hdr[0x84]); + ext_mem_start = READ_DWORD_LE(&this->my_pci_cfg_hdr[0x8C]); + mem_end = READ_DWORD_LE(&this->my_pci_cfg_hdr[0x94]); + ext_mem_end = READ_DWORD_LE(&this->my_pci_cfg_hdr[0x9C]); + } + bank_start = (((ext_mem_start >> bank * 8) & 3) << 30) | + (((mem_start >> bank * 8) & 0xFF) << 20); + bank_end = (((ext_mem_end >> bank * 8) & 3) << 30) | + (((mem_end >> bank * 8) & 0xFF) << 20) | 0xFFFFFUL; + if (bank && bank_start != ram_size) + std::cout << "MPC106 error: RAM not contiguous!" << std::endl; + ram_size += bank_end + 1; + } + } + + if (!this->add_ram_region(0, ram_size)) { + std::cout << "MPC106 RAM allocation failed!" << std::endl; + } +} diff --git a/devices/mpc106.h b/devices/mpc106.h index c5ddb8f..8166dd7 100644 --- a/devices/mpc106.h +++ b/devices/mpc106.h @@ -58,6 +58,8 @@ protected: //bool pci_register_device(int dev_num, PCIDevice *dev_instance); bool pci_register_mmio_region(uint32_t start_addr, uint32_t size, PCIDevice *obj); + void setup_ram(void); + private: uint8_t my_pci_cfg_hdr[256] = { 0x57, 0x10, // vendor ID: Motorola diff --git a/main.cpp b/main.cpp index c5fe13a..6f3af38 100644 --- a/main.cpp +++ b/main.cpp @@ -551,8 +551,7 @@ int main(int argc, char **argv) cout << "Initialize Gossamer hardware..."; MPC106 *mpc106 = new MPC106(); mem_ctrl_instance = mpc106; - if (!mem_ctrl_instance->add_rom_region(0xFFC00000, 0x400000) || - !mem_ctrl_instance->add_ram_region(0x00000000, 0x800000)) { + if (!mem_ctrl_instance->add_rom_region(0xFFC00000, 0x400000)) { cout << "failure!\n" << endl; delete(mem_ctrl_instance); romFile.close();