| // SPDX-License-Identifier: GPL-2.0+ |
| /* |
| * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
| */ |
| |
| /* |
| * CBFS commands |
| */ |
| #include <command.h> |
| #include <env.h> |
| #include <cbfs.h> |
| #include <vsprintf.h> |
| |
| static int do_cbfs_init(struct cmd_tbl *cmdtp, int flag, int argc, |
| char *const argv[]) |
| { |
| uintptr_t end_of_rom = 0xffffffff; |
| char *ep; |
| |
| if (argc > 2) { |
| printf("usage: cbfsls [end of rom]>\n"); |
| return 0; |
| } |
| if (argc == 2) { |
| end_of_rom = hextoul(argv[1], &ep); |
| if (*ep) { |
| puts("\n** Invalid end of ROM **\n"); |
| return 1; |
| } |
| } |
| if (file_cbfs_init(end_of_rom)) { |
| printf("%s.\n", file_cbfs_error()); |
| return 1; |
| } |
| return 0; |
| } |
| |
| U_BOOT_CMD( |
| cbfsinit, 2, 0, do_cbfs_init, |
| "initialize the cbfs driver", |
| "[end of rom]\n" |
| " - Initialize the cbfs driver. The optional 'end of rom'\n" |
| " parameter specifies where the end of the ROM is that the\n" |
| " CBFS is in. It defaults to 0xFFFFFFFF\n" |
| ); |
| |
| static int do_cbfs_fsload(struct cmd_tbl *cmdtp, int flag, int argc, |
| char *const argv[]) |
| { |
| const struct cbfs_cachenode *file; |
| unsigned long offset; |
| unsigned long count; |
| long size; |
| |
| if (argc < 3) { |
| printf("usage: cbfsload <addr> <filename> [bytes]\n"); |
| return 1; |
| } |
| |
| /* parse offset and count */ |
| offset = hextoul(argv[1], NULL); |
| if (argc == 4) |
| count = hextoul(argv[3], NULL); |
| else |
| count = 0; |
| |
| file = file_cbfs_find(argv[2]); |
| if (!file) { |
| if (cbfs_get_result() == CBFS_FILE_NOT_FOUND) |
| printf("%s: %s\n", file_cbfs_error(), argv[2]); |
| else |
| printf("%s.\n", file_cbfs_error()); |
| return 1; |
| } |
| |
| printf("reading %s\n", file_cbfs_name(file)); |
| |
| size = file_cbfs_read(file, (void *)offset, count); |
| |
| printf("\n%ld bytes read\n", size); |
| |
| env_set_hex("filesize", size); |
| |
| return 0; |
| } |
| |
| U_BOOT_CMD( |
| cbfsload, 4, 0, do_cbfs_fsload, |
| "load binary file from a cbfs filesystem", |
| "<addr> <filename> [bytes]\n" |
| " - load binary file 'filename' from the cbfs to address 'addr'\n" |
| ); |
| |
| static int do_cbfs_ls(struct cmd_tbl *cmdtp, int flag, int argc, |
| char *const argv[]) |
| { |
| const struct cbfs_cachenode *file = file_cbfs_get_first(); |
| int files = 0; |
| |
| if (!file) { |
| printf("%s.\n", file_cbfs_error()); |
| return 1; |
| } |
| |
| printf(" size type name\n"); |
| printf("------------------------------------------\n"); |
| while (file) { |
| int type = file_cbfs_type(file); |
| char *type_name = NULL; |
| const char *filename = file_cbfs_name(file); |
| |
| printf(" %8d", file_cbfs_size(file)); |
| |
| switch (type) { |
| case CBFS_TYPE_BOOTBLOCK: |
| type_name = "bootblock"; |
| break; |
| case CBFS_TYPE_CBFSHEADER: |
| type_name = "cbfs header"; |
| break; |
| case CBFS_TYPE_LEGACY_STAGE: |
| type_name = "stage"; |
| break; |
| case CBFS_TYPE_PAYLOAD: |
| type_name = "payload"; |
| break; |
| case CBFS_TYPE_FIT: |
| type_name = "fit"; |
| break; |
| case CBFS_TYPE_OPTIONROM: |
| type_name = "option rom"; |
| break; |
| case CBFS_TYPE_BOOTSPLASH: |
| type_name = "boot splash"; |
| break; |
| case CBFS_TYPE_RAW: |
| type_name = "raw"; |
| break; |
| case CBFS_TYPE_VSA: |
| type_name = "vsa"; |
| break; |
| case CBFS_TYPE_MBI: |
| type_name = "mbi"; |
| break; |
| case CBFS_TYPE_MICROCODE: |
| type_name = "microcode"; |
| break; |
| case CBFS_TYPE_FSP: |
| type_name = "fsp"; |
| break; |
| case CBFS_TYPE_MRC: |
| type_name = "mrc"; |
| break; |
| case CBFS_TYPE_MMA: |
| type_name = "mma"; |
| break; |
| case CBFS_TYPE_EFI: |
| type_name = "efi"; |
| break; |
| case CBFS_TYPE_STRUCT: |
| type_name = "struct"; |
| break; |
| case CBFS_TYPE_CMOS_DEFAULT: |
| type_name = "cmos default"; |
| break; |
| case CBFS_TYPE_SPD: |
| type_name = "spd"; |
| break; |
| case CBFS_TYPE_MRC_CACHE: |
| type_name = "mrc cache"; |
| break; |
| case CBFS_TYPE_CMOS_LAYOUT: |
| type_name = "cmos layout"; |
| break; |
| case -1: |
| case 0: |
| type_name = "null"; |
| break; |
| } |
| if (type_name) |
| printf(" %16s", type_name); |
| else |
| printf(" %16d", type); |
| |
| if (filename[0]) |
| printf(" %s\n", filename); |
| else |
| printf(" %s\n", "(empty)"); |
| file_cbfs_get_next(&file); |
| files++; |
| } |
| |
| printf("\n%d file(s)\n\n", files); |
| return 0; |
| } |
| |
| U_BOOT_CMD( |
| cbfsls, 1, 1, do_cbfs_ls, |
| "list files", |
| " - list the files in the cbfs\n" |
| ); |
| |
| static int do_cbfs_fsinfo(struct cmd_tbl *cmdtp, int flag, int argc, |
| char *const argv[]) |
| { |
| const struct cbfs_header *header = file_cbfs_get_header(); |
| |
| if (!header) { |
| printf("%s.\n", file_cbfs_error()); |
| return 1; |
| } |
| |
| printf("\n"); |
| printf("CBFS version: %#x\n", header->version); |
| printf("ROM size: %#x\n", header->rom_size); |
| printf("Boot block size: %#x\n", header->boot_block_size); |
| printf("CBFS size: %#x\n", |
| header->rom_size - header->boot_block_size - header->offset); |
| printf("Alignment: %d\n", header->align); |
| printf("Offset: %#x\n", header->offset); |
| printf("\n"); |
| |
| return 0; |
| } |
| |
| U_BOOT_CMD( |
| cbfsinfo, 1, 1, do_cbfs_fsinfo, |
| "print information about filesystem", |
| " - print information about the cbfs filesystem\n" |
| ); |