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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [sim/] [ppc/] [hw_htab.c] - Blame information for rev 280

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

Line No. Rev Author Line
1 24 jeremybenn
/*  This file is part of the program psim.
2
 
3
    Copyright 1994, 1995, 1996, 2003, 2004 Andrew Cagney
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_HTAB_C_
23
#define _HW_HTAB_C_
24
 
25
#include "device_table.h"
26
 
27
#include "bfd.h"
28
 
29
 
30
/* DEVICE
31
 
32
 
33
   htab - pseudo-device describing a PowerPC hash table
34
 
35
 
36
   DESCRIPTION
37
 
38
 
39
   During the initialization of the device tree, the pseudo-device
40
   <<htab>>, in conjunction with any child <<pte>> pseudo-devices,
41
   will create a PowerPC hash table in memory.  The hash table values
42
   are written using dma transfers.
43
 
44
   The size and address of the hash table are determined by properties
45
   of the htab node.
46
 
47
   By convention, the htab device is made a child of the
48
   <</openprom/init>> node.
49
 
50
   By convention, the real address of the htab is used as the htab
51
   nodes unit address.
52
 
53
 
54
   PROPERTIES
55
 
56
 
57
   real-address = <address> (required)
58
 
59
   The physical address of the hash table.  The PowerPC architecture
60
   places limitations on what is a valid hash table real-address.
61
 
62
 
63
   nr-bytes = <size> (required)
64
 
65
   The size of the hash table (in bytes) that is to be created at
66
   <<real-address>>.  The PowerPC architecture places limitations on
67
   what is a valid hash table size.
68
 
69
 
70
   claim = <anything> (optional)
71
 
72
   If this property is present, the memory used to construct the hash
73
   table will be claimed from the memory device.  The memory device
74
   being specified by the <</chosen/memory>> ihandle property.
75
 
76
 
77
   EXAMPLES
78
 
79
   Enable tracing.
80
 
81
   |  $  psim -t htab-device \
82
 
83
 
84
   Create a htab specifying the base address and minimum size.
85
 
86
   |    -o '/openprom/init/htab@0x10000/real-address 0x10000' \
87
   |    -o '/openprom/init/htab@0x10000/claim 0' \
88
   |    -o '/openprom/init/htab@0x10000/nr-bytes 65536' \
89
 
90
 
91
   BUGS
92
 
93
 
94
   See the <<pte>> device.
95
 
96
 
97
   */
98
 
99
 
