mirror of
https://github.com/Klipper3d/klipper.git
synced 2025-07-22 06:04:03 -06:00
pru: Add initial pru_rpmsg library code for Beaglebone PRU
Add external code for using RPMsg on the Beaglebone PRU. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
969ee4c8f9
commit
ccaa25eaa5
20 changed files with 4163 additions and 3 deletions
268
lib/pru_rpmsg/include/pru_rpmsg.h
Normal file
268
lib/pru_rpmsg/include/pru_rpmsg.h
Normal file
|
@ -0,0 +1,268 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* * Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* File : pru_rpmsg.h
|
||||
*
|
||||
* Summary : An RPMsg interface for the PRU to use while communicating with
|
||||
* the ARM host.
|
||||
*
|
||||
* Notes :
|
||||
* - This file creates a structure (pru_rpmsg_transport) that contains
|
||||
* pointers to two pru_virtqueue structures. This structure is used as the
|
||||
* underlying transport layer of all RPMsg communication. Only one
|
||||
* pru_rpmsg_transport structure is needed because multiple logical channels
|
||||
* can use the same underlying transport.
|
||||
* - This pru_rpmsg interface is meant to sit on top of the pru_virtqueue
|
||||
* interface and abstract the communication even further away from the
|
||||
* underlying data structures. The goal is to make the communication as
|
||||
* simple as possible at the user application level.
|
||||
* - The logic for the PRU side is summarized below:
|
||||
*
|
||||
* PRU Slave:
|
||||
* - To receive buffer from the ARM host:
|
||||
* pru_rpmsg_receive(*transport, *src, *dst, *data, *len);
|
||||
* - To send buffer to the host:
|
||||
* pru_rpmsg_send(*transport, src, dst, *data, len);
|
||||
*/
|
||||
|
||||
#ifndef _PRU_RPMSG_H_
|
||||
#define _PRU_RPMSG_H_
|
||||
|
||||
#include <pru_virtqueue.h>
|
||||
#include <pru_virtio_ring.h>
|
||||
|
||||
/* Return value indicating no kick was sent */
|
||||
#define PRU_RPMSG_NO_KICK 1
|
||||
/* Return value indicating success */
|
||||
#define PRU_RPMSG_SUCCESS 0
|
||||
/* Return value indicating there were no available buffers */
|
||||
#define PRU_RPMSG_NO_BUF_AVAILABLE -1
|
||||
/* Return value indicating that the buffer from the virtqueue was too small */
|
||||
#define PRU_RPMSG_BUF_TOO_SMALL -2
|
||||
/* Return value indicating that an invalid head index was given */
|
||||
#define PRU_RPMSG_INVALID_HEAD -3
|
||||
/* Return value indication that an invalid event number was given */
|
||||
#define PRU_RPMSG_INVALID_EVENT -4
|
||||
|
||||
/* Max PRU-ICSS system event number for pru_mst_intr */
|
||||
#define MAX_VALID_EVENT 31
|
||||
/* Min PRU-ICSS system event number for pru_mst_intr */
|
||||
#define MIN_VALID_EVENT 16
|
||||
|
||||
/* The maximum size of the channel name and description */
|
||||
#define RPMSG_NAME_SIZE 32
|
||||
/* The maximum size of the buffer (including the header) */
|
||||
#define RPMSG_BUF_SIZE 512
|
||||
|
||||
enum pru_rpmsg_ns_flags {
|
||||
RPMSG_NS_CREATE = 0,
|
||||
RPMSG_NS_DESTROY = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* Summary : pru_rpmsg_transport is a structure that groups together the
|
||||
* two pru_virtqueues that are needed for two-way communication
|
||||
* with the ARM. This structure provides a logical wrapper for
|
||||
* the transport layer of the application. NOTE: Multiple
|
||||
* (logical) channels can be implemented on top of the same
|
||||
* transport layer.
|
||||
*
|
||||
* Variables : virtqueue0: contains the pru_virtqueue that is used for the
|
||||
* PRU->ARM communication
|
||||
* virtqueue1: contains the pru_virtqueue that is used for
|
||||
* the ARM->PRU communication
|
||||
*/
|
||||
struct pru_rpmsg_transport {
|
||||
struct pru_virtqueue virtqueue0;
|
||||
struct pru_virtqueue virtqueue1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Summary : pru_rpmsg_init initializes the underlying transport layer
|
||||
* data structures.
|
||||
*
|
||||
* Parameters : transport: a pointer to the transport data structure that
|
||||
* contains the underlying data structures to be
|
||||
* initialized
|
||||
* vring0: a pointer to vring0 which is provided by the ARM
|
||||
* core through the resource table
|
||||
* vring1: a pointer to vring1 which is provided by the ARM
|
||||
* core through the resource table
|
||||
* to_arm_event: the number of the PRU-ICSS system event
|
||||
* that is specified in the device tree that
|
||||
* is used to 'kick' the ARM core
|
||||
* from_arm_event: the number of the PRU-ICSS system event
|
||||
* that is specified in the device tree
|
||||
* that is used to receive 'kicks' from the
|
||||
* ARM core
|
||||
*
|
||||
* Description : pru_rpmsg_init takes the vrings and the events provided
|
||||
* through the resource table and initializes the transport
|
||||
* layer. Once this function call is successful RPMsg
|
||||
* channels can be created and used.
|
||||
*
|
||||
* Return Value : Returns PRU_RPMSG_INVALID_EVENT if the values provided
|
||||
* in to_arm_event or from_arm_event are outside of the
|
||||
* allowable range of events. Returns PRU_RPMSG_SUCCESS
|
||||
* if the initialization is successful.
|
||||
*/
|
||||
int16_t pru_rpmsg_init(
|
||||
struct pru_rpmsg_transport *transport,
|
||||
struct fw_rsc_vdev_vring *vring0,
|
||||
struct fw_rsc_vdev_vring *vring1,
|
||||
uint32_t to_arm_event,
|
||||
uint32_t from_arm_event
|
||||
);
|
||||
|
||||
/**
|
||||
* Summary : pru_rpmsg_receive receives a message, if available, from
|
||||
* the ARM host.
|
||||
*
|
||||
* Parameters : transport: a pointer to the transport layer from which the
|
||||
* message should be received
|
||||
* src: a pointer that is populated with the source address
|
||||
* where the message originated
|
||||
* dst: a pointer that is populated with the destination
|
||||
* address where the message was sent (can help determine
|
||||
* for which channel the message is intended on the PRU)
|
||||
* data: a pointer that is populated with a local data buffer
|
||||
* containing the message payload
|
||||
* len: a pointer that is populated with the length of the
|
||||
* message payload
|
||||
*
|
||||
* Description : pru_rpmsg_receive uses the pru_virtqueue interface to get
|
||||
* an available buffer, copy the buffer into local memory,
|
||||
* add the buffer as a used buffer to the vring, and then kick
|
||||
* the remote processor if necessary. The src, dst, data, and
|
||||
* len pointers are populated with the information about the
|
||||
* message and local buffer data if the reception is
|
||||
* successful.
|
||||
*
|
||||
* Return Value : Returns PRU_RPMSG_NO_BUF_AVAILABLE if there is currently no
|
||||
* buffer available for receive. Returns PRU_RPMSG_INVALID_HEAD
|
||||
* if the head index returned for the available buffer is
|
||||
* invalid. Returns PRU_RPMSG_SUCCESS if the message is
|
||||
* successfully received.
|
||||
*/
|
||||
int16_t pru_rpmsg_receive(
|
||||
struct pru_rpmsg_transport *transport,
|
||||
uint16_t *src,
|
||||
uint16_t *dst,
|
||||
void *data,
|
||||
uint16_t *len
|
||||
);
|
||||
|
||||
/**
|
||||
* Summary : pru_rpmsg_send sends a message to the ARM host using the
|
||||
* virtqueues in the pru_rpmsg_transport structure. The
|
||||
* source and destination address of the message are passed
|
||||
* in as parameters to the function. The data to be sent and
|
||||
* its length are passed in the data and len parameters.
|
||||
*
|
||||
* Parameters : transport: a pointer to the transport layer from which the
|
||||
* message should be sent
|
||||
* src: the source address where this message will originate
|
||||
* dst: the destination address where the message will be sent
|
||||
* data: a pointer to a local data buffer containing the
|
||||
* message payload
|
||||
* len: the length of the message payload
|
||||
*
|
||||
* Description : pru_rpmsg_send sends a message to the src parameter and
|
||||
* from the dst parameter. The transport structure defines the
|
||||
* underlying transport mechanism that will be used. The
|
||||
* data parameter is a pointer to a local buffer that should
|
||||
* be sent to the destination address and the len parameter is
|
||||
* the length of that buffer.
|
||||
*
|
||||
* Return Value : Returns PRU_RPMSG_NO_BUF_AVAILABLE if there is currently no
|
||||
* buffer available for send. Returns PRU_RPMSG_BUF_TOO_SMALL
|
||||
* if the buffer from the vring is too small to hold the
|
||||
* message payload being sent. Returns PRU_RPMSG_INVALID_HEAD
|
||||
* if the head index returned for the send buffer is invalid.
|
||||
* Returns PRU_RPMSG_SUCCESS if the message is successfully
|
||||
* sent.
|
||||
*/
|
||||
int16_t pru_rpmsg_send(
|
||||
struct pru_rpmsg_transport *transport,
|
||||
uint32_t src,
|
||||
uint32_t dst,
|
||||
void *data,
|
||||
uint16_t len
|
||||
);
|
||||
|
||||
/**
|
||||
* Summary : pru_rpmsg_channel uses an RPMsg Name Service Announcment
|
||||
* to either create or destroy an RPMsg channel depending on
|
||||
* the pru_rpmsg_ns_flags parameter that is specified.
|
||||
*
|
||||
* Parameters : flags: an enum that is used to create (RPMSG_NS_CREATE) or
|
||||
* destroy (RPMSG_NS_DESTROY) an RPMsg channel
|
||||
* transport: a pointer to the transport layer on which this
|
||||
* Name Service Announcement will be sent
|
||||
* name: the name of the channel being created or destroyed
|
||||
* ******* The name of the channel is very important as
|
||||
* ******* it is the method that Linux on the ARM uses
|
||||
* ******* to connect a PRU firmware with a corresponding
|
||||
* ******* Linux driver
|
||||
* desc: the description of the RPMsg channel being created
|
||||
* or destroyed
|
||||
* port: the local source address of the RPMsg channel. This
|
||||
* is the address where PRU messages destined for the
|
||||
* ARM host will originate
|
||||
*
|
||||
* Description : pru_rpmsg_channel sends a message letting the ARM
|
||||
* host know that a channel is to be created or destroyed. If
|
||||
* a channel is to be created then this message will notify
|
||||
* the name server on the ARM host to create a new channel. If
|
||||
* a channel is to be destroyed this will tear down this
|
||||
* logical channel of communication between the PRU and the
|
||||
* ARM host.
|
||||
*
|
||||
* Return Value : Returns PRU_RPMSG_NO_BUF_AVAILABLE if there is currently no
|
||||
* buffer available for send. Returns PRU_RPMSG_BUF_TOO_SMALL
|
||||
* if the buffer from the vring is too small to hold the
|
||||
* message payload being sent. Returns PRU_RPMSG_INVALID_HEAD
|
||||
* if the head index returned for the send buffer is invalid.
|
||||
* Returns PRU_RPMSG_SUCCESS if the message is successfully
|
||||
* sent.
|
||||
*/
|
||||
int16_t pru_rpmsg_channel(
|
||||
enum pru_rpmsg_ns_flags flags,
|
||||
struct pru_rpmsg_transport *transport,
|
||||
char *name,
|
||||
char *desc,
|
||||
int32_t port
|
||||
);
|
||||
|
||||
#endif /* _PRU_RPMSG_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue