blob: a5ff54c287956bb64ab2b7dcc3e84e54a1f08d41 [file] [log] [blame]
Peng Fan125d1932016-04-03 21:52:13 +08001/*
2 * (C) Copyright 2010-2016 Freescale Semiconductor, Inc.
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7/* #define DEBUG */
8
9#include <common.h>
10
11#include <command.h>
12#include <environment.h>
13#include <linux/stddef.h>
14#include <errno.h>
15#include <memalign.h>
16#include <sata.h>
17#include <search.h>
18
19#if defined(CONFIG_ENV_SIZE_REDUND) || defined(CONFIG_ENV_OFFSET_REDUND)
20#error ENV REDUND not supported
21#endif
22
23#if !defined(CONFIG_ENV_OFFSET) || !defined(CONFIG_ENV_SIZE)
24#error CONFIG_ENV_OFFSET or CONFIG_ENV_SIZE not defined
25#endif
26
27char *env_name_spec = "SATA";
28
29DECLARE_GLOBAL_DATA_PTR;
30
31__weak int sata_get_env_dev(void)
32{
33 return CONFIG_SYS_SATA_ENV_DEV;
34}
35
Peng Fan125d1932016-04-03 21:52:13 +080036#ifdef CONFIG_CMD_SAVEENV
37static inline int write_env(struct blk_desc *sata, unsigned long size,
38 unsigned long offset, void *buffer)
39{
40 uint blk_start, blk_cnt, n;
41
42 blk_start = ALIGN(offset, sata->blksz) / sata->blksz;
43 blk_cnt = ALIGN(size, sata->blksz) / sata->blksz;
44
45 n = blk_dwrite(sata, blk_start, blk_cnt, buffer);
46
47 return (n == blk_cnt) ? 0 : -1;
48}
49
Simon Glasse5bce242017-08-03 12:22:01 -060050static int env_sata_save(void)
Peng Fan125d1932016-04-03 21:52:13 +080051{
52 ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
53 struct blk_desc *sata = NULL;
54 int env_sata, ret;
55
56 if (sata_initialize())
57 return 1;
58
59 env_sata = sata_get_env_dev();
60
61 sata = sata_get_dev(env_sata);
62 if (sata == NULL) {
63 printf("Unknown SATA(%d) device for environment!\n",
64 env_sata);
65 return 1;
66 }
67
68 ret = env_export(env_new);
69 if (ret)
70 return 1;
71
72 printf("Writing to SATA(%d)...", env_sata);
73 if (write_env(sata, CONFIG_ENV_SIZE, CONFIG_ENV_OFFSET, &env_new)) {
74 puts("failed\n");
75 return 1;
76 }
77
78 puts("done\n");
79 return 0;
80}
81#endif /* CONFIG_CMD_SAVEENV */
82
83static inline int read_env(struct blk_desc *sata, unsigned long size,
84 unsigned long offset, void *buffer)
85{
86 uint blk_start, blk_cnt, n;
87
88 blk_start = ALIGN(offset, sata->blksz) / sata->blksz;
89 blk_cnt = ALIGN(size, sata->blksz) / sata->blksz;
90
91 n = blk_dread(sata, blk_start, blk_cnt, buffer);
92
93 return (n == blk_cnt) ? 0 : -1;
94}
95
Simon Glasse5bce242017-08-03 12:22:01 -060096static void env_sata_load(void)
Peng Fan125d1932016-04-03 21:52:13 +080097{
98 ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
99 struct blk_desc *sata = NULL;
100 int env_sata;
101
102 if (sata_initialize())
103 return;
104
105 env_sata = sata_get_env_dev();
106
107 sata = sata_get_dev(env_sata);
108 if (sata == NULL) {
109 printf("Unknown SATA(%d) device for environment!\n",
110 env_sata);
111 return;
112 }
113
114 if (read_env(sata, CONFIG_ENV_SIZE, CONFIG_ENV_OFFSET, buf))
115 return set_default_env(NULL);
116
117 env_import(buf, 1);
118}
Simon Glass4415f1d2017-08-03 12:21:58 -0600119
120U_BOOT_ENV_LOCATION(sata) = {
121 .location = ENVL_ESATA,
Simon Glasse5bce242017-08-03 12:22:01 -0600122 .load = env_sata_load,
123 .save = env_save_ptr(env_sata_save),
Simon Glass4415f1d2017-08-03 12:21:58 -0600124};