100
/* DEVICE
101
 
102
 
103
   pte - pseudo-device describing a htab entry
104
 
105
 
106
   DESCRIPTION
107
 
108
 
109
   The <<pte>> pseudo-device, which must be a child of a <<htabl>>
110
   node, describes a virtual to physical mapping that is to be entered
111
   into the parents hash table.
112
 
113
   Two alternative specifications of the mapping are allowed.  Either
114
   a section of physical memory can be mapped to a virtual address, or
115
   the header of an executible image can be used to define the
116
   mapping.
117
 
118
   By convention, the real address of the map is specified as the pte
119
   devices unit address.
120
 
121
 
122
   PROPERTIES
123
 
124
 
125
   real-address = <address> (required)
126
 
127
   The starting physical address that is to be mapped by the hash
128
   table.
129
 
130
 
131
   wimg = <int> (required)
132
   pp = <int> (required)
133
 
134
   The value of hash table protection bits that are to be used when
135
   creating the virtual to physical address map.
136
 
137
 
138
   claim = <anything> (optional)
139
 
140
   If this property is present, the real memory that is being mapped by the
141
   hash table will be claimed from the memory node (specified by the
142
   ihandle <</chosen/memory>>).
143
 
144
 
145
   virtual-address = <integer> [ <integer> ]  (option A)
146
   nr-bytes = <size>  (option A)
147
 
148
   Option A - Virtual virtual address (and size) at which the physical
149
   address is to be mapped.  If multiple values are specified for the
150
   virtual address then they are concatenated to gether to form a
151
   longer virtual address.
152
 
153
 
154
   file-name = <string>  (option B)
155
 
156
   Option B - An executable image that is to be loaded (starting at
157
   the physical address specified above) and then mapped in using
158
   informatioin taken from the executables header.  information found
159
   in the files header.
160
 
161
 
162
   EXAMPLES
163
 
164
 
165
   Enable tracing (note that both the <<htab>> and <<pte>> device use the
166
   same trace option).
167
 
168
   |   -t htab-device \
169
 
170
 
171
   Map a block of physical memory into a specified virtual address:
172
 
173
   |  -o '/openprom/init/htab/pte@0x0/real-address 0' \
174
   |  -o '/openprom/init/htab/pte@0x0/nr-bytes 4096' \
175
   |  -o '/openprom/init/htab/pte@0x0/virtual-address 0x1000000' \
176
   |  -o '/openprom/init/htab/pte@0x0/claim 0' \
177
   |  -o '/openprom/init/htab/pte@0x0/wimg 0x7' \
178
   |  -o '/openprom/init/htab/pte@0x0/pp 0x2' \
179
 
180
 
181
   Map a file into memory.
182
 
183
   |  -o '/openprom/init/htab/pte@0x10000/real-address 0x10000' \
184
   |  -o '/openprom/init/htab/pte@0x10000/file-name "netbsd.elf' \
185
   |  -o '/openprom/init/htab/pte@0x10000/wimg 0x7' \
186
   |  -o '/openprom/init/htab/pte@0x10000/pp 0x2' \
187
 
188
 
189
   BUGS
190
 
191
 
192
   For an ELF executable, the header defines both the virtual and real
193
   address at which each file section should be loaded.  At present, the
194
   real addresses that are specified in the header are ignored, the file
195
   instead being loaded in to physical memory in a linear fashion.
196
 
197
   When claiming memory, this device assumes that the #address-cells
198
   and #size-cells is one.  For future implementations, this may not
199
   be the case.
200
 
201
   */
202
 
203
 
204
 
205
static void
206
htab_decode_hash_table(device *me,
207
                       unsigned32 *htaborg,
208
                       unsigned32 *htabmask)
209
{
210
  unsigned_word htab_ra;
211
  unsigned htab_nr_bytes;
212
  unsigned n;
213
  device *parent = device_parent(me);
214
  /* determine the location/size of the hash table */
215
  if (parent == NULL
216
      || strcmp(device_name(parent), "htab") != 0)
217
    device_error(parent, "must be a htab device");
218
  htab_ra = device_find_integer_property(parent, "real-address");
219
  htab_nr_bytes = device_find_integer_property(parent, "nr-bytes");
220
  if (htab_nr_bytes < 0x10000) {
221
    device_error(parent, "htab size 0x%x less than 0x1000",
222
                 htab_nr_bytes);
223
  }
224
  for (n = htab_nr_bytes; n > 1; n = n / 2) {
225
    if (n % 2 != 0)
226
      device_error(parent, "htab size 0x%x not a power of two",
227
                   htab_nr_bytes);
228
  }
229
  *htaborg = htab_ra;
230
  /* Position the HTABMASK ready for use against a hashed address and
231
     not ready for insertion into SDR1.HTABMASK.  */
232
  *htabmask = MASKED32(htab_nr_bytes - 1, 7, 31-6);
233
  /* Check that the MASK and ADDRESS do not overlap.  */
234
  if ((htab_ra & (*htabmask)) != 0) {
235
    device_error(parent, "htaborg 0x%lx not aligned to htabmask 0x%lx",
236
                 (unsigned long)*htaborg, (unsigned long)*htabmask);
237
  }
238
  DTRACE(htab, ("htab - htaborg=0x%lx htabmask=0x%lx\n",
239
                (unsigned long)*htaborg, (unsigned long)*htabmask));
240
}
241
 
242
static void
243
htab_map_page(device *me,
244
              unsigned_word ra,
245
              unsigned64 va,
246
              unsigned wimg,
247
              unsigned pp,
248
              unsigned32 htaborg,
249
              unsigned32 htabmask)
