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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [ppc/] [emul_generic.c] - Blame information for rev 1774

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

Line No. Rev Author Line
1 578 markom
/*  This file is part of the program psim.
2
 
3
    Copyright (C) 1994-1997, 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 _EMUL_GENERIC_C_
23
#define _EMUL_GENERIC_C_
24
 
25
#include "emul_generic.h"
26
 
27
#ifndef STATIC_INLINE_EMUL_GENERIC
28
#define STATIC_INLINE_EMUL_GENERIC STATIC_INLINE
29
#endif
30
 
31
 
32
STATIC_INLINE_EMUL_GENERIC void
33
emul_syscall_enter(emul_syscall *emul,
34
                   int call,
35
                   int arg0,
36
                   cpu *processor,
37
                   unsigned_word cia)
38
{
39
  printf_filtered("%d:0x%lx:%s(",
40
                  cpu_nr(processor) + 1,
41
                  (long)cia,
42
                  emul->syscall_descriptor[call].name);
43
}
44
 
45
 
46
STATIC_INLINE_EMUL_GENERIC void
47
emul_syscall_exit(emul_syscall *emul,
48
                  int call,
49
                  int arg0,
50
                  cpu *processor,
51
                  unsigned_word cia)
52
{
53
  int status = cpu_registers(processor)->gpr[3];
54
  int error = cpu_registers(processor)->gpr[0];
55
  printf_filtered(")=%d", status);
56
  if (error > 0 && error < emul->nr_error_names)
57
    printf_filtered("[%s]", emul->error_names[error]);
58
  printf_filtered("\n");
59
}
60
 
61
 
62
INLINE_EMUL_GENERIC unsigned64
63
emul_read_gpr64(cpu *processor,
64
                int g)
65
{
66
  unsigned32 hi;
67
  unsigned32 lo;
68
  if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN) {
69
    hi = cpu_registers(processor)->gpr[g];
70
    lo = cpu_registers(processor)->gpr[g+1];
71
  }
72
  else {
73
    lo = cpu_registers(processor)->gpr[g];
74
    hi = cpu_registers(processor)->gpr[g+1];
75
  }
76
  return (INSERTED64(hi, 0, 31) | INSERTED64(lo, 32, 63));
77
}
78
 
79
 
80
INLINE_EMUL_GENERIC void
81
emul_write_gpr64(cpu *processor,
82
                 int g,
83
                 unsigned64 val)
84
{
85
  unsigned32 hi = EXTRACTED64(val, 0, 31);
86
  unsigned32 lo = EXTRACTED64(val, 32, 63);
87
  if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN) {
88
    cpu_registers(processor)->gpr[g] = hi;
89
    cpu_registers(processor)->gpr[g+1] = lo;
90
  }
91
  else {
92
    cpu_registers(processor)->gpr[g] = lo;
93
    cpu_registers(processor)->gpr[g+1] = hi;
94
  }
95
}
96
 
97
 
98
INLINE_EMUL_GENERIC char *
99
emul_read_string(char *dest,
100
                 unsigned_word addr,
101
                 unsigned nr_bytes,
102
                 cpu *processor,
103
                 unsigned_word cia)
104
{
105
  unsigned nr_moved = 0;
106
  if (addr == 0)
107
    return NULL;
108
  while (1) {
109
    dest[nr_moved] = vm_data_map_read_1(cpu_data_map(processor),
110
                                        addr + nr_moved,
111
                                        processor, cia);
112
    if (dest[nr_moved] == '\0' || nr_moved >= nr_bytes)
113
      break;
114
    nr_moved++;
115
  }
116
  dest[nr_moved] = '\0';
117
  return dest;
118
}
119
 
120
 
121
INLINE_EMUL_GENERIC void
122
emul_write_status(cpu *processor,
123
                  int status,
124
                  int errno)
125
{
126
  if (status == -1 && errno != 0) {
127
    cpu_registers(processor)->gpr[3] = errno;
128
    CR_SET(0, cr_i_summary_overflow);
129
  }
130
  else {
131
    cpu_registers(processor)->gpr[3] = status;
132
    CR_SET(0, 0);
133
  }
134
}
135
 
136
 
137
INLINE_EMUL_GENERIC void
138
emul_write2_status(cpu *processor,
139
                   int status1,
140
                   int status2,
141
                   int errno)
142
{
143
  if (status1 == -1 && errno != 0) {
144
    cpu_registers(processor)->gpr[3] = errno;
145
    CR_SET(0, cr_i_summary_overflow);
146
  }
147
  else {
148
    cpu_registers(processor)->gpr[3] = status1;
149
    cpu_registers(processor)->gpr[4] = status2;
150
    CR_SET(0, 0);
151
  }
152
}
153
 
154
 
155
INLINE_EMUL_GENERIC unsigned_word
156
emul_read_word(unsigned_word addr,
157
               cpu *processor,
158
               unsigned_word cia)
159
{
160
  return vm_data_map_read_word(cpu_data_map(processor),
161
                               addr,
162
                               processor, cia);
163
}
164
 
165
 
166
INLINE_EMUL_GENERIC void
167
emul_write_word(unsigned_word addr,
168
                unsigned_word buf,
169
                cpu *processor,
170
                unsigned_word cia)
171
{
172
  vm_data_map_write_word(cpu_data_map(processor),
173
                         addr,
174
                         buf,
175
                         processor, cia);
176
}
177
 
178
 
179
INLINE_EMUL_GENERIC void
180
emul_write_buffer(const void *source,
181
                  unsigned_word addr,
182
                  unsigned nr_bytes,
183
                  cpu *processor,
184
                  unsigned_word cia)
185
{
186
  int nr_moved;
187
  for (nr_moved = 0; nr_moved < nr_bytes; nr_moved++) {
188
    vm_data_map_write_1(cpu_data_map(processor),
189
                        addr + nr_moved,
190
                        ((const char*)source)[nr_moved],
191
                        processor, cia);
192
  }
193
}
194
 
195
 
196
INLINE_EMUL_GENERIC void
197
emul_read_buffer(void *dest,
198
                 unsigned_word addr,
199
                 unsigned nr_bytes,
200
                 cpu *processor,
201
                 unsigned_word cia)
202
{
203
  int nr_moved;
204
  for (nr_moved = 0; nr_moved < nr_bytes; nr_moved++) {
205
    ((char*)dest)[nr_moved] = vm_data_map_read_1(cpu_data_map(processor),
206
                                                 addr + nr_moved,
207
                                                 processor, cia);
208
  }
209
}
210
 
211
 
212
INLINE_EMUL_GENERIC void
213
emul_do_system_call(os_emul_data *emul_data,
214
                    emul_syscall *emul,
215
                    unsigned call,
216
                    const int arg0,
217
                    cpu *processor,
218
                    unsigned_word cia)
219
{
220
  emul_syscall_handler *handler = NULL;
221
  if (call >= emul->nr_system_calls)
222
    error("do_call() os_emul call %d out-of-range\n", call);
223
 
224
  handler = emul->syscall_descriptor[call].handler;
225
  if (handler == NULL) {
226
    if (emul->syscall_descriptor[call].name) {
227
      error("do_call() unimplemented call %s\n", emul->syscall_descriptor[call].name);
228
    } else {
229
      error("do_call() unimplemented call %d\n", call);
230
    }
231
  }
232
 
233
  if (WITH_TRACE && ppc_trace[trace_os_emul])
234
    emul_syscall_enter(emul, call, arg0, processor, cia);
235
 
236
  cpu_registers(processor)->gpr[0] = 0; /* default success */
