Do top level sim-hw module for device tree.
[deliverable/binutils-gdb.git] / sim / common / hw-device.c
CommitLineData
e5f0d498
AC
1/* This file is part of the program psim.
2
3 Copyright (C) 1994-1998, Andrew Cagney <cagney@highland.com.au>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21
22#include "sim-main.h"
23
24#include "hw-device.h"
25#include "hw-properties.h"
26
27#if HAVE_STDLIB_H
28#include <stdlib.h>
29#endif
30
31\f
32/* Address methods */
33
34const hw_unit *
35hw_unit_address (struct hw *me)
36{
37 return &me->unit_address_of_hw;
38}
39
40
41\f
42/* IOCTL: */
43
44int
45hw_ioctl (struct hw *me,
46 sim_cpu *processor,
47 sim_cia cia,
48 hw_ioctl_request request,
49 ...)
50{
51 int status;
52 va_list ap;
53 va_start(ap, request);
54 status = me->to_ioctl (me, processor, cia, request, ap);
55 va_end(ap);
56 return status;
57}
58
59/* I/O */
60
61void volatile
62hw_abort (struct hw *me,
63 const char *fmt,
64 ...)
65{
66 SIM_DESC sd;
67 const char *name;
68 va_list ap;
69 va_start(ap, fmt);
70 /* find a system to abort through */
71 if (me == NULL || hw_system (me) == NULL)
72 sd = NULL;
73 else
74 sd = hw_system (me);
75 /* find an identity */
76 if (me != NULL && hw_path (me) != NULL && hw_path (me) [0] != '\0')
77 name = hw_path (me);
78 else if (me != NULL && hw_name (me) != NULL && hw_name (me)[0] != '\0')
79 name = hw_name (me);
80 else if (me != NULL && hw_family (me) != NULL && hw_family (me)[0] != '\0')
81 name = hw_family (me);
82 else
83 name = "device";
84 /* report the problem */
85 sim_io_eprintf (sd, "%s: ", name);
86 sim_io_evprintf (sd, fmt, ap);
87 sim_io_error (sd, "%s", "");
88}
89
937a4bdc
AC
90void
91hw_trace (struct hw *me,
92 const char *fmt,
93 ...)
94{
95 if (hw_trace_p (me)) /* to be sure, to be sure */
96 {
97 va_list ap;
98 va_start (ap, fmt);
99 sim_io_eprintf (hw_system (me), "%s: ", hw_path (me));
100 sim_io_evprintf (hw_system (me), fmt, ap);
101 sim_io_eprintf (hw_system (me), "\n");
102 va_end (ap);
103 }
104}
105
e5f0d498
AC
106\f
107/* The event queue abstraction (for devices) */
108
109
110struct _hw_event {
111 void *data;
112 struct hw *me;
113 hw_event_handler *handler;
114 sim_event *real;
115};
116
117/* Pass the H/W event onto the real handler */
118
119static void
120bounce_hw_event (SIM_DESC sd,
121 void *data)
122{
123 hw_event event = * (hw_event*) data;
124 zfree (data);
125 event.handler (event.me, event.data);
126}
127
128
129/* Map onto the event functions */
130
131hw_event *
132hw_event_queue_schedule (struct hw *me,
133 signed64 delta_time,
134 hw_event_handler *handler,
135 void *data)
136{
137 hw_event *event = ZALLOC (hw_event);
138 event->data = data;
139 event->handler = handler;
140 event->me = me;
141 event->real = sim_events_schedule (hw_system (me),
142 delta_time,
143 bounce_hw_event,
144 event);
145 return event;
146}
147
148void
149hw_event_queue_deschedule (struct hw *me,
150 hw_event *event_to_remove)
151{
152 sim_events_deschedule (hw_system (me),
153 event_to_remove->real);
154 zfree (event_to_remove);
155}
156
157signed64
158hw_event_queue_time (struct hw *me)
159{
160 return sim_events_time (hw_system (me));
161}
162
163\f
164/* Mechanism for associating allocated memory regions to a device.
165 When a device is deleted any remaining memory regions are also
166 reclaimed.
167
168 FIXME: Perhaphs this can be generalized, perhaphs it should not
169 be. */
170
171struct hw_alloc_data {
172 void *alloc;
173 int zalloc_p;
174 struct hw_alloc_data *next;
175};
176
177extern void *
178hw_zalloc (struct hw *me, unsigned long size)
179{
180 struct hw_alloc_data *memory = ZALLOC (struct hw_alloc_data);
181 memory->alloc = zalloc (size);
182 memory->zalloc_p = 1;
183 memory->next = me->alloc_of_hw;
184 me->alloc_of_hw = memory;
185 return memory->alloc;
186}
187
188extern void *
189hw_malloc (struct hw *me, unsigned long size)
190{
191 struct hw_alloc_data *memory = ZALLOC (struct hw_alloc_data);
192 memory->alloc = zalloc (size);
193 memory->zalloc_p = 0;
194 memory->next = me->alloc_of_hw;
195 me->alloc_of_hw = memory;
196 return memory->alloc;
197}
198
199extern void
200hw_free (struct hw *me,
201 void *alloc)
202{
203 struct hw_alloc_data **memory;
204 for (memory = &me->alloc_of_hw;
205 *memory != NULL;
206 memory = &(*memory)->next)
207 {
208 if ((*memory)->alloc == alloc)
209 {
210 struct hw_alloc_data *die = (*memory);
211 (*memory) = die->next;
212 if (die->zalloc_p)
213 zfree (die->alloc);
214 else
215 free (die->alloc);
216 zfree (die);
217 return;
218 }
219 }
220 hw_abort (me, "free of memory not belonging to a device");
221}
222
223extern void
224hw_free_all (struct hw *me)
225{
226 while (me->alloc_of_hw != NULL)
227 {
228 hw_free (me, me->alloc_of_hw->alloc);
229 }
230}
This page took 0.030482 seconds and 4 git commands to generate.