summaryrefslogtreecommitdiff
path: root/soc/common/boot_control/boot_control.c
diff options
context:
space:
mode:
authorYu Jun <yujun@marvell.com>2015-12-02 21:31:20 -0800
committerMohammed Habibulla <moch@google.com>2015-12-07 10:52:47 -0800
commit19a55c0cf21b4a83fcd893f1d3bd7ae55b7ed975 (patch)
treeaa566a6cade92c485ba8e501ecdeefce58a27243 /soc/common/boot_control/boot_control.c
parentfab620ac9a9596ad7c56d6070561cf061dd0f262 (diff)
downloadmarvell-19a55c0cf21b4a83fcd893f1d3bd7ae55b7ed975.tar.gz
To move the boot_control module from device to hardware
Fixed the problem: While following the codelab steps to create the ledflasher product based upon abox_edge device, the boot_control function is not built-in. BUG=25984558 Change-Id: I8215ce66bf1113374f90a1c5349b22dea4bfbf8d
Diffstat (limited to 'soc/common/boot_control/boot_control.c')
-rw-r--r--soc/common/boot_control/boot_control.c215
1 files changed, 215 insertions, 0 deletions
diff --git a/soc/common/boot_control/boot_control.c b/soc/common/boot_control/boot_control.c
new file mode 100644
index 0000000..fe40373
--- /dev/null
+++ b/soc/common/boot_control/boot_control.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <fs_mgr.h>
+#include <hardware/hardware.h>
+#include <hardware/boot_control.h>
+#include <cutils/properties.h>
+
+#include "bootinfo.h"
+
+
+void boot_control_init(struct boot_control_module *module)
+{
+ return;
+}
+
+unsigned get_number_slots(struct boot_control_module *module)
+{
+ return 2;
+}
+
+unsigned get_current_slot(struct boot_control_module *module)
+{
+ char propbuf[PROPERTY_VALUE_MAX];
+ const char* suffix[2] = {"_a", "_b"};
+ int i;
+
+ property_get("ro.boot.slot_suffix", propbuf, "");
+
+ if (propbuf[0] != '\0') {
+ for (i = 0; i < 2; i++) {
+ if (strncmp(propbuf, suffix[i], 2) == 0)
+ return i;
+ }
+
+ if (i == 2)
+ fprintf(stderr, "WARNING: androidboot.slot_suffix is invalid\n");
+ } else {
+ fprintf(stderr, "WARNING: androidboot.slot_suffix is NULL\n");
+ }
+
+ return 0;
+}
+
+int mark_boot_successful(struct boot_control_module *module)
+{
+ BrilloBootInfo info;
+ unsigned current_slot;
+ int i;
+
+ if (!boot_info_load(&info)) {
+ fprintf(stderr, "WARNING: Error loading boot-info. Resetting.\n");
+ boot_info_reset(&info);
+ } else {
+ if (!boot_info_validate(&info)) {
+ fprintf(stderr, "WARNING: boot-info is invalid. Resetting.\n");
+ boot_info_reset(&info);
+ }
+ }
+
+ current_slot = get_current_slot(module);
+
+ info.slot_info[current_slot].boot_successful = true;
+ info.slot_info[current_slot].tries_remaining = 0;
+
+ if (!boot_info_save(&info)) {
+ fprintf(stderr, "WARNING: Error saving boot-info.\n");
+ return -errno;
+ }
+
+ return 0;
+}
+
+int set_active_boot_slot(struct boot_control_module *module, unsigned slot)
+{
+ BrilloBootInfo info;
+ unsigned other_slot;
+ int i;
+
+ if (slot >= 2)
+ return -EINVAL;
+
+ if (!boot_info_load(&info)) {
+ fprintf(stderr, "WARNING: Error loading boot-info. Resetting.\n");
+ boot_info_reset(&info);
+ } else {
+ if (!boot_info_validate(&info)) {
+ fprintf(stderr, "WARNING: boot-info is invalid. Resetting.\n");
+ boot_info_reset(&info);
+ }
+ }
+
+ other_slot = 1 - slot;
+ if (info.slot_info[other_slot].priority == 15)
+ info.slot_info[other_slot].priority = 14;
+
+ info.slot_info[slot].bootable = true;
+ info.slot_info[slot].priority = 15;
+ info.slot_info[slot].tries_remaining = 7;
+ info.slot_info[slot].boot_successful = false;
+
+ if (!boot_info_save(&info)) {
+ fprintf(stderr, "WARNING: Error saving boot-info.\n");
+ return -errno;
+ }
+
+ return 0;
+}
+
+int set_slot_as_unbootable(struct boot_control_module *module, unsigned slot)
+{
+ BrilloBootInfo info;
+
+ if (slot >= 2)
+ return -EINVAL;
+
+ if (!boot_info_load(&info)) {
+ fprintf(stderr, "WARNING: Error loading boot-info. Resetting.\n");
+ boot_info_reset(&info);
+ } else {
+ if (!boot_info_validate(&info)) {
+ fprintf(stderr, "WARNING: boot-info is invalid. Resetting.\n");
+ boot_info_reset(&info);
+ }
+ }
+
+ info.slot_info[slot].bootable = false;
+ info.slot_info[slot].priority = 0;
+ info.slot_info[slot].tries_remaining = 0;
+ info.slot_info[slot].boot_successful = false;
+
+ if (!boot_info_save(&info)) {
+ fprintf(stderr, "WARNING: Error saving boot-info.\n");
+ return -errno;
+ }
+
+ return 0;
+}
+
+int is_slot_bootable(struct boot_control_module *module, unsigned slot)
+{
+ BrilloBootInfo info;
+
+ if (slot >= 2)
+ return -EINVAL;
+
+ if (!boot_info_load(&info)) {
+ fprintf(stderr, "WARNING: Error loading boot-info. Resetting.\n");
+ boot_info_reset(&info);
+ } else {
+ if (!boot_info_validate(&info)) {
+ fprintf(stderr, "WARNING: boot-info is invalid. Resetting.\n");
+ boot_info_reset(&info);
+ }
+ }
+
+ return info.slot_info[slot].bootable;
+}
+
+const char* get_suffix(struct boot_control_module *module, unsigned slot)
+{
+ static const char* suffix[2] = {"_a", "_b"};
+
+ if (slot >= 2)
+ return NULL;
+
+ return suffix[slot];
+}
+
+static struct hw_module_methods_t boot_control_module_methods = {
+ .open = NULL,
+};
+
+struct boot_control_module HAL_MODULE_INFO_SYM = {
+ .common = {
+ .tag = HARDWARE_MODULE_TAG,
+ .module_api_version = BOOT_CONTROL_MODULE_API_VERSION_0_1,
+ .hal_api_version = HARDWARE_HAL_API_VERSION,
+ .id = BOOT_CONTROL_HARDWARE_MODULE_ID,
+ .name = "Marvell Boot Control HAL",
+ .author = "Marvell SEEDS",
+ .methods = &boot_control_module_methods,
+ },
+
+ .init = boot_control_init,
+ .getNumberSlots = get_number_slots,
+ .getCurrentSlot = get_current_slot,
+ .markBootSuccessful = mark_boot_successful,
+ .setActiveBootSlot = set_active_boot_slot,
+ .setSlotAsUnbootable = set_slot_as_unbootable,
+ .isSlotBootable = is_slot_bootable,
+ .getSuffix = get_suffix,
+};