erpt: actually support non-sequential ids, nintendo why

This commit is contained in:
Michael Scire 2024-03-28 04:36:14 -07:00
parent b4d453882d
commit e6cf70a18a
7 changed files with 91 additions and 36 deletions

View file

@ -35,7 +35,7 @@
HANDLER(FieldType_NumericU8, 12) \
HANDLER(FieldType_NumericI16, 13) \
HANDLER(FieldType_NumericI8, 14) \
HANDLER(FieldType_I8Array, 15) \
HANDLER(FieldType_I8Array, 15)
#define AMS_ERPT_FOREACH_CATEGORY(HANDLER) \
HANDLER(Test, 0 ) \
@ -180,7 +180,7 @@
HANDLER(EthernetAdapterOUIInfo, 139 ) \
HANDLER(NANDTypeInfo, 140 ) \
HANDLER(MicroSDTypeInfo, 141 ) \
HANDLER(TestNx, 1000) \
HANDLER(TestNx, 1000)
#define AMS_ERPT_FOREACH_FIELD(HANDLER) \
HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \
@ -355,13 +355,13 @@
HANDLER(CompositorDisplayState, 169, CompositorDisplayInfo, FieldType_String, FieldFlag_None ) \
HANDLER(CompositorHWCState, 170, CompositorHWCInfo, FieldType_String, FieldFlag_None ) \
HANDLER(InputCurrentLimit, 171, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(BoostModeCurrentLimit, 172, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(BoostModeCurrentLimitDeprecated, 172, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(FastChargeCurrentLimit, 173, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(ChargeVoltageLimit, 174, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(ChargeConfiguration, 175, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(HizMode, 176, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \
HANDLER(ChargeConfigurationDeprecated, 175, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(HizModeDeprecated, 176, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \
HANDLER(ChargeEnabled, 177, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \
HANDLER(PowerSupplyPath, 178, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(PowerSupplyPathDeprecated, 178, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(BatteryTemperature, 179, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(BatteryChargePercent, 180, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(BatteryChargeVoltage, 181, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
@ -371,8 +371,8 @@
HANDLER(PowerSupplyVoltage, 185, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(PowerSupplyCurrent, 186, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \
HANDLER(FastBatteryChargingEnabled, 187, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \
HANDLER(ControllerPowerSupplyAcquired, 188, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \
HANDLER(OtgRequested, 189, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \
HANDLER(ControllerPowerSupplyAcquiredDeprecated, 188, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \
HANDLER(OtgRequestedDeprecated, 189, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \
HANDLER(NANDPreEolInfo, 190, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(NANDDeviceLifeTimeEstTypA, 191, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(NANDDeviceLifeTimeEstTypB, 192, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \
@ -436,15 +436,15 @@
HANDLER(GpuErrorPbdmaGpShadow1, 250, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(AccessPointChannel, 251, AccessPointInfo, FieldType_NumericU16, FieldFlag_None ) \
HANDLER(ThreadName, 252, ErrorInfo, FieldType_String, FieldFlag_None ) \
HANDLER(AdspExceptionRegisters, 253, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \
HANDLER(AdspExceptionSpsr, 254, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(AdspExceptionRegistersDeprecated, 253, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \
HANDLER(AdspExceptionSpsrDeprecated, 254, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(AdspExceptionProgramCounter, 255, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(AdspExceptionLinkRegister, 256, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(AdspExceptionStackPointer, 257, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(AdspExceptionArmModeRegisters, 258, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \
HANDLER(AdspExceptionStackAddress, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(AdspExceptionStackDump, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \
HANDLER(AdspExceptionReason, 261, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(AdspExceptionArmModeRegistersDeprecated, 258, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \
HANDLER(AdspExceptionStackAddressDeprecated, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(AdspExceptionStackDumpDeprecated, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \
HANDLER(AdspExceptionReasonDeprecated, 261, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(OscillatorClock, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(CpuDvfsTableClocks, 263, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \
HANDLER(CpuDvfsTableVoltages, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \
@ -877,5 +877,5 @@
HANDLER(AdspExceptionArmModeRegisters, 1009, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \
HANDLER(AdspExceptionStackAddress, 1010, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(AdspExceptionStackDump, 1011, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \
HANDLER(AdspExceptionReason, 1012, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \
HANDLER(AdspExceptionReason, 1012, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None )

View file

@ -34,7 +34,6 @@ namespace ams::erpt {
enum CategoryId {
AMS_ERPT_FOREACH_CATEGORY(GENERATE_ENUM)
CategoryId_Count,
};
#undef GENERATE_ENUM
@ -43,7 +42,6 @@ namespace ams::erpt {
enum FieldId {
AMS_ERPT_FOREACH_FIELD(GENERATE_ENUM)
FieldId_Count,
};
#undef GENERATE_ENUM

View file

@ -58,34 +58,88 @@ namespace ams::erpt::srv {
};
#undef STRINGIZE_HANDLER
#define GET_FIELD_CATEGORY(FIELD, ID, CATEGORY, TYPE, FLAG) [FieldId_##FIELD] = CategoryId_##CATEGORY,
constexpr inline const CategoryId FieldToCategoryMap[] = {
#define GET_FIELD_CATEGORY(FIELD, ID, CATEGORY, TYPE, FLAG) CategoryId_##CATEGORY,
constexpr inline const CategoryId FieldIndexToCategoryMap[] = {
AMS_ERPT_FOREACH_FIELD(GET_FIELD_CATEGORY)
};
#undef GET_FIELD_CATEGORY
#define GET_FIELD_TYPE(FIELD, ID, CATEGORY, TYPE, FLAG) [FieldId_##FIELD] = TYPE,
constexpr inline const FieldType FieldToTypeMap[] = {
#define GET_FIELD_TYPE(FIELD, ID, CATEGORY, TYPE, FLAG) TYPE,
constexpr inline const FieldType FieldIndexToTypeMap[] = {
AMS_ERPT_FOREACH_FIELD(GET_FIELD_TYPE)
};
#undef GET_FIELD_TYPE
#define GET_FIELD_FLAG(FIELD, ID, CATEGORY, TYPE, FLAG) [FieldId_##FIELD] = FLAG,
constexpr inline const FieldFlag FieldToFlagMap[] = {
#define GET_FIELD_FLAG(FIELD, ID, CATEGORY, TYPE, FLAG) FLAG,
constexpr inline const FieldFlag FieldIndexToFlagMap[] = {
AMS_ERPT_FOREACH_FIELD(GET_FIELD_FLAG)
};
#undef GET_FIELD_FLAG
inline CategoryId ConvertFieldToCategory(FieldId id) {
return FieldToCategoryMap[id];
#define GET_FIELD_ID(FIELD, ...) FieldId_##FIELD,
constexpr inline const FieldId FieldIndexToFieldIdMap[] = {
AMS_ERPT_FOREACH_FIELD(GET_FIELD_ID)
};
#undef GET_FIELD_ID
#define GET_CATEGORY_ID(CATEGORY, ...) CategoryId_##CATEGORY,
constexpr inline const CategoryId CategoryIndexToCategoryIdMap[] = {
AMS_ERPT_FOREACH_CATEGORY(GET_CATEGORY_ID)
};
#undef GET_CATEGORY_ID
constexpr util::optional<size_t> FindFieldIndex(FieldId id) {
if (std::is_constant_evaluated()) {
for (size_t i = 0; i < util::size(FieldIndexToFieldIdMap); ++i) {
if (FieldIndexToFieldIdMap[i] == id) {
return i;
}
}
return util::nullopt;
} else {
if (const auto it = std::lower_bound(std::begin(FieldIndexToFieldIdMap), std::end(FieldIndexToFieldIdMap), id); it != std::end(FieldIndexToFieldIdMap) && *it == id) {
return std::distance(FieldIndexToFieldIdMap, it);
} else {
return util::nullopt;
}
}
}
inline FieldType ConvertFieldToType(FieldId id) {
return FieldToTypeMap[id];
constexpr util::optional<size_t> FindCategoryIndex(CategoryId id) {
if (std::is_constant_evaluated()) {
for (size_t i = 0; i < util::size(CategoryIndexToCategoryIdMap); ++i) {
if (CategoryIndexToCategoryIdMap[i] == id) {
return i;
}
}
return util::nullopt;
} else {
if (const auto it = std::lower_bound(std::begin(CategoryIndexToCategoryIdMap), std::end(CategoryIndexToCategoryIdMap), id); it != std::end(CategoryIndexToCategoryIdMap) && *it == id) {
return std::distance(CategoryIndexToCategoryIdMap, it);
} else {
return util::nullopt;
}
}
}
inline FieldFlag ConvertFieldToFlag(FieldId id) {
return FieldToFlagMap[id];
constexpr inline CategoryId ConvertFieldToCategory(FieldId id) {
const auto index = FindFieldIndex(id);
AMS_ASSERT(index.has_value());
return FieldIndexToCategoryMap[index.value()];
}
constexpr inline FieldType ConvertFieldToType(FieldId id) {
const auto index = FindFieldIndex(id);
AMS_ASSERT(index.has_value());
return FieldIndexToTypeMap[index.value()];
}
constexpr inline FieldFlag ConvertFieldToFlag(FieldId id) {
const auto index = FindFieldIndex(id);
AMS_ASSERT(index.has_value());
return FieldIndexToFlagMap[index.value()];
}
constexpr inline ReportFlagSet MakeNoReportFlags() {

View file

@ -69,13 +69,13 @@ namespace ams::erpt::srv {
auto guard = SCOPE_GUARD { m_ctx.field_count = 0; };
R_UNLESS(m_ctx.field_count <= FieldsPerContext, erpt::ResultInvalidArgument());
R_UNLESS(0 <= m_ctx.category && m_ctx.category < CategoryId_Count, erpt::ResultInvalidArgument());
R_UNLESS(m_ctx.field_count <= FieldsPerContext, erpt::ResultInvalidArgument());
R_UNLESS(FindCategoryIndex(m_ctx.category).has_value(), erpt::ResultInvalidArgument());
for (u32 i = 0; i < m_ctx.field_count; i++) {
m_ctx.fields[i] = ctx_ptr->fields[i];
R_UNLESS(0 <= m_ctx.fields[i].id && m_ctx.fields[i].id < FieldId_Count, erpt::ResultInvalidArgument());
R_UNLESS(FindFieldIndex(m_ctx.fields[i].id).has_value(), erpt::ResultInvalidArgument());
R_UNLESS(0 <= m_ctx.fields[i].type && m_ctx.fields[i].type < FieldType_Count, erpt::ResultInvalidArgument());
R_UNLESS(m_ctx.fields[i].type == ConvertFieldToType(m_ctx.fields[i].id), erpt::ResultFieldTypeMismatch());

View file

@ -62,7 +62,10 @@ namespace ams::erpt::srv {
static Result AddId(Report *report, FieldId field_id) {
static_assert(MaxFieldStringSize < ElementSize_256);
R_TRY(AddStringValue(report, FieldString[field_id], strnlen(FieldString[field_id], MaxFieldStringSize)));
const auto index = FindFieldIndex(field_id);
AMS_ASSERT(index.has_value());
R_TRY(AddStringValue(report, FieldString[index.value()], strnlen(FieldString[index.value()], MaxFieldStringSize)));
R_SUCCEED();
}

View file

@ -105,8 +105,8 @@ namespace ams::erpt::srv {
g_sf_allocator.Attach(g_heap_handle);
for (auto i = 0; i < CategoryId_Count; i++) {
Context *ctx = new Context(static_cast<CategoryId>(i));
for (const auto category_id : CategoryIndexToCategoryIdMap) {
Context *ctx = new Context(category_id);
AMS_ABORT_UNLESS(ctx != nullptr);
}

View file

@ -277,7 +277,7 @@ namespace ams::erpt::srv {
void SaveSyslogReportIfRequired(const ContextEntry *ctx, const ReportId &report_id) {
bool needs_save_syslog = true;
for (u32 i = 0; i < ctx->field_count; i++) {
static_assert(FieldToTypeMap[FieldId_HasSyslogFlag] == FieldType_Bool);
static_assert(FieldIndexToTypeMap[*FindFieldIndex(FieldId_HasSyslogFlag)] == FieldType_Bool);
if (ctx->fields[i].id == FieldId_HasSyslogFlag && !ctx->fields[i].value_bool) {
needs_save_syslog = false;
break;