OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [sim/] [ppc/] [device_table.c] - Blame information for rev 106

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
/*  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_C_
23
#define _DEVICE_TABLE_C_
24
 
25
#include "device_table.h"
26
 
27
#if HAVE_STDLIB_H
28
#include <stdlib.h>
29
#endif
30
 
31
#include <ctype.h>
32
 
33
 
34
/* Helper functions */
35
 
36
 
37
/* Go through the devices various reg properties for those that
38
   specify attach addresses */
39
 
40
 
41
void
42
generic_device_init_address(device *me)
43
{
44
  static const char *(reg_property_names[]) = {
45
    "attach-addresses",
46
    "assigned-addresses",
47
    "reg",
48
    "alternate-reg" ,
49
    NULL
50
  };
51
  const char **reg_property_name;
52
  int nr_valid_reg_properties = 0;
53
  for (reg_property_name = reg_property_names;
54
       *reg_property_name != NULL;
55
       reg_property_name++) {
56
    if (device_find_property(me, *reg_property_name) != NULL) {
57
      reg_property_spec reg;
58
      int reg_entry;
59
      for (reg_entry = 0;
60
           device_find_reg_array_property(me, *reg_property_name, reg_entry,
61
                                          &reg);
62
           reg_entry++) {
63
        unsigned_word attach_address;
64
        int attach_space;
65
        unsigned attach_size;
66
        if (!device_address_to_attach_address(device_parent(me),
67
                                              &reg.address,
68
                                              &attach_space, &attach_address,
69
                                              me))
70
          continue;
71
        if (!device_size_to_attach_size(device_parent(me),
72
                                        &reg.size,
73
                                        &attach_size, me))
74
          continue;
75
        device_attach_address(device_parent(me),
76
                              attach_callback,
77
                              attach_space, attach_address, attach_size,
78
                              access_read_write_exec,
79
                              me);
80
        nr_valid_reg_properties++;
81
      }
82
      /* if first option matches don't try for any others */
83
      if (reg_property_name == reg_property_names)
84
        break;
85
    }
86
  }
87
}
88
 
89
int
90
generic_device_unit_decode(device *bus,
91
                           const char *unit,
92
                           device_unit *phys)
93
{
94
  memset(phys, 0, sizeof(device_unit));
95
  if (unit == NULL)
96
    return 0;
97
  else {
98
    int nr_cells = 0;
99
    const int max_nr_cells = device_nr_address_cells(bus);
100
    while (1) {
101
      char *end = NULL;
102
      unsigned long val;
103
      val = strtoul(unit, &end, 0);
104
      /* parse error? */
105
      if (unit == end)
106
        return -1;
107
      /* two many cells? */
108
      if (nr_cells >= max_nr_cells)
109
        return -1;
110
      /* save it */
111
      phys->cells[nr_cells] = val;
112
      nr_cells++;
113
      unit = end;
114
      /* more to follow? */
115
      if (isspace(*unit) || *unit == '\0')
116
        break;
117
      if (*unit != ',')
118
        return -1;
119
      unit++;
120
    }
121
    if (nr_cells < max_nr_cells) {
122
      /* shift everything to correct position */
123
      int i;
124
      for (i = 1; i <= nr_cells; i++)
125
        phys->cells[max_nr_cells - i] = phys->cells[nr_cells - i];
126
      for (i = 0; i < (max_nr_cells - nr_cells); i++)
127
        phys->cells[i] = 0;
128
    }
129
    phys->nr_cells = max_nr_cells;
130
    return max_nr_cells;
131
  }
132
}
133
 
134
int
135
generic_device_unit_encode(device *bus,
136
                           const device_unit *phys,
137
                           char *buf,
138
                           int sizeof_buf)
139
{
140
  int i;
141
  int len;
142
  char *pos = buf;
143
  /* skip leading zero's */
144
  for (i = 0; i < phys->nr_cells; i++) {
145
    if (phys->cells[i] != 0)
146
      break;
147
  }
148
  /* don't output anything if empty */
149
  if (phys->nr_cells == 0) {
150
    strcpy(pos, "");
151
    len = 0;
152
  }
153
  else if (i == phys->nr_cells) {
154
    /* all zero */
155
    strcpy(pos, "0");
156
    len = 1;
157
  }
158
  else {
159
    for (; i < phys->nr_cells; i++) {
160
      if (pos != buf) {
161
        strcat(pos, ",");
162
        pos = strchr(pos, '\0');
163
      }
164
      if (phys->cells[i] < 10)
165
        sprintf(pos, "%ld", (unsigned long)phys->cells[i]);
166
      else
167
        sprintf(pos, "0x%lx", (unsigned long)phys->cells[i]);
168
      pos = strchr(pos, '\0');
169
    }
170
    len = pos - buf;
171
  }
172
  if (len >= sizeof_buf)
173
    error("generic_unit_encode - buffer overflow\n");
174
  return len;
175
}
176
 
