imx7_snvs.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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/module.h"
  17. #include "sysemu/runstate.h"
  18. static uint64_t imx7_snvs_read(void *opaque, hwaddr offset, unsigned size)
  19. {
  20. return 0;
  21. }
  22. static void imx7_snvs_write(void *opaque, hwaddr offset,
  23. uint64_t v, unsigned size)
  24. {
  25. const uint32_t value = v;
  26. const uint32_t mask = SNVS_LPCR_TOP | SNVS_LPCR_DP_EN;
  27. if (offset == SNVS_LPCR && ((value & mask) == mask)) {
  28. qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
  29. }
  30. }
  31. static const struct MemoryRegionOps imx7_snvs_ops = {
  32. .read = imx7_snvs_read,
  33. .write = imx7_snvs_write,
  34. .endianness = DEVICE_NATIVE_ENDIAN,
  35. .impl = {
  36. /*
  37. * Our device would not work correctly if the guest was doing
  38. * unaligned access. This might not be a limitation on the real
  39. * device but in practice there is no reason for a guest to access
  40. * this device unaligned.
  41. */
  42. .min_access_size = 4,
  43. .max_access_size = 4,
  44. .unaligned = false,
  45. },
  46. };
  47. static void imx7_snvs_init(Object *obj)
  48. {
  49. SysBusDevice *sd = SYS_BUS_DEVICE(obj);
  50. IMX7SNVSState *s = IMX7_SNVS(obj);
  51. memory_region_init_io(&s->mmio, obj, &imx7_snvs_ops, s,
  52. TYPE_IMX7_SNVS, 0x1000);
  53. sysbus_init_mmio(sd, &s->mmio);
  54. }
  55. static void imx7_snvs_class_init(ObjectClass *klass, void *data)
  56. {
  57. DeviceClass *dc = DEVICE_CLASS(klass);
  58. dc->desc = "i.MX7 Secure Non-Volatile Storage Module";
  59. }
  60. static const TypeInfo imx7_snvs_info = {
  61. .name = TYPE_IMX7_SNVS,
  62. .parent = TYPE_SYS_BUS_DEVICE,
  63. .instance_size = sizeof(IMX7SNVSState),
  64. .instance_init = imx7_snvs_init,
  65. .class_init = imx7_snvs_class_init,
  66. };
  67. static void imx7_snvs_register_type(void)
  68. {
  69. type_register_static(&imx7_snvs_info);
  70. }
  71. type_init(imx7_snvs_register_type)