diff options
author | Richard Zhu <r65037@freescale.com> | 2014-04-15 14:21:48 +0800 |
---|---|---|
committer | Nitin Garg <nitin.garg@freescale.com> | 2014-04-16 08:58:21 -0500 |
commit | 81b4f7898ff6f212d016f0ad8877a15160c7f0e1 (patch) | |
tree | f5d2d2e488e99e28aaf18580fbd13be5fdf5e6ef /include | |
parent | 86b70d1ee6ecd60d7e7b4a93deebd7de5e92739f (diff) |
ENGR00308060-1 mcc: implementation mcc common on imx6sx
- inherited mcc ver 001.002 from vibryd mqx release.
- let lwevent related codes mqx specified.
- use the offset address to do the MQX_TO_VIRT and VIRT_TO_MQX
exchanges.
- add some modification in mcc common codes, since all the shm
access should be protected by sema4.
- double check the list head, and make the recv more robust.
Acked-by: Shawn Guo
Signed-off-by: Richard Zhu <r65037@freescale.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/mcc_api.h | 47 | ||||
-rw-r--r-- | include/linux/mcc_common.h | 323 |
2 files changed, 370 insertions, 0 deletions
diff --git a/include/linux/mcc_api.h b/include/linux/mcc_api.h new file mode 100644 index 000000000000..dda45ff1d266 --- /dev/null +++ b/include/linux/mcc_api.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * Freescale IMX Linux-specific MCC implementation. + * Prototypes for MCC library API functions. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __MCC_API__ +#define __MCC_API__ + +/* + * MCC return values + */ +#define MCC_SUCCESS (0) /* function returned successfully */ +#define MCC_ERR_TIMEOUT (1) /* blocking function timed out before completing */ +#define MCC_ERR_INVAL (2) /* invalid input parameter */ +#define MCC_ERR_NOMEM (3) /* out of shared memory for message transmission */ +#define MCC_ERR_ENDPOINT (4) /* invalid endpoint / endpoint doesn't exist */ +#define MCC_ERR_SEMAPHORE (5) /* semaphore handling error */ +#define MCC_ERR_DEV (6) /* Device Open Error */ +#define MCC_ERR_INT (7) /* Interrupt Error */ +#define MCC_ERR_SQ_FULL (8) /* Signal queue is full */ +#define MCC_ERR_SQ_EMPTY (9) /* Signal queue is empty */ + +int mcc_initialize(MCC_NODE); +int mcc_destroy(MCC_NODE); +int mcc_create_endpoint(MCC_ENDPOINT*, MCC_PORT); +int mcc_destroy_endpoint(MCC_ENDPOINT*); +int mcc_send(MCC_ENDPOINT*, void*, MCC_MEM_SIZE, unsigned int); +int mcc_recv_copy(MCC_ENDPOINT*, void*, MCC_MEM_SIZE, MCC_MEM_SIZE*, unsigned int); +int mcc_recv_nocopy(MCC_ENDPOINT*, void**, MCC_MEM_SIZE*, unsigned int); +int mcc_msgs_available(MCC_ENDPOINT*, unsigned int*); +int mcc_free_buffer(void*); +int mcc_get_info(MCC_NODE, MCC_INFO_STRUCT*); + +#endif /* __MCC_API__ */ diff --git a/include/linux/mcc_common.h b/include/linux/mcc_common.h new file mode 100644 index 000000000000..4a5acc2f22c5 --- /dev/null +++ b/include/linux/mcc_common.h @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * Freescale IMX Linux-specific MCC implementation. + * MCC library header file + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __MCC_COMMON__ +#define __MCC_COMMON__ + +/* base address of shared memory */ +#define MCC_BASE_ADDRESS (0xB0000000) + +/* size (in bytes) and number of receive buffers */ +#define MCC_ATTR_NUM_RECEIVE_BUFFERS (10) +#define MCC_ATTR_BUFFER_SIZE_IN_BYTES (1024) + +/* maximum number of receive endpoints (application specific setting), + * do not assign it to a value greater than 255 ! */ +#define MCC_ATTR_MAX_RECEIVE_ENDPOINTS (5) + +/* size of the signal queue */ +#define MCC_MAX_OUTSTANDING_SIGNALS (10) + +/* number of cores */ +#define MCC_NUM_CORES (2) + +/* core number */ +#define MCC_CORE_NUMBER (_psp_core_num()) + +/* core number */ +#define MCC_NODE_NUMBER (MCC_NODE_LINUX_NUMBER) + +#define MCC_INIT_STRING "mccisrd" +#define MCC_VERSION_STRING "001.002" +#define null ((void*)0) + +/*! + * \brief MCC_BOOLEAN type. + * + * Boolean type definiton for the MCC library. + */ +typedef unsigned int MCC_BOOLEAN; + +/*! + * \brief MCC_MEM_SIZE type. + * + * Mem size type definiton for the MCC library. + */ +typedef unsigned int MCC_MEM_SIZE; + +/*! + * \brief MCC_CORE type. + * + * This unsigned integer value specifies the core number for the endpoint definition. + * + * \see MCC_NODE + * \see MCC_PORT + * \see MCC_ENDPOINT + */ +typedef unsigned int MCC_CORE; + +/*! + * \brief MCC_NODE type. + * + * This unsigned integer value specifies the node number for the endpoint definition. + * + * \see MCC_CORE + * \see MCC_PORT + * \see MCC_ENDPOINT + */ +typedef unsigned int MCC_NODE; + +/*! + * \brief MCC_PORT type. + * + * This unsigned integer value specifies the port number for the endpoint definition. + * + * \see MCC_CORE + * \see MCC_NODE + * \see MCC_ENDPOINT + */ +typedef unsigned int MCC_PORT; + +#if defined(__IAR_SYSTEMS_ICC__) +__packed +#endif +/*! + * \brief Endpoint structure. + * + * Endpoints are receive buffer queues, implemented in shared RAM, + * and are addressed by a triplet containing core, node, and port. + * + * \see MCC_BOOKEEPING_STRUCT + * \see MCC_CORE + * \see MCC_NODE + * \see MCC_PORT + */ +struct mcc_endpoint { + /*! \brief Core number - identifies the core within the processor */ + MCC_CORE core; + + /*! \brief Node number - in Linux any user process participating in MCC is a unique node; + MQX has only one node */ + MCC_NODE node; + + /*! \brief Port number - both Linux and MQX can have an arbitrary number of ports per node */ + MCC_PORT port; +#if defined(__IAR_SYSTEMS_ICC__) +}; +#else +}__attribute__((packed)); +#endif +typedef struct mcc_endpoint MCC_ENDPOINT; + +#if defined(__IAR_SYSTEMS_ICC__) +__packed +#endif +/*! + * \brief Receive buffer structure. + * + * This is the receive buffer structure used for exchanging data. + * + * \see MCC_BOOKEEPING_STRUCT + */ +struct mcc_receive_buffer { + /*! \brief Pointer to the next receive buffer */ + struct mcc_receive_buffer *next; + + /*! \brief Length of data stored in this buffer */ + MCC_MEM_SIZE data_len; + + /*! \brief Space for data storage */ + char data [MCC_ATTR_BUFFER_SIZE_IN_BYTES]; +#if defined(__IAR_SYSTEMS_ICC__) +}; +#else +}__attribute__((packed)); +#endif +typedef struct mcc_receive_buffer MCC_RECEIVE_BUFFER; + +#if defined(__IAR_SYSTEMS_ICC__) +__packed +#endif +/*! + * \brief List of buffers. + * + * Each endpoint keeps the list of received buffers. + * The list of free buffers is kept in bookkeeping data structure. + * + * \see MCC_RECEIVE_BUFFER + * \see MCC_BOOKEEPING_STRUCT + */ +struct mcc_receive_list { + /*! \brief Head of a buffers list */ + MCC_RECEIVE_BUFFER * head; + + /*! \brief Tail of a buffers list */ + MCC_RECEIVE_BUFFER * tail; +#if defined(__IAR_SYSTEMS_ICC__) +}; +#else +}__attribute__((packed)); +#endif +typedef struct mcc_receive_list MCC_RECEIVE_LIST; + +#define BUFFER_QUEUED (0) +#define BUFFER_FREED (1) +typedef unsigned int MCC_SIGNAL_TYPE; +#if defined(__IAR_SYSTEMS_ICC__) +__packed +#endif +/*! + * \brief Signals and signal queues. + * + * This is one item of a signal queue. + * + * \see MCC_SIGNAL_TYPE + * \see MCC_ENDPOINT + * \see MCC_BOOKEEPING_STRUCT + */ +struct mcc_signal { + /*! \brief Signal type - BUFFER_QUEUED or BUFFER_FREED */ + MCC_SIGNAL_TYPE type; + + /*! \brief Destination endpoint */ + MCC_ENDPOINT destination; +#if defined(__IAR_SYSTEMS_ICC__) +}; +#else +}__attribute__((packed)); +#endif +typedef struct mcc_signal MCC_SIGNAL; + +#if defined(__IAR_SYSTEMS_ICC__) +__packed +#endif +/*! + * \brief Endpoint registration table. + * + * This is used for matching each endpoint structure with it's list of received buffers. + * + * \see MCC_ENDPOINT + * \see MCC_RECEIVE_LIST + * \see MCC_BOOKEEPING_STRUCT + */ +struct mcc_endpoint_map_item { + /*! \brief Endpoint tripplet */ + MCC_ENDPOINT endpoint; + + /*! \brief List of received buffers */ + MCC_RECEIVE_LIST list; +#if defined(__IAR_SYSTEMS_ICC__) +}; +#else +}__attribute__((packed)); +#endif +typedef struct mcc_endpoint_map_item MCC_ENDPOINT_MAP_ITEM; + +#if defined(__IAR_SYSTEMS_ICC__) +__packed +#endif +/*! + * \brief MCC info structure. + * + * This is used for additional information about the MCC implementation. + * + * \see MCC_BOOKEEPING_STRUCT + */ +struct mcc_info_struct { + /*! \brief <major>.<minor> - minor is changed whenever patched, major indicates compatibility */ + char version_string[sizeof(MCC_VERSION_STRING)]; +#if defined(__IAR_SYSTEMS_ICC__) +}; +#else +}__attribute__((packed)); +#endif +typedef struct mcc_info_struct MCC_INFO_STRUCT; + +#if defined(__IAR_SYSTEMS_ICC__) +__packed +#endif +/*! + * \brief Share Memory data - Bookkeeping data and buffers. + * + * This is used for "bookkeeping data" such as endpoint and signal queue head + * and tail pointers and fixed size data buffers. The whole mcc_bookeeping_struct + * as well as each individual structure members has to be defined and stored in the + * memory as packed structure. This way, the same structure member offsets will be ensured + * on all cores/OSes/compilers. Compiler-specific pragmas for data packing have to be applied. + * + * \see MCC_RECEIVE_LIST + * \see MCC_SIGNAL + * \see MCC_ENDPOINT_MAP_ITEM + * \see MCC_RECEIVE_BUFFER + */ +struct mcc_bookeeping_struct { + /*! \brief String that indicates if this structure has been already initialized */ + char init_string[sizeof(MCC_INIT_STRING)]; + + /*! \brief String that indicates the MCC library version */ + char version_string[sizeof(MCC_VERSION_STRING)]; + + /*! \brief List of free buffers */ + MCC_RECEIVE_LIST free_list; + + /*! \brief Each core has it's own queue of received signals */ + MCC_SIGNAL signals_received[MCC_NUM_CORES][MCC_MAX_OUTSTANDING_SIGNALS]; + + /*! \brief Signal queue head for each core */ + unsigned int signal_queue_head[MCC_NUM_CORES]; + + /*! \brief Signal queue tail for each core */ + unsigned int signal_queue_tail[MCC_NUM_CORES]; + + /*! \brief Endpoint map */ + MCC_ENDPOINT_MAP_ITEM endpoint_table[MCC_ATTR_MAX_RECEIVE_ENDPOINTS]; + + /*! \brief Receive buffers, the number is defined in mcc_config.h (MCC_ATTR_NUM_RECEIVE_BUFFERS) */ + MCC_RECEIVE_BUFFER r_buffers[MCC_ATTR_NUM_RECEIVE_BUFFERS]; +#if defined(__IAR_SYSTEMS_ICC__) +}; +#else +}__attribute__((packed)); +#endif +typedef struct mcc_bookeeping_struct MCC_BOOKEEPING_STRUCT; + +extern MCC_BOOKEEPING_STRUCT * bookeeping_data; + +/* + * Common Macros + */ +#define MCC_RESERVED_PORT_NUMBER (0) +#define MCC_MAX_RECEIVE_ENDPOINTS_COUNT (255) + +MCC_RECEIVE_LIST * mcc_get_endpoint_list(MCC_ENDPOINT endpoint); +MCC_RECEIVE_BUFFER * mcc_dequeue_buffer(MCC_RECEIVE_LIST *list); +void mcc_queue_buffer(MCC_RECEIVE_LIST *list, MCC_RECEIVE_BUFFER * r_buffer); +int mcc_remove_endpoint(MCC_ENDPOINT endpoint); +int mcc_register_endpoint(MCC_ENDPOINT endpoint); +int mcc_queue_signal(MCC_CORE core, MCC_SIGNAL signal); +int mcc_dequeue_signal(MCC_CORE core, MCC_SIGNAL *signal); + +#define MCC_SIGNAL_QUEUE_FULL(core) (((bookeeping_data->signal_queue_tail[core] + 1) % MCC_MAX_OUTSTANDING_SIGNALS) == bookeeping_data->signal_queue_head[core]) +#define MCC_SIGNAL_QUEUE_EMPTY(core) (bookeeping_data->signal_queue_head[core] == bookeeping_data->signal_queue_tail[core]) +#define MCC_ENDPOINTS_EQUAL(e1, e2) ((e1.core == e2.core) && (e1.node == e2.node) && (e1.port == e2.port)) + +#if (MCC_ATTR_MAX_RECEIVE_ENDPOINTS > MCC_MAX_RECEIVE_ENDPOINTS_COUNT) +#error User-defined maximum number of endpoints can not exceed the value of MCC_MAX_RECEIVE_ENDPOINTS_COUNT +#endif + +#endif /* __MCC_COMMON__ */ |