diff options
Diffstat (limited to 'chip/g/board_id.c')
-rw-r--r-- | chip/g/board_id.c | 280 |
1 files changed, 0 insertions, 280 deletions
diff --git a/chip/g/board_id.c b/chip/g/board_id.c deleted file mode 100644 index 6a7309e739..0000000000 --- a/chip/g/board_id.c +++ /dev/null @@ -1,280 +0,0 @@ -/* Copyright 2017 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "common.h" -#include "board_id.h" -#include "endian.h" -#include "extension.h" -#include "flash_info.h" -#include "system.h" -#include "util.h" - -#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) - -#define BLANK_FIELD 0xffffffff - -/** - * Return the image header for the current image copy - */ -const struct SignedHeader *get_current_image_header(void) -{ - return (const struct SignedHeader *) - get_program_memory_addr(system_get_image_copy()); -} - -int board_id_type_is_blank(const struct board_id *id) -{ - return (id->type & id->type_inv) == BLANK_FIELD; -} - -static int board_id_flags_are_blank(const struct board_id *id) -{ - return id->flags == BLANK_FIELD; -} - -int board_id_is_blank(const struct board_id *id) -{ - return board_id_type_is_blank(id) && board_id_flags_are_blank(id); -} - -uint32_t check_board_id_vs_header(const struct board_id *id, - const struct SignedHeader *h) -{ - uint32_t mismatch; - uint32_t header_board_id_type; - uint32_t header_board_id_mask; - uint32_t header_board_id_flags; - - /* Blank Board ID matches all headers */ - if (board_id_is_blank(id)) - return 0; - - header_board_id_type = SIGNED_HEADER_PADDING ^ h->board_id_type; - header_board_id_mask = SIGNED_HEADER_PADDING ^ h->board_id_type_mask; - header_board_id_flags = SIGNED_HEADER_PADDING ^ h->board_id_flags; - - /* - * All 1-bits in header Board ID flags must be present in flags from - * flash - */ - mismatch = - ((header_board_id_flags & id->flags) != header_board_id_flags); - /* - * Masked bits in header Board ID type must match type and inverse from - * flash. - */ - if (!mismatch && !board_id_type_is_blank(id)) { - mismatch = header_board_id_type ^ id->type; - mismatch |= header_board_id_type ^ ~id->type_inv; - mismatch &= header_board_id_mask; - } - return mismatch; -} - -int read_board_id(struct board_id *id) -{ - uint32_t *id_p; - int i; - - /* - * Board ID structure size is guaranteed to be divisible by 4, and it - * is guaranteed to be aligned at 4 bytes. - */ - - id_p = (uint32_t *)id; - - for (i = 0; i < sizeof(*id); i += sizeof(uint32_t)) { - int rv; - - rv = flash_physical_info_read_word - (INFO_BOARD_ID_OFFSET + i, id_p); - if (rv != EC_SUCCESS) { - CPRINTF("%s: failed to read word %d, error %d\n", - __func__, i, rv); - return rv; - } - id_p++; - } - return EC_SUCCESS; -} - -uint32_t board_id_mismatch(const struct SignedHeader *sh) -{ - struct board_id id; - - if (!sh) - /* Get header of the currently running image. */ - sh = get_current_image_header(); - - /* Get Board ID from INFO1. */ - if (read_board_id(&id) != EC_SUCCESS) { - /* - * On failure, set id fields to 0. This will only match an - * unrestricted image header (board_id_mask=board_id_flags=0), - * which would run on any Board ID. - * - * Don't return error, because that would prevent all images - * from running. - */ - id.type = id.type_inv = id.flags = 0; - } - - return check_board_id_vs_header(&id, sh); -} - -/** - * Write board ID into the flash INFO1 space. - * - * @param id Pointer to a Board ID structure to copy into INFO1 - * - * @return EC_SUCCESS or an error code in cases of various failures to read or - * if the space has been already initialized. - */ -static int write_board_id(struct board_id *id) -{ - struct board_id id_test; - uint32_t rv; - - /* Fail if Board ID is already programmed */ - rv = read_board_id(&id_test); - if (rv != EC_SUCCESS) { - CPRINTS("%s: error reading Board ID", __func__); - return rv; - } - - if (!board_id_is_blank(&id_test)) { - if (!board_id_type_is_blank(&id_test)) { - CPRINTS("%s: Board ID already programmed", __func__); - return EC_ERROR_ACCESS_DENIED; - } - CPRINTS("%s: using old flags.", __func__); - id->flags = id_test.flags; - } - - /* - * Make sure the current header will still validate against the - * proposed values. If it doesn't, then programming these values - * would cause the next boot to fail. - */ - if (check_board_id_vs_header(id, get_current_image_header()) != 0) { - CPRINTS("%s: Board ID wouldn't allow current header", __func__); - return EC_ERROR_INVAL; - } - - flash_info_write_enable(); - - /* Write Board ID */ - rv = flash_info_physical_write(INFO_BOARD_ID_OFFSET + - offsetof(struct info1_board_space, bid), - sizeof(*id), (const char *)id); - if (rv != EC_SUCCESS) - CPRINTS("%s: write failed", __func__); - - flash_info_write_disable(); - - return rv; -} - -static enum vendor_cmd_rc vc_set_board_id(enum vendor_cmd_cc code, - void *buf, - size_t input_size, - size_t *response_size) -{ - struct board_id id; - uint8_t *pbuf = buf; - - *response_size = 1; - - /* Exactly two fields are expected. */ - if (input_size != sizeof(id.type) + sizeof(id.flags)) { - *pbuf = VENDOR_RC_BOGUS_ARGS; - return VENDOR_RC_BOGUS_ARGS; - } - - memcpy(&id.type, pbuf, sizeof(id.type)); - id.type = be32toh(id.type); - if (id.type == BLANK_FIELD) - id.type_inv = BLANK_FIELD; - else - id.type_inv = ~id.type; - - memcpy(&id.flags, pbuf + sizeof(id.type), sizeof(id.flags)); - id.flags = be32toh(id.flags); - - /* We care about the LSB only. */ - *pbuf = write_board_id(&id); - - return *pbuf; -} -DECLARE_VENDOR_COMMAND(VENDOR_CC_SET_BOARD_ID, vc_set_board_id); - -static int command_board_id(int argc, char **argv) -{ - struct board_id id; - int rv = EC_ERROR_PARAM_COUNT; - - if (argc == 1) { - rv = read_board_id(&id); - - if (rv != EC_SUCCESS) { - ccprintf("Failed to read board ID space\n"); - return rv; - } - ccprintf("Board ID: %08x:%08x, flags %08x\n", id.type, - id.type_inv, id.flags); - - if (board_id_is_blank(&id)) - return rv; /* The space is not initialized. */ - - if (!board_id_type_is_blank(&id) && id.type != ~id.type_inv) - ccprintf("Inv Type Mismatch (%08x instead of %08x)!\n", - id.type_inv, ~id.type); - } -#ifdef CR50_DEV - else if (argc == 3) { - char *e; - - id.type = strtoi(argv[1], &e, 0); - if (*e) - return EC_ERROR_PARAM1; - id.type_inv = ~id.type; - id.flags = strtoi(argv[2], &e, 0); - if (*e) - return EC_ERROR_PARAM2; - rv = write_board_id(&id); - } -#endif - return rv; -} -DECLARE_SAFE_CONSOLE_COMMAND(bid, command_board_id, -#ifdef CR50_DEV - "[bid flags]", -#else - NULL, -#endif - "Set/Get Board ID"); - -static enum vendor_cmd_rc vc_get_board_id(enum vendor_cmd_cc code, - void *buf, - size_t input_size, - size_t *response_size) -{ - struct board_id id; - - if (read_board_id(&id)) - return VENDOR_RC_READ_FLASH_FAIL; - - /* Convert to line representation. */ - id.type = htobe32(id.type); - id.type_inv = htobe32(id.type_inv); - id.flags = htobe32(id.flags); - - memcpy(buf, &id, sizeof(id)); - *response_size = sizeof(id); - - return VENDOR_RC_SUCCESS; -} -DECLARE_VENDOR_COMMAND(VENDOR_CC_GET_BOARD_ID, vc_get_board_id); |