From f2fed0c1971b020ab03ee9b00df8f760cdf6e6cd Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 19 Nov 2014 12:24:07 +0100 Subject: bsps/arm: L2C 310 add compile time checks Simplify initialization. Replace some assert() with fatal errors. --- .../lib/libbsp/arm/altera-cyclone-v/include/bsp.h | 6 +- c/src/lib/libbsp/arm/shared/arm-l2c-310/cache_.h | 149 ++++++++++----------- c/src/lib/libbsp/arm/xilinx-zynq/include/bsp.h | 4 +- c/src/lib/libbsp/shared/include/fatal.h | 6 +- 4 files changed, 80 insertions(+), 85 deletions(-) diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/include/bsp.h b/c/src/lib/libbsp/arm/altera-cyclone-v/include/bsp.h index b96066fe5a..3ab9d551aa 100644 --- a/c/src/lib/libbsp/arm/altera-cyclone-v/include/bsp.h +++ b/c/src/lib/libbsp/arm/altera-cyclone-v/include/bsp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -39,7 +39,9 @@ extern "C" { #define BSP_ARM_GIC_DIST_BASE ( BSP_ARM_A9MPCORE_SCU_BASE + 0x00001000 ) -#define BSP_ARM_L2C_310_BASE 0xFFFEF000U +#define BSP_ARM_L2C_310_BASE 0xfffef000 + +#define BSP_ARM_L2C_310_ID 0x410000c9 /* Forward declaration */ struct rtems_bsdnet_ifconfig; diff --git a/c/src/lib/libbsp/arm/shared/arm-l2c-310/cache_.h b/c/src/lib/libbsp/arm/shared/arm-l2c-310/cache_.h index 61e3064c86..94c23229ba 100644 --- a/c/src/lib/libbsp/arm/shared/arm-l2c-310/cache_.h +++ b/c/src/lib/libbsp/arm/shared/arm-l2c-310/cache_.h @@ -58,6 +58,7 @@ #include #include +#include #include #include #include @@ -117,6 +118,7 @@ typedef struct { #define CACHE_L2C_310_L2CC_ID_PART_MASK ( 0xf << 6 ) #define CACHE_L2C_310_L2CC_ID_PART_L210 ( 1 << 6 ) #define CACHE_L2C_310_L2CC_ID_PART_L310 ( 3 << 6 ) +#define CACHE_L2C_310_L2CC_ID_IMPL_MASK ( 0xff << 24 ) /** @brief Cache type */ uint32_t cache_type; /** @brief 1 if data banking implemented, 0 if not */ @@ -1100,11 +1102,8 @@ cache_l2c_310_get_cache_size( void ) return size; } -static void cache_l2c_310_unlock( void ) +static void cache_l2c_310_unlock( volatile L2CC *l2cc ) { - volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE; - - l2cc->d_lockdown_0 = 0; l2cc->i_lockdown_0 = 0; l2cc->d_lockdown_1 = 0; @@ -1123,95 +1122,89 @@ static void cache_l2c_310_unlock( void ) l2cc->i_lockdown_7 = 0; } +static void cache_l2c_310_wait_for_background_ops( volatile L2CC *l2cc ) +{ + while ( l2cc->inv_way & CACHE_l2C_310_WAY_MASK ) ; + + while ( l2cc->clean_way & CACHE_l2C_310_WAY_MASK ) ; + + while ( l2cc->clean_inv_way & CACHE_l2C_310_WAY_MASK ) ; +} + +/* We support only the L2C-310 revisions r3p2 and r3p3 cache controller */ + +#if (BSP_ARM_L2C_310_ID & CACHE_L2C_310_L2CC_ID_PART_MASK) \ + != CACHE_L2C_310_L2CC_ID_PART_L310 +#error "invalid L2-310 cache controller part number" +#endif + +#if ((BSP_ARM_L2C_310_ID & CACHE_L2C_310_L2CC_ID_RTL_MASK) != 0x8) \ + && ((BSP_ARM_L2C_310_ID & CACHE_L2C_310_L2CC_ID_RTL_MASK) != 0x9) +#error "invalid L2-310 cache controller RTL revision" +#endif + static inline void cache_l2c_310_enable( void ) { volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE; + uint32_t cache_id = l2cc->cache_id; cache_l2c_310_rtl_release rtl_release = - l2cc->cache_id & CACHE_L2C_310_L2CC_ID_RTL_MASK; + cache_id & CACHE_L2C_310_L2CC_ID_RTL_MASK; + uint32_t id_mask = + CACHE_L2C_310_L2CC_ID_IMPL_MASK | CACHE_L2C_310_L2CC_ID_PART_MASK; + + /* + * Do we actually have an L2C-310 cache controller? Has BSP_ARM_L2C_310_BASE + * been configured correctly? + */ + if ( + (BSP_ARM_L2C_310_ID & id_mask) != (cache_id & id_mask) + || rtl_release < (BSP_ARM_L2C_310_ID & CACHE_L2C_310_L2CC_ID_RTL_MASK) + ) { + bsp_fatal( ARM_FATAL_L2C_310_UNEXPECTED_ID ); + } + + l2c_310_cache_check_errata( rtl_release ); /* Only enable if L2CC is currently disabled */ if( ( l2cc->ctrl & CACHE_L2C_310_L2CC_ENABLE_MASK ) == 0 ) { - uint32_t cache_id = - l2cc->cache_id & CACHE_L2C_310_L2CC_ID_PART_MASK; - int ways = 0; - - /* Do we actually have an L2C-310 cache controller? - * Has BSP_ARM_L2C_310_BASE been configured correctly? */ - switch ( cache_id ) { - case CACHE_L2C_310_L2CC_ID_PART_L310: - { - /* If this assertion fails, you have a release of the - * L2C-310 cache for which the l2c_310_cache_errata_is_applicable_ ... - * methods are not yet implemented. This means you will get incorrect - * errata handling */ - assert( rtl_release == CACHE_L2C_310_RTL_RELEASE_R3_P3 - || rtl_release == CACHE_L2C_310_RTL_RELEASE_R3_P2 - || rtl_release == CACHE_L2C_310_RTL_RELEASE_R3_P1 - || rtl_release == CACHE_L2C_310_RTL_RELEASE_R3_P0 - || rtl_release == CACHE_L2C_310_RTL_RELEASE_R2_P0 - || rtl_release == CACHE_L2C_310_RTL_RELEASE_R1_P0 - || rtl_release == CACHE_L2C_310_RTL_RELEASE_R0_P0 ); - if ( l2cc->aux_ctrl & ( 1 << 16 ) ) { - ways = 16; - } else { - ways = 8; - } - - assert( ways == CACHE_l2C_310_NUM_WAYS ); - } - break; - case CACHE_L2C_310_L2CC_ID_PART_L210: + uint32_t aux_ctrl; + int ways; - /* Invalid case */ + /* Make sure that I&D is not locked down when starting */ + cache_l2c_310_unlock( l2cc ); - /* Support for this type is not implemented in this driver. - * Either support needs to get added or a seperate driver needs to get - * implemented */ - assert( cache_id != CACHE_L2C_310_L2CC_ID_PART_L210 ); - break; - default: - - /* Unknown case */ - assert( cache_id == CACHE_L2C_310_L2CC_ID_PART_L310 ); - break; - } - - if ( ways > 0 ) { - uint32_t aux; - - /* Set up the way size */ - aux = l2cc->aux_ctrl; - aux &= CACHE_L2C_310_L2CC_AUX_REG_ZERO_MASK; /* Set way_size to 0 */ - aux |= CACHE_L2C_310_L2CC_AUX_REG_DEFAULT_MASK; - - /* Make sure that I&D is not locked down when starting */ - cache_l2c_310_unlock(); + cache_l2c_310_wait_for_background_ops( l2cc ); - /* Level 2 configuration and control registers must not get written while - * background operations are pending */ - while ( l2cc->inv_way & CACHE_l2C_310_WAY_MASK ) ; + aux_ctrl = l2cc->aux_ctrl; - while ( l2cc->clean_way & CACHE_l2C_310_WAY_MASK ) ; + if ( (aux_ctrl & ( 1 << 16 )) != 0 ) { + ways = 16; + } else { + ways = 8; + } - while ( l2cc->clean_inv_way & CACHE_l2C_310_WAY_MASK ) ; + if ( ways != CACHE_l2C_310_NUM_WAYS ) { + bsp_fatal( ARM_FATAL_L2C_310_UNEXPECTED_NUM_WAYS ); + } - l2cc->aux_ctrl = aux; + /* Set up the way size */ + aux_ctrl &= CACHE_L2C_310_L2CC_AUX_REG_ZERO_MASK; /* Set way_size to 0 */ + aux_ctrl |= CACHE_L2C_310_L2CC_AUX_REG_DEFAULT_MASK; - /* Set up the latencies */ - l2cc->tag_ram_ctrl = CACHE_L2C_310_L2CC_TAG_RAM_DEFAULT_LAT; - l2cc->data_ram_ctrl = CACHE_L2C_310_L2CC_DATA_RAM_DEFAULT_MASK; + l2cc->aux_ctrl = aux_ctrl; - cache_l2c_310_invalidate_entire(); + /* Set up the latencies */ + l2cc->tag_ram_ctrl = CACHE_L2C_310_L2CC_TAG_RAM_DEFAULT_LAT; + l2cc->data_ram_ctrl = CACHE_L2C_310_L2CC_DATA_RAM_DEFAULT_MASK; - /* Clear the pending interrupts */ - l2cc->int_clr = l2cc->int_raw_status; + cache_l2c_310_invalidate_entire(); - l2c_310_cache_check_errata( rtl_release ); + /* Clear the pending interrupts */ + l2cc->int_clr = l2cc->int_raw_status; - /* Enable the L2CC */ - l2cc->ctrl |= CACHE_L2C_310_L2CC_ENABLE_MASK; - } + /* Enable the L2CC */ + l2cc->ctrl |= CACHE_L2C_310_L2CC_ENABLE_MASK; } } @@ -1226,13 +1219,7 @@ cache_l2c_310_disable( void ) cache_l2c_310_flush_entire(); rtems_interrupt_lock_acquire( &l2c_310_cache_lock, &lock_context ); - /* Level 2 configuration and control registers must not get written while - * background operations are pending */ - while ( l2cc->inv_way & CACHE_l2C_310_WAY_MASK ) ; - - while ( l2cc->clean_way & CACHE_l2C_310_WAY_MASK ) ; - - while ( l2cc->clean_inv_way & CACHE_l2C_310_WAY_MASK ) ; + cache_l2c_310_wait_for_background_ops( l2cc ); /* Disable the L2 cache */ l2cc->ctrl &= ~CACHE_L2C_310_L2CC_ENABLE_MASK; diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/include/bsp.h b/c/src/lib/libbsp/arm/xilinx-zynq/include/bsp.h index e8687b4488..bf3ad92b96 100644 --- a/c/src/lib/libbsp/arm/xilinx-zynq/include/bsp.h +++ b/c/src/lib/libbsp/arm/xilinx-zynq/include/bsp.h @@ -55,7 +55,9 @@ extern "C" { #define BSP_ARM_GIC_DIST_BASE 0xf8f01000 -#define BSP_ARM_L2C_310_BASE 0xF8F02000U +#define BSP_ARM_L2C_310_BASE 0xf8f02000 + +#define BSP_ARM_L2C_310_ID 0x410000c8 /** * @brief Zynq specific set up of the MMU. diff --git a/c/src/lib/libbsp/shared/include/fatal.h b/c/src/lib/libbsp/shared/include/fatal.h index 11dd20dd2e..a6c5736d44 100644 --- a/c/src/lib/libbsp/shared/include/fatal.h +++ b/c/src/lib/libbsp/shared/include/fatal.h @@ -106,7 +106,11 @@ typedef enum { PPC_FATAL_EXCEPTION_INITIALIZATION = BSP_FATAL_CODE_BLOCK(7), /* Libchip fatal codes */ - DWMAC_FATAL_TOO_MANY_RBUFS_CONFIGURED = BSP_FATAL_CODE_BLOCK(8) + DWMAC_FATAL_TOO_MANY_RBUFS_CONFIGURED = BSP_FATAL_CODE_BLOCK(8), + + /* ARM fatal codes */ + ARM_FATAL_L2C_310_UNEXPECTED_ID = BSP_FATAL_CODE_BLOCK(9), + ARM_FATAL_L2C_310_UNEXPECTED_NUM_WAYS } bsp_fatal_code; RTEMS_COMPILER_NO_RETURN_ATTRIBUTE static inline void -- cgit v1.2.3