1/*  This file is part of the program psim.
2
3    Copyright (C) 1994-1996, 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#ifndef _DEVICE_TABLE_H_
23#define _DEVICE_TABLE_H_
24
25#include "basics.h"
26#include "device.h"
27#include "tree.h"
28
29#ifdef HAVE_STRING_H
30#include <string.h>
31#else
32#ifdef HAVE_STRINGS_H
33#include <strings.h>
34#endif
35#endif
36
37
38typedef struct _device_callbacks device_callbacks;
39
40
41/* The creator, returns a pointer to any data that should be allocated
42   once during (multiple) simulation runs */
43
44typedef void *(device_creator)
45     (const char *name,
46      const device_unit *unit_address,
47      const char *args);
48
49
50/* two stages of initialization */
51
52typedef void (device_init_callback)
53     (device *me);
54
55typedef struct _device_init_callbacks {
56  device_init_callback *address; /* NULL - ignore */
57  device_init_callback *data; /* NULL - ignore */
58} device_init_callbacks;
59
60
61/* attaching/detaching a devices address space to its parent */
62
63typedef void (device_address_callback)
64     (device *me,
65      attach_type attach,
66      int space,
67      unsigned_word addr,
68      unsigned nr_bytes,
69      access_type access,
70      device *client); /*callback/default*/
71
72typedef struct _device_address_callbacks {
73  device_address_callback *attach;
74  device_address_callback *detach;
75} device_address_callbacks;
76
77
78/* I/O operations - from parent */
79
80typedef unsigned (device_io_read_buffer_callback)
81     (device *me,
82      void *dest,
83      int space,
84      unsigned_word addr,
85      unsigned nr_bytes,
86      cpu *processor,
87      unsigned_word cia);
88
89typedef unsigned (device_io_write_buffer_callback)
90     (device *me,
91      const void *source,
92      int space,
93      unsigned_word addr,
94      unsigned nr_bytes,
95      cpu *processor,
96      unsigned_word cia);
97
98typedef struct _device_io_callbacks { /* NULL - error */
99  device_io_read_buffer_callback *read_buffer;
100  device_io_write_buffer_callback *write_buffer;
101} device_io_callbacks;
102
103
104/* DMA transfers by a device via its parent */
105
106typedef unsigned (device_dma_read_buffer_callback)
107     (device *me,
108      void *dest,
109      int space,
110      unsigned_word addr,
111      unsigned nr_bytes);
112
113typedef unsigned (device_dma_write_buffer_callback)
114     (device *me,
115      const void *source,
116      int space,
117      unsigned_word addr,
118      unsigned nr_bytes,
119      int violate_read_only_section);
120
121typedef struct _device_dma_callbacks { /* NULL - error */
122  device_dma_read_buffer_callback *read_buffer;
123  device_dma_write_buffer_callback *write_buffer;
124} device_dma_callbacks;
125
126
127/* Interrupts */
128
129typedef void (device_interrupt_event_callback)
130     (device *me,
131      int my_port,
132      device *source,
133      int source_port,
134      int level,
135      cpu *processor,
136      unsigned_word cia);
137
138typedef void (device_child_interrupt_event_callback)
139     (device *me,
140      device *parent,
141      device *source,
142      int source_port,
143      int level,
144      cpu *processor,
145      unsigned_word cia);
146
147typedef struct _device_interrupt_port_descriptor {
148  const char *name;
149  int number;
150  int nr_ports;
151  port_direction direction;
152} device_interrupt_port_descriptor;
153
154typedef struct _device_interrupt_callbacks {
155  device_interrupt_event_callback *event;
156  device_child_interrupt_event_callback *child_event;
157  const device_interrupt_port_descriptor *ports;
158} device_interrupt_callbacks;
159
160
161/* symbolic value decoding */
162
163typedef int (device_unit_decode_callback)
164     (device *bus,
165      const char *unit,
166      device_unit *address);
167
168typedef int (device_unit_encode_callback)
169     (device *bus,
170      const device_unit *unit_address,
171      char *buf,
172      int sizeof_buf);
173
174typedef int (device_address_to_attach_address_callback)
175     (device *bus,
176      const device_unit *address,
177      int *attach_space,
178      unsigned_word *attach_address,
179      device *client);
180
181typedef int (device_size_to_attach_size_callback)
182     (device *bus,
183      const device_unit *size,
184      unsigned *nr_bytes,
185      device *client);
186
187typedef struct _device_convert_callbacks {
188  device_unit_decode_callback *decode_unit;
189  device_unit_encode_callback *encode_unit;
190  device_address_to_attach_address_callback *address_to_attach_address;
191  device_size_to_attach_size_callback *size_to_attach_size;
192} device_convert_callbacks;
193
194
195/* instances */
196
197typedef void (device_instance_delete_callback)
198     (device_instance *instance);
199
200typedef int (device_instance_read_callback)
201     (device_instance *instance,
202      void *buf,
203      unsigned_word len);
204
205typedef int (device_instance_write_callback)
206     (device_instance *instance,
207      const void *buf,
208      unsigned_word len);
209
210typedef int (device_instance_seek_callback)
211     (device_instance *instance,
212      unsigned_word pos_hi,
213      unsigned_word pos_lo);
214
215typedef int (device_instance_method)
216     (device_instance *instance,
217      int n_stack_args,
218      unsigned_cell stack_args[/*n_stack_args*/],
219      int n_stack_returns,
220      unsigned_cell stack_returns[/*n_stack_returns*/]);
221
222typedef struct _device_instance_methods {
223  const char *name;
224  device_instance_method *method;
225} device_instance_methods;
226
227struct _device_instance_callbacks { /* NULL - error */
228  device_instance_delete_callback *delete;
229  device_instance_read_callback *read;
230  device_instance_write_callback *write;
231  device_instance_seek_callback *seek;
232  const device_instance_methods *methods;
233};
234
235typedef device_instance *(device_create_instance_callback)
236     (device *me,
237      const char *full_path,
238      const char *args);
239
240typedef device_instance *(package_create_instance_callback)
241     (device_instance *parent,
242      const char *args);
243
244
245/* all else fails */
246
247typedef int (device_ioctl_callback)
248     (device *me,
249      cpu *processor,
250      unsigned_word cia,
251      device_ioctl_request request,
252      va_list ap);
253
254typedef void (device_usage_callback)
255     (int verbose);
256
257
258/* the callbacks */
259
260struct _device_callbacks {
261
262  /* initialization */
263  device_init_callbacks init;
264
265  /* address/data config - from child */
266  device_address_callbacks address;
267
268  /* address/data transfer - from parent */
269  device_io_callbacks io;
270
271  /* address/data transfer - from child */
272  device_dma_callbacks dma;
273
274  /* interrupt signalling */
275  device_interrupt_callbacks interrupt;
276
277  /* bus address decoding */
278  device_convert_callbacks convert;
279
280  /* instances */
281  device_create_instance_callback *instance_create;
282
283  /* back door to anything we've forgot */
284  device_ioctl_callback *ioctl;
285  device_usage_callback *usage;
286};
287
288
289/* Table of all the devices and a function to lookup/create a device
290   from its name */
291
292typedef struct _device_descriptor device_descriptor;
293struct _device_descriptor {
294  const char *name;
295  device_creator *creator;
296  const device_callbacks *callbacks;
297};
298
299extern const device_descriptor *const device_table[];
300#include "hw.h"
301
302
303/* Pass through, ignore and generic callback functions.  A call going
304   towards the root device are passed on up, local calls are ignored
305   and call downs abort */
306
307extern device_address_callback passthrough_device_address_attach;
308extern device_address_callback passthrough_device_address_detach;
309extern device_dma_read_buffer_callback passthrough_device_dma_read_buffer;
310extern device_dma_write_buffer_callback passthrough_device_dma_write_buffer;
311
312extern device_unit_decode_callback ignore_device_unit_decode;
313
314extern device_init_callback generic_device_init_address;
315extern device_unit_decode_callback generic_device_unit_decode;
316extern device_unit_encode_callback generic_device_unit_encode;
317extern device_address_to_attach_address_callback generic_device_address_to_attach_address;
318extern device_size_to_attach_size_callback generic_device_size_to_attach_size;
319
320
321extern const device_callbacks passthrough_device_callbacks;
322
323#endif /* _DEVICE_TABLE_H_ */
324