2 * Copyright (C) 2010 Samsung Electrnoics
3 * Kyungmin Park <kyungmin.park@samsung.com>
10 #define SIGNATURE ((unsigned short) 0xAA55)
12 static int logical = 4;
13 static int extended_lba;
15 static inline void set_chs_value(struct mbr_partition *part, int part_num)
19 part->f_chs[0] = 0x01;
20 part->f_chs[1] = 0x01;
21 part->f_chs[2] = 0x00;
23 part->f_chs[0] = 0x03;
24 part->f_chs[1] = 0xd0;
25 part->f_chs[2] = 0xff;
27 part->l_chs[0] = 0x03;
28 part->l_chs[1] = 0xd0;
29 part->l_chs[2] = 0xff;
32 void set_mbr_table(unsigned int start_addr, int parts,
33 unsigned int *blocks, unsigned int *part_offset)
35 struct mmc *mmc = find_mmc_device(0);
37 unsigned int offset = start_addr;
39 unsigned int size = 0;
43 max = mmc->capacity / mmc->read_bl_len;
45 memset(&mbr_table, 0, sizeof(struct mbr));
47 mbr_table.signature = SIGNATURE;
49 if (blocks[parts - 1] == 0) {
51 for (i = 0; i < parts; i++)
53 blocks[parts - 1] = max - size;
57 for (i = 0; i < 3; i++) {
58 mbr_table.parts[i].partition_type = 0x83; /* Linux */
59 mbr_table.parts[i].lba = offset;
60 mbr_table.parts[i].nsectors = blocks[i];
61 part_offset[i] = offset;
64 set_chs_value(&mbr_table.parts[i], i);
68 mmc->block_dev.block_write(0, 0, 1, &mbr_table);
73 mbr_table.parts[i].partition_type = 0x05; /* Extended */
74 mbr_table.parts[i].lba = offset;
75 mbr_table.parts[i].nsectors = max - offset;
76 set_chs_value(&mbr_table.parts[i], i);
78 mmc->block_dev.block_write(0, 0, 1, &mbr_table);
80 for (; i < parts; i++) {
82 memset(&ebr_table, 0, sizeof(struct mbr));
84 ebr_table.signature = SIGNATURE;
86 for (j = 0; j < 2; j++) {
88 blocks[parts - 1] -= 0x10;
89 ebr_table.parts[j].partition_type = 0x83;
90 ebr_table.parts[j].lba = 0x10;
91 ebr_table.parts[j].nsectors = blocks[i];
92 set_chs_value(&ebr_table.parts[j], i);
95 ebr_table.parts[j].partition_type = 0x05;
96 ebr_table.parts[j].lba = 0x10 + blocks[i];
97 ebr_table.parts[j].nsectors = blocks[i + 1];
98 set_chs_value(&ebr_table.parts[j], i);
103 mmc->block_dev.block_write(0, offset, 1, &ebr_table);
105 offset += ebr_table.parts[0].lba;
106 part_offset[i] = offset;
107 offset += ebr_table.parts[0].nsectors;
111 static int get_ebr_table(struct mmc *mmc, struct mbr_partition *mp,
112 int ebr_next, unsigned int *part_offset, int parts)
115 struct mbr_partition *p;
124 ret = mmc->block_dev.block_read(0, lba, 1, buf);
126 printf("%s[%d] mmc_read_blocks %d\n", __func__, __LINE__, ret);
129 ebr = (struct mbr *) buf;
131 if (ebr->signature != SIGNATURE) {
132 printf("Signature error 0x%x\n", ebr->signature);
136 for (i = 0; i < 2; i++) {
137 p = (struct mbr_partition *) &ebr->parts[i];
142 if (p->partition_type == 0x83) {
143 part_offset[parts] = lba;
149 if (p->lba && p->partition_type == 0x5)
150 parts = get_ebr_table(mmc, p, 1, part_offset, parts);
155 int get_mbr_table(unsigned int *part_offset)
157 struct mmc *mmc = find_mmc_device(0);
158 struct mbr_partition *mp;
166 ret = mmc->block_dev.block_read(0, 0, 1, buf);
168 printf("%s[%d] mmc_read_blocks %d\n", __func__, __LINE__, ret);
172 mbr = (struct mbr *) buf;
174 if (mbr->signature != SIGNATURE)
175 printf("Signature error 0x%x\n", mbr->signature);
179 for (i = 0; i < 4; i++) {
180 mp = (struct mbr_partition *) &mbr->parts[i];
182 if (!mp->partition_type)
185 if (mp->partition_type == 0x83) {
186 part_offset[parts] = mp->lba;
190 if (mp->lba && mp->partition_type == 0x5) {
191 extended_lba = mp->lba;
192 parts = get_ebr_table(mmc, mp, 0, part_offset, parts);
199 static inline int get_cylinder(char chs1, char chs2, int *sector)
201 *sector = chs1 & 0x3f;
203 return ((chs1 & 0xc0) << 2) | chs2;
206 static void ebr_show(struct mmc *mmc, struct mbr_partition *mp, int ebr_next)
209 struct mbr_partition *p;
211 int ret, i, sector, cylinder;
218 printf(">>> Read sector from 0x%08x (LBA: 0x%08x + 0x%x)\n",
219 lba, mp->lba, (lba == mp->lba) ? 0 : lba - mp->lba);
221 ret = mmc->block_dev.block_read(0, lba, 1, buf);
223 printf("%s[%d] mmc_read_blocks %d\n", __func__, __LINE__, ret);
226 ebr = (struct mbr *) buf;
228 if (ebr->signature != SIGNATURE) {
229 printf("Signature error 0x%x\n", ebr->signature);
233 for (i = 0; i < 2; i++) {
234 p = (struct mbr_partition *) &ebr->parts[i];
239 printf("Extended Part %d\n", logical);
241 printf("Extended Part next\n");
243 printf("status 0x%02x\n", p->status);
244 printf("head 0x%02x,", p->f_chs[0]);
245 cylinder = get_cylinder(p->f_chs[1], p->f_chs[2], §or);
246 printf("\tsector 0x%02x,", sector);
247 printf("\tcylinder 0x%04x\n", cylinder);
248 printf("type 0x%02x\n", p->partition_type);
249 printf("head 0x%02x,", p->l_chs[0]);
250 cylinder = get_cylinder(p->l_chs[1], p->l_chs[2], §or);
251 printf("\tsector 0x%02x,", sector);
252 printf("\tcylinder 0x%04x\n", cylinder);
253 printf("lba 0x%08x (%d), ", p->lba, p->lba);
254 printf("nsectors 0x%08x (%d)\n", p->nsectors, p->nsectors);
257 if (p->lba && p->partition_type == 0x5)
261 static void mbr_show(void)
263 struct mmc *mmc = find_mmc_device(0);
264 struct mbr_partition *mp;
272 ret = mmc->block_dev.block_read(0, 0, 1, buf);
274 printf("%s[%d] mmc_read_blocks %d\n", __func__, __LINE__, ret);
278 mbr = (struct mbr *) buf;
280 if (mbr->signature != SIGNATURE)
281 printf("Signature error 0x%x\n", mbr->signature);
284 printf("MBR partition info\n");
285 for (i = 0; i < 4; i++) {
286 mp = (struct mbr_partition *) &mbr->parts[i];
288 if (!mp->partition_type)
291 printf("Part %d\n", i + 1);
292 printf("status 0x%02x\n", mp->status);
293 printf("head 0x%02x,", mp->f_chs[0]);
294 printf("\tsector 0x%02x,", mp->f_chs[1] & 0x3f);
295 cylinder = (mp->f_chs[1] & 0xc0) << 2;
296 cylinder |= mp->f_chs[2];
297 printf("\tcylinder 0x%04x\n", cylinder);
298 printf("type 0x%02x\n", mp->partition_type);
299 printf("head 0x%02x,", mp->l_chs[0]);
300 printf("\tsector 0x%02x,", mp->l_chs[1] & 0x3f);
301 cylinder = (mp->l_chs[1] & 0xc0) << 2;
302 cylinder |= mp->l_chs[2];
303 printf("\tcylinder 0x%04x\n", cylinder);
304 printf("lba 0x%08x (%d), ", mp->lba, mp->lba);
305 printf("nsectors 0x%08x (%d)\n", mp->nsectors, mp->nsectors);
307 if (mp->lba && mp->partition_type == 0x5) {
308 extended_lba = mp->lba;
309 ebr_show(mmc, mp, 0);
314 static int do_mbr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
318 if (strncmp(argv[1], "show", 2) == 0) {
331 mbr, CONFIG_SYS_MAXARGS, 1, do_mbr,
332 "Master Boot Record",