| // 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. |
| |
| #ifndef HPS_UTILS_H_ |
| #define HPS_UTILS_H_ |
| |
| #include <optional> |
| #include <string> |
| #include <utility> |
| |
| #include <base/files/file_path.h> |
| #include <base/strings/stringprintf.h> |
| |
| #include "hps/dev.h" |
| #include "hps/hps_reg.h" |
| |
| namespace hps { |
| |
| constexpr int kVersionOffset = 20; |
| |
| // Read the version number from the MCU firmware version file. |
| // Returns false on failure. |
| bool ReadVersionFromFile(const base::FilePath& path, uint32_t* version); |
| |
| enum class RegType { |
| kUint16, |
| kPartIdArray, // decoding this is not implemented |
| kString, |
| }; |
| |
| struct RegInfo { |
| HpsReg num; |
| const char* name; |
| bool readable; |
| RegType type; |
| }; |
| |
| // Look up info about the given register. |
| // Returns nullopt for unrecognized registers. |
| std::optional<RegInfo> HpsRegInfo(int reg); |
| std::optional<RegInfo> HpsRegInfo(HpsReg reg); |
| |
| // Return a pretty printed register value, |
| // or empty string if there is nothing pretty to print |
| std::string HpsRegValToString(HpsReg reg, uint16_t val); |
| |
| // Iterate through all HPS registers from `start` to `end` (inclusive), |
| // reading their values and writing their contents to `callback`. |
| // Only registers which are known to exist and be readable are included; |
| // others are silently skipped. |
| // `callback` should be a functor that accepts std::string. |
| template <typename Callback> |
| int DumpHpsRegisters(DevInterface& dev, |
| Callback callback, |
| int start = 0, |
| int end = static_cast<int>(HpsReg::kMax)) { |
| int failures = 0; |
| for (int i = start; i <= end; i++) { |
| auto reg = HpsRegInfo(i); |
| if (!reg.has_value()) { |
| // Not a real register, skip it. |
| continue; |
| } |
| if (!reg->readable) { |
| continue; |
| } |
| std::string dump_out; |
| switch (reg->type) { |
| // Part IDs are [u32; 5] but decoding it is not implemented yet. |
| case RegType::kPartIdArray: |
| case RegType::kUint16: { |
| std::optional<uint16_t> result = dev.ReadReg(reg->num); |
| if (!result) { |
| dump_out = |
| base::StringPrintf("Register %3d: error (%s)", i, reg->name); |
| failures++; |
| } else { |
| dump_out = base::StringPrintf( |
| "Register %3d: 0x%04x (%s) %s", i, result.value(), reg->name, |
| HpsRegValToString(reg->num, result.value()).c_str()); |
| } |
| break; |
| } |
| case RegType::kString: { |
| std::optional<std::string> result = dev.ReadStringReg(reg->num, 256); |
| if (!result) { |
| dump_out = |
| base::StringPrintf("Register %3d: error (%s)", i, reg->name); |
| failures++; |
| } else { |
| dump_out = base::StringPrintf("Register %3d: ...... (%s) %s", i, |
| reg->name, result.value().c_str()); |
| } |
| break; |
| } |
| } |
| callback(std::move(dump_out)); |
| } |
| return failures; |
| } |
| |
| } // namespace hps |
| |
| #endif // HPS_UTILS_H_ |