blob: 645c8d05d9afbc09ca09590a052717cf2121e5ee [file] [log] [blame]
Shad Ansari2f7f9be2017-06-07 13:34:53 -07001/*
2<:copyright-BRCM:2016:DUAL/GPL:standard
3
4 Broadcom Proprietary and Confidential.(c) 2016 Broadcom
5 All Rights Reserved
6
7Unless you and Broadcom execute a separate written software license
8agreement governing use of this software, this software is licensed
9to you under the terms of the GNU General Public License version 2
10(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
11with the following added to such license:
12
13 As a special exception, the copyright holders of this software give
14 you permission to link this software with independent modules, and
15 to copy and distribute the resulting executable under terms of your
16 choice, provided that you also meet, for each linked independent
17 module, the terms and conditions of the license of that module.
18 An independent module is a module which is not derived from this
19 software. The special exception does not apply to any modifications
20 of the software.
21
22Not withstanding the above, under no circumstances may you combine
23this software in any way with any other Broadcom software provided
24under a license other than the GPL, without Broadcom's express prior
25written consent.
26
27:>
28 */
29
30#include "bcmos_system.h"
31#include <vxWorks.h>
32#include <unistd.h>
33#include <taskLib.h>
34#include <wdLib.h>
35#include <sysLib.h>
36#include <errnoLib.h>
37#include <time.h>
38#include <intLib.h>
39#include <cacheLib.h>
40#include "memPartLib.h"
41
42#ifdef HOST_CPU_IS_MIPS
43#include "arch/mips/archMips.h"
44#endif
45
46#include <iv.h>
47
48#define BCMOS_DEFAULT_STACK_SIZE (100*1024)/*0x4000*/
49#define BCMOS_MICROSECONDS_TO_TICKS(u) (u)/1000000*bcmos_timer_get_frequency() + BCMOS_DIVIDE_ROUND_UP(((u)%1000000)*bcmos_timer_get_frequency(),1000000)
50
51/* task control blocks */
52extern STAILQ_HEAD(task_list, bcmos_task) task_list;
53
54/* global OS lock */
55extern bcmos_mutex bcmos_res_lock;
56
57/*
58 * Default task handler
59 */
60extern int bcmos_dft_task_handler(long data);
61
62bcmos_errno bcmos_sys_init(void)
63{
64 return BCM_ERR_OK;
65}
66
67/* Clean-up system library */
68void bcmos_sys_exit(void)
69{
70}
71
72static uint32_t bcmos_timer_get_frequency()
73{
74 static uint32_t frequency = 0;
75 if (!frequency)
76 frequency = sysClkRateGet();
77 return frequency;
78}
79
80bcmos_errno bcmos_task_create(bcmos_task *task, const bcmos_task_parm *parm)
81{
82 F_bcmos_task_handler handler;
83 void *data;
84
85 if (!task || !parm)
86 BCMOS_TRACE_RETURN(BCM_ERR_PARM, "task %p, parm %p\n", (void* )task, (void* )parm);
87 memset(task, 0, sizeof ( *task ));
88
89 if (parm->handler)
90 {
91 /* "traditional task */
92 handler = parm->handler;
93 data = (void *)parm->data;
94 }
95 else
96 {
97 bcmos_errno rc;
98 /* "integrated" task */
99 handler = bcmos_dft_task_handler;
100 data = task;
101
102 /* Initialize and lock mutex to wait on */
103 rc = bcmos_sem_create(&task->active_sem, 0, task->parm.flags, parm->name);
104 if (rc)
105 {
106 BCMOS_TRACE_ERR("Task %s: can't create active_sem. Error %s (%d)\n",
107 parm->name, bcmos_strerror(rc), rc);
108 return rc;
109 }
110 }
111
112 task->parm = *parm;
113 /* Copy name to make sure that it is not released - in case it was on the stack */
114 if (task->parm.name)
115 {
116 strncpy(task->name, task->parm.name, sizeof(task->name) - 1);
117 task->parm.name = task->name;
118 }
119 bcmos_fastlock_init(&task->active_lock, 0);
120 bcmos_mutex_lock(&bcmos_res_lock);
121 STAILQ_INSERT_TAIL(&task_list, task, list);
122 bcmos_mutex_unlock(&bcmos_res_lock);
123 task->magic = BCMOS_TASK_MAGIC;
124 task->sys_task.t = taskSpawn((char*)parm->name,
125 10 + parm->priority * 2,
126 0,
127 parm->stack_size ? parm->stack_size : BCMOS_DEFAULT_STACK_SIZE,
128 (FUNCPTR)handler,
129 (int32_t)data,
130 0,
131 0,
132 0,
133 0,
134 0,
135 0,
136 0,
137 0,
138 0);
139
140 if (task->sys_task.t == ERROR)
141 {
142 bcmos_mutex_lock(&bcmos_res_lock);
143 STAILQ_REMOVE(&task_list, task, bcmos_task, list);
144 bcmos_mutex_unlock(&bcmos_res_lock);
145 task->magic = 0;
146 if (!parm->handler)
147 {
148 bcmos_sem_destroy(&task->active_sem);
149 }
150 BCMOS_TRACE_ERR("(%s) Error: taskSpawn, errnoGet()=%d\n", __FUNCTION__, errnoGet());
151 BUG();
152 }
153
154 return BCM_ERR_OK;
155}
156
157bcmos_errno bcmos_task_destroy(bcmos_task *task)
158{
159 if (task->magic != BCMOS_TASK_MAGIC)
160 {
161 return BCM_ERR_PARM;
162 }
163 task->destroy_request = BCMOS_TRUE;
164 bcmos_mutex_lock(&bcmos_res_lock);
165 STAILQ_REMOVE(&task_list, task, bcmos_task, list);
166 bcmos_mutex_unlock(&bcmos_res_lock);
167 task->magic = BCMOS_TASK_MAGIC_DESTROYED;
168 /* The task may be waiting on semaphore. Kick it */
169 if (!task->parm.handler)
170 {
171 bcmos_sem_post(&task->active_sem);
172 }
173 if (taskDelete(task->sys_task.t) != OK)
174 {
175 BCMOS_TRACE_ERR("(%s) Error: taskDelete, errnoGet()=%d\n", __FUNCTION__, errnoGet());
176 BUG();
177 }
178
179 return BCM_ERR_OK;
180}
181
182bcmos_task *bcmos_task_current(void)
183{
184 uint32_t pt = taskIdSelf();
185 bcmos_task *t, *tmp;
186
187 STAILQ_FOREACH_SAFE(t, &task_list, list, tmp)
188 {
189 if (pt == t->sys_task.t)
190 break;
191 }
192 return t;
193}
194
195void *bcmos_alloc(uint32_t size)
196{
197 return malloc(size);
198}
199
200void bcmos_free(void *ptr)
201{
202 free(ptr);
203}
204
205inline static void bcmos_sem_mutex_destroy(uint32_t sm)
206{
207 if (semDelete((SEM_ID)sm) != OK)
208 {
209 BCMOS_TRACE_ERR("(%s) Error: semDelete, errnoGet()=%d\n", __FUNCTION__, errnoGet());
210 BUG();
211 }
212}
213
214inline static bcmos_errno bcmos_sem_mutex_wait(uint32_t sm, uint32_t timeout)
215{
216 int errno;
217 STATUS status;
218
219 timeout = ((timeout == BCMOS_WAIT_FOREVER )? WAIT_FOREVER : BCMOS_MICROSECONDS_TO_TICKS(timeout));
220 status = semTake((SEM_ID)sm, timeout);
221 if (status != OK)
222 {
223 errno = errnoGet();
224 if (errno == S_objLib_OBJ_TIMEOUT)
225 {
226 return BCM_ERR_TIMEOUT;
227 }
228 BUG();
229 return BCM_ERR_INTERNAL;
230 }
231 return BCM_ERR_OK;
232}
233
234inline static void bcmos_sem_mutex_post(uint32_t sm)
235{
236 STATUS status;
237
238 status = semGive((SEM_ID)sm);
239 if (status != OK)
240 {
241 BCMOS_TRACE_ERR("(%s) Error: semGive, status=%d\n", __FUNCTION__, status);
242 BUG();
243 }
244}
245
246bcmos_errno bcmos_sem_create(bcmos_sem *sem, uint32_t count, uint32_t flags, const char *name)
247{
248 SEM_ID semaphore;
249
250 semaphore = semCCreate(SEM_Q_PRIORITY, (SEM_B_STATE)count);
251 if (semaphore == NULL)
252 {
253 BCMOS_TRACE_ERR("(%s) Error: semCCreate, errnoGet()=%d\n", __FUNCTION__, errnoGet());
254 BUG();
255 }
256 sem->s = (uint32_t)semaphore;
257
258 return BCM_ERR_OK;
259}
260
261void bcmos_sem_destroy(bcmos_sem *sem)
262{
263 bcmos_sem_mutex_destroy(sem->s);
264}
265
266bcmos_errno bcmos_sem_wait(bcmos_sem *sem, uint32_t timeout)
267{
268 return bcmos_sem_mutex_wait(sem->s, timeout);
269}
270
271void bcmos_sem_post(bcmos_sem *sem)
272{
273 bcmos_sem_mutex_post(sem->s);
274}
275
276bcmos_errno bcmos_mutex_create(bcmos_mutex *mutex, uint32_t flags, const char *name)
277{
278 SEM_ID semaphore;
279 int options;
280
281 /* SEM_INVERSION_SAFE: Enable (by default) the prevention of priority inversion problem */
282 options = SEM_Q_PRIORITY | SEM_INVERSION_SAFE;
283
284 semaphore = semMCreate(options);
285 if (semaphore == NULL)
286 {
287 BCMOS_TRACE_ERR("(%s) Error: semCCreate, errnoGet()=%d\n", __FUNCTION__, errnoGet());
288 BUG();
289 }
290
291 mutex->m = (uint32_t)semaphore;
292
293 return BCM_ERR_OK;
294}
295
296void bcmos_mutex_destroy(bcmos_mutex *mutex)
297{
298 bcmos_sem_mutex_destroy(mutex->m);
299}
300
301void bcmos_mutex_lock(bcmos_mutex *mutex)
302{
303 bcmos_sem_mutex_wait(mutex->m, BCMOS_WAIT_FOREVER);
304}
305
306void bcmos_mutex_unlock(bcmos_mutex *mutex)
307{
308 bcmos_sem_mutex_post(mutex->m);
309}
310
311void bcmos_fastlock_init(bcmos_fastlock *lock, uint32_t flags)
312{
313}
314
315long bcmos_fastlock_lock(bcmos_fastlock *lock)
316{
317 return (long)intLock();
318}
319
320void bcmos_fastlock_unlock(bcmos_fastlock *lock, long flags)
321{
322 intUnlock(flags);
323}
324
325bcmos_errno bcmos_sys_timer_create(bcmos_sys_timer *timer, bcmos_sys_timer_handler handler, void *data)
326{
327 WDOG_ID watchdog;
328
329 if (!timer || !handler)
330 BCMOS_TRACE_RETURN(BCM_ERR_PARM, "timer %p, handler %p\n", timer, handler);
331
332 /* Call the underlying OS */
333 watchdog = wdCreate();
334 if (watchdog == NULL)
335 BCMOS_TRACE_RETURN(BCM_ERR_SYSCALL_ERR, "errno %s\n", strerror(errno));
336
337 timer->t = (uint32_t)watchdog;
338 timer->handler = handler;
339 timer->data = data;
340
341 return BCM_ERR_OK;
342}
343
344void bcmos_sys_timer_destroy(bcmos_sys_timer *timer)
345{
346 STATUS status;
347 status = wdDelete((WDOG_ID)timer->t);
348 BCMOS_TRACE_DEBUG("wdDelete: status=%d\n", status);
349}
350
351static void _bcmos_time_handler_wrapper(long data)
352{
353 bcmos_sys_timer * timer = (bcmos_sys_timer*)data ;
354 timer->handler(timer->data);
355}
356
357void bcmos_sys_timer_start(bcmos_sys_timer *timer, uint32_t delay)
358{
359 STATUS status;
360 status = wdStart((WDOG_ID)timer->t, BCMOS_MICROSECONDS_TO_TICKS(delay), (FUNCPTR)_bcmos_time_handler_wrapper, (long)timer);
361 if (status == ERROR)
362 {
363 BCMOS_TRACE_ERR("wdStart status %d\n", status);
364 BUG();
365 }
366}
367
368void bcmos_sys_timer_stop(bcmos_sys_timer *timer)
369{
370 STATUS status;
371 status = wdCancel((WDOG_ID)timer->t);
372 if (status == ERROR)
373 {
374 BCMOS_TRACE_ERR("wdCancel status=%d\n", status);
375 BUG();
376 }
377}
378
379void bcmos_usleep(uint32_t us)
380{
381 struct timespec ts;
382
383 ts.tv_sec = us / 1000000;
384 ts.tv_nsec = ( us % 1000000 ) * 1000;
385
386 nanosleep(&ts, 0);
387}
388
389uint32_t bcmos_timestamp(void)
390{
391 struct timespec ts;
392 clock_gettime(CLOCK_REALTIME, &ts);
393 return (ts.tv_sec * 1000000 + ts.tv_nsec / 1000);
394}
395
396/** Get current timestamp - 64 bit
397 * \returns the current system timestamp (us)
398 */
399uint64_t bcmos_timestamp64(void)
400{
401 struct timespec ts;
402 clock_gettime(CLOCK_REALTIME, &ts);
403 return ((uint64_t)ts.tv_sec * 1000000LL + (uint64_t)ts.tv_nsec / 1000LL);
404}
405
406/*
407 * Byte memory pool
408 */
409
410/* Memory block header */
411typedef struct bcmos_byte_memblk
412{
413 bcmos_byte_pool *pool; /** pool that owns the block */
414 uint32_t size; /** block size (bytes) including bcmos_byte_memblk header */
415#ifdef BCMOS_MEM_DEBUG
416 uint32_t magic; /** magic number */
417#define BCMOS_MEM_MAGIC_ALLOC (('m'<<24) | ('b' << 16) | ('l' << 8) | 'k')
418#define BCMOS_MEM_MAGIC_FREE (('m'<<24) | ('b' << 16) | ('l' << 8) | '~')
419#endif
420} bcmos_byte_memblk;
421
422/* Create byte memory pool */
423bcmos_errno bcmos_byte_pool_create(bcmos_byte_pool *pool, const bcmos_byte_pool_parm *parm)
424{
425 if (!pool || !parm)
426 {
427 BCMOS_TRACE_RETURN(BCM_ERR_PARM, "pool %p, parm %p\n", pool, parm);
428 }
429
430 BCM_MEMZERO_STRUCT(pool);
431 pool->parm = *parm;
432 if (!pool->parm.size)
433 {
434 BCMOS_TRACE_RETURN(BCM_ERR_PARM, "size %u\n", parm->size);
435 }
436#ifdef BCMOS_MEM_DEBUG
437 pool->magic = BCMOS_BYTE_POOL_VALID;
438#endif
439 return BCM_ERR_OK;
440}
441
442/* Destroy memory pool */
443bcmos_errno bcmos_byte_pool_destroy(bcmos_byte_pool *pool)
444{
445 if (pool->allocated)
446 {
447 BCMOS_TRACE_RETURN(BCM_ERR_STATE, "%u bytes of memory are still allocated from the pool %s\n",
448 pool->allocated, pool->parm.name);
449 }
450#ifdef BCMOS_MEM_DEBUG
451 pool->magic = BCMOS_BYTE_POOL_DELETED;
452#endif
453 return BCM_ERR_OK;
454}
455
456/* Allocate memory from memory pool */
457void *bcmos_byte_pool_alloc(bcmos_byte_pool *pool, uint32_t size)
458{
459 bcmos_byte_memblk *blk;
460 uint32_t byte_size;
461 void *ptr;
462
463#ifdef BCMOS_MEM_DEBUG
464 BUG_ON(pool->magic != BCMOS_BYTE_POOL_VALID);
465#endif
466
467 if (size + pool->allocated > pool->parm.size)
468 return NULL;
469
470 byte_size = size + sizeof(bcmos_byte_memblk);
471#ifdef BCMOS_MEM_DEBUG
472 byte_size += sizeof(uint32_t); /* block suffix */
473#endif
474 /* ToDo: Maintain LL of allocated blocks */
475 blk = (bcmos_byte_memblk *)malloc(byte_size);
476 if (!blk)
477 return NULL;
478 ptr = (void *)(blk + 1);
479 blk->size = byte_size;
480 pool->allocated += byte_size;
481 blk->pool = pool;
482#ifdef BCMOS_MEM_DEBUG
483 blk->magic = BCMOS_MEM_MAGIC_ALLOC;
484 *(uint32_t *)((long)blk + byte_size - sizeof(uint32_t)) = BCMOS_MEM_MAGIC_ALLOC;
485#endif
486
487 return ptr;
488}
489
490/* Release memory allocated using bcmos_byte_pool_alloc() */
491void bcmos_byte_pool_free(void *ptr)
492{
493 bcmos_byte_memblk *blk;
494 bcmos_byte_pool *pool;
495
496 BUG_ON(!ptr);
497 blk = (bcmos_byte_memblk *)((long)ptr - sizeof(bcmos_byte_memblk));
498 pool = blk->pool;
499#ifdef BCMOS_MEM_DEBUG
500 BUG_ON(pool->magic != BCMOS_BYTE_POOL_VALID);
501 BUG_ON(blk->magic != BCMOS_MEM_MAGIC_ALLOC);
502 BUG_ON(*(uint32_t *)((long)blk + blk->size - sizeof(uint32_t)) != BCMOS_MEM_MAGIC_ALLOC);
503 blk->magic = BCMOS_MEM_MAGIC_FREE;
504#endif
505 pool->allocated -= blk->size;
506 free(blk);
507}
508
509void _bcmos_backtrace(void)
510{
511 /*todo implement this*/
512}
513
514int ffsll(long long int i)
515{
516 int l = ffs(i & 0xFFFFFFFF);
517 int h = ffs((i >> 32) & 0xFFFFFFFF);
518
519 if (l)
520 return l;
521
522 if (h)
523 return h + 32;
524
525 return 0;
526}
527
528/* stub for int enable */
529void bcmos_int_enable(int irq)
530{
531}
532
533typedef struct bcmos_int_data
534{
535 int (*isr)(int irq, void *priv);
536 int irq;
537 void *priv;
538} bcmos_int_data;
539
540static void _bcmos_int_handler(long priv)
541{
542 bcmos_int_data *data = (bcmos_int_data *)priv;
543 data->isr(data->irq, data->priv);
544}
545
546int bcmos_int_connect(int irq, int cpu, int flags, int (*isr)(int irq, void *priv), const char *name, void *priv)
547{
548 bcmos_int_data *data = bcmos_calloc(sizeof(bcmos_int_data));
549 if (!data)
550 return (int)BCM_ERR_NOMEM;
551 data->isr = isr;
552 data->irq = irq;
553 data->priv = priv;
554 return pciIntConnect(INUM_TO_IVEC(irq), _bcmos_int_handler, (long)data);
555}
556
557/* Disconnect system interrupt */
558void bcmos_int_disconnect(int irq, void *priv)
559{
560 pciIntDisconnect(INUM_TO_IVEC(irq), _bcmos_int_handler);
561}
562
563/**************************************************************
564 * Check in-irq status *
565 * related header file: "intLib.h" *
566 * param[in] none *
567 * param[out] none *
568 * return BCMOS_TRUE (1) - in interrupt context; *
569 * BCMOS_FALSE (0) - in task context; *
570 **************************************************************/
571
572bcmos_bool is_irq_mode(void)
573{
574 return intContext();
575}
576
577// from bsp
578extern int isIntDisabled();
579/**************************************************************
580 * Check if interrupts are disabled *
581 * related header file: "mipsinc.h" *
582 * param[in] none *
583 * param[out] none *
584 * return BCMOS_TRUE (1) - Gloal interrupt disable *
585 BCMOS_FALSE (0) - Gloal interrupt enable; *
586 * comment if BSP team can provide similar function, *
587 we will call it; *
588 * Another option is share this macro used on switch product *
589 *************************************************************/
590bcmos_bool is_irq_disabled(void)
591{
592 return isIntDisabled();
593}
594
595/**************************************************************
596 * write barrier *
597 * related header file: none *
598 * param[in] none *
599 * param[out] none *
600 * return none *
601 * comment:use "sync" base on MIPS (GNU style) *
602 *************************************************************/
603
604void bcmos_barrier(void)
605{
606 #if defined(HOST_CPU_IS_MIPS) || defined(HOST_CPU_IS_PPC)
607 {__asm__ __volatile__("sync");}
608 #else
609 #error HOST CPU MUST BE MIPS OR POWERPC
610 #endif
611}
612
613/**************************************************************
614 * Allocate DMA-able memory *
615 * related header file:memPartLib.h *
616 * param[in] device Device id *
617 * param[in] size Block size (bytes) *
618 * param[out] none *
619 * returns memory block pointer(uncached memory) or NULL *
620 * comment: BSP need to allocate uncached memory pool first *
621 * if BSP team can provide such function,call it directly; *
622 * suggestion: memPartCreate()create uncached memory and *
623 * return memory ID:uncachePoolMemPartId *
624 * memPartAlloc()/memPartFree():allocate/free memory via *
625 * memory ID:uncachePoolMemPartId and size *
626 * if BSP can gurantee the Memory allocated by cacheDmaMalloc *
627 * cacheDmaFree() is noncached memory,we can call them directly*
628 *************************************************************/
629
630void *bcmos_dma_alloc(uint8_t device, uint32_t size)
631{
632 void * pBuffer;
633#ifdef NON_CACHED_MEMORY_CREATED_BY_CACHEDMAMALLOC
634 pBuffer = cacheDmaMalloc(size);
635 return (pBuffer);
636#else
637 pBuffer = (void *)memPartAlloc(uncachePoolMemPartId, size));
638 return (pBuffer);
639#endif
640}
641
642/**************************************************************
643 * Release DMA-able memory *
644 * related header file: memPartLib.h *
645 * param[in] device Device id *
646 * param[in] ptr Block pointer *
647 * param[out] none *
648 * return none *
649 * comment: see above *
650 *************************************************************/
651void bcmos_dma_free(uint8_t device, void *ptr)
652{
653#ifdef NON_CACHED_MEMORY_CREATED_BY_CACHEDMAMALLOC
654 cacheDmaFree((void *)(ptr));
655#else
656 memPartFree(uncachePoolMemPartId,ptr);
657#endif
658 return;
659}
660
661/**************************************************************
662 * Convert virtual address to physical address *
663 * related header file:for MIPS CPU archMips.h *
664 * param[in] va Virtual address *
665 * return - physical address va is mapped to *
666**************************************************************/
667unsigned long bcmos_virt_to_phys(void *va)
668{
669#ifdef HOST_CPU_IS_MIPS
670 return (unsigned long)(K0_TO_PHYS(va));
671
672#else
673 /* this is an just an example,
674 if you are not working with mips make sure you define the correct mapping for your system */
675 return (unsigned long)(va);
676#endif
677}
678
679/**************************************************************
680 * Invalidate address area in data cache. *
681 * related header file: cacheLib.h *
682 * param[in] start Address area start *
683 * param[in] size Address area size *
684 * return none *
685 **************************************************************/
686void bcmos_dcache_inv(void *start, uint32_t size)
687{
688 cacheInvalidate(DATA_CACHE,start, size);
689 return;
690}
691
692/**************************************************************
693 * Flush address area in data cache. *
694 * related header file: cacheLib.h *
695 * param[in] start Address area start *
696 * param[in] size Address area size *
697 * return none *
698**************************************************************/
699void bcmos_dcache_flush(void *start, uint32_t size)
700{
701 cacheFlush(DATA_CACHE,start, size);
702 return;
703}
704
705/**************************************************************
706 * write value to PCI memory *
707 * related header file: bcmos_common2.h *
708 * param[in] address pointer to Address *
709 * param[in] value value *
710 * return none *
711 * Comment re-use BCMOS_ENDIAN_CPU_TO_LITTLE_U32 which is from*
712 * bcmos_common2.h,by this macro,can support both big endian *
713 * host and little endian host.move PCI access functions after*
714 * bcmos_common2.h *
715 **************************************************************/
716void bcm_pci_write32(volatile uint32_t *address, uint32_t value)
717{
718#ifdef HOST_PCIE_SWAP_NEEDED
719 value = BCMOS_ENDIAN_CPU_TO_LITTLE_U32(value);
720#endif
721 *address = value;
722}
723
724/**************************************************************
725 * read value to PCI memory *
726 * related header file: bcmos_common2.h *
727 * param[in] address pointer to Address *
728 * return value *
729 * Comment see above *
730**************************************************************/
731uint32_t bcm_pci_read32(const volatile uint32_t *address)
732{
733 uint32_t value;
734 value = *address;
735#ifdef HOST_PCIE_SWAP_NEEDED
736 value = BCMOS_ENDIAN_LITTLE_TO_CPU_U32(value);
737#endif
738 return value;
739
740}
741
742