File indexing completed on 2025-05-11 08:23:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <pthread.h>
0020
0021 #include <bsp.h>
0022 #include <bsp/raspberrypi.h>
0023 #include <bsp/mailbox.h>
0024 #include <bsp/vc.h>
0025 #include <libcpu/arm-cp15.h>
0026 #include "vc_defines.h"
0027
0028 #if ( RPI_L2_CACHE_ENABLE == 1 )
0029 #define BCM2835_VC_MEMORY_MAPPING 0x40000000
0030 #else
0031 #define BCM2835_VC_MEMORY_MAPPING 0xC0000000
0032 #endif
0033
0034 #define BCM2835_VC_MEMORY_MAPPING_MASK 0x3fffffff
0035
0036 static inline bool bcm2835_mailbox_buffer_suceeded(
0037 const bcm2835_mbox_buf_hdr *hdr )
0038 {
0039 RTEMS_COMPILER_MEMORY_BARRIER();
0040 return ( hdr->buf_code == BCM2835_MBOX_BUF_CODE_REQUEST_SUCCEED );
0041 }
0042
0043 static inline int bcm2835_mailbox_send_read_buffer( void *buf )
0044 {
0045 RTEMS_COMPILER_MEMORY_BARRIER();
0046 raspberrypi_mailbox_write( BCM2835_MBOX_CHANNEL_PROP_AVC,
0047 (unsigned int) buf + BCM2835_VC_MEMORY_MAPPING );
0048 raspberrypi_mailbox_read( BCM2835_MBOX_CHANNEL_PROP_AVC );
0049 RTEMS_COMPILER_MEMORY_BARRIER();
0050 return 0;
0051 }
0052
0053
0054
0055
0056
0057
0058 static inline void bcm2835_mailbox_buffer_flush_and_invalidate(
0059 void *buf,
0060 size_t size
0061 )
0062 {
0063 rtems_cache_flush_multiple_data_lines( buf, size );
0064 rtems_cache_invalidate_multiple_data_lines( buf, size );
0065 }
0066
0067 #define BCM2835_MBOX_VAL_LENGTH_MASK( _val_len ) \
0068 ( _val_len & ( ~BCM2835_MBOX_TAG_VAL_LEN_RESPONSE ) )
0069
0070 int bcm2835_mailbox_get_display_size(
0071 bcm2835_get_display_size_entries *_entries )
0072 {
0073 struct BCM2835_MBOX_BUF_ALIGN_ATTRIBUTE {
0074 bcm2835_mbox_buf_hdr hdr;
0075 bcm2835_mbox_tag_display_size get_display_size;
0076 uint32_t end_tag;
0077 uint32_t padding_reserve[16];
0078 } buffer;
0079 BCM2835_MBOX_INIT_BUF( &buffer );
0080 BCM2835_MBOX_INIT_TAG_NO_REQ( &buffer.get_display_size,
0081 BCM2835_MAILBOX_TAG_GET_DISPLAY_SIZE );
0082 bcm2835_mailbox_buffer_flush_and_invalidate( &buffer, sizeof( buffer ) );
0083
0084 if ( bcm2835_mailbox_send_read_buffer( &buffer ) )
0085 return -1;
0086
0087 _entries->width = buffer.get_display_size.body.resp.width;
0088 _entries->height = buffer.get_display_size.body.resp.height;
0089
0090 if ( !bcm2835_mailbox_buffer_suceeded( &buffer.hdr ) )
0091 return -2;
0092
0093 if ( !BCM2835_MBOX_TAG_REPLY_IS_SET( &buffer.get_display_size ) )
0094 return -3;
0095
0096 return 0;
0097 }
0098
0099 int bcm2835_mailbox_init_frame_buffer(
0100 bcm2835_init_frame_buffer_entries *_entries )
0101 {
0102 struct BCM2835_MBOX_BUF_ALIGN_ATTRIBUTE {
0103 bcm2835_mbox_buf_hdr hdr;
0104 bcm2835_mbox_tag_display_size set_display_size;
0105 bcm2835_mbox_tag_virtual_size set_virtual_size;
0106 bcm2835_mbox_tag_depth set_depth;
0107 bcm2835_mbox_tag_pixel_order set_pixel_order;
0108 bcm2835_mbox_tag_alpha_mode set_alpha_mode;
0109 bcm2835_mbox_tag_virtual_offset set_virtual_offset;
0110 bcm2835_mbox_tag_overscan set_overscan;
0111 bcm2835_mbox_tag_allocate_buffer allocate_buffer;
0112 bcm2835_mbox_tag_get_pitch get_pitch;
0113 uint32_t end_tag;
0114 uint32_t padding_reserve[16];
0115 } buffer;
0116 BCM2835_MBOX_INIT_BUF( &buffer );
0117 BCM2835_MBOX_INIT_TAG( &buffer.set_display_size,
0118 BCM2835_MAILBOX_TAG_SET_DISPLAY_SIZE );
0119 buffer.set_display_size.body.req.width = _entries->xres;
0120 buffer.set_display_size.body.req.height = _entries->yres;
0121 BCM2835_MBOX_INIT_TAG( &buffer.set_virtual_size,
0122 BCM2835_MAILBOX_TAG_SET_VIRTUAL_SIZE );
0123 buffer.set_virtual_size.body.req.vwidth = _entries->xvirt;
0124 buffer.set_virtual_size.body.req.vheight = _entries->yvirt;
0125 BCM2835_MBOX_INIT_TAG( &buffer.set_depth,
0126 BCM2835_MAILBOX_TAG_SET_DEPTH );
0127 buffer.set_depth.body.req.depth = _entries->depth;
0128 BCM2835_MBOX_INIT_TAG( &buffer.set_pixel_order,
0129 BCM2835_MAILBOX_TAG_SET_PIXEL_ORDER );
0130 buffer.set_pixel_order.body.req.pixel_order = _entries->pixel_order;
0131 BCM2835_MBOX_INIT_TAG( &buffer.set_alpha_mode,
0132 BCM2835_MAILBOX_TAG_SET_ALPHA_MODE );
0133 buffer.set_alpha_mode.body.req.alpha_mode = _entries->alpha_mode;
0134 BCM2835_MBOX_INIT_TAG( &buffer.set_virtual_offset,
0135 BCM2835_MAILBOX_TAG_SET_VIRTUAL_OFFSET );
0136 buffer.set_virtual_offset.body.req.voffset_x = _entries->voffset_x;
0137 buffer.set_virtual_offset.body.req.voffset_x = _entries->voffset_y;
0138 BCM2835_MBOX_INIT_TAG( &buffer.set_overscan,
0139 BCM2835_MAILBOX_TAG_SET_OVERSCAN );
0140 buffer.set_overscan.body.req.overscan_top = _entries->overscan_top;
0141 buffer.set_overscan.body.req.overscan_bottom = _entries->overscan_bottom;
0142 buffer.set_overscan.body.req.overscan_left = _entries->overscan_left;
0143 buffer.set_overscan.body.req.overscan_right = _entries->overscan_right;
0144 BCM2835_MBOX_INIT_TAG( &buffer.allocate_buffer,
0145 BCM2835_MAILBOX_TAG_ALLOCATE_BUFFER );
0146 buffer.allocate_buffer.body.req.align = 0x100;
0147 BCM2835_MBOX_INIT_TAG_NO_REQ( &buffer.get_pitch,
0148 BCM2835_MAILBOX_TAG_GET_PITCH );
0149 bcm2835_mailbox_buffer_flush_and_invalidate( &buffer, sizeof( buffer ) );
0150
0151 if ( bcm2835_mailbox_send_read_buffer( &buffer ) )
0152 return -1;
0153
0154 _entries->xres = buffer.set_display_size.body.resp.width;
0155 _entries->yres = buffer.set_display_size.body.resp.height;
0156 _entries->xvirt = buffer.set_virtual_size.body.resp.vwidth;
0157 _entries->yvirt = buffer.set_virtual_size.body.resp.vheight;
0158 _entries->depth = buffer.set_depth.body.resp.depth;
0159 _entries->base = buffer.allocate_buffer.body.resp.base;
0160 _entries->base &= BCM2835_VC_MEMORY_MAPPING_MASK;
0161 _entries->size = buffer.allocate_buffer.body.resp.size;
0162 _entries->pixel_order = buffer.set_pixel_order.body.resp.pixel_order;
0163 _entries->alpha_mode = buffer.set_alpha_mode.body.resp.alpha_mode;
0164 _entries->voffset_x = buffer.set_virtual_offset.body.resp.voffset_x;
0165 _entries->voffset_y = buffer.set_virtual_offset.body.resp.voffset_y;
0166 _entries->overscan_left = buffer.set_overscan.body.resp.overscan_left;
0167 _entries->overscan_right = buffer.set_overscan.body.resp.overscan_right;
0168 _entries->overscan_top = buffer.set_overscan.body.resp.overscan_top;
0169 _entries->overscan_bottom = buffer.set_overscan.body.resp.overscan_bottom;
0170
0171 if ( !bcm2835_mailbox_buffer_suceeded( &buffer.hdr ) )
0172 return -2;
0173
0174 if ( !BCM2835_MBOX_TAG_REPLY_IS_SET( &buffer.allocate_buffer ) )
0175 return -3;
0176
0177 if ( _entries->base < 0x100000 )
0178 return -4;
0179
0180 return 0;
0181 }
0182
0183 int bcm2835_mailbox_get_pitch( bcm2835_get_pitch_entries *_entries )
0184 {
0185 struct BCM2835_MBOX_BUF_ALIGN_ATTRIBUTE {
0186 bcm2835_mbox_buf_hdr hdr;
0187 bcm2835_mbox_tag_get_pitch get_pitch;
0188 uint32_t end_tag;
0189 uint32_t padding_reserve[16];
0190 } buffer;
0191 BCM2835_MBOX_INIT_BUF( &buffer );
0192 BCM2835_MBOX_INIT_TAG_NO_REQ( &buffer.get_pitch,
0193 BCM2835_MAILBOX_TAG_GET_PITCH );
0194 bcm2835_mailbox_buffer_flush_and_invalidate( &buffer, sizeof( buffer ) );
0195
0196 if ( bcm2835_mailbox_send_read_buffer( &buffer ) )
0197 return -1;
0198
0199 _entries->pitch = buffer.get_pitch.body.resp.pitch;
0200
0201 if ( !bcm2835_mailbox_buffer_suceeded( &buffer.hdr ) )
0202 return -2;
0203
0204 if ( !BCM2835_MBOX_TAG_REPLY_IS_SET( &buffer.get_pitch ) )
0205 return -3;
0206
0207 return 0;
0208 }
0209
0210 int bcm2835_mailbox_get_cmdline( bcm2835_get_cmdline_entries *_entries )
0211 {
0212 int i;
0213
0214 struct BCM2835_MBOX_BUF_ALIGN_ATTRIBUTE {
0215 bcm2835_mbox_buf_hdr hdr;
0216 bcm2835_mbox_tag_get_cmd_line get_cmd_line;
0217 uint32_t end_tag;
0218 uint32_t padding_reserve[16];
0219 } buffer;
0220 BCM2835_MBOX_INIT_BUF( &buffer );
0221 BCM2835_MBOX_INIT_TAG_NO_REQ( &buffer.get_cmd_line,
0222 BCM2835_MAILBOX_TAG_GET_CMD_LINE );
0223 bcm2835_mailbox_buffer_flush_and_invalidate( &buffer, sizeof( buffer ) );
0224
0225 if ( bcm2835_mailbox_send_read_buffer( &buffer ) )
0226 return -1;
0227
0228 for ( i = 0;
0229 i < BCM2835_MBOX_VAL_LENGTH_MASK( buffer.get_cmd_line.tag_hdr.val_len );
0230 ++i ) {
0231 _entries->cmdline[ i ] = buffer.get_cmd_line.body.resp.cmdline[ i ];
0232 }
0233
0234 _entries->cmdline[ i ] = '\0';
0235
0236 if ( !bcm2835_mailbox_buffer_suceeded( &buffer.hdr ) )
0237 return -2;
0238
0239 if ( !BCM2835_MBOX_TAG_REPLY_IS_SET( &buffer.get_cmd_line ) )
0240 return -3;
0241
0242 return 0;
0243 }
0244
0245 int bcm2835_mailbox_get_power_state( bcm2835_set_power_state_entries *_entries )
0246 {
0247 struct BCM2835_MBOX_BUF_ALIGN_ATTRIBUTE {
0248 bcm2835_mbox_buf_hdr hdr;
0249 bcm2835_mbox_tag_get_power_state get_power_state;
0250 uint32_t end_tag;
0251 uint32_t padding_reserve[16];
0252 } buffer;
0253 BCM2835_MBOX_INIT_BUF( &buffer );
0254 BCM2835_MBOX_INIT_TAG( &buffer.get_power_state,
0255 BCM2835_MAILBOX_TAG_GET_POWER_STATE );
0256 buffer.get_power_state.body.req.dev_id = _entries->dev_id;
0257 bcm2835_mailbox_buffer_flush_and_invalidate( &buffer, sizeof( &buffer ) );
0258
0259 if ( bcm2835_mailbox_send_read_buffer( &buffer ) )
0260 return -1;
0261
0262 _entries->dev_id = buffer.get_power_state.body.resp.dev_id;
0263 _entries->state = buffer.get_power_state.body.resp.state;
0264
0265 if ( !bcm2835_mailbox_buffer_suceeded( &buffer.hdr ) )
0266 return -2;
0267
0268 return 0;
0269 }
0270
0271 int bcm2835_mailbox_set_power_state( bcm2835_set_power_state_entries *_entries )
0272 {
0273 struct BCM2835_MBOX_BUF_ALIGN_ATTRIBUTE {
0274 bcm2835_mbox_buf_hdr hdr;
0275 bcm2835_mbox_tag_power_state set_power_state;
0276 uint32_t end_tag;
0277 uint32_t padding_reserve[16];
0278 } buffer;
0279 BCM2835_MBOX_INIT_BUF( &buffer );
0280 BCM2835_MBOX_INIT_TAG( &buffer.set_power_state,
0281 BCM2835_MAILBOX_TAG_SET_POWER_STATE );
0282 buffer.set_power_state.body.req.dev_id = _entries->dev_id;
0283 buffer.set_power_state.body.req.state = _entries->state;
0284 bcm2835_mailbox_buffer_flush_and_invalidate( &buffer, sizeof( buffer ) );
0285
0286 if ( bcm2835_mailbox_send_read_buffer( &buffer ) )
0287 return -1;
0288
0289 _entries->dev_id = buffer.set_power_state.body.resp.dev_id;
0290 _entries->state = buffer.set_power_state.body.resp.state;
0291
0292 if ( !bcm2835_mailbox_buffer_suceeded( &buffer.hdr ) )
0293 return -2;
0294
0295 return 0;
0296 }
0297
0298 int bcm2835_mailbox_get_arm_memory( bcm2835_get_arm_memory_entries *_entries )
0299 {
0300 struct BCM2835_MBOX_BUF_ALIGN_ATTRIBUTE {
0301 bcm2835_mbox_buf_hdr hdr;
0302 bcm2835_mbox_tag_get_arm_memory get_arm_memory;
0303 uint32_t end_tag;
0304 uint32_t padding_reserve[16];
0305 } buffer;
0306 BCM2835_MBOX_INIT_BUF( &buffer );
0307 BCM2835_MBOX_INIT_TAG_NO_REQ( &buffer.get_arm_memory,
0308 BCM2835_MAILBOX_TAG_GET_ARM_MEMORY );
0309 bcm2835_mailbox_buffer_flush_and_invalidate( &buffer, sizeof( buffer ) );
0310
0311 if ( bcm2835_mailbox_send_read_buffer( &buffer ) )
0312 return -1;
0313
0314 _entries->base = buffer.get_arm_memory.body.resp.base;
0315 _entries->size = buffer.get_arm_memory.body.resp.size;
0316
0317 if ( !bcm2835_mailbox_buffer_suceeded( &buffer.hdr ) )
0318 return -2;
0319
0320 if ( !BCM2835_MBOX_TAG_REPLY_IS_SET( &buffer.get_arm_memory ) )
0321 return -3;
0322
0323 return 0;
0324 }
0325
0326 int bcm2835_mailbox_get_vc_memory( bcm2835_get_vc_memory_entries *_entries )
0327 {
0328 struct BCM2835_MBOX_BUF_ALIGN_ATTRIBUTE {
0329 bcm2835_mbox_buf_hdr hdr;
0330 bcm2835_mbox_tag_get_vc_memory get_vc_memory;
0331 uint32_t end_tag;
0332 uint32_t padding_reserve[16];
0333 } buffer;
0334 BCM2835_MBOX_INIT_BUF( &buffer );
0335 BCM2835_MBOX_INIT_TAG_NO_REQ( &buffer.get_vc_memory,
0336 BCM2835_MAILBOX_TAG_GET_VC_MEMORY );
0337 bcm2835_mailbox_buffer_flush_and_invalidate( &buffer, sizeof( buffer ) );
0338
0339 if ( bcm2835_mailbox_send_read_buffer( &buffer ) )
0340 return -1;
0341
0342 _entries->base = buffer.get_vc_memory.body.resp.base;
0343 _entries->size = buffer.get_vc_memory.body.resp.size;
0344
0345 if ( !bcm2835_mailbox_buffer_suceeded( &buffer.hdr ) )
0346 return -2;
0347
0348 if ( !BCM2835_MBOX_TAG_REPLY_IS_SET( &buffer.get_vc_memory ) )
0349 return -3;
0350
0351 return 0;
0352 }
0353
0354 int bcm2835_mailbox_get_firmware_revision(
0355 bcm2835_mailbox_get_fw_rev_entries *_entries )
0356 {
0357 struct BCM2835_MBOX_BUF_ALIGN_ATTRIBUTE {
0358 bcm2835_mbox_buf_hdr hdr;
0359 bcm2835_mbox_tag_get_fw_rev get_fw_rev;
0360 uint32_t end_tag;
0361 uint32_t padding_reserve[16];
0362 } buffer;
0363 BCM2835_MBOX_INIT_BUF( &buffer );
0364 BCM2835_MBOX_INIT_TAG_NO_REQ( &buffer.get_fw_rev,
0365 BCM2835_MAILBOX_TAG_FIRMWARE_REVISION );
0366 bcm2835_mailbox_buffer_flush_and_invalidate( &buffer, sizeof( buffer ) );
0367
0368 if ( bcm2835_mailbox_send_read_buffer( &buffer ) )
0369 return -1;
0370
0371 _entries->fw_rev = buffer.get_fw_rev.body.resp.rev;
0372
0373 if ( !bcm2835_mailbox_buffer_suceeded( &buffer.hdr ) )
0374 return -2;
0375
0376 if ( !BCM2835_MBOX_TAG_REPLY_IS_SET( &buffer.get_fw_rev ) )
0377 return -3;
0378
0379 return 0;
0380 }
0381
0382 int bcm2835_mailbox_get_board_model( bcm2835_get_board_spec_entries *_entries )
0383 {
0384 struct BCM2835_MBOX_BUF_ALIGN_ATTRIBUTE {
0385 bcm2835_mbox_buf_hdr hdr;
0386 bcm2835_mbox_tag_get_board_spec get_board_model;
0387 uint32_t end_tag;
0388 uint32_t padding_reserve[16];
0389 } buffer;
0390 BCM2835_MBOX_INIT_BUF( &buffer );
0391 BCM2835_MBOX_INIT_TAG_NO_REQ( &buffer.get_board_model,
0392 BCM2835_MAILBOX_TAG_GET_BOARD_MODEL );
0393 bcm2835_mailbox_buffer_flush_and_invalidate( &buffer, sizeof( buffer ) );
0394
0395 if ( bcm2835_mailbox_send_read_buffer( &buffer ) )
0396 return -1;
0397
0398 _entries->spec = buffer.get_board_model.body.resp.spec;
0399
0400 if ( !bcm2835_mailbox_buffer_suceeded( &buffer.hdr ) )
0401 return -2;
0402
0403 if ( !BCM2835_MBOX_TAG_REPLY_IS_SET( &buffer.get_board_model ) )
0404 return -3;
0405
0406 return 0;
0407 }
0408
0409 int bcm2835_mailbox_get_board_revision(
0410 bcm2835_get_board_spec_entries *_entries )
0411 {
0412 struct BCM2835_MBOX_BUF_ALIGN_ATTRIBUTE {
0413 bcm2835_mbox_buf_hdr hdr;
0414 bcm2835_mbox_tag_get_board_spec get_board_revision;
0415 uint32_t end_tag;
0416 uint32_t padding_reserve[16];
0417 } buffer;
0418 BCM2835_MBOX_INIT_BUF( &buffer );
0419 BCM2835_MBOX_INIT_TAG_NO_REQ( &buffer.get_board_revision,
0420 BCM2835_MAILBOX_TAG_GET_BOARD_VERSION );
0421 bcm2835_mailbox_buffer_flush_and_invalidate( &buffer, sizeof( buffer ) );
0422
0423 if ( bcm2835_mailbox_send_read_buffer( &buffer ) )
0424 return -1;
0425
0426 _entries->spec = buffer.get_board_revision.body.resp.spec;
0427
0428 if ( !bcm2835_mailbox_buffer_suceeded( &buffer.hdr ) )
0429 return -2;
0430
0431 if ( !BCM2835_MBOX_TAG_REPLY_IS_SET( &buffer.get_board_revision ) )
0432 return -3;
0433
0434 return 0;
0435 }
0436
0437 int bcm2835_mailbox_get_board_serial(
0438 bcm2835_get_board_serial_entries *_entries )
0439 {
0440 struct BCM2835_MBOX_BUF_ALIGN_ATTRIBUTE {
0441 bcm2835_mbox_buf_hdr hdr;
0442 bcm2835_mbox_tag_get_board_serial get_board_serial;
0443 uint32_t end_tag;
0444 uint32_t padding_reserve[16];
0445 } buffer;
0446 BCM2835_MBOX_INIT_BUF( &buffer );
0447 BCM2835_MBOX_INIT_TAG_NO_REQ( &buffer.get_board_serial,
0448 BCM2835_MAILBOX_TAG_GET_BOARD_SERIAL );
0449 bcm2835_mailbox_buffer_flush_and_invalidate( &buffer, sizeof( &buffer ) );
0450
0451 if ( bcm2835_mailbox_send_read_buffer( &buffer ) )
0452 return -1;
0453
0454 _entries->board_serial = buffer.get_board_serial.body.resp.board_serial;
0455
0456 if ( !bcm2835_mailbox_buffer_suceeded( &buffer.hdr ) )
0457 return -2;
0458
0459 return 0;
0460 }
0461
0462 int bcm2835_mailbox_get_clock_rate(
0463 bcm2835_get_clock_rate_entries *_entries )
0464 {
0465 struct BCM2835_MBOX_BUF_ALIGN_ATTRIBUTE {
0466 bcm2835_mbox_buf_hdr hdr;
0467 bcm2835_mbox_tag_get_clock_rate get_clock_rate;
0468 uint32_t end_tag;
0469 uint32_t padding_reserve[16];
0470 } buffer;
0471 BCM2835_MBOX_INIT_BUF( &buffer );
0472 BCM2835_MBOX_INIT_TAG_NO_REQ( &buffer.get_clock_rate,
0473 BCM2835_MAILBOX_TAG_GET_CLOCK_RATE );
0474 buffer.get_clock_rate.body.req.clock_id = _entries->clock_id;
0475 bcm2835_mailbox_buffer_flush_and_invalidate( &buffer, sizeof( &buffer ) );
0476
0477 if ( bcm2835_mailbox_send_read_buffer( &buffer ) )
0478 return -1;
0479
0480 _entries->clock_id = buffer.get_clock_rate.body.resp.clock_id;
0481 _entries->clock_rate = buffer.get_clock_rate.body.resp.clock_rate;
0482
0483 if ( !bcm2835_mailbox_buffer_suceeded( &buffer.hdr ) )
0484 return -2;
0485
0486 return 0;
0487 }