237
  handler(emul_data, call, arg0, processor, cia);
238
 
239
  if (WITH_TRACE && ppc_trace[trace_os_emul])
240
    emul_syscall_exit(emul, call, arg0, processor, cia);
241
}
242
 
243
 
244
/* default size for the first bank of memory */
245
 
246
#ifndef OEA_MEMORY_SIZE
247
#define OEA_MEMORY_SIZE 0x100000
248
#endif
249
 
250
 
251
/* Add options to the device tree */
252
 
253
INLINE_EMUL_GENERIC void
254
emul_add_tree_options(device *tree,
255
                      bfd *image,
256
                      const char *emul,
257
                      const char *env,
258
                      int oea_interrupt_prefix)
259
{
260
  int little_endian = 0;
261
 
262
  /* sort out little endian */
263
  if (tree_find_property(tree, "/options/little-endian?"))
264
    little_endian = tree_find_boolean_property(tree, "/options/little-endian?");
265
  else {
266
#ifdef bfd_little_endian        /* new bfd */
267
    little_endian = (image != NULL && bfd_little_endian(image));
268
#else
269
    little_endian = (image != NULL &&
270
                     !image->xvec->byteorder_big_p);
271
#endif
272
    tree_parse(tree, "/options/little-endian? %s",
273
               little_endian ? "true" : "false");
274
  }
275
 
276
  /* misc other stuff */
277
  tree_parse(tree, "/openprom/options/oea-memory-size 0x%x",
278
             OEA_MEMORY_SIZE);
279
  tree_parse(tree, "/openprom/options/oea-interrupt-prefix %d",
280
             oea_interrupt_prefix);
281
  tree_parse(tree, "/openprom/options/smp 1");
282
  tree_parse(tree, "/openprom/options/env %s", env);
283
  tree_parse(tree, "/openprom/options/os-emul %s", emul);
284
  tree_parse(tree, "/openprom/options/strict-alignment? %s",
285
             (WITH_ALIGNMENT == STRICT_ALIGNMENT)
286
             ? "true" : "false");
287
  tree_parse(tree, "/openprom/options/floating-point? %s",
288
             WITH_FLOATING_POINT ? "true" : "false");
289
  tree_parse(tree, "/openprom/options/use-stdio? %s",
290
             ((WITH_STDIO == DO_USE_STDIO
291
               || WITH_STDIO == 0)
292
              ? "true" : "false"));
293
  tree_parse(tree, "/openprom/options/model \"%s",
294
             model_name[WITH_DEFAULT_MODEL]);
295
  tree_parse(tree, "/openprom/options/model-issue %d",
296
             MODEL_ISSUE_IGNORE);
297
 
298
  /* useful options */
299
}
300
 
