/** * @file * * @ingroup mpc83xx * * @brief Source for BSP startup code. */ /* * Copyright (c) 2008 * Embedded Brains GmbH * Obere Lagerstr. 30 * D-82178 Puchheim * Germany * rtems@embedded-brains.de * * The license and distribution terms for this file may be found in the file * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE. * * $Id$ */ #include #include #include #include #include #include #include #include #ifdef HAS_UBOOT /* * We want this in the data section, because the startup code clears the BSS * section after the initialization of the board info. */ bd_t mpc83xx_uboot_board_info = { .bi_baudrate = 123 }; /* Size in words */ const size_t mpc83xx_uboot_board_info_size = (sizeof( bd_t) + 3) / 4; #endif /* HAS_UBOOT */ /* Configuration parameters for console driver, ... */ unsigned int BSP_bus_frequency; /* Configuration parameters for clock driver, ... */ uint32_t bsp_clicks_per_usec; static char *BSP_heap_start, *BSP_heap_end; /* * Use the shared implementations of the following routines. * Look in rtems/c/src/lib/libbsp/shared/bsplibc.c. */ extern void cpu_init( void); void BSP_panic( char *s) { rtems_interrupt_level level; rtems_interrupt_disable( level); printk( "%s PANIC %s\n", _RTEMS_version, s); while (1) { /* Do nothing */ } } void _BSP_Fatal_error( unsigned n) { rtems_interrupt_level level; rtems_interrupt_disable( level); printk( "%s PANIC ERROR %u\n", _RTEMS_version, n); while (1) { /* Do nothing */ } } void bsp_pretasking_hook( void) { /* Initialize libc including the heap */ bsp_libc_init( BSP_heap_start, BSP_heap_end - BSP_heap_start, 0); } void bsp_calc_mem_layout() { size_t workspace_size = rtems_configuration_get_work_space_size(); /* We clear the workspace here */ Configuration.do_zero_of_workspace = 0; /* TODO mpc83xx_zero_4( bsp_workspace_start, workspace_size); */ mpc83xx_zero_4( bsp_interrupt_stack_start, bsp_ram_end - bsp_interrupt_stack_start); Configuration.work_space_start = bsp_workspace_start; BSP_heap_start = (char *) Configuration.work_space_start + workspace_size; #ifdef HAS_UBOOT BSP_heap_end = mpc83xx_uboot_board_info.bi_memstart + mpc83xx_uboot_board_info.bi_memsize; #else /* HAS_UBOOT */ BSP_heap_end = bsp_ram_end; #endif /* HAS_UBOOT */ } void bsp_start( void) { ppc_cpu_id_t myCpu; ppc_cpu_revision_t myCpuRevision; uint32_t interrupt_stack_start = (uint32_t) bsp_interrupt_stack_start; uint32_t interrupt_stack_size = (uint32_t) bsp_interrupt_stack_size; /* * Get CPU identification dynamically. Note that the get_ppc_cpu_type() function * store the result in global variables so that it can be used latter... */ myCpu = get_ppc_cpu_type(); myCpuRevision = get_ppc_cpu_revision(); /* Determine heap and workspace placement */ bsp_calc_mem_layout(); cpu_init(); /* * This is evaluated during runtime, so it should be ok to set it * before we initialize the drivers. */ /* Initialize some device driver parameters */ #ifdef HAS_UBOOT BSP_bus_frequency = mpc83xx_uboot_board_info.bi_busfreq; #else /* HAS_UBOOT */ BSP_bus_frequency = BSP_CLKIN_FRQ * BSP_SYSPLL_MF / BSP_SYSPLL_CKID; #endif /* HAS_UBOOT */ bsp_clicks_per_usec = BSP_bus_frequency / 4000000; /* * Enable instruction and data caches. Do not force writethrough mode. */ #if INSTRUCTION_CACHE_ENABLE rtems_cache_enable_instruction(); #endif #if DATA_CACHE_ENABLE rtems_cache_enable_data(); #endif /* Initialize exception handler */ ppc_exc_initialize( PPC_INTERRUPT_DISABLE_MASK_DEFAULT, interrupt_stack_start, interrupt_stack_size ); /* Initalize interrupt support */ if (bsp_interrupt_initialize() != RTEMS_SUCCESSFUL) { BSP_panic("Cannot intitialize interrupt support\n"); } #ifdef SHOW_MORE_INIT_SETTINGS printk("Exit from bspstart\n"); #endif } /** * @brief Idle thread body. * * Replaces the one in c/src/exec/score/src/threadidlebody.c * The MSR[POW] bit is set to put the CPU into the low power mode * defined in HID0. HID0 is set during starup in start.S. */ Thread _Thread_Idle_body( uint32_t ignored) { while (1) { asm volatile ( "mfmsr 3;" "oris 3, 3, 4;" "sync;" "mtmsr 3;" "isync;" "ori 3, 3, 0;" "ori 3, 3, 0" ); } return NULL; }