1 /*
2 * Copyright (c) 2011 Aeroflex Gaisler
3 *
4 * BSD license:
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25
26 #include <asm-leon/amba.h>
27 #undef AMBA_TYPE_AHBIO_ADDR
28 #include <asm-leon/lambapp.h>
29 #include <string.h>
30
31 #define AMBA_CONF_AREA 0xff000
32 #define AMBA_AHB_SLAVE_CONF_AREA (1 << 11)
33 #define AMBA_APB_SLAVES 16
34
35 #define DPRINTF(p) printf p
36
37 /* Allocate */
38 struct ambapp_dev_hdr *
ambapp_alloc_dev_struct(int dev_type)39 ambapp_alloc_dev_struct (int dev_type)
40 {
41 int size = sizeof (struct ambapp_dev_hdr);
42 struct ambapp_dev_hdr *dev;
43
44 if (dev_type == DEV_APB_SLV)
45 {
46 size += sizeof (struct ambapp_apb_info);
47 }
48 else
49 {
50 /* AHB */
51 size += sizeof (struct ambapp_ahb_info);
52 }
53 dev = malloc (size);
54 if (dev == NULL)
55 return NULL;
56 memset (dev, 0, size);
57 dev->devinfo = (void *) (dev + 1);
58 dev->dev_type = dev_type;
59 return dev;
60 }
61
62 unsigned int
ambapp_addr_from(struct ambapp_mmap * mmaps,unsigned int address)63 ambapp_addr_from (struct ambapp_mmap *mmaps, unsigned int address)
64 {
65 /* no translation? */
66 if (!mmaps)
67 return address;
68
69 while (mmaps->size)
70 {
71 if ((address >= mmaps->remote_adr)
72 && (address <= (mmaps->remote_adr + (mmaps->size - 1))))
73 {
74 return (address - mmaps->remote_adr) + mmaps->local_adr;
75 }
76 mmaps++;
77 }
78 return 1;
79 }
80
81 void
ambapp_ahb_dev_init(unsigned int ioarea,struct ambapp_mmap * mmaps,struct ambapp_pnp_ahb * ahb,struct ambapp_dev_hdr * dev)82 ambapp_ahb_dev_init (unsigned int ioarea,
83 struct ambapp_mmap *mmaps,
84 struct ambapp_pnp_ahb *ahb, struct ambapp_dev_hdr *dev)
85 {
86 int bar;
87 struct ambapp_ahb_info *ahb_info;
88 unsigned int addr, mask, mbar;
89
90 /* Setup device struct */
91 dev->vendor = ambapp_pnp_vendor (ahb->id);
92 dev->device = ambapp_pnp_device (ahb->id);
93 ahb_info = dev->devinfo;
94 ahb_info->ver = ambapp_pnp_ver (ahb->id);
95 ahb_info->irq = ambapp_pnp_irq (ahb->id);
96 ahb_info->custom[0] = (unsigned int) ahb->custom[0];
97 ahb_info->custom[1] = (unsigned int) ahb->custom[1];
98 ahb_info->custom[2] = (unsigned int) ahb->custom[2];
99
100 DPRINTF (("+AHB device %d:%d\n", dev->device, dev->vendor));
101
102 /* Memory BARs */
103 for (bar = 0; bar < 4; bar++)
104 {
105 mbar = ahb->mbar[bar];
106 if (mbar == 0)
107 {
108 addr = 0;
109 mask = 0;
110 }
111 else
112 {
113 addr = ambapp_pnp_start (mbar);
114 if (ambapp_pnp_mbar_type (mbar) == AMBA_TYPE_AHBIO)
115 {
116 /* AHB I/O area is releative IO_AREA */
117 addr = AMBA_TYPE_AHBIO_ADDR (addr, ioarea);
118 mask =
119 (((unsigned int) (ambapp_pnp_mbar_mask ((~mbar)) << 8) |
120 0xff)) + 1;
121 }
122 else
123 {
124 /* AHB memory area, absolute address */
125 addr = ambapp_addr_from (mmaps, addr);
126 mask =
127 (~((unsigned int) (ambapp_pnp_mbar_mask (mbar) << 20))) + 1;
128 }
129 }
130 ahb_info->start[bar] = addr;
131 ahb_info->mask[bar] = mask;
132 }
133 }
134
135 void
ambapp_apb_dev_init(unsigned int base,struct ambapp_mmap * mmaps,struct ambapp_pnp_apb * apb,struct ambapp_dev_hdr * dev)136 ambapp_apb_dev_init (unsigned int base,
137 struct ambapp_mmap *mmaps,
138 struct ambapp_pnp_apb *apb, struct ambapp_dev_hdr *dev)
139 {
140 struct ambapp_apb_info *apb_info;
141
142 /* Setup device struct */
143 dev->vendor = ambapp_pnp_vendor (apb->id);
144 dev->device = ambapp_pnp_device (apb->id);
145 apb_info = dev->devinfo;
146 apb_info->ver = ambapp_pnp_ver (apb->id);
147 apb_info->irq = ambapp_pnp_irq (apb->id);
148 apb_info->start = ambapp_pnp_apb_start (apb->iobar, base);
149 apb_info->mask = ambapp_pnp_apb_mask (apb->iobar);
150
151 DPRINTF (("+APB device %d:%d\n", dev->device, dev->vendor));
152
153
154 }
155
156 #define MAX_NUM_BUSES 16
157 void
ambapp_add_scanned_bus(unsigned int * ioareas,unsigned int ioarea)158 ambapp_add_scanned_bus (unsigned int *ioareas, unsigned int ioarea)
159 {
160 int i;
161 for (i = 0; i < MAX_NUM_BUSES; i++)
162 {
163 if (ioareas[i] == 0)
164 {
165 ioareas[i] = ioarea;
166 return;
167 }
168 }
169 }
170
171 int
ambapp_has_been_scanned(unsigned int * ioareas,unsigned int ioarea)172 ambapp_has_been_scanned (unsigned int *ioareas, unsigned int ioarea)
173 {
174 int i;
175 if (!ioareas)
176 return 0;
177
178 for (i = 0; i < MAX_NUM_BUSES; i++)
179 {
180 if (ioareas[i] == 0)
181 {
182 break;
183 }
184 else if (ioareas[i] == ioarea)
185 {
186 return 1;
187 }
188 }
189 return 0;
190 }
191
192 int
ambapp_scan(unsigned int ioarea,struct ambapp_dev_hdr * parent,struct ambapp_mmap * mmaps,void * (* memfunc)(void * dest,const void * src,int n),struct ambapp_dev_hdr ** root,void * internal)193 ambapp_scan (unsigned int ioarea,
194 struct ambapp_dev_hdr *parent,
195 struct ambapp_mmap *mmaps,
196 void *(*memfunc) (void *dest, const void *src, int n),
197 struct ambapp_dev_hdr **root, void *internal)
198 {
199 struct ambapp_pnp_ahb *ahb, ahb_buf;
200 struct ambapp_pnp_apb *apb, apb_buf;
201 struct ambapp_dev_hdr *dev, *prev, *prevapb, *apbdev;
202 struct ambapp_ahb_info *ahb_info;
203 int maxloops = 64;
204 unsigned int apbbase, bridge_address;
205 int i, j;
206
207 DPRINTF (("Scan at 0x%08x\n", ioarea));
208
209 /* Default to memcpy() */
210 if (!memfunc)
211 memfunc = (void *(*)(void *dest, const void *src, int n)) memcpy;
212
213 *root = NULL;
214
215 if (parent)
216 {
217 /* scan first bus for 64 devices, rest for 16 devices */
218 maxloops = 16;
219 }
220 else
221 {
222 DPRINTF (("+(malloc:"));
223 internal = malloc (sizeof (unsigned int) * MAX_NUM_BUSES);
224 DPRINTF (("0x%x)\n", internal));
225
226 if (!internal)
227 return -1;
228 memset (internal, 0, sizeof (unsigned int) * MAX_NUM_BUSES);
229
230 ambapp_add_scanned_bus (internal, ioarea);
231 }
232
233 prev = parent;
234
235 /* AHB MASTERS */
236 ahb = (struct ambapp_pnp_ahb *) (ioarea | AMBA_CONF_AREA);
237 for (i = 0; i < maxloops; i++)
238 {
239 memfunc (&ahb_buf, ahb, sizeof (struct ambapp_pnp_ahb));
240 if (ahb_buf.id != 0)
241 {
242 /* A AHB device present here */
243 dev = ambapp_alloc_dev_struct (DEV_AHB_MST);
244 if (!dev)
245 return -1;
246
247 ambapp_ahb_dev_init (ioarea, mmaps, &ahb_buf, dev);
248
249 if (*root == NULL)
250 *root = dev;
251
252 if (prev != parent)
253 prev->next = dev;
254 dev->prev = prev;
255 prev = dev;
256 }
257 ahb++;
258 }
259
260 /* AHB SLAVES */
261 ahb =
262 (struct ambapp_pnp_ahb *) (ioarea | AMBA_CONF_AREA |
263 AMBA_AHB_SLAVE_CONF_AREA);
264 for (i = 0; i < maxloops; i++)
265 {
266 memfunc (&ahb_buf, ahb, sizeof (struct ambapp_pnp_ahb));
267 if (ahb_buf.id != 0)
268 {
269 /* A AHB device present here */
270 dev = ambapp_alloc_dev_struct (DEV_AHB_SLV);
271 if (!dev)
272 return -1;
273
274 ambapp_ahb_dev_init (ioarea, mmaps, &ahb_buf, dev);
275
276 if (prev != parent)
277 prev->next = dev;
278 dev->prev = prev;
279 prev = dev;
280
281 /* Is it a AHB/AHB Bridge ? */
282 if ((dev->device == GAISLER_AHB2AHB)
283 && (dev->vendor == VENDOR_GAISLER))
284 {
285 /* AHB/AHB Bridge Found, recurse down the Bridge */
286 ahb_info = dev->devinfo;
287 if (ahb_info->ver)
288 {
289 bridge_address =
290 ambapp_addr_from (mmaps, ahb_info->custom[1]);
291
292 DPRINTF (("+(AHBAHB:0x%x)\n", bridge_address));
293
294 /* Makes sure bus only scanned once */
295 if (ambapp_has_been_scanned (internal, bridge_address) ==
296 NULL)
297 {
298 ambapp_add_scanned_bus (internal, bridge_address);
299 if (ambapp_scan
300 (bridge_address, dev, mmaps, memfunc,
301 &dev->children, internal))
302 return -1;
303 }
304 }
305 }
306 else if ((dev->device == GAISLER_APBMST)
307 && (dev->vendor == VENDOR_GAISLER))
308 {
309 /* AHB/APB Bridge Found, add the APB devices to this AHB Slave's children */
310 prevapb = dev;
311 ahb_info = dev->devinfo;
312 apbbase = ahb_info->start[0];
313 apb = (struct ambapp_pnp_apb *) (apbbase | AMBA_CONF_AREA);
314 for (j = 0; j < AMBA_APB_SLAVES; j++)
315 {
316 memfunc (&apb_buf, apb, sizeof (struct ambapp_pnp_apb));
317 if (apb_buf.id)
318 {
319 apbdev = ambapp_alloc_dev_struct (DEV_APB_SLV);
320 if (!dev)
321 return -1;
322
323 ambapp_apb_dev_init (apbbase, mmaps, &apb_buf, apbdev);
324
325 if (prevapb != dev)
326 prevapb->next = apbdev;
327 else
328 dev->children = apbdev;
329 apbdev->prev = prevapb;
330 prevapb = apbdev;
331 }
332 apb++;
333 }
334 }
335 }
336 ahb++;
337 }
338
339 if (parent == NULL)
340 {
341 free (internal);
342 }
343
344 return 0;
345 }
346
347 /* Match search options againt device */
348 int
ambapp_dev_match_options(struct ambapp_dev_hdr * dev,unsigned int options,int vendor,int device)349 ambapp_dev_match_options (struct ambapp_dev_hdr *dev, unsigned int options,
350 int vendor, int device)
351 {
352 if ((((options & (OPTIONS_ALL_DEVS)) == OPTIONS_ALL_DEVS) || /* Match TYPE */
353 ((options & OPTIONS_AHB_MSTS) && (dev->dev_type == DEV_AHB_MST)) || ((options & OPTIONS_AHB_SLVS) && (dev->dev_type == DEV_AHB_SLV)) || ((options & OPTIONS_APB_SLVS) && (dev->dev_type == DEV_APB_SLV))) && ((vendor == -1) || (vendor == dev->vendor)) && /* Match ID */
354 ((device == -1) || (device == dev->device)) && (((options & OPTIONS_ALL) == OPTIONS_ALL) || /* Match Allocated State */
355 ((options &
356 OPTIONS_FREE)
357 && DEV_IS_FREE (dev))
358 ||
359 ((options &
360 OPTIONS_ALLOCATED)
361 &&
362 DEV_IS_ALLOCATED
363 (dev))))
364 {
365 return 1;
366 }
367 return 0;
368 }
369
370 /* If device is an APB bridge all devices on the APB bridge is processed */
371 static int
ambapp_for_each_apb(struct ambapp_dev_hdr * dev,unsigned int options,int vendor,int device,int maxdepth,ambapp_func_t func,void * arg)372 ambapp_for_each_apb (struct ambapp_dev_hdr *dev,
373 unsigned int options,
374 int vendor,
375 int device, int maxdepth, ambapp_func_t func, void *arg)
376 {
377 int index;
378 struct ambapp_dev_hdr *apbslv;
379
380 if (maxdepth < 0)
381 return 0;
382
383 if (dev->children && (dev->children->dev_type == DEV_APB_SLV))
384 {
385 /* Found a APB Bridge */
386 index = 0;
387 apbslv = dev->children;
388 while (apbslv)
389 {
390 if (ambapp_dev_match_options (apbslv, options, vendor, device) == 1)
391 {
392 if (func (apbslv, index, maxdepth, arg) == 1)
393 return 1; /* Signalled stopped */
394 }
395 index++;
396 apbslv = apbslv->next;
397 }
398 }
399 return 0;
400 }
401
402 /* Traverse the prescanned device information */
403 int
ambapp_for_each(struct ambapp_dev_hdr * root,unsigned int options,int vendor,int device,int maxdepth,ambapp_func_t func,void * arg)404 ambapp_for_each (struct ambapp_dev_hdr *root,
405 unsigned int options,
406 int vendor,
407 int device, int maxdepth, ambapp_func_t func, void *arg)
408 {
409 struct ambapp_dev_hdr *dev;
410 int ahb_slave = 0;
411 int index;
412
413 if (maxdepth < 0)
414 return 0;
415
416 /* Start at device 'root' and process downwards.
417 *
418 * Breadth first search, search order
419 * 1. AHB MSTS
420 * 2. AHB SLVS
421 * 3. APB SLVS on primary bus
422 * 4. AHB/AHB secondary... -> step to 1.
423 */
424
425 /* AHB MST / AHB SLV */
426 if (options & (OPTIONS_AHB_MSTS | OPTIONS_AHB_SLVS | OPTIONS_DEPTH_FIRST))
427 {
428 index = 0;
429 dev = root;
430 while (dev)
431 {
432 if ((dev->dev_type == DEV_AHB_SLV) && !ahb_slave)
433 {
434 /* First AHB Slave */
435 ahb_slave = 1;
436 index = 0;
437 }
438
439 /* Conditions must be fullfilled for function to be called */
440 if (ambapp_dev_match_options (dev, options, vendor, device) == 1)
441 {
442 /* Correct device and vendor ID */
443 if (func (dev, index, maxdepth, arg) == 1)
444 return 1; /* Signalled stopped */
445 }
446
447 if ((options & OPTIONS_DEPTH_FIRST) && (options & OPTIONS_APB_SLVS))
448 {
449 /* Check is APB bridge, and process all APB Slaves in that case */
450 if (ambapp_for_each_apb
451 (dev, options, vendor, device, (maxdepth - 1), func,
452 arg) == 1)
453 return 1; /* Signalled stopped */
454 }
455
456 if (options & OPTIONS_DEPTH_FIRST)
457 {
458 if (dev->children && (dev->children->dev_type != DEV_APB_SLV))
459 {
460 /* Found AHB Bridge, recurse */
461 if (ambapp_for_each
462 (dev->children, options, vendor, device, (maxdepth - 1),
463 func, arg) == 1)
464 return 1;
465 }
466 }
467
468 index++;
469 dev = dev->next;
470 }
471 }
472
473 /* Find APB Bridges */
474 if ((options & OPTIONS_APB_SLVS) && !(options & OPTIONS_DEPTH_FIRST))
475 {
476 dev = root;
477 while (dev)
478 {
479 /* Check is APB bridge, and process all APB Slaves in that case */
480 if (ambapp_for_each_apb
481 (dev, options, vendor, device, (maxdepth - 1), func, arg) == 1)
482 return 1; /* Signalled stopped */
483 dev = dev->next;
484 }
485 }
486
487 /* Find AHB Bridges */
488 if (!(options & OPTIONS_DEPTH_FIRST))
489 {
490 dev = root;
491 while (dev)
492 {
493 if (dev->children && (dev->children->dev_type != DEV_APB_SLV))
494 {
495 /* Found AHB Bridge, recurse */
496 if (ambapp_for_each
497 (dev->children, options, vendor, device, (maxdepth - 1),
498 func, arg) == 1)
499 return 1;
500 }
501 dev = dev->next;
502 }
503 }
504
505 return 0;
506 }
507
508 int
ambapp_alloc_dev(struct ambapp_dev_hdr * dev,void * owner)509 ambapp_alloc_dev (struct ambapp_dev_hdr *dev, void *owner)
510 {
511 if (dev->owner)
512 return -1;
513 dev->owner = owner;
514 return 0;
515 }
516
517 void
ambapp_free_dev(struct ambapp_dev_hdr * dev)518 ambapp_free_dev (struct ambapp_dev_hdr *dev)
519 {
520 dev->owner = NULL;
521 }
522
523 struct ambapp_dev_find_match_arg
524 {
525 int index;
526 int count;
527 int type;
528 void *dev;
529 };
530
531 /* AMBA PP find routines */
532 int
ambapp_dev_find_match(struct ambapp_dev_hdr * dev,int index,int maxdepth,void * arg)533 ambapp_dev_find_match (struct ambapp_dev_hdr *dev, int index, int maxdepth,
534 void *arg)
535 {
536 struct ambapp_dev_find_match_arg *p = arg;
537
538 if (p->index == 0)
539 {
540 /* Found controller, stop */
541 if (p->type == DEV_APB_SLV)
542 {
543 *(struct ambapp_apb_info *) p->dev =
544 *(struct ambapp_apb_info *) dev->devinfo;
545 p->dev = ((struct ambapp_apb_info *) p->dev) + 1;
546 }
547 else
548 {
549 *(struct ambapp_ahb_info *) p->dev =
550 *(struct ambapp_ahb_info *) dev->devinfo;
551 p->dev = ((struct ambapp_ahb_info *) p->dev) + 1;
552 }
553 p->count--;
554 if (p->count < 1)
555 return 1;
556 }
557 else
558 {
559 p->index--;
560 }
561 return 0;
562 }
563
564 int
ambapp_find_apbslvs_next(struct ambapp_dev_hdr * root,int vendor,int device,struct ambapp_apb_info * dev,int index,int maxno)565 ambapp_find_apbslvs_next (struct ambapp_dev_hdr *root, int vendor, int device,
566 struct ambapp_apb_info *dev, int index, int maxno)
567 {
568 struct ambapp_dev_find_match_arg arg;
569
570 arg.index = index;
571 arg.count = maxno;
572 arg.type = DEV_APB_SLV; /* APB */
573 arg.dev = dev;
574
575 ambapp_for_each (root, (OPTIONS_ALL | OPTIONS_APB_SLVS), vendor, device, 10,
576 ambapp_dev_find_match, &arg);
577
578 return maxno - arg.count;
579 }
580
581 int
ambapp_find_apbslv(struct ambapp_dev_hdr * root,int vendor,int device,struct ambapp_apb_info * dev)582 ambapp_find_apbslv (struct ambapp_dev_hdr *root, int vendor, int device,
583 struct ambapp_apb_info *dev)
584 {
585 return ambapp_find_apbslvs_next (root, vendor, device, dev, 0, 1);
586 }
587
588 int
ambapp_find_apbslv_next(struct ambapp_dev_hdr * root,int vendor,int device,struct ambapp_apb_info * dev,int index)589 ambapp_find_apbslv_next (struct ambapp_dev_hdr *root, int vendor, int device,
590 struct ambapp_apb_info *dev, int index)
591 {
592 return ambapp_find_apbslvs_next (root, vendor, device, dev, index, 1);
593 }
594
595 int
ambapp_find_apbslvs(struct ambapp_dev_hdr * root,int vendor,int device,struct ambapp_apb_info * dev,int maxno)596 ambapp_find_apbslvs (struct ambapp_dev_hdr *root, int vendor, int device,
597 struct ambapp_apb_info *dev, int maxno)
598 {
599 return ambapp_find_apbslvs_next (root, vendor, device, dev, 0, maxno);
600 }
601
602 int
ambapp_find_ahbslvs_next(struct ambapp_dev_hdr * root,int vendor,int device,struct ambapp_ahb_info * dev,int index,int maxno)603 ambapp_find_ahbslvs_next (struct ambapp_dev_hdr *root, int vendor, int device,
604 struct ambapp_ahb_info *dev, int index, int maxno)
605 {
606 struct ambapp_dev_find_match_arg arg;
607
608 arg.index = index;
609 arg.count = maxno;
610 arg.type = DEV_AHB_SLV; /* AHB SLV */
611 arg.dev = dev;
612
613 ambapp_for_each (root, (OPTIONS_ALL | OPTIONS_AHB_SLVS), vendor, device, 10,
614 ambapp_dev_find_match, &arg);
615
616 return maxno - arg.count;
617 }
618
619 int
ambapp_find_ahbslv_next(struct ambapp_dev_hdr * root,int vendor,int device,struct ambapp_ahb_info * dev,int index)620 ambapp_find_ahbslv_next (struct ambapp_dev_hdr *root, int vendor, int device,
621 struct ambapp_ahb_info *dev, int index)
622 {
623 return ambapp_find_ahbslvs_next (root, vendor, device, dev, index, 1);
624 }
625
626 int
ambapp_find_ahbslv(struct ambapp_dev_hdr * root,int vendor,int device,struct ambapp_ahb_info * dev)627 ambapp_find_ahbslv (struct ambapp_dev_hdr *root, int vendor, int device,
628 struct ambapp_ahb_info *dev)
629 {
630 return ambapp_find_ahbslvs_next (root, vendor, device, dev, 0, 1);
631 }
632
633 int
ambapp_find_ahbslvs(struct ambapp_dev_hdr * root,int vendor,int device,struct ambapp_ahb_info * dev,int maxno)634 ambapp_find_ahbslvs (struct ambapp_dev_hdr *root, int vendor, int device,
635 struct ambapp_ahb_info *dev, int maxno)
636 {
637 return ambapp_find_ahbslvs_next (root, vendor, device, dev, 0, maxno);
638 }
639
640 struct ambapp_dev_hdr *
ambapp_find_parent(struct ambapp_dev_hdr * dev)641 ambapp_find_parent (struct ambapp_dev_hdr *dev)
642 {
643 while (dev->prev)
644 {
645 if (dev == dev->prev->children)
646 {
647 return dev->prev;
648 }
649 dev = dev->prev;
650 }
651 return NULL;
652 }
653
654
655 struct ambapp_dev_hdr *ambapp_root = NULL;
656 extern unsigned int console;
657 extern unsigned int rtc;
658
659 void
pnpinit(void)660 pnpinit (void)
661 {
662 struct ambapp_apb_info dev;
663 int n;
664 ambapp_scan (LEON3_IO_AREA, NULL, NULL, NULL, &ambapp_root, NULL);
665 if ((n =
666 ambapp_find_apbslv (ambapp_root, VENDOR_GAISLER, GAISLER_APBUART,
667 &dev)) == 1)
668 {
669 console = dev.start;
670 DPRINTF (("Found abuart at 0x%x\n", console));
671 }
672 if ((n =
673 ambapp_find_apbslv (ambapp_root, VENDOR_GAISLER, GAISLER_GPTIMER,
674 &dev)) == 1)
675 {
676 rtc = dev.start + 0x10;
677 DPRINTF (("Found rtc at 0x%x\n", rtc));
678 }
679 }
680