301
INLINE_EMUL_GENERIC void
302
emul_add_tree_hardware(device *root)
303
{
304
  int i;
305
  int nr_cpus = tree_find_integer_property(root, "/openprom/options/smp");
306
 
307
  /* sanity check the number of processors */
308
  if (nr_cpus > MAX_NR_PROCESSORS)
309
    error("Specified number of processors (%d) exceeds the number configured (%d).\n",
310
          nr_cpus, MAX_NR_PROCESSORS);
311
 
312
  /* set the number of address cells (1 or 2) */
313
  tree_parse(root, "#address-cells %d", WITH_TARGET_WORD_BITSIZE / 32);
314
 
315
  /* add some memory */
316
  if (tree_find_device(root, "/memory") == NULL) {
317
    unsigned_word memory_size =
318
      tree_find_integer_property(root, "/openprom/options/oea-memory-size");
319
    const unsigned_word avail_start = 0x3000;
320
    tree_parse(root, "/memory@0/reg 0x0 0x%lx",
321
               (unsigned long)memory_size);
322
    /* reserve the first 0x3000 for the PowerPC interrupt table */
323
    tree_parse(root, "/memory@0/available 0x%lx  0x%lx",
324
               (unsigned long)avail_start,
325
               (unsigned long)memory_size - avail_start);
326
  }
327
 
328
  /* our processors */
329
  for (i = 0; i < nr_cpus; i++) {
330
    tree_parse(root, "/cpus/cpu@%d/cpu-nr %d", i, i);
331
  }
332
 
333
  /* the debugging pal - hide it in the openprom and don't attach it
334
     to any bus */
335
  tree_parse(root, "/openprom/pal");
336
 
337
  /* chosen etc */
338
  tree_parse(root, "/chosen/stdin */openprom/pal");
339
  tree_parse(root, "/chosen/stdout !/chosen/stdin");
340
  tree_parse(root, "/chosen/memory */memory");
341
}
342
 
343
#endif /* _EMUL_GENERIC_C_ */

powered by: WebSVN 2.1.0

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