File indexing completed on 2025-05-11 08:24:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 #ifdef HAVE_CONFIG_H
0052 #include "config.h"
0053 #endif
0054
0055 #include <rtems.h>
0056
0057 #include <rtems/test.h>
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 typedef enum {
0068 RtemsPartReqReturnBuffer_Pre_Id_NoObj,
0069 RtemsPartReqReturnBuffer_Pre_Id_Part,
0070 RtemsPartReqReturnBuffer_Pre_Id_NA
0071 } RtemsPartReqReturnBuffer_Pre_Id;
0072
0073 typedef enum {
0074 RtemsPartReqReturnBuffer_Pre_Buf_Valid,
0075 RtemsPartReqReturnBuffer_Pre_Buf_BadAlign,
0076 RtemsPartReqReturnBuffer_Pre_Buf_BelowArea,
0077 RtemsPartReqReturnBuffer_Pre_Buf_AboveArea,
0078 RtemsPartReqReturnBuffer_Pre_Buf_NA
0079 } RtemsPartReqReturnBuffer_Pre_Buf;
0080
0081 typedef enum {
0082 RtemsPartReqReturnBuffer_Post_Status_Ok,
0083 RtemsPartReqReturnBuffer_Post_Status_InvId,
0084 RtemsPartReqReturnBuffer_Post_Status_InvAddr,
0085 RtemsPartReqReturnBuffer_Post_Status_NA
0086 } RtemsPartReqReturnBuffer_Post_Status;
0087
0088 typedef enum {
0089 RtemsPartReqReturnBuffer_Post_Buf_Free,
0090 RtemsPartReqReturnBuffer_Post_Buf_InUse,
0091 RtemsPartReqReturnBuffer_Post_Buf_NA
0092 } RtemsPartReqReturnBuffer_Post_Buf;
0093
0094 typedef struct {
0095 uint8_t Skip : 1;
0096 uint8_t Pre_Id_NA : 1;
0097 uint8_t Pre_Buf_NA : 1;
0098 uint8_t Post_Status : 2;
0099 uint8_t Post_Buf : 2;
0100 } RtemsPartReqReturnBuffer_Entry;
0101
0102
0103
0104
0105 typedef struct {
0106 rtems_status_code status;
0107
0108 rtems_id id;
0109
0110 rtems_id id_value;
0111
0112 void *buffer;
0113
0114 void *buffer_in_use;
0115
0116 struct {
0117
0118
0119
0120 size_t pcs[ 2 ];
0121
0122
0123
0124
0125 bool in_action_loop;
0126
0127
0128
0129
0130 size_t index;
0131
0132
0133
0134
0135 RtemsPartReqReturnBuffer_Entry entry;
0136
0137
0138
0139
0140
0141 bool skip;
0142 } Map;
0143 } RtemsPartReqReturnBuffer_Context;
0144
0145 static RtemsPartReqReturnBuffer_Context
0146 RtemsPartReqReturnBuffer_Instance;
0147
0148 static const char * const RtemsPartReqReturnBuffer_PreDesc_Id[] = {
0149 "NoObj",
0150 "Part",
0151 "NA"
0152 };
0153
0154 static const char * const RtemsPartReqReturnBuffer_PreDesc_Buf[] = {
0155 "Valid",
0156 "BadAlign",
0157 "BelowArea",
0158 "AboveArea",
0159 "NA"
0160 };
0161
0162 static const char * const * const RtemsPartReqReturnBuffer_PreDesc[] = {
0163 RtemsPartReqReturnBuffer_PreDesc_Id,
0164 RtemsPartReqReturnBuffer_PreDesc_Buf,
0165 NULL
0166 };
0167
0168 #define BUFFER_COUNT 1
0169
0170 #define BUFFER_SIZE ( 2 * sizeof( void * ) )
0171
0172 static RTEMS_ALIGNED( RTEMS_PARTITION_ALIGNMENT ) uint8_t
0173 buffers[ BUFFER_COUNT ][ BUFFER_SIZE ];
0174
0175 static void RtemsPartReqReturnBuffer_Pre_Id_Prepare(
0176 RtemsPartReqReturnBuffer_Context *ctx,
0177 RtemsPartReqReturnBuffer_Pre_Id state
0178 )
0179 {
0180 switch ( state ) {
0181 case RtemsPartReqReturnBuffer_Pre_Id_NoObj: {
0182
0183
0184
0185 ctx->id = 0xffffffff;
0186 break;
0187 }
0188
0189 case RtemsPartReqReturnBuffer_Pre_Id_Part: {
0190
0191
0192
0193 ctx->id = ctx->id_value;
0194 break;
0195 }
0196
0197 case RtemsPartReqReturnBuffer_Pre_Id_NA:
0198 break;
0199 }
0200 }
0201
0202 static void RtemsPartReqReturnBuffer_Pre_Buf_Prepare(
0203 RtemsPartReqReturnBuffer_Context *ctx,
0204 RtemsPartReqReturnBuffer_Pre_Buf state
0205 )
0206 {
0207 switch ( state ) {
0208 case RtemsPartReqReturnBuffer_Pre_Buf_Valid: {
0209
0210
0211
0212
0213 ctx->buffer = ctx->buffer_in_use;
0214 break;
0215 }
0216
0217 case RtemsPartReqReturnBuffer_Pre_Buf_BadAlign: {
0218
0219
0220
0221
0222 ctx->buffer = (void *) ( (uintptr_t) ctx->buffer_in_use + 1 );
0223 break;
0224 }
0225
0226 case RtemsPartReqReturnBuffer_Pre_Buf_BelowArea: {
0227
0228
0229
0230
0231 ctx->buffer = (void *) ( (uintptr_t) buffers - 1 );
0232 break;
0233 }
0234
0235 case RtemsPartReqReturnBuffer_Pre_Buf_AboveArea: {
0236
0237
0238
0239
0240 ctx->buffer = (void *) ( (uintptr_t) buffers + sizeof( buffers ) );
0241 break;
0242 }
0243
0244 case RtemsPartReqReturnBuffer_Pre_Buf_NA:
0245 break;
0246 }
0247 }
0248
0249 static void RtemsPartReqReturnBuffer_Post_Status_Check(
0250 RtemsPartReqReturnBuffer_Context *ctx,
0251 RtemsPartReqReturnBuffer_Post_Status state
0252 )
0253 {
0254 switch ( state ) {
0255 case RtemsPartReqReturnBuffer_Post_Status_Ok: {
0256
0257
0258
0259
0260 T_rsc_success( ctx->status );
0261 break;
0262 }
0263
0264 case RtemsPartReqReturnBuffer_Post_Status_InvId: {
0265
0266
0267
0268
0269 T_rsc( ctx->status, RTEMS_INVALID_ID );
0270 break;
0271 }
0272
0273 case RtemsPartReqReturnBuffer_Post_Status_InvAddr: {
0274
0275
0276
0277
0278 T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
0279 break;
0280 }
0281
0282 case RtemsPartReqReturnBuffer_Post_Status_NA:
0283 break;
0284 }
0285 }
0286
0287 static void RtemsPartReqReturnBuffer_Post_Buf_Check(
0288 RtemsPartReqReturnBuffer_Context *ctx,
0289 RtemsPartReqReturnBuffer_Post_Buf state
0290 )
0291 {
0292 rtems_status_code sc;
0293 void *no_buffer;
0294
0295 switch ( state ) {
0296 case RtemsPartReqReturnBuffer_Post_Buf_Free: {
0297
0298
0299
0300
0301 sc = rtems_partition_get_buffer( ctx->id_value, &ctx->buffer_in_use );
0302 T_rsc_success( sc );
0303 T_eq_ptr( ctx->buffer_in_use, buffers );
0304 break;
0305 }
0306
0307 case RtemsPartReqReturnBuffer_Post_Buf_InUse: {
0308
0309
0310
0311
0312 sc = rtems_partition_get_buffer( ctx->id_value, &no_buffer );
0313 T_rsc( sc, RTEMS_UNSATISFIED );
0314 break;
0315 }
0316
0317 case RtemsPartReqReturnBuffer_Post_Buf_NA:
0318 break;
0319 }
0320 }
0321
0322 static void RtemsPartReqReturnBuffer_Setup(
0323 RtemsPartReqReturnBuffer_Context *ctx
0324 )
0325 {
0326 rtems_status_code sc;
0327
0328 ctx->buffer_in_use = NULL;
0329 ctx->id_value = 0;
0330
0331 sc = rtems_partition_create(
0332 rtems_build_name( 'N', 'A', 'M', 'E' ),
0333 buffers,
0334 sizeof( buffers ),
0335 sizeof( buffers[ 0 ] ),
0336 RTEMS_DEFAULT_ATTRIBUTES,
0337 &ctx->id_value
0338 );
0339 T_assert_rsc_success( sc );
0340
0341 sc = rtems_partition_get_buffer( ctx->id_value, &ctx->buffer_in_use );
0342 T_assert_rsc_success( sc );
0343 T_assert_eq_ptr( ctx->buffer_in_use, buffers );
0344 }
0345
0346 static void RtemsPartReqReturnBuffer_Setup_Wrap( void *arg )
0347 {
0348 RtemsPartReqReturnBuffer_Context *ctx;
0349
0350 ctx = arg;
0351 ctx->Map.in_action_loop = false;
0352 RtemsPartReqReturnBuffer_Setup( ctx );
0353 }
0354
0355 static void RtemsPartReqReturnBuffer_Teardown(
0356 RtemsPartReqReturnBuffer_Context *ctx
0357 )
0358 {
0359 rtems_status_code sc;
0360
0361 if ( ctx->buffer_in_use != NULL ) {
0362 sc = rtems_partition_return_buffer( ctx->id_value, ctx->buffer_in_use );
0363 T_rsc_success( sc );
0364 }
0365
0366 if ( ctx->id_value != 0 ) {
0367 sc = rtems_partition_delete( ctx->id_value );
0368 T_rsc_success( sc );
0369 }
0370 }
0371
0372 static void RtemsPartReqReturnBuffer_Teardown_Wrap( void *arg )
0373 {
0374 RtemsPartReqReturnBuffer_Context *ctx;
0375
0376 ctx = arg;
0377 ctx->Map.in_action_loop = false;
0378 RtemsPartReqReturnBuffer_Teardown( ctx );
0379 }
0380
0381 static void RtemsPartReqReturnBuffer_Action(
0382 RtemsPartReqReturnBuffer_Context *ctx
0383 )
0384 {
0385 ctx->status = rtems_partition_return_buffer( ctx->id, ctx->buffer );
0386 }
0387
0388 static const RtemsPartReqReturnBuffer_Entry
0389 RtemsPartReqReturnBuffer_Entries[] = {
0390 { 0, 0, 0, RtemsPartReqReturnBuffer_Post_Status_InvId,
0391 RtemsPartReqReturnBuffer_Post_Buf_InUse },
0392 { 0, 0, 0, RtemsPartReqReturnBuffer_Post_Status_InvAddr,
0393 RtemsPartReqReturnBuffer_Post_Buf_InUse },
0394 { 0, 0, 0, RtemsPartReqReturnBuffer_Post_Status_Ok,
0395 RtemsPartReqReturnBuffer_Post_Buf_Free }
0396 };
0397
0398 static const uint8_t
0399 RtemsPartReqReturnBuffer_Map[] = {
0400 0, 0, 0, 0, 2, 1, 1, 1
0401 };
0402
0403 static size_t RtemsPartReqReturnBuffer_Scope( void *arg, char *buf, size_t n )
0404 {
0405 RtemsPartReqReturnBuffer_Context *ctx;
0406
0407 ctx = arg;
0408
0409 if ( ctx->Map.in_action_loop ) {
0410 return T_get_scope(
0411 RtemsPartReqReturnBuffer_PreDesc,
0412 buf,
0413 n,
0414 ctx->Map.pcs
0415 );
0416 }
0417
0418 return 0;
0419 }
0420
0421 static T_fixture RtemsPartReqReturnBuffer_Fixture = {
0422 .setup = RtemsPartReqReturnBuffer_Setup_Wrap,
0423 .stop = NULL,
0424 .teardown = RtemsPartReqReturnBuffer_Teardown_Wrap,
0425 .scope = RtemsPartReqReturnBuffer_Scope,
0426 .initial_context = &RtemsPartReqReturnBuffer_Instance
0427 };
0428
0429 static inline RtemsPartReqReturnBuffer_Entry RtemsPartReqReturnBuffer_PopEntry(
0430 RtemsPartReqReturnBuffer_Context *ctx
0431 )
0432 {
0433 size_t index;
0434
0435 index = ctx->Map.index;
0436 ctx->Map.index = index + 1;
0437 return RtemsPartReqReturnBuffer_Entries[
0438 RtemsPartReqReturnBuffer_Map[ index ]
0439 ];
0440 }
0441
0442 static void RtemsPartReqReturnBuffer_TestVariant(
0443 RtemsPartReqReturnBuffer_Context *ctx
0444 )
0445 {
0446 RtemsPartReqReturnBuffer_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0447 RtemsPartReqReturnBuffer_Pre_Buf_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0448 RtemsPartReqReturnBuffer_Action( ctx );
0449 RtemsPartReqReturnBuffer_Post_Status_Check(
0450 ctx,
0451 ctx->Map.entry.Post_Status
0452 );
0453 RtemsPartReqReturnBuffer_Post_Buf_Check( ctx, ctx->Map.entry.Post_Buf );
0454 }
0455
0456
0457
0458
0459 T_TEST_CASE_FIXTURE(
0460 RtemsPartReqReturnBuffer,
0461 &RtemsPartReqReturnBuffer_Fixture
0462 )
0463 {
0464 RtemsPartReqReturnBuffer_Context *ctx;
0465
0466 ctx = T_fixture_context();
0467 ctx->Map.in_action_loop = true;
0468 ctx->Map.index = 0;
0469
0470 for (
0471 ctx->Map.pcs[ 0 ] = RtemsPartReqReturnBuffer_Pre_Id_NoObj;
0472 ctx->Map.pcs[ 0 ] < RtemsPartReqReturnBuffer_Pre_Id_NA;
0473 ++ctx->Map.pcs[ 0 ]
0474 ) {
0475 for (
0476 ctx->Map.pcs[ 1 ] = RtemsPartReqReturnBuffer_Pre_Buf_Valid;
0477 ctx->Map.pcs[ 1 ] < RtemsPartReqReturnBuffer_Pre_Buf_NA;
0478 ++ctx->Map.pcs[ 1 ]
0479 ) {
0480 ctx->Map.entry = RtemsPartReqReturnBuffer_PopEntry( ctx );
0481 RtemsPartReqReturnBuffer_TestVariant( ctx );
0482 }
0483 }
0484 }
0485
0486