1 /*-
2 * Copyright (c) 2011 Semihalf.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include <sys/param.h>
28 #include <sys/systm.h>
29 #include <sys/kernel.h>
30 #include <sys/malloc.h>
31 #include <sys/bus.h>
32 #include <sys/interrupt.h>
33 #include <sys/lock.h>
34 #include <sys/mutex.h>
35 #include <sys/proc.h>
36 #include <sys/queue.h>
37 #include <sys/rman.h>
38 #include <sys/sched.h>
39 #include <sys/smp.h>
40
41 #include <vm/vm.h>
42 #include <vm/vm_param.h>
43 #include <vm/vm_page.h>
44
45 #include <machine/cpufunc.h>
46 #include <machine/intr_machdep.h>
47 #include <machine/pmap.h>
48 #include <machine/stdarg.h>
49
50 #include <dev/dpaa/bman.h>
51 #include <dev/dpaa/qman.h>
52 #include <dev/dpaa/portals.h>
53
54 #include <powerpc/mpc85xx/mpc85xx.h>
55 #include "error_ext.h"
56 #include "std_ext.h"
57 #include "list_ext.h"
58 #include "mm_ext.h"
59
60 /* Configuration */
61
62 /* Define the number of dTSEC ports active in system */
63 #define MALLOCSMART_DTSEC_IN_USE 4
64
65 /*
66 * Calculate malloc's pool size for dTSEC's buffers.
67 * We reserve 1MB pool for each dTSEC port.
68 */
69 #define MALLOCSMART_POOL_SIZE \
70 (MALLOCSMART_DTSEC_IN_USE * 1024 * 1024)
71
72 #define MALLOCSMART_SLICE_SIZE (PAGE_SIZE / 2) /* 2kB */
73
74 /* Defines */
75 #define MALLOCSMART_SIZE_TO_SLICE(x) \
76 (((x) + MALLOCSMART_SLICE_SIZE - 1) / MALLOCSMART_SLICE_SIZE)
77 #define MALLOCSMART_SLICES \
78 MALLOCSMART_SIZE_TO_SLICE(MALLOCSMART_POOL_SIZE)
79
80 /* Malloc Pool for NetCommSW */
81 MALLOC_DEFINE(M_NETCOMMSW, "NetCommSW", "NetCommSW software stack");
82 MALLOC_DEFINE(M_NETCOMMSW_MT, "NetCommSWTrack",
83 "NetCommSW software allocation tracker");
84
85 /* MallocSmart data structures */
86 static void *XX_MallocSmartPool;
87 static int XX_MallocSmartMap[MALLOCSMART_SLICES];
88
89 static struct mtx XX_MallocSmartLock;
90 static struct mtx XX_MallocTrackLock;
91 MTX_SYSINIT(XX_MallocSmartLockInit, &XX_MallocSmartLock,
92 "NetCommSW MallocSmart Lock", MTX_DEF);
93 MTX_SYSINIT(XX_MallocTrackLockInit, &XX_MallocTrackLock,
94 "NetCommSW MallocTrack Lock", MTX_DEF);
95
96 /* Interrupt info */
97 #define XX_INTR_FLAG_PREALLOCATED (1 << 0)
98
99 struct XX_IntrInfo {
100 driver_intr_t *handler;
101 void *arg;
102 int cpu;
103 int flags;
104 void *cookie;
105 };
106
107 static struct XX_IntrInfo XX_IntrInfo[INTR_VECTORS];
108 /* Portal type identifiers */
109 enum XX_PortalIdent{
110 BM_PORTAL = 0,
111 QM_PORTAL,
112 };
113 /* Structure to store portals' properties */
114 struct XX_PortalInfo {
115 vm_paddr_t portal_ce_pa[2][MAXCPU];
116 vm_paddr_t portal_ci_pa[2][MAXCPU];
117 uint32_t portal_ce_size[2][MAXCPU];
118 uint32_t portal_ci_size[2][MAXCPU];
119 vm_offset_t portal_ce_va[2];
120 vm_offset_t portal_ci_va[2];
121 uintptr_t portal_intr[2][MAXCPU];
122 };
123
124 static struct XX_PortalInfo XX_PInfo;
125
126 void
XX_Exit(int status)127 XX_Exit(int status)
128 {
129
130 panic("NetCommSW: Exit called with status %i", status);
131 }
132
133 void
XX_Print(char * str,...)134 XX_Print(char *str, ...)
135 {
136 va_list ap;
137
138 va_start(ap, str);
139 vprintf(str, ap);
140 va_end(ap);
141 }
142
143 void *
XX_Malloc(uint32_t size)144 XX_Malloc(uint32_t size)
145 {
146 void *p = (malloc(size, M_NETCOMMSW, M_NOWAIT));
147
148 return (p);
149 }
150
151 static int
XX_MallocSmartMapCheck(unsigned int start,unsigned int slices)152 XX_MallocSmartMapCheck(unsigned int start, unsigned int slices)
153 {
154 unsigned int i;
155
156 mtx_assert(&XX_MallocSmartLock, MA_OWNED);
157 for (i = start; i < start + slices; i++)
158 if (XX_MallocSmartMap[i])
159 return (FALSE);
160 return (TRUE);
161 }
162
163 static void
XX_MallocSmartMapSet(unsigned int start,unsigned int slices)164 XX_MallocSmartMapSet(unsigned int start, unsigned int slices)
165 {
166 unsigned int i;
167
168 mtx_assert(&XX_MallocSmartLock, MA_OWNED);
169
170 for (i = start; i < start + slices; i++)
171 XX_MallocSmartMap[i] = ((i == start) ? slices : -1);
172 }
173
174 static void
XX_MallocSmartMapClear(unsigned int start,unsigned int slices)175 XX_MallocSmartMapClear(unsigned int start, unsigned int slices)
176 {
177 unsigned int i;
178
179 mtx_assert(&XX_MallocSmartLock, MA_OWNED);
180
181 for (i = start; i < start + slices; i++)
182 XX_MallocSmartMap[i] = 0;
183 }
184
185 int
XX_MallocSmartInit(void)186 XX_MallocSmartInit(void)
187 {
188 int error;
189
190 error = E_OK;
191 mtx_lock(&XX_MallocSmartLock);
192
193 if (XX_MallocSmartPool)
194 goto out;
195
196 /* Allocate MallocSmart pool */
197 XX_MallocSmartPool = contigmalloc(MALLOCSMART_POOL_SIZE, M_NETCOMMSW,
198 M_NOWAIT, 0, 0xFFFFFFFFFull, MALLOCSMART_POOL_SIZE, 0);
199 if (!XX_MallocSmartPool) {
200 error = E_NO_MEMORY;
201 goto out;
202 }
203
204 out:
205 mtx_unlock(&XX_MallocSmartLock);
206 return (error);
207 }
208
209 void *
XX_MallocSmart(uint32_t size,int memPartitionId,uint32_t alignment)210 XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
211 {
212 unsigned int i;
213 vm_offset_t addr;
214
215 addr = 0;
216
217 /* Convert alignment and size to number of slices */
218 alignment = MALLOCSMART_SIZE_TO_SLICE(alignment);
219 size = MALLOCSMART_SIZE_TO_SLICE(size);
220
221 /* Lock resources */
222 mtx_lock(&XX_MallocSmartLock);
223
224 /* Allocate region */
225 for (i = 0; i + size <= MALLOCSMART_SLICES; i += alignment) {
226 if (XX_MallocSmartMapCheck(i, size)) {
227 XX_MallocSmartMapSet(i, size);
228 addr = (vm_offset_t)XX_MallocSmartPool +
229 (i * MALLOCSMART_SLICE_SIZE);
230 break;
231 }
232 }
233
234 /* Unlock resources */
235 mtx_unlock(&XX_MallocSmartLock);
236
237 return ((void *)addr);
238 }
239
240 void
XX_FreeSmart(void * p)241 XX_FreeSmart(void *p)
242 {
243 unsigned int start, slices;
244
245 /* Calculate first slice of region */
246 start = MALLOCSMART_SIZE_TO_SLICE((vm_offset_t)(p) -
247 (vm_offset_t)XX_MallocSmartPool);
248
249 /* Lock resources */
250 mtx_lock(&XX_MallocSmartLock);
251
252 KASSERT(XX_MallocSmartMap[start] > 0,
253 ("XX_FreeSmart: Double or mid-block free!\n"));
254
255 /* Free region */
256 slices = XX_MallocSmartMap[start];
257 XX_MallocSmartMapClear(start, slices);
258
259 /* Unlock resources */
260 mtx_unlock(&XX_MallocSmartLock);
261 }
262
263 void
XX_Free(void * p)264 XX_Free(void *p)
265 {
266
267 free(p, M_NETCOMMSW);
268 }
269
270 uint32_t
XX_DisableAllIntr(void)271 XX_DisableAllIntr(void)
272 {
273
274 return (intr_disable());
275 }
276
277 void
XX_RestoreAllIntr(uint32_t flags)278 XX_RestoreAllIntr(uint32_t flags)
279 {
280
281 intr_restore(flags);
282 }
283
284 static bool
XX_IsPortalIntr(uintptr_t irq)285 XX_IsPortalIntr(uintptr_t irq)
286 {
287 int cpu, type;
288 /* Check interrupt numbers of all available portals */
289 for (type = 0; type < 2; type++)
290 for (cpu = 0; cpu < MAXCPU; cpu++)
291 if (irq == XX_PInfo.portal_intr[type][cpu])
292 return (1);
293
294 return (0);
295 }
296
297 static void
XX_Dispatch(void * arg)298 XX_Dispatch(void *arg)
299 {
300 struct XX_IntrInfo *info;
301
302 info = arg;
303
304 if (info->handler == NULL) {
305 printf("%s(): IRQ handler is NULL!\n", __func__);
306 return;
307 }
308
309 info->handler(info->arg);
310 }
311
312 t_Error
XX_PreallocAndBindIntr(device_t dev,uintptr_t irq,unsigned int cpu)313 XX_PreallocAndBindIntr(device_t dev, uintptr_t irq, unsigned int cpu)
314 {
315 struct resource *r;
316 unsigned int inum;
317 t_Error error;
318
319 r = (struct resource *)irq;
320 inum = rman_get_start(r);
321
322 error = XX_SetIntr(irq, XX_Dispatch, &XX_IntrInfo[inum]);
323 if (error != 0)
324 return (error);
325
326 error = bus_bind_intr(dev, r, cpu);
327 if (error != 0)
328 return (error);
329
330 XX_IntrInfo[inum].flags = XX_INTR_FLAG_PREALLOCATED;
331 XX_IntrInfo[inum].cpu = cpu;
332
333 return (E_OK);
334 }
335
336 t_Error
XX_DeallocIntr(uintptr_t irq)337 XX_DeallocIntr(uintptr_t irq)
338 {
339 struct resource *r;
340 unsigned int inum;
341
342 r = (struct resource *)irq;
343 inum = rman_get_start(r);
344
345 if ((XX_IntrInfo[inum].flags & XX_INTR_FLAG_PREALLOCATED) == 0)
346 return (E_INVALID_STATE);
347
348 XX_IntrInfo[inum].flags = 0;
349 return (XX_FreeIntr(irq));
350 }
351
352 t_Error
XX_SetIntr(uintptr_t irq,t_Isr * f_Isr,t_Handle handle)353 XX_SetIntr(uintptr_t irq, t_Isr *f_Isr, t_Handle handle)
354 {
355 device_t dev;
356 struct resource *r;
357 unsigned int flags;
358 int err;
359
360 r = (struct resource *)irq;
361 dev = rman_get_device(r);
362 irq = rman_get_start(r);
363
364 /* Handle preallocated interrupts */
365 if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) {
366 if (XX_IntrInfo[irq].handler != NULL)
367 return (E_BUSY);
368
369 XX_IntrInfo[irq].handler = f_Isr;
370 XX_IntrInfo[irq].arg = handle;
371
372 return (E_OK);
373 }
374
375 flags = INTR_TYPE_NET | INTR_MPSAFE;
376
377 /* BMAN/QMAN Portal interrupts must be exlusive */
378 if (XX_IsPortalIntr(irq))
379 flags |= INTR_EXCL;
380
381 err = bus_setup_intr(dev, r, flags, NULL, f_Isr, handle,
382 &XX_IntrInfo[irq].cookie);
383
384 return (err);
385 }
386
387 t_Error
XX_FreeIntr(uintptr_t irq)388 XX_FreeIntr(uintptr_t irq)
389 {
390 device_t dev;
391 struct resource *r;
392
393 r = (struct resource *)irq;
394 dev = rman_get_device(r);
395 irq = rman_get_start(r);
396
397 /* Handle preallocated interrupts */
398 if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) {
399 if (XX_IntrInfo[irq].handler == NULL)
400 return (E_INVALID_STATE);
401
402 XX_IntrInfo[irq].handler = NULL;
403 XX_IntrInfo[irq].arg = NULL;
404
405 return (E_OK);
406 }
407
408 return (bus_teardown_intr(dev, r, XX_IntrInfo[irq].cookie));
409 }
410
411 t_Error
XX_EnableIntr(uintptr_t irq)412 XX_EnableIntr(uintptr_t irq)
413 {
414 struct resource *r;
415
416 r = (struct resource *)irq;
417 irq = rman_get_start(r);
418
419 powerpc_intr_unmask(irq);
420
421 return (E_OK);
422 }
423
424 t_Error
XX_DisableIntr(uintptr_t irq)425 XX_DisableIntr(uintptr_t irq)
426 {
427 struct resource *r;
428
429 r = (struct resource *)irq;
430 irq = rman_get_start(r);
431
432 powerpc_intr_mask(irq);
433
434 return (E_OK);
435 }
436
437 t_TaskletHandle
XX_InitTasklet(void (* routine)(void *),void * data)438 XX_InitTasklet (void (*routine)(void *), void *data)
439 {
440 /* Not referenced */
441 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
442 return (NULL);
443 }
444
445
446 void
XX_FreeTasklet(t_TaskletHandle h_Tasklet)447 XX_FreeTasklet (t_TaskletHandle h_Tasklet)
448 {
449 /* Not referenced */
450 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
451 }
452
453 int
XX_ScheduleTask(t_TaskletHandle h_Tasklet,int immediate)454 XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
455 {
456 /* Not referenced */
457 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
458 return (0);
459 }
460
461 void
XX_FlushScheduledTasks(void)462 XX_FlushScheduledTasks(void)
463 {
464 /* Not referenced */
465 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
466 }
467
468 int
XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)469 XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
470 {
471 /* Not referenced */
472 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
473 return (0);
474 }
475
476 void
XX_SetTaskletData(t_TaskletHandle h_Tasklet,t_Handle data)477 XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
478 {
479 /* Not referenced */
480 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
481 }
482
483 t_Handle
XX_GetTaskletData(t_TaskletHandle h_Tasklet)484 XX_GetTaskletData(t_TaskletHandle h_Tasklet)
485 {
486 /* Not referenced */
487 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
488 return (NULL);
489 }
490
491 t_Handle
XX_InitSpinlock(void)492 XX_InitSpinlock(void)
493 {
494 struct mtx *m;
495
496 m = malloc(sizeof(*m), M_NETCOMMSW, M_NOWAIT | M_ZERO);
497 if (!m)
498 return (0);
499
500 mtx_init(m, "NetCommSW Lock", NULL, MTX_DEF | MTX_DUPOK);
501
502 return (m);
503 }
504
505 void
XX_FreeSpinlock(t_Handle h_Spinlock)506 XX_FreeSpinlock(t_Handle h_Spinlock)
507 {
508 struct mtx *m;
509
510 m = h_Spinlock;
511
512 mtx_destroy(m);
513 free(m, M_NETCOMMSW);
514 }
515
516 void
XX_LockSpinlock(t_Handle h_Spinlock)517 XX_LockSpinlock(t_Handle h_Spinlock)
518 {
519 struct mtx *m;
520
521 m = h_Spinlock;
522 mtx_lock(m);
523 }
524
525 void
XX_UnlockSpinlock(t_Handle h_Spinlock)526 XX_UnlockSpinlock(t_Handle h_Spinlock)
527 {
528 struct mtx *m;
529
530 m = h_Spinlock;
531 mtx_unlock(m);
532 }
533
534 uint32_t
XX_LockIntrSpinlock(t_Handle h_Spinlock)535 XX_LockIntrSpinlock(t_Handle h_Spinlock)
536 {
537
538 XX_LockSpinlock(h_Spinlock);
539 return (0);
540 }
541
542 void
XX_UnlockIntrSpinlock(t_Handle h_Spinlock,uint32_t intrFlags)543 XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
544 {
545
546 XX_UnlockSpinlock(h_Spinlock);
547 }
548
549 uint32_t
XX_Sleep(uint32_t msecs)550 XX_Sleep(uint32_t msecs)
551 {
552
553 XX_UDelay(1000 * msecs);
554 return (0);
555 }
556
557 void
XX_UDelay(uint32_t usecs)558 XX_UDelay(uint32_t usecs)
559 {
560 DELAY(usecs);
561 }
562
563 t_Error
XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],t_IpcMsgHandler * f_MsgHandler,t_Handle h_Module,uint32_t replyLength)564 XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
565 t_IpcMsgHandler *f_MsgHandler, t_Handle h_Module, uint32_t replyLength)
566 {
567
568 /*
569 * This function returns fake E_OK status and does nothing
570 * as NetCommSW IPC is not used by FreeBSD drivers.
571 */
572 return (E_OK);
573 }
574
575 t_Error
XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])576 XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
577 {
578 /*
579 * This function returns fake E_OK status and does nothing
580 * as NetCommSW IPC is not used by FreeBSD drivers.
581 */
582 return (E_OK);
583 }
584
585
586 t_Error
XX_IpcSendMessage(t_Handle h_Session,uint8_t * p_Msg,uint32_t msgLength,uint8_t * p_Reply,uint32_t * p_ReplyLength,t_IpcMsgCompletion * f_Completion,t_Handle h_Arg)587 XX_IpcSendMessage(t_Handle h_Session,
588 uint8_t *p_Msg, uint32_t msgLength, uint8_t *p_Reply,
589 uint32_t *p_ReplyLength, t_IpcMsgCompletion *f_Completion, t_Handle h_Arg)
590 {
591
592 /* Should not be called */
593 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
594 return (E_OK);
595 }
596
597 t_Handle
XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])598 XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
599 char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
600 {
601
602 /* Should not be called */
603 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
604 return (NULL);
605 }
606
607 t_Error
XX_IpcFreeSession(t_Handle h_Session)608 XX_IpcFreeSession(t_Handle h_Session)
609 {
610
611 /* Should not be called */
612 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
613 return (E_OK);
614 }
615
616 physAddress_t
XX_VirtToPhys(void * addr)617 XX_VirtToPhys(void *addr)
618 {
619 vm_paddr_t paddr;
620 int cpu;
621
622 cpu = PCPU_GET(cpuid);
623
624 /* Handle NULL address */
625 if (addr == NULL)
626 return (-1);
627
628 /* Check CCSR */
629 if ((vm_offset_t)addr >= ccsrbar_va &&
630 (vm_offset_t)addr < ccsrbar_va + ccsrbar_size)
631 return (((vm_offset_t)addr - ccsrbar_va) + ccsrbar_pa);
632
633 /* Handle BMAN mappings */
634 if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[BM_PORTAL]) &&
635 ((vm_offset_t)addr < XX_PInfo.portal_ce_va[BM_PORTAL] +
636 XX_PInfo.portal_ce_size[BM_PORTAL][cpu]))
637 return (XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] +
638 (vm_offset_t)addr - XX_PInfo.portal_ce_va[BM_PORTAL]);
639
640 if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[BM_PORTAL]) &&
641 ((vm_offset_t)addr < XX_PInfo.portal_ci_va[BM_PORTAL] +
642 XX_PInfo.portal_ci_size[BM_PORTAL][cpu]))
643 return (XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] +
644 (vm_offset_t)addr - XX_PInfo.portal_ci_va[BM_PORTAL]);
645
646 /* Handle QMAN mappings */
647 if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[QM_PORTAL]) &&
648 ((vm_offset_t)addr < XX_PInfo.portal_ce_va[QM_PORTAL] +
649 XX_PInfo.portal_ce_size[QM_PORTAL][cpu]))
650 return (XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] +
651 (vm_offset_t)addr - XX_PInfo.portal_ce_va[QM_PORTAL]);
652
653 if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[QM_PORTAL]) &&
654 ((vm_offset_t)addr < XX_PInfo.portal_ci_va[QM_PORTAL] +
655 XX_PInfo.portal_ci_size[QM_PORTAL][cpu]))
656 return (XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] +
657 (vm_offset_t)addr - XX_PInfo.portal_ci_va[QM_PORTAL]);
658
659 if (PMAP_HAS_DMAP && (vm_offset_t)addr >= DMAP_BASE_ADDRESS &&
660 (vm_offset_t)addr <= DMAP_MAX_ADDRESS)
661 return (DMAP_TO_PHYS((vm_offset_t)addr));
662 else
663 paddr = pmap_kextract((vm_offset_t)addr);
664
665 if (paddr == 0)
666 printf("NetCommSW: "
667 "Unable to translate virtual address %p!\n", addr);
668 else
669 pmap_track_page(kernel_pmap, (vm_offset_t)addr);
670
671 return (paddr);
672 }
673
674 void *
XX_PhysToVirt(physAddress_t addr)675 XX_PhysToVirt(physAddress_t addr)
676 {
677 struct pv_entry *pv;
678 vm_page_t page;
679 int cpu;
680
681 /* Check CCSR */
682 if (addr >= ccsrbar_pa && addr < ccsrbar_pa + ccsrbar_size)
683 return ((void *)((vm_offset_t)(addr - ccsrbar_pa) +
684 ccsrbar_va));
685
686 cpu = PCPU_GET(cpuid);
687
688 /* Handle BMAN mappings */
689 if ((addr >= XX_PInfo.portal_ce_pa[BM_PORTAL][cpu]) &&
690 (addr < XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] +
691 XX_PInfo.portal_ce_size[BM_PORTAL][cpu]))
692 return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] +
693 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu])));
694
695 if ((addr >= XX_PInfo.portal_ci_pa[BM_PORTAL][cpu]) &&
696 (addr < XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] +
697 XX_PInfo.portal_ci_size[BM_PORTAL][cpu]))
698 return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] +
699 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu])));
700
701 /* Handle QMAN mappings */
702 if ((addr >= XX_PInfo.portal_ce_pa[QM_PORTAL][cpu]) &&
703 (addr < XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] +
704 XX_PInfo.portal_ce_size[QM_PORTAL][cpu]))
705 return ((void *)(XX_PInfo.portal_ce_va[QM_PORTAL] +
706 (vm_offset_t)(addr - XX_PInfo.portal_ce_pa[QM_PORTAL][cpu])));
707
708 if ((addr >= XX_PInfo.portal_ci_pa[QM_PORTAL][cpu]) &&
709 (addr < XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] +
710 XX_PInfo.portal_ci_size[QM_PORTAL][cpu]))
711 return ((void *)(XX_PInfo.portal_ci_va[QM_PORTAL] +
712 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[QM_PORTAL][cpu])));
713
714 page = PHYS_TO_VM_PAGE(addr);
715 pv = TAILQ_FIRST(&page->md.pv_list);
716
717 if (pv != NULL)
718 return ((void *)(pv->pv_va + ((vm_offset_t)addr & PAGE_MASK)));
719
720 if (PMAP_HAS_DMAP)
721 return ((void *)(uintptr_t)PHYS_TO_DMAP(addr));
722
723 printf("NetCommSW: "
724 "Unable to translate physical address 0x%09jx!\n", (uintmax_t)addr);
725
726 return (NULL);
727 }
728
729 void
XX_PortalSetInfo(device_t dev)730 XX_PortalSetInfo(device_t dev)
731 {
732 char *dev_name;
733 struct dpaa_portals_softc *sc;
734 int i, type, len;
735
736 dev_name = malloc(sizeof(*dev_name), M_TEMP, M_WAITOK |
737 M_ZERO);
738
739 len = strlen("bman-portals");
740
741 strncpy(dev_name, device_get_name(dev), len);
742
743 if (strncmp(dev_name, "bman-portals", len) && strncmp(dev_name,
744 "qman-portals", len))
745 goto end;
746
747 if (strncmp(dev_name, "bman-portals", len) == 0)
748 type = BM_PORTAL;
749 else
750 type = QM_PORTAL;
751
752 sc = device_get_softc(dev);
753
754 for (i = 0; sc->sc_dp[i].dp_ce_pa != 0; i++) {
755 XX_PInfo.portal_ce_pa[type][i] = sc->sc_dp[i].dp_ce_pa;
756 XX_PInfo.portal_ci_pa[type][i] = sc->sc_dp[i].dp_ci_pa;
757 XX_PInfo.portal_ce_size[type][i] = sc->sc_dp[i].dp_ce_size;
758 XX_PInfo.portal_ci_size[type][i] = sc->sc_dp[i].dp_ci_size;
759 XX_PInfo.portal_intr[type][i] = sc->sc_dp[i].dp_intr_num;
760 }
761
762 XX_PInfo.portal_ce_va[type] = rman_get_bushandle(sc->sc_rres[0]);
763 XX_PInfo.portal_ci_va[type] = rman_get_bushandle(sc->sc_rres[1]);
764 end:
765 free(dev_name, M_TEMP);
766 }
767