uboot/drivers/fastboot/fb_getvar.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-2-Clause
   2/*
   3 * Copyright (C) 2016 The Android Open Source Project
   4 */
   5
   6#include <common.h>
   7#include <fastboot.h>
   8#include <fastboot-internal.h>
   9#include <fb_mmc.h>
  10#include <fb_nand.h>
  11#include <fs.h>
  12#include <version.h>
  13
  14static void getvar_version(char *var_parameter, char *response);
  15static void getvar_bootloader_version(char *var_parameter, char *response);
  16static void getvar_downloadsize(char *var_parameter, char *response);
  17static void getvar_serialno(char *var_parameter, char *response);
  18static void getvar_version_baseband(char *var_parameter, char *response);
  19static void getvar_product(char *var_parameter, char *response);
  20static void getvar_current_slot(char *var_parameter, char *response);
  21static void getvar_slot_suffixes(char *var_parameter, char *response);
  22static void getvar_has_slot(char *var_parameter, char *response);
  23#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
  24static void getvar_partition_type(char *part_name, char *response);
  25#endif
  26#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
  27static void getvar_partition_size(char *part_name, char *response);
  28#endif
  29
  30static const struct {
  31        const char *variable;
  32        void (*dispatch)(char *var_parameter, char *response);
  33} getvar_dispatch[] = {
  34        {
  35                .variable = "version",
  36                .dispatch = getvar_version
  37        }, {
  38                .variable = "bootloader-version",
  39                .dispatch = getvar_bootloader_version
  40        }, {
  41                .variable = "version-bootloader",
  42                .dispatch = getvar_bootloader_version
  43        }, {
  44                .variable = "downloadsize",
  45                .dispatch = getvar_downloadsize
  46        }, {
  47                .variable = "max-download-size",
  48                .dispatch = getvar_downloadsize
  49        }, {
  50                .variable = "serialno",
  51                .dispatch = getvar_serialno
  52        }, {
  53                .variable = "version-baseband",
  54                .dispatch = getvar_version_baseband
  55        }, {
  56                .variable = "product",
  57                .dispatch = getvar_product
  58        }, {
  59                .variable = "current-slot",
  60                .dispatch = getvar_current_slot
  61        }, {
  62                .variable = "slot-suffixes",
  63                .dispatch = getvar_slot_suffixes
  64        }, {
  65                .variable = "has_slot",
  66                .dispatch = getvar_has_slot
  67#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
  68        }, {
  69                .variable = "partition-type",
  70                .dispatch = getvar_partition_type
  71#endif
  72#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
  73        }, {
  74                .variable = "partition-size",
  75                .dispatch = getvar_partition_size
  76#endif
  77        }
  78};
  79
  80static void getvar_version(char *var_parameter, char *response)
  81{
  82        fastboot_okay(FASTBOOT_VERSION, response);
  83}
  84
  85static void getvar_bootloader_version(char *var_parameter, char *response)
  86{
  87        fastboot_okay(U_BOOT_VERSION, response);
  88}
  89
  90static void getvar_downloadsize(char *var_parameter, char *response)
  91{
  92        fastboot_response("OKAY", response, "0x%08x", fastboot_buf_size);
  93}
  94
  95static void getvar_serialno(char *var_parameter, char *response)
  96{
  97        const char *tmp = env_get("serial#");
  98
  99        if (tmp)
 100                fastboot_okay(tmp, response);
 101        else
 102                fastboot_fail("Value not set", response);
 103}
 104
 105static void getvar_version_baseband(char *var_parameter, char *response)
 106{
 107        fastboot_okay("N/A", response);
 108}
 109
 110static void getvar_product(char *var_parameter, char *response)
 111{
 112        const char *board = env_get("board");
 113
 114        if (board)
 115                fastboot_okay(board, response);
 116        else
 117                fastboot_fail("Board not set", response);
 118}
 119
 120static void getvar_current_slot(char *var_parameter, char *response)
 121{
 122        /* A/B not implemented, for now always return _a */
 123        fastboot_okay("_a", response);
 124}
 125
 126static void getvar_slot_suffixes(char *var_parameter, char *response)
 127{
 128        fastboot_okay("_a,_b", response);
 129}
 130
 131static void getvar_has_slot(char *part_name, char *response)
 132{
 133        if (part_name && (!strcmp(part_name, "boot") ||
 134                          !strcmp(part_name, "system")))
 135                fastboot_okay("yes", response);
 136        else
 137                fastboot_okay("no", response);
 138}
 139
 140#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
 141static void getvar_partition_type(char *part_name, char *response)
 142{
 143        int r;
 144        struct blk_desc *dev_desc;
 145        disk_partition_t part_info;
 146
 147        r = fastboot_mmc_get_part_info(part_name, &dev_desc, &part_info,
 148                                       response);
 149        if (r >= 0) {
 150                r = fs_set_blk_dev_with_part(dev_desc, r);
 151                if (r < 0)
 152                        fastboot_fail("failed to set partition", response);
 153                else
 154                        fastboot_okay(fs_get_type_name(), response);
 155        }
 156}
 157#endif
 158
 159#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
 160static void getvar_partition_size(char *part_name, char *response)
 161{
 162        int r;
 163        size_t size;
 164
 165#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
 166        struct blk_desc *dev_desc;
 167        disk_partition_t part_info;
 168
 169        r = fastboot_mmc_get_part_info(part_name, &dev_desc, &part_info,
 170                                       response);
 171        if (r >= 0)
 172                size = part_info.size;
 173#endif
 174#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
 175        struct part_info *part_info;
 176
 177        r = fastboot_nand_get_part_info(part_name, &part_info, response);
 178        if (r >= 0)
 179                size = part_info->size;
 180#endif
 181        if (r >= 0)
 182                fastboot_response("OKAY", response, "0x%016zx", size);
 183}
 184#endif
 185
 186/**
 187 * fastboot_getvar() - Writes variable indicated by cmd_parameter to response.
 188 *
 189 * @cmd_parameter: Pointer to command parameter
 190 * @response: Pointer to fastboot response buffer
 191 *
 192 * Look up cmd_parameter first as an environment variable of the form
 193 * fastboot.<cmd_parameter>, if that exists return use its value to set
 194 * response.
 195 *
 196 * Otherwise lookup the name of variable and execute the appropriate
 197 * function to return the requested value.
 198 */
 199void fastboot_getvar(char *cmd_parameter, char *response)
 200{
 201        if (!cmd_parameter) {
 202                fastboot_fail("missing var", response);
 203        } else {
 204#define FASTBOOT_ENV_PREFIX     "fastboot."
 205                int i;
 206                char *var_parameter = cmd_parameter;
 207                char envstr[FASTBOOT_RESPONSE_LEN];
 208                const char *s;
 209
 210                snprintf(envstr, sizeof(envstr) - 1,
 211                         FASTBOOT_ENV_PREFIX "%s", cmd_parameter);
 212                s = env_get(envstr);
 213                if (s) {
 214                        fastboot_response("OKAY", response, "%s", s);
 215                        return;
 216                }
 217
 218                strsep(&var_parameter, ":");
 219                for (i = 0; i < ARRAY_SIZE(getvar_dispatch); ++i) {
 220                        if (!strcmp(getvar_dispatch[i].variable,
 221                                    cmd_parameter)) {
 222                                getvar_dispatch[i].dispatch(var_parameter,
 223                                                            response);
 224                                return;
 225                        }
 226                }
 227                pr_warn("WARNING: unknown variable: %s\n", cmd_parameter);
 228                fastboot_fail("Variable not implemented", response);
 229        }
 230}
 231