Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:57

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSBSPsPowerPCQorIQInterCom
0007  *
0008  * @brief Inter-Processor Communication implementation.
0009  */
0010 
0011 /*
0012  * Copyright (c) 2011 embedded brains GmbH & Co. KG
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #include <assert.h>
0037 
0038 #include <libcpu/powerpc-utility.h>
0039 
0040 #include <bsp/intercom.h>
0041 
0042 #ifdef RTEMS_MULTIPROCESSING
0043 
0044 typedef struct {
0045     intercom_packet *head;
0046     intercom_packet *tail;
0047 } mpic_fifo;
0048 
0049 static mpic_fifo fifo;
0050 
0051 static void mpci_service(intercom_packet *packet, void *arg)
0052 {
0053     rtems_interrupt_level level;
0054 
0055     rtems_interrupt_disable(level);
0056     packet->glue.next = NULL;
0057     if (fifo.head != NULL) {
0058         fifo.tail->glue.next = packet;
0059     } else {
0060         fifo.head = packet;
0061     }
0062     fifo.tail = packet;
0063     rtems_interrupt_enable(level);
0064 
0065     rtems_multiprocessing_announce();
0066 }
0067 
0068 static void mpci_init(void)
0069 {
0070     qoriq_intercom_service_install(INTERCOM_TYPE_MPCI, mpci_service, NULL);
0071 }
0072 
0073 static intercom_packet *packet_of_prefix(rtems_packet_prefix *prefix)
0074 {
0075     return (intercom_packet *) ((char *) prefix - sizeof(intercom_packet));
0076 }
0077 
0078 static rtems_packet_prefix *prefix_of_packet(intercom_packet *packet)
0079 {
0080     return (rtems_packet_prefix *) packet->data;
0081 }
0082 
0083 static void mpci_get_packet(rtems_packet_prefix **prefix_ptr)
0084 {
0085     intercom_packet *packet = qoriq_intercom_allocate_packet(
0086         INTERCOM_TYPE_MPCI,
0087         INTERCOM_SIZE_512
0088     );
0089     *prefix_ptr = prefix_of_packet(packet);
0090 }
0091 
0092 static void mpci_return_packet(rtems_packet_prefix *prefix)
0093 {
0094     intercom_packet *packet = packet_of_prefix(prefix);
0095 
0096     qoriq_intercom_free_packet(packet);
0097 }
0098 
0099 static void mpci_send_packet(uint32_t destination_node, rtems_packet_prefix *prefix)
0100 {
0101     intercom_packet *packet = packet_of_prefix(prefix);
0102     if (destination_node != MPCI_ALL_NODES) {
0103         qoriq_intercom_send_packet((int) destination_node - 1, packet);
0104     } else {
0105         uint32_t self = ppc_processor_id();
0106         int other = self == 0 ? 1 : 0;
0107 
0108         qoriq_intercom_send_packet(other, packet);
0109     }
0110 }
0111 
0112 static void mpci_receive_packet(rtems_packet_prefix **prefix_ptr)
0113 {
0114     rtems_interrupt_level level;
0115 
0116     rtems_interrupt_disable(level);
0117     intercom_packet *packet = fifo.head;
0118     if (packet != NULL) {
0119         fifo.head = packet->glue.next;
0120         *prefix_ptr = prefix_of_packet(packet);
0121     } else {
0122         *prefix_ptr = NULL;
0123     }
0124     rtems_interrupt_enable(level);
0125 }
0126 
0127 rtems_mpci_table qoriq_intercom_mpci = {
0128     .default_timeout = UINT32_MAX,
0129     .maximum_packet_size = 512,
0130     .initialization = mpci_init,
0131     .get_packet = mpci_get_packet,
0132     .return_packet = mpci_return_packet,
0133     .send_packet = mpci_send_packet,
0134     .receive_packet = mpci_receive_packet
0135 };
0136 
0137 #endif /* RTEMS_MULTIPROCESSING */