64 lines
2.5 KiB
C
Raw Normal View History

2016-08-25 18:22:08 +01:00
/* This file is part of the dynarmic project.
* Copyright (c) 2016 MerryMage
* This software may be used and distributed according to the terms of the GNU
* General Public License version 2 or any later version.
*/
#pragma once
#include <array>
#include <cstddef>
2016-08-25 18:22:08 +01:00
#include <cstdint>
2016-12-31 10:38:24 +00:00
#include <memory>
2016-08-25 18:22:08 +01:00
namespace Dynarmic {
2016-12-31 10:38:24 +00:00
class Coprocessor;
2016-08-25 18:22:08 +01:00
class Jit;
/// These function pointers may be inserted into compiled code.
struct UserCallbacks {
// All reads through this callback are 4-byte aligned.
// Memory must be interpreted as little endian.
std::uint32_t (*MemoryReadCode)(std::uint32_t vaddr);
2016-12-21 20:37:15 +00:00
// Reads through these callbacks may not be aligned.
// Memory must be interpreted as if ENDIANSTATE == 0, endianness will be corrected by the JIT.
2016-08-25 18:22:08 +01:00
std::uint8_t (*MemoryRead8)(std::uint32_t vaddr);
std::uint16_t (*MemoryRead16)(std::uint32_t vaddr);
std::uint32_t (*MemoryRead32)(std::uint32_t vaddr);
std::uint64_t (*MemoryRead64)(std::uint32_t vaddr);
2016-12-21 20:37:15 +00:00
// Writes through these callbacks may not be aligned.
// Memory must be interpreted as if ENDIANSTATE == 0, endianness will be corrected by the JIT.
2016-08-25 18:22:08 +01:00
void (*MemoryWrite8)(std::uint32_t vaddr, std::uint8_t value);
void (*MemoryWrite16)(std::uint32_t vaddr, std::uint16_t value);
void (*MemoryWrite32)(std::uint32_t vaddr, std::uint32_t value);
void (*MemoryWrite64)(std::uint32_t vaddr, std::uint64_t value);
2016-12-21 20:37:15 +00:00
// If this callback returns true, the JIT will assume MemoryRead* callbacks will always
// return the same value at any point in time for this vaddr. The JIT may use this information
// in optimizations.
// An conservative implementation that always returns false is safe.
2016-08-25 18:22:08 +01:00
bool (*IsReadOnlyMemory)(std::uint32_t vaddr);
/// The intrepreter must execute only one instruction at PC.
void (*InterpreterFallback)(std::uint32_t pc, Jit* jit, void* user_arg);
void* user_arg = nullptr;
2016-08-25 18:22:08 +01:00
2016-12-21 20:37:15 +00:00
// This callback is called whenever a SVC instruction is executed.
2016-09-05 19:15:45 +01:00
void (*CallSVC)(std::uint32_t swi);
// Page Table
2016-12-21 20:37:15 +00:00
// The page table is used for faster memory access. If an entry in the table is nullptr,
// the JIT will fallback to calling the MemoryRead*/MemoryWrite* callbacks.
static constexpr std::size_t PAGE_BITS = 12;
static constexpr std::size_t NUM_PAGE_TABLE_ENTRIES = 1 << (32 - PAGE_BITS);
std::array<std::uint8_t*, NUM_PAGE_TABLE_ENTRIES>* page_table = nullptr;
2016-12-31 10:38:24 +00:00
// Coprocessors
std::array<std::shared_ptr<Coprocessor>, 16> coprocessors;
2016-08-25 18:22:08 +01:00
};
} // namespace Dynarmic