bus.cpp (69192B)
1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #include "bus.h" 5 #include "bios.h" 6 #include "cdrom.h" 7 #include "cpu_code_cache.h" 8 #include "cpu_core.h" 9 #include "cpu_core_private.h" 10 #include "cpu_disasm.h" 11 #include "dma.h" 12 #include "gpu.h" 13 #include "host.h" 14 #include "interrupt_controller.h" 15 #include "mdec.h" 16 #include "pad.h" 17 #include "psf_loader.h" 18 #include "settings.h" 19 #include "sio.h" 20 #include "spu.h" 21 #include "system.h" 22 #include "timers.h" 23 #include "timing_event.h" 24 25 #include "util/cd_image.h" 26 #include "util/state_wrapper.h" 27 28 #include "common/align.h" 29 #include "common/assert.h" 30 #include "common/error.h" 31 #include "common/file_system.h" 32 #include "common/intrin.h" 33 #include "common/log.h" 34 #include "common/memmap.h" 35 #include "common/path.h" 36 37 #include <cstdio> 38 #include <tuple> 39 #include <utility> 40 41 Log_SetChannel(Bus); 42 43 // TODO: Get rid of page code bits, instead use page faults to track SMC. 44 45 // Exports for external debugger access 46 #ifndef __ANDROID__ 47 namespace Exports { 48 49 extern "C" { 50 #ifdef _WIN32 51 _declspec(dllexport) uintptr_t RAM; 52 _declspec(dllexport) u32 RAM_SIZE, RAM_MASK; 53 #else 54 __attribute__((visibility("default"), used)) uintptr_t RAM; 55 __attribute__((visibility("default"), used)) u32 RAM_SIZE, RAM_MASK; 56 #endif 57 } 58 59 } // namespace Exports 60 #endif 61 62 namespace Bus { 63 64 namespace { 65 union MEMDELAY 66 { 67 u32 bits; 68 69 BitField<u32, u8, 4, 4> access_time; // cycles 70 BitField<u32, bool, 8, 1> use_com0_time; 71 BitField<u32, bool, 9, 1> use_com1_time; 72 BitField<u32, bool, 10, 1> use_com2_time; 73 BitField<u32, bool, 11, 1> use_com3_time; 74 BitField<u32, bool, 12, 1> data_bus_16bit; 75 BitField<u32, u8, 16, 5> memory_window_size; 76 77 static constexpr u32 WRITE_MASK = 0b10101111'00011111'11111111'11111111; 78 }; 79 80 union COMDELAY 81 { 82 u32 bits; 83 84 BitField<u32, u8, 0, 4> com0; 85 BitField<u32, u8, 4, 4> com1; 86 BitField<u32, u8, 8, 4> com2; 87 BitField<u32, u8, 12, 4> com3; 88 BitField<u32, u8, 16, 2> comunk; 89 90 static constexpr u32 WRITE_MASK = 0b00000000'00000011'11111111'11111111; 91 }; 92 93 union MEMCTRL 94 { 95 u32 regs[MEMCTRL_REG_COUNT]; 96 97 struct 98 { 99 u32 exp1_base; 100 u32 exp2_base; 101 MEMDELAY exp1_delay_size; 102 MEMDELAY exp3_delay_size; 103 MEMDELAY bios_delay_size; 104 MEMDELAY spu_delay_size; 105 MEMDELAY cdrom_delay_size; 106 MEMDELAY exp2_delay_size; 107 COMDELAY common_delay; 108 }; 109 }; 110 111 union RAM_SIZE_REG 112 { 113 u32 bits; 114 115 // All other bits unknown/unhandled. 116 BitField<u32, u8, 9, 3> memory_window; 117 }; 118 } // namespace 119 120 static void* s_shmem_handle = nullptr; 121 static std::string s_shmem_name; 122 123 std::bitset<RAM_8MB_CODE_PAGE_COUNT> g_ram_code_bits{}; 124 u8* g_ram = nullptr; 125 u8* g_unprotected_ram = nullptr; 126 u32 g_ram_size = 0; 127 u32 g_ram_mapped_size = 0; 128 u32 g_ram_mask = 0; 129 u8* g_bios = nullptr; 130 void** g_memory_handlers = nullptr; 131 void** g_memory_handlers_isc = nullptr; 132 133 std::array<TickCount, 3> g_exp1_access_time = {}; 134 std::array<TickCount, 3> g_exp2_access_time = {}; 135 std::array<TickCount, 3> g_bios_access_time = {}; 136 std::array<TickCount, 3> g_cdrom_access_time = {}; 137 std::array<TickCount, 3> g_spu_access_time = {}; 138 139 static std::vector<u8> s_exp1_rom; 140 141 static MEMCTRL s_MEMCTRL = {}; 142 static RAM_SIZE_REG s_RAM_SIZE = {}; 143 144 static std::string s_tty_line_buffer; 145 146 static CPUFastmemMode s_fastmem_mode = CPUFastmemMode::Disabled; 147 148 #ifdef ENABLE_MMAP_FASTMEM 149 static SharedMemoryMappingArea s_fastmem_arena; 150 static std::vector<std::pair<u8*, size_t>> s_fastmem_ram_views; 151 #endif 152 153 static u8** s_fastmem_lut = nullptr; 154 155 static bool s_kernel_initialize_hook_run = false; 156 157 static bool AllocateMemoryMap(bool export_shared_memory, Error* error); 158 static void ReleaseMemoryMap(); 159 static void SetRAMSize(bool enable_8mb_ram); 160 161 static std::tuple<TickCount, TickCount, TickCount> CalculateMemoryTiming(MEMDELAY mem_delay, COMDELAY common_delay); 162 static void RecalculateMemoryTimings(); 163 164 static u8* GetLUTFastmemPointer(u32 address, u8* ram_ptr); 165 166 static void SetRAMPageWritable(u32 page_index, bool writable); 167 168 static void KernelInitializedHook(); 169 static bool SideloadEXE(const std::string& path, Error* error); 170 171 static void SetHandlers(); 172 static void UpdateMappedRAMSize(); 173 174 template<typename FP> 175 static FP* OffsetHandlerArray(void** handlers, MemoryAccessSize size, MemoryAccessType type); 176 } // namespace Bus 177 178 namespace MemoryMap { 179 static constexpr size_t RAM_OFFSET = 0; 180 static constexpr size_t RAM_SIZE = Bus::RAM_8MB_SIZE; 181 static constexpr size_t BIOS_OFFSET = RAM_OFFSET + RAM_SIZE; 182 static constexpr size_t BIOS_SIZE = Bus::BIOS_SIZE; 183 static constexpr size_t LUT_OFFSET = BIOS_OFFSET + BIOS_SIZE; 184 static constexpr size_t LUT_SIZE = (sizeof(void*) * Bus::MEMORY_LUT_SLOTS) * 2; // normal and isolated 185 static constexpr size_t TOTAL_SIZE = LUT_OFFSET + LUT_SIZE; 186 } // namespace MemoryMap 187 188 #define FIXUP_HALFWORD_OFFSET(size, offset) ((size >= MemoryAccessSize::HalfWord) ? (offset) : ((offset) & ~1u)) 189 #define FIXUP_HALFWORD_READ_VALUE(size, offset, value) \ 190 ((size >= MemoryAccessSize::HalfWord) ? (value) : ((value) >> (((offset) & u32(1)) * 8u))) 191 #define FIXUP_HALFWORD_WRITE_VALUE(size, offset, value) \ 192 ((size >= MemoryAccessSize::HalfWord) ? (value) : ((value) << (((offset) & u32(1)) * 8u))) 193 194 #define FIXUP_WORD_OFFSET(size, offset) ((size == MemoryAccessSize::Word) ? (offset) : ((offset) & ~3u)) 195 #define FIXUP_WORD_READ_VALUE(size, offset, value) \ 196 ((size == MemoryAccessSize::Word) ? (value) : ((value) >> (((offset) & 3u) * 8))) 197 #define FIXUP_WORD_WRITE_VALUE(size, offset, value) \ 198 ((size == MemoryAccessSize::Word) ? (value) : ((value) << (((offset) & 3u) * 8))) 199 200 bool Bus::AllocateMemoryMap(bool export_shared_memory, Error* error) 201 { 202 INFO_LOG("Allocating{} shared memory map.", export_shared_memory ? " EXPORTED" : ""); 203 if (export_shared_memory) 204 { 205 s_shmem_name = MemMap::GetFileMappingName("duckstation"); 206 INFO_LOG("Shared memory object name is \"{}\".", s_shmem_name); 207 } 208 s_shmem_handle = MemMap::CreateSharedMemory(s_shmem_name.c_str(), MemoryMap::TOTAL_SIZE, error); 209 if (!s_shmem_handle) 210 { 211 #ifndef __linux__ 212 Error::AddSuffix(error, "\nYou may need to close some programs to free up additional memory."); 213 #else 214 Error::AddSuffix( 215 error, "\nYou may need to close some programs to free up additional memory, or increase the size of /dev/shm."); 216 #endif 217 return false; 218 } 219 220 g_ram = static_cast<u8*>(MemMap::MapSharedMemory(s_shmem_handle, MemoryMap::RAM_OFFSET, nullptr, MemoryMap::RAM_SIZE, 221 PageProtect::ReadWrite)); 222 g_unprotected_ram = static_cast<u8*>(MemMap::MapSharedMemory(s_shmem_handle, MemoryMap::RAM_OFFSET, nullptr, 223 MemoryMap::RAM_SIZE, PageProtect::ReadWrite)); 224 if (!g_ram || !g_unprotected_ram) 225 { 226 Error::SetStringView(error, "Failed to map memory for RAM"); 227 ReleaseMemoryMap(); 228 return false; 229 } 230 231 VERBOSE_LOG("RAM is mapped at {}.", static_cast<void*>(g_ram)); 232 233 g_bios = static_cast<u8*>(MemMap::MapSharedMemory(s_shmem_handle, MemoryMap::BIOS_OFFSET, nullptr, 234 MemoryMap::BIOS_SIZE, PageProtect::ReadWrite)); 235 if (!g_bios) 236 { 237 Error::SetStringView(error, "Failed to map memory for BIOS"); 238 ReleaseMemoryMap(); 239 return false; 240 } 241 242 VERBOSE_LOG("BIOS is mapped at {}.", static_cast<void*>(g_bios)); 243 244 g_memory_handlers = static_cast<void**>(MemMap::MapSharedMemory(s_shmem_handle, MemoryMap::LUT_OFFSET, nullptr, 245 MemoryMap::LUT_SIZE, PageProtect::ReadWrite)); 246 if (!g_memory_handlers) 247 { 248 Error::SetStringView(error, "Failed to map memory for LUTs"); 249 ReleaseMemoryMap(); 250 return false; 251 } 252 253 VERBOSE_LOG("LUTs are mapped at {}.", static_cast<void*>(g_memory_handlers)); 254 g_memory_handlers_isc = g_memory_handlers + MEMORY_LUT_SLOTS; 255 SetHandlers(); 256 257 #ifndef __ANDROID__ 258 Exports::RAM = reinterpret_cast<uintptr_t>(g_unprotected_ram); 259 #endif 260 261 return true; 262 } 263 264 void Bus::ReleaseMemoryMap() 265 { 266 #ifndef __ANDROID__ 267 Exports::RAM = 0; 268 Exports::RAM_SIZE = 0; 269 Exports::RAM_MASK = 0; 270 #endif 271 272 g_memory_handlers_isc = nullptr; 273 if (g_memory_handlers) 274 { 275 MemMap::UnmapSharedMemory(g_memory_handlers, MemoryMap::LUT_SIZE); 276 g_memory_handlers = nullptr; 277 } 278 279 if (g_bios) 280 { 281 MemMap::UnmapSharedMemory(g_bios, MemoryMap::BIOS_SIZE); 282 g_bios = nullptr; 283 } 284 285 if (g_unprotected_ram) 286 { 287 MemMap::UnmapSharedMemory(g_unprotected_ram, MemoryMap::RAM_SIZE); 288 g_unprotected_ram = nullptr; 289 } 290 291 if (g_ram) 292 { 293 MemMap::UnmapSharedMemory(g_ram, MemoryMap::RAM_SIZE); 294 g_ram = nullptr; 295 } 296 297 if (s_shmem_handle) 298 { 299 MemMap::DestroySharedMemory(s_shmem_handle); 300 s_shmem_handle = nullptr; 301 302 if (!s_shmem_name.empty()) 303 { 304 MemMap::DeleteSharedMemory(s_shmem_name.c_str()); 305 s_shmem_name = {}; 306 } 307 } 308 } 309 310 bool Bus::AllocateMemory(bool export_shared_memory, Error* error) 311 { 312 if (!AllocateMemoryMap(export_shared_memory, error)) 313 return false; 314 315 #ifdef ENABLE_MMAP_FASTMEM 316 if (!s_fastmem_arena.Create(FASTMEM_ARENA_SIZE)) 317 { 318 Error::SetStringView(error, "Failed to create fastmem arena"); 319 ReleaseMemory(); 320 return false; 321 } 322 323 INFO_LOG("Fastmem base: {}", static_cast<void*>(s_fastmem_arena.BasePointer())); 324 #endif 325 326 return true; 327 } 328 329 void Bus::ReleaseMemory() 330 { 331 #ifdef ENABLE_MMAP_FASTMEM 332 DebugAssert(s_fastmem_ram_views.empty()); 333 s_fastmem_arena.Destroy(); 334 #endif 335 336 std::free(s_fastmem_lut); 337 s_fastmem_lut = nullptr; 338 339 ReleaseMemoryMap(); 340 } 341 342 bool Bus::ReallocateMemoryMap(bool export_shared_memory, Error* error) 343 { 344 // Need to back up RAM+BIOS. 345 DynamicHeapArray<u8> ram_backup; 346 DynamicHeapArray<u8> bios_backup; 347 348 if (System::IsValid()) 349 { 350 CPU::CodeCache::InvalidateAllRAMBlocks(); 351 UpdateFastmemViews(CPUFastmemMode::Disabled); 352 353 ram_backup.resize(RAM_8MB_SIZE); 354 std::memcpy(ram_backup.data(), g_unprotected_ram, RAM_8MB_SIZE); 355 bios_backup.resize(BIOS_SIZE); 356 std::memcpy(bios_backup.data(), g_bios, BIOS_SIZE); 357 } 358 359 ReleaseMemoryMap(); 360 if (!AllocateMemoryMap(export_shared_memory, error)) [[unlikely]] 361 return false; 362 363 if (System::IsValid()) 364 { 365 UpdateMappedRAMSize(); 366 std::memcpy(g_unprotected_ram, ram_backup.data(), RAM_8MB_SIZE); 367 std::memcpy(g_bios, bios_backup.data(), BIOS_SIZE); 368 UpdateFastmemViews(g_settings.cpu_fastmem_mode); 369 } 370 371 return true; 372 } 373 374 void Bus::CleanupMemoryMap() 375 { 376 #if !defined(_WIN32) && !defined(__ANDROID__) 377 // This is only needed on Linux. 378 if (!s_shmem_name.empty()) 379 MemMap::DeleteSharedMemory(s_shmem_name.c_str()); 380 #endif 381 } 382 383 bool Bus::Initialize() 384 { 385 SetRAMSize(g_settings.enable_8mb_ram); 386 Reset(); 387 return true; 388 } 389 390 void Bus::SetRAMSize(bool enable_8mb_ram) 391 { 392 g_ram_size = enable_8mb_ram ? RAM_8MB_SIZE : RAM_2MB_SIZE; 393 g_ram_mask = enable_8mb_ram ? RAM_8MB_MASK : RAM_2MB_MASK; 394 395 #ifndef __ANDROID__ 396 Exports::RAM_SIZE = g_ram_size; 397 Exports::RAM_MASK = g_ram_mask; 398 #endif 399 } 400 401 void Bus::Shutdown() 402 { 403 UpdateFastmemViews(CPUFastmemMode::Disabled); 404 CPU::g_state.fastmem_base = nullptr; 405 406 g_ram_mask = 0; 407 g_ram_size = 0; 408 } 409 410 void Bus::Reset() 411 { 412 std::memset(g_ram, 0, g_ram_size); 413 s_MEMCTRL.exp1_base = 0x1F000000; 414 s_MEMCTRL.exp2_base = 0x1F802000; 415 s_MEMCTRL.exp1_delay_size.bits = 0x0013243F; 416 s_MEMCTRL.exp3_delay_size.bits = 0x00003022; 417 s_MEMCTRL.bios_delay_size.bits = 0x0013243F; 418 s_MEMCTRL.spu_delay_size.bits = 0x200931E1; 419 s_MEMCTRL.cdrom_delay_size.bits = 0x00020843; 420 s_MEMCTRL.exp2_delay_size.bits = 0x00070777; 421 s_MEMCTRL.common_delay.bits = 0x00031125; 422 g_ram_code_bits = {}; 423 s_kernel_initialize_hook_run = false; 424 RecalculateMemoryTimings(); 425 426 // Avoid remapping if unchanged. 427 if (s_RAM_SIZE.bits != 0x00000B88) 428 { 429 s_RAM_SIZE.bits = 0x00000B88; 430 UpdateMappedRAMSize(); 431 } 432 } 433 434 bool Bus::DoState(StateWrapper& sw) 435 { 436 u32 ram_size = g_ram_size; 437 sw.DoEx(&ram_size, 52, static_cast<u32>(RAM_2MB_SIZE)); 438 if (ram_size != g_ram_size) 439 { 440 const bool using_8mb_ram = (ram_size == RAM_8MB_SIZE); 441 SetRAMSize(using_8mb_ram); 442 UpdateFastmemViews(s_fastmem_mode); 443 CPU::UpdateMemoryPointers(); 444 } 445 446 sw.Do(&g_exp1_access_time); 447 sw.Do(&g_exp2_access_time); 448 sw.Do(&g_bios_access_time); 449 sw.Do(&g_cdrom_access_time); 450 sw.Do(&g_spu_access_time); 451 sw.DoBytes(g_ram, g_ram_size); 452 453 if (sw.GetVersion() < 58) [[unlikely]] 454 { 455 WARNING_LOG("Overwriting loaded BIOS with old save state."); 456 sw.DoBytes(g_bios, BIOS_SIZE); 457 } 458 459 sw.DoArray(s_MEMCTRL.regs, countof(s_MEMCTRL.regs)); 460 461 const RAM_SIZE_REG old_ram_size_reg = s_RAM_SIZE; 462 sw.Do(&s_RAM_SIZE.bits); 463 if (s_RAM_SIZE.memory_window != old_ram_size_reg.memory_window) 464 UpdateMappedRAMSize(); 465 466 sw.Do(&s_tty_line_buffer); 467 468 sw.DoEx(&s_kernel_initialize_hook_run, 68, true); 469 470 return !sw.HasError(); 471 } 472 473 std::tuple<TickCount, TickCount, TickCount> Bus::CalculateMemoryTiming(MEMDELAY mem_delay, COMDELAY common_delay) 474 { 475 // from nocash spec 476 s32 first = 0, seq = 0, min = 0; 477 if (mem_delay.use_com0_time) 478 { 479 first += s32(common_delay.com0) - 1; 480 seq += s32(common_delay.com0) - 1; 481 } 482 if (mem_delay.use_com2_time) 483 { 484 first += s32(common_delay.com2); 485 seq += s32(common_delay.com2); 486 } 487 if (mem_delay.use_com3_time) 488 { 489 min = s32(common_delay.com3); 490 } 491 if (first < 6) 492 first++; 493 494 first = first + s32(mem_delay.access_time) + 2; 495 seq = seq + s32(mem_delay.access_time) + 2; 496 497 if (first < (min + 6)) 498 first = min + 6; 499 if (seq < (min + 2)) 500 seq = min + 2; 501 502 const TickCount byte_access_time = first; 503 const TickCount halfword_access_time = mem_delay.data_bus_16bit ? first : (first + seq); 504 const TickCount word_access_time = mem_delay.data_bus_16bit ? (first + seq) : (first + seq + seq + seq); 505 return std::tie(std::max(byte_access_time - 1, 0), std::max(halfword_access_time - 1, 0), 506 std::max(word_access_time - 1, 0)); 507 } 508 509 void Bus::RecalculateMemoryTimings() 510 { 511 std::tie(g_bios_access_time[0], g_bios_access_time[1], g_bios_access_time[2]) = 512 CalculateMemoryTiming(s_MEMCTRL.bios_delay_size, s_MEMCTRL.common_delay); 513 std::tie(g_cdrom_access_time[0], g_cdrom_access_time[1], g_cdrom_access_time[2]) = 514 CalculateMemoryTiming(s_MEMCTRL.cdrom_delay_size, s_MEMCTRL.common_delay); 515 std::tie(g_spu_access_time[0], g_spu_access_time[1], g_spu_access_time[2]) = 516 CalculateMemoryTiming(s_MEMCTRL.spu_delay_size, s_MEMCTRL.common_delay); 517 518 TRACE_LOG("BIOS Memory Timing: {} bit bus, byte={}, halfword={}, word={}", 519 s_MEMCTRL.bios_delay_size.data_bus_16bit ? 16 : 8, g_bios_access_time[0] + 1, g_bios_access_time[1] + 1, 520 g_bios_access_time[2] + 1); 521 TRACE_LOG("CDROM Memory Timing: {} bit bus, byte={}, halfword={}, word={}", 522 s_MEMCTRL.cdrom_delay_size.data_bus_16bit ? 16 : 8, g_cdrom_access_time[0] + 1, g_cdrom_access_time[1] + 1, 523 g_cdrom_access_time[2] + 1); 524 TRACE_LOG("SPU Memory Timing: {} bit bus, byte={}, halfword={}, word={}", 525 s_MEMCTRL.spu_delay_size.data_bus_16bit ? 16 : 8, g_spu_access_time[0] + 1, g_spu_access_time[1] + 1, 526 g_spu_access_time[2] + 1); 527 } 528 529 CPUFastmemMode Bus::GetFastmemMode() 530 { 531 return s_fastmem_mode; 532 } 533 534 void* Bus::GetFastmemBase(bool isc) 535 { 536 #ifdef ENABLE_MMAP_FASTMEM 537 if (s_fastmem_mode == CPUFastmemMode::MMap) 538 return isc ? nullptr : s_fastmem_arena.BasePointer(); 539 #endif 540 if (s_fastmem_mode == CPUFastmemMode::LUT) 541 return reinterpret_cast<u8*>(s_fastmem_lut + (isc ? (FASTMEM_LUT_SIZE * sizeof(void*)) : 0)); 542 543 return nullptr; 544 } 545 546 u8* Bus::GetLUTFastmemPointer(u32 address, u8* ram_ptr) 547 { 548 return ram_ptr - address; 549 } 550 551 void Bus::UpdateFastmemViews(CPUFastmemMode mode) 552 { 553 #ifndef ENABLE_MMAP_FASTMEM 554 Assert(mode != CPUFastmemMode::MMap); 555 #else 556 for (const auto& it : s_fastmem_ram_views) 557 s_fastmem_arena.Unmap(it.first, it.second); 558 s_fastmem_ram_views.clear(); 559 #endif 560 561 s_fastmem_mode = mode; 562 if (mode == CPUFastmemMode::Disabled) 563 return; 564 565 #ifdef ENABLE_MMAP_FASTMEM 566 if (mode == CPUFastmemMode::MMap) 567 { 568 auto MapRAM = [](u32 base_address) { 569 u8* map_address = s_fastmem_arena.BasePointer() + base_address; 570 if (!s_fastmem_arena.Map(s_shmem_handle, 0, map_address, g_ram_size, PageProtect::ReadWrite)) [[unlikely]] 571 { 572 ERROR_LOG("Failed to map RAM at fastmem area {} (offset 0x{:08X})", static_cast<void*>(map_address), 573 g_ram_size); 574 return; 575 } 576 577 // mark all pages with code as non-writable 578 for (u32 i = 0; i < static_cast<u32>(g_ram_code_bits.size()); i++) 579 { 580 if (g_ram_code_bits[i]) 581 { 582 u8* page_address = map_address + (i * HOST_PAGE_SIZE); 583 if (!MemMap::MemProtect(page_address, HOST_PAGE_SIZE, PageProtect::ReadOnly)) [[unlikely]] 584 { 585 ERROR_LOG("Failed to write-protect code page at {}", static_cast<void*>(page_address)); 586 s_fastmem_arena.Unmap(map_address, g_ram_size); 587 return; 588 } 589 } 590 } 591 592 s_fastmem_ram_views.emplace_back(map_address, g_ram_size); 593 }; 594 595 // KUSEG - cached 596 MapRAM(0x00000000); 597 598 // KSEG0 - cached 599 MapRAM(0x80000000); 600 601 // KSEG1 - uncached 602 MapRAM(0xA0000000); 603 604 return; 605 } 606 #endif 607 608 if (!s_fastmem_lut) 609 { 610 s_fastmem_lut = static_cast<u8**>(std::malloc(sizeof(u8*) * FASTMEM_LUT_SLOTS)); 611 Assert(s_fastmem_lut); 612 613 INFO_LOG("Fastmem base (software): {}", static_cast<void*>(s_fastmem_lut)); 614 } 615 616 // This assumes the top 4KB of address space is not mapped. It shouldn't be on any sane OSes. 617 for (u32 i = 0; i < FASTMEM_LUT_SLOTS; i++) 618 s_fastmem_lut[i] = GetLUTFastmemPointer(i << FASTMEM_LUT_PAGE_SHIFT, nullptr); 619 620 auto MapRAM = [](u32 base_address) { 621 u8* ram_ptr = g_ram + (base_address & g_ram_mask); 622 for (u32 address = 0; address < g_ram_size; address += FASTMEM_LUT_PAGE_SIZE) 623 { 624 const u32 lut_index = (base_address + address) >> FASTMEM_LUT_PAGE_SHIFT; 625 s_fastmem_lut[lut_index] = GetLUTFastmemPointer(base_address + address, ram_ptr); 626 ram_ptr += FASTMEM_LUT_PAGE_SIZE; 627 } 628 }; 629 630 // KUSEG - cached 631 MapRAM(0x00000000); 632 MapRAM(0x00200000); 633 MapRAM(0x00400000); 634 MapRAM(0x00600000); 635 636 // KSEG0 - cached 637 MapRAM(0x80000000); 638 MapRAM(0x80200000); 639 MapRAM(0x80400000); 640 MapRAM(0x80600000); 641 642 // KSEG1 - uncached 643 MapRAM(0xA0000000); 644 MapRAM(0xA0200000); 645 MapRAM(0xA0400000); 646 MapRAM(0xA0600000); 647 } 648 649 bool Bus::CanUseFastmemForAddress(VirtualMemoryAddress address) 650 { 651 const PhysicalMemoryAddress paddr = address & CPU::PHYSICAL_MEMORY_ADDRESS_MASK; 652 653 switch (s_fastmem_mode) 654 { 655 #ifdef ENABLE_MMAP_FASTMEM 656 case CPUFastmemMode::MMap: 657 { 658 // Currently since we don't map the mirrors, don't use fastmem for them. 659 // This is because the swapping of page code bits for SMC is too expensive. 660 return (paddr < g_ram_size); 661 } 662 #endif 663 664 case CPUFastmemMode::LUT: 665 return (paddr < RAM_MIRROR_END); 666 667 case CPUFastmemMode::Disabled: 668 default: 669 return false; 670 } 671 } 672 673 bool Bus::IsRAMCodePage(u32 index) 674 { 675 return g_ram_code_bits[index]; 676 } 677 678 void Bus::SetRAMCodePage(u32 index) 679 { 680 if (g_ram_code_bits[index]) 681 return; 682 683 // protect fastmem pages 684 g_ram_code_bits[index] = true; 685 SetRAMPageWritable(index, false); 686 } 687 688 void Bus::ClearRAMCodePage(u32 index) 689 { 690 if (!g_ram_code_bits[index]) 691 return; 692 693 // unprotect fastmem pages 694 g_ram_code_bits[index] = false; 695 SetRAMPageWritable(index, true); 696 } 697 698 void Bus::SetRAMPageWritable(u32 page_index, bool writable) 699 { 700 if (!MemMap::MemProtect(&g_ram[page_index * HOST_PAGE_SIZE], HOST_PAGE_SIZE, 701 writable ? PageProtect::ReadWrite : PageProtect::ReadOnly)) [[unlikely]] 702 { 703 ERROR_LOG("Failed to set RAM host page {} ({}) to {}", page_index, 704 reinterpret_cast<const void*>(&g_ram[page_index * HOST_PAGE_SIZE]), 705 writable ? "read-write" : "read-only"); 706 } 707 708 #ifdef ENABLE_MMAP_FASTMEM 709 if (s_fastmem_mode == CPUFastmemMode::MMap) 710 { 711 const PageProtect protect = writable ? PageProtect::ReadWrite : PageProtect::ReadOnly; 712 713 // unprotect fastmem pages 714 for (const auto& it : s_fastmem_ram_views) 715 { 716 u8* page_address = it.first + (page_index * HOST_PAGE_SIZE); 717 if (!MemMap::MemProtect(page_address, HOST_PAGE_SIZE, protect)) [[unlikely]] 718 { 719 ERROR_LOG("Failed to {} code page {} (0x{:08X}) @ {}", writable ? "unprotect" : "protect", page_index, 720 page_index * static_cast<u32>(HOST_PAGE_SIZE), static_cast<void*>(page_address)); 721 } 722 } 723 724 return; 725 } 726 #endif 727 } 728 729 void Bus::ClearRAMCodePageFlags() 730 { 731 g_ram_code_bits.reset(); 732 733 if (!MemMap::MemProtect(g_ram, RAM_8MB_SIZE, PageProtect::ReadWrite)) 734 ERROR_LOG("Failed to restore RAM protection to read-write."); 735 736 #ifdef ENABLE_MMAP_FASTMEM 737 if (s_fastmem_mode == CPUFastmemMode::MMap) 738 { 739 // unprotect fastmem pages 740 for (const auto& it : s_fastmem_ram_views) 741 { 742 if (!MemMap::MemProtect(it.first, it.second, PageProtect::ReadWrite)) 743 ERROR_LOG("Failed to unprotect code pages for fastmem view @ {}", static_cast<void*>(it.first)); 744 } 745 } 746 #endif 747 } 748 749 bool Bus::IsCodePageAddress(PhysicalMemoryAddress address) 750 { 751 return IsRAMAddress(address) ? g_ram_code_bits[(address & g_ram_mask) / HOST_PAGE_SIZE] : false; 752 } 753 754 bool Bus::HasCodePagesInRange(PhysicalMemoryAddress start_address, u32 size) 755 { 756 if (!IsRAMAddress(start_address)) 757 return false; 758 759 start_address = (start_address & g_ram_mask); 760 761 const u32 end_address = start_address + size; 762 while (start_address < end_address) 763 { 764 const u32 code_page_index = start_address / HOST_PAGE_SIZE; 765 if (g_ram_code_bits[code_page_index]) 766 return true; 767 768 start_address += HOST_PAGE_SIZE; 769 } 770 771 return false; 772 } 773 774 const TickCount* Bus::GetMemoryAccessTimePtr(PhysicalMemoryAddress address, MemoryAccessSize size) 775 { 776 // Currently only BIOS, but could be EXP1 as well. 777 if (address >= BIOS_BASE && address < (BIOS_BASE + BIOS_MIRROR_SIZE)) 778 return &g_bios_access_time[static_cast<size_t>(size)]; 779 780 return nullptr; 781 } 782 783 std::optional<Bus::MemoryRegion> Bus::GetMemoryRegionForAddress(PhysicalMemoryAddress address) 784 { 785 if (address < RAM_2MB_SIZE) 786 return MemoryRegion::RAM; 787 else if (address < RAM_MIRROR_END) 788 return static_cast<MemoryRegion>(static_cast<u32>(MemoryRegion::RAM) + (address / RAM_2MB_SIZE)); 789 else if (address >= EXP1_BASE && address < (EXP1_BASE + EXP1_SIZE)) 790 return MemoryRegion::EXP1; 791 else if (address >= CPU::SCRATCHPAD_ADDR && address < (CPU::SCRATCHPAD_ADDR + CPU::SCRATCHPAD_SIZE)) 792 return MemoryRegion::Scratchpad; 793 else if (address >= BIOS_BASE && address < (BIOS_BASE + BIOS_SIZE)) 794 return MemoryRegion::BIOS; 795 796 return std::nullopt; 797 } 798 799 static constexpr std::array<std::pair<PhysicalMemoryAddress, PhysicalMemoryAddress>, 800 static_cast<u32>(Bus::MemoryRegion::Count)> 801 s_code_region_ranges = {{ 802 {0, Bus::RAM_2MB_SIZE}, 803 {Bus::RAM_2MB_SIZE, Bus::RAM_2MB_SIZE * 2}, 804 {Bus::RAM_2MB_SIZE * 2, Bus::RAM_2MB_SIZE * 3}, 805 {Bus::RAM_2MB_SIZE * 3, Bus::RAM_MIRROR_END}, 806 {Bus::EXP1_BASE, Bus::EXP1_BASE + Bus::EXP1_SIZE}, 807 {CPU::SCRATCHPAD_ADDR, CPU::SCRATCHPAD_ADDR + CPU::SCRATCHPAD_SIZE}, 808 {Bus::BIOS_BASE, Bus::BIOS_BASE + Bus::BIOS_SIZE}, 809 }}; 810 811 PhysicalMemoryAddress Bus::GetMemoryRegionStart(MemoryRegion region) 812 { 813 return s_code_region_ranges[static_cast<u32>(region)].first; 814 } 815 816 PhysicalMemoryAddress Bus::GetMemoryRegionEnd(MemoryRegion region) 817 { 818 return s_code_region_ranges[static_cast<u32>(region)].second; 819 } 820 821 u8* Bus::GetMemoryRegionPointer(MemoryRegion region) 822 { 823 switch (region) 824 { 825 case MemoryRegion::RAM: 826 return g_unprotected_ram; 827 828 case MemoryRegion::RAMMirror1: 829 return (g_unprotected_ram + (RAM_2MB_SIZE & g_ram_mask)); 830 831 case MemoryRegion::RAMMirror2: 832 return (g_unprotected_ram + ((RAM_2MB_SIZE * 2) & g_ram_mask)); 833 834 case MemoryRegion::RAMMirror3: 835 return (g_unprotected_ram + ((RAM_8MB_SIZE * 3) & g_ram_mask)); 836 837 case MemoryRegion::EXP1: 838 return nullptr; 839 840 case MemoryRegion::Scratchpad: 841 return CPU::g_state.scratchpad.data(); 842 843 case MemoryRegion::BIOS: 844 return g_bios; 845 846 default: 847 return nullptr; 848 } 849 } 850 851 static ALWAYS_INLINE_RELEASE bool MaskedMemoryCompare(const u8* pattern, const u8* mask, u32 pattern_length, 852 const u8* mem) 853 { 854 if (!mask) 855 return std::memcmp(mem, pattern, pattern_length) == 0; 856 857 for (u32 i = 0; i < pattern_length; i++) 858 { 859 if ((mem[i] & mask[i]) != (pattern[i] & mask[i])) 860 return false; 861 } 862 863 return true; 864 } 865 866 std::optional<PhysicalMemoryAddress> Bus::SearchMemory(PhysicalMemoryAddress start_address, const u8* pattern, 867 const u8* mask, u32 pattern_length) 868 { 869 std::optional<MemoryRegion> region = GetMemoryRegionForAddress(start_address); 870 if (!region.has_value()) 871 return std::nullopt; 872 873 PhysicalMemoryAddress current_address = start_address; 874 MemoryRegion current_region = region.value(); 875 while (current_region != MemoryRegion::Count) 876 { 877 const u8* mem = GetMemoryRegionPointer(current_region); 878 const PhysicalMemoryAddress region_start = GetMemoryRegionStart(current_region); 879 const PhysicalMemoryAddress region_end = GetMemoryRegionEnd(current_region); 880 881 if (mem) 882 { 883 PhysicalMemoryAddress region_offset = current_address - region_start; 884 PhysicalMemoryAddress bytes_remaining = region_end - current_address; 885 while (bytes_remaining >= pattern_length) 886 { 887 if (MaskedMemoryCompare(pattern, mask, pattern_length, mem + region_offset)) 888 return region_start + region_offset; 889 890 region_offset++; 891 bytes_remaining--; 892 } 893 } 894 895 // skip RAM mirrors 896 if (current_region == MemoryRegion::RAM) 897 current_region = MemoryRegion::EXP1; 898 else 899 current_region = static_cast<MemoryRegion>(static_cast<int>(current_region) + 1); 900 901 if (current_region != MemoryRegion::Count) 902 current_address = GetMemoryRegionStart(current_region); 903 } 904 905 return std::nullopt; 906 } 907 908 void Bus::SetExpansionROM(std::vector<u8> data) 909 { 910 s_exp1_rom = std::move(data); 911 } 912 913 void Bus::AddTTYCharacter(char ch) 914 { 915 if (ch == '\r') 916 { 917 } 918 else if (ch == '\n') 919 { 920 if (!s_tty_line_buffer.empty()) 921 { 922 Log::FastWrite("TTY", "", LOGLEVEL_INFO, "\033[1;34m{}\033[0m", s_tty_line_buffer); 923 #ifdef _DEBUG 924 if (CPU::IsTraceEnabled()) 925 CPU::WriteToExecutionLog("TTY: %s\n", s_tty_line_buffer.c_str()); 926 #endif 927 } 928 s_tty_line_buffer.clear(); 929 } 930 else 931 { 932 s_tty_line_buffer += ch; 933 } 934 } 935 936 void Bus::AddTTYString(std::string_view str) 937 { 938 for (char ch : str) 939 AddTTYCharacter(ch); 940 } 941 942 bool Bus::InjectExecutable(std::span<const u8> buffer, bool set_pc, Error* error) 943 { 944 BIOS::PSEXEHeader header; 945 if (buffer.size() < sizeof(header)) 946 { 947 Error::SetStringView(error, "Executable does not contain a header."); 948 return false; 949 } 950 951 std::memcpy(&header, buffer.data(), sizeof(header)); 952 if (!BIOS::IsValidPSExeHeader(header, buffer.size())) 953 { 954 Error::SetStringView(error, "Executable does not contain a valid header."); 955 return false; 956 } 957 958 if (header.memfill_size > 0) 959 { 960 const u32 words_to_write = header.memfill_size / 4; 961 u32 address = header.memfill_start & ~UINT32_C(3); 962 for (u32 i = 0; i < words_to_write; i++) 963 { 964 CPU::SafeWriteMemoryWord(address, 0); 965 address += sizeof(u32); 966 } 967 } 968 969 const u32 data_load_size = 970 std::min(static_cast<u32>(static_cast<u32>(buffer.size() - sizeof(BIOS::PSEXEHeader))), header.file_size); 971 if (data_load_size > 0) 972 { 973 if (!CPU::SafeWriteMemoryBytes(header.load_address, &buffer[sizeof(header)], data_load_size)) 974 { 975 Error::SetStringFmt(error, "Failed to upload {} bytes to memory at address 0x{:08X}.", data_load_size, 976 header.load_address); 977 } 978 } 979 980 // patch the BIOS to jump to the executable directly 981 if (set_pc) 982 { 983 const u32 r_pc = header.initial_pc; 984 const u32 r_gp = header.initial_gp; 985 const u32 r_sp = header.initial_sp_base + header.initial_sp_offset; 986 CPU::g_state.regs.gp = r_gp; 987 if (r_sp != 0) 988 { 989 CPU::g_state.regs.sp = r_sp; 990 CPU::g_state.regs.fp = r_sp; 991 } 992 CPU::SetPC(r_pc); 993 } 994 995 return true; 996 } 997 998 void Bus::KernelInitializedHook() 999 { 1000 if (s_kernel_initialize_hook_run) 1001 return; 1002 1003 INFO_LOG("Kernel initialized."); 1004 s_kernel_initialize_hook_run = true; 1005 1006 const System::BootMode boot_mode = System::GetBootMode(); 1007 if (boot_mode == System::BootMode::BootEXE || boot_mode == System::BootMode::BootPSF) 1008 { 1009 Error error; 1010 if (((boot_mode == System::BootMode::BootEXE) ? SideloadEXE(System::GetExeOverride(), &error) : 1011 PSFLoader::Load(System::GetExeOverride(), &error))) 1012 { 1013 // Clear all state, since we're blatently overwriting memory. 1014 CPU::CodeCache::Reset(); 1015 CPU::ClearICache(); 1016 1017 // Stop executing the current block and shell init, and jump straight to the new code. 1018 DebugAssert(!TimingEvents::IsRunningEvents()); 1019 CPU::ExitExecution(); 1020 } 1021 else 1022 { 1023 // Shut down system on load failure. 1024 Host::ReportErrorAsync("EXE/PSF Load Failed", error.GetDescription()); 1025 System::ShutdownSystem(false); 1026 } 1027 } 1028 } 1029 1030 bool Bus::SideloadEXE(const std::string& path, Error* error) 1031 { 1032 // look for a libps.exe next to the exe, if it exists, load it 1033 bool okay = true; 1034 if (const std::string libps_path = Path::BuildRelativePath(path, "libps.exe"); 1035 FileSystem::FileExists(libps_path.c_str())) 1036 { 1037 const std::optional<DynamicHeapArray<u8>> exe_data = FileSystem::ReadBinaryFile(libps_path.c_str(), error); 1038 okay = (exe_data.has_value() && InjectExecutable(exe_data->cspan(), false, error)); 1039 if (!okay) 1040 Error::AddPrefix(error, "Failed to load libps.exe: "); 1041 } 1042 if (okay) 1043 { 1044 const std::optional<DynamicHeapArray<u8>> exe_data = FileSystem::ReadBinaryFile(System::GetExeOverride().c_str(), error); 1045 okay = (exe_data.has_value() && InjectExecutable(exe_data->cspan(), true, error)); 1046 if (!okay) 1047 Error::AddPrefixFmt(error, "Failed to load {}: ", Path::GetFileName(path)); 1048 } 1049 1050 return okay; 1051 } 1052 1053 #define BUS_CYCLES(n) CPU::g_state.pending_ticks += n 1054 1055 // TODO: Move handlers to own files for better inlining. 1056 namespace Bus { 1057 static void ClearHandlers(void** handlers); 1058 static void SetHandlerForRegion(void** handlers, VirtualMemoryAddress address, u32 size, 1059 MemoryReadHandler read_byte_handler, MemoryReadHandler read_halfword_handler, 1060 MemoryReadHandler read_word_handler, MemoryWriteHandler write_byte_handler, 1061 MemoryWriteHandler write_halfword_handler, MemoryWriteHandler write_word_handler); 1062 1063 // clang-format off 1064 template<MemoryAccessSize size> static u32 UnknownReadHandler(VirtualMemoryAddress address); 1065 template<MemoryAccessSize size> static void UnknownWriteHandler(VirtualMemoryAddress address, u32 value); 1066 template<MemoryAccessSize size> static void IgnoreWriteHandler(VirtualMemoryAddress address, u32 value); 1067 template<MemoryAccessSize size> static u32 UnmappedReadHandler(VirtualMemoryAddress address); 1068 template<MemoryAccessSize size> static void UnmappedWriteHandler(VirtualMemoryAddress address, u32 value); 1069 1070 template<MemoryAccessSize size> static u32 RAMReadHandler(VirtualMemoryAddress address); 1071 template<MemoryAccessSize size> static void RAMWriteHandler(VirtualMemoryAddress address, u32 value); 1072 1073 template<MemoryAccessSize size> static u32 BIOSReadHandler(VirtualMemoryAddress address); 1074 1075 template<MemoryAccessSize size> static u32 ScratchpadReadHandler(VirtualMemoryAddress address); 1076 template<MemoryAccessSize size> static void ScratchpadWriteHandler(VirtualMemoryAddress address, u32 value); 1077 1078 template<MemoryAccessSize size> static u32 CacheControlReadHandler(VirtualMemoryAddress address); 1079 template<MemoryAccessSize size> static void CacheControlWriteHandler(VirtualMemoryAddress address, u32 value); 1080 1081 template<MemoryAccessSize size> static u32 ICacheReadHandler(VirtualMemoryAddress address); 1082 template<MemoryAccessSize size> static void ICacheWriteHandler(VirtualMemoryAddress address, u32 value); 1083 1084 template<MemoryAccessSize size> static u32 EXP1ReadHandler(VirtualMemoryAddress address); 1085 template<MemoryAccessSize size> static void EXP1WriteHandler(VirtualMemoryAddress address, u32 value); 1086 template<MemoryAccessSize size> static u32 EXP2ReadHandler(VirtualMemoryAddress address); 1087 template<MemoryAccessSize size> static void EXP2WriteHandler(VirtualMemoryAddress address, u32 value); 1088 template<MemoryAccessSize size> static u32 EXP3ReadHandler(VirtualMemoryAddress address); 1089 template<MemoryAccessSize size> static void EXP3WriteHandler(VirtualMemoryAddress address, u32 value); 1090 template<MemoryAccessSize size> static u32 SIO2ReadHandler(PhysicalMemoryAddress address); 1091 template<MemoryAccessSize size> static void SIO2WriteHandler(PhysicalMemoryAddress address, u32 value); 1092 1093 template<MemoryAccessSize size> static u32 HardwareReadHandler(VirtualMemoryAddress address); 1094 template<MemoryAccessSize size> static void HardwareWriteHandler(VirtualMemoryAddress address, u32 value); 1095 1096 // clang-format on 1097 } // namespace Bus 1098 1099 template<MemoryAccessSize size> 1100 u32 Bus::UnknownReadHandler(VirtualMemoryAddress address) 1101 { 1102 static constexpr const char* sizes[3] = {"byte", "halfword", "word"}; 1103 ERROR_LOG("Invalid {} read at address 0x{:08X}, pc 0x{:08X}", sizes[static_cast<u32>(size)], address, 1104 CPU::g_state.pc); 1105 return 0xFFFFFFFFu; 1106 } 1107 1108 template<MemoryAccessSize size> 1109 void Bus::UnknownWriteHandler(VirtualMemoryAddress address, u32 value) 1110 { 1111 static constexpr const char* sizes[3] = {"byte", "halfword", "word"}; 1112 ERROR_LOG("Invalid {} write at address 0x{:08X}, value 0x{:08X}, pc 0x{:08X}", sizes[static_cast<u32>(size)], address, 1113 value, CPU::g_state.pc); 1114 CPU::g_state.bus_error = true; 1115 } 1116 1117 template<MemoryAccessSize size> 1118 void Bus::IgnoreWriteHandler(VirtualMemoryAddress address, u32 value) 1119 { 1120 // noop 1121 } 1122 1123 template<MemoryAccessSize size> 1124 u32 Bus::UnmappedReadHandler(VirtualMemoryAddress address) 1125 { 1126 CPU::g_state.bus_error = true; 1127 return UnknownReadHandler<size>(address); 1128 } 1129 1130 template<MemoryAccessSize size> 1131 void Bus::UnmappedWriteHandler(VirtualMemoryAddress address, u32 value) 1132 { 1133 CPU::g_state.bus_error = true; 1134 UnknownWriteHandler<size>(address, value); 1135 } 1136 1137 template<MemoryAccessSize size> 1138 u32 Bus::RAMReadHandler(VirtualMemoryAddress address) 1139 { 1140 BUS_CYCLES(RAM_READ_TICKS); 1141 1142 const u32 offset = address & g_ram_mask; 1143 if constexpr (size == MemoryAccessSize::Byte) 1144 { 1145 return ZeroExtend32(g_ram[offset]); 1146 } 1147 else if constexpr (size == MemoryAccessSize::HalfWord) 1148 { 1149 u16 temp; 1150 std::memcpy(&temp, &g_ram[offset], sizeof(u16)); 1151 return ZeroExtend32(temp); 1152 } 1153 else if constexpr (size == MemoryAccessSize::Word) 1154 { 1155 u32 value; 1156 std::memcpy(&value, &g_ram[offset], sizeof(u32)); 1157 return value; 1158 } 1159 } 1160 1161 template<MemoryAccessSize size> 1162 void Bus::RAMWriteHandler(VirtualMemoryAddress address, u32 value) 1163 { 1164 const u32 offset = address & g_ram_mask; 1165 1166 if constexpr (size == MemoryAccessSize::Byte) 1167 { 1168 g_ram[offset] = Truncate8(value); 1169 } 1170 else if constexpr (size == MemoryAccessSize::HalfWord) 1171 { 1172 const u16 temp = Truncate16(value); 1173 std::memcpy(&g_ram[offset], &temp, sizeof(u16)); 1174 } 1175 else if constexpr (size == MemoryAccessSize::Word) 1176 { 1177 std::memcpy(&g_ram[offset], &value, sizeof(u32)); 1178 } 1179 } 1180 1181 template<MemoryAccessSize size> 1182 u32 Bus::BIOSReadHandler(VirtualMemoryAddress address) 1183 { 1184 BUS_CYCLES(g_bios_access_time[static_cast<u32>(size)]); 1185 1186 // TODO: Configurable mirroring. 1187 const u32 offset = address & UINT32_C(0x7FFFF); 1188 if constexpr (size == MemoryAccessSize::Byte) 1189 { 1190 return ZeroExtend32(g_bios[offset]); 1191 } 1192 else if constexpr (size == MemoryAccessSize::HalfWord) 1193 { 1194 u16 temp; 1195 std::memcpy(&temp, &g_bios[offset], sizeof(u16)); 1196 return ZeroExtend32(temp); 1197 } 1198 else 1199 { 1200 u32 value; 1201 std::memcpy(&value, &g_bios[offset], sizeof(u32)); 1202 return value; 1203 } 1204 } 1205 1206 template<MemoryAccessSize size> 1207 u32 Bus::ScratchpadReadHandler(VirtualMemoryAddress address) 1208 { 1209 const PhysicalMemoryAddress cache_offset = address & MEMORY_LUT_PAGE_MASK; 1210 if (cache_offset >= CPU::SCRATCHPAD_SIZE) [[unlikely]] 1211 return UnknownReadHandler<size>(address); 1212 1213 if constexpr (size == MemoryAccessSize::Byte) 1214 { 1215 return ZeroExtend32(CPU::g_state.scratchpad[cache_offset]); 1216 } 1217 else if constexpr (size == MemoryAccessSize::HalfWord) 1218 { 1219 u16 temp; 1220 std::memcpy(&temp, &CPU::g_state.scratchpad[cache_offset], sizeof(temp)); 1221 return ZeroExtend32(temp); 1222 } 1223 else 1224 { 1225 u32 value; 1226 std::memcpy(&value, &CPU::g_state.scratchpad[cache_offset], sizeof(value)); 1227 return value; 1228 } 1229 } 1230 1231 template<MemoryAccessSize size> 1232 void Bus::ScratchpadWriteHandler(VirtualMemoryAddress address, u32 value) 1233 { 1234 const PhysicalMemoryAddress cache_offset = address & MEMORY_LUT_PAGE_MASK; 1235 if (cache_offset >= CPU::SCRATCHPAD_SIZE) [[unlikely]] 1236 { 1237 UnknownWriteHandler<size>(address, value); 1238 return; 1239 } 1240 1241 if constexpr (size == MemoryAccessSize::Byte) 1242 CPU::g_state.scratchpad[cache_offset] = Truncate8(value); 1243 else if constexpr (size == MemoryAccessSize::HalfWord) 1244 std::memcpy(&CPU::g_state.scratchpad[cache_offset], &value, sizeof(u16)); 1245 else if constexpr (size == MemoryAccessSize::Word) 1246 std::memcpy(&CPU::g_state.scratchpad[cache_offset], &value, sizeof(u32)); 1247 } 1248 1249 template<MemoryAccessSize size> 1250 u32 Bus::CacheControlReadHandler(VirtualMemoryAddress address) 1251 { 1252 if (address != 0xFFFE0130) 1253 return UnknownReadHandler<size>(address); 1254 1255 return CPU::g_state.cache_control.bits; 1256 } 1257 1258 template<MemoryAccessSize size> 1259 void Bus::CacheControlWriteHandler(VirtualMemoryAddress address, u32 value) 1260 { 1261 if (address != 0xFFFE0130) 1262 return UnknownWriteHandler<size>(address, value); 1263 1264 DEV_LOG("Cache control <- 0x{:08X}", value); 1265 CPU::g_state.cache_control.bits = value; 1266 } 1267 1268 template<MemoryAccessSize size> 1269 u32 Bus::ICacheReadHandler(VirtualMemoryAddress address) 1270 { 1271 const u32 line = CPU::GetICacheLine(address); 1272 const u8* line_data = &CPU::g_state.icache_data[line * CPU::ICACHE_LINE_SIZE]; 1273 const u32 offset = CPU::GetICacheLineOffset(address); 1274 u32 result; 1275 std::memcpy(&result, &line_data[offset], sizeof(result)); 1276 return result; 1277 } 1278 1279 template<MemoryAccessSize size> 1280 void Bus::ICacheWriteHandler(VirtualMemoryAddress address, u32 value) 1281 { 1282 const u32 line = CPU::GetICacheLine(address); 1283 const u32 offset = CPU::GetICacheLineOffset(address); 1284 CPU::g_state.icache_tags[line] = CPU::GetICacheTagForAddress(address) | CPU::ICACHE_INVALID_BITS; 1285 if constexpr (size == MemoryAccessSize::Byte) 1286 std::memcpy(&CPU::g_state.icache_data[line * CPU::ICACHE_LINE_SIZE + offset], &value, sizeof(u8)); 1287 else if constexpr (size == MemoryAccessSize::HalfWord) 1288 std::memcpy(&CPU::g_state.icache_data[line * CPU::ICACHE_LINE_SIZE + offset], &value, sizeof(u16)); 1289 else 1290 std::memcpy(&CPU::g_state.icache_data[line * CPU::ICACHE_LINE_SIZE + offset], &value, sizeof(u32)); 1291 } 1292 1293 template<MemoryAccessSize size> 1294 u32 Bus::EXP1ReadHandler(VirtualMemoryAddress address) 1295 { 1296 BUS_CYCLES(g_exp1_access_time[static_cast<u32>(size)]); 1297 1298 const u32 offset = address & EXP1_MASK; 1299 u32 value; 1300 if (s_exp1_rom.empty()) 1301 { 1302 // EXP1 not present. 1303 value = UINT32_C(0xFFFFFFFF); 1304 } 1305 else if (offset == 0x20018) 1306 { 1307 // Bit 0 - Action Replay On/Off 1308 value = UINT32_C(1); 1309 } 1310 else 1311 { 1312 const u32 transfer_size = u32(1) << static_cast<u32>(size); 1313 if ((offset + transfer_size) > s_exp1_rom.size()) 1314 { 1315 value = UINT32_C(0); 1316 } 1317 else 1318 { 1319 if constexpr (size == MemoryAccessSize::Byte) 1320 { 1321 value = ZeroExtend32(s_exp1_rom[offset]); 1322 } 1323 else if constexpr (size == MemoryAccessSize::HalfWord) 1324 { 1325 u16 halfword; 1326 std::memcpy(&halfword, &s_exp1_rom[offset], sizeof(halfword)); 1327 value = ZeroExtend32(halfword); 1328 } 1329 else 1330 { 1331 std::memcpy(&value, &s_exp1_rom[offset], sizeof(value)); 1332 } 1333 1334 // Log_DevPrintf("EXP1 read: 0x%08X -> 0x%08X", address, value); 1335 } 1336 } 1337 1338 return value; 1339 } 1340 1341 template<MemoryAccessSize size> 1342 void Bus::EXP1WriteHandler(VirtualMemoryAddress address, u32 value) 1343 { 1344 WARNING_LOG("EXP1 write: 0x{:08X} <- 0x{:08X}", address, value); 1345 } 1346 1347 template<MemoryAccessSize size> 1348 u32 Bus::EXP2ReadHandler(VirtualMemoryAddress address) 1349 { 1350 BUS_CYCLES(g_exp2_access_time[static_cast<u32>(size)]); 1351 1352 const u32 offset = address & EXP2_MASK; 1353 u32 value; 1354 1355 // rx/tx buffer empty 1356 if (offset == 0x21) 1357 { 1358 value = 0x04 | 0x08; 1359 } 1360 else if (offset >= 0x60 && offset <= 0x67) 1361 { 1362 // nocash expansion area 1363 value = UINT32_C(0xFFFFFFFF); 1364 } 1365 else 1366 { 1367 WARNING_LOG("EXP2 read: 0x{:08X}", address); 1368 value = UINT32_C(0xFFFFFFFF); 1369 } 1370 1371 return value; 1372 } 1373 1374 template<MemoryAccessSize size> 1375 void Bus::EXP2WriteHandler(VirtualMemoryAddress address, u32 value) 1376 { 1377 const u32 offset = address & EXP2_MASK; 1378 if (offset == 0x23 || offset == 0x80) 1379 { 1380 AddTTYCharacter(static_cast<char>(value)); 1381 } 1382 else if (offset == 0x41 || offset == 0x42) 1383 { 1384 const u32 post_code = value & UINT32_C(0x0F); 1385 DEV_LOG("BIOS POST status: {:02X}", post_code); 1386 if (post_code == 0x07) 1387 KernelInitializedHook(); 1388 } 1389 else if (offset == 0x70) 1390 { 1391 DEV_LOG("BIOS POST2 status: {:02X}", value & UINT32_C(0x0F)); 1392 } 1393 #if 0 1394 // TODO: Put behind configuration variable 1395 else if (offset == 0x81) 1396 { 1397 Log_WarningPrint("pcsx_debugbreak()"); 1398 Host::ReportErrorAsync("Error", "pcsx_debugbreak()"); 1399 System::PauseSystem(true); 1400 CPU::ExitExecution(); 1401 } 1402 else if (offset == 0x82) 1403 { 1404 Log_WarningFmt("pcsx_exit() with status 0x{:02X}", value & UINT32_C(0xFF)); 1405 Host::ReportErrorAsync("Error", fmt::format("pcsx_exit() with status 0x{:02X}", value & UINT32_C(0xFF))); 1406 System::ShutdownSystem(false); 1407 CPU::ExitExecution(); 1408 } 1409 #endif 1410 else 1411 { 1412 WARNING_LOG("EXP2 write: 0x{:08X} <- 0x{:08X}", address, value); 1413 } 1414 } 1415 1416 template<MemoryAccessSize size> 1417 u32 Bus::EXP3ReadHandler(VirtualMemoryAddress address) 1418 { 1419 WARNING_LOG("EXP3 read: 0x{:08X}", address); 1420 return UINT32_C(0xFFFFFFFF); 1421 } 1422 1423 template<MemoryAccessSize size> 1424 void Bus::EXP3WriteHandler(VirtualMemoryAddress address, u32 value) 1425 { 1426 const u32 offset = address & EXP3_MASK; 1427 if (offset == 0) 1428 { 1429 const u32 post_code = value & UINT32_C(0x0F); 1430 WARNING_LOG("BIOS POST3 status: {:02X}", post_code); 1431 if (post_code == 0x07) 1432 KernelInitializedHook(); 1433 } 1434 } 1435 1436 template<MemoryAccessSize size> 1437 u32 Bus::SIO2ReadHandler(PhysicalMemoryAddress address) 1438 { 1439 // Stub for using PS2 BIOS. 1440 if (const BIOS::ImageInfo* ii = System::GetBIOSImageInfo(); 1441 !ii || ii->fastboot_patch != BIOS::ImageInfo::FastBootPatch::Type2) [[unlikely]] 1442 { 1443 // Throw exception when not using PS2 BIOS. 1444 return UnmappedReadHandler<size>(address); 1445 } 1446 1447 WARNING_LOG("SIO2 read: 0x{:08X}", address); 1448 return 0; 1449 } 1450 1451 template<MemoryAccessSize size> 1452 void Bus::SIO2WriteHandler(PhysicalMemoryAddress address, u32 value) 1453 { 1454 // Stub for using PS2 BIOS. 1455 if (const BIOS::ImageInfo* ii = System::GetBIOSImageInfo(); 1456 !ii || ii->fastboot_patch != BIOS::ImageInfo::FastBootPatch::Type2) [[unlikely]] 1457 { 1458 // Throw exception when not using PS2 BIOS. 1459 UnmappedWriteHandler<size>(address, value); 1460 return; 1461 } 1462 1463 WARNING_LOG("SIO2 write: 0x{:08X} <- 0x{:08X}", address, value); 1464 } 1465 1466 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1467 // HARDWARE HANDLERS 1468 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1469 1470 namespace Bus::HWHandlers { 1471 // clang-format off 1472 template<MemoryAccessSize size> static u32 MemCtrlRead(PhysicalMemoryAddress address); 1473 template<MemoryAccessSize size> static void MemCtrlWrite(PhysicalMemoryAddress address, u32 value); 1474 template<MemoryAccessSize size> static u32 PADRead(PhysicalMemoryAddress address); 1475 template<MemoryAccessSize size> static void PADWrite(PhysicalMemoryAddress address, u32 value); 1476 template<MemoryAccessSize size> static u32 SIORead(PhysicalMemoryAddress address); 1477 template<MemoryAccessSize size> static void SIOWrite(PhysicalMemoryAddress address, u32 value); 1478 template<MemoryAccessSize size> static u32 MemCtrl2Read(PhysicalMemoryAddress address); 1479 template<MemoryAccessSize size> static void MemCtrl2Write(PhysicalMemoryAddress address, u32 value); 1480 template<MemoryAccessSize size> static u32 INTCRead(PhysicalMemoryAddress address); 1481 template<MemoryAccessSize size> static void INTCWrite(PhysicalMemoryAddress address, u32 value); 1482 template<MemoryAccessSize size> static u32 DMARead(PhysicalMemoryAddress address); 1483 template<MemoryAccessSize size> static void DMAWrite(PhysicalMemoryAddress address, u32 value); 1484 template<MemoryAccessSize size> static u32 TimersRead(PhysicalMemoryAddress address); 1485 template<MemoryAccessSize size> static void TimersWrite(PhysicalMemoryAddress address, u32 value); 1486 template<MemoryAccessSize size> static u32 CDROMRead(PhysicalMemoryAddress address); 1487 template<MemoryAccessSize size> static void CDROMWrite(PhysicalMemoryAddress address, u32 value); 1488 template<MemoryAccessSize size> static u32 GPURead(PhysicalMemoryAddress address); 1489 template<MemoryAccessSize size> static void GPUWrite(PhysicalMemoryAddress address, u32 value); 1490 template<MemoryAccessSize size> static u32 MDECRead(PhysicalMemoryAddress address); 1491 template<MemoryAccessSize size> static void MDECWrite(PhysicalMemoryAddress address, u32 value); 1492 template<MemoryAccessSize size> static u32 SPURead(PhysicalMemoryAddress address); 1493 template<MemoryAccessSize size> static void SPUWrite(PhysicalMemoryAddress address, u32 value); 1494 // clang-format on 1495 } // namespace Bus::HWHandlers 1496 1497 template<MemoryAccessSize size> 1498 u32 Bus::HWHandlers::MemCtrlRead(PhysicalMemoryAddress address) 1499 { 1500 const u32 offset = address & MEMCTRL_MASK; 1501 const u32 index = FIXUP_WORD_OFFSET(size, offset) / 4; 1502 if (index >= std::size(s_MEMCTRL.regs)) [[unlikely]] 1503 return 0; 1504 1505 u32 value = s_MEMCTRL.regs[index]; 1506 value = FIXUP_WORD_READ_VALUE(size, offset, value); 1507 BUS_CYCLES(2); 1508 return value; 1509 } 1510 1511 template<MemoryAccessSize size> 1512 void Bus::HWHandlers::MemCtrlWrite(PhysicalMemoryAddress address, u32 value) 1513 { 1514 const u32 offset = address & MEMCTRL_MASK; 1515 const u32 index = FIXUP_WORD_OFFSET(size, offset) / 4; 1516 if (index >= std::size(s_MEMCTRL.regs)) [[unlikely]] 1517 return; 1518 1519 value = FIXUP_WORD_WRITE_VALUE(size, offset, value); 1520 1521 const u32 write_mask = (index == 8) ? COMDELAY::WRITE_MASK : MEMDELAY::WRITE_MASK; 1522 const u32 new_value = (s_MEMCTRL.regs[index] & ~write_mask) | (value & write_mask); 1523 if (s_MEMCTRL.regs[index] != new_value) 1524 { 1525 s_MEMCTRL.regs[index] = new_value; 1526 RecalculateMemoryTimings(); 1527 } 1528 } 1529 1530 template<MemoryAccessSize size> 1531 u32 Bus::HWHandlers::MemCtrl2Read(PhysicalMemoryAddress address) 1532 { 1533 const u32 offset = address & MEMCTRL2_MASK; 1534 1535 u32 value; 1536 if (offset == 0x00) 1537 { 1538 value = s_RAM_SIZE.bits; 1539 } 1540 else 1541 { 1542 return UnknownReadHandler<size>(address); 1543 } 1544 1545 BUS_CYCLES(2); 1546 return value; 1547 } 1548 1549 template<MemoryAccessSize size> 1550 void Bus::HWHandlers::MemCtrl2Write(PhysicalMemoryAddress address, u32 value) 1551 { 1552 const u32 offset = address & MEMCTRL2_MASK; 1553 1554 if (offset == 0x00) 1555 { 1556 if (s_RAM_SIZE.bits != value) 1557 { 1558 DEV_LOG("RAM size register set to 0x{:08X}", value); 1559 1560 const RAM_SIZE_REG old_ram_size_reg = s_RAM_SIZE; 1561 s_RAM_SIZE.bits = value; 1562 1563 if (s_RAM_SIZE.memory_window != old_ram_size_reg.memory_window) 1564 UpdateMappedRAMSize(); 1565 } 1566 } 1567 else 1568 { 1569 return UnknownWriteHandler<size>(address, value); 1570 } 1571 } 1572 1573 template<MemoryAccessSize size> 1574 u32 Bus::HWHandlers::PADRead(PhysicalMemoryAddress address) 1575 { 1576 const u32 offset = address & PAD_MASK; 1577 1578 u32 value = Pad::ReadRegister(FIXUP_HALFWORD_OFFSET(size, offset)); 1579 value = FIXUP_HALFWORD_READ_VALUE(size, offset, value); 1580 BUS_CYCLES(2); 1581 return value; 1582 } 1583 1584 template<MemoryAccessSize size> 1585 void Bus::HWHandlers::PADWrite(PhysicalMemoryAddress address, u32 value) 1586 { 1587 const u32 offset = address & PAD_MASK; 1588 Pad::WriteRegister(FIXUP_HALFWORD_OFFSET(size, offset), FIXUP_HALFWORD_WRITE_VALUE(size, offset, value)); 1589 } 1590 1591 template<MemoryAccessSize size> 1592 u32 Bus::HWHandlers::SIORead(PhysicalMemoryAddress address) 1593 { 1594 const u32 offset = address & SIO_MASK; 1595 u32 value = SIO::ReadRegister(FIXUP_HALFWORD_OFFSET(size, offset)); 1596 value = FIXUP_HALFWORD_READ_VALUE(size, offset, value); 1597 BUS_CYCLES(2); 1598 return value; 1599 } 1600 1601 template<MemoryAccessSize size> 1602 void Bus::HWHandlers::SIOWrite(PhysicalMemoryAddress address, u32 value) 1603 { 1604 const u32 offset = address & SIO_MASK; 1605 SIO::WriteRegister(FIXUP_HALFWORD_OFFSET(size, offset), FIXUP_HALFWORD_WRITE_VALUE(size, offset, value)); 1606 } 1607 1608 template<MemoryAccessSize size> 1609 u32 Bus::HWHandlers::CDROMRead(PhysicalMemoryAddress address) 1610 { 1611 const u32 offset = address & CDROM_MASK; 1612 1613 u32 value; 1614 switch (size) 1615 { 1616 case MemoryAccessSize::Word: 1617 { 1618 const u32 b0 = ZeroExtend32(CDROM::ReadRegister(offset)); 1619 const u32 b1 = ZeroExtend32(CDROM::ReadRegister(offset + 1u)); 1620 const u32 b2 = ZeroExtend32(CDROM::ReadRegister(offset + 2u)); 1621 const u32 b3 = ZeroExtend32(CDROM::ReadRegister(offset + 3u)); 1622 value = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24); 1623 } 1624 break; 1625 1626 case MemoryAccessSize::HalfWord: 1627 { 1628 const u32 lsb = ZeroExtend32(CDROM::ReadRegister(offset)); 1629 const u32 msb = ZeroExtend32(CDROM::ReadRegister(offset + 1u)); 1630 value = lsb | (msb << 8); 1631 } 1632 break; 1633 1634 case MemoryAccessSize::Byte: 1635 default: 1636 value = ZeroExtend32(CDROM::ReadRegister(offset)); 1637 break; 1638 } 1639 1640 BUS_CYCLES(Bus::g_cdrom_access_time[static_cast<u32>(size)]); 1641 return value; 1642 } 1643 1644 template<MemoryAccessSize size> 1645 void Bus::HWHandlers::CDROMWrite(PhysicalMemoryAddress address, u32 value) 1646 { 1647 const u32 offset = address & CDROM_MASK; 1648 switch (size) 1649 { 1650 case MemoryAccessSize::Word: 1651 { 1652 CDROM::WriteRegister(offset, Truncate8(value & 0xFFu)); 1653 CDROM::WriteRegister(offset + 1u, Truncate8((value >> 8) & 0xFFu)); 1654 CDROM::WriteRegister(offset + 2u, Truncate8((value >> 16) & 0xFFu)); 1655 CDROM::WriteRegister(offset + 3u, Truncate8((value >> 24) & 0xFFu)); 1656 } 1657 break; 1658 1659 case MemoryAccessSize::HalfWord: 1660 { 1661 CDROM::WriteRegister(offset, Truncate8(value & 0xFFu)); 1662 CDROM::WriteRegister(offset + 1u, Truncate8((value >> 8) & 0xFFu)); 1663 } 1664 break; 1665 1666 case MemoryAccessSize::Byte: 1667 default: 1668 CDROM::WriteRegister(offset, Truncate8(value)); 1669 break; 1670 } 1671 } 1672 1673 template<MemoryAccessSize size> 1674 u32 Bus::HWHandlers::GPURead(PhysicalMemoryAddress address) 1675 { 1676 const u32 offset = address & GPU_MASK; 1677 u32 value = g_gpu->ReadRegister(FIXUP_WORD_OFFSET(size, offset)); 1678 value = FIXUP_WORD_READ_VALUE(size, offset, value); 1679 BUS_CYCLES(2); 1680 return value; 1681 } 1682 1683 template<MemoryAccessSize size> 1684 void Bus::HWHandlers::GPUWrite(PhysicalMemoryAddress address, u32 value) 1685 { 1686 const u32 offset = address & GPU_MASK; 1687 g_gpu->WriteRegister(FIXUP_WORD_OFFSET(size, offset), FIXUP_WORD_WRITE_VALUE(size, offset, value)); 1688 } 1689 1690 template<MemoryAccessSize size> 1691 u32 Bus::HWHandlers::MDECRead(PhysicalMemoryAddress address) 1692 { 1693 const u32 offset = address & MDEC_MASK; 1694 u32 value = MDEC::ReadRegister(FIXUP_WORD_OFFSET(size, offset)); 1695 value = FIXUP_WORD_READ_VALUE(size, offset, value); 1696 BUS_CYCLES(2); 1697 return value; 1698 } 1699 1700 template<MemoryAccessSize size> 1701 void Bus::HWHandlers::MDECWrite(PhysicalMemoryAddress address, u32 value) 1702 { 1703 const u32 offset = address & MDEC_MASK; 1704 MDEC::WriteRegister(FIXUP_WORD_OFFSET(size, offset), FIXUP_WORD_WRITE_VALUE(size, offset, value)); 1705 } 1706 1707 template<MemoryAccessSize size> 1708 u32 Bus::HWHandlers::INTCRead(PhysicalMemoryAddress address) 1709 { 1710 const u32 offset = address & INTERRUPT_CONTROLLER_MASK; 1711 u32 value = InterruptController::ReadRegister(FIXUP_WORD_OFFSET(size, offset)); 1712 value = FIXUP_WORD_READ_VALUE(size, offset, value); 1713 BUS_CYCLES(2); 1714 return value; 1715 } 1716 1717 template<MemoryAccessSize size> 1718 void Bus::HWHandlers::INTCWrite(PhysicalMemoryAddress address, u32 value) 1719 { 1720 const u32 offset = address & INTERRUPT_CONTROLLER_MASK; 1721 InterruptController::WriteRegister(FIXUP_WORD_OFFSET(size, offset), FIXUP_WORD_WRITE_VALUE(size, offset, value)); 1722 } 1723 1724 template<MemoryAccessSize size> 1725 u32 Bus::HWHandlers::TimersRead(PhysicalMemoryAddress address) 1726 { 1727 const u32 offset = address & TIMERS_MASK; 1728 u32 value = Timers::ReadRegister(FIXUP_WORD_OFFSET(size, offset)); 1729 value = FIXUP_WORD_READ_VALUE(size, offset, value); 1730 BUS_CYCLES(2); 1731 return value; 1732 } 1733 1734 template<MemoryAccessSize size> 1735 void Bus::HWHandlers::TimersWrite(PhysicalMemoryAddress address, u32 value) 1736 { 1737 const u32 offset = address & TIMERS_MASK; 1738 Timers::WriteRegister(FIXUP_WORD_OFFSET(size, offset), FIXUP_WORD_WRITE_VALUE(size, offset, value)); 1739 } 1740 1741 template<MemoryAccessSize size> 1742 u32 Bus::HWHandlers::SPURead(PhysicalMemoryAddress address) 1743 { 1744 const u32 offset = address & SPU_MASK; 1745 u32 value; 1746 1747 switch (size) 1748 { 1749 case MemoryAccessSize::Word: 1750 { 1751 // 32-bit reads are read as two 16-bit accesses. 1752 const u16 lsb = SPU::ReadRegister(offset); 1753 const u16 msb = SPU::ReadRegister(offset + 2); 1754 value = ZeroExtend32(lsb) | (ZeroExtend32(msb) << 16); 1755 } 1756 break; 1757 1758 case MemoryAccessSize::HalfWord: 1759 { 1760 value = ZeroExtend32(SPU::ReadRegister(offset)); 1761 } 1762 break; 1763 1764 case MemoryAccessSize::Byte: 1765 default: 1766 { 1767 const u16 value16 = SPU::ReadRegister(FIXUP_HALFWORD_OFFSET(size, offset)); 1768 value = FIXUP_HALFWORD_READ_VALUE(size, offset, value16); 1769 } 1770 break; 1771 } 1772 1773 BUS_CYCLES(Bus::g_spu_access_time[static_cast<u32>(size)]); 1774 return value; 1775 } 1776 1777 template<MemoryAccessSize size> 1778 void Bus::HWHandlers::SPUWrite(PhysicalMemoryAddress address, u32 value) 1779 { 1780 const u32 offset = address & SPU_MASK; 1781 1782 // 32-bit writes are written as two 16-bit writes. 1783 switch (size) 1784 { 1785 case MemoryAccessSize::Word: 1786 { 1787 DebugAssert(Common::IsAlignedPow2(offset, 2)); 1788 SPU::WriteRegister(offset, Truncate16(value)); 1789 SPU::WriteRegister(offset + 2, Truncate16(value >> 16)); 1790 break; 1791 } 1792 1793 case MemoryAccessSize::HalfWord: 1794 { 1795 DebugAssert(Common::IsAlignedPow2(offset, 2)); 1796 SPU::WriteRegister(offset, Truncate16(value)); 1797 break; 1798 } 1799 1800 case MemoryAccessSize::Byte: 1801 { 1802 // Byte writes to unaligned addresses are apparently ignored. 1803 if (address & 1) 1804 return; 1805 1806 SPU::WriteRegister(offset, Truncate16(FIXUP_HALFWORD_READ_VALUE(size, offset, value))); 1807 break; 1808 } 1809 } 1810 } 1811 1812 template<MemoryAccessSize size> 1813 u32 Bus::HWHandlers::DMARead(PhysicalMemoryAddress address) 1814 { 1815 const u32 offset = address & DMA_MASK; 1816 u32 value = DMA::ReadRegister(FIXUP_WORD_OFFSET(size, offset)); 1817 value = FIXUP_WORD_READ_VALUE(size, offset, value); 1818 BUS_CYCLES(2); 1819 return value; 1820 } 1821 1822 template<MemoryAccessSize size> 1823 void Bus::HWHandlers::DMAWrite(PhysicalMemoryAddress address, u32 value) 1824 { 1825 const u32 offset = address & DMA_MASK; 1826 DMA::WriteRegister(FIXUP_WORD_OFFSET(size, offset), FIXUP_WORD_WRITE_VALUE(size, offset, value)); 1827 } 1828 1829 #undef BUS_CYCLES 1830 1831 namespace Bus::HWHandlers { 1832 // We index hardware registers by bits 15..8. 1833 template<MemoryAccessType type, MemoryAccessSize size, 1834 typename RT = std::conditional_t<type == MemoryAccessType::Read, MemoryReadHandler, MemoryWriteHandler>> 1835 static constexpr std::array<RT, 256> GetHardwareRegisterHandlerTable() 1836 { 1837 std::array<RT, 256> ret = {}; 1838 for (size_t i = 0; i < ret.size(); i++) 1839 { 1840 if constexpr (type == MemoryAccessType::Read) 1841 ret[i] = UnmappedReadHandler<size>; 1842 else 1843 ret[i] = UnmappedWriteHandler<size>; 1844 } 1845 1846 #if 0 1847 // Verifies no region has >1 handler, but doesn't compile on older GCC. 1848 #define SET(raddr, rsize, read_handler, write_handler) \ 1849 static_assert(raddr >= 0x1F801000 && (raddr + rsize) <= 0x1F802000); \ 1850 for (u32 taddr = raddr; taddr < (raddr + rsize); taddr += 16) \ 1851 { \ 1852 const u32 i = (taddr >> 4) & 0xFFu; \ 1853 if constexpr (type == MemoryAccessType::Read) \ 1854 ret[i] = (ret[i] == UnmappedReadHandler<size>) ? read_handler<size> : (abort(), read_handler<size>); \ 1855 else \ 1856 ret[i] = (ret[i] == UnmappedWriteHandler<size>) ? write_handler<size> : (abort(), write_handler<size>); \ 1857 } 1858 #else 1859 #define SET(raddr, rsize, read_handler, write_handler) \ 1860 static_assert(raddr >= 0x1F801000 && (raddr + rsize) <= 0x1F802000); \ 1861 for (u32 taddr = raddr; taddr < (raddr + rsize); taddr += 16) \ 1862 { \ 1863 const u32 i = (taddr >> 4) & 0xFFu; \ 1864 if constexpr (type == MemoryAccessType::Read) \ 1865 ret[i] = read_handler<size>; \ 1866 else \ 1867 ret[i] = write_handler<size>; \ 1868 } 1869 #endif 1870 1871 SET(MEMCTRL_BASE, MEMCTRL_SIZE, MemCtrlRead, MemCtrlWrite); 1872 SET(PAD_BASE, PAD_SIZE, PADRead, PADWrite); 1873 SET(SIO_BASE, SIO_SIZE, SIORead, SIOWrite); 1874 SET(MEMCTRL2_BASE, MEMCTRL2_SIZE, MemCtrl2Read, MemCtrl2Write); 1875 SET(INTC_BASE, INTC_SIZE, INTCRead, INTCWrite); 1876 SET(DMA_BASE, DMA_SIZE, DMARead, DMAWrite); 1877 SET(TIMERS_BASE, TIMERS_SIZE, TimersRead, TimersWrite); 1878 SET(CDROM_BASE, CDROM_SIZE, CDROMRead, CDROMWrite); 1879 SET(GPU_BASE, GPU_SIZE, GPURead, GPUWrite); 1880 SET(MDEC_BASE, MDEC_SIZE, MDECRead, MDECWrite); 1881 SET(SPU_BASE, SPU_SIZE, SPURead, SPUWrite); 1882 1883 #undef SET 1884 1885 return ret; 1886 } 1887 } // namespace Bus::HWHandlers 1888 1889 template<MemoryAccessSize size> 1890 u32 Bus::HardwareReadHandler(VirtualMemoryAddress address) 1891 { 1892 static constexpr const auto table = HWHandlers::GetHardwareRegisterHandlerTable<MemoryAccessType::Read, size>(); 1893 const u32 table_index = (address >> 4) & 0xFFu; 1894 return table[table_index](address); 1895 } 1896 1897 template<MemoryAccessSize size> 1898 void Bus::HardwareWriteHandler(VirtualMemoryAddress address, u32 value) 1899 { 1900 static constexpr const auto table = HWHandlers::GetHardwareRegisterHandlerTable<MemoryAccessType::Write, size>(); 1901 const u32 table_index = (address >> 4) & 0xFFu; 1902 return table[table_index](address, value); 1903 } 1904 1905 ////////////////////////////////////////////////////////////////////////// 1906 1907 static constexpr u32 KUSEG = 0; 1908 static constexpr u32 KSEG0 = 0x80000000U; 1909 static constexpr u32 KSEG1 = 0xA0000000U; 1910 static constexpr u32 KSEG2 = 0xC0000000U; 1911 1912 void Bus::SetHandlers() 1913 { 1914 ClearHandlers(g_memory_handlers); 1915 ClearHandlers(g_memory_handlers_isc); 1916 1917 #define SET(table, start, size, read_handler, write_handler) \ 1918 SetHandlerForRegion(table, start, size, read_handler<MemoryAccessSize::Byte>, \ 1919 read_handler<MemoryAccessSize::HalfWord>, read_handler<MemoryAccessSize::Word>, \ 1920 write_handler<MemoryAccessSize::Byte>, write_handler<MemoryAccessSize::HalfWord>, \ 1921 write_handler<MemoryAccessSize::Word>) 1922 #define SETUC(start, size, read_handler, write_handler) \ 1923 SET(g_memory_handlers, start, size, read_handler, write_handler); \ 1924 SET(g_memory_handlers_isc, start, size, read_handler, write_handler) 1925 1926 // KUSEG - Cached 1927 // Cache isolated appears to affect KUSEG+KSEG0. 1928 SET(g_memory_handlers, KUSEG | RAM_BASE, RAM_MIRROR_SIZE, RAMReadHandler, RAMWriteHandler); 1929 SET(g_memory_handlers, KUSEG | CPU::SCRATCHPAD_ADDR, 0x1000, ScratchpadReadHandler, ScratchpadWriteHandler); 1930 SET(g_memory_handlers, KUSEG | BIOS_BASE, BIOS_MIRROR_SIZE, BIOSReadHandler, IgnoreWriteHandler); 1931 SET(g_memory_handlers, KUSEG | EXP1_BASE, EXP1_SIZE, EXP1ReadHandler, EXP1WriteHandler); 1932 SET(g_memory_handlers, KUSEG | HW_BASE, HW_SIZE, HardwareReadHandler, HardwareWriteHandler); 1933 SET(g_memory_handlers, KUSEG | EXP2_BASE, EXP2_SIZE, EXP2ReadHandler, EXP2WriteHandler); 1934 SET(g_memory_handlers, KUSEG | EXP3_BASE, EXP3_SIZE, EXP3ReadHandler, EXP3WriteHandler); 1935 SET(g_memory_handlers, KUSEG | SIO2_BASE, SIO2_SIZE, SIO2ReadHandler, SIO2WriteHandler); 1936 SET(g_memory_handlers_isc, KUSEG, 0x80000000, ICacheReadHandler, ICacheWriteHandler); 1937 1938 // KSEG0 - Cached 1939 SET(g_memory_handlers, KSEG0 | RAM_BASE, RAM_MIRROR_SIZE, RAMReadHandler, RAMWriteHandler); 1940 SET(g_memory_handlers, KSEG0 | CPU::SCRATCHPAD_ADDR, 0x1000, ScratchpadReadHandler, ScratchpadWriteHandler); 1941 SET(g_memory_handlers, KSEG0 | BIOS_BASE, BIOS_MIRROR_SIZE, BIOSReadHandler, IgnoreWriteHandler); 1942 SET(g_memory_handlers, KSEG0 | EXP1_BASE, EXP1_SIZE, EXP1ReadHandler, EXP1WriteHandler); 1943 SET(g_memory_handlers, KSEG0 | HW_BASE, HW_SIZE, HardwareReadHandler, HardwareWriteHandler); 1944 SET(g_memory_handlers, KSEG0 | EXP2_BASE, EXP2_SIZE, EXP2ReadHandler, EXP2WriteHandler); 1945 SET(g_memory_handlers, KSEG0 | EXP3_BASE, EXP3_SIZE, EXP3ReadHandler, EXP3WriteHandler); 1946 SET(g_memory_handlers, KSEG0 | SIO2_BASE, SIO2_SIZE, SIO2ReadHandler, SIO2WriteHandler); 1947 SET(g_memory_handlers_isc, KSEG0, 0x20000000, ICacheReadHandler, ICacheWriteHandler); 1948 1949 // KSEG1 - Uncached 1950 SETUC(KSEG1 | RAM_BASE, RAM_MIRROR_SIZE, RAMReadHandler, RAMWriteHandler); 1951 SETUC(KSEG1 | BIOS_BASE, BIOS_MIRROR_SIZE, BIOSReadHandler, IgnoreWriteHandler); 1952 SETUC(KSEG1 | EXP1_BASE, EXP1_SIZE, EXP1ReadHandler, EXP1WriteHandler); 1953 SETUC(KSEG1 | HW_BASE, HW_SIZE, HardwareReadHandler, HardwareWriteHandler); 1954 SETUC(KSEG1 | EXP2_BASE, EXP2_SIZE, EXP2ReadHandler, EXP2WriteHandler); 1955 SETUC(KSEG1 | EXP3_BASE, EXP3_SIZE, EXP3ReadHandler, EXP3WriteHandler); 1956 SETUC(KSEG1 | SIO2_BASE, SIO2_SIZE, SIO2ReadHandler, SIO2WriteHandler); 1957 1958 // KSEG2 - Uncached - 0xFFFE0130 1959 SETUC(KSEG2 | 0xFFFE0000, 0x1000, CacheControlReadHandler, CacheControlWriteHandler); 1960 } 1961 1962 void Bus::UpdateMappedRAMSize() 1963 { 1964 switch (s_RAM_SIZE.memory_window) 1965 { 1966 case 4: // 2MB memory + 6MB unmapped 1967 { 1968 // Used by Rock-Climbing - Mitouhou e no Chousen - Alps Hen (Japan). 1969 // By default, all 8MB is mapped, so we only need to remap the high 6MB. 1970 constexpr u32 MAPPED_SIZE = RAM_2MB_SIZE; 1971 constexpr u32 UNMAPPED_START = RAM_BASE + MAPPED_SIZE; 1972 constexpr u32 UNMAPPED_SIZE = RAM_MIRROR_SIZE - MAPPED_SIZE; 1973 SET(g_memory_handlers, KUSEG | UNMAPPED_START, UNMAPPED_SIZE, UnmappedReadHandler, UnmappedWriteHandler); 1974 SET(g_memory_handlers, KSEG0 | UNMAPPED_START, UNMAPPED_SIZE, UnmappedReadHandler, UnmappedWriteHandler); 1975 SET(g_memory_handlers, KSEG1 | UNMAPPED_START, UNMAPPED_SIZE, UnmappedReadHandler, UnmappedWriteHandler); 1976 g_ram_mapped_size = MAPPED_SIZE; 1977 } 1978 break; 1979 1980 case 0: // 1MB memory + 7MB unmapped 1981 case 1: // 4MB memory + 4MB unmapped 1982 case 2: // 1MB memory + 1MB HighZ + 6MB unmapped 1983 case 3: // 4MB memory + 4MB HighZ 1984 case 6: // 2MB memory + 2MB HighZ + 4MB unmapped 1985 case 7: // 8MB memory 1986 { 1987 // These aren't implemented because nothing is known to use them, so it can't be tested. 1988 // If you find something that does, please let us know. 1989 WARNING_LOG("Unhandled memory window 0x{} (register 0x{:08X}). Please report this game to developers.", 1990 s_RAM_SIZE.memory_window.GetValue(), s_RAM_SIZE.bits); 1991 } 1992 [[fallthrough]]; 1993 1994 case 5: // 8MB memory 1995 { 1996 // We only unmap the upper 6MB above, so we only need to remap this as well. 1997 constexpr u32 REMAP_START = RAM_BASE + RAM_2MB_SIZE; 1998 constexpr u32 REMAP_SIZE = RAM_MIRROR_SIZE - RAM_2MB_SIZE; 1999 SET(g_memory_handlers, KUSEG | REMAP_START, REMAP_SIZE, RAMReadHandler, RAMWriteHandler); 2000 SET(g_memory_handlers, KSEG0 | REMAP_START, REMAP_SIZE, RAMReadHandler, RAMWriteHandler); 2001 SET(g_memory_handlers, KSEG1 | REMAP_START, REMAP_SIZE, RAMReadHandler, RAMWriteHandler); 2002 g_ram_mapped_size = RAM_8MB_SIZE; 2003 } 2004 break; 2005 } 2006 } 2007 2008 #undef SET 2009 #undef SETUC 2010 2011 void Bus::ClearHandlers(void** handlers) 2012 { 2013 for (u32 size = 0; size < 3; size++) 2014 { 2015 MemoryReadHandler* read_handlers = 2016 OffsetHandlerArray<MemoryReadHandler>(handlers, static_cast<MemoryAccessSize>(size), MemoryAccessType::Read); 2017 const MemoryReadHandler read_handler = 2018 (size == 0) ? 2019 UnmappedReadHandler<MemoryAccessSize::Byte> : 2020 ((size == 1) ? UnmappedReadHandler<MemoryAccessSize::HalfWord> : UnmappedReadHandler<MemoryAccessSize::Word>); 2021 MemsetPtrs(read_handlers, read_handler, MEMORY_LUT_SIZE); 2022 2023 MemoryWriteHandler* write_handlers = 2024 OffsetHandlerArray<MemoryWriteHandler>(handlers, static_cast<MemoryAccessSize>(size), MemoryAccessType::Write); 2025 const MemoryWriteHandler write_handler = 2026 (size == 0) ? 2027 UnmappedWriteHandler<MemoryAccessSize::Byte> : 2028 ((size == 1) ? UnmappedWriteHandler<MemoryAccessSize::HalfWord> : UnmappedWriteHandler<MemoryAccessSize::Word>); 2029 MemsetPtrs(write_handlers, write_handler, MEMORY_LUT_SIZE); 2030 } 2031 } 2032 2033 void Bus::SetHandlerForRegion(void** handlers, VirtualMemoryAddress address, u32 size, 2034 MemoryReadHandler read_byte_handler, MemoryReadHandler read_halfword_handler, 2035 MemoryReadHandler read_word_handler, MemoryWriteHandler write_byte_handler, 2036 MemoryWriteHandler write_halfword_handler, MemoryWriteHandler write_word_handler) 2037 { 2038 // Should be 4K aligned. 2039 DebugAssert(Common::IsAlignedPow2(size, MEMORY_LUT_PAGE_SIZE)); 2040 2041 const u32 start_page = (address / MEMORY_LUT_PAGE_SIZE); 2042 const u32 num_pages = ((size + (MEMORY_LUT_PAGE_SIZE - 1)) / MEMORY_LUT_PAGE_SIZE); 2043 2044 for (u32 acc_size = 0; acc_size < 3; acc_size++) 2045 { 2046 MemoryReadHandler* read_handlers = 2047 OffsetHandlerArray<MemoryReadHandler>(handlers, static_cast<MemoryAccessSize>(acc_size), MemoryAccessType::Read) + 2048 start_page; 2049 const MemoryReadHandler read_handler = 2050 (acc_size == 0) ? read_byte_handler : ((acc_size == 1) ? read_halfword_handler : read_word_handler); 2051 #if 0 2052 for (u32 i = 0; i < num_pages; i++) 2053 { 2054 DebugAssert((acc_size == 0 && read_handlers[i] == UnmappedReadHandler<MemoryAccessSize::Byte>) || 2055 (acc_size == 1 && read_handlers[i] == UnmappedReadHandler<MemoryAccessSize::HalfWord>) || 2056 (acc_size == 2 && read_handlers[i] == UnmappedReadHandler<MemoryAccessSize::Word>)); 2057 2058 read_handlers[i] = read_handler; 2059 } 2060 #else 2061 MemsetPtrs(read_handlers, read_handler, num_pages); 2062 #endif 2063 2064 MemoryWriteHandler* write_handlers = OffsetHandlerArray<MemoryWriteHandler>( 2065 handlers, static_cast<MemoryAccessSize>(acc_size), MemoryAccessType::Write) + 2066 start_page; 2067 const MemoryWriteHandler write_handler = 2068 (acc_size == 0) ? write_byte_handler : ((acc_size == 1) ? write_halfword_handler : write_word_handler); 2069 #if 0 2070 for (u32 i = 0; i < num_pages; i++) 2071 { 2072 DebugAssert((acc_size == 0 && write_handlers[i] == UnmappedWriteHandler<MemoryAccessSize::Byte>) || 2073 (acc_size == 1 && write_handlers[i] == UnmappedWriteHandler<MemoryAccessSize::HalfWord>) || 2074 (acc_size == 2 && write_handlers[i] == UnmappedWriteHandler<MemoryAccessSize::Word>)); 2075 2076 write_handlers[i] = write_handler; 2077 } 2078 #else 2079 MemsetPtrs(write_handlers, write_handler, num_pages); 2080 #endif 2081 } 2082 } 2083 2084 void** Bus::GetMemoryHandlers(bool isolate_cache, bool swap_caches) 2085 { 2086 if (!isolate_cache) 2087 return g_memory_handlers; 2088 2089 #ifdef _DEBUG 2090 if (swap_caches) 2091 WARNING_LOG("Cache isolated and swapped, icache will be written instead of scratchpad?"); 2092 #endif 2093 2094 return g_memory_handlers_isc; 2095 }