summaryrefslogtreecommitdiff
path: root/board/cr50/board.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/cr50/board.c')
-rw-r--r--board/cr50/board.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c
index 0f801de447..c625be6090 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -12,6 +12,7 @@
#include "device_state.h"
#include "ec_version.h"
#include "extension.h"
+#include "flash.h"
#include "flash_config.h"
#include "gpio.h"
#include "hooks.h"
@@ -801,3 +802,55 @@ static enum vendor_cmd_rc vc_sysinfo(enum vendor_cmd_cc code,
return VENDOR_RC_SUCCESS;
}
DECLARE_VENDOR_COMMAND(VENDOR_CC_SYSINFO, vc_sysinfo);
+
+static enum vendor_cmd_rc vc_invalidate_inactive_rw(enum vendor_cmd_cc code,
+ void *buf,
+ size_t input_size,
+ size_t *response_size)
+{
+ struct SignedHeader *header;
+ uint32_t ctrl;
+ uint32_t base_addr;
+ uint32_t size;
+ const char zero[4] = {}; /* value to write to magic. */
+
+ if (system_get_image_copy() == SYSTEM_IMAGE_RW) {
+ header = (struct SignedHeader *)
+ get_program_memory_addr(SYSTEM_IMAGE_RW_B);
+ } else {
+ header = (struct SignedHeader *)
+ get_program_memory_addr(SYSTEM_IMAGE_RW);
+ }
+
+ /* save the original flash region6 register values */
+ ctrl = GREAD(GLOBALSEC, FLASH_REGION6_CTRL);
+ base_addr = GREG32(GLOBALSEC, FLASH_REGION6_BASE_ADDR);
+ size = GREG32(GLOBALSEC, FLASH_REGION6_SIZE);
+
+ /* Enable RW access to the other header. */
+ GREG32(GLOBALSEC, FLASH_REGION6_BASE_ADDR) = (uint32_t) header;
+ GREG32(GLOBALSEC, FLASH_REGION6_SIZE) = 1023;
+ GWRITE_FIELD(GLOBALSEC, FLASH_REGION6_CTRL, EN, 1);
+ GWRITE_FIELD(GLOBALSEC, FLASH_REGION6_CTRL, RD_EN, 1);
+ GWRITE_FIELD(GLOBALSEC, FLASH_REGION6_CTRL, WR_EN, 1);
+
+ CPRINTS("%s: TPM verified corrupting inactive image, magic before %x",
+ __func__, header->magic);
+
+ flash_physical_write((intptr_t)&header->magic -
+ CONFIG_PROGRAM_MEMORY_BASE,
+ sizeof(zero), zero);
+
+ CPRINTS("%s: magic after: %x", __func__, header->magic);
+
+ /* Restore original values */
+ GREG32(GLOBALSEC, FLASH_REGION6_BASE_ADDR) = base_addr;
+ GREG32(GLOBALSEC, FLASH_REGION6_SIZE) = size;
+ GREG32(GLOBALSEC, FLASH_REGION6_CTRL) = ctrl;
+
+ *response_size = 0;
+
+ return VENDOR_RC_SUCCESS;
+}
+DECLARE_VENDOR_COMMAND(VENDOR_CC_INVALIDATE_INACTIVE_RW,
+ vc_invalidate_inactive_rw);