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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [ppc/] [hw_htab.c] - Blame information for rev 1765

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-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 _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
  for (n = htab_nr_bytes; n > 1; n = n / 2) {
221
    if (n % 2 != 0)
222
      device_error(parent, "htab size 0x%x not a power of two",
223
                   htab_nr_bytes);
224
  }
225
  *htaborg = htab_ra;
226
  *htabmask = MASKED32(htab_nr_bytes - 1, 7, 31-6);
227
  if ((htab_ra & INSERTED32(*htabmask, 7, 15)) != 0) {
228
    device_error(parent, "htaborg 0x%lx not aligned to htabmask 0x%lx",
229
                 (unsigned long)*htaborg, (unsigned long)*htabmask);
230
  }
231
  DTRACE(htab, ("htab - htaborg=0x%lx htabmask=0x%lx\n",
232
                (unsigned long)*htaborg, (unsigned long)*htabmask));
233
}
234
 
235
static void
236
htab_map_page(device *me,
237
              unsigned_word ra,
238
              unsigned64 va,
239
              unsigned wimg,
240
              unsigned pp,
241
              unsigned32 htaborg,
242
              unsigned32 htabmask)
243
{
244
  /* keep everything left shifted so that the numbering is easier */
245
  unsigned64 vpn = va << 12;
246
  unsigned32 vsid = INSERTED32(EXTRACTED64(vpn, 0, 23), 0, 23);
247
  unsigned32 vpage = INSERTED32(EXTRACTED64(vpn, 24, 39), 0, 15);
248
  unsigned32 hash = INSERTED32(EXTRACTED32(vsid, 5, 23)
249
                               ^ EXTRACTED32(vpage, 0, 15),
250
                               7, 31-6);
251
  int h;
252
  for (h = 0; h < 2; h++) {
253
    unsigned32 pteg = (htaborg | (hash & htabmask));
254
    int pti;
255
    for (pti = 0; pti < 8; pti++) {
256
      unsigned32 pte = pteg + 8 * pti;
257
      unsigned32 current_target_pte0;
258
      unsigned32 current_pte0;
259
      if (device_dma_read_buffer(device_parent(me),
260
                                 &current_target_pte0,
261
                                 0, /*space*/
262
                                 pte,
263
                                 sizeof(current_target_pte0)) != 4)
264
        device_error(me, "failed to read a pte at 0x%lx", (unsigned long)pte);
265
      current_pte0 = T2H_4(current_target_pte0);
266
      if (MASKED32(current_pte0, 0, 0)) {
267
        /* full pte, check it isn't already mapping the same virtual
268
           address */
269
        unsigned32 curr_vsid = INSERTED32(EXTRACTED32(current_pte0, 1, 24), 0, 23);
270
        unsigned32 curr_api = INSERTED32(EXTRACTED32(current_pte0, 26, 31), 0, 5);
271
        unsigned32 curr_h = EXTRACTED32(current_pte0, 25, 25);
272
        if (curr_h == h
273
            && curr_vsid == vsid
274
            && curr_api == MASKED32(vpage, 0, 5))
275
          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",
276
                       (unsigned long)va,
277
                       (unsigned long)ra,
278
                       (unsigned long)vsid,
279
                       h,
280
                       (unsigned long)vpage,
281
                       (unsigned long)hash,
282
                       (unsigned long)pteg,
283
                       pti * 8,
284
                       (unsigned long)current_pte0);
285
      }
286
      else {
287
        /* empty pte fill it */
288
        unsigned32 pte0 = (MASK32(0, 0)
289
                           | INSERTED32(EXTRACTED32(vsid, 0, 23), 1, 24)
290
                           | INSERTED32(h, 25, 25)
291
                           | INSERTED32(EXTRACTED32(vpage, 0, 5), 26, 31));
292
        unsigned32 target_pte0 = H2T_4(pte0);
293
        unsigned32 pte1 = (INSERTED32(EXTRACTED32(ra, 0, 19), 0, 19)
294
                           | INSERTED32(wimg, 25, 28)
295
                           | INSERTED32(pp, 30, 31));
296
        unsigned32 target_pte1 = H2T_4(pte1);
297
        if (device_dma_write_buffer(device_parent(me),
298
                                    &target_pte0,
299
                                    0, /*space*/
300
                                    pte,
301
                                    sizeof(target_pte0),
302
                                    1/*ro?*/) != 4
303
            || device_dma_write_buffer(device_parent(me),
304
                                       &target_pte1,
305
                                       0, /*space*/
306
                                       pte + 4,
307
                                       sizeof(target_pte1),
308
                                       1/*ro?*/) != 4)
309
          device_error(me, "failed to write a pte a 0x%lx", (unsigned long)pte);
310
        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",
311
                      (unsigned long)va,
312
                      (unsigned long)ra,
313
                      (unsigned long)vsid,
314
                      h,
315
                      (unsigned long)vpage,
316
                      (unsigned long)hash,
317
                      (unsigned long)pteg,
318
                      pti * 8,
319
                      (unsigned long)pte0,
320
                      (unsigned long)pte1));
321
        return;
322
      }
