source: rtems/cpukit/rtems/src/partmp.c @ 453bb4b

5
Last change on this file since 453bb4b was 453bb4b, checked in by Sebastian Huber <sebastian.huber@…>, on 12/29/19 at 16:43:46

rtems: Fix MPCI initialization

Update #2408.

  • Property mode set to 100644
File size: 7.8 KB
Line 
1/**
2 * @file
3 *
4 * @brief Partition_MP_Send_process_packet
5 * @ingroup ClassicPartMP Partition MP Support
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2008.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/rtems/partimpl.h>
22#include <rtems/rtems/statusimpl.h>
23#include <rtems/score/statesimpl.h>
24#include <rtems/score/threadimpl.h>
25#include <rtems/score/threadqimpl.h>
26#include <rtems/sysinit.h>
27
28RTEMS_STATIC_ASSERT(
29  sizeof(Partition_MP_Packet) <= MP_PACKET_MINIMUM_PACKET_SIZE,
30  Partition_MP_Packet
31);
32
33static Partition_MP_Packet *_Partition_MP_Get_packet( void )
34{
35  return (Partition_MP_Packet *) _MPCI_Get_packet();
36}
37
38static void _Partition_MP_Initialize_packet(
39  Partition_MP_Packet            *the_packet,
40  Objects_Id                      id,
41  Partition_MP_Remote_operations  operation
42)
43{
44  the_packet->Prefix.the_class  = MP_PACKET_PARTITION;
45  the_packet->Prefix.length     = sizeof( *the_packet );
46  the_packet->Prefix.to_convert = sizeof( *the_packet );
47  the_packet->Prefix.id         = id;
48  the_packet->operation         = operation;
49}
50
51/*
52 *  _Partition_MP_Send_process_packet
53 *
54 */
55
56void _Partition_MP_Send_process_packet (
57  Partition_MP_Remote_operations  operation,
58  Objects_Id                      partition_id,
59  rtems_name                      name,
60  Objects_Id                      proxy_id
61)
62{
63  Partition_MP_Packet *the_packet;
64  uint32_t             node;
65
66  switch ( operation ) {
67
68    case PARTITION_MP_ANNOUNCE_CREATE:
69    case PARTITION_MP_ANNOUNCE_DELETE:
70    case PARTITION_MP_EXTRACT_PROXY:
71
72      the_packet = _Partition_MP_Get_packet();
73      _Partition_MP_Initialize_packet( the_packet, partition_id, operation );
74      the_packet->name     = name;
75      the_packet->proxy_id = proxy_id;
76
77      if ( operation == PARTITION_MP_EXTRACT_PROXY )
78         node = _Objects_Get_node( partition_id );
79      else
80         node = MPCI_ALL_NODES;
81
82      _MPCI_Send_process_packet( node, &the_packet->Prefix );
83      break;
84
85    case PARTITION_MP_GET_BUFFER_REQUEST:
86    case PARTITION_MP_GET_BUFFER_RESPONSE:
87    case PARTITION_MP_RETURN_BUFFER_REQUEST:
88    case PARTITION_MP_RETURN_BUFFER_RESPONSE:
89      break;
90  }
91}
92
93/*
94 *  _Partition_MP_Send_request_packet
95 *
96 */
97
98static rtems_status_code _Partition_MP_Send_request_packet (
99  Objects_Id                      partition_id,
100  void                           *buffer,
101  Partition_MP_Remote_operations  operation
102)
103{
104  Partition_MP_Packet *the_packet;
105  Status_Control       status;
106
107  if ( !_Partition_MP_Is_remote( partition_id ) ) {
108    return RTEMS_INVALID_ID;
109  }
110
111  switch ( operation ) {
112
113    case PARTITION_MP_GET_BUFFER_REQUEST:
114    case PARTITION_MP_RETURN_BUFFER_REQUEST:
115
116      the_packet = _Partition_MP_Get_packet();
117      _Partition_MP_Initialize_packet( the_packet, partition_id, operation );
118      the_packet->buffer = buffer;
119
120      status = _MPCI_Send_request_packet(
121        _Objects_Get_node( partition_id ),
122        &the_packet->Prefix,
123        STATES_READY /* Not used */
124      );
125      return _Status_Get( status );
126
127    case PARTITION_MP_ANNOUNCE_CREATE:
128    case PARTITION_MP_ANNOUNCE_DELETE:
129    case PARTITION_MP_EXTRACT_PROXY:
130    case PARTITION_MP_GET_BUFFER_RESPONSE:
131    case PARTITION_MP_RETURN_BUFFER_RESPONSE:
132      break;
133
134  }
135  /*
136   *  The following line is included to satisfy compilers which
137   *  produce warnings when a function does not end with a return.
138   */
139  return RTEMS_SUCCESSFUL;
140}
141
142rtems_status_code _Partition_MP_Get_buffer(
143  rtems_id   id,
144  void     **buffer
145)
146{
147  _Thread_Get_executing()->Wait.return_argument = buffer;
148  return _Partition_MP_Send_request_packet(
149    id,
150    buffer,
151    PARTITION_MP_GET_BUFFER_REQUEST
152  );
153}
154
155rtems_status_code _Partition_MP_Return_buffer(
156  rtems_id  id,
157  void     *buffer
158)
159{
160  return _Partition_MP_Send_request_packet(
161    id,
162    buffer,
163    PARTITION_MP_RETURN_BUFFER_REQUEST
164  );
165}
166
167/*
168 *  _Partition_MP_Send_response_packet
169 *
170 */
171
172static void _Partition_MP_Send_response_packet (
173  Partition_MP_Remote_operations  operation,
174  Objects_Id                      partition_id,
175  Thread_Control                 *the_thread
176)
177{
178  Partition_MP_Packet *the_packet;
179
180  switch ( operation ) {
181
182    case PARTITION_MP_GET_BUFFER_RESPONSE:
183    case PARTITION_MP_RETURN_BUFFER_RESPONSE:
184
185      the_packet = ( Partition_MP_Packet *) the_thread->receive_packet;
186
187/*
188 *  The packet being returned already contains the class, length, and
189 *  to_convert fields, therefore they are not set in this routine.
190 */
191      the_packet->operation = operation;
192      the_packet->Prefix.id = the_packet->Prefix.source_tid;
193
194      _MPCI_Send_response_packet(
195        _Objects_Get_node( the_packet->Prefix.source_tid ),
196        &the_packet->Prefix
197      );
198      break;
199
200    case PARTITION_MP_ANNOUNCE_CREATE:
201    case PARTITION_MP_ANNOUNCE_DELETE:
202    case PARTITION_MP_EXTRACT_PROXY:
203    case PARTITION_MP_GET_BUFFER_REQUEST:
204    case PARTITION_MP_RETURN_BUFFER_REQUEST:
205      break;
206
207  }
208}
209
210static void _Partition_MP_Process_packet(
211  rtems_packet_prefix  *the_packet_prefix
212)
213{
214  Partition_MP_Packet *the_packet;
215  Thread_Control      *the_thread;
216
217  the_packet = (Partition_MP_Packet *) the_packet_prefix;
218
219  switch ( the_packet->operation ) {
220
221    case PARTITION_MP_ANNOUNCE_CREATE:
222
223      _Objects_MP_Allocate_and_open(
224        &_Partition_Information,
225        the_packet->name,
226        the_packet->Prefix.id,
227        true
228      );
229
230      _MPCI_Return_packet( the_packet_prefix );
231      break;
232
233    case PARTITION_MP_ANNOUNCE_DELETE:
234
235      _Objects_MP_Close( &_Partition_Information, the_packet->Prefix.id );
236
237      _MPCI_Return_packet( the_packet_prefix );
238      break;
239
240    case PARTITION_MP_EXTRACT_PROXY:
241
242      the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id );
243
244      if ( ! _Thread_Is_null( the_thread ) )
245         _Thread_queue_Extract( the_thread );
246
247      _MPCI_Return_packet( the_packet_prefix );
248      break;
249
250    case PARTITION_MP_GET_BUFFER_REQUEST:
251
252      the_packet->Prefix.return_code = rtems_partition_get_buffer(
253        the_packet->Prefix.id,
254        &the_packet->buffer
255      );
256
257      _Partition_MP_Send_response_packet(
258        PARTITION_MP_GET_BUFFER_RESPONSE,
259        the_packet->Prefix.id,
260        _Thread_Executing
261      );
262      break;
263
264    case PARTITION_MP_GET_BUFFER_RESPONSE:
265
266      the_thread = _MPCI_Process_response( the_packet_prefix );
267
268      *(void **)the_thread->Wait.return_argument = the_packet->buffer;
269
270      _MPCI_Return_packet( the_packet_prefix );
271      break;
272
273    case PARTITION_MP_RETURN_BUFFER_REQUEST:
274
275      the_packet->Prefix.return_code = rtems_partition_return_buffer(
276        the_packet->Prefix.id,
277        the_packet->buffer
278      );
279
280      _Partition_MP_Send_response_packet(
281        PARTITION_MP_RETURN_BUFFER_RESPONSE,
282        the_packet->Prefix.id,
283        _Thread_Executing
284      );
285      break;
286
287    case PARTITION_MP_RETURN_BUFFER_RESPONSE:
288
289      the_thread = _MPCI_Process_response( the_packet_prefix );
290
291      _MPCI_Return_packet( the_packet_prefix );
292      break;
293
294  }
295}
296
297/*
298 *  _Partition_MP_Send_object_was_deleted
299 *
300 *  This routine is not needed by the Partition since a partition
301 *  cannot be deleted when buffers are in use.
302 *
303 */
304
305/*
306 *  _Partition_MP_Send_extract_proxy
307 *
308 */
309
310void _Partition_MP_Send_extract_proxy (
311  Thread_Control *the_thread,
312  Objects_Id      id
313)
314{
315  _Partition_MP_Send_process_packet(
316    PARTITION_MP_EXTRACT_PROXY,
317    id,
318    (rtems_name) 0,
319    the_thread->Object.id
320  );
321
322}
323
324static void _Partition_MP_Initialize( void )
325{
326  _MPCI_Register_packet_processor(
327    MP_PACKET_PARTITION,
328    _Partition_MP_Process_packet
329  );
330}
331
332RTEMS_SYSINIT_ITEM(
333  _Partition_MP_Initialize,
334  RTEMS_SYSINIT_CLASSIC_PARTITION_MP,
335  RTEMS_SYSINIT_ORDER_MIDDLE
336);
Note: See TracBrowser for help on using the repository browser.