diff options
Diffstat (limited to 'hifi/xaf/hifi-dpf/core')
-rw-r--r-- | hifi/xaf/hifi-dpf/core/util/gdbstub/gdbstub-entry.S | 198 | ||||
-rw-r--r-- | hifi/xaf/hifi-dpf/core/util/gdbstub/gdbstub.c | 756 | ||||
-rw-r--r-- | hifi/xaf/hifi-dpf/core/util/gdbstub/xtensa-defs.h | 37 | ||||
-rw-r--r-- | hifi/xaf/hifi-dpf/core/util/mutex.c | 156 | ||||
-rw-r--r-- | hifi/xaf/hifi-dpf/core/util/rbtree.c | 842 | ||||
-rw-r--r-- | hifi/xaf/hifi-dpf/core/util/tinyvprintf.c | 198 | ||||
-rw-r--r-- | hifi/xaf/hifi-dpf/core/xf-core.c | 709 | ||||
-rw-r--r-- | hifi/xaf/hifi-dpf/core/xf-io.c | 644 | ||||
-rw-r--r-- | hifi/xaf/hifi-dpf/core/xf-isr.c | 68 | ||||
-rw-r--r-- | hifi/xaf/hifi-dpf/core/xf-mem.c | 361 | ||||
-rw-r--r-- | hifi/xaf/hifi-dpf/core/xf-msg.c | 107 | ||||
-rw-r--r-- | hifi/xaf/hifi-dpf/core/xf-sched.c | 153 | ||||
-rw-r--r-- | hifi/xaf/hifi-dpf/core/xf-shmem.c | 350 |
13 files changed, 0 insertions, 4579 deletions
diff --git a/hifi/xaf/hifi-dpf/core/util/gdbstub/gdbstub-entry.S b/hifi/xaf/hifi-dpf/core/util/gdbstub/gdbstub-entry.S deleted file mode 100644 index 50a33a93..00000000 --- a/hifi/xaf/hifi-dpf/core/util/gdbstub/gdbstub-entry.S +++ /dev/null @@ -1,198 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2018 Cadence Design Systems, Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to use this Software with Cadence processor cores only and -* not with any other processors and platforms, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -******************************************************************************/ -#include "xtensa-defs.h" - -.macro SAVE_ reg, loc - rsr a1, \reg - s32i a1, a3, \loc * 4 -.endm -.macro SAVE reg - SAVE_ \reg, \reg -.endm - -.macro LOAD_ reg, loc - l32i a1, a3, \loc * 4 - wsr a1, \reg -.endm -.macro LOAD reg - LOAD_ \reg, \reg -.endm - - .section ".DebugExceptionVector.text", "ax" - .global DebugExceptionVector - -DebugExceptionVector: - j 1f - .align 4 - .literal_position -1: - xsr a2, DEBUG_EXCSAVE - jx a2 - - .text - .global DebugExceptionEntry - .align 4 - -DebugExceptionEntry: - j 1f - .align 4 - .literal_position -1: - movi a2, aregs - s32i a0, a2, 0 - s32i a1, a2, 4 - rsr a1, DEBUG_EXCSAVE - s32i a1, a2, 8 - s32i a3, a2, 12 - - movi a3, sregs - SAVE LBEG - SAVE LEND - SAVE LCOUNT - SAVE SAR - SAVE WINDOWBASE - SAVE WINDOWSTART - - rsr a1, DEBUG_PC - movi a2, initial_breakpoint - bne a1, a2, 1f - addi a1, a1, 3 -1: - s32i a1, a3, DEBUG_PC * 4 - - SAVE EXCSAVE_1 - SAVE_ DEBUG_PS, PS - SAVE EXCCAUSE - SAVE DEBUGCAUSE - SAVE EXCVADDR - - movi a1, XCHAL_NUM_AREGS / 4 - 1 - movi a2, aregs -1: - s32i a4, a2, 16 - s32i a5, a2, 20 - s32i a6, a2, 24 - s32i a7, a2, 28 - - addi a6, a2, 16 - addi a5, a1, -1 - rotw 1 - bnez a1, 1b - - movi a1, 1 - wsr a1, windowstart - movi a0, 0 - wsr a0, windowbase - rsync - - movi a0, 0 - movi a1, stack + STACK_SIZE - 20 - rsr a2, ps - addi a2, a2, -PS_EXCM_MASK - wsr a2, ps - rsync - - movi a4, handle_exception - callx4 a4 - -DebugExceptionExit: - movi a2, DebugExceptionEntry - wsr a2, DEBUG_EXCSAVE - - rsr a2, ps - addi a2, a2, PS_EXCM_MASK - wsr a2, ps - rsync - - movi a3, sregs - LOAD LBEG - LOAD LEND - LOAD LCOUNT - /* TODO: handle unlikely return-to-lend case */ - LOAD SAR - LOAD WINDOWBASE - rsync - movi a3, sregs - LOAD WINDOWSTART - LOAD DEBUG_PC - LOAD EXCSAVE_1 - LOAD_ DEBUG_PS, PS - LOAD EXCCAUSE - LOAD EXCVADDR - - movi a6, aregs - movi a5, XCHAL_NUM_AREGS / 4 - 2 -1: - l32i a0, a6, 0 - l32i a1, a6, 4 - l32i a2, a6, 8 - l32i a3, a6, 12 - - beqz a5, 2f - addi a10, a6, 16 - addi a9, a5, -1 - rotw 1 - j 1b -2: - l32i a4, a6, 16 - l32i a5, a6, 20 - l32i a7, a6, 28 - l32i a6, a6, 24 - rotw 2 - - rfi XCHAL_DEBUGLEVEL - - -#ifdef LIBC_LEVEL1_HANDLER - .global fault_handler - .align 4 -fault_handler: - rsr a2, epc1 - addi a2, a2, 3 - wsr a2, epc1 - rsync - movi a2, mem_err - s32i a2, a2, 0 - - l32i a2, a1, 16 - l32i a3, a1, 20 - addi a1, a1, 256 - rfe -#endif - - - .global init_debug_entry - .align 4 -init_debug_entry: - entry a1, 16 - movi a2, DebugExceptionEntry - wsr a2, DEBUG_EXCSAVE - isync - retw - - .global breakpoint - .align 4 -breakpoint: - entry a1, 16 -initial_breakpoint: - _break 0, 0 - retw diff --git a/hifi/xaf/hifi-dpf/core/util/gdbstub/gdbstub.c b/hifi/xaf/hifi-dpf/core/util/gdbstub/gdbstub.c deleted file mode 100644 index e125b94c..00000000 --- a/hifi/xaf/hifi-dpf/core/util/gdbstub/gdbstub.c +++ /dev/null @@ -1,756 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2018 Cadence Design Systems, Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to use this Software with Cadence processor cores only and -* not with any other processors and platforms, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -******************************************************************************/ - -/**************************************************************************** - - THIS SOFTWARE IS NOT COPYRIGHTED - - HP offers the following for use in the public domain. HP makes no - warranty with regard to the software or it's performance and the - user accepts the software "AS IS" with all faults. - - HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD - TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -****************************************************************************/ - -/**************************************************************************** - * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ - * - * Module name: remcom.c $ - * Revision: 1.34 $ - * Date: 91/03/09 12:29:49 $ - * Contributor: Lake Stevens Instrument Division$ - * - * Description: low level support for gdb debugger. $ - * - * Considerations: only works on target hardware $ - * - * Written by: Glenn Engel $ - * ModuleState: Experimental $ - * - * NOTES: See Below $ - * - * Modified for SPARC by Stu Grossman, Cygnus Support. - * - * This code has been extensively tested on the Fujitsu SPARClite demo board. - * - * To enable debugger support, two things need to happen. One, a - * call to set_debug_traps() is necessary in order to allow any breakpoints - * or error conditions to be properly intercepted and reported to gdb. - * Two, a breakpoint needs to be generated to begin communication. This - * is most easily accomplished by a call to breakpoint(). Breakpoint() - * simulates a breakpoint by executing a trap #1. - * - ************* - * - * The following gdb commands are supported: - * - * command function Return value - * - * g return the value of the CPU registers hex data or ENN - * G set the value of the CPU registers OK or ENN - * - * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN - * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN - * - * c Resume at current address SNN ( signal NN) - * cAA..AA Continue at address AA..AA SNN - * - * s Step one instruction SNN - * sAA..AA Step one instruction from AA..AA SNN - * - * k kill - * - * ? What was the last sigval ? SNN (signal NN) - * - * All commands and responses are sent with a packet which includes a - * checksum. A packet consists of - * - * $<packet info>#<checksum>. - * - * where - * <packet info> :: <characters representing the command or response> - * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>> - * - * When a packet is received, it is first acknowledged with either '+' or '-'. - * '+' indicates a successful transfer. '-' indicates a failed transfer. - * - * Example: - * - * Host: Reply: - * $m0,10#2a +$00010203040506070809101112131415#42 - * - ****************************************************************************/ -#ifdef XAF_ENABLE_NON_HIKEY -#include "xf.h" -#else -#include <string.h> -#include <signal.h> -#include <stdint.h> -#include <xtensa/xtruntime.h> -#endif -#include "xtensa-defs.h" - -/******************************************************************************* - * Ring-buffer definition - ******************************************************************************/ - -#define RING_SIZE 256 - -struct ring { - unsigned char head; - unsigned char fill1[63]; - unsigned char tail; - unsigned char fill2[63]; - unsigned char data[RING_SIZE]; -}; - -#define GDB_INVALIDATE(p) \ - xthal_dcache_region_invalidate((void *)(p), sizeof(*p)) - -#define GDB_FLUSH(p) \ - xthal_dcache_region_writeback((void *)(p), sizeof(*p)) - -static inline unsigned int ring_next_head(const volatile struct ring *ring) -{ - return (ring->head + 1) & (RING_SIZE - 1); -} - -static inline unsigned int ring_next_tail(const volatile struct ring *ring) -{ - return (ring->tail + 1) & (RING_SIZE - 1); -} - -static inline int ring_have_space(const volatile struct ring *ring) -{ - /* ...invalidate tail pointer of tx-ring (updated by host) */ - GDB_INVALIDATE(&ring->tail); - - return ring_next_head(ring) != ring->tail; -} - -static inline int ring_have_data(const volatile struct ring *ring) -{ - /* ...invalidate head pointer of rx-ring (updated by host) */ - GDB_INVALIDATE(&ring->head); - - return ring->head != ring->tail; -} -#ifdef XAF_ENABLE_NON_HIKEY -#define DEBUG_RX_BASE XF_CFG_GDB_RING_RX -#define DEBUG_TX_BASE XF_CFG_GDB_RING_TX -#else -//#define DEBUG_RX_BASE (0x72000000) -//#define DEBUG_TX_BASE (0x72000800) -#define DEBUG_RX_BASE (0x6FFFF000) -#define DEBUG_TX_BASE (0x6FFFF800) -#endif - -volatile struct ring * const rx = (void *)DEBUG_RX_BASE; -volatile struct ring * const tx = (void *)DEBUG_TX_BASE; - -void init_debug_comm(void) -{ - rx->head = rx->tail = 0; - tx->head = tx->tail = 0; - GDB_FLUSH(&rx->head); - GDB_FLUSH(&rx->tail); - GDB_FLUSH(&tx->head); - GDB_FLUSH(&tx->tail); -} - -/* ...functions defined in asm code */ -extern void breakpoint(void); -extern void init_debug_entry(void); - -void poll_debug_ring(void) -{ - if (ring_have_data(rx)) { - breakpoint(); - } -} - -static void putDebugChar(char c) -{ - while (!ring_have_space(tx)) - ; - - tx->data[tx->head] = c; - - /* ...flush data buffer to main memory */ - GDB_FLUSH(&tx->data[tx->head]); - - tx->head = ring_next_head(tx); - - /* ...flush head pointer to main memory */ - GDB_FLUSH(&tx->head); -} - -static int getDebugChar(void) -{ - int v; - while (!ring_have_data(rx)) - ; - - /* ...inavlidate data buffer */ - GDB_INVALIDATE(&rx->data[rx->tail]); - - v = rx->data[rx->tail]; - rx->tail = ring_next_tail(rx); - - /* ...update tail index */ - GDB_FLUSH(&rx->tail); - - return v; -} - -/************************************************************************/ -/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ -/* at least NUMREGBYTES*2 are needed for register packets */ -#define BUFMAX 256 - -#ifdef USE_GDBSTUB -#define bulk_data __attribute__((section (".ddr0.data"))) -#else -#define bulk_data -#endif -uint32_t stack[STACK_SIZE / sizeof(uint32_t)] bulk_data; -static uint8_t sregs_read[32] bulk_data; -static uint8_t sregs_mod[32] bulk_data; -static uint8_t sregs_late[32] bulk_data; -uint32_t sregs[256] bulk_data; -uint32_t aregs[XCHAL_NUM_AREGS] bulk_data; -static uint8_t remcomInBuffer[BUFMAX] bulk_data; -static uint8_t remcomOutBuffer[BUFMAX] bulk_data; - -static const char hexchars[]="0123456789abcdef"; - -/* Convert ch from a hex digit to an int */ - -static int hex(unsigned char ch) -{ - if (ch >= 'a' && ch <= 'f') - return ch-'a'+10; - if (ch >= '0' && ch <= '9') - return ch-'0'; - if (ch >= 'A' && ch <= 'F') - return ch-'A'+10; - return -1; -} - -/* scan for the sequence $<data>#<checksum> */ - -unsigned char *getpacket(void) -{ - unsigned char *buffer = &remcomInBuffer[0]; - unsigned char checksum; - unsigned char xmitcsum; - int count; - char ch; - - while (1) { - /* wait around for the start character, ignore all other characters */ - while ((ch = getDebugChar ()) != '$') - ; - -retry: - checksum = 0; - xmitcsum = -1; - count = 0; - - /* now, read until a # or end of buffer is found */ - while (count < BUFMAX - 1) { - ch = getDebugChar (); - if (ch == '$') - goto retry; - if (ch == '#') - break; - checksum = checksum + ch; - buffer[count] = ch; - count = count + 1; - } - buffer[count] = 0; - - if (ch == '#') { - ch = getDebugChar (); - xmitcsum = hex (ch) << 4; - ch = getDebugChar (); - xmitcsum += hex (ch); - - if (checksum != xmitcsum) { - putDebugChar ('-'); /* failed checksum */ - } else { - putDebugChar ('+'); /* successful transfer */ - - /* if a sequence char is present, reply the sequence ID */ - if (buffer[2] == ':') { - putDebugChar (buffer[0]); - putDebugChar (buffer[1]); - - return &buffer[3]; - } - - return &buffer[0]; - } - } - } -} - -/* send the packet in buffer. */ - -static void putpacket(uint8_t *buffer) -{ - unsigned char checksum; - int count; - unsigned char ch; - - /* $<packet info>#<checksum>. */ - do { - putDebugChar('$'); - checksum = 0; - count = 0; - - while ((ch = buffer[count]) != 0) { - putDebugChar(ch); - checksum += ch; - count += 1; - } - - putDebugChar('#'); - putDebugChar(hexchars[checksum >> 4]); - putDebugChar(hexchars[checksum & 0xf]); - - } while (getDebugChar() != '+'); -} - -/* Indicate to caller of mem2hex or hex2mem that there has been an - error. */ -volatile int mem_err = 0; - -/* Convert the memory pointed to by mem into hex, placing result in buf. - * Return a pointer to the last char put in buf (null), in case of mem fault, - * return 0. - */ - -static uint8_t * mem2hex(const void *mem_, uint8_t *buf, int count) -{ - const unsigned char *mem = mem_; - unsigned char ch; - - mem_err = 0; - while (count-- > 0) { -#ifdef __XTENSA__ - unsigned long v; - unsigned long addr = (unsigned long)mem; - asm volatile ("_l32i %0, %1, 0\n" - : "=r"(v) - : "r"(addr & ~3) - : "memory"); - ch = v >> (addr & 3) * 8; -#endif - mem++; - if (mem_err) - return NULL; - *buf++ = hexchars[ch >> 4]; - *buf++ = hexchars[ch & 0xf]; - } - - *buf = 0; - - return buf; -} - -/* convert the hex array pointed to by buf into binary to be placed in mem - * return a pointer to the character AFTER the last byte written */ - -static uint8_t * hex2mem(const uint8_t *buf, void *mem_, int count) -{ - uint8_t *mem = mem_; - int i; - uint8_t ch; - - if ((unsigned long)mem >= 0xece80000) - return NULL; - - mem_err = 0; - for (i=0; i<count; i++) { - ch = hex(*buf++) << 4; - ch |= hex(*buf++); -#ifdef __XTENSA__ - unsigned long tmp; - unsigned long addr = (unsigned long)mem; - asm volatile ("_l32i %0, %1, 0\n" - "and %0, %0, %2\n" - "or %0, %0, %3\n" - "_s32i %0, %1, 0\n" - "dhwb %1, 0\n" - "ihi %1, 0\n" - : "=r"(tmp) - : "r"(addr & ~3), "r"(0xffffffff ^ (0xff << (addr & 3) * 8)), "r"(ch << (addr & 3) * 8) - : "memory"); -#endif - mem++; - if (mem_err) - return NULL; - } - - return mem; -} - -/* - * While we find nice hex chars, build an int. - * Return number of chars processed. - */ - -static int hexToInt(uint8_t **ptr, int *intValue) -{ - int numChars = 0; - int hexValue; - - *intValue = 0; - - while (**ptr) { - hexValue = hex(**ptr); - if (hexValue < 0) - break; - - *intValue = (*intValue << 4) | hexValue; - numChars ++; - - (*ptr)++; - } - - return (numChars); -} - -static inline int test_bit(const uint8_t *p, int bit) -{ - return (p[bit / 8] >> (bit & 0x7)) & 1; -} -static inline int set_bit(uint8_t *p, int bit) -{ - return (p[bit / 8] |= 1u << (bit & 0x7)); -} - -static inline void mark_read(int sr) -{ - set_bit(sregs_read, sr); -} -static inline int is_read(int sr) -{ - return test_bit(sregs_read, sr); -} -static inline void mark_mod(int sr) -{ - set_bit(sregs_mod, sr); -} -static inline int is_mod(int sr) -{ - return test_bit(sregs_mod, sr); -} -static inline void mark_late(int sr) -{ - set_bit(sregs_late, sr); -} -static inline int is_late(int sr) -{ - return test_bit(sregs_late, sr); -} - -static void read_sr(int sr) -{ - if (!is_read(sr)) { -#ifdef __XTENSA__ - uint32_t val; - asm volatile ("movi a3, 1f + 1\n" - "s8i %1, a3, 0\n" - "dhwb a3, 0\n" - "ihi a3, 0\n" - "isync\n" - "1:\n" - "rsr %0, lbeg\n" - : "=r"(val) - : "r"(sr) - : "a3", "memory"); - sregs[sr] = val; -#endif - mark_read(sr); - } -} - -static void write_sr(int sr) -{ -#ifdef __XTENSA__ - asm volatile ("movi a3, 1f + 1\n" - "s8i %1, a3, 0\n" - "dhwb a3, 0\n" - "ihi a3, 0\n" - "isync\n" - "1:\n" - "wsr %0, lbeg\n" - : - : "r"(sregs[sr]), "r"(sr) - : "a3", "memory"); -#endif -} - -static void restore_sr(void) -{ - int i; - for (i = 0; i < 256; ++i) - if (is_mod(i) && !is_late(i)) - write_sr(i); -} - -extern void *_xtos_exc_handler_table[]; -void fault_handler(void); -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) - -void handle_exception(void) -{ - int sigval = 0; - int addr; - int length; - uint8_t *ptr; - unsigned i; - const unsigned windowbase = 4 * sregs[WINDOWBASE]; - uint8_t stop_status[4] = "Sxx"; -#ifdef LIBC_LEVEL1_HANDLER - static const int cause[] = { - EXCCAUSE_LOAD_STORE_ERROR, - EXCCAUSE_LOAD_STORE_DATA_ERROR, - EXCCAUSE_LOAD_STORE_ADDR_ERROR, - EXCCAUSE_DTLB_MISS, - EXCCAUSE_DTLB_MULTIHIT, - EXCCAUSE_LOAD_PROHIBITED, - EXCCAUSE_STORE_PROHIBITED, - }; - _xtos_handler handler[sizeof(cause) / sizeof(cause[0])]; - - for (i = 0; i < ARRAY_SIZE(cause); ++i) { - handler[i] = _xtos_exc_handler_table[cause[i]]; - _xtos_exc_handler_table[cause[i]] = fault_handler; - } -#endif - memcpy(sregs_read, sregs_late, sizeof(sregs_read)); - memset(sregs_mod, 0, sizeof(sregs_mod)); - - sigval = 5; - stop_status[1] = hexchars[sigval >> 4]; - stop_status[2] = hexchars[sigval & 0xf]; - - if (sregs[DEBUGCAUSE] & DEBUGCAUSE_ICOUNT_MASK) { - sregs[ICOUNTLEVEL] = 0; - mark_mod(ICOUNTLEVEL); - } - putpacket(stop_status); - - while (1) { - remcomOutBuffer[0] = 0; - - ptr = getpacket(); - switch (*ptr++) { - case '?': - memcpy(remcomOutBuffer, stop_status, sizeof(stop_status)); - break; - - case 'c': /* cAA..AA Continue at address AA..AA(optional) */ - /* try to read optional parameter, pc unchanged if no parm */ - - if (hexToInt(&ptr, &addr)) - sregs[DEBUG_PC] = addr; - goto out; - - case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ - /* Try to read %x,%x. */ - - if (hexToInt(&ptr, &addr) && *ptr++ == ',' && - hexToInt(&ptr, &length)) { - if (mem2hex((void *)addr, remcomOutBuffer, length)) - break; - - strcpy((char *)remcomOutBuffer, "E03"); - } else { - strcpy((char *)remcomOutBuffer, "E01"); - } - break; - - case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - /* Try to read '%x,%x:'. */ - - if (hexToInt(&ptr, &addr) && *ptr++ == ',' && - hexToInt(&ptr, &length) && *ptr++ == ':') { - if (hex2mem(ptr, (void *)addr, length)) - strcpy((char *)remcomOutBuffer, "OK"); - else - strcpy((char *)remcomOutBuffer, "E03"); - } else { - strcpy((char *)remcomOutBuffer, "E02"); - } - break; - - case 'p': /* pAA..AA read register number AA..AA */ - if (hexToInt(&ptr, &addr)) { - if (addr < 0x10) { /* read address register in the current window */ - mem2hex(aregs + addr, remcomOutBuffer, 4); - } else if (addr == 0x20) { /* read PC */ - mem2hex(sregs + DEBUG_PC, remcomOutBuffer, 4); - } else if (addr >= 0x100 && addr < 0x100 + XCHAL_NUM_AREGS) { /* read address register by absolute index */ - mem2hex(aregs + ((addr - windowbase) & 0xff), remcomOutBuffer, 4); - } else if (addr >= 0x200 && addr < 0x300) { /* read special register */ - addr &= 0xff; - read_sr(addr); - mem2hex(sregs + addr, remcomOutBuffer, 4); - } else if (addr >= 0x300 && addr < 0x400) { /* TODO read user register */ - strcpy((char *)remcomOutBuffer, "deadbabe"); - } else { /* unexpected register number */ - strcpy((char *)remcomOutBuffer, "E00"); - } - } - break; - - case 'P': /* PAA..AA=VV..VV Set register number AA..AA to a value VV..VV */ - if (hexToInt(&ptr, &addr) && *(ptr++) == '=') { - int ok = 1; - - if (addr < 0x10) { - hex2mem(ptr, aregs + addr, 4); - } else if (addr == 0x20) { - hex2mem(ptr, sregs + DEBUG_PC, 4); - } else if (addr >= 0x100 && addr < 0x100 + XCHAL_NUM_AREGS) { - hex2mem(ptr, aregs + ((addr - windowbase) & 0xff), 4); - } else if (addr >= 0x200 && addr < 0x300) { - addr &= 0xff; - hex2mem(ptr, sregs + addr, 4); - mark_read(addr); - mark_mod(addr); - } else { - ok = 0; - strcpy((char *)remcomOutBuffer, "E00"); - } - if (ok) - strcpy((char *)remcomOutBuffer, "OK"); - } - break; - - case 'q': /* generic query */ - if (strncmp((char *)ptr, "Supported", 9) == 0) - strcpy((char *)remcomOutBuffer, "PacketSize=100"); /* must match BUFMAX */ - break; - - case 's': /* s[AA..AA] Single step */ - if (hexToInt(&ptr, &addr)) - sregs[DEBUG_PC] = addr; - sregs[ICOUNT] = 0xfffffffe; - mark_mod(ICOUNT); - sregs[ICOUNTLEVEL] = XCHAL_DEBUGLEVEL; - mark_mod(ICOUNTLEVEL); - goto out; - - case 'Z': /* insert HW breakpoint*/ - switch (*ptr++) { - case '1': - read_sr(IBREAKENABLE); - if (*ptr++ == ',' && hexToInt(&ptr, &addr) && - *ptr++ == ',' && hexToInt(&ptr, &length) && - *ptr == 0) { - for (i = 0; i < XCHAL_NUM_IBREAK; ++i) { - if (!(sregs[IBREAKENABLE] & (1 << i)) || - sregs[IBREAKA + i] == addr) { - sregs[IBREAKA + i] = addr; - mark_mod(IBREAKA + i); - sregs[IBREAKENABLE] |= (1 << i); - mark_mod(IBREAKENABLE); - break; - } - } - if (i == XCHAL_NUM_IBREAK) - strcpy((char *)remcomOutBuffer, "E02"); - else - strcpy((char *)remcomOutBuffer, "OK"); - } else { - strcpy((char *)remcomOutBuffer, "E01"); - } - break; - } - break; - - case 'z': /* remove HW breakpoint */ - switch (*ptr++) { - case '1': - read_sr(IBREAKENABLE); - if (*ptr++ == ',' && hexToInt(&ptr, &addr) && - *ptr++ == ',' && hexToInt(&ptr, &length)) { - for (i = 0; i < XCHAL_NUM_IBREAK; ++i) { - read_sr(IBREAKA + i); - if (sregs[IBREAKENABLE] & (1 << i) && - sregs[IBREAKA + i] == addr) { - sregs[IBREAKENABLE] &= ~(1 << i); - mark_mod(IBREAKENABLE); - break; - } - } - if (i == XCHAL_NUM_IBREAK) - strcpy((char *)remcomOutBuffer, "E02"); - else - strcpy((char *)remcomOutBuffer, "OK"); - } else { - strcpy((char *)remcomOutBuffer, "E01"); - } - break; - } - break; - } - - /* reply to the request */ - putpacket(remcomOutBuffer); - } -out: -#ifdef LIBC_LEVEL1_HANDLER - for (i = 0; i < ARRAY_SIZE(cause); ++i) { - _xtos_exc_handler_table[cause[i]] = handler[i]; - } -#endif - restore_sr(); -} - -void init_gdbstub(void) -{ - mark_late(LBEG); - mark_late(LEND); - mark_late(LCOUNT); - mark_late(SAR); - mark_late(WINDOWBASE); - mark_late(WINDOWSTART); - mark_late(DEBUG_PC); - mark_late(EXCSAVE_1); - mark_late(PS); - mark_late(EXCCAUSE); - mark_late(DEBUGCAUSE); - mark_late(EXCVADDR); -#ifdef __XTENSA__ - init_debug_comm(); - init_debug_entry(); -#endif -} diff --git a/hifi/xaf/hifi-dpf/core/util/gdbstub/xtensa-defs.h b/hifi/xaf/hifi-dpf/core/util/gdbstub/xtensa-defs.h deleted file mode 100644 index 6ba485ff..00000000 --- a/hifi/xaf/hifi-dpf/core/util/gdbstub/xtensa-defs.h +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2018 Cadence Design Systems, Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to use this Software with Cadence processor cores only and -* not with any other processors and platforms, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -******************************************************************************/ - -#ifndef XTENSA_DEFS_H -#define XTENSA_DEFS_H - -#include <xtensa/specreg.h> -#include <xtensa/config/core-isa.h> -#include <xtensa/corebits.h> - -#define _AREG0 256 - -#define STACK_SIZE 1024 -#define DEBUG_PC (EPC + XCHAL_DEBUGLEVEL) -#define DEBUG_EXCSAVE (EXCSAVE + XCHAL_DEBUGLEVEL) -#define DEBUG_PS (EPS + XCHAL_DEBUGLEVEL) - -#endif /* XTENSA_DEFS_H */ diff --git a/hifi/xaf/hifi-dpf/core/util/mutex.c b/hifi/xaf/hifi-dpf/core/util/mutex.c deleted file mode 100644 index d62a6a17..00000000 --- a/hifi/xaf/hifi-dpf/core/util/mutex.c +++ /dev/null @@ -1,156 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2018 Cadence Design Systems, Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to use this Software with Cadence processor cores only and -* not with any other processors and platforms, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -******************************************************************************/ - -/******************************************************************************* - * mutex.c - * - * Implementation of non-robust Szymanski linear-waiting algorithm. Types of - * failures tolerated by Szymanski's "robust" algorithm are not specific for - * Xtensa DSP cluster and therefore more lightweight version of the algorithm - * is used. FIFO servicing property is of low importance, and faster/smaller - * version with linear-wait property is preferable. - ******************************************************************************/ - -#include "xf.h" - -/******************************************************************************* - * Local constants definitions - ******************************************************************************/ - -/* ...communication variables */ -#define __M_A (1 << 0) -#define __M_W (1 << 1) -#define __M_S (1 << 2) - -/* ...process states (updated atomically) */ -#define M_PASSIVE (0) -#define M_ENTRY (__M_A) -#define M_INSIDE (__M_W) -#define M_TRANSIENT (__M_S | __M_W) -#define M_EXIT (__M_S) - -/* ...total number of cores */ -#define M_N XF_CFG_CORES_NUM - -/* ...do not compile the code if there is just a single core */ -#if M_N > 1 -/******************************************************************************* - * Entry points - ******************************************************************************/ - -void mutex_lock(u32 i) -{ - u32 j; - - /* ...p1: i-th core goes into "entry" state (aws = true,false,false) */ - MUTEX_SHARED_WRITE(i, M_ENTRY); - - /* ...p2: wait all processes have sj=false (waiting room door is open) */ - for (j = 0; j < M_N; j++) - { - /* ...wait until sj = false */ - while (MUTEX_SHARED_READ(j) & __M_S) (void) 0; - } - - /* ...p3: i-th core enters "inside" state (aws = false,true,false) */ - MUTEX_SHARED_WRITE(i, M_INSIDE); - -p4: - /* ...p4: wait in "inside" state */ - for (j = 0; j < M_N; j++) - { - /* ...p5: check if any of the cores appears is in "entry" state (aj=true) */ - if (MUTEX_SHARED_READ(j) & __M_A) - { - /* ...p5: found core in "entry" state (j < n); wait until it enters waiting room */ - goto p7; - } - } - - /* ...p6: j == n; enter into "transient" state (ai=false, wi=true, si=true) */ - MUTEX_SHARED_WRITE(i, M_TRANSIENT); - - /* ...p6.1: check for any core appearing in "entry" room */ - for (j = 0; j < M_N; j++) - { - if (MUTEX_SHARED_READ(j) & __M_A) - { - /* ...p6.2: found core in "entry" state (j < n) */ - MUTEX_SHARED_WRITE(i, M_INSIDE); - - /* ...back of to the "inside" state */ - goto p7; - } - } - - /* ...p6.3: no cores in "entry" room (j == n); go to "exit" state (ai=false, wi=false, si=true) */ - MUTEX_SHARED_WRITE(i, M_EXIT); - - /* ...p6.4: allow all cores to leave "transient" state (i.e. switch to "exit") */ - for (j = 0; j < M_N; j++) - { - while (MUTEX_SHARED_READ(j) & __M_W) (void) 0; - } - - goto p9; - -p7: - /* ...j < n condition is met; find any cores in "inside" state (wj = true, sj = false) */ - for (j = 0; j < M_N; j++) - { - /* ...check if the core is in "exit" state */ - if (MUTEX_SHARED_READ(j) == M_EXIT) - { - /* ...p8.1: different core is a leader; go to "exit" state (ai=false, wi=false, si=true) */ - MUTEX_SHARED_WRITE(i, M_EXIT); - - goto p9; - } - } - - /* ...wait in "inside" state while all transients settle */ - goto p4; - -p9: - /* ...p9: i-th core is in "exit" state; enter critical section in accordance with numbering */ - for (j = 0; j < i; j++) - { - /* ...wait until core with lower number in "inside"/"transient"/"exit" states leaves */ - while (MUTEX_SHARED_READ(j) & (__M_W | __M_S)) (void) 0; - } - - /* ...critical section entered */ -} - -/******************************************************************************* - * mutex_unlock - * - * Release multi-core mutex - ******************************************************************************/ - -void mutex_unlock(u32 i) -{ - /* ...enter into "passive" state (ai=false, wi=false, si=false) */ - MUTEX_SHARED_WRITE(i, M_PASSIVE); -} - -#endif /* M_N > 1 */ diff --git a/hifi/xaf/hifi-dpf/core/util/rbtree.c b/hifi/xaf/hifi-dpf/core/util/rbtree.c deleted file mode 100644 index 740e0255..00000000 --- a/hifi/xaf/hifi-dpf/core/util/rbtree.c +++ /dev/null @@ -1,842 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2018 Cadence Design Systems, Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to use this Software with Cadence processor cores only and -* not with any other processors and platforms, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -******************************************************************************/ - -/******************************************************************************* - * rbtree.c - * - * Red-black tree library - ******************************************************************************/ - -#include "xf.h" - -/******************************************************************************* - * Macros definitions - ******************************************************************************/ - -/* ...node color */ -#define RB_RED (1) -#define RB_BLK (0) - -/* ...pointer to parent node */ -#define RB_PARENT(tree, node) ((node)->parent) - -/* ...pointer to left child node */ -#define RB_LEFT(tree, node) ((node)->left) - -/* ...pointer to right child node */ -#define RB_RIGHT(tree, node) ((node)->right) - -/* ...pointer to right child node */ -#define RB_COLOR(tree, node) ((node)->color & 1) - -/* ...check if node is black */ -#define RB_IS_BLACK(tree, node) (!((node)->color & RB_RED)) - -/* ...root node index of the tree - can be simplified? */ -#define RB_ROOT(tree) RB_LEFT((tree), &(tree)->root) - -/* ...empty node */ -#define RB_NULL(tree) (&(tree)->root) - -/******************************************************************************* - * Helpers - ******************************************************************************/ - -#define RB_SET_P(t, n, p) \ - ({ (n)->parent = (p); }) - -#define RB_SET_L(t, n, l) \ - ({ (n)->left = (l); }) - -#define RB_SET_R(t, n, r) \ - ({ (n)->right = (r); }) - -#define RB_SET_C(t, n, c) \ - RB_SET_C_##c((t), (n)) - -#define RB_SET_C_RB_BLK(t, n) \ - ({ (n)->color &= ~1; }) - -#define RB_SET_C_RB_RED(t, n) \ - ({ (n)->color |= 1; }) - -#define RB_SET_P_C(t, n, p, c) \ - ({ (n)->parent = (p); RB_SET_C_##c(t, n); }) - -#define RB_SET_P_L(t, n, p, l) \ - ({ (n)->parent = (p); (n)->left = (l); }) - -#define RB_SET_P_L_C(t, n, p, l, c) \ - ({ (n)->parent = (p); (n)->left = (l); RB_SET_C_##c(t, n); }) - -#define RB_SET_P_R(t, n, p, r) \ - ({ (n)->parent = (p); (n)->right = (r); }) - -#define RB_SET_P_R_C(t, n, p, r, c) \ - ({ (n)->parent = (p); (n)->right = (r); RB_SET_C_##c(t, n); }) - -#define RB_SET_P_L_R(t, n, p, l, r) \ - ({ (n)->parent = (p); (n)->left = (l); (n)->right = (r); }) - -#define RB_SET_P_L_R_C(t, n, p, l, r, c)\ - ({ (n)->parent = (p); (n)->left = (l); (n)->right = (r); RB_SET_C_##c(t, n); }) - -#define RB_SET_ROOT(t, n) \ - RB_SET_L((t), &(t)->root, (n)) - -/******************************************************************************* - * RB-tree functions - ******************************************************************************/ - -/******************************************************************************* - * rb_first, rb_last - * - * Return pointer to first/last item in the tree - ******************************************************************************/ - -rb_idx_t rb_first(rb_tree_t *tree) -{ - rb_idx_t p_idx, t_idx; - - if ((p_idx = RB_ROOT(tree)) != RB_NULL(tree)) - { - /* ...find left-most item in non-empty tree */ - while ((t_idx = RB_LEFT(tree, p_idx)) != RB_NULL(tree)) - p_idx = t_idx; - } - - return p_idx; -} - -rb_idx_t rb_last(rb_tree_t *tree) -{ - rb_idx_t p_idx, t_idx; - - if ((p_idx = RB_ROOT(tree)) != RB_NULL(tree)) - { - /* ...find right-most item in non-empty tree */ - while ((t_idx = RB_RIGHT(tree, p_idx)) != RB_NULL(tree)) - p_idx = t_idx; - } - - return p_idx; -} - -/******************************************************************************* - * rb_next, rb_prev - * - * Return next / previous in-order item in the tree - ******************************************************************************/ - -rb_idx_t rb_next(rb_tree_t *tree, rb_idx_t n_idx) -{ - rb_idx_t p_idx, c_idx, t_idx; - - /* ...if we have any right children, process them */ - if ((c_idx = RB_RIGHT(tree, n_idx)) != RB_NULL(tree)) - { - /* ...descent to the left-most node starting from right child */ - while ((t_idx = RB_LEFT(tree, c_idx)) != RB_NULL(tree)) - c_idx = t_idx; - return c_idx; - } - - /* ...no right children; ascend to our parent while we are right child */ - while ((p_idx = RB_PARENT(tree, n_idx)) != RB_NULL(tree)) - { - /* ...as soon as "n" is a left child, return "p" */ - if (n_idx == RB_RIGHT(tree, p_idx)) - n_idx = p_idx; - else - return p_idx; - } - - /* ...we were right-most child */ - return p_idx; -} - -rb_idx_t rb_prev(rb_tree_t *tree, rb_idx_t n_idx) -{ - rb_idx_t p_idx, c_idx, t_idx; - - /* ...if we have any left children, process them */ - if ((c_idx = RB_LEFT(tree, n_idx)) != RB_NULL(tree)) - { - /* ...descent to the right-most node starting from left child */ - while ((t_idx = RB_RIGHT(tree, c_idx)) != RB_NULL(tree)) - c_idx = t_idx; - return c_idx; - } - - /* ...no left children; ascend to our parent while we are left child */ - while ((p_idx = RB_PARENT(tree, n_idx)) != RB_NULL(tree)) - { - /* ...as soon as "n" is a right child, return "p" */ - if (n_idx == RB_LEFT(tree, p_idx)) - n_idx = p_idx; - else - return p_idx; - } - - /* ...we were left-most child */ - return p_idx; -} - -/******************************************************************************* - * rb_init - * - * Initialize rb-tree structure - ******************************************************************************/ - -void rb_init(rb_tree_t *tree) -{ - /* ...initialize sentinel node of the empty tree */ - RB_SET_P_L_R_C(tree, &tree->root, RB_NULL(tree), RB_NULL(tree), RB_NULL(tree), RB_BLK); -} - -/******************************************************************************* - * rb_insert - * - * Insert new item into RB-tree. Returns non-zero node index on success - ******************************************************************************/ - -/* ...internal tree balancing function */ -static void __rb_insert_balance(rb_tree_t *tree, rb_idx_t n_idx, rb_idx_t p_idx) -{ - rb_idx_t u_idx, g_idx, t_idx, cl_idx, cr_idx; - -rebalance: - - /*************************************************************************** - * Trivial case #1 - N (red) is a root - **************************************************************************/ - - if (p_idx == RB_NULL(tree)) - { - RB_SET_C(tree, n_idx, RB_BLK); - goto root; - } - - /*************************************************************************** - * Trivial case #2 - P is black - **************************************************************************/ - - if (RB_IS_BLACK(tree, p_idx)) - goto done; - - /*************************************************************************** - * Complex cases - P is red, N is red - **************************************************************************/ - - /* ...grandparent must exist and be black */ - g_idx = RB_PARENT(tree, p_idx); - if (p_idx == RB_LEFT(tree, g_idx)) - { - /* ...we are left grandchild; get uncle (if it exists) */ - u_idx = RB_RIGHT(tree, g_idx); - - /* ...if U is read, we have conditions of case #3 */ - if (!RB_IS_BLACK(tree, u_idx)) - goto case3; - - /* ...we will need grand-grand-parent later */ - t_idx = RB_PARENT(tree, g_idx); - - /* ...U is black/null; if we are LL grandchild, we have case #5 */ - if (n_idx == RB_LEFT(tree, p_idx)) - goto case5_ll; - - /* ...N is RL grandchild of G; case #4 */ - goto case4_rl; - } - else - { - /* ...we are right grandchild; get uncle (if it exists) */ - u_idx = RB_LEFT(tree, g_idx); - - /* ...if U is read, we have conditions of case #3 */ - if (!RB_IS_BLACK(tree, u_idx)) - goto case3; - - /* ...we will need grand-grand-parent later */ - t_idx = RB_PARENT(tree, g_idx); - - /* ...U is black/null; if we are RR grandchild, we have case #5 */ - if (n_idx == RB_RIGHT(tree, p_idx)) - goto case5_rr; - - /* ...N is LR grandchild of G; case #4 */ - goto case4_lr; - } - -case4_rl: - - /*************************************************************************** - * Case #4 - P is red, U is black, N is red RL grandchild of G. We will do - * two tree rotations - first the one described in case #4, second is the - * one described in case #5 (as have conditions for case #5(LL) with P and - * N changing roles - **************************************************************************/ - - cl_idx = RB_LEFT(tree, n_idx), cr_idx = RB_RIGHT(tree, n_idx); - RB_SET_P_L_R_C(tree, n_idx, t_idx, p_idx, g_idx, RB_BLK); - RB_SET_P_R(tree, p_idx, n_idx, cl_idx); - RB_SET_P(tree, cl_idx, p_idx); - RB_SET_P_L_C(tree, g_idx, n_idx, cr_idx, RB_RED); - RB_SET_P(tree, cr_idx, g_idx); - - /* ...new root of subtree is N; adjust T pointer */ - goto case5_xx; - -case4_lr: - - /*************************************************************************** - * Case #4 - P is red, U is black, N is red LR grandchild of G. We will do - * two tree rotations - first the one described in case #4, second is the - * one described in case #5 (as have conditions for case #5(RR) with P and - * N changing roles - **************************************************************************/ - - cl_idx = RB_LEFT(tree, n_idx), cr_idx = RB_RIGHT(tree, n_idx); - RB_SET_P_L_R_C(tree, n_idx, t_idx, g_idx, p_idx, RB_BLK); - RB_SET_P_L(tree, p_idx, n_idx, cr_idx); - RB_SET_P(tree, cr_idx, p_idx); - RB_SET_P_R_C(tree, g_idx, n_idx, cl_idx, RB_RED); - RB_SET_P(tree, cl_idx, g_idx); - - /* ...new root of the subtree is N; adjust T pointer */ - goto case5_xx; - -case5_ll: - - /*************************************************************************** - * Case #5: N is LL grandchild of P; N and P red, G and U black - **************************************************************************/ - - cr_idx = RB_RIGHT(tree, p_idx); - RB_SET_P_L_C(tree, g_idx, p_idx, cr_idx, RB_RED); - RB_SET_P(tree, cr_idx, g_idx); - RB_SET_P_R_C(tree, p_idx, t_idx, g_idx, RB_BLK); - - /* ...new root of the subtree is P; relabel and adjust T pointer */ - n_idx = p_idx; - goto case5_xx; - -case5_rr: - - /*************************************************************************** - * Case #5: N is RR grandchild of P; N and P red, G and U black - **************************************************************************/ - - cl_idx = RB_LEFT(tree, p_idx); - RB_SET_P_R_C(tree, g_idx, p_idx, cl_idx, RB_RED); - RB_SET_P(tree, cl_idx, g_idx); - RB_SET_P_L_C(tree, p_idx, t_idx, g_idx, RB_BLK); - - /* ...new root of the subtree is P; relabel and adjust T pointer */ - n_idx = p_idx; - goto case5_xx; - -case5_xx: - - /* ...N is a (black) root of subtree; check if it is a root of tree as well */ - if (t_idx == RB_NULL(tree)) - goto root; - else if (g_idx == RB_LEFT(tree, t_idx)) - RB_SET_L(tree, t_idx, n_idx); - else - RB_SET_R(tree, t_idx, n_idx); - - goto done; - -case3: - - /*************************************************************************** - * Case #3 - P and U are red, G is black - **************************************************************************/ - - RB_SET_C(tree, p_idx, RB_BLK); - RB_SET_C(tree, u_idx, RB_BLK); - RB_SET_C(tree, g_idx, RB_RED); - - /* ...rebalance the tree for a G */ - n_idx = g_idx, p_idx = RB_PARENT(tree, g_idx); - goto rebalance; - -root: - /* ...adjust root pointer of the tree */ - RB_SET_ROOT(tree, n_idx); - -done: - /* ...tree is balanced */ - return; -} - -/* ...high-level API function */ -void rb_insert(rb_tree_t *tree, rb_idx_t n_idx, rb_idx_t p_idx) -{ - if (p_idx == RB_NULL(tree)) - { - /* ...set black root node */ - RB_SET_P_L_R_C(tree, n_idx, p_idx, p_idx, p_idx, RB_BLK); - - /* ...tree consists of the only root node; is balanced */ - RB_SET_ROOT(tree, n_idx); - } - else - { - /* ...create new node - set parent pointer and paint red */ - RB_SET_P_L_R_C(tree, n_idx, p_idx, RB_NULL(tree), RB_NULL(tree), RB_RED); - - /* ...and rebalance the tree */ - __rb_insert_balance(tree, n_idx, p_idx); - } -} - -/******************************************************************************* - * rb_delete - * - * Remove item from RB-key (by key). Returns zero on success - ******************************************************************************/ - -/* ...internal tree balancing function */ -static void __rb_delete_rebalance(rb_tree_t *tree, rb_idx_t p_idx) -{ - rb_idx_t n_idx, s_idx, sl_idx, sr_idx, g_idx, c_idx, cl_idx, cr_idx; - - /* ...initialize rebalancing procedure with null-child of P */ - n_idx = RB_NULL(tree); - -rebalance: - - /* ...save grand-parent pointer (may be null) */ - g_idx = RB_PARENT(tree, p_idx); - - /*************************************************************************** - * Check for complex cases - **************************************************************************/ - - if (n_idx == RB_LEFT(tree, p_idx)) - { - /* ...N is left child; get sibling (must exist) and its children */ - s_idx = RB_RIGHT(tree, p_idx); - sl_idx = RB_LEFT(tree, s_idx); - sr_idx = RB_RIGHT(tree, s_idx); - - /* ...if S is black, test for conditions 3,4,5,6; otherwise - case 2 */ - if (RB_IS_BLACK(tree, s_idx)) - goto test3_l; - else - goto case2_l; - } - else - { - /* ...N is right child; get sibling (must exist) and its children */ - s_idx = RB_LEFT(tree, p_idx); - sl_idx = RB_LEFT(tree, s_idx); - sr_idx = RB_RIGHT(tree, s_idx); - - /* ...if S is black, test for conditions 3,4,5,6; otherwise - case 2 */ - if (RB_IS_BLACK(tree, s_idx)) - goto test3_r; - else - goto case2_r; - } - -case2_l: - - /*************************************************************************** - * Case #2: N is a left child of P; S is red - **************************************************************************/ - - c_idx = sl_idx; - RB_SET_P_L_C(tree, s_idx, g_idx, p_idx, RB_BLK); - RB_SET_P_R_C(tree, p_idx, s_idx, c_idx, RB_RED); - RB_SET_P(tree, c_idx, p_idx); - - /* ...S is new root of subtree, Sl(C) is new sibling of N; update G */ - goto case2_x; - -case2_r: - - /*************************************************************************** - * Case #2: N is a right child of P; S is red - **************************************************************************/ - - c_idx = sr_idx; - RB_SET_P_R_C(tree, s_idx, g_idx, p_idx, RB_BLK); - RB_SET_P_L_C(tree, p_idx, s_idx, c_idx, RB_RED); - RB_SET_P(tree, c_idx, p_idx); - - /* ...S is new root of subtree, Sr(C) is new sibling of N; update G */ - goto case2_x; - -case2_x: - - /* ...check if S is becoming new (black) root of the tree */ - if (g_idx == RB_NULL(tree)) - RB_SET_ROOT(tree, s_idx); - else if (p_idx == RB_LEFT(tree, g_idx)) - RB_SET_L(tree, g_idx, s_idx); - else - RB_SET_R(tree, g_idx, s_idx); - - /* ...relabel new N's grandparent (now S) as G and new sibling (now C) as S */ - g_idx = s_idx, s_idx = c_idx; - sl_idx = RB_LEFT(tree, s_idx); - sr_idx = RB_RIGHT(tree, s_idx); - - /* ...N is still one of P's children; select proper side */ - if (n_idx == RB_LEFT(tree, p_idx)) - goto test3_l; - else - goto test3_r; - -test3_l: - - /*************************************************************************** - * Test for cases 3,4,5,6; P is any, S is black. N is left child of P - **************************************************************************/ - - if (!RB_IS_BLACK(tree, sr_idx)) - /* ...Sr is red, Sl of any color; conditions for case #6 are met */ - goto case6_l; - else if (!RB_IS_BLACK(tree, sl_idx)) - /* ...Sr is black and Sl is red; conditions for case #5 are met */ - goto case5_l; - else if (RB_IS_BLACK(tree, p_idx)) - /* ...Sl and Sr are of the same (black) color and P is black */ - goto case3; - else - /* ...Sl and Sr are of the same (black) color and P is red */ - goto case4; - -test3_r: - - /*************************************************************************** - * Test for cases 3,4,5,6; P is any, S is black. N is right child of P - **************************************************************************/ - - if (!RB_IS_BLACK(tree, sl_idx)) - /* ...Sl is red, Sr of any color; conditions for case #6 are met */ - goto case6_r; - else if (!RB_IS_BLACK(tree, sr_idx)) - /* ...Sl is black and Sr is red; conditions for case #5 are met */ - goto case5_r; - else if (RB_IS_BLACK(tree, p_idx)) - /* ...Sl and Sr are of the same (black) color and P is black */ - goto case3; - else - /* ...Sl and Sr are of the same (black) color and P is red */ - goto case4; - -case3: - - /*************************************************************************** - * Case #3: N, P, S, Sl and Sr are black - **************************************************************************/ - - RB_SET_C(tree, s_idx, RB_RED); - - /* ...and rebalance the tree for parent */ - n_idx = p_idx, p_idx = RB_PARENT(tree, p_idx); - - if (p_idx == RB_NULL(tree)) - goto done; - else - goto rebalance; - -case4: - - /*************************************************************************** - * Case #4: N and S are black, P is red, Sl and Sr are all black - **************************************************************************/ - - RB_SET_C(tree, s_idx, RB_RED); - RB_SET_C(tree, p_idx, RB_BLK); - - goto done; - -case5_l: - /*************************************************************************** - * Case #5: S is black, Sl is red, Sr is black; N is left child of P. We - * have two subsequent transformations (case #5 and case #6) combined - **************************************************************************/ - - cl_idx = RB_LEFT(tree, sl_idx); - cr_idx = RB_RIGHT(tree, sl_idx); - - if (RB_IS_BLACK(tree, p_idx)) - RB_SET_P_L_R_C(tree, sl_idx, g_idx, p_idx, s_idx, RB_BLK); - else - RB_SET_P_L_R_C(tree, sl_idx, g_idx, p_idx, s_idx, RB_RED); - - RB_SET_P_R_C(tree, p_idx, sl_idx, cl_idx, RB_BLK); - RB_SET_P(tree, cl_idx, p_idx); - RB_SET_P_L(tree, s_idx, sl_idx, cr_idx); - RB_SET_P(tree, cr_idx, s_idx); - - /* ...relabel new root as S (for common processing in case #6) */ - s_idx = sl_idx; - goto case6_x; - -case5_r: - /*************************************************************************** - * Case #5: S is black, Sr is red, Sl is black; N is right child of P. We - * have two subsequent transformations (case #5 and case #6) combined - **************************************************************************/ - - cl_idx = RB_LEFT(tree, sr_idx); - cr_idx = RB_RIGHT(tree, sr_idx); - - if (RB_IS_BLACK(tree, p_idx)) - RB_SET_P_L_R_C(tree, sr_idx, g_idx, s_idx, p_idx, RB_BLK); - else - RB_SET_P_L_R_C(tree, sr_idx, g_idx, s_idx, p_idx, RB_RED); - - RB_SET_P_L_C(tree, p_idx, sr_idx, cr_idx, RB_BLK); - RB_SET_P(tree, cr_idx, p_idx); - RB_SET_P_R(tree, s_idx, sr_idx, cl_idx); - RB_SET_P(tree, cl_idx, s_idx); - - /* ...relabel new root as S (for common processing in case #6) */ - s_idx = sr_idx; - goto case6_x; - -case6_l: - - /*************************************************************************** - * Case #6: S is black, N is the left child of P, Sr is red - **************************************************************************/ - - if (RB_IS_BLACK(tree, p_idx)) - RB_SET_P_L(tree, s_idx, g_idx, p_idx); - else - RB_SET_P_L_C(tree, s_idx, g_idx, p_idx, RB_RED); - - RB_SET_P_R_C(tree, p_idx, s_idx, sl_idx, RB_BLK); - RB_SET_P(tree, sl_idx, p_idx); - RB_SET_C(tree, sr_idx, RB_BLK); - - /* ...S is a new root of subtree; update G */ - goto case6_x; - -case6_r: - - /*************************************************************************** - * Case #6: S is black, N is the right child of P, Sl is red - **************************************************************************/ - - if (RB_IS_BLACK(tree, p_idx)) - RB_SET_P_R(tree, s_idx, g_idx, p_idx); - else - RB_SET_P_R_C(tree, s_idx, g_idx, p_idx, RB_RED); - - RB_SET_P_L_C(tree, p_idx, s_idx, sr_idx, RB_BLK); - RB_SET_P(tree, sr_idx, p_idx); - RB_SET_C(tree, sl_idx, RB_BLK); - - /* ...S is a new root of subtree; update G */ - goto case6_x; - -case6_x: - - /* ...S is a new root of subtree; update G's pointer */ - if (g_idx == RB_NULL(tree)) - RB_SET_ROOT(tree, s_idx); - else if (p_idx == RB_LEFT(tree, g_idx)) - RB_SET_L(tree, g_idx, s_idx); - else - RB_SET_R(tree, g_idx, s_idx); - - /* ...tree is balanced; pass through */ - -done: - - return; -} - -/* ...high-level API function */ -rb_idx_t rb_delete(rb_tree_t *tree, rb_idx_t n_idx) -{ - rb_idx_t p_idx, t_idx, m_idx, c_idx, l_idx, r_idx, k_idx; - u32 color; - - /* ...save parent of element N that we are going to remove */ - p_idx = RB_PARENT(tree, n_idx); - - /* ...get in-order predecessor/successor of n_idx, if possible */ - if ((m_idx = RB_LEFT(tree, n_idx)) != RB_NULL(tree)) - { - while ((t_idx = RB_RIGHT(tree, m_idx)) != RB_NULL(tree)) - m_idx = t_idx; - - /* ...set the child of in-order predecessor (may be null) */ - c_idx = RB_LEFT(tree, m_idx); - } - else if ((m_idx = RB_RIGHT(tree, n_idx)) != RB_NULL(tree)) - { - while ((t_idx = RB_LEFT(tree, m_idx)) != RB_NULL(tree)) - m_idx = t_idx; - - /* ...set the child of in-order successor (may be null) */ - c_idx = RB_RIGHT(tree, m_idx); - } - else if (p_idx == RB_NULL(tree)) - { - /* ...tree consists of the only root node N that we are removing */ - RB_SET_ROOT(tree, m_idx); - - /* ..return tree null pointer */ - return m_idx; - } - else - { - /* ...N is a (non-root) leaf node; M and C are null */ - c_idx = m_idx; - - /* ...save the color of the node we are going to delete */ - color = RB_COLOR(tree, n_idx); - - /* ...set new parent of C */ - t_idx = p_idx; - - /* ...pointer that we return as in-order predecessor/successor */ - k_idx = p_idx; - - /* ...adjust only parent of the N */ - goto adjust_parent; - } - - /* ...node that replaces our component is M */ - k_idx = m_idx; - - /*************************************************************************** - * Replace node N with M - **************************************************************************/ - - /* ...save original color of M (the node that we are deleting) */ - color = RB_COLOR(tree, m_idx); - - /* ...put M in place of N; get N's children */ - l_idx = RB_LEFT(tree, n_idx); - r_idx = RB_RIGHT(tree, n_idx); - - /* ...see if M is a child of N */ - if ((t_idx = RB_PARENT(tree, m_idx)) != n_idx) - { - /* ...C becomes left or right child of M's original parent T */ - if (c_idx == RB_LEFT(tree, m_idx)) - RB_SET_R(tree, t_idx, c_idx); - else - RB_SET_L(tree, t_idx, c_idx); - - /* ...adjust C parent pointer (okay if it's null) */ - RB_SET_P(tree, c_idx, t_idx); - - /* ...set all pointers of node M (it replaces N) */ - RB_SET_P_L_R(tree, m_idx, p_idx, l_idx, r_idx); - RB_SET_P(tree, l_idx, m_idx); - RB_SET_P(tree, r_idx, m_idx); - } - else - { - /* ...M is a left or right child of N; it gets to N's place, and C remains intact */ - if (m_idx == l_idx) - { - RB_SET_P_R(tree, m_idx, p_idx, r_idx); - RB_SET_P(tree, r_idx, m_idx); - } - else - { - RB_SET_P_L(tree, m_idx, p_idx, l_idx); - RB_SET_P(tree, l_idx, m_idx); - } - - /* ...parent of C is still M (we label it as T) */ - t_idx = m_idx; - } - - /* ...paint M in the same color as N which it replaced */ - if (RB_IS_BLACK(tree, n_idx)) - RB_SET_C(tree, m_idx, RB_BLK); - else - RB_SET_C(tree, m_idx, RB_RED); - -adjust_parent: - - /* ...adjust N's parent node to point to M */ - if (p_idx == RB_NULL(tree)) - RB_SET_ROOT(tree, m_idx); - else if (n_idx == RB_LEFT(tree, p_idx)) - RB_SET_L(tree, p_idx, m_idx); - else - RB_SET_R(tree, p_idx, m_idx); - - /* ...check for a color of deleted item (M or N in case it is a leaf) */ - if (color == RB_BLK) - { - if (c_idx == RB_NULL(tree)) - /* ...rebalance the tree for a T node (it is never a null)*/ - __rb_delete_rebalance(tree, t_idx); - else - /* ...C node exists and is necessarily red; repaint it black */ - RB_SET_C(tree, c_idx, RB_BLK); - } - - /* ....return the node K which replaced deleted node N */ - return k_idx; -} - -/******************************************************************************* - * rb_replace - * - * Replace the node with the same-key node - adjust tree pointers - ******************************************************************************/ - -void rb_replace(rb_tree_t *tree, rb_idx_t n_idx, rb_idx_t t_idx) -{ - rb_idx_t p_idx, l_idx, r_idx; - - /* ...get node pointers */ - p_idx = RB_PARENT(tree, n_idx), l_idx = RB_LEFT(tree, n_idx), r_idx = RB_RIGHT(tree, n_idx); - - /* ...set new node pointers */ - RB_SET_P_L_R(tree, t_idx, p_idx, l_idx, r_idx); - - /* ...set node color */ - if (RB_IS_BLACK(tree, n_idx)) - RB_SET_C(tree, t_idx, RB_BLK); - else - RB_SET_C(tree, t_idx, RB_RED); - - /* ...update parent node */ - if (p_idx == RB_NULL(tree)) - RB_SET_ROOT(tree, t_idx); - else if (n_idx == RB_LEFT(tree, p_idx)) - RB_SET_L(tree, p_idx, t_idx); - else - RB_SET_R(tree, p_idx, t_idx); - - /* ...update children's parent node (okay if null) */ - RB_SET_P(tree, l_idx, t_idx), RB_SET_P(tree, r_idx, t_idx); -} diff --git a/hifi/xaf/hifi-dpf/core/util/tinyvprintf.c b/hifi/xaf/hifi-dpf/core/util/tinyvprintf.c deleted file mode 100644 index 25d7e03e..00000000 --- a/hifi/xaf/hifi-dpf/core/util/tinyvprintf.c +++ /dev/null @@ -1,198 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2018 Cadence Design Systems, Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to use this Software with Cadence processor cores only and -* not with any other processors and platforms, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -******************************************************************************/ - - -#include <string.h> -#include "lib/tinyput.h" - - -/* - * Simple formatted output routine. - * Designed primarily for small size (and secondarily for efficiency). - * Only a common subset of printf formats and options are handled: - * - * %[-+ ][0][width]i decimal signed integer - * %[-+ ][0][width]d decimal signed integer - * %[-][0][width]u decimal unsigned integer - * %[-][0][width]x hex unsigned integer - * %[-][0][width]p hex unsigned integer with 0x prefix ("pointer") - * %[-][width]c single character - * %[-][width]s string - * - * These modifiers are ignored (legally on 32-bit Xtensa): - * # (alternate format) - * h (short) expands to int on 32-bit Xtensa - * l (long) same as int on 32-bit Xtensa - * j (intmax_t or uintmax_t) same as int on 32-bit Xtensa - * z (size_t or ssize_t) same as int on 32-bit Xtensa - * t (ptrdiff_t) same as int on 32-bit Xtensa - * - * Does NOT support: - * width.prec (precision modifier) - * %X (capitalized hex; handles this as lowercase hex) - * %o (octal) - * %[L][feEgG] (floating point formats) - * %a %A (hex floating point formats, C99) - * %C (multibyte character) - * %S (multibyte character string) - * %n (returning count of character written) - * ll (long long) - * q j z t (other size modifiers, eg. see glibc) - */ -int tiny_vsprintf(char *out, const char *fmt, va_list ap) -{ - int total = 0; - char c, space = ' ', buf[11]; /* largest 32-bit integer output (octal) */ - - while ((c = *(char*)fmt++) != 0) { - if (c != '%') { - *out++ = c; - total++; - } else { - int width = 0, len = 1, rightjust = 1; - unsigned n; - char *s = buf, *t, pad = ' ', sign = 0; - while (1) { - c = *(char*)fmt++; - switch (c) { - case 'c': buf[0] = va_arg(ap, int); goto donefmt; - case 's': s = va_arg(ap, char*); - if (s == 0) - len = 0; - else { - for (t = s; *t; t++) ; - len = t - s; - } - goto donefmt; - - case '#': /* ignore (not supported) */ - case 'h': /* ignore (short; passed as int) */ - case 'l': /* ignore (long; same as int) */ - case 'j': /* ignore (intmax_t or uintmax_t; same as int) */ - case 'z': /* ignore (size_t or ssize_t; same as int) */ - case 't': /* ignore (ptrdiff_t; same as int) */ - break; - - case ' ': sign = ' '; break; - case '+': sign = '+'; break; - case '-': rightjust = 0; break; - - case 'i': /*FALLTHROUGH*/ - case 'd': n = va_arg(ap, int); - if ((int)n < 0) { - sign = '-'; - n = -(int)n; - } - if (sign) { - if (rightjust && pad == ' ') - *s++ = sign; - else { - *out++ = sign; - width--; - total++; - } - } - goto do_decimal; - case 'u': n = va_arg(ap, int); - do_decimal: - { - /* (avoids division or multiplication) */ - int digit, i, seen = 0; - for (digit = 0; n >= 1000000000; digit++) - n -= 1000000000; - for (i = 9;;) { - if (!seen && digit != 0) - seen = i; - if (seen) - *s++ = '0' + digit; - for (digit = 0; n >= 100000000; digit++) - n -= 100000000; - if (--i == 0) { - *s++ = '0' + digit; - len = s - buf; - s = buf; - goto donefmt; - } - n = ((n << 1) + (n << 3)); - } - } - /*NOTREACHED*/ - -#if 0 - case 'o': n = va_arg(ap, unsigned); - s = buf + 11; - do { - *--s = '0' + (n & 7); - n = (unsigned)n >> 3; - } while (n); - len = buf + 11 - s; - goto donefmt; -#endif - - case 'p': *out++ = '0', *out++ = 'x'; - total += 2; - /*FALLTHROUGH*/ - case 'X': /*FALLTHROUGH*/ - case 'x': n = va_arg(ap, unsigned); - s = buf + 8; - do { - *--s = "0123456789abcdef"[n & 0xF]; - n = (unsigned)n >> 4; - } while (n); - len = buf + 8 - s; - goto donefmt; - - case 0: goto done; - case '0': if (width == 0) pad = '0'; /*FALLTHROUGH*/ - default: if (c >= '0' && c <= '9') - width = ((width<<1) + (width<<3)) + (c - '0'); - else { - buf[0] = c; /* handles case of '%' */ - goto donefmt; - } - } - } - /*NOTREACHED*/ - donefmt: - if (len < width) { - total += width; - if (rightjust) - do { *out++ = pad; } while (len < --width); - } else - total += len; - for(n = len; n > 0; n--) *out++ = *s++; - for (; len < width; len++) *out++ = space; - } - } -done: - return total; -} - -int tiny_sprintf(char *out, const char *fmt, ...) -{ - int n = 0; - va_list ap; - va_start(ap, fmt); - n = tiny_vsprintf(out, fmt, ap); - va_end(ap); - return n; -} diff --git a/hifi/xaf/hifi-dpf/core/xf-core.c b/hifi/xaf/hifi-dpf/core/xf-core.c deleted file mode 100644 index 95bca129..00000000 --- a/hifi/xaf/hifi-dpf/core/xf-core.c +++ /dev/null @@ -1,709 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2018 Cadence Design Systems, Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to use this Software with Cadence processor cores only and -* not with any other processors and platforms, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -******************************************************************************/ - -/******************************************************************************* - * xf-core.c - * - * DSP processing framework core - * - ******************************************************************************/ - -#define MODULE_TAG CORE - -/******************************************************************************* - * Includes - ******************************************************************************/ - -#include "xf.h" - -/******************************************************************************* - * Tracing tags - ******************************************************************************/ - -/* ...general initialization sequence */ -TRACE_TAG(INIT, 1); - -/* ...message dispatching */ -TRACE_TAG(DISP, 1); - -/* ...client registration procedures */ -TRACE_TAG(REG, 1); - -/* ...ports routing/unrouting */ -TRACE_TAG(ROUTE, 1); - -#ifdef XAF_PROFILE_DSP -/* ... MCPS/profile info */ -#include "xa_profiler.h" -#endif -/******************************************************************************* - * Internal helpers - ******************************************************************************/ - -/* ...translate client-id into component handle */ -static inline xf_component_t * xf_client_lookup(xf_core_data_t *cd, u32 client) -{ - xf_cmap_link_t *link = &cd->cmap[client]; - - /* ...if link pointer is less than XF_CFG_MAX_CLIENTS, it is a free descriptor */ - return (link->next > XF_CFG_MAX_CLIENTS ? link->c : NULL); -} - -/* ...allocate client-id */ -static inline u32 xf_client_alloc(xf_core_data_t *cd) -{ - u32 client = cd->free; - - /* ...advance list head to next free id */ - (client < XF_CFG_MAX_CLIENTS ? cd->free = cd->cmap[client].next : 0); - - return client; -} - -/* ...recycle client-id */ -static inline void xf_client_free(xf_core_data_t *cd, u32 client) -{ - /* ...put client into the head of the free id list */ - cd->cmap[client].next = cd->free, cd->free = client; -} - -/******************************************************************************* - * Process commands to a proxy - ******************************************************************************/ - -/* ...register new client */ -static int xf_proxy_register(u32 core, xf_message_t *m) -{ - xf_core_data_t *cd = XF_CORE_DATA(core); - u32 src = XF_MSG_SRC(m->id); - u32 client; - xf_component_t *component; - - /* ...allocate new client-id */ - XF_CHK_ERR((client = xf_client_alloc(cd)) != XF_CFG_MAX_CLIENTS, -EBUSY); - - /* ...create component via class factory */ - if ((component = xf_component_factory(core, m->buffer, m->length)) == NULL) - { - TRACE(ERROR, _x("Component creation failed")); - - /* ...recycle client-id */ - xf_client_free(cd, client); - - /* ...return generic out-of-memory code always (tbd) */ - return -ENOMEM; - } - - /* ...register component in a map */ - cd->cmap[client].c = component; - - /* ...set component "default" port specification ("destination") */ - component->id = __XF_PORT_SPEC(core, client, 0); - - /* ...adjust session-id to include newly created component-id */ - m->id = __XF_MSG_ID(src, component->id); - - /* ...do system-specific registration of component within IPC layer */ - xf_ipc_component_addref(m->id); - - TRACE(REG, _b("registered client: %u:%u (%s)"), core, client, (xf_id_t)m->buffer); - - /* ...and return success to remote proxy (zero-length output) */ - xf_response_ok(m); - - return 0; -} - -/* ...shared buffer allocation request */ -static int xf_proxy_alloc(u32 core, xf_message_t *m) -{ - /* ...command is valid only if shared memory interface for core is specified */ - XF_CHK_ERR(xf_shmem_enabled(core), -EPERM); - - /* ...allocate shared memory buffer (system-specific function; may fail) */ - xf_shmem_alloc(core, m); - - /* ...pass result to remote proxy (on success buffer is non-null) */ - xf_response(m); - - return 0; -} - -/* ...shared buffer freeing request */ -static int xf_proxy_free(u32 core, xf_message_t *m) -{ - /* ...command is valid only if shared memory interface for core is specified */ - XF_CHK_ERR(xf_shmem_enabled(core), -EPERM); - - /* ...pass buffer freeing request to system-specific function */ - xf_shmem_free(core, m); - - /* ...return success to remote proxy (function never fails) */ - xf_response(m); - - return 0; -} - -#if 0 -/* ...port routing command processing */ -static int xf_proxy_route(u32 core, xf_message_t *m) -{ - xf_route_port_msg_t *cmd = m->buffer; - u32 src = cmd->src; - u32 dst = cmd->dst; - xf_component_t *component; - xf_output_port_t *port; - - /* ...source component must reside on the local core */ - XF_CHK_ERR(XF_MSG_SRC_CORE(src) == core, -EINVAL); - - /* ...make sure the "src" component is valid ("dst" may reside on other core) */ - if ((component = xf_client_lookup(XF_CORE_DATA(core), XF_PORT_CLIENT(src))) == NULL) - { - TRACE(ERROR, _x("Source port lookup failed: %x"), src); - return -ENOENT; - } - else if (!component->port || !(port = component->port(component, XF_PORT_ID(src)))) - { - TRACE(ERROR, _b("Source port doesn't exist: %x"), src); - return -ENOENT; - } - else if (xf_output_port_routed(port)) - { - TRACE(ERROR, _b("Source port is already routed: %x"), src); - return -EBUSY; - } - - /* ...route output port with source port set as destination */ - XF_CHK_API(xf_output_port_route(port, __XF_MSG_ID(dst, src), cmd->alloc_number, cmd->alloc_size, cmd->alloc_align)); - - TRACE(ROUTE, _b("Ports routed: %03x -> %03x"), src, dst); - - /* ...invoke component data-processing function directly (ignore errors? - tbd) */ - component->entry(component, NULL); - - /* ...return success result code (no output attached) */ - xf_response_ok(m); - - return 0; -} - -/* ...disconnect ports */ -static int xf_proxy_unroute(u32 core, xf_message_t *m) -{ - xf_unroute_port_msg_t *cmd = m->buffer; - u32 src = cmd->src; - xf_component_t *component; - xf_output_port_t *port; - - /* ...source component must reside on the local core */ - XF_CHK_ERR(XF_MSG_SRC_CORE(src) == core, -EINVAL); - - /* ...lookup source (output) port */ - if ((component = xf_client_lookup(XF_CORE_DATA(core), XF_PORT_CLIENT(src))) == NULL) - { - TRACE(ERROR, _b("Source port lookup failed: %x"), src); - return -ENOENT; - } - else if (!component->port || !(port = component->port(component, XF_PORT_ID(src)))) - { - TRACE(ERROR, _b("Source port doesn't exist: %x"), src); - return -ENOENT; - } - else if (!xf_output_port_routed(port)) - { - /* ...port is not routed; satisfy immediately */ - goto done; - } - else if (!xf_output_port_idle(port)) - { - TRACE(ERROR, _b("Source port is not idle: %x"), src); - return -EBUSY; - } - - /* ...unroute port (call must succeed) */ - xf_output_port_unroute(port); - - /* ...we cannot satisfy the command now, and need to propagate it to a sink - tbd */ - //return 0; - -done: - /* ...pass success result code to caller */ - xf_response_ok(m); - - return 0; -} -#endif - -/* ...fill-this-buffer command processing */ -static int xf_proxy_output(u32 core, xf_message_t *m) -{ - /* ...determine destination "client" */ - switch (XF_MSG_SRC_CLIENT(m->id)) - { -#if XF_TRACE_REMOTE - case 0: - /* ...destination is a tracer facility; submit buffer to tracer */ - xf_trace_submit(core, m); - return 0; -#endif - - default: - /* ...unrecognized destination; return general failure response */ - return XF_CHK_ERR(0, -EINVAL); - } -} - -/* ...flush command processing */ -static int xf_proxy_flush(u32 core, xf_message_t *m) -{ - /* ...determine destination "client" */ - switch (XF_MSG_SRC_CLIENT(m->id)) - { -#if XF_TRACE_REMOTE - case 0: - /* ...destination is a tracer facility; flush current buffer */ - xf_trace_flush(core, m); - return 0; -#endif - - default: - /* ...unrecognized destination; return general failure response */ - return XF_CHK_ERR(0, -EINVAL); - } -} - -/* ...proxy command processing table */ -static int (* const xf_proxy_cmd[])(u32, xf_message_t *) = -{ - [XF_OPCODE_TYPE(XF_REGISTER)] = xf_proxy_register, - [XF_OPCODE_TYPE(XF_ALLOC)] = xf_proxy_alloc, - [XF_OPCODE_TYPE(XF_FREE)] = xf_proxy_free, -#if 0 - [XF_OPCODE_TYPE(XF_ROUTE)] = xf_proxy_route, - [XF_OPCODE_TYPE(XF_UNROUTE)] = xf_proxy_unroute, -#endif - [XF_OPCODE_TYPE(XF_FILL_THIS_BUFFER)] = xf_proxy_output, - [XF_OPCODE_TYPE(XF_FLUSH)] = xf_proxy_flush, -}; - -/* ...total number of commands supported */ -#define XF_PROXY_CMD_NUM (sizeof(xf_proxy_cmd) / sizeof(xf_proxy_cmd[0])) - -/* ...process commands to a proxy */ -static void xf_proxy_command(u32 core, xf_message_t *m) -{ - u32 opcode = m->opcode; - int res; - - /* ...dispatch command to proper hook */ - if (XF_OPCODE_TYPE(opcode) < XF_PROXY_CMD_NUM) - { - if ((res = xf_proxy_cmd[XF_OPCODE_TYPE(opcode)](core, m)) >= 0) - { - /* ...command processed successfully; do nothing */ - return; - } - } - else - { - TRACE(ERROR, _x("invalid opcode: %x"), opcode); - } - - /* ...command processing failed; return generic failure response */ - xf_response_err(m); -} - -/******************************************************************************* - * Message completion helper - ******************************************************************************/ - -/* ...put message into local IPC command queue on remote core (src != dst) */ -static inline void xf_msg_local_ipc_put(u32 src, u32 dst, xf_message_t *m) -{ - xf_core_rw_data_t *rw = XF_CORE_RW_DATA(dst); - int first; - - /* ...flush message payload if needed */ - if (XF_LOCAL_IPC_NON_COHERENT) - { - /* ...it may be a command with output payload only - tbd */ - XF_PROXY_FLUSH(m->buffer, m->length); - } - - /* ...acquire mutex to target rw-data (running on source core) */ - xf_mutex_lock(src); - - /* ...assure memory coherency as needed */ - if (XF_LOCAL_IPC_NON_COHERENT) - { - /* ...invalidate local queue data */ - XF_PROXY_INVALIDATE(&rw->local, sizeof(rw->local)); - - /* ...place message into queue */ - first = xf_msg_enqueue(&rw->local, m); - - /* ...flush both queue and message data */ - XF_PROXY_FLUSH(&rw->local, sizeof(rw->local)), XF_PROXY_FLUSH(m, sizeof(*m)); - } - else - { - /* ...just enqueue the message */ - first = xf_msg_enqueue(&rw->local, m); - } - - /* ...release global rw-memory access lock */ - xf_mutex_unlock(src); - - /* ...signal IPI interrupt on destination core as needed */ - (first ? xf_ipi_assert(dst), 1 : 0); -} - -/* ...dequeue message from core-specific dispatch queue */ -static inline xf_message_t * xf_msg_local_ipc_get(u32 core) -{ - xf_core_rw_data_t *rw = XF_CORE_RW_DATA(core); - xf_message_t *m; - - /* ...retrieve message from queue in atomic fashion */ - xf_mutex_lock(core); - - /* ...process memory coherency as required */ - if (XF_LOCAL_IPC_NON_COHERENT) - { - /* ...inavlidate local rw-data */ - XF_PROXY_INVALIDATE(&rw->local, sizeof(rw->local)); - - /* ...get message from the queue */ - if ((m = xf_msg_dequeue(&rw->local)) != NULL) - { - /* ...flush rw-queue data */ - XF_PROXY_FLUSH(&rw->local, sizeof(rw->local)); - } - } - else - { - /* ...just dequeue message from the queue */ - m = xf_msg_dequeue(&rw->local); - } - - /* ...release rw-memory access lock */ - xf_mutex_unlock(core); - - /* ...invalidate message header and data as needed */ - if (XF_LOCAL_IPC_NON_COHERENT && m != NULL) - { - /* ...invalidate message header */ - XF_PROXY_INVALIDATE(m, sizeof(*m)); - - /* ...and data if needed (it may not be always needed - tbd) */ - (m->length ? XF_PROXY_INVALIDATE(m->buffer, m->length) : 0); - } - - /* ...return message */ - return m; -} - -/* ...retrieve message from local queue (protected from ISR) */ -static inline int xf_msg_local_put(u32 core, xf_message_t *m) -{ - xf_core_data_t *cd = XF_CORE_DATA(core); - int first; - u32 status; - - /* ...use interrupt masking protocol to protect message queue */ - status = xf_isr_disable(core); - first = xf_msg_enqueue(&cd->queue, m); - xf_isr_restore(core, status); - - return first; -} - -/* ...retrieve message from local queue (protected from ISR) */ -static inline xf_message_t * xf_msg_local_get(u32 core) -{ - xf_core_data_t *cd = XF_CORE_DATA(core); - xf_message_t *m; - u32 status; - - /* ...use interrupt masking protocol to protect message queue */ - status = xf_isr_disable(core); - m = xf_msg_dequeue(&cd->queue); - xf_isr_restore(core, status); - - return m; -} - -/* ...retrieve message from local queue (protected from ISR) */ -static inline xf_message_t * xf_msg_local_response_get(u32 core) -{ - xf_core_data_t *cd = XF_CORE_DATA(core); - xf_message_t *m; - u32 status; - - /* ...use interrupt masking protocol to protect message queue */ - status = xf_isr_disable(core); - m = xf_msg_dequeue(&cd->response); - xf_isr_restore(core, status); - - return m; -} - -/* ...call component data processing function */ -static inline void xf_core_process(xf_component_t *component) -{ - u32 id = component->id; - - /* ...client look-up successfull */ - TRACE(DISP, _b("core[%u]::client[%u]::process"), XF_PORT_CORE(id), XF_PORT_CLIENT(id)); - - /* ...call data-processing interface */ - if (component->entry(component, NULL) < 0) - { - TRACE(ERROR, _b("execution error (ignored)")); - } -} - -/* ...dispatch message queue execution */ -static inline void xf_core_dispatch(xf_core_data_t *cd, u32 core, xf_message_t *m) -{ - u32 client; - xf_component_t *component; - - /* ...do client-id/component lookup */ - if (XF_MSG_DST_PROXY(m->id)) - { - TRACE(DISP, _b("core[%u]::proxy-cmd(id=%x, opcode=%x)"), core, m->id, m->opcode); - - /* ...process message addressed to proxy */ - xf_proxy_command(core, m); - - /* ...do not like this return statement... - tbd */ - return; - } - - /* ...message goes to local component */ - client = XF_MSG_DST_CLIENT(m->id); - - /* ...check if client is alive */ - if ((component = xf_client_lookup(cd, client)) != NULL) - { - /* ...client look-up successfull */ - TRACE(DISP, _b("core[%u]::client[%u]::cmd(id=%x, opcode=%x)"), core, client, m->id, m->opcode); - - /* ...pass message to component entry point */ - if (component->entry(component, m) < 0) - { - /* ...call component destructor */ - if (component->exit(component, m) == 0) - { - /* ...component cleanup completed; recycle component-id */ - xf_client_free(cd, client); - - /* ...do system-specific deregistration of component within IPC layer */ - xf_ipc_component_rmref(__XF_PORT_SPEC(core, client, 0)); - } - } - } - else - { - TRACE(DISP, _b("Discard message id=%x - client %u:%u not registered"), m->id, core, client); - - /* ...complete message with general failure response */ - xf_response_err(m); - } -} - -/******************************************************************************* - * Entry points - ******************************************************************************/ - -/* ...submit message for instant execution on some core */ -void xf_msg_submit(xf_message_t *m) -{ - u32 src = XF_MSG_SRC_CORE(m->id); - u32 dst = XF_MSG_DST_CORE(m->id); - - /* ...check if message shall go through local IPC layer */ - if (src ^ dst) - { - /* ...put message into local IPC queue */ - xf_msg_local_ipc_put(src, dst, m); - } - else - { - /* ...message is addressed to same core */ - xf_msg_local_put(src, m); - } -} - -/* ...complete message and pass response to a caller */ -void xf_msg_complete(xf_message_t *m) -{ - u32 src = XF_MSG_SRC(m->id); - u32 dst = XF_MSG_DST(m->id); - - /* ...swap src/dst specifiers */ - m->id = __XF_MSG_ID(dst, src); - - /* ...check if message goes to remote IPC layer */ - if (XF_MSG_DST_PROXY(m->id)) - { - /* ...return message to proxy */ - xf_msg_proxy_complete(m); - } - else - { - /* ...destination is within DSP cluster; check if that is a data buffer */ - switch (m->opcode) - { - case XF_EMPTY_THIS_BUFFER: - /* ...emptied buffer goes back to the output port */ - m->opcode = XF_FILL_THIS_BUFFER; - break; - - case XF_FILL_THIS_BUFFER: - /* ...filled buffer is passed to the input port */ - m->opcode = XF_EMPTY_THIS_BUFFER; - break; - } - - /* ...submit message for execution */ - xf_msg_submit(m); - } -} - -/* ...initialize per-core framework data */ -int xf_core_init(u32 core) -{ - xf_core_data_t *cd = XF_CORE_DATA(core); - xf_cmap_link_t *link; - u32 i; - - /* ...create list of free client descriptors */ - for (link = &cd->cmap[i = 0]; i < XF_CFG_MAX_CLIENTS; i++, link++) - { - link->next = i + 1; - } - - /* ...set head of free clients list */ - cd->free = 0; - - /* ...initialize local queue scheduler */ - xf_sched_init(&cd->sched); - - /* ...initialize IPI subsystem */ - XF_CHK_API(xf_ipi_init(core)); - - /* ...initialize shared read-write memory */ - XF_CHK_API(xf_shmem_enabled(core) ? xf_shmem_init(core) : 0); - - /* ...initialize scratch memory */ - XF_CHK_ERR(cd->scratch = xf_scratch_mem_init(core), -ENOMEM); - - /* ...okay... it's all good */ - TRACE(INIT, _b("core-%u initialized"), core); - - return 0; -} - -/* ...core executive loop function */ -void xf_core_service(u32 core) -{ - xf_core_data_t *cd = &xf_core_data[core]; - u32 status; - xf_message_t *m; - xf_task_t *t; - -#ifdef XAF_PROFILE_DSP - START_TIME_XA_PROFILER(prof); -#endif - do - { - /* ...clear local status change */ - status = 0; - - /* ...if core is servicing shared memory with AP, do it first - actually, they all need to support it */ - if (xf_shmem_enabled(core)) - { - /* ...process all commands */ - xf_shmem_process_queues(core); - } - - /* ...check if we have a backlog message placed into interim queue */ - while ((m = xf_msg_local_ipc_get(core)) || (m = xf_msg_local_get(core))) - { - /* ...dispatch message execution */ - xf_core_dispatch(cd, core, m); - - /* ...set local status change */ - status = 1; - } - - /* ...check if we have pending responses (submitted from ISR) we need to process */ - while ((m = xf_msg_local_response_get(core)) != NULL) - { - /* ...call completion handler on current stack */ - xf_msg_complete(m); - - /* ...set local status change */ - status = 1; - - } - - /* ...if scheduler queue is empty, break the loop and pause the core */ - if ((t = xf_sched_get(&cd->sched)) != NULL) - { - /* ...data-processing execution (ignore internal errors) */ - xf_core_process((xf_component_t *)t); - - /* ...set local status change */ - status = 1; - } - } - while (status); - -#ifdef XAF_PROFILE_DSP - STOP_TIME_XA_PROFILER(prof); - - if(prof.g_output_bytes) - { - unsigned long output_samples = prof.g_output_bytes; - output_samples >>= (prof.channels == 2 ? 1 : 0); - output_samples >>= (prof.pcm_width == 24 ? 2 : 1); - - COMPUTE_MHZ_XA_PROFILER(prof, output_samples, prof.sample_rate, 0); - - prof.g_output_bytes = prof.cycles = 0; /* reset counters */ - } -#endif - -} - -/* ...global data initialization function */ -int xf_global_init(void) -{ - /* ...what global data we have to initialize? - tbd */ - TRACE(INIT, _b("Global data initialized")); - - return 0; -} diff --git a/hifi/xaf/hifi-dpf/core/xf-io.c b/hifi/xaf/hifi-dpf/core/xf-io.c deleted file mode 100644 index 09f8e3e6..00000000 --- a/hifi/xaf/hifi-dpf/core/xf-io.c +++ /dev/null @@ -1,644 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2018 Cadence Design Systems, Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to use this Software with Cadence processor cores only and -* not with any other processors and platforms, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -******************************************************************************/ - -/******************************************************************************* - * xf-io.c - * - * Generic input/output ports handling - * - ******************************************************************************/ - -#define MODULE_TAG IO - -/******************************************************************************* - * Includes - ******************************************************************************/ - -#include "xf.h" - -/******************************************************************************* - * Tracing configuration - ******************************************************************************/ - -TRACE_TAG(INIT, 1); -TRACE_TAG(INPUT, 1); -TRACE_TAG(OUTPUT, 1); -TRACE_TAG(ROUTE, 1); - -/******************************************************************************* - * Input port API - ******************************************************************************/ - -/* ...initialize input port structure */ -int xf_input_port_init(xf_input_port_t *port, u32 size, u32 align, u32 core) -{ - /* ...allocate local internal buffer of particular size and alignment */ - if (size) - { - /* ...internal buffer is used */ - XF_CHK_ERR(port->buffer = xf_mem_alloc(size, align, core, 0), -ENOMEM); - } - else - { - /* ...no internal buffering is used */ - port->buffer = NULL; - } - - /* ...initialize message queue */ - xf_msg_queue_init(&port->queue); - - /* ...set buffer size */ - port->length = size; - - /* ...enable input by default */ - port->flags = XF_INPUT_FLAG_ENABLED | XF_INPUT_FLAG_CREATED; - - /* ...mark buffer is empty */ - port->filled = 0, port->access = NULL; - - TRACE(INIT, _b("input-port[%p] created - %p@%u[%u]"), port, port->buffer, align, size); - - return 0; -} - -/* ...put message into input port queue; return non-zero if queue was empty */ -int xf_input_port_put(xf_input_port_t *port, xf_message_t *m) -{ - /* ...check if input is enabled */ - if ((port->flags & XF_INPUT_FLAG_ENABLED) == 0) - { - /* ...input disabled; this is an error condition, likely */ - TRACE(INPUT, _b("input-port[%p] disabled"), port); - - /* ...release the message instantly */ - xf_response_ok(m); - - /* ...buffer has not been accepted - no actions to take */ - return 0; - } - else if (m->length == 0) - { - /* ...it is forbidden to pass more than one zero-length message */ - BUG(port->flags & XF_INPUT_FLAG_EOS, _x("invalid state: %x"), port->flags); - - /* ...received a message with zero-length; mark end-of-stream condition */ - port->flags ^= XF_INPUT_FLAG_ENABLED | XF_INPUT_FLAG_EOS; - - /* ...still enqueue that zero-length message; it will be processed afterwards */ - TRACE(INPUT, _b("input-port[%p]: zero-length buffer received"), port); - } - else - { - TRACE(INPUT, _b("input-port[%p]: buffer received - %u bytes"), port, m->length); - } - - /* ...enqueue message and set access pointer as needed */ - if (xf_msg_enqueue(&port->queue, m)) - { - /* ...first message put - set access pointer and length */ - port->access = m->buffer, port->remaining = m->length; - - /* ...if first message is empty, mark port is done */ - (!port->access ? port->flags ^= XF_INPUT_FLAG_EOS | XF_INPUT_FLAG_DONE : 0); - - /* ...return non-zero to indicate the first buffer is placed into port */ - return 1; - } - else - { - /* ...subsequent message placed into buffer */ - return 0; - } -} - -/* ...internal helper - input message completion */ -static inline int xf_input_port_complete(xf_input_port_t *port) -{ - /* ...dequeue message from queue */ - xf_message_t *m = xf_msg_dequeue(&port->queue); - - /* ...message cannot be NULL */ - BUG(m == NULL, _x("invalid port state")); - - /* ...complete current message (EMPTY-THIS-BUFFER always; no length adjustment) */ - xf_response(m); - - /* ...set up next head */ - if ((m = xf_msg_queue_head(&port->queue)) != NULL) - { - /* ...set new access pointers */ - port->access = m->buffer, port->remaining = m->length; - - /* ...return indication that there is an input message */ - return 1; - } - else - { - /* ...no more messages; reset access pointer */ - port->access = NULL; - - /* ...return indication that input port has no data available */ - return 0; - } -} - -/* ...fill-in required amount of data into input port buffer */ -int xf_input_port_fill(xf_input_port_t *port) -{ - u32 filled = port->filled; - u32 remaining = port->remaining; - u32 copied = 0; - s32 n; - - /* ...function shall not be called if no internal buffering is used */ - BUG(xf_input_port_bypass(port), _x("Invalid transaction")); - - /* ...if there is no message pending, bail out */ - if (!xf_msg_queue_head(&port->queue)) - { - TRACE(INPUT, _b("No message ready")); - return 0; - } - - /* ...calculate total amount of bytes we need to copy */ - n = (s32)(port->length - filled); - - /* ...get at most "n" bytes from input message(s) buffer(s) */ - while (n > 0) - { - u32 k; - - /* ...determine the size of the chunk to copy */ - ((k = remaining) > n ? k = n : 0); - - /* ...process zero-length input message separately */ - if (k == 0) - { - /* ...end-of-stream condition must be set */ - BUG((port->flags & XF_INPUT_FLAG_EOS) == 0, _x("port[%p]: invalid state: %x"), port, port->flags); - - /* ...mark stream is completed */ - port->flags ^= XF_INPUT_FLAG_EOS | XF_INPUT_FLAG_DONE; - - /* ...reset total amount of bytes to fill */ - n = 0; - - /* ...do not release message yet */ - TRACE(INPUT, _b("input-port[%p] done"), port); - - /* ...and break the loop */ - break; - } - - /* ...buffer must be set */ - BUG(!port->access, _x("invalid port state")); - - /* ...get required amount from input buffer */ - memcpy(port->buffer + filled, port->access, k), port->access += k; - - /* ...advance buffer positions */ - filled += k, copied += k, n -= k; - - /* ...check if input buffer is processed completely */ - if ((remaining -= k) == 0) - { - if (!xf_input_port_complete(port)) - { - /* ...no more input messages; break the loop */ - break; - } - else - { - /* ...update remaining counter */ - remaining = port->remaining; - } - } - } - - /* ...update buffer positions */ - port->filled = filled, port->remaining = remaining; - - /* ...return indicator whether input buffer is prefilled */ - return (n == 0); -} - -/* ...pad input buffer with given pattern */ -void xf_input_port_pad(xf_input_port_t *port, u8 pad) -{ - u32 filled = port->filled; - s32 k; - - /* ...do padding if port buffer is not filled */ - if ((k = port->length - filled) > 0) - { - memset(port->buffer + filled, pad, k); - - /* ...indicate port is filled */ - port->filled = port->length; - } -} - -/* ...consume input buffer data */ -void xf_input_port_consume(xf_input_port_t *port, u32 n) -{ - /* ...check whether input port is in bypass mode */ - if (xf_input_port_bypass(port)) - { - /* ...port is in bypass mode; advance access pointer */ - if ((port->remaining -= n) == 0) - { - /* ...complete message and try to rearm input port */ - xf_input_port_complete(port); - - /* ...check if end-of-stream flag is set */ - if (xf_msg_queue_head(&port->queue) && !port->access) - { - BUG((port->flags & XF_INPUT_FLAG_EOS) == 0, _x("port[%p]: invalid state: %x"), port, port->flags); - - /* ...mark stream is completed */ - port->flags ^= XF_INPUT_FLAG_EOS | XF_INPUT_FLAG_DONE; - - TRACE(INPUT, _b("input-port[%p] done"), port); - } - } - else - { - /* ...advance message buffer pointer */ - port->access += n; - } - } - else if (port->filled > n) - { - u32 k = port->filled - n; - - /* ...move tail of buffer to the head (safe to use memcpy) */ - memcpy(port->buffer, port->buffer + n, k); - - /* ...adjust filled position */ - port->filled = k; - } - else - { - /* ...entire buffer is consumed; reset fill level */ - port->filled = 0; - } -} - -/* ...purge input port queue */ -void xf_input_port_purge(xf_input_port_t *port) -{ - xf_message_t *m; - - /* ...bail out early if port is not created */ - if (!xf_input_port_created(port)) return; - - /* ...free all queued messages with generic "ok" response */ - while ((m = xf_msg_dequeue(&port->queue)) != NULL) - { - xf_response_ok(m); - } - - /* ...reset internal buffer position */ - port->filled = 0, port->access = NULL; - - /* ...reset port flags */ - port->flags = (port->flags & ~__XF_INPUT_FLAGS(~0)) | XF_INPUT_FLAG_ENABLED | XF_INPUT_FLAG_CREATED; - - TRACE(INPUT, _b("input-port[%p] purged"), port); -} - -/* ...save flow-control message for propagated input port purging sequence */ -void xf_input_port_control_save(xf_input_port_t *port, xf_message_t *m) -{ - /* ...make sure purging sequence is not active */ - BUG(port->flags & XF_INPUT_FLAG_PURGING, _x("invalid state: %x"), port->flags); - - /* ...place message into internal queue */ - xf_msg_enqueue(&port->queue, m); - - /* ...set port purging flag */ - port->flags ^= XF_INPUT_FLAG_PURGING; - - TRACE(INPUT, _b("port[%p] start purge sequence"), port); -} - -/* ...mark flushing sequence is completed */ -void xf_input_port_purge_done(xf_input_port_t *port) -{ - /* ...make sure flushing sequence is ongoing */ - BUG((port->flags & XF_INPUT_FLAG_PURGING) == 0, _x("invalid state: %x"), port->flags); - - /* ...complete saved flow-control message */ - xf_response_ok(xf_msg_dequeue(&port->queue)); - - /* ...clear port purging flag */ - port->flags ^= XF_INPUT_FLAG_PURGING; - - TRACE(INPUT, _b("port[%p] purge sequence completed"), port); -} - -/* ...destroy input port data */ -void xf_input_port_destroy(xf_input_port_t *port, u32 core) -{ - /* ...bail out earlier if port is not created */ - if (!xf_input_port_created(port)) return; - - /* ...deallocate input buffer if needed */ - (port->buffer ? xf_mem_free(port->buffer, port->length, core, 0), port->buffer = NULL : 0); - - /* ...reset input port flags */ - port->flags = 0; - - TRACE(INIT, _b("input-port[%p] destroyed"), port); -} - -/******************************************************************************* - * Output port API - ******************************************************************************/ - -/* ...initialize output port (structure must be zero-initialized) */ -int xf_output_port_init(xf_output_port_t *port, u32 size) -{ - /* ...initialize message queue */ - xf_msg_queue_init(&port->queue); - - /* ...set output buffer length */ - port->length = size; - - /* ...mark port is created */ - port->flags = XF_OUTPUT_FLAG_CREATED; - - TRACE(INIT, _b("output-port[%p] initialized"), port); - - return 0; -} - -/* ...route output port */ -int xf_output_port_route(xf_output_port_t *port, u32 id, u32 n, u32 length, u32 align) -{ - u32 core = XF_MSG_DST_CORE(id); - u32 shared = XF_MSG_SHARED(id); - xf_message_t *m; - u32 i; - - /* ...allocate message pool for a port; extra message for control */ - XF_CHK_API(xf_msg_pool_init(&port->pool, n + 1, core)); - - /* ...allocate required amount of buffers */ - for (i = 1; i <= n; i++) - { - /* ...get message from pool (directly; bypass that "get" interface) */ - m = xf_msg_pool_item(&port->pool, i); - - /* ...wipe out message link pointer (debugging) */ - m->next = NULL; - - /* ...set message parameters */ - m->id = id; - m->opcode = XF_FILL_THIS_BUFFER; - m->length = length; - m->buffer = xf_mem_alloc(length, align, core, shared); - - /* ...if allocation failed, do a cleanup */ - if (!m->buffer) goto error; - - /* ...place message into output port */ - xf_msg_enqueue(&port->queue, m); - } - - /* ...setup flow-control message */ - m = xf_output_port_control_msg(port); - m->id = id; - m->length = 0; - m->buffer = NULL; - - /* ...wipe out message link pointer (debugging) */ - m->next = NULL; - - /* ...save port length */ - port->length = length; - - /* ...mark port is routed */ - port->flags |= XF_OUTPUT_FLAG_ROUTED | XF_OUTPUT_FLAG_IDLE; - - TRACE(ROUTE, _b("output-port[%p] routed: %x -> %x"), port, XF_MSG_DST(id), XF_MSG_SRC(id)); - - return 0; - -error: - /* ...allocation failed; do a cleanup */ - while (--i) - { - m = xf_msg_pool_item(&port->pool, i); - - /* ...free item */ - xf_mem_free(m->buffer, length, core, shared); - } - - /* ...destroy pool data */ - xf_msg_pool_destroy(&port->pool, core); - - return -ENOMEM; -} - -/* ...start output port unrouting sequence */ -void xf_output_port_unroute_start(xf_output_port_t *port, xf_message_t *m) -{ - /* ...port must be routed */ - BUG(!xf_output_port_routed(port), _x("invalid state: %x"), port->flags); - - /* ...save message in the queue */ - port->unroute = m; - - /* ...put port unrouting flag */ - port->flags |= XF_OUTPUT_FLAG_UNROUTING; -} - -/* ...complete port unrouting sequence */ -void xf_output_port_unroute_done(xf_output_port_t *port) -{ - xf_message_t *m; - - /* ...make sure we have an outstanding port unrouting sequence */ - BUG(!xf_output_port_unrouting(port), _x("invalid state: %x"), port->flags); - - /* ...retrieve enqueued control-flow message */ - m = port->unroute, port->unroute = NULL; - - /* ...destroy port buffers */ - xf_output_port_unroute(port); - - /* ...and pass response to the caller */ - xf_response_ok(m); -} - -/* ...unroute output port and destroy all memory buffers allocated */ -void xf_output_port_unroute(xf_output_port_t *port) -{ - xf_message_t *m = xf_output_port_control_msg(port); - u32 core = XF_MSG_DST_CORE(m->id); - u32 shared = XF_MSG_SHARED(m->id); - u32 n = port->pool.n - 1; - u32 i; - - /* ...free all messages (we are running on "dst" core) */ - for (i = 1; i <= n; i++) - { - /* ...directly obtain message item */ - m = xf_msg_pool_item(&port->pool, i); - - /* ...free message buffer (must exist) */ - xf_mem_free(m->buffer, port->length, core, shared); - } - - /* ...destroy pool data */ - xf_msg_pool_destroy(&port->pool, core); - - /* ...reset all flags */ - port->flags = XF_OUTPUT_FLAG_CREATED; - - /* ...reset message queue (it is empty again) */ - xf_msg_queue_init(&port->queue); - - TRACE(ROUTE, _b("output-port[%p] unrouted"), port); -} - -/* ...put next message to the port */ -int xf_output_port_put(xf_output_port_t *port, xf_message_t *m) -{ - /* ...in case of port unrouting sequence the flag returned will always be 0 */ - return xf_msg_enqueue(&port->queue, m); -} - -/* ...retrieve next message from the port */ -void * xf_output_port_data(xf_output_port_t *port) -{ - xf_message_t *m = xf_msg_queue_head(&port->queue); - - /* ...bail out if there is nothing enqueued */ - if (m == NULL) return NULL; - - /* ...it is not permitted to access port data when port is being unrouted */ - BUG(xf_output_port_unrouting(port), _x("invalid transaction")); - - /* ...make sure message length is valid */ - BUG(m->length < port->length, _x("Insufficient buffer length: %u < %u"), m->length, port->length); - - /* ...return access buffer pointer */ - return m->buffer; -} - -/* ...produce output message marking amount of bytes produced */ -int xf_output_port_produce(xf_output_port_t *port, u32 n) -{ - xf_message_t *m = xf_msg_dequeue(&port->queue); - - /* ...message cannot be NULL */ - BUG(m == NULL, _x("Invalid transaction")); - - /* ...it is not permitted to invoke this when port is being unrouted (or flushed - tbd) */ - BUG(xf_output_port_unrouting(port), _x("invalid transaction")); - - /* ...complete message with specified amount of bytes produced */ - xf_response_data(m, n); - - /* ...clear port idle flag (technically, not needed for unrouted port) */ - port->flags &= ~XF_OUTPUT_FLAG_IDLE; - - /* ...return indication of pending message availability */ - return (xf_msg_queue_head(&port->queue) != NULL); -} - -/* ...flush output port */ -int xf_output_port_flush(xf_output_port_t *port, u32 opcode) -{ - xf_message_t *m; - - /* ...if port is routed, we shall pass flush command to sink port */ - if (xf_output_port_routed(port)) - { - /* ...if port is idle, satisfy immediately */ - if (port->flags & XF_OUTPUT_FLAG_IDLE) return 1; - - /* ...start flushing sequence if not already started */ - if ((port->flags & XF_OUTPUT_FLAG_FLUSHING) == 0) - { - /* ...put flushing flag */ - port->flags ^= XF_OUTPUT_FLAG_FLUSHING; - - /* ...get control message from associated pool */ - m = xf_output_port_control_msg(port); - - /* ...set flow-control operation */ - m->opcode = opcode; - - /* ...message is a command, but source and destination are swapped */ - xf_response(m); - } - - /* ...zero-result indicates the flushing is in progress */ - return 0; - } - else - { - /* ...for non-routed port just complete all queued messages */ - while ((m = xf_msg_dequeue(&port->queue)) != NULL) - { - /* ...pass generic zero-length "okay" response - tbd */ - xf_response_ok(m); - } - - /* ...non-zero result indicates the flushing is done */ - return 1; - } -} - -/* ...mark flushing sequence is completed */ -void xf_output_port_flush_done(xf_output_port_t *port) -{ - /* ...make sure flushing sequence is ongoing */ - BUG((port->flags & XF_OUTPUT_FLAG_FLUSHING) == 0, _x("invalid state: %x"), port->flags); - - /* ...clear flushing flag and set idle flag */ - port->flags ^= XF_OUTPUT_FLAG_IDLE | XF_OUTPUT_FLAG_FLUSHING; - - TRACE(OUTPUT, _b("port[%p] flush sequence completed"), port); -} - -/* ...destroy output port */ -void xf_output_port_destroy(xf_output_port_t *port, u32 core) -{ - /* ...check if port is routed */ - if (xf_output_port_routed(port)) - { - /* ...port must be in idle state */ - BUG(!xf_output_port_idle(port), _x("destroying non-idle port[%p]"), port); - - /* ...unroute port */ - xf_output_port_unroute(port); - } - - /* ...reset port flags */ - port->flags = 0; - - TRACE(INIT, _b("output-port[%p] destroyed"), port); -} diff --git a/hifi/xaf/hifi-dpf/core/xf-isr.c b/hifi/xaf/hifi-dpf/core/xf-isr.c deleted file mode 100644 index 4e2add1e..00000000 --- a/hifi/xaf/hifi-dpf/core/xf-isr.c +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2018 Cadence Design Systems, Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to use this Software with Cadence processor cores only and -* not with any other processors and platforms, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -******************************************************************************/ - -/******************************************************************************* - * xf-isr.c - * - * DSP processing framework - code running from interrupt context - * - ******************************************************************************/ - -#define MODULE_TAG ISR - -/******************************************************************************* - * Includes - ******************************************************************************/ - -#include "xf.h" - -/******************************************************************************* - * API functions definitions - ******************************************************************************/ - -/* ...submit command message from interrupt context on local core */ -void xf_msg_schedule_isr(xf_message_t *m) -{ - u32 core = XF_MSG_DST_CORE(m->id); - xf_core_data_t *cd = XF_CORE_DATA(core); - - /* ...interrupt masking protocol is used for protecting local message queue */ - if (xf_msg_enqueue(&cd->queue, m)) - { - /* ...resume local scheduler if that is the first message */ - xf_ipi_resume(core); - } -} - -/* ...complete message from interrupt handler */ -void xf_msg_complete_isr(xf_message_t *m) -{ - u32 core = XF_MSG_DST_CORE(m->id); - xf_core_data_t *cd = XF_CORE_DATA(core); - - /* ...place message into response queue */ - if (xf_msg_enqueue(&cd->response, m)) - { - /* ...notify local scheduler if that is the first message */ - xf_ipi_resume(core); - } -} diff --git a/hifi/xaf/hifi-dpf/core/xf-mem.c b/hifi/xaf/hifi-dpf/core/xf-mem.c deleted file mode 100644 index ce5d8a6a..00000000 --- a/hifi/xaf/hifi-dpf/core/xf-mem.c +++ /dev/null @@ -1,361 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2018 Cadence Design Systems, Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to use this Software with Cadence processor cores only and -* not with any other processors and platforms, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -******************************************************************************/ - -/******************************************************************************* - * xf-mem.c - * - * Dynamic memory allocator implementation (based on rb-tree index) - * - ******************************************************************************/ - -#define MODULE_TAG MM - -/******************************************************************************* - * Includes - ******************************************************************************/ - -#include "xf.h" - -/******************************************************************************* - * Tracing configuration - ******************************************************************************/ - -TRACE_TAG(INIT, 1); - -/******************************************************************************* - * Internal helpers - ******************************************************************************/ - -/* ...initialize block */ -static inline xf_mm_block_t * xf_mm_block_init(void *addr, u32 size) -{ - xf_mm_block_t *b = (xf_mm_block_t *)addr; - - /* ...use 31 available bits of node color to keep aligned size */ - return b->l_node.color = size, b; -} - -/* ...check if the length of the block is less than given */ -static inline int xf_mm_block_length_less(xf_mm_block_t *b, u32 size) -{ - /* ...we don't really care about LSB of color */ - return (b->l_node.color < size); -} - -/* ...return exact block length */ -static inline u32 xf_mm_block_length(xf_mm_block_t *b) -{ - /* ...wipe out least-significant bit from node color */ - return (b->l_node.color & ~1); -} - -/* ...increase block length */ -static inline u32 xf_mm_block_length_add(xf_mm_block_t *b, u32 size) -{ - /* ...return exact block length after increase */ - return ((b->l_node.color += size) & ~1); -} - -/* ...decrease block length */ -static inline u32 xf_mm_block_length_sub(xf_mm_block_t *b, u32 size) -{ - /* ...return exact block length after decrease */ - return ((b->l_node.color -= size) & ~1); -} - -/******************************************************************************* - * Internal functions - ******************************************************************************/ - -/* ...find best-match node given requested size */ -static inline xf_mm_block_t * xf_mm_find_by_size(xf_mm_pool_t *pool, u32 size) -{ - rb_tree_t *tree = &pool->l_map; - rb_idx_t p_idx, t_idx; - - /* ...find first block having length greater than requested */ - for (p_idx = rb_root(tree); p_idx != rb_null(tree); p_idx = rb_right(tree, p_idx)) - { - xf_mm_block_t *b = container_of(p_idx, xf_mm_block_t, l_node); - - /* ...break upon finding first matching candidate */ - if (!xf_mm_block_length_less(b, size)) - break; - } - - /* ...bail out if haven't found a block with sufficient size */ - if (p_idx == rb_null(tree)) - return NULL; - - /* ...try to find better match in left subtree */ - for (t_idx = rb_left(tree, p_idx); t_idx != rb_null(tree); ) - { - xf_mm_block_t *b = container_of(t_idx, xf_mm_block_t, l_node); - - /* ...check the size of the block */ - if (!xf_mm_block_length_less(b, size)) - { - /* ...update best match */ - p_idx = t_idx; - - /* ...and check if we have anything better in left sbtree */ - t_idx = rb_left(tree, t_idx); - } - else - { - /* ...move towards higher block sizes in that subtree */ - t_idx = rb_right(tree, t_idx); - } - } - - /* ...p_idx is our best choice */ - return container_of(p_idx, xf_mm_block_t, l_node); -} - -/* ...find the neighbours of the block basing on its address */ -static void xf_mm_find_by_addr(xf_mm_pool_t *pool, void *addr, xf_mm_block_t **n) -{ - rb_tree_t *tree = &pool->a_map; - rb_idx_t p_idx, l_idx, r_idx; - - /* ...it is not possible to have exact match in this map */ - for (p_idx = rb_root(tree), l_idx = r_idx = NULL; p_idx != rb_null(tree); ) - { - /* ...only "is less than" comparison is valid (as "a_node" pointer is biased) */ - if ((u32)p_idx < (u32)addr) - { - /* ...update lower neighbour */ - l_idx = p_idx; - - /* ...and move towards higher addresses */ - p_idx = rb_right(tree, p_idx); - } - else - { - /* ...update higher neighbour */ - r_idx = p_idx; - - /* ...and move towards lower addresses */ - p_idx = rb_left(tree, p_idx); - } - } - - /* ...translate nodes into blocks */ - n[0] = (l_idx ? container_of(l_idx, xf_mm_block_t, a_node) : NULL); - n[1] = (r_idx ? container_of(r_idx, xf_mm_block_t, a_node) : NULL); -} - -/* ...insert the block into L-map */ -static void xf_mm_insert_size(xf_mm_pool_t *pool, xf_mm_block_t *b, u32 size) -{ - rb_tree_t *tree = &pool->l_map; - rb_idx_t p_idx, t_idx; - - /* ...find the parent node for the next block */ - for (p_idx = rb_root(tree); p_idx != rb_null(tree); p_idx = t_idx) - { - /* ...check for the size */ - if (xf_mm_block_length_less(container_of(p_idx, xf_mm_block_t, l_node), size)) - { - /* ...move towards higher addresses */ - if ((t_idx = rb_right(tree, p_idx)) == rb_null(tree)) - { - /* ...node becomes a right child of parent p */ - rb_set_right(tree, p_idx, &b->l_node); - break; - } - } - else - { - /* ...move towards lower addresses (ok if exact size match is found) */ - if ((t_idx = rb_left(tree, p_idx)) == rb_null(tree)) - { - /* ...node becomes a left child of parent p */ - rb_set_left(tree, p_idx, &b->l_node); - break; - } - } - } - - /* ...insert node into tree */ - rb_insert(tree, &b->l_node, p_idx); -} - -/* ...insert the block into A-map */ -static void xf_mm_insert_addr(xf_mm_pool_t *pool, xf_mm_block_t *b) -{ - rb_tree_t *tree = &pool->a_map; - rb_idx_t p_idx, t_idx; - - /* ...find the parent node for the next block */ - for (p_idx = rb_root(tree); p_idx != rb_null(tree); p_idx = t_idx) - { - /* ...check for the address (only "is less than" comparison is valid) */ - if ((u32)p_idx < (u32)b) - { - /* ...move towards higher addresses */ - if ((t_idx = rb_right(tree, p_idx)) == rb_null(tree)) - { - /* ...node becomes a right child of parent p */ - rb_set_right(tree, p_idx, &b->a_node); - break; - } - } - else - { - /* ...move towards lower addresses (by design there cannot be exact match) */ - if ((t_idx = rb_left(tree, p_idx)) == rb_null(tree)) - { - /* ...node becomes a left child of parent p */ - rb_set_left(tree, p_idx, &b->a_node); - break; - } - } - } - - /* ...insert node into tree */ - rb_insert(tree, &b->a_node, p_idx); -} - -/******************************************************************************* - * Entry points - ******************************************************************************/ - -/* ...block allocation */ -void * xf_mm_alloc(xf_mm_pool_t *pool, u32 size) -{ - xf_mm_block_t *b; - - /* ...find best-fit free block */ - XF_CHK_ERR(b = xf_mm_find_by_size(pool, size), NULL); - - /* ...remove the block from the L-map */ - rb_delete(&pool->l_map, &b->l_node); - - /* ...check if the size is exactly the same as requested */ - if ((size = xf_mm_block_length_sub(b, size)) == 0) - { - /* ...the block needs to be removed from the A-map as well */ - rb_delete(&pool->a_map, &b->a_node); - - /* ...entire block goes to user */ - return (void *) b; - } - else - { - /* ...insert the block into L-map */ - xf_mm_insert_size(pool, b, size); - - /* ...A-map remains intact; tail of the block goes to user */ - return (void *) b + size; - } -} - -/* ...block deallocation */ -void xf_mm_free(xf_mm_pool_t *pool, void *addr, u32 size) -{ - xf_mm_block_t *b = xf_mm_block_init(addr, size); - xf_mm_block_t *n[2]; - - /* ...find block neighbours in A-map */ - xf_mm_find_by_addr(pool, addr, n); - - /* ...check if we can merge block to left neighbour */ - if (n[0]) - { - if ((void *)n[0] + xf_mm_block_length(n[0]) == addr) - { - /* ...merge free block with left neighbour; delete it from L-map */ - rb_delete(&pool->l_map, &n[0]->l_node); - - /* ...adjust block length (block remains in A-map) */ - addr = (void *)(b = n[0]), size = xf_mm_block_length_add(b, size); - } - else - { - /* ...mark there is no left-merge */ - n[0] = NULL; - } - } - - /* ...check if we can merge block to right neighbour */ - if (n[1]) - { - if ((void *)n[1] == addr + size) - { - /* ...merge free block with right neighbour; delete it from L-map */ - rb_delete(&pool->l_map, &n[1]->l_node); - - /* ...adjust block length */ - size = xf_mm_block_length_add(b, xf_mm_block_length(n[1])); - - /* ...check if left merge took place as well */ - if (n[0]) - { - /* ...left neighbour covers now all three blocks; drop record from A-map */ - rb_delete(&pool->a_map, &n[1]->a_node); - } - else - { - /* ...fixup tree pointers (equivalent to remove/reinsert the same key) */ - rb_replace(&pool->a_map, &n[1]->a_node, &b->a_node); - } - } - else - { - n[1] = NULL; - } - } - - /* ...if any merge has occured, A-map is updated */ - if (n[0] == NULL && n[1] == NULL) - { - /* ...add new block into A-map */ - xf_mm_insert_addr(pool, b); - } - - /* ...add (new or adjusted) block into L-map */ - xf_mm_insert_size(pool, b, size); -} - -/* ...initialize memory allocator */ -int xf_mm_init(xf_mm_pool_t *pool, void *addr, u32 size) -{ - /* ...check pool alignment validity */ - XF_CHK_ERR(((u32)addr & (sizeof(xf_mm_block_t) - 1)) == 0, -EINVAL); - - /* ...check pool size validity */ - XF_CHK_ERR(((size) & (sizeof(xf_mm_block_t) - 1)) == 0, -EINVAL); - - /* ...set pool parameters (need that stuff at all? - tbd) */ - pool->addr = addr, pool->size = size; - - /* ...initialize rb-trees */ - rb_init(&pool->l_map), rb_init(&pool->a_map); - - /* ..."free" the entire block */ - xf_mm_free(pool, addr, size); - - TRACE(INIT, _b("memory allocator initialized: [%p..%p)"), addr, addr + size); - - return 0; -} diff --git a/hifi/xaf/hifi-dpf/core/xf-msg.c b/hifi/xaf/hifi-dpf/core/xf-msg.c deleted file mode 100644 index 4253e1e3..00000000 --- a/hifi/xaf/hifi-dpf/core/xf-msg.c +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2018 Cadence Design Systems, Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to use this Software with Cadence processor cores only and -* not with any other processors and platforms, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -******************************************************************************/ - -/******************************************************************************* - * xf-msg.c - * - * Message/message pool handling - * - ******************************************************************************/ - -#define MODULE_TAG MSG - -/******************************************************************************* - * Includes - ******************************************************************************/ - -#include "xf.h" - -/******************************************************************************* - * Entry points - ******************************************************************************/ - -/* ...allocate message pool */ -int xf_msg_pool_init(xf_msg_pool_t *pool, u32 n, u32 core) -{ - u32 i; - - /* ...allocate shared memory from global pool */ - XF_CHK_ERR(pool->p = xf_mem_alloc(XF_MM(sizeof(*pool->p) * n), XF_PROXY_ALIGNMENT, core, 1), -ENOMEM); - - /* ...place all messages into single-liked list */ - for (pool->head = &pool->p[i = 0]; i < n - 1; i++) - { - /* ...set message pointer to next message in the pool */ - xf_msg_pool_item(pool, i)->next = xf_msg_pool_item(pool, i + 1); - } - - /* ...set tail of the list */ - xf_msg_pool_item(pool, i)->next = NULL; - - /* ...save pool size */ - pool->n = n; - - return 0; -} - -/* ...destroy memory pool */ -void xf_msg_pool_destroy(xf_msg_pool_t *pool, u32 core) -{ - /* ...release pool memory (from shared local-IPC memory) */ - xf_mem_free(pool->p, XF_MM(sizeof(*pool->p) * pool->n), core, 1); -} - -/* ...allocate message from a pool (no concurrent access from other cores) */ -xf_message_t * xf_msg_pool_get(xf_msg_pool_t *pool) -{ - __xf_message_t *_m; - - /* ...pop message from the head of the pool */ - XF_CHK_ERR(_m = pool->head, NULL); - - /* ...advance list head */ - pool->head = (__xf_message_t *)(((xf_message_t *) _m)->next); - - /* ...debug - wipe out message "next" pointer */ - ((xf_message_t *) _m)->next = NULL; - - /* ...return properly aligned message pointer */ - return (xf_message_t *) _m; -} - -/* ...return message back to the pool (no concurrent access from other cores) */ -void xf_msg_pool_put(xf_msg_pool_t *pool, xf_message_t *m) -{ - __xf_message_t *_m = (__xf_message_t *) m; - - /* ...make sure the message is properly aligned object */ - BUG(!XF_IS_ALIGNED(_m), _x("Corrupted message pointer: %p"), _m); - - /* ...make sure it is returned to the same pool (need a length for that - tbd) */ - BUG(!xf_msg_from_pool(pool, m) < 0, _x("Bad pool/message: %p/%p"), pool->p, _m); - - /* ...place message into the head */ - m->next = (xf_message_t *) pool->head; - - /* ...advance pool head */ - pool->head = _m; -} diff --git a/hifi/xaf/hifi-dpf/core/xf-sched.c b/hifi/xaf/hifi-dpf/core/xf-sched.c deleted file mode 100644 index cc1b4e8d..00000000 --- a/hifi/xaf/hifi-dpf/core/xf-sched.c +++ /dev/null @@ -1,153 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2018 Cadence Design Systems, Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to use this Software with Cadence processor cores only and -* not with any other processors and platforms, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -******************************************************************************/ - -/******************************************************************************* - * xf-sched.c - * - * Non-preemptive earliest-deadline-first scheduler - * - ******************************************************************************/ - -#define MODULE_TAG SCHED - -/******************************************************************************* - * Includes - ******************************************************************************/ - -#include "xf.h" - -/******************************************************************************* - * Tracing configuration - ******************************************************************************/ - -TRACE_TAG(DEBUG, 1); - -/******************************************************************************* - * Global functions definitions - ******************************************************************************/ - -/* ...place task into scheduler queue */ -void xf_sched_put(xf_sched_t *sched, xf_task_t *t, u32 ts) -{ - rb_tree_t *tree = (rb_tree_t *)sched; - rb_node_t *node = (rb_node_t *)t; - rb_idx_t p_idx, t_idx; - u32 _ts; - - /* ...set scheduling timestamp */ - xf_task_timestamp_set(t, ts); - - /* ...find a place in the tree where the message should be inserted */ - for (p_idx = rb_root(tree); p_idx != rb_null(tree); p_idx = t_idx) - { - /* ...get timestamp of the p_idx */ - _ts = xf_task_timestamp((xf_task_t *)p_idx); - - /* ...ordering respects FIFO order of messages with same timestamp */ - if (xf_timestamp_before(ts, _ts)) - { - if ((t_idx = rb_left(tree, p_idx)) == rb_null(tree)) - { - /* ...p_idx is a direct successor of the message */ - rb_set_left(tree, p_idx, node); - - /* ...adjust head of the tree if needed */ - if (p_idx == rb_cache(tree)) goto insert_head; - else goto insert; - } - } - else - { - if ((t_idx = rb_right(tree, p_idx)) == rb_null(tree)) - { - /* ...p_idx is a direct predeccessor of the message */ - rb_set_right(tree, p_idx, node); - - goto insert; - } - } - } - -insert_head: - /* ...adjust scheduler head element */ - rb_set_cache(tree, node); - -insert: - /* ...insert item and rebalance the tree */ - rb_insert(tree, node, p_idx); - - /* ...head cannot be NULL */ - BUG(rb_cache(tree) == rb_null(tree), _x("Invalid scheduler state")); - - TRACE(DEBUG, _b("in: %x:[%p] (ts:%x)"), ts, node, xf_sched_timestamp(sched)); -} - -/* ...get first item from the scheduler */ -xf_task_t * xf_sched_get(xf_sched_t *sched) -{ - rb_tree_t *tree = (rb_tree_t *)sched; - rb_idx_t n_idx, t_idx; - u32 ts; - - /* ...head of the tree is cached; replace it with its parent (direct successor) */ - if ((n_idx = rb_cache(tree)) == rb_null(tree)) - { - /* ...tree is empty; bail out */ - return NULL; - } - else - { - /* ...delete current node and rebalance the tree */ - t_idx = rb_delete(tree, n_idx), rb_set_cache(tree, t_idx); - - /* ...get task timestamp */ - ts = xf_task_timestamp((xf_task_t *)n_idx); - - /* ...advance scheduler timestamp */ - xf_sched_timestamp_set(sched, ts); - - TRACE(DEBUG, _b("out: %x:[%p]"), ts, n_idx); - - /* ...return task */ - return (xf_task_t *)n_idx; - } -} - -/* ...cancel specified task execution (must be scheduled!) */ -void xf_sched_cancel(xf_sched_t *sched, xf_task_t *t) -{ - rb_tree_t *tree = (rb_tree_t *)sched; - rb_idx_t n_idx = t; - rb_idx_t t_idx; - - /* ...delete message from tree */ - t_idx = rb_delete(tree, n_idx); - - /* ...adjust head if that was the first message */ - (n_idx == rb_cache(tree) ? rb_set_cache(tree, t_idx), 1 : 0); -} - -/* ...initialize scheduler data */ -void xf_sched_init(xf_sched_t *sched) -{ - rb_init((rb_tree_t *)sched); -} diff --git a/hifi/xaf/hifi-dpf/core/xf-shmem.c b/hifi/xaf/hifi-dpf/core/xf-shmem.c deleted file mode 100644 index 15d3b1d9..00000000 --- a/hifi/xaf/hifi-dpf/core/xf-shmem.c +++ /dev/null @@ -1,350 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2018 Cadence Design Systems, Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to use this Software with Cadence processor cores only and -* not with any other processors and platforms, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -******************************************************************************/ - -/******************************************************************************* - * xf-shmem.c - * - * DSP shared memory interface implementation - * - ******************************************************************************/ - -#define MODULE_TAG SHMEM - -/******************************************************************************* - * Includes - ******************************************************************************/ - -#include "xf.h" - -/******************************************************************************* - * Tracing tags - ******************************************************************************/ - -/* ...general initialization sequence */ -TRACE_TAG(INIT, 1); - -/* ...interface status change */ -TRACE_TAG(EXEC, 0); - -/* ...command reception */ -TRACE_TAG(CMD, 1); - -/* ...response generation */ -TRACE_TAG(RSP, 1); - -#ifdef XAF_PROFILE_DSP -#include "xa_profiler.h" -#endif -/******************************************************************************* - * Local constants definitions - ******************************************************************************/ - -/* ...local interface status change flag */ -#define XF_PROXY_STATUS_LOCAL (1 << 0) - -/* ...remote status change notification flag */ -#define XF_PROXY_STATUS_REMOTE (1 << 1) - -/******************************************************************************* - * Internal helpers - ******************************************************************************/ - -/* ...put message into proxy queue */ -static inline void xf_msg_proxy_put(xf_message_t *m) -{ - u32 dst = XF_MSG_DST_CORE(m->id); - u32 src = XF_MSG_SRC_CORE(m->id); - xf_core_rw_data_t *rw = XF_CORE_RW_DATA(dst); - int first; - - /* ...get an access to shared rw-memory (we are running on "source" core) */ - xf_mutex_lock(src); - - /* ...assure memory coherency if needed */ - if (XF_REMOTE_IPC_NON_COHERENT) - { - /* ...invalidate rw-shared memory region */ - XF_PROXY_INVALIDATE(rw, sizeof(*rw)); - - /* ...put message into shared queue */ - first = xf_msg_enqueue(&rw->remote, m); - - /* ...flush both message and shared queue data */ - XF_PROXY_FLUSH(rw, sizeof(*rw)), XF_PROXY_FLUSH(m, sizeof(*m)); - } - else - { - /* ...no memory coherency concerns; just place a message in the queue */ - first = xf_msg_enqueue(&rw->remote, m); - } - - /* ...release rw-memory region lock */ - xf_mutex_unlock(src); - - /* ...assert IPI interrupt on target ("destination") core if needed */ - if (first && (dst ^ src)) - { - xf_ipi_assert(dst); - } -} - -/* ...retrieve message from proxy queue */ -static inline xf_message_t * xf_msg_proxy_get(u32 core) -{ - xf_core_rw_data_t *rw = XF_CORE_RW_DATA(core); - xf_message_t *m; - - /* ...retrieve message from queue in atomic fashion */ - xf_mutex_lock(core); - - /* ...assure memory coherency if needed */ - if (XF_REMOTE_IPC_NON_COHERENT) - { - /* ...invalidate rw-memory */ - XF_PROXY_INVALIDATE(rw, sizeof(*rw)); - - /* ...dequeue message from response queue */ - m = xf_msg_dequeue(&rw->remote); - - /* ...flush rw memory */ - XF_PROXY_FLUSH(rw, sizeof(*rw)); - - /* ...invalidate message data if found */ - (m ? XF_PROXY_INVALIDATE(m, sizeof(*m)) : 0); - } - else - { - /* ...just dequeue message from response queue */ - m = xf_msg_dequeue(&rw->remote); - } - - /* ...release the rw-lock */ - xf_mutex_unlock(core); - - return m; -} - -/******************************************************************************* - * Internal functions definitions - ******************************************************************************/ - -/* ...retrieve all incoming commands from shared memory ring-buffer */ -static u32 xf_shmem_process_input(u32 core) -{ - xf_message_t *m; - u32 read_idx; - u32 write_idx; - u32 status = 0; - - /* ...get current value of write pointer */ - read_idx = XF_PROXY_READ(core, cmd_read_idx); - write_idx = XF_PROXY_READ(core, cmd_write_idx); - - TRACE(EXEC, _b("Command queue: write = %x / read = %x"), write_idx, read_idx); - - /* ...process all committed commands */ - while (!XF_QUEUE_EMPTY(read_idx, write_idx)) - { - xf_proxy_message_t *command; - - /* ...allocate message; the call should not fail */ - if ((m = xf_msg_pool_get(&XF_CORE_RO_DATA(core)->pool)) == NULL) - break; - - /* ...if queue was full, set global proxy update flag */ - if (XF_QUEUE_FULL(read_idx, write_idx)) - status |= XF_PROXY_STATUS_REMOTE | XF_PROXY_STATUS_LOCAL; - else - status |= XF_PROXY_STATUS_LOCAL; - - /* ...get oldest not processed command */ - command = XF_PROXY_COMMAND(core, XF_QUEUE_IDX(read_idx)); - - /* ...synchronize memory contents */ - XF_PROXY_INVALIDATE(command, sizeof(*command)); - - /* ...fill message parameters */ - m->id = command->session_id; - m->opcode = command->opcode; - m->length = command->length; - m->buffer = xf_ipc_a2b(core, command->address); - TRACE(CMD, _b("C[%x]:(%x,%u,%p)"), m->id, m->opcode, m->length, m->buffer); - - /* ...invalidate message buffer contents as required - not here - tbd */ - (XF_OPCODE_CDATA(m->opcode) ? XF_PROXY_INVALIDATE(m->buffer, m->length) : 0); - - /* ...advance local reading index copy */ - read_idx = XF_QUEUE_ADVANCE_IDX(read_idx); - - /* ...update shadow copy of reading index */ - XF_PROXY_WRITE(core, cmd_read_idx, read_idx); - - /* ...and schedule message execution on proper core */ - xf_msg_submit(m); - } - - return status; -} - -/* ...send out all pending outgoing responses to the shared memory ring-buffer */ -static u32 xf_shmem_process_output(u32 core) -{ - xf_message_t *m; - u32 read_idx; - u32 write_idx; - u32 status = 0; - - /* ...get current value of peer read pointer */ - write_idx = XF_PROXY_READ(core, rsp_write_idx); - read_idx = XF_PROXY_READ(core, rsp_read_idx); - - TRACE(EXEC, _b("Response queue: write = %08X / read = %08X"), write_idx, read_idx); - - /* ...while we have response messages and there's space to write out one */ - while (!XF_QUEUE_FULL(read_idx, write_idx)) - { - xf_proxy_message_t *response; - - /* ...remove message from internal queue */ - if ((m = xf_msg_proxy_get(core)) == NULL) - break; - - /* ...notify remote interface each time we send it a message (only if it was empty?) */ - status = XF_PROXY_STATUS_REMOTE | XF_PROXY_STATUS_LOCAL; - -#if 0 - /* ...need to decide on best strategy - tbd */ - if (XF_QUEUE_EMPTY(read_idx, write_idx)) - status |= XF_PROXY_STATUS_REMOTE | XF_PROXY_STATUS_LOCAL; - else - status |= XF_PROXY_STATUS_LOCAL; -#endif - - /* ...flush message buffer contents to main memory as required - too late - different core - tbd */ - (XF_OPCODE_RDATA(m->opcode) ? XF_PROXY_FLUSH(m->buffer, m->length) : 0); - - /* ...find place in a queue for next response */ - response = XF_PROXY_RESPONSE(core, XF_QUEUE_IDX(write_idx)); - - /* ...put the response message fields */ - response->session_id = m->id; - response->opcode = m->opcode; - response->length = m->length; - response->address = xf_ipc_b2a(core, m->buffer); - /* ...flush the content of the caches to main memory */ - XF_PROXY_FLUSH(response, sizeof(*response)); - -#ifdef XAF_PROFILE_DSP - if((m->opcode == XF_FILL_THIS_BUFFER)) - { - if((m->length != 0) && (m->length != 20)) - { - prof.g_output_bytes += (unsigned long)m->length; - } - else if (m->length == 20) - { - /* Profiler re-initialization */ - INIT_XA_PROFILER(prof,"DSP core"); - - /* update stream params on re-init */ - xf_start_msg_t *sm = (xf_start_msg_t *)m->buffer; - prof.sample_rate = sm->sample_rate; - prof.channels = sm->channels; - prof.pcm_width = sm->pcm_width; - } - } -#endif - TRACE(RSP, _b("R[%x]:(%x,%u,%p)"), m->id, m->opcode, m->length, m->buffer); - - /* ...return message back to the pool */ - xf_msg_pool_put(&XF_CORE_RO_DATA(core)->pool, m); - - /* ...advance local writing index copy */ - write_idx = XF_QUEUE_ADVANCE_IDX(write_idx); - - /* ...update shared copy of queue write pointer */ - XF_PROXY_WRITE(core, rsp_write_idx, write_idx); - } - - /* ...return interface status change flags */ - return status; -} - -/******************************************************************************* - * Entry points - ******************************************************************************/ - -/* ...process local/remote shared memory interface status change */ -void xf_shmem_process_queues(u32 core) -{ - u32 status; - - do - { - /* ...acknowledge/clear any pending incoming interrupt */ - XF_PROXY_SYNC_PEER(core); - - /* ...send out pending response messages (frees message buffers, so do it first) */ - status = xf_shmem_process_output(core); - - /* ...receive and forward incoming command messages (allocates message buffers) */ - status |= xf_shmem_process_input(core); - - /* ...assert remote mailbox interrupt if global update bit is set */ - if (status & XF_PROXY_STATUS_REMOTE) - { - XF_PROXY_NOTIFY_PEER(core); - } - } - while (status); -} - -/* ...completion callback for message originating from remote proxy */ -void xf_msg_proxy_complete(xf_message_t *m) -{ - /* ...place message into proxy response queue */ - xf_msg_proxy_put(m); -} - -/* ...initialize shared memory interface (DSP side) */ -int xf_shmem_init(u32 core) -{ - xf_core_rw_data_t *rw = XF_CORE_RW_DATA(core); - xf_core_ro_data_t *ro = XF_CORE_RO_DATA(core); - - /* ...initialize local/remote message queues */ - xf_msg_queue_init(&rw->local); - xf_msg_queue_init(&rw->remote); - - /* ...initialize global message list */ - XF_CHK_API(xf_msg_pool_init(&ro->pool, XF_CFG_MESSAGE_POOL_SIZE, core)); - - /* ...flush memory content as needed */ - (XF_REMOTE_IPC_NON_COHERENT ? XF_PROXY_FLUSH(rw, sizeof(*rw)) : 0); - - /* ...system-specific initialization of IPC layer */ - XF_CHK_API(xf_ipc_init(core)); - - TRACE(INIT, _b("SHMEM-%u subsystem initialized"), core); - - return 0; -} |