323
    }
324
    /* re-hash */
325
    hash = MASKED32(~hash, 0, 18);
326
  }
327
}
328
 
329
static unsigned_word
330
claim_memory(device *me,
331
             device_instance *memory,
332
             unsigned_word ra,
333
             unsigned_word size)
334
{
335
  unsigned32 args[3];
336
  unsigned32 results[1];
337
  int status;
338
  args[0] = 0; /* alignment */
339
  args[1] = size;
340
  args[2] = ra;
341
  status = device_instance_call_method(memory, "claim", 3, args, 1, results);
342
  if (status != 0)
343
    device_error(me, "failed to claim memory");
344
  return results[0];
345
}
346
 
347
static void
348
htab_map_region(device *me,
349
                device_instance *memory,
350
                unsigned_word pte_ra,
351
                unsigned64 pte_va,
352
                unsigned nr_bytes,
353
                unsigned wimg,
354
                unsigned pp,
355
                unsigned32 htaborg,
356
                unsigned32 htabmask)
357
{
358
  unsigned_word ra;
359
  unsigned64 va;
360
  /* claim the memory */
361
  if (memory != NULL)
362
    claim_memory(me, memory, pte_ra, nr_bytes);
363
  /* go through all pages and create a pte for each */
364
  for (ra = pte_ra, va = pte_va;
365
       ra < pte_ra + nr_bytes;
366
       ra += 0x1000, va += 0x1000) {
367
    htab_map_page(me, ra, va, wimg, pp, htaborg, htabmask);
368
  }
369
}
370
 
371
typedef struct _htab_binary_sizes {
372
  unsigned_word text_ra;
373
  unsigned_word text_base;
374
  unsigned_word text_bound;
375
  unsigned_word data_ra;
376
  unsigned_word data_base;
377
  unsigned data_bound;
378
  device *me;
379
} htab_binary_sizes;
380
 
381
static void
382
htab_sum_binary(bfd *abfd,
383
                sec_ptr sec,
384
                PTR data)
385
{
386
  htab_binary_sizes *sizes = (htab_binary_sizes*)data;
387
  unsigned_word size = bfd_get_section_size_before_reloc (sec);
388
  unsigned_word vma = bfd_get_section_vma (abfd, sec);
389
#define bfd_get_section_lma(abfd, sec) ((sec)->lma + 0)
390
  unsigned_word ra = bfd_get_section_lma (abfd, sec);
391
 
392
  /* skip the section if no memory to allocate */
393
  if (! (bfd_get_section_flags(abfd, sec) & SEC_ALLOC))
394
    return;
395
 
396
  if ((bfd_get_section_flags (abfd, sec) & SEC_CODE)
397
      || (bfd_get_section_flags (abfd, sec) & SEC_READONLY)) {
398
    if (sizes->text_bound < vma + size)
399
      sizes->text_bound = ALIGN_PAGE(vma + size);
400
    if (sizes->text_base > vma)
401
      sizes->text_base = FLOOR_PAGE(vma);
402
    if (sizes->text_ra > ra)
403
      sizes->text_ra = FLOOR_PAGE(ra);
404
  }
405
  else if ((bfd_get_section_flags (abfd, sec) & SEC_DATA)
406
           || (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)) {
407
    if (sizes->data_bound < vma + size)
408
      sizes->data_bound = ALIGN_PAGE(vma + size);
409
    if (sizes->data_base > vma)
410
      sizes->data_base = FLOOR_PAGE(vma);
411
    if (sizes->data_ra > ra)
412
      sizes->data_ra = FLOOR_PAGE(ra);
413
  }
414
}
415
 
