1 1.1 christos /* The common simulator framework for GDB, the GNU Debugger. 2 1.1 christos 3 1.11 christos Copyright 2002-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos Contributed by Andrew Cagney and Red Hat. 6 1.1 christos 7 1.1 christos This file is part of GDB. 8 1.1 christos 9 1.1 christos This program is free software; you can redistribute it and/or modify 10 1.1 christos it under the terms of the GNU General Public License as published by 11 1.1 christos the Free Software Foundation; either version 3 of the License, or 12 1.1 christos (at your option) any later version. 13 1.1 christos 14 1.1 christos This program is distributed in the hope that it will be useful, 15 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 16 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 1.1 christos GNU General Public License for more details. 18 1.1 christos 19 1.1 christos You should have received a copy of the GNU General Public License 20 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 1.1 christos 22 1.10 christos /* This must come before any other includes. */ 23 1.10 christos #include "defs.h" 24 1.1 christos 25 1.1 christos #include "hw-main.h" 26 1.1 christos #include "hw-base.h" 27 1.1 christos 28 1.1 christos #include "sim-io.h" 29 1.1 christos #include "sim-assert.h" 30 1.1 christos 31 1.1 christos struct hw_instance_data 32 1.1 christos { 33 1.1 christos hw_finish_instance_method *to_finish; 34 1.1 christos struct hw_instance *instances; 35 1.1 christos }; 36 1.1 christos 37 1.1 christos static hw_finish_instance_method abort_hw_finish_instance; 38 1.1 christos 39 1.1 christos void 40 1.1 christos create_hw_instance_data (struct hw *me) 41 1.1 christos { 42 1.1 christos me->instances_of_hw = HW_ZALLOC (me, struct hw_instance_data); 43 1.1 christos set_hw_finish_instance (me, abort_hw_finish_instance); 44 1.1 christos } 45 1.1 christos 46 1.1 christos void 47 1.1 christos delete_hw_instance_data (struct hw *me) 48 1.1 christos { 49 1.1 christos /* NOP */ 50 1.1 christos } 51 1.1 christos 52 1.1 christos 53 1.1 christos static void 54 1.1 christos abort_hw_finish_instance (struct hw *hw, 55 1.1 christos struct hw_instance *instance) 56 1.1 christos { 57 1.1 christos hw_abort (hw, "no instance finish method"); 58 1.1 christos } 59 1.1 christos 60 1.1 christos void 61 1.1 christos set_hw_finish_instance (struct hw *me, 62 1.1 christos hw_finish_instance_method *finish) 63 1.1 christos { 64 1.1 christos me->instances_of_hw->to_finish = finish; 65 1.1 christos } 66 1.1 christos 67 1.1 christos 68 1.1 christos #if 0 69 1.1 christos void 70 1.1 christos clean_hw_instances (struct hw *me) 71 1.1 christos { 72 1.1 christos struct hw_instance **instance = &me->instances; 73 1.1 christos while (*instance != NULL) 74 1.1 christos { 75 1.1 christos struct hw_instance *old_instance = *instance; 76 1.1 christos hw_instance_delete (old_instance); 77 1.1 christos instance = &me->instances; 78 1.1 christos } 79 1.1 christos } 80 1.1 christos #endif 81 1.1 christos 82 1.1 christos 83 1.1 christos void 84 1.1 christos hw_instance_delete (struct hw_instance *instance) 85 1.1 christos { 86 1.1 christos #if 1 87 1.1 christos hw_abort (hw_instance_hw (instance), "not implemented"); 88 1.1 christos #else 89 1.1 christos struct hw *me = hw_instance_hw (instance); 90 1.1 christos if (instance->to_instance_delete == NULL) 91 1.1 christos hw_abort (me, "no delete method"); 92 1.1 christos instance->method->delete (instance); 93 1.1 christos if (instance->args != NULL) 94 1.1 christos free (instance->args); 95 1.1 christos if (instance->path != NULL) 96 1.1 christos free (instance->path); 97 1.1 christos if (instance->child == NULL) 98 1.1 christos { 99 1.1 christos /* only remove leaf nodes */ 100 1.1 christos struct hw_instance **curr = &me->instances; 101 1.1 christos while (*curr != instance) 102 1.1 christos { 103 1.1 christos ASSERT (*curr != NULL); 104 1.1 christos curr = &(*curr)->next; 105 1.1 christos } 106 1.1 christos *curr = instance->next; 107 1.1 christos } 108 1.1 christos else 109 1.1 christos { 110 1.1 christos /* check it isn't in the instance list */ 111 1.1 christos struct hw_instance *curr = me->instances; 112 1.1 christos while (curr != NULL) 113 1.1 christos { 114 1.1 christos ASSERT (curr != instance); 115 1.1 christos curr = curr->next; 116 1.1 christos } 117 1.1 christos /* unlink the child */ 118 1.1 christos ASSERT (instance->child->parent == instance); 119 1.1 christos instance->child->parent = NULL; 120 1.1 christos } 121 1.1 christos cap_remove (me->ihandles, instance); 122 1.1 christos free (instance); 123 1.1 christos #endif 124 1.1 christos } 125 1.1 christos 126 1.1 christos 127 1.1 christos static int 128 1.1 christos panic_hw_instance_read (struct hw_instance *instance, 129 1.1 christos void *addr, 130 1.1 christos unsigned_word len) 131 1.1 christos { 132 1.1 christos hw_abort (hw_instance_hw (instance), "no read method"); 133 1.1 christos return -1; 134 1.1 christos } 135 1.1 christos 136 1.1 christos 137 1.1 christos 138 1.1 christos static int 139 1.1 christos panic_hw_instance_write (struct hw_instance *instance, 140 1.1 christos const void *addr, 141 1.1 christos unsigned_word len) 142 1.1 christos { 143 1.1 christos hw_abort (hw_instance_hw (instance), "no write method"); 144 1.1 christos return -1; 145 1.1 christos } 146 1.1 christos 147 1.1 christos 148 1.1 christos static int 149 1.1 christos panic_hw_instance_seek (struct hw_instance *instance, 150 1.1 christos unsigned_word pos_hi, 151 1.1 christos unsigned_word pos_lo) 152 1.1 christos { 153 1.1 christos hw_abort (hw_instance_hw (instance), "no seek method"); 154 1.1 christos return -1; 155 1.1 christos } 156 1.1 christos 157 1.1 christos 158 1.1 christos int 159 1.1 christos hw_instance_call_method (struct hw_instance *instance, 160 1.1 christos const char *method_name, 161 1.1 christos int n_stack_args, 162 1.1 christos unsigned_cell stack_args[/*n_stack_args*/], 163 1.1 christos int n_stack_returns, 164 1.1 christos unsigned_cell stack_returns[/*n_stack_args*/]) 165 1.1 christos { 166 1.1 christos #if 1 167 1.1 christos hw_abort (hw_instance_hw (instance), "not implemented"); 168 1.1 christos return -1; 169 1.1 christos #else 170 1.1 christos struct hw *me = instance->owner; 171 1.1 christos const hw_instance_methods *method = instance->method->methods; 172 1.1 christos if (method == NULL) 173 1.1 christos { 174 1.1 christos hw_abort (me, "no methods (want %s)", method_name); 175 1.1 christos } 176 1.1 christos while (method->name != NULL) 177 1.1 christos { 178 1.1 christos if (strcmp (method->name, method_name) == 0) 179 1.1 christos { 180 1.1 christos return method->method (instance, 181 1.1 christos n_stack_args, stack_args, 182 1.1 christos n_stack_returns, stack_returns); 183 1.1 christos } 184 1.1 christos method++; 185 1.1 christos } 186 1.1 christos hw_abort (me, "no %s method", method_name); 187 1.1 christos return 0; 188 1.1 christos #endif 189 1.1 christos } 190 1.1 christos 191 1.1 christos 192 1.1 christos #define set_hw_instance_read(instance, method)\ 193 1.1 christos ((instance)->to_instance_read = (method)) 194 1.1 christos 195 1.1 christos #define set_hw_instance_write(instance, method)\ 196 1.1 christos ((instance)->to_instance_write = (method)) 197 1.1 christos 198 1.1 christos #define set_hw_instance_seek(instance, method)\ 199 1.1 christos ((instance)->to_instance_seek = (method)) 200 1.1 christos 201 1.1 christos 202 1.1 christos #if 0 203 1.1 christos static void 204 1.1 christos set_hw_instance_finish (struct hw *me, 205 1.1 christos hw_instance_finish_method *method) 206 1.1 christos { 207 1.1 christos if (me->instances_of_hw == NULL) 208 1.1 christos me->instances_of_hw = HW_ZALLOC (me, struct hw_instance_data); 209 1.1 christos me->instances_of_hw->to_finish = method; 210 1.1 christos } 211 1.1 christos #endif 212 1.1 christos 213 1.1 christos 214 1.1 christos struct hw_instance * 215 1.1 christos hw_instance_create (struct hw *me, 216 1.1 christos struct hw_instance *parent, 217 1.1 christos const char *path, 218 1.1 christos const char *args) 219 1.1 christos { 220 1.1 christos struct hw_instance *instance = ZALLOC (struct hw_instance); 221 1.1 christos /*instance->unit*/ 222 1.1 christos /* link this instance into the devices list */ 223 1.1 christos instance->hw_of_instance = me; 224 1.1 christos instance->parent_of_instance = NULL; 225 1.1 christos /* link this instance into the front of the devices instance list */ 226 1.1 christos instance->sibling_of_instance = me->instances_of_hw->instances; 227 1.1 christos me->instances_of_hw->instances = instance; 228 1.1 christos if (parent != NULL) 229 1.1 christos { 230 1.1 christos ASSERT (parent->child_of_instance == NULL); 231 1.1 christos parent->child_of_instance = instance; 232 1.1 christos instance->parent_of_instance = parent; 233 1.1 christos } 234 1.1 christos instance->args_of_instance = hw_strdup (me, args); 235 1.1 christos instance->path_of_instance = hw_strdup (me, path); 236 1.1 christos set_hw_instance_read (instance, panic_hw_instance_read); 237 1.1 christos set_hw_instance_write (instance, panic_hw_instance_write); 238 1.1 christos set_hw_instance_seek (instance, panic_hw_instance_seek); 239 1.1 christos hw_handle_add_ihandle (me, instance); 240 1.1 christos me->instances_of_hw->to_finish (me, instance); 241 1.1 christos return instance; 242 1.1 christos } 243 1.1 christos 244 1.1 christos 245 1.1 christos struct hw_instance * 246 1.1 christos hw_instance_interceed (struct hw_instance *parent, 247 1.1 christos const char *path, 248 1.1 christos const char *args) 249 1.1 christos { 250 1.1 christos #if 1 251 1.1 christos return NULL; 252 1.1 christos #else 253 1.1 christos struct hw_instance *instance = ZALLOC (struct hw_instance); 254 1.1 christos /*instance->unit*/ 255 1.1 christos /* link this instance into the devices list */ 256 1.1 christos if (me != NULL) 257 1.1 christos { 258 1.1 christos ASSERT (parent == NULL); 259 1.1 christos instance->hw_of_instance = me; 260 1.1 christos instance->parent_of_instance = NULL; 261 1.1 christos /* link this instance into the front of the devices instance list */ 262 1.1 christos instance->sibling_of_instance = me->instances_of_hw->instances; 263 1.1 christos me->instances_of_hw->instances = instance; 264 1.1 christos } 265 1.1 christos if (parent != NULL) 266 1.1 christos { 267 1.1 christos struct hw_instance **previous; 268 1.1 christos ASSERT (parent->child_of_instance == NULL); 269 1.1 christos parent->child_of_instance = instance; 270 1.1 christos instance->owner = parent->owner; 271 1.1 christos instance->parent_of_instance = parent; 272 1.1 christos /* in the devices instance list replace the parent instance with 273 1.1 christos this one */ 274 1.1 christos instance->next = parent->next; 275 1.1 christos /* replace parent with this new node */ 276 1.1 christos previous = &instance->owner->instances; 277 1.1 christos while (*previous != parent) 278 1.1 christos { 279 1.1 christos ASSERT (*previous != NULL); 280 1.1 christos previous = &(*previous)->next; 281 1.1 christos } 282 1.1 christos *previous = instance; 283 1.1 christos } 284 1.1 christos instance->data = data; 285 1.1 christos instance->args = (args == NULL ? NULL : (char *) strdup (args)); 286 1.1 christos instance->path = (path == NULL ? NULL : (char *) strdup (path)); 287 1.1 christos cap_add (instance->owner->ihandles, instance); 288 1.1 christos return instance; 289 1.1 christos #endif 290 1.1 christos } 291