blob: 0369d413530af496eae4fa33b6e0365c74a92c98 [file] [log] [blame] [edit]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "rmad/utils/ec_utils_impl.h"
#include <fcntl.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <libec/flash_protect_command.h>
#include <libec/reboot_command.h>
#include <optional>
namespace {
constexpr char kEcPath[] = "/dev/cros_ec";
} // namespace
namespace rmad {
bool EcUtilsImpl::Reboot() {
base::ScopedFD ec_fd = GetEcFd();
if (!ec_fd.is_valid()) {
return false;
}
ec::RebootCommand reboot_cmd;
return reboot_cmd.Run(ec_fd.get());
}
bool EcUtilsImpl::SetEcSoftwareWriteProtection(bool enable) {
base::ScopedFD ec_fd = GetEcFd();
if (!ec_fd.is_valid()) {
return false;
}
ec::flash_protect::Flags mask = ec::flash_protect::Flags::kRoNow |
ec::flash_protect::Flags::kRwNow |
ec::flash_protect::Flags::kRoAtBoot;
ec::flash_protect::Flags flags =
enable ? mask : ec::flash_protect::Flags::kNone;
auto flashprotect_cmd = ec::FlashProtectCommand_v1(flags, mask);
return flashprotect_cmd.Run(ec_fd.get());
}
bool EcUtilsImpl::EnableEcSoftwareWriteProtection() {
return EcUtilsImpl::SetEcSoftwareWriteProtection(true);
}
bool EcUtilsImpl::DisableEcSoftwareWriteProtection() {
return EcUtilsImpl::SetEcSoftwareWriteProtection(false);
}
std::optional<bool> EcUtilsImpl::GetEcWriteProtectionStatus() {
base::ScopedFD ec_fd = GetEcFd();
if (!ec_fd.is_valid()) {
return std::nullopt;
}
ec::flash_protect::Flags flags = ec::flash_protect::Flags::kNone;
auto flashprotect_cmd = ec::FlashProtectCommand_v1(flags, flags);
if (!flashprotect_cmd.Run(ec_fd.get())) {
LOG(ERROR) << "Failed to run EC WP status command";
return std::nullopt;
}
return (flashprotect_cmd.GetFlags() & ec::flash_protect::Flags::kRoAtBoot) !=
ec::flash_protect::Flags::kNone;
}
base::ScopedFD EcUtilsImpl::GetEcFd() const {
int ec_fd = open(kEcPath, O_RDWR | O_CLOEXEC);
if (ec_fd == -1) {
LOG(ERROR) << "Failed to get EC FD";
return base::ScopedFD();
}
return base::ScopedFD(ec_fd);
}
} // namespace rmad