static void start_thread_if_necessary(uint32_t cpu_index_self) { #if QORIQ_THREAD_COUNT > 1 uint32_t i; for (i = 1; i < QORIQ_THREAD_COUNT; ++i) { uint32_t cpu_index_next = cpu_index_self + i; if ( is_started_by_u_boot(cpu_index_self) && cpu_index_next < rtems_configuration_get_maximum_processors() && _SMP_Should_start_processor(cpu_index_next) ) { /* Thread Initial Next Instruction Address (INIA) */ PPC_SET_THREAD_MGMT_REGISTER(321, (uint32_t) _start_thread); /* Thread Initial Machine State (IMSR) */ PPC_SET_THREAD_MGMT_REGISTER(289, QORIQ_INITIAL_MSR); /* Thread Enable Set (TENS) */ PPC_SET_SPECIAL_PURPOSE_REGISTER(438, 1U << i); } } #endif }
void _ISR_Handler_initialization( void ) { _ISR_Nest_level = 0; #if (CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE) _ISR_Vector_table = _Workspace_Allocate_or_fatal_error( sizeof(ISR_Handler_entry) * ISR_NUMBER_OF_VECTORS ); _CPU_Initialize_vectors(); #endif #if ( CPU_ALLOCATE_INTERRUPT_STACK == TRUE ) { size_t stack_size = rtems_configuration_get_interrupt_stack_size(); uint32_t max_cpus = rtems_configuration_get_maximum_processors(); uint32_t cpu; if ( !_Stack_Is_enough( stack_size ) ) _Terminate( INTERNAL_ERROR_CORE, true, INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL ); for ( cpu = 0 ; cpu < max_cpus; ++cpu ) { Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu ); void *low = _Workspace_Allocate_or_fatal_error( stack_size ); void *high = _Addresses_Add_offset( low, stack_size ); #if (CPU_STACK_ALIGNMENT != 0) high = _Addresses_Align_down( high, CPU_STACK_ALIGNMENT ); #endif per_cpu->interrupt_stack_low = low; per_cpu->interrupt_stack_high = high; /* * Interrupt stack might have to be aligned and/or setup in a specific * way. Do not use the local low or high variables here since * _CPU_Interrupt_stack_setup() is a nasty macro that might want to play * with the real memory locations. */ #if defined(_CPU_Interrupt_stack_setup) _CPU_Interrupt_stack_setup( per_cpu->interrupt_stack_low, per_cpu->interrupt_stack_high ); #endif } } #endif #if ( CPU_HAS_HARDWARE_INTERRUPT_STACK == TRUE ) _CPU_Install_interrupt_stack(); #endif }
uint32_t _CPU_SMP_Initialize(void) { uint32_t cpu_count = 1; if (rtems_configuration_get_maximum_processors() > 0) { cpu_count = discover_processors(); } start_thread_if_necessary(0); return cpu_count; }
uint32_t _CPU_SMP_Initialize( void ) { if ( !leon3_data_cache_snooping_enabled() ) bsp_fatal( LEON3_FATAL_INVALID_CACHE_CONFIG_MAIN_PROCESSOR ); if ( rtems_configuration_get_maximum_processors() > 1 ) { LEON_Unmask_interrupt(LEON3_mp_irq); set_vector(bsp_inter_processor_interrupt, LEON_TRAP_TYPE(LEON3_mp_irq), 1); } return leon3_get_cpu_count(LEON3_IrqCtrl_Regs); }
void _SMP_Start_multitasking_on_secondary_processor( void ) { Per_CPU_Control *self_cpu = _Per_CPU_Get(); uint32_t cpu_index_self = _Per_CPU_Get_index( self_cpu ); if ( cpu_index_self >= rtems_configuration_get_maximum_processors() ) { _SMP_Fatal( SMP_FATAL_MULTITASKING_START_ON_INVALID_PROCESSOR ); } if ( !_SMP_Should_start_processor( cpu_index_self ) ) { _SMP_Fatal( SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR ); } _Per_CPU_State_change( self_cpu, PER_CPU_STATE_READY_TO_START_MULTITASKING ); _Thread_Start_multitasking(); }
void _SMP_Handler_initialize(void) { uint32_t max_cpus = rtems_configuration_get_maximum_processors(); uint32_t cpu; /* * Initialize per cpu pointer table */ _Per_CPU_Information_p[0] = _Per_CPU_Get_by_index( 0 ); for ( cpu = 1 ; cpu < max_cpus; ++cpu ) { Per_CPU_Control *p = _Per_CPU_Get_by_index( cpu ); _Per_CPU_Information_p[cpu] = p; #if CPU_ALLOCATE_INTERRUPT_STACK == TRUE { size_t size = rtems_configuration_get_interrupt_stack_size(); uintptr_t ptr; p->interrupt_stack_low = _Workspace_Allocate_or_fatal_error( size ); ptr = (uintptr_t) _Addresses_Add_offset( p->interrupt_stack_low, size ); ptr &= ~(CPU_STACK_ALIGNMENT - 1); p->interrupt_stack_high = (void *)ptr; } #endif } /* * Discover and initialize the secondary cores in an SMP system. */ max_cpus = bsp_smp_initialize( max_cpus ); _SMP_Processor_count = max_cpus; for ( cpu = 1 ; cpu < max_cpus; ++cpu ) { const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu ); _Per_CPU_Wait_for_state( per_cpu, PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING ); } }
static rtems_status_code test_driver_init( rtems_device_major_number major, rtems_device_minor_number minor, void *arg ) { uint32_t self = rtems_get_current_processor(); uint32_t cpu_count = rtems_get_processor_count(); uint32_t cpu; rtems_test_begink(); assert(rtems_configuration_get_maximum_processors() == MAX_CPUS); main_cpu = self; for (cpu = 0; cpu < MAX_CPUS; ++cpu) { const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu ); Per_CPU_State state = per_cpu->state; if (cpu == self) { assert(state == PER_CPU_STATE_INITIAL); } else if (cpu < cpu_count) { assert( state == PER_CPU_STATE_INITIAL || state == PER_CPU_STATE_READY_TO_START_MULTITASKING ); } else { assert(state == PER_CPU_STATE_INITIAL); } } if (cpu_count > 1) { rtems_fatal(RTEMS_FATAL_SOURCE_APPLICATION, 0xdeadbeef); } else { rtems_test_endk(); exit(0); } return RTEMS_SUCCESSFUL; }
void _CPU_SMP_Finalize_initialization(uint32_t cpu_count) { if (rtems_configuration_get_maximum_processors() > 0) { mmu_config_undo(); } if (cpu_count > 1) { rtems_status_code sc; sc = rtems_interrupt_handler_install( QORIQ_IRQ_IPI_0, "IPI", RTEMS_INTERRUPT_UNIQUE, bsp_inter_processor_interrupt, NULL ); if (sc != RTEMS_SUCCESSFUL) { bsp_fatal(QORIQ_FATAL_SMP_IPI_HANDLER_INSTALL); } } }
uint32_t _CPU_SMP_Initialize(void) { if (rtems_configuration_get_maximum_processors() > 0) { qoriq_mmu_context mmu_context; qoriq_mmu_context_init(&mmu_context); qoriq_mmu_add( &mmu_context, BOOT_BEGIN, BOOT_LAST, 0, 0, FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW, 0 ); qoriq_mmu_partition(&mmu_context, TLB_COUNT); qoriq_mmu_write_to_tlb1(&mmu_context, TLB_BEGIN); } start_thread_if_necessary(0); return QORIQ_CPU_COUNT; }
void _SMP_Handler_initialize( void ) { uint32_t cpu_max = rtems_configuration_get_maximum_processors(); uint32_t cpu_count; uint32_t cpu_index; for ( cpu_index = 0 ; cpu_index < cpu_max; ++cpu_index ) { Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index ); _ISR_lock_Initialize( &cpu->Watchdog.Lock, "Watchdog" ); _SMP_ticket_lock_Initialize( &cpu->Lock ); _SMP_lock_Stats_initialize( &cpu->Lock_stats, "Per-CPU" ); _Chain_Initialize_empty( &cpu->Threads_in_need_for_help ); } /* * Discover and initialize the secondary cores in an SMP system. */ cpu_count = _CPU_SMP_Initialize(); cpu_count = cpu_count < cpu_max ? cpu_count : cpu_max; _SMP_Processor_count = cpu_count; for ( cpu_index = cpu_count ; cpu_index < cpu_max; ++cpu_index ) { const Scheduler_Assignment *assignment; assignment = _Scheduler_Get_initial_assignment( cpu_index ); if ( _Scheduler_Is_mandatory_processor( assignment ) ) { _SMP_Fatal( SMP_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT ); } } _SMP_Start_processors( cpu_count ); _CPU_SMP_Finalize_initialization( cpu_count ); }
void *POSIX_Init( void *argument ) { long sc; TEST_BEGIN(); puts( "sysconf -- bad configuration parameter - negative" ); sc = sysconf( -1 ); fatal_posix_service_status_errno( sc, EINVAL, "bad conf name" ); #if UNUSED /* FIXME: This test doesn't make sense. * On targets with sizeof(int) < sizeof(long), compilation will fail, * On targets with sizeof(int) == sizeof(long) the call is valid. */ puts( "sysconf -- bad configuration parameter - too large" ); sc = sysconf( LONG_MAX ); fatal_posix_service_status_errno( sc, EINVAL, "bad conf name" ); #endif sc = sysconf( _SC_CLK_TCK ); printf( "sysconf - _SC_CLK_TCK=%ld\n", sc ); if ( sc == -1 ) rtems_test_exit(0); sc = sysconf( _SC_OPEN_MAX ); printf( "sysconf - _SC_OPEN_MAX=%ld\n", sc ); if ( sc == -1 ) rtems_test_exit(0); sc = sysconf( _SC_GETPW_R_SIZE_MAX ); printf( "sysconf - _SC_GETPW_R_SIZE_MAX=%ld\n", sc ); if ( sc == -1 ) rtems_test_exit(0); sc = sysconf( _SC_PAGESIZE ); printf( "sysconf - _SC_PAGESIZE=%ld\n", sc ); if ( sc == -1 ) rtems_test_exit(0); sc = getpagesize(); printf( "getpagesize = %ld\n", sc ); if ( sc == -1 ) rtems_test_exit(0); sc = sysconf( INT_MAX ); printf( "sysconf - bad parameter = %ld errno=%s\n", sc, strerror(errno) ); if ( (sc != -1) || (errno != EINVAL) ) rtems_test_exit(0); rtems_test_assert( sysconf( _SC_NPROCESSORS_CONF ) == (long) rtems_configuration_get_maximum_processors() ); rtems_test_assert( sysconf( _SC_NPROCESSORS_ONLN ) == (long) rtems_get_processor_count() ); #if defined(__sparc__) /* Solaris _SC_STACK_PROT - 515 */ sc = sysconf( _SC_PAGESIZE ); printf( "sysconf - (SPARC only) _SC_STACK_PROT=%ld\n", sc ); if ( sc == -1 ) rtems_test_exit(0); #endif TEST_END(); rtems_test_exit( 0 ); return NULL; /* just so the compiler thinks we returned something */ }