From c42415531f41feb005b09b17d0775ba9f2f66210 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 3 Dec 2018 16:57:49 +0000 Subject: [PATCH 1/2] abi: ipc: Move mem caps and panics codes to coreect header. Topology mem capabilities and trace panics codes should be in the correct header for their users. Signed-off-by: Liam Girdwood --- src/include/sof/alloc.h | 1 + src/include/sof/debug.h | 2 +- src/include/uapi/ipc/header.h | 26 -------------------------- src/include/uapi/ipc/topology.h | 12 ++++++++++++ src/include/uapi/ipc/trace.h | 18 ++++++++++++++++++ 5 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/include/sof/alloc.h b/src/include/sof/alloc.h index e470b797fd17..2254262bedf1 100644 --- a/src/include/sof/alloc.h +++ b/src/include/sof/alloc.h @@ -38,6 +38,7 @@ #include #include #include +#include struct sof; diff --git a/src/include/sof/debug.h b/src/include/sof/debug.h index 7f6b1c23c32f..02ce77c898b5 100644 --- a/src/include/sof/debug.h +++ b/src/include/sof/debug.h @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/include/uapi/ipc/header.h b/src/include/uapi/ipc/header.h index 2e1bf073aa11..c58455e70539 100644 --- a/src/include/uapi/ipc/header.h +++ b/src/include/uapi/ipc/header.h @@ -139,34 +139,8 @@ #define SOF_IPC_MSG_MAX_SIZE 384 /* - * SOF panic codes */ -#define SOF_IPC_PANIC_MAGIC 0x0dead000 -#define SOF_IPC_PANIC_MAGIC_MASK 0x0ffff000 -#define SOF_IPC_PANIC_CODE_MASK 0x00000fff -#define SOF_IPC_PANIC_MEM (SOF_IPC_PANIC_MAGIC | 0x0) -#define SOF_IPC_PANIC_WORK (SOF_IPC_PANIC_MAGIC | 0x1) -#define SOF_IPC_PANIC_IPC (SOF_IPC_PANIC_MAGIC | 0x2) -#define SOF_IPC_PANIC_ARCH (SOF_IPC_PANIC_MAGIC | 0x3) -#define SOF_IPC_PANIC_PLATFORM (SOF_IPC_PANIC_MAGIC | 0x4) -#define SOF_IPC_PANIC_TASK (SOF_IPC_PANIC_MAGIC | 0x5) -#define SOF_IPC_PANIC_EXCEPTION (SOF_IPC_PANIC_MAGIC | 0x6) -#define SOF_IPC_PANIC_DEADLOCK (SOF_IPC_PANIC_MAGIC | 0x7) -#define SOF_IPC_PANIC_STACK (SOF_IPC_PANIC_MAGIC | 0x8) -#define SOF_IPC_PANIC_IDLE (SOF_IPC_PANIC_MAGIC | 0x9) -#define SOF_IPC_PANIC_WFI (SOF_IPC_PANIC_MAGIC | 0xa) -/* - * SOF memory capabilities, add new ones at the end - */ -#define SOF_MEM_CAPS_RAM (1 << 0) -#define SOF_MEM_CAPS_ROM (1 << 1) -#define SOF_MEM_CAPS_EXT (1 << 2) /**< external */ -#define SOF_MEM_CAPS_LP (1 << 3) /**< low power */ -#define SOF_MEM_CAPS_HP (1 << 4) /**< high performance */ -#define SOF_MEM_CAPS_DMA (1 << 5) /**< DMA'able */ -#define SOF_MEM_CAPS_CACHE (1 << 6) /**< cacheable */ -#define SOF_MEM_CAPS_EXEC (1 << 7) /**< executable */ /* * Command Header - Header for all IPC. Identifies IPC message. diff --git a/src/include/uapi/ipc/topology.h b/src/include/uapi/ipc/topology.h index a28f62fef0bd..1c8924c2aa44 100644 --- a/src/include/uapi/ipc/topology.h +++ b/src/include/uapi/ipc/topology.h @@ -86,6 +86,18 @@ struct sof_ipc_comp { * Component Buffers */ +/* + * SOF memory capabilities, add new ones at the end + */ +#define SOF_MEM_CAPS_RAM (1 << 0) +#define SOF_MEM_CAPS_ROM (1 << 1) +#define SOF_MEM_CAPS_EXT (1 << 2) /**< external */ +#define SOF_MEM_CAPS_LP (1 << 3) /**< low power */ +#define SOF_MEM_CAPS_HP (1 << 4) /**< high performance */ +#define SOF_MEM_CAPS_DMA (1 << 5) /**< DMA'able */ +#define SOF_MEM_CAPS_CACHE (1 << 6) /**< cacheable */ +#define SOF_MEM_CAPS_EXEC (1 << 7) /**< executable */ + /* create new component buffer - SOF_IPC_TPLG_BUFFER_NEW */ struct sof_ipc_buffer { struct sof_ipc_comp comp; diff --git a/src/include/uapi/ipc/trace.h b/src/include/uapi/ipc/trace.h index 519226d94398..5828e2f80b2a 100644 --- a/src/include/uapi/ipc/trace.h +++ b/src/include/uapi/ipc/trace.h @@ -67,6 +67,24 @@ struct sof_ipc_dma_trace_posn { * Commom debug */ +/* + * SOF panic codes + */ +#define SOF_IPC_PANIC_MAGIC 0x0dead000 +#define SOF_IPC_PANIC_MAGIC_MASK 0x0ffff000 +#define SOF_IPC_PANIC_CODE_MASK 0x00000fff +#define SOF_IPC_PANIC_MEM (SOF_IPC_PANIC_MAGIC | 0x0) +#define SOF_IPC_PANIC_WORK (SOF_IPC_PANIC_MAGIC | 0x1) +#define SOF_IPC_PANIC_IPC (SOF_IPC_PANIC_MAGIC | 0x2) +#define SOF_IPC_PANIC_ARCH (SOF_IPC_PANIC_MAGIC | 0x3) +#define SOF_IPC_PANIC_PLATFORM (SOF_IPC_PANIC_MAGIC | 0x4) +#define SOF_IPC_PANIC_TASK (SOF_IPC_PANIC_MAGIC | 0x5) +#define SOF_IPC_PANIC_EXCEPTION (SOF_IPC_PANIC_MAGIC | 0x6) +#define SOF_IPC_PANIC_DEADLOCK (SOF_IPC_PANIC_MAGIC | 0x7) +#define SOF_IPC_PANIC_STACK (SOF_IPC_PANIC_MAGIC | 0x8) +#define SOF_IPC_PANIC_IDLE (SOF_IPC_PANIC_MAGIC | 0x9) +#define SOF_IPC_PANIC_WFI (SOF_IPC_PANIC_MAGIC | 0xa) + /* panic info include filename and line number */ struct sof_ipc_panic_info { char filename[SOF_TRACE_FILENAME_SIZE]; From 119f53494f1f31b09d1cc84cfd0e3c9feefd0134 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 3 Dec 2018 21:11:57 +0000 Subject: [PATCH 2/2] abi: ipc: Allow ABI to grow with MINOR/PATCH updates. This patch allows ABI changes to incrementally grow certain IPC structure and sub structures without changing MAJOR and keeping backwards compatability. Adds some helper IPC copier and validation macros that should be used when handling external IPC structures. These ensure IPC changes are handled correctly without causing errors or failures. IPC size should be the first item in each structure to make it as easy as possible to manage MINOR and PATCH ABI updates without unnecessary replacement of FW or kernel. This patch also makes size first in the IPC command header and introduces a new header for internal IPC sub structures. The sub structure size can be used to validate IPC and also be used to grow tail IPC command sub structures as MINOR/PATCH ABI changes. Signed-off-by: Liam Girdwood --- src/arch/xtensa/include/arch/sof.h | 3 + src/audio/dai.c | 6 + src/audio/eq_fir.c | 6 + src/audio/eq_iir.c | 6 + src/audio/host.c | 5 + src/audio/mixer.c | 7 + src/audio/src.c | 6 + src/audio/tone.c | 6 + src/audio/volume.c | 7 + src/include/sof/debug.h | 20 +- src/include/sof/ipc.h | 60 ++++ src/include/uapi/abi.h | 2 +- src/include/uapi/ipc/control.h | 2 +- src/include/uapi/ipc/dai-intel.h | 4 + src/include/uapi/ipc/dai.h | 2 +- src/include/uapi/ipc/header.h | 17 +- src/include/uapi/ipc/info.h | 16 +- src/include/uapi/ipc/pm.h | 5 +- src/include/uapi/ipc/stream.h | 15 +- src/include/uapi/ipc/topology.h | 16 +- src/include/uapi/ipc/trace.h | 4 +- src/include/uapi/ipc/xtensa.h | 3 + src/ipc/handler.c | 277 +++++++++--------- .../apollolake/include/platform/memory.h | 18 +- .../baytrail/include/platform/memory.h | 12 +- src/platform/baytrail/platform.c | 1 + .../cannonlake/include/platform/memory.h | 12 +- .../haswell/include/platform/memory.h | 4 +- src/platform/haswell/platform.c | 1 + .../icelake/include/platform/memory.h | 16 +- src/platform/intel/cavs/memory.c | 1 - src/platform/intel/cavs/platform.c | 1 + 32 files changed, 354 insertions(+), 207 deletions(-) diff --git a/src/arch/xtensa/include/arch/sof.h b/src/arch/xtensa/include/arch/sof.h index 76a9679b3791..f51f0c230359 100644 --- a/src/arch/xtensa/include/arch/sof.h +++ b/src/arch/xtensa/include/arch/sof.h @@ -57,6 +57,9 @@ static inline void *arch_dump_regs(uint32_t ps) struct sof_ipc_dsp_oops_xtensa *x = (struct sof_ipc_dsp_oops_xtensa *) mailbox_get_exception_base(); + /* tell users how much data is here */ + x->hdr.size = sizeof(*x); + /* Exception Vector number - 0x0 */ __asm__ __volatile__ ("rsr %0, EXCCAUSE" : "=a" (x->exccause) : : "memory"); /* Exception Vector address - 0x4 */ diff --git a/src/audio/dai.c b/src/audio/dai.c index b8a3393a5a66..bc122d3f6026 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -176,6 +177,11 @@ static struct comp_dev *dai_new(struct sof_ipc_comp *comp) trace_dai("dai_new()"); + if (IPC_IS_SIZE_INVALID(ipc_dai->config)) { + IPC_SIZE_ERROR_TRACE(TRACE_CLASS_DAI, ipc_dai->config); + return NULL; + } + dev = rzalloc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, COMP_SIZE(struct sof_ipc_comp_dai)); if (dev == NULL) diff --git a/src/audio/eq_fir.c b/src/audio/eq_fir.c index eb559568d5d2..f2b9a927b009 100644 --- a/src/audio/eq_fir.c +++ b/src/audio/eq_fir.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "fir_config.h" @@ -382,6 +383,11 @@ static struct comp_dev *eq_fir_new(struct sof_ipc_comp *comp) trace_eq("eq_fir_new()"); + if (IPC_IS_SIZE_INVALID(ipc_fir->config)) { + IPC_SIZE_ERROR_TRACE(TRACE_CLASS_EQ_FIR, ipc_fir->config); + return NULL; + } + /* Check first before proceeding with dev and cd that coefficients * blob size is sane. */ diff --git a/src/audio/eq_iir.c b/src/audio/eq_iir.c index 5c3ec57c26c4..f1212ec8df6f 100644 --- a/src/audio/eq_iir.c +++ b/src/audio/eq_iir.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -351,6 +352,11 @@ static struct comp_dev *eq_iir_new(struct sof_ipc_comp *comp) trace_eq("eq_iir_new()"); + if (IPC_IS_SIZE_INVALID(ipc_iir->config)) { + IPC_SIZE_ERROR_TRACE(TRACE_CLASS_EQ_IIR, ipc_iir->config); + return NULL; + } + /* Check first before proceeding with dev and cd that coefficients * blob size is sane. */ diff --git a/src/audio/host.c b/src/audio/host.c index 1aa76b140cf0..465127a91bfe 100644 --- a/src/audio/host.c +++ b/src/audio/host.c @@ -337,6 +337,11 @@ static struct comp_dev *host_new(struct sof_ipc_comp *comp) trace_host("host_new()"); + if (IPC_IS_SIZE_INVALID(ipc_host->config)) { + IPC_SIZE_ERROR_TRACE(TRACE_CLASS_HOST, ipc_host->config); + return NULL; + } + dev = rzalloc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, COMP_SIZE(struct sof_ipc_comp_host)); if (dev == NULL) diff --git a/src/audio/mixer.c b/src/audio/mixer.c index e66e4d15d09e..63c800d12239 100644 --- a/src/audio/mixer.c +++ b/src/audio/mixer.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -86,6 +87,12 @@ static struct comp_dev *mixer_new(struct sof_ipc_comp *comp) struct mixer_data *md; trace_mixer("mixer_new()"); + + if (IPC_IS_SIZE_INVALID(ipc_mixer->config)) { + IPC_SIZE_ERROR_TRACE(TRACE_CLASS_MIXER, ipc_mixer->config); + return NULL; + } + dev = rzalloc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, COMP_SIZE(struct sof_ipc_comp_mixer)); if (dev == NULL) diff --git a/src/audio/src.c b/src/audio/src.c index b44bc4097243..9c7d35a66076 100644 --- a/src/audio/src.c +++ b/src/audio/src.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -545,6 +546,11 @@ static struct comp_dev *src_new(struct sof_ipc_comp *comp) trace_src("src_new()"); + if (IPC_IS_SIZE_INVALID(ipc_src->config)) { + IPC_SIZE_ERROR_TRACE(TRACE_CLASS_SRC, ipc_src->config); + return NULL; + } + /* validate init data - either SRC sink or source rate must be set */ if (ipc_src->source_rate == 0 && ipc_src->sink_rate == 0) { trace_src_error("src_new() error: " diff --git a/src/audio/tone.c b/src/audio/tone.c index ff337e784b58..723742a098d7 100644 --- a/src/audio/tone.c +++ b/src/audio/tone.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -404,6 +405,11 @@ static struct comp_dev *tone_new(struct sof_ipc_comp *comp) trace_tone("tone_new()"); + if (IPC_IS_SIZE_INVALID(ipc_tone->config)) { + IPC_SIZE_ERROR_TRACE(TRACE_CLASS_TONE, ipc_tone->config); + return NULL; + } + dev = rzalloc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, COMP_SIZE(struct sof_ipc_comp_tone)); if (dev == NULL) diff --git a/src/audio/volume.c b/src/audio/volume.c index 29547b5526be..d61335b15aa3 100644 --- a/src/audio/volume.c +++ b/src/audio/volume.c @@ -47,8 +47,10 @@ #include #include #include +#include #include "volume.h" #include + /** * \brief Synchronize host mmap() volume with real value. * \param[in,out] cd Volume component private data. @@ -175,6 +177,11 @@ static struct comp_dev *volume_new(struct sof_ipc_comp *comp) trace_volume("volume_new()"); + if (IPC_IS_SIZE_INVALID(ipc_vol->config)) { + IPC_SIZE_ERROR_TRACE(TRACE_CLASS_VOLUME, ipc_vol->config); + return NULL; + } + dev = rzalloc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, COMP_SIZE(struct sof_ipc_comp_volume)); if (dev == NULL) diff --git a/src/include/sof/debug.h b/src/include/sof/debug.h index 02ce77c898b5..59009b42741f 100644 --- a/src/include/sof/debug.h +++ b/src/include/sof/debug.h @@ -45,10 +45,12 @@ #ifdef DEBUG_BUILD #define DEBUG_SET_FW_READY_FLAGS \ -{ \ - .build = 1, \ - .locks = DEBUG_LOCKS, \ - .locks_verbose = DEBUG_LOCKS_VERBOSE, \ +{ \ + .bits = { \ + .build = 1, \ + .locks = DEBUG_LOCKS, \ + .locks_verbose = DEBUG_LOCKS_VERBOSE, \ + }, \ } /* dump file and line to start of mailbox or shared memory */ @@ -126,10 +128,12 @@ #else #define DEBUG_SET_FW_READY_FLAGS \ -{ \ - .build = 0, \ - .locks = DEBUG_LOCKS, \ - .locks_verbose = DEBUG_LOCKS_VERBOSE, \ +{ \ + .bits = { \ + .build = 0, \ + .locks = DEBUG_LOCKS, \ + .locks_verbose = DEBUG_LOCKS_VERBOSE, \ + }, \ } #define dbg() diff --git a/src/include/sof/ipc.h b/src/include/sof/ipc.h index c4890cdfd556..a3709eb36ef8 100644 --- a/src/include/sof/ipc.h +++ b/src/include/sof/ipc.h @@ -41,6 +41,7 @@ #include #include #include +#include struct sof; struct dai_config; @@ -58,6 +59,65 @@ struct dai_config; #define COMP_TYPE_BUFFER 2 #define COMP_TYPE_PIPELINE 3 +/* + * IPC ABI version compatibility rules :- + * + * 1) FW binaries will only support one MAJOR ABI version which is advertised + * to host at FW boot. + * + * 2) Host drivers will support the current and older MAJOR ABI versions of + * the IPC ABI (up to a certain age to be determined by market information). + * + * 3) MINOR and PATCH ABI versions can differ between host and FW but must be + * backwards compatible on both host and FW. + * + * IPC messages sizes can be different for sender and receiver if MINOR or + * PATCH ABI versions differ as new fields can be added to the end of + * messages. + * + * i) Sender > receiver: receiver only copies it's own ABI structure size. + * + * ii) Receiver > sender: receiver copies its's own ABI size and zero pads + * new fields. i.e. new structure fields must be non + * zero to be activated. + * + * Guidelines for extending ABI compatible messages :- + * + * i) Use reserved fields. + * ii) Grow structure at the end. + * iii) Iff (i) and (ii) are not possible then MAJOR ABI is bumped. + */ + +#define _IPC_COPY_CMD(rx, tx, rx_size) \ + do { \ + if (rx_size > tx->size) { \ + memcpy(rx, tx, tx->size); \ + bzero((void *)rx + tx->size, rx_size - tx->size);\ + trace_ipc("ipc: hdr 0x%x rx (%d) > tx (%d)", \ + rx->cmd, rx_size, tx->size); \ + } else if (tx->size > rx_size) { \ + memcpy(rx, tx, tx->size); \ + trace_ipc("ipc: hdr 0x%x tx (%d) > rx (%d)", \ + rx->cmd, tx->size, rx_size); \ + } else \ + memcpy(rx, tx, rx_size); \ + } while (0) + +/* copies whole message from Tx to Rx, follows above ABI rules */ +#define IPC_COPY_CMD(rx, tx) \ + _IPC_COPY_CMD(((struct sof_ipc_cmd_hdr *)&rx), \ + ((struct sof_ipc_cmd_hdr *)tx), \ + sizeof(rx)) + +/* validates internal non tail structures within IPC command structure */ +#define IPC_IS_SIZE_INVALID(object) \ + object.hdr.size == sizeof(object) ? 0 : 1 + +/* convenience error trace for mismatched internal structures */ +#define IPC_SIZE_ERROR_TRACE(class, object) \ + trace_error(class, "ipc: size %d expected %d", \ + object.hdr.size, sizeof(object)) + /* IPC generic component device */ struct ipc_comp_dev { uint16_t type; /* COMP_TYPE_ */ diff --git a/src/include/uapi/abi.h b/src/include/uapi/abi.h index 4669f10457f6..848f68effe37 100644 --- a/src/include/uapi/abi.h +++ b/src/include/uapi/abi.h @@ -51,7 +51,7 @@ #define __INCLUDE_UAPI_ABI_H__ /** \brief SOF ABI version major, minor and patch numbers */ -#define SOF_ABI_MAJOR 2 +#define SOF_ABI_MAJOR 3 #define SOF_ABI_MINOR 0 #define SOF_ABI_PATCH 0 diff --git a/src/include/uapi/ipc/control.h b/src/include/uapi/ipc/control.h index eaf2d643056c..9ab1252ff5ad 100644 --- a/src/include/uapi/ipc/control.h +++ b/src/include/uapi/ipc/control.h @@ -136,7 +136,7 @@ struct sof_ipc_ctrl_data { /* control data - can either be appended or DMAed from host */ struct sof_ipc_host_buffer buffer; - uint32_t num_elems; /**< in array elems or bytes */ + uint32_t num_elems; /**< in array elems or bytes for data type */ /* reserved for future use */ uint32_t reserved[8]; diff --git a/src/include/uapi/ipc/dai-intel.h b/src/include/uapi/ipc/dai-intel.h index 2d459778f631..b0650e243178 100644 --- a/src/include/uapi/ipc/dai-intel.h +++ b/src/include/uapi/ipc/dai-intel.h @@ -78,6 +78,7 @@ /* SSP Configuration Request - SOF_IPC_DAI_SSP_CONFIG */ struct sof_ipc_dai_ssp_params { + struct sof_ipc_hdr hdr; uint16_t reserved1; uint16_t mclk_id; @@ -106,6 +107,7 @@ struct sof_ipc_dai_ssp_params { /* HDA Configuration Request - SOF_IPC_DAI_HDA_CONFIG */ struct sof_ipc_dai_hda_params { + struct sof_ipc_hdr hdr; uint32_t link_dma_ch; } __attribute__((packed)); @@ -129,6 +131,7 @@ struct sof_ipc_dai_hda_params { * data integrity problems. */ struct sof_ipc_dai_dmic_pdm_ctrl { + struct sof_ipc_hdr hdr; uint16_t id; /**< PDM controller ID */ uint16_t enable_mic_a; /**< Use A (left) channel mic (0 or 1)*/ @@ -173,6 +176,7 @@ struct sof_ipc_dai_dmic_pdm_ctrl { * treated as an error. */ struct sof_ipc_dai_dmic_params { + struct sof_ipc_hdr hdr; uint32_t driver_ipc_version; /**< Version (1..N) */ uint32_t pdmclk_min; /**< Minimum microphone clock in Hz (100000..N) */ diff --git a/src/include/uapi/ipc/dai.h b/src/include/uapi/ipc/dai.h index e2d54160f42c..3994b05c7006 100644 --- a/src/include/uapi/ipc/dai.h +++ b/src/include/uapi/ipc/dai.h @@ -83,7 +83,7 @@ enum sof_ipc_dai_type { /* general purpose DAI configuration */ struct sof_ipc_dai_config { - struct sof_ipc_hdr hdr; + struct sof_ipc_cmd_hdr hdr; uint32_t type; /**< DAI type - enum sof_ipc_dai_type */ uint32_t dai_index; /**< index of this type dai */ diff --git a/src/include/uapi/ipc/header.h b/src/include/uapi/ipc/header.h index c58455e70539..69d68c48c99b 100644 --- a/src/include/uapi/ipc/header.h +++ b/src/include/uapi/ipc/header.h @@ -139,19 +139,26 @@ #define SOF_IPC_MSG_MAX_SIZE 384 /* + * Structure Header - Header for all IPC structures except command structs. + * The size can be greater than the structure size and that means there is + * extended bespoke data beyond the end of the structure including variable + * arrays. */ +struct sof_ipc_hdr { + uint32_t size; /**< size of structure */ +} __attribute__((packed)); /* - * Command Header - Header for all IPC. Identifies IPC message. + * Command Header - Header for all IPC commands. Identifies IPC message. * The size can be greater than the structure size and that means there is * extended bespoke data beyond the end of the structure including variable * arrays. */ -struct sof_ipc_hdr { - uint32_t cmd; /**< SOF_IPC_GLB_ + cmd */ +struct sof_ipc_cmd_hdr { uint32_t size; /**< size of structure */ + uint32_t cmd; /**< SOF_IPC_GLB_ + cmd */ } __attribute__((packed)); /* @@ -159,7 +166,7 @@ struct sof_ipc_hdr { * types that must include this at start. */ struct sof_ipc_reply { - struct sof_ipc_hdr hdr; + struct sof_ipc_cmd_hdr hdr; int32_t error; /**< negative error numbers */ } __attribute__((packed)); @@ -173,7 +180,7 @@ struct sof_ipc_reply { */ struct sof_ipc_compound_hdr { - struct sof_ipc_hdr hdr; + struct sof_ipc_cmd_hdr hdr; uint32_t count; /**< count of 0 means end of compound sequence */ } __attribute__((packed)); diff --git a/src/include/uapi/ipc/info.h b/src/include/uapi/ipc/info.h index 1efe454f935e..65c451ddb84c 100644 --- a/src/include/uapi/ipc/info.h +++ b/src/include/uapi/ipc/info.h @@ -56,6 +56,7 @@ enum sof_ipc_ext_data { /* FW version - SOF_IPC_GLB_VERSION */ struct sof_ipc_fw_version { + struct sof_ipc_hdr hdr; uint16_t major; uint16_t minor; uint16_t micro; @@ -71,7 +72,7 @@ struct sof_ipc_fw_version { /* FW ready Message - sent by firmware when boot has completed */ struct sof_ipc_fw_ready { - struct sof_ipc_hdr hdr; + struct sof_ipc_cmd_hdr hdr; uint32_t dspbox_offset; /* dsp initiated IPC mailbox */ uint32_t hostbox_offset; /* host initiated IPC mailbox */ uint32_t dspbox_size; @@ -81,9 +82,12 @@ struct sof_ipc_fw_ready { /* Miscellaneous debug flags showing build/debug features enabled */ union { uint64_t reserved; - uint64_t build:1; - uint64_t locks:1; - uint64_t locks_verbose:1; + struct { + uint64_t build:1; + uint64_t locks:1; + uint64_t locks_verbose:1; + uint64_t gdb:1; + } bits; } debug; uint32_t gdb_enabled; @@ -106,11 +110,12 @@ enum sof_ipc_region { }; struct sof_ipc_ext_data_hdr { - struct sof_ipc_hdr hdr; + struct sof_ipc_cmd_hdr hdr; uint32_t type; /**< SOF_IPC_EXT_ */ } __attribute__((packed)); struct sof_ipc_dma_buffer_elem { + struct sof_ipc_hdr hdr; uint32_t type; /**< SOF_IPC_REGION_ */ uint32_t id; /**< platform specific - used to map to host memory */ struct sof_ipc_host_buffer buffer; @@ -126,6 +131,7 @@ struct sof_ipc_dma_buffer_data { } __attribute__((packed)); struct sof_ipc_window_elem { + struct sof_ipc_hdr hdr; uint32_t type; /**< SOF_IPC_REGION_ */ uint32_t id; /**< platform specific - used to map to host memory */ uint32_t flags; /**< R, W, RW, etc - to define */ diff --git a/src/include/uapi/ipc/pm.h b/src/include/uapi/ipc/pm.h index c78b19f32f6b..5bb7fb4144f0 100644 --- a/src/include/uapi/ipc/pm.h +++ b/src/include/uapi/ipc/pm.h @@ -47,6 +47,7 @@ /* PM context element */ struct sof_ipc_pm_ctx_elem { + struct sof_ipc_hdr hdr; uint32_t type; uint32_t size; uint64_t addr; @@ -57,7 +58,7 @@ struct sof_ipc_pm_ctx_elem { * SOF_IPC_PM_CTX_SIZE */ struct sof_ipc_pm_ctx { - struct sof_ipc_hdr hdr; + struct sof_ipc_cmd_hdr hdr; struct sof_ipc_host_buffer buffer; uint32_t num_elems; uint32_t size; @@ -70,7 +71,7 @@ struct sof_ipc_pm_ctx { /* enable or disable cores - SOF_IPC_PM_CORE_ENABLE */ struct sof_ipc_pm_core_config { - struct sof_ipc_hdr hdr; + struct sof_ipc_cmd_hdr hdr; uint32_t enable_mask; } __attribute__((packed)); diff --git a/src/include/uapi/ipc/stream.h b/src/include/uapi/ipc/stream.h index 801c39aac62e..beef3067888e 100644 --- a/src/include/uapi/ipc/stream.h +++ b/src/include/uapi/ipc/stream.h @@ -67,6 +67,9 @@ #define SOF_RATE_CONTINUOUS (1 << 30) /**< range */ #define SOF_RATE_KNOT (1 << 31) /**< non-continuous */ +/* generic PCM flags for runtime settings */ +#define SOF_PCM_FLAG_XRUN_STOP (1 << 0) /**< Stop on any XRUN */ + /* stream PCM frame format */ enum sof_ipc_frame { SOF_IPC_FRAME_S16_LE = 0, @@ -91,15 +94,18 @@ enum sof_ipc_stream_direction { /* stream ring info */ struct sof_ipc_host_buffer { + struct sof_ipc_hdr hdr; uint32_t phy_addr; uint32_t pages; uint32_t size; uint32_t offset; + uint32_t reserved[2]; } __attribute__((packed)); struct sof_ipc_stream_params { + struct sof_ipc_hdr hdr; struct sof_ipc_host_buffer buffer; - uint32_t direction; /**< enum sof_ipc_stream_directio */ + uint32_t direction; /**< enum sof_ipc_stream_direction */ uint32_t frame_fmt; /**< enum sof_ipc_frame */ uint32_t buffer_fmt; /**< enum sof_ipc_buffer_format */ uint32_t rate; @@ -111,13 +117,16 @@ struct sof_ipc_stream_params { /* for notifying host period has completed - 0 means no period IRQ */ uint32_t host_period_bytes; + uint32_t reserved[2]; uint16_t chmap[SOF_IPC_MAX_CHANNELS]; /**< channel map - SOF_CHMAP_ */ } __attribute__((packed)); /* PCM params info - SOF_IPC_STREAM_PCM_PARAMS */ struct sof_ipc_pcm_params { - struct sof_ipc_hdr hdr; + struct sof_ipc_cmd_hdr hdr; uint32_t comp_id; + uint32_t flags; /**< generic PCM flags - SOF_PCM_FLAG_ */ + uint32_t reserved[2]; struct sof_ipc_stream_params params; } __attribute__((packed)); @@ -130,7 +139,7 @@ struct sof_ipc_pcm_params_reply { /* free stream - SOF_IPC_STREAM_PCM_PARAMS */ struct sof_ipc_stream { - struct sof_ipc_hdr hdr; + struct sof_ipc_cmd_hdr hdr; uint32_t comp_id; } __attribute__((packed)); diff --git a/src/include/uapi/ipc/topology.h b/src/include/uapi/ipc/topology.h index 1c8924c2aa44..c85283151813 100644 --- a/src/include/uapi/ipc/topology.h +++ b/src/include/uapi/ipc/topology.h @@ -73,7 +73,7 @@ enum sof_comp_type { /* create new generic component - SOF_IPC_TPLG_COMP_NEW */ struct sof_ipc_comp { - struct sof_ipc_hdr hdr; + struct sof_ipc_cmd_hdr hdr; uint32_t id; enum sof_comp_type type; uint32_t pipeline_id; @@ -107,6 +107,7 @@ struct sof_ipc_buffer { /* generic component config data - must always be after struct sof_ipc_comp */ struct sof_ipc_comp_config { + struct sof_ipc_cmd_hdr hdr; uint32_t periods_sink; /**< 0 means variable */ uint32_t periods_source; /**< 0 means variable */ uint32_t preload_count; /**< how many periods to preload */ @@ -201,6 +202,7 @@ enum sof_ipc_effect_type { /* general purpose EFFECT configuration */ struct sof_ipc_comp_effect { + struct sof_ipc_hdr hdr; uint32_t type; /** sof_ipc_effect_type */ } __attribute__((packed)); @@ -232,7 +234,7 @@ struct sof_ipc_comp_eq_iir { * SOF_IPC_TPLG_COMP_FREE, SOF_IPC_TPLG_PIPE_FREE, SOF_IPC_TPLG_BUFFER_FREE */ struct sof_ipc_free { - struct sof_ipc_hdr hdr; + struct sof_ipc_cmd_hdr hdr; uint32_t id; } __attribute__((packed)); @@ -248,10 +250,10 @@ struct sof_ipc_comp_reply { /* new pipeline - SOF_IPC_TPLG_PIPE_NEW */ struct sof_ipc_pipe_new { - struct sof_ipc_hdr hdr; + struct sof_ipc_cmd_hdr hdr; uint32_t comp_id; /**< component id for pipeline */ uint32_t pipeline_id; /**< pipeline id */ - uint32_t sched_id; /**< sheduling component id */ + uint32_t sched_id; /**< Scheduling component id */ uint32_t core; /**< core we run on */ uint32_t deadline; /**< execution completion deadline in us*/ uint32_t priority; /**< priority level 0 (low) to 10 (max) */ @@ -265,18 +267,18 @@ struct sof_ipc_pipe_new { /* pipeline construction complete - SOF_IPC_TPLG_PIPE_COMPLETE */ struct sof_ipc_pipe_ready { - struct sof_ipc_hdr hdr; + struct sof_ipc_cmd_hdr hdr; uint32_t comp_id; } __attribute__((packed)); struct sof_ipc_pipe_free { - struct sof_ipc_hdr hdr; + struct sof_ipc_cmd_hdr hdr; uint32_t comp_id; } __attribute__((packed)); /* connect two components in pipeline - SOF_IPC_TPLG_COMP_CONNECT */ struct sof_ipc_pipe_comp_connect { - struct sof_ipc_hdr hdr; + struct sof_ipc_cmd_hdr hdr; uint32_t source_id; uint32_t sink_id; } __attribute__((packed)); diff --git a/src/include/uapi/ipc/trace.h b/src/include/uapi/ipc/trace.h index 5828e2f80b2a..8fb914e640bd 100644 --- a/src/include/uapi/ipc/trace.h +++ b/src/include/uapi/ipc/trace.h @@ -50,7 +50,7 @@ /* DMA for Trace params info - SOF_IPC_DEBUG_DMA_PARAMS */ struct sof_ipc_dma_trace_params { - struct sof_ipc_hdr hdr; + struct sof_ipc_cmd_hdr hdr; struct sof_ipc_host_buffer buffer; uint32_t stream_tag; } __attribute__((packed)); @@ -87,6 +87,8 @@ struct sof_ipc_dma_trace_posn { /* panic info include filename and line number */ struct sof_ipc_panic_info { + struct sof_ipc_hdr hdr; + uint32_t code; /* SOF_IPC_PANIC_ */ char filename[SOF_TRACE_FILENAME_SIZE]; uint32_t linenum; } __attribute__((packed)); diff --git a/src/include/uapi/ipc/xtensa.h b/src/include/uapi/ipc/xtensa.h index 31a71c1d5605..9359a5b60fb3 100644 --- a/src/include/uapi/ipc/xtensa.h +++ b/src/include/uapi/ipc/xtensa.h @@ -39,12 +39,15 @@ #ifndef __INCLUDE_UAPI_IPC_XTENSA_H__ #define __INCLUDE_UAPI_IPC_XTENSA_H__ +#include + /* * Architecture specific debug */ /* Xtensa Firmware Oops data */ struct sof_ipc_dsp_oops_xtensa { + struct sof_ipc_hdr hdr; uint32_t exccause; uint32_t excvaddr; uint32_t ps; diff --git a/src/ipc/handler.c b/src/ipc/handler.c index bd72416358af..1279e3130595 100644 --- a/src/ipc/handler.c +++ b/src/ipc/handler.c @@ -70,15 +70,12 @@ #define iGS(x) ((x >> SOF_GLB_TYPE_SHIFT) & 0xf) #define iCS(x) ((x >> SOF_CMD_TYPE_SHIFT) & 0xfff) -#define IPC_INVALID_SIZE(ipc) \ - (sizeof(*(ipc)) != ipc->hdr.size) - /* IPC context - shared with platform IPC driver */ struct ipc *_ipc; -static inline struct sof_ipc_hdr *mailbox_validate(void) +static inline struct sof_ipc_cmd_hdr *mailbox_validate(void) { - struct sof_ipc_hdr *hdr = _ipc->comp_data; + struct sof_ipc_cmd_hdr *hdr = _ipc->comp_data; /* read component values from the inbox */ mailbox_hostbox_read(hdr, 0, sizeof(*hdr)); @@ -177,38 +174,38 @@ static int ipc_stream_pcm_params(uint32_t stream) struct dma_sg_elem_array elem_array; uint32_t ring_size; #endif - struct sof_ipc_pcm_params *pcm_params = _ipc->comp_data; + struct sof_ipc_pcm_params pcm_params; struct sof_ipc_pcm_params_reply reply; struct ipc_comp_dev *pcm_dev; struct comp_dev *cd; int err, posn_offset; - trace_ipc("ipc: comp %d -> params", pcm_params->comp_id); + /* copy message with ABI safe method */ + IPC_COPY_CMD(pcm_params, _ipc->comp_data); - /* sanity check size */ - if (IPC_INVALID_SIZE(pcm_params)) { - trace_ipc_error("ipc:_invalid IPC size 0x%x got 0x%x", - sizeof(*pcm_params), pcm_params->hdr.size); - return -EINVAL; - } + trace_ipc("ipc: comp %d -> params", pcm_params.comp_id); /* get the pcm_dev */ - pcm_dev = ipc_get_comp(_ipc, pcm_params->comp_id); + pcm_dev = ipc_get_comp(_ipc, pcm_params.comp_id); if (pcm_dev == NULL) { - trace_ipc_error("ipc: comp %d not found", pcm_params->comp_id); + trace_ipc_error("ipc: comp %d not found", pcm_params.comp_id); return -ENODEV; } /* sanity check comp */ if (pcm_dev->cd->pipeline == NULL) { trace_ipc_error("ipc: comp %d pipeline not found", - pcm_params->comp_id); + pcm_params.comp_id); return -EINVAL; } /* set params component params */ cd = pcm_dev->cd; - cd->params = pcm_params->params; + if (IPC_IS_SIZE_INVALID(pcm_params.params)) { + IPC_SIZE_ERROR_TRACE(TRACE_CLASS_IPC, pcm_params.params); + return -EINVAL; + } + cd->params = pcm_params.params; #ifdef CONFIG_HOST_PTABLE dma_sg_init(&elem_array); @@ -222,30 +219,35 @@ static int ipc_stream_pcm_params(uint32_t stream) /* use DMA to read in compressed page table ringbuffer from host */ err = ipc_get_page_descriptors(iipc->dmac, iipc->page_table, - &pcm_params->params.buffer); + &pcm_params.params.buffer); if (err < 0) { trace_ipc_error("ipc: comp %d get descriptors failed %d", - pcm_params->comp_id, err); + pcm_params.comp_id, err); goto error; } /* Parse host tables */ host = (struct sof_ipc_comp_host *)&cd->comp; - ring_size = pcm_params->params.buffer.size; + if (IPC_IS_SIZE_INVALID(host->config)) { + IPC_SIZE_ERROR_TRACE(TRACE_CLASS_IPC, host->config); + goto error; + } + + ring_size = pcm_params.params.buffer.size; err = ipc_parse_page_descriptors(iipc->page_table, - &pcm_params->params.buffer, + &pcm_params.params.buffer, &elem_array, host->direction); if (err < 0) { trace_ipc_error("ipc: comp %d parse descriptors failed %d", - pcm_params->comp_id, err); + pcm_params.comp_id, err); goto error; } err = comp_host_buffer(cd, &elem_array, ring_size); if (err < 0) { trace_ipc_error("ipc: comp %d host buffer failed %d", - pcm_params->comp_id, err); + pcm_params.comp_id, err); goto error; } @@ -253,11 +255,11 @@ static int ipc_stream_pcm_params(uint32_t stream) #endif /* configure pipeline audio params */ - err = pipeline_params(pcm_dev->cd->pipeline, pcm_dev->cd, pcm_params); + err = pipeline_params(pcm_dev->cd->pipeline, pcm_dev->cd, &pcm_params); if (err < 0) { trace_ipc_error("ipc: pipe %d comp %d params failed %d", pcm_dev->cd->pipeline->ipc_pipe.pipeline_id, - pcm_params->comp_id, err); + pcm_params.comp_id, err); goto error; } @@ -266,7 +268,7 @@ static int ipc_stream_pcm_params(uint32_t stream) if (err < 0) { trace_ipc_error("ipc: pipe %d comp %d prepare failed %d", pcm_dev->cd->pipeline->ipc_pipe.pipeline_id, - pcm_params->comp_id, err); + pcm_params.comp_id, err); goto error; } @@ -274,14 +276,14 @@ static int ipc_stream_pcm_params(uint32_t stream) if (posn_offset < 0) { trace_ipc_error("ipc: pipe %d comp %d posn offset failed %d", pcm_dev->cd->pipeline->ipc_pipe.pipeline_id, - pcm_params->comp_id, err); + pcm_params.comp_id, err); goto error; } /* write component values to the outbox */ reply.rhdr.hdr.size = sizeof(reply); reply.rhdr.hdr.cmd = stream; reply.rhdr.error = 0; - reply.comp_id = pcm_params->comp_id; + reply.comp_id = pcm_params.comp_id; reply.posn_offset = posn_offset; mailbox_hostbox_write(0, &reply, sizeof(reply)); return 1; @@ -295,36 +297,32 @@ static int ipc_stream_pcm_params(uint32_t stream) if (err < 0) trace_ipc_error("ipc: pipe %d comp %d reset failed %d", pcm_dev->cd->pipeline->ipc_pipe.pipeline_id, - pcm_params->comp_id, err); + pcm_params.comp_id, err); return -EINVAL; } /* free stream resources */ static int ipc_stream_pcm_free(uint32_t header) { - struct sof_ipc_stream *free_req = _ipc->comp_data; + struct sof_ipc_stream free_req; struct ipc_comp_dev *pcm_dev; - trace_ipc("ipc: comp %d -> free", free_req->comp_id); + /* copy message with ABI safe method */ + IPC_COPY_CMD(free_req, _ipc->comp_data); - /* sanity check size */ - if (IPC_INVALID_SIZE(free_req)) { - trace_ipc_error("ipc:_invalid IPC size 0x%x got 0x%x", - sizeof(*free_req), free_req->hdr.size); - return -EINVAL; - } + trace_ipc("ipc: comp %d -> free", free_req.comp_id); /* get the pcm_dev */ - pcm_dev = ipc_get_comp(_ipc, free_req->comp_id); + pcm_dev = ipc_get_comp(_ipc, free_req.comp_id); if (pcm_dev == NULL) { - trace_ipc_error("ipc: comp %d not found", free_req->comp_id); + trace_ipc_error("ipc: comp %d not found", free_req.comp_id); return -ENODEV; } /* sanity check comp */ if (pcm_dev->cd->pipeline == NULL) { trace_ipc_error("ipc: comp %d pipeline not found", - free_req->comp_id); + free_req.comp_id); return -EINVAL; } @@ -335,33 +333,29 @@ static int ipc_stream_pcm_free(uint32_t header) /* get stream position */ static int ipc_stream_position(uint32_t header) { - struct sof_ipc_stream *stream = _ipc->comp_data; + struct sof_ipc_stream stream; struct sof_ipc_stream_posn posn; struct ipc_comp_dev *pcm_dev; - trace_ipc("ipc: comp %d -> position", stream->comp_id); + /* copy message with ABI safe method */ + IPC_COPY_CMD(stream, _ipc->comp_data); - memset(&posn, 0, sizeof(posn)); + trace_ipc("ipc: comp %d -> position", stream.comp_id); - /* sanity check size */ - if (IPC_INVALID_SIZE(stream)) { - trace_ipc_error("ipc:_invalid IPC size 0x%x got 0x%x", - sizeof(*stream), stream->hdr.size); - return -EINVAL; - } + memset(&posn, 0, sizeof(posn)); /* get the pcm_dev */ - pcm_dev = ipc_get_comp(_ipc, stream->comp_id); + pcm_dev = ipc_get_comp(_ipc, stream.comp_id); if (pcm_dev == NULL) { - trace_ipc_error("ipc: comp %d not found", stream->comp_id); + trace_ipc_error("ipc: comp %d not found", stream.comp_id); return -ENODEV; } /* set message fields - TODO; get others */ posn.rhdr.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_POSITION | - stream->comp_id; + stream.comp_id; posn.rhdr.hdr.size = sizeof(posn); - posn.comp_id = stream->comp_id; + posn.comp_id = stream.comp_id; /* get the stream positions and timestamps */ pipeline_get_timestamp(pcm_dev->cd->pipeline, pcm_dev->cd, &posn); @@ -405,24 +399,20 @@ int ipc_stream_send_xrun(struct comp_dev *cdev, static int ipc_stream_trigger(uint32_t header) { struct ipc_comp_dev *pcm_dev; - uint32_t cmd = COMP_TRIGGER_RELEASE; - struct sof_ipc_stream *stream = _ipc->comp_data; + struct sof_ipc_stream stream; uint32_t ipc_cmd = (header & SOF_CMD_TYPE_MASK) >> SOF_CMD_TYPE_SHIFT; + uint32_t cmd; int ret; - trace_ipc("ipc: comp %d -> trigger cmd %d", stream->comp_id, ipc_cmd); + /* copy message with ABI safe method */ + IPC_COPY_CMD(stream, _ipc->comp_data); - /* sanity check size */ - if (IPC_INVALID_SIZE(stream)) { - trace_ipc_error("ipc:_invalid IPC size 0x%x got 0x%x", - sizeof(*stream), stream->hdr.size); - return -EINVAL; - } + trace_ipc("ipc: comp %d -> trigger cmd %d", stream.comp_id, ipc_cmd); /* get the pcm_dev */ - pcm_dev = ipc_get_comp(_ipc, stream->comp_id); + pcm_dev = ipc_get_comp(_ipc, stream.comp_id); if (pcm_dev == NULL) { - trace_ipc_error("ipc: comp %d not found", stream->comp_id); + trace_ipc_error("ipc: comp %d not found", stream.comp_id); return -ENODEV; } @@ -442,13 +432,16 @@ static int ipc_stream_trigger(uint32_t header) /* XRUN is special case- TODO */ case iCS(SOF_IPC_STREAM_TRIG_XRUN): return 0; + default: + trace_ipc_error("ipc: invalid trigger cmd %d", ipc_cmd); + return -ENODEV; } /* trigger the component */ ret = pipeline_trigger(pcm_dev->cd->pipeline, pcm_dev->cd, cmd); if (ret < 0) { trace_ipc_error("ipc: comp %d trigger %d failed %d", - stream->comp_id, ipc_cmd, ret); + stream.comp_id, ipc_cmd, ret); } return ret; @@ -484,32 +477,35 @@ static int ipc_glb_stream_message(uint32_t header) static int ipc_dai_config(uint32_t header) { - struct sof_ipc_dai_config *config = _ipc->comp_data; + struct sof_ipc_dai_config config; struct dai *dai; int ret; - trace_ipc("ipc: dai %d,%d -> config ", config->type, - config->dai_index); + /* copy message with ABI safe method */ + IPC_COPY_CMD(config, _ipc->comp_data); + + trace_ipc("ipc: dai %d,%d -> config ", config.type, + config.dai_index); /* get DAI */ - dai = dai_get(config->type, config->dai_index, 0 /* existing only */); + dai = dai_get(config.type, config.dai_index, 0 /* existing only */); if (dai == NULL) { trace_ipc_error("ipc: dai %d,%d not found", - config->type, config->dai_index); + config.type, config.dai_index); return -ENODEV; } /* configure DAI */ - ret = dai_set_config(dai, config); + ret = dai_set_config(dai, &config); dai_put(dai); /* free ref immediately */ if (ret < 0) { trace_ipc_error("ipc: dai %d,%d config failed %d", - config->type, config->dai_index, ret); + config.type, config.dai_index, ret); return ret; } /* now send params to all DAI components who use that physical DAI */ - return ipc_comp_dai_config(_ipc, config); + return ipc_comp_dai_config(_ipc, &config); } static int ipc_glb_dai_message(uint32_t header) @@ -598,15 +594,18 @@ static int ipc_pm_context_restore(uint32_t header) static int ipc_pm_core_enable(uint32_t header) { - struct sof_ipc_pm_core_config *pm_core_config = _ipc->comp_data; + struct sof_ipc_pm_core_config pm_core_config; int i = 0; + /* copy message with ABI safe method */ + IPC_COPY_CMD(pm_core_config, _ipc->comp_data); + trace_ipc("ipc: pm core mask 0x%x -> enable", - pm_core_config->enable_mask); + pm_core_config.enable_mask); for (i = 0; i < PLATFORM_CORE_COUNT; i++) { if (i != PLATFORM_MASTER_CORE_ID) { - if (pm_core_config->enable_mask & (1 << i)) + if (pm_core_config.enable_mask & (1 << i)) cpu_enable_core(i); else cpu_disable_core(i); @@ -648,15 +647,11 @@ static int ipc_dma_trace_config(uint32_t header) struct dma_sg_elem_array elem_array; uint32_t ring_size; #endif - struct sof_ipc_dma_trace_params *params = _ipc->comp_data; + struct sof_ipc_dma_trace_params params; int err; - /* sanity check size */ - if (IPC_INVALID_SIZE(params)) { - trace_ipc_error("ipc:_invalid IPC size 0x%x got 0x%x", - sizeof(*params), params->hdr.size); - return -EINVAL; - } + /* copy message with ABI safe method */ + IPC_COPY_CMD(params, _ipc->comp_data); #ifdef CONFIG_HOST_PTABLE @@ -664,16 +659,16 @@ static int ipc_dma_trace_config(uint32_t header) /* use DMA to read in compressed page table ringbuffer from host */ err = ipc_get_page_descriptors(iipc->dmac, iipc->page_table, - ¶ms->buffer); + ¶ms.buffer); if (err < 0) { trace_ipc_error("ipc: trace failed to get descriptors %u", err); goto error; } /* Parse host tables */ - ring_size = params->buffer.size; + ring_size = params.buffer.size; - err = ipc_parse_page_descriptors(iipc->page_table, ¶ms->buffer, + err = ipc_parse_page_descriptors(iipc->page_table, ¶ms.buffer, &elem_array, SOF_IPC_STREAM_CAPTURE); if (err < 0) { trace_ipc_error("ipc: trace failed to parse descriptors %d", @@ -690,10 +685,10 @@ static int ipc_dma_trace_config(uint32_t header) #else /* stream tag of capture stream for DMA trace */ - _ipc->dmat->stream_tag = params->stream_tag; + _ipc->dmat->stream_tag = params.stream_tag; /* host buffer size for DMA trace */ - _ipc->dmat->host_size = params->buffer.size; + _ipc->dmat->host_size = params.buffer.size; #endif err = dma_trace_enable(_ipc->dmat); @@ -791,28 +786,31 @@ static int ipc_comp_cmd(struct comp_dev *dev, int cmd, static int ipc_comp_value(uint32_t header, uint32_t cmd) { struct ipc_comp_dev *comp_dev; - struct sof_ipc_ctrl_data *data = _ipc->comp_data; + struct sof_ipc_ctrl_data data; int ret; - trace_ipc("ipc: comp %d -> cmd %d", data->comp_id, data->cmd); + /* copy message with ABI safe method */ + IPC_COPY_CMD(data, _ipc->comp_data); + + trace_ipc("ipc: comp %d -> cmd %d", data.comp_id, data.cmd); /* get the component */ - comp_dev = ipc_get_comp(_ipc, data->comp_id); + comp_dev = ipc_get_comp(_ipc, data.comp_id); if (comp_dev == NULL){ - trace_ipc_error("ipc: comp %d not found", data->comp_id); + trace_ipc_error("ipc: comp %d not found", data.comp_id); return -ENODEV; } /* get component values */ - ret = ipc_comp_cmd(comp_dev->cd, cmd, data); + ret = ipc_comp_cmd(comp_dev->cd, cmd, &data); if (ret < 0) { - trace_ipc_error("ipc: comp %d cmd %u failed 5d", data->comp_id, - data->cmd, ret); + trace_ipc_error("ipc: comp %d cmd %u failed %d", data.comp_id, + data.cmd, ret); return ret; } /* write component values to the outbox */ - mailbox_hostbox_write(0, data, data->rhdr.hdr.size); + mailbox_hostbox_write(0, &data, data.rhdr.hdr.size); return 1; } @@ -837,18 +835,21 @@ static int ipc_glb_comp_message(uint32_t header) static int ipc_glb_tplg_comp_new(uint32_t header) { - struct sof_ipc_comp *comp = _ipc->comp_data; + struct sof_ipc_comp comp; struct sof_ipc_comp_reply reply; int ret; - trace_ipc("ipc: pipe %d comp %d -> new (type %d)", comp->pipeline_id, - comp->id, comp->type); + /* copy message with ABI safe method */ + IPC_COPY_CMD(comp, _ipc->comp_data); + + trace_ipc("ipc: pipe %d comp %d -> new (type %d)", comp.pipeline_id, + comp.id, comp.type); /* register component */ - ret = ipc_comp_new(_ipc, comp); + ret = ipc_comp_new(_ipc, &comp); if (ret < 0) { trace_ipc_error("ipc: pipe %d comp %d creation failed %d", - comp->pipeline_id, comp->id, ret); + comp.pipeline_id, comp.id, ret); return ret; } @@ -863,19 +864,22 @@ static int ipc_glb_tplg_comp_new(uint32_t header) static int ipc_glb_tplg_buffer_new(uint32_t header) { - struct sof_ipc_buffer *ipc_buffer = _ipc->comp_data; + struct sof_ipc_buffer ipc_buffer; struct sof_ipc_comp_reply reply; int ret; + /* copy message with ABI safe method */ + IPC_COPY_CMD(ipc_buffer, _ipc->comp_data); + trace_ipc("ipc: pipe %d buffer %d -> new (0x%x bytes)", - ipc_buffer->comp.pipeline_id, ipc_buffer->comp.id, - ipc_buffer->size); + ipc_buffer.comp.pipeline_id, ipc_buffer.comp.id, + ipc_buffer.size); - ret = ipc_buffer_new(_ipc, ipc_buffer); + ret = ipc_buffer_new(_ipc, &ipc_buffer); if (ret < 0) { trace_ipc_error("ipc: pipe %d buffer %d creation failed %d", - ipc_buffer->comp.pipeline_id, - ipc_buffer->comp.id, ret); + ipc_buffer.comp.pipeline_id, + ipc_buffer.comp.id, ret); return ret; } @@ -890,23 +894,19 @@ static int ipc_glb_tplg_buffer_new(uint32_t header) static int ipc_glb_tplg_pipe_new(uint32_t header) { - struct sof_ipc_pipe_new *ipc_pipeline = _ipc->comp_data; + struct sof_ipc_pipe_new ipc_pipeline; struct sof_ipc_comp_reply reply; int ret; - trace_ipc("ipc: pipe %d -> new", ipc_pipeline->pipeline_id); + /* copy message with ABI safe method */ + IPC_COPY_CMD(ipc_pipeline, _ipc->comp_data); - /* sanity check size */ - if (IPC_INVALID_SIZE(ipc_pipeline)) { - trace_ipc_error("ipc:_invalid IPC size 0x%x got 0x%x", - sizeof(*ipc_pipeline), ipc_pipeline->hdr.size); - return -EINVAL; - } + trace_ipc("ipc: pipe %d -> new", ipc_pipeline.pipeline_id); - ret = ipc_pipeline_new(_ipc, ipc_pipeline); + ret = ipc_pipeline_new(_ipc, &ipc_pipeline); if (ret < 0) { trace_ipc_error("ipc: pipe %d creation failed %d", - ipc_pipeline->pipeline_id, ret); + ipc_pipeline.pipeline_id, ret); return ret; } @@ -921,51 +921,46 @@ static int ipc_glb_tplg_pipe_new(uint32_t header) static int ipc_glb_tplg_pipe_complete(uint32_t header) { - struct sof_ipc_pipe_ready *ipc_pipeline = _ipc->comp_data; + struct sof_ipc_pipe_ready ipc_pipeline; + + /* copy message with ABI safe method */ + IPC_COPY_CMD(ipc_pipeline, _ipc->comp_data); - trace_ipc("ipc: pipe %d -> complete", ipc_pipeline->comp_id); + trace_ipc("ipc: pipe %d -> complete", ipc_pipeline.comp_id); - return ipc_pipeline_complete(_ipc, ipc_pipeline->comp_id); + return ipc_pipeline_complete(_ipc, ipc_pipeline.comp_id); } static int ipc_glb_tplg_comp_connect(uint32_t header) { - struct sof_ipc_pipe_comp_connect *connect = _ipc->comp_data; + struct sof_ipc_pipe_comp_connect connect; - trace_ipc("ipc: comp sink %d, source %d -> connect", - connect->sink_id, connect->source_id); + /* copy message with ABI safe method */ + IPC_COPY_CMD(connect, _ipc->comp_data); - /* sanity check size */ - if (IPC_INVALID_SIZE(connect)) { - trace_ipc_error("ipc:_invalid IPC size 0x%x got 0x%x", - sizeof(*connect), connect->hdr.size); - return -EINVAL; - } + trace_ipc("ipc: comp sink %d, source %d -> connect", + connect.sink_id, connect.source_id); - return ipc_comp_connect(_ipc, connect); + return ipc_comp_connect(_ipc, &connect); } static int ipc_glb_tplg_free(uint32_t header, int (*free_func)(struct ipc *ipc, uint32_t id)) { - struct sof_ipc_free *ipc_free = _ipc->comp_data; + struct sof_ipc_free ipc_free; int ret; - trace_ipc("ipc: comp %d -> free", ipc_free->id); + /* copy message with ABI safe method */ + IPC_COPY_CMD(ipc_free, _ipc->comp_data); - /* sanity check size */ - if (IPC_INVALID_SIZE(ipc_free)) { - trace_ipc_error("ipc:_invalid IPC size 0x%x got 0x%x", - sizeof(*ipc_free), ipc_free->hdr.size); - return -EINVAL; - } + trace_ipc("ipc: comp %d -> free", ipc_free.id); /* free the object */ - ret = free_func(_ipc, ipc_free->id); + ret = free_func(_ipc, ipc_free.id); if (ret < 0) { trace_ipc_error("ipc: comp %d free failed %d", - ipc_free->id, ret); + ipc_free.id, ret); } return ret; @@ -1004,7 +999,7 @@ static int ipc_glb_tplg_message(uint32_t header) int ipc_cmd(void) { - struct sof_ipc_hdr *hdr; + struct sof_ipc_cmd_hdr *hdr; uint32_t type; hdr = mailbox_validate(); diff --git a/src/platform/apollolake/include/platform/memory.h b/src/platform/apollolake/include/platform/memory.h index fee970cb63ae..2ca42ef6b623 100644 --- a/src/platform/apollolake/include/platform/memory.h +++ b/src/platform/apollolake/include/platform/memory.h @@ -143,11 +143,11 @@ #define HEAP_SYS_RT_X_COUNT1024 4 /* Heap section sizes for module pool */ -#define HEAP_RT_COUNT64 192 -#define HEAP_RT_COUNT128 32 -#define HEAP_RT_COUNT256 80 -#define HEAP_RT_COUNT512 16 -#define HEAP_RT_COUNT1024 4 +#define HEAP_RT_COUNT64 128 +#define HEAP_RT_COUNT128 64 +#define HEAP_RT_COUNT256 128 +#define HEAP_RT_COUNT512 64 +#define HEAP_RT_COUNT1024 8 #define L2_VECTOR_SIZE 0x1000 @@ -192,7 +192,7 @@ #define LOG_ENTRY_ELF_SIZE 0x2000000 /* - * The HP SRAM Region Apololake is organised like this :- + * The HP SRAM Region Apollolake is organised like this :- * +--------------------------------------------------------------------------+ * | Offset | Region | Size | * +---------------------+----------------+-----------------------------------+ @@ -276,7 +276,7 @@ #define SOF_TEXT_START (HP_SRAM_VECBASE_RESET + 0x400) #define SOF_TEXT_BASE (SOF_TEXT_START) -#define SOF_TEXT_SIZE (0x1c000 - 0x400) +#define SOF_TEXT_SIZE (0x1d000 - 0x400) /* initialized data */ #define SOF_DATA_START (SOF_TEXT_BASE + SOF_TEXT_SIZE) @@ -327,8 +327,8 @@ #define HEAP_RT_LP_COUNT16 256 #define HEAP_RT_LP_COUNT32 128 #define HEAP_RT_LP_COUNT64 64 -#define HEAP_RT_LP_COUNT128 32 -#define HEAP_RT_LP_COUNT256 16 +#define HEAP_RT_LP_COUNT128 64 +#define HEAP_RT_LP_COUNT256 96 #define HEAP_RT_LP_COUNT512 8 #define HEAP_RT_LP_COUNT1024 4 diff --git a/src/platform/baytrail/include/platform/memory.h b/src/platform/baytrail/include/platform/memory.h index cab66a6b445b..8334809137c3 100644 --- a/src/platform/baytrail/include/platform/memory.h +++ b/src/platform/baytrail/include/platform/memory.h @@ -104,12 +104,12 @@ /* Heap section sizes for module pool */ #define HEAP_RT_COUNT8 0 -#define HEAP_RT_COUNT16 64 -#define HEAP_RT_COUNT32 64 -#define HEAP_RT_COUNT64 64 -#define HEAP_RT_COUNT128 64 -#define HEAP_RT_COUNT256 64 -#define HEAP_RT_COUNT512 8 +#define HEAP_RT_COUNT16 48 +#define HEAP_RT_COUNT32 48 +#define HEAP_RT_COUNT64 32 +#define HEAP_RT_COUNT128 32 +#define HEAP_RT_COUNT256 32 +#define HEAP_RT_COUNT512 4 #define HEAP_RT_COUNT1024 4 /* Heap section sizes for system runtime heap */ diff --git a/src/platform/baytrail/platform.c b/src/platform/baytrail/platform.c index e6cbf64fccc2..96ff8e48972a 100644 --- a/src/platform/baytrail/platform.c +++ b/src/platform/baytrail/platform.c @@ -65,6 +65,7 @@ static const struct sof_ipc_fw_ready ready }, /* dspbox is for DSP initiated IPC, hostbox is for host initiated IPC */ .version = { + .hdr.size = sizeof(struct sof_ipc_fw_version), .micro = SOF_MICRO, .minor = SOF_MINOR, .major = SOF_MAJOR, diff --git a/src/platform/cannonlake/include/platform/memory.h b/src/platform/cannonlake/include/platform/memory.h index 6799c2fe76fb..fb329152190c 100644 --- a/src/platform/cannonlake/include/platform/memory.h +++ b/src/platform/cannonlake/include/platform/memory.h @@ -189,9 +189,9 @@ #define HEAP_SYS_RT_X_COUNT1024 4 /* Heap section sizes for module pool */ -#define HEAP_RT_COUNT64 192 -#define HEAP_RT_COUNT128 32 -#define HEAP_RT_COUNT256 80 +#define HEAP_RT_COUNT64 128 +#define HEAP_RT_COUNT128 64 +#define HEAP_RT_COUNT256 128 #define HEAP_RT_COUNT512 16 #define HEAP_RT_COUNT1024 4 @@ -253,7 +253,7 @@ /* initialized data */ #define SOF_DATA_START (SOF_TEXT_BASE + SOF_TEXT_SIZE) #if defined CONFIG_DMIC -#define SOF_DATA_SIZE 0x1b000 +#define SOF_DATA_SIZE 0x1d000 #else #define SOF_DATA_SIZE 0x19000 #endif @@ -361,8 +361,8 @@ #define HEAP_RT_LP_COUNT16 256 #define HEAP_RT_LP_COUNT32 128 #define HEAP_RT_LP_COUNT64 64 -#define HEAP_RT_LP_COUNT128 32 -#define HEAP_RT_LP_COUNT256 16 +#define HEAP_RT_LP_COUNT128 64 +#define HEAP_RT_LP_COUNT256 96 #define HEAP_RT_LP_COUNT512 8 #define HEAP_RT_LP_COUNT1024 4 diff --git a/src/platform/haswell/include/platform/memory.h b/src/platform/haswell/include/platform/memory.h index 90f5c1e7c46f..4a45b838d353 100644 --- a/src/platform/haswell/include/platform/memory.h +++ b/src/platform/haswell/include/platform/memory.h @@ -102,8 +102,8 @@ #define HEAP_RT_COUNT16 192 #define HEAP_RT_COUNT32 128 #define HEAP_RT_COUNT64 64 -#define HEAP_RT_COUNT128 32 -#define HEAP_RT_COUNT256 16 +#define HEAP_RT_COUNT128 64 +#define HEAP_RT_COUNT256 64 #define HEAP_RT_COUNT512 8 #define HEAP_RT_COUNT1024 4 diff --git a/src/platform/haswell/platform.c b/src/platform/haswell/platform.c index 8c9060fd30db..1ebc8604041f 100644 --- a/src/platform/haswell/platform.c +++ b/src/platform/haswell/platform.c @@ -64,6 +64,7 @@ static const struct sof_ipc_fw_ready ready }, /* dspbox is for DSP initiated IPC, hostbox is for host initiated IPC */ .version = { + .hdr.size = sizeof(struct sof_ipc_fw_version), .micro = SOF_MICRO, .minor = SOF_MINOR, .major = SOF_MAJOR, diff --git a/src/platform/icelake/include/platform/memory.h b/src/platform/icelake/include/platform/memory.h index fe326a65817b..39c2fcc71389 100644 --- a/src/platform/icelake/include/platform/memory.h +++ b/src/platform/icelake/include/platform/memory.h @@ -189,11 +189,11 @@ #define HEAP_SYS_RT_X_COUNT1024 4 /* Heap section sizes for module pool */ -#define HEAP_RT_COUNT64 192 -#define HEAP_RT_COUNT128 32 -#define HEAP_RT_COUNT256 80 -#define HEAP_RT_COUNT512 16 -#define HEAP_RT_COUNT1024 4 +#define HEAP_RT_COUNT64 128 +#define HEAP_RT_COUNT128 64 +#define HEAP_RT_COUNT256 128 +#define HEAP_RT_COUNT512 64 +#define HEAP_RT_COUNT1024 8 #define L2_VECTOR_SIZE 0x1000 @@ -248,7 +248,7 @@ /* text and data share the same HP L2 SRAM on Icelake */ #define SOF_TEXT_START 0xBE040400 #define SOF_TEXT_BASE (SOF_TEXT_START) -#define SOF_TEXT_SIZE (0x1c000 - 0x400) +#define SOF_TEXT_SIZE (0x1d000 - 0x400) /* initialized data */ #define SOF_DATA_START (SOF_TEXT_BASE + SOF_TEXT_SIZE) @@ -357,8 +357,8 @@ #define HEAP_RT_LP_COUNT16 256 #define HEAP_RT_LP_COUNT32 128 #define HEAP_RT_LP_COUNT64 64 -#define HEAP_RT_LP_COUNT128 32 -#define HEAP_RT_LP_COUNT256 16 +#define HEAP_RT_LP_COUNT128 64 +#define HEAP_RT_LP_COUNT256 96 #define HEAP_RT_LP_COUNT512 8 #define HEAP_RT_LP_COUNT1024 4 diff --git a/src/platform/intel/cavs/memory.c b/src/platform/intel/cavs/memory.c index 7ee75fccf144..995ce1f60942 100644 --- a/src/platform/intel/cavs/memory.c +++ b/src/platform/intel/cavs/memory.c @@ -30,7 +30,6 @@ */ #include -#include /* Heap blocks for system runtime for master core */ static struct block_hdr sys_rt_0_block64[HEAP_SYS_RT_0_COUNT64]; diff --git a/src/platform/intel/cavs/platform.c b/src/platform/intel/cavs/platform.c index c8e7091a29e2..eb21912dcc8e 100644 --- a/src/platform/intel/cavs/platform.c +++ b/src/platform/intel/cavs/platform.c @@ -65,6 +65,7 @@ static const struct sof_ipc_fw_ready ready .size = sizeof(struct sof_ipc_fw_ready), }, .version = { + .hdr.size = sizeof(struct sof_ipc_fw_version), .micro = SOF_MICRO, .minor = SOF_MINOR, .major = SOF_MAJOR,