summaryrefslogtreecommitdiff
path: root/src/set.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/set.c')
-rw-r--r--src/set.c206
1 files changed, 206 insertions, 0 deletions
diff --git a/src/set.c b/src/set.c
new file mode 100644
index 0000000..08c9fb6
--- /dev/null
+++ b/src/set.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ */
+
+/*
+ * set.c - State setting support for the cbootimage tool
+ */
+
+#include "set.h"
+#include "cbootimage.h"
+#include "crypto.h"
+#include "data_layout.h"
+
+/*
+ * Function prototypes
+ *
+ * ParseXXX() parses XXX in the input
+ * SetXXX() sets state based on the parsing results but does not perform
+ * any parsing of its own
+ * A ParseXXX() function may call other parse functions and set functions.
+ * A SetXXX() function may not call any parseing functions.
+ */
+#define DEFAULT() \
+ default: \
+ printf("Unexpected token %d at line %d\n", \
+ token, __LINE__); \
+ return 1
+
+int
+read_from_image(char *filename,
+ u_int8_t **image,
+ u_int32_t *actual_size,
+ file_type f_type)
+{
+ int result = 0; /* 0 = success, 1 = failure */
+ FILE *fp;
+ struct stat stats;
+
+ fp = fopen(filename, "r");
+ if (fp == NULL) {
+ result = 1;
+ return result;
+ }
+
+ if (stat(filename, &stats) != 0) {
+ printf("Error: Unable to query info on bootloader path %s\n",
+ filename);
+ result = 1;
+ goto cleanup;
+ }
+
+ *actual_size = (u_int32_t)stats.st_size;
+
+ if (f_type == file_type_bl && *actual_size > MAX_BOOTLOADER_SIZE) {
+ printf("Error: Bootloader file %s is too large.\n",
+ filename);
+ result = 1;
+ goto cleanup;
+ }
+ *image = malloc(*actual_size);
+ if (*image == NULL) {
+ result = 1;
+ goto cleanup;
+ }
+
+ memset(*image, 0, *actual_size);
+
+ if (fread(*image, 1, (size_t)stats.st_size, fp) != stats.st_size) {
+ result = 1;
+ goto cleanup;
+ }
+
+cleanup:
+ fclose(fp);
+ return result;
+}
+
+/*
+ * Processes commands to set a bootloader.
+ *
+ * @param context The main context pointer
+ * @param filename The file name of bootloader
+ * @param load_addr The load address value for bootloader
+ * @param entry_point The entry point value for bootloader
+ * @return 0 and 1 for success and failure
+ */
+int
+set_bootloader(build_image_context *context,
+ char *filename,
+ u_int32_t load_addr,
+ u_int32_t entry_point)
+{
+ context->newbl_filename = filename;
+ context->newbl_load_addr = load_addr;
+ context->newbl_entry_point = entry_point;
+ return update_bl(context);
+}
+
+#define DEFAULT() \
+ default: \
+ printf("Unexpected token %d at line %d\n", \
+ token, __LINE__); \
+ return 1
+
+/*
+ * General handler for setting values in config files.
+ *
+ * @param context The main context pointer
+ * @param token The parse token value
+ * @param value The value to set
+ * @return 0 for success
+ */
+int context_set_value(build_image_context *context,
+ parse_token token,
+ u_int32_t value)
+{
+ assert(context != NULL);
+
+ switch (token) {
+ case token_attribute:
+ context->newbl_attr = value;
+ break;
+
+ case token_block_size:
+ context->block_size = value;
+ context->block_size_log2 = log2(value);
+
+ if (context->memory != NULL) {
+ printf("Error: Too late to change block size.\n");
+ return 1;
+ }
+
+ if (value != (u_int32_t)(1 << context->block_size_log2)) {
+ printf("Error: Block size must be a power of 2.\n");
+ return 1;
+ }
+ context->pages_per_blk= 1 << (context->block_size_log2-
+ context->page_size_log2);
+ g_soc_config->set_value(token_block_size_log2,
+ context->block_size_log2, context->bct);
+ break;
+
+ case token_partition_size:
+ if (context->memory != NULL) {
+ printf("Error: Too late to change block size.\n");
+ return 1;
+ }
+
+ context->partition_size= value;
+ g_soc_config->set_value(token_partition_size,
+ value, context->bct);
+ break;
+
+ case token_page_size:
+ context->page_size = value;
+ context->page_size_log2 = log2(value);
+ context->pages_per_blk= 1 << (context->block_size_log2-
+ context->page_size_log2);
+
+ g_soc_config->set_value(token_page_size_log2,
+ context->page_size_log2, context->bct);
+ break;
+ case token_redundancy:
+ context->redundancy = value;
+ break;
+
+ case token_version:
+ context->version = value;
+ break;
+
+ case token_bct_copy:
+ context->bct_copy = value;
+ break;
+
+ case token_odm_data:
+ context->odm_data = value;
+ break;
+
+ case token_pre_bct_pad_blocks:
+ if (context->bct_init) {
+ printf("Error: Too late to pre-BCT pad.\n");
+ return 1;
+ }
+ context->pre_bct_pad_blocks = value;
+ break;
+
+ DEFAULT();
+ }
+
+ return 0;
+}