2
0

reset.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. * Reset handlers.
  3. *
  4. * Copyright (c) 2003-2008 Fabrice Bellard
  5. * Copyright (c) 2016 Red Hat, Inc.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. */
  25. #include "qemu/osdep.h"
  26. #include "system/reset.h"
  27. #include "hw/resettable.h"
  28. #include "hw/core/resetcontainer.h"
  29. /*
  30. * Return a pointer to the singleton container that holds all the Resettable
  31. * items that will be reset when qemu_devices_reset() is called.
  32. */
  33. static ResettableContainer *get_root_reset_container(void)
  34. {
  35. static ResettableContainer *root_reset_container;
  36. if (!root_reset_container) {
  37. root_reset_container =
  38. RESETTABLE_CONTAINER(object_new(TYPE_RESETTABLE_CONTAINER));
  39. }
  40. return root_reset_container;
  41. }
  42. /*
  43. * This is an Object which implements Resettable simply to call the
  44. * callback function in the hold phase.
  45. */
  46. #define TYPE_LEGACY_RESET "legacy-reset"
  47. OBJECT_DECLARE_SIMPLE_TYPE(LegacyReset, LEGACY_RESET)
  48. struct LegacyReset {
  49. Object parent;
  50. ResettableState reset_state;
  51. QEMUResetHandler *func;
  52. void *opaque;
  53. bool skip_on_snapshot_load;
  54. };
  55. OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(LegacyReset, legacy_reset, LEGACY_RESET, OBJECT, { TYPE_RESETTABLE_INTERFACE }, { })
  56. static ResettableState *legacy_reset_get_state(Object *obj)
  57. {
  58. LegacyReset *lr = LEGACY_RESET(obj);
  59. return &lr->reset_state;
  60. }
  61. static void legacy_reset_hold(Object *obj, ResetType type)
  62. {
  63. LegacyReset *lr = LEGACY_RESET(obj);
  64. if (type == RESET_TYPE_SNAPSHOT_LOAD && lr->skip_on_snapshot_load) {
  65. return;
  66. }
  67. lr->func(lr->opaque);
  68. }
  69. static void legacy_reset_init(Object *obj)
  70. {
  71. }
  72. static void legacy_reset_finalize(Object *obj)
  73. {
  74. }
  75. static void legacy_reset_class_init(ObjectClass *klass, void *data)
  76. {
  77. ResettableClass *rc = RESETTABLE_CLASS(klass);
  78. rc->get_state = legacy_reset_get_state;
  79. rc->phases.hold = legacy_reset_hold;
  80. }
  81. void qemu_register_reset(QEMUResetHandler *func, void *opaque)
  82. {
  83. Object *obj = object_new(TYPE_LEGACY_RESET);
  84. LegacyReset *lr = LEGACY_RESET(obj);
  85. lr->func = func;
  86. lr->opaque = opaque;
  87. qemu_register_resettable(obj);
  88. }
  89. void qemu_register_reset_nosnapshotload(QEMUResetHandler *func, void *opaque)
  90. {
  91. Object *obj = object_new(TYPE_LEGACY_RESET);
  92. LegacyReset *lr = LEGACY_RESET(obj);
  93. lr->func = func;
  94. lr->opaque = opaque;
  95. lr->skip_on_snapshot_load = true;
  96. qemu_register_resettable(obj);
  97. }
  98. typedef struct FindLegacyInfo {
  99. QEMUResetHandler *func;
  100. void *opaque;
  101. LegacyReset *lr;
  102. } FindLegacyInfo;
  103. static void find_legacy_reset_cb(Object *obj, void *opaque, ResetType type)
  104. {
  105. LegacyReset *lr;
  106. FindLegacyInfo *fli = opaque;
  107. /* Not everything in the ResettableContainer will be a LegacyReset */
  108. lr = LEGACY_RESET(object_dynamic_cast(obj, TYPE_LEGACY_RESET));
  109. if (lr && lr->func == fli->func && lr->opaque == fli->opaque) {
  110. fli->lr = lr;
  111. }
  112. }
  113. static LegacyReset *find_legacy_reset(QEMUResetHandler *func, void *opaque)
  114. {
  115. /*
  116. * Find the LegacyReset with the specified func and opaque,
  117. * by getting the ResettableContainer to call our callback for
  118. * every item in it.
  119. */
  120. ResettableContainer *rootcon = get_root_reset_container();
  121. ResettableClass *rc = RESETTABLE_GET_CLASS(rootcon);
  122. FindLegacyInfo fli;
  123. fli.func = func;
  124. fli.opaque = opaque;
  125. fli.lr = NULL;
  126. rc->child_foreach(OBJECT(rootcon), find_legacy_reset_cb,
  127. &fli, RESET_TYPE_COLD);
  128. return fli.lr;
  129. }
  130. void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
  131. {
  132. Object *obj = OBJECT(find_legacy_reset(func, opaque));
  133. if (obj) {
  134. qemu_unregister_resettable(obj);
  135. object_unref(obj);
  136. }
  137. }
  138. void qemu_register_resettable(Object *obj)
  139. {
  140. resettable_container_add(get_root_reset_container(), obj);
  141. }
  142. void qemu_unregister_resettable(Object *obj)
  143. {
  144. resettable_container_remove(get_root_reset_container(), obj);
  145. }
  146. void qemu_devices_reset(ResetType type)
  147. {
  148. /* Reset the simulation */
  149. resettable_reset(OBJECT(get_root_reset_container()), type);
  150. }