/*
* 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 .
*/
#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 . - 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__ */