payloads/libpayload: Add Wno-address-of-packed-member flag
[coreboot.git] / src / commonlib / storage / storage.c
blob41f84bc91ca7783678bce749435cde1e79bdee0b
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * MultiMediaCard (MMC), eMMC and Secure Digital (SD) common code which
4 * transitions the card from the standby state to the transfer state. The
5 * common code supports read operations, erase and write operations are in
6 * a separate modules. This code is controller independent.
7 */
9 #include <commonlib/storage.h>
10 #include "sd_mmc.h"
11 #include "storage.h"
12 #include <string.h>
14 #define DECIMAL_CAPACITY_MULTIPLIER 1000ULL
15 #define HEX_CAPACITY_MULTIPLIER 1024ULL
17 struct capacity {
18 const char *const units;
19 uint64_t bytes;
22 static void display_capacity(struct storage_media *media, int partition_number)
24 uint64_t capacity;
25 uint64_t decimal_divisor;
26 const char *decimal_units;
27 uint64_t hex_divisor;
28 const char *hex_units;
29 int index;
30 const char *name;
31 const char *separator;
32 const struct capacity decimal_list[] = {
33 {"TB", DECIMAL_CAPACITY_MULTIPLIER * DECIMAL_CAPACITY_MULTIPLIER
34 * DECIMAL_CAPACITY_MULTIPLIER
35 * DECIMAL_CAPACITY_MULTIPLIER},
36 {"GB", DECIMAL_CAPACITY_MULTIPLIER * DECIMAL_CAPACITY_MULTIPLIER
37 * DECIMAL_CAPACITY_MULTIPLIER},
38 {"MB", DECIMAL_CAPACITY_MULTIPLIER
39 * DECIMAL_CAPACITY_MULTIPLIER},
40 {"KB", DECIMAL_CAPACITY_MULTIPLIER},
41 {"B", 1}
43 const struct capacity hex_list[] = {
44 {"TiB", HEX_CAPACITY_MULTIPLIER * HEX_CAPACITY_MULTIPLIER
45 * HEX_CAPACITY_MULTIPLIER * HEX_CAPACITY_MULTIPLIER},
46 {"GiB", HEX_CAPACITY_MULTIPLIER * HEX_CAPACITY_MULTIPLIER
47 * HEX_CAPACITY_MULTIPLIER},
48 {"MiB", HEX_CAPACITY_MULTIPLIER * HEX_CAPACITY_MULTIPLIER},
49 {"KiB", HEX_CAPACITY_MULTIPLIER},
50 {"B", 1}
53 /* Get the partition name */
54 capacity = media->capacity[partition_number];
55 name = storage_partition_name(media, partition_number);
56 separator = "";
57 if (CONFIG(COMMONLIB_STORAGE_MMC) && !IS_SD(media))
58 separator = ": ";
60 /* Determine the decimal divisor for the capacity */
61 for (index = 0; index < ARRAY_SIZE(decimal_list) - 1; index++) {
62 if (capacity >= decimal_list[index].bytes)
63 break;
65 decimal_divisor = decimal_list[index].bytes;
66 decimal_units = decimal_list[index].units;
68 /* Determine the hex divisor for the capacity */
69 for (index = 0; index < ARRAY_SIZE(hex_list) - 1; index++) {
70 if (capacity >= hex_list[index].bytes)
71 break;
73 hex_divisor = hex_list[index].bytes;
74 hex_units = hex_list[index].units;
76 /* Display the capacity */
77 sdhc_debug("%3lld.%03lld %sytes (%3lld.%03lld %sytes)%s%s\n",
78 capacity / decimal_divisor,
79 (capacity / (decimal_divisor / 1000)) % 1000,
80 decimal_units,
81 capacity / hex_divisor,
82 ((capacity / (hex_divisor / 1024)) * 1000 / 1024) % 1000,
83 hex_units,
84 separator,
85 name);
88 void storage_display_setup(struct storage_media *media)
90 int partition_number;
92 /* Display the device info */
93 sd_mmc_debug("Man %06x Snr %u ",
94 media->cid[0] >> 24,
95 (((media->cid[2] & 0xffff) << 16) |
96 ((media->cid[3] >> 16) & 0xffff)));
97 sd_mmc_debug("Product %c%c%c%c", media->cid[0] & 0xff,
98 (media->cid[1] >> 24), (media->cid[1] >> 16) & 0xff,
99 (media->cid[1] >> 8) & 0xff);
100 if (!IS_SD(media)) /* eMMC product string is longer */
101 sd_mmc_debug("%c%c", media->cid[1] & 0xff,
102 (media->cid[2] >> 24) & 0xff);
103 sd_mmc_debug(" Revision %d.%d\n", (media->cid[2] >> 20) & 0xf,
104 (media->cid[2] >> 16) & 0xf);
106 /* Display the erase block size */
107 sdhc_debug("Erase block size: 0x%08x\n", media->erase_blocks
108 * media->write_bl_len);
110 /* Display the partition capacities */
111 if (CONFIG(SDHC_DEBUG)) {
112 for (partition_number = 0; partition_number
113 < ARRAY_SIZE(media->capacity); partition_number++) {
114 if (!media->capacity[partition_number])
115 continue;
116 display_capacity(media, partition_number);
121 int storage_startup(struct storage_media *media)
123 int err;
124 uint64_t capacity;
125 uint64_t cmult, csize;
126 struct mmc_command cmd;
127 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
129 /* Determine the storage capacity */
130 if (media->high_capacity) {
131 cmult = 8;
132 csize = sd_mmc_extract_uint32_bits(media->csd, 58, 22);
133 } else {
134 csize = sd_mmc_extract_uint32_bits(media->csd, 54, 12);
135 cmult = sd_mmc_extract_uint32_bits(media->csd, 78, 3);
137 capacity = (csize + 1) << (cmult + 2);
138 capacity *= media->read_bl_len;
139 media->capacity[0] = capacity;
141 /* Limit the block size to 512 bytes */
142 if (media->read_bl_len > 512)
143 media->read_bl_len = 512;
144 if (media->write_bl_len > 512)
145 media->write_bl_len = 512;
147 /* Get the erase size in blocks */
148 media->erase_blocks =
149 (sd_mmc_extract_uint32_bits(media->csd, 47, 3) + 1)
150 * (sd_mmc_extract_uint32_bits(media->csd, 42, 5) + 1);
152 /* Select the card, and put it into Transfer Mode */
153 cmd.cmdidx = MMC_CMD_SELECT_CARD;
154 cmd.resp_type = CARD_RSP_R1;
155 cmd.cmdarg = media->rca << 16;
156 cmd.flags = 0;
157 err = ctrlr->send_cmd(ctrlr, &cmd, NULL);
158 if (err)
159 return err;
161 /* Increase the bus frequency */
162 if (CONFIG(COMMONLIB_STORAGE_SD) && IS_SD(media))
163 err = sd_change_freq(media);
164 else if (CONFIG(COMMONLIB_STORAGE_MMC)) {
165 err = mmc_change_freq(media);
166 if (!err)
167 mmc_update_capacity(media);
169 if (err)
170 return err;
172 /* Restrict card's capabilities by what the controller can do */
173 media->caps &= ctrlr->caps;
175 /* Increase the bus width if possible */
176 if (CONFIG(COMMONLIB_STORAGE_SD) && IS_SD(media))
177 err = sd_set_bus_width(media);
178 else if (CONFIG(COMMONLIB_STORAGE_MMC))
179 err = mmc_set_bus_width(media);
180 if (err)
181 return err;
183 /* Display the card setup */
184 storage_display_setup(media);
185 return 0;
188 int storage_setup_media(struct storage_media *media, struct sd_mmc_ctrlr *ctrlr)
190 int err;
192 memset(media, 0, sizeof(*media));
193 media->ctrlr = ctrlr;
195 err = sd_mmc_enter_standby(media);
196 if (err)
197 return err;
198 return storage_startup(media);
201 static int storage_read(struct storage_media *media, void *dest, uint32_t start,
202 uint32_t block_count)
204 struct mmc_command cmd;
205 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
207 cmd.resp_type = CARD_RSP_R1;
208 cmd.flags = 0;
210 if (block_count > 1)
211 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
212 else
213 cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
215 if (media->high_capacity)
216 cmd.cmdarg = start;
217 else
218 cmd.cmdarg = start * media->read_bl_len;
220 struct mmc_data data;
221 data.dest = dest;
222 data.blocks = block_count;
223 data.blocksize = media->read_bl_len;
224 data.flags = DATA_FLAG_READ;
226 if (ctrlr->send_cmd(ctrlr, &cmd, &data))
227 return 0;
229 if ((block_count > 1) && !(ctrlr->caps
230 & DRVR_CAP_AUTO_CMD12)) {
231 cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
232 cmd.cmdarg = 0;
233 cmd.resp_type = CARD_RSP_R1b;
234 cmd.flags = CMD_FLAG_IGNORE_INHIBIT;
235 if (ctrlr->send_cmd(ctrlr, &cmd, NULL)) {
236 sd_mmc_error("Failed to send stop cmd\n");
237 return 0;
240 /* Waiting for the ready status */
241 sd_mmc_send_status(media, SD_MMC_IO_RETRIES);
244 return block_count;
247 /////////////////////////////////////////////////////////////////////////////
248 // BlockDevice utilities and callbacks
250 int storage_block_setup(struct storage_media *media, uint64_t start,
251 uint64_t count, int is_read)
253 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
254 int partition_number;
256 if (count == 0)
257 return 0;
259 uint32_t bl_len = is_read ? media->read_bl_len :
260 media->write_bl_len;
262 /* Validate the block range */
263 partition_number = media->partition_config & EXT_CSD_PART_ACCESS_MASK;
264 if (((start * bl_len) > media->capacity[partition_number])
265 || (((start + count) * bl_len) >
266 media->capacity[partition_number])) {
267 sd_mmc_error("Block range exceeds device capacity\n");
268 return 0;
272 * CMD16 only applies to single data rate mode, and block
273 * length for double data rate is always 512 bytes.
275 if ((ctrlr->timing == BUS_TIMING_UHS_DDR50) ||
276 (ctrlr->timing == BUS_TIMING_MMC_DDR52) ||
277 (ctrlr->timing == BUS_TIMING_MMC_HS400) ||
278 (ctrlr->timing == BUS_TIMING_MMC_HS400ES))
279 return 1;
280 if (sd_mmc_set_blocklen(ctrlr, bl_len))
281 return 0;
283 return 1;
286 uint64_t storage_block_read(struct storage_media *media, uint64_t start,
287 uint64_t count, void *buffer)
289 uint8_t *dest = (uint8_t *)buffer;
291 if (storage_block_setup(media, start, count, 1) == 0)
292 return 0;
294 uint64_t todo = count;
295 struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
296 do {
297 uint32_t cur = (uint32_t)MIN(todo, ctrlr->b_max);
298 if (storage_read(media, dest, start, cur) != cur)
299 return 0;
300 todo -= cur;
301 sd_mmc_trace("%s: Got %d blocks, more %d (total %d) to go.\n",
302 __func__, (int)cur, (int)todo, (int)count);
303 start += cur;
304 dest += cur * media->read_bl_len;
305 } while (todo > 0);
306 return count;
309 int storage_set_partition(struct storage_media *media,
310 unsigned int partition_number)
312 int err;
314 /* Select the partition */
315 err = -1;
316 if (CONFIG(COMMONLIB_STORAGE_SD) && IS_SD(media))
317 err = sd_set_partition(media, partition_number);
318 else if (CONFIG(COMMONLIB_STORAGE_MMC))
319 err = mmc_set_partition(media, partition_number);
320 if (err)
321 sd_mmc_error("Invalid partition number!\n");
322 return err;
325 const char *storage_partition_name(struct storage_media *media,
326 unsigned int partition_number)
328 const char *name;
330 /* Get the partition name */
331 name = NULL;
332 if (CONFIG(COMMONLIB_STORAGE_SD) && IS_SD(media))
333 name = sd_partition_name(media, partition_number);
334 else if (CONFIG(COMMONLIB_STORAGE_MMC))
335 name = mmc_partition_name(media, partition_number);
336 return name;
339 unsigned int storage_get_current_partition(struct storage_media *media)
341 return media->partition_config & EXT_CSD_PART_ACCESS_MASK;