250
{
251
  /* keep everything left shifted so that the numbering is easier */
252
  unsigned64 vpn = va << 12;
253
  unsigned32 vsid = INSERTED32(EXTRACTED64(vpn, 0, 23), 0, 23);
254
  unsigned32 vpage = INSERTED32(EXTRACTED64(vpn, 24, 39), 0, 15);
255
  unsigned32 hash = INSERTED32(EXTRACTED32(vsid, 5, 23)
256
                               ^ EXTRACTED32(vpage, 0, 15),
257
                               7, 31-6);
258
  int h;
259
  for (h = 0; h < 2; h++) {
260
    unsigned32 pteg = (htaborg | (hash & htabmask));
261
    int pti;
262
    for (pti = 0; pti < 8; pti++) {
263
      unsigned32 pte = pteg + 8 * pti;
264
      unsigned32 current_target_pte0;
265
      unsigned32 current_pte0;
266
      if (device_dma_read_buffer(device_parent(me),
267
                                 &current_target_pte0,
268
                                 0, /*space*/
269
                                 pte,
270
                                 sizeof(current_target_pte0)) != 4)
271
        device_error(me, "failed to read a pte at 0x%lx", (unsigned long)pte);
272
      current_pte0 = T2H_4(current_target_pte0);
273
      if (MASKED32(current_pte0, 0, 0)) {
274
        /* full pte, check it isn't already mapping the same virtual
275
           address */
276
        unsigned32 curr_vsid = INSERTED32(EXTRACTED32(current_pte0, 1, 24), 0, 23);
277
        unsigned32 curr_api = INSERTED32(EXTRACTED32(current_pte0, 26, 31), 0, 5);
278
        unsigned32 curr_h = EXTRACTED32(current_pte0, 25, 25);
279
        if (curr_h == h
280
            && curr_vsid == vsid
281
            && curr_api == MASKED32(vpage, 0, 5))
282
          device_error(me, "duplicate map - va=0x%08lx ra=0x%lx vsid=0x%lx h=%d vpage=0x%lx hash=0x%lx pteg=0x%lx+%2d pte0=0x%lx",
283
                       (unsigned long)va,
284
                       (unsigned long)ra,
285
                       (unsigned long)vsid,
286
                       h,
287
                       (unsigned long)vpage,
288
                       (unsigned long)hash,
289
                       (unsigned long)pteg,
290
                       pti * 8,
291
                       (unsigned long)current_pte0);
292
      }
293
      else {
294
        /* empty pte fill it */
295
        unsigned32 pte0 = (MASK32(0, 0)
296
                           | INSERTED32(EXTRACTED32(vsid, 0, 23), 1, 24)
297
                           | INSERTED32(h, 25, 25)
298
                           | INSERTED32(EXTRACTED32(vpage, 0, 5), 26, 31));
299
        unsigned32 target_pte0 = H2T_4(pte0);
300
        unsigned32 pte1 = (INSERTED32(EXTRACTED32(ra, 0, 19), 0, 19)
301
                           | INSERTED32(wimg, 25, 28)
302
                           | INSERTED32(pp, 30, 31));
303
        unsigned32 target_pte1 = H2T_4(pte1);
304
        if (device_dma_write_buffer(device_parent(me),
305
                                    &target_pte0,
306
                                    0, /*space*/
307
                                    pte,
308
                                    sizeof(target_pte0),
309
                                    1/*ro?*/) != 4
310
            || device_dma_write_buffer(device_parent(me),
311
                                       &target_pte1,
312
                                       0, /*space*/
313
                                       pte + 4,
314
                                       sizeof(target_pte1),
315
                                       1/*ro?*/) != 4)
316
          device_error(me, "failed to write a pte a 0x%lx", (unsigned long)pte);
317
        DTRACE(htab, ("map - va=0x%08lx ra=0x%lx vsid=0x%lx h=%d vpage=0x%lx hash=0x%lx pteg=0x%lx+%2d pte0=0x%lx pte1=0x%lx\n",
318
                      (unsigned long)va,
319
                      (unsigned long)ra,
320
                      (unsigned long)vsid,
321
                      h,
322
                      (unsigned long)vpage,
323
                      (unsigned long)hash,
324
                      (unsigned long)pteg,
325
                      pti * 8,
326
                      (unsigned long)pte0,
327
                      (unsigned long)pte1));
328
        return;
329
      }
330
    }
331
    /* re-hash */
332
    hash = MASKED32(~hash, 0, 18);
333
  }
334
}
335
 
