blob: ed19e141988bbafd43a627f0da8053864ff28da1 [file] [log] [blame]
// 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_