[Feature]add MT2731_MP2_MR2_SVN388 baseline version
Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/bsp/lk/lib/upgrade_app_ctrl/include/lib/upgrade_app_ctrl.h b/src/bsp/lk/lib/upgrade_app_ctrl/include/lib/upgrade_app_ctrl.h
new file mode 100644
index 0000000..d39fe0a
--- /dev/null
+++ b/src/bsp/lk/lib/upgrade_app_ctrl/include/lib/upgrade_app_ctrl.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ *
+ * Use of this source code is governed by MIT-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/MIT
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#define UPG_SUCCEED 2
+
+#define BOOTCTRL_SUFFIX_A "_a"
+#define BOOTCTRL_SUFFIX_B "_b"
+
+
+/* upgrade_app boot control API */
+
+/**
+* get_suffix() returns the current slot' suffix.
+*/
+const char *get_suffix(void);
diff --git a/src/bsp/lk/lib/upgrade_app_ctrl/rules.mk b/src/bsp/lk/lib/upgrade_app_ctrl/rules.mk
new file mode 100644
index 0000000..33c1053
--- /dev/null
+++ b/src/bsp/lk/lib/upgrade_app_ctrl/rules.mk
@@ -0,0 +1,10 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+MODULE := $(LOCAL_DIR)
+
+
+MODULE_SRCS += \
+ $(LOCAL_DIR)/upgrade_app_ctrl_api.c
+
+MODULE_DEPS += lib/mempool lib/bio
+
+include make/module.mk
diff --git a/src/bsp/lk/lib/upgrade_app_ctrl/upgrade_app_ctrl_api.c b/src/bsp/lk/lib/upgrade_app_ctrl/upgrade_app_ctrl_api.c
new file mode 100644
index 0000000..a2d9559
--- /dev/null
+++ b/src/bsp/lk/lib/upgrade_app_ctrl/upgrade_app_ctrl_api.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ *
+ * Use of this source code is governed by MIT-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/MIT
+ */
+#include <assert.h>
+#include <errno.h>
+#include <lib/bio.h>
+#include <lib/mempool.h>
+#include <lib/upgrade_app_ctrl.h>
+#include <platform.h>
+#include <string.h>
+#include <trace.h>
+
+#define BOOTCTR_PARTITION "misc"
+#define LOCAL_TRACE 0
+
+typedef struct boot_flag boot_flag;
+struct boot_flag {
+ int lastboot; //0:last boot from system A, 1:last boot from system B
+ int usea; //0:upgrade A failed or not upgrade, 2:upgrade A success
+ int useb; //0:upgrade B failed or not upgrade, 2:upgrade B success
+ int current; //0:current boot from system A, 1:current boot from system B
+};
+
+/**
+* set the cuurent_boot flag
+* last_flag: last_boot flag
+* current_flag: current_boot flag
+* part_name: partition name of storing boot flags
+*
+* return: 0-success, -1 failed
+*/
+static u32 set_currently_boot_flag(int last_flag, int current_flag, const char *part_name)
+{
+ int ret = -1;
+ long len = 0;
+ size_t bdev_erase_size;
+ char *buf = NULL;
+ boot_flag set_flag;
+
+ struct bdev *bdev_MISC = bio_open_by_label(part_name);
+ if (bdev_MISC == NULL) {
+ LTRACEF_LEVEL(CRITICAL, "open partition %s failed! %d \n",
+ part_name, __LINE__);
+ goto err;
+ }
+ ASSERT(bdev_MISC->geometry != NULL);
+ bdev_erase_size = (size_t)bdev_MISC->geometry->erase_size;
+ LTRACEF("bdev_erase_size is %d. \n", bdev_erase_size);
+
+ buf = mempool_alloc(bdev_erase_size, MEMPOOL_ANY);
+ if (buf == NULL) {
+ LTRACEF_LEVEL(CRITICAL, "malloc buffer failed! %d \n", __LINE__);
+ goto err;
+ }
+ len = bio_read(bdev_MISC, buf, 0, bdev_erase_size);
+ if (len < 0) {
+ LTRACEF_LEVEL(CRITICAL, "bio_read error: %d\n", len);
+ goto err;
+ }
+
+ /* dump flag for debug */
+ LTRACEF("current boot flag is %d\n", current_flag);
+ /* set currently flag to buf */
+ set_flag.lastboot = last_flag;
+ set_flag.current = current_flag;
+ set_flag.usea = -1;
+ LTRACEF("last_flag boot flag is %d\n", last_flag);
+ set_flag.useb = -1;
+ memcpy(buf, (void *)&set_flag, sizeof(boot_flag));
+
+ // earse the partition
+ len = bio_erase(bdev_MISC, 0, bdev_erase_size);
+ if (len < 0) {
+ LTRACEF_LEVEL(CRITICAL, "bio_erase error: %d\n", len);
+ goto err;
+ }
+ /* write buf to offset 0 */
+ len = bio_write(bdev_MISC, (char *)buf, 0, bdev_erase_size);
+ if (len <= 0) {
+ LTRACEF_LEVEL(CRITICAL, "bio write fail, return : %d, error: %s \n",
+ len, strerror(errno));
+ LTRACEF_LEVEL(CRITICAL, "buf: %s\n", buf);
+ goto err;
+ }
+ LTRACEF("set flag: lastboot = %d, use A = %d, use B = %d, current = %d\n",
+ set_flag.lastboot, set_flag.usea, set_flag.useb, set_flag.current);
+ ret = 0;
+err:
+ if (buf) {
+ mempool_free(buf);
+ }
+ if (bdev_MISC) {
+ bio_close(bdev_MISC);
+ }
+ return ret;
+}
+
+/**
+* check boot flags to decide boot from system A or system B
+* part_name: partition name of storing boot flags
+*
+* return: 0-choose system A to boot, 1-choose system B to boot
+*/
+static u32 check_boot_partition(const char *part_name)
+{
+ int ret = 0;
+ boot_flag flag;
+ int boot = 0;
+
+ struct bdev *bdev_MISC = bio_open_by_label(part_name);
+ int len = -1;
+ char *buf = NULL;
+
+ if (!bdev_MISC) {
+ LTRACEF_LEVEL(CRITICAL, "failed to open MISC\n");
+ goto err;
+ }
+
+ /* read partition */
+ buf = mempool_alloc(sizeof(boot_flag), MEMPOOL_ANY);
+ if (buf == NULL) {
+ LTRACEF_LEVEL(CRITICAL, "malloc buffer failed! %d \n", __LINE__);
+ goto err;
+ }
+ len = bio_read(bdev_MISC, buf, 0, sizeof(boot_flag));
+ memcpy(&flag, (void *)buf, sizeof(boot_flag));
+ if (len < 0) {
+ LTRACEF_LEVEL(CRITICAL, "read %s: boot flag read error. LINE: %d\n",
+ part_name, __LINE__);
+ goto err;
+ }
+
+ /* dump flag for debug */
+ LTRACEF("lastboot = %d, use A = %d, use B = %d, current = %d\n",
+ flag.lastboot, flag.usea, flag.useb, flag.current);
+
+ /* make decision */
+ if (flag.lastboot == 0) {
+ if (flag.useb == UPG_SUCCEED) {
+ boot = 1;
+ LTRACEF_LEVEL(ALWAYS, "***last succeed boot from A system,upgrade B succeed***\n");
+ } else {
+ boot = 0;
+ LTRACEF_LEVEL(ALWAYS, "***last succeed boot from A system,upgrade B failed or no upgrade B***\n");
+ }
+ } else if (flag.lastboot == 1) {
+ if (flag.usea == UPG_SUCCEED) {
+ boot = 0;
+ LTRACEF_LEVEL(ALWAYS, "***last succeed boot from B system,upgrade A succeed***\n");
+ } else {
+ boot = 1;
+ LTRACEF_LEVEL(ALWAYS, "***last succeed boot from B system,upgrade A failed or no upgrade A***\n");
+ }
+ } else {
+ LTRACEF_LEVEL(ALWAYS, "boot flag is not match, use default boot partition\n");
+ boot = 0;
+ }
+
+ if ((flag.current != boot) || (flag.usea == UPG_SUCCEED) ||
+ (flag.useb == UPG_SUCCEED)) {
+ ret = set_currently_boot_flag(flag.lastboot, boot, part_name);
+ if (ret != 0)
+ LTRACEF_LEVEL(CRITICAL, "set flags fail. LINE: %d\n", __LINE__);
+ }
+
+err:
+ if (buf) {
+ mempool_free(buf);
+ }
+ if (bdev_MISC) {
+ bio_close(bdev_MISC);
+ }
+ return boot;
+}
+
+const char *get_suffix(void)
+{
+ u32 boot_part;
+ LTRACEF("Enter AB upgrade_app flow\n");
+ boot_part = check_boot_partition(BOOTCTR_PARTITION);
+ LTRACEF_LEVEL(ALWAYS, "boot_part=%u, suffix=%c\n",
+ boot_part, (boot_part == 1) ? 'B' : 'A');
+ return (boot_part == 1) ? BOOTCTRL_SUFFIX_B : BOOTCTRL_SUFFIX_A;
+}
+