imx7_snvs.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /*
  2. * IMX7 Secure Non-Volatile Storage
  3. *
  4. * Copyright (c) 2018, Impinj, Inc.
  5. *
  6. * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
  7. *
  8. * This work is licensed under the terms of the GNU GPL, version 2 or later.
  9. * See the COPYING file in the top-level directory.
  10. *
  11. * Bare minimum emulation code needed to support being able to shut
  12. * down linux guest gracefully.
  13. */
  14. #include "qemu/osdep.h"
  15. #include "hw/misc/imx7_snvs.h"
  16. #include "qemu/log.h"
  17. #include "qemu/module.h"
  18. #include "sysemu/runstate.h"
  19. static uint64_t imx7_snvs_read(void *opaque, hwaddr offset, unsigned size)
  20. {
  21. return 0;
  22. }
  23. static void imx7_snvs_write(void *opaque, hwaddr offset,
  24. uint64_t v, unsigned size)
  25. {
  26. const uint32_t value = v;
  27. const uint32_t mask = SNVS_LPCR_TOP | SNVS_LPCR_DP_EN;
  28. if (offset == SNVS_LPCR && ((value & mask) == mask)) {
  29. qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
  30. }
  31. }
  32. static const struct MemoryRegionOps imx7_snvs_ops = {
  33. .read = imx7_snvs_read,
  34. .write = imx7_snvs_write,
  35. .endianness = DEVICE_NATIVE_ENDIAN,
  36. .impl = {
  37. /*
  38. * Our device would not work correctly if the guest was doing
  39. * unaligned access. This might not be a limitation on the real
  40. * device but in practice there is no reason for a guest to access
  41. * this device unaligned.
  42. */
  43. .min_access_size = 4,
  44. .max_access_size = 4,
  45. .unaligned = false,
  46. },
  47. };
  48. static void imx7_snvs_init(Object *obj)
  49. {
  50. SysBusDevice *sd = SYS_BUS_DEVICE(obj);
  51. IMX7SNVSState *s = IMX7_SNVS(obj);
  52. memory_region_init_io(&s->mmio, obj, &imx7_snvs_ops, s,
  53. TYPE_IMX7_SNVS, 0x1000);
  54. sysbus_init_mmio(sd, &s->mmio);
  55. }
  56. static void imx7_snvs_class_init(ObjectClass *klass, void *data)
  57. {
  58. DeviceClass *dc = DEVICE_CLASS(klass);
  59. dc->desc = "i.MX7 Secure Non-Volatile Storage Module";
  60. }
  61. static const TypeInfo imx7_snvs_info = {
  62. .name = TYPE_IMX7_SNVS,
  63. .parent = TYPE_SYS_BUS_DEVICE,
  64. .instance_size = sizeof(IMX7SNVSState),
  65. .instance_init = imx7_snvs_init,
  66. .class_init = imx7_snvs_class_init,
  67. };
  68. static void imx7_snvs_register_type(void)
  69. {
  70. type_register_static(&imx7_snvs_info);
  71. }
  72. type_init(imx7_snvs_register_type)