416
static void
417
htab_dma_binary(bfd *abfd,
418
                sec_ptr sec,
419
                PTR data)
420
{
421
  htab_binary_sizes *sizes = (htab_binary_sizes*)data;
422
  void *section_init;
423
  unsigned_word section_vma;
424
  unsigned_word section_size;
425
  unsigned_word section_ra;
426
  device *me = sizes->me;
427
 
428
  /* skip the section if no memory to allocate */
429
  if (! (bfd_get_section_flags(abfd, sec) & SEC_ALLOC))
430
    return;
431
 
432
  /* check/ignore any sections of size zero */
433
  section_size = bfd_get_section_size_before_reloc(sec);
434
  if (section_size == 0)
435
    return;
436
 
437
  /* if nothing to load, ignore this one */
438
  if (! (bfd_get_section_flags(abfd, sec) & SEC_LOAD))
439
    return;
440
 
441
  /* find where it is to go */
442
  section_vma = bfd_get_section_vma(abfd, sec);
443
  section_ra = 0;
444
  if ((bfd_get_section_flags (abfd, sec) & SEC_CODE)
445
      || (bfd_get_section_flags (abfd, sec) & SEC_READONLY))
446
    section_ra = (section_vma - sizes->text_base + sizes->text_ra);
447
  else if ((bfd_get_section_flags (abfd, sec) & SEC_DATA))
448
    section_ra = (section_vma - sizes->data_base + sizes->data_ra);
449
  else
450
    return; /* just ignore it */
451
 
452
  DTRACE(htab,
453
         ("load - name=%-7s vma=0x%.8lx size=%6ld ra=0x%.8lx flags=%3lx(%s%s%s%s%s )\n",
454
          bfd_get_section_name(abfd, sec),
455
          (long)section_vma,
456
          (long)section_size,
457
          (long)section_ra,
458
          (long)bfd_get_section_flags(abfd, sec),
459
          bfd_get_section_flags(abfd, sec) & SEC_LOAD ? " LOAD" : "",
460
          bfd_get_section_flags(abfd, sec) & SEC_CODE ? " CODE" : "",
461
          bfd_get_section_flags(abfd, sec) & SEC_DATA ? " DATA" : "",
462
          bfd_get_section_flags(abfd, sec) & SEC_ALLOC ? " ALLOC" : "",
463
          bfd_get_section_flags(abfd, sec) & SEC_READONLY ? " READONLY" : ""
464
          ));
465
 
466
  /* dma in the sections data */
467
  section_init = zalloc(section_size);
468
  if (!bfd_get_section_contents(abfd,
469
                                sec,
470
                                section_init, 0,
471
                                section_size)) {
472
    bfd_perror("devices/pte");
473
    device_error(me, "no data loaded");
474
  }
475
  if (device_dma_write_buffer(device_parent(me),
476
                              section_init,
477
 
478
                              section_ra,
479
                              section_size,
480
                              1 /*violate_read_only*/)
481
      != section_size)
482
    device_error(me, "broken dma transfer");
483
  zfree(section_init); /* only free if load */
484
}
485
 
486
/* create a memory map from a binaries virtual addresses to a copy of
487
   the binary laid out linearly in memory */
488
 
489
static void
490
htab_map_binary(device *me,
491
                device_instance *memory,
492
                unsigned_word ra,
493
                unsigned wimg,
494
                unsigned pp,
495
                const char *file_name,
496
                unsigned32 htaborg,
497
                unsigned32 htabmask)