336
static unsigned_word
337
claim_memory(device *me,
338
             device_instance *memory,
339
             unsigned_word ra,
340
             unsigned_word size)
341
{
342
  unsigned32 args[3];
343
  unsigned32 results[1];
344
  int status;
345
  args[0] = 0; /* alignment */
346
  args[1] = size;
347
  args[2] = ra;
348
  status = device_instance_call_method(memory, "claim", 3, args, 1, results);
349
  if (status != 0)
350
    device_error(me, "failed to claim memory");
351
  return results[0];
352
}
353
 
354
static void
355
htab_map_region(device *me,
356
                device_instance *memory,
357
                unsigned_word pte_ra,
358
                unsigned64 pte_va,
359
                unsigned nr_bytes,
360
                unsigned wimg,
361
                unsigned pp,
362
                unsigned32 htaborg,
363
                unsigned32 htabmask)
364
{
365
  unsigned_word ra;
366
  unsigned64 va;
367
  /* claim the memory */
368
  if (memory != NULL)
369
    claim_memory(me, memory, pte_ra, nr_bytes);
370
  /* go through all pages and create a pte for each */
371
  for (ra = pte_ra, va = pte_va;
372
       ra < pte_ra + nr_bytes;
373
       ra += 0x1000, va += 0x1000) {
374
    htab_map_page(me, ra, va, wimg, pp, htaborg, htabmask);
375
  }
376
}
377
 
378
typedef struct _htab_binary_sizes {
379
  unsigned_word text_ra;
380
  unsigned_word text_base;
381
  unsigned_word text_bound;
382
  unsigned_word data_ra;
383
  unsigned_word data_base;
384
  unsigned data_bound;
385
  device *me;
386
} htab_binary_sizes;
387
 
388
static void
389
htab_sum_binary(bfd *abfd,
390
                sec_ptr sec,
391
                PTR data)
392
{
393
  htab_binary_sizes *sizes = (htab_binary_sizes*)data;
394
  unsigned_word size = bfd_get_section_size (sec);
395
  unsigned_word vma = bfd_get_section_vma (abfd, sec);
396
  unsigned_word ra = bfd_get_section_lma (abfd, sec);
397
 
398
  /* skip the section if no memory to allocate */
399
  if (! (bfd_get_section_flags(abfd, sec) & SEC_ALLOC))
400
    return;
401
 
402
  if ((bfd_get_section_flags (abfd, sec) & SEC_CODE)
403
      || (bfd_get_section_flags (abfd, sec) & SEC_READONLY)) {
404
    if (sizes->text_bound < vma + size)
405
      sizes->text_bound = ALIGN_PAGE(vma + size);
406
    if (sizes->text_base > vma)
407
      sizes->text_base = FLOOR_PAGE(vma);
408
    if (sizes->text_ra > ra)
409
      sizes->text_ra = FLOOR_PAGE(ra);
410
  }
411
  else if ((bfd_get_section_flags (abfd, sec) & SEC_DATA)
412
           || (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)) {
413
    if (sizes->data_bound < vma + size)
414
      sizes->data_bound = ALIGN_PAGE(vma + size);
415
    if (sizes->data_base > vma)
416
      sizes->data_base = FLOOR_PAGE(vma);
417
    if (sizes->data_ra > ra)
418
      sizes->data_ra = FLOOR_PAGE(ra);
419
  }
420
}
421
 
422
static void
423
htab_dma_binary(bfd *abfd,
424
                sec_ptr sec,
425
                PTR data)
