diff options
Diffstat (limited to 'drivers/staging/nmf-cm/cm/engine/utils/src')
-rw-r--r-- | drivers/staging/nmf-cm/cm/engine/utils/src/convert.c | 20 | ||||
-rw-r--r-- | drivers/staging/nmf-cm/cm/engine/utils/src/mem.c | 27 | ||||
-rw-r--r-- | drivers/staging/nmf-cm/cm/engine/utils/src/string.c | 231 | ||||
-rw-r--r-- | drivers/staging/nmf-cm/cm/engine/utils/src/swap.c | 156 | ||||
-rw-r--r-- | drivers/staging/nmf-cm/cm/engine/utils/src/table.c | 155 |
5 files changed, 589 insertions, 0 deletions
diff --git a/drivers/staging/nmf-cm/cm/engine/utils/src/convert.c b/drivers/staging/nmf-cm/cm/engine/utils/src/convert.c new file mode 100644 index 00000000000..ad6e097bfe6 --- /dev/null +++ b/drivers/staging/nmf-cm/cm/engine/utils/src/convert.c @@ -0,0 +1,20 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * Author: Jean-Philippe FASSINO <jean-philippe.fassino@stericsson.com> for ST-Ericsson. + * License terms: GNU General Public License (GPL) version 2. + */ +/* + * + */ +#include <cm/engine/utils/inc/convert.h> + +const char* dspNames[NB_CORE_IDS] = { + "ARM", + "SVA", + "SIA" +}; + + +const char* cm_getDspName(t_nmf_core_id dsp) { + return dspNames[dsp]; +} diff --git a/drivers/staging/nmf-cm/cm/engine/utils/src/mem.c b/drivers/staging/nmf-cm/cm/engine/utils/src/mem.c new file mode 100644 index 00000000000..130a044bbf8 --- /dev/null +++ b/drivers/staging/nmf-cm/cm/engine/utils/src/mem.c @@ -0,0 +1,27 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * Author: Jean-Philippe FASSINO <jean-philippe.fassino@stericsson.com> for ST-Ericsson. + * License terms: GNU General Public License (GPL) version 2. + */ +/* + * + */ +#include <cm/engine/utils/inc/mem.h> + + +/* + * Methods + */ +void cm_MemCopy(void* dest, const void *src, int count) { + char *tmp = (char *) dest, *s = (char *) src; + + while (count--) + *tmp++ = *s++; +} + +void cm_MemSet(void *str, int c, int count) { + char *tmp = (char *)str; + + while (count--) + *tmp++ = c; +} diff --git a/drivers/staging/nmf-cm/cm/engine/utils/src/string.c b/drivers/staging/nmf-cm/cm/engine/utils/src/string.c new file mode 100644 index 00000000000..89058d5825a --- /dev/null +++ b/drivers/staging/nmf-cm/cm/engine/utils/src/string.c @@ -0,0 +1,231 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * Author: Jean-Philippe FASSINO <jean-philippe.fassino@stericsson.com> for ST-Ericsson. + * License terms: GNU General Public License (GPL) version 2. + */ +/* + * + * Shared string manipulation. + * TODO This is a list today, must be a hash later !!!!! + */ +#include <cm/engine/utils/inc/string.h> +#include <cm/engine/trace/inc/trace.h> + +#include <cm/engine/memory/inc/memory.h> +#include <cm/engine/os_adaptation_layer/inc/os_adaptation_layer.h> + +#undef NHASH +#define NHASH 257 //Use a prime number! +#define MULT 17 + +/* + * Data + */ +struct t_linkedstring +{ + struct t_linkedstring *next; + int referencer; + char string[1]; +}; + +static struct t_linkedstring *list[NHASH]; + +#undef myoffsetof +#define myoffsetof(st, m) \ + ((int) ( (char *)&((st *)(0))->m - (char *)0 )) + +unsigned int hash(const char *str) +{ + unsigned int h = 0; + for(; *str; str++) + h = MULT * h + *str; + return h % NHASH; +} +/* + * Methods + */ +PRIVATE struct t_linkedstring *lookupString( + const char* str, + struct t_linkedstring *first) +{ + while(first != 0) + { + if(cm_StringCompare(str, first->string, MAX_INTERNAL_STRING_LENGTH) == 0) + break; + first = first->next; + } + + return first; +} + +t_dup_char cm_StringGet(const char* str) +{ + struct t_linkedstring *entry; + + entry = lookupString(str, list[hash(str)]); + CM_ASSERT(entry != 0); + + return (t_dup_char)entry->string; +} + +t_dup_char cm_StringReference(t_dup_char str) +{ + struct t_linkedstring* entry = (struct t_linkedstring*)((t_uint32)str - myoffsetof(struct t_linkedstring, string)); + + // One more referencer + entry->referencer++; + + return (t_dup_char)entry->string; +} + +t_dup_char cm_StringDuplicate(const char* str) +{ + struct t_linkedstring *entry; + unsigned int h; + + h = hash(str); + entry = lookupString(str, list[h]); + if(entry != 0) + { + // One more referencer + entry->referencer++; + } + else + { + // Allocate new entry + entry = (struct t_linkedstring *)OSAL_Alloc(sizeof(struct t_linkedstring)-1 + cm_StringLength(str, MAX_INTERNAL_STRING_LENGTH)+1); + if(entry == NULL) + return NULL; + + entry->referencer = 1; + cm_StringCopy(entry->string, str, MAX_INTERNAL_STRING_LENGTH); + + // Link it in list + entry->next = list[h]; + list[h] = entry; + } + + return (t_dup_char)entry->string; +} + +void cm_StringRelease(t_dup_char str) +{ + if(str != NULL) + { + struct t_linkedstring* entry = (struct t_linkedstring*)((t_uint32)str - myoffsetof(struct t_linkedstring, string)); + + // One less referencer + entry->referencer--; + + if(entry->referencer == 0) + { + int h = hash(entry->string); + + if(list[h] == entry) // This first first one + { + list[h] = entry->next; + } + else + { + struct t_linkedstring *tmp = list[h]; + + // Here we assume that entry is in the list + while(/*tmp != NULL && */tmp->next != entry) + tmp = tmp->next; + + tmp->next = entry->next; + } + OSAL_Free(entry); + } + } +} + +#if 0 +void checkString() +{ + struct t_linkedstring *tmp = list; + + while(tmp != 0) + { + printf(" stay %s %d\n", tmp->string, tmp->referencer); + tmp = tmp->next; + } +} +#endif + +/* + * LibC method + */ +void cm_StringCopy(char* dest, const char *src, int count) +{ + while (count-- && (*dest++ = *src++) != '\0') + /* nothing */ + ; +} +#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080) + +int cm_StringCompare(const char* str1, const char* str2, int count) +{ + /* If s1 and s2 are word-aligned, compare them a word at a time. */ + if ((((int)str1 & 3) | ((int)str2 & 3)) == 0) + { + unsigned int *a1 = (unsigned int*)str1; + unsigned int *a2 = (unsigned int*)str2; + + while (count >= sizeof (unsigned int) && *a1 == *a2) + { + count -= sizeof (unsigned int); + + /* If we've run out of bytes or hit a null, return zero since we already know *a1 == *a2. */ + if (count == 0 || DETECTNULL (*a1)) + return 0; + + a1++; + a2++; + } + + /* A difference was detected in last few bytes of s1, so search bytewise */ + str1 = (char*)a1; + str2 = (char*)a2; + } + + while (count-- > 0 && *str1 == *str2) + { + /* If we've run out of bytes or hit a null, return zero + since we already know *s1 == *s2. */ + if (count == 0 || *str1 == '\0') + return 0; + str1++; + str2++; + } + + return (*(unsigned char *) str1) - (*(unsigned char *) str2); +} + +int cm_StringLength(const char * str, int count) +{ + const char *sc; + + for (sc = str; count-- && *sc != '\0'; ++sc) + /* nothing */ + ; + return sc - str; +} + +void cm_StringConcatenate(char* dest, const char* src, int count) +{ + while ((*dest) != '\0') + { + dest++; + count--; + } + cm_StringCopy(dest, src, count); +} + +char* cm_StringSearch(const char* str, int c) +{ + for(; *str != (char) c; ++str) + if (*str == '\0') + return 0; + return (char *) str; +} diff --git a/drivers/staging/nmf-cm/cm/engine/utils/src/swap.c b/drivers/staging/nmf-cm/cm/engine/utils/src/swap.c new file mode 100644 index 00000000000..e3e2d536144 --- /dev/null +++ b/drivers/staging/nmf-cm/cm/engine/utils/src/swap.c @@ -0,0 +1,156 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * Author: Jean-Philippe FASSINO <jean-philippe.fassino@stericsson.com> for ST-Ericsson. + * License terms: GNU General Public License (GPL) version 2. + */ +/* + * + */ +#include <cm/engine/utils/inc/swap.h> + + +/* + * Methods + */ +t_uint16 swap16(t_uint16 x) +{ + return ((x >> 8) | + ((x << 8) & 0xff00U)); +} + +#ifdef LINUX + +#if defined(__STN_8815) /* __STN_8815 -> ARMv5*/ +t_uint32 swap32(t_uint32 x) +{ + asm volatile ( + "EOR r1, r0, r0, ROR #16 \n\t" + "BIC r1, r1, #0xFF0000 \n\t" + "MOV r0, r0, ROR #8 \n\t" + "EOR r0, r0, r1, LSR #8" + : : : "r3" ); + + return x; +} + +t_uint64 swap64(t_uint64 x) +{ + asm volatile ( + "MOV r2, r1 \n\t" + " \n\t" + "EOR r3, r0, r0, ROR #16 \n\t" + "BIC r3, r3, #0xFF0000 \n\t" + "MOV r0, r0, ROR #8 \n\t" + "EOR r1, r0, r3, LSR #8 \n\t" + " \n\t" + "EOR r3, r2, r2, ROR #16 \n\t" + "BIC r3, r3, #0xFF0000 \n\t" + "MOV r2, r2, ROR #8 \n\t" + "EOR r0, r2, r3, LSR #8" + : : : "r3", "r2" ); + + return x; +} +#else /* -> ARMv6 or later */ + +t_uint32 swap32(t_uint32 x) +{ + asm volatile ( + "REV %0, %0" + : "+r"(x) : ); + + return x; +} + +t_uint64 swap64(t_uint64 x) +{ + asm volatile ( + "REV r2, %Q0 \n\t" + "REV %Q0, %R0 \n\t" + "MOV %R0, r2" + : "+&r" (x) : : "r2" ); + + return x; +} + +#endif + +#else /* Symbian, Think -> We assume ARMCC */ + +#if defined(__thumb__) + +t_uint32 swap32(t_uint32 x) +{ + return ((x >> 24) | + ((x >> 8) & 0xff00U) | + ((x << 8) & 0xff0000U) | + ((x << 24) & 0xff000000U)); +} + +t_uint64 swap64(t_uint64 x) +{ + return ((x >> 56) | + ((x >> 40) & 0xff00UL) | + ((x >> 24) & 0xff0000UL) | + ((x >> 8) & 0xff000000UL) | + ((x << 8) & 0xff00000000ULL) | + ((x << 24) & 0xff0000000000ULL) | + ((x << 40) & 0xff000000000000ULL) | + ((x << 56))); +} + +#elif (__TARGET_ARCH_ARM < 6) + +__asm t_uint32 swap32(t_uint32 x) +{ + EOR r1, r0, r0, ROR #16 + BIC r1, r1, #0xFF0000 + MOV r0, r0, ROR #8 + EOR r0, r0, r1, LSR #8 + + BX lr +} + +__asm t_uint64 swap64(t_uint64 x) +{ + MOV r2, r1 + + EOR r3, r0, r0, ROR #16 // Swap low (r0) and store it in high (r1) + BIC r3, r3, #0xFF0000 + MOV r0, r0, ROR #8 + EOR r1, r0, r3, LSR #8 + + EOR r3, r2, r2, ROR #16 // Swap high (r2 = ex r1) and store it in low (r0) + BIC r3, r3, #0xFF0000 + MOV r2, r2, ROR #8 + EOR r0, r2, r3, LSR #8 + + BX lr +} + +#else /* -> ARMv6 or later */ + +__asm t_uint32 swap32(t_uint32 x) +{ + REV r0, r0 + + BX lr +} + +__asm t_uint64 swap64(t_uint64 x) +{ + REV r2, r0 + REV r0, r1 + MOV r1, r2 + + BX lr +} + +#endif + +#endif + +t_uint32 noswap32(t_uint32 x) { + return x; +} + diff --git a/drivers/staging/nmf-cm/cm/engine/utils/src/table.c b/drivers/staging/nmf-cm/cm/engine/utils/src/table.c new file mode 100644 index 00000000000..708396a01b2 --- /dev/null +++ b/drivers/staging/nmf-cm/cm/engine/utils/src/table.c @@ -0,0 +1,155 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * Author: Jean-Philippe FASSINO <jean-philippe.fassino@stericsson.com> for ST-Ericsson. + * License terms: GNU General Public License (GPL) version 2. + */ +/* + * + */ +#include <cm/engine/os_adaptation_layer/inc/os_adaptation_layer.h> +#include <cm/engine/trace/inc/trace.h> +#include <cm/engine/utils/inc/mem.h> +#include <cm/engine/utils/inc/table.h> + +/* + * Methods + */ +t_cm_error cm_initTable(t_nmf_table* table) +{ + table->idxMax = TABLE_DEF_SIZE / sizeof(table->entries); + + table->entries = OSAL_Alloc_Zero(table->idxMax*sizeof(table->entries)); + + if (table->entries == NULL) { + table->idxMax = 0; + return CM_NO_MORE_MEMORY; + } + + return CM_OK; +} + +void cm_destroyTable(t_nmf_table* table) +{ + if (table->idxNb) { + ERROR("Attempt to free non-empty table !!!\n", 0, 0, 0, 0, 0, 0); + return; + } + OSAL_Free(table->entries); + table->idxMax = 0; +} + +static t_cm_error cm_increaseTable(t_nmf_table* table) +{ + t_uint32 new_max; + void *mem; + + if (table->idxMax == INDEX_MASK) { + ERROR("CM_NO_MORE_MEMORY: Maximum table entries reached\n", 0, 0, 0, 0, 0, 0); + return CM_NO_MORE_MEMORY; + } + + new_max = table->idxMax + + TABLE_DEF_SIZE / sizeof(table->entries); + + if (new_max > INDEX_MAX) + new_max = INDEX_MAX; + + mem = OSAL_Alloc(new_max * sizeof(table->entries)); + + if (mem == NULL) { + ERROR("CM_NO_MORE_MEMORY: Unable to allocate memory for a table\n", 0, 0, 0, 0, 0, 0); + return CM_NO_MORE_MEMORY; + } + + cm_MemCopy(mem, table->entries, + table->idxMax*sizeof(table->entries)); + cm_MemSet((void *)((t_uint32) mem + table->idxMax*sizeof(*table->entries)), 0, + (new_max-table->idxMax) * sizeof(*table->entries)); + + OSAL_Free(table->entries); + table->entries = mem; + table->idxMax = new_max; + + return CM_OK; +} + +/** cm_addEntry - Add an local pointer to an element to the list + * + * 1. Increase the size of the list if it's full + * 2. Search an empty entry + * 3. Add the element to the list + * 4. Compute and return the "user handle" + */ +t_uint32 cm_addEntry(t_nmf_table *table, void *entry) +{ + unsigned int i; + t_uint32 hdl = 0; + + if (table->idxNb == table->idxMax) + cm_increaseTable(table); + + for (i = table->idxCur; + table->entries[i] != 0 && i != (table->idxCur-1); + i = (i+1)%table->idxMax); + + if (table->entries[i] == 0) { + table->entries[i] = entry; + table->idxCur = (i+1) % table->idxMax; + table->idxNb++; + hdl = ENTRY2HANDLE(entry, i); + } else + ERROR("No free entry found in table\n", 0, 0, 0, 0, 0, 0); + + return hdl; +} + +/** cm_delEntry - remove the given element from the list + * + * 1. Check if the handle is valid + * 2. Search the entry and free it + */ +void cm_delEntry(t_nmf_table *table, t_uint32 idx) +{ + table->entries[idx] = NULL; + table->idxNb--; +} + +/** cm_lookupEntry - search the entry corresponding to + * the user handle. + * + * 1. Check if the handle is valid + * 2. Return a pointer to the element + */ +void *cm_lookupEntry(const t_nmf_table *table, const t_uint32 hdl) +{ + unsigned int idx = hdl & INDEX_MASK; + + if ((idx >= table->idxMax) + || (((unsigned int)table->entries[idx] << INDEX_SHIFT) != (hdl & ~INDEX_MASK))) + return NULL; + else + return table->entries[idx]; +} + +/** cm_lookupHandle - search the handle corresponding + * to the given element + * + * 1. Check if the handler is valid or is a special handler + * 2. Loop in the table to retrieve the entry matching and return its value + */ +t_uint32 cm_lookupHandle(const t_nmf_table *table, const void *entry) +{ + t_uint32 i; + + /* NULL is an invalid value that must be handle separatly + as it'll match all used/free entries value */ + if (entry == NULL) + return 0; + + for (i=0; i < table->idxMax; i++) { + if (table->entries[i] == entry) + return ENTRY2HANDLE(table->entries[i], i); + } + + return 0; +} |