diff --git a/doc/classic_cli_manpage.rst b/doc/classic_cli_manpage.rst index e2ce68472..c8aa61f09 100644 --- a/doc/classic_cli_manpage.rst +++ b/doc/classic_cli_manpage.rst @@ -616,6 +616,18 @@ Example:: syntax where ``state`` is ``yes`` or ``no`` (default value). ``yes`` means active state of the pin implies that chip is write-protected (on real hardware the pin is usually negated, but not here). +**Frequency** + Frequency can be specified in ``Hz`` (default), ``KHz``, or ``MHz`` (not case sensitive). + If ``freq`` parameter is passed in from command line, commands will delay for certain time before returning, + so that to emulate the requested frequency. + + Valid range is [1Hz, 8000Mhz] and there is no delay by default. + + The delay of an SPI command is proportional to the number of bits send over SPI bus in both directions + and is calculated based on the assumption that we transfer at 1 bit/Hz:: + + flashrom -p dummy:emulate=W25Q128FV,freq=64mhz + nic3com, nicrealtek, nicnatsemi, nicintel, nicintel_eeprom, nicintel_spi, gfxnvidia, ogp_spi, drkaiser, satasii, satamv, atahpt, atavia, atapromise, it8212 programmers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/dummyflasher.c b/dummyflasher.c index cf4ca03b9..ef49f48f9 100644 --- a/dummyflasher.c +++ b/dummyflasher.c @@ -55,7 +55,7 @@ struct emu_data { uint8_t emu_status_len; /* number of emulated status registers */ /* If "freq" parameter is passed in from command line, commands will delay * for this period before returning. */ - unsigned long int delay_us; + unsigned long long delay_ns; unsigned int emu_max_byteprogram_size; unsigned int emu_max_aai_size; unsigned int emu_jedec_se_size; @@ -901,7 +901,7 @@ static int dummy_spi_send_command(const struct flashctx *flash, unsigned int wri msg_pspew(" 0x%02x", readarr[i]); msg_pspew("\n"); - default_delay((writecnt + readcnt) * emu_data->delay_us); + default_delay(((writecnt + readcnt) * emu_data->delay_ns) / 1000); return 0; } @@ -1128,7 +1128,7 @@ static int init_data(const struct programmer_cfg *cfg, /* frequency to emulate in Hz (default), KHz, or MHz */ tmp = extract_programmer_param_str(cfg, "freq"); if (tmp) { - unsigned long int freq; + unsigned long long freq; char *units = tmp; char *end = tmp + strlen(tmp); @@ -1166,13 +1166,13 @@ static int init_data(const struct programmer_cfg *cfg, } } - if (freq == 0) { - msg_perr("%s: invalid value 0 for freq parameter\n", __func__); + if (freq == 0 || freq > 8000000000) { + msg_perr("%s: invalid value %llu for freq parameter\n", __func__, freq); free(tmp); return 1; } /* Assume we only work with bytes and transfer at 1 bit/Hz */ - data->delay_us = (1000000 * 8) / freq; + data->delay_ns = (1000000000ull * 8) / freq; } free(tmp); @@ -1402,7 +1402,7 @@ static int dummy_init(const struct programmer_cfg *cfg) return 1; } data->emu_chip = EMULATE_NONE; - data->delay_us = 0; + data->delay_ns = 0; data->spi_write_256_chunksize = 256; msg_pspew("%s\n", __func__); diff --git a/tests/dummyflasher.c b/tests/dummyflasher.c index 052938bec..9878bef70 100644 --- a/tests/dummyflasher.c +++ b/tests/dummyflasher.c @@ -141,6 +141,25 @@ void dummy_all_buses_test_success(void **state) run_basic_lifecycle(state, &dummy_io, &programmer_dummy, "bus=parallel+lpc+spi"); } +void dummy_freq_param_init(void **state) +{ + struct io_mock_fallback_open_state dummy_fallback_open_state = { + .noc = 0, + .paths = { NULL }, + }; + const struct io_mock dummy_io = { + .fallback_open_state = &dummy_fallback_open_state, + }; + + run_basic_lifecycle(state, &dummy_io, &programmer_dummy, "bus=spi,freq=12Hz"); + run_basic_lifecycle(state, &dummy_io, &programmer_dummy, "bus=spi,freq=123KHz"); + run_basic_lifecycle(state, &dummy_io, &programmer_dummy, "bus=spi,freq=345MHz"); + run_basic_lifecycle(state, &dummy_io, &programmer_dummy, "bus=spi,freq=8000MHz"); + /* Valid values for freq param are within the range [1Hz, 8000Mhz] */ + run_init_error_path(state, &dummy_io, &programmer_dummy, "bus=spi,freq=0Hz", 0x1); + run_init_error_path(state, &dummy_io, &programmer_dummy, "bus=spi,freq=8001Mhz", 0x1); +} + #else SKIP_TEST(dummy_basic_lifecycle_test_success) SKIP_TEST(dummy_probe_lifecycle_test_success) @@ -150,4 +169,5 @@ void dummy_all_buses_test_success(void **state) SKIP_TEST(dummy_init_success_unhandled_param_test_success) SKIP_TEST(dummy_null_prog_param_test_success) SKIP_TEST(dummy_all_buses_test_success) + SKIP_TEST(dummy_freq_param_init) #endif /* CONFIG_DUMMY */ diff --git a/tests/tests.c b/tests/tests.c index 78f1b4772..8a9dc6b4f 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -461,6 +461,7 @@ int main(int argc, char *argv[]) cmocka_unit_test(dummy_init_success_unhandled_param_test_success), cmocka_unit_test(dummy_null_prog_param_test_success), cmocka_unit_test(dummy_all_buses_test_success), + cmocka_unit_test(dummy_freq_param_init), cmocka_unit_test(nicrealtek_basic_lifecycle_test_success), cmocka_unit_test(raiden_debug_basic_lifecycle_test_success), cmocka_unit_test(raiden_debug_targetAP_basic_lifecycle_test_success), diff --git a/tests/tests.h b/tests/tests.h index 3536d1d12..100bda1bc 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -53,6 +53,7 @@ void dummy_init_success_invalid_param_test_success(void **state); void dummy_init_success_unhandled_param_test_success(void **state); void dummy_null_prog_param_test_success(void **state); void dummy_all_buses_test_success(void **state); +void dummy_freq_param_init(void **state); void nicrealtek_basic_lifecycle_test_success(void **state); void raiden_debug_basic_lifecycle_test_success(void **state); void raiden_debug_targetAP_basic_lifecycle_test_success(void **state);