summaryrefslogtreecommitdiff
path: root/drivers/staging/nmf-cm/cm/engine/elf
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/nmf-cm/cm/engine/elf')
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/inc/bfd.h123
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/inc/common.h125
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/inc/elfabi.h539
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/inc/elfapi.h125
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/inc/memory.h77
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/inc/mmdsp-loadmap.h47
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/inc/mmdsp.h31
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/inc/mpcal.h20
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/inc/reloc.h35
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/src/elf64.c47
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/src/elfload.c773
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/src/elfmmdsp.c575
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/src/elfrelocate.c79
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/src/elfxx.c591
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/src/mmdsp-debug.c435
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/src/mpcal.c6
16 files changed, 3628 insertions, 0 deletions
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/inc/bfd.h b/drivers/staging/nmf-cm/cm/engine/elf/inc/bfd.h
new file mode 100644
index 00000000000..2bccf9c073b
--- /dev/null
+++ b/drivers/staging/nmf-cm/cm/engine/elf/inc/bfd.h
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+/*!
+ * \internal
+ * \brief Elf bfd relocation.
+ *
+ * \defgroup ELFLOADER MMDSP ELF loader.
+ */
+#ifndef __INC_CM_ELF_BFD_H
+#define __INC_CM_ELF_BFD_H
+
+#include <cm/inc/cm_type.h>
+
+/*
+ * Relocation spcification
+ */
+enum complain_overflow
+{
+ /* Do not complain on overflow. */
+ complain_overflow_dont,
+
+ /* Complain if the bitfield overflows, whether it is considered
+ as signed or unsigned. */
+ complain_overflow_bitfield,
+
+ /* Complain if the value overflows when considered as signed
+ number. */
+ complain_overflow_signed,
+
+ /* Complain if the value overflows when considered as an
+ unsigned number. */
+ complain_overflow_unsigned
+};
+
+struct reloc_howto_struct
+{
+ /* The type field has mainly a documentary use - the back end can
+ do what it wants with it, though normally the back end's
+ external idea of what a reloc number is stored
+ in this field. For example, a PC relative word relocation
+ in a coff environment has the type 023 - because that's
+ what the outside world calls a R_PCRWORD reloc. */
+ unsigned int type;
+
+ /* The value the final relocation is shifted right by. This drops
+ unwanted data from the relocation. */
+ unsigned int rightshift;
+
+ /* The size of the item to be relocated. This is *not* a
+ power-of-two measure. To get the number of bytes operated
+ on by a type of relocation, use bfd_get_reloc_size. */
+ int size;
+
+ /* The number of bits in the item to be relocated. This is used
+ when doing overflow checking. */
+ unsigned int bitsize;
+
+ /* Notes that the relocation is relative to the location in the
+ data section of the addend. The relocation function will
+ subtract from the relocation value the address of the location
+ being relocated. */
+ t_uint64 pc_relative;
+
+ /* The bit position of the reloc value in the destination.
+ The relocated value is left shifted by this amount. */
+ unsigned int bitpos;
+
+ /* What type of overflow error should be checked for when
+ relocating. */
+ enum complain_overflow complain_on_overflow;
+
+ void (*special_function)(void);
+
+ /* The textual name of the relocation type. */
+ char *name;
+
+ /* Some formats record a relocation addend in the section contents
+ rather than with the relocation. For ELF formats this is the
+ distinction between USE_REL and USE_RELA (though the code checks
+ for USE_REL == 1/0). The value of this field is TRUE if the
+ addend is recorded with the section contents; when performing a
+ partial link (ld -r) the section contents (the data) will be
+ modified. The value of this field is FALSE if addends are
+ recorded with the relocation (in arelent.addend); when performing
+ a partial link the relocation will be modified.
+ All relocations for all ELF USE_RELA targets should set this field
+ to FALSE (values of TRUE should be looked on with suspicion).
+ However, the converse is not true: not all relocations of all ELF
+ USE_REL targets set this field to TRUE. Why this is so is peculiar
+ to each particular target. For relocs that aren't used in partial
+ links (e.g. GOT stuff) it doesn't matter what this is set to. */
+ char partial_inplace;
+
+ /* src_mask selects the part of the instruction (or data) to be used
+ in the relocation sum. If the target relocations don't have an
+ addend in the reloc, eg. ELF USE_REL, src_mask will normally equal
+ dst_mask to extract the addend from the section contents. If
+ relocations do have an addend in the reloc, eg. ELF USE_RELA, this
+ field should be zero. Non-zero values for ELF USE_RELA targets are
+ bogus as in those cases the value in the dst_mask part of the
+ section contents should be treated as garbage. */
+ t_uint64 src_mask;
+
+ /* dst_mask selects which parts of the instruction (or data) are
+ replaced with a relocated value. */
+ t_uint64 dst_mask;
+
+ /* When some formats create PC relative instructions, they leave
+ the value of the pc of the place being relocated in the offset
+ slot of the instruction, so that a PC relative relocation can
+ be made just by adding in an ordinary offset (e.g., sun3 a.out).
+ Some formats leave the displacement part of an instruction
+ empty (e.g., m88k bcs); this flag signals the fact. */
+ char pcrel_offset;
+};
+
+#define HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
+ { (unsigned) C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC }
+
+#endif
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/inc/common.h b/drivers/staging/nmf-cm/cm/engine/elf/inc/common.h
new file mode 100644
index 00000000000..c51845d5f96
--- /dev/null
+++ b/drivers/staging/nmf-cm/cm/engine/elf/inc/common.h
@@ -0,0 +1,125 @@
+/*
+ * 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.
+ */
+/*!
+ * \internal
+ * \brief Elf common definition.
+ */
+#ifndef __INC_CM_ELF_COMMON_H
+#define __INC_CM_ELF_COMMON_H
+
+#include <cm/engine/component/inc/nmfheaderabi.h>
+#include <cm/engine/elf/inc/elfabi.h>
+#include <cm/engine/elf/inc/reloc.h>
+#include <cm/engine/memory/inc/domain.h>
+#include <cm/engine/component/inc/description.h>
+#include <cm/engine/utils/inc/string.h>
+
+
+#define MAX_SEGMENT 20 // Just in order to not allocate them dynamically
+
+struct XXElf;
+
+/**
+ * \brief Structure used as database of pushed component.
+ */
+typedef struct {
+ t_instance_property instanceProperty;
+ t_uint32 magicNumber; //!< Magic Number
+ t_dup_char foundedTemplateName;
+ t_uint32 minStackSize; //!< Minimum stack size
+
+ struct XXElf *ELF;
+
+ t_elfSegment segments[NUMBER_OF_MMDSP_MEMORY];
+
+ t_bool temporaryDescription;
+
+ t_memory_reference memoryForConstruct;
+ t_memory_reference memoryForStart;
+ t_memory_reference memoryForStop;
+ t_memory_reference memoryForDestroy;
+
+ t_uint8 requireNumber; //!< Number of interface required by this template
+ t_uint8 attributeNumber; //!< Number of attributes in this template
+ t_uint8 propertyNumber; //!< Number of properties in this template
+ t_uint8 provideNumber; //!< Number of interface provided by this template
+
+ t_interface_require *requires; //!< Array of interface required by this template
+ t_attribute *attributes; //!< Array of attributes in this template
+ t_property *properties; //!< Array of properties in this template
+ t_interface_provide *provides; //!< Array of interface provided by this template
+
+} t_elfdescription;
+
+/**
+ * \brief Temporary structure used as database when pushing component.
+ */
+typedef struct
+{
+ const char *elfdata;
+ const char *sectionData[50]; // YES it must be dynamic, but i'm tired.
+
+ t_bool isExecutable;
+
+ t_sint32 nmfSectionIndex;
+ const void *relaNmfSegment, *relaNmfSegmentEnd;
+ const void *relaNmfSegmentSymbols;
+ const char *relaNmfSegmentStrings;
+
+ const t_elf_component_header*elfheader;
+
+
+} t_tmp_elfdescription;
+
+
+t_cm_error ELF64_LoadComponent(
+ t_uint16 e_machine,
+ const char *elfdata,
+ t_elfdescription **elfhandlePtr,
+ t_tmp_elfdescription *elftmp);
+t_cm_error ELF64_ComputeSegment(
+ t_elfdescription *elfhandle,
+ t_tmp_elfdescription *elftmp);
+
+void ELF64_UnloadComponent(
+ t_elfdescription *elfhandle);
+
+t_cm_error ELF64_loadSegment(
+ t_elfdescription *elfhandle,
+ t_memory_handle *memory,
+ t_memory_property property);
+t_cm_error ELF64_relocateSegments(
+ t_memory_handle *memories,
+ t_elfdescription *elf,
+ t_memory_property property,
+ void *cbContext);
+t_cm_error ELF64_getRelocationMemory(
+ t_elfdescription *elfhandle,
+ t_tmp_elfdescription *elftmp,
+ t_uint32 offsetInNmf,
+ t_memory_reference *memory);
+
+const t_elfmemory* MMDSP_getMappingById(t_memory_id memId);
+const t_elfmemory* MMDSP_getMappingByName(const char* sectionName, t_instance_property property);
+void MMDSP_serializeMemories(t_instance_property property,
+ const t_elfmemory** codeMemory, const t_elfmemory** thisMemory);
+void MMDSP_copySection(t_uint32 origAddr, t_uint32 remoteAddr, t_uint32 sizeInByte);
+void MMDSP_bzeroSection(t_uint32 remoteAddr, t_uint32 sizeInByte);
+void MMDSP_loadedSection(t_nmf_core_id coreId, t_memory_id memId, t_memory_handle handle);
+void MMDSP_unloadedSection(t_nmf_core_id coreId, t_memory_id memId, t_memory_handle handle);
+
+void MMDSP_copyCode(t_uint64 * remoteAddr64, const char* origAddr, int nb);
+void MMDSP_copyData24(t_uint32 * remoteAddr32, const char* origAddr, int nb);
+void MMDSP_copyData16(t_uint16 * remoteAddr16, const char* origAddr, int nb);
+
+t_uint32 cm_resolvSymbol(
+ void* context,
+ t_uint32 type,
+ t_dup_char symbolName,
+ char* reloc_addr);
+
+
+#endif
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/inc/elfabi.h b/drivers/staging/nmf-cm/cm/engine/elf/inc/elfabi.h
new file mode 100644
index 00000000000..cbcc6db3b9b
--- /dev/null
+++ b/drivers/staging/nmf-cm/cm/engine/elf/inc/elfabi.h
@@ -0,0 +1,539 @@
+/*
+ * 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.
+ */
+#ifndef _CM_ELF_H
+#define _CM_ELF_H 1
+
+typedef t_uint16 Elf32_Half;
+typedef t_uint16 Elf64_Half;
+
+typedef t_uint32 Elf32_Word;
+typedef t_sint32 Elf32_Sword;
+typedef t_uint32 Elf64_Word;
+typedef t_sint32 Elf64_Sword;
+
+typedef t_uint64 Elf32_Xword;
+typedef t_sint64 Elf32_Sxword;
+typedef t_uint64 Elf64_Xword;
+typedef t_sint64 Elf64_Sxword;
+
+typedef t_uint32 Elf32_Addr;
+typedef t_uint64 Elf64_Addr;
+
+typedef t_uint32 Elf32_Off;
+typedef t_uint64 Elf64_Off;
+
+typedef t_uint16 Elf32_Section;
+typedef t_uint16 Elf64_Section;
+
+typedef Elf32_Half Elf32_Versym;
+typedef Elf64_Half Elf64_Versym;
+
+
+/*********************************************
+ * Header
+ *********************************************/
+#define EI_NIDENT (16) //!< Size of e_ident[]
+
+#define EI_MAG0 0 //!< File identification
+#define ELFMAG0 0x7f
+
+#define EI_MAG1 1 //!< File identification
+#define ELFMAG1 'E'
+
+#define EI_MAG2 2 //!< File identification
+#define ELFMAG2 'L'
+
+#define EI_MAG3 3 //!< File identification
+#define ELFMAG3 'F'
+
+#define EI_CLASS 4 //!< File class
+#define ELFCLASSNONE 0 //!< Invalid class
+#define ELFCLASS32 1 //!< 32-bit objects
+#define ELFCLASS64 2 //!< 64-bit objects
+
+#define EI_DATA 5 //!< Data encoding
+#define ELFDATANONE 0 //!< Invalid data encoding
+#define ELFDATA2LSB 1 //!< 2's complement, little endian
+#define ELFDATA2MSB 2 //!< 2's complement, big endian
+
+#define EI_VERSION 6 //!< File version
+
+#define EI_OSABI 7 //!< OS ABI identification
+#define ELFOSABI_NONE 0 //!< No extension
+#define ELFOSABI_HPUX 1 //!< HP-UX
+#define ELFOSABI_NETBSD 2 //!< NetBSD
+#define ELFOSABI_LINUX 3 //!< Linux
+#define ELFOSABI_SOLARIS 6 //!< Sun Solaris
+#define ELFOSABI_AIX 7 //!< AIX
+#define ELFOSABI_IRIX 8 //!< IRIX
+#define ELFOSABI_FREEBSD 9 //!< FreeBSD
+#define ELFOSABI_TRU64 10 //!< Compaq TRU64 UNIX
+#define ELFOSABI_MODESTO 11 //!< Novell Modesto
+#define ELFOSABI_OPENBSD 12 //!< Open BSD
+#define ELFOSABI_OPENVMS 13 //!< Open VMS
+#define ELFOSABI_NSK 14 //!< HP Non-Stop-Kernel
+
+#define EI_ABIVERSION 8 //!< ABI version
+
+#define EI_PAD 9 //!< Start of padding byte
+
+
+typedef struct
+{
+ unsigned char e_ident[EI_NIDENT]; //!< The initial bytes mark the file as an object file and provide machine-independent data with which to decode and interpret the file's contents
+ Elf32_Half e_type; //!< This member identifies the object file type
+ Elf32_Half e_machine; //!< This member's value specifies the required architecture for an individual file
+ Elf32_Word e_version; //!< This member identifies the object file version
+ Elf32_Addr e_entry; //!< This member gives the virtual address to which the system first transfers control, thus starting the process
+ Elf32_Off e_phoff; //!< This member holds the program header table's file offset in bytes
+ Elf32_Off e_shoff; //!< This member holds the section header table's file offset in bytes
+ Elf32_Word e_flags; //!< This member holds processor-specific flags associated with the file
+ Elf32_Half e_ehsize; //!< This member holds the ELF header's size in bytes
+ Elf32_Half e_phentsize; //!< This member holds the size in bytes of one entry in the file's program header table; all entries are the same size
+ Elf32_Half e_phnum; //!< This member holds the number of entries in the program header table
+ Elf32_Half e_shentsize; //!< This member holds a section header's size in bytes
+ Elf32_Half e_shnum; //!< This member holds the number of entries in the section header table
+ Elf32_Half e_shstrndx; //!< This member holds the section header table index of the entry associated with the section name string table
+} Elf32_Ehdr; //!< 32bit Entry Header
+
+typedef struct
+{
+ unsigned char e_ident[EI_NIDENT]; //!< The initial bytes mark the file as an object file and provide machine-independent data with which to decode and interpret the file's contents
+ Elf64_Half e_type; //!< This member identifies the object file type
+ Elf64_Half e_machine; //!< This member's value specifies the required architecture for an individual file
+ Elf64_Word e_version; //!< This member identifies the object file version
+ Elf64_Addr e_entry; //!< This member gives the virtual address to which the system first transfers control, thus starting the process
+ Elf64_Off e_phoff; //!< This member holds the program header table's file offset in bytes
+ Elf64_Off e_shoff; //!< This member holds the section header table's file offset in bytes
+ Elf64_Word e_flags; //!< This member holds processor-specific flags associated with the file
+ Elf64_Half e_ehsize; //!< This member holds the ELF header's size in bytes
+ Elf64_Half e_phentsize; //!< This member holds the size in bytes of one entry in the file's program header table; all entries are the same size
+ Elf64_Half e_phnum; //!< This member holds the number of entries in the program header table
+ Elf64_Half e_shentsize; //!< This member holds a section header's size in bytes
+ Elf64_Half e_shnum; //!< This member holds the number of entries in the section header table
+ Elf64_Half e_shstrndx; //!< This member holds the section header table index of the entry associated with the section name string table
+} Elf64_Ehdr; //!< 64bit Entry Header
+
+/*
+ * e_type
+ */
+#define ET_NONE 0 //!< No file type
+#define ET_REL 1 //!< Relocatable file
+#define ET_EXEC 2 //!< Executable file
+#define ET_DYN 3 //!< Shared object file
+#define ET_CORE 4 //!< Core file
+#define ET_LOOS 0xfe00 //!< Operating system-specific
+#define ET_HIOS 0xfeff //!< Operating system-specific
+#define ET_LOPROC 0xff00 //!< Processor-specific
+#define ET_HIPROC 0xffff //!< Processor-specific
+
+/*
+ * e_machine
+ */
+#define EM_NONE 0 //!< No machine
+#define EM_M32 1 //!< AT&T WE 32100
+#define EM_SPARC 2 //!< SUN SPARC
+#define EM_386 3 //!< Intel 80386
+#define EM_68K 4 //!< Motorola 68000
+#define EM_88K 5 //!< Motorola 88000
+#define EM_860 7 //!< Intel 80860
+#define EM_MIPS 8 //!< MIPS I architecture
+#define EM_S370 9 //!< IBM System/370
+#define EM_MIPS_RS3_LE 10 //!< MIPS R3000 little-endian
+#define EM_PARISC 15 //!< HPPA
+#define EM_VPP500 17 //!< Fujitsu VPP500
+#define EM_SPARC32PLUS 18 //!< Enhanced instruction set SPARC
+#define EM_960 19 //!< Intel 80960
+#define EM_PPC 20 //!< PowerPC
+#define EM_PPC64 21 //!< 64-bit PowerPC
+#define EM_S390 22 //!< IBM System/390 Processor
+#define EM_V800 36 //!< NEC V800
+#define EM_FR20 37 //!< Fujitsu FR20
+#define EM_RH32 38 //!< TRW RH-32
+#define EM_RCE 39 //!< Motorola RCE
+#define EM_ARM 40 //!< Advanced RISC Machines ARM
+#define EM_FAKE_ALPHA 41 //!< Digital Alpha
+#define EM_SH 42 //!< Hitachi SH
+#define EM_SPARCV9 43 //!< SPARC Version 9
+#define EM_TRICORE 44 //!< Siemens TriCore embedded processor
+#define EM_ARC 45 //!< Argonaut RISC Core, Argonaut Technologies Inc
+#define EM_H8_300 46 //!< Hitachi H8/300
+#define EM_H8_300H 47 //!< Hitachi H8/300H
+#define EM_H8S 48 //!< Hitachi H8S
+#define EM_H8_500 49 //!< Hitachi H8/500
+#define EM_IA_64 50 //!< Intel IA-64 processor architecture
+#define EM_MIPS_X 51 //!< Stanford MIPS-X
+#define EM_COLDFIRE 52 //!< Motorola ColdFire
+#define EM_68HC12 53 //!< Motorola M68HC12
+#define EM_MMA 54 //!< Fujitsu MMA Multimedia Accelerator
+#define EM_PCP 55 //!< Siemens PCP
+#define EM_NCPU 56 //!< Sony nCPU embedded RISC processor
+#define EM_NDR1 57 //!< Denso NDR1 microprocessor
+#define EM_STARCORE 58 //!< Motorola Start*Core processor
+#define EM_ME16 59 //!< Toyota ME16 processor
+#define EM_ST100 60 //!< STMicroelectronics ST100 processor
+#define EM_TINYJ 61 //!< Advanced Logic Corp. TinyJ embedded processor family
+#define EM_X86_64 62 //!< AMD x86-64 architecture
+#define EM_PDSP 63 //!< Sony DSP Processor
+#define EM_PDP10 64 //!< Digital Equipment Corp. PDP-10
+#define EM_PDP11 65 //!< Digital Equipment Corp. PDP-11
+#define EM_FX66 66 //!< Siemens FX66 microcontroller
+#define EM_ST9PLUS 67 //!< STMicroelectronics ST9+ 8/16 bit microcontroller
+#define EM_ST7 68 //!< STMicroelectronics ST7 8-bit microcontroller
+#define EM_68HC16 69 //!< Motorola MC68HC16 Microcontroller
+#define EM_68HC11 70 //!< Motorola MC68HC11 Microcontroller
+#define EM_68HC08 71 //!< Motorola MC68HC08 Microcontroller
+#define EM_68HC05 72 //!< Motorola MC68HC05 Microcontroller
+#define EM_SVX 73 //!< Silicon Graphics SVx
+#define EM_ST19 74 //!< STMicroelectronics ST19 8-bit microcontroller
+#define EM_VAX 75 //!< Digital VAX
+#define EM_CRIS 76 //!< Axis Communications 32-bit embedded processor
+#define EM_JAVELIN 77 //!< Infifineon Technologies 32-bit embedded processor
+#define EM_FIREPATH 78 //!< Element 14 64-bit DSP Processor
+#define EM_ZSP 79 //!< LSI Logic 16-bit DSP Processor
+#define EM_MMIX 80 //!< Donald Knuth's educational 64-bit processor
+#define EM_HUANY 81 //!< Harvard University machine-independent object files
+#define EM_PRISM 82 //!< SiTera Prism
+#define EM_AVR 83 //!< Atmel AVR 8-bit microcontroller
+#define EM_FR30 84 //!< Fujitsu FR30
+#define EM_D10V 85 //!< Mitsubishi D10V
+#define EM_D30V 86 //!< Mitsubishi D30V
+#define EM_V850 87 //!< NEC v850
+#define EM_M32R 88 //!< Mitsubishi M32R
+#define EM_MN10300 89 //!< Matsushita MN10300
+#define EM_MN10200 90 //!< Matsushita MN10200
+#define EM_PJ 91 //!< picoJava
+#define EM_OPENRISC 92 //!< OpenRISC 32-bit embedded processor
+#define EM_ARC_A5 93 //!< ARC International ARCompact processor (old spelling/synonym: EM_ARC_A5)
+#define EM_XTENSA 94 //!< Tensilica Xtensa Architecture
+#define EM_VIDEOCORE 95 //!< Alphamosaic VideoCore processor
+#define EM_TMM_GPP 96 //!< Thompson Multimedia General Purpose Processor
+#define EM_NS32K 97 //!< National Semiconductor 32000 series
+#define EM_TPC 98 //!< Tenor Network TPC processor
+#define EM_SNP1K 99 //!< Trebia SNP 1000 processor
+#define EM_ST200 100 //!< STMicroelectronics (www.st.com) ST200 microcontroller
+#define EM_IP2K 101 //!< Ubicom IP2xxx microcontroller family
+#define EM_MAX 102 //!< MAX Processor
+#define EM_CR 103 //!< National Semiconductor CompactRISC microprocessor
+#define EM_F2MC16 104 //!< Fujitsu F2MC16
+#define EM_MSP430 105 //!< Texaxas Instruments embedded microcontroller msp430
+#define EM_BLACKFIN 106 //!< Analog Devices Blackfin (DSP) processor
+#define EM_SE_C33 107 //!< S1C33 Family of Seiko Epspson processors
+#define EM_SEP 108 //!< Sharp embedded microprocessor
+#define EM_ARCA 109 //!< Arca RISC Microprocessor
+#define EM_UNICORE 110 //!< Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University
+#define EM_EXCESS 111 //!< eXcess: 16/32/64-bit configurable embedded CPU
+#define EM_DXP 112 //!< Icera Semiconductor Inc. Deep Execution Processor
+#define EM_ALTERA_NIOS2 113 //!< Altera Nios II soft-core processor
+#define EM_CRX 114 //!< National Semiconductor CompactRISC CRX microprocessor
+#define EM_XGATE 115 //!< Motorola XGATE embedded processor
+#define EM_C166 116 //!< Infifineon C16x/XC16x processor
+#define EM_M16C 117 //!< Renesas M16C series microprocessors
+#define EM_DSPIC30F 118 //!< Microchip Technology dsPIC30F Digital Signal Controller
+#define EM_CE 119 //!< Freescale Communication Engine RISC core
+#define EM_M32C 120 //!< Renesas M32C series microprocessors
+#define EM_TSK3000 131 //!< Altium TSK3000 core
+#define EM_RS08 132 //!< Freescale RS08 embedded processor
+#define EM_ECOG2 134 //!< Cyan Technology eCOG2 microprocessor
+#define EM_SCORE7 135 //!< Sunplus S+core7 RISC processor
+#define EM_DSP24 136 //!< New Japan Radio (NJR) 24-bit DSP Processor
+#define EM_VIDEOCORE3 137 //!< Broadcom VideoCore III processor
+#define EM_LATTICEMICO32 138 //!< RISC processor for Lattice FPGA architecture
+#define EM_SE_C17 139 //!< Seiko Epspson C17 family
+#define EM_TI_C6000 140 //!< The Texaxas Instruments TMS320C6000 DSP family
+#define EM_TI_C2000 141 //!< The Texaxas Instruments TMS320C2000 DSP family
+#define EM_TI_C5500 142 //!< The Texaxas Instruments TMS320C55x DSP family
+#define EM_MMDSP_PLUS 160 //!< STMicroelectronics 64bit VLIW Data Signal Processor
+#define EM_CYPRESS_M8C 161 //!< Cypress M8C microprocessor
+#define EM_R32C 162 //!< Renesas R32C series microprocessors
+#define EM_TRIMEDIA 163 //!< NXP Semiconductors TriMedia architecture family
+#define EM_QDSP6 164 //!< QUALCOMM DSP6 Processor
+#define EM_8051 165 //!< Intel 8051 and variants
+#define EM_STXP7X 166 //!< STMicroelectronics STxP7x family of configurable and extensible RISC processors
+#define EM_NDS32 167 //!< Andes Technology compact code size embedded RISC processor family
+#define EM_ECOG1 168 //!< Cyan Technology eCOG1X family
+#define EM_ECOG1X 168 //!< Cyan Technology eCOG1X family
+#define EM_MAXQ30 169 //!< Dallas Semiconductor MAXQ30 Core Micro-controllers
+#define EM_XIMO16 170 //!< New Japan Radio (NJR) 16-bit DSP Processor
+#define EM_MANIK 171 //!< M2000 Reconfigurable RISC Microprocessor
+#define EM_CRAYNV2 172 //!< Cray Inc. NV2 vector architecture
+#define EM_RX 173 //!< Renesas RX family
+#define EM_METAG 174 //!< Imagination Technologies META processor architecture
+#define EM_MCST_ELBRUS 175 //!< MCST Elbrus general purpose hardware architecture
+#define EM_ECOG16 176 //!< Cyan Technology eCOG16 family
+#define EM_CR16 177 //!< National Semiconductor CompactRISC CR16 16-bit microprocessor
+#define EM_ETPU 178 //!< Freescale Extended Time Processing Unit
+#define EM_SLE9X 179 //!< Infifineon Technologies SLE9X core
+#define EM_AVR32 185 //!< Atmel Corporation 32-bit microprocessor family
+#define EM_STM8 186 //!< STMicroeletronics STM8 8-bit microcontroller
+#define EM_TILE64 187 //!< Tilera TILE64 multicore architecture family
+#define EM_TILEPRO 188 //!< Tilera TILEPro multicore architecture family
+#define EM_MICROBLAZE 189 //!< Xilinx MicroBlaze 32-bit RISC soft processor core
+#define EM_CUDA 190 //!< NVIDIA CUDA architecture
+#define EM_TILEGX 191 //!< Tilera TILE-Gx multicore architecture family
+
+/*
+ * e_version (version)
+ */
+#define EV_NONE 0 //!< Invalid version
+#define EV_CURRENT 1 //!< Current version
+
+
+/*********************************************
+ * Section
+ *********************************************/
+typedef struct
+{
+ Elf32_Word sh_name; //!< This member specifies the name of the section
+ Elf32_Word sh_type; //!< This member categorizes the section's contents and semantics
+ Elf32_Word sh_flags; //!< Sections support 1-bit flags that describe miscellaneous attributes
+ Elf32_Addr sh_addr; //!< If the section will appear in the memory image of a process, this member gives the address at which the section's first byte should reside
+ Elf32_Off sh_offset; //!< This member's value gives the byte offset from the beginning of the file to the first byte in the section
+ Elf32_Word sh_size; //!< This member gives the section's size in bytes
+ Elf32_Word sh_link; //!< This member holds a section header table index link, whose interpretation depends on the section type
+ Elf32_Word sh_info; //!< This member holds extra information, whose interpretation depends on the section type
+ Elf32_Word sh_addralign; //!< Some sections have address alignment constraints
+ Elf32_Word sh_entsize; //!< Some sections hold a table of fixed-size entries, such as a symbol table
+} Elf32_Shdr; //!< 32bit Section header
+
+typedef struct
+{
+ Elf64_Word sh_name; //!< This member specifies the name of the section
+ Elf64_Word sh_type; //!< This member categorizes the section's contents and semantics
+ Elf64_Xword sh_flags; //!< Sections support 1-bit flags that describe miscellaneous attributes
+ Elf64_Addr sh_addr; //!< If the section will appear in the memory image of a process, this member gives the address at which the section's first byte should reside
+ Elf64_Off sh_offset; //!< This member's value gives the byte offset from the beginning of the file to the first byte in the section
+ Elf64_Xword sh_size; //!< This member gives the section's size in bytes
+ Elf64_Word sh_link; //!< This member holds a section header table index link, whose interpretation depends on the section type
+ Elf64_Word sh_info; //!< This member holds extra information, whose interpretation depends on the section type
+ Elf64_Xword sh_addralign; //!< Some sections have address alignment constraints
+ Elf64_Xword sh_entsize; //!< Some sections hold a table of fixed-size entries, such as a symbol table
+} Elf64_Shdr; //!< 64bit Section header
+
+/*
+ * Special Section Indexes
+ */
+#define SHN_UNDEF 0 //!< This value marks an undefined, missing, irrelevant, or otherwise meaningless section reference
+#define SHN_LORESERVE 0xff00 //!< This value specifies the lower bound of the range of reserved indexes
+#define SHN_LOPROC 0xff00 //!< Values in this inclusive range are reserved for processor-specific semantics
+#define SHN_HIPROC 0xff1f //!< Values in this inclusive range are reserved for processor-specific semantics
+#define SHN_LOOS 0xff20 //!< Values in this inclusive range are reserved for operating system-specific semantics
+#define SHN_HIOS 0xff3f //!< Values in this inclusive range are reserved for operating system-specific semantics
+#define SHN_ABS 0xfff1 //!< This value specifies absolute values for the corresponding reference
+#define SHN_COMMON 0xfff2 //!< Symbols defined relative to this section are common symbols
+#define SHN_XINDEX 0xffff //!< This value is an escape value
+#define SHN_HIRESERVE 0xffff //!< This value specifies the upper bound of the range of reserved indexes
+
+/*
+ * sh_type
+ */
+#define SHT_NULL 0 //!< This value marks the section header as inactive
+#define SHT_PROGBITS 1 //!< The section holds information defined by the program
+#define SHT_SYMTAB 2 //!< These sections hold a symbol table
+#define SHT_STRTAB 3 //!< The section holds a string table
+#define SHT_RELA 4 //!< The section holds relocation entries with explicit addends, such as type Elf32_Rela for the 32-bit class of object files or type Elf64_Rela for the 64-bit class of object files
+#define SHT_HASH 5 //!< The section holds a symbol hash table
+#define SHT_DYNAMIC 6 //!< The section holds information for dynamic linking
+#define SHT_NOTE 7 //!< The section holds information that marks the file in some way
+#define SHT_NOBITS 8 //!< A section of this type occupies no space in the file but otherwise resembles SHT_PROGBITS
+#define SHT_REL 9 //!< The section holds relocation entries without explicit addends, such as type Elf32_Rel for the 32-bit class of object files or type Elf64_Rel for the 64-bit class of object files
+#define SHT_SHLIB 10 //!< This section type is reserved but has unspecified semantics
+#define SHT_DYNSYM 11 //!<
+#define SHT_INIT_ARRAY 14 //!< This section contains an array of pointers to initialization functions
+#define SHT_FINI_ARRAY 15 //!< This section contains an array of pointers to termination functions
+#define SHT_PREINIT_ARRAY 16 //!< This section contains an array of pointers to functions that are invoked before all other initialization functions
+#define SHT_GROUP 17 //!< This section defines a section group
+#define SHT_SYMTAB_SHNDX 18 //!< This section is associated with a section of type SHT_SYMTAB and is required if any of the section header indexes referenced by that symbol table contain the escape value SHN_XINDEX
+#define SHT_LOOS 0x60000000 //!< Values in this inclusive range are reserved for operating system-specific semantics
+#define SHT_HIOS 0x6fffffff //!< Values in this inclusive range are reserved for operating system-specific semantics
+#define SHT_LOPROC 0x70000000 //!< Values in this inclusive range are reserved for processor-specific semantics
+#define SHT_HIPROC 0x7fffffff //!< Values in this inclusive range are reserved for processor-specific semantics
+#define SHT_LOUSER 0x80000000 //!< This value specifies the upper bound of the range of indexes reserved for application programs
+#define SHT_HIUSER 0x8fffffff //!< This value specifies the upper bound of the range of indexes reserved for application programs
+
+/*
+ * sh_flags
+ */
+#define SHF_WRITE 0x1 //!< The section contains data that should be writable during process execution
+#define SHF_ALLOC 0x2 //!< The section occupies memory during process execution
+#define SHF_EXECINSTR 0x4 //!< The section contains executable machine instructions
+#define SHF_MERGE 0x10 //!< The data in the section may be merged to eliminate duplication
+#define SHF_STRINGS 0x20 //!< The data elements in the section consist of null-terminated character strings
+#define SHF_INFO_LINK 0x40 //!< The sh_info field of this section header holds a section header table index
+#define SHF_LINK_ORDER 0x80 //!< This flag adds special ordering requirements for link editors
+#define SHF_OS_NONCONFORMING 0x100 //!< This section requires special OS-specific processing (beyond the standard linking rules) to avoid incorrect behavior
+#define SHF_GROUP 0x200 //!< This section is a member (perhaps the only one) of a section group
+#define SHF_TLS 0x400 //!< This section holds Thread-Local Storage, meaning that each separate execution flow has its own distinct instance of this data
+#define SHF_MASKOS 0x0ff00000 //!< All bits included in this mask are reserved for operating system-specific semantics
+#define SHF_MASKPROC 0xf0000000 //!< All bits included in this mask are reserved for processor-specific semantics
+
+
+/*********************************************
+ * Symbol
+ *********************************************/
+typedef struct
+{
+ Elf32_Word st_name; //!< This member holds an index into the object file's symbol string table, which holds the character representations of the symbol names
+ Elf32_Addr st_value; //!< This member gives the value of the associated symbol
+ Elf32_Word st_size; //!< Many symbols have associated sizes
+ unsigned char st_info; //!< This member specifies the symbol's type and binding attributes
+ unsigned char st_other; //!< This member currently specifies a symbol's visibility
+ Elf32_Section st_shndx; //!< Every symbol table entry is defined in relation to some section
+} Elf32_Sym;
+
+typedef struct
+{
+ Elf64_Word st_name; //!< This member holds an index into the object file's symbol string table, which holds the character representations of the symbol names
+ unsigned char st_info; //!< This member specifies the symbol's type and binding attributes
+ unsigned char st_other; //!< This member currently specifies a symbol's visibility
+ Elf64_Section st_shndx; //!< Every symbol table entry is defined in relation to some section
+ Elf64_Addr st_value; //!< This member gives the value of the associated symbol
+ Elf64_Xword st_size; //!< Many symbols have associated sizes
+} Elf64_Sym;
+
+/*
+ * st_info
+ */
+#define ELF32_ST_BIND(i) ((i)>>4)
+#define ELF32_ST_TYPE(i) ((i)&0xf)
+#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
+
+#define ELF64_ST_BIND(i) ((i)>>4)
+#define ELF64_ST_TYPE(i) ((i)&0xf)
+#define ELF64_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
+
+
+/* st_info (symbol binding) */
+#define STB_LOCAL 0 //!< Local symbols are not visible outside the object file containing their definition
+#define STB_GLOBAL 1 //!< Global symbols are visible to all object files being combined
+#define STB_WEAK 2 //!< Weak symbols resemble global symbols, but their definitions have lower precedence
+#define STB_LOOS 10 //!< Values in this inclusive range are reserved for operating system-specific semantics
+#define STB_HIOS 12 //!< Values in this inclusive range are reserved for operating system-specific semantics
+#define STB_LOPROC 13 //!< Values in this inclusive range are reserved for processor-specific semantics
+#define STB_HIPROC 15 //!< Values in this inclusive range are reserved for processor-specific semantics
+
+/* st_info (symbol type) */
+#define STT_NOTYPE 0 //!< The symbol's type is not specified
+#define STT_OBJECT 1 //!< The symbol is associated with a data object, such as a variable, an array, and so on
+#define STT_FUNC 2 //!< The symbol is associated with a function or other executable code
+#define STT_SECTION 3 //!< The symbol is associated with a section
+#define STT_FILE 4 //!< Conventionally, the symbol's name gives the name of the source file associated with the object file
+#define STT_COMMON 5 //!< The symbol labels an uninitialized common block
+#define STT_TLS 6 //!< The symbol specifies a Thread-Local Storage entity
+#define STT_LOOS 10 //!< Values in this inclusive range are reserved for operating system-specific semantics
+#define STT_HIOS 12 //!< Values in this inclusive range are reserved for operating system-specific semantics
+#define STT_LOPROC 13 //!< Values in this inclusive range are reserved for processor-specific semantics
+#define STT_HIPROC 15 //!< Values in this inclusive range are reserved for processor-specific semantics
+
+/*
+ * st_other
+ */
+#define ELF32_ST_VISIBILITY(o) ((o)&0x3)
+#define ELF64_ST_VISIBILITY(o) ((o)&0x3)
+
+
+#define STV_DEFAULT 0 //!< The visibility of symbols with the STV_DEFAULT attribute is as specified by the symbol's binding type
+#define STV_INTERNAL 1 //!< A symbol defined in the current component is protected if it is visible in other components but not preemptable, meaning that any reference to such a symbol from within the defining component must be resolved to the definition in that component, even if there is a definition in another component that would preempt by the default rules
+#define STV_HIDDEN 2 //!< A symbol defined in the current component is hidden if its name is not visible to other components
+#define STV_PROTECTED 3 //!< The meaning of this visibility attribute may be defined by processor supplements to further constrain hidden symbols
+
+
+/*********************************************
+ * Relocation
+ *********************************************/
+typedef struct
+{
+ Elf32_Addr r_offset; //!< This member gives the location at which to apply the relocation action
+ Elf32_Word r_info; //!< This member gives both the symbol table index with respect to which the relocation must be made, and the type of relocation to apply
+} Elf32_Rel; //!< 32bits Relocation Entries
+
+typedef struct
+{
+ Elf64_Addr r_offset; //!< This member gives the location at which to apply the relocation action
+ Elf64_Xword r_info; //!< This member gives both the symbol table index with respect to which the relocation must be made, and the type of relocation to apply
+} Elf64_Rel; //!< 32bits Relocation Entries
+
+typedef struct
+{
+ Elf32_Addr r_offset; //!< This member gives the location at which to apply the relocation action
+ Elf32_Word r_info; //!< This member gives both the symbol table index with respect to which the relocation must be made, and the type of relocation to apply
+ Elf32_Sword r_addend; //!< This member specifies a constant addend used to compute the value to be stored into the relocatable field
+} Elf32_Rela; //!< 32bits Relocation Addend Entries
+
+typedef struct
+{
+ Elf64_Addr r_offset; //!< This member gives the location at which to apply the relocation action
+ Elf64_Xword r_info; //!< This member gives both the symbol table index with respect to which the relocation must be made, and the type of relocation to apply
+ Elf64_Sxword r_addend; //!< This member specifies a constant addend used to compute the value to be stored into the relocatable field
+} Elf64_Rela; //!< 32bits Relocation Addend Entries
+
+
+/*
+ * r_info
+ */
+#define ELF32_R_SYM(i) ((i)>>8)
+#define ELF32_R_TYPE(i) ((unsigned char)(i))
+#define ELF32_R_INFO(s,t) (((s)<<8)+(unsigned char)(t))
+
+#define ELF64_R_SYM(i) ((i)>>32)
+#define ELF64_R_TYPE(i) ((i)&0xffffffffL)
+#define ELF64_R_INFO(s,t) (((s)<<32)+((t)&0xffffffffL))
+
+
+
+/*********************************************
+ * Program
+ *********************************************/
+typedef struct
+{
+ Elf32_Word p_type; //!< This member tells what kind of segment this array element describes or how to interpret the array element's information
+ Elf32_Off p_offset; //!< This member gives the offset from the beginning of the file at which the first byte of the segment resides
+ Elf32_Addr p_vaddr; //!< This member gives the virtual address at which the first byte of the segment resides in memory
+ Elf32_Addr p_paddr; //!< On systems for which physical addressing is relevant, this member is reserved for the segment's physical address
+ Elf32_Word p_filesz; //!< This member gives the number of bytes in the file image of the segment; it may be zero
+ Elf32_Word p_memsz; //!< This member gives the number of bytes in the memory image of the segment; it may be zero
+ Elf32_Word p_flags; //!< This member gives flags relevant to the segment
+ Elf32_Word p_align; //!< As ``Program Loading'' describes in this chapter of the processor supplement, loadable process segments must have congruent values for p_vaddr and p_offset, modulo the page size
+} Elf32_Phdr; //!< 32bits Program header
+
+typedef struct
+{
+ Elf64_Word p_type; //!< This member tells what kind of segment this array element describes or how to interpret the array element's information
+ Elf64_Word p_flags; //!< This member gives flags relevant to the segment
+ Elf64_Off p_offset; //!< This member gives the offset from the beginning of the file at which the first byte of the segment resides
+ Elf64_Addr p_vaddr; //!< This member gives the virtual address at which the first byte of the segment resides in memory
+ Elf64_Addr p_paddr; //!< On systems for which physical addressing is relevant, this member is reserved for the segment's physical address
+ Elf64_Xword p_filesz; //!< This member gives the number of bytes in the file image of the segment; it may be zero
+ Elf64_Xword p_memsz; //!< This member gives the number of bytes in the memory image of the segment; it may be zero
+ Elf64_Xword p_align; //!< As ``Program Loading'' describes in this chapter of the processor supplement, loadable process segments must have congruent values for p_vaddr and p_offset, modulo the page size
+} Elf64_Phdr; //!< 64bits Program header
+
+/*
+ * p_type
+ */
+#define PT_NULL 0 //!< The array element is unused; other members' values are undefined
+#define PT_LOAD 1 //!< The array element specifies a loadable segment, described by p_filesz and p_memsz
+#define PT_DYNAMIC 2 //!< The array element specifies dynamic linking information
+#define PT_INTERP 3 //!< The array element specifies the location and size of a null-terminated path name to invoke as an interpreter
+#define PT_NOTE 4 //!< The array element specifies the location and size of auxiliary information
+#define PT_SHLIB 5 //!< This segment type is reserved but has unspecified semantics
+#define PT_PHDR 6 //!< The array element, if present, specifies the location and size of the program header table itself, both in the file and in the memory image of the program
+#define PT_TLS 7 //!< The array element specifies the Thread-Local Storage template
+#define PT_LOOS 0x60000000 //!< Values in this inclusive range are reserved for operating system-specific semantics
+#define PT_HIOS 0x6fffffff //!< Values in this inclusive range are reserved for operating system-specific semantics
+#define PT_LOPROC 0x70000000 //!< Values in this inclusive range are reserved for processor-specific semantics
+#define PT_HIPROC 0x7fffffff //!< Values in this inclusive range are reserved for processor-specific semantics
+
+/*
+ * p_flags
+ */
+#define PF_X (1 << 0) //!< Execute
+#define PF_W (1 << 1) //!< Write
+#define PF_R (1 << 2) //!< Read
+#define PF_MASKOS 0x0ff00000 //!< Unspecified
+#define PF_MASKPROC 0xf0000000 //!< Unspecified
+
+#endif
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/inc/elfapi.h b/drivers/staging/nmf-cm/cm/engine/elf/inc/elfapi.h
new file mode 100644
index 00000000000..cce6d158b4e
--- /dev/null
+++ b/drivers/staging/nmf-cm/cm/engine/elf/inc/elfapi.h
@@ -0,0 +1,125 @@
+/*
+ * 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.
+ */
+/*!
+ * \internal
+ * \brief Elf loder internal methods.
+ *
+ * \defgroup ELFLOADER MMDSP ELF loader.
+ */
+#ifndef __INC_CM_ELFLOADER_H
+#define __INC_CM_ELFLOADER_H
+
+#include <cm/engine/elf/inc/common.h>
+
+/*!
+ * \internal
+ * \brief ELF Parsing & checking
+ * \ingroup ELFLOADER
+ */
+t_cm_error cm_ELF_CheckFile(
+ const char *elfdata,
+ t_bool temporaryDescription,
+ t_elfdescription **elfhandlePtr);
+
+void cm_ELF_ReleaseDescription(
+ t_uint32 requireNumber, t_interface_require *requires,
+ t_uint32 attributeNumber, t_attribute *attributes,
+ t_uint32 propertyNumber, t_property *properties,
+ t_uint32 provideNumber, t_interface_provide *provides);
+
+/*!
+ * \internal
+ * \brief ELF closing
+ * \ingroup ELFLOADER
+ */
+void cm_ELF_CloseFile(
+ t_bool temporaryDescription,
+ t_elfdescription *elfhandle);
+
+/*!
+ * \internal
+ * \brief Load a component template shared memories.
+ *
+ * \note In case of error, part of memory could have been allocated and must be free by calling cm_DSPABI_FreeTemplate.
+ */
+t_cm_error cm_ELF_LoadTemplate(
+ t_cm_domain_id domainId,
+ t_elfdescription *elfhandle,
+ t_memory_handle sharedMemories[NUMBER_OF_MMDSP_MEMORY],
+ t_bool isSingleton);
+
+/*!
+ * \internal
+ * \brief Clean cache memory of a component template shared code.
+ */
+void cm_ELF_FlushTemplate(
+ t_nmf_core_id coreId,
+ t_memory_handle sharedMemories[NUMBER_OF_MMDSP_MEMORY]);
+
+void cm_ELF_FlushInstance(
+ t_nmf_core_id coreId,
+ t_memory_handle sharedMemories[NUMBER_OF_MMDSP_MEMORY],
+ t_memory_handle privateMemories[NUMBER_OF_MMDSP_MEMORY]);
+
+/*!
+ * \internal
+ * \brief Load a component instance private memories.
+ *
+ * \note In case of error, part of memory could have been allocated and must be free by calling cm_DSPABI_FreeInstance.
+ */
+t_cm_error cm_ELF_LoadInstance(
+ t_cm_domain_id domainId,
+ t_elfdescription *elfhandle,
+ t_memory_handle sharedMemories[NUMBER_OF_MMDSP_MEMORY],
+ t_memory_handle privateMemories[NUMBER_OF_MMDSP_MEMORY],
+ t_bool isSingleton);
+
+void cm_ELF_FreeInstance(
+ t_nmf_core_id coreId,
+ t_memory_handle sharedMemories[NUMBER_OF_MMDSP_MEMORY],
+ t_memory_handle privateMemories[NUMBER_OF_MMDSP_MEMORY]);
+void cm_ELF_FreeTemplate(
+ t_nmf_core_id coreId,
+ t_memory_handle sharedMemories[NUMBER_OF_MMDSP_MEMORY]);
+
+
+t_cm_error cm_ELF_relocateSharedSegments(
+ t_memory_handle *memories,
+ t_elfdescription *elfhandle,
+ void *cbContext);
+t_cm_error cm_ELF_relocatePrivateSegments(
+ t_memory_handle *memories,
+ t_elfdescription *elfhandle,
+ void *cbContext);
+void cm_ELF_performRelocation(
+ t_uint32 type,
+ const char *symbol_name,
+ t_uint32 symbol_addr,
+ char *reloc_addr);
+t_cm_error cm_ELF_GetMemory(
+ t_elfdescription *elf,
+ t_tmp_elfdescription *elftmp,
+ t_uint32 address,
+ t_memory_purpose purpose,
+ t_memory_reference *memory);
+
+
+#include <cm/engine/component/inc/component_type.h>
+
+t_cm_error cm_DSPABI_AddLoadMap(
+ t_cm_domain_id domainId,
+ const char* templateName,
+ const char* localname,
+ t_memory_handle *memories,
+ void *componentHandle);
+t_cm_error cm_DSPABI_RemoveLoadMap(
+ t_cm_domain_id domainId,
+ const char* templateName,
+ t_memory_handle *memories,
+ const char* localname,
+ void *componentHandle);
+
+#endif
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/inc/memory.h b/drivers/staging/nmf-cm/cm/engine/elf/inc/memory.h
new file mode 100644
index 00000000000..9eab94f173c
--- /dev/null
+++ b/drivers/staging/nmf-cm/cm/engine/elf/inc/memory.h
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+/*!
+ * \internal
+ * \brief Elf memory.
+ */
+#ifndef __INC_CM_ELF_MEMORY_H
+#define __INC_CM_ELF_MEMORY_H
+
+#include <cm/engine/dsp/inc/dsp.h>
+
+/**
+ * \brief Memory identifier
+ */
+typedef t_uint8 t_memory_id;
+
+/**
+ * \brief Memory property
+ */
+typedef enum {
+ MEM_FOR_MULTIINSTANCE,
+ MEM_FOR_SINGLETON,
+ MEM_FOR_LAST
+} t_instance_property;
+
+/**
+ * \brief Memory prupose (for processor with different address space for code and data/
+ */
+typedef enum {
+ MEM_CODE,
+ MEM_DATA
+} t_memory_purpose;
+
+/**
+ * \brief Memory property
+ */
+typedef enum {
+ MEM_PRIVATE,
+ MEM_SHARABLE,
+} t_memory_property;
+
+/**
+ * \brief Elf memory mapping description
+ */
+typedef struct
+{
+ t_memory_id id;
+ t_dsp_memory_type_id dspMemType;
+ t_uint32 startAddr;
+ t_cm_memory_alignment memAlignement;
+ t_memory_property property;
+ t_memory_purpose purpose;
+ t_uint8 fileEntSize;
+ t_uint8 memEntSize;
+ char* memoryName;
+} t_elfmemory;
+
+#define NUMBER_OF_MMDSP_MEMORY 15
+
+/*
+ * \brief Elf segment description
+ */
+typedef struct {
+ // Data in Bytes
+ t_uint32 sumSize;
+ t_bool sumSizeSetted;
+ t_cm_logical_address hostAddr; // Valid only if section Load in memory
+ t_uint32 maxAlign;
+ // Data in word
+ t_uint32 mpcAddr; // Valid only if section Load in memory
+} t_elfSegment;
+
+
+#endif
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/inc/mmdsp-loadmap.h b/drivers/staging/nmf-cm/cm/engine/elf/inc/mmdsp-loadmap.h
new file mode 100644
index 00000000000..bb65c0b1244
--- /dev/null
+++ b/drivers/staging/nmf-cm/cm/engine/elf/inc/mmdsp-loadmap.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+/*!
+ * \internal
+ * \brief Elf writer internal methods.
+ *
+ * \defgroup LOADMAP MMDSP ELF writer (a linker in fact).
+ */
+#ifndef __INC_CM_LOADMAP_H
+#define __INC_CM_LOADMAP_H
+
+#include <cm/inc/cm_type.h>
+
+/*
+ * Align with loadmap :
+ * https://codex.cro.st.com/wiki/index.php?pagename=Specification%2FLoadmap%2Fv1.2&group_id=310
+ */
+#define LOADMAP_MAGIC_NUMBER 0xFBBF
+
+#define LOADMAP_VERSION_MSB 1
+#define LOADMAP_VERSION_LSB 2
+
+struct LoadMapItem
+{
+ const char* pSolibFilename; // Filename of shared library object
+ void* pAddrProg; // Load address of program section
+ void* pAddrEmbProg; // Load address of embedded program section
+ void* pThis; // Data base address of component instance
+ void* pARMThis; // ARM component debug ID
+ const char* pComponentName; // Pretty name of the component instance, NULL if none.
+ struct LoadMapItem* pNextItem;// Pointer on the next list item, NULL if last one.
+ void* pXROM; // Start address of XROM
+ void* pYROM; // Start address of YROM
+};
+
+struct LoadMapHdr
+{
+ t_uint16 nMagicNumber; // Equal to 0xFBBF.
+ t_uint16 nVersion; // The version of the load map format.
+ t_uint32 nRevision; // A counter incremented at each load map list modification.
+ struct LoadMapItem* pFirstItem;// Pointer on the first item, NULL if no shared library loaded.
+};
+
+#endif /* __INC_CM_LOADMAP_H */
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/inc/mmdsp.h b/drivers/staging/nmf-cm/cm/engine/elf/inc/mmdsp.h
new file mode 100644
index 00000000000..1662def6c1a
--- /dev/null
+++ b/drivers/staging/nmf-cm/cm/engine/elf/inc/mmdsp.h
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+/*!
+ * \internal
+ * \brief MMDSP elf.
+ */
+#ifndef __INC_CM_ELF_MMDSP_H
+#define __INC_CM_ELF_MMDSP_H
+
+#include <cm/engine/elf/inc/common.h>
+
+#define CODE_MEMORY_INDEX 0
+#define ECODE_MEMORY_INDEX 7
+
+#define XROM_MEMORY_INDEX 1
+#define YROM_MEMORY_INDEX 2
+#define PRIVATE_DATA_MEMORY_INDEX 8
+#define SHARE_DATA_MEMORY_INDEX 1
+
+/*
+ * Relocation
+ */
+#define R_MMDSP_IMM16 5
+#define R_MMDSP_IMM20_16 6
+#define R_MMDSP_IMM20_4 7
+#define R_MMDSP_24 13
+
+#endif
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/inc/mpcal.h b/drivers/staging/nmf-cm/cm/engine/elf/inc/mpcal.h
new file mode 100644
index 00000000000..718b7f61ceb
--- /dev/null
+++ b/drivers/staging/nmf-cm/cm/engine/elf/inc/mpcal.h
@@ -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.
+ */
+/*!
+ * \internal
+ * \brief MPC Abraction Layer.
+ *
+ * \defgroup MPCAL MPC Abraction Layer.
+ */
+#ifndef __INC_CM_DSP_MPCAL_H
+#define __INC_CM_DSP_MPCAL_H
+
+#include <cm/inc/cm_type.h>
+#include <share/inc/nmf.h>
+
+#include <cm/engine/elf/inc/common.h>
+
+#endif
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/inc/reloc.h b/drivers/staging/nmf-cm/cm/engine/elf/inc/reloc.h
new file mode 100644
index 00000000000..b38be48d689
--- /dev/null
+++ b/drivers/staging/nmf-cm/cm/engine/elf/inc/reloc.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+/*!
+ * \internal
+ * \brief Elf relocation.
+ */
+#ifndef __INC_CM_ELF_RELOC_H
+#define __INC_CM_ELF_RELOC_H
+
+
+void MMDSP_performRelocation(
+ t_uint32 type,
+ const char* symbol_name,
+ t_uint32 symbol_addr,
+ char* reloc_addr,
+ const char* inPlaceAddr,
+ t_uint32 reloc_offset);
+
+/*
+ *
+ * Return:
+ * 0x0 returned if symbol not found
+ * 0xFFFFFFFE returned if out of memory
+ * 0xFFFFFFFF returned if symbol found in static required binding
+ */
+typedef t_uint32 (*CBresolvSymbol)(
+ void* context,
+ t_uint32 type,
+ const char* symbolName,
+ char* reloc_addr);
+
+#endif
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/src/elf64.c b/drivers/staging/nmf-cm/cm/engine/elf/src/elf64.c
new file mode 100644
index 00000000000..2e0f5928ffd
--- /dev/null
+++ b/drivers/staging/nmf-cm/cm/engine/elf/src/elf64.c
@@ -0,0 +1,47 @@
+/*
+ * 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/elf/inc/common.h>
+#include <cm/engine/elf/inc/elfabi.h>
+
+#include <cm/engine/utils/inc/swap.h>
+#include <cm/engine/trace/inc/trace.h>
+
+typedef Elf64_Half ElfXX_Half;
+typedef Elf64_Word ElfXX_Word;
+typedef Elf64_Addr ElfXX_Addr;
+typedef Elf64_Off ElfXX_Off;
+
+typedef Elf64_Xword ElfXX_Xword;
+
+typedef Elf64_Ehdr ElfXX_Ehdr;
+typedef Elf64_Shdr ElfXX_Shdr;
+typedef Elf64_Sym ElfXX_Sym;
+typedef Elf64_Rela ElfXX_Rela;
+
+#undef ELFXX_R_SYM
+#define ELFXX_R_SYM ELF64_R_SYM
+#undef ELFXX_R_TYPE
+#define ELFXX_R_TYPE ELF64_R_TYPE
+#undef ELFXX_R_INFO
+#define ELFXX_R_INFO ELF64_R_INFO
+
+// TODO Here we assume big endian (MMDSP !)
+static Elf64_Half swapHalf(Elf64_Half half)
+{
+ return (Elf64_Half)swap16(half);
+}
+
+static Elf64_Word swapWord(Elf64_Word word)
+{
+ return (Elf64_Word)swap32(word);
+}
+
+static Elf64_Xword swapXword(Elf64_Xword xword)
+{
+ return (Elf64_Xword)swap64(xword);
+}
+
+#include "elfxx.c"
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/src/elfload.c b/drivers/staging/nmf-cm/cm/engine/elf/src/elfload.c
new file mode 100644
index 00000000000..274a1b6b59f
--- /dev/null
+++ b/drivers/staging/nmf-cm/cm/engine/elf/src/elfload.c
@@ -0,0 +1,773 @@
+/*
+ * 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/elf/inc/elfapi.h>
+#include <cm/engine/elf/inc/mpcal.h>
+#include <cm/inc/cm_def.h>
+
+//#include <cm/engine/component/inc/introspection.h>
+
+#include <cm/engine/utils/inc/mem.h>
+#include <cm/engine/trace/inc/trace.h>
+#include <cm/engine/utils/inc/swap.h>
+#include <cm/engine/utils/inc/string.h>
+
+static void* getElfHeaderReference(t_tmp_elfdescription *elftmp, void* hdrref)
+{
+ if(hdrref != NULL)
+ return (void*)((int)swap32((t_uint32)hdrref) + (int)elftmp->elfheader);
+ else
+ return NULL;
+}
+
+static t_dup_char copyElfString(t_tmp_elfdescription *elftmp, char* idx)
+{
+ return cm_StringDuplicate((char*)getElfHeaderReference(elftmp, (void*)idx));
+}
+
+static t_cm_error getMemoryOffset(
+ t_elfdescription *elfhandle,
+ t_tmp_elfdescription *elftmp,
+ t_memory_purpose purpose,
+ const t_uint32 *addressInNmf,
+ t_memory_reference *memory) {
+
+ if(elftmp->isExecutable) {
+ return cm_ELF_GetMemory(elfhandle, elftmp,
+ swap32(*addressInNmf),
+ purpose,
+ memory);
+ } else {
+ return ELF64_getRelocationMemory(elfhandle, elftmp,
+ (t_uint32)addressInNmf - (t_uint32)elftmp->elfheader,
+ memory);
+ }
+}
+
+static t_cm_error getAdressForExecutableOffsetElsewhere(
+ t_elfdescription *elfhandle,
+ t_tmp_elfdescription *elftmp,
+ const t_uint32 *addressInNmf,
+ t_memory_reference *memory) {
+ t_uint32 address;
+
+ address = swap32(*addressInNmf);
+ if(address == 0xFFFFFFFF)
+ {
+ memory->offset = 0x0;
+ memory->memory = NULL;
+ return CM_OK;
+ }
+
+ if(elftmp->isExecutable)
+ {
+ memory->offset = address;
+ memory->memory = NULL;
+ return CM_OK;
+ }
+
+ // Error log in elfhandle by previous call will be check in loadTemplate
+ return ELF64_getRelocationMemory(elfhandle, elftmp,
+ (t_uint32)addressInNmf - (t_uint32)elftmp->elfheader,
+ memory);
+}
+
+/*
+ * Interface Management
+ */
+static t_interface_description* interfaceList = NULL;
+
+static t_interface_description* getInterfaceDescription(t_tmp_elfdescription *elftmp, t_elf_interface_description* elfitf) {
+ t_dup_char itfType;
+ t_interface_description* itf;
+ int i;
+
+ itfType = copyElfString(elftmp, elfitf->type);
+ if(itfType == NULL)
+ return NULL;
+
+ // Search if interfane already loaded
+ for(itf = interfaceList; itf != NULL; itf = itf->next) {
+ if(itf->type == itfType) {
+ if (itf->methodNumber != elfitf->methodNumber) {
+ ERROR("When loading component template %s:\n\tNumber of methods in interface type %s\n\tdiffers from previous declaration: was %d, found %d\n",
+ getElfHeaderReference(elftmp, (void*)elftmp->elfheader->templateName), itfType, itf->methodNumber, elfitf->methodNumber, 0, 0);
+ //Do not fail for now for compatibility reason
+ //goto out_itf_type;
+ }
+ if (cmIntensiveCheckState) {
+ for(i = 0; i < itf->methodNumber; i++) {
+ if (cm_StringCompare(itf->methodNames[i], getElfHeaderReference(elftmp, (void*)elfitf->methodNames[i]), MAX_INTERNAL_STRING_LENGTH) != 0) {
+ ERROR("When loading component template %s:\n"
+ "\tName of method number %d in interface type %s\n"
+ "\tdiffers from previous declaration: previous name was %s, new name found is %s\n",
+ getElfHeaderReference(elftmp, (void*)elftmp->elfheader->templateName), i,
+ itfType, itf->methodNames[i],
+ getElfHeaderReference(elftmp, (void*)elfitf->methodNames[i]), 0);
+ //Do not fail for now for compatibility reason
+ //goto out_itf_type;
+ }
+ }
+ }
+ itf->referenceCounter++;
+ cm_StringRelease(itfType);
+ return itf;
+ }
+ }
+
+ // Create a new interface if not exists
+ itf = (t_interface_description*)OSAL_Alloc_Zero(sizeof(t_interface_description) + sizeof(t_dup_char) * (elfitf->methodNumber - 1));
+ if(itf == NULL)
+ goto out_itf_type;
+ itf->referenceCounter = 1;
+ itf->type = itfType;
+ itf->methodNumber = elfitf->methodNumber;
+ for(i = 0; i < itf->methodNumber; i++) {
+ itf->methodNames[i] = copyElfString(elftmp, elfitf->methodNames[i]);
+ if(itf->methodNames[i] == NULL)
+ goto out_method;
+ }
+
+ // Put it in Top
+ itf->next = interfaceList;
+ interfaceList = itf;
+
+ return itf;
+
+out_method:
+ for(i = 0; i < itf->methodNumber; i++)
+ cm_StringRelease(itf->methodNames[i]);
+ OSAL_Free(itf);
+out_itf_type:
+ cm_StringRelease(itfType);
+ return NULL;
+}
+
+static void releaseInterfaceDescription(t_interface_description* itf) {
+ if(itf == NULL)
+ return;
+
+ if(--itf->referenceCounter == 0) {
+ int i;
+
+ // Remove it from list
+ if(interfaceList == itf) {
+ interfaceList = interfaceList->next;
+ } else {
+ t_interface_description* prev = interfaceList;
+ while(prev->next != itf)
+ prev = prev->next;
+ prev->next = itf->next;
+ }
+
+ // Destroy interface description
+ for(i = 0; i < itf->methodNumber; i++) {
+ cm_StringRelease(itf->methodNames[i]);
+ }
+ cm_StringRelease(itf->type);
+ OSAL_Free(itf);
+ }
+}
+
+
+t_cm_error cm_ELF_CheckFile(
+ const char *elfdata,
+ t_bool temporaryDescription,
+ t_elfdescription **elfhandlePtr)
+{
+ t_elfdescription *elfhandle;
+ t_tmp_elfdescription elftmp;
+ t_cm_error error;
+ t_uint32 version;
+ t_uint32 compatibleVersion;
+ int i, j, k;
+
+ /*
+ * Sanity check
+ */
+ if (elfdata[EI_MAG0] != ELFMAG0 ||
+ elfdata[EI_MAG1] != ELFMAG1 ||
+ elfdata[EI_MAG2] != ELFMAG2 ||
+ elfdata[EI_MAG3] != ELFMAG3 ||
+ elfdata[EI_CLASS] != ELFCLASS64)
+ {
+ ERROR("CM_INVALID_ELF_FILE: component file is not a MMDSP ELF file\n", 0, 0, 0, 0, 0, 0);
+ return CM_INVALID_ELF_FILE;
+ }
+
+ /*
+ * Create elf data
+ */
+ if((error = ELF64_LoadComponent(EM_MMDSP_PLUS, elfdata, elfhandlePtr, &elftmp)) != CM_OK)
+ return error;
+
+ elfhandle = *elfhandlePtr;
+
+ elfhandle->temporaryDescription = temporaryDescription;
+
+ version = swap32(elftmp.elfheader->nmfVersion);
+
+ compatibleVersion = (VERSION_MAJOR(version) == VERSION_MAJOR(NMF_VERSION));
+ if(compatibleVersion)
+ {
+ switch(VERSION_MINOR(NMF_VERSION))
+ {
+ case 10: // Compatible with 2.9, 2.10
+ compatibleVersion =
+ (VERSION_MINOR(version) == 9) ||
+ (VERSION_MINOR(version) == 10);
+ break;
+ default: // Strict compatibility 2.x == 2.x
+ compatibleVersion = (VERSION_MINOR(version) == VERSION_MINOR(NMF_VERSION));
+ }
+ }
+
+ if(! compatibleVersion)
+ {
+ ERROR("CM_INVALID_ELF_FILE: incompatible version for Component %d.%d.x != CM:%d.%d.x\n",
+ VERSION_MAJOR(version), VERSION_MINOR(version),
+ VERSION_MAJOR(NMF_VERSION), VERSION_MINOR(NMF_VERSION), 0, 0);
+ error = CM_INVALID_ELF_FILE;
+ goto onerror;
+ }
+
+
+ /*
+ * Commented since to many noise !!!!
+ if(VERSION_PATCH(version) != VERSION_PATCH(NMF_VERSION))
+ {
+ WARNING("CM_INVALID_ELF_FILE: incompatible version, Component:%d.%d.%d != CM:%d.%d.%d\n",
+ VERSION_MAJOR(version), VERSION_MINOR(version), VERSION_PATCH(version),
+ VERSION_MAJOR(NMF_VERSION), VERSION_MINOR(NMF_VERSION), VERSION_PATCH(NMF_VERSION));
+ }
+ */
+
+ if((error = ELF64_ComputeSegment(elfhandle, &elftmp)) != CM_OK)
+ goto onerror;
+
+ //
+ elfhandle->foundedTemplateName = copyElfString(&elftmp, elftmp.elfheader->templateName);
+ if(elfhandle->foundedTemplateName == NULL)
+ goto oom;
+ elfhandle->minStackSize = swap32(elftmp.elfheader->minStackSize);
+
+ // Get Life-cycle memory
+ if((error = getAdressForExecutableOffsetElsewhere(elfhandle, &elftmp, &elftmp.elfheader->LCCConstruct, &elfhandle->memoryForConstruct)) != CM_OK)
+ goto onerror;
+ if((error = getAdressForExecutableOffsetElsewhere(elfhandle, &elftmp, &elftmp.elfheader->LCCStart, &elfhandle->memoryForStart)) != CM_OK)
+ goto onerror;
+ if((error = getAdressForExecutableOffsetElsewhere(elfhandle, &elftmp, &elftmp.elfheader->LCCStop, &elfhandle->memoryForStop)) != CM_OK)
+ goto onerror;
+ if((error = getAdressForExecutableOffsetElsewhere(elfhandle, &elftmp, &elftmp.elfheader->LCCDestroy, &elfhandle->memoryForDestroy)) != CM_OK)
+ goto onerror;
+
+ // Copy attributes information
+ elfhandle->attributeNumber = swap32(elftmp.elfheader->attributeNumber);
+ if(elfhandle->attributeNumber > 0)
+ {
+ elfhandle->attributes =
+ (t_attribute*)OSAL_Alloc_Zero(sizeof(t_attribute) * elfhandle->attributeNumber);
+ if(elfhandle->attributes == NULL)
+ goto oom;
+
+ if(elfhandle->attributeNumber > 0)
+ {
+ t_elf_attribute *attributes = (t_elf_attribute*)getElfHeaderReference(&elftmp, (void*)elftmp.elfheader->attributes);
+
+ for(i = 0; i < elfhandle->attributeNumber; i++)
+ {
+ elfhandle->attributes[i].name = copyElfString(&elftmp, attributes[i].name);
+ if(elfhandle->attributes[i].name == NULL)
+ goto oom;
+
+ if((error = getMemoryOffset(elfhandle, &elftmp,
+ MEM_DATA,
+ &attributes[i].symbols,
+ &elfhandle->attributes[i].memory)) != CM_OK)
+ goto onerror;
+ LOG_INTERNAL(2, " attribute %s mem=%s offset=%x\n",
+ elfhandle->attributes[i].name,
+ elfhandle->attributes[i].memory.memory->memoryName,
+ elfhandle->attributes[i].memory.offset,
+ 0, 0, 0);
+ }
+ }
+ }
+
+ // Copy properties information
+ elfhandle->propertyNumber = swap32(elftmp.elfheader->propertyNumber);
+ if(elfhandle->propertyNumber > 0)
+ {
+ elfhandle->properties =
+ (t_property*)OSAL_Alloc_Zero(sizeof(t_property) * elfhandle->propertyNumber);
+ if(elfhandle->properties == NULL)
+ goto oom;
+
+ if(elfhandle->propertyNumber > 0)
+ {
+ t_elf_property *properties = (t_elf_property*)getElfHeaderReference(&elftmp, (void*)elftmp.elfheader->properties);
+
+ for(i = 0; i < elfhandle->propertyNumber; i++)
+ {
+ elfhandle->properties[i].name = copyElfString(&elftmp, properties[i].name);
+ if(elfhandle->properties[i].name == NULL)
+ goto oom;
+
+ elfhandle->properties[i].value = copyElfString(&elftmp, properties[i].value);
+ if(elfhandle->properties[i].value == NULL)
+ goto oom;
+
+ LOG_INTERNAL(3, " property %s = %s\n",
+ elfhandle->properties[i].name,
+ elfhandle->properties[i].value,
+ 0, 0, 0, 0);
+ }
+ }
+ }
+
+ // Copy requires information
+ elfhandle->requireNumber = swap32(elftmp.elfheader->requireNumber);
+ if(elfhandle->requireNumber > 0)
+ {
+ char *ref = getElfHeaderReference(&elftmp, (void*)elftmp.elfheader->requires);
+
+ elfhandle->requires = (t_interface_require*)OSAL_Alloc_Zero(sizeof(t_interface_require) * elfhandle->requireNumber);
+ if(elfhandle->requires == NULL)
+ goto oom;
+
+ for(i = 0; i < elfhandle->requireNumber; i++)
+ {
+ t_elf_required_interface *require = (t_elf_required_interface*)ref;
+ t_elf_interface_description *interface = (t_elf_interface_description*)getElfHeaderReference(&elftmp, (void*)require->interface);
+
+ elfhandle->requires[i].name = copyElfString(&elftmp, require->name);
+ if(elfhandle->requires[i].name == NULL)
+ goto oom;
+
+ elfhandle->requires[i].requireTypes = require->requireTypes;
+ elfhandle->requires[i].collectionSize = require->collectionSize;
+ elfhandle->requires[i].interface = getInterfaceDescription(&elftmp, interface);
+ if(elfhandle->requires[i].interface == NULL)
+ goto oom;
+
+ LOG_INTERNAL(2, " require %s <%s> %x\n",
+ elfhandle->requires[i].name,
+ elfhandle->requires[i].interface->type,
+ elfhandle->requires[i].requireTypes, 0, 0, 0);
+ CM_ASSERT(elfhandle->requires[i].collectionSize != 0);
+
+ ref = (char*)&require->indexes[0];
+
+ if((elfhandle->requires[i].requireTypes & VIRTUAL_REQUIRE) == 0 &&
+ (elfhandle->requires[i].requireTypes & STATIC_REQUIRE) == 0)
+ {
+ elfhandle->requires[i].indexes =
+ (t_interface_require_index*)OSAL_Alloc_Zero(sizeof(t_interface_require_index) * elfhandle->requires[i].collectionSize);
+ if(elfhandle->requires[i].indexes == NULL)
+ goto oom;
+
+ for(j = 0; j < elfhandle->requires[i].collectionSize; j++)
+ {
+ t_elf_interface_require_index* index = (t_elf_interface_require_index*)ref;
+
+ elfhandle->requires[i].indexes[j].numberOfClient = swap32(index->numberOfClient);
+ if(elfhandle->requires[i].indexes[j].numberOfClient != 0)
+ {
+ elfhandle->requires[i].indexes[j].memories =
+ (t_memory_reference*)OSAL_Alloc(sizeof(t_memory_reference) * elfhandle->requires[i].indexes[j].numberOfClient);
+ if(elfhandle->requires[i].indexes[j].memories == NULL)
+ goto oom;
+
+ for(k = 0; k < elfhandle->requires[i].indexes[j].numberOfClient; k++) {
+ if((error = getMemoryOffset(elfhandle,&elftmp,
+ MEM_DATA,
+ &index->symbols[k],
+ &elfhandle->requires[i].indexes[j].memories[k])) != CM_OK)
+ goto onerror;
+ LOG_INTERNAL(2, " [%d, %d] mem=%s offset=%x\n",
+ j, k,
+ elfhandle->requires[i].indexes[j].memories[k].memory->memoryName,
+ elfhandle->requires[i].indexes[j].memories[k].offset,
+ 0, 0);
+ }
+ }
+
+ ref += sizeof(index->numberOfClient) + elfhandle->requires[i].indexes[j].numberOfClient * sizeof(index->symbols[0]);
+ }
+ }
+ }
+ }
+
+ // Copy provides informations
+ elfhandle->provideNumber = swap32(elftmp.elfheader->provideNumber);
+ if(elfhandle->provideNumber != 0)
+ {
+ elfhandle->provides =
+ (t_interface_provide*)OSAL_Alloc_Zero(sizeof(t_interface_provide) * elfhandle->provideNumber);
+ if(elfhandle->provides == NULL)
+ goto oom;
+
+ if(elfhandle->provideNumber > 0)
+ {
+ char *ref = getElfHeaderReference(&elftmp, (void*)elftmp.elfheader->provides);
+
+ for(i = 0; i < elfhandle->provideNumber; i++)
+ {
+ t_elf_provided_interface *provide = (t_elf_provided_interface*)ref;
+ t_elf_interface_description *interface = (t_elf_interface_description*)getElfHeaderReference(&elftmp, (void*)provide->interface);
+
+ elfhandle->provides[i].name = copyElfString(&elftmp, provide->name);
+ if(elfhandle->provides[i].name == NULL)
+ goto oom;
+
+ elfhandle->provides[i].provideTypes = provide->provideTypes;
+ elfhandle->provides[i].interruptLine = provide->interruptLine;
+ elfhandle->provides[i].collectionSize = provide->collectionSize;
+ elfhandle->provides[i].interface = getInterfaceDescription(&elftmp, interface);
+ if(elfhandle->provides[i].interface == NULL)
+ goto oom;
+
+ LOG_INTERNAL(2, " provide %s <%s>\n",
+ elfhandle->provides[i].name,
+ elfhandle->provides[i].interface->type,
+ 0,0, 0, 0);
+ CM_ASSERT(elfhandle->provides[i].collectionSize != 0);
+
+ ref = (char*)&provide->methodSymbols[0];
+
+ {
+ t_uint32 *methodSymbols = (t_uint32*)ref;
+
+ elfhandle->provides[i].indexes = (t_interface_provide_index**)OSAL_Alloc_Zero(
+ sizeof(t_interface_provide_index*) * elfhandle->provides[i].collectionSize);
+ if(elfhandle->provides[i].indexes == NULL)
+ goto oom;
+
+ if(elfhandle->provides[i].interface->methodNumber != 0)
+ {
+ for(j = 0; j < elfhandle->provides[i].collectionSize; j++)
+ {
+ elfhandle->provides[i].indexes[j] = (t_interface_provide_index*)OSAL_Alloc(
+ sizeof(t_interface_provide_index) * elfhandle->provides[i].interface->methodNumber);
+ if(elfhandle->provides[i].indexes[j] == NULL)
+ goto oom;
+
+ for(k = 0; k < elfhandle->provides[i].interface->methodNumber; k++)
+ {
+ if((error = getAdressForExecutableOffsetElsewhere(elfhandle, &elftmp,
+ methodSymbols++,
+ &elfhandle->provides[i].indexes[j][k].memory)) != CM_OK)
+ goto onerror;
+
+ if(elfhandle->provides[i].indexes[j][k].memory.memory != NULL)
+ LOG_INTERNAL(2, " [%d, %d] method '%s' mem=%s offset=%x\n",
+ j, k,
+ elfhandle->provides[i].interface->methodNames[k],
+ elfhandle->provides[i].indexes[j][k].memory.memory->memoryName,
+ elfhandle->provides[i].indexes[j][k].memory.offset,
+ 0);
+ else
+ LOG_INTERNAL(2, " [%d, %d] method '%s' address=%x\n",
+ j, k,
+ elfhandle->provides[i].interface->methodNames[k],
+ elfhandle->provides[i].indexes[j][k].memory.offset,
+ 0, 0);
+ }
+ }
+ }
+
+ ref += elfhandle->provides[i].collectionSize * elfhandle->provides[i].interface->methodNumber * sizeof(methodSymbols[0]);
+ }
+ }
+ }
+ }
+
+ return CM_OK;
+
+oom:
+ error = CM_NO_MORE_MEMORY;
+onerror:
+ cm_ELF_CloseFile(temporaryDescription, elfhandle);
+ *elfhandlePtr = NULL;
+ return error;
+}
+
+void cm_ELF_ReleaseDescription(
+ t_uint32 requireNumber, t_interface_require *requires,
+ t_uint32 attributeNumber, t_attribute *attributes,
+ t_uint32 propertyNumber, t_property *properties,
+ t_uint32 provideNumber, t_interface_provide *provides)
+{
+ int i, j;
+
+ // Free provides (Number set when array allocated)
+ if(provides != NULL)
+ {
+ for(i = 0; i < provideNumber; i++)
+ {
+ if(provides[i].indexes != NULL)
+ {
+ for(j = 0; j < provides[i].collectionSize; j++)
+ {
+ OSAL_Free(provides[i].indexes[j]);
+ }
+ OSAL_Free(provides[i].indexes);
+ }
+ releaseInterfaceDescription(provides[i].interface);
+ cm_StringRelease(provides[i].name);
+ }
+ OSAL_Free(provides);
+ }
+
+ // Free requires (Number set when array allocated)
+ if(requires != NULL)
+ {
+ for(i = 0; i < requireNumber; i++)
+ {
+ if(requires[i].indexes != 0)
+ {
+ for(j = 0; j < requires[i].collectionSize; j++)
+ {
+ OSAL_Free(requires[i].indexes[j].memories);
+ }
+ OSAL_Free(requires[i].indexes);
+ }
+ releaseInterfaceDescription(requires[i].interface);
+ cm_StringRelease(requires[i].name);
+ }
+ OSAL_Free(requires);
+ }
+
+ // Free properties (Number set when array allocated)
+ if(properties != NULL)
+ {
+ for(i = 0; i < propertyNumber; i++)
+ {
+ cm_StringRelease(properties[i].value);
+ cm_StringRelease(properties[i].name);
+ }
+ OSAL_Free(properties);
+ }
+
+ // Free Attributes (Number set when array allocated)
+ if(attributes != NULL)
+ {
+ for(i = 0; i < attributeNumber; i++)
+ {
+ cm_StringRelease(attributes[i].name);
+ }
+ OSAL_Free(attributes);
+ }
+}
+
+void cm_ELF_CloseFile(
+ t_bool temporaryDescription,
+ t_elfdescription *elfhandle)
+{
+ if(elfhandle == NULL)
+ return;
+
+ if(temporaryDescription && ! elfhandle->temporaryDescription)
+ return;
+
+ // Release description if not moved to template
+ cm_ELF_ReleaseDescription(
+ elfhandle->requireNumber, elfhandle->requires,
+ elfhandle->attributeNumber, elfhandle->attributes,
+ elfhandle->propertyNumber, elfhandle->properties,
+ elfhandle->provideNumber, elfhandle->provides);
+
+ cm_StringRelease(elfhandle->foundedTemplateName);
+
+ ELF64_UnloadComponent(elfhandle);
+}
+
+
+static t_cm_error allocSegment(
+ t_cm_domain_id domainId,
+ t_elfdescription *elfhandle,
+ t_memory_handle memories[NUMBER_OF_MMDSP_MEMORY],
+ t_memory_property property,
+ t_bool isSingleton) {
+ t_memory_id memId;
+ const t_elfmemory *thisMemory; //!< Memory used to determine this
+ const t_elfmemory *codeMemory; //!< Memory used to determine code
+
+ MMDSP_serializeMemories(elfhandle->instanceProperty, &codeMemory, &thisMemory);
+
+ for(memId = 0; memId < NUMBER_OF_MMDSP_MEMORY; memId++)
+ {
+ const t_elfmemory* mapping;
+
+ if(elfhandle->segments[memId].sumSize == 0x0)
+ continue;
+
+ mapping = MMDSP_getMappingById(memId);
+
+ if(
+ (mapping->property == property && elfhandle->instanceProperty != MEM_FOR_SINGLETON) ||
+ (property == MEM_SHARABLE && elfhandle->instanceProperty == MEM_FOR_SINGLETON) )
+ {
+ // Allocate segment
+ memories[memId] = cm_DM_Alloc(domainId, mapping->dspMemType,
+ elfhandle->segments[memId].sumSize / mapping->fileEntSize,
+ mapping->memAlignement, TRUE);
+
+ if(memories[memId] == INVALID_MEMORY_HANDLE)
+ {
+ ERROR("CM_NO_MORE_MEMORY(%s): %x too big\n", mapping->memoryName, elfhandle->segments[memId].sumSize / mapping->fileEntSize, 0, 0, 0, 0);
+ return CM_NO_MORE_MEMORY;
+ }
+
+ // Get reference in memory
+ elfhandle->segments[memId].hostAddr = cm_DSP_GetHostLogicalAddress(memories[memId]);
+
+ cm_DSP_GetDspAddress(memories[memId], &elfhandle->segments[memId].mpcAddr);
+
+ if (isSingleton)
+ cm_DM_SetDefaultDomain(memories[memId], cm_DM_GetDomainCoreId(domainId));
+
+ // Log it
+ LOG_INTERNAL(1, "\t%s%s: 0x%x..+0x%x (0x%x)\n",
+ mapping->memoryName,
+ (thisMemory == mapping) ? "(THIS)" : "",
+ elfhandle->segments[memId].mpcAddr,
+ elfhandle->segments[memId].sumSize / mapping->fileEntSize,
+ elfhandle->segments[memId].hostAddr, 0);
+ }
+ else if(property == MEM_PRIVATE) // Since we allocate private segment, if not allocate, it's a share one
+ {
+ // In order to allow further relocation based on cached address like mpcAddr & hostAddr,
+ // initialize them also !
+
+ // Get reference in memory
+ elfhandle->segments[memId].hostAddr = cm_DSP_GetHostLogicalAddress(memories[memId]);
+
+ cm_DSP_GetDspAddress(memories[memId], &elfhandle->segments[memId].mpcAddr);
+ }
+ }
+
+ return CM_OK;
+}
+
+/*
+ * Note: in case of error, part of memory could have been allocated and must be free by calling cm_DSPABI_FreeTemplate
+ */
+t_cm_error cm_ELF_LoadTemplate(
+ t_cm_domain_id domainId,
+ t_elfdescription *elfhandle,
+ t_memory_handle sharedMemories[NUMBER_OF_MMDSP_MEMORY],
+ t_bool isSingleton)
+{
+ t_cm_error error;
+
+ if((error = allocSegment(domainId, elfhandle, sharedMemories, MEM_SHARABLE, isSingleton)) != CM_OK)
+ return error;
+
+ // Load each readonly segment
+ if((error = ELF64_loadSegment(elfhandle, sharedMemories, MEM_SHARABLE)) != CM_OK)
+ return error;
+
+ return CM_OK;
+}
+
+t_cm_error cm_ELF_LoadInstance(
+ t_cm_domain_id domainId,
+ t_elfdescription *elfhandle,
+ t_memory_handle sharedMemories[NUMBER_OF_MMDSP_MEMORY],
+ t_memory_handle privateMemories[NUMBER_OF_MMDSP_MEMORY],
+ t_bool isSingleton)
+{
+ t_memory_id memId;
+ t_cm_error error;
+
+ // Erase whole memories to make free in case of error
+ for(memId = 0; memId < NUMBER_OF_MMDSP_MEMORY; memId++)
+ {
+ privateMemories[memId] = sharedMemories[memId];
+ }
+
+ if((error = allocSegment(domainId, elfhandle, privateMemories, MEM_PRIVATE, isSingleton)) != CM_OK)
+ return error;
+
+ // Load each writable memory
+ if((error = ELF64_loadSegment(elfhandle, privateMemories, MEM_PRIVATE)) != CM_OK)
+ return error;
+
+ return CM_OK;
+}
+
+void cm_ELF_FlushTemplate(
+ t_nmf_core_id coreId,
+ t_memory_handle sharedMemories[NUMBER_OF_MMDSP_MEMORY])
+{
+ t_memory_id memId;
+
+ for(memId = 0; memId < NUMBER_OF_MMDSP_MEMORY; memId++)
+ {
+ if(sharedMemories[memId] != INVALID_MEMORY_HANDLE)
+ MMDSP_loadedSection(
+ coreId, memId,
+ sharedMemories[memId]);
+ }
+}
+
+void cm_ELF_FlushInstance(
+ t_nmf_core_id coreId,
+ t_memory_handle sharedMemories[NUMBER_OF_MMDSP_MEMORY],
+ t_memory_handle privateMemories[NUMBER_OF_MMDSP_MEMORY])
+{
+ t_memory_id memId;
+
+ for(memId = 0; memId < NUMBER_OF_MMDSP_MEMORY; memId++)
+ {
+ if(privateMemories[memId] != INVALID_MEMORY_HANDLE && privateMemories[memId] != sharedMemories[memId])
+ MMDSP_loadedSection(
+ coreId, memId,
+ privateMemories[memId]);
+ }
+}
+
+void cm_ELF_FreeInstance(
+ t_nmf_core_id coreId,
+ t_memory_handle sharedMemories[NUMBER_OF_MMDSP_MEMORY],
+ t_memory_handle privateMemories[NUMBER_OF_MMDSP_MEMORY])
+{
+ t_memory_id memId;
+
+ if(privateMemories == NULL)
+ return;
+
+ for(memId = 0; memId < NUMBER_OF_MMDSP_MEMORY; memId++)
+ {
+ if(privateMemories[memId] != INVALID_MEMORY_HANDLE && privateMemories[memId] != sharedMemories[memId])
+ {
+ MMDSP_unloadedSection(coreId, memId, privateMemories[memId]);
+ cm_DM_Free(privateMemories[memId], TRUE);
+ }
+ }
+}
+
+void cm_ELF_FreeTemplate(
+ t_nmf_core_id coreId,
+ t_memory_handle sharedMemories[NUMBER_OF_MMDSP_MEMORY])
+{
+ t_memory_id memId;
+
+ if(sharedMemories == NULL)
+ return;
+
+ for(memId = 0; memId < NUMBER_OF_MMDSP_MEMORY; memId++)
+ {
+ if(sharedMemories[memId] != INVALID_MEMORY_HANDLE)
+ {
+ MMDSP_unloadedSection(coreId, memId, sharedMemories[memId]);
+ cm_DM_Free(sharedMemories[memId], TRUE);
+ }
+ }
+}
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/src/elfmmdsp.c b/drivers/staging/nmf-cm/cm/engine/elf/src/elfmmdsp.c
new file mode 100644
index 00000000000..5f6641b188d
--- /dev/null
+++ b/drivers/staging/nmf-cm/cm/engine/elf/src/elfmmdsp.c
@@ -0,0 +1,575 @@
+/*
+ * 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/elf/inc/mmdsp.h>
+#include <cm/engine/elf/inc/bfd.h>
+#include <cm/engine/elf/inc/mpcal.h>
+
+#include <cm/engine/component/inc/initializer.h>
+
+#include <cm/engine/utils/inc/string.h>
+#include <cm/engine/utils/inc/swap.h>
+#include <cm/engine/trace/inc/trace.h>
+
+#include <cm/engine/dsp/mmdsp/inc/mmdsp_hwp.h>
+
+static const t_elfmemory mmdspMemories[NUMBER_OF_MMDSP_MEMORY] = {
+ {0, SDRAM_CODE, SDRAMTEXT_BASE_ADDR, CM_MM_ALIGN_2WORDS, MEM_SHARABLE, MEM_CODE, 8, 8, "SDRAM_CODE"}, /* 0: Program memory */
+ {1, INTERNAL_XRAM24, 0, CM_MM_ALIGN_2WORDS, MEM_SHARABLE, MEM_DATA, 3, 4, "XROM"}, /* 1: Internal X memory */
+ {2, INTERNAL_YRAM24, 0, CM_MM_ALIGN_2WORDS, MEM_SHARABLE, MEM_DATA, 3, 4, "YROM"}, /* 2: Y memory */
+ {3, SDRAM_EXT24, SDRAMMEM24_BASE_ADDR, CM_MM_ALIGN_2WORDS, MEM_SHARABLE, MEM_DATA, 3, 4, "SDR0M24"}, /* 5: SDRAM24 */
+ {4, SDRAM_EXT16, SDRAMMEM16_BASE_ADDR, CM_MM_ALIGN_2WORDS, MEM_SHARABLE, MEM_DATA, 3, 2, "SDROM16"}, /* 6: SDRAM16 */
+ {5, ESRAM_EXT24, ESRAMMEM24_BASE_ADDR, CM_MM_ALIGN_2WORDS, MEM_SHARABLE, MEM_DATA, 3, 4, "ESROM24"}, /* 8: ESRAM24 */
+ {6, ESRAM_EXT16, ESRAMMEM16_BASE_ADDR, CM_MM_ALIGN_2WORDS, MEM_SHARABLE, MEM_DATA, 3, 2, "ESROM16"}, /* 9: ESRAM16 */
+ {7, ESRAM_CODE, ESRAMTEXT_BASE_ADDR, CM_MM_ALIGN_2WORDS, MEM_SHARABLE, MEM_CODE, 8, 8, "ESRAM_CODE"}, /*10: ESRAM code */
+ {8, INTERNAL_XRAM24, 0, CM_MM_ALIGN_2WORDS, MEM_PRIVATE, MEM_DATA, 3, 4, "XRAM"}, /* 1: Internal X memory */
+ {9, INTERNAL_YRAM24, 0, CM_MM_ALIGN_2WORDS, MEM_PRIVATE, MEM_DATA, 3, 4, "YRAM"}, /* 2: Y memory */
+ {10, SDRAM_EXT24, SDRAMMEM24_BASE_ADDR, CM_MM_ALIGN_2WORDS, MEM_PRIVATE, MEM_DATA, 3, 4, "SDRAM24"}, /* 5: SDRAM24 */
+ {11, SDRAM_EXT16, SDRAMMEM16_BASE_ADDR, CM_MM_ALIGN_2WORDS, MEM_PRIVATE, MEM_DATA, 3, 2, "SDRAM16"}, /* 6: SDRAM16 */
+ {12, ESRAM_EXT24, ESRAMMEM24_BASE_ADDR, CM_MM_ALIGN_2WORDS, MEM_PRIVATE, MEM_DATA, 3, 4, "ESRAM24"}, /* 8: ESRAM24 */
+ {13, ESRAM_EXT16, ESRAMMEM16_BASE_ADDR, CM_MM_ALIGN_2WORDS, MEM_PRIVATE, MEM_DATA, 3, 2, "ESRAM16"}, /* 9: ESRAM16 */
+ {14, LOCKED_CODE, SDRAMTEXT_BASE_ADDR, CM_MM_ALIGN_2WORDS, MEM_SHARABLE, MEM_CODE, 8, 8, "LOCKED_CODE"}, /* : .locked */
+};
+
+#define MAX_ELFSECTIONNAME 10
+struct memoryMapping {
+ char *elfSectionName;
+ t_uint32 memoryIndex[MEM_FOR_LAST]; // memoryIndex[t_instance_property]
+};
+
+static const struct memoryMapping mappingmem0[] = {
+ {"mem0.0", {0, 0}},
+ {"mem0.1", {0, 0}},
+ {"mem0.2", {0, 0}}
+};
+static const struct memoryMapping mappingmem10 =
+ {"mem10", {7, 7}};
+static const struct memoryMapping mappinglocked =
+ {".locked", {14, 14}};
+static const struct memoryMapping mappingmem1[] = {
+ {"", {0xff, 0xff}},
+ {"mem1.1", {1, 1}},
+ {"mem1.2", {8, 1}},
+ {"mem1.3", {1, 1}},
+ {"mem1.4", {8, 1}},
+ {"mem1.stack", {8, 1}}
+};
+static const struct memoryMapping mappingmem2[] = {
+ {"", {0xff, 0xff}},
+ {"mem2.1", {2, 2}},
+ {"mem2.2", {9, 2}},
+ {"mem2.3", {2, 2}},
+ {"mem2.4", {9, 2}}
+};
+static const struct memoryMapping mappingmem5[] = {
+ {"", {0xff, 0xff}},
+ {"mem5.1", {3, 3}},
+ {"mem5.2", {10, 3}},
+ {"mem5.3", {3, 3}},
+ {"mem5.4", {10, 3}}
+};
+static const struct memoryMapping mappingmem6[] = {
+ {"", {0xff, 0xff}},
+ {"mem6.1", {4, 4}},
+ {"mem6.2", {11, 4}},
+ {"mem6.3", {4, 4}},
+ {"mem6.4", {11, 4}}
+};
+static const struct memoryMapping mappingmem8[] = {
+ {"", {0xff, 0xff}},
+ {"mem8.1", {5, 5}},
+ {"mem8.2", {12, 5}},
+ {"mem8.3", {5, 5}},
+ {"mem8.4", {12, 5}}
+};
+static const struct memoryMapping mappingmem9[] = {
+ {"", {0xff, 0xff}},
+ {"mem9.1", {6, 6}},
+ {"mem9.2", {13, 6}},
+ {"mem9.3", {6, 6}},
+ {"mem9.4", {13, 6}}
+};
+
+static const struct {
+ const struct memoryMapping* mapping;
+ unsigned int number;
+} hashMappings[10] = {
+ {mappingmem0, sizeof(mappingmem0) / sizeof(mappingmem0[0])},
+ {mappingmem1, sizeof(mappingmem1) / sizeof(mappingmem1[0])},
+ {mappingmem2, sizeof(mappingmem2) / sizeof(mappingmem2[0])},
+ {0x0, 0},
+ {0x0, 0},
+ {mappingmem5, sizeof(mappingmem5) / sizeof(mappingmem5[0])},
+ {mappingmem6, sizeof(mappingmem6) / sizeof(mappingmem6[0])},
+ {0x0, 0},
+ {mappingmem8, sizeof(mappingmem8) / sizeof(mappingmem8[0])},
+ {mappingmem9, sizeof(mappingmem9) / sizeof(mappingmem9[0])},
+};
+
+const t_elfmemory* MMDSP_getMappingById(t_memory_id memId)
+{
+ return &mmdspMemories[memId];
+}
+
+const t_elfmemory* MMDSP_getMappingByName(const char* sectionName, t_instance_property property)
+{
+ if(sectionName[0] == 'm' && sectionName[1] == 'e' && sectionName[2] == 'm')
+ {
+ if(sectionName[4] == '.')
+ {
+ if(sectionName[5] >= '0' && sectionName[5] <= '9')
+ {
+ if(sectionName[3] >= '0' && sectionName[3] <= '9')
+ {
+ unsigned int m, sm;
+
+ m = sectionName[3] - '0';
+ sm = sectionName[5] - '0';
+ if(sm < hashMappings[m].number)
+ return &mmdspMemories[hashMappings[m].mapping[sm].memoryIndex[property]];
+ }
+ } else if(sectionName[3] == '1' && sectionName[5] == 's')
+ return &mmdspMemories[mappingmem1[5].memoryIndex[property]];
+ }
+ else if(sectionName[3] == '1' && sectionName[4] == '0')
+ return &mmdspMemories[mappingmem10.memoryIndex[property]];
+ }
+ else if(sectionName[0] == '.' && sectionName[1] == 'l' && sectionName[2] == 'o' && sectionName[3] == 'c' &&
+ sectionName[4] == 'k' && sectionName[5] == 'e' && sectionName[6] == 'd')
+ {
+ return &mmdspMemories[mappinglocked.memoryIndex[property]];
+ }
+
+ return NULL;
+}
+
+void MMDSP_serializeMemories(t_instance_property property,
+ const t_elfmemory** codeMemory, const t_elfmemory** thisMemory) {
+ // Return meory reference
+ *codeMemory = &mmdspMemories[0];
+ if(property == MEM_FOR_SINGLETON)
+ {
+ *thisMemory = &mmdspMemories[1];
+ }
+ else
+ {
+ *thisMemory = &mmdspMemories[8];
+ }
+}
+
+void MMDSP_copyCode(t_uint64 * remoteAddr64, const char* origAddr, int nb)
+{
+ int m;
+
+ // Linux allow unaligned access
+#ifdef LINUX
+ t_uint64 *origAddr64 = (t_uint64*)origAddr;
+#else
+ __packed t_uint64 *origAddr64 = (__packed t_uint64*)origAddr;
+#endif
+
+ for (m = 0; m < nb; m += 8)
+ {
+ *remoteAddr64++ = swap64(*origAddr64++);
+ }
+}
+
+void MMDSP_copyData24(t_uint32 * remoteAddr32, const char* origAddr, int nb)
+{
+ int m;
+
+ for (m = 0; m < nb; m+=4)
+ {
+ t_uint32 value1;
+
+ value1 = (*origAddr++ << 16);
+ value1 |= (*origAddr++ << 8);
+ value1 |= (*origAddr++ << 0);
+ *remoteAddr32++ = value1;
+ }
+}
+
+void MMDSP_copyData16(t_uint16 * remoteAddr16, const char* origAddr, int nb)
+{
+ int m;
+
+ for (m = 0; m < nb; m+=2)
+ {
+ t_uint16 value1;
+
+ origAddr++; // Skip this byte (which is put in elf file for historical reason)
+ value1 = (*origAddr++ << 8);
+ value1 |= (*origAddr++ << 0);
+ *remoteAddr16++ = value1;
+ }
+}
+
+#if 0
+__asm void MMDSP_copyCode(void* dst, const void* src, int nb)
+{
+ PUSH {r4-r8, lr}
+ SUBS r2,r2,#0x20
+ BCC l4
+
+l5
+ SETEND BE
+ LDR r4, [r1], #0x4
+ LDR r3, [r1], #0x4
+ LDR r6, [r1], #0x4
+ LDR r5, [r1], #0x4
+ LDR r8, [r1], #0x4
+ LDR r7, [r1], #0x4
+ LDR lr, [r1], #0x4
+ LDR r12, [r1], #0x4
+
+ SETEND LE
+ STM r0!,{r3-r8,r12, lr}
+ SUBS r2,r2,#0x20
+ BCS l5
+
+l4
+ LSLS r12,r2,#28
+
+ SETEND BE
+ LDRCS r4, [r1], #0x4
+ LDRCS r3, [r1], #0x4
+ LDRCS r6, [r1], #0x4
+ LDRCS r5, [r1], #0x4
+ SETEND LE
+ STMCS r0!,{r3-r6}
+
+ SETEND BE
+ LDRMI r4, [r1], #0x4
+ LDRMI r3, [r1], #0x4
+ SETEND LE
+ STMMI r0!,{r3-r4}
+
+ POP {r4-r8, pc}
+}
+#endif
+
+#ifdef LINUX
+static void PLD5(int r)
+{
+ asm volatile (
+ "PLD [r0, #0x20] \n\t"
+ "PLD [r0, #0x40] \n\t"
+ "PLD [r0, #0x60] \n\t"
+ "PLD [r0, #0x80] \n\t"
+ "PLD [r0, #0xA0]" );
+}
+
+static void PLD1(int r)
+{
+ asm volatile (
+ "PLD [r0, #0xC0]" );
+}
+#else /* Symbian, Think -> We assume ARMCC */
+static __asm void PLD5(int r)
+{
+ PLD [r0, #0x20]
+ PLD [r0, #0x40]
+ PLD [r0, #0x60]
+ PLD [r0, #0x80]
+ PLD [r0, #0xA0]
+
+ bx lr
+}
+
+static __asm void PLD1(int r)
+{
+ PLD [r0, #0xC0]
+
+ bx lr
+}
+#endif
+
+#if 0
+__asm void COPY(void* dst, const void* src, int nb)
+{
+ PUSH {r4-r8, lr}
+ SUBS r2,r2,#0x20
+ BCC l4a
+ PLD [r1, #0x20]
+ PLD [r1, #0x40]
+ PLD [r1, #0x60]
+ PLD [r1, #0x80]
+ PLD [r1, #0xA0]
+
+l5a
+ PLD [r1, #0xC0]
+ LDM r1!,{r3-r8,r12,lr}
+ STM r0!,{r3-r8,r12,lr}
+ SUBS r2,r2,#0x20
+ BCS l5a
+
+l4a
+ LSLS r12,r2,#28
+ LDMCS r1!,{r3,r4,r12,lr}
+ STMCS r0!,{r3,r4,r12,lr}
+ LDMMI r1!,{r3,r4}
+ STMMI r0!,{r3,r4}
+ POP {r4-r8,lr}
+ LSLS r12,r2,#30
+ LDRCS r3,[r1],#4
+ STRCS r3,[r0],#4
+ BXEQ lr
+l6b
+ LSLS r2,r2,#31
+ LDRHCS r3,[r1],#2
+ LDRBMI r2,[r1],#1
+ STRHCS r3,[r0],#2
+ STRBMI r2,[r0],#1
+ BX lr
+}
+#endif
+
+
+void MMDSP_copySection(t_uint32 origAddr, t_uint32 remoteAddr, t_uint32 sizeInByte) {
+ t_uint32 endAddr = remoteAddr + sizeInByte;
+
+ PLD5(origAddr);
+
+ // Align on 32bits
+ if((remoteAddr & 0x3) != 0)
+ {
+ *(t_uint16*)remoteAddr = *(t_uint16*)origAddr;
+ remoteAddr += sizeof(t_uint16);
+ origAddr += sizeof(t_uint16);
+ }
+
+ // Align on 64bits
+ if((remoteAddr & 0x7) != 0 && (remoteAddr <= endAddr - sizeof(t_uint32)))
+ {
+ *(t_uint32*)remoteAddr = *(t_uint32*)origAddr;
+ remoteAddr += sizeof(t_uint32);
+ origAddr += sizeof(t_uint32);
+ }
+
+ // 64bits burst access
+ for(; remoteAddr <= endAddr - sizeof(t_uint64); remoteAddr += sizeof(t_uint64), origAddr += sizeof(t_uint64))
+ {
+ PLD1(origAddr);
+ *(volatile t_uint64*)remoteAddr = *(t_uint64*)origAddr;
+ }
+
+ // Remain 32bits access
+ if(remoteAddr <= endAddr - sizeof(t_uint32))
+ {
+ *(t_uint32*)remoteAddr = *(t_uint32*)origAddr;
+ remoteAddr += sizeof(t_uint32);
+ origAddr += sizeof(t_uint32);
+ }
+
+ // Remain 16bits access
+ if(remoteAddr <= endAddr - sizeof(t_uint16))
+ *(t_uint16*)remoteAddr = *(t_uint16*)origAddr;
+}
+
+
+void MMDSP_bzeroSection(t_uint32 remoteAddr, t_uint32 sizeInByte) {
+ t_uint32 endAddr = remoteAddr + sizeInByte;
+
+ // Align on 32bits
+ if((remoteAddr & 0x3) != 0)
+ {
+ *(t_uint16*)remoteAddr = 0;
+ remoteAddr += sizeof(t_uint16);
+ }
+
+ // Align on 64bits
+ if((remoteAddr & 0x7) != 0 && (remoteAddr <= endAddr - sizeof(t_uint32)))
+ {
+ *(t_uint32*)remoteAddr = 0;
+ remoteAddr += sizeof(t_uint32);
+ }
+
+ // 64bits burst access
+ for(; remoteAddr <= endAddr - sizeof(t_uint64); remoteAddr += sizeof(t_uint64))
+ *(volatile t_uint64*)remoteAddr = 0ULL;
+
+ // Remain 32bits access
+ if(remoteAddr <= endAddr - sizeof(t_uint32))
+ {
+ *(t_uint32*)remoteAddr = 0;
+ remoteAddr += sizeof(t_uint32);
+ }
+
+ // Remain 16bits access
+ if(remoteAddr <= endAddr - sizeof(t_uint16))
+ *(t_uint16*)remoteAddr = 0;
+}
+
+void MMDSP_loadedSection(t_nmf_core_id coreId, t_memory_id memId, t_memory_handle handle)
+{
+ if(mmdspMemories[memId].purpose == MEM_CODE)
+ {
+ OSAL_CleanDCache(cm_DSP_GetHostLogicalAddress(handle), cm_MM_GetSize(handle));
+ }
+
+ if(memId == LOCKED_CODE)
+ {
+ t_uint32 DspAddress, DspSize;
+
+ cm_DSP_GetDspMemoryHandleSize(handle, &DspSize);
+ cm_DSP_GetDspAddress(handle, &DspAddress);
+
+ cm_COMP_InstructionCacheLock(coreId, DspAddress, DspSize);
+ }
+}
+
+void MMDSP_unloadedSection(t_nmf_core_id coreId, t_memory_id memId, t_memory_handle handle)
+{
+ if(memId == LOCKED_CODE)
+ {
+ t_uint32 DspAddress, DspSize;
+
+ cm_DSP_GetDspMemoryHandleSize(handle, &DspSize);
+ cm_DSP_GetDspAddress(handle, &DspAddress);
+
+ cm_COMP_InstructionCacheUnlock(coreId, DspAddress, DspSize);
+ }
+
+}
+
+static struct reloc_howto_struct elf64_mmdsp_howto_table[] =
+{
+ HOWTO (R_MMDSP_IMM20_16, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 8, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0x0, /* special_function */
+ "R_MMDSP_IMM20_16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x0000000000ffff00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 4-bit absolute relocation for splitted 20 bits immediate, shifted by 56 */
+
+ HOWTO (R_MMDSP_IMM20_4, /* type */
+ 16, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 4, /* bitsize */
+ FALSE, /* pc_relative */
+ 56, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0x0, /* special_function */
+ "R_MMDSP_IMM20_4", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x0f00000000000000LL, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MMDSP_24, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0x0, /* special_function */
+ "R_MMDSP_24", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MMDSP_IMM16, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 8, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0x0, /* special_function */
+ "R_MMDSP_IMM16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x0000000000ffff00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+static const char* lastInPlaceAddr = 0;
+static long long lastInPlaceValue;
+
+void MMDSP_performRelocation(
+ t_uint32 type,
+ const char* symbol_name,
+ t_uint32 symbol_addr,
+ char* reloc_addr,
+ const char* inPlaceAddr,
+ t_uint32 reloc_offset) {
+ int i;
+
+ for(i = 0; i < sizeof(elf64_mmdsp_howto_table) / sizeof(elf64_mmdsp_howto_table[0]); i++)
+ {
+ struct reloc_howto_struct* howto = &elf64_mmdsp_howto_table[i];
+ if(howto->type == type)
+ {
+ t_uint64 relocation;
+
+ LOG_INTERNAL(2, "reloc '%s:0x%x' type %s at 0x%x (0x%x)\n",
+ symbol_name ? symbol_name : "??", symbol_addr,
+ howto->name,
+ reloc_offset, reloc_addr, 0);
+
+ relocation = symbol_addr;
+
+ if (howto->pc_relative) {
+ // Not handle yet
+ }
+
+ if (howto->complain_on_overflow != complain_overflow_dont) {
+ // Not handle yet
+ }
+
+ relocation >>= howto->rightshift;
+
+ relocation <<= howto->bitpos;
+
+#define DOIT(x) \
+ x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
+
+ switch (howto->size) {
+ case 2: {
+ long x = *(long*)inPlaceAddr;
+
+ // CM_ASSERT(*(long*)inPlaceAddr == *(long*)reloc_addr);
+
+ DOIT (x);
+ *(long*)reloc_addr = x;
+ }
+ break;
+ case 4: {
+ long long x;
+ if(lastInPlaceAddr == inPlaceAddr)
+ {
+ x = lastInPlaceValue;
+ }
+ else
+ {
+ // CM_ASSERT(*(__packed long long*)inPlaceAddr == *(long long*)reloc_addr);
+ x = *(long long*)inPlaceAddr;
+ lastInPlaceAddr = inPlaceAddr;
+ }
+
+ DOIT (x);
+ *(long long*)reloc_addr = lastInPlaceValue = x;
+ }
+ break;
+ default:
+ CM_ASSERT(0);
+ }
+
+ return;
+ }
+ }
+
+ ERROR("Relocation type %d not supported for '%s'\n", type, symbol_name, 0, 0, 0, 0);
+}
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/src/elfrelocate.c b/drivers/staging/nmf-cm/cm/engine/elf/src/elfrelocate.c
new file mode 100644
index 00000000000..b08ac6a361e
--- /dev/null
+++ b/drivers/staging/nmf-cm/cm/engine/elf/src/elfrelocate.c
@@ -0,0 +1,79 @@
+/*
+ * 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/elf/inc/bfd.h>
+#include <cm/engine/elf/inc/mpcal.h>
+#include <cm/engine/trace/inc/trace.h>
+#include <cm/engine/utils/inc/string.h>
+
+t_cm_error cm_ELF_relocateSharedSegments(
+ t_memory_handle *memories,
+ t_elfdescription *elfhandle,
+ void *cbContext)
+{
+ return ELF64_relocateSegments(
+ memories,
+ elfhandle,
+ MEM_SHARABLE,
+ cbContext);
+}
+
+t_cm_error cm_ELF_relocatePrivateSegments(
+ t_memory_handle *memories,
+ t_elfdescription *elfhandle,
+ void *cbContext)
+{
+ return ELF64_relocateSegments(
+ memories,
+ elfhandle,
+ MEM_PRIVATE,
+ cbContext);
+}
+
+void cm_ELF_performRelocation(
+ t_uint32 type,
+ const char* symbol_name,
+ t_uint32 symbol_addr,
+ char* reloc_addr)
+{
+ MMDSP_performRelocation(
+ type,
+ symbol_name,
+ symbol_addr,
+ reloc_addr,
+ reloc_addr,
+ 0xBEEF);
+
+ OSAL_CleanDCache((t_uint32)reloc_addr, 8);
+}
+
+t_cm_error cm_ELF_GetMemory(
+ t_elfdescription *elf,
+ t_tmp_elfdescription *elftmp,
+ t_uint32 address,
+ t_memory_purpose purpose,
+ t_memory_reference *memory) {
+ t_memory_id memId;
+
+ for(memId = 0; memId < NUMBER_OF_MMDSP_MEMORY; memId++)
+ {
+ const t_elfmemory* mem = MMDSP_getMappingById(memId);
+
+ if(mem->purpose == purpose && // Memory correspond
+ elf->segments[mem->id].sumSize != 0 && // Segment allocated
+ (elf->segments[mem->id].mpcAddr <= address) &&
+ (address < elf->segments[mem->id].mpcAddr + elf->segments[mem->id].sumSize / mem->fileEntSize)) {
+ memory->memory = mem;
+ memory->offset = address - elf->segments[mem->id].mpcAddr;
+ return CM_OK;
+ }
+ }
+
+ ERROR("Memory %x,%d not found\n", address, purpose, 0, 0, 0, 0);
+ return CM_INVALID_ELF_FILE;
+}
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/src/elfxx.c b/drivers/staging/nmf-cm/cm/engine/elf/src/elfxx.c
new file mode 100644
index 00000000000..4a2976a6bc1
--- /dev/null
+++ b/drivers/staging/nmf-cm/cm/engine/elf/src/elfxx.c
@@ -0,0 +1,591 @@
+/*
+ * 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/elf/inc/mpcal.h>
+
+#include <cm/engine/utils/inc/string.h>
+#include <cm/engine/utils/inc/mem.h>
+
+
+static t_uint32 max(t_uint32 a, t_uint32 b)
+{
+ return (a >= b) ? a : b;
+}
+/*
+static t_uint32 min(t_uint32 a, t_uint32 b)
+{
+ return (a <= b) ? a : b;
+}
+*/
+
+struct XXrelocation
+{
+ t_uint32 st_value;
+ ElfXX_Half st_shndx;
+ Elf64_Sxword r_addend;
+ t_uint32 OffsetInElf;
+ t_uint32 type;
+
+ t_dup_char symbol_name; // Valid only if st_shndx == SHN_UNDEF
+};
+
+struct XXSection {
+ ElfXX_Word sh_type; /* Section type */
+ t_uint32 sh_size; /* Section size in bytes */
+ ElfXX_Word sh_info; /* Additional section information */
+ ElfXX_Word sh_link; /* Link to another section */
+ t_uint32 sh_addralign; /* Some sections have address alignment constraints */
+ t_uint32 sh_addr; /* Section addr */
+ ElfXX_Xword sh_flags; /* Section flags */
+
+ const char *data;
+ t_uint32 trueDataSize; /* Valid if different from sh_size */
+ const char *sectionName;
+
+ t_uint32 offsetInSegment;
+ const t_elfmemory *meminfo;
+
+ t_uint32 relocationNumber;
+ struct XXrelocation *relocations;
+};
+
+struct XXElf {
+ t_uint32 e_shnum;
+ struct XXSection sectionss[1];
+};
+
+t_cm_error ELF64_LoadComponent(
+ t_uint16 e_machine,
+ const char *elfdata,
+ t_elfdescription **elfhandlePtr,
+ t_tmp_elfdescription *elftmp)
+{
+ t_elfdescription *elfhandle;
+ const ElfXX_Ehdr *header = (ElfXX_Ehdr*)elfdata;
+ const ElfXX_Shdr *sections;
+ const char *strings;
+ struct XXElf* ELF;
+ int i, nb;
+
+ elftmp->elfdata = elfdata;
+
+ /* Sanity check */
+ if (swapHalf(header->e_machine) != e_machine)
+ {
+ ERROR("This is not a executable for such MPC\n", 0, 0, 0, 0, 0, 0);
+ return CM_INVALID_ELF_FILE;
+ }
+
+ // Cache elf file informations
+ nb = swapHalf(header->e_shnum);
+ elftmp->isExecutable = (swapHalf(header->e_type) == ET_EXEC);
+
+ elfhandle = (t_elfdescription*)OSAL_Alloc_Zero(
+ sizeof(t_elfdescription) + sizeof(struct XXElf) + sizeof(struct XXSection) * (nb - 1));
+ if(elfhandle == NULL)
+ return CM_NO_MORE_MEMORY;
+
+ ELF = elfhandle->ELF = (struct XXElf*)(elfhandle + 1);
+
+ ELF->e_shnum = nb;
+
+ sections = (ElfXX_Shdr*)&elfdata[swapXword(header->e_shoff)];
+ // Compute and swap section infromation
+ for(i = 0; i < ELF->e_shnum; i++)
+ {
+ ELF->sectionss[i].sh_type = swapWord(sections[i].sh_type);
+ ELF->sectionss[i].sh_info = swapWord(sections[i].sh_info);
+ ELF->sectionss[i].sh_link = swapWord(sections[i].sh_link);
+ ELF->sectionss[i].sh_size = (t_uint32)swapXword(sections[i].sh_size);
+ ELF->sectionss[i].sh_addralign = (t_uint32)swapXword(sections[i].sh_addralign);
+ ELF->sectionss[i].sh_addr = (t_uint32)swapXword(sections[i].sh_addr);
+ ELF->sectionss[i].sh_flags = swapXword(sections[i].sh_flags);
+
+ elftmp->sectionData[i] = &elfdata[(t_uint32)swapXword(sections[i].sh_offset)];
+ }
+
+ /*
+ * search nmf_segment
+ */
+ strings = elftmp->sectionData[swapHalf(header->e_shstrndx)];
+ for(i = 0; i < ELF->e_shnum; i++)
+ {
+ ELF->sectionss[i].sectionName = &strings[swapWord(sections[i].sh_name)];
+
+ // Found nmf_segment to see if it's
+ if(cm_StringCompare("nmf_segment", ELF->sectionss[i].sectionName, 11) == 0) {
+ elftmp->nmfSectionIndex = i;
+ elftmp->elfheader = (const t_elf_component_header*)elftmp->sectionData[i];
+ }
+ }
+
+ if(elftmp->nmfSectionIndex == 0)
+ {
+ ERROR("This is not a NMF component\n", 0, 0, 0, 0, 0, 0);
+ goto invalid;
+ }
+
+ /*
+ * Determine component type
+ */
+ elfhandle->magicNumber = swap32(elftmp->elfheader->magic);
+ switch(elfhandle->magicNumber) {
+ case MAGIC_COMPONENT:
+ elfhandle->instanceProperty = MEM_FOR_MULTIINSTANCE;
+ break;
+ case MAGIC_SINGLETON:
+ case MAGIC_FIRMWARE:
+ elfhandle->instanceProperty = MEM_FOR_SINGLETON;
+ break;
+ }
+
+ // Copy content
+ for(i = 0; i < ELF->e_shnum; i++)
+ {
+ ELF->sectionss[i].meminfo = MMDSP_getMappingByName(
+ ELF->sectionss[i].sectionName,
+ elfhandle->instanceProperty);
+
+ if(ELF->sectionss[i].meminfo != NULL)
+ ELF->sectionss[i].trueDataSize = (ELF->sectionss[i].sh_size / ELF->sectionss[i].meminfo->fileEntSize) * ELF->sectionss[i].meminfo->memEntSize;
+
+ if(ELF->sectionss[i].sh_size != 0 &&
+ ELF->sectionss[i].sh_type == SHT_PROGBITS &&
+ (ELF->sectionss[i].sh_flags & SHF_ALLOC) != 0)
+ {
+ const char* elfAddr = elftmp->sectionData[i];
+
+ ELF->sectionss[i].data = OSAL_Alloc(ELF->sectionss[i].trueDataSize);
+ if(ELF->sectionss[i].data == NULL)
+ goto oom;
+
+ if(ELF->sectionss[i].meminfo->purpose == MEM_CODE)
+ {
+ MMDSP_copyCode(
+ (t_uint64*)ELF->sectionss[i].data,
+ elfAddr,
+ ELF->sectionss[i].trueDataSize);
+ }
+ else if(ELF->sectionss[i].meminfo->purpose == MEM_DATA &&
+ // Always 3 for data ELF->sectionss[i].meminfo->fileEntSize == 3 &&
+ ELF->sectionss[i].meminfo->memEntSize == 4)
+ {
+ MMDSP_copyData24(
+ (t_uint32*)ELF->sectionss[i].data,
+ elfAddr,
+ ELF->sectionss[i].trueDataSize);
+ }
+ else if(ELF->sectionss[i].meminfo->purpose == MEM_DATA &&
+ // Always 3 for data ELF->sectionss[i].meminfo->fileEntSize == 3 &&
+ ELF->sectionss[i].meminfo->memEntSize == 2)
+ {
+ MMDSP_copyData16(
+ (t_uint16*)ELF->sectionss[i].data,
+ elfAddr,
+ ELF->sectionss[i].trueDataSize);
+ }
+ else
+ CM_ASSERT(0);
+ }
+ }
+
+ // Copy relocation
+ // Loop on all relocation section
+ for(i=0; i < ELF->e_shnum; i++)
+ {
+ int sh_info;
+
+ // Does this section is a relocation table (only RELA supported)
+ if((ELF->sectionss[i].sh_type != SHT_RELA) ||
+ ELF->sectionss[i].sh_size == 0) continue;
+
+ // Copy only relocation for loaded section
+ sh_info = ELF->sectionss[i].sh_info;
+ if(ELF->sectionss[sh_info].meminfo != NULL)
+ {
+ const ElfXX_Sym* symtab;
+ const char* strtab;
+ ElfXX_Rela* rel_start;
+ int n;
+
+ ELF->sectionss[sh_info].relocationNumber = ELF->sectionss[i].sh_size / sizeof(ElfXX_Rela);
+ ELF->sectionss[sh_info].relocations = (struct XXrelocation*)OSAL_Alloc_Zero(sizeof(struct XXrelocation) * ELF->sectionss[sh_info].relocationNumber);
+ if(ELF->sectionss[sh_info].relocations == NULL)
+ goto oom;
+
+ symtab = (ElfXX_Sym *)elftmp->sectionData[ELF->sectionss[i].sh_link];
+ strtab = elftmp->sectionData[ELF->sectionss[ELF->sectionss[i].sh_link].sh_link];
+ rel_start = (ElfXX_Rela*)elftmp->sectionData[i];
+ for(n = 0; n < ELF->sectionss[sh_info].relocationNumber; n++, rel_start++)
+ {
+ struct XXrelocation* relocation = &ELF->sectionss[sh_info].relocations[n];
+ ElfXX_Xword r_info = swapXword(rel_start->r_info);
+ int strtab_index = ELFXX_R_SYM(r_info);
+ const char* symbol_name = &strtab[swapWord(symtab[strtab_index].st_name)];
+
+ relocation->st_shndx = swapHalf(symtab[strtab_index].st_shndx);
+ relocation->st_value = (t_uint32)swapXword(symtab[strtab_index].st_value);
+ relocation->r_addend = swapXword(rel_start->r_addend);
+ relocation->OffsetInElf = (t_uint32)swapXword(rel_start->r_offset) / ELF->sectionss[sh_info].meminfo->fileEntSize;
+ relocation->type = ELFXX_R_TYPE(r_info);
+
+ switch(relocation->st_shndx) {
+ case SHN_UNDEF:
+ relocation->symbol_name = cm_StringDuplicate(symbol_name + 1); /* Remove '_' prefix */
+ if(relocation->symbol_name == NULL)
+ goto oom;
+ break;
+ case SHN_COMMON:
+ ERROR("SHN_COMMON not handle for %s\n", symbol_name, 0, 0, 0, 0, 0);
+ goto invalid;
+ }
+ }
+ }
+ }
+
+ *elfhandlePtr = elfhandle;
+ return CM_OK;
+invalid:
+ ELF64_UnloadComponent(elfhandle);
+ return CM_INVALID_ELF_FILE;
+oom:
+ ELF64_UnloadComponent(elfhandle);
+ return CM_NO_MORE_MEMORY;
+}
+
+t_cm_error ELF64_ComputeSegment(
+ t_elfdescription *elfhandle,
+ t_tmp_elfdescription *elftmp)
+{
+ struct XXElf* ELF = elfhandle->ELF;
+ int i;
+
+ for(i = 0; i < ELF->e_shnum; i++)
+ {
+ ELF->sectionss[i].offsetInSegment = 0xFFFFFFFF;
+
+ if(ELF->sectionss[i].sh_type == SHT_PROGBITS || ELF->sectionss[i].sh_type == SHT_NOBITS) {
+ // This is a loadable memory (memory size could be zero since we can have symbol on it)...
+ const t_elfmemory* meminfo = ELF->sectionss[i].meminfo;
+
+ if(meminfo != NULL) {
+ // Which correspond to MPC memory
+
+ if(elftmp->isExecutable)
+ {
+ if(! elfhandle->segments[meminfo->id].sumSizeSetted)
+ {
+ CM_ASSERT(ELF->sectionss[i].sh_addr >= meminfo->startAddr * meminfo->fileEntSize);
+
+ elfhandle->segments[meminfo->id].sumSizeSetted = TRUE;
+ elfhandle->segments[meminfo->id].sumSize = ELF->sectionss[i].sh_addr - meminfo->startAddr * meminfo->fileEntSize;
+ }
+ else
+ CM_ASSERT(elfhandle->segments[meminfo->id].sumSize == ELF->sectionss[i].sh_addr - meminfo->startAddr * meminfo->fileEntSize);
+ }
+ else
+ {
+ while(elfhandle->segments[meminfo->id].sumSize % ELF->sectionss[i].sh_addralign != 0)
+ elfhandle->segments[meminfo->id].sumSize++;
+ }
+
+ elfhandle->segments[meminfo->id].maxAlign = max(elfhandle->segments[meminfo->id].maxAlign, ELF->sectionss[i].sh_addralign);
+ ELF->sectionss[i].offsetInSegment = elfhandle->segments[meminfo->id].sumSize / meminfo->fileEntSize;
+ elfhandle->segments[meminfo->id].sumSize += ELF->sectionss[i].sh_size;
+ }
+ } else if(ELF->sectionss[i].sh_type == SHT_RELA && ELF->sectionss[i].sh_info == elftmp->nmfSectionIndex) {
+ int secsym = ELF->sectionss[i].sh_link;
+ elftmp->relaNmfSegment = (ElfXX_Rela*)elftmp->sectionData[i];
+ elftmp->relaNmfSegmentEnd = (ElfXX_Rela*)((t_uint32)elftmp->relaNmfSegment + ELF->sectionss[i].sh_size);
+ elftmp->relaNmfSegmentSymbols = (ElfXX_Sym*)elftmp->sectionData[secsym];
+ elftmp->relaNmfSegmentStrings = elftmp->sectionData[ELF->sectionss[secsym].sh_link];
+ }
+ }
+
+ return CM_OK;
+}
+
+void ELF64_UnloadComponent(
+ t_elfdescription *elfhandle)
+{
+ struct XXElf* ELF = elfhandle->ELF;
+ int i, n;
+
+ for(i = 0; i < ELF->e_shnum; i++)
+ {
+ if(ELF->sectionss[i].relocations != NULL)
+ {
+ for(n = 0; n < ELF->sectionss[i].relocationNumber; n++)
+ cm_StringRelease(ELF->sectionss[i].relocations[n].symbol_name);
+ OSAL_Free(ELF->sectionss[i].relocations);
+ }
+
+ OSAL_Free((void*)ELF->sectionss[i].data);
+ }
+ OSAL_Free(elfhandle);
+}
+
+t_cm_error ELF64_loadSegment(
+ t_elfdescription *elfhandle,
+ t_memory_handle *memory,
+ t_memory_property property)
+{
+ struct XXElf* ELF = elfhandle->ELF;
+ int i;
+
+ /*
+ * Copy ELF data in this segment
+ */
+ for(i = 0; i < ELF->e_shnum; i++)
+ {
+ const t_elfmemory* mapping = ELF->sectionss[i].meminfo;
+
+ if(mapping == NULL)
+ continue;
+ if((! (ELF->sectionss[i].sh_flags & SHF_ALLOC)) || (ELF->sectionss[i].sh_size == 0))
+ continue;
+
+ // This is a loadable memory ...
+ if(
+ (mapping->property == property && elfhandle->instanceProperty != MEM_FOR_SINGLETON) ||
+ (property == MEM_SHARABLE && elfhandle->instanceProperty == MEM_FOR_SINGLETON) )
+ {
+ // Where memory exist and waited share/private correspond
+ t_uint32 remoteData = elfhandle->segments[mapping->id].hostAddr +
+ ELF->sectionss[i].offsetInSegment * mapping->memEntSize;
+
+ if(ELF->sectionss[i].sh_type != SHT_NOBITS)
+ {
+ LOG_INTERNAL(2, "loadSection(%s, 0x%x, 0x%x, 0x%08x)\n",
+ ELF->sectionss[i].sectionName, remoteData, ELF->sectionss[i].trueDataSize,
+ (t_uint32)ELF->sectionss[i].data, 0, 0);
+
+ MMDSP_copySection((t_uint32)ELF->sectionss[i].data, remoteData, ELF->sectionss[i].trueDataSize);
+ }
+ else
+ {
+ LOG_INTERNAL(2, "bzeroSection(%s, 0x%x, 0x%x)\n",
+ ELF->sectionss[i].sectionName, remoteData, ELF->sectionss[i].trueDataSize, 0, 0, 0);
+
+ MMDSP_bzeroSection(remoteData, ELF->sectionss[i].trueDataSize);
+ }
+ }
+ }
+
+ return CM_OK;
+}
+
+
+
+static const t_elfmemory* getSectionAddress(
+ t_memory_handle *memories,
+ t_elfdescription *elfhandle,
+ t_uint32 sectionIdx,
+ t_uint32 *sectionOffset,
+ t_cm_logical_address *sectionAddr) {
+ struct XXElf* ELF = elfhandle->ELF;
+ const t_elfmemory* mapping = ELF->sectionss[sectionIdx].meminfo;
+
+ if(mapping != NULL) {
+ *sectionOffset = (elfhandle->segments[mapping->id].mpcAddr +
+ ELF->sectionss[sectionIdx].offsetInSegment);
+
+ *sectionAddr = (t_cm_logical_address)(elfhandle->segments[mapping->id].hostAddr +
+ ELF->sectionss[sectionIdx].offsetInSegment * mapping->memEntSize);
+ }
+
+ return mapping;
+}
+
+static t_uint32 getSymbolAddress(
+ t_memory_handle *memories,
+ t_elfdescription *elfhandle,
+ t_uint32 symbolSectionIdx,
+ t_uint32 symbolOffet) {
+ struct XXElf* ELF = elfhandle->ELF;
+ const t_elfmemory* mapping = ELF->sectionss[symbolSectionIdx].meminfo;
+
+ if(mapping == NULL)
+ return 0xFFFFFFFF;
+ // CM_ASSERT(elfhandle->segments[mapping->id].sumSize != 0);
+ // CM_ASSERT(elfhandle->sections[symbolSectionIdx].offsetInSegment != 0xFFFFFFFF);
+
+ return elfhandle->segments[mapping->id].mpcAddr +
+ ELF->sectionss[symbolSectionIdx].offsetInSegment +
+ symbolOffet;
+}
+
+#if 0
+t_bool ELFXX_getSymbolLocation(
+ const t_mpcal_memory *mpcalmemory,
+ t_elfdescription *elf,
+ char *symbolName,
+ const t_elfmemory **memory,
+ t_uint32 *offset) {
+ const ElfXX_Ehdr *header = (ElfXX_Ehdr*)elf->elfdata;
+ const ElfXX_Shdr *sections = (ElfXX_Shdr*)&elf->elfdata[swapXword(header->e_shoff)];
+ const char *strings = &elf->elfdata[swapXword(sections[swapHalf(header->e_shstrndx)].sh_offset)];
+ int len = cm_StringLength(symbolName, 256); // TO BE FIXED
+ int i;
+
+ for(i = 0; i < ELF->e_shnum; i++)
+ {
+ ElfXX_Sym* symtab;
+ const char* strtab;
+ unsigned int size, j;
+
+ if(ELF->sectionss[i].sh_type != SHT_SYMTAB && ELF->sectionss[i].sh_type != SHT_DYNSYM) continue;
+
+ // Section is a symbol table
+ symtab = (ElfXX_Sym*)&elf->elfdata[swapXword(sections[i].sh_offset)];
+ strtab = &elf->elfdata[swapXword(sections[swapWord(sections[i].sh_link)].sh_offset)];
+ size = ELF->sectionss[i].sh_size / (unsigned int)swapXword(sections[i].sh_entsize);
+
+ for(j = 0; j < size; j++) {
+ const char* foundName = &strtab[swapWord(symtab[j].st_name)];
+
+ if(cm_StringCompare(symbolName, foundName, len) == 0) {
+ if(swapHalf(symtab[j].st_shndx) != SHN_UNDEF) {
+ int sectionIdx = (int)swapHalf(symtab[j].st_shndx);
+ ElfXX_Xword sh_flags = swapXword(sections[sectionIdx].sh_flags);
+
+ *memory = mpcalmemory->getMappingByName(&strings[swapWord(sections[sectionIdx].sh_name)],
+ sh_flags & SHF_WRITE ? MEM_RW : (sh_flags & SHF_EXECINSTR ? MEM_X : MEM_RO));
+ *offset = (t_uint32)swapXword(symtab[j].st_value);
+
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+#endif
+
+t_cm_error ELF64_relocateSegments(
+ t_memory_handle *memories,
+ t_elfdescription *elfhandle,
+ t_memory_property property,
+ void *cbContext) {
+ struct XXElf* ELF = elfhandle->ELF;
+ int sec, n;
+
+ // Loop on all relocation section
+ for(sec=0; sec < ELF->e_shnum; sec++)
+ {
+ t_cm_logical_address sectionAddr = 0;
+ t_uint32 sectionOffset = 0;
+ const t_elfmemory* mapping;
+
+ if(ELF->sectionss[sec].relocations == NULL)
+ continue;
+
+ // Relocate only section in memory
+ mapping = getSectionAddress(memories,
+ elfhandle,
+ sec,
+ &sectionOffset,
+ &sectionAddr);
+ if(mapping == NULL)
+ continue;
+
+ if(
+ (mapping->property == property && elfhandle->instanceProperty != MEM_FOR_SINGLETON) ||
+ (property == MEM_SHARABLE && elfhandle->instanceProperty == MEM_FOR_SINGLETON) )
+ {
+ LOG_INTERNAL(2, "relocSection(%s)\n", ELF->sectionss[sec].sectionName, 0, 0, 0, 0, 0);
+
+ for(n = 0; n < ELF->sectionss[sec].relocationNumber; n++)
+ {
+ struct XXrelocation* relocation = &ELF->sectionss[sec].relocations[n];
+ t_uint32 symbol_addr;
+ char* relocAddr = (char*)(sectionAddr + relocation->OffsetInElf * mapping->memEntSize);
+
+ switch(relocation->st_shndx) {
+ case SHN_ABS: // Absolute external reference
+ symbol_addr = relocation->st_value;
+ break;
+ case SHN_UNDEF: // External reference
+ // LOG_INTERNAL(0, "cm_resolvSymbol(%d, %s)\n", relocation->type, relocation->symbol_name, 0,0, 0, 0);
+ symbol_addr = cm_resolvSymbol(cbContext,
+ relocation->type,
+ relocation->symbol_name,
+ relocAddr);
+ if(symbol_addr == 0x0) { // Not defined symbol
+ ERROR("Symbol %s not found\n", relocation->symbol_name, 0, 0, 0, 0, 0);
+ return CM_INVALID_ELF_FILE;
+ } else if(symbol_addr == 0xFFFFFFFE) { // OOM
+ return CM_NO_MORE_MEMORY;
+ } else if(symbol_addr == 0xFFFFFFFF) { // Defined inside static binding
+ continue;
+ }
+ break;
+ default: // Internal reference in loaded section
+ symbol_addr = getSymbolAddress(
+ memories,
+ elfhandle,
+ (t_uint32)relocation->st_shndx,
+ relocation->st_value);
+ if(symbol_addr == 0xFFFFFFFF) {
+ ERROR("Symbol in section %s+%d not loaded\n",
+ ELF->sectionss[relocation->st_shndx].sectionName,
+ relocation->st_value, 0, 0, 0, 0);
+ return CM_INVALID_ELF_FILE;
+ }
+ break;
+ }
+
+ symbol_addr += relocation->r_addend;
+
+ MMDSP_performRelocation(
+ relocation->type,
+ relocation->symbol_name,
+ symbol_addr,
+ relocAddr,
+ ELF->sectionss[sec].data + relocation->OffsetInElf * mapping->memEntSize,
+ sectionOffset + relocation->OffsetInElf);
+ }
+ }
+ }
+
+ return CM_OK;
+}
+
+t_cm_error ELF64_getRelocationMemory(
+ t_elfdescription *elfhandle,
+ t_tmp_elfdescription *elftmp,
+ t_uint32 offsetInNmf,
+ t_memory_reference *memory) {
+ struct XXElf* ELF = elfhandle->ELF;
+ const ElfXX_Rela* rel_start;
+ const ElfXX_Sym* relaNmfSegmentSymbols = (ElfXX_Sym*)elftmp->relaNmfSegmentSymbols;
+
+ for(rel_start = (ElfXX_Rela*)elftmp->relaNmfSegment; rel_start < (ElfXX_Rela*)elftmp->relaNmfSegmentEnd; rel_start++)
+ {
+ if((t_uint32)swapXword(rel_start->r_offset) == offsetInNmf)
+ {
+ int strtab_index = ELFXX_R_SYM(swapXword(rel_start->r_info));
+ int sectionIdx = (int)swapHalf(relaNmfSegmentSymbols[strtab_index].st_shndx);
+
+ memory->memory = ELF->sectionss[sectionIdx].meminfo;
+
+ if(memory->memory != NULL) {
+ memory->offset = (
+ ELF->sectionss[sectionIdx].offsetInSegment + // Offset in Segment
+ (t_uint32)swapXword(relaNmfSegmentSymbols[strtab_index].st_value) + // Offset in Elf Section
+ (t_uint32)swapXword(rel_start->r_addend)); // Addend
+
+ return CM_OK;
+ } else {
+ const char* symbol_name = &elftmp->relaNmfSegmentStrings[swapWord(relaNmfSegmentSymbols[strtab_index].st_name)];
+ ERROR("Symbol %s not found\n", symbol_name, 0, 0, 0, 0, 0);
+ return CM_INVALID_ELF_FILE;
+ }
+ }
+ }
+
+ ERROR("Unknown relocation error\n", 0, 0, 0, 0, 0, 0);
+ return CM_INVALID_ELF_FILE;
+}
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/src/mmdsp-debug.c b/drivers/staging/nmf-cm/cm/engine/elf/src/mmdsp-debug.c
new file mode 100644
index 00000000000..c6c316046b3
--- /dev/null
+++ b/drivers/staging/nmf-cm/cm/engine/elf/src/mmdsp-debug.c
@@ -0,0 +1,435 @@
+/*
+ * 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/elf/inc/mmdsp-loadmap.h>
+#include <cm/engine/elf/inc/mmdsp.h>
+#include <cm/engine/dsp/inc/semaphores_dsp.h>
+#include <cm/engine/dsp/mmdsp/inc/mmdsp_hwp.h>
+#include <cm/engine/os_adaptation_layer/inc/os_adaptation_layer.h>
+
+#include <cm/engine/power_mgt/inc/power.h>
+
+#include <cm/engine/utils/inc/string.h>
+#include <cm/engine/trace/inc/trace.h>
+#include <cm/engine/memory/inc/domain.h>
+#include <cm/engine/component/inc/instance.h>
+#include <cm/engine/component/inc/component_type.h>
+#include <inc/nmf-limits.h>
+
+#define LOADMAP_SEMAPHORE_USE_NB 7
+
+static t_memory_handle headerHandle[NB_CORE_IDS] = {INVALID_MEMORY_HANDLE, };
+static struct LoadMapHdr *headerAddresses[NB_CORE_IDS] = {0, };
+static t_uint32 headerOffsets[NB_CORE_IDS] = {0, };
+static t_uint32 entryNumber[NB_CORE_IDS] = {0, };
+
+#undef myoffsetof
+#define myoffsetof(TYPE, MEMBER) ((unsigned int) &((TYPE *)0)->MEMBER)
+
+t_cm_error cm_DSPABI_AddLoadMap(
+ t_cm_domain_id domainId,
+ const char* templateName,
+ const char* localname,
+ t_memory_handle *memories,
+ void *componentHandle)
+{
+ t_nmf_core_id coreId = cm_DM_GetDomainCoreId(domainId);
+ int count=0;
+ struct LoadMapItem* curItem = NULL;
+
+ if (headerHandle[coreId] == 0) /* Create loadmap header */
+ {
+ headerHandle[coreId] = cm_DM_Alloc(domainId, SDRAM_EXT16,
+ sizeof(struct LoadMapHdr)/2, CM_MM_ALIGN_2WORDS, TRUE);
+ if (headerHandle[coreId] == INVALID_MEMORY_HANDLE) {
+ ERROR("CM_NO_MORE_MEMORY: Unable to allocate loadmap in cm_DSPABI_AddLoadMap()\n", 0, 0, 0, 0, 0, 0);
+ return CM_NO_MORE_MEMORY;
+ }
+
+ headerAddresses[coreId] = (struct LoadMapHdr*)cm_DSP_GetHostLogicalAddress(headerHandle[coreId]);
+
+ headerAddresses[coreId]->nMagicNumber = LOADMAP_MAGIC_NUMBER;
+ headerAddresses[coreId]->nVersion = (LOADMAP_VERSION_MSB<<8)|(LOADMAP_VERSION_LSB);
+ headerAddresses[coreId]->nRevision = 0;
+ headerAddresses[coreId]->pFirstItem = 0;
+
+ //Register Header into XRAM:2
+ cm_DSP_GetDspAddress(headerHandle[coreId], &headerOffsets[coreId]);
+ cm_DSP_WriteXRamWord(coreId, 2, headerOffsets[coreId]);
+ }
+
+ // update Header nRevision field
+ headerAddresses[coreId]->nRevision++;
+
+ /*
+ * Build loadmap entry
+ */
+ {
+ t_memory_handle handle;
+ struct LoadMapItem* pItem;
+ t_uint32 dspentry;
+ unsigned char* pos;
+ t_uint32 fnlen, lnlen;
+ t_uint32 fnlenaligned, lnlenaligned;
+ t_uint32 address;
+ t_uint32 postStringLength;
+ int i;
+
+ postStringLength = cm_StringLength(".elf", 16);
+ fnlenaligned = fnlen = cm_StringLength(templateName, MAX_COMPONENT_FILE_PATH_LENGTH) + postStringLength + 2;
+ if((fnlenaligned % 2) != 0) fnlenaligned++;
+ lnlenaligned = lnlen = cm_StringLength(localname, MAX_TEMPLATE_NAME_LENGTH);
+ if((lnlenaligned % 2) != 0) lnlenaligned++;
+
+ // Allocate new loap map
+ handle = cm_DM_Alloc(domainId, SDRAM_EXT16,
+ sizeof(struct LoadMapItem)/2 + (1 + fnlenaligned/2) + (1 + lnlenaligned/2),
+ CM_MM_ALIGN_2WORDS, TRUE);
+ if (handle == INVALID_MEMORY_HANDLE) {
+ ERROR("CM_NO_MORE_MEMORY: Unable to allocate loadmap entry in cm_DSPABI_AddLoadMap\n", 0, 0, 0, 0, 0, 0);
+ return CM_NO_MORE_MEMORY;
+ }
+
+ pItem = (struct LoadMapItem*)cm_DSP_GetHostLogicalAddress(handle);
+ cm_DSP_GetDspAddress(handle, &dspentry);
+ count++;
+ entryNumber[coreId]++;
+
+ // Link this new loadmap with the previous one
+ if(headerAddresses[coreId]->pFirstItem == NULL)
+ headerAddresses[coreId]->pFirstItem = (struct LoadMapItem *)dspentry;
+ else
+ {
+ const t_dsp_desc* pDspDesc = cm_DSP_GetState(coreId);
+ t_uint32 endSegmentAddr = SDRAMMEM16_BASE_ADDR + pDspDesc->segments[SDRAM_DATA_USER].size / 2;
+ struct LoadMapItem* curItem, *prevItem = NULL;
+ t_uint32 curItemDspAdress;
+
+ if(
+ ((t_uint32)headerAddresses[coreId]->pFirstItem < SDRAMMEM16_BASE_ADDR) ||
+ ((t_uint32)headerAddresses[coreId]->pFirstItem > endSegmentAddr))
+ {
+ ERROR("Memory corruption in MMDSP: at data DSP address=%x or ARM address=%x\n",
+ headerOffsets[coreId], &headerAddresses[coreId]->pFirstItem, 0, 0, 0, 0);
+
+ return CM_INVALID_DATA;
+ }
+ curItemDspAdress = (t_uint32)headerAddresses[coreId]->pFirstItem;
+ curItem = (struct LoadMapItem*)((curItemDspAdress - headerOffsets[coreId]) * 2 + (t_uint32)headerAddresses[coreId]); // To ARM address
+ count++;
+ while(curItem->pNextItem != NULL)
+ {
+ if(((t_uint32)curItem->pNextItem < SDRAMMEM16_BASE_ADDR) || ((t_uint32)curItem->pNextItem > endSegmentAddr))
+ {
+ if (prevItem == NULL)
+ ERROR("AddLoadMap: Memory corruption in MMDSP: at data DSP address=%x or ARM address=%x\n",
+ curItemDspAdress + myoffsetof(struct LoadMapItem, pNextItem), &curItem->pNextItem,
+ 0, 0, 0, 0);
+ else
+ ERROR("AddLoadMap: Memory corruption in MMDSP: at data DSP address=%x or ARM address=%x\n",
+ curItemDspAdress + myoffsetof(struct LoadMapItem, pNextItem), &curItem->pNextItem,
+ 0, 0, 0, 0);
+ return CM_INVALID_DATA;
+ }
+ curItemDspAdress = (t_uint32)curItem->pNextItem;
+ prevItem = curItem;
+ curItem = (struct LoadMapItem*)((curItemDspAdress - headerOffsets[coreId]) * 2 + (t_uint32)headerAddresses[coreId]); // To ARM address
+ count++;
+ }
+ curItem->pNextItem = (struct LoadMapItem *)dspentry;
+ }
+
+ // DSP Address of the string at the end of the load map
+ pos = (unsigned char*)pItem + sizeof(struct LoadMapItem);
+
+ /*
+ * Set SolibFilename address information
+ * -> string = "./origfilename"
+ */
+ pItem->pSolibFilename = (char*)(dspentry + sizeof(struct LoadMapItem) / 2);
+ *(t_uint16*)pos = fnlen;
+ pos += 2;
+ *pos++ = '.';
+ *pos++ = '\\';
+ for(i = 0; i < fnlen - 2 - postStringLength; i++)
+ {
+ *pos++ = (templateName[i] == '.') ? '\\' : templateName[i];
+ }
+ *pos++ = '.';
+ *pos++ = 'e';
+ *pos++ = 'l';
+ *pos++ = 'f';
+ // add padding if needed
+ if ((t_uint32)pos & 1)
+ *pos++ = '\0';
+
+ /*
+ * Set Component Name address information
+ */
+ if (lnlen != 0)
+ {
+ pItem->pComponentName = (char*)(dspentry + sizeof(struct LoadMapItem) / 2 + 1 + fnlenaligned / 2);
+
+ *(t_uint16*)pos = lnlen;
+ pos += 2;
+ for(i = 0; i < lnlenaligned; i++)
+ {
+ // If not aligned null ending copied
+ *pos++ = localname[i];
+ }
+ }
+ else
+ {
+ pItem->pComponentName = 0;
+ }
+
+ /*
+ * Set PROG information
+ */
+ if(memories[CODE_MEMORY_INDEX] == INVALID_MEMORY_HANDLE)
+ address = 0;
+ else
+ cm_DSP_GetDspAddress(memories[CODE_MEMORY_INDEX], &address);
+ pItem->pAddrProg = (void*)address;
+
+ /*
+ * Set ERAMCODE information
+ */
+ if(memories[ECODE_MEMORY_INDEX] == INVALID_MEMORY_HANDLE)
+ address = 0;
+ else
+ cm_DSP_GetDspAddress(memories[ECODE_MEMORY_INDEX], &address);
+ pItem->pAddrEmbProg = (void*)address;
+
+ /*
+ * Set THIS information
+ */
+ if(memories[PRIVATE_DATA_MEMORY_INDEX] != INVALID_MEMORY_HANDLE) {
+ // Standard component
+ cm_DSP_GetDspAddress(memories[PRIVATE_DATA_MEMORY_INDEX], &address);
+ } else if(memories[SHARE_DATA_MEMORY_INDEX] != INVALID_MEMORY_HANDLE) {
+ // Singleton component where data are shared (simulate THIS with shared memory)
+ cm_DSP_GetDspAddress(memories[SHARE_DATA_MEMORY_INDEX], &address);
+ } else {
+ // Component without data (take unique identifier -> arbitrary take host component handle)
+ address = (t_uint32)componentHandle;
+ }
+ pItem->pThis = (void*)address;
+
+ /*
+ * Set ARM THIS information
+ */
+ pItem->pARMThis = componentHandle;
+
+ /*
+ * Set Link to null (end of list)
+ */
+ pItem->pNextItem = 0;
+
+ /*
+ * Set XROM information
+ */
+ if(memories[XROM_MEMORY_INDEX] == INVALID_MEMORY_HANDLE)
+ address = 0;
+ else
+ cm_DSP_GetDspAddress(memories[XROM_MEMORY_INDEX], &address);
+ pItem->pXROM = (void*)address;
+
+ /*
+ * Set YROM information
+ */
+ if(memories[YROM_MEMORY_INDEX] == INVALID_MEMORY_HANDLE)
+ address = 0;
+ else
+ cm_DSP_GetDspAddress(memories[YROM_MEMORY_INDEX], &address);
+ pItem->pYROM = (void*)address;
+
+ /*
+ * Set memory handle (not used externally)
+ */
+ ((t_component_instance *)componentHandle)->loadMapHandle = handle;
+ }
+
+ OSAL_mb();
+
+ if (count != entryNumber[coreId]) {
+ ERROR("AddLoadMap: corrumption, number of component differs: count=%d, expected %d (last item @ %p)\n",
+ count, entryNumber[coreId], curItem, 0, 0, 0);
+ return CM_INVALID_DATA;
+ }
+ return CM_OK;
+}
+
+t_cm_error cm_DSPABI_RemoveLoadMap(
+ t_cm_domain_id domainId,
+ const char* templateName,
+ t_memory_handle *memories,
+ const char* localname,
+ void *componentHandle)
+{
+ struct LoadMapItem **prevItemReference;
+ t_uint32 prevItemReferenceDspAddress, curItemDspAdress;
+ t_nmf_core_id coreId = cm_DM_GetDomainCoreId(domainId);
+ const t_dsp_desc* pDspDesc = cm_DSP_GetState(coreId);
+ t_uint32 endSegmentAddr = SDRAMMEM16_BASE_ADDR + pDspDesc->segments[SDRAM_DATA_USER].size / 2;
+ struct LoadMapItem* curItem = NULL;
+
+ CM_ASSERT (headerHandle[coreId] != INVALID_MEMORY_HANDLE);
+
+ /* parse list until we find this */
+ prevItemReferenceDspAddress = 0x2; // DSP address of load map head pointer
+ prevItemReference = &headerAddresses[coreId]->pFirstItem;
+ curItemDspAdress = (t_uint32)*prevItemReference;
+ while(curItemDspAdress != 0x0)
+ {
+ if((curItemDspAdress < SDRAMMEM16_BASE_ADDR) || (curItemDspAdress > endSegmentAddr))
+ {
+ ERROR("Memory corruption in MMDSP: at data DSP address=%x or ARM address=%x\n",
+ prevItemReferenceDspAddress, prevItemReference, 0, 0, 0, 0);
+
+ /* free the entry anyway to avoid leakage */
+ cm_DM_Free(((t_component_instance *)componentHandle)->loadMapHandle, TRUE);
+
+ return CM_OK;
+ }
+
+ curItem = (struct LoadMapItem*)((curItemDspAdress - headerOffsets[coreId]) * 2 + (t_uint32)headerAddresses[coreId]); // To ARM address
+
+ if(curItem->pARMThis == componentHandle)
+ {
+ // Remove component from loadmap
+
+ /* take local semaphore */
+ cm_DSP_SEM_Take(coreId,LOADMAP_SEMAPHORE_USE_NB);
+
+ /* remove element from list */
+ *prevItemReference = curItem->pNextItem;
+
+ /* update nRevision field in header */
+ headerAddresses[coreId]->nRevision++;
+
+ /* If this is the last item, deallocate !!! */
+ if(headerAddresses[coreId]->pFirstItem == NULL)
+ {
+ // Deallocate memory
+ cm_DM_Free(headerHandle[coreId], TRUE);
+ headerHandle[coreId] = INVALID_MEMORY_HANDLE;
+
+ //Register Header into XRAM:2
+ cm_DSP_WriteXRamWord(coreId, 2, 0);
+ }
+
+ /* deallocate memory */
+ cm_DM_Free(((t_component_instance *)componentHandle)->loadMapHandle, TRUE);
+
+ /* be sure memory is updated before releasing local semaphore */
+ OSAL_mb();
+
+ /* release local semaphore */
+ cm_DSP_SEM_Give(coreId,LOADMAP_SEMAPHORE_USE_NB);
+
+ entryNumber[coreId]--;
+
+ return CM_OK;
+ }
+
+ prevItemReferenceDspAddress = curItemDspAdress + myoffsetof(struct LoadMapItem, pNextItem);
+ prevItemReference = &curItem->pNextItem;
+ curItemDspAdress = (t_uint32)*prevItemReference;
+ };
+
+ ERROR("Memory corruption in MMDSP: component not in LoadMap %s\n", localname, 0, 0, 0, 0, 0);
+
+ /* free the entry anyway to avoid leakage */
+ cm_DM_Free(((t_component_instance *)componentHandle)->loadMapHandle, TRUE);
+
+ return CM_OK;
+}
+
+#if 0
+t_cm_error cm_DSPABI_CheckLoadMap_nolock(t_nmf_core_id coreId)
+{
+ int count=0;
+ static int dump = 5;
+ struct LoadMapItem* curItem = NULL;
+
+ if (!dump)
+ return CM_OK;
+ if (headerHandle[coreId] == 0) /* No load map yet */
+ return CM_OK;
+
+ {
+ // No entry in loadmap
+ if(headerAddresses[coreId]->pFirstItem == NULL)
+ return CM_OK;
+
+ {
+ const t_dsp_desc* pDspDesc = cm_DSP_GetState(coreId);
+ t_uint32 endSegmentAddr = SDRAMMEM16_BASE_ADDR + pDspDesc->segments[SDRAM_DATA_USER].size / 2;
+ struct LoadMapItem *prevItem=NULL;
+ t_uint32 curItemDspAdress;
+
+ if (((t_uint32)headerAddresses[coreId]->pFirstItem < SDRAMMEM16_BASE_ADDR) ||
+ ((t_uint32)headerAddresses[coreId]->pFirstItem > endSegmentAddr))
+ {
+ ERROR("CheckLoadMap: Memory corruption in MMDSP at first item: at data DSP address=%x or ARM address=%x\n",
+ headerOffsets[coreId], &headerAddresses[coreId]->pFirstItem, 0, 0, 0, 0);
+ dump--;
+ return CM_INVALID_COMPONENT_HANDLE;
+ }
+ curItemDspAdress = (t_uint32)headerAddresses[coreId]->pFirstItem;
+ curItem = (struct LoadMapItem*)((curItemDspAdress - headerOffsets[coreId]) * 2 + (t_uint32)headerAddresses[coreId]);
+ count++;
+ while(curItem->pNextItem != NULL)
+ {
+ if(((t_uint32)curItem->pNextItem < SDRAMMEM16_BASE_ADDR) || ((t_uint32)curItem->pNextItem > endSegmentAddr))
+ {
+ if (!prevItem)
+ ERROR("CheckLoadMap: Memory corruption in MMDSP (count=%d): at data DSP address=%x or ARM address=%x\n"
+ "Previous (first) component name %s<%s>\n",
+ count,
+ curItemDspAdress + myoffsetof(struct LoadMapItem, pNextItem), &curItem->pNextItem,
+ (char*)(((t_component_instance *)&curItem->pARMThis)->pathname),
+ (char*)(((t_component_instance *)&curItem->pARMThis)->Template->name), 0);
+ else
+ ERROR("CheckLoadMap: Memory corruption in MMDSP (count=%d): at data DSP address=%x or ARM address=%x\n"
+ "Previous valid component name %s<%s>",
+ count,
+ curItemDspAdress + myoffsetof(struct LoadMapItem, pNextItem), &curItem->pNextItem,
+ (char*)(((t_component_instance *)&prevItem->pARMThis)->pathname),
+ (char*)(((t_component_instance *)&prevItem->pARMThis)->Template->name), 0);
+ dump--;
+ return CM_INVALID_COMPONENT_HANDLE;
+ }
+ curItemDspAdress = (t_uint32)curItem->pNextItem;
+ prevItem = curItem;
+ curItem = (struct LoadMapItem*)((curItemDspAdress - headerOffsets[coreId]) * 2 + (t_uint32)headerAddresses[coreId]); // To ARM address
+ count++;
+ }
+ }
+
+ }
+
+ if (count != entryNumber[coreId]) {
+ ERROR("CheckLoadMap: number of component differs: count=%d, expected %d (last item @ %p)\n", count, entryNumber[coreId],
+ curItem, 0, 0, 0);
+ dump--;
+ return CM_INVALID_COMPONENT_HANDLE;
+ }
+ return CM_OK;
+}
+
+t_cm_error cm_DSPABI_CheckLoadMap(t_nmf_core_id coreId)
+{
+ t_cm_error error;
+ OSAL_LOCK_API();
+ error = cm_DSPABI_CheckLoadMap_nolock(coreId);
+ OSAL_UNLOCK_API();
+ return error;
+}
+#endif
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/src/mpcal.c b/drivers/staging/nmf-cm/cm/engine/elf/src/mpcal.c
new file mode 100644
index 00000000000..93d910a5ed6
--- /dev/null
+++ b/drivers/staging/nmf-cm/cm/engine/elf/src/mpcal.c
@@ -0,0 +1,6 @@
+/*
+ * 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/elf/inc/mpcal.h>