426
{
427
  htab_binary_sizes *sizes = (htab_binary_sizes*)data;
428
  void *section_init;
429
  unsigned_word section_vma;
430
  unsigned_word section_size;
431
  unsigned_word section_ra;
432
  device *me = sizes->me;
433
 
434
  /* skip the section if no memory to allocate */
435
  if (! (bfd_get_section_flags(abfd, sec) & SEC_ALLOC))
436
    return;
437
 
438
  /* check/ignore any sections of size zero */
439
  section_size = bfd_get_section_size (sec);
440
  if (section_size == 0)
441
    return;
442
 
443
  /* if nothing to load, ignore this one */
444
  if (! (bfd_get_section_flags(abfd, sec) & SEC_LOAD))
445
    return;
446
 
447
  /* find where it is to go */
448
  section_vma = bfd_get_section_vma(abfd, sec);
449
  section_ra = 0;
450
  if ((bfd_get_section_flags (abfd, sec) & SEC_CODE)
451
      || (bfd_get_section_flags (abfd, sec) & SEC_READONLY))
452
    section_ra = (section_vma - sizes->text_base + sizes->text_ra);
453
  else if ((bfd_get_section_flags (abfd, sec) & SEC_DATA))
454
    section_ra = (section_vma - sizes->data_base + sizes->data_ra);
455
  else
456
    return; /* just ignore it */
457
 
458
  DTRACE(htab,
459
         ("load - name=%-7s vma=0x%.8lx size=%6ld ra=0x%.8lx flags=%3lx(%s%s%s%s%s )\n",
460
          bfd_get_section_name(abfd, sec),
461
          (long)section_vma,
462
          (long)section_size,
463
          (long)section_ra,
464
          (long)bfd_get_section_flags(abfd, sec),
465
          bfd_get_section_flags(abfd, sec) & SEC_LOAD ? " LOAD" : "",
466
          bfd_get_section_flags(abfd, sec) & SEC_CODE ? " CODE" : "",
467
          bfd_get_section_flags(abfd, sec) & SEC_DATA ? " DATA" : "",
468
          bfd_get_section_flags(abfd, sec) & SEC_ALLOC ? " ALLOC" : "",
469
          bfd_get_section_flags(abfd, sec) & SEC_READONLY ? " READONLY" : ""
470
          ));
471
 
472
  /* dma in the sections data */
473
  section_init = zalloc(section_size);
474
  if (!bfd_get_section_contents(abfd,
475
                                sec,
476
                                section_init, 0,
477
                                section_size)) {
478
    bfd_perror("devices/pte");
479
    device_error(me, "no data loaded");
480
  }
481
  if (device_dma_write_buffer(device_parent(me),
482
                              section_init,
483
 
484
                              section_ra,
485
                              section_size,
486
                              1 /*violate_read_only*/)
487
      != section_size)
488
    device_error(me, "broken dma transfer");
489
  zfree(section_init); /* only free if load */
490
}
491
 
492
/* create a memory map from a binaries virtual addresses to a copy of
493
   the binary laid out linearly in memory */
494
 
495
static void
496
htab_map_binary(device *me,
497
                device_instance *memory,
498
                unsigned_word ra,
499
                unsigned wimg,
500
                unsigned pp,
501
                const char *file_name,
502
                unsigned32 htaborg,
503
                unsigned32 htabmask)
