sdmmc: add most of SdHostStandardController
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <vapours/util.hpp>
|
||||
#include <vapours/results.hpp>
|
||||
#include <vapours/reg.hpp>
|
||||
#include <vapours/crypto.hpp>
|
||||
#include <vapours/svc.hpp>
|
||||
|
||||
|
||||
@@ -19,4 +19,6 @@
|
||||
#include <vapours/assert.hpp>
|
||||
#include <vapours/results.hpp>
|
||||
|
||||
#include <vapours/dd/dd_device_virtual_address.hpp>
|
||||
#include <vapours/dd/dd_common_types.hpp>
|
||||
#include <vapours/dd/dd_io_mapping.hpp>
|
||||
#include <vapours/dd/dd_cache.hpp>
|
||||
|
||||
25
libraries/libvapours/include/vapours/dd/dd_cache.hpp
Normal file
25
libraries/libvapours/include/vapours/dd/dd_cache.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <vapours/dd/dd_common_types.hpp>
|
||||
|
||||
namespace ams::dd {
|
||||
|
||||
void InvalidateDataCache(void *addr, size_t size);
|
||||
void StoreDataCache(void *addr, size_t size);
|
||||
void FlushDataCache(void *addr, size_t size);
|
||||
|
||||
}
|
||||
29
libraries/libvapours/include/vapours/dd/dd_common_types.hpp
Normal file
29
libraries/libvapours/include/vapours/dd/dd_common_types.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <vapours/common.hpp>
|
||||
#include <vapours/assert.hpp>
|
||||
#include <vapours/results.hpp>
|
||||
|
||||
namespace ams::dd {
|
||||
|
||||
using PhysicalAddress = u64;
|
||||
using DeviceVirtualAddress = u64;
|
||||
|
||||
static_assert(std::same_as<PhysicalAddress, ams::svc::PhysicalAddress>);
|
||||
|
||||
}
|
||||
23
libraries/libvapours/include/vapours/dd/dd_io_mapping.hpp
Normal file
23
libraries/libvapours/include/vapours/dd/dd_io_mapping.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <vapours/dd/dd_common_types.hpp>
|
||||
|
||||
namespace ams::dd {
|
||||
|
||||
uintptr_t QueryIoMapping(dd::PhysicalAddress phys_addr, size_t size);
|
||||
|
||||
}
|
||||
247
libraries/libvapours/include/vapours/reg.hpp
Normal file
247
libraries/libvapours/include/vapours/reg.hpp
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
|
||||
namespace ams::reg {
|
||||
|
||||
using BitsValue = std::tuple<u16, u16, u32>;
|
||||
using BitsMask = std::tuple<u16, u16>;
|
||||
|
||||
constexpr ALWAYS_INLINE u32 GetOffset(const BitsMask v) { return static_cast<u32>(std::get<0>(v)); }
|
||||
constexpr ALWAYS_INLINE u32 GetOffset(const BitsValue v) { return static_cast<u32>(std::get<0>(v)); }
|
||||
constexpr ALWAYS_INLINE u32 GetWidth(const BitsMask v) { return static_cast<u32>(std::get<1>(v)); }
|
||||
constexpr ALWAYS_INLINE u32 GetWidth(const BitsValue v) { return static_cast<u32>(std::get<1>(v)); }
|
||||
constexpr ALWAYS_INLINE u32 GetValue(const BitsValue v) { return static_cast<u32>(std::get<2>(v)); }
|
||||
|
||||
constexpr ALWAYS_INLINE ::ams::reg::BitsValue GetValue(const BitsMask m, const u32 v) {
|
||||
return ::ams::reg::BitsValue{GetOffset(m), GetWidth(m), v};
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE u32 EncodeMask(const BitsMask v) {
|
||||
return (~0u >> (BITSIZEOF(u32) - GetWidth(v))) << GetOffset(v);
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE u32 EncodeMask(const BitsValue v) {
|
||||
return (~0u >> (BITSIZEOF(u32) - GetWidth(v))) << GetOffset(v);
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE u32 EncodeValue(const BitsValue v) {
|
||||
return ((GetValue(v) << GetOffset(v)) & EncodeMask(v));
|
||||
}
|
||||
|
||||
template<typename... Values> requires ((sizeof...(Values) > 0) && (std::is_same<Values, BitsValue>::value && ...))
|
||||
constexpr ALWAYS_INLINE u32 Encode(const Values... values) {
|
||||
return (EncodeValue(values) | ...);
|
||||
}
|
||||
|
||||
template<typename IntType> requires std::unsigned_integral<IntType>
|
||||
ALWAYS_INLINE void Write(volatile IntType *reg, std::type_identity_t<IntType> val) { *reg = val; }
|
||||
|
||||
template<typename IntType> requires std::unsigned_integral<IntType>
|
||||
ALWAYS_INLINE void Write(volatile IntType ®, std::type_identity_t<IntType> val) { reg = val; }
|
||||
|
||||
ALWAYS_INLINE void Write(uintptr_t reg, u32 val) { Write(reinterpret_cast<volatile u32 *>(reg), val); }
|
||||
|
||||
template<typename IntType, typename... Values> requires std::unsigned_integral<IntType> && ((sizeof...(Values) > 0) && (std::is_same<Values, BitsValue>::value && ...))
|
||||
ALWAYS_INLINE void Write(volatile IntType *reg, const Values... values) { return Write(reg, static_cast<IntType>((EncodeValue(values) | ...))); }
|
||||
|
||||
template<typename IntType, typename... Values> requires std::unsigned_integral<IntType> && ((sizeof...(Values) > 0) && (std::is_same<Values, BitsValue>::value && ...))
|
||||
ALWAYS_INLINE void Write(volatile IntType ®, const Values... values) { return Write(reg, static_cast<IntType>((EncodeValue(values) | ...))); }
|
||||
|
||||
template<typename... Values> requires ((sizeof...(Values) > 0) && (std::is_same<Values, BitsValue>::value && ...))
|
||||
ALWAYS_INLINE void Write(uintptr_t reg, const Values... values) { return Write(reg, (EncodeValue(values) | ...)); }
|
||||
|
||||
template<typename IntType> requires std::unsigned_integral<IntType>
|
||||
ALWAYS_INLINE IntType Read(volatile IntType *reg) { return *reg; }
|
||||
|
||||
template<typename IntType> requires std::unsigned_integral<IntType>
|
||||
ALWAYS_INLINE IntType Read(volatile IntType ®) { return reg; }
|
||||
|
||||
ALWAYS_INLINE u32 Read(uintptr_t reg) { return Read(reinterpret_cast<volatile u32 *>(reg)); }
|
||||
|
||||
template<typename IntType> requires std::unsigned_integral<IntType>
|
||||
ALWAYS_INLINE IntType Read(volatile IntType *reg, std::type_identity_t<IntType> mask) { return *reg & mask; }
|
||||
|
||||
template<typename IntType> requires std::unsigned_integral<IntType>
|
||||
ALWAYS_INLINE IntType Read(volatile IntType ®, std::type_identity_t<IntType> mask) { return reg & mask; }
|
||||
|
||||
ALWAYS_INLINE u32 Read(uintptr_t reg, u32 mask) { return Read(reinterpret_cast<volatile u32 *>(reg), mask); }
|
||||
|
||||
template<typename IntType, typename... Masks> requires std::unsigned_integral<IntType> && ((sizeof...(Masks) > 0) && (std::is_same<Masks, BitsMask>::value && ...))
|
||||
ALWAYS_INLINE IntType Read(volatile IntType *reg, const Masks... masks) { return Read(reg, static_cast<IntType>((EncodeMask(masks) | ...))); }
|
||||
|
||||
template<typename IntType, typename... Masks> requires std::unsigned_integral<IntType> && ((sizeof...(Masks) > 0) && (std::is_same<Masks, BitsMask>::value && ...))
|
||||
ALWAYS_INLINE IntType Read(volatile IntType ®, const Masks... masks) { return Read(reg, static_cast<IntType>((EncodeMask(masks) | ...))); }
|
||||
|
||||
template<typename... Masks> requires ((sizeof...(Masks) > 0) && (std::is_same<Masks, BitsMask>::value && ...))
|
||||
ALWAYS_INLINE u32 Read(uintptr_t reg, const Masks... masks) { return Read(reg, (EncodeMask(masks) | ...)); }
|
||||
|
||||
template<typename IntType, typename... Values> requires std::unsigned_integral<IntType> && ((sizeof...(Values) > 0) && (std::is_same<Values, BitsValue>::value && ...))
|
||||
ALWAYS_INLINE bool HasValue(volatile IntType *reg, const Values... values) { return Read(reg, static_cast<IntType>((EncodeMask(values) | ...))) == static_cast<IntType>(Encode(values...)); }
|
||||
|
||||
template<typename IntType, typename... Values> requires std::unsigned_integral<IntType> && ((sizeof...(Values) > 0) && (std::is_same<Values, BitsValue>::value && ...))
|
||||
ALWAYS_INLINE bool HasValue(volatile IntType ®, const Values... values) { return Read(reg, static_cast<IntType>((EncodeMask(values) | ...))) == static_cast<IntType>(Encode(values...)); }
|
||||
|
||||
template<typename... Values> requires ((sizeof...(Values) > 0) && (std::is_same<Values, BitsValue>::value && ...))
|
||||
ALWAYS_INLINE bool HasValue(uintptr_t reg, const Values... values) { return Read(reg, (EncodeMask(values) | ...)) == Encode(values...); }
|
||||
|
||||
template<typename IntType> requires std::unsigned_integral<IntType>
|
||||
ALWAYS_INLINE IntType GetValue(volatile IntType *reg, const BitsMask mask) { return Read(reg, mask) >> GetOffset(mask); }
|
||||
|
||||
template<typename IntType> requires std::unsigned_integral<IntType>
|
||||
ALWAYS_INLINE IntType GetValue(volatile IntType ®, const BitsMask mask) { return Read(reg, mask) >> GetOffset(mask); }
|
||||
|
||||
ALWAYS_INLINE u32 GetValue(uintptr_t reg, const BitsMask mask) { return Read(reg, mask) >> GetOffset(mask); }
|
||||
|
||||
template<typename IntType> requires std::unsigned_integral<IntType>
|
||||
ALWAYS_INLINE void ReadWrite(volatile IntType *reg, std::type_identity_t<IntType> val, std::type_identity_t<IntType> mask) { *reg = (*reg & (~mask)) | (val & mask); }
|
||||
|
||||
template<typename IntType> requires std::unsigned_integral<IntType>
|
||||
ALWAYS_INLINE void ReadWrite(volatile IntType ®, std::type_identity_t<IntType> val, std::type_identity_t<IntType> mask) { reg = ( reg & (~mask)) | (val & mask); }
|
||||
|
||||
ALWAYS_INLINE void ReadWrite(uintptr_t reg, u32 val, u32 mask) { ReadWrite(reinterpret_cast<volatile u32 *>(reg), val, mask); }
|
||||
|
||||
template<typename IntType, typename... Values> requires std::unsigned_integral<IntType> && ((sizeof...(Values) > 0) && (std::is_same<Values, BitsValue>::value && ...))
|
||||
ALWAYS_INLINE void ReadWrite(volatile IntType *reg, const Values... values) { return ReadWrite(reg, static_cast<IntType>((EncodeValue(values) | ...)), static_cast<IntType>((EncodeMask(values) | ...))); }
|
||||
|
||||
template<typename IntType, typename... Values> requires std::unsigned_integral<IntType> && ((sizeof...(Values) > 0) && (std::is_same<Values, BitsValue>::value && ...))
|
||||
ALWAYS_INLINE void ReadWrite(volatile IntType ®, const Values... values) { return ReadWrite(reg, static_cast<IntType>((EncodeValue(values) | ...)), static_cast<IntType>((EncodeMask(values) | ...))); }
|
||||
|
||||
template<typename... Values> requires ((sizeof...(Values) > 0) && (std::is_same<Values, BitsValue>::value && ...))
|
||||
ALWAYS_INLINE void ReadWrite(uintptr_t reg, const Values... values) { return ReadWrite(reg, (EncodeValue(values) | ...), (EncodeMask(values) | ...)); }
|
||||
|
||||
template<typename IntType> requires std::unsigned_integral<IntType>
|
||||
ALWAYS_INLINE void SetBits(volatile IntType *reg, std::type_identity_t<IntType> mask) { *reg = *reg | mask; }
|
||||
|
||||
template<typename IntType> requires std::unsigned_integral<IntType>
|
||||
ALWAYS_INLINE void SetBits(volatile IntType ®, std::type_identity_t<IntType> mask) { reg = reg | mask; }
|
||||
|
||||
ALWAYS_INLINE void SetBits(uintptr_t reg, u32 mask) { SetBits(reinterpret_cast<volatile u32 *>(reg), mask); }
|
||||
|
||||
template<typename IntType, typename... Masks> requires std::unsigned_integral<IntType> && ((sizeof...(Masks) > 0) && (std::is_same<Masks, BitsMask>::value && ...))
|
||||
ALWAYS_INLINE void SetBits(volatile IntType *reg, const Masks... masks) { return SetBits(reg, static_cast<IntType>((EncodeMask(masks) | ...))); }
|
||||
|
||||
template<typename IntType, typename... Masks> requires std::unsigned_integral<IntType> && ((sizeof...(Masks) > 0) && (std::is_same<Masks, BitsMask>::value && ...))
|
||||
ALWAYS_INLINE void SetBits(volatile IntType ®, const Masks... masks) { return SetBits(reg, static_cast<IntType>((EncodeMask(masks) | ...))); }
|
||||
|
||||
template<typename... Masks> requires ((sizeof...(Masks) > 0) && (std::is_same<Masks, BitsMask>::value && ...))
|
||||
ALWAYS_INLINE void SetBits(uintptr_t reg, const Masks... masks) { return SetBits(reg, (EncodeMask(masks) | ...)); }
|
||||
|
||||
template<typename IntType> requires std::unsigned_integral<IntType>
|
||||
ALWAYS_INLINE void ClearBits(volatile IntType *reg, std::type_identity_t<IntType> mask) { *reg = *reg & ~mask; }
|
||||
|
||||
template<typename IntType> requires std::unsigned_integral<IntType>
|
||||
ALWAYS_INLINE void ClearBits(volatile IntType ®, std::type_identity_t<IntType> mask) { reg = reg & ~mask; }
|
||||
|
||||
ALWAYS_INLINE void ClearBits(uintptr_t reg, u32 mask) { ClearBits(reinterpret_cast<volatile u32 *>(reg), mask); }
|
||||
|
||||
template<typename IntType, typename... Masks> requires std::unsigned_integral<IntType> && ((sizeof...(Masks) > 0) && (std::is_same<Masks, BitsMask>::value && ...))
|
||||
ALWAYS_INLINE void ClearBits(volatile IntType *reg, const Masks... masks) { return ClearBits(reg, static_cast<IntType>((EncodeMask(masks) | ...))); }
|
||||
|
||||
template<typename IntType, typename... Masks> requires std::unsigned_integral<IntType> && ((sizeof...(Masks) > 0) && (std::is_same<Masks, BitsMask>::value && ...))
|
||||
ALWAYS_INLINE void ClearBits(volatile IntType ®, const Masks... masks) { return ClearBits(reg, static_cast<IntType>((EncodeMask(masks) | ...))); }
|
||||
|
||||
template<typename... Masks> requires ((sizeof...(Masks) > 0) && (std::is_same<Masks, BitsMask>::value && ...))
|
||||
ALWAYS_INLINE void ClearBits(uintptr_t reg, const Masks... masks) { return ClearBits(reg, (EncodeMask(masks) | ...)); }
|
||||
|
||||
template<typename IntType> requires std::unsigned_integral<IntType>
|
||||
ALWAYS_INLINE void MaskBits(volatile IntType *reg, std::type_identity_t<IntType> mask) { *reg = *reg & mask; }
|
||||
|
||||
template<typename IntType> requires std::unsigned_integral<IntType>
|
||||
ALWAYS_INLINE void MaskBits(volatile IntType ®, std::type_identity_t<IntType> mask) { reg = reg & mask; }
|
||||
|
||||
ALWAYS_INLINE void MaskBits(uintptr_t reg, u32 mask) { MaskBits(reinterpret_cast<volatile u32 *>(reg), mask); }
|
||||
|
||||
template<typename IntType, typename... Masks> requires std::unsigned_integral<IntType> && ((sizeof...(Masks) > 0) && (std::is_same<Masks, BitsMask>::value && ...))
|
||||
ALWAYS_INLINE void MaskBits(volatile IntType *reg, const Masks... masks) { return MaskBits(reg, static_cast<IntType>((EncodeMask(masks) | ...))); }
|
||||
|
||||
template<typename IntType, typename... Masks> requires std::unsigned_integral<IntType> && ((sizeof...(Masks) > 0) && (std::is_same<Masks, BitsMask>::value && ...))
|
||||
ALWAYS_INLINE void MaskBits(volatile IntType ®, const Masks... masks) { return MaskBits(reg, static_cast<IntType>((EncodeMask(masks) | ...))); }
|
||||
|
||||
template<typename... Masks> requires ((sizeof...(Masks) > 0) && (std::is_same<Masks, BitsMask>::value && ...))
|
||||
ALWAYS_INLINE void MaskBits(uintptr_t reg, const Masks... masks) { return MaskBits(reg, (EncodeMask(masks) | ...)); }
|
||||
|
||||
#define REG_BITS_MASK(OFFSET, WIDTH) ::ams::reg::BitsMask{OFFSET, WIDTH}
|
||||
#define REG_BITS_VALUE(OFFSET, WIDTH, VALUE) ::ams::reg::BitsValue{OFFSET, WIDTH, VALUE}
|
||||
|
||||
#define REG_BITS_VALUE_FROM_MASK(MASK, VALUE) ::ams::reg::GetValue(MASK, VALUE)
|
||||
|
||||
#define REG_NAMED_BITS_MASK(PREFIX, NAME) REG_BITS_MASK(PREFIX##_##NAME##_OFFSET, PREFIX##_##NAME##_WIDTH)
|
||||
#define REG_NAMED_BITS_VALUE(PREFIX, NAME, VALUE) REG_BITS_VALUE(PREFIX##_##NAME##_OFFSET, PREFIX##_##NAME##_WIDTH, VALUE)
|
||||
#define REG_NAMED_BITS_ENUM(PREFIX, NAME, ENUM) REG_BITS_VALUE(PREFIX##_##NAME##_OFFSET, PREFIX##_##NAME##_WIDTH, PREFIX##_##NAME##_##ENUM)
|
||||
|
||||
#define REG_NAMED_BITS_ENUM_SEL(PREFIX, NAME, __COND__, TRUE_ENUM, FALSE_ENUM) REG_BITS_VALUE(PREFIX##_##NAME##_OFFSET, PREFIX##_##NAME##_WIDTH, (__COND__) ? PREFIX##_##NAME##_##TRUE_ENUM : PREFIX##_##NAME##_##FALSE_ENUM)
|
||||
|
||||
#define REG_DEFINE_NAMED_REG(PREFIX, NAME, __OFFSET__, __WIDTH__) \
|
||||
constexpr inline u32 PREFIX##_##NAME##_OFFSET = __OFFSET__; \
|
||||
constexpr inline u32 PREFIX##_##NAME##_WIDTH = __WIDTH__
|
||||
|
||||
#define REG_DEFINE_NAMED_BIT_ENUM(PREFIX, NAME, __OFFSET__, ZERO, ONE) \
|
||||
REG_DEFINE_NAMED_REG(PREFIX, NAME, __OFFSET__, 1); \
|
||||
\
|
||||
enum PREFIX##_##NAME { \
|
||||
PREFIX##_##NAME##_##ZERO = 0, \
|
||||
PREFIX##_##NAME##_##ONE = 1, \
|
||||
};
|
||||
|
||||
#define REG_DEFINE_NAMED_TWO_BIT_ENUM(PREFIX, NAME, __OFFSET__, ZERO, ONE, TWO, THREE) \
|
||||
REG_DEFINE_NAMED_REG(PREFIX, NAME, __OFFSET__, 2); \
|
||||
\
|
||||
enum PREFIX##_##NAME { \
|
||||
PREFIX##_##NAME##_##ZERO = 0, \
|
||||
PREFIX##_##NAME##_##ONE = 1, \
|
||||
PREFIX##_##NAME##_##TWO = 2, \
|
||||
PREFIX##_##NAME##_##THREE = 3, \
|
||||
};
|
||||
|
||||
#define REG_DEFINE_NAMED_THREE_BIT_ENUM(PREFIX, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN) \
|
||||
REG_DEFINE_NAMED_REG(PREFIX, NAME, __OFFSET__, 3); \
|
||||
\
|
||||
enum PREFIX##_##NAME { \
|
||||
PREFIX##_##NAME##_##ZERO = 0, \
|
||||
PREFIX##_##NAME##_##ONE = 1, \
|
||||
PREFIX##_##NAME##_##TWO = 2, \
|
||||
PREFIX##_##NAME##_##THREE = 3, \
|
||||
PREFIX##_##NAME##_##FOUR = 4, \
|
||||
PREFIX##_##NAME##_##FIVE = 5, \
|
||||
PREFIX##_##NAME##_##SIX = 6, \
|
||||
PREFIX##_##NAME##_##SEVEN = 7, \
|
||||
};
|
||||
|
||||
#define REG_DEFINE_NAMED_FOUR_BIT_ENUM(PREFIX, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN) \
|
||||
REG_DEFINE_NAMED_REG(PREFIX, NAME, __OFFSET__, 4); \
|
||||
\
|
||||
enum PREFIX##_##NAME { \
|
||||
PREFIX##_##NAME##_##ZERO = 0, \
|
||||
PREFIX##_##NAME##_##ONE = 1, \
|
||||
PREFIX##_##NAME##_##TWO = 2, \
|
||||
PREFIX##_##NAME##_##THREE = 3, \
|
||||
PREFIX##_##NAME##_##FOUR = 4, \
|
||||
PREFIX##_##NAME##_##FIVE = 5, \
|
||||
PREFIX##_##NAME##_##SIX = 6, \
|
||||
PREFIX##_##NAME##_##SEVEN = 7, \
|
||||
PREFIX##_##NAME##_##EIGHT = 8, \
|
||||
PREFIX##_##NAME##_##NINE = 9, \
|
||||
PREFIX##_##NAME##_##TEN = 10, \
|
||||
PREFIX##_##NAME##_##ELEVEN = 11, \
|
||||
PREFIX##_##NAME##_##TWELVE = 12, \
|
||||
PREFIX##_##NAME##_##THIRTEEN = 13, \
|
||||
PREFIX##_##NAME##_##FOURTEEN = 14, \
|
||||
PREFIX##_##NAME##_##FIFTEEN = 15, \
|
||||
};
|
||||
|
||||
}
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <vapours/results/pm_results.hpp>
|
||||
#include <vapours/results/psc_results.hpp>
|
||||
#include <vapours/results/ro_results.hpp>
|
||||
#include <vapours/results/sdmmc_results.hpp>
|
||||
#include <vapours/results/settings_results.hpp>
|
||||
#include <vapours/results/sf_results.hpp>
|
||||
#include <vapours/results/sm_results.hpp>
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <vapours/results/results_common.hpp>
|
||||
|
||||
namespace ams::sdmmc {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(24);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NotActivated, 2);
|
||||
R_DEFINE_ERROR_RESULT(DeviceRemoved, 3);
|
||||
R_DEFINE_ERROR_RESULT(NotAwakened, 4);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(CommunicationError, 32, 126);
|
||||
R_DEFINE_ERROR_RANGE(CommunicationNotAttained, 33, 46);
|
||||
R_DEFINE_ERROR_RESULT(ResponseIndexError, 34);
|
||||
R_DEFINE_ERROR_RESULT(ResponseEndBitError, 35);
|
||||
R_DEFINE_ERROR_RESULT(ResponseCrcError, 36);
|
||||
R_DEFINE_ERROR_RESULT(ResponseTimeoutError, 37);
|
||||
R_DEFINE_ERROR_RESULT(DataEndBitError, 38);
|
||||
R_DEFINE_ERROR_RESULT(DataCrcError, 39);
|
||||
R_DEFINE_ERROR_RESULT(DataTimeoutError, 40);
|
||||
R_DEFINE_ERROR_RESULT(AutoCommandResponseIndexError, 41);
|
||||
R_DEFINE_ERROR_RESULT(AutoCommandResponseEndBitError, 42);
|
||||
R_DEFINE_ERROR_RESULT(AutoCommandResponseCrcError, 43);
|
||||
R_DEFINE_ERROR_RESULT(AutoCommandResponseTimeoutError, 44);
|
||||
R_DEFINE_ERROR_RESULT(CommandCompleteSoftwareTimeout, 45);
|
||||
R_DEFINE_ERROR_RESULT(TransferCompleteSoftwareTimeout, 46);
|
||||
R_DEFINE_ERROR_RESULT(AbortTransactionSoftwareTimeout, 74);
|
||||
R_DEFINE_ERROR_RESULT(CommandInhibitCmdSoftwareTimeout, 75);
|
||||
R_DEFINE_ERROR_RESULT(CommandInhibitDatSoftwareTimeout, 76);
|
||||
R_DEFINE_ERROR_RESULT(BusySoftwareTimeout, 77);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(HostControllerUnexpected, 128, 158);
|
||||
R_DEFINE_ERROR_RESULT(SdHostStandardUnknownAutoCmdError, 130);
|
||||
R_DEFINE_ERROR_RESULT(SdHostStandardUnknownError, 131);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(InternalError, 160, 190);
|
||||
R_DEFINE_ERROR_RESULT(NoWaitedInterrupt, 161);
|
||||
R_DEFINE_ERROR_RESULT(WaitInterruptSoftwareTimeout, 162);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NotImplemented, 201);
|
||||
}
|
||||
@@ -27,19 +27,25 @@
|
||||
//#define AMS_SDMMC_USE_DEVICE_VIRTUAL_ADDRESS
|
||||
//#define AMS_SDMMC_USE_PCV_CLOCK_RESET_CONTROL
|
||||
//#define AMS_SDMMC_USE_OS_EVENTS
|
||||
//#define AMS_SDMMC_USE_OS_TIMER
|
||||
#define AMS_SDMMC_USE_UTIL_TIMER
|
||||
|
||||
#elif defined(ATMOSPHERE_IS_MESOSPHERE)
|
||||
|
||||
//#define AMS_SDMMC_USE_DEVICE_VIRTUAL_ADDRESS
|
||||
//#define AMS_SDMMC_USE_PCV_CLOCK_RESET_CONTROL
|
||||
//#define AMS_SDMMC_USE_OS_EVENTS
|
||||
//#define AMS_SDMMC_USE_OS_TIMER
|
||||
#define AMS_SDMMC_USE_UTIL_TIMER
|
||||
|
||||
#elif defined(ATMOSPHERE_IS_STRATOSPHERE)
|
||||
|
||||
#define AMS_SDMMC_USE_DEVICE_VIRTUAL_ADDRESS
|
||||
#define AMS_SDMMC_USE_PCV_CLOCK_RESET_CONTROL
|
||||
#define AMS_SDMMC_USE_OS_EVENTS
|
||||
#define AMS_SDMMC_USE_OS_TIMER
|
||||
//#define AMS_SDMMC_USE_UTIL_TIMER
|
||||
|
||||
#else
|
||||
#error "Unknown execution context for ams::sdmmc!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#pragma once
|
||||
#include <vapours/sdmmc/sdmmc_build_config.hpp>
|
||||
|
||||
|
||||
namespace ams::sdmmc {
|
||||
|
||||
enum BusPower {
|
||||
@@ -110,6 +109,4 @@ namespace ams::sdmmc {
|
||||
|
||||
void GetAndClearErrorInfo(ErrorInfo *out_error_info, size_t *out_log_size, char *out_log_buffer, size_t log_buffer_size, Port port);
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <vapours/util/util_intrusive_list.hpp>
|
||||
#include <vapours/util/util_intrusive_red_black_tree.hpp>
|
||||
#include <vapours/util/util_tinymt.hpp>
|
||||
#include <vapours/util/util_timer.hpp>
|
||||
#include <vapours/util/util_uuid.hpp>
|
||||
#include <vapours/util/util_bounded_map.hpp>
|
||||
#include <vapours/util/util_overlap.hpp>
|
||||
|
||||
@@ -73,4 +73,9 @@ namespace ams::util {
|
||||
return IsAligned(reinterpret_cast<uintptr_t>(value), alignment);
|
||||
}
|
||||
|
||||
}
|
||||
template<typename T, typename U> requires std::integral<T> && std::integral<U>
|
||||
constexpr ALWAYS_INLINE T DivideUp(T x, U y) {
|
||||
return (x + (y - 1)) / y;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
#pragma once
|
||||
#include <vapours/common.hpp>
|
||||
#include <vapours/assert.hpp>
|
||||
#include <vapours/results.hpp>
|
||||
|
||||
namespace ams::dd {
|
||||
namespace ams::util {
|
||||
|
||||
using DeviceVirtualAddress = u64;
|
||||
u32 GetMicroSeconds();
|
||||
void WaitMicroSeconds(int us);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user