rtems_status_code rtems_port_create( rtems_name name, void *internal_start, void *external_start, uint32_t length, rtems_id *id ) { register Dual_ported_memory_Control *the_port; if ( !rtems_is_name_valid( name ) ) return RTEMS_INVALID_NAME; if ( !id ) return RTEMS_INVALID_ADDRESS; if ( !_Addresses_Is_aligned( internal_start ) || !_Addresses_Is_aligned( external_start ) ) return RTEMS_INVALID_ADDRESS; _Thread_Disable_dispatch(); /* to prevent deletion */ the_port = _Dual_ported_memory_Allocate(); if ( !the_port ) { _Thread_Enable_dispatch(); return RTEMS_TOO_MANY; } the_port->internal_base = internal_start; the_port->external_base = external_start; the_port->length = length - 1; _Objects_Open( &_Dual_ported_memory_Information, &the_port->Object, (Objects_Name) name ); *id = the_port->Object.id; _Thread_Enable_dispatch(); return RTEMS_SUCCESSFUL; }
void _Workspace_Handler_initialization( void *starting_address, size_t size ) { uint32_t *zero_out_array; uint32_t index; uint32_t memory_available; if ( !starting_address || !_Addresses_Is_aligned( starting_address ) ) _Internal_error_Occurred( INTERNAL_ERROR_CORE, TRUE, INTERNAL_ERROR_INVALID_WORKSPACE_ADDRESS ); if ( _CPU_Table.do_zero_of_workspace ) { for( zero_out_array = (uint32_t *) starting_address, index = 0 ; index < size / sizeof( uint32_t ) ; index++ ) zero_out_array[ index ] = 0; } memory_available = _Heap_Initialize( &_Workspace_Area, starting_address, size, CPU_HEAP_ALIGNMENT ); if ( memory_available == 0 ) _Internal_error_Occurred( INTERNAL_ERROR_CORE, TRUE, INTERNAL_ERROR_TOO_LITTLE_WORKSPACE ); }
rtems_status_code rtems_partition_create( rtems_name name, void *starting_address, uint32_t length, uint32_t buffer_size, rtems_attribute attribute_set, rtems_id *id ) { register Partition_Control *the_partition; if ( !rtems_is_name_valid( name ) ) return RTEMS_INVALID_NAME; if ( !starting_address ) return RTEMS_INVALID_ADDRESS; if ( !id ) return RTEMS_INVALID_ADDRESS; if ( length == 0 || buffer_size == 0 || length < buffer_size || !_Partition_Is_buffer_size_aligned( buffer_size ) ) return RTEMS_INVALID_SIZE; if ( !_Addresses_Is_aligned( starting_address ) ) return RTEMS_INVALID_ADDRESS; #if defined(RTEMS_MULTIPROCESSING) if ( _Attributes_Is_global( attribute_set ) && !_System_state_Is_multiprocessing ) return RTEMS_MP_NOT_CONFIGURED; #endif _Thread_Disable_dispatch(); /* prevents deletion */ the_partition = _Partition_Allocate(); if ( !the_partition ) { _Thread_Enable_dispatch(); return RTEMS_TOO_MANY; } #if defined(RTEMS_MULTIPROCESSING) if ( _Attributes_Is_global( attribute_set ) && !( _Objects_MP_Allocate_and_open( &_Partition_Information, name, the_partition->Object.id, false ) ) ) { _Partition_Free( the_partition ); _Thread_Enable_dispatch(); return RTEMS_TOO_MANY; } #endif the_partition->starting_address = starting_address; the_partition->length = length; the_partition->buffer_size = buffer_size; the_partition->attribute_set = attribute_set; the_partition->number_of_used_blocks = 0; _Chain_Initialize( &the_partition->Memory, starting_address, length / buffer_size, buffer_size ); _Objects_Open( &_Partition_Information, &the_partition->Object, (Objects_Name) name ); *id = the_partition->Object.id; #if defined(RTEMS_MULTIPROCESSING) if ( _Attributes_Is_global( attribute_set ) ) _Partition_MP_Send_process_packet( PARTITION_MP_ANNOUNCE_CREATE, the_partition->Object.id, name, 0 /* Not used */ ); #endif _Thread_Enable_dispatch(); return RTEMS_SUCCESSFUL; }
static bool _Heap_Walk_check_control( int source, Heap_Walk_printer printer, Heap_Control *heap ) { uintptr_t const page_size = heap->page_size; uintptr_t const min_block_size = heap->min_block_size; Heap_Block *const first_free_block = _Heap_Free_list_first( heap ); Heap_Block *const last_free_block = _Heap_Free_list_last( heap ); Heap_Block *const first_block = heap->first_block; Heap_Block *const last_block = heap->last_block; (*printer)( source, false, "page size %u, min block size %u\n" "\tarea begin 0x%08x, area end 0x%08x\n" "\tfirst block 0x%08x, last block 0x%08x\n" "\tfirst free 0x%08x, last free 0x%08x\n", page_size, min_block_size, heap->area_begin, heap->area_end, first_block, last_block, first_free_block, last_free_block ); if ( page_size == 0 ) { (*printer)( source, true, "page size is zero\n" ); return false; } if ( !_Addresses_Is_aligned( (void *) page_size ) ) { (*printer)( source, true, "page size %u not CPU aligned\n", page_size ); return false; } if ( !_Heap_Is_aligned( min_block_size, page_size ) ) { (*printer)( source, true, "min block size %u not page aligned\n", min_block_size ); return false; } if ( !_Heap_Is_aligned( _Heap_Alloc_area_of_block( first_block ), page_size ) ) { (*printer)( source, true, "first block 0x%08x: alloc area not page aligned\n", first_block ); return false; } if ( !_Heap_Is_prev_used( first_block ) ) { (*printer)( source, true, "first block: HEAP_PREV_BLOCK_USED is cleared\n" ); return false; } if ( _Heap_Is_free( last_block ) ) { (*printer)( source, true, "last block: is free\n" ); return false; } if ( _Heap_Block_at( last_block, _Heap_Block_size( last_block ) ) != first_block ) { (*printer)( source, true, "last block: next block is not the first block\n" ); return false; } return _Heap_Walk_check_free_list( source, printer, heap ); }
rtems_status_code rtems_region_create( rtems_name name, void *starting_address, uintptr_t length, uintptr_t page_size, rtems_attribute attribute_set, rtems_id *id ) { rtems_status_code return_status; Region_Control *the_region; if ( !rtems_is_name_valid( name ) ) return RTEMS_INVALID_NAME; if ( !starting_address ) return RTEMS_INVALID_ADDRESS; if ( !id ) return RTEMS_INVALID_ADDRESS; if ( !_Addresses_Is_aligned( starting_address ) ) return RTEMS_INVALID_ADDRESS; _RTEMS_Lock_allocator(); /* to prevent deletion */ the_region = _Region_Allocate(); if ( !the_region ) return_status = RTEMS_TOO_MANY; else { the_region->maximum_segment_size = _Heap_Initialize( &the_region->Memory, starting_address, length, page_size ); if ( !the_region->maximum_segment_size ) { _Region_Free( the_region ); return_status = RTEMS_INVALID_SIZE; } else { the_region->starting_address = starting_address; the_region->length = length; the_region->page_size = page_size; the_region->attribute_set = attribute_set; the_region->number_of_used_blocks = 0; _Thread_queue_Initialize( &the_region->Wait_queue, _Attributes_Is_priority( attribute_set ) ? THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO, STATES_WAITING_FOR_SEGMENT, RTEMS_TIMEOUT ); _Objects_Open( &_Region_Information, &the_region->Object, (Objects_Name) name ); *id = the_region->Object.id; return_status = RTEMS_SUCCESSFUL; } } _RTEMS_Unlock_allocator(); return return_status; }