504
{
505
  htab_binary_sizes sizes;
506
  bfd *image;
507
  sizes.text_ra = -1;
508
  sizes.data_ra = -1;
509
  sizes.text_base = -1;
510
  sizes.data_base = -1;
511
  sizes.text_bound = 0;
512
  sizes.data_bound = 0;
513
  sizes.me = me;
514
 
515
  /* open the file */
516
  image = bfd_openr(file_name, NULL);
517
  if (image == NULL) {
518
    bfd_perror("devices/pte");
519
    device_error(me, "the file %s not loaded", file_name);
520
  }
521
 
522
  /* check it is valid */
523
  if (!bfd_check_format(image, bfd_object)) {
524
    bfd_close(image);
525
    device_error(me, "the file %s has an invalid binary format", file_name);
526
  }
527
 
528
  /* determine the size of each of the files regions */
529
  bfd_map_over_sections (image, htab_sum_binary, (PTR) &sizes);
530
 
531
  /* if needed, determine the real addresses of the sections */
532
  if (ra != -1) {
533
    sizes.text_ra = ra;
534
    sizes.data_ra = ALIGN_PAGE(sizes.text_ra +
535
                               (sizes.text_bound - sizes.text_base));
536
  }
537
 
538
  DTRACE(htab, ("text map - base=0x%lx bound=0x%lx-1 ra=0x%lx\n",
539
                (unsigned long)sizes.text_base,
540
                (unsigned long)sizes.text_bound,
541
                (unsigned long)sizes.text_ra));
542
  DTRACE(htab, ("data map - base=0x%lx bound=0x%lx-1 ra=0x%lx\n",
543
                (unsigned long)sizes.data_base,
544
                (unsigned long)sizes.data_bound,
545
                (unsigned long)sizes.data_ra));
546
 
547
  /* check for and fix a botched image (text and data segments
548
     overlap) */
549
  if ((sizes.text_base <= sizes.data_base
550
       && sizes.text_bound >= sizes.data_bound)
551
      || (sizes.data_base <= sizes.text_base
552
          && sizes.data_bound >= sizes.data_bound)
553
      || (sizes.text_bound > sizes.data_base
554
          && sizes.text_bound <= sizes.data_bound)
555
      || (sizes.text_base >= sizes.data_base
556
          && sizes.text_base < sizes.data_bound)) {
557
    DTRACE(htab, ("text and data segment overlaped - using just data segment\n"));
558
    /* check va->ra linear */
559
    if ((sizes.text_base - sizes.text_ra)
560
        != (sizes.data_base - sizes.data_ra))
561
      device_error(me, "overlapping but missaligned text and data segments");
562
    /* enlarge the data segment */
563
    if (sizes.text_base < sizes.data_base)
564
      sizes.data_base = sizes.text_base;
565
    if (sizes.text_bound > sizes.data_bound)
566
      sizes.data_bound = sizes.text_bound;
567
    if (sizes.text_ra < sizes.data_ra)
568
      sizes.data_ra = sizes.text_ra;
569
    /* zap the text segment */
570
    sizes.text_base = 0;
571
    sizes.text_bound = 0;
572
    sizes.text_ra = 0;
573
    DTRACE(htab, ("common map - base=0x%lx bound=0x%lx-1 ra=0x%lx\n",
574
                  (unsigned long)sizes.data_base,
575
                  (unsigned long)sizes.data_bound,
576
                  (unsigned long)sizes.data_ra));
577
  }
578
 
579
  /* set up virtual memory maps for each of the regions */
580
  if (sizes.text_bound - sizes.text_base > 0) {
581
    htab_map_region(me, memory, sizes.text_ra, sizes.text_base,
582
                    sizes.text_bound - sizes.text_base,
583
                    wimg, pp,
584
                    htaborg, htabmask);
585
  }
586
 
587
  htab_map_region(me, memory, sizes.data_ra, sizes.data_base,
588
                  sizes.data_bound - sizes.data_base,
589
                  wimg, pp,
590
                  htaborg, htabmask);
591
 
592
  /* dma the sections into physical memory */
593
  bfd_map_over_sections (image, htab_dma_binary, (PTR) &sizes);
594
}
595
 
