Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:22

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSImplClassicPartitionMP
0007  *
0008  * @brief This source file contains the implementation to support the Partition
0009  *   Manager in multiprocessing (MP) configurations.
0010  */
0011 
0012 /*
0013  *  COPYRIGHT (c) 1989-2008.
0014  *  On-Line Applications Research Corporation (OAR).
0015  *
0016  * Redistribution and use in source and binary forms, with or without
0017  * modification, are permitted provided that the following conditions
0018  * are met:
0019  * 1. Redistributions of source code must retain the above copyright
0020  *    notice, this list of conditions and the following disclaimer.
0021  * 2. Redistributions in binary form must reproduce the above copyright
0022  *    notice, this list of conditions and the following disclaimer in the
0023  *    documentation and/or other materials provided with the distribution.
0024  *
0025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0026  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0028  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0029  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0030  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0031  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0033  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0034  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0035  * POSSIBILITY OF SUCH DAMAGE.
0036  */
0037 
0038 #ifdef HAVE_CONFIG_H
0039 #include "config.h"
0040 #endif
0041 
0042 #include <rtems/rtems/partimpl.h>
0043 #include <rtems/rtems/statusimpl.h>
0044 #include <rtems/score/statesimpl.h>
0045 #include <rtems/score/threadimpl.h>
0046 #include <rtems/score/threadqimpl.h>
0047 #include <rtems/sysinit.h>
0048 
0049 RTEMS_STATIC_ASSERT(
0050   sizeof(Partition_MP_Packet) <= MP_PACKET_MINIMUM_PACKET_SIZE,
0051   Partition_MP_Packet
0052 );
0053 
0054 static Partition_MP_Packet *_Partition_MP_Get_packet( void )
0055 {
0056   return (Partition_MP_Packet *) _MPCI_Get_packet();
0057 }
0058 
0059 static void _Partition_MP_Initialize_packet(
0060   Partition_MP_Packet            *the_packet,
0061   Objects_Id                      id,
0062   Partition_MP_Remote_operations  operation
0063 )
0064 {
0065   the_packet->Prefix.the_class  = MP_PACKET_PARTITION;
0066   the_packet->Prefix.length     = sizeof( *the_packet );
0067   the_packet->Prefix.to_convert = sizeof( *the_packet );
0068   the_packet->Prefix.id         = id;
0069   the_packet->operation         = operation;
0070 }
0071 
0072 /*
0073  *  _Partition_MP_Send_process_packet
0074  *
0075  */
0076 
0077 void _Partition_MP_Send_process_packet (
0078   Partition_MP_Remote_operations  operation,
0079   Objects_Id                      partition_id,
0080   rtems_name                      name,
0081   Objects_Id                      proxy_id
0082 )
0083 {
0084   Partition_MP_Packet *the_packet;
0085   uint32_t             node;
0086 
0087   switch ( operation ) {
0088 
0089     case PARTITION_MP_ANNOUNCE_CREATE:
0090     case PARTITION_MP_ANNOUNCE_DELETE:
0091     case PARTITION_MP_EXTRACT_PROXY:
0092 
0093       the_packet = _Partition_MP_Get_packet();
0094       _Partition_MP_Initialize_packet( the_packet, partition_id, operation );
0095       the_packet->name     = name;
0096       the_packet->proxy_id = proxy_id;
0097 
0098       if ( operation == PARTITION_MP_EXTRACT_PROXY )
0099          node = _Objects_Get_node( partition_id );
0100       else
0101          node = MPCI_ALL_NODES;
0102 
0103       _MPCI_Send_process_packet( node, &the_packet->Prefix );
0104       break;
0105 
0106     case PARTITION_MP_GET_BUFFER_REQUEST:
0107     case PARTITION_MP_GET_BUFFER_RESPONSE:
0108     case PARTITION_MP_RETURN_BUFFER_REQUEST:
0109     case PARTITION_MP_RETURN_BUFFER_RESPONSE:
0110       break;
0111   }
0112 }
0113 
0114 /*
0115  *  _Partition_MP_Send_request_packet
0116  *
0117  */
0118 
0119 static rtems_status_code _Partition_MP_Send_request_packet (
0120   Objects_Id                      partition_id,
0121   void                           *buffer,
0122   Partition_MP_Remote_operations  operation
0123 )
0124 {
0125   Partition_MP_Packet *the_packet;
0126   Status_Control       status;
0127 
0128   if ( !_Partition_MP_Is_remote( partition_id ) ) {
0129     return RTEMS_INVALID_ID;
0130   }
0131 
0132   switch ( operation ) {
0133 
0134     case PARTITION_MP_GET_BUFFER_REQUEST:
0135     case PARTITION_MP_RETURN_BUFFER_REQUEST:
0136 
0137       the_packet = _Partition_MP_Get_packet();
0138       _Partition_MP_Initialize_packet( the_packet, partition_id, operation );
0139       the_packet->buffer = buffer;
0140 
0141       status = _MPCI_Send_request_packet(
0142         _Objects_Get_node( partition_id ),
0143         &the_packet->Prefix,
0144         STATES_READY /* Not used */
0145       );
0146       return _Status_Get( status );
0147 
0148     case PARTITION_MP_ANNOUNCE_CREATE:
0149     case PARTITION_MP_ANNOUNCE_DELETE:
0150     case PARTITION_MP_EXTRACT_PROXY:
0151     case PARTITION_MP_GET_BUFFER_RESPONSE:
0152     case PARTITION_MP_RETURN_BUFFER_RESPONSE:
0153       break;
0154 
0155   }
0156   /*
0157    *  The following line is included to satisfy compilers which
0158    *  produce warnings when a function does not end with a return.
0159    */
0160   return RTEMS_SUCCESSFUL;
0161 }
0162 
0163 rtems_status_code _Partition_MP_Get_buffer(
0164   rtems_id   id,
0165   void     **buffer
0166 )
0167 {
0168   _Thread_Get_executing()->Wait.return_argument = buffer;
0169   return _Partition_MP_Send_request_packet(
0170     id,
0171     buffer,
0172     PARTITION_MP_GET_BUFFER_REQUEST
0173   );
0174 }
0175 
0176 rtems_status_code _Partition_MP_Return_buffer(
0177   rtems_id  id,
0178   void     *buffer
0179 )
0180 {
0181   return _Partition_MP_Send_request_packet(
0182     id,
0183     buffer,
0184     PARTITION_MP_RETURN_BUFFER_REQUEST
0185   );
0186 }
0187 
0188 /*
0189  *  _Partition_MP_Send_response_packet
0190  *
0191  */
0192 
0193 static void _Partition_MP_Send_response_packet (
0194   Partition_MP_Remote_operations  operation,
0195   Objects_Id                      partition_id,
0196   Thread_Control                 *the_thread
0197 )
0198 {
0199   Partition_MP_Packet *the_packet;
0200 
0201   switch ( operation ) {
0202 
0203     case PARTITION_MP_GET_BUFFER_RESPONSE:
0204     case PARTITION_MP_RETURN_BUFFER_RESPONSE:
0205 
0206       the_packet = ( Partition_MP_Packet *) the_thread->receive_packet;
0207 
0208 /*
0209  *  The packet being returned already contains the class, length, and
0210  *  to_convert fields, therefore they are not set in this routine.
0211  */
0212       the_packet->operation = operation;
0213       the_packet->Prefix.id = the_packet->Prefix.source_tid;
0214 
0215       _MPCI_Send_response_packet(
0216         _Objects_Get_node( the_packet->Prefix.source_tid ),
0217         &the_packet->Prefix
0218       );
0219       break;
0220 
0221     case PARTITION_MP_ANNOUNCE_CREATE:
0222     case PARTITION_MP_ANNOUNCE_DELETE:
0223     case PARTITION_MP_EXTRACT_PROXY:
0224     case PARTITION_MP_GET_BUFFER_REQUEST:
0225     case PARTITION_MP_RETURN_BUFFER_REQUEST:
0226       break;
0227 
0228   }
0229 }
0230 
0231 static void _Partition_MP_Process_packet(
0232   rtems_packet_prefix  *the_packet_prefix
0233 )
0234 {
0235   Partition_MP_Packet *the_packet;
0236   Thread_Control      *the_thread;
0237 
0238   the_packet = (Partition_MP_Packet *) the_packet_prefix;
0239 
0240   switch ( the_packet->operation ) {
0241 
0242     case PARTITION_MP_ANNOUNCE_CREATE:
0243 
0244       _Objects_MP_Allocate_and_open(
0245         &_Partition_Information,
0246         the_packet->name,
0247         the_packet->Prefix.id,
0248         true
0249       );
0250 
0251       _MPCI_Return_packet( the_packet_prefix );
0252       break;
0253 
0254     case PARTITION_MP_ANNOUNCE_DELETE:
0255 
0256       _Objects_MP_Close( &_Partition_Information, the_packet->Prefix.id );
0257 
0258       _MPCI_Return_packet( the_packet_prefix );
0259       break;
0260 
0261     case PARTITION_MP_EXTRACT_PROXY:
0262 
0263       the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id );
0264 
0265       if ( the_thread != NULL ) {
0266         _Thread_queue_Extract( the_thread );
0267       }
0268 
0269       _MPCI_Return_packet( the_packet_prefix );
0270       break;
0271 
0272     case PARTITION_MP_GET_BUFFER_REQUEST:
0273 
0274       the_packet->Prefix.return_code = rtems_partition_get_buffer(
0275         the_packet->Prefix.id,
0276         &the_packet->buffer
0277       );
0278 
0279       _Partition_MP_Send_response_packet(
0280         PARTITION_MP_GET_BUFFER_RESPONSE,
0281         the_packet->Prefix.id,
0282         _Thread_Executing
0283       );
0284       break;
0285 
0286     case PARTITION_MP_GET_BUFFER_RESPONSE:
0287 
0288       the_thread = _MPCI_Process_response( the_packet_prefix );
0289 
0290       *(void **)the_thread->Wait.return_argument = the_packet->buffer;
0291 
0292       _MPCI_Return_packet( the_packet_prefix );
0293       break;
0294 
0295     case PARTITION_MP_RETURN_BUFFER_REQUEST:
0296 
0297       the_packet->Prefix.return_code = rtems_partition_return_buffer(
0298         the_packet->Prefix.id,
0299         the_packet->buffer
0300       );
0301 
0302       _Partition_MP_Send_response_packet(
0303         PARTITION_MP_RETURN_BUFFER_RESPONSE,
0304         the_packet->Prefix.id,
0305         _Thread_Executing
0306       );
0307       break;
0308 
0309     case PARTITION_MP_RETURN_BUFFER_RESPONSE:
0310 
0311       the_thread = _MPCI_Process_response( the_packet_prefix );
0312 
0313       _MPCI_Return_packet( the_packet_prefix );
0314       break;
0315 
0316   }
0317 }
0318 
0319 /*
0320  *  _Partition_MP_Send_object_was_deleted
0321  *
0322  *  This routine is not needed by the Partition since a partition
0323  *  cannot be deleted when buffers are in use.
0324  *
0325  */
0326 
0327 /*
0328  *  _Partition_MP_Send_extract_proxy
0329  *
0330  */
0331 
0332 void _Partition_MP_Send_extract_proxy (
0333   Thread_Control *the_thread,
0334   Objects_Id      id
0335 )
0336 {
0337   _Partition_MP_Send_process_packet(
0338     PARTITION_MP_EXTRACT_PROXY,
0339     id,
0340     (rtems_name) 0,
0341     the_thread->Object.id
0342   );
0343 
0344 }
0345 
0346 static void _Partition_MP_Initialize( void )
0347 {
0348   _MPCI_Register_packet_processor(
0349     MP_PACKET_PARTITION,
0350     _Partition_MP_Process_packet
0351   );
0352 }
0353 
0354 RTEMS_SYSINIT_ITEM(
0355   _Partition_MP_Initialize,
0356   RTEMS_SYSINIT_CLASSIC_PARTITION_MP,
0357   RTEMS_SYSINIT_ORDER_MIDDLE
0358 );