spapr_nvram.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /*
  2. * QEMU sPAPR NVRAM emulation
  3. *
  4. * Copyright (C) 2012 David Gibson, IBM Corporation.
  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/module.h"
  26. #include "qemu/units.h"
  27. #include "qapi/error.h"
  28. #include <libfdt.h>
  29. #include "system/block-backend.h"
  30. #include "system/device_tree.h"
  31. #include "system/system.h"
  32. #include "system/runstate.h"
  33. #include "migration/vmstate.h"
  34. #include "hw/nvram/chrp_nvram.h"
  35. #include "hw/ppc/spapr.h"
  36. #include "hw/ppc/spapr_vio.h"
  37. #include "hw/qdev-properties.h"
  38. #include "hw/qdev-properties-system.h"
  39. #include "qom/object.h"
  40. struct SpaprNvram {
  41. SpaprVioDevice sdev;
  42. uint32_t size;
  43. uint8_t *buf;
  44. BlockBackend *blk;
  45. VMChangeStateEntry *vmstate;
  46. };
  47. #define TYPE_VIO_SPAPR_NVRAM "spapr-nvram"
  48. OBJECT_DECLARE_SIMPLE_TYPE(SpaprNvram, VIO_SPAPR_NVRAM)
  49. #define MIN_NVRAM_SIZE (8 * KiB)
  50. #define DEFAULT_NVRAM_SIZE (64 * KiB)
  51. #define MAX_NVRAM_SIZE (1 * MiB)
  52. static void rtas_nvram_fetch(PowerPCCPU *cpu, SpaprMachineState *spapr,
  53. uint32_t token, uint32_t nargs,
  54. target_ulong args,
  55. uint32_t nret, target_ulong rets)
  56. {
  57. SpaprNvram *nvram = spapr->nvram;
  58. hwaddr offset, buffer, len;
  59. void *membuf;
  60. if ((nargs != 3) || (nret != 2)) {
  61. rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
  62. return;
  63. }
  64. if (!nvram) {
  65. rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
  66. rtas_st(rets, 1, 0);
  67. return;
  68. }
  69. offset = rtas_ld(args, 0);
  70. buffer = rtas_ld(args, 1);
  71. len = rtas_ld(args, 2);
  72. if (((offset + len) < offset)
  73. || ((offset + len) > nvram->size)) {
  74. rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
  75. rtas_st(rets, 1, 0);
  76. return;
  77. }
  78. assert(nvram->buf);
  79. membuf = cpu_physical_memory_map(buffer, &len, true);
  80. memcpy(membuf, nvram->buf + offset, len);
  81. cpu_physical_memory_unmap(membuf, len, 1, len);
  82. rtas_st(rets, 0, RTAS_OUT_SUCCESS);
  83. rtas_st(rets, 1, len);
  84. }
  85. static void rtas_nvram_store(PowerPCCPU *cpu, SpaprMachineState *spapr,
  86. uint32_t token, uint32_t nargs,
  87. target_ulong args,
  88. uint32_t nret, target_ulong rets)
  89. {
  90. SpaprNvram *nvram = spapr->nvram;
  91. hwaddr offset, buffer, len;
  92. int ret;
  93. void *membuf;
  94. if ((nargs != 3) || (nret != 2)) {
  95. rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
  96. return;
  97. }
  98. if (!nvram) {
  99. rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
  100. return;
  101. }
  102. offset = rtas_ld(args, 0);
  103. buffer = rtas_ld(args, 1);
  104. len = rtas_ld(args, 2);
  105. if (((offset + len) < offset)
  106. || ((offset + len) > nvram->size)) {
  107. rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
  108. return;
  109. }
  110. membuf = cpu_physical_memory_map(buffer, &len, false);
  111. ret = 0;
  112. if (nvram->blk) {
  113. ret = blk_pwrite(nvram->blk, offset, len, membuf, 0);
  114. }
  115. assert(nvram->buf);
  116. memcpy(nvram->buf + offset, membuf, len);
  117. cpu_physical_memory_unmap(membuf, len, 0, len);
  118. rtas_st(rets, 0, (ret < 0) ? RTAS_OUT_HW_ERROR : RTAS_OUT_SUCCESS);
  119. rtas_st(rets, 1, (ret < 0) ? 0 : len);
  120. }
  121. static void spapr_nvram_realize(SpaprVioDevice *dev, Error **errp)
  122. {
  123. SpaprNvram *nvram = VIO_SPAPR_NVRAM(dev);
  124. int ret;
  125. if (nvram->blk) {
  126. int64_t len = blk_getlength(nvram->blk);
  127. if (len < 0) {
  128. error_setg_errno(errp, -len,
  129. "could not get length of backing image");
  130. return;
  131. }
  132. nvram->size = len;
  133. ret = blk_set_perm(nvram->blk,
  134. BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE,
  135. BLK_PERM_ALL, errp);
  136. if (ret < 0) {
  137. return;
  138. }
  139. } else {
  140. nvram->size = DEFAULT_NVRAM_SIZE;
  141. }
  142. nvram->buf = g_malloc0(nvram->size);
  143. if ((nvram->size < MIN_NVRAM_SIZE) || (nvram->size > MAX_NVRAM_SIZE)) {
  144. error_setg(errp,
  145. "spapr-nvram must be between %" PRId64
  146. " and %" PRId64 " bytes in size",
  147. MIN_NVRAM_SIZE, MAX_NVRAM_SIZE);
  148. return;
  149. }
  150. if (nvram->blk) {
  151. ret = blk_pread(nvram->blk, 0, nvram->size, nvram->buf, 0);
  152. if (ret < 0) {
  153. error_setg(errp, "can't read spapr-nvram contents");
  154. return;
  155. }
  156. } else if (nb_prom_envs > 0) {
  157. /* Create a system partition to pass the -prom-env variables */
  158. chrp_nvram_create_system_partition(nvram->buf, MIN_NVRAM_SIZE / 4,
  159. nvram->size);
  160. chrp_nvram_create_free_partition(&nvram->buf[MIN_NVRAM_SIZE / 4],
  161. nvram->size - MIN_NVRAM_SIZE / 4);
  162. }
  163. spapr_rtas_register(RTAS_NVRAM_FETCH, "nvram-fetch", rtas_nvram_fetch);
  164. spapr_rtas_register(RTAS_NVRAM_STORE, "nvram-store", rtas_nvram_store);
  165. }
  166. static int spapr_nvram_devnode(SpaprVioDevice *dev, void *fdt, int node_off)
  167. {
  168. SpaprNvram *nvram = VIO_SPAPR_NVRAM(dev);
  169. return fdt_setprop_cell(fdt, node_off, "#bytes", nvram->size);
  170. }
  171. static int spapr_nvram_pre_load(void *opaque)
  172. {
  173. SpaprNvram *nvram = VIO_SPAPR_NVRAM(opaque);
  174. g_free(nvram->buf);
  175. nvram->buf = NULL;
  176. nvram->size = 0;
  177. return 0;
  178. }
  179. static void postload_update_cb(void *opaque, bool running, RunState state)
  180. {
  181. SpaprNvram *nvram = opaque;
  182. /* This is called after bdrv_activate_all. */
  183. qemu_del_vm_change_state_handler(nvram->vmstate);
  184. nvram->vmstate = NULL;
  185. blk_pwrite(nvram->blk, 0, nvram->size, nvram->buf, 0);
  186. }
  187. static int spapr_nvram_post_load(void *opaque, int version_id)
  188. {
  189. SpaprNvram *nvram = VIO_SPAPR_NVRAM(opaque);
  190. if (nvram->blk) {
  191. nvram->vmstate = qemu_add_vm_change_state_handler(postload_update_cb,
  192. nvram);
  193. }
  194. return 0;
  195. }
  196. static const VMStateDescription vmstate_spapr_nvram = {
  197. .name = "spapr_nvram",
  198. .version_id = 1,
  199. .minimum_version_id = 1,
  200. .pre_load = spapr_nvram_pre_load,
  201. .post_load = spapr_nvram_post_load,
  202. .fields = (const VMStateField[]) {
  203. VMSTATE_UINT32(size, SpaprNvram),
  204. VMSTATE_VBUFFER_ALLOC_UINT32(buf, SpaprNvram, 1, NULL, size),
  205. VMSTATE_END_OF_LIST()
  206. },
  207. };
  208. static const Property spapr_nvram_properties[] = {
  209. DEFINE_SPAPR_PROPERTIES(SpaprNvram, sdev),
  210. DEFINE_PROP_DRIVE("drive", SpaprNvram, blk),
  211. };
  212. static void spapr_nvram_class_init(ObjectClass *klass, void *data)
  213. {
  214. DeviceClass *dc = DEVICE_CLASS(klass);
  215. SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
  216. k->realize = spapr_nvram_realize;
  217. k->devnode = spapr_nvram_devnode;
  218. k->dt_name = "nvram";
  219. k->dt_type = "nvram";
  220. k->dt_compatible = "qemu,spapr-nvram";
  221. set_bit(DEVICE_CATEGORY_MISC, dc->categories);
  222. device_class_set_props(dc, spapr_nvram_properties);
  223. dc->vmsd = &vmstate_spapr_nvram;
  224. /* Reason: Internal device only, uses spapr_rtas_register() in realize() */
  225. dc->user_creatable = false;
  226. }
  227. static const TypeInfo spapr_nvram_type_info = {
  228. .name = TYPE_VIO_SPAPR_NVRAM,
  229. .parent = TYPE_VIO_SPAPR_DEVICE,
  230. .instance_size = sizeof(SpaprNvram),
  231. .class_init = spapr_nvram_class_init,
  232. };
  233. static void spapr_nvram_register_types(void)
  234. {
  235. type_register_static(&spapr_nvram_type_info);
  236. }
  237. type_init(spapr_nvram_register_types)