From 0c256db56071238d5593ef2d5b630c7cce26d784 Mon Sep 17 00:00:00 2001 From: jakcron Date: Fri, 7 Jul 2017 17:09:03 +1000 Subject: [PATCH] [nx] Add ACI kernel capability Classes. --- lib/nx/HandleTableSizeEntry.cpp | 54 ++++++++++++++ lib/nx/HandleTableSizeEntry.h | 43 +++++++++++ lib/nx/IKernelCapabilityHandler.h | 15 ++++ lib/nx/InteruptEntry.cpp | 73 +++++++++++++++++++ lib/nx/InteruptEntry.h | 50 +++++++++++++ lib/nx/KernelCapability.cpp | 66 +++++++++++++++++ lib/nx/KernelCapability.h | 62 ++++++++++++++++ lib/nx/KernelVersionEntry.cpp | 74 +++++++++++++++++++ lib/nx/KernelVersionEntry.h | 52 ++++++++++++++ lib/nx/MemoryPageEntry.cpp | 91 ++++++++++++++++++++++++ lib/nx/MemoryPageEntry.h | 56 +++++++++++++++ lib/nx/MiscFlagsEntry.cpp | 54 ++++++++++++++ lib/nx/MiscFlagsEntry.h | 64 +++++++++++++++++ lib/nx/MiscParamsEntry.cpp | 54 ++++++++++++++ lib/nx/MiscParamsEntry.h | 45 ++++++++++++ lib/nx/SystemCallEntry.cpp | 76 ++++++++++++++++++++ lib/nx/SystemCallEntry.h | 53 ++++++++++++++ lib/nx/ThreadInfoEntry.cpp | 114 ++++++++++++++++++++++++++++++ lib/nx/ThreadInfoEntry.h | 62 ++++++++++++++++ lib/nx/nx.vcxproj | 19 +++++ lib/nx/nx.vcxproj.filters | 57 +++++++++++++++ 21 files changed, 1234 insertions(+) create mode 100644 lib/nx/HandleTableSizeEntry.cpp create mode 100644 lib/nx/HandleTableSizeEntry.h create mode 100644 lib/nx/IKernelCapabilityHandler.h create mode 100644 lib/nx/InteruptEntry.cpp create mode 100644 lib/nx/InteruptEntry.h create mode 100644 lib/nx/KernelCapability.cpp create mode 100644 lib/nx/KernelCapability.h create mode 100644 lib/nx/KernelVersionEntry.cpp create mode 100644 lib/nx/KernelVersionEntry.h create mode 100644 lib/nx/MemoryPageEntry.cpp create mode 100644 lib/nx/MemoryPageEntry.h create mode 100644 lib/nx/MiscFlagsEntry.cpp create mode 100644 lib/nx/MiscFlagsEntry.h create mode 100644 lib/nx/MiscParamsEntry.cpp create mode 100644 lib/nx/MiscParamsEntry.h create mode 100644 lib/nx/SystemCallEntry.cpp create mode 100644 lib/nx/SystemCallEntry.h create mode 100644 lib/nx/ThreadInfoEntry.cpp create mode 100644 lib/nx/ThreadInfoEntry.h diff --git a/lib/nx/HandleTableSizeEntry.cpp b/lib/nx/HandleTableSizeEntry.cpp new file mode 100644 index 0000000..ebd7ff3 --- /dev/null +++ b/lib/nx/HandleTableSizeEntry.cpp @@ -0,0 +1,54 @@ +#include "HandleTableSizeEntry.h" + + + +nx::HandleTableSizeEntry::HandleTableSizeEntry() : + mCap(kCapId), + mHandleTableSize(0) +{} + +nx::HandleTableSizeEntry::HandleTableSizeEntry(const KernelCapability & kernel_cap) : + mCap(kCapId), + mHandleTableSize(0) +{ + setKernelCapability(kernel_cap); +} + +nx::HandleTableSizeEntry::HandleTableSizeEntry(u16 size) : + mCap(kCapId), + mHandleTableSize(0) +{ + setHandleTableSize(size); +} + +const nx::KernelCapability & nx::HandleTableSizeEntry::getKernelCapability() const +{ + return mCap; +} + +void nx::HandleTableSizeEntry::setKernelCapability(const KernelCapability & kernel_cap) +{ + if (kernel_cap.getType() != kCapId) + { + throw fnd::Exception(kModuleName, "KernelCapability is not type 'HandleTableSize'"); + } + + mCap = kernel_cap; + processCapField(); +} + +u16 nx::HandleTableSizeEntry::getHandleTableSize() const +{ + return mHandleTableSize; +} + +void nx::HandleTableSizeEntry::setHandleTableSize(u16 size) +{ + if (size > kMaxHandleTableSize) + { + throw fnd::Exception(kModuleName, "Illegal HandleTableSize. (range: 0-1023 inclusive)"); + } + + mHandleTableSize = size; + updateCapField(); +} \ No newline at end of file diff --git a/lib/nx/HandleTableSizeEntry.h b/lib/nx/HandleTableSizeEntry.h new file mode 100644 index 0000000..e00578d --- /dev/null +++ b/lib/nx/HandleTableSizeEntry.h @@ -0,0 +1,43 @@ +#pragma once +#include +#include +#include + +namespace nx +{ + class HandleTableSizeEntry + { + public: + HandleTableSizeEntry(); + HandleTableSizeEntry(const KernelCapability& kernel_cap); + HandleTableSizeEntry(u16 size); + + // kernel capability + const KernelCapability& getKernelCapability() const; + void setKernelCapability(const KernelCapability& kernel_cap); + + // variables + u16 getHandleTableSize() const; + void setHandleTableSize(u16 size); + private: + const std::string kModuleName = "HANDLE_TABLE_SIZE_ENTRY"; + static const KernelCapability::KernelCapId kCapId = KernelCapability::KC_HANDLE_TABLE_SIZE; + static const u16 kValBits = 10; + static const u16 kMaxHandleTableSize = BIT(kValBits) - 1; + + KernelCapability mCap; + u16 mHandleTableSize; + + inline void updateCapField() + { + u32 field = mHandleTableSize & kMaxHandleTableSize; + mCap.setField(field); + } + + inline void processCapField() + { + u32 field = mCap.getField(); + mHandleTableSize = field & kMaxHandleTableSize; + } + }; +} \ No newline at end of file diff --git a/lib/nx/IKernelCapabilityHandler.h b/lib/nx/IKernelCapabilityHandler.h new file mode 100644 index 0000000..4b97ac8 --- /dev/null +++ b/lib/nx/IKernelCapabilityHandler.h @@ -0,0 +1,15 @@ +#pragma once +#include +#include +#include + +namespace nx +{ + class IKernelCapabilityHandler + { + public: + virtual void importKernelCapabilityList(const fnd::List& caps) = 0; + virtual const fnd::List& exportKernelCapabilityList() = 0; + }; +} + diff --git a/lib/nx/InteruptEntry.cpp b/lib/nx/InteruptEntry.cpp new file mode 100644 index 0000000..f29c2bf --- /dev/null +++ b/lib/nx/InteruptEntry.cpp @@ -0,0 +1,73 @@ +#include "InteruptEntry.h" + + + +nx::InteruptEntry::InteruptEntry() : + mCap(kCapId), + mInterupt{0,0} +{ + +} + +nx::InteruptEntry::InteruptEntry(const KernelCapability & kernel_cap) : + mCap(kCapId), + mInterupt{ 0,0 } +{ + setKernelCapability(kernel_cap); +} + +nx::InteruptEntry::InteruptEntry(u32 interupt0, u32 interupt1) : + mCap(kCapId), + mInterupt{ 0,0 } +{ + setInterupt0(interupt0); + setInterupt1(interupt1); +} + +const nx::KernelCapability & nx::InteruptEntry::getKernelCapability() const +{ + return mCap; +} + +void nx::InteruptEntry::setKernelCapability(const KernelCapability & kernel_cap) +{ + if (kernel_cap.getType() != kCapId) + { + throw fnd::Exception(kModuleName, "KernelCapability is not type 'EnableInterupts'"); + } + + mCap = kernel_cap; + processCapField(); +} + +u32 nx::InteruptEntry::getInterupt0() const +{ + return mInterupt[0]; +} + +void nx::InteruptEntry::setInterupt0(u32 interupt) +{ + if (interupt > kInteruptMax) + { + throw fnd::Exception(kModuleName, "Illegal interupt value."); + } + + mInterupt[0] = interupt; + updateCapField(); +} + +u32 nx::InteruptEntry::getInterupt1() const +{ + return mInterupt[1]; +} + +void nx::InteruptEntry::setInterupt1(u32 interupt) +{ + if (interupt > kInteruptMax) + { + throw fnd::Exception(kModuleName, "Illegal interupt value."); + } + + mInterupt[1] = interupt; + updateCapField(); +} diff --git a/lib/nx/InteruptEntry.h b/lib/nx/InteruptEntry.h new file mode 100644 index 0000000..cf86a00 --- /dev/null +++ b/lib/nx/InteruptEntry.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include +#include + +namespace nx +{ + class InteruptEntry + { + public: + InteruptEntry(); + InteruptEntry(const KernelCapability& kernel_cap); + InteruptEntry(u32 interupt0, u32 interupt1); + + // kernel capability + const KernelCapability& getKernelCapability() const; + void setKernelCapability(const KernelCapability& kernel_cap); + + // variables + u32 getInterupt0() const; + void setInterupt0(u32 interupt); + u32 getInterupt1() const; + void setInterupt1(u32 interupt); + + private: + const std::string kModuleName = "INTERUPT_ENTRY"; + static const KernelCapability::KernelCapId kCapId = KernelCapability::KC_ENABLE_INTERUPTS; + static const u32 kInteruptBits = 10; + static const u32 kInteruptMax = BIT(kInteruptBits) - 1; + + KernelCapability mCap; + u32 mInterupt[2]; + + inline void updateCapField() + { + u32 field = 0; + field |= (u32)(mInterupt[0] & kInteruptMax) << 0; + field |= (u32)(mInterupt[1] & kInteruptMax) << kInteruptBits; + mCap.setField(field); + } + + inline void processCapField() + { + u32 field = mCap.getField(); + mInterupt[0] = (field >> 0) & kInteruptMax; + mInterupt[1] = (field >> kInteruptBits) & kInteruptMax; + } + }; + +} diff --git a/lib/nx/KernelCapability.cpp b/lib/nx/KernelCapability.cpp new file mode 100644 index 0000000..15e8e33 --- /dev/null +++ b/lib/nx/KernelCapability.cpp @@ -0,0 +1,66 @@ +#include "KernelCapability.h" + +using namespace nx; + +KernelCapability::KernelCapability() : + mType(KC_INVALID) +{} + +KernelCapability::KernelCapability(KernelCapId type) : + mType(type), + mField(0) +{} + +KernelCapability::KernelCapability(KernelCapId type, u32 field) : + mType(type), + mField(field) +{} + +const KernelCapability & nx::KernelCapability::operator=(const KernelCapability & other) +{ + mType = other.mType; + mField = other.mField; + return *this; +} + +bool nx::KernelCapability::operator==(const KernelCapability & other) const +{ + return (mType == other.mType) \ + && (mField == other.mField); +} + +bool nx::KernelCapability::operator!=(const KernelCapability & other) const +{ + return !operator==(other); +} + +u32 KernelCapability::getCap() const +{ + return (mField & getFieldMask()) << getFieldShift() | getCapMask(); +} + +void KernelCapability::setCap(u32 cap) +{ + mType = getCapId(cap); + mField = (cap >> getFieldShift()) & getFieldMask(); +} + +KernelCapability::KernelCapId KernelCapability::getType() const +{ + return mType; +} + +void KernelCapability::setType(KernelCapId type) +{ + mType = type; +} + +u32 KernelCapability::getField() const +{ + return mField & getFieldMask(); +} + +void KernelCapability::setField(u32 field) +{ + mField = field; +} diff --git a/lib/nx/KernelCapability.h b/lib/nx/KernelCapability.h new file mode 100644 index 0000000..55c0020 --- /dev/null +++ b/lib/nx/KernelCapability.h @@ -0,0 +1,62 @@ +#pragma once +#include + +namespace nx +{ + class KernelCapability + { + public: + enum KernelCapId + { + KC_INVALID = 0, + KC_THREAD_INFO = 3, + KC_ENABLE_SYSTEM_CALLS = 4, + KC_MEMORY_MAP = 6, + KC_IO_MEMORY_MAP = 7, + KC_ENABLE_INTERUPTS = 11, + KC_MISC_PARAMS = 13, + KC_KERNEL_VERSION = 14, + KC_HANDLE_TABLE_SIZE = 15, + KC_MISC_FLAGS = 16 + }; + + KernelCapability(); + KernelCapability(KernelCapId type); + KernelCapability(KernelCapId type, u32 field); + + const KernelCapability& operator=(const KernelCapability& other); + bool operator==(const KernelCapability& other) const; + bool operator!=(const KernelCapability& other) const; + + u32 getCap() const; + void setCap(u32 cap); + + KernelCapId getType() const; + void setType(KernelCapId type); + + u32 getField() const; + void setField(u32 field); + + private: + KernelCapId mType; + u32 mField; + + inline u32 getFieldShift() const { return mType + 1; } + inline u32 getFieldMask() const { return BIT(31 - mType) - 1; } + inline u32 getCapMask() const { return BIT(mType) - 1; } + inline KernelCapId getCapId(u32 cap) const + { + KernelCapId id = KC_INVALID; + for (u8 tmp = 0; tmp < 31; tmp++) + { + if (((cap >> tmp) & 1) == 0) + { + id = (KernelCapId)tmp; + break; + } + } + return id; + } + }; +} + diff --git a/lib/nx/KernelVersionEntry.cpp b/lib/nx/KernelVersionEntry.cpp new file mode 100644 index 0000000..19277ce --- /dev/null +++ b/lib/nx/KernelVersionEntry.cpp @@ -0,0 +1,74 @@ +#include "KernelVersionEntry.h" + + + +nx::KernelVersionEntry::KernelVersionEntry() : + mCap(kCapId), + mVerMajor(0), + mVerMinor(0) +{} + +nx::KernelVersionEntry::KernelVersionEntry(const KernelCapability & kernel_cap) : + mCap(kCapId), + mVerMajor(0), + mVerMinor(0) +{ + setKernelCapability(kernel_cap); +} + +nx::KernelVersionEntry::KernelVersionEntry(u16 major, u8 minor) : + mCap(kCapId), + mVerMajor(0), + mVerMinor(0) +{ + setVerMajor(major); + setVerMinor(minor); +} + +const nx::KernelCapability & nx::KernelVersionEntry::getKernelCapability() const +{ + return mCap; +} + +void nx::KernelVersionEntry::setKernelCapability(const KernelCapability & kernel_cap) +{ + if (kernel_cap.getType() != kCapId) + { + throw fnd::Exception(kModuleName, "KernelCapability is not type 'KernelVersion'"); + } + + mCap = kernel_cap; + processCapField(); +} + +u16 nx::KernelVersionEntry::getVerMajor() const +{ + return mVerMajor; +} + +void nx::KernelVersionEntry::setVerMajor(u16 major) +{ + if (major > kVerMajorMax) + { + throw fnd::Exception(kModuleName, "Illegal KernelVersionMajor. (range: 0-0x1fff)"); + } + + mVerMajor = major; + updateCapField(); +} + +u8 nx::KernelVersionEntry::getVerMinor() const +{ + return mVerMinor; +} + +void nx::KernelVersionEntry::setVerMinor(u8 minor) +{ + if (minor > kVerMinorMax) + { + throw fnd::Exception(kModuleName, "Illegal KernelVersionMinor. (range: 0-0xf)"); + } + + mVerMinor = minor; + updateCapField(); +} diff --git a/lib/nx/KernelVersionEntry.h b/lib/nx/KernelVersionEntry.h new file mode 100644 index 0000000..c5cbb89 --- /dev/null +++ b/lib/nx/KernelVersionEntry.h @@ -0,0 +1,52 @@ +#pragma once +#include +#include +#include + +namespace nx +{ + class KernelVersionEntry + { + public: + KernelVersionEntry(); + KernelVersionEntry(const KernelCapability& kernel_cap); + KernelVersionEntry(u16 major, u8 minor); + + // kernel capability + const KernelCapability& getKernelCapability() const; + void setKernelCapability(const KernelCapability& kernel_cap); + + // variables + u16 getVerMajor() const; + void setVerMajor(u16 major); + u8 getVerMinor() const; + void setVerMinor(u8 minor); + private: + const std::string kModuleName = "KERNEL_VERSION_ENTRY"; + static const KernelCapability::KernelCapId kCapId = KernelCapability::KC_KERNEL_VERSION; + static const u32 kVerMajorBits = 13; + static const u32 kVerMajorMax = BIT(kVerMajorBits) - 1; + static const u32 kVerMinorBits = 4; + static const u32 kVerMinorMax = BIT(kVerMinorBits) - 1; + + KernelCapability mCap; + u16 mVerMajor; + u8 mVerMinor; + + inline void updateCapField() + { + u32 field = 0; + field |= (u32)(mVerMinor & kVerMinorMax) << 0; + field |= (u32)(mVerMajor & kVerMajorMax) << kVerMinorBits; + mCap.setField(field); + } + + inline void processCapField() + { + u32 field = mCap.getField(); + mVerMinor = (field >> 0) & kVerMinorMax; + mVerMajor = (field >> kVerMinorBits) & kVerMajorMax; + } + }; +} + diff --git a/lib/nx/MemoryPageEntry.cpp b/lib/nx/MemoryPageEntry.cpp new file mode 100644 index 0000000..6a3b541 --- /dev/null +++ b/lib/nx/MemoryPageEntry.cpp @@ -0,0 +1,91 @@ +#include "MemoryPageEntry.h" + + + +nx::MemoryPageEntry::MemoryPageEntry() : + mCap(KernelCapability::KC_INVALID), + mPage(0), + mFlag(false), + mUseFlag(false) +{} + +nx::MemoryPageEntry::MemoryPageEntry(const KernelCapability & kernel_cap) : + mCap(KernelCapability::KC_INVALID), + mPage(0), + mFlag(false), + mUseFlag(false) +{ + setKernelCapability(kernel_cap); +} + +nx::MemoryPageEntry::MemoryPageEntry(u32 page) : + mCap(KernelCapability::KC_INVALID), + mPage(0), + mFlag(false), + mUseFlag(false) +{ + setPage(page); +} + +nx::MemoryPageEntry::MemoryPageEntry(u32 page, bool flag) : + mCap(KernelCapability::KC_INVALID), + mPage(0), + mFlag(false), + mUseFlag(true) +{ + setPage(page); + setFlag(flag); +} + +const nx::KernelCapability & nx::MemoryPageEntry::getKernelCapability() const +{ + return mCap; +} + +void nx::MemoryPageEntry::setKernelCapability(const KernelCapability & kernel_cap) +{ + if (kernel_cap.getType() != KernelCapability::KC_MEMORY_MAP && kernel_cap.getType() != KernelCapability::KC_IO_MEMORY_MAP) + { + throw fnd::Exception(kModuleName, "KernelCapability is not type 'MemoryMap' or 'IOMemoryMap"); + } + + mCap = kernel_cap; + processCapField(); +} + +u32 nx::MemoryPageEntry::getPage() const +{ + return mPage; +} + +void nx::MemoryPageEntry::setPage(u32 page) +{ + if (page > kMaxPage) + { + throw fnd::Exception(kModuleName, "Illegal memory page. (range: 0x000000 - 0xFFFFFF)"); + } + + mPage = page; + updateCapField(); +} + +bool nx::MemoryPageEntry::getFlag() const +{ + return mFlag; +} + +void nx::MemoryPageEntry::setFlag(bool flag) +{ + mFlag = flag; + updateCapField(); +} + +bool nx::MemoryPageEntry::hasFlag() const +{ + return mUseFlag; +} + +void nx::MemoryPageEntry::useFlag(bool useFlag) +{ + mUseFlag = useFlag; +} diff --git a/lib/nx/MemoryPageEntry.h b/lib/nx/MemoryPageEntry.h new file mode 100644 index 0000000..378efbf --- /dev/null +++ b/lib/nx/MemoryPageEntry.h @@ -0,0 +1,56 @@ +#pragma once +#include +#include +#include + +namespace nx +{ + class MemoryPageEntry + { + public: + MemoryPageEntry(); + MemoryPageEntry(const KernelCapability& kernel_cap); + MemoryPageEntry(u32 page); + MemoryPageEntry(u32 page, bool flag); + + // kernel capability + const KernelCapability& getKernelCapability() const; + void setKernelCapability(const KernelCapability& kernel_cap); + + // variables + u32 getPage() const; + void setPage(u32 page); + bool getFlag() const; + void setFlag(bool flag); + + bool hasFlag() const; + void useFlag(bool useFlag); + private: + const std::string kModuleName = "MEMORY_PAGE_ENTRY"; + static const u32 kPageBits = 24; + static const u32 kMaxPage = BIT(kPageBits) - 1; + + KernelCapability mCap; + u32 mPage; + bool mFlag; + bool mUseFlag; + + inline void updateCapField() + { + u32 field = 0; + field |= (u32)(mPage & kMaxPage) << 0; + field |= (u32)(mFlag) << kPageBits; + mCap.setField(field); + mCap.setType(mUseFlag ? KernelCapability::KC_MEMORY_MAP : KernelCapability::KC_IO_MEMORY_MAP); + } + + inline void processCapField() + { + u32 field = mCap.getField(); + mPage = (field >> 0) & kMaxPage; + mFlag = (field >> kPageBits); + mUseFlag = mCap.getType() == KernelCapability::KC_MEMORY_MAP; + } + }; + +} diff --git a/lib/nx/MiscFlagsEntry.cpp b/lib/nx/MiscFlagsEntry.cpp new file mode 100644 index 0000000..4b40de6 --- /dev/null +++ b/lib/nx/MiscFlagsEntry.cpp @@ -0,0 +1,54 @@ +#include "MiscFlagsEntry.h" + + + +nx::MiscFlagsEntry::MiscFlagsEntry() : + mCap(kCapId), + mFlags(0) +{} + +nx::MiscFlagsEntry::MiscFlagsEntry(const KernelCapability & kernel_cap) : + mCap(kCapId), + mFlags(0) +{ + setKernelCapability(kernel_cap); +} + +nx::MiscFlagsEntry::MiscFlagsEntry(u32 flags) : + mCap(kCapId), + mFlags(0) +{ + setFlags(flags); +} + +const nx::KernelCapability & nx::MiscFlagsEntry::getKernelCapability() const +{ + return mCap; +} + +void nx::MiscFlagsEntry::setKernelCapability(const KernelCapability & kernel_cap) +{ + if (kernel_cap.getType() != kCapId) + { + throw fnd::Exception(kModuleName, "KernelCapability is not type 'MiscFlags'"); + } + + mCap = kernel_cap; + processCapField(); +} + +u32 nx::MiscFlagsEntry::getFlags() const +{ + return mFlags; +} + +void nx::MiscFlagsEntry::setFlags(u32 flags) +{ + if ((flags & ~kMaxVal) != 0) + { + throw fnd::Exception(kModuleName, "Illegal MiscFlag bits set. (settable bits: 0-14 inclusive)"); + } + + mFlags = flags; + updateCapField(); +} diff --git a/lib/nx/MiscFlagsEntry.h b/lib/nx/MiscFlagsEntry.h new file mode 100644 index 0000000..08c1c7e --- /dev/null +++ b/lib/nx/MiscFlagsEntry.h @@ -0,0 +1,64 @@ +#pragma once +#include +#include +#include + +namespace nx +{ + class MiscFlagsEntry + { + public: + // consider different definition location, perhaps in MiscFlagsHandler? + enum Flags + { + FLAG_ENABLE_DEBUG = BIT(0), + FLAG_FORCE_DEBUG = BIT(1), + FLAG_UNK02 = BIT(2), + FLAG_UNK03 = BIT(3), + FLAG_UNK04 = BIT(4), + FLAG_UNK05 = BIT(5), + FLAG_UNK06 = BIT(6), + FLAG_UNK07 = BIT(7), + FLAG_UNK08 = BIT(8), + FLAG_UNK09 = BIT(9), + FLAG_UNK10 = BIT(10), + FLAG_UNK11 = BIT(11), + FLAG_UNK12 = BIT(12), + FLAG_UNK13 = BIT(13), + FLAG_UNK14 = BIT(14), + }; + + MiscFlagsEntry(); + MiscFlagsEntry(const KernelCapability& kernel_cap); + MiscFlagsEntry(u32 flags); + + // kernel capability + const KernelCapability& getKernelCapability() const; + void setKernelCapability(const KernelCapability& kernel_cap); + + // variables + u32 getFlags() const; + void setFlags(u32 flags); + private: + const std::string kModuleName = "MISC_FLAG_ENTRY"; + static const KernelCapability::KernelCapId kCapId = KernelCapability::KC_MISC_FLAGS; + static const u32 kValueBits = 15; + static const u32 kMaxVal = BIT(kValueBits)-1; + + KernelCapability mCap; + u32 mFlags; + + inline void updateCapField() + { + u32 field = mFlags & kMaxVal; + mCap.setField(field); + } + + inline void processCapField() + { + u32 field = mCap.getField(); + mFlags = field & kMaxVal; + } + }; + +} diff --git a/lib/nx/MiscParamsEntry.cpp b/lib/nx/MiscParamsEntry.cpp new file mode 100644 index 0000000..581d303 --- /dev/null +++ b/lib/nx/MiscParamsEntry.cpp @@ -0,0 +1,54 @@ +#include "MiscParamsEntry.h" + + + +nx::MiscParamsEntry::MiscParamsEntry() : + mCap(kCapId), + mProgramType(0) +{} + +nx::MiscParamsEntry::MiscParamsEntry(const KernelCapability & kernel_cap) : + mCap(kCapId), + mProgramType(0) +{ + setKernelCapability(kernel_cap); +} + +nx::MiscParamsEntry::MiscParamsEntry(u8 program_type) : + mCap(kCapId), + mProgramType(0) +{ + setProgramType(program_type); +} + +const nx::KernelCapability & nx::MiscParamsEntry::getKernelCapability() const +{ + return mCap; +} + +void nx::MiscParamsEntry::setKernelCapability(const KernelCapability & kernel_cap) +{ + if (kernel_cap.getType() != kCapId) + { + throw fnd::Exception(kModuleName, "KernelCapability is not type 'ThreadInfo'"); + } + + mCap = kernel_cap; + processCapField(); +} + +u8 nx::MiscParamsEntry::getProgramType() const +{ + return mProgramType; +} + +void nx::MiscParamsEntry::setProgramType(u8 type) +{ + if (type > kMaxProgramType) + { + throw fnd::Exception(kModuleName, "Illegal ProgramType. (range: 0-7 inclusive)"); + } + + mProgramType = type; + updateCapField(); +} diff --git a/lib/nx/MiscParamsEntry.h b/lib/nx/MiscParamsEntry.h new file mode 100644 index 0000000..4ffd591 --- /dev/null +++ b/lib/nx/MiscParamsEntry.h @@ -0,0 +1,45 @@ +#pragma once +#include +#include +#include + +namespace nx +{ + class MiscParamsEntry + { + public: + MiscParamsEntry(); + MiscParamsEntry(const KernelCapability& kernel_cap); + MiscParamsEntry(u8 program_type); + + // kernel capability + const KernelCapability& getKernelCapability() const; + void setKernelCapability(const KernelCapability& kernel_cap); + + // variables + u8 getProgramType() const; + void setProgramType(u8 type); + private: + const std::string kModuleName = "MISC_PARAMS_ENTRY"; + static const KernelCapability::KernelCapId kCapId = KernelCapability::KC_MISC_PARAMS; + static const u8 kValBits = 3; + static const u8 kMaxProgramType = BIT(kValBits)-1; + + KernelCapability mCap; + u8 mProgramType; + + inline void updateCapField() + { + u32 field = mProgramType & kMaxProgramType; + mCap.setField(field); + } + + inline void processCapField() + { + u32 field = mCap.getField(); + mProgramType = field & kMaxProgramType; + } + }; + + +} \ No newline at end of file diff --git a/lib/nx/SystemCallEntry.cpp b/lib/nx/SystemCallEntry.cpp new file mode 100644 index 0000000..dde30ba --- /dev/null +++ b/lib/nx/SystemCallEntry.cpp @@ -0,0 +1,76 @@ +#include "SystemCallEntry.h" + + + +nx::SystemCallEntry::SystemCallEntry() : + mCap(kCapId), + mSystemCallUpper(0), + mSystemCallLower(0) +{ + +} + +nx::SystemCallEntry::SystemCallEntry(const KernelCapability & kernel_cap) : + mCap(kCapId), + mSystemCallUpper(0), + mSystemCallLower(0) +{ + setKernelCapability(kernel_cap); +} + +nx::SystemCallEntry::SystemCallEntry(u32 upper_bits, u32 lower_bits) : + mCap(kCapId), + mSystemCallUpper(0), + mSystemCallLower(0) +{ + setSystemCallUpperBits(upper_bits); + setSystemCallLowerBits(lower_bits); +} + +const nx::KernelCapability & nx::SystemCallEntry::getKernelCapability() const +{ + return mCap; +} + +void nx::SystemCallEntry::setKernelCapability(const KernelCapability & kernel_cap) +{ + if (kernel_cap.getType() != kCapId) + { + throw fnd::Exception(kModuleName, "KernelCapability is not type 'EnableSystemCalls'"); + } + + mCap = kernel_cap; + processCapField(); +} + +u32 nx::SystemCallEntry::getSystemCallUpperBits() const +{ + return mSystemCallUpper; +} + +void nx::SystemCallEntry::setSystemCallUpperBits(u32 upper_bits) +{ + if (upper_bits > kSysCallUpperMax) + { + throw fnd::Exception(kModuleName, "Illegal SystemCall upper bits."); + } + + mSystemCallUpper = upper_bits; + updateCapField(); +} + +u32 nx::SystemCallEntry::getSystemCallLowerBits() const +{ + return mSystemCallLower; +} + +void nx::SystemCallEntry::setSystemCallLowerBits(u32 lower_bits) +{ + if (lower_bits > kSysCallLowerMax) + { + throw fnd::Exception(kModuleName, "Illegal SystemCall upper bits."); + } + + mSystemCallLower = lower_bits; + updateCapField(); +} diff --git a/lib/nx/SystemCallEntry.h b/lib/nx/SystemCallEntry.h new file mode 100644 index 0000000..222ae4b --- /dev/null +++ b/lib/nx/SystemCallEntry.h @@ -0,0 +1,53 @@ +#pragma once +#include +#include +#include + +namespace nx +{ + class SystemCallEntry + { + public: + SystemCallEntry(); + SystemCallEntry(const KernelCapability& kernel_cap); + SystemCallEntry(u32 upper_bits, u32 lower_bits); + + // kernel capability + const KernelCapability& getKernelCapability() const; + void setKernelCapability(const KernelCapability& kernel_cap); + + // variables + u32 getSystemCallUpperBits() const; + void setSystemCallUpperBits(u32 upper_bits); + u32 getSystemCallLowerBits() const; + void setSystemCallLowerBits(u32 lower_bits); + + private: + const std::string kModuleName = "SYSTEM_CALL_ENTRY"; + static const KernelCapability::KernelCapId kCapId = KernelCapability::KC_ENABLE_SYSTEM_CALLS; + static const u32 kSysCallUpperBits = 3; + static const u32 kSysCallLowerBits = 23; + static const u32 kSysCallUpperMax = BIT(kSysCallUpperBits) - 1; + static const u32 kSysCallLowerMax = BIT(kSysCallLowerBits) - 1; + + KernelCapability mCap; + u32 mSystemCallUpper; + u32 mSystemCallLower; + + inline void updateCapField() + { + u32 field = 0; + field |= (u32)(mSystemCallLower & kSysCallLowerMax) << 0; + field |= (u32)(mSystemCallUpper & kSysCallUpperMax) << kSysCallLowerBits; + mCap.setField(field); + } + + inline void processCapField() + { + u32 field = mCap.getField(); + mSystemCallLower = (field >> 0) & kSysCallLowerMax; + mSystemCallUpper = (field >> kSysCallLowerBits) & kSysCallUpperMax; + } + }; +} + diff --git a/lib/nx/ThreadInfoEntry.cpp b/lib/nx/ThreadInfoEntry.cpp new file mode 100644 index 0000000..09f8f3d --- /dev/null +++ b/lib/nx/ThreadInfoEntry.cpp @@ -0,0 +1,114 @@ +#include "ThreadInfoEntry.h" + + + +nx::ThreadInfoEntry::ThreadInfoEntry() : + mCap(kCapId), + mMinPriority(kDefaultPriority), + mMaxPriority(kDefaultPriority), + mMinCoreNumber(kDefaultCoreNumber), + mMaxCoreNumber(kDefaultCoreNumber) +{} + +nx::ThreadInfoEntry::ThreadInfoEntry(const KernelCapability & kernel_cap) : + mCap(kCapId), + mMinPriority(kDefaultPriority), + mMaxPriority(kDefaultPriority), + mMinCoreNumber(kDefaultCoreNumber), + mMaxCoreNumber(kDefaultCoreNumber) +{ + setKernelCapability(kernel_cap); +} + +nx::ThreadInfoEntry::ThreadInfoEntry(u8 min_priority, u8 max_priority, u8 min_core_number, u8 max_core_number) : + mCap(kCapId), + mMinPriority(kDefaultPriority), + mMaxPriority(kDefaultPriority), + mMinCoreNumber(kDefaultCoreNumber), + mMaxCoreNumber(kDefaultCoreNumber) +{ + setMinPriority(min_priority); + setMaxPriority(max_priority); + setMinCoreNumber(min_core_number); + setMaxCoreNumber(max_core_number); +} + +const nx::KernelCapability & nx::ThreadInfoEntry::getKernelCapability() const +{ + return mCap; +} + +void nx::ThreadInfoEntry::setKernelCapability(const KernelCapability & kernel_cap) +{ + if (kernel_cap.getType() != kCapId) + { + throw fnd::Exception(kModuleName, "KernelCapability is not type 'ThreadInfo'"); + } + + mCap = kernel_cap; + processCapField(); +} + +u8 nx::ThreadInfoEntry::getMinPriority() const +{ + return mMinPriority; +} + +void nx::ThreadInfoEntry::setMinPriority(u8 priority) +{ + if (priority > kMaxVal) + { + throw fnd::Exception(kModuleName, "Illegal MinPriority (range 0-63)"); + } + + mMinPriority = priority; + updateCapField(); +} + +u8 nx::ThreadInfoEntry::getMaxPriority() const +{ + return mMaxPriority; +} + +void nx::ThreadInfoEntry::setMaxPriority(u8 priority) +{ + if (priority > kMaxVal) + { + throw fnd::Exception(kModuleName, "Illegal MaxPriority (range 0-63)"); + } + + mMaxPriority = priority; + updateCapField(); +} + +u8 nx::ThreadInfoEntry::getMinCoreNumber() const +{ + return mMinCoreNumber; +} + +void nx::ThreadInfoEntry::setMinCoreNumber(u8 core_num) +{ + if (core_num > kMaxVal) + { + throw fnd::Exception(kModuleName, "Illegal MinCoreNumber (range 0-63)"); + } + + mMinCoreNumber = core_num; + updateCapField(); +} + +u8 nx::ThreadInfoEntry::getMaxCoreNumber() const +{ + return mMaxCoreNumber; +} + +void nx::ThreadInfoEntry::setMaxCoreNumber(u8 core_num) +{ + if (core_num > kMaxVal) + { + throw fnd::Exception(kModuleName, "Illegal MaxCoreNumber (range 0-63)"); + } + + mMaxCoreNumber = core_num; + updateCapField(); +} diff --git a/lib/nx/ThreadInfoEntry.h b/lib/nx/ThreadInfoEntry.h new file mode 100644 index 0000000..de0c349 --- /dev/null +++ b/lib/nx/ThreadInfoEntry.h @@ -0,0 +1,62 @@ +#pragma once +#include +#include +#include + +namespace nx +{ + class ThreadInfoEntry + { + public: + ThreadInfoEntry(); + ThreadInfoEntry(const KernelCapability& kernel_cap); + ThreadInfoEntry(u8 min_priority, u8 max_priority, u8 min_core_number, u8 max_core_number); + + // kernel capability + const KernelCapability& getKernelCapability() const; + void setKernelCapability(const KernelCapability& kernel_cap); + + // variables + u8 getMinPriority() const; + void setMinPriority(u8 priority); + u8 getMaxPriority() const; + void setMaxPriority(u8 priority); + u8 getMinCoreNumber() const; + void setMinCoreNumber(u8 core_num); + u8 getMaxCoreNumber() const; + void setMaxCoreNumber(u8 core_num); + + private: + const std::string kModuleName = "THREAD_INFO_ENTRY"; + static const KernelCapability::KernelCapId kCapId = KernelCapability::KC_THREAD_INFO; + static const u8 kValBits = 6; + static const u8 kMaxVal = BIT(kValBits)-1; + static const u8 kDefaultPriority = 6; + static const u8 kDefaultCoreNumber = 8; + + KernelCapability mCap; + u8 mMinPriority; + u8 mMaxPriority; + u8 mMinCoreNumber; + u8 mMaxCoreNumber; + + inline void updateCapField() + { + u32 field = 0; + field |= (u32)(mMinPriority & kMaxVal) << (kValBits * 0); + field |= (u32)(mMaxPriority & kMaxVal) << (kValBits * 1); + field |= (u32)(mMinCoreNumber & kMaxVal) << (kValBits * 2); + field |= (u32)(mMaxCoreNumber & kMaxVal) << (kValBits * 3); + mCap.setField(field); + } + + inline void processCapField() + { + u32 field = mCap.getField(); + mMinPriority = (field >> (kValBits * 0)) & kMaxVal; + mMaxPriority = (field >> (kValBits * 1)) & kMaxVal; + mMinCoreNumber = (field >> (kValBits * 2)) & kMaxVal; + mMaxCoreNumber = (field >> (kValBits * 3)) & kMaxVal; + } + }; +} diff --git a/lib/nx/nx.vcxproj b/lib/nx/nx.vcxproj index 704c06d..e54c4d9 100644 --- a/lib/nx/nx.vcxproj +++ b/lib/nx/nx.vcxproj @@ -22,21 +22,40 @@ + + + + + + + + + + + + + + + + + + + 15.0 diff --git a/lib/nx/nx.vcxproj.filters b/lib/nx/nx.vcxproj.filters index 9b39e72..146d82e 100644 --- a/lib/nx/nx.vcxproj.filters +++ b/lib/nx/nx.vcxproj.filters @@ -42,6 +42,36 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + @@ -65,5 +95,32 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + \ No newline at end of file