1296177Sjhibbits/*-
2296177Sjhibbits * Copyright (c) 2011 Semihalf.
3296177Sjhibbits * All rights reserved.
4296177Sjhibbits *
5296177Sjhibbits * Redistribution and use in source and binary forms, with or without
6296177Sjhibbits * modification, are permitted provided that the following conditions
7296177Sjhibbits * are met:
8296177Sjhibbits * 1. Redistributions of source code must retain the above copyright
9296177Sjhibbits *    notice, this list of conditions and the following disclaimer.
10296177Sjhibbits * 2. Redistributions in binary form must reproduce the above copyright
11296177Sjhibbits *    notice, this list of conditions and the following disclaimer in the
12296177Sjhibbits *    documentation and/or other materials provided with the distribution.
13296177Sjhibbits *
14296177Sjhibbits * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15296177Sjhibbits * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16296177Sjhibbits * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17296177Sjhibbits * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18296177Sjhibbits * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19296177Sjhibbits * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20296177Sjhibbits * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21296177Sjhibbits * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22296177Sjhibbits * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23296177Sjhibbits * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24296177Sjhibbits * SUCH DAMAGE.
25296177Sjhibbits */
26296177Sjhibbits
27296177Sjhibbits#include <sys/param.h>
28296177Sjhibbits#include <sys/systm.h>
29296177Sjhibbits#include <sys/kernel.h>
30296177Sjhibbits#include <sys/malloc.h>
31296177Sjhibbits#include <sys/bus.h>
32296177Sjhibbits#include <sys/interrupt.h>
33296177Sjhibbits#include <sys/lock.h>
34296177Sjhibbits#include <sys/mutex.h>
35296177Sjhibbits#include <sys/proc.h>
36296177Sjhibbits#include <sys/queue.h>
37296177Sjhibbits#include <sys/rman.h>
38296177Sjhibbits#include <sys/sched.h>
39296177Sjhibbits#include <sys/smp.h>
40296177Sjhibbits
41296177Sjhibbits#include <vm/vm.h>
42296177Sjhibbits#include <vm/vm_param.h>
43296177Sjhibbits#include <vm/vm_page.h>
44296177Sjhibbits
45296177Sjhibbits#include <machine/cpufunc.h>
46296177Sjhibbits#include <machine/intr_machdep.h>
47296177Sjhibbits#include <machine/pmap.h>
48296177Sjhibbits#include <machine/stdarg.h>
49296177Sjhibbits
50296177Sjhibbits#include <dev/dpaa/bman.h>
51296177Sjhibbits#include <dev/dpaa/qman.h>
52296177Sjhibbits#include <dev/dpaa/portals.h>
53296177Sjhibbits
54296177Sjhibbits#include "error_ext.h"
55296177Sjhibbits#include "std_ext.h"
56296177Sjhibbits#include "list_ext.h"
57296177Sjhibbits#include "mm_ext.h"
58296177Sjhibbits
59296177Sjhibbits/* Configuration */
60296177Sjhibbits
61296177Sjhibbits/* Define the number of dTSEC ports active in system */
62296177Sjhibbits#define MALLOCSMART_DTSEC_IN_USE	4
63296177Sjhibbits
64296177Sjhibbits/*
65296177Sjhibbits * Calculate malloc's pool size for dTSEC's buffers.
66296177Sjhibbits * We reserve 1MB pool for each dTSEC port.
67296177Sjhibbits */
68296177Sjhibbits#define	MALLOCSMART_POOL_SIZE		\
69296177Sjhibbits    (MALLOCSMART_DTSEC_IN_USE * 1024 * 1024)
70296177Sjhibbits
71296177Sjhibbits#define MALLOCSMART_SLICE_SIZE		(PAGE_SIZE / 2)		/* 2kB */
72296177Sjhibbits
73296177Sjhibbits/* Defines */
74296177Sjhibbits#define MALLOCSMART_SIZE_TO_SLICE(x)	\
75296177Sjhibbits    (((x) + MALLOCSMART_SLICE_SIZE - 1) / MALLOCSMART_SLICE_SIZE)
76296177Sjhibbits#define MALLOCSMART_SLICES		\
77296177Sjhibbits    MALLOCSMART_SIZE_TO_SLICE(MALLOCSMART_POOL_SIZE)
78296177Sjhibbits
79296177Sjhibbits/* Malloc Pool for NetCommSW */
80296177SjhibbitsMALLOC_DEFINE(M_NETCOMMSW, "NetCommSW", "NetCommSW software stack");
81296177SjhibbitsMALLOC_DEFINE(M_NETCOMMSW_MT, "NetCommSWTrack",
82296177Sjhibbits    "NetCommSW software allocation tracker");
83296177Sjhibbits
84296177Sjhibbits/* MallocSmart data structures */
85296177Sjhibbitsstatic void *XX_MallocSmartPool;
86296177Sjhibbitsstatic int XX_MallocSmartMap[MALLOCSMART_SLICES];
87296177Sjhibbits
88296177Sjhibbitsstatic struct mtx XX_MallocSmartLock;
89296177Sjhibbitsstatic struct mtx XX_MallocTrackLock;
90296177SjhibbitsMTX_SYSINIT(XX_MallocSmartLockInit, &XX_MallocSmartLock,
91296177Sjhibbits    "NetCommSW MallocSmart Lock", MTX_DEF);
92296177SjhibbitsMTX_SYSINIT(XX_MallocTrackLockInit, &XX_MallocTrackLock,
93296177Sjhibbits    "NetCommSW MallocTrack Lock", MTX_DEF);
94296177Sjhibbits
95296177Sjhibbits/* Interrupt info */
96296177Sjhibbits#define XX_INTR_FLAG_PREALLOCATED	(1 << 0)
97296177Sjhibbits#define XX_INTR_FLAG_BOUND		(1 << 1)
98296177Sjhibbits#define XX_INTR_FLAG_FMAN_FIX		(1 << 2)
99296177Sjhibbits
100296177Sjhibbitsstruct XX_IntrInfo {
101296177Sjhibbits	driver_intr_t	*handler;
102296177Sjhibbits	void		*arg;
103296177Sjhibbits	int		cpu;
104296177Sjhibbits	int		flags;
105296177Sjhibbits	void		*cookie;
106296177Sjhibbits};
107296177Sjhibbits
108296177Sjhibbitsstatic struct XX_IntrInfo XX_IntrInfo[INTR_VECTORS];
109296177Sjhibbits/* Portal type identifiers */
110296177Sjhibbitsenum XX_PortalIdent{
111296177Sjhibbits	BM_PORTAL = 0,
112296177Sjhibbits	QM_PORTAL,
113296177Sjhibbits};
114296177Sjhibbits/* Structure to store portals' properties */
115296177Sjhibbitsstruct XX_PortalInfo {
116296177Sjhibbits	vm_paddr_t	portal_ce_pa[2][MAXCPU];
117296177Sjhibbits	vm_paddr_t	portal_ci_pa[2][MAXCPU];
118296177Sjhibbits	uint32_t	portal_ce_size[2][MAXCPU];
119296177Sjhibbits	uint32_t	portal_ci_size[2][MAXCPU];
120296177Sjhibbits	vm_offset_t	portal_ce_va[2];
121296177Sjhibbits	vm_offset_t	portal_ci_va[2];
122296177Sjhibbits	uint32_t	portal_intr[2][MAXCPU];
123296177Sjhibbits};
124296177Sjhibbits
125296177Sjhibbitsstatic struct XX_PortalInfo XX_PInfo;
126296177Sjhibbits
127296177Sjhibbits/* The lower 9 bits, through emprical testing, tend to be 0. */
128296177Sjhibbits#define	XX_MALLOC_TRACK_SHIFT	9
129296177Sjhibbits
130296177Sjhibbitstypedef struct XX_MallocTrackStruct {
131296177Sjhibbits	LIST_ENTRY(XX_MallocTrackStruct) entries;
132296177Sjhibbits	physAddress_t pa;
133296177Sjhibbits	void *va;
134296177Sjhibbits} XX_MallocTrackStruct;
135296177Sjhibbits
136296177SjhibbitsLIST_HEAD(XX_MallocTrackerList, XX_MallocTrackStruct) *XX_MallocTracker;
137296177Sjhibbitsu_long XX_MallocHashMask;
138296177Sjhibbitsstatic XX_MallocTrackStruct * XX_FindTracker(physAddress_t pa);
139296177Sjhibbits
140296177Sjhibbitsvoid
141296177SjhibbitsXX_Exit(int status)
142296177Sjhibbits{
143296177Sjhibbits
144296177Sjhibbits	panic("NetCommSW: Exit called with status %i", status);
145296177Sjhibbits}
146296177Sjhibbits
147296177Sjhibbitsvoid
148296177SjhibbitsXX_Print(char *str, ...)
149296177Sjhibbits{
150296177Sjhibbits	va_list ap;
151296177Sjhibbits
152296177Sjhibbits	va_start(ap, str);
153296177Sjhibbits	vprintf(str, ap);
154296177Sjhibbits	va_end(ap);
155296177Sjhibbits}
156296177Sjhibbits
157296177Sjhibbitsvoid *
158296177SjhibbitsXX_Malloc(uint32_t size)
159296177Sjhibbits{
160296177Sjhibbits	void *p = (malloc(size, M_NETCOMMSW, M_NOWAIT));
161296177Sjhibbits
162296177Sjhibbits	return (p);
163296177Sjhibbits}
164296177Sjhibbits
165296177Sjhibbitsstatic int
166296177SjhibbitsXX_MallocSmartMapCheck(unsigned int start, unsigned int slices)
167296177Sjhibbits{
168296177Sjhibbits	unsigned int i;
169296177Sjhibbits
170296177Sjhibbits	mtx_assert(&XX_MallocSmartLock, MA_OWNED);
171296177Sjhibbits	for (i = start; i < start + slices; i++)
172296177Sjhibbits		if (XX_MallocSmartMap[i])
173296177Sjhibbits			return (FALSE);
174296177Sjhibbits	return (TRUE);
175296177Sjhibbits}
176296177Sjhibbits
177296177Sjhibbitsstatic void
178296177SjhibbitsXX_MallocSmartMapSet(unsigned int start, unsigned int slices)
179296177Sjhibbits{
180296177Sjhibbits	unsigned int i;
181296177Sjhibbits
182296177Sjhibbits	mtx_assert(&XX_MallocSmartLock, MA_OWNED);
183296177Sjhibbits
184296177Sjhibbits	for (i = start; i < start + slices; i++)
185296177Sjhibbits		XX_MallocSmartMap[i] = ((i == start) ? slices : -1);
186296177Sjhibbits}
187296177Sjhibbits
188296177Sjhibbitsstatic void
189296177SjhibbitsXX_MallocSmartMapClear(unsigned int start, unsigned int slices)
190296177Sjhibbits{
191296177Sjhibbits	unsigned int i;
192296177Sjhibbits
193296177Sjhibbits	mtx_assert(&XX_MallocSmartLock, MA_OWNED);
194296177Sjhibbits
195296177Sjhibbits	for (i = start; i < start + slices; i++)
196296177Sjhibbits		XX_MallocSmartMap[i] = 0;
197296177Sjhibbits}
198296177Sjhibbits
199296177Sjhibbitsint
200296177SjhibbitsXX_MallocSmartInit(void)
201296177Sjhibbits{
202296177Sjhibbits	int error;
203296177Sjhibbits
204296177Sjhibbits	error = E_OK;
205296177Sjhibbits	mtx_lock(&XX_MallocSmartLock);
206296177Sjhibbits
207296177Sjhibbits	if (XX_MallocSmartPool)
208296177Sjhibbits		goto out;
209296177Sjhibbits
210296177Sjhibbits	/* Allocate MallocSmart pool */
211296177Sjhibbits	XX_MallocSmartPool = contigmalloc(MALLOCSMART_POOL_SIZE, M_NETCOMMSW,
212296177Sjhibbits	    M_NOWAIT, 0, 0xFFFFFFFFFull, MALLOCSMART_POOL_SIZE, 0);
213296177Sjhibbits	if (!XX_MallocSmartPool) {
214296177Sjhibbits		error = E_NO_MEMORY;
215296177Sjhibbits		goto out;
216296177Sjhibbits	}
217296177Sjhibbits
218296177Sjhibbitsout:
219296177Sjhibbits	mtx_unlock(&XX_MallocSmartLock);
220296177Sjhibbits	return (error);
221296177Sjhibbits}
222296177Sjhibbits
223296177Sjhibbitsvoid *
224296177SjhibbitsXX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
225296177Sjhibbits{
226296177Sjhibbits	unsigned int i;
227296177Sjhibbits	vm_offset_t addr;
228296177Sjhibbits
229296177Sjhibbits	addr = 0;
230296177Sjhibbits
231296177Sjhibbits	/* Convert alignment and size to number of slices */
232296177Sjhibbits	alignment = MALLOCSMART_SIZE_TO_SLICE(alignment);
233296177Sjhibbits	size = MALLOCSMART_SIZE_TO_SLICE(size);
234296177Sjhibbits
235296177Sjhibbits	/* Lock resources */
236296177Sjhibbits	mtx_lock(&XX_MallocSmartLock);
237296177Sjhibbits
238296177Sjhibbits	/* Allocate region */
239296177Sjhibbits	for (i = 0; i + size <= MALLOCSMART_SLICES; i += alignment) {
240296177Sjhibbits		if (XX_MallocSmartMapCheck(i, size)) {
241296177Sjhibbits			XX_MallocSmartMapSet(i, size);
242296177Sjhibbits			addr = (vm_offset_t)XX_MallocSmartPool +
243296177Sjhibbits			    (i * MALLOCSMART_SLICE_SIZE);
244296177Sjhibbits			break;
245296177Sjhibbits		}
246296177Sjhibbits	}
247296177Sjhibbits
248296177Sjhibbits	/* Unlock resources */
249296177Sjhibbits	mtx_unlock(&XX_MallocSmartLock);
250296177Sjhibbits
251296177Sjhibbits	return ((void *)addr);
252296177Sjhibbits}
253296177Sjhibbits
254296177Sjhibbitsvoid
255296177SjhibbitsXX_FreeSmart(void *p)
256296177Sjhibbits{
257296177Sjhibbits	unsigned int start, slices;
258296177Sjhibbits
259296177Sjhibbits	/* Calculate first slice of region */
260296177Sjhibbits	start = MALLOCSMART_SIZE_TO_SLICE((vm_offset_t)(p) -
261296177Sjhibbits	    (vm_offset_t)XX_MallocSmartPool);
262296177Sjhibbits
263296177Sjhibbits	/* Lock resources */
264296177Sjhibbits	mtx_lock(&XX_MallocSmartLock);
265296177Sjhibbits
266296177Sjhibbits	KASSERT(XX_MallocSmartMap[start] > 0,
267296177Sjhibbits	    ("XX_FreeSmart: Double or mid-block free!\n"));
268296177Sjhibbits
269296177Sjhibbits	XX_UntrackAddress(p);
270296177Sjhibbits	/* Free region */
271296177Sjhibbits	slices = XX_MallocSmartMap[start];
272296177Sjhibbits	XX_MallocSmartMapClear(start, slices);
273296177Sjhibbits
274296177Sjhibbits	/* Unlock resources */
275296177Sjhibbits	mtx_unlock(&XX_MallocSmartLock);
276296177Sjhibbits}
277296177Sjhibbits
278296177Sjhibbitsvoid
279296177SjhibbitsXX_Free(void *p)
280296177Sjhibbits{
281296177Sjhibbits
282296177Sjhibbits	if (p != NULL)
283296177Sjhibbits		XX_UntrackAddress(p);
284296177Sjhibbits	free(p, M_NETCOMMSW);
285296177Sjhibbits}
286296177Sjhibbits
287296177Sjhibbitsuint32_t
288296177SjhibbitsXX_DisableAllIntr(void)
289296177Sjhibbits{
290296177Sjhibbits
291296177Sjhibbits	return (intr_disable());
292296177Sjhibbits}
293296177Sjhibbits
294296177Sjhibbitsvoid
295296177SjhibbitsXX_RestoreAllIntr(uint32_t flags)
296296177Sjhibbits{
297296177Sjhibbits
298296177Sjhibbits	intr_restore(flags);
299296177Sjhibbits}
300296177Sjhibbits
301296177Sjhibbitst_Error
302296177SjhibbitsXX_Call(uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
303296177Sjhibbits{
304296177Sjhibbits	/* Not referenced */
305296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
306296177Sjhibbits	return (E_OK);
307296177Sjhibbits}
308296177Sjhibbits
309296177Sjhibbitsstatic bool
310296177SjhibbitsXX_IsPortalIntr(int irq)
311296177Sjhibbits{
312296177Sjhibbits	int cpu, type;
313296177Sjhibbits	/* Check interrupt numbers of all available portals */
314296177Sjhibbits	for (cpu = 0, type = 0; XX_PInfo.portal_intr[type][cpu] != 0; cpu++) {
315296177Sjhibbits		if (irq == XX_PInfo.portal_intr[type][cpu]) {
316296177Sjhibbits			/* Found it! */
317296177Sjhibbits			return (1);
318296177Sjhibbits		}
319296177Sjhibbits		if (XX_PInfo.portal_intr[type][cpu + 1] == 0) {
320296177Sjhibbits			type++;
321296177Sjhibbits			cpu = 0;
322296177Sjhibbits		}
323296177Sjhibbits	}
324296177Sjhibbits
325296177Sjhibbits	return (0);
326296177Sjhibbits}
327296177Sjhibbits
328296177Sjhibbitsvoid
329296177SjhibbitsXX_FmanFixIntr(int irq)
330296177Sjhibbits{
331296177Sjhibbits
332296177Sjhibbits	XX_IntrInfo[irq].flags |= XX_INTR_FLAG_FMAN_FIX;
333296177Sjhibbits}
334296177Sjhibbits
335296177Sjhibbitsstatic bool
336296177SjhibbitsXX_FmanNeedsIntrFix(int irq)
337296177Sjhibbits{
338296177Sjhibbits
339296177Sjhibbits	if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_FMAN_FIX)
340296177Sjhibbits		return (1);
341296177Sjhibbits
342296177Sjhibbits	return (0);
343296177Sjhibbits}
344296177Sjhibbits
345296177Sjhibbitsstatic void
346296177SjhibbitsXX_Dispatch(void *arg)
347296177Sjhibbits{
348296177Sjhibbits	struct XX_IntrInfo *info;
349296177Sjhibbits
350296177Sjhibbits	info = arg;
351296177Sjhibbits
352296177Sjhibbits	/* Bind this thread to proper CPU when SMP has been already started. */
353296177Sjhibbits	if ((info->flags & XX_INTR_FLAG_BOUND) == 0 && smp_started &&
354296177Sjhibbits	    info->cpu >= 0) {
355296177Sjhibbits		thread_lock(curthread);
356296177Sjhibbits		sched_bind(curthread, info->cpu);
357296177Sjhibbits		thread_unlock(curthread);
358296177Sjhibbits
359296177Sjhibbits		info->flags |= XX_INTR_FLAG_BOUND;
360296177Sjhibbits	}
361296177Sjhibbits
362296177Sjhibbits	if (info->handler == NULL) {
363296177Sjhibbits		printf("%s(): IRQ handler is NULL!\n", __func__);
364296177Sjhibbits		return;
365296177Sjhibbits	}
366296177Sjhibbits
367296177Sjhibbits	info->handler(info->arg);
368296177Sjhibbits}
369296177Sjhibbits
370296177Sjhibbitst_Error
371296177SjhibbitsXX_PreallocAndBindIntr(int irq, unsigned int cpu)
372296177Sjhibbits{
373296177Sjhibbits	struct resource *r;
374296177Sjhibbits	unsigned int inum;
375296177Sjhibbits	t_Error error;
376296177Sjhibbits
377296177Sjhibbits	r = (struct resource *)irq;
378296177Sjhibbits	inum = rman_get_start(r);
379296177Sjhibbits
380296177Sjhibbits	error = XX_SetIntr(irq, XX_Dispatch, &XX_IntrInfo[inum]);
381296177Sjhibbits	if (error != 0)
382296177Sjhibbits		return (error);
383296177Sjhibbits
384296177Sjhibbits	XX_IntrInfo[inum].flags = XX_INTR_FLAG_PREALLOCATED;
385296177Sjhibbits	XX_IntrInfo[inum].cpu = cpu;
386296177Sjhibbits
387296177Sjhibbits	return (E_OK);
388296177Sjhibbits}
389296177Sjhibbits
390296177Sjhibbitst_Error
391296177SjhibbitsXX_DeallocIntr(int irq)
392296177Sjhibbits{
393296177Sjhibbits	struct resource *r;
394296177Sjhibbits	unsigned int inum;
395296177Sjhibbits
396296177Sjhibbits	r = (struct resource *)irq;
397296177Sjhibbits	inum = rman_get_start(r);
398296177Sjhibbits
399296177Sjhibbits	if ((XX_IntrInfo[inum].flags & XX_INTR_FLAG_PREALLOCATED) == 0)
400296177Sjhibbits		return (E_INVALID_STATE);
401296177Sjhibbits
402296177Sjhibbits	XX_IntrInfo[inum].flags = 0;
403296177Sjhibbits	return (XX_FreeIntr(irq));
404296177Sjhibbits}
405296177Sjhibbits
406296177Sjhibbitst_Error
407296177SjhibbitsXX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
408296177Sjhibbits{
409296177Sjhibbits	struct device *dev;
410296177Sjhibbits	struct resource *r;
411296177Sjhibbits	unsigned int flags;
412296177Sjhibbits	int err;
413296177Sjhibbits
414296177Sjhibbits	r = (struct resource *)irq;
415296177Sjhibbits	dev = rman_get_device(r);
416296177Sjhibbits	irq = rman_get_start(r);
417296177Sjhibbits
418296177Sjhibbits	/* Handle preallocated interrupts */
419296177Sjhibbits	if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) {
420296177Sjhibbits		if (XX_IntrInfo[irq].handler != NULL)
421296177Sjhibbits			return (E_BUSY);
422296177Sjhibbits
423296177Sjhibbits		XX_IntrInfo[irq].handler = f_Isr;
424296177Sjhibbits		XX_IntrInfo[irq].arg = handle;
425296177Sjhibbits
426296177Sjhibbits		return (E_OK);
427296177Sjhibbits	}
428296177Sjhibbits
429296177Sjhibbits	flags = INTR_TYPE_NET | INTR_MPSAFE;
430296177Sjhibbits
431296177Sjhibbits	/* BMAN/QMAN Portal interrupts must be exlusive */
432296177Sjhibbits	if (XX_IsPortalIntr(irq))
433296177Sjhibbits		flags |= INTR_EXCL;
434296177Sjhibbits
435296177Sjhibbits	err = bus_setup_intr(dev, r, flags, NULL, f_Isr, handle,
436296177Sjhibbits		    &XX_IntrInfo[irq].cookie);
437296177Sjhibbits	if (err)
438296177Sjhibbits		goto finish;
439296177Sjhibbits
440296177Sjhibbits	/*
441296177Sjhibbits	 * XXX: Bind FMan IRQ to CPU0. Current interrupt subsystem directs each
442296177Sjhibbits	 * interrupt to all CPUs. Race between an interrupt assertion and
443296177Sjhibbits	 * masking may occur and interrupt handler may be called multiple times
444296177Sjhibbits	 * per one interrupt. FMan doesn't support such a situation. Workaround
445296177Sjhibbits	 * is to bind FMan interrupt to one CPU0 only.
446296177Sjhibbits	 */
447296177Sjhibbits#ifdef SMP
448296177Sjhibbits	if (XX_FmanNeedsIntrFix(irq))
449296177Sjhibbits		err = powerpc_bind_intr(irq, 0);
450296177Sjhibbits#endif
451296177Sjhibbitsfinish:
452296177Sjhibbits	return (err);
453296177Sjhibbits}
454296177Sjhibbits
455296177Sjhibbitst_Error
456296177SjhibbitsXX_FreeIntr(int irq)
457296177Sjhibbits{
458296177Sjhibbits	struct device *dev;
459296177Sjhibbits	struct resource *r;
460296177Sjhibbits
461296177Sjhibbits	r = (struct resource *)irq;
462296177Sjhibbits	dev = rman_get_device(r);
463296177Sjhibbits	irq = rman_get_start(r);
464296177Sjhibbits
465296177Sjhibbits	/* Handle preallocated interrupts */
466296177Sjhibbits	if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) {
467296177Sjhibbits		if (XX_IntrInfo[irq].handler == NULL)
468296177Sjhibbits			return (E_INVALID_STATE);
469296177Sjhibbits
470296177Sjhibbits		XX_IntrInfo[irq].handler = NULL;
471296177Sjhibbits		XX_IntrInfo[irq].arg = NULL;
472296177Sjhibbits
473296177Sjhibbits		return (E_OK);
474296177Sjhibbits	}
475296177Sjhibbits
476296177Sjhibbits	return (bus_teardown_intr(dev, r, XX_IntrInfo[irq].cookie));
477296177Sjhibbits}
478296177Sjhibbits
479296177Sjhibbitst_Error
480296177SjhibbitsXX_EnableIntr(int irq)
481296177Sjhibbits{
482296177Sjhibbits	struct resource *r;
483296177Sjhibbits
484296177Sjhibbits	r = (struct resource *)irq;
485296177Sjhibbits	irq = rman_get_start(r);
486296177Sjhibbits
487296177Sjhibbits	powerpc_intr_unmask(irq);
488296177Sjhibbits
489296177Sjhibbits	return (E_OK);
490296177Sjhibbits}
491296177Sjhibbits
492296177Sjhibbitst_Error
493296177SjhibbitsXX_DisableIntr(int irq)
494296177Sjhibbits{
495296177Sjhibbits	struct resource *r;
496296177Sjhibbits
497296177Sjhibbits	r = (struct resource *)irq;
498296177Sjhibbits	irq = rman_get_start(r);
499296177Sjhibbits
500296177Sjhibbits	powerpc_intr_mask(irq);
501296177Sjhibbits
502296177Sjhibbits	return (E_OK);
503296177Sjhibbits}
504296177Sjhibbits
505296177Sjhibbitst_TaskletHandle
506296177SjhibbitsXX_InitTasklet (void (*routine)(void *), void *data)
507296177Sjhibbits{
508296177Sjhibbits	/* Not referenced */
509296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
510296177Sjhibbits	return (NULL);
511296177Sjhibbits}
512296177Sjhibbits
513296177Sjhibbits
514296177Sjhibbitsvoid
515296177SjhibbitsXX_FreeTasklet (t_TaskletHandle h_Tasklet)
516296177Sjhibbits{
517296177Sjhibbits	/* Not referenced */
518296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
519296177Sjhibbits}
520296177Sjhibbits
521296177Sjhibbitsint
522296177SjhibbitsXX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
523296177Sjhibbits{
524296177Sjhibbits	/* Not referenced */
525296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
526296177Sjhibbits	return (0);
527296177Sjhibbits}
528296177Sjhibbits
529296177Sjhibbitsvoid
530296177SjhibbitsXX_FlushScheduledTasks(void)
531296177Sjhibbits{
532296177Sjhibbits	/* Not referenced */
533296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
534296177Sjhibbits}
535296177Sjhibbits
536296177Sjhibbitsint
537296177SjhibbitsXX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
538296177Sjhibbits{
539296177Sjhibbits	/* Not referenced */
540296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
541296177Sjhibbits	return (0);
542296177Sjhibbits}
543296177Sjhibbits
544296177Sjhibbitsvoid
545296177SjhibbitsXX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
546296177Sjhibbits{
547296177Sjhibbits	/* Not referenced */
548296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
549296177Sjhibbits}
550296177Sjhibbits
551296177Sjhibbitst_Handle
552296177SjhibbitsXX_GetTaskletData(t_TaskletHandle h_Tasklet)
553296177Sjhibbits{
554296177Sjhibbits	/* Not referenced */
555296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
556296177Sjhibbits	return (NULL);
557296177Sjhibbits}
558296177Sjhibbits
559296177Sjhibbitst_Handle
560296177SjhibbitsXX_InitSpinlock(void)
561296177Sjhibbits{
562296177Sjhibbits	struct mtx *m;
563296177Sjhibbits
564298526Sjhibbits	m = malloc(sizeof(*m), M_NETCOMMSW, M_NOWAIT | M_ZERO);
565296177Sjhibbits	if (!m)
566296177Sjhibbits		return (0);
567296177Sjhibbits
568296177Sjhibbits	mtx_init(m, "NetCommSW Lock", NULL, MTX_DEF | MTX_DUPOK);
569296177Sjhibbits
570296177Sjhibbits	return (m);
571296177Sjhibbits}
572296177Sjhibbits
573296177Sjhibbitsvoid
574296177SjhibbitsXX_FreeSpinlock(t_Handle h_Spinlock)
575296177Sjhibbits{
576296177Sjhibbits	struct mtx *m;
577296177Sjhibbits
578296177Sjhibbits	m = h_Spinlock;
579296177Sjhibbits
580296177Sjhibbits	mtx_destroy(m);
581296177Sjhibbits	free(m, M_NETCOMMSW);
582296177Sjhibbits}
583296177Sjhibbits
584296177Sjhibbitsvoid
585296177SjhibbitsXX_LockSpinlock(t_Handle h_Spinlock)
586296177Sjhibbits{
587296177Sjhibbits	struct mtx *m;
588296177Sjhibbits
589296177Sjhibbits	m = h_Spinlock;
590296177Sjhibbits	mtx_lock(m);
591296177Sjhibbits}
592296177Sjhibbits
593296177Sjhibbitsvoid
594296177SjhibbitsXX_UnlockSpinlock(t_Handle h_Spinlock)
595296177Sjhibbits{
596296177Sjhibbits	struct mtx *m;
597296177Sjhibbits
598296177Sjhibbits	m = h_Spinlock;
599296177Sjhibbits	mtx_unlock(m);
600296177Sjhibbits}
601296177Sjhibbits
602296177Sjhibbitsuint32_t
603296177SjhibbitsXX_LockIntrSpinlock(t_Handle h_Spinlock)
604296177Sjhibbits{
605296177Sjhibbits
606296177Sjhibbits	XX_LockSpinlock(h_Spinlock);
607296177Sjhibbits	return (0);
608296177Sjhibbits}
609296177Sjhibbits
610296177Sjhibbitsvoid
611296177SjhibbitsXX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
612296177Sjhibbits{
613296177Sjhibbits
614296177Sjhibbits	XX_UnlockSpinlock(h_Spinlock);
615296177Sjhibbits}
616296177Sjhibbits
617296177Sjhibbitsuint32_t
618296177SjhibbitsXX_CurrentTime(void)
619296177Sjhibbits{
620296177Sjhibbits	/* Not referenced */
621296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
622296177Sjhibbits	return (0);
623296177Sjhibbits}
624296177Sjhibbits
625296177Sjhibbits
626296177Sjhibbitst_Handle
627296177SjhibbitsXX_CreateTimer(void)
628296177Sjhibbits{
629296177Sjhibbits	/* Not referenced */
630296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
631296177Sjhibbits	return (NULL);
632296177Sjhibbits}
633296177Sjhibbits
634296177Sjhibbitsvoid
635296177SjhibbitsXX_FreeTimer(t_Handle h_Timer)
636296177Sjhibbits{
637296177Sjhibbits	/* Not referenced */
638296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
639296177Sjhibbits}
640296177Sjhibbits
641296177Sjhibbitsvoid
642296177SjhibbitsXX_StartTimer(t_Handle h_Timer,
643296177Sjhibbits                   uint32_t msecs,
644296177Sjhibbits                   bool     periodic,
645296177Sjhibbits                   void     (*f_TimerExpired)(t_Handle),
646296177Sjhibbits                   t_Handle h_Arg)
647296177Sjhibbits{
648296177Sjhibbits	/* Not referenced */
649296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
650296177Sjhibbits}
651296177Sjhibbits
652296177Sjhibbitsuint32_t
653296177SjhibbitsXX_GetExpirationTime(t_Handle h_Timer)
654296177Sjhibbits{
655296177Sjhibbits	/* Not referenced */
656296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
657296177Sjhibbits	return (0);
658296177Sjhibbits}
659296177Sjhibbits
660296177Sjhibbitsvoid
661296177SjhibbitsXX_StopTimer(t_Handle h_Timer)
662296177Sjhibbits{
663296177Sjhibbits	/* Not referenced */
664296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
665296177Sjhibbits}
666296177Sjhibbits
667296177Sjhibbitsvoid
668296177SjhibbitsXX_ModTimer(t_Handle h_Timer, uint32_t msecs)
669296177Sjhibbits{
670296177Sjhibbits	/* Not referenced */
671296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
672296177Sjhibbits}
673296177Sjhibbits
674296177Sjhibbitsint
675296177SjhibbitsXX_TimerIsActive(t_Handle h_Timer)
676296177Sjhibbits{
677296177Sjhibbits	/* Not referenced */
678296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
679296177Sjhibbits	return (0);
680296177Sjhibbits}
681296177Sjhibbits
682296177Sjhibbitsuint32_t
683296177SjhibbitsXX_Sleep(uint32_t msecs)
684296177Sjhibbits{
685296177Sjhibbits
686296177Sjhibbits	XX_UDelay(1000 * msecs);
687296177Sjhibbits	return (0);
688296177Sjhibbits}
689296177Sjhibbits
690296177Sjhibbitsvoid
691296177SjhibbitsXX_UDelay(uint32_t usecs)
692296177Sjhibbits{
693296177Sjhibbits	DELAY(usecs);
694296177Sjhibbits}
695296177Sjhibbits
696296177Sjhibbitst_Error
697296177SjhibbitsXX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
698296177Sjhibbits    t_IpcMsgHandler *f_MsgHandler, t_Handle  h_Module, uint32_t replyLength)
699296177Sjhibbits{
700296177Sjhibbits
701296177Sjhibbits	/*
702296177Sjhibbits	 * This function returns fake E_OK status and does nothing
703296177Sjhibbits	 * as NetCommSW IPC is not used by FreeBSD drivers.
704296177Sjhibbits	 */
705296177Sjhibbits	return (E_OK);
706296177Sjhibbits}
707296177Sjhibbits
708296177Sjhibbitst_Error
709296177SjhibbitsXX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
710296177Sjhibbits{
711296177Sjhibbits	/*
712296177Sjhibbits	 * This function returns fake E_OK status and does nothing
713296177Sjhibbits	 * as NetCommSW IPC is not used by FreeBSD drivers.
714296177Sjhibbits	 */
715296177Sjhibbits	return (E_OK);
716296177Sjhibbits}
717296177Sjhibbits
718296177Sjhibbits
719296177Sjhibbitst_Error
720296177SjhibbitsXX_IpcSendMessage(t_Handle h_Session,
721296177Sjhibbits    uint8_t *p_Msg, uint32_t msgLength, uint8_t *p_Reply,
722296177Sjhibbits    uint32_t *p_ReplyLength, t_IpcMsgCompletion *f_Completion, t_Handle h_Arg)
723296177Sjhibbits{
724296177Sjhibbits
725296177Sjhibbits	/* Should not be called */
726296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
727296177Sjhibbits	return (E_OK);
728296177Sjhibbits}
729296177Sjhibbits
730296177Sjhibbitst_Handle
731296177SjhibbitsXX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
732296177Sjhibbits    char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
733296177Sjhibbits{
734296177Sjhibbits
735296177Sjhibbits	/* Should not be called */
736296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
737296177Sjhibbits	return (E_OK);
738296177Sjhibbits}
739296177Sjhibbits
740296177Sjhibbitst_Error
741296177SjhibbitsXX_IpcFreeSession(t_Handle h_Session)
742296177Sjhibbits{
743296177Sjhibbits
744296177Sjhibbits	/* Should not be called */
745296177Sjhibbits	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
746296177Sjhibbits	return (E_OK);
747296177Sjhibbits}
748296177Sjhibbits
749296177Sjhibbitsextern void db_trace_self(void);
750296177SjhibbitsphysAddress_t
751296177SjhibbitsXX_VirtToPhys(void *addr)
752296177Sjhibbits{
753296177Sjhibbits	vm_paddr_t paddr;
754296177Sjhibbits	int cpu;
755296177Sjhibbits
756296177Sjhibbits	cpu = PCPU_GET(cpuid);
757296177Sjhibbits
758296177Sjhibbits	/* Handle NULL address */
759296177Sjhibbits	if (addr == NULL)
760296177Sjhibbits		return (-1);
761296177Sjhibbits
762296177Sjhibbits	/* Handle BMAN mappings */
763296177Sjhibbits	if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[BM_PORTAL]) &&
764296177Sjhibbits	    ((vm_offset_t)addr < XX_PInfo.portal_ce_va[BM_PORTAL] +
765296177Sjhibbits	    XX_PInfo.portal_ce_size[BM_PORTAL][cpu]))
766296177Sjhibbits		return (XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] +
767296177Sjhibbits		    (vm_offset_t)addr - XX_PInfo.portal_ce_va[BM_PORTAL]);
768296177Sjhibbits
769296177Sjhibbits	if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[BM_PORTAL]) &&
770296177Sjhibbits	    ((vm_offset_t)addr < XX_PInfo.portal_ci_va[BM_PORTAL] +
771296177Sjhibbits	    XX_PInfo.portal_ci_size[BM_PORTAL][cpu]))
772296177Sjhibbits		return (XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] +
773296177Sjhibbits		    (vm_offset_t)addr - XX_PInfo.portal_ci_va[BM_PORTAL]);
774296177Sjhibbits
775296177Sjhibbits	/* Handle QMAN mappings */
776296177Sjhibbits	if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[QM_PORTAL]) &&
777296177Sjhibbits	    ((vm_offset_t)addr < XX_PInfo.portal_ce_va[QM_PORTAL] +
778296177Sjhibbits	    XX_PInfo.portal_ce_size[QM_PORTAL][cpu]))
779296177Sjhibbits		return (XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] +
780296177Sjhibbits		    (vm_offset_t)addr - XX_PInfo.portal_ce_va[QM_PORTAL]);
781296177Sjhibbits
782296177Sjhibbits	if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[QM_PORTAL]) &&
783296177Sjhibbits	    ((vm_offset_t)addr < XX_PInfo.portal_ci_va[QM_PORTAL] +
784296177Sjhibbits	    XX_PInfo.portal_ci_size[QM_PORTAL][cpu]))
785296177Sjhibbits		return (XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] +
786296177Sjhibbits		    (vm_offset_t)addr - XX_PInfo.portal_ci_va[QM_PORTAL]);
787296177Sjhibbits
788296177Sjhibbits	paddr = pmap_kextract((vm_offset_t)addr);
789296177Sjhibbits	if (!paddr)
790296177Sjhibbits		printf("NetCommSW: "
791296177Sjhibbits		    "Unable to translate virtual address 0x%08X!\n", addr);
792296177Sjhibbits	else
793296177Sjhibbits	    XX_TrackAddress(addr);
794296177Sjhibbits
795296177Sjhibbits	return (paddr);
796296177Sjhibbits}
797296177Sjhibbits
798296177Sjhibbitsvoid *
799296177SjhibbitsXX_PhysToVirt(physAddress_t addr)
800296177Sjhibbits{
801296177Sjhibbits	XX_MallocTrackStruct *ts;
802296177Sjhibbits	int cpu;
803296177Sjhibbits
804296177Sjhibbits	cpu = PCPU_GET(cpuid);
805296177Sjhibbits
806296177Sjhibbits	/* Handle BMAN mappings */
807296177Sjhibbits	if ((addr >= XX_PInfo.portal_ce_pa[BM_PORTAL][cpu]) &&
808296177Sjhibbits	    (addr < XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] +
809296177Sjhibbits	    XX_PInfo.portal_ce_size[BM_PORTAL][cpu]))
810296177Sjhibbits		return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] +
811296177Sjhibbits		    (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu])));
812296177Sjhibbits
813296177Sjhibbits	if ((addr >= XX_PInfo.portal_ci_pa[BM_PORTAL][cpu]) &&
814296177Sjhibbits	    (addr < XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] +
815296177Sjhibbits	    XX_PInfo.portal_ci_size[BM_PORTAL][cpu]))
816296177Sjhibbits		return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] +
817296177Sjhibbits		    (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu])));
818296177Sjhibbits
819296177Sjhibbits	/* Handle QMAN mappings */
820296177Sjhibbits	if ((addr >= XX_PInfo.portal_ce_pa[QM_PORTAL][cpu]) &&
821296177Sjhibbits	    (addr < XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] +
822296177Sjhibbits	    XX_PInfo.portal_ce_size[QM_PORTAL][cpu]))
823296177Sjhibbits		return ((void *)(XX_PInfo.portal_ce_va[QM_PORTAL] +
824296177Sjhibbits		    (vm_offset_t)(addr - XX_PInfo.portal_ce_pa[QM_PORTAL][cpu])));
825296177Sjhibbits
826296177Sjhibbits	if ((addr >= XX_PInfo.portal_ci_pa[QM_PORTAL][cpu]) &&
827296177Sjhibbits	    (addr < XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] +
828296177Sjhibbits	    XX_PInfo.portal_ci_size[QM_PORTAL][cpu]))
829296177Sjhibbits		return ((void *)(XX_PInfo.portal_ci_va[QM_PORTAL] +
830296177Sjhibbits		    (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[QM_PORTAL][cpu])));
831296177Sjhibbits
832296177Sjhibbits	mtx_lock(&XX_MallocTrackLock);
833296177Sjhibbits	ts = XX_FindTracker(addr);
834296177Sjhibbits	mtx_unlock(&XX_MallocTrackLock);
835296177Sjhibbits
836296177Sjhibbits	if (ts != NULL)
837296177Sjhibbits		return ts->va;
838296177Sjhibbits
839296177Sjhibbits	printf("NetCommSW: "
840296177Sjhibbits	    "Unable to translate physical address 0x%08llX!\n", addr);
841296177Sjhibbits
842296177Sjhibbits	return (NULL);
843296177Sjhibbits}
844296177Sjhibbits
845296177Sjhibbitsvoid
846296177SjhibbitsXX_PortalSetInfo(device_t dev)
847296177Sjhibbits{
848296177Sjhibbits	char *dev_name;
849296177Sjhibbits	struct dpaa_portals_softc *sc;
850296177Sjhibbits	int i, type, len;
851296177Sjhibbits
852296177Sjhibbits	dev_name = malloc(sizeof(*dev_name), M_TEMP, M_WAITOK |
853296177Sjhibbits	    M_ZERO);
854296177Sjhibbits
855296177Sjhibbits	len = strlen("bman-portals");
856296177Sjhibbits
857296177Sjhibbits	strncpy(dev_name, device_get_name(dev), len);
858296177Sjhibbits
859296177Sjhibbits	if (strncmp(dev_name, "bman-portals", len) && strncmp(dev_name,
860296177Sjhibbits	    "qman-portals", len))
861296177Sjhibbits		goto end;
862296177Sjhibbits
863296177Sjhibbits	if (strncmp(dev_name, "bman-portals", len) == 0)
864296177Sjhibbits		type = BM_PORTAL;
865296177Sjhibbits	else
866296177Sjhibbits		type = QM_PORTAL;
867296177Sjhibbits
868296177Sjhibbits	sc = device_get_softc(dev);
869296177Sjhibbits
870296177Sjhibbits	for (i = 0; sc->sc_dp[i].dp_ce_pa != 0; i++) {
871296177Sjhibbits		XX_PInfo.portal_ce_pa[type][i] = sc->sc_dp[i].dp_ce_pa;
872296177Sjhibbits		XX_PInfo.portal_ci_pa[type][i] = sc->sc_dp[i].dp_ci_pa;
873296177Sjhibbits		XX_PInfo.portal_ce_size[type][i] = sc->sc_dp[i].dp_ce_size;
874296177Sjhibbits		XX_PInfo.portal_ci_size[type][i] = sc->sc_dp[i].dp_ci_size;
875296177Sjhibbits		XX_PInfo.portal_intr[type][i] = sc->sc_dp[i].dp_intr_num;
876296177Sjhibbits	}
877296177Sjhibbits
878296177Sjhibbits	XX_PInfo.portal_ce_va[type] = rman_get_bushandle(sc->sc_rres[0]);
879296177Sjhibbits	XX_PInfo.portal_ci_va[type] = rman_get_bushandle(sc->sc_rres[1]);
880296177Sjhibbitsend:
881296177Sjhibbits	free(dev_name, M_TEMP);
882296177Sjhibbits}
883296177Sjhibbits
884296177Sjhibbitsstatic XX_MallocTrackStruct *
885296177SjhibbitsXX_FindTracker(physAddress_t pa)
886296177Sjhibbits{
887296177Sjhibbits	struct XX_MallocTrackerList *l;
888296177Sjhibbits	XX_MallocTrackStruct *tp;
889296177Sjhibbits
890296177Sjhibbits	l = &XX_MallocTracker[(pa >> XX_MALLOC_TRACK_SHIFT) & XX_MallocHashMask];
891296177Sjhibbits
892296177Sjhibbits	LIST_FOREACH(tp, l, entries) {
893296177Sjhibbits		if (tp->pa == pa)
894296177Sjhibbits			return tp;
895296177Sjhibbits	}
896296177Sjhibbits
897296177Sjhibbits	return NULL;
898296177Sjhibbits}
899296177Sjhibbits
900296177Sjhibbitsvoid
901296177SjhibbitsXX_TrackInit(void)
902296177Sjhibbits{
903296177Sjhibbits	if (XX_MallocTracker == NULL) {
904296177Sjhibbits		XX_MallocTracker = hashinit(64, M_NETCOMMSW_MT,
905296177Sjhibbits		    &XX_MallocHashMask);
906296177Sjhibbits	}
907296177Sjhibbits}
908296177Sjhibbits
909296177Sjhibbitsvoid
910296177SjhibbitsXX_TrackAddress(void *addr)
911296177Sjhibbits{
912296177Sjhibbits	physAddress_t pa;
913296177Sjhibbits	struct XX_MallocTrackerList *l;
914296177Sjhibbits	XX_MallocTrackStruct *ts;
915296177Sjhibbits
916296177Sjhibbits	pa = pmap_kextract((vm_offset_t)addr);
917296177Sjhibbits
918296177Sjhibbits	ts = malloc(sizeof(*ts), M_NETCOMMSW_MT, M_NOWAIT);
919296177Sjhibbits	ts->va = addr;
920296177Sjhibbits	ts->pa = pa;
921296177Sjhibbits
922296177Sjhibbits	l = &XX_MallocTracker[(pa >> XX_MALLOC_TRACK_SHIFT) & XX_MallocHashMask];
923296177Sjhibbits
924296177Sjhibbits	mtx_lock(&XX_MallocTrackLock);
925296177Sjhibbits	if (XX_FindTracker(pa) != NULL)
926296177Sjhibbits		free(ts, M_NETCOMMSW_MT);
927296177Sjhibbits	else
928296177Sjhibbits		LIST_INSERT_HEAD(l, ts, entries);
929296177Sjhibbits	mtx_unlock(&XX_MallocTrackLock);
930296177Sjhibbits}
931296177Sjhibbits
932296177Sjhibbitsvoid
933296177SjhibbitsXX_UntrackAddress(void *addr)
934296177Sjhibbits{
935296177Sjhibbits	physAddress_t pa;
936296177Sjhibbits	XX_MallocTrackStruct *ts;
937296177Sjhibbits
938296177Sjhibbits	pa = pmap_kextract((vm_offset_t)addr);
939296177Sjhibbits
940296177Sjhibbits	KASSERT(XX_MallocTracker != NULL,
941296177Sjhibbits	    ("Untracking an address before it's even initialized!\n"));
942296177Sjhibbits
943296177Sjhibbits	mtx_lock(&XX_MallocTrackLock);
944296177Sjhibbits	ts = XX_FindTracker(pa);
945296177Sjhibbits	if (ts != NULL)
946296177Sjhibbits		LIST_REMOVE(ts, entries);
947296177Sjhibbits	mtx_unlock(&XX_MallocTrackLock);
948296177Sjhibbits	free(ts, M_NETCOMMSW_MT);
949296177Sjhibbits}
950