summaryrefslogtreecommitdiff
path: root/drivers/staging/nmf-cm/cm/engine/utils/src
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/nmf-cm/cm/engine/utils/src')
-rw-r--r--drivers/staging/nmf-cm/cm/engine/utils/src/convert.c20
-rw-r--r--drivers/staging/nmf-cm/cm/engine/utils/src/mem.c27
-rw-r--r--drivers/staging/nmf-cm/cm/engine/utils/src/string.c231
-rw-r--r--drivers/staging/nmf-cm/cm/engine/utils/src/swap.c156
-rw-r--r--drivers/staging/nmf-cm/cm/engine/utils/src/table.c155
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;
+}