From 98f9d442b44dbe2e3e4b3c8296be7e78d5d05450 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 24 Jul 2011 09:39:28 +0200 Subject: initial import of the usb ccid example for the sam7s --- at91lib/peripherals/cp15/cp15.c | 268 ++++++++++++++++++++++++++++++++++++ at91lib/peripherals/cp15/cp15.h | 84 +++++++++++ at91lib/peripherals/cp15/cp15_asm.S | 138 +++++++++++++++++++ 3 files changed, 490 insertions(+) create mode 100644 at91lib/peripherals/cp15/cp15.c create mode 100644 at91lib/peripherals/cp15/cp15.h create mode 100644 at91lib/peripherals/cp15/cp15_asm.S (limited to 'at91lib/peripherals/cp15') diff --git a/at91lib/peripherals/cp15/cp15.c b/at91lib/peripherals/cp15/cp15.c new file mode 100644 index 0000000..17a1f70 --- /dev/null +++ b/at91lib/peripherals/cp15/cp15.c @@ -0,0 +1,268 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//----------------------------------------------------------------------------- +// Headers +//----------------------------------------------------------------------------- + +#include + +#ifdef CP15_PRESENT + +#include +#include "cp15.h" + +#if defined(__ICCARM__) +#include +#endif + + +//----------------------------------------------------------------------------- +// Macros +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- +/* +#define CP15_RR_BIT 14 // RR bit Replacement strategy for ICache and DCache: + // 0 = Random replacement + // 1 = Round-robin replacement. + +#define CP15_V_BIT 13 // V bit Location of exception vectors: + // 0 = Normal exception vectors selected address range = 0x0000 0000 to 0x0000 001C + // 1 = High exception vect selected, address range = 0xFFFF 0000 to 0xFFFF 001C +*/ +#define CP15_I_BIT 12 // I bit ICache enable/disable: + // 0 = ICache disabled + // 1 = ICache enabled +/* +#define CP15_R_BIT 9 // R bit ROM protection + +#define CP15_S_BIT 8 // S bit System protection + +#define CP15_B_BIT 7 // B bit Endianness: + // 0 = Little-endian operation + // 1 = Big-endian operation. +*/ +#define CP15_C_BIT 2 // C bit DCache enable/disable: + // 0 = Cache disabled + // 1 = Cache enabled +/* +#define CP15_A_BIT 1 // A bit Alignment fault enable/disable: + // 0 = Data address alignment fault checking disabled + // 1 = Data address alignment fault checking enabled +*/ +#define CP15_M_BIT 0 // M bit MMU enable/disable: 0 = disabled 1 = enabled. + // 0 = disabled + // 1 = enabled + + +//----------------------------------------------------------------------------- +// Global functions +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +/// Check Instruction Cache +/// \return 0 if I_Cache disable, 1 if I_Cache enable +//------------------------------------------------------------------------------ +unsigned int CP15_Is_I_CacheEnabled(void) +{ + unsigned int control; + + control = _readControlRegister(); + return ((control & (1 << CP15_I_BIT)) != 0); +} + +//------------------------------------------------------------------------------ +/// Enable Instruction Cache +//------------------------------------------------------------------------------ +void CP15_Enable_I_Cache(void) +{ + unsigned int control; + + control = _readControlRegister(); + + // Check if cache is disabled + if ((control & (1 << CP15_I_BIT)) == 0) { + + control |= (1 << CP15_I_BIT); + _writeControlRegister(control); + TRACE_INFO("I cache enabled.\n\r"); + } +#if !defined(OP_BOOTSTRAP_on) + else { + + TRACE_INFO("I cache is already enabled.\n\r"); + } +#endif +} + +//------------------------------------------------------------------------------ +/// Disable Instruction Cache +//------------------------------------------------------------------------------ +void CP15_Disable_I_Cache(void) +{ + unsigned int control; + + control = _readControlRegister(); + + // Check if cache is enabled + if ((control & (1 << CP15_I_BIT)) != 0) { + + control &= ~(1 << CP15_I_BIT); + _writeControlRegister(control); + TRACE_INFO("I cache disabled.\n\r"); + } + else { + + TRACE_INFO("I cache is already disabled.\n\r"); + } +} + +//------------------------------------------------------------------------------ +/// Check MMU +/// \return 0 if MMU disable, 1 if MMU enable +//------------------------------------------------------------------------------ +unsigned int CP15_Is_MMUEnabled(void) +{ + unsigned int control; + + control = _readControlRegister(); + return ((control & (1 << CP15_M_BIT)) != 0); +} + +//------------------------------------------------------------------------------ +/// Enable MMU +//------------------------------------------------------------------------------ +void CP15_EnableMMU(void) +{ + unsigned int control; + + control = _readControlRegister(); + + // Check if MMU is disabled + if ((control & (1 << CP15_M_BIT)) == 0) { + + control |= (1 << CP15_M_BIT); + _writeControlRegister(control); + TRACE_INFO("MMU enabled.\n\r"); + } + else { + + TRACE_INFO("MMU is already enabled.\n\r"); + } +} + +//------------------------------------------------------------------------------ +/// Disable MMU +//------------------------------------------------------------------------------ +void CP15_DisableMMU(void) +{ + unsigned int control; + + control = _readControlRegister(); + + // Check if MMU is enabled + if ((control & (1 << CP15_M_BIT)) != 0) { + + control &= ~(1 << CP15_M_BIT); + control &= ~(1 << CP15_C_BIT); + _writeControlRegister(control); + TRACE_INFO("MMU disabled.\n\r"); + } + else { + + TRACE_INFO("MMU is already disabled.\n\r"); + } +} + +//------------------------------------------------------------------------------ +/// Check D_Cache +/// \return 0 if D_Cache disable, 1 if D_Cache enable (with MMU of course) +//------------------------------------------------------------------------------ +unsigned int CP15_Is_DCacheEnabled(void) +{ + unsigned int control; + + control = _readControlRegister(); + return ((control & ((1 << CP15_C_BIT)||(1 << CP15_M_BIT))) != 0); +} + +//------------------------------------------------------------------------------ +/// Enable Data Cache +//------------------------------------------------------------------------------ +void CP15_Enable_D_Cache(void) +{ + unsigned int control; + + control = _readControlRegister(); + + if( !CP15_Is_MMUEnabled() ) { + TRACE_ERROR("Do nothing: MMU not enabled\n\r"); + } + else { + // Check if cache is disabled + if ((control & (1 << CP15_C_BIT)) == 0) { + + control |= (1 << CP15_C_BIT); + _writeControlRegister(control); + TRACE_INFO("D cache enabled.\n\r"); + } + else { + + TRACE_INFO("D cache is already enabled.\n\r"); + } + } +} + +//------------------------------------------------------------------------------ +/// Disable Data Cache +//------------------------------------------------------------------------------ +void CP15_Disable_D_Cache(void) +{ + unsigned int control; + + control = _readControlRegister(); + + // Check if cache is enabled + if ((control & (1 << CP15_C_BIT)) != 0) { + + control &= ~(1 << CP15_C_BIT); + _writeControlRegister(control); + TRACE_INFO("D cache disabled.\n\r"); + } + else { + + TRACE_INFO("D cache is already disabled.\n\r"); + } +} + +#endif // CP15_PRESENT + diff --git a/at91lib/peripherals/cp15/cp15.h b/at91lib/peripherals/cp15/cp15.h new file mode 100644 index 0000000..ddaaeb6 --- /dev/null +++ b/at91lib/peripherals/cp15/cp15.h @@ -0,0 +1,84 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +/// \unit +/// +/// !Purpose +/// +/// Methods to manage the Coprocessor 15. Coprocessor 15, or System Control +/// Coprocessor CP15, is used to configure and control all the items in the +/// list below: +/// • ARM core +/// • Caches (ICache, DCache and write buffer) +/// • TCM +/// • MMU +/// • Other system options +/// +/// !Usage +/// +/// -# Enable or disable D cache with Enable_D_Cache and Disable_D_Cache +/// -# Enable or disable I cache with Enable_I_Cache and Disable_I_Cache +/// +//------------------------------------------------------------------------------ + +#ifndef _CP15_H +#define _CP15_H + +#ifdef CP15_PRESENT + +//----------------------------------------------------------------------------- +// Exported functions +//----------------------------------------------------------------------------- +extern void CP15_Enable_I_Cache(void); +extern unsigned int CP15_Is_I_CacheEnabled(void); +extern void CP15_Enable_I_Cache(void); +extern void CP15_Disable_I_Cache(void); +extern unsigned int CP15_Is_MMUEnabled(void); +extern void CP15_EnableMMU(void); +extern void CP15_DisableMMU(void); +extern unsigned int CP15_Is_DCacheEnabled(void); +extern void CP15_Enable_D_Cache(void); +extern void CP15_Disable_D_Cache(void); + +//----------------------------------------------------------------------------- +// External functions defined in cp15.S +//----------------------------------------------------------------------------- +extern unsigned int _readControlRegister(void); +extern void _writeControlRegister(unsigned int value); +extern void _waitForInterrupt(void); +extern void _writeTTB(unsigned int value); +extern void _writeDomain(unsigned int value); +extern void _writeITLBLockdown(unsigned int value); +extern void _prefetchICacheLine(unsigned int value); + +#endif // CP15_PRESENT + +#endif // #ifndef _CP15_H + diff --git a/at91lib/peripherals/cp15/cp15_asm.S b/at91lib/peripherals/cp15/cp15_asm.S new file mode 100644 index 0000000..00ef47d --- /dev/null +++ b/at91lib/peripherals/cp15/cp15_asm.S @@ -0,0 +1,138 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#define __ASSEMBLY__ +#include "board.h" + +#ifdef CP15_PRESENT + +//------------------------------------------------------------------------------ +/// Functions to access CP15 coprocessor register +//------------------------------------------------------------------------------ + + .global _readControlRegister + .global _writeControlRegister + .global _waitForInterrupt + .global _writeTTB + .global _writeDomain + .global _writeITLBLockdown + .global _prefetchICacheLine + +//------------------------------------------------------------------------------ +/// Control Register c1 +/// Register c1 is the Control Register for the ARM926EJ-S processor. +/// This register specifies the configuration used to enable and disable the +/// caches and MMU. It is recommended that you access this register using a +/// read-modify-write sequence. +//------------------------------------------------------------------------------ +// CP15 Read Control Register +_readControlRegister: + mov r0, #0 + mrc p15, 0, r0, c1, c0, 0 + bx lr + +// CP15 Write Control Register +_writeControlRegister: + mcr p15, 0, r0, c1, c0, 0 + bx lr + +//------------------------------------------------------------------------------ +/// CP15 Wait For Interrupt operation +/// The purpose of the Wait For Interrupt operation is to put the processor in +/// to a low power state. +/// This puts the processor into a low-power state and stops it executing more +/// instructions until an interrupt, or debug request occurs, regardless of +/// whether the interrupts are disabled by the masks in the CPSR. +/// When an interrupt does occur, the MCR instruction completes and the IRQ or +/// FIQ handler is entered as normal. The return link in r14_irq or r14_fiq +/// contains the address of the MCR instruction plus 8, so that the normal +/// instruction used for interrupt return (SUBS PC,R14,#4) returns to the +/// instruction following the MCR. +/// Wait For Interrupt : MCR p15, 0, , c7, c0, 4 +//------------------------------------------------------------------------------ +_waitForInterrupt: + mov r0, #0 + mcr p15, 0, r0, c7, c0, 4 + bx lr + +//------------------------------------------------------------------------------ +/// CP15 Translation Table Base Register c2 +/// Register c2 is the Translation Table Base Register (TTBR), for the base +/// address of the first-level translation table. +/// Reading from c2 returns the pointer to the currently active first-level +/// translation table in bits [31:14] and an Unpredictable value in bits [13:0]. +/// Writing to register c2 updates the pointer to the first-level translation +/// table from the value in bits [31:14] of the written value. Bits [13:0] +/// Should Be Zero. +/// You can use the following instructions to access the TTBR: +/// Read TTBR : MRC p15, 0, , c2, c0, 0 +/// Write TTBR : MCR p15, 0, , c2, c0, 0 +//------------------------------------------------------------------------------ +_writeTTB: + MCR p15, 0, r0, c2, c0, 0 + bx lr + +//------------------------------------------------------------------------------ +/// Domain Access Control Register c3 +/// Read domain access permissions : MRC p15, 0, , c3, c0, 0 +/// Write domain access permissions : MCR p15, 0, , c3, c0, 0 +//------------------------------------------------------------------------------ +_writeDomain: + MCR p15, 0, r0, c3, c0, 0 + bx lr + +//------------------------------------------------------------------------------ +/// TLB Lockdown Register c10 +/// The TLB Lockdown Register controls where hardware page table walks place the +/// TLB entry, in the set associative region or the lockdown region of the TLB, +/// and if in the lockdown region, which entry is written. The lockdown region +/// of the TLB contains eight entries. See TLB structure for a description of +/// the structure of the TLB. +/// Read data TLB lockdown victim : MRC p15,0,,c10,c0,0 +/// Write data TLB lockdown victim : MCR p15,0,,c10,c0,0 +//------------------------------------------------------------------------------ +_writeITLBLockdown: + MCR p15, 0, r0, c10, c0, 0 + bx lr + +//------------------------------------------------------------------------------ +/// Prefetch ICache line +/// Performs an ICache lookup of the specified modified virtual address. +/// If the cache misses, and the region is cacheable, a linefill is performed. +/// Prefetch ICache line (MVA): MCR p15, 0, , c7, c13, 1 +//------------------------------------------------------------------------------ +_prefetchICacheLine: + MCR p15, 0, r0, c7, c13, 1 + bx lr +#endif + -- cgit v1.2.3