From: George Wright Date: Thu, 25 Jun 2026 02:27:01 +0000 (-0700) Subject: sa1100: add initial memory controller implementation X-Git-Url: http://git.gwright.org.uk/?a=commitdiff_plain;h=b73f829e536d2fd7afb7122a8b2713a83ec1622b;p=WindEmu.git sa1100: add initial memory controller implementation --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f957b7..5b875a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ set(WIND_CORE_SOURCES WindCore/series5mx/windermere.cpp WindCore/series7/gpio_controller.cpp WindCore/series7/lcd_controller.cpp + WindCore/series7/memory_controller.cpp WindCore/series7/os_timer.cpp WindCore/series7/reset_controller.cpp WindCore/series7/rtc.cpp diff --git a/WindCore/series7/memory_controller.cpp b/WindCore/series7/memory_controller.cpp new file mode 100644 index 0000000..f4a5cfc --- /dev/null +++ b/WindCore/series7/memory_controller.cpp @@ -0,0 +1,187 @@ +// ARMware - an ARM emulator +// Copyright (C) <2007> Wei Hu +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#include "memory_controller.h" + +#include "logger.h" + +namespace SA1100 { + +void MemoryController::initRegisters() { + mMDCNFG = 0; + mMDCAS00 = 0; + mMDCAS01 = 0; + mMDCAS02 = 0; + mMSC0 = 0; + mMSC1 = 0; + mMECR = 0; + mMDREFR = 0; + mMDCAS20 = 0; + mMDCAS21 = 0; + mMDCAS22 = 0; + mMSC2 = 0; + mSMCNFG = 0; +} + +void MemoryController::reset() { + // :NOTE: Wei 2004-Jan-18: + // + // Bits 0, 1, 16, 17 will reset to 0 when reset. + mMDCNFG &= ~((1 << 0) | (1 << 1) | (1 << 16) | (1 << 17)); + + // :NOTE: Wei 2003-Dec-11: + // + // I assume all of the bits which have unknown values when reset have value 0. + mMDREFR = + static_cast((1 << 31) | (1 << 26) | (1 << 22) | (1 << 18)); + + // :NOTE: Wei 2003-Dec-11: + // + // I assume all of the bits which have unknown values when reset have value 0. + mMDCAS00 = (1 << 10) | (1 << 8) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 3) | + (1 << 2) | (1 << 1) | 1; + mMDCAS01 = mMDCAS00; + mMDCAS02 = mMDCAS00; + mMDCAS20 = mMDCAS00; + mMDCAS21 = mMDCAS00; + mMDCAS22 = mMDCAS00; + + // :NOTE: Wei 2003-Dec-11: + // + // I assume all of the bits which have unknown values when reset have value 0. + // + // :SA-1110 Developer's Manual: p.141: Wei 2004-Jun-09: + // + // On iPaq H3600, RBW0 have to be 0 to indicate 32-bit 'ROM bus width'. + mMSC0 = (1 << 15) | (1 << 14) | (1 << 13) | (1 << 12) | (1 << 11) | + (1 << 10) | (1 << 9) | (1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | + (1 << 4) | (1 << 3); + + // :NOTE: Wei 2003-Dec-11: + // + // I assume all of the bits which have unknown values when reset have value 0. + mSMCNFG = (1 << 15) | (1 << 14) | (1 << 6); +} + +uint32_t MemoryController::read32(const uint32_t address) const { + switch (address) { + case MDCNFG: + LOG_REG_R("MemoryController MDCNFG", address, mMDCNFG); + return mMDCNFG; + case MDCAS00: + LOG_REG_R("MemoryController MDCAS00", address, mMDCAS00); + return mMDCAS00; + case MDCAS01: + LOG_REG_R("MemoryController MDCAS01", address, mMDCAS01); + return mMDCAS01; + case MDCAS02: + LOG_REG_R("MemoryController MDCAS02", address, mMDCAS02); + return mMDCAS02; + case MSC0: + LOG_REG_R("MemoryController MSC0", address, mMSC0); + return mMSC0; + case MSC1: + LOG_REG_R("MemoryController MSC1", address, mMSC1); + return mMSC1; + case MECR: + LOG_REG_R("MemoryController MECR", address, mMECR); + return mMECR; + case MDREFR: + LOG_REG_R("MemoryController MDREFR", address, mMDREFR); + return mMDREFR; + case MDCAS20: + LOG_REG_R("MemoryController MDCAS20", address, mMDCAS20); + return mMDCAS20; + case MDCAS21: + LOG_REG_R("MemoryController MDCAS21", address, mMDCAS21); + return mMDCAS21; + case MDCAS22: + LOG_REG_R("MemoryController MDCAS22", address, mMDCAS22); + return mMDCAS22; + case MSC2: + LOG_REG_R("MemoryController MSC2", address, mMSC2); + return mMSC2; + case SMCNFG: + LOG_REG_R("MemoryController SMCNFG", address, mSMCNFG); + return mSMCNFG; + default: + LOG_REG_R("MemoryController Unknown", address, 0); + return 0; + } +} + +void MemoryController::write32(const uint32_t address, const uint32_t value) { + switch (address) { + case MDCNFG: + LOG_REG_W("MemoryController MDCNFG", address, value); + mMDCNFG = value; + break; + case MDCAS00: + LOG_REG_W("MemoryController MDCAS00", address, value); + mMDCAS00 = value; + break; + case MDCAS01: + LOG_REG_W("MemoryController MDCAS01", address, value); + mMDCAS01 = value; + break; + case MDCAS02: + LOG_REG_W("MemoryController MDCAS02", address, value); + mMDCAS02 = value; + break; + case MSC0: + LOG_REG_W("MemoryController MSC0", address, value); + mMSC0 = value; + break; + case MSC1: + LOG_REG_W("MemoryController MSC1", address, value); + mMSC1 = value; + break; + case MECR: + LOG_REG_W("MemoryController MECR", address, value); + mMECR = value; + break; + case MDREFR: + LOG_REG_W("MemoryController MDREFR", address, value); + mMDREFR = value; + break; + case MDCAS20: + LOG_REG_W("MemoryController MDCAS20", address, value); + mMDCAS20 = value; + break; + case MDCAS21: + LOG_REG_W("MemoryController MDCAS21", address, value); + mMDCAS21 = value; + break; + case MDCAS22: + LOG_REG_W("MemoryController MDCAS22", address, value); + mMDCAS22 = value; + break; + case MSC2: + LOG_REG_W("MemoryController MSC2", address, value); + mMSC2 = value; + break; + case SMCNFG: + LOG_REG_W("MemoryController SMCNFG", address, value); + mSMCNFG = value; + break; + default: + LOG_REG_W("MemoryController Unknown", address, value); + break; + } +} + +} // namespace SA1100 diff --git a/WindCore/series7/memory_controller.h b/WindCore/series7/memory_controller.h new file mode 100644 index 0000000..15bf561 --- /dev/null +++ b/WindCore/series7/memory_controller.h @@ -0,0 +1,70 @@ +// ARMware - an ARM emulator +// Copyright (C) <2007> Wei Hu +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef MEMORY_CONTROLLER_H +#define MEMORY_CONTROLLER_H + +#include + +namespace SA1100 { + +class MemoryController { +public: + MemoryController() { initRegisters(); } + + void reset(); + + uint32_t read32(const uint32_t address) const; + void write32(const uint32_t address, const uint32_t value); + +private: + void initRegisters(); + + enum { + MDCNFG = 0xA0000000, + MDCAS00 = 0xA0000004, + MDCAS01 = 0xA0000008, + MDCAS02 = 0xA000000C, + MSC0 = 0xA0000010, + MSC1 = 0xA0000014, + MECR = 0xA0000018, + MDREFR = 0xA000001C, + MDCAS20 = 0xA0000020, + MDCAS21 = 0xA0000024, + MDCAS22 = 0xA0000028, + MSC2 = 0xA000002C, + SMCNFG = 0xA0000030 + }; + + uint32_t mMDCNFG; // DRAM Configuration register + uint32_t mMDCAS00; // CAS waveform rotate register 0 for DRAM bank pair 0/1 + uint32_t mMDCAS01; // CAS waveform rotate register 1 for DRAM bank pair 0/1 + uint32_t mMDCAS02; // CAS waveform rotate register 2 for DRAM bank pair 0/1 + uint32_t mMSC0; // Static memory control register 0 + uint32_t mMSC1; // Static memory control register 1 + uint32_t mMECR; // Expansion memory (PC-Card) bus configuration register + uint32_t mMDREFR; // DRAM refresh control register + uint32_t mMDCAS20; // CAS waveform rotate register 0 for DRAM bank pair 2/3 + uint32_t mMDCAS21; // CAS waveform rotate register 1 for DRAM bank pair 2/3 + uint32_t mMDCAS22; // CAS waveform rotate register 2 for DRAM bank pair 2/3 + uint32_t mMSC2; // Static memory control register 2 + uint32_t mSMCNFG; // SMROM configuration register +}; + +} // namespace SA1100 + +#endif // MEMORY_CONTROLLER_H