diff options
author | Przemyslaw Marczak <p.marczak@samsung.com> | 2014-11-05 21:09:07 +0100 |
---|---|---|
committer | Przemyslaw Marczak <p.marczak@samsung.com> | 2015-05-18 12:07:01 +0200 |
commit | 9949ee49f17112b80c700ac87aabe656136ca220 (patch) | |
tree | 7471ba3c782d2013890cea416c2474a07e8002d4 | |
parent | 6dbf3b993f1ee88a061501a2cd56f04919b352a8 (diff) | |
download | u-boot-9949ee49f17112b80c700ac87aabe656136ca220.tar.gz u-boot-9949ee49f17112b80c700ac87aabe656136ca220.tar.bz2 u-boot-9949ee49f17112b80c700ac87aabe656136ca220.zip |
samsung: misc: add new feature for configure partitions layout at boot.
This feature requires some platform configuration data
in the environment, which is:
-${platname}_setup_N_name - name of this setup
-${platname}_setup_N_partitions - GPT partitions or NULL if MBR
-${platname}_setup_N_alt_system - dfu_alt_info with system entities
-${platname}_setup_N_bootpart - boot partition number for this setup
-${platname}_setup_N_rootpart - root partition number for this setup
And for at least one setup it requires:
-${platname}_setup_cnt - number of ${platname} configs
-${platname}_setup_chosen - chosen plaform config
-${platname}_setup_active - active platform config (autoset)
Two environment variables are used to switch/check active setup:
-${platname}_setup_chosen - can be changed manually
-${platname}_setup_active - should be the same as chosen
If chosen setup is not set, then will be automatically set on boot
by setting proper env:
- $partitions := ${platname}_setup_N_partitions
- $dfu_alt_system_${platname} := ${platname}_setup_N_alt_system
- $mmcbootpart := ${platname}_setup_N_bootpart
- $mmcrootpart := ${platname}_setup_N_rootpart
- ${platname}_setup_active := ${platname}_setup_chosen
If ${partitions} are:
- set, then gpt write is called
- unset, e.g. when using MBR - then partition table is unchanged
Config:
- CONFIG_PLATFORM_SETUP
Change-Id: Ib9f90415b92ec1d67a9bf6b84e7ab5d5deea8a7d
Signed-off-by: Przemyslaw Marczak <p.marczak@samsung.com>
-rw-r--r-- | board/samsung/common/misc.c | 192 | ||||
-rw-r--r-- | include/samsung/misc.h | 4 |
2 files changed, 194 insertions, 2 deletions
diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c index 183789caaa..1bd4213acf 100644 --- a/board/samsung/common/misc.c +++ b/board/samsung/common/misc.c @@ -9,6 +9,7 @@ #include <lcd.h> #include <libtizen.h> #include <samsung/misc.h> +#include <samsung/platform_setup.h> #include <errno.h> #include <version.h> #include <malloc.h> @@ -17,9 +18,198 @@ #include <asm/gpio.h> #include <power/pmic.h> #include <mmc.h> +#include <part.h> DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_PLATFORM_SETUP +#define PLATFORM_SETUP_STR_BUF_LEN 64 +#define PLATFORM_SETUP_NUM_BUF_LEN 8 +#define BLOCK_SIZE 512 + +#if 0 +#define DBG(fmt, args...) printf(fmt, ##args) +#else +#define DBG(fmt, args...) { } +#endif + +static char *getenv_by_args(const char *fmt, ...) +{ + char buf[PLATFORM_SETUP_STR_BUF_LEN]; + char *env_var; + + va_list args; + + va_start(args, fmt); + vsnprintf(buf, GETENV_BY_ARGS_BUF_LEN,fmt, args); + va_end(args); + + /* Get source variable */ + env_var = getenv(buf); + if (!env_var) { + DBG("DBG: ${%s} not found!\n", buf); + return NULL; + } + + return env_var; +} + +static int platform_write(bool save_env) +{ + int ret = 0; + char *env_setup_active; + char *platname; + char *partitions; + + platname = getenv("platname"); + if (!platname) { + error("Undefined platname!\n"); + return CMD_RET_FAILURE; + } + + /* Get active setup number */ + env_setup_active = getenv_by_args("%s_setup_active", platname); + if (!env_setup_active) { + printf("Platform active configuration not found\n"); + printf("Check your setup and set: ${%s_setup_active} number\n", + platname); + printf("Then run: \"platform setup; platform write env\"\n"); + return CMD_RET_FAILURE; + } + + if (save_env && run_command("saveenv", 0)) { + error("Environment save failed"); + return CMD_RET_FAILURE; + } + + partitions = getenv("partitions"); + if (!partitions) { + printf("Partition table not changed.\n"); + return CMD_RET_SUCCESS; + } + + ret = run_command("gpt write mmc 0 $partitions", 0); + if (ret) { + error("gpt write failed"); + return ret; + } + + return CMD_RET_SUCCESS; +} + +int platform_setup(void) +{ + int setup_cnt, setup_chosen, setup_done = 0; + int buf_len = PLATFORM_SETUP_STR_BUF_LEN; + int buf_num_len = PLATFORM_SETUP_NUM_BUF_LEN; + char buf[buf_len]; + char buf_num[buf_num_len]; + char *env_setup_cnt; + char *env_setup_active; + char *env_setup_chosen; + char *env_setup_name; + char *value; + const char *platname; + int i; + + platname = getenv("platname"); + if (!platname) { + error("Undefined platname!\n"); + return CMD_RET_FAILURE; + } + + /* Get chosen setup number */ + env_setup_chosen = getenv_by_args("%s_setup_chosen", platname); + if (!env_setup_chosen) { + printf("Platform chosen setup not found!\n"); + return CMD_RET_FAILURE; + } + setup_chosen = simple_strtoul(env_setup_chosen, NULL, 0); + + /* Get chosen setup name */ + env_setup_name = getenv_by_args("%s_setup_%d_name", platname, + setup_chosen); + printf("Setup:[%d] %s for %s ", setup_chosen, env_setup_name, platname); + + /* Get active setup number */ + env_setup_active = getenv_by_args("%s_setup_active", platname); + + /* Check if setup_chosen == setup_active */ + if (env_setup_active && !strcmp(env_setup_chosen, env_setup_active)) { + printf("(active)\n"); + return CMD_RET_SUCCESS; + } + + printf("(not active)\n"); + + DBG("DBG: Setting chosen platform configuration.\n"); + + /* Get setup count for ${platname} */ + env_setup_cnt = getenv_by_args("%s_setup_cnt", platname); + if (!env_setup_cnt) { + error("Platform setup count not found!\n"); + return CMD_RET_FAILURE; + } + setup_cnt = simple_strtoul(env_setup_cnt, NULL, 0); + + DBG("DBG: Board: %s available setup_cnt: %s\n", platname, env_setup_cnt); + + for (i = 1; i <= setup_cnt; i++) { + if (i != setup_chosen) + continue; + + /* Get ${platname}_setup_N_alt_system */ + value = getenv_by_args("%s_setup_%d_alt_system", platname, i); + if (!value) { + printf("%s_setup_%d_alt_system - not found!\n", + platname, i); + return CMD_RET_FAILURE; + } + + /* Set dfu_alt_system_${board} */ + snprintf(buf, buf_len, "dfu_alt_system_%s", platname); + DBG("DBG: setenv($%s, %.16s[...])\n", buf, value); + setenv(buf, value); + + /* Get ${platname}_setup_N_partitions */ + value = getenv_by_args("%s_setup_%d_partitions", platname, i); + /* Set ${partitions} - NULL if not GPT */ + DBG("DBG: setenv($partitions, %.16s[...])\n", value); + setenv("partitions", value); + + /* Set ${mmcbootpart} */ + value = getenv_by_args("%s_setup_%d_bootpart", platname, i); + DBG("DBG: setenv($mmcbootpart, %s)\n", value); + setenv("mmcbootpart", value); + + /* Set ${mmcrootpart} */ + value = getenv_by_args("%s_setup_%d_rootpart", platname, i); + DBG("DBG: setenv($mmcrootpart, %s)\n", value); + setenv("mmcrootpart", value); + + /* Set active setup */ + snprintf(buf, buf_len, "%s_setup_active", platname); + snprintf(buf_num, buf_num_len, "%d", i); + DBG("DBG: setenv($%s, %s)\n", buf, buf_num); + setenv(buf, buf_num); + + printf("Setup:[%d] activated!\n", i); + setup_done = 1; + } + + if (!setup_done) { + printf("Chosen setup not found!\n"); +// lcd_display_bitmap(configuration fail logo with instructions!); + return CMD_RET_FAILURE; + } + + /* Save the setup to env */ + platform_write(true); + + return CMD_RET_SUCCESS; +} +#endif /* CONFIG_PLATFORM_SETUP */ + #ifdef CONFIG_SET_DFU_ALT_INFO void set_dfu_alt_info(char *interface, char *devstr) { @@ -78,7 +268,6 @@ void set_board_info(void) #endif #ifdef CONFIG_OF_LIBFDT const char *bdname = CONFIG_SYS_BOARD; - #ifdef CONFIG_BOARD_TYPES #ifdef CONFIG_OF_MULTI const char *platname = get_plat_name(); @@ -741,3 +930,4 @@ void draw_logo(void) bmp_display(addr, x, y); } #endif /* CONFIG_CMD_BMP */ + diff --git a/include/samsung/misc.h b/include/samsung/misc.h index 574d30ec15..ed8b24a3c3 100644 --- a/include/samsung/misc.h +++ b/include/samsung/misc.h @@ -71,5 +71,7 @@ const char *get_plat_name(void); const char *get_board_name(void); #endif #endif - +#ifdef CONFIG_PLATFORM_SETUP +int platform_setup(void); +#endif #endif /* __SAMSUNG_MISC_COMMON_H__ */ |