blob: c1d5e12228256b5d41a7d93067d779bf773d4f38 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#include "sw/device/silicon_creator/lib/epmp_state.h"
#include "sw/device/lib/base/csr.h"
#include "sw/device/lib/base/hardened.h"
// The context is declared as weak so that the ROM and ROM_EXT may
// override its location.
OT_WEAK epmp_state_t epmp_state;
/**
* Extern declarations of inline functions.
*/
extern void epmp_state_configure_tor(uint32_t entry, epmp_region_t region,
epmp_perm_t perm);
extern void epmp_state_configure_na4(uint32_t entry, epmp_region_t region,
epmp_perm_t perm);
extern void epmp_state_configure_napot(uint32_t entry, epmp_region_t region,
epmp_perm_t perm);
rom_error_t epmp_state_check(void) {
uint32_t checks = 0;
const epmp_state_t *s = &epmp_state;
#define CHECK_CSR(reg, value) \
do { \
uint32_t csr; \
CSR_READ(reg, &csr); \
checks += csr == (value); \
} while (false)
// Check address registers.
CHECK_CSR(CSR_REG_PMPADDR0, s->pmpaddr[0]);
CHECK_CSR(CSR_REG_PMPADDR1, s->pmpaddr[1]);
CHECK_CSR(CSR_REG_PMPADDR2, s->pmpaddr[2]);
CHECK_CSR(CSR_REG_PMPADDR3, s->pmpaddr[3]);
CHECK_CSR(CSR_REG_PMPADDR4, s->pmpaddr[4]);
CHECK_CSR(CSR_REG_PMPADDR5, s->pmpaddr[5]);
CHECK_CSR(CSR_REG_PMPADDR6, s->pmpaddr[6]);
CHECK_CSR(CSR_REG_PMPADDR7, s->pmpaddr[7]);
CHECK_CSR(CSR_REG_PMPADDR8, s->pmpaddr[8]);
CHECK_CSR(CSR_REG_PMPADDR9, s->pmpaddr[9]);
CHECK_CSR(CSR_REG_PMPADDR10, s->pmpaddr[10]);
CHECK_CSR(CSR_REG_PMPADDR11, s->pmpaddr[11]);
CHECK_CSR(CSR_REG_PMPADDR12, s->pmpaddr[12]);
CHECK_CSR(CSR_REG_PMPADDR13, s->pmpaddr[13]);
CHECK_CSR(CSR_REG_PMPADDR14, s->pmpaddr[14]);
CHECK_CSR(CSR_REG_PMPADDR15, s->pmpaddr[15]);
// Check configuration registers.
CHECK_CSR(CSR_REG_PMPCFG0, s->pmpcfg[0]);
CHECK_CSR(CSR_REG_PMPCFG1, s->pmpcfg[1]);
CHECK_CSR(CSR_REG_PMPCFG2, s->pmpcfg[2]);
CHECK_CSR(CSR_REG_PMPCFG3, s->pmpcfg[3]);
// Check Machine Security Configuration (MSECCFG) register.
// High bits are hardcoded to 0.
CHECK_CSR(CSR_REG_MSECCFG, s->mseccfg);
CHECK_CSR(CSR_REG_MSECCFGH, 0);
#undef CHECK_CSR
enum { kTotalChecks = 22 };
// Hamming distance of 3, error = 0x72f, kErrorOk = 0x739.
rom_error_t error = kErrorOk ^ kTotalChecks;
if (launder32(checks) == kTotalChecks) {
HARDENED_CHECK_EQ(checks, kTotalChecks);
error ^= checks;
HARDENED_CHECK_EQ(error, kErrorOk);
return error;
}
return kErrorEpmpBadCheck;
}