state.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2011-2012 The Chromium OS Authors.
  4. */
  5. #include <common.h>
  6. #include <autoboot.h>
  7. #include <bloblist.h>
  8. #include <errno.h>
  9. #include <fdtdec.h>
  10. #include <log.h>
  11. #include <os.h>
  12. #include <trace.h>
  13. #include <asm/malloc.h>
  14. #include <asm/state.h>
  15. #include <asm/test.h>
  16. /* Main state record for the sandbox */
  17. static struct sandbox_state main_state;
  18. static struct sandbox_state *state; /* Pointer to current state record */
  19. static int state_ensure_space(int extra_size)
  20. {
  21. void *blob = state->state_fdt;
  22. int used, size, free_bytes;
  23. void *buf;
  24. int ret;
  25. used = fdt_off_dt_strings(blob) + fdt_size_dt_strings(blob);
  26. size = fdt_totalsize(blob);
  27. free_bytes = size - used;
  28. if (free_bytes > extra_size)
  29. return 0;
  30. size = used + extra_size;
  31. buf = os_malloc(size);
  32. if (!buf)
  33. return -ENOMEM;
  34. ret = fdt_open_into(blob, buf, size);
  35. if (ret) {
  36. os_free(buf);
  37. return -EIO;
  38. }
  39. os_free(blob);
  40. state->state_fdt = buf;
  41. return 0;
  42. }
  43. static int state_read_file(struct sandbox_state *state, const char *fname)
  44. {
  45. loff_t size;
  46. int ret;
  47. int fd;
  48. ret = os_get_filesize(fname, &size);
  49. if (ret < 0) {
  50. printf("Cannot find sandbox state file '%s'\n", fname);
  51. return -ENOENT;
  52. }
  53. state->state_fdt = os_malloc(size);
  54. if (!state->state_fdt) {
  55. puts("No memory to read sandbox state\n");
  56. return -ENOMEM;
  57. }
  58. fd = os_open(fname, OS_O_RDONLY);
  59. if (fd < 0) {
  60. printf("Cannot open sandbox state file '%s'\n", fname);
  61. ret = -EPERM;
  62. goto err_open;
  63. }
  64. if (os_read(fd, state->state_fdt, size) != size) {
  65. printf("Cannot read sandbox state file '%s'\n", fname);
  66. ret = -EIO;
  67. goto err_read;
  68. }
  69. os_close(fd);
  70. return 0;
  71. err_read:
  72. os_close(fd);
  73. err_open:
  74. /*
  75. * tainted scalar, since size is obtained from the file. But we can rely
  76. * on os_malloc() to handle invalid values.
  77. */
  78. os_free(state->state_fdt);
  79. state->state_fdt = NULL;
  80. return ret;
  81. }
  82. /***
  83. * sandbox_read_state_nodes() - Read state associated with a driver
  84. *
  85. * This looks through all compatible nodes and calls the read function on
  86. * each one, to read in the state.
  87. *
  88. * If nothing is found, it still calls the read function once, to set up a
  89. * single global state for that driver.
  90. *
  91. * @state: Sandbox state
  92. * @io: Method to use for reading state
  93. * @blob: FDT containing state
  94. * Return: 0 if OK, -EINVAL if the read function returned failure
  95. */
  96. int sandbox_read_state_nodes(struct sandbox_state *state,
  97. struct sandbox_state_io *io, const void *blob)
  98. {
  99. int count;
  100. int node;
  101. int ret;
  102. debug(" - read %s\n", io->name);
  103. if (!io->read)
  104. return 0;
  105. node = -1;
  106. count = 0;
  107. while (blob) {
  108. node = fdt_node_offset_by_compatible(blob, node, io->compat);
  109. if (node < 0)
  110. return 0; /* No more */
  111. debug(" - read node '%s'\n", fdt_get_name(blob, node, NULL));
  112. ret = io->read(blob, node);
  113. if (ret) {
  114. printf("Unable to read state for '%s'\n", io->compat);
  115. return -EINVAL;
  116. }
  117. count++;
  118. }
  119. /*
  120. * If we got no saved state, call the read function once without a
  121. * node, to set up the global state.
  122. */
  123. if (count == 0) {
  124. debug(" - read global\n");
  125. ret = io->read(NULL, -1);
  126. if (ret) {
  127. printf("Unable to read global state for '%s'\n",
  128. io->name);
  129. return -EINVAL;
  130. }
  131. }
  132. return 0;
  133. }
  134. int sandbox_read_state(struct sandbox_state *state, const char *fname)
  135. {
  136. struct sandbox_state_io *io;
  137. const void *blob;
  138. bool got_err;
  139. int ret;
  140. if (state->read_state && fname) {
  141. ret = state_read_file(state, fname);
  142. if (ret == -ENOENT && state->ignore_missing_state_on_read)
  143. ret = 0;
  144. if (ret)
  145. return ret;
  146. }
  147. /* Call all the state read functions */
  148. got_err = false;
  149. blob = state->state_fdt;
  150. io = ll_entry_start(struct sandbox_state_io, state_io);
  151. for (; io < ll_entry_end(struct sandbox_state_io, state_io); io++) {
  152. ret = sandbox_read_state_nodes(state, io, blob);
  153. if (ret < 0)
  154. got_err = true;
  155. }
  156. if (state->read_state && fname) {
  157. debug("Read sandbox state from '%s'%s\n", fname,
  158. got_err ? " (with errors)" : "");
  159. }
  160. return got_err ? -1 : 0;
  161. }
  162. /***
  163. * sandbox_write_state_node() - Write state associated with a driver
  164. *
  165. * This calls the write function to write out global state for that driver.
  166. *
  167. * TODO(sjg@chromium.org): Support writing out state from multiple drivers
  168. * of the same time. We don't need this yet,and it will be much easier to
  169. * do when driver model is available.
  170. *
  171. * @state: Sandbox state
  172. * @io: Method to use for writing state
  173. * Return: 0 if OK, -EIO if there is a fatal error (such as out of space
  174. * for adding the data), -EINVAL if the write function failed.
  175. */
  176. int sandbox_write_state_node(struct sandbox_state *state,
  177. struct sandbox_state_io *io)
  178. {
  179. void *blob;
  180. int node;
  181. int ret;
  182. if (!io->write)
  183. return 0;
  184. ret = state_ensure_space(SANDBOX_STATE_MIN_SPACE);
  185. if (ret) {
  186. printf("Failed to add more space for state\n");
  187. return -EIO;
  188. }
  189. /* The blob location can change when the size increases */
  190. blob = state->state_fdt;
  191. node = fdt_node_offset_by_compatible(blob, -1, io->compat);
  192. if (node == -FDT_ERR_NOTFOUND) {
  193. node = fdt_add_subnode(blob, 0, io->name);
  194. if (node < 0) {
  195. printf("Cannot create node '%s': %s\n", io->name,
  196. fdt_strerror(node));
  197. return -EIO;
  198. }
  199. if (fdt_setprop_string(blob, node, "compatible", io->compat)) {
  200. puts("Cannot set compatible\n");
  201. return -EIO;
  202. }
  203. } else if (node < 0) {
  204. printf("Cannot access node '%s': %s\n", io->name,
  205. fdt_strerror(node));
  206. return -EIO;
  207. }
  208. debug("Write state for '%s' to node %d\n", io->compat, node);
  209. ret = io->write(blob, node);
  210. if (ret) {
  211. printf("Unable to write state for '%s'\n", io->compat);
  212. return -EINVAL;
  213. }
  214. return 0;
  215. }
  216. int sandbox_write_state(struct sandbox_state *state, const char *fname)
  217. {
  218. struct sandbox_state_io *io;
  219. bool got_err;
  220. int size;
  221. int ret;
  222. int fd;
  223. /* Create a state FDT if we don't have one */
  224. if (!state->state_fdt) {
  225. size = 0x4000;
  226. state->state_fdt = os_malloc(size);
  227. if (!state->state_fdt) {
  228. puts("No memory to create FDT\n");
  229. return -ENOMEM;
  230. }
  231. ret = fdt_create_empty_tree(state->state_fdt, size);
  232. if (ret < 0) {
  233. printf("Cannot create empty state FDT: %s\n",
  234. fdt_strerror(ret));
  235. ret = -EIO;
  236. goto err_create;
  237. }
  238. }
  239. /* Call all the state write funtcions */
  240. got_err = false;
  241. io = ll_entry_start(struct sandbox_state_io, state_io);
  242. ret = 0;
  243. for (; io < ll_entry_end(struct sandbox_state_io, state_io); io++) {
  244. ret = sandbox_write_state_node(state, io);
  245. if (ret == -EIO)
  246. break;
  247. else if (ret)
  248. got_err = true;
  249. }
  250. if (ret == -EIO) {
  251. printf("Could not write sandbox state\n");
  252. goto err_create;
  253. }
  254. ret = fdt_pack(state->state_fdt);
  255. if (ret < 0) {
  256. printf("Cannot pack state FDT: %s\n", fdt_strerror(ret));
  257. ret = -EINVAL;
  258. goto err_create;
  259. }
  260. size = fdt_totalsize(state->state_fdt);
  261. fd = os_open(fname, OS_O_WRONLY | OS_O_CREAT);
  262. if (fd < 0) {
  263. printf("Cannot open sandbox state file '%s'\n", fname);
  264. ret = -EIO;
  265. goto err_create;
  266. }
  267. if (os_write(fd, state->state_fdt, size) != size) {
  268. printf("Cannot write sandbox state file '%s'\n", fname);
  269. ret = -EIO;
  270. goto err_write;
  271. }
  272. os_close(fd);
  273. debug("Wrote sandbox state to '%s'%s\n", fname,
  274. got_err ? " (with errors)" : "");
  275. return 0;
  276. err_write:
  277. os_close(fd);
  278. err_create:
  279. os_free(state->state_fdt);
  280. return ret;
  281. }
  282. int state_setprop(int node, const char *prop_name, const void *data, int size)
  283. {
  284. void *blob;
  285. int len;
  286. int ret;
  287. fdt_getprop(state->state_fdt, node, prop_name, &len);
  288. /* Add space for the new property, its name and some overhead */
  289. ret = state_ensure_space(size - len + strlen(prop_name) + 32);
  290. if (ret)
  291. return ret;
  292. /* This should succeed, barring a mutiny */
  293. blob = state->state_fdt;
  294. ret = fdt_setprop(blob, node, prop_name, data, size);
  295. if (ret) {
  296. printf("%s: Unable to set property '%s' in node '%s': %s\n",
  297. __func__, prop_name, fdt_get_name(blob, node, NULL),
  298. fdt_strerror(ret));
  299. return -ENOSPC;
  300. }
  301. return 0;
  302. }
  303. struct sandbox_state *state_get_current(void)
  304. {
  305. assert(state);
  306. return state;
  307. }
  308. void state_set_skip_delays(bool skip_delays)
  309. {
  310. struct sandbox_state *state = state_get_current();
  311. state->skip_delays = skip_delays;
  312. }
  313. bool state_get_skip_delays(void)
  314. {
  315. struct sandbox_state *state = state_get_current();
  316. return state->skip_delays;
  317. }
  318. void state_reset_for_test(struct sandbox_state *state)
  319. {
  320. /* No reset yet, so mark it as such. Always allow power reset */
  321. state->last_sysreset = SYSRESET_COUNT;
  322. state->sysreset_allowed[SYSRESET_POWER_OFF] = true;
  323. state->sysreset_allowed[SYSRESET_COLD] = true;
  324. state->allow_memio = false;
  325. sandbox_set_eth_enable(true);
  326. memset(&state->wdt, '\0', sizeof(state->wdt));
  327. memset(state->spi, '\0', sizeof(state->spi));
  328. /*
  329. * Set up the memory tag list. Use the top of emulated SDRAM for the
  330. * first tag number, since that address offset is outside the legal
  331. * range, and can be assumed to be a tag.
  332. */
  333. INIT_LIST_HEAD(&state->mapmem_head);
  334. state->next_tag = state->ram_size;
  335. }
  336. bool autoboot_keyed(void)
  337. {
  338. struct sandbox_state *state = state_get_current();
  339. return IS_ENABLED(CONFIG_AUTOBOOT_KEYED) && state->autoboot_keyed;
  340. }
  341. bool autoboot_set_keyed(bool autoboot_keyed)
  342. {
  343. struct sandbox_state *state = state_get_current();
  344. bool old_val = state->autoboot_keyed;
  345. state->autoboot_keyed = autoboot_keyed;
  346. return old_val;
  347. }
  348. int state_get_rel_filename(const char *rel_path, char *buf, int size)
  349. {
  350. struct sandbox_state *state = state_get_current();
  351. int rel_len, prog_len;
  352. char *p;
  353. int len;
  354. rel_len = strlen(rel_path);
  355. p = strrchr(state->argv[0], '/');
  356. prog_len = p ? p - state->argv[0] : 0;
  357. /* allow space for a / and a terminator */
  358. len = prog_len + 1 + rel_len + 1;
  359. if (len > size)
  360. return -ENOSPC;
  361. strncpy(buf, state->argv[0], prog_len);
  362. buf[prog_len] = '/';
  363. strcpy(buf + prog_len + 1, rel_path);
  364. return len;
  365. }
  366. int state_load_other_fdt(const char **bufp, int *sizep)
  367. {
  368. struct sandbox_state *state = state_get_current();
  369. char fname[256];
  370. int len, ret;
  371. /* load the file if needed */
  372. if (!state->other_fdt_buf) {
  373. len = state_get_rel_filename("arch/sandbox/dts/other.dtb",
  374. fname, sizeof(fname));
  375. if (len < 0)
  376. return len;
  377. ret = os_read_file(fname, &state->other_fdt_buf,
  378. &state->other_size);
  379. if (ret) {
  380. log_err("Cannot read file '%s'\n", fname);
  381. return ret;
  382. }
  383. }
  384. *bufp = state->other_fdt_buf;
  385. *sizep = state->other_size;
  386. return 0;
  387. }
  388. void sandbox_set_eth_enable(bool enable)
  389. {
  390. struct sandbox_state *state = state_get_current();
  391. state->disable_eth = !enable;
  392. }
  393. bool sandbox_eth_enabled(void)
  394. {
  395. struct sandbox_state *state = state_get_current();
  396. return !state->disable_eth;
  397. }
  398. void sandbox_sf_set_enable_bootdevs(bool enable)
  399. {
  400. struct sandbox_state *state = state_get_current();
  401. state->disable_sf_bootdevs = !enable;
  402. }
  403. bool sandbox_sf_bootdev_enabled(void)
  404. {
  405. struct sandbox_state *state = state_get_current();
  406. return !state->disable_sf_bootdevs;
  407. }
  408. int state_init(void)
  409. {
  410. state = &main_state;
  411. state->ram_size = CFG_SYS_SDRAM_SIZE;
  412. state->ram_buf = os_malloc(state->ram_size);
  413. if (!state->ram_buf) {
  414. printf("Out of memory\n");
  415. os_exit(1);
  416. }
  417. state_reset_for_test(state);
  418. /*
  419. * Example of how to use GPIOs:
  420. *
  421. * sandbox_gpio_set_direction(170, 0);
  422. * sandbox_gpio_set_value(170, 0);
  423. */
  424. return 0;
  425. }
  426. int state_uninit(void)
  427. {
  428. int err;
  429. if (state->write_ram_buf || state->write_state)
  430. log_debug("Writing sandbox state\n");
  431. state = &main_state;
  432. /* Finish the bloblist, so that it is correct before writing memory */
  433. bloblist_finish();
  434. if (state->write_ram_buf) {
  435. err = os_write_ram_buf(state->ram_buf_fname);
  436. if (err) {
  437. printf("Failed to write RAM buffer\n");
  438. return err;
  439. }
  440. }
  441. if (state->write_state) {
  442. if (sandbox_write_state(state, state->state_fname)) {
  443. printf("Failed to write sandbox state\n");
  444. return -1;
  445. }
  446. }
  447. /* Delete this at the last moment so as not to upset gdb too much */
  448. if (state->jumped_fname)
  449. os_unlink(state->jumped_fname);
  450. /* Disable tracing before unmapping RAM */
  451. if (IS_ENABLED(CONFIG_TRACE))
  452. trace_set_enabled(0);
  453. os_free(state->state_fdt);
  454. os_free(state->ram_buf);
  455. memset(state, '\0', sizeof(*state));
  456. return 0;
  457. }