"Das U-Boot" Source Tree
at master 111 lines 2.5 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * (C) Copyright 2010 DENX Software Engineering 4 * Wolfgang Denk <wd@denx.de> 5 * 6 * (C) Copyright 2005-2009 Samsung Electronics 7 * Kyungmin Park <kyungmin.park@samsung.com> 8 */ 9 10#include <command.h> 11#include <env_internal.h> 12#include <asm/global_data.h> 13#include <linux/stddef.h> 14#include <malloc.h> 15#include <search.h> 16#include <errno.h> 17#include <onenand_uboot.h> 18 19#include <linux/compat.h> 20#include <linux/mtd/mtd.h> 21#include <linux/mtd/onenand.h> 22 23#define ONENAND_MAX_ENV_SIZE CONFIG_ENV_SIZE 24#define ONENAND_ENV_SIZE(mtd) (ONENAND_MAX_ENV_SIZE - ENV_HEADER_SIZE) 25 26DECLARE_GLOBAL_DATA_PTR; 27 28static int env_onenand_load(void) 29{ 30 struct mtd_info *mtd = &onenand_mtd; 31#ifdef CONFIG_ENV_ADDR_FLEX 32 struct onenand_chip *this = &onenand_chip; 33#endif 34 int rc; 35 size_t retlen; 36#ifdef ENV_IS_EMBEDDED 37 char *buf = (char *)&environment; 38#else 39 loff_t env_addr = CONFIG_ENV_ADDR; 40 char onenand_env[ONENAND_MAX_ENV_SIZE]; 41 char *buf = (char *)&onenand_env[0]; 42#endif /* ENV_IS_EMBEDDED */ 43 44#ifndef ENV_IS_EMBEDDED 45# ifdef CONFIG_ENV_ADDR_FLEX 46 if (FLEXONENAND(this)) 47 env_addr = CONFIG_ENV_ADDR_FLEX; 48# endif 49 /* Check OneNAND exist */ 50 if (mtd->writesize) 51 /* Ignore read fail */ 52 mtd_read(mtd, env_addr, ONENAND_MAX_ENV_SIZE, 53 &retlen, (u_char *)buf); 54 else 55 mtd->writesize = MAX_ONENAND_PAGESIZE; 56#endif /* !ENV_IS_EMBEDDED */ 57 58 rc = env_import(buf, 1, H_EXTERNAL); 59 if (!rc) 60 gd->env_valid = ENV_VALID; 61 62 return rc; 63} 64 65static int env_onenand_save(void) 66{ 67 env_t env_new; 68 int ret; 69 struct mtd_info *mtd = &onenand_mtd; 70#ifdef CONFIG_ENV_ADDR_FLEX 71 struct onenand_chip *this = &onenand_chip; 72#endif 73 loff_t env_addr = CONFIG_ENV_ADDR; 74 size_t retlen; 75 struct erase_info instr = {}; 76 77 ret = env_export(&env_new); 78 if (ret) 79 return ret; 80 81 instr.len = CONFIG_ENV_SIZE; 82#ifdef CONFIG_ENV_ADDR_FLEX 83 if (FLEXONENAND(this)) { 84 env_addr = CONFIG_ENV_ADDR_FLEX; 85 instr.len = CONFIG_ENV_SIZE_FLEX; 86 instr.len <<= onenand_mtd.eraseregions[0].numblocks == 1 ? 87 1 : 0; 88 } 89#endif 90 instr.addr = env_addr; 91 instr.mtd = mtd; 92 if (mtd_erase(mtd, &instr)) { 93 printf("OneNAND: erase failed at 0x%08llx\n", env_addr); 94 return 1; 95 } 96 97 if (mtd_write(mtd, env_addr, ONENAND_MAX_ENV_SIZE, &retlen, 98 (u_char *)&env_new)) { 99 printf("OneNAND: write failed at 0x%llx\n", instr.addr); 100 return 2; 101 } 102 103 return 0; 104} 105 106U_BOOT_ENV_LOCATION(onenand) = { 107 .location = ENVL_ONENAND, 108 ENV_NAME("OneNAND") 109 .load = env_onenand_load, 110 .save = env_save_ptr(env_onenand_save), 111};