498
{
499
  htab_binary_sizes sizes;
500
  bfd *image;
501
  sizes.text_ra = -1;
502
  sizes.data_ra = -1;
503
  sizes.text_base = -1;
504
  sizes.data_base = -1;
505
  sizes.text_bound = 0;
506
  sizes.data_bound = 0;
507
  sizes.me = me;
508
 
509
  /* open the file */
510
  image = bfd_openr(file_name, NULL);
511
  if (image == NULL) {
512
    bfd_perror("devices/pte");
513
    device_error(me, "the file %s not loaded", file_name);
514
  }
515
 
516
  /* check it is valid */
517
  if (!bfd_check_format(image, bfd_object)) {
518
    bfd_close(image);
519
    device_error(me, "the file %s has an invalid binary format", file_name);
520
  }
521
 
522
  /* determine the size of each of the files regions */
523
  bfd_map_over_sections (image, htab_sum_binary, (PTR) &sizes);
524
 
525
  /* if needed, determine the real addresses of the sections */
526
  if (ra != -1) {
527
    sizes.text_ra = ra;
528
    sizes.data_ra = ALIGN_PAGE(sizes.text_ra +
529
                               (sizes.text_bound - sizes.text_base));
530
  }
531
 
532
  DTRACE(htab, ("text map - base=0x%lx bound=0x%lx-1 ra=0x%lx\n",
533
                (unsigned long)sizes.text_base,
534
                (unsigned long)sizes.text_bound,
535
                (unsigned long)sizes.text_ra));
536
  DTRACE(htab, ("data map - base=0x%lx bound=0x%lx-1 ra=0x%lx\n",
537
                (unsigned long)sizes.data_base,
538
                (unsigned long)sizes.data_bound,
539
                (unsigned long)sizes.data_ra));
540
 
541
  /* check for and fix a botched image (text and data segments
542
     overlap) */
543
  if ((sizes.text_base <= sizes.data_base
544
       && sizes.text_bound >= sizes.data_bound)
545
      || (sizes.data_base <= sizes.text_base
546
          && sizes.data_bound >= sizes.data_bound)
547
      || (sizes.text_bound > sizes.data_base
548
          && sizes.text_bound <= sizes.data_bound)
549
      || (sizes.text_base >= sizes.data_base
550
          && sizes.text_base < sizes.data_bound)) {
551
    DTRACE(htab, ("text and data segment overlaped - using just data segment\n"));
552
    /* check va->ra linear */
553
    if ((sizes.text_base - sizes.text_ra)
554
        != (sizes.data_base - sizes.data_ra))
555
      device_error(me, "overlapping but missaligned text and data segments");
556
    /* enlarge the data segment */
557
    if (sizes.text_base < sizes.data_base)
558
      sizes.data_base = sizes.text_base;
559
    if (sizes.text_bound > sizes.data_bound)
560
      sizes.data_bound = sizes.text_bound;
561
    if (sizes.text_ra < sizes.data_ra)
562
      sizes.data_ra = sizes.text_ra;
563
    /* zap the text segment */
564
    sizes.text_base = 0;
565
    sizes.text_bound = 0;
566
    sizes.text_ra = 0;
567
    DTRACE(htab, ("common map - base=0x%lx bound=0x%lx-1 ra=0x%lx\n",
568
                  (unsigned long)sizes.data_base,
569
                  (unsigned long)sizes.data_bound,
570
                  (unsigned long)sizes.data_ra));
571
  }
572
 
573
  /* set up virtual memory maps for each of the regions */
574
  htab_map_region(me, memory, sizes.text_ra, sizes.text_base,
575
                  sizes.text_bound - sizes.text_base,
576
                  wimg, pp,
577
                  htaborg, htabmask);
578
 
579
  htab_map_region(me, memory, sizes.data_ra, sizes.data_base,
580
                  sizes.data_bound - sizes.data_base,
581
                  wimg, pp,
582
                  htaborg, htabmask);
583
 
584
  /* dma the sections into physical memory */
585
  bfd_map_over_sections (image, htab_dma_binary, (PTR) &sizes);
586
}
587
 
