fw_cfg.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255
  1. /*
  2. * QEMU Firmware configuration device emulation
  3. *
  4. * Copyright (c) 2008 Gleb Natapov
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. #include "qemu/osdep.h"
  25. #include "qemu-common.h"
  26. #include "sysemu/sysemu.h"
  27. #include "sysemu/dma.h"
  28. #include "sysemu/reset.h"
  29. #include "hw/boards.h"
  30. #include "hw/nvram/fw_cfg.h"
  31. #include "hw/qdev-properties.h"
  32. #include "hw/sysbus.h"
  33. #include "migration/qemu-file-types.h"
  34. #include "migration/vmstate.h"
  35. #include "trace.h"
  36. #include "qemu/error-report.h"
  37. #include "qemu/option.h"
  38. #include "qemu/config-file.h"
  39. #include "qemu/cutils.h"
  40. #include "qapi/error.h"
  41. #define FW_CFG_FILE_SLOTS_DFLT 0x20
  42. /* FW_CFG_VERSION bits */
  43. #define FW_CFG_VERSION 0x01
  44. #define FW_CFG_VERSION_DMA 0x02
  45. /* FW_CFG_DMA_CONTROL bits */
  46. #define FW_CFG_DMA_CTL_ERROR 0x01
  47. #define FW_CFG_DMA_CTL_READ 0x02
  48. #define FW_CFG_DMA_CTL_SKIP 0x04
  49. #define FW_CFG_DMA_CTL_SELECT 0x08
  50. #define FW_CFG_DMA_CTL_WRITE 0x10
  51. #define FW_CFG_DMA_SIGNATURE 0x51454d5520434647ULL /* "QEMU CFG" */
  52. struct FWCfgEntry {
  53. uint32_t len;
  54. bool allow_write;
  55. uint8_t *data;
  56. void *callback_opaque;
  57. FWCfgCallback select_cb;
  58. FWCfgWriteCallback write_cb;
  59. };
  60. /**
  61. * key_name:
  62. *
  63. * @key: The uint16 selector key.
  64. *
  65. * Returns: The stringified name if the selector refers to a well-known
  66. * numerically defined item, or NULL on key lookup failure.
  67. */
  68. static const char *key_name(uint16_t key)
  69. {
  70. static const char *fw_cfg_wellknown_keys[FW_CFG_FILE_FIRST] = {
  71. [FW_CFG_SIGNATURE] = "signature",
  72. [FW_CFG_ID] = "id",
  73. [FW_CFG_UUID] = "uuid",
  74. [FW_CFG_RAM_SIZE] = "ram_size",
  75. [FW_CFG_NOGRAPHIC] = "nographic",
  76. [FW_CFG_NB_CPUS] = "nb_cpus",
  77. [FW_CFG_MACHINE_ID] = "machine_id",
  78. [FW_CFG_KERNEL_ADDR] = "kernel_addr",
  79. [FW_CFG_KERNEL_SIZE] = "kernel_size",
  80. [FW_CFG_KERNEL_CMDLINE] = "kernel_cmdline",
  81. [FW_CFG_INITRD_ADDR] = "initrd_addr",
  82. [FW_CFG_INITRD_SIZE] = "initdr_size",
  83. [FW_CFG_BOOT_DEVICE] = "boot_device",
  84. [FW_CFG_NUMA] = "numa",
  85. [FW_CFG_BOOT_MENU] = "boot_menu",
  86. [FW_CFG_MAX_CPUS] = "max_cpus",
  87. [FW_CFG_KERNEL_ENTRY] = "kernel_entry",
  88. [FW_CFG_KERNEL_DATA] = "kernel_data",
  89. [FW_CFG_INITRD_DATA] = "initrd_data",
  90. [FW_CFG_CMDLINE_ADDR] = "cmdline_addr",
  91. [FW_CFG_CMDLINE_SIZE] = "cmdline_size",
  92. [FW_CFG_CMDLINE_DATA] = "cmdline_data",
  93. [FW_CFG_SETUP_ADDR] = "setup_addr",
  94. [FW_CFG_SETUP_SIZE] = "setup_size",
  95. [FW_CFG_SETUP_DATA] = "setup_data",
  96. [FW_CFG_FILE_DIR] = "file_dir",
  97. };
  98. if (key & FW_CFG_ARCH_LOCAL) {
  99. return fw_cfg_arch_key_name(key);
  100. }
  101. if (key < FW_CFG_FILE_FIRST) {
  102. return fw_cfg_wellknown_keys[key];
  103. }
  104. return NULL;
  105. }
  106. static inline const char *trace_key_name(uint16_t key)
  107. {
  108. const char *name = key_name(key);
  109. return name ? name : "unknown";
  110. }
  111. #define JPG_FILE 0
  112. #define BMP_FILE 1
  113. static char *read_splashfile(char *filename, gsize *file_sizep,
  114. int *file_typep)
  115. {
  116. GError *err = NULL;
  117. gchar *content;
  118. int file_type;
  119. unsigned int filehead;
  120. int bmp_bpp;
  121. if (!g_file_get_contents(filename, &content, file_sizep, &err)) {
  122. error_report("failed to read splash file '%s': %s",
  123. filename, err->message);
  124. g_error_free(err);
  125. return NULL;
  126. }
  127. /* check file size */
  128. if (*file_sizep < 30) {
  129. goto error;
  130. }
  131. /* check magic ID */
  132. filehead = lduw_le_p(content);
  133. if (filehead == 0xd8ff) {
  134. file_type = JPG_FILE;
  135. } else if (filehead == 0x4d42) {
  136. file_type = BMP_FILE;
  137. } else {
  138. goto error;
  139. }
  140. /* check BMP bpp */
  141. if (file_type == BMP_FILE) {
  142. bmp_bpp = lduw_le_p(&content[28]);
  143. if (bmp_bpp != 24) {
  144. goto error;
  145. }
  146. }
  147. /* return values */
  148. *file_typep = file_type;
  149. return content;
  150. error:
  151. error_report("splash file '%s' format not recognized; must be JPEG "
  152. "or 24 bit BMP", filename);
  153. g_free(content);
  154. return NULL;
  155. }
  156. static void fw_cfg_bootsplash(FWCfgState *s)
  157. {
  158. const char *boot_splash_filename = NULL;
  159. const char *boot_splash_time = NULL;
  160. char *filename, *file_data;
  161. gsize file_size;
  162. int file_type;
  163. /* get user configuration */
  164. QemuOptsList *plist = qemu_find_opts("boot-opts");
  165. QemuOpts *opts = QTAILQ_FIRST(&plist->head);
  166. boot_splash_filename = qemu_opt_get(opts, "splash");
  167. boot_splash_time = qemu_opt_get(opts, "splash-time");
  168. /* insert splash time if user configurated */
  169. if (boot_splash_time) {
  170. int64_t bst_val = qemu_opt_get_number(opts, "splash-time", -1);
  171. uint16_t bst_le16;
  172. /* validate the input */
  173. if (bst_val < 0 || bst_val > 0xffff) {
  174. error_report("splash-time is invalid,"
  175. "it should be a value between 0 and 65535");
  176. exit(1);
  177. }
  178. /* use little endian format */
  179. bst_le16 = cpu_to_le16(bst_val);
  180. fw_cfg_add_file(s, "etc/boot-menu-wait",
  181. g_memdup(&bst_le16, sizeof bst_le16), sizeof bst_le16);
  182. }
  183. /* insert splash file if user configurated */
  184. if (boot_splash_filename) {
  185. filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, boot_splash_filename);
  186. if (filename == NULL) {
  187. error_report("failed to find file '%s'", boot_splash_filename);
  188. return;
  189. }
  190. /* loading file data */
  191. file_data = read_splashfile(filename, &file_size, &file_type);
  192. if (file_data == NULL) {
  193. g_free(filename);
  194. return;
  195. }
  196. g_free(boot_splash_filedata);
  197. boot_splash_filedata = (uint8_t *)file_data;
  198. /* insert data */
  199. if (file_type == JPG_FILE) {
  200. fw_cfg_add_file(s, "bootsplash.jpg",
  201. boot_splash_filedata, file_size);
  202. } else {
  203. fw_cfg_add_file(s, "bootsplash.bmp",
  204. boot_splash_filedata, file_size);
  205. }
  206. g_free(filename);
  207. }
  208. }
  209. static void fw_cfg_reboot(FWCfgState *s)
  210. {
  211. const char *reboot_timeout = NULL;
  212. uint64_t rt_val = -1;
  213. uint32_t rt_le32;
  214. /* get user configuration */
  215. QemuOptsList *plist = qemu_find_opts("boot-opts");
  216. QemuOpts *opts = QTAILQ_FIRST(&plist->head);
  217. reboot_timeout = qemu_opt_get(opts, "reboot-timeout");
  218. if (reboot_timeout) {
  219. rt_val = qemu_opt_get_number(opts, "reboot-timeout", -1);
  220. /* validate the input */
  221. if (rt_val > 0xffff && rt_val != (uint64_t)-1) {
  222. error_report("reboot timeout is invalid,"
  223. "it should be a value between -1 and 65535");
  224. exit(1);
  225. }
  226. }
  227. rt_le32 = cpu_to_le32(rt_val);
  228. fw_cfg_add_file(s, "etc/boot-fail-wait", g_memdup(&rt_le32, 4), 4);
  229. }
  230. static void fw_cfg_write(FWCfgState *s, uint8_t value)
  231. {
  232. /* nothing, write support removed in QEMU v2.4+ */
  233. }
  234. static inline uint16_t fw_cfg_file_slots(const FWCfgState *s)
  235. {
  236. return s->file_slots;
  237. }
  238. /* Note: this function returns an exclusive limit. */
  239. static inline uint32_t fw_cfg_max_entry(const FWCfgState *s)
  240. {
  241. return FW_CFG_FILE_FIRST + fw_cfg_file_slots(s);
  242. }
  243. static int fw_cfg_select(FWCfgState *s, uint16_t key)
  244. {
  245. int arch, ret;
  246. FWCfgEntry *e;
  247. s->cur_offset = 0;
  248. if ((key & FW_CFG_ENTRY_MASK) >= fw_cfg_max_entry(s)) {
  249. s->cur_entry = FW_CFG_INVALID;
  250. ret = 0;
  251. } else {
  252. s->cur_entry = key;
  253. ret = 1;
  254. /* entry successfully selected, now run callback if present */
  255. arch = !!(key & FW_CFG_ARCH_LOCAL);
  256. e = &s->entries[arch][key & FW_CFG_ENTRY_MASK];
  257. if (e->select_cb) {
  258. e->select_cb(e->callback_opaque);
  259. }
  260. }
  261. trace_fw_cfg_select(s, key, trace_key_name(key), ret);
  262. return ret;
  263. }
  264. static uint64_t fw_cfg_data_read(void *opaque, hwaddr addr, unsigned size)
  265. {
  266. FWCfgState *s = opaque;
  267. int arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL);
  268. FWCfgEntry *e = (s->cur_entry == FW_CFG_INVALID) ? NULL :
  269. &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
  270. uint64_t value = 0;
  271. assert(size > 0 && size <= sizeof(value));
  272. if (s->cur_entry != FW_CFG_INVALID && e->data && s->cur_offset < e->len) {
  273. /* The least significant 'size' bytes of the return value are
  274. * expected to contain a string preserving portion of the item
  275. * data, padded with zeros on the right in case we run out early.
  276. * In technical terms, we're composing the host-endian representation
  277. * of the big endian interpretation of the fw_cfg string.
  278. */
  279. do {
  280. value = (value << 8) | e->data[s->cur_offset++];
  281. } while (--size && s->cur_offset < e->len);
  282. /* If size is still not zero, we *did* run out early, so continue
  283. * left-shifting, to add the appropriate number of padding zeros
  284. * on the right.
  285. */
  286. value <<= 8 * size;
  287. }
  288. trace_fw_cfg_read(s, value);
  289. return value;
  290. }
  291. static void fw_cfg_data_mem_write(void *opaque, hwaddr addr,
  292. uint64_t value, unsigned size)
  293. {
  294. FWCfgState *s = opaque;
  295. unsigned i = size;
  296. do {
  297. fw_cfg_write(s, value >> (8 * --i));
  298. } while (i);
  299. }
  300. static void fw_cfg_dma_transfer(FWCfgState *s)
  301. {
  302. dma_addr_t len;
  303. FWCfgDmaAccess dma;
  304. int arch;
  305. FWCfgEntry *e;
  306. int read = 0, write = 0;
  307. dma_addr_t dma_addr;
  308. /* Reset the address before the next access */
  309. dma_addr = s->dma_addr;
  310. s->dma_addr = 0;
  311. if (dma_memory_read(s->dma_as, dma_addr, &dma, sizeof(dma))) {
  312. stl_be_dma(s->dma_as, dma_addr + offsetof(FWCfgDmaAccess, control),
  313. FW_CFG_DMA_CTL_ERROR);
  314. return;
  315. }
  316. dma.address = be64_to_cpu(dma.address);
  317. dma.length = be32_to_cpu(dma.length);
  318. dma.control = be32_to_cpu(dma.control);
  319. if (dma.control & FW_CFG_DMA_CTL_SELECT) {
  320. fw_cfg_select(s, dma.control >> 16);
  321. }
  322. arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL);
  323. e = (s->cur_entry == FW_CFG_INVALID) ? NULL :
  324. &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
  325. if (dma.control & FW_CFG_DMA_CTL_READ) {
  326. read = 1;
  327. write = 0;
  328. } else if (dma.control & FW_CFG_DMA_CTL_WRITE) {
  329. read = 0;
  330. write = 1;
  331. } else if (dma.control & FW_CFG_DMA_CTL_SKIP) {
  332. read = 0;
  333. write = 0;
  334. } else {
  335. dma.length = 0;
  336. }
  337. dma.control = 0;
  338. while (dma.length > 0 && !(dma.control & FW_CFG_DMA_CTL_ERROR)) {
  339. if (s->cur_entry == FW_CFG_INVALID || !e->data ||
  340. s->cur_offset >= e->len) {
  341. len = dma.length;
  342. /* If the access is not a read access, it will be a skip access,
  343. * tested before.
  344. */
  345. if (read) {
  346. if (dma_memory_set(s->dma_as, dma.address, 0, len)) {
  347. dma.control |= FW_CFG_DMA_CTL_ERROR;
  348. }
  349. }
  350. if (write) {
  351. dma.control |= FW_CFG_DMA_CTL_ERROR;
  352. }
  353. } else {
  354. if (dma.length <= (e->len - s->cur_offset)) {
  355. len = dma.length;
  356. } else {
  357. len = (e->len - s->cur_offset);
  358. }
  359. /* If the access is not a read access, it will be a skip access,
  360. * tested before.
  361. */
  362. if (read) {
  363. if (dma_memory_write(s->dma_as, dma.address,
  364. &e->data[s->cur_offset], len)) {
  365. dma.control |= FW_CFG_DMA_CTL_ERROR;
  366. }
  367. }
  368. if (write) {
  369. if (!e->allow_write ||
  370. len != dma.length ||
  371. dma_memory_read(s->dma_as, dma.address,
  372. &e->data[s->cur_offset], len)) {
  373. dma.control |= FW_CFG_DMA_CTL_ERROR;
  374. } else if (e->write_cb) {
  375. e->write_cb(e->callback_opaque, s->cur_offset, len);
  376. }
  377. }
  378. s->cur_offset += len;
  379. }
  380. dma.address += len;
  381. dma.length -= len;
  382. }
  383. stl_be_dma(s->dma_as, dma_addr + offsetof(FWCfgDmaAccess, control),
  384. dma.control);
  385. trace_fw_cfg_read(s, 0);
  386. }
  387. static uint64_t fw_cfg_dma_mem_read(void *opaque, hwaddr addr,
  388. unsigned size)
  389. {
  390. /* Return a signature value (and handle various read sizes) */
  391. return extract64(FW_CFG_DMA_SIGNATURE, (8 - addr - size) * 8, size * 8);
  392. }
  393. static void fw_cfg_dma_mem_write(void *opaque, hwaddr addr,
  394. uint64_t value, unsigned size)
  395. {
  396. FWCfgState *s = opaque;
  397. if (size == 4) {
  398. if (addr == 0) {
  399. /* FWCfgDmaAccess high address */
  400. s->dma_addr = value << 32;
  401. } else if (addr == 4) {
  402. /* FWCfgDmaAccess low address */
  403. s->dma_addr |= value;
  404. fw_cfg_dma_transfer(s);
  405. }
  406. } else if (size == 8 && addr == 0) {
  407. s->dma_addr = value;
  408. fw_cfg_dma_transfer(s);
  409. }
  410. }
  411. static bool fw_cfg_dma_mem_valid(void *opaque, hwaddr addr,
  412. unsigned size, bool is_write,
  413. MemTxAttrs attrs)
  414. {
  415. return !is_write || ((size == 4 && (addr == 0 || addr == 4)) ||
  416. (size == 8 && addr == 0));
  417. }
  418. static bool fw_cfg_data_mem_valid(void *opaque, hwaddr addr,
  419. unsigned size, bool is_write,
  420. MemTxAttrs attrs)
  421. {
  422. return addr == 0;
  423. }
  424. static uint64_t fw_cfg_ctl_mem_read(void *opaque, hwaddr addr, unsigned size)
  425. {
  426. return 0;
  427. }
  428. static void fw_cfg_ctl_mem_write(void *opaque, hwaddr addr,
  429. uint64_t value, unsigned size)
  430. {
  431. fw_cfg_select(opaque, (uint16_t)value);
  432. }
  433. static bool fw_cfg_ctl_mem_valid(void *opaque, hwaddr addr,
  434. unsigned size, bool is_write,
  435. MemTxAttrs attrs)
  436. {
  437. return is_write && size == 2;
  438. }
  439. static void fw_cfg_comb_write(void *opaque, hwaddr addr,
  440. uint64_t value, unsigned size)
  441. {
  442. switch (size) {
  443. case 1:
  444. fw_cfg_write(opaque, (uint8_t)value);
  445. break;
  446. case 2:
  447. fw_cfg_select(opaque, (uint16_t)value);
  448. break;
  449. }
  450. }
  451. static bool fw_cfg_comb_valid(void *opaque, hwaddr addr,
  452. unsigned size, bool is_write,
  453. MemTxAttrs attrs)
  454. {
  455. return (size == 1) || (is_write && size == 2);
  456. }
  457. static const MemoryRegionOps fw_cfg_ctl_mem_ops = {
  458. .read = fw_cfg_ctl_mem_read,
  459. .write = fw_cfg_ctl_mem_write,
  460. .endianness = DEVICE_BIG_ENDIAN,
  461. .valid.accepts = fw_cfg_ctl_mem_valid,
  462. };
  463. static const MemoryRegionOps fw_cfg_data_mem_ops = {
  464. .read = fw_cfg_data_read,
  465. .write = fw_cfg_data_mem_write,
  466. .endianness = DEVICE_BIG_ENDIAN,
  467. .valid = {
  468. .min_access_size = 1,
  469. .max_access_size = 1,
  470. .accepts = fw_cfg_data_mem_valid,
  471. },
  472. };
  473. static const MemoryRegionOps fw_cfg_comb_mem_ops = {
  474. .read = fw_cfg_data_read,
  475. .write = fw_cfg_comb_write,
  476. .endianness = DEVICE_LITTLE_ENDIAN,
  477. .valid.accepts = fw_cfg_comb_valid,
  478. };
  479. static const MemoryRegionOps fw_cfg_dma_mem_ops = {
  480. .read = fw_cfg_dma_mem_read,
  481. .write = fw_cfg_dma_mem_write,
  482. .endianness = DEVICE_BIG_ENDIAN,
  483. .valid.accepts = fw_cfg_dma_mem_valid,
  484. .valid.max_access_size = 8,
  485. .impl.max_access_size = 8,
  486. };
  487. static void fw_cfg_reset(DeviceState *d)
  488. {
  489. FWCfgState *s = FW_CFG(d);
  490. /* we never register a read callback for FW_CFG_SIGNATURE */
  491. fw_cfg_select(s, FW_CFG_SIGNATURE);
  492. }
  493. /* Save restore 32 bit int as uint16_t
  494. This is a Big hack, but it is how the old state did it.
  495. Or we broke compatibility in the state, or we can't use struct tm
  496. */
  497. static int get_uint32_as_uint16(QEMUFile *f, void *pv, size_t size,
  498. const VMStateField *field)
  499. {
  500. uint32_t *v = pv;
  501. *v = qemu_get_be16(f);
  502. return 0;
  503. }
  504. static int put_unused(QEMUFile *f, void *pv, size_t size,
  505. const VMStateField *field, QJSON *vmdesc)
  506. {
  507. fprintf(stderr, "uint32_as_uint16 is only used for backward compatibility.\n");
  508. fprintf(stderr, "This functions shouldn't be called.\n");
  509. return 0;
  510. }
  511. static const VMStateInfo vmstate_hack_uint32_as_uint16 = {
  512. .name = "int32_as_uint16",
  513. .get = get_uint32_as_uint16,
  514. .put = put_unused,
  515. };
  516. #define VMSTATE_UINT16_HACK(_f, _s, _t) \
  517. VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_hack_uint32_as_uint16, uint32_t)
  518. static bool is_version_1(void *opaque, int version_id)
  519. {
  520. return version_id == 1;
  521. }
  522. bool fw_cfg_dma_enabled(void *opaque)
  523. {
  524. FWCfgState *s = opaque;
  525. return s->dma_enabled;
  526. }
  527. static const VMStateDescription vmstate_fw_cfg_dma = {
  528. .name = "fw_cfg/dma",
  529. .needed = fw_cfg_dma_enabled,
  530. .fields = (VMStateField[]) {
  531. VMSTATE_UINT64(dma_addr, FWCfgState),
  532. VMSTATE_END_OF_LIST()
  533. },
  534. };
  535. static const VMStateDescription vmstate_fw_cfg = {
  536. .name = "fw_cfg",
  537. .version_id = 2,
  538. .minimum_version_id = 1,
  539. .fields = (VMStateField[]) {
  540. VMSTATE_UINT16(cur_entry, FWCfgState),
  541. VMSTATE_UINT16_HACK(cur_offset, FWCfgState, is_version_1),
  542. VMSTATE_UINT32_V(cur_offset, FWCfgState, 2),
  543. VMSTATE_END_OF_LIST()
  544. },
  545. .subsections = (const VMStateDescription*[]) {
  546. &vmstate_fw_cfg_dma,
  547. NULL,
  548. }
  549. };
  550. static void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key,
  551. FWCfgCallback select_cb,
  552. FWCfgWriteCallback write_cb,
  553. void *callback_opaque,
  554. void *data, size_t len,
  555. bool read_only)
  556. {
  557. int arch = !!(key & FW_CFG_ARCH_LOCAL);
  558. key &= FW_CFG_ENTRY_MASK;
  559. assert(key < fw_cfg_max_entry(s) && len < UINT32_MAX);
  560. assert(s->entries[arch][key].data == NULL); /* avoid key conflict */
  561. s->entries[arch][key].data = data;
  562. s->entries[arch][key].len = (uint32_t)len;
  563. s->entries[arch][key].select_cb = select_cb;
  564. s->entries[arch][key].write_cb = write_cb;
  565. s->entries[arch][key].callback_opaque = callback_opaque;
  566. s->entries[arch][key].allow_write = !read_only;
  567. }
  568. static void *fw_cfg_modify_bytes_read(FWCfgState *s, uint16_t key,
  569. void *data, size_t len)
  570. {
  571. void *ptr;
  572. int arch = !!(key & FW_CFG_ARCH_LOCAL);
  573. key &= FW_CFG_ENTRY_MASK;
  574. assert(key < fw_cfg_max_entry(s) && len < UINT32_MAX);
  575. /* return the old data to the function caller, avoid memory leak */
  576. ptr = s->entries[arch][key].data;
  577. s->entries[arch][key].data = data;
  578. s->entries[arch][key].len = len;
  579. s->entries[arch][key].callback_opaque = NULL;
  580. s->entries[arch][key].allow_write = false;
  581. return ptr;
  582. }
  583. void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len)
  584. {
  585. trace_fw_cfg_add_bytes(key, trace_key_name(key), len);
  586. fw_cfg_add_bytes_callback(s, key, NULL, NULL, NULL, data, len, true);
  587. }
  588. void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value)
  589. {
  590. size_t sz = strlen(value) + 1;
  591. trace_fw_cfg_add_string(key, trace_key_name(key), value);
  592. fw_cfg_add_bytes(s, key, g_memdup(value, sz), sz);
  593. }
  594. void fw_cfg_modify_string(FWCfgState *s, uint16_t key, const char *value)
  595. {
  596. size_t sz = strlen(value) + 1;
  597. char *old;
  598. old = fw_cfg_modify_bytes_read(s, key, g_memdup(value, sz), sz);
  599. g_free(old);
  600. }
  601. void fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value)
  602. {
  603. uint16_t *copy;
  604. copy = g_malloc(sizeof(value));
  605. *copy = cpu_to_le16(value);
  606. trace_fw_cfg_add_i16(key, trace_key_name(key), value);
  607. fw_cfg_add_bytes(s, key, copy, sizeof(value));
  608. }
  609. void fw_cfg_modify_i16(FWCfgState *s, uint16_t key, uint16_t value)
  610. {
  611. uint16_t *copy, *old;
  612. copy = g_malloc(sizeof(value));
  613. *copy = cpu_to_le16(value);
  614. old = fw_cfg_modify_bytes_read(s, key, copy, sizeof(value));
  615. g_free(old);
  616. }
  617. void fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value)
  618. {
  619. uint32_t *copy;
  620. copy = g_malloc(sizeof(value));
  621. *copy = cpu_to_le32(value);
  622. trace_fw_cfg_add_i32(key, trace_key_name(key), value);
  623. fw_cfg_add_bytes(s, key, copy, sizeof(value));
  624. }
  625. void fw_cfg_modify_i32(FWCfgState *s, uint16_t key, uint32_t value)
  626. {
  627. uint32_t *copy, *old;
  628. copy = g_malloc(sizeof(value));
  629. *copy = cpu_to_le32(value);
  630. old = fw_cfg_modify_bytes_read(s, key, copy, sizeof(value));
  631. g_free(old);
  632. }
  633. void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value)
  634. {
  635. uint64_t *copy;
  636. copy = g_malloc(sizeof(value));
  637. *copy = cpu_to_le64(value);
  638. trace_fw_cfg_add_i64(key, trace_key_name(key), value);
  639. fw_cfg_add_bytes(s, key, copy, sizeof(value));
  640. }
  641. void fw_cfg_modify_i64(FWCfgState *s, uint16_t key, uint64_t value)
  642. {
  643. uint64_t *copy, *old;
  644. copy = g_malloc(sizeof(value));
  645. *copy = cpu_to_le64(value);
  646. old = fw_cfg_modify_bytes_read(s, key, copy, sizeof(value));
  647. g_free(old);
  648. }
  649. void fw_cfg_set_order_override(FWCfgState *s, int order)
  650. {
  651. assert(s->fw_cfg_order_override == 0);
  652. s->fw_cfg_order_override = order;
  653. }
  654. void fw_cfg_reset_order_override(FWCfgState *s)
  655. {
  656. assert(s->fw_cfg_order_override != 0);
  657. s->fw_cfg_order_override = 0;
  658. }
  659. /*
  660. * This is the legacy order list. For legacy systems, files are in
  661. * the fw_cfg in the order defined below, by the "order" value. Note
  662. * that some entries (VGA ROMs, NIC option ROMS, etc.) go into a
  663. * specific area, but there may be more than one and they occur in the
  664. * order that the user specifies them on the command line. Those are
  665. * handled in a special manner, using the order override above.
  666. *
  667. * For non-legacy, the files are sorted by filename to avoid this kind
  668. * of complexity in the future.
  669. *
  670. * This is only for x86, other arches don't implement versioning so
  671. * they won't set legacy mode.
  672. */
  673. static struct {
  674. const char *name;
  675. int order;
  676. } fw_cfg_order[] = {
  677. { "etc/boot-menu-wait", 10 },
  678. { "bootsplash.jpg", 11 },
  679. { "bootsplash.bmp", 12 },
  680. { "etc/boot-fail-wait", 15 },
  681. { "etc/smbios/smbios-tables", 20 },
  682. { "etc/smbios/smbios-anchor", 30 },
  683. { "etc/e820", 40 },
  684. { "etc/reserved-memory-end", 50 },
  685. { "genroms/kvmvapic.bin", 55 },
  686. { "genroms/linuxboot.bin", 60 },
  687. { }, /* VGA ROMs from pc_vga_init come here, 70. */
  688. { }, /* NIC option ROMs from pc_nic_init come here, 80. */
  689. { "etc/system-states", 90 },
  690. { }, /* User ROMs come here, 100. */
  691. { }, /* Device FW comes here, 110. */
  692. { "etc/extra-pci-roots", 120 },
  693. { "etc/acpi/tables", 130 },
  694. { "etc/table-loader", 140 },
  695. { "etc/tpm/log", 150 },
  696. { "etc/acpi/rsdp", 160 },
  697. { "bootorder", 170 },
  698. #define FW_CFG_ORDER_OVERRIDE_LAST 200
  699. };
  700. static int get_fw_cfg_order(FWCfgState *s, const char *name)
  701. {
  702. int i;
  703. if (s->fw_cfg_order_override > 0) {
  704. return s->fw_cfg_order_override;
  705. }
  706. for (i = 0; i < ARRAY_SIZE(fw_cfg_order); i++) {
  707. if (fw_cfg_order[i].name == NULL) {
  708. continue;
  709. }
  710. if (strcmp(name, fw_cfg_order[i].name) == 0) {
  711. return fw_cfg_order[i].order;
  712. }
  713. }
  714. /* Stick unknown stuff at the end. */
  715. warn_report("Unknown firmware file in legacy mode: %s", name);
  716. return FW_CFG_ORDER_OVERRIDE_LAST;
  717. }
  718. void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
  719. FWCfgCallback select_cb,
  720. FWCfgWriteCallback write_cb,
  721. void *callback_opaque,
  722. void *data, size_t len, bool read_only)
  723. {
  724. int i, index, count;
  725. size_t dsize;
  726. MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
  727. int order = 0;
  728. if (!s->files) {
  729. dsize = sizeof(uint32_t) + sizeof(FWCfgFile) * fw_cfg_file_slots(s);
  730. s->files = g_malloc0(dsize);
  731. fw_cfg_add_bytes(s, FW_CFG_FILE_DIR, s->files, dsize);
  732. }
  733. count = be32_to_cpu(s->files->count);
  734. assert(count < fw_cfg_file_slots(s));
  735. /* Find the insertion point. */
  736. if (mc->legacy_fw_cfg_order) {
  737. /*
  738. * Sort by order. For files with the same order, we keep them
  739. * in the sequence in which they were added.
  740. */
  741. order = get_fw_cfg_order(s, filename);
  742. for (index = count;
  743. index > 0 && order < s->entry_order[index - 1];
  744. index--);
  745. } else {
  746. /* Sort by file name. */
  747. for (index = count;
  748. index > 0 && strcmp(filename, s->files->f[index - 1].name) < 0;
  749. index--);
  750. }
  751. /*
  752. * Move all the entries from the index point and after down one
  753. * to create a slot for the new entry. Because calculations are
  754. * being done with the index, make it so that "i" is the current
  755. * index and "i - 1" is the one being copied from, thus the
  756. * unusual start and end in the for statement.
  757. */
  758. for (i = count; i > index; i--) {
  759. s->files->f[i] = s->files->f[i - 1];
  760. s->files->f[i].select = cpu_to_be16(FW_CFG_FILE_FIRST + i);
  761. s->entries[0][FW_CFG_FILE_FIRST + i] =
  762. s->entries[0][FW_CFG_FILE_FIRST + i - 1];
  763. s->entry_order[i] = s->entry_order[i - 1];
  764. }
  765. memset(&s->files->f[index], 0, sizeof(FWCfgFile));
  766. memset(&s->entries[0][FW_CFG_FILE_FIRST + index], 0, sizeof(FWCfgEntry));
  767. pstrcpy(s->files->f[index].name, sizeof(s->files->f[index].name), filename);
  768. for (i = 0; i <= count; i++) {
  769. if (i != index &&
  770. strcmp(s->files->f[index].name, s->files->f[i].name) == 0) {
  771. error_report("duplicate fw_cfg file name: %s",
  772. s->files->f[index].name);
  773. exit(1);
  774. }
  775. }
  776. fw_cfg_add_bytes_callback(s, FW_CFG_FILE_FIRST + index,
  777. select_cb, write_cb,
  778. callback_opaque, data, len,
  779. read_only);
  780. s->files->f[index].size = cpu_to_be32(len);
  781. s->files->f[index].select = cpu_to_be16(FW_CFG_FILE_FIRST + index);
  782. s->entry_order[index] = order;
  783. trace_fw_cfg_add_file(s, index, s->files->f[index].name, len);
  784. s->files->count = cpu_to_be32(count+1);
  785. }
  786. void fw_cfg_add_file(FWCfgState *s, const char *filename,
  787. void *data, size_t len)
  788. {
  789. fw_cfg_add_file_callback(s, filename, NULL, NULL, NULL, data, len, true);
  790. }
  791. void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
  792. void *data, size_t len)
  793. {
  794. int i, index;
  795. void *ptr = NULL;
  796. assert(s->files);
  797. index = be32_to_cpu(s->files->count);
  798. for (i = 0; i < index; i++) {
  799. if (strcmp(filename, s->files->f[i].name) == 0) {
  800. ptr = fw_cfg_modify_bytes_read(s, FW_CFG_FILE_FIRST + i,
  801. data, len);
  802. s->files->f[i].size = cpu_to_be32(len);
  803. return ptr;
  804. }
  805. }
  806. assert(index < fw_cfg_file_slots(s));
  807. /* add new one */
  808. fw_cfg_add_file_callback(s, filename, NULL, NULL, NULL, data, len, true);
  809. return NULL;
  810. }
  811. static void fw_cfg_machine_reset(void *opaque)
  812. {
  813. MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
  814. FWCfgState *s = opaque;
  815. void *ptr;
  816. size_t len;
  817. char *buf;
  818. buf = get_boot_devices_list(&len);
  819. ptr = fw_cfg_modify_file(s, "bootorder", (uint8_t *)buf, len);
  820. g_free(ptr);
  821. if (!mc->legacy_fw_cfg_order) {
  822. buf = get_boot_devices_lchs_list(&len);
  823. ptr = fw_cfg_modify_file(s, "bios-geometry", (uint8_t *)buf, len);
  824. g_free(ptr);
  825. }
  826. }
  827. static void fw_cfg_machine_ready(struct Notifier *n, void *data)
  828. {
  829. FWCfgState *s = container_of(n, FWCfgState, machine_ready);
  830. qemu_register_reset(fw_cfg_machine_reset, s);
  831. }
  832. static void fw_cfg_common_realize(DeviceState *dev, Error **errp)
  833. {
  834. FWCfgState *s = FW_CFG(dev);
  835. MachineState *machine = MACHINE(qdev_get_machine());
  836. uint32_t version = FW_CFG_VERSION;
  837. if (!fw_cfg_find()) {
  838. error_setg(errp, "at most one %s device is permitted", TYPE_FW_CFG);
  839. return;
  840. }
  841. fw_cfg_add_bytes(s, FW_CFG_SIGNATURE, (char *)"QEMU", 4);
  842. fw_cfg_add_bytes(s, FW_CFG_UUID, &qemu_uuid, 16);
  843. fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)!machine->enable_graphics);
  844. fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu);
  845. fw_cfg_bootsplash(s);
  846. fw_cfg_reboot(s);
  847. if (s->dma_enabled) {
  848. version |= FW_CFG_VERSION_DMA;
  849. }
  850. fw_cfg_add_i32(s, FW_CFG_ID, version);
  851. s->machine_ready.notify = fw_cfg_machine_ready;
  852. qemu_add_machine_init_done_notifier(&s->machine_ready);
  853. }
  854. FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase,
  855. AddressSpace *dma_as)
  856. {
  857. DeviceState *dev;
  858. SysBusDevice *sbd;
  859. FWCfgIoState *ios;
  860. FWCfgState *s;
  861. bool dma_requested = dma_iobase && dma_as;
  862. dev = qdev_create(NULL, TYPE_FW_CFG_IO);
  863. if (!dma_requested) {
  864. qdev_prop_set_bit(dev, "dma_enabled", false);
  865. }
  866. object_property_add_child(OBJECT(qdev_get_machine()), TYPE_FW_CFG,
  867. OBJECT(dev), NULL);
  868. qdev_init_nofail(dev);
  869. sbd = SYS_BUS_DEVICE(dev);
  870. ios = FW_CFG_IO(dev);
  871. sysbus_add_io(sbd, iobase, &ios->comb_iomem);
  872. s = FW_CFG(dev);
  873. if (s->dma_enabled) {
  874. /* 64 bits for the address field */
  875. s->dma_as = dma_as;
  876. s->dma_addr = 0;
  877. sysbus_add_io(sbd, dma_iobase, &s->dma_iomem);
  878. }
  879. return s;
  880. }
  881. FWCfgState *fw_cfg_init_io(uint32_t iobase)
  882. {
  883. return fw_cfg_init_io_dma(iobase, 0, NULL);
  884. }
  885. FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
  886. hwaddr data_addr, uint32_t data_width,
  887. hwaddr dma_addr, AddressSpace *dma_as)
  888. {
  889. DeviceState *dev;
  890. SysBusDevice *sbd;
  891. FWCfgState *s;
  892. bool dma_requested = dma_addr && dma_as;
  893. dev = qdev_create(NULL, TYPE_FW_CFG_MEM);
  894. qdev_prop_set_uint32(dev, "data_width", data_width);
  895. if (!dma_requested) {
  896. qdev_prop_set_bit(dev, "dma_enabled", false);
  897. }
  898. object_property_add_child(OBJECT(qdev_get_machine()), TYPE_FW_CFG,
  899. OBJECT(dev), NULL);
  900. qdev_init_nofail(dev);
  901. sbd = SYS_BUS_DEVICE(dev);
  902. sysbus_mmio_map(sbd, 0, ctl_addr);
  903. sysbus_mmio_map(sbd, 1, data_addr);
  904. s = FW_CFG(dev);
  905. if (s->dma_enabled) {
  906. s->dma_as = dma_as;
  907. s->dma_addr = 0;
  908. sysbus_mmio_map(sbd, 2, dma_addr);
  909. }
  910. return s;
  911. }
  912. FWCfgState *fw_cfg_init_mem(hwaddr ctl_addr, hwaddr data_addr)
  913. {
  914. return fw_cfg_init_mem_wide(ctl_addr, data_addr,
  915. fw_cfg_data_mem_ops.valid.max_access_size,
  916. 0, NULL);
  917. }
  918. FWCfgState *fw_cfg_find(void)
  919. {
  920. /* Returns NULL unless there is exactly one fw_cfg device */
  921. return FW_CFG(object_resolve_path_type("", TYPE_FW_CFG, NULL));
  922. }
  923. static void fw_cfg_class_init(ObjectClass *klass, void *data)
  924. {
  925. DeviceClass *dc = DEVICE_CLASS(klass);
  926. dc->reset = fw_cfg_reset;
  927. dc->vmsd = &vmstate_fw_cfg;
  928. }
  929. static const TypeInfo fw_cfg_info = {
  930. .name = TYPE_FW_CFG,
  931. .parent = TYPE_SYS_BUS_DEVICE,
  932. .abstract = true,
  933. .instance_size = sizeof(FWCfgState),
  934. .class_init = fw_cfg_class_init,
  935. };
  936. static void fw_cfg_file_slots_allocate(FWCfgState *s, Error **errp)
  937. {
  938. uint16_t file_slots_max;
  939. if (fw_cfg_file_slots(s) < FW_CFG_FILE_SLOTS_MIN) {
  940. error_setg(errp, "\"file_slots\" must be at least 0x%x",
  941. FW_CFG_FILE_SLOTS_MIN);
  942. return;
  943. }
  944. /* (UINT16_MAX & FW_CFG_ENTRY_MASK) is the highest inclusive selector value
  945. * that we permit. The actual (exclusive) value coming from the
  946. * configuration is (FW_CFG_FILE_FIRST + fw_cfg_file_slots(s)). */
  947. file_slots_max = (UINT16_MAX & FW_CFG_ENTRY_MASK) - FW_CFG_FILE_FIRST + 1;
  948. if (fw_cfg_file_slots(s) > file_slots_max) {
  949. error_setg(errp, "\"file_slots\" must not exceed 0x%" PRIx16,
  950. file_slots_max);
  951. return;
  952. }
  953. s->entries[0] = g_new0(FWCfgEntry, fw_cfg_max_entry(s));
  954. s->entries[1] = g_new0(FWCfgEntry, fw_cfg_max_entry(s));
  955. s->entry_order = g_new0(int, fw_cfg_max_entry(s));
  956. }
  957. static Property fw_cfg_io_properties[] = {
  958. DEFINE_PROP_BOOL("dma_enabled", FWCfgIoState, parent_obj.dma_enabled,
  959. true),
  960. DEFINE_PROP_UINT16("x-file-slots", FWCfgIoState, parent_obj.file_slots,
  961. FW_CFG_FILE_SLOTS_DFLT),
  962. DEFINE_PROP_END_OF_LIST(),
  963. };
  964. static void fw_cfg_io_realize(DeviceState *dev, Error **errp)
  965. {
  966. FWCfgIoState *s = FW_CFG_IO(dev);
  967. Error *local_err = NULL;
  968. fw_cfg_file_slots_allocate(FW_CFG(s), &local_err);
  969. if (local_err) {
  970. error_propagate(errp, local_err);
  971. return;
  972. }
  973. /* when using port i/o, the 8-bit data register ALWAYS overlaps
  974. * with half of the 16-bit control register. Hence, the total size
  975. * of the i/o region used is FW_CFG_CTL_SIZE */
  976. memory_region_init_io(&s->comb_iomem, OBJECT(s), &fw_cfg_comb_mem_ops,
  977. FW_CFG(s), "fwcfg", FW_CFG_CTL_SIZE);
  978. if (FW_CFG(s)->dma_enabled) {
  979. memory_region_init_io(&FW_CFG(s)->dma_iomem, OBJECT(s),
  980. &fw_cfg_dma_mem_ops, FW_CFG(s), "fwcfg.dma",
  981. sizeof(dma_addr_t));
  982. }
  983. fw_cfg_common_realize(dev, errp);
  984. }
  985. static void fw_cfg_io_class_init(ObjectClass *klass, void *data)
  986. {
  987. DeviceClass *dc = DEVICE_CLASS(klass);
  988. dc->realize = fw_cfg_io_realize;
  989. dc->props = fw_cfg_io_properties;
  990. }
  991. static const TypeInfo fw_cfg_io_info = {
  992. .name = TYPE_FW_CFG_IO,
  993. .parent = TYPE_FW_CFG,
  994. .instance_size = sizeof(FWCfgIoState),
  995. .class_init = fw_cfg_io_class_init,
  996. };
  997. static Property fw_cfg_mem_properties[] = {
  998. DEFINE_PROP_UINT32("data_width", FWCfgMemState, data_width, -1),
  999. DEFINE_PROP_BOOL("dma_enabled", FWCfgMemState, parent_obj.dma_enabled,
  1000. true),
  1001. DEFINE_PROP_UINT16("x-file-slots", FWCfgMemState, parent_obj.file_slots,
  1002. FW_CFG_FILE_SLOTS_DFLT),
  1003. DEFINE_PROP_END_OF_LIST(),
  1004. };
  1005. static void fw_cfg_mem_realize(DeviceState *dev, Error **errp)
  1006. {
  1007. FWCfgMemState *s = FW_CFG_MEM(dev);
  1008. SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
  1009. const MemoryRegionOps *data_ops = &fw_cfg_data_mem_ops;
  1010. Error *local_err = NULL;
  1011. fw_cfg_file_slots_allocate(FW_CFG(s), &local_err);
  1012. if (local_err) {
  1013. error_propagate(errp, local_err);
  1014. return;
  1015. }
  1016. memory_region_init_io(&s->ctl_iomem, OBJECT(s), &fw_cfg_ctl_mem_ops,
  1017. FW_CFG(s), "fwcfg.ctl", FW_CFG_CTL_SIZE);
  1018. sysbus_init_mmio(sbd, &s->ctl_iomem);
  1019. if (s->data_width > data_ops->valid.max_access_size) {
  1020. s->wide_data_ops = *data_ops;
  1021. s->wide_data_ops.valid.max_access_size = s->data_width;
  1022. s->wide_data_ops.impl.max_access_size = s->data_width;
  1023. data_ops = &s->wide_data_ops;
  1024. }
  1025. memory_region_init_io(&s->data_iomem, OBJECT(s), data_ops, FW_CFG(s),
  1026. "fwcfg.data", data_ops->valid.max_access_size);
  1027. sysbus_init_mmio(sbd, &s->data_iomem);
  1028. if (FW_CFG(s)->dma_enabled) {
  1029. memory_region_init_io(&FW_CFG(s)->dma_iomem, OBJECT(s),
  1030. &fw_cfg_dma_mem_ops, FW_CFG(s), "fwcfg.dma",
  1031. sizeof(dma_addr_t));
  1032. sysbus_init_mmio(sbd, &FW_CFG(s)->dma_iomem);
  1033. }
  1034. fw_cfg_common_realize(dev, errp);
  1035. }
  1036. static void fw_cfg_mem_class_init(ObjectClass *klass, void *data)
  1037. {
  1038. DeviceClass *dc = DEVICE_CLASS(klass);
  1039. dc->realize = fw_cfg_mem_realize;
  1040. dc->props = fw_cfg_mem_properties;
  1041. }
  1042. static const TypeInfo fw_cfg_mem_info = {
  1043. .name = TYPE_FW_CFG_MEM,
  1044. .parent = TYPE_FW_CFG,
  1045. .instance_size = sizeof(FWCfgMemState),
  1046. .class_init = fw_cfg_mem_class_init,
  1047. };
  1048. static void fw_cfg_register_types(void)
  1049. {
  1050. type_register_static(&fw_cfg_info);
  1051. type_register_static(&fw_cfg_io_info);
  1052. type_register_static(&fw_cfg_mem_info);
  1053. }
  1054. type_init(fw_cfg_register_types)