596
static void
597
htab_init_data_callback(device *me)
598
{
599
  device_instance *memory = NULL;
600
  if (WITH_TARGET_WORD_BITSIZE != 32)
601
    device_error(me, "only 32bit targets currently suported");
602
 
603
  /* find memory device */
604
  if (device_find_property(me, "claim") != NULL)
605
    memory = tree_find_ihandle_property(me, "/chosen/memory");
606
 
607
  /* for the htab, just allocate space for it */
608
  if (strcmp(device_name(me), "htab") == 0) {
609
    unsigned_word address = device_find_integer_property(me, "real-address");
610
    unsigned_word length = device_find_integer_property(me, "nr-bytes");
611
    unsigned_word base = claim_memory(me, memory, address, length);
612
    if (base == -1 || base != address)
613
      device_error(me, "cannot allocate hash table");
614
  }
615
 
616
  /* for the pte, do all the real work */
617
  if (strcmp(device_name(me), "pte") == 0) {
618
    unsigned32 htaborg;
619
    unsigned32 htabmask;
620
 
621
    htab_decode_hash_table(me, &htaborg, &htabmask);
622
 
623
    if (device_find_property(me, "file-name") != NULL) {
624
      /* map in a binary */
625
      unsigned pte_wimg = device_find_integer_property(me, "wimg");
626
      unsigned pte_pp = device_find_integer_property(me, "pp");
627
      const char *file_name = device_find_string_property(me, "file-name");
628
      if (device_find_property(me, "real-address") != NULL) {
629
        unsigned32 pte_ra = device_find_integer_property(me, "real-address");
630
        DTRACE(htab, ("pte - ra=0x%lx, wimg=%ld, pp=%ld, file-name=%s\n",
631
                      (unsigned long)pte_ra,
632
                      (unsigned long)pte_wimg,
633
                      (long)pte_pp,
634
                      file_name));
635
        htab_map_binary(me, memory, pte_ra, pte_wimg, pte_pp, file_name,
636
                        htaborg, htabmask);
637
      }
638
      else {
639
        DTRACE(htab, ("pte - wimg=%ld, pp=%ld, file-name=%s\n",
640
                      (unsigned long)pte_wimg,
641
                      (long)pte_pp,
642
                      file_name));
643
        htab_map_binary(me, memory, -1, pte_wimg, pte_pp, file_name,
644
                        htaborg, htabmask);
645
      }
646
    }
647
    else {
648
      /* handle a normal mapping definition */
649
      unsigned64 pte_va = 0;
650
      unsigned32 pte_ra = device_find_integer_property(me, "real-address");
651
      unsigned pte_nr_bytes = device_find_integer_property(me, "nr-bytes");
652
      unsigned pte_wimg = device_find_integer_property(me, "wimg");
653
      unsigned pte_pp = device_find_integer_property(me, "pp");
654
      signed_cell partial_va;
655
      int i;
656
      for (i = 0;
657
           device_find_integer_array_property(me, "virtual-address", i, &partial_va);
658
           i++) {
659
        pte_va = (pte_va << WITH_TARGET_WORD_BITSIZE) | (unsigned_cell)partial_va;
660
      }
661
      DTRACE(htab, ("pte - ra=0x%lx, wimg=%ld, pp=%ld, va=0x%lx, nr_bytes=%ld\n",
662
                    (unsigned long)pte_ra,
663
                    (long)pte_wimg,
664
                    (long)pte_pp,
665
                    (unsigned long)pte_va,
666
                    (long)pte_nr_bytes));
667
      htab_map_region(me, memory, pte_ra, pte_va, pte_nr_bytes, pte_wimg, pte_pp,
668
                      htaborg, htabmask);
669
    }
670
  }
671
}
672
 
673
 
674
static device_callbacks const htab_callbacks = {
675
  { NULL, htab_init_data_callback, },
676
  { NULL, }, /* address */
677
  { NULL, }, /* IO */
678
  { passthrough_device_dma_read_buffer,
679
    passthrough_device_dma_write_buffer, },
680
  { NULL, }, /* interrupt */
681
  { generic_device_unit_decode,
682
    generic_device_unit_encode, },
683
};
684
 
685
const device_descriptor hw_htab_device_descriptor[] = {
686
  { "htab", NULL, &htab_callbacks },
687
  { "pte", NULL, &htab_callbacks }, /* yep - uses htab's table */
688
  { NULL },
689
};
690
 
691
#endif /* _HW_HTAB_C_ */

powered by: WebSVN 2.1.0

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