588
static void
589
htab_init_data_callback(device *me)
590
{
591
  device_instance *memory = NULL;
592
  if (WITH_TARGET_WORD_BITSIZE != 32)
593
    device_error(me, "only 32bit targets currently suported");
594
 
595
  /* find memory device */
596
  if (device_find_property(me, "claim") != NULL)
597
    memory = tree_find_ihandle_property(me, "/chosen/memory");
598
 
599
  /* for the htab, just allocate space for it */
600
  if (strcmp(device_name(me), "htab") == 0) {
601
    unsigned_word address = device_find_integer_property(me, "real-address");
602
    unsigned_word length = device_find_integer_property(me, "nr-bytes");
603
    unsigned_word base = claim_memory(me, memory, address, length);
604
    if (base == -1 || base != address)
605
      device_error(me, "cannot allocate hash table");
606
  }
607
 
608
  /* for the pte, do all the real work */
609
  if (strcmp(device_name(me), "pte") == 0) {
610
    unsigned32 htaborg;
611
    unsigned32 htabmask;
612
 
613
    htab_decode_hash_table(me, &htaborg, &htabmask);
614
 
615
    if (device_find_property(me, "file-name") != NULL) {
616
      /* map in a binary */
617
      unsigned pte_wimg = device_find_integer_property(me, "wimg");
618
      unsigned pte_pp = device_find_integer_property(me, "pp");
619
      const char *file_name = device_find_string_property(me, "file-name");
620
      if (device_find_property(me, "real-address") != NULL) {
621
        unsigned32 pte_ra = device_find_integer_property(me, "real-address");
622
        DTRACE(htab, ("pte - ra=0x%lx, wimg=%ld, pp=%ld, file-name=%s\n",
623
                      (unsigned long)pte_ra,
624
                      (unsigned long)pte_wimg,
625
                      (long)pte_pp,
626
                      file_name));
627
        htab_map_binary(me, memory, pte_ra, pte_wimg, pte_pp, file_name,
628
                        htaborg, htabmask);
629
      }
630
      else {
631
        DTRACE(htab, ("pte - wimg=%ld, pp=%ld, file-name=%s\n",
632
                      (unsigned long)pte_wimg,
633
                      (long)pte_pp,
634
                      file_name));
635
        htab_map_binary(me, memory, -1, pte_wimg, pte_pp, file_name,
636
                        htaborg, htabmask);
637
      }
638
    }
639
    else {
640
      /* handle a normal mapping definition */
641
      unsigned64 pte_va = 0;
642
      unsigned32 pte_ra = device_find_integer_property(me, "real-address");
643
      unsigned pte_nr_bytes = device_find_integer_property(me, "nr-bytes");
644
      unsigned pte_wimg = device_find_integer_property(me, "wimg");
645
      unsigned pte_pp = device_find_integer_property(me, "pp");
646
      signed_cell partial_va;
647
      int i;
648
      for (i = 0;
649
           device_find_integer_array_property(me, "virtual-address", i, &partial_va);
650
           i++) {
651
        pte_va = (pte_va << WITH_TARGET_WORD_BITSIZE) | (unsigned_cell)partial_va;
652
      }
653
      DTRACE(htab, ("pte - ra=0x%lx, wimg=%ld, pp=%ld, va=0x%lx, nr_bytes=%ld\n",
654
                    (unsigned long)pte_ra,
655
                    (long)pte_wimg,
656
                    (long)pte_pp,
657
                    (unsigned long)pte_va,
658
                    (long)pte_nr_bytes));
659
      htab_map_region(me, memory, pte_ra, pte_va, pte_nr_bytes, pte_wimg, pte_pp,
660
                      htaborg, htabmask);
661
    }
662
  }
663
}
664
 
665
 
666
static device_callbacks const htab_callbacks = {
667
  { NULL, htab_init_data_callback, },
668
  { NULL, }, /* address */
669
  { NULL, }, /* IO */
670
  { passthrough_device_dma_read_buffer,
671
    passthrough_device_dma_write_buffer, },
672
  { NULL, }, /* interrupt */
673
  { generic_device_unit_decode,
674
    generic_device_unit_encode, },
675
};
676
 
677
const device_descriptor hw_htab_device_descriptor[] = {
678
  { "htab", NULL, &htab_callbacks },
679
  { "pte", NULL, &htab_callbacks }, /* yep - uses htab's table */
680
  { NULL },
681
};
682
 
683
#endif /* _HW_HTAB_C_ */

powered by: WebSVN 2.1.0

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