This commit is contained in:
pvvx 2017-06-21 03:00:20 +03:00
parent 34d3652711
commit 39f77eb92b
1844 changed files with 899433 additions and 7 deletions

View file

@ -0,0 +1,64 @@
/*
* Routines to access hardware
*
* Copyright (c) 2013 Realtek Semiconductor Corp.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*/
#include "osdep_service.h"
#include "device_lock.h"
//------------------------------------------------------
#define DEVICE_MUTEX_IS_INIT(device) (mutex_init & (1<<device))
#define DEVICE_MUTEX_SET_INIT(device) (mutex_init |= (1<<device))
#define DEVICE_MUTEX_CLR_INIT(device) (mutex_init &= (~(1<<device)))
static u32 mutex_init = 0;
static _mutex device_mutex[RT_DEV_LOCK_MAX];
//======================================================
static void device_mutex_init(RT_DEV_LOCK_E device)
{
if(!DEVICE_MUTEX_IS_INIT(device)){
_lock lock;
_irqL irqL;
rtw_enter_critical(&lock, &irqL);
if(!DEVICE_MUTEX_IS_INIT(device)){
rtw_mutex_init(&device_mutex[device]);
DEVICE_MUTEX_SET_INIT(device);
}
rtw_exit_critical(&lock, &irqL);
}
}
//======================================================
static void device_mutex_free(RT_DEV_LOCK_E device)
{
if(DEVICE_MUTEX_IS_INIT(device)){
_lock lock;
_irqL irqL;
rtw_enter_critical(&lock, &irqL);
if(!DEVICE_MUTEX_IS_INIT(device)){
rtw_mutex_free(&device_mutex[device]);
DEVICE_MUTEX_CLR_INIT(device);
}
rtw_exit_critical(&lock, &irqL);
}
}
//======================================================
void device_mutex_lock(RT_DEV_LOCK_E device)
{
device_mutex_init(device);
while(rtw_mutex_get_timeout(&device_mutex[device], 10000)<0)
printf("device lock timeout: %d\n", device);
}
//======================================================
void device_mutex_unlock(RT_DEV_LOCK_E device)
{
device_mutex_init(device);
rtw_mutex_put(&device_mutex[device]);
}

View file

@ -0,0 +1,25 @@
/*
* Routines to access hardware
*
* Copyright (c) 2013 Realtek Semiconductor Corp.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*/
#ifndef _DEVICE_LOCK_H_
#define _DEVICE_LOCK_H_
typedef enum _RT_DEV_LOCK_E
{
RT_DEV_LOCK_EFUSE = 0,
RT_DEV_LOCK_FLASH = 1,
RT_DEV_LOCK_CRYPTO = 2,
RT_DEV_LOCK_PTA = 3,
RT_DEV_LOCK_MAX = 4
}RT_DEV_LOCK_E;
void device_mutex_lock(RT_DEV_LOCK_E device);
void device_mutex_unlock(RT_DEV_LOCK_E device);
#endif //_DEVICE_LOCK_H_

View file

