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 #define XX_INTR_FLAG_BOUND (1 << 1)
99 #define XX_INTR_FLAG_FMAN_FIX (1 << 2)
100
101 struct XX_IntrInfo {
102 driver_intr_t *handler;
103 void *arg;
104 int cpu;
105 int flags;
106 void *cookie;
107 };
108
109 static struct XX_IntrInfo XX_IntrInfo[INTR_VECTORS];
110 /* Portal type identifiers */
111 enum XX_PortalIdent{
112 BM_PORTAL = 0,
113 QM_PORTAL,
114 };
115 /* Structure to store portals' properties */
116 struct XX_PortalInfo {
117 vm_paddr_t portal_ce_pa[2][MAXCPU];
118 vm_paddr_t portal_ci_pa[2][MAXCPU];
119 uint32_t portal_ce_size[2][MAXCPU];
120 uint32_t portal_ci_size[2][MAXCPU];
121 vm_offset_t portal_ce_va[2];
122 vm_offset_t portal_ci_va[2];
123 uintptr_t portal_intr[2][MAXCPU];
124 };
125
126 static struct XX_PortalInfo XX_PInfo;
127
128 void
XX_Exit(int status)129 XX_Exit(int status)
130 {
131
132 panic("NetCommSW: Exit called with status %i", status);
133 }
134
135 void
XX_Print(char * str,...)136 XX_Print(char *str, ...)
137 {
138 va_list ap;
139
140 va_start(ap, str);
141 vprintf(str, ap);
142 va_end(ap);
143 }
144
145 void *
XX_Malloc(uint32_t size)146 XX_Malloc(uint32_t size)
147 {
148 void *p = (malloc(size, M_NETCOMMSW, M_NOWAIT));
149
150 return (p);
151 }
152
153 static int
XX_MallocSmartMapCheck(unsigned int start,unsigned int slices)154 XX_MallocSmartMapCheck(unsigned int start, unsigned int slices)
155 {
156 unsigned int i;
157
158 mtx_assert(&XX_MallocSmartLock, MA_OWNED);
159 for (i = start; i < start + slices; i++)
160 if (XX_MallocSmartMap[i])
161 return (FALSE);
162 return (TRUE);
163 }
164
165 static void
XX_MallocSmartMapSet(unsigned int start,unsigned int slices)166 XX_MallocSmartMapSet(unsigned int start, unsigned int slices)
167 {
168 unsigned int i;
169
170 mtx_assert(&XX_MallocSmartLock, MA_OWNED);
171
172 for (i = start; i < start + slices; i++)
173 XX_MallocSmartMap[i] = ((i == start) ? slices : -1);
174 }
175
176 static void
XX_MallocSmartMapClear(unsigned int start,unsigned int slices)177 XX_MallocSmartMapClear(unsigned int start, unsigned int slices)
178 {
179 unsigned int i;
180
181 mtx_assert(&XX_MallocSmartLock, MA_OWNED);
182
183 for (i = start; i < start + slices; i++)
184 XX_MallocSmartMap[i] = 0;
185 }
186
187 int
XX_MallocSmartInit(void)188 XX_MallocSmartInit(void)
189 {
190 int error;
191
192 error = E_OK;
193 mtx_lock(&XX_MallocSmartLock);
194
195 if (XX_MallocSmartPool)
196 goto out;
197
198 /* Allocate MallocSmart pool */
199 XX_MallocSmartPool = contigmalloc(MALLOCSMART_POOL_SIZE, M_NETCOMMSW,
200 M_NOWAIT, 0, 0xFFFFFFFFFull, MALLOCSMART_POOL_SIZE, 0);
201 if (!XX_MallocSmartPool) {
202 error = E_NO_MEMORY;
203 goto out;
204 }
205
206 out:
207 mtx_unlock(&XX_MallocSmartLock);
208 return (error);
209 }
210
211 void *
XX_MallocSmart(uint32_t size,int memPartitionId,uint32_t alignment)212 XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
213 {
214 unsigned int i;
215 vm_offset_t addr;
216
217 addr = 0;
218
219 /* Convert alignment and size to number of slices */
220 alignment = MALLOCSMART_SIZE_TO_SLICE(alignment);
221 size = MALLOCSMART_SIZE_TO_SLICE(size);
222
223 /* Lock resources */
224 mtx_lock(&XX_MallocSmartLock);
225
226 /* Allocate region */
227 for (i = 0; i + size <= MALLOCSMART_SLICES; i += alignment) {
228 if (XX_MallocSmartMapCheck(i, size)) {
229 XX_MallocSmartMapSet(i, size);
230 addr = (vm_offset_t)XX_MallocSmartPool +
231 (i * MALLOCSMART_SLICE_SIZE);
232 break;
233 }
234 }
235
236 /* Unlock resources */
237 mtx_unlock(&XX_MallocSmartLock);
238
239 return ((void *)addr);
240 }
241
242 void
XX_FreeSmart(void * p)243 XX_FreeSmart(void *p)
244 {
245 unsigned int start, slices;
246
247 /* Calculate first slice of region */
248 start = MALLOCSMART_SIZE_TO_SLICE((vm_offset_t)(p) -
249 (vm_offset_t)XX_MallocSmartPool);
250
251 /* Lock resources */
252 mtx_lock(&XX_MallocSmartLock);
253
254 KASSERT(XX_MallocSmartMap[start] > 0,
255 ("XX_FreeSmart: Double or mid-block free!\n"));
256
257 /* Free region */
258 slices = XX_MallocSmartMap[start];
259 XX_MallocSmartMapClear(start, slices);
260
261 /* Unlock resources */
262 mtx_unlock(&XX_MallocSmartLock);
263 }
264
265 void
XX_Free(void * p)266 XX_Free(void *p)
267 {
268
269 free(p, M_NETCOMMSW);
270 }
271
272 uint32_t
XX_DisableAllIntr(void)273 XX_DisableAllIntr(void)
274 {
275
276 return (intr_disable());
277 }
278
279 void
XX_RestoreAllIntr(uint32_t flags)280 XX_RestoreAllIntr(uint32_t flags)
281 {
282
283 intr_restore(flags);
284 }
285
286 static bool
XX_IsPortalIntr(uintptr_t irq)287 XX_IsPortalIntr(uintptr_t irq)
288 {
289 int cpu, type;
290 /* Check interrupt numbers of all available portals */
291 for (cpu = 0, type = 0; XX_PInfo.portal_intr[type][cpu] != 0; cpu++) {
292 if (irq == XX_PInfo.portal_intr[type][cpu]) {
293 /* Found it! */
294 return (1);
295 }
296 if (XX_PInfo.portal_intr[type][cpu + 1] == 0) {
297 type++;
298 cpu = 0;
299 }
300 }
301
302 return (0);
303 }
304
305 void
XX_FmanFixIntr(int irq)306 XX_FmanFixIntr(int irq)
307 {
308
309 XX_IntrInfo[irq].flags |= XX_INTR_FLAG_FMAN_FIX;
310 }
311
312 static bool
XX_FmanNeedsIntrFix(int irq)313 XX_FmanNeedsIntrFix(int irq)
314 {
315
316 if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_FMAN_FIX)
317 return (1);
318
319 return (0);
320 }
321
322 static void
XX_Dispatch(void * arg)323 XX_Dispatch(void *arg)
324 {
325 struct XX_IntrInfo *info;
326
327 info = arg;
328
329 /* Bind this thread to proper CPU when SMP has been already started. */
330 if ((info->flags & XX_INTR_FLAG_BOUND) == 0 && smp_started &&
331 info->cpu >= 0) {
332 thread_lock(curthread);
333 sched_bind(curthread, info->cpu);
334 thread_unlock(curthread);
335
336 info->flags |= XX_INTR_FLAG_BOUND;
337 }
338
339 if (info->handler == NULL) {
340 printf("%s(): IRQ handler is NULL!\n", __func__);
341 return;
342 }
343
344 info->handler(info->arg);
345 }
346
347 t_Error
XX_PreallocAndBindIntr(uintptr_t irq,unsigned int cpu)348 XX_PreallocAndBindIntr(uintptr_t irq, unsigned int cpu)
349 {
350 struct resource *r;
351 unsigned int inum;
352 t_Error error;
353
354 r = (struct resource *)irq;
355 inum = rman_get_start(r);
356
357 error = XX_SetIntr(irq, XX_Dispatch, &XX_IntrInfo[inum]);
358 if (error != 0)
359 return (error);
360
361 XX_IntrInfo[inum].flags = XX_INTR_FLAG_PREALLOCATED;
362 XX_IntrInfo[inum].cpu = cpu;
363
364 return (E_OK);
365 }
366
367 t_Error
XX_DeallocIntr(uintptr_t irq)368 XX_DeallocIntr(uintptr_t irq)
369 {
370 struct resource *r;
371 unsigned int inum;
372
373 r = (struct resource *)irq;
374 inum = rman_get_start(r);
375
376 if ((XX_IntrInfo[inum].flags & XX_INTR_FLAG_PREALLOCATED) == 0)
377 return (E_INVALID_STATE);
378
379 XX_IntrInfo[inum].flags = 0;
380 return (XX_FreeIntr(irq));
381 }
382
383 t_Error
XX_SetIntr(uintptr_t irq,t_Isr * f_Isr,t_Handle handle)384 XX_SetIntr(uintptr_t irq, t_Isr *f_Isr, t_Handle handle)
385 {
386 device_t dev;
387 struct resource *r;
388 unsigned int flags;
389 int err;
390
391 r = (struct resource *)irq;
392 dev = rman_get_device(r);
393 irq = rman_get_start(r);
394
395 /* Handle preallocated interrupts */
396 if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) {
397 if (XX_IntrInfo[irq].handler != NULL)
398 return (E_BUSY);
399
400 XX_IntrInfo[irq].handler = f_Isr;
401 XX_IntrInfo[irq].arg = handle;
402
403 return (E_OK);
404 }
405
406 flags = INTR_TYPE_NET | INTR_MPSAFE;
407
408 /* BMAN/QMAN Portal interrupts must be exlusive */
409 if (XX_IsPortalIntr(irq))
410 flags |= INTR_EXCL;
411
412 err = bus_setup_intr(dev, r, flags, NULL, f_Isr, handle,
413 &XX_IntrInfo[irq].cookie);
414 if (err)
415 goto finish;
416
417 /*
418 * XXX: Bind FMan IRQ to CPU0. Current interrupt subsystem directs each
419 * interrupt to all CPUs. Race between an interrupt assertion and
420 * masking may occur and interrupt handler may be called multiple times
421 * per one interrupt. FMan doesn't support such a situation. Workaround
422 * is to bind FMan interrupt to one CPU0 only.
423 */
424 #ifdef SMP
425 if (XX_FmanNeedsIntrFix(irq))
426 err = powerpc_bind_intr(irq, 0);
427 #endif
428 finish:
429 return (err);
430 }
431
432 t_Error
XX_FreeIntr(uintptr_t irq)433 XX_FreeIntr(uintptr_t irq)
434 {
435 device_t dev;
436 struct resource *r;
437
438 r = (struct resource *)irq;
439 dev = rman_get_device(r);
440 irq = rman_get_start(r);
441
442 /* Handle preallocated interrupts */
443 if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) {
444 if (XX_IntrInfo[irq].handler == NULL)
445 return (E_INVALID_STATE);
446
447 XX_IntrInfo[irq].handler = NULL;
448 XX_IntrInfo[irq].arg = NULL;
449
450 return (E_OK);
451 }
452
453 return (bus_teardown_intr(dev, r, XX_IntrInfo[irq].cookie));
454 }
455
456 t_Error
XX_EnableIntr(uintptr_t irq)457 XX_EnableIntr(uintptr_t irq)
458 {
459 struct resource *r;
460
461 r = (struct resource *)irq;
462 irq = rman_get_start(r);
463
464 powerpc_intr_unmask(irq);
465
466 return (E_OK);
467 }
468
469 t_Error
XX_DisableIntr(uintptr_t irq)470 XX_DisableIntr(uintptr_t irq)
471 {
472 struct resource *r;
473
474 r = (struct resource *)irq;
475 irq = rman_get_start(r);
476
477 powerpc_intr_mask(irq);
478
479 return (E_OK);
480 }
481
482 t_TaskletHandle
XX_InitTasklet(void (* routine)(void *),void * data)483 XX_InitTasklet (void (*routine)(void *), void *data)
484 {
485 /* Not referenced */
486 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
487 return (NULL);
488 }
489
490
491 void
XX_FreeTasklet(t_TaskletHandle h_Tasklet)492 XX_FreeTasklet (t_TaskletHandle h_Tasklet)
493 {
494 /* Not referenced */
495 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
496 }
497
498 int
XX_ScheduleTask(t_TaskletHandle h_Tasklet,int immediate)499 XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
500 {
501 /* Not referenced */
502 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
503 return (0);
504 }
505
506 void
XX_FlushScheduledTasks(void)507 XX_FlushScheduledTasks(void)
508 {
509 /* Not referenced */
510 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
511 }
512
513 int
XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)514 XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
515 {
516 /* Not referenced */
517 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
518 return (0);
519 }
520
521 void
XX_SetTaskletData(t_TaskletHandle h_Tasklet,t_Handle data)522 XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
523 {
524 /* Not referenced */
525 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
526 }
527
528 t_Handle
XX_GetTaskletData(t_TaskletHandle h_Tasklet)529 XX_GetTaskletData(t_TaskletHandle h_Tasklet)
530 {
531 /* Not referenced */
532 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
533 return (NULL);
534 }
535
536 t_Handle
XX_InitSpinlock(void)537 XX_InitSpinlock(void)
538 {
539 struct mtx *m;
540
541 m = malloc(sizeof(*m), M_NETCOMMSW, M_NOWAIT | M_ZERO);
542 if (!m)
543 return (0);
544
545 mtx_init(m, "NetCommSW Lock", NULL, MTX_DEF | MTX_DUPOK);
546
547 return (m);
548 }
549
550 void
XX_FreeSpinlock(t_Handle h_Spinlock)551 XX_FreeSpinlock(t_Handle h_Spinlock)
552 {
553 struct mtx *m;
554
555 m = h_Spinlock;
556
557 mtx_destroy(m);
558 free(m, M_NETCOMMSW);
559 }
560
561 void
XX_LockSpinlock(t_Handle h_Spinlock)562 XX_LockSpinlock(t_Handle h_Spinlock)
563 {
564 struct mtx *m;
565
566 m = h_Spinlock;
567 mtx_lock(m);
568 }
569
570 void
XX_UnlockSpinlock(t_Handle h_Spinlock)571 XX_UnlockSpinlock(t_Handle h_Spinlock)
572 {
573 struct mtx *m;
574
575 m = h_Spinlock;
576 mtx_unlock(m);
577 }
578
579 uint32_t
XX_LockIntrSpinlock(t_Handle h_Spinlock)580 XX_LockIntrSpinlock(t_Handle h_Spinlock)
581 {
582
583 XX_LockSpinlock(h_Spinlock);
584 return (0);
585 }
586
587 void
XX_UnlockIntrSpinlock(t_Handle h_Spinlock,uint32_t intrFlags)588 XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
589 {
590
591 XX_UnlockSpinlock(h_Spinlock);
592 }
593
594 uint32_t
XX_Sleep(uint32_t msecs)595 XX_Sleep(uint32_t msecs)
596 {
597
598 XX_UDelay(1000 * msecs);
599 return (0);
600 }
601
602 void
XX_UDelay(uint32_t usecs)603 XX_UDelay(uint32_t usecs)
604 {
605 DELAY(usecs);
606 }
607
608 t_Error
XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],t_IpcMsgHandler * f_MsgHandler,t_Handle h_Module,uint32_t replyLength)609 XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
610 t_IpcMsgHandler *f_MsgHandler, t_Handle h_Module, uint32_t replyLength)
611 {
612
613 /*
614 * This function returns fake E_OK status and does nothing
615 * as NetCommSW IPC is not used by FreeBSD drivers.
616 */
617 return (E_OK);
618 }
619
620 t_Error
XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])621 XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
622 {
623 /*
624 * This function returns fake E_OK status and does nothing
625 * as NetCommSW IPC is not used by FreeBSD drivers.
626 */
627 return (E_OK);
628 }
629
630
631 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)632 XX_IpcSendMessage(t_Handle h_Session,
633 uint8_t *p_Msg, uint32_t msgLength, uint8_t *p_Reply,
634 uint32_t *p_ReplyLength, t_IpcMsgCompletion *f_Completion, t_Handle h_Arg)
635 {
636
637 /* Should not be called */
638 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
639 return (E_OK);
640 }
641
642 t_Handle
XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])643 XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
644 char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
645 {
646
647 /* Should not be called */
648 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
649 return (E_OK);
650 }
651
652 t_Error
XX_IpcFreeSession(t_Handle h_Session)653 XX_IpcFreeSession(t_Handle h_Session)
654 {
655
656 /* Should not be called */
657 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
658 return (E_OK);
659 }
660
661 physAddress_t
XX_VirtToPhys(void * addr)662 XX_VirtToPhys(void *addr)
663 {
664 vm_paddr_t paddr;
665 int cpu;
666
667 cpu = PCPU_GET(cpuid);
668
669 /* Handle NULL address */
670 if (addr == NULL)
671 return (-1);
672
673 /* Check CCSR */
674 if ((vm_offset_t)addr >= ccsrbar_va &&
675 (vm_offset_t)addr < ccsrbar_va + ccsrbar_size)
676 return (((vm_offset_t)addr - ccsrbar_va) + ccsrbar_pa);
677
678 /* Handle BMAN mappings */
679 if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[BM_PORTAL]) &&
680 ((vm_offset_t)addr < XX_PInfo.portal_ce_va[BM_PORTAL] +
681 XX_PInfo.portal_ce_size[BM_PORTAL][cpu]))
682 return (XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] +
683 (vm_offset_t)addr - XX_PInfo.portal_ce_va[BM_PORTAL]);
684
685 if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[BM_PORTAL]) &&
686 ((vm_offset_t)addr < XX_PInfo.portal_ci_va[BM_PORTAL] +
687 XX_PInfo.portal_ci_size[BM_PORTAL][cpu]))
688 return (XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] +
689 (vm_offset_t)addr - XX_PInfo.portal_ci_va[BM_PORTAL]);
690
691 /* Handle QMAN mappings */
692 if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[QM_PORTAL]) &&
693 ((vm_offset_t)addr < XX_PInfo.portal_ce_va[QM_PORTAL] +
694 XX_PInfo.portal_ce_size[QM_PORTAL][cpu]))
695 return (XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] +
696 (vm_offset_t)addr - XX_PInfo.portal_ce_va[QM_PORTAL]);
697
698 if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[QM_PORTAL]) &&
699 ((vm_offset_t)addr < XX_PInfo.portal_ci_va[QM_PORTAL] +
700 XX_PInfo.portal_ci_size[QM_PORTAL][cpu]))
701 return (XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] +
702 (vm_offset_t)addr - XX_PInfo.portal_ci_va[QM_PORTAL]);
703
704 if (PMAP_HAS_DMAP && (vm_offset_t)addr >= DMAP_BASE_ADDRESS &&
705 (vm_offset_t)addr <= DMAP_MAX_ADDRESS)
706 return (DMAP_TO_PHYS((vm_offset_t)addr));
707 else
708 paddr = pmap_kextract((vm_offset_t)addr);
709
710 if (paddr == 0)
711 printf("NetCommSW: "
712 "Unable to translate virtual address %p!\n", addr);
713 else
714 pmap_track_page(kernel_pmap, (vm_offset_t)addr);
715
716 return (paddr);
717 }
718
719 void *
XX_PhysToVirt(physAddress_t addr)720 XX_PhysToVirt(physAddress_t addr)
721 {
722 struct pv_entry *pv;
723 vm_page_t page;
724 int cpu;
725
726 /* Check CCSR */
727 if (addr >= ccsrbar_pa && addr < ccsrbar_pa + ccsrbar_size)
728 return ((void *)((vm_offset_t)(addr - ccsrbar_pa) +
729 ccsrbar_va));
730
731 cpu = PCPU_GET(cpuid);
732
733 /* Handle BMAN mappings */
734 if ((addr >= XX_PInfo.portal_ce_pa[BM_PORTAL][cpu]) &&
735 (addr < XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] +
736 XX_PInfo.portal_ce_size[BM_PORTAL][cpu]))
737 return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] +
738 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu])));
739
740 if ((addr >= XX_PInfo.portal_ci_pa[BM_PORTAL][cpu]) &&
741 (addr < XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] +
742 XX_PInfo.portal_ci_size[BM_PORTAL][cpu]))
743 return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] +
744 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu])));
745
746 /* Handle QMAN mappings */
747 if ((addr >= XX_PInfo.portal_ce_pa[QM_PORTAL][cpu]) &&
748 (addr < XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] +
749 XX_PInfo.portal_ce_size[QM_PORTAL][cpu]))
750 return ((void *)(XX_PInfo.portal_ce_va[QM_PORTAL] +
751 (vm_offset_t)(addr - XX_PInfo.portal_ce_pa[QM_PORTAL][cpu])));
752
753 if ((addr >= XX_PInfo.portal_ci_pa[QM_PORTAL][cpu]) &&
754 (addr < XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] +
755 XX_PInfo.portal_ci_size[QM_PORTAL][cpu]))
756 return ((void *)(XX_PInfo.portal_ci_va[QM_PORTAL] +
757 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[QM_PORTAL][cpu])));
758
759 page = PHYS_TO_VM_PAGE(addr);
760 pv = TAILQ_FIRST(&page->md.pv_list);
761
762 if (pv != NULL)
763 return ((void *)(pv->pv_va + ((vm_offset_t)addr & PAGE_MASK)));
764
765 if (PMAP_HAS_DMAP)
766 return ((void *)(uintptr_t)PHYS_TO_DMAP(addr));
767
768 printf("NetCommSW: "
769 "Unable to translate physical address 0x%09jx!\n", (uintmax_t)addr);
770
771 return (NULL);
772 }
773
774 void
XX_PortalSetInfo(device_t dev)775 XX_PortalSetInfo(device_t dev)
776 {
777 char *dev_name;
778 struct dpaa_portals_softc *sc;
779 int i, type, len;
780
781 dev_name = malloc(sizeof(*dev_name), M_TEMP, M_WAITOK |
782 M_ZERO);
783
784 len = strlen("bman-portals");
785
786 strncpy(dev_name, device_get_name(dev), len);
787
788 if (strncmp(dev_name, "bman-portals", len) && strncmp(dev_name,
789 "qman-portals", len))
790 goto end;
791
792 if (strncmp(dev_name, "bman-portals", len) == 0)
793 type = BM_PORTAL;
794 else
795 type = QM_PORTAL;
796
797 sc = device_get_softc(dev);
798
799 for (i = 0; sc->sc_dp[i].dp_ce_pa != 0; i++) {
800 XX_PInfo.portal_ce_pa[type][i] = sc->sc_dp[i].dp_ce_pa;
801 XX_PInfo.portal_ci_pa[type][i] = sc->sc_dp[i].dp_ci_pa;
802 XX_PInfo.portal_ce_size[type][i] = sc->sc_dp[i].dp_ce_size;
803 XX_PInfo.portal_ci_size[type][i] = sc->sc_dp[i].dp_ci_size;
804 XX_PInfo.portal_intr[type][i] = sc->sc_dp[i].dp_intr_num;
805 }
806
807 XX_PInfo.portal_ce_va[type] = rman_get_bushandle(sc->sc_rres[0]);
808 XX_PInfo.portal_ci_va[type] = rman_get_bushandle(sc->sc_rres[1]);
809 end:
810 free(dev_name, M_TEMP);
811 }
812