1*bfeba017SMoritz Fischer /* 2*bfeba017SMoritz Fischer * Chromium OS cros_ec driver 3*bfeba017SMoritz Fischer * 4*bfeba017SMoritz Fischer * Copyright (c) 2016 The Chromium OS Authors. 5*bfeba017SMoritz Fischer * Copyright (c) 2016 National Instruments Corp 6*bfeba017SMoritz Fischer * 7*bfeba017SMoritz Fischer * SPDX-License-Identifier: GPL-2.0+ 8*bfeba017SMoritz Fischer */ 9*bfeba017SMoritz Fischer 10*bfeba017SMoritz Fischer #include <common.h> 11*bfeba017SMoritz Fischer #include <command.h> 12*bfeba017SMoritz Fischer #include <cros_ec.h> 13*bfeba017SMoritz Fischer #include <dm.h> 14*bfeba017SMoritz Fischer #include <dm/device-internal.h> 15*bfeba017SMoritz Fischer #include <dm/uclass-internal.h> 16*bfeba017SMoritz Fischer 17*bfeba017SMoritz Fischer /* Note: depends on enum ec_current_image */ 18*bfeba017SMoritz Fischer static const char * const ec_current_image_name[] = {"unknown", "RO", "RW"}; 19*bfeba017SMoritz Fischer 20*bfeba017SMoritz Fischer DECLARE_GLOBAL_DATA_PTR; 21*bfeba017SMoritz Fischer 22*bfeba017SMoritz Fischer /** 23*bfeba017SMoritz Fischer * Perform a flash read or write command 24*bfeba017SMoritz Fischer * 25*bfeba017SMoritz Fischer * @param dev CROS-EC device to read/write 26*bfeba017SMoritz Fischer * @param is_write 1 do to a write, 0 to do a read 27*bfeba017SMoritz Fischer * @param argc Number of arguments 28*bfeba017SMoritz Fischer * @param argv Arguments (2 is region, 3 is address) 29*bfeba017SMoritz Fischer * @return 0 for ok, 1 for a usage error or -ve for ec command error 30*bfeba017SMoritz Fischer * (negative EC_RES_...) 31*bfeba017SMoritz Fischer */ 32*bfeba017SMoritz Fischer static int do_read_write(struct cros_ec_dev *dev, int is_write, int argc, 33*bfeba017SMoritz Fischer char * const argv[]) 34*bfeba017SMoritz Fischer { 35*bfeba017SMoritz Fischer uint32_t offset, size = -1U, region_size; 36*bfeba017SMoritz Fischer unsigned long addr; 37*bfeba017SMoritz Fischer char *endp; 38*bfeba017SMoritz Fischer int region; 39*bfeba017SMoritz Fischer int ret; 40*bfeba017SMoritz Fischer 41*bfeba017SMoritz Fischer region = cros_ec_decode_region(argc - 2, argv + 2); 42*bfeba017SMoritz Fischer if (region == -1) 43*bfeba017SMoritz Fischer return 1; 44*bfeba017SMoritz Fischer if (argc < 4) 45*bfeba017SMoritz Fischer return 1; 46*bfeba017SMoritz Fischer addr = simple_strtoul(argv[3], &endp, 16); 47*bfeba017SMoritz Fischer if (*argv[3] == 0 || *endp != 0) 48*bfeba017SMoritz Fischer return 1; 49*bfeba017SMoritz Fischer if (argc > 4) { 50*bfeba017SMoritz Fischer size = simple_strtoul(argv[4], &endp, 16); 51*bfeba017SMoritz Fischer if (*argv[4] == 0 || *endp != 0) 52*bfeba017SMoritz Fischer return 1; 53*bfeba017SMoritz Fischer } 54*bfeba017SMoritz Fischer 55*bfeba017SMoritz Fischer ret = cros_ec_flash_offset(dev, region, &offset, ®ion_size); 56*bfeba017SMoritz Fischer if (ret) { 57*bfeba017SMoritz Fischer debug("%s: Could not read region info\n", __func__); 58*bfeba017SMoritz Fischer return ret; 59*bfeba017SMoritz Fischer } 60*bfeba017SMoritz Fischer if (size == -1U) 61*bfeba017SMoritz Fischer size = region_size; 62*bfeba017SMoritz Fischer 63*bfeba017SMoritz Fischer ret = is_write ? 64*bfeba017SMoritz Fischer cros_ec_flash_write(dev, (uint8_t *)addr, offset, size) : 65*bfeba017SMoritz Fischer cros_ec_flash_read(dev, (uint8_t *)addr, offset, size); 66*bfeba017SMoritz Fischer if (ret) { 67*bfeba017SMoritz Fischer debug("%s: Could not %s region\n", __func__, 68*bfeba017SMoritz Fischer is_write ? "write" : "read"); 69*bfeba017SMoritz Fischer return ret; 70*bfeba017SMoritz Fischer } 71*bfeba017SMoritz Fischer 72*bfeba017SMoritz Fischer return 0; 73*bfeba017SMoritz Fischer } 74*bfeba017SMoritz Fischer 75*bfeba017SMoritz Fischer static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 76*bfeba017SMoritz Fischer { 77*bfeba017SMoritz Fischer struct cros_ec_dev *dev; 78*bfeba017SMoritz Fischer struct udevice *udev; 79*bfeba017SMoritz Fischer const char *cmd; 80*bfeba017SMoritz Fischer int ret = 0; 81*bfeba017SMoritz Fischer 82*bfeba017SMoritz Fischer if (argc < 2) 83*bfeba017SMoritz Fischer return CMD_RET_USAGE; 84*bfeba017SMoritz Fischer 85*bfeba017SMoritz Fischer cmd = argv[1]; 86*bfeba017SMoritz Fischer if (0 == strcmp("init", cmd)) { 87*bfeba017SMoritz Fischer /* Remove any existing device */ 88*bfeba017SMoritz Fischer ret = uclass_find_device(UCLASS_CROS_EC, 0, &udev); 89*bfeba017SMoritz Fischer if (!ret) 90*bfeba017SMoritz Fischer device_remove(udev); 91*bfeba017SMoritz Fischer ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev); 92*bfeba017SMoritz Fischer if (ret) { 93*bfeba017SMoritz Fischer printf("Could not init cros_ec device (err %d)\n", ret); 94*bfeba017SMoritz Fischer return 1; 95*bfeba017SMoritz Fischer } 96*bfeba017SMoritz Fischer return 0; 97*bfeba017SMoritz Fischer } 98*bfeba017SMoritz Fischer 99*bfeba017SMoritz Fischer ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev); 100*bfeba017SMoritz Fischer if (ret) { 101*bfeba017SMoritz Fischer printf("Cannot get cros-ec device (err=%d)\n", ret); 102*bfeba017SMoritz Fischer return 1; 103*bfeba017SMoritz Fischer } 104*bfeba017SMoritz Fischer dev = dev_get_uclass_priv(udev); 105*bfeba017SMoritz Fischer if (0 == strcmp("id", cmd)) { 106*bfeba017SMoritz Fischer char id[MSG_BYTES]; 107*bfeba017SMoritz Fischer 108*bfeba017SMoritz Fischer if (cros_ec_read_id(dev, id, sizeof(id))) { 109*bfeba017SMoritz Fischer debug("%s: Could not read KBC ID\n", __func__); 110*bfeba017SMoritz Fischer return 1; 111*bfeba017SMoritz Fischer } 112*bfeba017SMoritz Fischer printf("%s\n", id); 113*bfeba017SMoritz Fischer } else if (0 == strcmp("info", cmd)) { 114*bfeba017SMoritz Fischer struct ec_response_mkbp_info info; 115*bfeba017SMoritz Fischer 116*bfeba017SMoritz Fischer if (cros_ec_info(dev, &info)) { 117*bfeba017SMoritz Fischer debug("%s: Could not read KBC info\n", __func__); 118*bfeba017SMoritz Fischer return 1; 119*bfeba017SMoritz Fischer } 120*bfeba017SMoritz Fischer printf("rows = %u\n", info.rows); 121*bfeba017SMoritz Fischer printf("cols = %u\n", info.cols); 122*bfeba017SMoritz Fischer printf("switches = %#x\n", info.switches); 123*bfeba017SMoritz Fischer } else if (0 == strcmp("curimage", cmd)) { 124*bfeba017SMoritz Fischer enum ec_current_image image; 125*bfeba017SMoritz Fischer 126*bfeba017SMoritz Fischer if (cros_ec_read_current_image(dev, &image)) { 127*bfeba017SMoritz Fischer debug("%s: Could not read KBC image\n", __func__); 128*bfeba017SMoritz Fischer return 1; 129*bfeba017SMoritz Fischer } 130*bfeba017SMoritz Fischer printf("%d\n", image); 131*bfeba017SMoritz Fischer } else if (0 == strcmp("hash", cmd)) { 132*bfeba017SMoritz Fischer struct ec_response_vboot_hash hash; 133*bfeba017SMoritz Fischer int i; 134*bfeba017SMoritz Fischer 135*bfeba017SMoritz Fischer if (cros_ec_read_hash(dev, &hash)) { 136*bfeba017SMoritz Fischer debug("%s: Could not read KBC hash\n", __func__); 137*bfeba017SMoritz Fischer return 1; 138*bfeba017SMoritz Fischer } 139*bfeba017SMoritz Fischer 140*bfeba017SMoritz Fischer if (hash.hash_type == EC_VBOOT_HASH_TYPE_SHA256) 141*bfeba017SMoritz Fischer printf("type: SHA-256\n"); 142*bfeba017SMoritz Fischer else 143*bfeba017SMoritz Fischer printf("type: %d\n", hash.hash_type); 144*bfeba017SMoritz Fischer 145*bfeba017SMoritz Fischer printf("offset: 0x%08x\n", hash.offset); 146*bfeba017SMoritz Fischer printf("size: 0x%08x\n", hash.size); 147*bfeba017SMoritz Fischer 148*bfeba017SMoritz Fischer printf("digest: "); 149*bfeba017SMoritz Fischer for (i = 0; i < hash.digest_size; i++) 150*bfeba017SMoritz Fischer printf("%02x", hash.hash_digest[i]); 151*bfeba017SMoritz Fischer printf("\n"); 152*bfeba017SMoritz Fischer } else if (0 == strcmp("reboot", cmd)) { 153*bfeba017SMoritz Fischer int region; 154*bfeba017SMoritz Fischer enum ec_reboot_cmd cmd; 155*bfeba017SMoritz Fischer 156*bfeba017SMoritz Fischer if (argc >= 3 && !strcmp(argv[2], "cold")) { 157*bfeba017SMoritz Fischer cmd = EC_REBOOT_COLD; 158*bfeba017SMoritz Fischer } else { 159*bfeba017SMoritz Fischer region = cros_ec_decode_region(argc - 2, argv + 2); 160*bfeba017SMoritz Fischer if (region == EC_FLASH_REGION_RO) 161*bfeba017SMoritz Fischer cmd = EC_REBOOT_JUMP_RO; 162*bfeba017SMoritz Fischer else if (region == EC_FLASH_REGION_RW) 163*bfeba017SMoritz Fischer cmd = EC_REBOOT_JUMP_RW; 164*bfeba017SMoritz Fischer else 165*bfeba017SMoritz Fischer return CMD_RET_USAGE; 166*bfeba017SMoritz Fischer } 167*bfeba017SMoritz Fischer 168*bfeba017SMoritz Fischer if (cros_ec_reboot(dev, cmd, 0)) { 169*bfeba017SMoritz Fischer debug("%s: Could not reboot KBC\n", __func__); 170*bfeba017SMoritz Fischer return 1; 171*bfeba017SMoritz Fischer } 172*bfeba017SMoritz Fischer } else if (0 == strcmp("events", cmd)) { 173*bfeba017SMoritz Fischer uint32_t events; 174*bfeba017SMoritz Fischer 175*bfeba017SMoritz Fischer if (cros_ec_get_host_events(dev, &events)) { 176*bfeba017SMoritz Fischer debug("%s: Could not read host events\n", __func__); 177*bfeba017SMoritz Fischer return 1; 178*bfeba017SMoritz Fischer } 179*bfeba017SMoritz Fischer printf("0x%08x\n", events); 180*bfeba017SMoritz Fischer } else if (0 == strcmp("clrevents", cmd)) { 181*bfeba017SMoritz Fischer uint32_t events = 0x7fffffff; 182*bfeba017SMoritz Fischer 183*bfeba017SMoritz Fischer if (argc >= 3) 184*bfeba017SMoritz Fischer events = simple_strtol(argv[2], NULL, 0); 185*bfeba017SMoritz Fischer 186*bfeba017SMoritz Fischer if (cros_ec_clear_host_events(dev, events)) { 187*bfeba017SMoritz Fischer debug("%s: Could not clear host events\n", __func__); 188*bfeba017SMoritz Fischer return 1; 189*bfeba017SMoritz Fischer } 190*bfeba017SMoritz Fischer } else if (0 == strcmp("read", cmd)) { 191*bfeba017SMoritz Fischer ret = do_read_write(dev, 0, argc, argv); 192*bfeba017SMoritz Fischer if (ret > 0) 193*bfeba017SMoritz Fischer return CMD_RET_USAGE; 194*bfeba017SMoritz Fischer } else if (0 == strcmp("write", cmd)) { 195*bfeba017SMoritz Fischer ret = do_read_write(dev, 1, argc, argv); 196*bfeba017SMoritz Fischer if (ret > 0) 197*bfeba017SMoritz Fischer return CMD_RET_USAGE; 198*bfeba017SMoritz Fischer } else if (0 == strcmp("erase", cmd)) { 199*bfeba017SMoritz Fischer int region = cros_ec_decode_region(argc - 2, argv + 2); 200*bfeba017SMoritz Fischer uint32_t offset, size; 201*bfeba017SMoritz Fischer 202*bfeba017SMoritz Fischer if (region == -1) 203*bfeba017SMoritz Fischer return CMD_RET_USAGE; 204*bfeba017SMoritz Fischer if (cros_ec_flash_offset(dev, region, &offset, &size)) { 205*bfeba017SMoritz Fischer debug("%s: Could not read region info\n", __func__); 206*bfeba017SMoritz Fischer ret = -1; 207*bfeba017SMoritz Fischer } else { 208*bfeba017SMoritz Fischer ret = cros_ec_flash_erase(dev, offset, size); 209*bfeba017SMoritz Fischer if (ret) { 210*bfeba017SMoritz Fischer debug("%s: Could not erase region\n", 211*bfeba017SMoritz Fischer __func__); 212*bfeba017SMoritz Fischer } 213*bfeba017SMoritz Fischer } 214*bfeba017SMoritz Fischer } else if (0 == strcmp("regioninfo", cmd)) { 215*bfeba017SMoritz Fischer int region = cros_ec_decode_region(argc - 2, argv + 2); 216*bfeba017SMoritz Fischer uint32_t offset, size; 217*bfeba017SMoritz Fischer 218*bfeba017SMoritz Fischer if (region == -1) 219*bfeba017SMoritz Fischer return CMD_RET_USAGE; 220*bfeba017SMoritz Fischer ret = cros_ec_flash_offset(dev, region, &offset, &size); 221*bfeba017SMoritz Fischer if (ret) { 222*bfeba017SMoritz Fischer debug("%s: Could not read region info\n", __func__); 223*bfeba017SMoritz Fischer } else { 224*bfeba017SMoritz Fischer printf("Region: %s\n", region == EC_FLASH_REGION_RO ? 225*bfeba017SMoritz Fischer "RO" : "RW"); 226*bfeba017SMoritz Fischer printf("Offset: %x\n", offset); 227*bfeba017SMoritz Fischer printf("Size: %x\n", size); 228*bfeba017SMoritz Fischer } 229*bfeba017SMoritz Fischer } else if (0 == strcmp("flashinfo", cmd)) { 230*bfeba017SMoritz Fischer struct ec_response_flash_info p; 231*bfeba017SMoritz Fischer 232*bfeba017SMoritz Fischer ret = cros_ec_read_flashinfo(dev, &p); 233*bfeba017SMoritz Fischer if (!ret) { 234*bfeba017SMoritz Fischer printf("Flash size: %u\n", p.flash_size); 235*bfeba017SMoritz Fischer printf("Write block size: %u\n", p.write_block_size); 236*bfeba017SMoritz Fischer printf("Erase block size: %u\n", p.erase_block_size); 237*bfeba017SMoritz Fischer } 238*bfeba017SMoritz Fischer } else if (0 == strcmp("vbnvcontext", cmd)) { 239*bfeba017SMoritz Fischer uint8_t block[EC_VBNV_BLOCK_SIZE]; 240*bfeba017SMoritz Fischer char buf[3]; 241*bfeba017SMoritz Fischer int i, len; 242*bfeba017SMoritz Fischer unsigned long result; 243*bfeba017SMoritz Fischer 244*bfeba017SMoritz Fischer if (argc <= 2) { 245*bfeba017SMoritz Fischer ret = cros_ec_read_vbnvcontext(dev, block); 246*bfeba017SMoritz Fischer if (!ret) { 247*bfeba017SMoritz Fischer printf("vbnv_block: "); 248*bfeba017SMoritz Fischer for (i = 0; i < EC_VBNV_BLOCK_SIZE; i++) 249*bfeba017SMoritz Fischer printf("%02x", block[i]); 250*bfeba017SMoritz Fischer putc('\n'); 251*bfeba017SMoritz Fischer } 252*bfeba017SMoritz Fischer } else { 253*bfeba017SMoritz Fischer /* 254*bfeba017SMoritz Fischer * TODO(clchiou): Move this to a utility function as 255*bfeba017SMoritz Fischer * cmd_spi might want to call it. 256*bfeba017SMoritz Fischer */ 257*bfeba017SMoritz Fischer memset(block, 0, EC_VBNV_BLOCK_SIZE); 258*bfeba017SMoritz Fischer len = strlen(argv[2]); 259*bfeba017SMoritz Fischer buf[2] = '\0'; 260*bfeba017SMoritz Fischer for (i = 0; i < EC_VBNV_BLOCK_SIZE; i++) { 261*bfeba017SMoritz Fischer if (i * 2 >= len) 262*bfeba017SMoritz Fischer break; 263*bfeba017SMoritz Fischer buf[0] = argv[2][i * 2]; 264*bfeba017SMoritz Fischer if (i * 2 + 1 >= len) 265*bfeba017SMoritz Fischer buf[1] = '0'; 266*bfeba017SMoritz Fischer else 267*bfeba017SMoritz Fischer buf[1] = argv[2][i * 2 + 1]; 268*bfeba017SMoritz Fischer strict_strtoul(buf, 16, &result); 269*bfeba017SMoritz Fischer block[i] = result; 270*bfeba017SMoritz Fischer } 271*bfeba017SMoritz Fischer ret = cros_ec_write_vbnvcontext(dev, block); 272*bfeba017SMoritz Fischer } 273*bfeba017SMoritz Fischer if (ret) { 274*bfeba017SMoritz Fischer debug("%s: Could not %s VbNvContext\n", __func__, 275*bfeba017SMoritz Fischer argc <= 2 ? "read" : "write"); 276*bfeba017SMoritz Fischer } 277*bfeba017SMoritz Fischer } else if (0 == strcmp("test", cmd)) { 278*bfeba017SMoritz Fischer int result = cros_ec_test(dev); 279*bfeba017SMoritz Fischer 280*bfeba017SMoritz Fischer if (result) 281*bfeba017SMoritz Fischer printf("Test failed with error %d\n", result); 282*bfeba017SMoritz Fischer else 283*bfeba017SMoritz Fischer puts("Test passed\n"); 284*bfeba017SMoritz Fischer } else if (0 == strcmp("version", cmd)) { 285*bfeba017SMoritz Fischer struct ec_response_get_version *p; 286*bfeba017SMoritz Fischer char *build_string; 287*bfeba017SMoritz Fischer 288*bfeba017SMoritz Fischer ret = cros_ec_read_version(dev, &p); 289*bfeba017SMoritz Fischer if (!ret) { 290*bfeba017SMoritz Fischer /* Print versions */ 291*bfeba017SMoritz Fischer printf("RO version: %1.*s\n", 292*bfeba017SMoritz Fischer (int)sizeof(p->version_string_ro), 293*bfeba017SMoritz Fischer p->version_string_ro); 294*bfeba017SMoritz Fischer printf("RW version: %1.*s\n", 295*bfeba017SMoritz Fischer (int)sizeof(p->version_string_rw), 296*bfeba017SMoritz Fischer p->version_string_rw); 297*bfeba017SMoritz Fischer printf("Firmware copy: %s\n", 298*bfeba017SMoritz Fischer (p->current_image < 299*bfeba017SMoritz Fischer ARRAY_SIZE(ec_current_image_name) ? 300*bfeba017SMoritz Fischer ec_current_image_name[p->current_image] : 301*bfeba017SMoritz Fischer "?")); 302*bfeba017SMoritz Fischer ret = cros_ec_read_build_info(dev, &build_string); 303*bfeba017SMoritz Fischer if (!ret) 304*bfeba017SMoritz Fischer printf("Build info: %s\n", build_string); 305*bfeba017SMoritz Fischer } 306*bfeba017SMoritz Fischer } else if (0 == strcmp("ldo", cmd)) { 307*bfeba017SMoritz Fischer uint8_t index, state; 308*bfeba017SMoritz Fischer char *endp; 309*bfeba017SMoritz Fischer 310*bfeba017SMoritz Fischer if (argc < 3) 311*bfeba017SMoritz Fischer return CMD_RET_USAGE; 312*bfeba017SMoritz Fischer index = simple_strtoul(argv[2], &endp, 10); 313*bfeba017SMoritz Fischer if (*argv[2] == 0 || *endp != 0) 314*bfeba017SMoritz Fischer return CMD_RET_USAGE; 315*bfeba017SMoritz Fischer if (argc > 3) { 316*bfeba017SMoritz Fischer state = simple_strtoul(argv[3], &endp, 10); 317*bfeba017SMoritz Fischer if (*argv[3] == 0 || *endp != 0) 318*bfeba017SMoritz Fischer return CMD_RET_USAGE; 319*bfeba017SMoritz Fischer ret = cros_ec_set_ldo(udev, index, state); 320*bfeba017SMoritz Fischer } else { 321*bfeba017SMoritz Fischer ret = cros_ec_get_ldo(udev, index, &state); 322*bfeba017SMoritz Fischer if (!ret) { 323*bfeba017SMoritz Fischer printf("LDO%d: %s\n", index, 324*bfeba017SMoritz Fischer state == EC_LDO_STATE_ON ? 325*bfeba017SMoritz Fischer "on" : "off"); 326*bfeba017SMoritz Fischer } 327*bfeba017SMoritz Fischer } 328*bfeba017SMoritz Fischer 329*bfeba017SMoritz Fischer if (ret) { 330*bfeba017SMoritz Fischer debug("%s: Could not access LDO%d\n", __func__, index); 331*bfeba017SMoritz Fischer return ret; 332*bfeba017SMoritz Fischer } 333*bfeba017SMoritz Fischer } else { 334*bfeba017SMoritz Fischer return CMD_RET_USAGE; 335*bfeba017SMoritz Fischer } 336*bfeba017SMoritz Fischer 337*bfeba017SMoritz Fischer if (ret < 0) { 338*bfeba017SMoritz Fischer printf("Error: CROS-EC command failed (error %d)\n", ret); 339*bfeba017SMoritz Fischer ret = 1; 340*bfeba017SMoritz Fischer } 341*bfeba017SMoritz Fischer 342*bfeba017SMoritz Fischer return ret; 343*bfeba017SMoritz Fischer } 344*bfeba017SMoritz Fischer 345*bfeba017SMoritz Fischer U_BOOT_CMD( 346*bfeba017SMoritz Fischer crosec, 6, 1, do_cros_ec, 347*bfeba017SMoritz Fischer "CROS-EC utility command", 348*bfeba017SMoritz Fischer "init Re-init CROS-EC (done on startup automatically)\n" 349*bfeba017SMoritz Fischer "crosec id Read CROS-EC ID\n" 350*bfeba017SMoritz Fischer "crosec info Read CROS-EC info\n" 351*bfeba017SMoritz Fischer "crosec curimage Read CROS-EC current image\n" 352*bfeba017SMoritz Fischer "crosec hash Read CROS-EC hash\n" 353*bfeba017SMoritz Fischer "crosec reboot [rw | ro | cold] Reboot CROS-EC\n" 354*bfeba017SMoritz Fischer "crosec events Read CROS-EC host events\n" 355*bfeba017SMoritz Fischer "crosec clrevents [mask] Clear CROS-EC host events\n" 356*bfeba017SMoritz Fischer "crosec regioninfo <ro|rw> Read image info\n" 357*bfeba017SMoritz Fischer "crosec flashinfo Read flash info\n" 358*bfeba017SMoritz Fischer "crosec erase <ro|rw> Erase EC image\n" 359*bfeba017SMoritz Fischer "crosec read <ro|rw> <addr> [<size>] Read EC image\n" 360*bfeba017SMoritz Fischer "crosec write <ro|rw> <addr> [<size>] Write EC image\n" 361*bfeba017SMoritz Fischer "crosec vbnvcontext [hexstring] Read [write] VbNvContext from EC\n" 362*bfeba017SMoritz Fischer "crosec ldo <idx> [<state>] Switch/Read LDO state\n" 363*bfeba017SMoritz Fischer "crosec test run tests on cros_ec\n" 364*bfeba017SMoritz Fischer "crosec version Read CROS-EC version" 365*bfeba017SMoritz Fischer ); 366