@ -0,0 +1,343 @@
/******************************************************************************
*
* Name: sys-support.h - System type support for Linux
* $Revision: 1.1.1.1 $
*
*****************************************************************************/
#ifndef __OS_SUPPORT_H__
#define __OS_SUPPORT_H__
#include <FreeRTOS.h>
#include <basic_types.h>
#include "os_support.h"
//#include "diag.h"
#if 0
#define __init
#define __exit
#define __devinit
#define __devexit
#endif
#define RTL_HZ 100
#define SemaInit(sem, value) vSemaphoreCreateBinary(sem)
#define SemaPost(sem) xSemaphoreGive(sem)
#define SemaWait(sem, block_time) xSemaphoreTake(sem, block_time)
//#define printk DiagPrintf
#define SpinLockInit(lock) do { } while (0)
#define SpinLock(x) do { } while (0)
#define SpinUnlock(x) do { } while (0)
#define SpinLockBh(x) do { } while (0)
#define SpinUnlockBh(x) do { } while (0)
#ifdef PLATFORM_FREERTOS
#define RestoreFlags() portEXIT_CRITICAL()
#define SaveAndCli() portENTER_CRITICAL()
#define SpinLockIrqSave(lock, flags) SaveAndCli()
#define SpinUnlockIrqRestore(l, f) RestoreFlags()
#else
#define RestoreFlags(x) portENABLE_INTERRUPTS()
#define SaveAndCli(x) portDISABLE_INTERRUPTS()
#define SpinLockIrqSave(lock, flags) SaveAndCli(flags)
#define SpinUnlockIrqRestore(l, f) RestoreFlags(f)
#endif
//#define RtlKmalloc(size, flag) pvPortMallocAligned(size, 0)
#define RtlKmalloc(size, flag) pvPortMalloc(size)
#define RtlKfree(pv) vPortFreeAligned(pv)
#ifdef CONFIG_TIMER_MODULE
#define __Delay(t) HalDelayUs(t)
#else
static __inline__ u32 __Delay(u32 us)
{
DBG_8195A("No Delay: please enable hardware Timer\n");
}
#endif
#define Mdelay(t) __Delay(t*1000)
#define Udelay(t) __Delay(t)
#define ASSERT(_bool_) do { } while (0)
//#define panic_printk DiagPrintf
//#define sprintf DiagPrintf
//#define diag_sprintf DiagPrintf
//1TODO: Need check again; the below just for compile ok ; chris
/*
* ATOMIC_READ - read atomic variable
* @v: pointer of type atomic_t
*
* Atomically reads the value of @v. Note that the guaranteed
* useful range of an atomic_t is only 24 bits.
*/
//#define AtomicRead(v) ((*v))
static __inline__ u32
AtomicRead(
IN atomic_t * v
)
{
#ifdef PLATFORM_FREERTOS
u32 Temp;
SaveAndCli();
Temp = v->counter;
RestoreFlags();
return Temp;
#else
u32 Temp, Flags;
SaveAndCli(Flags);
Temp = v->counter;
RestoreFlags(Flags);
return Temp;
#endif
}
/*
* ATOMIC_SET - set atomic variable
* @v: pointer of type atomic_t
* @i: required value
*
* Atomically sets the value of @v to @i. Note that the guaranteed
* useful range of an atomic_t is only 24 bits.
*/
//#define AtomicSet(v,i) ((v)->counter = (i))
static __inline__ VOID
AtomicSet(
IN u32 i,
IN atomic_t * v
)
{
#ifdef PLATFORM_FREERTOS
SaveAndCli();
v->counter = i;
RestoreFlags();
#else
u32 Flags;
SaveAndCli(Flags);
v->counter = i;
RestoreFlags(Flags);
#endif
}
/*
* The MIPS I implementation is only atomic with respect to
* interrupts. R3000 based multiprocessor machines are rare anyway ...
*
* AtomicAdd - add integer to atomic variable
* @i: integer value to add
* @v: pointer of type atomic_t
*
* Atomically adds @i to @v. Note that the guaranteed useful range
* of an atomic_t is only 24 bits.
*/
static __inline__ VOID
AtomicAdd(
IN u32 i,
IN atomic_t * v
)
{
#ifdef PLATFORM_FREERTOS
SaveAndCli();
v->counter += i;
RestoreFlags();
#else
u32 Flags;
SaveAndCli(Flags);
v->counter += i;
RestoreFlags(Flags);
#endif
}
/*
* AtomicSub - subtract the atomic variable
* @i: integer value to subtract
* @v: pointer of type atomic_t
*
* Atomically subtracts @i from @v. Note that the guaranteed
* useful range of an atomic_t is only 24 bits.
*/
static __inline__ void
AtomicSub(
IN u32 i,
IN atomic_t * v
)
{
#ifdef PLATFORM_FREERTOS
SaveAndCli();
v->counter -= i;
RestoreFlags();
#else
u32 Flags;
SaveAndCli(Flags);
v->counter -= i;
RestoreFlags(Flags);
#endif
}
static __inline__ u32
AtomicAddReturn(
IN u32 i,
IN atomic_t * v
)
{
#ifdef PLATFORM_FREERTOS
u32 Temp;
SaveAndCli();
Temp = v->counter;
Temp += i;
v->counter = Temp;
RestoreFlags();
return Temp;
#else
u32 Temp, Flags;
SaveAndCli(Flags);
Temp = v->counter;
Temp += i;
v->counter = Temp;
RestoreFlags(Flags);
return Temp;
#endif
}
static __inline__ u32
AtomicSubReturn(
IN u32 i,
IN atomic_t * v
)
{
#ifdef PLATFORM_FREERTOS
u32 Temp;
SaveAndCli();
Temp = v->counter;
Temp -= i;
v->counter = Temp;
RestoreFlags();
return Temp;
#else
u32 Temp, Flags;
SaveAndCli(Flags);
Temp = v->counter;
Temp -= i;
v->counter = Temp;
RestoreFlags(Flags);
return Temp;
#endif
}
/*
* ATOMIC_INC - increment atomic variable
* @v: pointer of type atomic_t
*
* Atomically increments @v by 1. Note that the guaranteed
* useful range of an atomic_t is only 24 bits.
*/
#define AtomicInc(v) AtomicAdd(1,(v))
#define AtomicIncReturn(v) AtomicAddReturn(1,(v))
/*
* ATOMIC_DEC - decrement and test
* @v: pointer of type atomic_t
*
* Atomically decrements @v by 1. Note that the guaranteed
* useful range of an atomic_t is only 24 bits.
*/
#define AtomicDec(v) AtomicSub(1,(v))
#define AtomicDecReturn(v) AtomicSubReturn(1,(v))
/*
* ATOMIC_DEC_AND_TEST - decrement by 1 and test
* @v: pointer of type atomic_t
*
* Atomically decrements @v by 1 and
* returns true if the result is 0, or false for all other
* cases. Note that the guaranteed
* useful range of an atomic_t is only 24 bits.
*/
#define AtomicDecAndTest(v) (AtomicSubReturn(1, (v)) == 0)
/* Not needed on 64bit architectures */
static __inline__ u32
__Div64_32(
IN __uint64_t *n,
IN u32 base
)
{
__uint64_t rem = *n;
__uint64_t b = base;
__uint64_t res, d = 1;
u32 high = rem >> 32;
/* Reduce the thing a bit first */
res = 0;
if (high >= base) {
high /= base;
res = (__uint64_t) high << 32;
rem -= (__uint64_t) (high*base) << 32;
}
while ((__int64_t)b > 0 && b < rem) {
b = b+b;
d = d+d;
}
do {
if (rem >= b) {
rem -= b;
res += d;
}
b >>= 1;
d >>= 1;
} while (d);
*n = res;
return rem;
}
#define DO_DIV(n,base) ({ \
unsigned int __base = (base); \
unsigned int __rem; \
(void)(((typeof((n)) *)0) == ((__uint64_t *)0)); \
if (((n) >> 32) == 0) { \
__rem = (unsigned int)(n) % __base; \
(n) = (unsigned int)(n) / __base; \
} else \
__rem = __Div64_32(&(n), __base); \
__rem; \
})
#endif /* __SYS_SUPPORT_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,74 @@
#ifndef STRUCT_HEAP_H
#define STRUCT_HEAP_H
//#include <stdio.h>
#include <stdint.h>
#include <osdep_service.h>
#define TCM_HEAP_SIZE (42*1024) // min size
// MAX_BACKUP_SIZE in hal_soc_ps_monitor = 129*4, 0x1FFFFFFC - 129*4 = 0x1FFFFD18 !
#define tcm_heap_size ((0x20000000 - (u32)&tcm_heap - 768 + sizeof(heap_buf_t) - 1)/sizeof(heap_buf_t))*sizeof(heap_buf_t)
/* NOTE: struct size must be a 2's power! */
typedef struct _MemChunk
{
struct _MemChunk *next;
int size;
} MemChunk;
typedef MemChunk heap_buf_t;
/// A heap
typedef struct Heap
{
struct _MemChunk *FreeList; ///< Head of the free list
} Heap;
/**
* Utility macro to allocate a heap of size \a size.
*
* \param name Variable name for the heap.
* \param size Heap size in bytes.
*/
#define HEAP_DEFINE_BUF(name, size) \
heap_buf_t name[((size) + sizeof(heap_buf_t) - 1) / sizeof(heap_buf_t)]
/// Initialize \a heap within the buffer pointed by \a memory which is of \a size bytes
void tcm_heap_init(void);
/// Allocate a chunk of memory of \a size bytes from the heap
// void *tcm_heap_allocmem(int size);
/// Free a chunk of memory of \a size bytes from the heap
// void tcm_heap_freemem(void *mem, int size);
int tcm_heap_freeSpace(void);
#define HNEW(heap, type) \
(type*)tcm_heap_allocmem(heap, sizeof(type))
#define HNEWVEC(heap, type, nelem) \
(type*)tcm_heap_allocmem(heap, sizeof(type) * (nelem))
#define HDELETE(heap, type, mem) \
tcm_heap_freemem(heap, mem, sizeof(type))
#define HDELETEVEC(heap, type, nelem, mem) \
tcm_heap_freemem(heap, mem, sizeof(type) * (nelem))
extern HEAP_DEFINE_BUF(tcm_heap, TCM_HEAP_SIZE);
/**
* \name Compatibility interface with C standard library
* \{
*/
void *tcm_heap_malloc(int size);
void *tcm_heap_calloc(int size);
void tcm_heap_free(void * mem);
void tcm_heap_dump(void);
/** \} */
#endif /* STRUCT_HEAP_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,347 @@
//#include <autoconf.h>
#include "tcm_heap.h"
#include <string.h> // memset()
#include <osdep_service.h>
//#define _DEBUG
#if CONFIG_USE_TCM_HEAP
#define FREE_FILL_CODE 0xDEAD
#define ALLOC_FILL_CODE 0xBEEF
#define ROUND_UP2(x, pad) (((x) + ((pad) - 1)) & ~((pad) - 1))
//static
struct Heap g_tcm_heap;
#if defined (__ICCARM__)
#pragma location=".tcm.heap"
#else
__attribute__((section(".tcm.heap")))
#endif
HEAP_DEFINE_BUF(tcm_heap, TCM_HEAP_SIZE);
//unsigned char tcm_heap[TCM_HEAP_SIZE];
static int g_heap_inited = 0;
static _lock tcm_lock;
extern void vPortSetExtFree( void (*free)( void *p ), uint32_t upper, uint32_t lower );
void tcm_heap_init(void)
{
//#ifdef _DEBUG
//memset(memory, FREE_FILL_CODE, size);
//#endif
//ASSERT2(((int)memory % alignof(heap_buf_t)) == 0,
//"memory buffer is unaligned, please use the HEAP_DEFINE_BUF() macro to declare heap buffers!\n");
/* Initialize heap with a single big chunk */
g_tcm_heap.FreeList = (MemChunk *)&tcm_heap;
g_tcm_heap.FreeList->next = NULL;
// g_tcm_heap.FreeList->size = sizeof(tcm_heap);
g_tcm_heap.FreeList->size = tcm_heap_size; // ((0x20000000 - (u32)&tcm_heap - 520 + sizeof(heap_buf_t) - 1)/sizeof(heap_buf_t))*sizeof(heap_buf_t);
g_heap_inited = 1;
rtw_spinlock_init(&tcm_lock);
#if PLATFORM_FREERTOS
// let RTOS know how to free memory if using as task stack
vPortSetExtFree(tcm_heap_free, 0x20000000, 0x1fff0000);
#endif
}
void tcm_heap_dump(void)
{
#if CONFIG_DEBUG_LOG > 1
if(!g_heap_inited) tcm_heap_init();
MemChunk *chunk, *prev;
struct Heap* h = &g_tcm_heap;
int count = 0;
int free_mem;
DBG_8195A("TCM Free Heap Memory List:\n");
for (chunk = h->FreeList; chunk; chunk = chunk->next) {
DBG_8195A(" [%d]=%p, %d\n", ++count, chunk, chunk->size);
}
/*
for (prev = (MemChunk *)&h->FreeList, chunk = h->FreeList;
chunk;
prev = chunk, chunk = chunk->next)
{
DBG_8195A(" [%d]=%p, %d\n", ++count, chunk, chunk->size);
}
*/
#endif
}
static void *tcm_heap_allocmem(int size)
{
MemChunk *chunk, *prev;
struct Heap* h = &g_tcm_heap;
_irqL irqL;
rtw_enter_critical(&tcm_lock, &irqL);
if(!g_heap_inited) tcm_heap_init();
/* Round size up to the allocation granularity */
size = ROUND_UP2(size, sizeof(MemChunk));
/* Handle allocations of 0 bytes */
if (!size)
size = sizeof(MemChunk);
/* Walk on the free list looking for any chunk big enough to
* fit the requested block size.
*/
for (prev = (MemChunk *)&h->FreeList, chunk = h->FreeList;
chunk;
prev = chunk, chunk = chunk->next)
{
if (chunk->size >= size)
{
if (chunk->size == size)
{
/* Just remove this chunk from the free list */
prev->next = chunk->next;
}
else
{
/* Allocate from the END of an existing chunk */
chunk->size -= size;
chunk = (MemChunk *)((uint8_t *)chunk + chunk->size);
}
#ifdef _DEBUG
memset(chunk, ALLOC_FILL_CODE, size);
#endif
rtw_exit_critical(&tcm_lock, &irqL);
DBG_TCM_HEAP_INFO("tcm_alloc:%p[%d]\n", chunk, size);
return (void *)chunk;
}
}
rtw_exit_critical(&tcm_lock, &irqL);
DBG_TCM_HEAP_WARN("tcm_alloc(%d) - freeSpace(%d)!\n", size, tcm_heap_freeSpace());
return NULL; /* fail */
}
static void tcm_heap_freemem(void *mem, int size)
{
MemChunk *prev;
//ASSERT(mem);
struct Heap* h = &g_tcm_heap;
_irqL irqL;
rtw_enter_critical(&tcm_lock, &irqL);
// if(!g_heap_inited) tcm_heap_init();
#ifdef _DEBUG
memset(mem, FREE_FILL_CODE, size);
#endif
/* Round size up to the allocation granularity */
size = ROUND_UP2(size, sizeof(MemChunk));
/* Handle allocations of 0 bytes */
if (!size)
size = sizeof(MemChunk);
/* Special cases: first chunk in the free list or memory completely full */
//ASSERT((uint8_t*)mem != (uint8_t*)h->FreeList);
if (((uint8_t *)mem) < ((uint8_t *)h->FreeList) || !h->FreeList)
{
/* Insert memory block before the current free list head */
prev = (MemChunk *)mem;
prev->next = h->FreeList;
prev->size = size;
h->FreeList = prev;
}
else /* Normal case: not the first chunk in the free list */
{
/*
* Walk on the free list. Stop at the insertion point (when mem
* is between prev and prev->next)
*/
prev = h->FreeList;
while (prev->next < (MemChunk *)mem && prev->next)
prev = prev->next;
/* Make sure mem is not *within* prev */
//ASSERT((uint8_t*)mem >= (uint8_t*)prev + prev->size);
/* Should it be merged with previous block? */
if (((uint8_t *)prev) + prev->size == ((uint8_t *)mem))
{
/* Yes */
prev->size += size;
}
else /* not merged with previous chunk */
{
MemChunk *curr = (MemChunk*)mem;
/* insert it after the previous node
* and move the 'prev' pointer forward
* for the following operations
*/
curr->next = prev->next;
curr->size = size;
prev->next = curr;
/* Adjust for the following test */
prev = curr;
}
}
/* Also merge with next chunk? */
if (((uint8_t *)prev) + prev->size == ((uint8_t *)prev->next))
{
prev->size += prev->next->size;
prev->next = prev->next->next;
/* There should be only one merge opportunity, becuase we always merge on free */
//ASSERT((uint8_t*)prev + prev->size != (uint8_t*)prev->next);
}
rtw_exit_critical(&tcm_lock, &irqL);
DBG_TCM_HEAP_INFO("tcm_free:%p[%d]\n", mem, size);
}
int tcm_heap_freeSpace(void)
{
int free_mem = 0;
struct Heap* h = &g_tcm_heap;
_irqL irqL;
MemChunk *chunk;
rtw_enter_critical(&tcm_lock, &irqL);
if(!g_heap_inited) tcm_heap_init();
for (chunk = h->FreeList; chunk; chunk = chunk->next)
free_mem += chunk->size;
rtw_exit_critical(&tcm_lock, &irqL);
return free_mem;
}
/**
* Standard malloc interface
*/
void *tcm_heap_malloc(int size)
{
int *mem;
size += sizeof(int);
if ((mem = (int*)tcm_heap_allocmem(size))){
*mem++ = size;
}
return mem;
}
/**
* Standard calloc interface
*/
void *tcm_heap_calloc(int size)
{
void *mem;
if ((mem = tcm_heap_malloc(size)))
memset(mem, 0, size);
return mem;
}
/**
* Free a block of memory, determining its size automatically.
*
* \param h Heap from which the block was allocated.
* \param mem Pointer to a block of memory previously allocated with
* either heap_malloc() or heap_calloc().
*
* \note If \a mem is a NULL pointer, no operation is performed.
*
* \note Freeing the same memory block twice has undefined behavior.
*
* \note This function works like the ANSI C free().
*/
void tcm_heap_free(void *mem)
{
int *_mem = (int *)mem;
if (_mem)
{
--_mem;
tcm_heap_freemem(_mem, *_mem);
}
}
#if 0
//----------- Tests -------------
static void alloc_test(int size, int test_len)
{
//Simple test
uint8_t *a[100];
int i, j;
for (i = 0; i < test_len; i++)
{
a[i] = tcm_heap_allocmem(size);
//ASSERT(a[i]);
for (j = 0; j < size; j++)
a[i][j] = i;
}
//ASSERT(heap_freeSpace(&h) == HEAP_SIZE - test_len * ROUND_UP2(size, sizeof(MemChunk)));
for (i = 0; i < test_len; i++)
{
for (j = 0; j < size; j++)
{
DBG_8195A("a[%d][%d] = %d\n", i, j, a[i][j]);
//ASSERT(a[i][j] == i);
}
tcm_heap_freemem(a[i], size);
}
//ASSERT(heap_freeSpace(&h) == HEAP_SIZE);
}
#define ALLOC_SIZE 256
#define ALLOC_SIZE2 1024
#define TEST_LEN 20
#define TEST_LEN2 10
#define HEAP_SIZE 59*1024
int tcm_heap_testRun(void)
{
alloc_test(ALLOC_SIZE, TEST_LEN);
alloc_test(ALLOC_SIZE2, TEST_LEN2);
/* Try to allocate the whole heap */
uint8_t *b = tcm_heap_allocmem(HEAP_SIZE);
int i, j;
//ASSERT(b);
//ASSERT(heap_freeSpace(&h) == 0);
//ASSERT(!heap_allocmem(&h, HEAP_SIZE));
for (j = 0; j < HEAP_SIZE; j++)
b[j] = j;
for (j = 0; j < HEAP_SIZE; j++)
{
DBG_8195A("b[%d] = %d\n", j, j);
//ASSERT(b[j] == (j & 0xff));
}
tcm_heap_freemem(b, HEAP_SIZE);
//ASSERT(heap_freeSpace(&h) == HEAP_SIZE);
return 0;
}
#endif // tests
#endif