xref: /freebsd/sys/contrib/ncsw/user/env/xx.c (revision d9f0ce31900a48d1a2bfc1c8c86f79d1e831451a)
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 "error_ext.h"
55 #include "std_ext.h"
56 #include "list_ext.h"
57 #include "mm_ext.h"
58 
59 /* Configuration */
60 
61 /* Define the number of dTSEC ports active in system */
62 #define MALLOCSMART_DTSEC_IN_USE	4
63 
64 /*
65  * Calculate malloc's pool size for dTSEC's buffers.
66  * We reserve 1MB pool for each dTSEC port.
67  */
68 #define	MALLOCSMART_POOL_SIZE		\
69     (MALLOCSMART_DTSEC_IN_USE * 1024 * 1024)
70 
71 #define MALLOCSMART_SLICE_SIZE		(PAGE_SIZE / 2)		/* 2kB */
72 
73 /* Defines */
74 #define MALLOCSMART_SIZE_TO_SLICE(x)	\
75     (((x) + MALLOCSMART_SLICE_SIZE - 1) / MALLOCSMART_SLICE_SIZE)
76 #define MALLOCSMART_SLICES		\
77     MALLOCSMART_SIZE_TO_SLICE(MALLOCSMART_POOL_SIZE)
78 
79 /* Malloc Pool for NetCommSW */
80 MALLOC_DEFINE(M_NETCOMMSW, "NetCommSW", "NetCommSW software stack");
81 MALLOC_DEFINE(M_NETCOMMSW_MT, "NetCommSWTrack",
82     "NetCommSW software allocation tracker");
83 
84 /* MallocSmart data structures */
85 static void *XX_MallocSmartPool;
86 static int XX_MallocSmartMap[MALLOCSMART_SLICES];
87 
88 static struct mtx XX_MallocSmartLock;
89 static struct mtx XX_MallocTrackLock;
90 MTX_SYSINIT(XX_MallocSmartLockInit, &XX_MallocSmartLock,
91     "NetCommSW MallocSmart Lock", MTX_DEF);
92 MTX_SYSINIT(XX_MallocTrackLockInit, &XX_MallocTrackLock,
93     "NetCommSW MallocTrack Lock", MTX_DEF);
94 
95 /* Interrupt info */
96 #define XX_INTR_FLAG_PREALLOCATED	(1 << 0)
97 #define XX_INTR_FLAG_BOUND		(1 << 1)
98 #define XX_INTR_FLAG_FMAN_FIX		(1 << 2)
99 
100 struct XX_IntrInfo {
101 	driver_intr_t	*handler;
102 	void		*arg;
103 	int		cpu;
104 	int		flags;
105 	void		*cookie;
106 };
107 
108 static struct XX_IntrInfo XX_IntrInfo[INTR_VECTORS];
109 /* Portal type identifiers */
110 enum XX_PortalIdent{
111 	BM_PORTAL = 0,
112 	QM_PORTAL,
113 };
114 /* Structure to store portals' properties */
115 struct XX_PortalInfo {
116 	vm_paddr_t	portal_ce_pa[2][MAXCPU];
117 	vm_paddr_t	portal_ci_pa[2][MAXCPU];
118 	uint32_t	portal_ce_size[2][MAXCPU];
119 	uint32_t	portal_ci_size[2][MAXCPU];
120 	vm_offset_t	portal_ce_va[2];
121 	vm_offset_t	portal_ci_va[2];
122 	uint32_t	portal_intr[2][MAXCPU];
123 };
124 
125 static struct XX_PortalInfo XX_PInfo;
126 
127 /* The lower 9 bits, through emprical testing, tend to be 0. */
128 #define	XX_MALLOC_TRACK_SHIFT	9
129 
130 typedef struct XX_MallocTrackStruct {
131 	LIST_ENTRY(XX_MallocTrackStruct) entries;
132 	physAddress_t pa;
133 	void *va;
134 } XX_MallocTrackStruct;
135 
136 LIST_HEAD(XX_MallocTrackerList, XX_MallocTrackStruct) *XX_MallocTracker;
137 u_long XX_MallocHashMask;
138 static XX_MallocTrackStruct * XX_FindTracker(physAddress_t pa);
139 
140 void
141 XX_Exit(int status)
142 {
143 
144 	panic("NetCommSW: Exit called with status %i", status);
145 }
146 
147 void
148 XX_Print(char *str, ...)
149 {
150 	va_list ap;
151 
152 	va_start(ap, str);
153 	vprintf(str, ap);
154 	va_end(ap);
155 }
156 
157 void *
158 XX_Malloc(uint32_t size)
159 {
160 	void *p = (malloc(size, M_NETCOMMSW, M_NOWAIT));
161 
162 	return (p);
163 }
164 
165 static int
166 XX_MallocSmartMapCheck(unsigned int start, unsigned int slices)
167 {
168 	unsigned int i;
169 
170 	mtx_assert(&XX_MallocSmartLock, MA_OWNED);
171 	for (i = start; i < start + slices; i++)
172 		if (XX_MallocSmartMap[i])
173 			return (FALSE);
174 	return (TRUE);
175 }
176 
177 static void
178 XX_MallocSmartMapSet(unsigned int start, unsigned int slices)
179 {
180 	unsigned int i;
181 
182 	mtx_assert(&XX_MallocSmartLock, MA_OWNED);
183 
184 	for (i = start; i < start + slices; i++)
185 		XX_MallocSmartMap[i] = ((i == start) ? slices : -1);
186 }
187 
188 static void
189 XX_MallocSmartMapClear(unsigned int start, unsigned int slices)
190 {
191 	unsigned int i;
192 
193 	mtx_assert(&XX_MallocSmartLock, MA_OWNED);
194 
195 	for (i = start; i < start + slices; i++)
196 		XX_MallocSmartMap[i] = 0;
197 }
198 
199 int
200 XX_MallocSmartInit(void)
201 {
202 	int error;
203 
204 	error = E_OK;
205 	mtx_lock(&XX_MallocSmartLock);
206 
207 	if (XX_MallocSmartPool)
208 		goto out;
209 
210 	/* Allocate MallocSmart pool */
211 	XX_MallocSmartPool = contigmalloc(MALLOCSMART_POOL_SIZE, M_NETCOMMSW,
212 	    M_NOWAIT, 0, 0xFFFFFFFFFull, MALLOCSMART_POOL_SIZE, 0);
213 	if (!XX_MallocSmartPool) {
214 		error = E_NO_MEMORY;
215 		goto out;
216 	}
217 
218 out:
219 	mtx_unlock(&XX_MallocSmartLock);
220 	return (error);
221 }
222 
223 void *
224 XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
225 {
226 	unsigned int i;
227 	vm_offset_t addr;
228 
229 	addr = 0;
230 
231 	/* Convert alignment and size to number of slices */
232 	alignment = MALLOCSMART_SIZE_TO_SLICE(alignment);
233 	size = MALLOCSMART_SIZE_TO_SLICE(size);
234 
235 	/* Lock resources */
236 	mtx_lock(&XX_MallocSmartLock);
237 
238 	/* Allocate region */
239 	for (i = 0; i + size <= MALLOCSMART_SLICES; i += alignment) {
240 		if (XX_MallocSmartMapCheck(i, size)) {
241 			XX_MallocSmartMapSet(i, size);
242 			addr = (vm_offset_t)XX_MallocSmartPool +
243 			    (i * MALLOCSMART_SLICE_SIZE);
244 			break;
245 		}
246 	}
247 
248 	/* Unlock resources */
249 	mtx_unlock(&XX_MallocSmartLock);
250 
251 	return ((void *)addr);
252 }
253 
254 void
255 XX_FreeSmart(void *p)
256 {
257 	unsigned int start, slices;
258 
259 	/* Calculate first slice of region */
260 	start = MALLOCSMART_SIZE_TO_SLICE((vm_offset_t)(p) -
261 	    (vm_offset_t)XX_MallocSmartPool);
262 
263 	/* Lock resources */
264 	mtx_lock(&XX_MallocSmartLock);
265 
266 	KASSERT(XX_MallocSmartMap[start] > 0,
267 	    ("XX_FreeSmart: Double or mid-block free!\n"));
268 
269 	XX_UntrackAddress(p);
270 	/* Free region */
271 	slices = XX_MallocSmartMap[start];
272 	XX_MallocSmartMapClear(start, slices);
273 
274 	/* Unlock resources */
275 	mtx_unlock(&XX_MallocSmartLock);
276 }
277 
278 void
279 XX_Free(void *p)
280 {
281 
282 	if (p != NULL)
283 		XX_UntrackAddress(p);
284 	free(p, M_NETCOMMSW);
285 }
286 
287 uint32_t
288 XX_DisableAllIntr(void)
289 {
290 
291 	return (intr_disable());
292 }
293 
294 void
295 XX_RestoreAllIntr(uint32_t flags)
296 {
297 
298 	intr_restore(flags);
299 }
300 
301 t_Error
302 XX_Call(uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
303 {
304 	/* Not referenced */
305 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
306 	return (E_OK);
307 }
308 
309 static bool
310 XX_IsPortalIntr(int irq)
311 {
312 	int cpu, type;
313 	/* Check interrupt numbers of all available portals */
314 	for (cpu = 0, type = 0; XX_PInfo.portal_intr[type][cpu] != 0; cpu++) {
315 		if (irq == XX_PInfo.portal_intr[type][cpu]) {
316 			/* Found it! */
317 			return (1);
318 		}
319 		if (XX_PInfo.portal_intr[type][cpu + 1] == 0) {
320 			type++;
321 			cpu = 0;
322 		}
323 	}
324 
325 	return (0);
326 }
327 
328 void
329 XX_FmanFixIntr(int irq)
330 {
331 
332 	XX_IntrInfo[irq].flags |= XX_INTR_FLAG_FMAN_FIX;
333 }
334 
335 static bool
336 XX_FmanNeedsIntrFix(int irq)
337 {
338 
339 	if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_FMAN_FIX)
340 		return (1);
341 
342 	return (0);
343 }
344 
345 static void
346 XX_Dispatch(void *arg)
347 {
348 	struct XX_IntrInfo *info;
349 
350 	info = arg;
351 
352 	/* Bind this thread to proper CPU when SMP has been already started. */
353 	if ((info->flags & XX_INTR_FLAG_BOUND) == 0 && smp_started &&
354 	    info->cpu >= 0) {
355 		thread_lock(curthread);
356 		sched_bind(curthread, info->cpu);
357 		thread_unlock(curthread);
358 
359 		info->flags |= XX_INTR_FLAG_BOUND;
360 	}
361 
362 	if (info->handler == NULL) {
363 		printf("%s(): IRQ handler is NULL!\n", __func__);
364 		return;
365 	}
366 
367 	info->handler(info->arg);
368 }
369 
370 t_Error
371 XX_PreallocAndBindIntr(int irq, unsigned int cpu)
372 {
373 	struct resource *r;
374 	unsigned int inum;
375 	t_Error error;
376 
377 	r = (struct resource *)irq;
378 	inum = rman_get_start(r);
379 
380 	error = XX_SetIntr(irq, XX_Dispatch, &XX_IntrInfo[inum]);
381 	if (error != 0)
382 		return (error);
383 
384 	XX_IntrInfo[inum].flags = XX_INTR_FLAG_PREALLOCATED;
385 	XX_IntrInfo[inum].cpu = cpu;
386 
387 	return (E_OK);
388 }
389 
390 t_Error
391 XX_DeallocIntr(int irq)
392 {
393 	struct resource *r;
394 	unsigned int inum;
395 
396 	r = (struct resource *)irq;
397 	inum = rman_get_start(r);
398 
399 	if ((XX_IntrInfo[inum].flags & XX_INTR_FLAG_PREALLOCATED) == 0)
400 		return (E_INVALID_STATE);
401 
402 	XX_IntrInfo[inum].flags = 0;
403 	return (XX_FreeIntr(irq));
404 }
405 
406 t_Error
407 XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
408 {
409 	struct device *dev;
410 	struct resource *r;
411 	unsigned int flags;
412 	int err;
413 
414 	r = (struct resource *)irq;
415 	dev = rman_get_device(r);
416 	irq = rman_get_start(r);
417 
418 	/* Handle preallocated interrupts */
419 	if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) {
420 		if (XX_IntrInfo[irq].handler != NULL)
421 			return (E_BUSY);
422 
423 		XX_IntrInfo[irq].handler = f_Isr;
424 		XX_IntrInfo[irq].arg = handle;
425 
426 		return (E_OK);
427 	}
428 
429 	flags = INTR_TYPE_NET | INTR_MPSAFE;
430 
431 	/* BMAN/QMAN Portal interrupts must be exlusive */
432 	if (XX_IsPortalIntr(irq))
433 		flags |= INTR_EXCL;
434 
435 	err = bus_setup_intr(dev, r, flags, NULL, f_Isr, handle,
436 		    &XX_IntrInfo[irq].cookie);
437 	if (err)
438 		goto finish;
439 
440 	/*
441 	 * XXX: Bind FMan IRQ to CPU0. Current interrupt subsystem directs each
442 	 * interrupt to all CPUs. Race between an interrupt assertion and
443 	 * masking may occur and interrupt handler may be called multiple times
444 	 * per one interrupt. FMan doesn't support such a situation. Workaround
445 	 * is to bind FMan interrupt to one CPU0 only.
446 	 */
447 #ifdef SMP
448 	if (XX_FmanNeedsIntrFix(irq))
449 		err = powerpc_bind_intr(irq, 0);
450 #endif
451 finish:
452 	return (err);
453 }
454 
455 t_Error
456 XX_FreeIntr(int irq)
457 {
458 	struct device *dev;
459 	struct resource *r;
460 
461 	r = (struct resource *)irq;
462 	dev = rman_get_device(r);
463 	irq = rman_get_start(r);
464 
465 	/* Handle preallocated interrupts */
466 	if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) {
467 		if (XX_IntrInfo[irq].handler == NULL)
468 			return (E_INVALID_STATE);
469 
470 		XX_IntrInfo[irq].handler = NULL;
471 		XX_IntrInfo[irq].arg = NULL;
472 
473 		return (E_OK);
474 	}
475 
476 	return (bus_teardown_intr(dev, r, XX_IntrInfo[irq].cookie));
477 }
478 
479 t_Error
480 XX_EnableIntr(int irq)
481 {
482 	struct resource *r;
483 
484 	r = (struct resource *)irq;
485 	irq = rman_get_start(r);
486 
487 	powerpc_intr_unmask(irq);
488 
489 	return (E_OK);
490 }
491 
492 t_Error
493 XX_DisableIntr(int irq)
494 {
495 	struct resource *r;
496 
497 	r = (struct resource *)irq;
498 	irq = rman_get_start(r);
499 
500 	powerpc_intr_mask(irq);
501 
502 	return (E_OK);
503 }
504 
505 t_TaskletHandle
506 XX_InitTasklet (void (*routine)(void *), void *data)
507 {
508 	/* Not referenced */
509 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
510 	return (NULL);
511 }
512 
513 
514 void
515 XX_FreeTasklet (t_TaskletHandle h_Tasklet)
516 {
517 	/* Not referenced */
518 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
519 }
520 
521 int
522 XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
523 {
524 	/* Not referenced */
525 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
526 	return (0);
527 }
528 
529 void
530 XX_FlushScheduledTasks(void)
531 {
532 	/* Not referenced */
533 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
534 }
535 
536 int
537 XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
538 {
539 	/* Not referenced */
540 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
541 	return (0);
542 }
543 
544 void
545 XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
546 {
547 	/* Not referenced */
548 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
549 }
550 
551 t_Handle
552 XX_GetTaskletData(t_TaskletHandle h_Tasklet)
553 {
554 	/* Not referenced */
555 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
556 	return (NULL);
557 }
558 
559 t_Handle
560 XX_InitSpinlock(void)
561 {
562 	struct mtx *m;
563 
564 	m = malloc(sizeof(*m), M_NETCOMMSW, M_NOWAIT);
565 	if (!m)
566 		return (0);
567 
568 	mtx_init(m, "NetCommSW Lock", NULL, MTX_DEF | MTX_DUPOK);
569 
570 	return (m);
571 }
572 
573 void
574 XX_FreeSpinlock(t_Handle h_Spinlock)
575 {
576 	struct mtx *m;
577 
578 	m = h_Spinlock;
579 
580 	mtx_destroy(m);
581 	free(m, M_NETCOMMSW);
582 }
583 
584 void
585 XX_LockSpinlock(t_Handle h_Spinlock)
586 {
587 	struct mtx *m;
588 
589 	m = h_Spinlock;
590 	mtx_lock(m);
591 }
592 
593 void
594 XX_UnlockSpinlock(t_Handle h_Spinlock)
595 {
596 	struct mtx *m;
597 
598 	m = h_Spinlock;
599 	mtx_unlock(m);
600 }
601 
602 uint32_t
603 XX_LockIntrSpinlock(t_Handle h_Spinlock)
604 {
605 
606 	XX_LockSpinlock(h_Spinlock);
607 	return (0);
608 }
609 
610 void
611 XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
612 {
613 
614 	XX_UnlockSpinlock(h_Spinlock);
615 }
616 
617 uint32_t
618 XX_CurrentTime(void)
619 {
620 	/* Not referenced */
621 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
622 	return (0);
623 }
624 
625 
626 t_Handle
627 XX_CreateTimer(void)
628 {
629 	/* Not referenced */
630 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
631 	return (NULL);
632 }
633 
634 void
635 XX_FreeTimer(t_Handle h_Timer)
636 {
637 	/* Not referenced */
638 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
639 }
640 
641 void
642 XX_StartTimer(t_Handle h_Timer,
643                    uint32_t msecs,
644                    bool     periodic,
645                    void     (*f_TimerExpired)(t_Handle),
646                    t_Handle h_Arg)
647 {
648 	/* Not referenced */
649 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
650 }
651 
652 uint32_t
653 XX_GetExpirationTime(t_Handle h_Timer)
654 {
655 	/* Not referenced */
656 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
657 	return (0);
658 }
659 
660 void
661 XX_StopTimer(t_Handle h_Timer)
662 {
663 	/* Not referenced */
664 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
665 }
666 
667 void
668 XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
669 {
670 	/* Not referenced */
671 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
672 }
673 
674 int
675 XX_TimerIsActive(t_Handle h_Timer)
676 {
677 	/* Not referenced */
678 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
679 	return (0);
680 }
681 
682 uint32_t
683 XX_Sleep(uint32_t msecs)
684 {
685 
686 	XX_UDelay(1000 * msecs);
687 	return (0);
688 }
689 
690 void
691 XX_UDelay(uint32_t usecs)
692 {
693 	DELAY(usecs);
694 }
695 
696 t_Error
697 XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
698     t_IpcMsgHandler *f_MsgHandler, t_Handle  h_Module, uint32_t replyLength)
699 {
700 
701 	/*
702 	 * This function returns fake E_OK status and does nothing
703 	 * as NetCommSW IPC is not used by FreeBSD drivers.
704 	 */
705 	return (E_OK);
706 }
707 
708 t_Error
709 XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
710 {
711 	/*
712 	 * This function returns fake E_OK status and does nothing
713 	 * as NetCommSW IPC is not used by FreeBSD drivers.
714 	 */
715 	return (E_OK);
716 }
717 
718 
719 t_Error
720 XX_IpcSendMessage(t_Handle h_Session,
721     uint8_t *p_Msg, uint32_t msgLength, uint8_t *p_Reply,
722     uint32_t *p_ReplyLength, t_IpcMsgCompletion *f_Completion, t_Handle h_Arg)
723 {
724 
725 	/* Should not be called */
726 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
727 	return (E_OK);
728 }
729 
730 t_Handle
731 XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
732     char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
733 {
734 
735 	/* Should not be called */
736 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
737 	return (E_OK);
738 }
739 
740 t_Error
741 XX_IpcFreeSession(t_Handle h_Session)
742 {
743 
744 	/* Should not be called */
745 	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
746 	return (E_OK);
747 }
748 
749 extern void db_trace_self(void);
750 physAddress_t
751 XX_VirtToPhys(void *addr)
752 {
753 	vm_paddr_t paddr;
754 	int cpu;
755 
756 	cpu = PCPU_GET(cpuid);
757 
758 	/* Handle NULL address */
759 	if (addr == NULL)
760 		return (-1);
761 
762 	/* Handle BMAN mappings */
763 	if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[BM_PORTAL]) &&
764 	    ((vm_offset_t)addr < XX_PInfo.portal_ce_va[BM_PORTAL] +
765 	    XX_PInfo.portal_ce_size[BM_PORTAL][cpu]))
766 		return (XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] +
767 		    (vm_offset_t)addr - XX_PInfo.portal_ce_va[BM_PORTAL]);
768 
769 	if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[BM_PORTAL]) &&
770 	    ((vm_offset_t)addr < XX_PInfo.portal_ci_va[BM_PORTAL] +
771 	    XX_PInfo.portal_ci_size[BM_PORTAL][cpu]))
772 		return (XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] +
773 		    (vm_offset_t)addr - XX_PInfo.portal_ci_va[BM_PORTAL]);
774 
775 	/* Handle QMAN mappings */
776 	if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[QM_PORTAL]) &&
777 	    ((vm_offset_t)addr < XX_PInfo.portal_ce_va[QM_PORTAL] +
778 	    XX_PInfo.portal_ce_size[QM_PORTAL][cpu]))
779 		return (XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] +
780 		    (vm_offset_t)addr - XX_PInfo.portal_ce_va[QM_PORTAL]);
781 
782 	if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[QM_PORTAL]) &&
783 	    ((vm_offset_t)addr < XX_PInfo.portal_ci_va[QM_PORTAL] +
784 	    XX_PInfo.portal_ci_size[QM_PORTAL][cpu]))
785 		return (XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] +
786 		    (vm_offset_t)addr - XX_PInfo.portal_ci_va[QM_PORTAL]);
787 
788 	paddr = pmap_kextract((vm_offset_t)addr);
789 	if (!paddr)
790 		printf("NetCommSW: "
791 		    "Unable to translate virtual address 0x%08X!\n", addr);
792 	else
793 	    XX_TrackAddress(addr);
794 
795 	return (paddr);
796 }
797 
798 void *
799 XX_PhysToVirt(physAddress_t addr)
800 {
801 	XX_MallocTrackStruct *ts;
802 	int cpu;
803 
804 	cpu = PCPU_GET(cpuid);
805 
806 	/* Handle BMAN mappings */
807 	if ((addr >= XX_PInfo.portal_ce_pa[BM_PORTAL][cpu]) &&
808 	    (addr < XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] +
809 	    XX_PInfo.portal_ce_size[BM_PORTAL][cpu]))
810 		return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] +
811 		    (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu])));
812 
813 	if ((addr >= XX_PInfo.portal_ci_pa[BM_PORTAL][cpu]) &&
814 	    (addr < XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] +
815 	    XX_PInfo.portal_ci_size[BM_PORTAL][cpu]))
816 		return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] +
817 		    (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu])));
818 
819 	/* Handle QMAN mappings */
820 	if ((addr >= XX_PInfo.portal_ce_pa[QM_PORTAL][cpu]) &&
821 	    (addr < XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] +
822 	    XX_PInfo.portal_ce_size[QM_PORTAL][cpu]))
823 		return ((void *)(XX_PInfo.portal_ce_va[QM_PORTAL] +
824 		    (vm_offset_t)(addr - XX_PInfo.portal_ce_pa[QM_PORTAL][cpu])));
825 
826 	if ((addr >= XX_PInfo.portal_ci_pa[QM_PORTAL][cpu]) &&
827 	    (addr < XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] +
828 	    XX_PInfo.portal_ci_size[QM_PORTAL][cpu]))
829 		return ((void *)(XX_PInfo.portal_ci_va[QM_PORTAL] +
830 		    (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[QM_PORTAL][cpu])));
831 
832 	mtx_lock(&XX_MallocTrackLock);
833 	ts = XX_FindTracker(addr);
834 	mtx_unlock(&XX_MallocTrackLock);
835 
836 	if (ts != NULL)
837 		return ts->va;
838 
839 	printf("NetCommSW: "
840 	    "Unable to translate physical address 0x%08llX!\n", addr);
841 
842 	return (NULL);
843 }
844 
845 void
846 XX_PortalSetInfo(device_t dev)
847 {
848 	char *dev_name;
849 	struct dpaa_portals_softc *sc;
850 	int i, type, len;
851 
852 	dev_name = malloc(sizeof(*dev_name), M_TEMP, M_WAITOK |
853 	    M_ZERO);
854 
855 	len = strlen("bman-portals");
856 
857 	strncpy(dev_name, device_get_name(dev), len);
858 
859 	if (strncmp(dev_name, "bman-portals", len) && strncmp(dev_name,
860 	    "qman-portals", len))
861 		goto end;
862 
863 	if (strncmp(dev_name, "bman-portals", len) == 0)
864 		type = BM_PORTAL;
865 	else
866 		type = QM_PORTAL;
867 
868 	sc = device_get_softc(dev);
869 
870 	for (i = 0; sc->sc_dp[i].dp_ce_pa != 0; i++) {
871 		XX_PInfo.portal_ce_pa[type][i] = sc->sc_dp[i].dp_ce_pa;
872 		XX_PInfo.portal_ci_pa[type][i] = sc->sc_dp[i].dp_ci_pa;
873 		XX_PInfo.portal_ce_size[type][i] = sc->sc_dp[i].dp_ce_size;
874 		XX_PInfo.portal_ci_size[type][i] = sc->sc_dp[i].dp_ci_size;
875 		XX_PInfo.portal_intr[type][i] = sc->sc_dp[i].dp_intr_num;
876 	}
877 
878 	XX_PInfo.portal_ce_va[type] = rman_get_bushandle(sc->sc_rres[0]);
879 	XX_PInfo.portal_ci_va[type] = rman_get_bushandle(sc->sc_rres[1]);
880 end:
881 	free(dev_name, M_TEMP);
882 }
883 
884 static XX_MallocTrackStruct *
885 XX_FindTracker(physAddress_t pa)
886 {
887 	struct XX_MallocTrackerList *l;
888 	XX_MallocTrackStruct *tp;
889 
890 	l = &XX_MallocTracker[(pa >> XX_MALLOC_TRACK_SHIFT) & XX_MallocHashMask];
891 
892 	LIST_FOREACH(tp, l, entries) {
893 		if (tp->pa == pa)
894 			return tp;
895 	}
896 
897 	return NULL;
898 }
899 
900 void
901 XX_TrackInit(void)
902 {
903 	if (XX_MallocTracker == NULL) {
904 		XX_MallocTracker = hashinit(64, M_NETCOMMSW_MT,
905 		    &XX_MallocHashMask);
906 	}
907 }
908 
909 void
910 XX_TrackAddress(void *addr)
911 {
912 	physAddress_t pa;
913 	struct XX_MallocTrackerList *l;
914 	XX_MallocTrackStruct *ts;
915 
916 	pa = pmap_kextract((vm_offset_t)addr);
917 
918 	ts = malloc(sizeof(*ts), M_NETCOMMSW_MT, M_NOWAIT);
919 	ts->va = addr;
920 	ts->pa = pa;
921 
922 	l = &XX_MallocTracker[(pa >> XX_MALLOC_TRACK_SHIFT) & XX_MallocHashMask];
923 
924 	mtx_lock(&XX_MallocTrackLock);
925 	if (XX_FindTracker(pa) != NULL)
926 		free(ts, M_NETCOMMSW_MT);
927 	else
928 		LIST_INSERT_HEAD(l, ts, entries);
929 	mtx_unlock(&XX_MallocTrackLock);
930 }
931 
932 void
933 XX_UntrackAddress(void *addr)
934 {
935 	physAddress_t pa;
936 	XX_MallocTrackStruct *ts;
937 
938 	pa = pmap_kextract((vm_offset_t)addr);
939 
940 	KASSERT(XX_MallocTracker != NULL,
941 	    ("Untracking an address before it's even initialized!\n"));
942 
943 	mtx_lock(&XX_MallocTrackLock);
944 	ts = XX_FindTracker(pa);
945 	if (ts != NULL)
946 		LIST_REMOVE(ts, entries);
947 	mtx_unlock(&XX_MallocTrackLock);
948 	free(ts, M_NETCOMMSW_MT);
949 }
950