177
int
178
generic_device_address_to_attach_address(device *me,
179
                                         const device_unit *address,
180
                                         int *attach_space,
181
                                         unsigned_word *attach_address,
182
                                         device *client)
183
{
184
  int i;
185
  for (i = 0; i < address->nr_cells - 2; i++) {
186
    if (address->cells[i] != 0)
187
      device_error(me, "Only 32bit addresses supported");
188
  }
189
  if (address->nr_cells >= 2)
190
    *attach_space = address->cells[address->nr_cells - 2];
191
  else
192
    *attach_space = 0;
193
  *attach_address = address->cells[address->nr_cells - 1];
194
  return 1;
195
}
196
 
197
int
198
generic_device_size_to_attach_size(device *me,
199
                                   const device_unit *size,
200
                                   unsigned *nr_bytes,
201
                                   device *client)
202
{
203
  int i;
204
  for (i = 0; i < size->nr_cells - 1; i++) {
205
    if (size->cells[i] != 0)
206
      device_error(me, "Only 32bit sizes supported");
207
  }
208
  *nr_bytes = size->cells[0];
209
  return *nr_bytes;
210
}
211
 
212
 
213
/* ignore/passthrough versions of each function */
214
 
215
void
216
passthrough_device_address_attach(device *me,
217
                                  attach_type attach,
218
                                  int space,
219
                                  unsigned_word addr,
220
                                  unsigned nr_bytes,
221
                                  access_type access,
222
                                  device *client) /*callback/default*/
223
{
224
  device_attach_address(device_parent(me), attach,
225
                        space, addr, nr_bytes,
226
                        access,
227
                        client);
228
}
229
 
230
void
231
passthrough_device_address_detach(device *me,
232
                                  attach_type attach,
233
                                  int space,
234
                                  unsigned_word addr,
235
                                  unsigned nr_bytes,
236
                                  access_type access,
237
                                  device *client) /*callback/default*/
238
{
239
  device_detach_address(device_parent(me), attach,
240
                        space, addr, nr_bytes, access,
241
                        client);
242
}
243
 
244
unsigned
245
passthrough_device_dma_read_buffer(device *me,
246
                                   void *dest,
247
                                   int space,
248
                                   unsigned_word addr,
249
                                   unsigned nr_bytes)
250
{
251
  return device_dma_read_buffer(device_parent(me), dest,
252
                                space, addr, nr_bytes);
253
}
254
 
255
unsigned
256
passthrough_device_dma_write_buffer(device *me,
257
                             const void *source,
258
                             int space,
259
                             unsigned_word addr,
260
                             unsigned nr_bytes,
261
                             int violate_read_only_section)
262
{
263
  return device_dma_write_buffer(device_parent(me), source,
264
                                 space, addr,
265
                                 nr_bytes,
266
                                 violate_read_only_section);
267
}
268
 
269
int
270
ignore_device_unit_decode(device *me,
271
                          const char *unit,
272
                          device_unit *phys)
273
{
274
  memset(phys, 0, sizeof(device_unit));
275
  return 0;
276
}
277
 
278
 
279
static const device_callbacks passthrough_callbacks = {
280
  { NULL, }, /* init */
281
  { passthrough_device_address_attach,
282
    passthrough_device_address_detach, },
283
  { NULL, }, /* IO */
284
  { passthrough_device_dma_read_buffer, passthrough_device_dma_write_buffer, },
285
  { NULL, }, /* interrupt */
286
  { generic_device_unit_decode,
287
    generic_device_unit_encode, },
288
};
289
 
290
 
291
static const device_descriptor ob_device_table[] = {
292
  /* standard OpenBoot devices */
293
  { "aliases", NULL, &passthrough_callbacks },
294
  { "options", NULL, &passthrough_callbacks },
295
  { "chosen", NULL, &passthrough_callbacks },
296
  { "packages", NULL, &passthrough_callbacks },
297
  { "cpus", NULL, &passthrough_callbacks },
298
  { "openprom", NULL, &passthrough_callbacks },
299
  { "init", NULL, &passthrough_callbacks },
300
  { NULL },
301
};
302
 
303
const device_descriptor *const device_table[] = {
304
  ob_device_table,
305
#include "hw.c"
306
  NULL,
307
};
308
 
309
 
310
#endif /* _DEVICE_TABLE_C_ */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.