| // Copyright 2021 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include <utility> | |
| #include <vector> | |
| #include <base/files/file.h> | |
| #include <base/files/file_path.h> | |
| #include <base/files/file_util.h> | |
| #include <base/logging.h> | |
| #include <base/strings/stringprintf.h> | |
| #include <base/strings/string_number_conversions.h> | |
| #include <base/strings/string_util.h> | |
| #include <base/sys_byteorder.h> | |
| #include <hps/hps_reg.h> | |
| #include <hps/utils.h> | |
| namespace hps { | |
| #define ENUM_BIT(e) BIT(static_cast<int>(e)) | |
| bool ReadVersionFromFile(const base::FilePath& path, uint32_t* version) { | |
| std::string file_contents; | |
| if (!base::ReadFileToString(path, &file_contents)) { | |
| PLOG(ERROR) << "ReadVersionFromFile: \"" << path << "\""; | |
| return false; | |
| } | |
| base::TrimWhitespaceASCII(file_contents, base::TRIM_ALL, &file_contents); | |
| if (!base::StringToUint(file_contents, version)) { | |
| LOG(ERROR) << "ReadVersionFromFile: \"" << path | |
| << "\": file does not contain a valid integer version"; | |
| return false; | |
| } | |
| return true; | |
| } | |
| constexpr std::initializer_list<RegInfo> REGISTERS = { | |
| {.num = HpsReg::kMagic, | |
| .name = "kMagic", | |
| .readable = true, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kHwRev, | |
| .name = "kHwRev", | |
| .readable = true, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kSysStatus, | |
| .name = "kSysStatus", | |
| .readable = true, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kSysCmd, | |
| .name = "kSysCmd", | |
| .readable = false, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kBankReady, | |
| .name = "kBankReady", | |
| .readable = true, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kError, | |
| .name = "kError", | |
| .readable = true, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kFeatEn, | |
| .name = "kFeatEn", | |
| .readable = true, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kFeature0, | |
| .name = "kFeature0", | |
| .readable = true, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kFeature1, | |
| .name = "kFeature1", | |
| .readable = true, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kFirmwareVersionHigh, | |
| .name = "kFirmwareVersionHigh", | |
| .readable = true, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kFirmwareVersionLow, | |
| .name = "kFirmwareVersionLow", | |
| .readable = true, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kFpgaBootCount, | |
| .name = "kFpgaBootCount", | |
| .readable = true, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kFpgaLoopCount, | |
| .name = "kFpgaLoopCount", | |
| .readable = true, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kFpgaRomVersion, | |
| .name = "kFpgaRomVersion", | |
| .readable = true, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kSpiFlashStatus, | |
| .name = "kSpiFlashStatus", | |
| .readable = true, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kCameraConfig, | |
| .name = "kCameraConfig", | |
| .readable = true, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kStartCameraTest, | |
| .name = "kStartCameraTest", | |
| .readable = false, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kOptionBytesConfig, | |
| .name = "kOptionBytesConfig", | |
| .readable = true, | |
| .type = RegType::kUint16}, | |
| {.num = HpsReg::kPartIds, | |
| .name = "kPartIds", | |
| .readable = true, | |
| .type = RegType::kPartIdArray}, | |
| {.num = HpsReg::kPreviousCrashMessage, | |
| .name = "kPreviousCrashMessage", | |
| .readable = true, | |
| .type = RegType::kString}, | |
| {.num = HpsReg::kFpgaCrashMessage, | |
| .name = "kFpgaCrashMessage", | |
| .readable = true, | |
| .type = RegType::kString}, | |
| }; | |
| std::optional<RegInfo> HpsRegInfo(int reg) { | |
| auto ret = std::find_if( | |
| REGISTERS.begin(), REGISTERS.end(), | |
| [&](RegInfo info) { return static_cast<int>(info.num) == reg; }); | |
| if (ret != REGISTERS.end()) { | |
| return *ret; | |
| } | |
| return std::nullopt; | |
| } | |
| std::optional<RegInfo> HpsRegInfo(HpsReg reg) { | |
| return HpsRegInfo(static_cast<int>(reg)); | |
| } | |
| std::string HpsRegValToString(HpsReg reg, uint16_t val) { | |
| std::vector<std::string> ret; | |
| switch (reg) { | |
| case HpsReg::kSysStatus: | |
| if (val & kOK) { | |
| ret.push_back("kOK"); | |
| val ^= kOK; | |
| } | |
| if (val & kFault) { | |
| ret.push_back("kFault"); | |
| val ^= kFault; | |
| } | |
| if (val & kDeprecatedAVerify) { | |
| ret.push_back("kDeprecatedAVerify"); | |
| val ^= kDeprecatedAVerify; | |
| } | |
| if (val & kStage0) { | |
| ret.push_back("kStage0"); | |
| val ^= kStage0; | |
| } | |
| if (val & kWpOff) { | |
| ret.push_back("kWpOff"); | |
| val ^= kWpOff; | |
| } | |
| if (val & kWpOn) { | |
| ret.push_back("kWpOn"); | |
| val ^= kWpOn; | |
| } | |
| if (val & kStage1) { | |
| ret.push_back("kStage1"); | |
| val ^= kStage1; | |
| } | |
| if (val & kAppl) { | |
| ret.push_back("kAppl"); | |
| val ^= kAppl; | |
| } | |
| if (val & kCmdInProgress) { | |
| ret.push_back("kCmdInProgress"); | |
| val ^= kCmdInProgress; | |
| } | |
| if (val & kStage0Locked) { | |
| ret.push_back("kStage0Locked"); | |
| val ^= kStage0Locked; | |
| } | |
| if (val & kStage0PermLocked) { | |
| ret.push_back("kStage0PermLocked"); | |
| val ^= kStage0PermLocked; | |
| } | |
| if (val & kOneTimeInit) { | |
| ret.push_back("kOneTimeInit"); | |
| val ^= kOneTimeInit; | |
| } | |
| if (val) { | |
| ret.push_back(base::StringPrintf("0x%x", val)); | |
| } | |
| return base::JoinString(ret, "|"); | |
| case HpsReg::kBankReady: | |
| if (val & ENUM_BIT(HpsBank::kMcuFlash)) { | |
| ret.push_back("kMcuFlash"); | |
| val ^= ENUM_BIT(HpsBank::kMcuFlash); | |
| } | |
| if (val & ENUM_BIT(HpsBank::kSpiFlash)) { | |
| ret.push_back("kSpiFlash"); | |
| val ^= ENUM_BIT(HpsBank::kSpiFlash); | |
| } | |
| if (val & ENUM_BIT(HpsBank::kSocRom)) { | |
| ret.push_back("kSocRom"); | |
| val ^= ENUM_BIT(HpsBank::kSocRom); | |
| } | |
| if (val) { | |
| ret.push_back(base::StringPrintf("0x%x", val)); | |
| } | |
| return base::JoinString(ret, "|"); | |
| case HpsReg::kError: | |
| switch (val) { | |
| case RError::kNone: | |
| return "kNone"; | |
| case RError::kHostI2cUnderrun: | |
| return "kHostI2cUnderrun"; | |
| case RError::kMcuFlashWriteError: | |
| return "kMcuFlashWriteError"; | |
| case RError::kPanic: | |
| return "kPanic"; | |
| case RError::kFpgaPanic: | |
| return "kFpgaPanic"; | |
| case RError::kFpgaException: | |
| return "kFpgaException"; | |
| case RError::kHostI2cBusError: | |
| return "kHostI2cBusError"; | |
| case RError::kHostI2cOverrun: | |
| return "kHostI2cOverrun"; | |
| case RError::kCameraI2c: | |
| return "kCameraI2c"; | |
| case RError::kCameraImageTimeout: | |
| return "kCameraImageTimeout"; | |
| case RError::kCameraUnexpectedId: | |
| return "kCameraUnexpectedId"; | |
| case RError::kCameraUnexpectedReset: | |
| return "kCameraUnexpectedReset"; | |
| case RError::kSpiFlash: | |
| return "kSpiFlash"; | |
| case RError::kHostI2cBadRequest: | |
| return "kHostI2cBadRequest"; | |
| case RError::kBufferNotAvailable: | |
| return "kBufferNotAvailable"; | |
| case RError::kBufferOverrun: | |
| return "kBufferOverrun"; | |
| case RError::kSpiFlashNotVerified: | |
| return "kSpiFlashNotVerified"; | |
| case RError::kTfliteFailure: | |
| return "kTfliteFailure"; | |
| case RError::kSelfTestFailed: | |
| return "kSelfTestFailed"; | |
| case RError::kFpgaMcuCommError: | |
| return "kFpgaMcuCommError"; | |
| case RError::kFpgaTimeout: | |
| return "kFpgaTimeout"; | |
| case RError::kStage1NotFound: | |
| return "kStage1NotFound"; | |
| case RError::kStage1TooOld: | |
| return "kStage1TooOld"; | |
| case RError::kStage1InvalidSignature: | |
| return "kStage1InvalidSignature"; | |
| case RError::kInternal: | |
| return "kInternal"; | |
| case RError::kMcuFlashEcc: | |
| return "kMcuFlashEcc"; | |
| case RError::kMcuNmi: | |
| return "kMcuNmi"; | |
| default: | |
| return base::StringPrintf("0x%04x", val); | |
| } | |
| case HpsReg::kFeatEn: | |
| case HpsReg::kFeature0: | |
| case HpsReg::kFeature1: | |
| case HpsReg::kFirmwareVersionHigh: | |
| case HpsReg::kFirmwareVersionLow: | |
| case HpsReg::kHwRev: | |
| case HpsReg::kMagic: | |
| case HpsReg::kMax: | |
| case HpsReg::kSysCmd: | |
| case HpsReg::kFpgaBootCount: | |
| case HpsReg::kFpgaLoopCount: | |
| case HpsReg::kFpgaRomVersion: | |
| case HpsReg::kSpiFlashStatus: | |
| case HpsReg::kCameraConfig: | |
| case HpsReg::kStartCameraTest: | |
| case HpsReg::kOptionBytesConfig: | |
| case HpsReg::kPartIds: | |
| case HpsReg::kPreviousCrashMessage: | |
| case HpsReg::kFpgaCrashMessage: | |
| return ""; | |
| } | |
| } | |
| } // namespace hps |