1*c9d728ddSSimon Glass /* 2*c9d728ddSSimon Glass * Copyright (C) 2017 Google, Inc 3*c9d728ddSSimon Glass * Written by Simon Glass <sjg@chromium.org> 4*c9d728ddSSimon Glass * 5*c9d728ddSSimon Glass * SPDX-License-Identifier: GPL-2.0+ 6*c9d728ddSSimon Glass */ 7*c9d728ddSSimon Glass 8*c9d728ddSSimon Glass #include <common.h> 9*c9d728ddSSimon Glass #include <environment.h> 10*c9d728ddSSimon Glass 11*c9d728ddSSimon Glass DECLARE_GLOBAL_DATA_PTR; 12*c9d728ddSSimon Glass 13*c9d728ddSSimon Glass static struct env_driver *env_driver_lookup(enum env_location loc) 14*c9d728ddSSimon Glass { 15*c9d728ddSSimon Glass struct env_driver *drv; 16*c9d728ddSSimon Glass const int n_ents = ll_entry_count(struct env_driver, env_driver); 17*c9d728ddSSimon Glass struct env_driver *entry; 18*c9d728ddSSimon Glass 19*c9d728ddSSimon Glass drv = ll_entry_start(struct env_driver, env_driver); 20*c9d728ddSSimon Glass for (entry = drv; entry != drv + n_ents; entry++) { 21*c9d728ddSSimon Glass if (loc == entry->location) 22*c9d728ddSSimon Glass return entry; 23*c9d728ddSSimon Glass } 24*c9d728ddSSimon Glass 25*c9d728ddSSimon Glass /* Not found */ 26*c9d728ddSSimon Glass return NULL; 27*c9d728ddSSimon Glass } 28*c9d728ddSSimon Glass 29*c9d728ddSSimon Glass static enum env_location env_get_default_location(void) 30*c9d728ddSSimon Glass { 31*c9d728ddSSimon Glass if IS_ENABLED(CONFIG_ENV_IS_IN_DATAFLASH) 32*c9d728ddSSimon Glass return ENVL_DATAFLASH; 33*c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_IN_EEPROM) 34*c9d728ddSSimon Glass return ENVL_EEPROM; 35*c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_IN_FAT) 36*c9d728ddSSimon Glass return ENVL_FAT; 37*c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_IN_FLASH) 38*c9d728ddSSimon Glass return ENVL_FLASH; 39*c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_IN_MMC) 40*c9d728ddSSimon Glass return ENVL_MMC; 41*c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_IN_NAND) 42*c9d728ddSSimon Glass return ENVL_NAND; 43*c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_IN_NVRAM) 44*c9d728ddSSimon Glass return ENVL_NVRAM; 45*c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_IN_REMOTE) 46*c9d728ddSSimon Glass return ENVL_REMOTE; 47*c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH) 48*c9d728ddSSimon Glass return ENVL_SPI_FLASH; 49*c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_IN_UBI) 50*c9d728ddSSimon Glass return ENVL_UBI; 51*c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_NOWHERE) 52*c9d728ddSSimon Glass return ENVL_NOWHERE; 53*c9d728ddSSimon Glass else 54*c9d728ddSSimon Glass return ENVL_UNKNOWN; 55*c9d728ddSSimon Glass } 56*c9d728ddSSimon Glass 57*c9d728ddSSimon Glass static struct env_driver *env_driver_lookup_default(void) 58*c9d728ddSSimon Glass { 59*c9d728ddSSimon Glass enum env_location loc = env_get_default_location(); 60*c9d728ddSSimon Glass struct env_driver *drv; 61*c9d728ddSSimon Glass 62*c9d728ddSSimon Glass drv = env_driver_lookup(loc); 63*c9d728ddSSimon Glass if (!drv) { 64*c9d728ddSSimon Glass debug("%s: No environment driver for location %d\n", __func__, 65*c9d728ddSSimon Glass loc); 66*c9d728ddSSimon Glass return NULL; 67*c9d728ddSSimon Glass } 68*c9d728ddSSimon Glass 69*c9d728ddSSimon Glass return drv; 70*c9d728ddSSimon Glass } 71*c9d728ddSSimon Glass 72*c9d728ddSSimon Glass int env_get_char_new(int index) 73*c9d728ddSSimon Glass { 74*c9d728ddSSimon Glass struct env_driver *drv = env_driver_lookup_default(); 75*c9d728ddSSimon Glass int ret; 76*c9d728ddSSimon Glass 77*c9d728ddSSimon Glass if (!drv) 78*c9d728ddSSimon Glass return -ENODEV; 79*c9d728ddSSimon Glass if (!drv->get_char) 80*c9d728ddSSimon Glass return *(uchar *)(gd->env_addr + index); 81*c9d728ddSSimon Glass ret = drv->get_char(index); 82*c9d728ddSSimon Glass if (ret < 0) { 83*c9d728ddSSimon Glass debug("%s: Environment failed to load (err=%d)\n", 84*c9d728ddSSimon Glass __func__, ret); 85*c9d728ddSSimon Glass } 86*c9d728ddSSimon Glass 87*c9d728ddSSimon Glass return ret; 88*c9d728ddSSimon Glass } 89*c9d728ddSSimon Glass 90*c9d728ddSSimon Glass int env_load(void) 91*c9d728ddSSimon Glass { 92*c9d728ddSSimon Glass struct env_driver *drv = env_driver_lookup_default(); 93*c9d728ddSSimon Glass int ret = 0; 94*c9d728ddSSimon Glass 95*c9d728ddSSimon Glass if (!drv) 96*c9d728ddSSimon Glass return -ENODEV; 97*c9d728ddSSimon Glass if (!drv->load) 98*c9d728ddSSimon Glass return 0; 99*c9d728ddSSimon Glass drv->load(); /* TODO(sjg@chromium.org): Make this return an error */ 100*c9d728ddSSimon Glass if (ret) { 101*c9d728ddSSimon Glass debug("%s: Environment failed to load (err=%d)\n", __func__, 102*c9d728ddSSimon Glass ret); 103*c9d728ddSSimon Glass return ret; 104*c9d728ddSSimon Glass } 105*c9d728ddSSimon Glass 106*c9d728ddSSimon Glass return 0; 107*c9d728ddSSimon Glass } 108*c9d728ddSSimon Glass 109*c9d728ddSSimon Glass int env_save(void) 110*c9d728ddSSimon Glass { 111*c9d728ddSSimon Glass struct env_driver *drv = env_driver_lookup_default(); 112*c9d728ddSSimon Glass int ret; 113*c9d728ddSSimon Glass 114*c9d728ddSSimon Glass if (!drv) 115*c9d728ddSSimon Glass return -ENODEV; 116*c9d728ddSSimon Glass if (!drv->save) 117*c9d728ddSSimon Glass return -ENOSYS; 118*c9d728ddSSimon Glass ret = drv->save(); 119*c9d728ddSSimon Glass if (ret) { 120*c9d728ddSSimon Glass debug("%s: Environment failed to save (err=%d)\n", __func__, 121*c9d728ddSSimon Glass ret); 122*c9d728ddSSimon Glass return ret; 123*c9d728ddSSimon Glass } 124*c9d728ddSSimon Glass 125*c9d728ddSSimon Glass return 0; 126*c9d728ddSSimon Glass } 127*c9d728ddSSimon Glass 128*c9d728ddSSimon Glass int env_init_new(void) 129*c9d728ddSSimon Glass { 130*c9d728ddSSimon Glass struct env_driver *drv = env_driver_lookup_default(); 131*c9d728ddSSimon Glass int ret; 132*c9d728ddSSimon Glass 133*c9d728ddSSimon Glass if (!drv) 134*c9d728ddSSimon Glass return -ENODEV; 135*c9d728ddSSimon Glass if (!drv->init) 136*c9d728ddSSimon Glass return -ENOSYS; 137*c9d728ddSSimon Glass ret = drv->init(); 138*c9d728ddSSimon Glass if (ret) { 139*c9d728ddSSimon Glass debug("%s: Environment failed to init (err=%d)\n", __func__, 140*c9d728ddSSimon Glass ret); 141*c9d728ddSSimon Glass return ret; 142*c9d728ddSSimon Glass } 143*c9d728ddSSimon Glass 144*c9d728ddSSimon Glass return 0; 145*c9d728ddSSimon Glass } 146