blob: 3014f66be2b52b2c8f8c98cf3a513c2bacbc242d [file] [log] [blame]
/*
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _OTP_H
#define _OTP_H
#include <string>
#include <cassert>
#include <vector>
#include <cstdint>
#include "nlohmann/json.hpp"
using json = nlohmann::json;
template <typename T> std::basic_string<T> lowercase(const std::basic_string<T>& s);
template <typename T> std::basic_string<T> uppercase(const std::basic_string<T>& s);
struct otp_field {
otp_field() = default;
otp_field(std::string name, uint32_t mask) : name(std::move(name)), mask(mask) {
upper_name = uppercase(this->name);
}
otp_field(std::string name, uint32_t mask, std::string description) : otp_field(std::move(name), mask) {
this->description = std::move(description);
}
std::string name;
std::string upper_name;
uint32_t mask;
std::string description;
friend void to_json(json& nlohmann_json_j, const otp_field& nlohmann_json_t) {
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, name, mask, description))
}
friend void from_json(const json& nlohmann_json_j, otp_field& nlohmann_json_t) {
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, name, mask, description))
nlohmann_json_t.upper_name = uppercase(nlohmann_json_t.name);
}
};
struct otp_reg {
otp_reg() = default;
explicit otp_reg(std::string name, uint32_t row, uint32_t mask) : name(std::move(name)), row(row), mask(mask) {
upper_name = uppercase(this->name);
}
otp_reg& with_ecc() { assert(!redundancy); ecc = true; return *this; }
otp_reg& with_crit() { assert(!ecc); crit = true; return *this; }
otp_reg& with_redundancy(int r) { assert(!ecc); redundancy = r; return *this; }
otp_reg& with_description(std::string d) { description = std::move(d); return *this; }
otp_reg& with_field(const otp_field& field) { fields.push_back(field); return *this; }
otp_reg& with_sequence(std::string prefix, int index, int length) { seq_prefix = std::move(prefix); seq_index = index; seq_length = length; return *this; }
std::string name;
std::string upper_name;
std::string description;
uint32_t row = 0xffffffff;
uint32_t mask = 0;
bool ecc = false;
bool crit = false;
unsigned int redundancy = 0;
unsigned int seq_length = 0;
unsigned int seq_index = 0;
std::string seq_prefix;
std::vector<otp_field> fields;
friend void to_json(json& nlohmann_json_j, const otp_reg& nlohmann_json_t) {
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, name, description, ecc, crit, fields, mask, redundancy, row, seq_index, seq_length, seq_prefix))
}
friend void from_json(const json& nlohmann_json_j, otp_reg& nlohmann_json_t) {
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, name, description, row))
if (nlohmann_json_j.contains("ecc")) nlohmann_json_j.at("ecc").get_to(nlohmann_json_t.ecc);
if (nlohmann_json_j.contains("crit")) nlohmann_json_j.at("crit").get_to(nlohmann_json_t.crit);
if (nlohmann_json_j.contains("redundancy")) nlohmann_json_j.at("redundancy").get_to(nlohmann_json_t.redundancy);
if (nlohmann_json_j.contains("fields")) nlohmann_json_j.at("fields").get_to(nlohmann_json_t.fields);
if (nlohmann_json_j.contains("mask")){
nlohmann_json_j.at("mask").get_to(nlohmann_json_t.mask);
} else {
nlohmann_json_t.mask = nlohmann_json_t.ecc ? 0xffff : 0xffffff;
}
if (nlohmann_json_j.contains("seq_length") || nlohmann_json_j.contains("seq_index") || nlohmann_json_j.contains("seq_prefix")) {
nlohmann_json_j.at("seq_length").get_to(nlohmann_json_t.seq_length);
nlohmann_json_j.at("seq_index").get_to(nlohmann_json_t.seq_index);
nlohmann_json_j.at("seq_prefix").get_to(nlohmann_json_t.seq_prefix);
}
nlohmann_json_t.upper_name = uppercase(nlohmann_json_t.name);
}
};
void init_otp(std::map<uint32_t, otp_reg> &otp_regs, std::vector<std::string> extra_otp_files = {});
#endif