|
13 | 13 | #include <stats/stats.h>
|
14 | 14 | #include <string.h>
|
15 | 15 |
|
| 16 | +#ifdef CONFIG_ARCH_POSIX |
| 17 | + |
| 18 | +#include <unistd.h> |
| 19 | +#include <sys/types.h> |
| 20 | +#include <sys/stat.h> |
| 21 | +#include <sys/mman.h> |
| 22 | +#include <fcntl.h> |
| 23 | +#include <errno.h> |
| 24 | + |
| 25 | +#include "cmdline.h" |
| 26 | +#include "soc.h" |
| 27 | + |
| 28 | +#endif /* CONFIG_ARCH_POSIX */ |
| 29 | + |
16 | 30 | /* configuration derived from DT */
|
| 31 | +#ifdef CONFIG_ARCH_POSIX |
| 32 | +#define FLASH_SIMULATOR_BASE_OFFSET DT_FLASH_BASE_ADDRESS |
| 33 | +#define FLASH_SIMULATOR_ERASE_UNIT DT_FLASH_ERASE_BLOCK_SIZE |
| 34 | +#define FLASH_SIMULATOR_PROG_UNIT DT_FLASH_WRITE_BLOCK_SIZE |
| 35 | +#define FLASH_SIMULATOR_FLASH_SIZE (DT_FLASH_SIZE * 1024) |
| 36 | +#define FLASH_SIMULATOR_DEV_NAME DT_FLASH_DEV_NAME |
| 37 | +#else |
17 | 38 | #define FLASH_SIMULATOR_BASE_OFFSET DT_FLASH_SIM_BASE_ADDRESS
|
18 | 39 | #define FLASH_SIMULATOR_ERASE_UNIT DT_FLASH_SIM_ERASE_BLOCK_SIZE
|
19 | 40 | #define FLASH_SIMULATOR_PROG_UNIT DT_FLASH_SIM_WRITE_BLOCK_SIZE
|
20 | 41 | #define FLASH_SIMULATOR_FLASH_SIZE DT_FLASH_SIM_SIZE
|
| 42 | +#define FLASH_SIMULATOR_DEV_NAME "FLASH_SIMULATOR" |
| 43 | +#endif /* CONFIG_ARCH_POSIX */ |
21 | 44 |
|
22 | 45 | #define FLASH_SIMULATOR_PAGE_COUNT (FLASH_SIMULATOR_FLASH_SIZE / \
|
23 | 46 | FLASH_SIMULATOR_ERASE_UNIT)
|
@@ -102,7 +125,15 @@ STATS_NAME(flash_sim_thresholds, max_erase_calls)
|
102 | 125 | STATS_NAME(flash_sim_thresholds, max_len)
|
103 | 126 | STATS_NAME_END(flash_sim_thresholds);
|
104 | 127 |
|
| 128 | +#ifdef CONFIG_ARCH_POSIX |
| 129 | +static u8_t *mock_flash; |
| 130 | +static int flash_fd = -1; |
| 131 | +static const char *flash_file_path; |
| 132 | +static const char default_flash_file_path[] = "flash.bin"; |
| 133 | +#else |
105 | 134 | static u8_t mock_flash[FLASH_SIMULATOR_FLASH_SIZE];
|
| 135 | +#endif /* CONFIG_ARCH_POSIX */ |
| 136 | + |
106 | 137 | static bool write_protection;
|
107 | 138 |
|
108 | 139 | static const struct flash_driver_api flash_sim_api;
|
@@ -322,16 +353,96 @@ static const struct flash_driver_api flash_sim_api = {
|
322 | 353 | #endif
|
323 | 354 | };
|
324 | 355 |
|
| 356 | +#ifdef CONFIG_ARCH_POSIX |
| 357 | + |
| 358 | +static int flash_mock_init(struct device *dev) |
| 359 | +{ |
| 360 | + if (flash_file_path == NULL) { |
| 361 | + flash_file_path = default_flash_file_path; |
| 362 | + } |
| 363 | + |
| 364 | + flash_fd = open(flash_file_path, O_RDWR | O_CREAT, (mode_t)0600); |
| 365 | + if (flash_fd == -1) { |
| 366 | + posix_print_warning("Failed to open flash device file " |
| 367 | + "%s: %s\n", |
| 368 | + flash_file_path, strerror(errno)); |
| 369 | + return -EIO; |
| 370 | + } |
| 371 | + |
| 372 | + if (ftruncate(flash_fd, FLASH_SIMULATOR_FLASH_SIZE) == -1) { |
| 373 | + posix_print_warning("Failed to resize flash device file " |
| 374 | + "%s: %s\n", |
| 375 | + flash_file_path, strerror(errno)); |
| 376 | + return -EIO; |
| 377 | + } |
| 378 | + |
| 379 | + mock_flash = mmap(NULL, FLASH_SIMULATOR_FLASH_SIZE, |
| 380 | + PROT_WRITE | PROT_READ, MAP_SHARED, flash_fd, 0); |
| 381 | + if (mock_flash == MAP_FAILED) { |
| 382 | + posix_print_warning("Failed to mmap flash device file " |
| 383 | + "%s: %s\n", |
| 384 | + flash_file_path, strerror(errno)); |
| 385 | + return -EIO; |
| 386 | + } |
| 387 | + |
| 388 | + return 0; |
| 389 | +} |
| 390 | + |
| 391 | +#else |
| 392 | + |
| 393 | +static int flash_mock_init(struct device *dev) |
| 394 | +{ |
| 395 | + memset(mock_flash, 0xFF, ARRAY_SIZE(mock_flash)); |
| 396 | + return 0; |
| 397 | +} |
| 398 | + |
| 399 | +#endif /* CONFIG_ARCH_POSIX */ |
| 400 | + |
325 | 401 | static int flash_init(struct device *dev)
|
326 | 402 | {
|
327 | 403 | STATS_INIT_AND_REG(flash_sim_stats, STATS_SIZE_32, "flash_sim_stats");
|
328 | 404 | STATS_INIT_AND_REG(flash_sim_thresholds, STATS_SIZE_32,
|
329 | 405 | "flash_sim_thresholds");
|
330 |
| - memset(mock_flash, 0xFF, ARRAY_SIZE(mock_flash)); |
331 |
| - |
332 |
| - return 0; |
| 406 | + return flash_mock_init(dev); |
333 | 407 | }
|
334 | 408 |
|
335 |
| -DEVICE_AND_API_INIT(flash_simulator, "FLASH_SIMULATOR", flash_init, NULL, NULL, |
336 |
| - POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, |
| 409 | +DEVICE_AND_API_INIT(flash_simulator, FLASH_SIMULATOR_DEV_NAME, flash_init, |
| 410 | + NULL, NULL, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, |
337 | 411 | &flash_sim_api);
|
| 412 | + |
| 413 | +#ifdef CONFIG_ARCH_POSIX |
| 414 | + |
| 415 | +static void flash_native_posix_cleanup(void) |
| 416 | +{ |
| 417 | + if ((mock_flash != MAP_FAILED) && (mock_flash != NULL)) { |
| 418 | + munmap(mock_flash, FLASH_SIMULATOR_FLASH_SIZE); |
| 419 | + } |
| 420 | + |
| 421 | + if (flash_fd != -1) { |
| 422 | + close(flash_fd); |
| 423 | + } |
| 424 | +} |
| 425 | + |
| 426 | +static void flash_native_posix_options(void) |
| 427 | +{ |
| 428 | + static struct args_struct_t flash_options[] = { |
| 429 | + { .manual = false, |
| 430 | + .is_mandatory = false, |
| 431 | + .is_switch = false, |
| 432 | + .option = "flash", |
| 433 | + .name = "path", |
| 434 | + .type = 's', |
| 435 | + .dest = (void *)&flash_file_path, |
| 436 | + .call_when_found = NULL, |
| 437 | + .descript = "Path to binary file to be used as flash" }, |
| 438 | + ARG_TABLE_ENDMARKER |
| 439 | + }; |
| 440 | + |
| 441 | + native_add_command_line_opts(flash_options); |
| 442 | +} |
| 443 | + |
| 444 | + |
| 445 | +NATIVE_TASK(flash_native_posix_options, PRE_BOOT_1, 1); |
| 446 | +NATIVE_TASK(flash_native_posix_cleanup, ON_EXIT, 1); |
| 447 | + |
| 448 | +#endif /* CONFIG_ARCH_POSIX */ |
0 commit comments