| /**************************************************************************** |
| * |
| * Copyright (c) 2014 - 2016 Samsung Electronics Co., Ltd. All rights reserved |
| * |
| ****************************************************************************/ |
| |
| /** |
| * MIF stream (Interface) |
| * |
| * Provides a one-way communication mechanism between two points. The consumer side |
| * will be notified via an interrupt when the producer side writes data to the |
| * stream, and likewise the producer will be notified when the consumer has read |
| * data from the stream. |
| * |
| * It is expected that the data sent across the stream consists of fixed-size |
| * packets, and that the underlying storage mechanism is initialised to use a packet size |
| * that is at least as large as the largest message size. If this is not the case, |
| * callers are responsible for handling reading of partial messages from the stream |
| * in multiples of the packet size. |
| */ |
| |
| #ifndef MIFSTREAM_H__ |
| #define MIFSTREAM_H__ |
| |
| /* Uses */ |
| |
| #include "cpacket_buffer.h" |
| #include "mifintrbit.h" |
| #include "scsc_logring_common.h" |
| |
| /* Public Types */ |
| |
| enum MIF_STREAM_PEER { |
| MIF_STREAM_PEER_R4, |
| MIF_STREAM_PEER_M4, |
| }; |
| |
| enum MIF_STREAM_DIRECTION { |
| MIF_STREAM_DIRECTION_IN, |
| MIF_STREAM_DIRECTION_OUT, |
| }; |
| |
| /** |
| * Defines for the MIF Stream interrupt bits |
| * |
| * MIF_STREAM_INTRBIT_TYPE_RESERVED: the bits are reserved |
| * at initialization and are assigned to GDB transport channels. |
| * It is for purpose of forcing Panics from either MX manager or GDB |
| * |
| * MIF_STREAM_INTRBIT_TYPE_ALLOC: the bits are allocated dynamically |
| * when a stream is initialized |
| */ |
| enum MIF_STREAM_INTRBIT_TYPE { |
| MIF_STREAM_INTRBIT_TYPE_RESERVED, |
| MIF_STREAM_INTRBIT_TYPE_ALLOC, |
| }; |
| |
| /* Forward Decls */ |
| |
| struct mif_stream; |
| |
| /* Public Functions */ |
| |
| /** |
| * Initialises MIF Stream state. |
| */ |
| int mif_stream_init(struct mif_stream *stream, enum scsc_mif_abs_target target, enum MIF_STREAM_DIRECTION direction, uint32_t num_packets, uint32_t packet_size, |
| struct scsc_mx *mx, enum MIF_STREAM_INTRBIT_TYPE intrbit, mifintrbit_handler tohost_irq_handler, void *data); |
| /** |
| * Initialises MIF Output Stream state. |
| */ |
| void mif_stream_release(struct mif_stream *stream); |
| /** |
| * Reads the given number of bytes from the MIF stream, copying them |
| * to the provided address. This removes the read data from the stream. |
| * |
| * Returns the number of bytes read. |
| */ |
| uint32_t mif_stream_read(struct mif_stream *stream, void *buf, uint32_t num_bytes); |
| |
| /** |
| * Returns a pointer to the next packet of data within the stream, without |
| * removing it. This can be used to processss data in place without needing to |
| * copy it first. |
| * |
| * If multiple packets are present these can be read in turn by setting the value |
| * of current_packet to the returned value from the previous call to mif_stream_peek. |
| * Each time the returned pointer will advance in the stream by mif_stream_block_size() |
| * bytes. |
| * |
| * Callers cannot assume that multiple calls to mif_stream_peek() will return |
| * consecutive addresses. |
| * |
| * mif_stream_peek_complete must be called to remove the packet(s) from the stream. |
| * |
| * Returns a pointer to the beginning of the packet to read, or NULL if there is no |
| * packet to process. |
| * |
| * Example use: |
| * // Get the first data packet |
| * void *current_packet = mif_stream_peek( buffer, NULL ); |
| * void *last_packet = NULL; |
| * while( current_packet != NULL ) |
| * { |
| * // Process data packet |
| * ... |
| * |
| * // Get the next data packet |
| * last_packet = current_packet; |
| * current_packet = mif_stream_peek( buffer, current_packet ); |
| * } |
| * |
| * // Remove all processed packets from the stream |
| * if( last_packet != NULL ) |
| * { |
| * mif_stream_peek( buffer, last_packet ); |
| * } |
| */ |
| const void *mif_stream_peek(struct mif_stream *stream, const void *current_packet); |
| |
| /** |
| * Removes all packets from the stream up to and including the given |
| * packet. |
| * |
| * This must be called after using mif_stream_peek to indicate that packet(s) |
| * can be removed from the stream. |
| */ |
| void mif_stream_peek_complete(struct mif_stream *stream, const void *packet); |
| |
| /** |
| * Writes the given number of bytes to the MIF stream. |
| * |
| * Returns true if the block was written, false if there is not enough |
| * free space in the buffer for the data. |
| */ |
| bool mif_stream_write(struct mif_stream *stream, const void *buf, uint32_t num_bytes); |
| |
| /** |
| * Writes a set of non-contiguous data blocks to the MIF stream |
| * as a contiguous set. |
| * |
| * Returns true if the blocks were written, false if there is not enough |
| * free space in the buffer for the block. |
| */ |
| bool mif_stream_write_gather(struct mif_stream *stream, const void **bufs, uint32_t *lengths, uint32_t num_bufs); |
| |
| /** |
| * Returns the size in bytes of each individual block within the stream. |
| * |
| * When reading data from the stream using mif_stream_read or mif_stream_peek |
| * this value is the amount of data |
| */ |
| uint32_t mif_stream_block_size(struct mif_stream *stream); |
| |
| /** |
| * Returns the interrupt number that will be triggered by reads from the stream |
| */ |
| uint8_t mif_stream_read_interrupt(struct mif_stream *stream); |
| |
| /** |
| * Returns the interrupt number that will be triggered by writes to the stream |
| */ |
| uint8_t mif_stream_write_interrupt(struct mif_stream *stream); |
| |
| /* |
| * Initialises the stream's part of the configuration area |
| */ |
| void mif_stream_config_serialise(struct mif_stream *stream, struct mxstreamconf *stream_conf); |
| |
| /** |
| * Log the state of this stream at the specified log_level. |
| */ |
| void mif_stream_log(const struct mif_stream *stream, enum scsc_log_level log_level); |
| |
| /** |
| * MIF Packet Stream Descriptor. |
| */ |
| struct mif_stream { |
| struct scsc_mx *mx; |
| struct cpacketbuffer buffer; |
| |
| /** MIF stream peer, R4 or M4? */ |
| enum MIF_STREAM_PEER peer; |
| |
| /** MIF interrupt bit index, one in each direction */ |
| uint8_t read_bit_idx; |
| uint8_t write_bit_idx; |
| enum MIF_STREAM_DIRECTION direction; |
| }; |
| |
| #endif /* MIFSTREAM_H__ */ |