summaryrefslogtreecommitdiff
path: root/system/cbootimage/nvbctlib_ap20.c
diff options
context:
space:
mode:
Diffstat (limited to 'system/cbootimage/nvbctlib_ap20.c')
-rw-r--r--system/cbootimage/nvbctlib_ap20.c282
1 files changed, 282 insertions, 0 deletions
diff --git a/system/cbootimage/nvbctlib_ap20.c b/system/cbootimage/nvbctlib_ap20.c
new file mode 100644
index 0000000..2535432
--- /dev/null
+++ b/system/cbootimage/nvbctlib_ap20.c
@@ -0,0 +1,282 @@
+/**
+ * Copyright (c) 2011 NVIDIA Corporation. All rights reserved.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include "nvbctlib.h"
+#include "nvboot_bct.h"
+#include "string.h"
+#include "cbootimage.h"
+
+/* nvbctlib_ap20.c: The implementation of the nvbctlib API for AP20. */
+
+/* Definitions that simplify the code which follows. */
+#define CASE_GET_BL_PARAM(x) \
+case nvbct_lib_id_bl_##x:\
+ *data = bct_ptr->bootloader[set].x; \
+ break
+
+#define CASE_SET_BL_PARAM(x) \
+case nvbct_lib_id_bl_##x:\
+ bct_ptr->bootloader[set].x = *data; \
+ break
+
+#define CASE_GET_NVU32(id) \
+case nvbct_lib_id_##id:\
+ if (bct == NULL) return -ENODATA; \
+ *data = bct_ptr->id; \
+ break
+
+#define CASE_GET_CONST(id, val) \
+case nvbct_lib_id_##id:\
+ *data = val; \
+ break
+
+#define CASE_GET_CONST_PREFIX(id, val_prefix) \
+case nvbct_lib_id_##id:\
+ *data = val_prefix##id; \
+ break
+
+#define CASE_SET_NVU32(id) \
+case nvbct_lib_id_##id:\
+ bct_ptr->id = data; \
+ break
+
+#define CASE_GET_DATA(id, size) \
+case nvbct_lib_id_##id:\
+ if (*length < size) return -ENODATA;\
+ memcpy(data, &(bct_ptr->id), size); \
+ *length = size;\
+ break
+
+#define CASE_SET_DATA(id, size) \
+case nvbct_lib_id_##id:\
+ if (length < size) return -ENODATA;\
+ memcpy(&(bct_ptr->id), data, size); \
+ break
+
+
+static int
+getbl_param(u_int32_t set,
+ nvbct_lib_id id,
+ u_int32_t *data,
+ u_int8_t *bct)
+{
+ nvboot_config_table *bct_ptr = (nvboot_config_table*)bct;
+
+ if (set >= NVBOOT_MAX_BOOTLOADERS)
+ return -ENODATA;
+ if (data == NULL || bct == NULL)
+ return -ENODATA;
+
+ switch (id) {
+ CASE_GET_BL_PARAM(version);
+ CASE_GET_BL_PARAM(start_blk);
+ CASE_GET_BL_PARAM(start_page);
+ CASE_GET_BL_PARAM(length);
+ CASE_GET_BL_PARAM(load_addr);
+ CASE_GET_BL_PARAM(entry_point);
+ CASE_GET_BL_PARAM(attribute);
+
+ case nvbct_lib_id_bl_crypto_hash:
+ memcpy(data,
+ &(bct_ptr->bootloader[set].crypto_hash),
+ sizeof(nvboot_hash));
+ break;
+
+ default:
+ return -ENODATA;
+ }
+
+ return 0;
+}
+
+/* Note: The *Data argument is to support hash data. */
+static int
+setbl_param(u_int32_t set,
+ nvbct_lib_id id,
+ u_int32_t *data,
+ u_int8_t *bct)
+{
+ nvboot_config_table *bct_ptr = (nvboot_config_table*)bct;
+
+ if (set >= NVBOOT_MAX_BOOTLOADERS)
+ return -ENODATA;
+ if (data == NULL || bct == NULL)
+ return -ENODATA;
+
+ switch (id) {
+ CASE_SET_BL_PARAM(version);
+ CASE_SET_BL_PARAM(start_blk);
+ CASE_SET_BL_PARAM(start_page);
+ CASE_SET_BL_PARAM(length);
+ CASE_SET_BL_PARAM(load_addr);
+ CASE_SET_BL_PARAM(entry_point);
+ CASE_SET_BL_PARAM(attribute);
+
+ case nvbct_lib_id_bl_crypto_hash:
+ memcpy(&(bct_ptr->bootloader[set].crypto_hash),
+ data,
+ sizeof(nvboot_hash));
+ break;
+
+ default:
+ return -ENODATA;
+ }
+
+ return 0;
+}
+
+
+static int
+bct_get_value(nvbct_lib_id id, u_int32_t *data, u_int8_t *bct)
+{
+ nvboot_config_table *bct_ptr = (nvboot_config_table*)bct;
+ nvboot_config_table samplebct; /* Used for computing offsets. */
+
+ /*
+ * Note: Not all queries require use of the BCT, so testing for a
+ * valid BCT is distributed within the code.
+ */
+ if (data == NULL)
+ return -ENODATA;
+
+ switch (id) {
+ /*
+ * Simple BCT fields
+ */
+ CASE_GET_NVU32(boot_data_version);
+ CASE_GET_NVU32(block_size_log2);
+ CASE_GET_NVU32(page_size_log2);
+ CASE_GET_NVU32(partition_size);
+ CASE_GET_NVU32(bootloader_used);
+
+ /*
+ * Constants.
+ */
+
+ CASE_GET_CONST(bootloaders_max, NVBOOT_MAX_BOOTLOADERS);
+ CASE_GET_CONST(reserved_size, NVBOOT_BCT_RESERVED_SIZE);
+
+ case nvbct_lib_id_reserved_offset:
+ *data = (u_int8_t*)&(samplebct.reserved)
+ - (u_int8_t*)&samplebct;
+ break;
+
+ case nvbct_lib_id_bct_size:
+ *data = sizeof(nvboot_config_table);
+ break;
+
+ CASE_GET_CONST(hash_size, sizeof(nvboot_hash));
+
+ case nvbct_lib_id_crypto_offset:
+ /* Offset to region in BCT to encrypt & sign */
+ *data = (u_int8_t*)&(samplebct.random_aes_blk)
+ - (u_int8_t*)&samplebct;
+ break;
+
+ case nvbct_lib_id_crypto_length:
+ /* size of region in BCT to encrypt & sign */
+ *data = sizeof(nvboot_config_table) - sizeof(nvboot_hash);
+ break;
+
+ CASE_GET_CONST(max_bct_search_blks, NVBOOT_MAX_BCT_SEARCH_BLOCKS);
+
+ default:
+ return -ENODATA;
+ }
+ return 0;
+}
+
+static int
+bct_set_value(nvbct_lib_id id, u_int32_t data, u_int8_t *bct)
+{
+ nvboot_config_table *bct_ptr = (nvboot_config_table*)bct;
+
+ if (bct == NULL)
+ return -ENODATA;
+
+ switch (id) {
+ /*
+ * Simple BCT fields
+ */
+ CASE_SET_NVU32(boot_data_version);
+ CASE_SET_NVU32(block_size_log2);
+ CASE_SET_NVU32(page_size_log2);
+ CASE_SET_NVU32(partition_size);
+ CASE_SET_NVU32(bootloader_used);
+
+ default:
+ return -ENODATA;
+ }
+
+ return 0;
+}
+
+
+
+/*
+ * Note: On input, *length is the size of Data. On output, *length is the
+ * actual size used.
+ */
+static int
+bct_get_data(nvbct_lib_id id,
+ u_int8_t *data,
+ u_int32_t *length,
+ u_int8_t *bct)
+{
+ return 0;
+}
+
+static int
+bct_set_data(nvbct_lib_id id,
+ u_int8_t *data,
+ u_int32_t length,
+ u_int8_t *bct)
+{
+ nvboot_config_table *bct_ptr = (nvboot_config_table*)bct;
+
+ if (data == NULL || bct == NULL)
+ return -ENODATA;
+
+ switch (id) {
+
+ CASE_SET_DATA(crypto_hash, sizeof(nvboot_hash));
+
+ default:
+ return -ENODATA;
+ }
+
+ return 0;
+}
+
+
+void
+nvbct_lib_get_fns(nvbct_lib_fns *fns)
+{
+ fns->get_value = bct_get_value;
+ fns->set_value = bct_set_value;
+
+ fns->get_data = bct_get_data;
+ fns->set_data = bct_set_data;
+
+ fns->getbl_param = getbl_param;
+ fns->setbl_param = setbl_param;
+}