diff --git a/include/dynarmic/callbacks.h b/include/dynarmic/callbacks.h index d40e881f..dffc2542 100644 --- a/include/dynarmic/callbacks.h +++ b/include/dynarmic/callbacks.h @@ -9,9 +9,11 @@ #include #include #include +#include namespace Dynarmic { +class Coprocessor; class Jit; /// These function pointers may be inserted into compiled code. @@ -53,6 +55,9 @@ struct UserCallbacks { static constexpr std::size_t PAGE_BITS = 12; static constexpr std::size_t NUM_PAGE_TABLE_ENTRIES = 1 << (32 - PAGE_BITS); std::array* page_table = nullptr; + + // Coprocessors + std::array, 16> coprocessors; }; } // namespace Dynarmic diff --git a/include/dynarmic/coprocessor.h b/include/dynarmic/coprocessor.h new file mode 100644 index 00000000..9a0a33e4 --- /dev/null +++ b/include/dynarmic/coprocessor.h @@ -0,0 +1,98 @@ +/* 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 + +#include +#include + +#include + +namespace Dynarmic { + +class Jit; + +class Coprocessor { +public: + virtual ~Coprocessor() = 0; + + using CoprocReg = Arm::CoprocReg; + + struct Callback { + /** + * @param jit CPU state + * @param user_arg Set to Callback::user_arg at runtime + * @param arg0 Purpose of this argument depends on type of callback. + * @param arg1 Purpose of this argument depends on type of callback. + * @return Purpose of return value depends on type of callback. + */ + std::uint64_t (*function)(Jit* jit, void* user_arg, std::uint32_t arg0, std::uint32_t arg1); + /// If boost::none, function will be called with a user_arg parameter containing garbage. + boost::optional user_arg; + }; + + /** + * Called when compiling CDP or CDP2 for this coprocessor. + * A return value of boost::none will cause a coprocessor exception to be compiled. + * arg0, arg1 and return value of callback are ignored. + */ + virtual boost::optional CompileInternalOperation(bool two, unsigned opc1, CoprocReg CRd, CoprocReg CRn, CoprocReg CRm, unsigned opc2) = 0; + + /** + * Called when compiling MCR or MCR2 for this coprocessor. + * A return value of boost::none will cause a coprocessor exception to be compiled. + * arg0 of the callback will contain the word sent to the coprocessor. + * arg1 and return value of the callback are ignored. + */ + virtual boost::optional CompileSendOneWord(bool two, unsigned opc1, CoprocReg CRn, CoprocReg CRm, unsigned opc2) = 0; + + /** + * Called when compiling MCRR or MCRR2 for this coprocessor. + * A return value of boost::none will cause a coprocessor exception to be compiled. + * arg0 and arg1 of the callback will contain the words sent to the coprocessor. + * The return value of the callback is ignored. + */ + virtual boost::optional CompileSendTwoWords(bool two, unsigned opc, CoprocReg CRm) = 0; + + /** + * Called when compiling MRC or MRC2 for this coprocessor. + * A return value of boost::none will cause a coprocessor exception to be compiled. + * The return value of the callback should contain word from coprocessor. + * The low word of the return value will be stored in Rt. + * arg0 and arg1 of the callback are ignored. + */ + virtual boost::optional CompileGetOneWord(bool two, unsigned opc1, CoprocReg CRn, CoprocReg CRm, unsigned opc2) = 0; + + /** + * Called when compiling MRRC or MRRC2 for this coprocessor. + * A return value of boost::none will cause a coprocessor exception to be compiled. + * The return value of the callback should contain words from coprocessor. + * The low word of the return value will be stored in Rt. + * The high word of the return value will be stored in Rt2. + * arg0 and arg1 of the callback are ignored. + */ + virtual boost::optional CompileGetTwoWords(bool two, unsigned opc, CoprocReg CRm) = 0; + + /** + * Called when compiling LDC or LDC2 for this coprocessor. + * A return value of boost::none will cause a coprocessor exception to be compiled. + * arg0 of the callback will contain the start address. + * arg1 and return value of the callback are ignored. + */ + virtual boost::optional CompileLoadWords(bool two, bool long_transfer, CoprocReg CRd, boost::optional option) = 0; + + /** + * Called when compiling STC or STC2 for this coprocessor. + * A return value of boost::none will cause a coprocessor exception to be compiled. + * arg0 of the callback will contain the start address. + * arg1 and return value of the callback are ignored. + */ + virtual boost::optional CompileStoreWords(bool two, bool long_transfer, CoprocReg CRd, boost::optional option) = 0; +}; + +} // namespace Dynarmic diff --git a/include/dynarmic/coprocessor_util.h b/include/dynarmic/coprocessor_util.h new file mode 100644 index 00000000..8318e812 --- /dev/null +++ b/include/dynarmic/coprocessor_util.h @@ -0,0 +1,17 @@ +/* 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 + +namespace Dynarmic { +namespace Arm { + +enum class CoprocReg { + C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15 +}; + +} // namespace Arm +} // namespace Dynarmic diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ca2d4b6d..b029adb4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,9 +32,11 @@ set(SRCS ) set(HEADERS - ../include/dynarmic/dynarmic.h ../include/dynarmic/callbacks.h + ../include/dynarmic/coprocessor.h + ../include/dynarmic/coprocessor_util.h ../include/dynarmic/disassembler.h + ../include/dynarmic/dynarmic.h common/assert.h common/bit_util.h common/common_types.h