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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [ppc/] [hw_init.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 _HW_INIT_C_
23
#define _HW_INIT_C_
24
 
25
#include "device_table.h"
26
#include "bfd.h"
27
#include "psim.h"
28
 
29
 
30
/* DMA a file into memory */
31
static int
32
dma_file(device *me,
33
         const char *file_name,
34
         unsigned_word addr)
35
{
36
  int count;
37
  int inc;
38
  FILE *image;
39
  char buf[1024];
40
 
41
  /* get it open */
42
  image = fopen(file_name, "r");
43
  if (image == NULL)
44
    return -1;
45
 
46
  /* read it in slowly */
47
  count = 0;
48
  while (1) {
49
    inc = fread(buf, 1, sizeof(buf), image);
50
    if (inc <= 0)
51
      break;
52
    if (device_dma_write_buffer(device_parent(me),
53
                                buf,
54
 
55
                                addr+count,
56
                                inc /*nr-bytes*/,
57
                                1 /*violate ro*/) != inc) {
58
      fclose(image);
59
      return -1;
60
    }
61
    count += inc;
62
  }
63
 
64
  /* close down again */
65
  fclose(image);
66
 
67
  return count;
68
}
69
 
70
 
71
/* DEVICE
72
 
73
   file - load a file into memory
74
 
75
   DESCRIPTION
76
 
77
   Loads the entire contents of <file-name> into memory at starting at
78
   <<real-address>>.  Assumes that memory exists for the load.
79
 
80
   PROPERTIES
81
 
82
   file-name = <string>
83
 
84
   Name of the file to be loaded into memory
85
 
86
   real-address = <integer>
87
 
88
   Real address at which the file is to be loaded */
89
 
90
static void
91
hw_file_init_data_callback(device *me)
92
{
93
  int count;
94
  const char *file_name = device_find_string_property(me, "file-name");
95
  unsigned_word addr = device_find_integer_property(me, "real-address");
96
  /* load the file */
97
  count = dma_file(me, file_name, addr);
98
  if (count < 0)
99
    device_error(me, "Problem loading file %s\n", file_name);
100
}
101
 
102
 
103
static device_callbacks const hw_file_callbacks = {
104
  { NULL, hw_file_init_data_callback, },
105
  { NULL, }, /* address */
106
  { NULL, }, /* IO */
107
  { NULL, }, /* DMA */
108
  { NULL, }, /* interrupt */
109
  { NULL, }, /* unit */
110
};
111
 
112
 
113
/* DEVICE
114
 
115
 
116
   data - initialize a memory location with specified data
117
 
118
 
119
   DESCRIPTION
120
 
121
 
122
   The pseudo device <<data>> provides a mechanism specifying the
123
   initialization of a small section of memory.
124
 
125
   Normally, the data would be written using a dma operation.
126
   However, for some addresses this will not result in the desired
127
   result.  For instance, to initialize an address in an eeprom,
128
   instead of a simple dma of the data, a sequence of writes (and then
129
   real delays) that program the eeprom would be required.
130
 
131
   For dma write initialization, the data device will write the
132
   specified <<data>> to <<real-address>> using a normal dma.
133
 
134
   For instance write initialization, the specified <<instance>> is
135
   opened.  Then a seek to the <<real-address>> is performed followed
136
   by a write of the data.
137
 
138
 
139
   Integer properties are stored using the target's endian mode.
140
 
141
 
142
   PROPERTIES
143
 
144
 
145
   data = <any-valid-property> (required)
146
 
147
   Data to be loaded into memory.  The property type determines how it
148
   is loaded.
149
 
150
 
151
   real-address = <integer> (required)
152
 
153
   Start address at which the data is to be stored.
154
 
155
 
156
   instance = <string> (optional)
157
 
158
   Instance specification of the device that is to be opened so that
159
   the specified data can be written to it.
160
 
161
 
162
   EXAMPLES
163
 
164
 
165
   The examples below illustrate the two alternative mechanisms that
166
   can be used to store the value 0x12345678 at address 0xfff00c00,
167
   which is normally part of the 512k system eeprom.
168
 
169
 
170
   If the eeprom is being modeled by ram (<<memory>> device) then the
171
   standard dma initialization can be used.  By convention: the data
172
   devices are uniquely identified by argumenting them with the
173
   destinations real address; and all data devices are put under the
174
   node <</openprom/init>>.
175
 
176
   | /openprom/memory@0xfff00000/reg 0xfff00000 0x80000
177
   | /openprom/init/data@0x1000/data 0x12345678
178
   | /openprom/init/data@0x1000/real-address 0x1000
179
 
180
 
181
   If instead a real eeprom was being used the instance write method
182
   would instead need to be used (storing just a single byte in an
183
   eeprom requires a complex sequence of accesses).  The
184
   <<real-address>> is specified as <<0x0c00>> which is the offset
185
   into the eeprom.  For brevity, most of the eeprom properties have
186
   been omited.
187
 
188
   | /iobus/eeprom@0xfff00000/reg 0xfff00000 0x80000
189
   | /openprom/init/data@0xfff00c00/real-address 0x0c00
190
   | /openprom/init/data@0xfff00c00/data 0x12345667
191
   | /openprom/init/data@0xfff00c00/instance /iobus/eeprom@0xfff00000/reg
192
 
193
 
194
   BUGS
195
 
196
 
197
   At present, only <<integer>> properties can be specified for an
198
   initial data value.
199
 
200
   */
201
 
202
 
203
static void
204
hw_data_init_data_callback(device *me)
205
{
206
  unsigned_word addr = device_find_integer_property(me, "real-address");
207
  const device_property *data = device_find_property(me, "data");
208
  const char *instance_spec = (device_find_property(me, "instance") != NULL
209
                               ? device_find_string_property(me, "instance")
210
                               : NULL);
211
  device_instance *instance = NULL;
212
  if (data == NULL)
213
    device_error(me, "missing property <data>\n");
214
  if (instance_spec != NULL)
215
    instance = tree_instance(me, instance_spec);
216
  switch (data->type) {
217
  case integer_property:
218
    {
219
      unsigned_cell buf = device_find_integer_property(me, "data");
220
      H2T(buf);
221
      if (instance == NULL) {
222
        if (device_dma_write_buffer(device_parent(me),
223
                                    &buf,
224
 
225
                                    addr,
226
                                    sizeof(buf), /*nr-bytes*/
227
                                    1 /*violate ro*/) != sizeof(buf))
228
          device_error(me, "Problem storing integer 0x%x at 0x%lx\n",
229
                       (unsigned)buf, (unsigned long)addr);
230
      }
231
      else {
232
        if (device_instance_seek(instance, 0, addr) < 0
233
            || device_instance_write(instance, &buf, sizeof(buf)) != sizeof(buf))
234
          device_error(me, "Problem storing integer 0x%x at 0x%lx of instance %s\n",
235
                       (unsigned)buf, (unsigned long)addr, instance_spec);
236
      }
237
    }
238
    break;
239
  default:
240
    device_error(me, "Write of this data is not yet implemented\n");
241
    break;
242
  }
243
  if (instance != NULL)
244
    device_instance_delete(instance);
245
}
246
 
247
 
248
static device_callbacks const hw_data_callbacks = {
249
  { NULL, hw_data_init_data_callback, },
250
  { NULL, }, /* address */
251
  { NULL, }, /* IO */
252
  { NULL, }, /* DMA */
253
  { NULL, }, /* interrupt */
254
  { NULL, }, /* unit */
255
};
256
 
257
 
258
/* DEVICE
259
 
260
 
261
   load-binary - load binary segments into memory
262
 
263
 
264
   DESCRIPTION
265
 
266
   Each loadable segment of the specified binary is loaded into memory
267
   at its required address.  It is assumed that the memory at those
268
   addresses already exists.
269
 
270
   This device is normally used to load an executable into memory as
271
   part of real mode simulation.
272
 
273
 
274
   PROPERTIES
275
 
276
 
277
   file-name = <string>
278
 
279
   Name of the binary to be loaded.
280
 
281
 
282
   claim = <anything> (optional)
283
 
284
   If this property is present, the real memory that is to be used by
285
   the image being loaded will be claimed from the memory node
286
   (specified by the ihandle <</chosen/memory>>).
287
 
288
 
289
   BUGS
290
 
291
 
292
   When loading the binary the bfd virtual-address is used.  It should
293
   be using the bfd load-address.
294
 
295
   */
296
 
297
/* DEVICE
298
 
299
   map-binary - map the binary into the users address space
300
 
301
   DESCRIPTION
302
 
303
   Similar to load-binary except that memory for each segment is
304
   created before the corresponding data for the segment is loaded.
305
 
306
   This device is normally used to load an executable into a user mode
307
   simulation.
308
 
309
   PROPERTIES
310
 
311
   file-name = <string>
312
 
313
   Name of the binary to be loaded.
314
 
315
   */
316
 
317
static void
318
update_for_binary_section(bfd *abfd,
319
                          asection *the_section,
320
                          PTR obj)
321
{
322
  unsigned_word section_vma;
323
  unsigned_word section_size;
324
  access_type access;
325
  device *me = (device*)obj;
326
 
327
  /* skip the section if no memory to allocate */
328
  if (! (bfd_get_section_flags(abfd, the_section) & SEC_ALLOC))
329
    return;
330
 
331
  /* check/ignore any sections of size zero */
332
  section_size = bfd_get_section_size_before_reloc(the_section);
333
  if (section_size == 0)
334
    return;
335
 
336
  /* find where it is to go */
337
  section_vma = bfd_get_section_vma(abfd, the_section);
338
 
339
  DTRACE(binary,
340
         ("name=%-7s, vma=0x%.8lx, size=%6ld, flags=%3lx(%s%s%s%s%s )\n",
341
          bfd_get_section_name(abfd, the_section),
342
          (long)section_vma,
343
          (long)section_size,
344
          (long)bfd_get_section_flags(abfd, the_section),
345
          bfd_get_section_flags(abfd, the_section) & SEC_LOAD ? " LOAD" : "",
346
          bfd_get_section_flags(abfd, the_section) & SEC_CODE ? " CODE" : "",
347
          bfd_get_section_flags(abfd, the_section) & SEC_DATA ? " DATA" : "",
348
          bfd_get_section_flags(abfd, the_section) & SEC_ALLOC ? " ALLOC" : "",
349
          bfd_get_section_flags(abfd, the_section) & SEC_READONLY ? " READONLY" : ""
350
          ));
351
 
352
  /* If there is an .interp section, it means it needs a shared library interpreter.  */
353
  if (strcmp(".interp", bfd_get_section_name(abfd, the_section)) == 0)
354
    error("Shared libraries are not yet supported.\n");
355
 
356
  /* determine the devices access */
357
  access = access_read;
358
  if (bfd_get_section_flags(abfd, the_section) & SEC_CODE)
359
    access |= access_exec;
360
  if (!(bfd_get_section_flags(abfd, the_section) & SEC_READONLY))
361
    access |= access_write;
362
 
363
  /* if claim specified, allocate region from the memory device */
364
  if (device_find_property(me, "claim") != NULL) {
365
    device_instance *memory = tree_find_ihandle_property(me, "/chosen/memory");
366
    unsigned_cell mem_in[3];
367
    unsigned_cell mem_out[1];
368
    mem_in[0] = 0; /*alignment - top-of-stack*/
369
    mem_in[1] = section_size;
370
    mem_in[2] = section_vma;
371
    if (device_instance_call_method(memory, "claim", 3, mem_in, 1, mem_out) < 0)
372
      device_error(me, "failed to claim memory for section at 0x%lx (0x%lx",
373
                   section_vma,
374
                   section_size);
375
    if (mem_out[0] != section_vma)
376
      device_error(me, "section address not as requested");
377
  }
378
 
379
  /* if a map, pass up a request to create the memory in core */
380
  if (strncmp(device_name(me), "map-binary", strlen("map-binary")) == 0)
381
    device_attach_address(device_parent(me),
382
                          attach_raw_memory,
383
 
384
                          section_vma,
385
                          section_size,
386
                          access,
387
                          me);
388
 
389
  /* if a load dma in the required data */
390
  if (bfd_get_section_flags(abfd, the_section) & SEC_LOAD) {
391
    void *section_init = zalloc(section_size);
392
    if (!bfd_get_section_contents(abfd,
393
                                  the_section,
394
                                  section_init, 0,
395
                                  section_size)) {
396
      bfd_perror("binary");
397
      device_error(me, "load of data failed");
398
      return;
399
    }
400
    if (device_dma_write_buffer(device_parent(me),
401
                                section_init,
402
 
403
                                section_vma,
404
                                section_size,
405
                                1 /*violate_read_only*/)
406
        != section_size)
407
      device_error(me, "broken transfer\n");
408
    zfree(section_init); /* only free if load */
409
  }
410
}
411
 
412
static void
413
hw_binary_init_data_callback(device *me)
414
{
415
  /* get the file name */
416
  const char *file_name = device_find_string_property(me, "file-name");
417
  bfd *image;
418
 
419
  /* open the file */
420
  image = bfd_openr(file_name, NULL);
421
  if (image == NULL) {
422
    bfd_perror("binary");
423
    device_error(me, "Failed to open file %s\n", file_name);
424
  }
425
 
426
  /* check it is valid */
427
  if (!bfd_check_format(image, bfd_object)) {
428
    bfd_close(image);
429
    device_error(me, "The file %s has an invalid binary format\n", file_name);
430
  }
431
 
432
  /* and the data sections */
433
  bfd_map_over_sections(image,
434
                        update_for_binary_section,
435
                        (PTR)me);
436
 
437
  bfd_close(image);
438
}
439
 
440
 
441
static device_callbacks const hw_binary_callbacks = {
442
  { NULL, hw_binary_init_data_callback, },
443
  { NULL, }, /* address */
444
  { NULL, }, /* IO */
445
  { NULL, }, /* DMA */
446
  { NULL, }, /* interrupt */
447
  { NULL, }, /* unit */
448
};
449
 
450
 
451
/* DEVICE
452
 
453
   stack - create an initial stack frame in memory
454
 
455
   DESCRIPTION
456
 
457
   Creates a stack frame of the specified type in memory.
458
 
459
   Due to the startup sequence gdb uses when commencing a simulation,
460
   it is not possible for the data to be placed on the stack to be
461
   specified as part of the device tree.  Instead the arguments to be
462
   pushed onto the stack are specified using an IOCTL call.
463
 
464
   The IOCTL takes the additional arguments:
465
 
466
   | unsigned_word stack_end -- where the stack should come down from
467
   | char **argv -- ...
468
   | char **envp -- ...
469
 
470
   PROPERTIES
471
 
472
   stack-type = <string>
473
 
474
   The form of the stack frame that is to be created.
475
 
476
   */
477
 
478
static int
479
sizeof_argument_strings(char **arg)
480
{
481
  int sizeof_strings = 0;
482
 
483
  /* robust */
484
  if (arg == NULL)
485
    return 0;
486
 
487
  /* add up all the string sizes (padding as we go) */
488
  for (; *arg != NULL; arg++) {
489
    int len = strlen(*arg) + 1;
490
    sizeof_strings += ALIGN_8(len);
491
  }
492
 
493
  return sizeof_strings;
494
}
495
 
496
static int
497
number_of_arguments(char **arg)
498
{
499
  int nr;
500
  if (arg == NULL)
501
    return 0;
502
  for (nr = 0; *arg != NULL; arg++, nr++);
503
  return nr;
504
}
505
 
506
static int
507
sizeof_arguments(char **arg)
508
{
509
  return ALIGN_8((number_of_arguments(arg) + 1) * sizeof(unsigned_word));
510
}
511
 
512
static void
513
write_stack_arguments(device *me,
514
                      char **arg,
515
                      unsigned_word start_block,
516
                      unsigned_word end_block,
517
                      unsigned_word start_arg,
518
                      unsigned_word end_arg)
519
{
520
  DTRACE(stack,
521
        ("write_stack_arguments(device=%s, arg=0x%lx, start_block=0x%lx, end_block=0x%lx, start_arg=0x%lx, end_arg=0x%lx)\n",
522
         device_name(me), (long)arg, (long)start_block, (long)end_block, (long)start_arg, (long)end_arg));
523
  if (arg == NULL)
524
    device_error(me, "Attempt to write a null array onto the stack\n");
525
  /* only copy in arguments, memory is already zero */
526
  for (; *arg != NULL; arg++) {
527
    int len = strlen(*arg)+1;
528
    unsigned_word target_start_block;
529
    DTRACE(stack,
530
          ("write_stack_arguments() write %s=%s at %s=0x%lx %s=0x%lx %s=0x%lx\n",
531
           "**arg", *arg, "start_block", (long)start_block,
532
           "len", (long)len, "start_arg", (long)start_arg));
533
    if (psim_write_memory(device_system(me), 0, *arg,
534
                          start_block, len,
535
                          0/*violate_readonly*/) != len)
536
      device_error(me, "Write of **arg (%s) at 0x%lx of stack failed\n",
537
                   *arg, (unsigned long)start_block);
538
    target_start_block = H2T_word(start_block);
539
    if (psim_write_memory(device_system(me), 0, &target_start_block,
540
                          start_arg, sizeof(target_start_block),
541
                          0) != sizeof(target_start_block))
542
      device_error(me, "Write of *arg onto stack failed\n");
543
    start_block += ALIGN_8(len);
544
    start_arg += sizeof(start_block);
545
  }
546
  start_arg += sizeof(start_block); /*the null at the end*/
547
  if (start_block != end_block
548
      || ALIGN_8(start_arg) != end_arg)
549
    device_error(me, "Probable corrpution of stack arguments\n");
550
  DTRACE(stack, ("write_stack_arguments() = void\n"));
551
}
552
 
553
static void
554
create_ppc_elf_stack_frame(device *me,
555
                           unsigned_word bottom_of_stack,
556
                           char **argv,
557
                           char **envp)
558
{
559
  /* fixme - this is over aligned */
560
 
561
  /* information block */
562
  const unsigned sizeof_envp_block = sizeof_argument_strings(envp);
563
  const unsigned_word start_envp_block = bottom_of_stack - sizeof_envp_block;
564
  const unsigned sizeof_argv_block = sizeof_argument_strings(argv);
565
  const unsigned_word start_argv_block = start_envp_block - sizeof_argv_block;
566
 
567
  /* auxiliary vector - contains only one entry */
568
  const unsigned sizeof_aux_entry = 2*sizeof(unsigned_word); /* magic */
569
  const unsigned_word start_aux = start_argv_block - ALIGN_8(sizeof_aux_entry);
570
 
571
  /* environment points (including null sentinal) */
572
  const unsigned sizeof_envp = sizeof_arguments(envp);
573
  const unsigned_word start_envp = start_aux - sizeof_envp;
574
 
575
  /* argument pointers (including null sentinal) */
576
  const int argc = number_of_arguments(argv);
577
  const unsigned sizeof_argv = sizeof_arguments(argv);
578
  const unsigned_word start_argv = start_envp - sizeof_argv;
579
 
580
  /* link register save address - alligned to a 16byte boundary */
581
  const unsigned_word top_of_stack = ((start_argv
582
                                       - 2 * sizeof(unsigned_word))
583
                                      & ~0xf);
584
 
585
  /* install arguments on stack */
586
  write_stack_arguments(me, envp,
587
                        start_envp_block, bottom_of_stack,
588
                        start_envp, start_aux);
589
  write_stack_arguments(me, argv,
590
                        start_argv_block, start_envp_block,
591
                        start_argv, start_envp);
592
 
593
  /* set up the registers */
594
  psim_write_register(device_system(me), -1,
595
                      &top_of_stack, "sp", cooked_transfer);
596
  psim_write_register(device_system(me), -1,
597
                      &argc, "r3", cooked_transfer);
598
  psim_write_register(device_system(me), -1,
599
                      &start_argv, "r4", cooked_transfer);
600
  psim_write_register(device_system(me), -1,
601
                      &start_envp, "r5", cooked_transfer);
602
  psim_write_register(device_system(me), -1,
603
                      &start_aux, "r6", cooked_transfer);
604
}
605
 
606
static void
607
create_ppc_aix_stack_frame(device *me,
608
                           unsigned_word bottom_of_stack,
609
                           char **argv,
610
                           char **envp)
611
{
612
  unsigned_word core_envp;
613
  unsigned_word core_argv;
614
  unsigned_word core_argc;
615
  unsigned_word core_aux;
616
  unsigned_word top_of_stack;
617
 
618
  /* cheat - create an elf stack frame */
619
  create_ppc_elf_stack_frame(me, bottom_of_stack, argv, envp);
620
 
621
  /* extract argument addresses from registers */
622
  psim_read_register(device_system(me), 0,
623
                     &top_of_stack, "r1", cooked_transfer);
624
  psim_read_register(device_system(me), 0,
625
                     &core_argc, "r3", cooked_transfer);
626
  psim_read_register(device_system(me), 0,
627
                     &core_argv, "r4", cooked_transfer);
628
  psim_read_register(device_system(me), 0,
629
                     &core_envp, "r5", cooked_transfer);
630
  psim_read_register(device_system(me), 0,
631
                     &core_aux, "r6", cooked_transfer);
632
 
633
  /* extract arguments from registers */
634
  device_error(me, "Unfinished procedure create_ppc_aix_stack_frame\n");
635
}
636
 
637
 
638
static void
639
create_ppc_chirp_bootargs(device *me,
640
                          char **argv)
641
{
642
  /* concat the arguments */
643
  char args[1024];
644
  char **chp = argv + 1;
645
  args[0] = '\0';
646
  while (*chp != NULL) {
647
    if (strlen(args) > 0)
648
      strcat(args, " ");
649
    if (strlen(args) + strlen(*chp) >= sizeof(args))
650
      device_error(me, "buffer overflow");
651
    strcat(args, *chp);
652
    chp++;
653
  }
654
 
655
  /* set the arguments property */
656
  tree_parse(me, "/chosen/bootargs \"%s", args);
657
}
658
 
659
 
660
static int
661
hw_stack_ioctl(device *me,
662
               cpu *processor,
663
               unsigned_word cia,
664
               device_ioctl_request request,
665
               va_list ap)
666
{
667
  switch (request) {
668
  case device_ioctl_create_stack:
669
    {
670
      unsigned_word stack_pointer = va_arg(ap, unsigned_word);
671
      char **argv = va_arg(ap, char **);
672
      char **envp = va_arg(ap, char **);
673
      const char *stack_type;
674
      DTRACE(stack,
675
             ("stack_ioctl_callback(me=0x%lx:%s processor=0x%lx cia=0x%lx argv=0x%lx envp=0x%lx)\n",
676
              (long)me, device_name(me),
677
              (long)processor,
678
              (long)cia,
679
              (long)argv,
680
              (long)envp));
681
      stack_type = device_find_string_property(me, "stack-type");
682
      if (strcmp(stack_type, "ppc-elf") == 0)
683
        create_ppc_elf_stack_frame(me, stack_pointer, argv, envp);
684
      else if (strcmp(stack_type, "ppc-xcoff") == 0)
685
        create_ppc_aix_stack_frame(me, stack_pointer, argv, envp);
686
      else if (strcmp(stack_type, "chirp") == 0)
687
        create_ppc_chirp_bootargs(me, argv);
688
      else if (strcmp(stack_type, "none") != 0)
689
        device_error(me, "Unknown initial stack frame type %s", stack_type);
690
      DTRACE(stack,
691
             ("stack_ioctl_callback() = void\n"));
692
      break;
693
    }
694
  default:
695
    device_error(me, "Unsupported ioctl requested");
696
    break;
697
  }
698
  return 0;
699
}
700
 
701
static device_callbacks const hw_stack_callbacks = {
702
  { NULL, },
703
  { NULL, }, /* address */
704
  { NULL, }, /* IO */
705
  { NULL, }, /* DMA */
706
  { NULL, }, /* interrupt */
707
  { NULL, }, /* unit */
708
  NULL, /* instance */
709
  hw_stack_ioctl,
710
};
711
 
712
const device_descriptor hw_init_device_descriptor[] = {
713
  { "file", NULL, &hw_file_callbacks },
714
  { "data", NULL, &hw_data_callbacks },
715
  { "load-binary", NULL, &hw_binary_callbacks },
716
  { "map-binary", NULL, &hw_binary_callbacks },
717
  { "stack", NULL, &hw_stack_callbacks },
718
  { NULL },
719
};
720
 
721
#endif _HW_INIT_C_

powered by: WebSVN 2.1.0

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