/* delay x useconds */ void __udelay(unsigned long usec) { struct sandbox_state *state = state_get_current(); if (!state->skip_delays) os_usleep(usec); }
void board_init_f(ulong flag) { struct sandbox_state *state = state_get_current(); gd->arch.ram_buf = state->ram_buf; gd->ram_size = state->ram_size; }
static int dm_do_test(struct unit_test_state *uts, struct unit_test *test, bool of_live) { struct sandbox_state *state = state_get_current(); const char *fname = strrchr(test->file, '/') + 1; printf("Test: %s: %s%s\n", test->name, fname, !of_live ? " (flat tree)" : ""); ut_assertok(dm_test_init(uts, of_live)); uts->start = mallinfo(); if (test->flags & DM_TESTF_SCAN_PDATA) ut_assertok(dm_scan_platdata(false)); if (test->flags & DM_TESTF_PROBE_TEST) ut_assertok(do_autoprobe(uts)); if (test->flags & DM_TESTF_SCAN_FDT) ut_assertok(dm_extended_scan_fdt(gd->fdt_blob, false)); /* * Silence the console and rely on console reocrding to get * our output. */ console_record_reset(); if (!state->show_test_output) gd->flags |= GD_FLG_SILENT; test->func(uts); gd->flags &= ~GD_FLG_SILENT; state_set_skip_delays(false); ut_assertok(dm_test_destroy(uts)); return 0; }
/* Test that we can walk through the sysreset devices */ static int dm_test_sysreset_walk(struct unit_test_state *uts) { struct sandbox_state *state = state_get_current(); /* If we generate a power sysreset, we will exit sandbox! */ state->sysreset_allowed[SYSRESET_POWER] = false; state->sysreset_allowed[SYSRESET_POWER_OFF] = false; ut_asserteq(-EACCES, sysreset_walk(SYSRESET_WARM)); ut_asserteq(-EACCES, sysreset_walk(SYSRESET_COLD)); ut_asserteq(-EACCES, sysreset_walk(SYSRESET_POWER)); /* * Enable cold system reset - this should make cold system reset work, * plus a warm system reset should be promoted to cold, since this is * the next step along. */ state->sysreset_allowed[SYSRESET_COLD] = true; ut_asserteq(-EINPROGRESS, sysreset_walk(SYSRESET_WARM)); ut_asserteq(-EINPROGRESS, sysreset_walk(SYSRESET_COLD)); ut_asserteq(-EACCES, sysreset_walk(SYSRESET_POWER)); state->sysreset_allowed[SYSRESET_COLD] = false; state->sysreset_allowed[SYSRESET_POWER] = true; return 0; }
int os_find_u_boot(char *fname, int maxlen) { struct sandbox_state *state = state_get_current(); const char *progname = state->argv[0]; int len = strlen(progname); const char *suffix; char *p; int fd; if (len >= maxlen || len < 4) return -ENOSPC; strcpy(fname, progname); suffix = fname + len - 4; /* If we are TPL, boot to SPL */ if (!strcmp(suffix, "-tpl")) { fname[len - 3] = 's'; fd = os_open(fname, O_RDONLY); if (fd >= 0) { close(fd); return 0; } /* Look for 'u-boot-tpl' in the tpl/ directory */ p = strstr(fname, "/tpl/"); if (p) { p[1] = 's'; fd = os_open(fname, O_RDONLY); if (fd >= 0) { close(fd); return 0; } } return -ENOENT; } /* Look for 'u-boot' in the same directory as 'u-boot-spl' */ if (!strcmp(suffix, "-spl")) { fname[len - 4] = '\0'; fd = os_open(fname, O_RDONLY); if (fd >= 0) { close(fd); return 0; } } /* Look for 'u-boot' in the parent directory of spl/ */ p = strstr(fname, "/spl/"); if (p) { strcpy(p, p + 4); fd = os_open(fname, O_RDONLY); if (fd >= 0) { close(fd); return 0; } } return -ENOENT; }
int sandbox_sdl_init_display(int width, int height, int log2_bpp) { struct sandbox_state *state = state_get_current(); int err; if (!width || !state->show_lcd) return 0; err = sandbox_sdl_ensure_init(); if (err) return err; if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { printf("Unable to initialize SDL LCD: %s\n", SDL_GetError()); return -EPERM; } SDL_WM_SetCaption("U-Boot", "U-Boot"); sdl.width = width; sdl.height = height; sdl.depth = 1 << log2_bpp; sdl.pitch = sdl.width * sdl.depth / 8; sdl.screen = SDL_SetVideoMode(width, height, 0, 0); sandbox_sdl_poll_events(); return 0; }
/* Test that we can use particular sysreset devices */ static int dm_test_sysreset_base(struct unit_test_state *uts) { struct sandbox_state *state = state_get_current(); struct udevice *dev; /* Device 0 is the platform data device - it should never respond */ ut_assertok(uclass_get_device(UCLASS_SYSRESET, 0, &dev)); ut_asserteq(-ENODEV, sysreset_request(dev, SYSRESET_WARM)); ut_asserteq(-ENODEV, sysreset_request(dev, SYSRESET_COLD)); ut_asserteq(-ENODEV, sysreset_request(dev, SYSRESET_POWER)); /* Device 1 is the warm sysreset device */ ut_assertok(uclass_get_device(UCLASS_SYSRESET, 1, &dev)); ut_asserteq(-EACCES, sysreset_request(dev, SYSRESET_WARM)); ut_asserteq(-ENOSYS, sysreset_request(dev, SYSRESET_COLD)); ut_asserteq(-ENOSYS, sysreset_request(dev, SYSRESET_POWER)); state->sysreset_allowed[SYSRESET_WARM] = true; ut_asserteq(-EINPROGRESS, sysreset_request(dev, SYSRESET_WARM)); state->sysreset_allowed[SYSRESET_WARM] = false; /* Device 2 is the cold sysreset device */ ut_assertok(uclass_get_device(UCLASS_SYSRESET, 2, &dev)); ut_asserteq(-ENOSYS, sysreset_request(dev, SYSRESET_WARM)); ut_asserteq(-EACCES, sysreset_request(dev, SYSRESET_COLD)); state->sysreset_allowed[SYSRESET_POWER] = false; ut_asserteq(-EACCES, sysreset_request(dev, SYSRESET_POWER)); state->sysreset_allowed[SYSRESET_POWER] = true; return 0; }
/* Test that sandbox SPI works correctly */ static int dm_test_spi_xfer(struct dm_test_state *dms) { struct spi_slave *slave; struct udevice *bus; const int busnum = 0, cs = 0, mode = 0; const char dout[5] = {0x9f}; unsigned char din[5]; ut_assertok(spi_get_bus_and_cs(busnum, cs, 1000000, mode, NULL, 0, &bus, &slave)); ut_assertok(spi_claim_bus(slave)); ut_assertok(spi_xfer(slave, 40, dout, din, SPI_XFER_BEGIN | SPI_XFER_END)); ut_asserteq(0xff, din[0]); ut_asserteq(0x20, din[1]); ut_asserteq(0x20, din[2]); ut_asserteq(0x15, din[3]); spi_release_bus(slave); /* * Since we are about to destroy all devices, we must tell sandbox * to forget the emulation device */ #ifdef CONFIG_DM_SPI_FLASH sandbox_sf_unbind_emul(state_get_current(), busnum, cs); #endif return 0; }
static int sandbox_wdt_stop(struct udevice *dev) { struct sandbox_state *state = state_get_current(); state->wdt.running = false; return 0; }
static int sandbox_wdt_reset(struct udevice *dev) { struct sandbox_state *state = state_get_current(); state->wdt.reset_count++; return 0; }
static int setup_ram_buf(void) { struct sandbox_state *state = state_get_current(); gd->arch.ram_buf = state->ram_buf; gd->ram_size = state->ram_size; return 0; }
static int sandbox_wdt_start(struct udevice *dev, u64 timeout, ulong flags) { struct sandbox_state *state = state_get_current(); state->wdt.counter = timeout; state->wdt.running = true; return 0; }
int sandbox_main_loop_init(void) { struct sandbox_state *state = state_get_current(); /* Execute command if required */ if (state->cmd) { run_command_list(state->cmd, -1, 0); os_exit(state->exit_type); } return 0; }
int os_jump_to_image(const void *dest, int size) { struct sandbox_state *state = state_get_current(); char fname[30], mem_fname[30]; int fd, err; const char *extra_args[5]; char **argv = state->argv; #ifdef DEBUG int argc, i; #endif err = make_exec(fname, dest, size); if (err) return err; strcpy(mem_fname, "/tmp/u-boot.mem.XXXXXX"); fd = mkstemp(mem_fname); if (fd < 0) return -ENOENT; close(fd); err = os_write_ram_buf(mem_fname); if (err) return err; os_fd_restore(); extra_args[0] = "-j"; extra_args[1] = fname; extra_args[2] = "-m"; extra_args[3] = mem_fname; extra_args[4] = "--rm_memory"; err = add_args(&argv, extra_args, sizeof(extra_args) / sizeof(extra_args[0])); if (err) return err; #ifdef DEBUG for (i = 0; argv[i]; i++) printf("%d %s\n", i, argv[i]); #endif if (state_uninit()) os_exit(2); err = execv(fname, argv); free(argv); if (err) return err; return unlink(fname); }
int os_spl_to_uboot(const char *fname) { struct sandbox_state *state = state_get_current(); char *argv[state->argc + 1]; int ret; memcpy(argv, state->argv, sizeof(char *) * (state->argc + 1)); argv[0] = (char *)fname; ret = execv(fname, argv); if (ret) return ret; return unlink(fname); }
int sandbox_early_getopt_check(void) { struct sandbox_state *state = state_get_current(); struct sandbox_cmdline_option **sb_opt = __u_boot_sandbox_option_start; size_t num_options = __u_boot_sandbox_option_count(); size_t i; int max_arg_len, max_noarg_len; /* parse_err will be a string of the faulting option */ if (!state->parse_err) return 0; if (strcmp(state->parse_err, "help")) { printf("u-boot: error: failed while parsing option: %s\n" "\ttry running with --help for more information.\n", state->parse_err); os_exit(1); } printf( "u-boot, a command line test interface to U-Boot\n\n" "Usage: u-boot [options]\n" "Options:\n"); max_arg_len = 0; for (i = 0; i < num_options; ++i) max_arg_len = max((int)strlen(sb_opt[i]->flag), max_arg_len); max_noarg_len = max_arg_len + 7; for (i = 0; i < num_options; ++i) { struct sandbox_cmdline_option *opt = sb_opt[i]; /* first output the short flag if it has one */ if (opt->flag_short >= 0x100) printf(" "); else printf(" -%c, ", opt->flag_short); /* then the long flag */ if (opt->has_arg) printf("--%-*s <arg> ", max_arg_len, opt->flag); else printf("--%-*s", max_noarg_len, opt->flag); /* finally the help text */ printf(" %s\n", opt->help); } os_exit(0); }
int os_write_ram_buf(const char *fname) { struct sandbox_state *state = state_get_current(); int fd, ret; fd = open(fname, O_CREAT | O_WRONLY, 0777); if (fd < 0) return -ENOENT; ret = write(fd, state->ram_buf, state->ram_size); close(fd); if (ret != state->ram_size) return -EIO; return 0; }
/* Get ready for testing */ static int dm_test_init(struct unit_test_state *uts, bool of_live) { struct dm_test_state *dms = uts->priv; memset(dms, '\0', sizeof(*dms)); gd->dm_root = NULL; memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); state_reset_for_test(state_get_current()); #ifdef CONFIG_OF_LIVE /* Determine whether to make the live tree available */ gd->of_root = of_live ? uts->of_root : NULL; #endif ut_assertok(dm_init(of_live)); dms->root = dm_root(); return 0; }
int main(int argc, char *argv[]) { struct sandbox_state *state; gd_t data; int ret; ret = state_init(); if (ret) goto err; state = state_get_current(); if (os_parse_args(state, argc, argv)) return 1; ret = sandbox_read_state(state, state->state_fname); if (ret) goto err; /* Remove old memory file if required */ if (state->ram_buf_rm && state->ram_buf_fname) os_unlink(state->ram_buf_fname); memset(&data, '\0', sizeof(data)); gd = &data; #if CONFIG_VAL(SYS_MALLOC_F_LEN) gd->malloc_base = CONFIG_MALLOC_F_ADDR; #endif setup_ram_buf(state); /* Do pre- and post-relocation init */ board_init_f(0); board_init_r(gd->new_gd, 0); /* NOTREACHED - board_init_r() does not return */ return 0; err: printf("Error %d\n", ret); return 1; }
int main(int argc, char *argv[]) { struct sandbox_state *state; int err; err = state_init(); if (err) return err; state = state_get_current(); if (os_parse_args(state, argc, argv)) return 1; /* * Do pre- and post-relocation init, then start up U-Boot. This will * never return. */ board_init_f(0); /* NOTREACHED - board_init_f() does not return */ return 0; }
int sandbox_read_fdt_from_file(void) { struct sandbox_state *state = state_get_current(); const char *fname = state->fdt_fname; void *blob; loff_t size; int err; int fd; blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0); if (!state->fdt_fname) { err = fdt_create_empty_tree(blob, 256); if (!err) goto done; printf("Unable to create empty FDT: %s\n", fdt_strerror(err)); return -EINVAL; } err = os_get_filesize(fname, &size); if (err < 0) { printf("Failed to file FDT file '%s'\n", fname); return err; } fd = os_open(fname, OS_O_RDONLY); if (fd < 0) { printf("Failed to open FDT file '%s'\n", fname); return -EACCES; } if (os_read(fd, blob, size) != size) { os_close(fd); return -EIO; } os_close(fd); done: gd->fdt_blob = blob; return 0; }
int os_read_ram_buf(const char *fname) { struct sandbox_state *state = state_get_current(); int fd, ret; loff_t size; ret = os_get_filesize(fname, &size); if (ret < 0) return ret; if (size != state->ram_size) return -ENOSPC; fd = open(fname, O_RDONLY); if (fd < 0) return -ENOENT; ret = read(fd, state->ram_buf, state->ram_size); close(fd); if (ret != state->ram_size) return -EIO; return 0; }
int sandbox_main_loop_init(void) { struct sandbox_state *state = state_get_current(); /* Execute command if required */ if (state->cmd || state->run_distro_boot) { int retval = 0; cli_init(); #ifdef CONFIG_CMDLINE if (state->cmd) retval = run_command_list(state->cmd, -1, 0); if (state->run_distro_boot) retval = cli_simple_run_command("run distro_bootcmd", 0); #endif if (!state->interactive) os_exit(retval); } return 0; }
/** * This is a very strange probe function. If it has platform data (which may * have come from the device tree) then this function gets the filename and * device type from there. */ static int sandbox_sf_probe(struct udevice *dev) { /* spec = idcode:file */ struct sandbox_spi_flash *sbsf = dev_get_priv(dev); size_t len, idname_len; const struct flash_info *data; struct sandbox_spi_flash_plat_data *pdata = dev_get_platdata(dev); struct sandbox_state *state = state_get_current(); struct dm_spi_slave_platdata *slave_plat; struct udevice *bus = dev->parent; const char *spec = NULL; struct udevice *emul; int ret = 0; int cs = -1; debug("%s: bus %d, looking for emul=%p: ", __func__, bus->seq, dev); ret = sandbox_spi_get_emul(state, bus, dev, &emul); if (ret) { printf("Error: Unknown chip select for device '%s'\n", dev->name); return ret; } slave_plat = dev_get_parent_platdata(dev); cs = slave_plat->cs; debug("found at cs %d\n", cs); if (!pdata->filename) { printf("Error: No filename available\n"); return -EINVAL; } spec = strchr(pdata->device_name, ','); if (spec) spec++; else spec = pdata->device_name; idname_len = strlen(spec); debug("%s: device='%s'\n", __func__, spec); for (data = spi_nor_ids; data->name; data++) { len = strlen(data->name); if (idname_len != len) continue; if (!strncasecmp(spec, data->name, len)) break; } if (!data->name) { printf("%s: unknown flash '%*s'\n", __func__, (int)idname_len, spec); ret = -EINVAL; goto error; } if (sandbox_sf_0xff[0] == 0x00) memset(sandbox_sf_0xff, 0xff, sizeof(sandbox_sf_0xff)); sbsf->fd = os_open(pdata->filename, 02); if (sbsf->fd == -1) { printf("%s: unable to open file '%s'\n", __func__, pdata->filename); ret = -EIO; goto error; } sbsf->data = data; sbsf->cs = cs; return 0; error: debug("%s: Got error %d\n", __func__, ret); return ret; }
void state_set_skip_delays(bool skip_delays) { struct sandbox_state *state = state_get_current(); state->skip_delays = skip_delays; }
bool state_get_skip_delays(void) { struct sandbox_state *state = state_get_current(); return state->skip_delays; }
/** * This is a very strange probe function. If it has platform data (which may * have come from the device tree) then this function gets the filename and * device type from there. Failing that it looks at the command line * parameter. */ static int sandbox_sf_probe(struct udevice *dev) { /* spec = idcode:file */ struct sandbox_spi_flash *sbsf = dev_get_priv(dev); const char *file; size_t len, idname_len; const struct spi_flash_params *data; struct sandbox_spi_flash_plat_data *pdata = dev_get_platdata(dev); struct sandbox_state *state = state_get_current(); struct udevice *bus = dev->parent; const char *spec = NULL; int ret = 0; int cs = -1; int i; debug("%s: bus %d, looking for emul=%p: ", __func__, bus->seq, dev); if (bus->seq >= 0 && bus->seq < CONFIG_SANDBOX_SPI_MAX_BUS) { for (i = 0; i < CONFIG_SANDBOX_SPI_MAX_CS; i++) { if (state->spi[bus->seq][i].emul == dev) cs = i; } } if (cs == -1) { printf("Error: Unknown chip select for device '%s'\n", dev->name); return -EINVAL; } debug("found at cs %d\n", cs); if (!pdata->filename) { struct sandbox_state *state = state_get_current(); assert(bus->seq != -1); if (bus->seq < CONFIG_SANDBOX_SPI_MAX_BUS) spec = state->spi[bus->seq][cs].spec; if (!spec) { debug("%s: No spec found for bus %d, cs %d\n", __func__, bus->seq, cs); ret = -ENOENT; goto error; } file = strchr(spec, ':'); if (!file) { printf("%s: unable to parse file\n", __func__); ret = -EINVAL; goto error; } idname_len = file - spec; pdata->filename = file + 1; pdata->device_name = spec; ++file; } else { spec = strchr(pdata->device_name, ','); if (spec) spec++; else spec = pdata->device_name; idname_len = strlen(spec); } debug("%s: device='%s'\n", __func__, spec); for (data = spi_flash_params_table; data->name; data++) { len = strlen(data->name); if (idname_len != len) continue; if (!strncasecmp(spec, data->name, len)) break; } if (!data->name) { printf("%s: unknown flash '%*s'\n", __func__, (int)idname_len, spec); ret = -EINVAL; goto error; } if (sandbox_sf_0xff[0] == 0x00) memset(sandbox_sf_0xff, 0xff, sizeof(sandbox_sf_0xff)); sbsf->fd = os_open(pdata->filename, 02); if (sbsf->fd == -1) { printf("%s: unable to open file '%s'\n", __func__, pdata->filename); ret = -EIO; goto error; } sbsf->data = data; sbsf->cs = cs; return 0; error: debug("%s: Got error %d\n", __func__, ret); return ret; }
static int sandbox_spi_xfer(struct udevice *slave, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { struct udevice *bus = slave->parent; struct sandbox_state *state = state_get_current(); struct dm_spi_emul_ops *ops; struct udevice *emul; uint bytes = bitlen / 8, i; int ret; u8 *tx = (void *)dout, *rx = din; uint busnum, cs; if (bitlen == 0) return 0; /* we can only do 8 bit transfers */ if (bitlen % 8) { printf("sandbox_spi: xfer: invalid bitlen size %u; needs to be 8bit\n", bitlen); return -EINVAL; } busnum = bus->seq; cs = spi_chip_select(slave); if (busnum >= CONFIG_SANDBOX_SPI_MAX_BUS || cs >= CONFIG_SANDBOX_SPI_MAX_CS) { printf("%s: busnum=%u, cs=%u: out of range\n", __func__, busnum, cs); return -ENOENT; } ret = sandbox_spi_get_emul(state, bus, slave, &emul); if (ret) { printf("%s: busnum=%u, cs=%u: no emulation available (err=%d)\n", __func__, busnum, cs, ret); return -ENOENT; } ret = device_probe(emul); if (ret) return ret; /* make sure rx/tx buffers are full so clients can assume */ if (!tx) { debug("sandbox_spi: xfer: auto-allocating tx scratch buffer\n"); tx = malloc(bytes); if (!tx) { debug("sandbox_spi: Out of memory\n"); return -ENOMEM; } } if (!rx) { debug("sandbox_spi: xfer: auto-allocating rx scratch buffer\n"); rx = malloc(bytes); if (!rx) { debug("sandbox_spi: Out of memory\n"); return -ENOMEM; } } ops = spi_emul_get_ops(emul); ret = ops->xfer(emul, bitlen, dout, din, flags); debug("sandbox_spi: xfer: got back %i (that's %s)\n rx:", ret, ret ? "bad" : "good"); for (i = 0; i < bytes; ++i) debug(" %u:%02x", i, rx[i]); debug("\n"); if (tx != dout) free(tx); if (rx != din) free(rx); return ret; }
/* Test that we can find buses and chip-selects */ static int dm_test_spi_find(struct dm_test_state *dms) { struct sandbox_state *state = state_get_current(); struct spi_slave *slave; struct udevice *bus, *dev; const int busnum = 0, cs = 0, mode = 0, speed = 1000000, cs_b = 1; struct spi_cs_info info; int of_offset; ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_SPI, busnum, false, &bus)); /* * spi_post_bind() will bind devices to chip selects. Check this then * remove the emulation and the slave device. */ ut_asserteq(0, uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus)); ut_assertok(spi_cs_info(bus, cs, &info)); of_offset = info.dev->of_offset; device_remove(info.dev); device_unbind(info.dev); /* * Even though the device is gone, the sandbox SPI drivers always * reports that CS 0 is present */ ut_assertok(spi_cs_info(bus, cs, &info)); ut_asserteq_ptr(NULL, info.dev); /* This finds nothing because we removed the device */ ut_asserteq(-ENODEV, spi_find_bus_and_cs(busnum, cs, &bus, &dev)); ut_asserteq(-ENODEV, spi_get_bus_and_cs(busnum, cs, speed, mode, NULL, 0, &bus, &slave)); /* * This forces the device to be re-added, but there is no emulation * connected so the probe will fail. We require that bus is left * alone on failure, and that the spi_get_bus_and_cs() does not add * a 'partially-inited' device. */ ut_asserteq(-ENODEV, spi_find_bus_and_cs(busnum, cs, &bus, &dev)); ut_asserteq(-ENOENT, spi_get_bus_and_cs(busnum, cs, speed, mode, "spi_flash_std", "name", &bus, &slave)); sandbox_sf_unbind_emul(state_get_current(), busnum, cs); ut_assertok(spi_cs_info(bus, cs, &info)); ut_asserteq_ptr(NULL, info.dev); /* Add the emulation and try again */ ut_assertok(sandbox_sf_bind_emul(state, busnum, cs, bus, of_offset, "name")); ut_assertok(spi_find_bus_and_cs(busnum, cs, &bus, &dev)); ut_assertok(spi_get_bus_and_cs(busnum, cs, speed, mode, "spi_flash_std", "name", &bus, &slave)); ut_assertok(spi_cs_info(bus, cs, &info)); ut_asserteq_ptr(info.dev, slave->dev); /* We should be able to add something to another chip select */ ut_assertok(sandbox_sf_bind_emul(state, busnum, cs_b, bus, of_offset, "name")); ut_assertok(spi_get_bus_and_cs(busnum, cs_b, speed, mode, "spi_flash_std", "name", &bus, &slave)); ut_assertok(spi_cs_info(bus, cs_b, &info)); ut_asserteq_ptr(info.dev, slave->dev); /* * Since we are about to destroy all devices, we must tell sandbox * to forget the emulation device */ sandbox_sf_unbind_emul(state_get_current(), busnum, cs); sandbox_sf_unbind_emul(state_get_current(), busnum, cs_b); return 0; }