diff --git a/core/bitops.h b/core/bitops.h index a4c34d0..0025017 100644 --- a/core/bitops.h +++ b/core/bitops.h @@ -88,4 +88,9 @@ inline void set_bit(T &val, const int bit_num) { val |= ((T)1 << bit_num); } +static inline uint32_t extract_with_wrap_around(uint32_t val, int pos, int size) { + return (uint32_t)((((uint64_t)val << 32) | val) >> ((8 - (pos & 3) - size) << 3)) & + ((1LL << (size << 3)) - 1); +} + #endif // BIT_OPS_H diff --git a/devices/memctrl/hammerhead.h b/devices/memctrl/hammerhead.h index 534f1de..c2ec9d1 100644 --- a/devices/memctrl/hammerhead.h +++ b/devices/memctrl/hammerhead.h @@ -38,13 +38,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. #include <memory> namespace Hammerhead { - -#define RISC_MACHINE 0x3 -#define MACH_TYPE_TNT 0x1 -#define EXTENDED_ID_TNT 0x1 // examine some other registers to get full ID -#define MACH_TYPE_CATALYST 0x0 -#define HH_CPU_ID_TNT ((RISC_MACHINE << 4) | (EXTENDED_ID_TNT << 3) | MACH_TYPE_TNT) -#define HH_CPU_ID_CATALYST ((RISC_MACHINE << 4) | 0 | MACH_TYPE_CATALYST) + #define RISC_MACHINE 0x3 + #define MACH_TYPE_TNT 0x1 + #define EXTENDED_ID 0x1 // examine some other registers to get full ID + #define HH_CPU_ID_TNT ((RISC_MACHINE << 4) | (EXTENDED_ID << 3) | MACH_TYPE_TNT) // constants for the MBID field of the MOTHERBOARD_ID register enum { diff --git a/devices/memctrl/platinum.cpp b/devices/memctrl/platinum.cpp index 9d010d7..3eb1484 100644 --- a/devices/memctrl/platinum.cpp +++ b/devices/memctrl/platinum.cpp @@ -101,6 +101,8 @@ int PlatinumCtrl::device_postinit() { } uint32_t PlatinumCtrl::read(uint32_t rgn_start, uint32_t offset, int size) { + uint32_t value; + if (rgn_start == VRAM_REGION_BASE) { if (offset < this->vram_size) { // HACK: half bank configurations should return invalid data @@ -117,8 +119,6 @@ uint32_t PlatinumCtrl::read(uint32_t rgn_start, uint32_t offset, int size) { } } - uint32_t value; - switch (offset >> 4) { case PlatinumReg::CPU_ID: value = this->cpu_id; @@ -186,8 +186,8 @@ uint32_t PlatinumCtrl::read(uint32_t rgn_start, uint32_t offset, int size) { case PlatinumReg::IRIDIUM_CONFIG: value = this->iridium_cfg; break; - case PlatinumReg::_4B: - value = this->_4b; + case PlatinumReg::POWER_DOWN_CTRL: + value = this->power_down_ctrl; break; default: LOG_F(WARNING, "%s: unknown register read at offset 0x%X", this->name.c_str(), @@ -195,9 +195,10 @@ uint32_t PlatinumCtrl::read(uint32_t rgn_start, uint32_t offset, int size) { value = 0; } - uint32_t result = (uint32_t)( (((uint64_t)value << 32) | value) >> ((8 - (offset & 3) - size) << 3)) & ( (1LL << (size << 3)) - 1 ); - - return result; + if (size == 4) + return value; + else + return extract_with_wrap_around(value, offset, size); } void PlatinumCtrl::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size) @@ -328,8 +329,10 @@ void PlatinumCtrl::write(uint32_t rgn_start, uint32_t offset, uint32_t value, in LOG_F(ERROR, "%s: little-endian system bus is not implemented", this->name.c_str()); this->iridium_cfg = (this->iridium_cfg & ~7) | (value & 7); break; - case PlatinumReg::_4B: - this->_4b = value; + case PlatinumReg::POWER_DOWN_CTRL: + this->power_down_ctrl = value; + if (value & 1) + LOG_F(INFO, "%s: power down mode enabled", this->name.c_str()); break; default: LOG_F(WARNING, "%s: unknown register write at offset 0x%X", this->name.c_str(), diff --git a/devices/memctrl/platinum.h b/devices/memctrl/platinum.h index 05424ca..68598f9 100644 --- a/devices/memctrl/platinum.h +++ b/devices/memctrl/platinum.h @@ -167,7 +167,7 @@ enum PlatinumReg : uint32_t { // Iridium datapath registers IRIDIUM_CONFIG = 0x4A, // write 4 - _4B = 0x4B, // read ; write 1 + POWER_DOWN_CTRL = 0x4B, // 1-bit register, writing "1" enables power down mode }; #define REG_TO_INDEX(reg) ((reg) - FIRST_SWATCH) @@ -259,7 +259,7 @@ private: uint32_t swatch_config = 0xFFD; uint32_t swatch_params[17] = {}; uint32_t timing_adjust = 0; - uint32_t _4b = 0; + uint32_t power_down_ctrl = 0; // interrupt related state uint32_t swatch_int_mask = 0;