diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Kconfig | 3 | ||||
-rw-r--r-- | common/cli_simple.c | 3 | ||||
-rw-r--r-- | common/cmd_boot.c | 8 | ||||
-rw-r--r-- | common/cmd_disk.c | 6 | ||||
-rw-r--r-- | common/cmd_ide.c | 26 | ||||
-rw-r--r-- | common/cmd_mmc.c | 24 | ||||
-rw-r--r-- | common/cmd_read.c | 2 | ||||
-rw-r--r-- | common/cmd_sata.c | 16 | ||||
-rw-r--r-- | common/cmd_scsi.c | 21 | ||||
-rw-r--r-- | common/cmd_usb.c | 4 | ||||
-rw-r--r-- | common/cmd_usb_mass_storage.c | 141 | ||||
-rw-r--r-- | common/env_flags.c | 2 | ||||
-rw-r--r-- | common/env_mmc.c | 24 | ||||
-rw-r--r-- | common/fb_mmc.c | 7 | ||||
-rw-r--r-- | common/fdt_support.c | 64 | ||||
-rw-r--r-- | common/hash.c | 48 | ||||
-rw-r--r-- | common/init/board_init.c | 115 | ||||
-rw-r--r-- | common/spl/spl.c | 26 | ||||
-rw-r--r-- | common/spl/spl_mmc.c | 9 | ||||
-rw-r--r-- | common/usb_storage.c | 18 |
20 files changed, 379 insertions, 188 deletions
diff --git a/common/Kconfig b/common/Kconfig index ccf5475bac6..9d446bf86b0 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -184,6 +184,9 @@ config CMD_XIMG help Extract a part of a multi-image. +config CMD_POWEROFF + bool + endmenu menu "Environment commands" diff --git a/common/cli_simple.c b/common/cli_simple.c index 9c3d073d583..bb96aaead60 100644 --- a/common/cli_simple.c +++ b/common/cli_simple.c @@ -276,7 +276,8 @@ void cli_simple_loop(void) flag = 0; /* assume no special flags for now */ if (len > 0) - strcpy(lastcommand, console_buffer); + strlcpy(lastcommand, console_buffer, + CONFIG_SYS_CBSIZE + 1); else if (len == 0) flag |= CMD_FLAG_REPEAT; #ifdef CONFIG_BOOT_RETRY_TIME diff --git a/common/cmd_boot.c b/common/cmd_boot.c index 8f2e0701b54..72f2cf362d4 100644 --- a/common/cmd_boot.c +++ b/common/cmd_boot.c @@ -61,3 +61,11 @@ U_BOOT_CMD( "Perform RESET of the CPU", "" ); + +#ifdef CONFIG_CMD_POWEROFF +U_BOOT_CMD( + poweroff, 1, 0, do_poweroff, + "Perform POWEROFF of the device", + "" +); +#endif diff --git a/common/cmd_disk.c b/common/cmd_disk.c index 8a1fda9f68a..3025225c764 100644 --- a/common/cmd_disk.c +++ b/common/cmd_disk.c @@ -56,7 +56,7 @@ int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc, ", Block Size: %ld\n", info.start, info.size, info.blksz); - if (dev_desc->block_read(dev, info.start, 1, (ulong *) addr) != 1) { + if (dev_desc->block_read(dev_desc, info.start, 1, (ulong *)addr) != 1) { printf("** Read error on %d:%d\n", dev, part); bootstage_error(BOOTSTAGE_ID_IDE_PART_READ); return 1; @@ -100,8 +100,8 @@ int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc, cnt /= info.blksz; cnt -= 1; - if (dev_desc->block_read(dev, info.start + 1, cnt, - (ulong *)(addr + info.blksz)) != cnt) { + if (dev_desc->block_read(dev_desc, info.start + 1, cnt, + (ulong *)(addr + info.blksz)) != cnt) { printf("** Read error on %d:%d\n", dev, part); bootstage_error(BOOTSTAGE_ID_IDE_READ); return 1; diff --git a/common/cmd_ide.c b/common/cmd_ide.c index ecd3e9d64f0..f19a7ce42a7 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -79,8 +79,8 @@ static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len #ifdef CONFIG_ATAPI static void atapi_inquiry(block_dev_desc_t *dev_desc); -static ulong atapi_read(int device, lbaint_t blknr, lbaint_t blkcnt, - void *buffer); +static ulong atapi_read(block_dev_desc_t *block_dev, lbaint_t blknr, + lbaint_t blkcnt, void *buffer); #endif @@ -187,6 +187,7 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) if (strcmp(argv[1], "read") == 0) { ulong addr = simple_strtoul(argv[2], NULL, 16); ulong cnt = simple_strtoul(argv[4], NULL, 16); + block_dev_desc_t *dev_desc; ulong n; #ifdef CONFIG_SYS_64BIT_LBA @@ -201,9 +202,9 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) curr_device, blk, cnt); #endif - n = ide_dev_desc[curr_device].block_read(curr_device, - blk, cnt, - (ulong *)addr); + dev_desc = &ide_dev_desc[curr_device]; + n = dev_desc->block_read(dev_desc, blk, cnt, + (ulong *)addr); /* flush cache after read */ flush_cache(addr, cnt * ide_dev_desc[curr_device].blksz); @@ -230,7 +231,8 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) printf("\nIDE write: device %d block # %ld, count %ld ... ", curr_device, blk, cnt); #endif - n = ide_write(curr_device, blk, cnt, (ulong *) addr); + n = ide_write(&ide_dev_desc[curr_device], blk, cnt, + (ulong *)addr); printf("%ld blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR"); @@ -711,8 +713,10 @@ static void ide_ident(block_dev_desc_t *dev_desc) /* ------------------------------------------------------------------------- */ -ulong ide_read(int device, lbaint_t blknr, lbaint_t blkcnt, void *buffer) +ulong ide_read(block_dev_desc_t *block_dev, lbaint_t blknr, lbaint_t blkcnt, + void *buffer) { + int device = block_dev->dev; ulong n = 0; unsigned char c; unsigned char pwrsave = 0; /* power save */ @@ -835,8 +839,10 @@ IDE_READ_E: /* ------------------------------------------------------------------------- */ -ulong ide_write(int device, lbaint_t blknr, lbaint_t blkcnt, const void *buffer) +ulong ide_write(block_dev_desc_t *block_dev, lbaint_t blknr, lbaint_t blkcnt, + const void *buffer) { + int device = block_dev->dev; ulong n = 0; unsigned char c; @@ -1388,8 +1394,10 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc) #define ATAPI_READ_BLOCK_SIZE 2048 /* assuming CD part */ #define ATAPI_READ_MAX_BLOCK (ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE) -ulong atapi_read(int device, lbaint_t blknr, lbaint_t blkcnt, void *buffer) +ulong atapi_read(block_dev_desc_t *block_dev, lbaint_t blknr, lbaint_t blkcnt, + void *buffer) { + int device = block_dev->dev; ulong n = 0; unsigned char ccb[12]; /* Command descriptor block */ ulong cnt; diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index a6b7313e4a4..1c7156f19c5 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -312,20 +312,14 @@ static int do_mmcrpmb(cmd_tbl_t *cmdtp, int flag, return CMD_RET_FAILURE; } /* Switch to the RPMB partition */ - original_part = mmc->part_num; - if (mmc->part_num != MMC_PART_RPMB) { - if (mmc_switch_part(curr_device, MMC_PART_RPMB) != 0) - return CMD_RET_FAILURE; - mmc->part_num = MMC_PART_RPMB; - } + original_part = mmc->block_dev.part_num; + if (mmc_select_hwpart(curr_device, MMC_PART_RPMB) != 0) + return CMD_RET_FAILURE; ret = cp->cmd(cmdtp, flag, argc, argv); /* Return to original partition */ - if (mmc->part_num != original_part) { - if (mmc_switch_part(curr_device, original_part) != 0) - return CMD_RET_FAILURE; - mmc->part_num = original_part; - } + if (mmc_select_hwpart(curr_device, original_part) != 0) + return CMD_RET_FAILURE; return ret; } #endif @@ -351,7 +345,7 @@ static int do_mmc_read(cmd_tbl_t *cmdtp, int flag, printf("\nMMC read: dev # %d, block # %d, count %d ... ", curr_device, blk, cnt); - n = mmc->block_dev.block_read(curr_device, blk, cnt, addr); + n = mmc->block_dev.block_read(&mmc->block_dev, blk, cnt, addr); /* flush cache after read */ flush_cache((ulong)addr, cnt * 512); /* FIXME */ printf("%d blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR"); @@ -383,7 +377,7 @@ static int do_mmc_write(cmd_tbl_t *cmdtp, int flag, printf("Error: card is write protected!\n"); return CMD_RET_FAILURE; } - n = mmc->block_dev.block_write(curr_device, blk, cnt, addr); + n = mmc->block_dev.block_write(&mmc->block_dev, blk, cnt, addr); printf("%d blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR"); return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE; @@ -411,7 +405,7 @@ static int do_mmc_erase(cmd_tbl_t *cmdtp, int flag, printf("Error: card is write protected!\n"); return CMD_RET_FAILURE; } - n = mmc->block_dev.block_erase(curr_device, blk, cnt); + n = mmc->block_dev.block_erase(&mmc->block_dev, blk, cnt); printf("%d blocks erased: %s\n", n, (n == cnt) ? "OK" : "ERROR"); return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE; @@ -483,7 +477,7 @@ static int do_mmc_dev(cmd_tbl_t *cmdtp, int flag, printf("mmc%d is current device\n", curr_device); else printf("mmc%d(part %d) is current device\n", - curr_device, mmc->part_num); + curr_device, mmc->block_dev.hwpart); return CMD_RET_SUCCESS; } diff --git a/common/cmd_read.c b/common/cmd_read.c index f0fc9bfe17a..87102887817 100644 --- a/common/cmd_read.c +++ b/common/cmd_read.c @@ -66,7 +66,7 @@ int do_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; } - if (dev_desc->block_read(dev, offset + blk, cnt, addr) < 0) { + if (dev_desc->block_read(dev_desc, offset + blk, cnt, addr) < 0) { printf("Error reading blocks\n"); return 1; } diff --git a/common/cmd_sata.c b/common/cmd_sata.c index 51f67033ae3..76baceae8c9 100644 --- a/common/cmd_sata.c +++ b/common/cmd_sata.c @@ -18,6 +18,18 @@ static int sata_curr_device = -1; block_dev_desc_t sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE]; +static unsigned long sata_bread(block_dev_desc_t *block_dev, lbaint_t start, + lbaint_t blkcnt, void *dst) +{ + return sata_read(block_dev->dev, start, blkcnt, dst); +} + +static unsigned long sata_bwrite(block_dev_desc_t *block_dev, lbaint_t start, + lbaint_t blkcnt, const void *buffer) +{ + return sata_write(block_dev->dev, start, blkcnt, buffer); +} + int __sata_initialize(void) { int rc; @@ -32,8 +44,8 @@ int __sata_initialize(void) sata_dev_desc[i].lba = 0; sata_dev_desc[i].blksz = 512; sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz); - sata_dev_desc[i].block_read = sata_read; - sata_dev_desc[i].block_write = sata_write; + sata_dev_desc[i].block_read = sata_bread; + sata_dev_desc[i].block_write = sata_bwrite; rc = init_sata(i); if (!rc) { diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index 86954089fe7..bc7d1b6c530 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -66,9 +66,9 @@ void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len); static int scsi_read_capacity(ccb *pccb, lbaint_t *capacity, unsigned long *blksz); -static ulong scsi_read(int device, lbaint_t blknr, lbaint_t blkcnt, - void *buffer); -static ulong scsi_write(int device, lbaint_t blknr, +static ulong scsi_read(block_dev_desc_t *block_dev, lbaint_t blknr, + lbaint_t blkcnt, void *buffer); +static ulong scsi_write(block_dev_desc_t *block_dev, lbaint_t blknr, lbaint_t blkcnt, const void *buffer); @@ -346,7 +346,8 @@ int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) ulong n; printf ("\nSCSI read: device %d block # %ld, count %ld ... ", scsi_curr_dev, blk, cnt); - n = scsi_read(scsi_curr_dev, blk, cnt, (ulong *)addr); + n = scsi_read(&scsi_dev_desc[scsi_curr_dev], + blk, cnt, (ulong *)addr); printf ("%ld blocks read: %s\n",n,(n==cnt) ? "OK" : "ERROR"); return 0; } else if (strcmp(argv[1], "write") == 0) { @@ -357,8 +358,8 @@ int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("\nSCSI write: device %d block # %ld, " "count %ld ... ", scsi_curr_dev, blk, cnt); - n = scsi_write(scsi_curr_dev, blk, cnt, - (ulong *)addr); + n = scsi_write(&scsi_dev_desc[scsi_curr_dev], + blk, cnt, (ulong *)addr); printf("%ld blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR"); return 0; @@ -375,9 +376,10 @@ int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #define SCSI_MAX_READ_BLK 0xFFFF #define SCSI_LBA48_READ 0xFFFFFFF -static ulong scsi_read(int device, lbaint_t blknr, lbaint_t blkcnt, - void *buffer) +static ulong scsi_read(block_dev_desc_t *block_dev, lbaint_t blknr, + lbaint_t blkcnt, void *buffer) { + int device = block_dev->dev; lbaint_t start, blks; uintptr_t buf_addr; unsigned short smallblks = 0; @@ -441,9 +443,10 @@ static ulong scsi_read(int device, lbaint_t blknr, lbaint_t blkcnt, /* Almost the maximum amount of the scsi_ext command.. */ #define SCSI_MAX_WRITE_BLK 0xFFFF -static ulong scsi_write(int device, lbaint_t blknr, +static ulong scsi_write(block_dev_desc_t *block_dev, lbaint_t blknr, lbaint_t blkcnt, const void *buffer) { + int device = block_dev->dev; lbaint_t start, blks; uintptr_t buf_addr; unsigned short smallblks; diff --git a/common/cmd_usb.c b/common/cmd_usb.c index a540b422db3..c7b642c40af 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -759,7 +759,7 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("\nUSB read: device %d block # %ld, count %ld" " ... ", usb_stor_curr_dev, blk, cnt); stor_dev = usb_stor_get_dev(usb_stor_curr_dev); - n = stor_dev->block_read(usb_stor_curr_dev, blk, cnt, + n = stor_dev->block_read(stor_dev, blk, cnt, (ulong *)addr); printf("%ld blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR"); @@ -781,7 +781,7 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("\nUSB write: device %d block # %ld, count %ld" " ... ", usb_stor_curr_dev, blk, cnt); stor_dev = usb_stor_get_dev(usb_stor_curr_dev); - n = stor_dev->block_write(usb_stor_curr_dev, blk, cnt, + n = stor_dev->block_write(stor_dev, blk, cnt, (ulong *)addr); printf("%ld blocks write: %s\n", n, (n == cnt) ? "OK" : "ERROR"); diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c index 04073891129..041559172d9 100644 --- a/common/cmd_usb_mass_storage.c +++ b/common/cmd_usb_mass_storage.c @@ -2,6 +2,8 @@ * Copyright (C) 2011 Samsung Electronics * Lukasz Majewski <l.majewski@samsung.com> * + * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. + * * SPDX-License-Identifier: GPL-2.0+ */ @@ -17,50 +19,107 @@ static int ums_read_sector(struct ums *ums_dev, ulong start, lbaint_t blkcnt, void *buf) { - block_dev_desc_t *block_dev = ums_dev->block_dev; + block_dev_desc_t *block_dev = &ums_dev->block_dev; lbaint_t blkstart = start + ums_dev->start_sector; - int dev_num = block_dev->dev; - return block_dev->block_read(dev_num, blkstart, blkcnt, buf); + return block_dev->block_read(block_dev, blkstart, blkcnt, buf); } static int ums_write_sector(struct ums *ums_dev, ulong start, lbaint_t blkcnt, const void *buf) { - block_dev_desc_t *block_dev = ums_dev->block_dev; + block_dev_desc_t *block_dev = &ums_dev->block_dev; lbaint_t blkstart = start + ums_dev->start_sector; - int dev_num = block_dev->dev; - return block_dev->block_write(dev_num, blkstart, blkcnt, buf); + return block_dev->block_write(block_dev, blkstart, blkcnt, buf); +} + +static struct ums *ums; +static int ums_count; + +static void ums_fini(void) +{ + int i; + + for (i = 0; i < ums_count; i++) + free((void *)ums[i].name); + free(ums); + ums = 0; + ums_count = 0; } -static struct ums ums_dev = { - .read_sector = ums_read_sector, - .write_sector = ums_write_sector, - .name = "UMS disk", -}; +#define UMS_NAME_LEN 16 -struct ums *ums_init(const char *devtype, const char *devnum) +static int ums_init(const char *devtype, const char *devnums) { + char *s, *t, *devnum, *name; block_dev_desc_t *block_dev; int ret; + struct ums *ums_new; - ret = get_device(devtype, devnum, &block_dev); - if (ret < 0) - return NULL; + s = strdup(devnums); + if (!s) + return -1; + + t = s; + ums_count = 0; + + for (;;) { + devnum = strsep(&t, ","); + if (!devnum) + break; + + ret = get_device(devtype, devnum, &block_dev); + if (ret < 0) + goto cleanup; + + /* f_mass_storage.c assumes SECTOR_SIZE sectors */ + if (block_dev->blksz != SECTOR_SIZE) { + ret = -1; + goto cleanup; + } - /* f_mass_storage.c assumes SECTOR_SIZE sectors */ - if (block_dev->blksz != SECTOR_SIZE) - return NULL; + ums_new = realloc(ums, (ums_count + 1) * sizeof(*ums)); + if (!ums_new) { + ret = -1; + goto cleanup; + } + ums = ums_new; + + ums[ums_count].read_sector = ums_read_sector; + ums[ums_count].write_sector = ums_write_sector; + ums[ums_count].start_sector = 0; + ums[ums_count].num_sectors = block_dev->lba; + name = malloc(UMS_NAME_LEN); + if (!name) { + ret = -1; + goto cleanup; + } + snprintf(name, UMS_NAME_LEN, "UMS disk %d", ums_count); + ums[ums_count].name = name; + ums[ums_count].block_dev = *block_dev; + + printf("UMS: LUN %d, dev %d, hwpart %d, sector %#x, count %#x\n", + ums_count, ums[ums_count].block_dev.dev, + ums[ums_count].block_dev.hwpart, + ums[ums_count].start_sector, + ums[ums_count].num_sectors); + + ums_count++; + } + + if (!ums_count) + ret = -1; + else + ret = 0; - ums_dev.block_dev = block_dev; - ums_dev.start_sector = 0; - ums_dev.num_sectors = block_dev->lba; +cleanup: + free(s); - printf("UMS: disk start sector: %#x, count: %#x\n", - ums_dev.start_sector, ums_dev.num_sectors); + if (ret < 0) + ums_fini(); - return &ums_dev; + return ret; } int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, @@ -69,7 +128,6 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, const char *usb_controller; const char *devtype; const char *devnum; - struct ums *ums; unsigned int controller_index; int rc; int cable_ready_timeout __maybe_unused; @@ -86,27 +144,30 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, devnum = argv[2]; } - ums = ums_init(devtype, devnum); - if (!ums) + rc = ums_init(devtype, devnum); + if (rc < 0) return CMD_RET_FAILURE; controller_index = (unsigned int)(simple_strtoul( usb_controller, NULL, 0)); if (board_usb_init(controller_index, USB_INIT_DEVICE)) { error("Couldn't init USB controller."); - return CMD_RET_FAILURE; + rc = CMD_RET_FAILURE; + goto cleanup_ums_init; } - rc = fsg_init(ums); + rc = fsg_init(ums, ums_count); if (rc) { error("fsg_init failed"); - return CMD_RET_FAILURE; + rc = CMD_RET_FAILURE; + goto cleanup_board; } rc = g_dnl_register("usb_dnl_ums"); if (rc) { error("g_dnl_register failed"); - return CMD_RET_FAILURE; + rc = CMD_RET_FAILURE; + goto cleanup_board; } /* Timeout unit: seconds */ @@ -122,12 +183,14 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, while (!g_dnl_board_usb_cable_connected()) { if (ctrlc()) { puts("\rCTRL+C - Operation aborted.\n"); - goto exit; + rc = CMD_RET_SUCCESS; + goto cleanup_register; } if (!cable_ready_timeout) { puts("\rUSB cable not detected.\n" \ "Command exit.\n"); - goto exit; + rc = CMD_RET_SUCCESS; + goto cleanup_register; } printf("\rAuto exit in: %.2d s.", cable_ready_timeout); @@ -150,13 +213,19 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, if (rc == -EPIPE) printf("\rCTRL+C - Operation aborted\n"); - goto exit; + rc = CMD_RET_SUCCESS; + goto cleanup_register; } } -exit: + +cleanup_register: g_dnl_unregister(); +cleanup_board: board_usb_cleanup(controller_index, USB_INIT_DEVICE); - return CMD_RET_SUCCESS; +cleanup_ums_init: + ums_fini(); + + return rc; } U_BOOT_CMD(ums, 4, 1, do_usb_mass_storage, diff --git a/common/env_flags.c b/common/env_flags.c index 771935508cb..9c3aed15278 100644 --- a/common/env_flags.c +++ b/common/env_flags.c @@ -152,7 +152,7 @@ enum env_flags_varaccess env_flags_parse_varaccess_from_binflags(int binflags) { int i; - for (i = 0; i < sizeof(env_flags_varaccess_mask); i++) + for (i = 0; i < ARRAY_SIZE(env_flags_varaccess_mask); i++) if (env_flags_varaccess_mask[i] == (binflags & ENV_FLAGS_VARACCESS_BIN_MASK)) return (enum env_flags_varaccess)i; diff --git a/common/env_mmc.c b/common/env_mmc.c index 96398224cc8..15aa43d5e16 100644 --- a/common/env_mmc.c +++ b/common/env_mmc.c @@ -69,6 +69,8 @@ __weak uint mmc_get_env_part(struct mmc *mmc) return CONFIG_SYS_MMC_ENV_PART; } +static unsigned char env_mmc_orig_hwpart; + static int mmc_set_env_part(struct mmc *mmc) { uint part = mmc_get_env_part(mmc); @@ -79,11 +81,10 @@ static int mmc_set_env_part(struct mmc *mmc) dev = 0; #endif - if (part != mmc->part_num) { - ret = mmc_switch_part(dev, part); - if (ret) - puts("MMC partition switch failed\n"); - } + env_mmc_orig_hwpart = mmc->block_dev.hwpart; + ret = mmc_select_hwpart(dev, part); + if (ret) + puts("MMC partition switch failed\n"); return ret; } @@ -113,8 +114,7 @@ static void fini_mmc_for_env(struct mmc *mmc) #ifdef CONFIG_SPL_BUILD dev = 0; #endif - if (mmc_get_env_part(mmc) != mmc->part_num) - mmc_switch_part(dev, mmc->part_num); + mmc_select_hwpart(dev, env_mmc_orig_hwpart); #endif } @@ -127,7 +127,7 @@ static inline int write_env(struct mmc *mmc, unsigned long size, blk_start = ALIGN(offset, mmc->write_bl_len) / mmc->write_bl_len; blk_cnt = ALIGN(size, mmc->write_bl_len) / mmc->write_bl_len; - n = mmc->block_dev.block_write(CONFIG_SYS_MMC_ENV_DEV, blk_start, + n = mmc->block_dev.block_write(&mmc->block_dev, blk_start, blk_cnt, (u_char *)buffer); return (n == blk_cnt) ? 0 : -1; @@ -192,16 +192,12 @@ static inline int read_env(struct mmc *mmc, unsigned long size, unsigned long offset, const void *buffer) { uint blk_start, blk_cnt, n; - int dev = CONFIG_SYS_MMC_ENV_DEV; - -#ifdef CONFIG_SPL_BUILD - dev = 0; -#endif blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len; blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len; - n = mmc->block_dev.block_read(dev, blk_start, blk_cnt, (uchar *)buffer); + n = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt, + (uchar *)buffer); return (n == blk_cnt) ? 0 : -1; } diff --git a/common/fb_mmc.c b/common/fb_mmc.c index b480e76554b..6e742dac56f 100644 --- a/common/fb_mmc.c +++ b/common/fb_mmc.c @@ -58,7 +58,7 @@ static int fb_mmc_sparse_write(struct sparse_storage *storage, block_dev_desc_t *dev_desc = sparse->dev_desc; int ret; - ret = dev_desc->block_write(dev_desc->dev, offset, size, data); + ret = dev_desc->block_write(dev_desc, offset, size, data); if (!ret) return -EIO; @@ -84,8 +84,7 @@ static void write_raw_image(block_dev_desc_t *dev_desc, disk_partition_t *info, puts("Flashing Raw Image\n"); - blks = dev_desc->block_write(dev_desc->dev, info->start, blkcnt, - buffer); + blks = dev_desc->block_write(dev_desc, info->start, blkcnt, buffer); if (blks != blkcnt) { error("failed writing to device %d\n", dev_desc->dev); fastboot_fail(response_str, "failed writing to device"); @@ -206,7 +205,7 @@ void fb_mmc_erase(const char *cmd, char *response) printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n", blks_start, blks_start + blks_size); - blks = dev_desc->block_erase(dev_desc->dev, blks_start, blks_size); + blks = dev_desc->block_erase(dev_desc, blks_start, blks_size); if (blks != blks_size) { error("failed erasing from device %d", dev_desc->dev); fastboot_fail(response_str, "failed erasing from device"); diff --git a/common/fdt_support.c b/common/fdt_support.c index a539389a9e8..09f923716ca 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -482,47 +482,49 @@ int fdt_fixup_memory(void *blob, u64 start, u64 size) void fdt_fixup_ethernet(void *fdt) { int node, i, j; - char enet[16], *tmp, *end; + char *tmp, *end; char mac[16]; const char *path; unsigned char mac_addr[6]; + int offset; node = fdt_path_offset(fdt, "/aliases"); if (node < 0) return; - if (!getenv("ethaddr")) { - if (getenv("usbethaddr")) { - strcpy(mac, "usbethaddr"); - } else { - debug("No ethernet MAC Address defined\n"); - return; - } - } else { - strcpy(mac, "ethaddr"); - } - - i = 0; - while ((tmp = getenv(mac)) != NULL) { - sprintf(enet, "ethernet%d", i); - path = fdt_getprop(fdt, node, enet, NULL); - if (!path) { - debug("No alias for %s\n", enet); - sprintf(mac, "eth%daddr", ++i); - continue; - } + for (offset = fdt_first_property_offset(fdt, node); + offset > 0; + offset = fdt_next_property_offset(fdt, offset)) { + const char *name; + int len = strlen("ethernet"); + + path = fdt_getprop_by_offset(fdt, offset, &name, NULL); + if (!strncmp(name, "ethernet", len)) { + i = trailing_strtol(name); + if (i != -1) { + if (i == 0) + strcpy(mac, "ethaddr"); + else + sprintf(mac, "eth%daddr", i); + } else { + continue; + } + tmp = getenv(mac); + if (!tmp) + continue; + + for (j = 0; j < 6; j++) { + mac_addr[j] = tmp ? + simple_strtoul(tmp, &end, 16) : 0; + if (tmp) + tmp = (*end) ? end + 1 : end; + } - for (j = 0; j < 6; j++) { - mac_addr[j] = tmp ? simple_strtoul(tmp, &end, 16) : 0; - if (tmp) - tmp = (*end) ? end+1 : end; + do_fixup_by_path(fdt, path, "mac-address", + &mac_addr, 6, 0); + do_fixup_by_path(fdt, path, "local-mac-address", + &mac_addr, 6, 1); } - - do_fixup_by_path(fdt, path, "mac-address", &mac_addr, 6, 0); - do_fixup_by_path(fdt, path, "local-mac-address", - &mac_addr, 6, 1); - - sprintf(mac, "eth%daddr", ++i); } } diff --git a/common/hash.c b/common/hash.c index a1b048204d3..41de4df5368 100644 --- a/common/hash.c +++ b/common/hash.c @@ -247,6 +247,29 @@ int hash_parse_string(const char *algo_name, const char *str, uint8_t *result) return 0; } +int hash_block(const char *algo_name, const void *data, unsigned int len, + uint8_t *output, int *output_size) +{ + struct hash_algo *algo; + int ret; + + ret = hash_lookup_algo(algo_name, &algo); + if (ret) + return ret; + + if (output_size && *output_size < algo->digest_size) { + debug("Output buffer size %d too small (need %d bytes)", + *output_size, algo->digest_size); + return -ENOSPC; + } + if (output_size) + *output_size = algo->digest_size; + algo->hash_func_ws(data, len, output, algo->chunk_size); + + return 0; +} + +#if defined(CONFIG_CMD_HASH) || defined(CONFIG_CMD_SHA1SUM) || defined(CONFIG_CMD_CRC32) /** * store_result: Store the resulting sum to an address or variable * @@ -359,7 +382,7 @@ static int parse_verify_sum(struct hash_algo *algo, char *verify_str, return 0; } -void hash_show(struct hash_algo *algo, ulong addr, ulong len, uint8_t *output) +static void hash_show(struct hash_algo *algo, ulong addr, ulong len, uint8_t *output) { int i; @@ -368,28 +391,6 @@ void hash_show(struct hash_algo *algo, ulong addr, ulong len, uint8_t *output) printf("%02x", output[i]); } -int hash_block(const char *algo_name, const void *data, unsigned int len, - uint8_t *output, int *output_size) -{ - struct hash_algo *algo; - int ret; - - ret = hash_lookup_algo(algo_name, &algo); - if (ret) - return ret; - - if (output_size && *output_size < algo->digest_size) { - debug("Output buffer size %d too small (need %d bytes)", - *output_size, algo->digest_size); - return -ENOSPC; - } - if (output_size) - *output_size = algo->digest_size; - algo->hash_func_ws(data, len, output, algo->chunk_size); - - return 0; -} - int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { @@ -473,3 +474,4 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag, return 0; } #endif +#endif diff --git a/common/init/board_init.c b/common/init/board_init.c index 1c6126d8ce5..d98648eaa6f 100644 --- a/common/init/board_init.c +++ b/common/init/board_init.c @@ -21,39 +21,128 @@ DECLARE_GLOBAL_DATA_PTR; #define _USE_MEMCPY #endif -/* Unfortunately x86 can't compile this code as gd cannot be assigned */ -#ifndef CONFIG_X86 +/* Unfortunately x86 or ARM can't compile this code as gd cannot be assigned */ +#if !defined(CONFIG_X86) && !defined(CONFIG_ARM) __weak void arch_setup_gd(struct global_data *gd_ptr) { gd = gd_ptr; } -#endif /* !CONFIG_X86 */ +#endif /* !CONFIG_X86 && !CONFIG_ARM */ -ulong board_init_f_mem(ulong top) +/* + * Allocate reserved space for use as 'globals' from 'top' address and + * return 'bottom' address of allocated space + * + * Notes: + * + * Actual reservation cannot be done from within this function as + * it requires altering the C stack pointer, so this will be done by + * the caller upon return from this function. + * + * IMPORTANT: + * + * Alignment constraints may differ for each 'chunk' allocated. For now: + * + * - GD is aligned down on a 16-byte boundary + * + * - the early malloc arena is not aligned, therefore it follows the stack + * alignment constraint of the architecture for which we are bulding. + * + * - GD is allocated last, so that the return value of this functions is + * both the bottom of the reserved area and the address of GD, should + * the calling context need it. + */ + +ulong board_init_f_alloc_reserve(ulong top) +{ + /* Reserve early malloc arena */ +#if defined(CONFIG_SYS_MALLOC_F) + top -= CONFIG_SYS_MALLOC_F_LEN; +#endif + /* LAST : reserve GD (rounded up to a multiple of 16 bytes) */ + top = rounddown(top-sizeof(struct global_data), 16); + + return top; +} + +/* + * Initialize reserved space (which has been safely allocated on the C + * stack from the C runtime environment handling code). + * + * Notes: + * + * Actual reservation was done by the caller; the locations from base + * to base+size-1 (where 'size' is the value returned by the allocation + * function above) can be accessed freely without risk of corrupting the + * C runtime environment. + * + * IMPORTANT: + * + * Upon return from the allocation function above, on some architectures + * the caller will set gd to the lowest reserved location. Therefore, in + * this initialization function, the global data MUST be placed at base. + * + * ALSO IMPORTANT: + * + * On some architectures, gd will already be good when entering this + * function. On others, it will only be good once arch_setup_gd() returns. + * Therefore, global data accesses must be done: + * + * - through gd_ptr if before the call to arch_setup_gd(); + * + * - through gd once arch_setup_gd() has been called. + * + * Do not use 'gd->' until arch_setup_gd() has been called! + * + * IMPORTANT TOO: + * + * Initialization for each "chunk" (GD, early malloc arena...) ends with + * an incrementation line of the form 'base += <some size>'. The last of + * these incrementations seems useless, as base will not be used any + * more after this incrementation; but if/when a new "chunk" is appended, + * this increment will be essential as it will give base right value for + * this new chunk (which will have to end with its own incrementation + * statement). Besides, the compiler's optimizer will silently detect + * and remove the last base incrementation, therefore leaving that last + * (seemingly useless) incrementation causes no code increase. + */ + +void board_init_f_init_reserve(ulong base) { struct global_data *gd_ptr; #ifndef _USE_MEMCPY int *ptr; #endif - /* Leave space for the stack we are running with now */ - top -= 0x40; + /* + * clear GD entirely and set it up. + * Use gd_ptr, as gd may not be properly set yet. + */ - top -= sizeof(struct global_data); - top = ALIGN(top, 16); - gd_ptr = (struct global_data *)top; + gd_ptr = (struct global_data *)base; + /* zero the area */ #ifdef _USE_MEMCPY memset(gd_ptr, '\0', sizeof(*gd)); #else for (ptr = (int *)gd_ptr; ptr < (int *)(gd_ptr + 1); ) *ptr++ = 0; #endif + /* set GD unless architecture did it already */ +#if !defined(CONFIG_X86) && !defined(CONFIG_ARM) arch_setup_gd(gd_ptr); +#endif + /* next alloc will be higher by one GD plus 16-byte alignment */ + base += roundup(sizeof(struct global_data), 16); + + /* + * record early malloc arena start. + * Use gd as it is now properly set for all architectures. + */ #if defined(CONFIG_SYS_MALLOC_F) - top -= CONFIG_SYS_MALLOC_F_LEN; - gd->malloc_base = top; + /* go down one 'early malloc arena' */ + gd->malloc_base = base; + /* next alloc will be higher by one 'early malloc arena' size */ + base += CONFIG_SYS_MALLOC_F_LEN; #endif - - return top; } diff --git a/common/spl/spl.c b/common/spl/spl.c index 6e6dee7ec9b..e5167bf73e4 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -431,8 +431,13 @@ void preloader_console_init(void) * more stack space for things like the MMC sub-system. * * This function calculates the stack position, copies the global_data into - * place and returns the new stack position. The caller is responsible for - * setting up the sp register. + * place, sets the new gd (except for ARM, for which setting GD within a C + * function may not always work) and returns the new stack position. The + * caller is responsible for setting up the sp register and, in the case + * of ARM, setting up gd. + * + * All of this is done using the same layout and alignments as done in + * board_init_f_init_reserve() / board_init_f_alloc_reserve(). * * @return new stack location, or 0 to use the same stack */ @@ -440,14 +445,7 @@ ulong spl_relocate_stack_gd(void) { #ifdef CONFIG_SPL_STACK_R gd_t *new_gd; - ulong ptr; - - /* Get stack position: use 8-byte alignment for ABI compliance */ - ptr = CONFIG_SPL_STACK_R_ADDR - sizeof(gd_t); - ptr &= ~7; - new_gd = (gd_t *)ptr; - memcpy(new_gd, (void *)gd, sizeof(gd_t)); - gd = new_gd; + ulong ptr = CONFIG_SPL_STACK_R_ADDR; #ifdef CONFIG_SPL_SYS_MALLOC_SIMPLE if (CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN) { @@ -460,7 +458,13 @@ ulong spl_relocate_stack_gd(void) gd->malloc_ptr = 0; } #endif - + /* Get stack position: use 8-byte alignment for ABI compliance */ + ptr = CONFIG_SPL_STACK_R_ADDR - roundup(sizeof(gd_t),16); + new_gd = (gd_t *)ptr; + memcpy(new_gd, (void *)gd, sizeof(gd_t)); +#if !defined(CONFIG_ARM) + gd = new_gd; +#endif return ptr; #else return 0; diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index c1c29c02d7e..c3931c6c4d7 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -23,13 +23,12 @@ static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector) unsigned long count; u32 image_size_sectors; struct image_header *header; - int dev_num = mmc->block_dev.dev; header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); /* read image header to find the image size & load address */ - count = mmc->block_dev.block_read(dev_num, sector, 1, header); + count = mmc->block_dev.block_read(&mmc->block_dev, sector, 1, header); debug("read sector %lx, count=%lu\n", sector, count); if (count == 0) goto end; @@ -46,7 +45,8 @@ static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector) mmc->read_bl_len; /* Read the header too to avoid extra memcpy */ - count = mmc->block_dev.block_read(dev_num, sector, image_size_sectors, + count = mmc->block_dev.block_read(&mmc->block_dev, sector, + image_size_sectors, (void *)(ulong)spl_image.load_addr); debug("read %x sectors to %x\n", image_size_sectors, spl_image.load_addr); @@ -150,8 +150,7 @@ static int mmc_load_image_raw_os(struct mmc *mmc) { unsigned long count; - count = mmc->block_dev.block_read( - mmc->block_dev.dev, + count = mmc->block_dev.block_read(&mmc->block_dev, CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS, (void *) CONFIG_SYS_SPL_ARGS_ADDR); diff --git a/common/usb_storage.c b/common/usb_storage.c index e61a8c8adfd..4fdb55f9faf 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -119,10 +119,10 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *us, block_dev_desc_t *dev_desc); int usb_storage_probe(struct usb_device *dev, unsigned int ifnum, struct us_data *ss); -unsigned long usb_stor_read(int device, lbaint_t blknr, - lbaint_t blkcnt, void *buffer); -unsigned long usb_stor_write(int device, lbaint_t blknr, - lbaint_t blkcnt, const void *buffer); +static unsigned long usb_stor_read(block_dev_desc_t *block_dev, lbaint_t blknr, + lbaint_t blkcnt, void *buffer); +static unsigned long usb_stor_write(block_dev_desc_t *block_dev, lbaint_t blknr, + lbaint_t blkcnt, const void *buffer); void uhci_show_temp_int_td(void); #ifdef CONFIG_PARTITIONS @@ -1027,9 +1027,10 @@ static void usb_bin_fixup(struct usb_device_descriptor descriptor, } #endif /* CONFIG_USB_BIN_FIXUP */ -unsigned long usb_stor_read(int device, lbaint_t blknr, - lbaint_t blkcnt, void *buffer) +static unsigned long usb_stor_read(block_dev_desc_t *block_dev, lbaint_t blknr, + lbaint_t blkcnt, void *buffer) { + int device = block_dev->dev; lbaint_t start, blks; uintptr_t buf_addr; unsigned short smallblks; @@ -1097,9 +1098,10 @@ retry_it: return blkcnt; } -unsigned long usb_stor_write(int device, lbaint_t blknr, - lbaint_t blkcnt, const void *buffer) +static unsigned long usb_stor_write(block_dev_desc_t *block_dev, lbaint_t blknr, + lbaint_t blkcnt, const void *buffer) { + int device = block_dev->dev; lbaint_t start, blks; uintptr_t buf_addr; unsigned short smallblks; |