blob: 760f13d24018ab863880eed2ea5c042aaf10548b [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Ying Zhangbb0dc102013-08-16 15:16:11 +08002/*
3 * Copyright 2013 Freescale Semiconductor, Inc.
Ying Zhangbb0dc102013-08-16 15:16:11 +08004 */
5
6#include <common.h>
Simon Glass1eb69ae2019-11-14 12:57:39 -07007#include <cpu_func.h>
Simon Glassdb41d652019-12-28 10:45:07 -07008#include <hang.h>
Ying Zhangbb0dc102013-08-16 15:16:11 +08009#include <mmc.h>
10#include <malloc.h>
11
12/*
13 * The environment variables are written to just after the u-boot image
14 * on SDCard, so we must read the MBR to get the start address and code
15 * length of the u-boot image, then calculate the address of the env.
16 */
Pali Rohár0f58f032022-04-03 00:16:59 +020017#define ESDHC_BOOT_SIGNATURE_OFF 0x40
18#define ESDHC_BOOT_SIGNATURE 0x424f4f54
Ying Zhangbb0dc102013-08-16 15:16:11 +080019#define ESDHC_BOOT_IMAGE_SIZE 0x48
20#define ESDHC_BOOT_IMAGE_ADDR 0x50
21#define MBRDBR_BOOT_SIG_55 0x1fe
22#define MBRDBR_BOOT_SIG_AA 0x1ff
Ying Zhangbb0dc102013-08-16 15:16:11 +080023
Prabhakar Kushwaha1eaa7422014-04-08 19:13:22 +053024
25void mmc_spl_load_image(uint32_t offs, unsigned int size, void *vdst)
26{
27 uint blk_start, blk_cnt, err;
28
29 struct mmc *mmc = find_mmc_device(0);
30 if (!mmc) {
31 puts("spl: mmc device not found!!\n");
32 hang();
33 }
34
35 if (mmc_init(mmc)) {
36 puts("MMC init failed\n");
37 return;
38 }
39
40 blk_start = ALIGN(offs, mmc->read_bl_len) / mmc->read_bl_len;
41 blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len;
42
Stephen Warren7c4213f2015-12-07 11:38:48 -070043 err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt,
44 vdst);
Prabhakar Kushwaha1eaa7422014-04-08 19:13:22 +053045 if (err != blk_cnt) {
46 puts("spl: mmc read failed!!\n");
47 hang();
48 }
49}
50
Ying Zhangbb0dc102013-08-16 15:16:11 +080051/*
52 * The main entry for mmc booting. It's necessary that SDRAM is already
53 * configured and available since this code loads the main U-Boot image
54 * from mmc into SDRAM and starts it from there.
55 */
56
57void __noreturn mmc_boot(void)
58{
59 __attribute__((noreturn)) void (*uboot)(void);
60 uint blk_start, blk_cnt, err;
Prabhakar Kushwaha613ab322014-03-31 15:32:03 +053061#ifndef CONFIG_FSL_CORENET
Ying Zhangbb0dc102013-08-16 15:16:11 +080062 uchar *tmp_buf;
Prabhakar Kushwaha613ab322014-03-31 15:32:03 +053063 u32 blklen;
Pali Rohár0980cbb2022-04-04 18:33:11 +020064 u32 blk_off;
Ying Zhangbb0dc102013-08-16 15:16:11 +080065 uchar val;
Pali Rohár0f58f032022-04-03 00:16:59 +020066#ifndef CONFIG_SPL_FSL_PBL
67 u32 val32;
68#endif
Ying Zhangbb0dc102013-08-16 15:16:11 +080069 uint i, byte_num;
Pali Rohár0980cbb2022-04-04 18:33:11 +020070 u32 sector;
Prabhakar Kushwaha613ab322014-03-31 15:32:03 +053071#endif
Ying Zhangbb0dc102013-08-16 15:16:11 +080072 u32 offset, code_len;
73 struct mmc *mmc;
74
75 mmc = find_mmc_device(0);
76 if (!mmc) {
77 puts("spl: mmc device not found!!\n");
78 hang();
79 }
80
Pali Rohár57d527e2022-04-03 00:17:01 +020081 if (mmc_init(mmc)) {
82 puts("spl: mmc device init failed!\n");
83 hang();
84 }
85
Priyanka Jain4520a2f2013-11-28 10:12:16 +053086#ifdef CONFIG_FSL_CORENET
87 offset = CONFIG_SYS_MMC_U_BOOT_OFFS;
Priyanka Jain4520a2f2013-11-28 10:12:16 +053088#else
Ying Zhangbb0dc102013-08-16 15:16:11 +080089 blklen = mmc->read_bl_len;
Pali Rohár0980cbb2022-04-04 18:33:11 +020090 if (blklen < 512)
91 blklen = 512;
Ying Zhangbb0dc102013-08-16 15:16:11 +080092 tmp_buf = malloc(blklen);
93 if (!tmp_buf) {
94 puts("spl: malloc memory failed!!\n");
95 hang();
96 }
Pali Rohár0980cbb2022-04-04 18:33:11 +020097
98 sector = 0;
99again:
Ying Zhangbb0dc102013-08-16 15:16:11 +0800100 memset(tmp_buf, 0, blklen);
101
102 /*
103 * Read source addr from sd card
104 */
Pali Rohár0980cbb2022-04-04 18:33:11 +0200105 blk_start = (sector * 512) / mmc->read_bl_len;
106 blk_off = (sector * 512) % mmc->read_bl_len;
107 blk_cnt = DIV_ROUND_UP(512, mmc->read_bl_len);
108 err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt, tmp_buf);
Pali Rohárc1abf762022-05-11 20:28:28 +0200109 if (err != blk_cnt) {
Ying Zhangbb0dc102013-08-16 15:16:11 +0800110 puts("spl: mmc read failed!!\n");
Ying Zhangbb0dc102013-08-16 15:16:11 +0800111 hang();
112 }
113
Pali Rohár0f58f032022-04-03 00:16:59 +0200114#ifdef CONFIG_SPL_FSL_PBL
Pali Rohár0980cbb2022-04-04 18:33:11 +0200115 val = *(tmp_buf + blk_off + MBRDBR_BOOT_SIG_55);
Ying Zhangbb0dc102013-08-16 15:16:11 +0800116 if (0x55 != val) {
Pali Rohár0f58f032022-04-03 00:16:59 +0200117 puts("spl: mmc MBR/DBR signature is not valid!!\n");
Ying Zhangbb0dc102013-08-16 15:16:11 +0800118 hang();
119 }
Pali Rohár0980cbb2022-04-04 18:33:11 +0200120 val = *(tmp_buf + blk_off + MBRDBR_BOOT_SIG_AA);
Ying Zhangbb0dc102013-08-16 15:16:11 +0800121 if (0xAA != val) {
Pali Rohár0f58f032022-04-03 00:16:59 +0200122 puts("spl: mmc MBR/DBR signature is not valid!!\n");
Ying Zhangbb0dc102013-08-16 15:16:11 +0800123 hang();
124 }
Pali Rohár0f58f032022-04-03 00:16:59 +0200125#else
126 /*
127 * Booting from On-Chip ROM (eSDHC or eSPI), Document Number: AN3659, Rev. 2, 06/2012.
128 * Pre-PBL BootROMs (MPC8536E, MPC8569E, P2020, P1011, P1012, P1013, P1020, P1021, P1022)
129 * require custom BOOT signature on sector 0 and MBR/DBR signature is not required at all.
130 */
131 byte_num = 4;
132 val32 = 0;
133 for (i = 0; i < byte_num; i++) {
Pali Rohár0980cbb2022-04-04 18:33:11 +0200134 val = *(tmp_buf + blk_off + ESDHC_BOOT_SIGNATURE_OFF + i);
Pali Rohár0f58f032022-04-03 00:16:59 +0200135 val32 = (val32 << 8) + val;
136 }
137 if (val32 != ESDHC_BOOT_SIGNATURE) {
Pali Rohár0980cbb2022-04-04 18:33:11 +0200138 /* BOOT signature may be on the first 24 sectors (each being 512 bytes) */
139 if (++sector < 24)
140 goto again;
Pali Rohár0f58f032022-04-03 00:16:59 +0200141 puts("spl: mmc BOOT signature is not valid!!\n");
142 hang();
143 }
144#endif
Ying Zhangbb0dc102013-08-16 15:16:11 +0800145
146 byte_num = 4;
147 offset = 0;
148 for (i = 0; i < byte_num; i++) {
Pali Rohár0980cbb2022-04-04 18:33:11 +0200149 val = *(tmp_buf + blk_off + ESDHC_BOOT_IMAGE_ADDR + i);
Ying Zhangbb0dc102013-08-16 15:16:11 +0800150 offset = (offset << 8) + val;
151 }
152 offset += CONFIG_SYS_MMC_U_BOOT_OFFS;
Pali Rohára91998d2022-04-03 00:17:00 +0200153#endif
Ying Zhangbb0dc102013-08-16 15:16:11 +0800154 /*
155 * Load U-Boot image from mmc into RAM
156 */
Pali Rohára91998d2022-04-03 00:17:00 +0200157 code_len = CONFIG_SYS_MMC_U_BOOT_SIZE;
Ying Zhangbb0dc102013-08-16 15:16:11 +0800158 blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len;
159 blk_cnt = ALIGN(code_len, mmc->read_bl_len) / mmc->read_bl_len;
Stephen Warren7c4213f2015-12-07 11:38:48 -0700160 err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt,
Ying Zhangbb0dc102013-08-16 15:16:11 +0800161 (uchar *)CONFIG_SYS_MMC_U_BOOT_DST);
162 if (err != blk_cnt) {
163 puts("spl: mmc read failed!!\n");
Prabhakar Kushwaha613ab322014-03-31 15:32:03 +0530164#ifndef CONFIG_FSL_CORENET
Ying Zhangbb0dc102013-08-16 15:16:11 +0800165 free(tmp_buf);
Prabhakar Kushwaha613ab322014-03-31 15:32:03 +0530166#endif
Ying Zhangbb0dc102013-08-16 15:16:11 +0800167 hang();
168 }
169
170 /*
171 * Clean d-cache and invalidate i-cache, to
172 * make sure that no stale data is executed.
173 */
174 flush_cache(CONFIG_SYS_MMC_U_BOOT_DST, CONFIG_SYS_MMC_U_BOOT_SIZE);
175
176 /*
177 * Jump to U-Boot image
178 */
179 uboot = (void *)CONFIG_SYS_MMC_U_BOOT_START;
180 (*uboot)();
181}