Mercurial > ecos-v2_0-branch
changeset 348:94daa52ddaae
Rename xscale/core to xscale/cores
| author | msalter |
|---|---|
| date | Mon, 23 Sep 2002 15:57:52 +0000 |
| parents | 9cdf781366eb |
| children | 457711274bc5 |
| files | packages/ChangeLog packages/ecos.db packages/hal/arm/xscale/core/current/ChangeLog packages/hal/arm/xscale/core/current/cdl/hal_arm_xscale_core.cdl packages/hal/arm/xscale/core/current/include/hal_cache.h packages/hal/arm/xscale/core/current/include/hal_mm.h packages/hal/arm/xscale/core/current/include/hal_xscale.h packages/hal/arm/xscale/core/current/include/plf_stub.h packages/hal/arm/xscale/core/current/src/xscale_misc.c packages/hal/arm/xscale/core/current/src/xscale_stub.c packages/hal/arm/xscale/cores/current/ChangeLog packages/hal/arm/xscale/cores/current/cdl/hal_arm_xscale_core.cdl packages/hal/arm/xscale/cores/current/include/hal_cache.h packages/hal/arm/xscale/cores/current/include/hal_mm.h packages/hal/arm/xscale/cores/current/include/hal_xscale.h packages/hal/arm/xscale/cores/current/include/plf_stub.h packages/hal/arm/xscale/cores/current/src/xscale_misc.c packages/hal/arm/xscale/cores/current/src/xscale_stub.c |
| diffstat | 18 files changed, 1827 insertions(+), 1822 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/ChangeLog +++ b/packages/ChangeLog @@ -1,3 +1,7 @@ +2002-09-23 Mark Salter <msalter@redhat.com> + + * ecos.db: Change XScale core dirname to "cores". + 2002-09-19 Mark Salter <msalter@redhat.com> * ecos.db: Add XScale core package.
--- a/packages/ecos.db +++ b/packages/ecos.db @@ -1999,7 +1999,7 @@ CMA230 (ARM7TDMI) or CMA222 (ARM710T) ev package CYGPKG_HAL_ARM_XSCALE_CORE { alias { "Intel XScale Core" hal_arm_xscale_core } - directory hal/arm/xscale/core + directory hal/arm/xscale/cores script hal_arm_xscale_core.cdl hardware description "
deleted file mode 100644 --- a/packages/hal/arm/xscale/core/current/ChangeLog +++ /dev/null @@ -1,48 +0,0 @@ -2002-09-23 Mark Salter <msalter@redhat.com> - - * include/hal_cache.h: Remove mmap-related externs which don't belong - here. - -2002-09-20 Mark Salter <msalter@redhat.com> - - * src/xscale_stub.c: Fill in holes in logic used to decide which - of two watchpoints caused exception. - -2002-09-19 Mark Salter <msalter@redhat.com> - - * Initial checkin. - -//=========================================================================== -//####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with eCos; if not, write to the Free Software Foundation, Inc., -// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -// -// As a special exception, if other files instantiate templates or use macros -// or inline functions from this file, or you compile this file and link it -// with other works to produce a work based on this file, this file does not -// by itself cause the resulting work to be covered by the GNU General Public -// License. However the source code for this file must still be made available -// in accordance with section (3) of the GNU General Public License. -// -// This exception does not invalidate any other reasons why a work based on -// this file might be covered by the GNU General Public License. -// -// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. -// at http://sources.redhat.com/ecos/ecos-license/ -// ------------------------------------------- -//####ECOSGPLCOPYRIGHTEND#### -//===========================================================================
deleted file mode 100644 --- a/packages/hal/arm/xscale/core/current/cdl/hal_arm_xscale_core.cdl +++ /dev/null @@ -1,65 +0,0 @@ -# ==================================================================== -# -# hal_arm_xscale_core.cdl -# -# Intel XScale architectural HAL package configuration data -# -# ==================================================================== -#####ECOSGPLCOPYRIGHTBEGIN#### -## ------------------------------------------- -## This file is part of eCos, the Embedded Configurable Operating System. -## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. -## -## eCos is free software; you can redistribute it and/or modify it under -## the terms of the GNU General Public License as published by the Free -## Software Foundation; either version 2 or (at your option) any later version. -## -## eCos is distributed in the hope that it will be useful, but WITHOUT ANY -## WARRANTY; without even the implied warranty of MERCHANTABILITY or -## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -## for more details. -## -## You should have received a copy of the GNU General Public License along -## with eCos; if not, write to the Free Software Foundation, Inc., -## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -## -## As a special exception, if other files instantiate templates or use macros -## or inline functions from this file, or you compile this file and link it -## with other works to produce a work based on this file, this file does not -## by itself cause the resulting work to be covered by the GNU General Public -## License. However the source code for this file must still be made available -## in accordance with section (3) of the GNU General Public License. -## -## This exception does not invalidate any other reasons why a work based on -## this file might be covered by the GNU General Public License. -## -## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. -## at http://sources.redhat.com/ecos/ecos-license/ -## ------------------------------------------- -#####ECOSGPLCOPYRIGHTEND#### -# ==================================================================== -######DESCRIPTIONBEGIN#### -# -# Author(s): msalter -# Original data: msalter -# Contributors: -# Date: 2002-10-18 -# -#####DESCRIPTIONEND#### -# -# ==================================================================== -cdl_package CYGPKG_HAL_ARM_XSCALE_CORE { - display "Intel XScale Core Support" - parent CYGPKG_HAL_ARM - hardware - include_dir cyg/hal - define_header hal_arm_xscale_core.h - description " - This HAL variant package provides generic support common - to Intel XScale CPU cores. It is also necessary to select - a specific target platform and CPU HAL package." - - implements CYGINT_HAL_ARM_ARCH_XSCALE - - compile xscale_misc.c xscale_stub.c -}
deleted file mode 100644 --- a/packages/hal/arm/xscale/core/current/include/hal_cache.h +++ /dev/null @@ -1,386 +0,0 @@ -#ifndef CYGONCE_HAL_CACHE_H -#define CYGONCE_HAL_CACHE_H - -//============================================================================= -// -// hal_cache.h -// -// HAL cache control API -// -//============================================================================= -//####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with eCos; if not, write to the Free Software Foundation, Inc., -// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -// -// As a special exception, if other files instantiate templates or use macros -// or inline functions from this file, or you compile this file and link it -// with other works to produce a work based on this file, this file does not -// by itself cause the resulting work to be covered by the GNU General Public -// License. However the source code for this file must still be made available -// in accordance with section (3) of the GNU General Public License. -// -// This exception does not invalidate any other reasons why a work based on -// this file might be covered by the GNU General Public License. -// -// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. -// at http://sources.redhat.com/ecos/ecos-license/ -// ------------------------------------------- -//####ECOSGPLCOPYRIGHTEND#### -//============================================================================= -//#####DESCRIPTIONBEGIN#### -// -// Author(s): msalter -// Contributors: -// Date: 2001-12-03 -// Purpose: Cache control API -// Description: The macros defined here provide the HAL APIs for handling -// cache control operations. -// Usage: -// #include <cyg/hal/hal_cache.h> -// ... -// -// -//####DESCRIPTIONEND#### -// -//============================================================================= - -#include <pkgconf/system.h> // System-wide configuration info -#include <cyg/hal/hal_io.h> // DCACHE_FLUSH_AREA -#include <cyg/infra/cyg_type.h> -#include CYGBLD_HAL_VAR_H -#include <cyg/hal/hal_mmu.h> - -//----------------------------------------------------------------------------- -// Cache dimensions - -#define HAL_DCACHE_SIZE 0x8000 // Size of data cache in bytes -#define HAL_DCACHE_LINE_SIZE 32 // Size of a data cache line -#define HAL_DCACHE_WAYS 32 // Associativity of the cache -#define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS)) - -#define HAL_ICACHE_SIZE 0x8000 // Size of icache in bytes -#define HAL_ICACHE_LINE_SIZE 32 // Size of ins cache line -#define HAL_ICACHE_WAYS 32 // Associativity of the cache -#define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS)) - -//----------------------------------------------------------------------------- -// Global control of Instruction cache - -// Enable the instruction cache -#define HAL_ICACHE_ENABLE() \ -CYG_MACRO_START \ - asm volatile ( \ - "mrc p15,0,r1,c1,c0,0;" \ - "orr r1,r1,#0x1000;" /* enable ICache */ \ - "mcr p15,0,r1,c1,c0,0;" \ - : \ - : \ - : "r1" /* Clobber list */ \ - ); \ -CYG_MACRO_END - -// Disable the instruction cache (and invalidate it, required semanitcs) -#define HAL_ICACHE_DISABLE() \ -CYG_MACRO_START \ - asm volatile ( \ - "mrc p15,0,r1,c1,c0,0;" \ - "bic r1,r1,#0x1000;" /* disable Icache */ \ - "mcr p15,0,r1,c1,c0,0;" \ - "mcr p15,0,r1,c7,c5,0;" /* invalidate instruction cache */ \ - "nop;" /* next few instructions may be via cache */ \ - "nop;" \ - "nop;" \ - "nop;" \ - "nop;" \ - "nop" \ - : \ - : \ - : "r1" /* Clobber list */ \ - ); \ -CYG_MACRO_END - -// Query the state of the instruction cache -#define HAL_ICACHE_IS_ENABLED(_state_) \ -CYG_MACRO_START \ - register cyg_uint32 reg; \ - asm volatile ("mrc p15,0,%0,c1,c0,0" \ - : "=r"(reg) \ - : \ - ); \ - (_state_) = (0 != (0x1000 & reg)); /* Bit 12 is ICache enable */ \ -CYG_MACRO_END - -// Invalidate the entire cache -#define HAL_ICACHE_INVALIDATE_ALL() \ -CYG_MACRO_START \ - asm volatile ( \ - "mcr p15,0,r1,c7,c5,0;" /* clear instruction cache */ \ - "mcr p15,0,r1,c8,c5,0;" /* flush I TLB only */ \ - /* cpuwait */ \ - "mrc p15,0,r1,c2,c0,0;" /* arbitrary read */ \ - "mov r1,r1;" \ - "sub pc,pc,#4;" \ - "nop;" /* next few instructions may be via cache */ \ - "nop;" \ - "nop;" \ - "nop;" \ - "nop;" \ - "nop" \ - : \ - : \ - : "r1" /* Clobber list */ \ - ); \ -CYG_MACRO_END - -// Synchronize the contents of the cache with memory. -// (which includes flushing out pending writes) -#define HAL_ICACHE_SYNC() \ -CYG_MACRO_START \ - HAL_DCACHE_SYNC(); /* ensure data gets to RAM */ \ - HAL_ICACHE_INVALIDATE_ALL(); /* forget all we know */ \ -CYG_MACRO_END - -// Set the instruction cache refill burst size -//#define HAL_ICACHE_BURST_SIZE(_size_) -// This feature is not available on the SA11X0. - -// Load the contents of the given address range into the instruction cache -// and then lock the cache so that it stays there. -//#define HAL_ICACHE_LOCK(_base_, _size_) -// This feature is not available on the SA11X0. - -// Undo a previous lock operation -//#define HAL_ICACHE_UNLOCK(_base_, _size_) -// This feature is not available on the SA11X0. - -// Unlock entire cache -//#define HAL_ICACHE_UNLOCK_ALL() -// This feature is not available on the SA11X0. - -//----------------------------------------------------------------------------- -// Instruction cache line control - -// Invalidate cache lines in the given range without writing to memory. -//#define HAL_ICACHE_INVALIDATE( _base_ , _size_ ) -// This feature is not available on the SA11X0. - -//----------------------------------------------------------------------------- -// Global control of data cache - -// Enable the data cache -#define HAL_DCACHE_ENABLE() \ -CYG_MACRO_START \ - asm volatile ( \ - "mrc p15,0,r1,c7,c10,4;" /* drain write buffer */ \ - "mrc p15,0,r1,c1,c0,0;" \ - "orr r1,r1,#0x0007;" /* enable DCache (also ensures the */ \ - /* MMU and alignment faults are */ \ - /* enabled) */ \ - "mcr p15,0,r1,c1,c0,0;" \ - "mrc p15,0,r1,c1,c0,1;" \ - "bic r1,r1,#1;" \ - "mcr p15,0,r1,c1,c0,1;" \ - : \ - : \ - : "r1" /* Clobber list */ \ - ); \ -CYG_MACRO_END - -// Disable the data cache (and invalidate it, required semanitcs) -#define HAL_DCACHE_DISABLE() \ -CYG_MACRO_START \ - asm volatile ( \ - "mrc p15,0,r1,c1,c0,0;" /* disable cache */ \ - "bic r1,r1,#4;" \ - "mcr p15,0,r1,c1,c0,0;" \ - "mrc p15,0,r1,c1,c0,1;" /* disable coalescing */ \ - "orr r1,r1,#1;" \ - "mcr p15,0,r1,c1,c0,1;" \ - "mcr p15,0,r1,c7,c6,0;" /* invalidate data cache */ \ - /* cpuwait */ \ - "mrc p15,0,r1,c2,c0,0;" /* arbitrary read */ \ - "mov r1,r1;" \ - "sub pc,pc,#4;" \ - : \ - : \ - : "r1" /* Clobber list */ \ - ); \ -CYG_MACRO_END - -// Query the state of the data cache -#define HAL_DCACHE_IS_ENABLED(_state_) \ -CYG_MACRO_START \ - register int reg; \ - asm volatile ("mrc p15,0,%0,c1,c0,0" \ - : "=r"(reg) \ - : \ - /*:*/ \ - ); \ - (_state_) = (0 != (4 & reg)); /* Bit 2 is DCache enable */ \ -CYG_MACRO_END - -// Flush the entire dcache (and then both TLBs, just in case) -#define HAL_DCACHE_INVALIDATE_ALL() \ -CYG_MACRO_START /* this macro can discard dirty cache lines. */ \ - /* this macro can discard dirty cache lines. */ \ - asm volatile ( \ - "mcr p15,0,r1,c7,c6,0;" /* invalidate data cache */ \ - "mcr p15,0,r1,c8,c7,0;" /* flush I+D TLBs */ \ - : \ - : \ - : "r1" /* Clobber list */ \ - ); \ -CYG_MACRO_END - - -// Synchronize the contents of the cache with memory. -#define HAL_DCACHE_SYNC() \ -CYG_MACRO_START \ - /* The best way to evict a dirty line is by using the */ \ - /* line allocate operation on non-existent memory. */ \ - asm volatile ( \ - "mov r0, %0;" /* cache flush region */ \ - "add r1, r0, #0x8800;" /* 32KB main + 2KB mini cache */ \ - "667: " \ - "mcr p15,0,r0,c7,c2,5;" /* allocate a line */ \ - "add r0, r0, #32;" /* 32 bytes/line */ \ - "teq r1, r0;" \ - "bne 667b;" \ - "mcr p15,0,r0,c7,c6,0;" /* invalidate data cache */ \ - /* cpuwait */ \ - "mrc p15,0,r1,c2,c0,0;" /* arbitrary read */ \ - "mov r1,r1;" \ - "sub pc,pc,#4;" \ - "mcr p15,0,r0,c7,c10,4;" /* and drain the write buffer */ \ - /* cpuwait */ \ - "mrc p15,0,r1,c2,c0,0;" /* arbitrary read */ \ - "mov r1,r1;" \ - "sub pc,pc,#4;" \ - "nop" \ - : \ - : "i" (DCACHE_FLUSH_AREA) \ - : "r0","r1" /* Clobber list */ \ - ); \ -CYG_MACRO_END - -// Set the data cache refill burst size -//#define HAL_DCACHE_BURST_SIZE(_size_) -// This feature is not available on the SA11X0. - -// Set the data cache write mode -//#define HAL_DCACHE_WRITE_MODE( _mode_ ) -// This feature is not available on the SA11X0. - -#define HAL_DCACHE_WRITETHRU_MODE 0 -#define HAL_DCACHE_WRITEBACK_MODE 1 - -// Get the current writeback mode - or only writeback mode if fixed -#define HAL_DCACHE_QUERY_WRITE_MODE( _mode_ ) CYG_MACRO_START \ - _mode_ = HAL_DCACHE_WRITEBACK_MODE; \ -CYG_MACRO_END - -// Load the contents of the given address range into the data cache -// and then lock the cache so that it stays there. -//#define HAL_DCACHE_LOCK(_base_, _size_) -// This feature is not available on the SA11X0. - -// Undo a previous lock operation -//#define HAL_DCACHE_UNLOCK(_base_, _size_) -// This feature is not available on the SA11X0. - -// Unlock entire cache -//#define HAL_DCACHE_UNLOCK_ALL() -// This feature is not available on the SA11X0. - -//----------------------------------------------------------------------------- -// Data cache line control - -// Allocate cache lines for the given address range without reading its -// contents from memory. -//#define HAL_DCACHE_ALLOCATE( _base_ , _size_ ) -// This feature is not available on the SA11X0. - -// Write dirty cache lines to memory and invalidate the cache entries -// for the given address range. -#define HAL_DCACHE_FLUSH( _base_ , _size_ ) \ -CYG_MACRO_START \ - HAL_DCACHE_STORE( _base_ , _size_ ); \ - HAL_DCACHE_INVALIDATE( _base_ , _size_ ); \ -CYG_MACRO_END - -// Invalidate cache lines in the given range without writing to memory. -#define HAL_DCACHE_INVALIDATE( _base_ , _size_ ) \ -CYG_MACRO_START \ - register int addr, enda; \ - for ( addr = (~(HAL_DCACHE_LINE_SIZE - 1)) & (int)(_base_), \ - enda = (int)(_base_) + (_size_); \ - addr < enda ; \ - addr += HAL_DCACHE_LINE_SIZE ) \ - { \ - asm volatile ( \ - "mcr p15,0,%0,c7,c6,1;" /* flush entry away */ \ - : \ - : "r"(addr) \ - : "memory" \ - ); \ - } \ -CYG_MACRO_END - -// Write dirty cache lines to memory for the given address range. -#define HAL_DCACHE_STORE( _base_ , _size_ ) \ -CYG_MACRO_START \ - register int addr, enda; \ - for ( addr = (~(HAL_DCACHE_LINE_SIZE - 1)) & (int)(_base_), \ - enda = (int)(_base_) + (_size_); \ - addr < enda ; \ - addr += HAL_DCACHE_LINE_SIZE ) \ - { \ - asm volatile ("mcr p15,0,%0,c7,c10,1;" /* push entry to RAM */ \ - : \ - : "r"(addr) \ - : "memory" \ - ); \ - } \ - /* and also drain the write buffer */ \ - asm volatile ( \ - "mov r1,#0;" \ - "mcr p15,0,r1,c7,c10,4;" \ - : \ - : \ - : "r1", "memory" /* Clobber list */ \ - ); \ -CYG_MACRO_END - -// Preread the given range into the cache with the intention of reading -// from it later. -//#define HAL_DCACHE_READ_HINT( _base_ , _size_ ) -// This feature is available on the SA11X0, but due to tricky -// coherency issues with the read buffer (see SA11X0 developer's -// manual page 6-7) we don't bother to implement it here. - -// Preread the given range into the cache with the intention of writing -// to it later. -//#define HAL_DCACHE_WRITE_HINT( _base_ , _size_ ) -// This feature is not available on the SA11X0. - -// Allocate and zero the cache lines associated with the given range. -//#define HAL_DCACHE_ZERO( _base_ , _size_ ) -// This feature is not available on the SA11X0. - -//----------------------------------------------------------------------------- -#endif // ifndef CYGONCE_HAL_CACHE_H -// End of hal_cache.h
deleted file mode 100644 --- a/packages/hal/arm/xscale/core/current/include/hal_mm.h +++ /dev/null @@ -1,230 +0,0 @@ -#ifndef CYGONCE_HAL_MM_H -#define CYGONCE_HAL_MM_H - -//============================================================================= -// -// hal_mm.h -// -// Intel XScale MM common definitions -// -//============================================================================= -//####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with eCos; if not, write to the Free Software Foundation, Inc., -// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -// -// As a special exception, if other files instantiate templates or use macros -// or inline functions from this file, or you compile this file and link it -// with other works to produce a work based on this file, this file does not -// by itself cause the resulting work to be covered by the GNU General Public -// License. However the source code for this file must still be made available -// in accordance with section (3) of the GNU General Public License. -// -// This exception does not invalidate any other reasons why a work based on -// this file might be covered by the GNU General Public License. -// -// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. -// at http://sources.redhat.com/ecos/ecos-license/ -// ------------------------------------------- -//####ECOSGPLCOPYRIGHTEND#### -//============================================================================= -//#####DESCRIPTIONBEGIN#### -// -// Author(s): msalter -// Contributors: gthomas -// Date: 2001-12-03 -// Purpose: Intel XScale MM common definitions -// Description: The macros defined here provide common definitions for -// memory management initialization. -// Usage: -// #include <cyg/hal/hal_mm.h> -// ... -// -// -//####DESCRIPTIONEND#### -// -//============================================================================= - -#define PTE_SECTION_FLASH ((3 << 10) | (1 << 3) | 2) -#define PTE_SECTION_RAM ((1 << 12) | (3 << 10) | (1 << 3) | (1 << 2) | 2) -#define PTE_SECTION_UNCACHED ((3 << 10) | 2) - -#ifdef __ASSEMBLER__ - -// form a first-level section entry -.macro FL_SECTION_ENTRY base,x,ap,p,d,c,b -.word (\base << 20) | (\x << 12) | (\ap << 10) | (\p << 9) |\ - (\d << 5) | (\c << 3) | (\b << 2) | 2 -.endm - -// form a first-level page table entry -.macro FL_PT_ENTRY base,p,d -// I wanted to use logical operations here, but since I am using symbols later -// to fill in the parameters, I had to use addition to force the assembler to -// do it right -.word \base + (\p << 9) + (\d << 5) + 1 -.endm - -// form a second level small page entry -.macro SL_SMPAGE_ENTRY base,ap3,ap2,ap1,ap0,c,b -.word (\base << 12) | (\ap3 << 10) | (\ap2 << 8) | (\ap1 << 6) |\ - (\ap0 << 4) | (\c << 3) | (\b << 2) | 2 -.endm - -// form a second level extended small page entry -.macro SL_XSMPAGE_ENTRY base,x,ap,c,b -.word (\base << 12) | (\x << 6) | (\ap << 4) | (\c << 3) | (\b << 2) | 3 -.endm - -#else - -// ------------------------------------------------------------------------- -// MMU initialization: -// -// These structures are laid down in memory to define the translation -// table. -// - -/* - * XScale Translation Table Base Bit Masks - */ -#define ARM_TRANSLATION_TABLE_MASK 0xFFFFC000 - -/* - * XScale Domain Access Control Bit Masks - */ -#define ARM_ACCESS_TYPE_NO_ACCESS(domain_num) (0x0 << (domain_num)*2) -#define ARM_ACCESS_TYPE_CLIENT(domain_num) (0x1 << (domain_num)*2) -#define ARM_ACCESS_TYPE_MANAGER(domain_num) (0x3 << (domain_num)*2) - -struct ARM_MMU_FIRST_LEVEL_FAULT { - unsigned int id : 2; - unsigned int sbz : 30; -}; -#define ARM_MMU_FIRST_LEVEL_FAULT_ID 0x0 - -struct ARM_MMU_FIRST_LEVEL_PAGE_TABLE { - unsigned int id : 2; - unsigned int imp : 2; - unsigned int domain : 4; - unsigned int p : 1; - unsigned int base_address : 23; -}; -#define ARM_MMU_FIRST_LEVEL_PAGE_TABLE_ID 0x1 - -struct ARM_MMU_FIRST_LEVEL_SECTION { - unsigned int id : 2; - unsigned int b : 1; - unsigned int c : 1; - unsigned int imp : 1; - unsigned int domain : 4; - unsigned int p : 1; - unsigned int ap : 2; - unsigned int tex : 8; - unsigned int base_address : 12; -}; -#define ARM_MMU_FIRST_LEVEL_SECTION_ID 0x2 - -struct ARM_MMU_FIRST_LEVEL_RESERVED { - unsigned int id : 2; - unsigned int sbz : 30; -}; -#define ARM_MMU_FIRST_LEVEL_RESERVED_ID 0x3 - -#define ARM_MMU_FIRST_LEVEL_DESCRIPTOR_ADDRESS(ttb_base, table_index) \ - (unsigned long *)((unsigned long)(ttb_base) + ((table_index) << 2)) - -#define ARM_FIRST_LEVEL_PAGE_TABLE_SIZE 0x4000 - -#define ARM_MMU_SECTION(ttb_base, actual_base, virtual_base, \ - cacheable, bufferable, perm) \ - CYG_MACRO_START \ - register union ARM_MMU_FIRST_LEVEL_DESCRIPTOR desc; \ - \ - desc.word = 0; \ - desc.section.id = ARM_MMU_FIRST_LEVEL_SECTION_ID; \ - desc.section.domain = 0; \ - desc.section.c = (cacheable); \ - desc.section.b = (bufferable); \ - desc.section.ap = (perm); \ - desc.section.base_address = (actual_base); \ - *ARM_MMU_FIRST_LEVEL_DESCRIPTOR_ADDRESS(ttb_base, (virtual_base)) \ - = desc.word; \ - CYG_MACRO_END - -#define X_ARM_MMU_SECTION(abase,vbase,size,cache,buff,access) \ - { int i; int j = abase; int k = vbase; \ - for (i = size; i > 0 ; i--,j++,k++) \ - { \ - ARM_MMU_SECTION(ttb_base, j, k, cache, buff, access); \ - } \ - } - -union ARM_MMU_FIRST_LEVEL_DESCRIPTOR { - unsigned long word; - struct ARM_MMU_FIRST_LEVEL_FAULT fault; - struct ARM_MMU_FIRST_LEVEL_PAGE_TABLE page_table; - struct ARM_MMU_FIRST_LEVEL_SECTION section; - struct ARM_MMU_FIRST_LEVEL_RESERVED reserved; -}; - -#define ARM_UNCACHEABLE 0 -#define ARM_CACHEABLE 1 -#define ARM_UNBUFFERABLE 0 -#define ARM_BUFFERABLE 1 - -#define ARM_ACCESS_PERM_NONE_NONE 0 -#define ARM_ACCESS_PERM_RO_NONE 0 -#define ARM_ACCESS_PERM_RO_RO 0 -#define ARM_ACCESS_PERM_RW_NONE 1 -#define ARM_ACCESS_PERM_RW_RO 2 -#define ARM_ACCESS_PERM_RW_RW 3 - -/* - * Initialization for the Domain Access Control Register - */ -#define ARM_ACCESS_DACR_DEFAULT ( \ - ARM_ACCESS_TYPE_MANAGER(0) | \ - ARM_ACCESS_TYPE_NO_ACCESS(1) | \ - ARM_ACCESS_TYPE_NO_ACCESS(2) | \ - ARM_ACCESS_TYPE_NO_ACCESS(3) | \ - ARM_ACCESS_TYPE_NO_ACCESS(4) | \ - ARM_ACCESS_TYPE_NO_ACCESS(5) | \ - ARM_ACCESS_TYPE_NO_ACCESS(6) | \ - ARM_ACCESS_TYPE_NO_ACCESS(7) | \ - ARM_ACCESS_TYPE_NO_ACCESS(8) | \ - ARM_ACCESS_TYPE_NO_ACCESS(9) | \ - ARM_ACCESS_TYPE_NO_ACCESS(10) | \ - ARM_ACCESS_TYPE_NO_ACCESS(11) | \ - ARM_ACCESS_TYPE_NO_ACCESS(12) | \ - ARM_ACCESS_TYPE_NO_ACCESS(13) | \ - ARM_ACCESS_TYPE_NO_ACCESS(14) | \ - ARM_ACCESS_TYPE_NO_ACCESS(15) ) - -#endif // ifdef __ASSEMBLER__ - -// ------------------------------------------------------------------------ -// XScale extras. -#define MMU_Control_BTB 0x800 - - -#endif // ifndef CYGONCE_HAL_MM_H -// End of hal_mm.h - - - - -
deleted file mode 100644 --- a/packages/hal/arm/xscale/core/current/include/hal_xscale.h +++ /dev/null @@ -1,122 +0,0 @@ -/*============================================================================= -// -// hal_xscale.h -// -// XScale Core I/O module support. -// -//============================================================================= -//####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with eCos; if not, write to the Free Software Foundation, Inc., -// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -// -// As a special exception, if other files instantiate templates or use macros -// or inline functions from this file, or you compile this file and link it -// with other works to produce a work based on this file, this file does not -// by itself cause the resulting work to be covered by the GNU General Public -// License. However the source code for this file must still be made available -// in accordance with section (3) of the GNU General Public License. -// -// This exception does not invalidate any other reasons why a work based on -// this file might be covered by the GNU General Public License. -// -// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. -// at http://sources.redhat.com/ecos/ecos-license/ -// ------------------------------------------- -//####ECOSGPLCOPYRIGHTEND#### -//============================================================================= -//#####DESCRIPTIONBEGIN#### -// -// Author(s): msalter -// Contributors: msalter -// Date: 2002-10-18 -// Purpose: -// Description: XScale core I/O modules support. -// Usage: #include <cyg/hal/hal_xscale.h> -// -//####DESCRIPTIONEND#### -// -//===========================================================================*/ -#ifndef CYGONCE_HAL_ARM_XSCALE_HAL_XSCALE_H -#define CYGONCE_HAL_ARM_XSCALE_HAL_XSCALE_H - -#include <pkgconf/system.h> - -#ifdef __ASSEMBLER__ - // Useful CPU macros - - // Delay a bit - .macro DELAY_FOR cycles, reg0 - ldr \reg0, =\cycles - subs \reg0, \reg0, #1 - subne pc, pc, #0xc - .endm - - // wait for coprocessor write complete - .macro CPWAIT reg - mrc p15,0,\reg,c2,c0,0 - mov \reg,\reg - sub pc,pc,#4 - .endm - - // Enable the BTB - .macro BTB_INIT reg - mrc p15, 0, \reg, c1, c0, 0 - orr \reg, \reg, #MMU_Control_BTB - mcr p15, 0, \reg, c1, c0, 0 - CPWAIT \reg - .endm -#else -static inline void CPWAIT(void) { - cyg_uint32 tmp; - asm volatile ("mrc p15,0,%0,c2,c0,0\n" - "mov %0,%0\n" - "sub pc,pc,#4" : "=r" (tmp)); -} -#endif - -// Override the default MMU off code. This is intended -// to be included in an inline asm statement. -#define CYGARC_HAL_MMU_OFF(__paddr__) \ - " mrc p15,0,r0,c1,c0,0\n" \ - " bic r0,r0,#0x05\n" \ - " b 99f\n" \ - " .p2align 5\n" \ - "99:\n" \ - " mcr p15,0,r0,c1,c0,0\n" \ - " mrc p15,0,r0,c2,c0,0\n" \ - " mov r0,r0\n" \ - " sub pc,pc,#4\n" \ - " mov pc," #__paddr__ "\n" - -#ifdef __ASSEMBLER__ - -#define REG8(a,b) (b) -#define REG16(a,b) (b) -#define REG32(a,b) (b) - -#else /* __ASSEMBLER__ */ - -#define REG8(a,b) ((volatile unsigned char *)((a)+(b))) -#define REG16(a,b) ((volatile unsigned short *)((a)+(b))) -#define REG32(a,b) ((volatile unsigned int *)((a)+(b))) - -extern void hal_xscale_core_init(void); -#endif /* __ASSEMBLER__ */ - -//-------------------------------------------------------------- -#endif // CYGONCE_HAL_ARM_XSCALE_HAL_XSCALE_H -// EOF hal_xscale.h
deleted file mode 100644 --- a/packages/hal/arm/xscale/core/current/include/plf_stub.h +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef CYGONCE_HAL_PLF_STUB_H -#define CYGONCE_HAL_PLF_STUB_H - -//============================================================================= -// -// plf_stub.h -// -// Platform header for GDB stub support. -// -//============================================================================= -//####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with eCos; if not, write to the Free Software Foundation, Inc., -// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -// -// As a special exception, if other files instantiate templates or use macros -// or inline functions from this file, or you compile this file and link it -// with other works to produce a work based on this file, this file does not -// by itself cause the resulting work to be covered by the GNU General Public -// License. However the source code for this file must still be made available -// in accordance with section (3) of the GNU General Public License. -// -// This exception does not invalidate any other reasons why a work based on -// this file might be covered by the GNU General Public License. -// -// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. -// at http://sources.redhat.com/ecos/ecos-license/ -// ------------------------------------------- -//####ECOSGPLCOPYRIGHTEND#### -//============================================================================= -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors:jskov -// Travis C. Furrer <furrer@mit.edu> -// Date: 2000-05-08 -// Purpose: Platform HAL stub support for Intel XScale boards. -// Usage: #include <cyg/hal/plf_stub.h> -// -//####DESCRIPTIONEND#### -// -//============================================================================= - -#include <pkgconf/hal.h> -#include <cyg/infra/cyg_type.h> // CYG_UNUSED_PARAM -#include CYGBLD_HAL_VAR_H // registers -#include <cyg/hal/hal_io.h> // IO macros -#include <cyg/hal/hal_intr.h> // Interrupt macros -#include <cyg/hal/arm_stub.h> // architecture stub support - -#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS -//---------------------------------------------------------------------------- -// Define some platform specific communication details. This is mostly -// handled by hal_if now, but we need to make sure the comms tables are -// properly initialized. - -externC void cyg_hal_plf_comms_init(void); - -#define HAL_STUB_PLATFORM_INIT_SERIAL() cyg_hal_plf_comms_init() -#define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int, (baud)) -#define HAL_STUB_PLATFORM_INTERRUPTIBLE 0 - -//---------------------------------------------------------------------------- -// Stub initializer. -#define HAL_STUB_PLATFORM_INIT() CYG_EMPTY_STATEMENT - -extern int cyg_hal_plf_hw_breakpoint(int setflag, void *addr, int len); -extern int cyg_hal_plf_hw_watchpoint(int setflag, void *addr, int len, int type); -extern int cyg_hal_plf_is_stopped_by_hardware(void **paddr); - -#define HAL_STUB_HW_BREAKPOINT_LIST_SIZE 2 -#define HAL_STUB_HW_WATCHPOINT_LIST_SIZE 2 - -#define HAL_STUB_HW_BREAKPOINT(f,a,l) cyg_hal_plf_hw_breakpoint((f),(a),(l)) -#define HAL_STUB_HW_WATCHPOINT(f,a,l,t) cyg_hal_plf_hw_watchpoint((f),(a),(l),(t)) -#define HAL_STUB_IS_STOPPED_BY_HARDWARE(p) cyg_hal_plf_is_stopped_by_hardware(&(p)) - -#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS - -// start-sanitize-xscale -externC cyg_uint32 cyg_hal_iwmmxt_coprocessor_id(void); -// end-sanitize-xscale -//----------------------------------------------------------------------------- -#endif // CYGONCE_HAL_PLF_STUB_H -// End of plf_stub.h
deleted file mode 100644 --- a/packages/hal/arm/xscale/core/current/src/xscale_misc.c +++ /dev/null @@ -1,88 +0,0 @@ -//========================================================================== -// -// xscale_misc.c -// -// HAL misc support code for Intel XScale cores. -// -//========================================================================== -//####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with eCos; if not, write to the Free Software Foundation, Inc., -// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -// -// As a special exception, if other files instantiate templates or use macros -// or inline functions from this file, or you compile this file and link it -// with other works to produce a work based on this file, this file does not -// by itself cause the resulting work to be covered by the GNU General Public -// License. However the source code for this file must still be made available -// in accordance with section (3) of the GNU General Public License. -// -// This exception does not invalidate any other reasons why a work based on -// this file might be covered by the GNU General Public License. -// -// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. -// at http://sources.redhat.com/ecos/ecos-license/ -// ------------------------------------------- -//####ECOSGPLCOPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): msalter -// Contributors: msalter -// Date: 2002-10-18 -// Purpose: XScale core HAL support -// Description: Implementations of HAL interfaces -// -//####DESCRIPTIONEND#### -// -//========================================================================*/ - -#include <pkgconf/hal.h> -#include <pkgconf/system.h> -#include CYGBLD_HAL_PLATFORM_H -#include CYGHWR_MEMORY_LAYOUT_H - -void -hal_xscale_core_init(void) -{ - // Initialize debug control unit to sane state - asm volatile ("mov r0,#0\n" - "mcr p15,0,r0,c14,c8,0\n" // ibcr0 - "mcr p15,0,r0,c14,c9,0\n" // ibcr1 - "mcr p15,0,r0,c14,c4,0\n" // dbcon - "mov r0,#0x80000000\n" - "mcr p14,0,r0,c10,c0,0\n" // dcsr - : /* no outputs */ - : /* no inputs */ - : "r0" ); -} - -// start-sanitize-xscale -// Read IWMMXT Coprocessor ID register -#ifdef CYGHWR_HAL_ARM_IWMMXT -cyg_uint32 -cyg_hal_iwmmxt_coprocessor_id(void) -{ - cyg_uint32 val; - asm volatile ("tmcr wcid,%0\n" : "=r"(val) : ); - return val; -} -#endif // CYGHWR_HAL_ARM_IWMMXT - -// end-sanitize-xscale -/*------------------------------------------------------------------------*/ -// EOF xscale_misc.c -
deleted file mode 100644 --- a/packages/hal/arm/xscale/core/current/src/xscale_stub.c +++ /dev/null @@ -1,784 +0,0 @@ -//========================================================================== -// -// xscale_stub.c -// -// HAL stub support code for Intel XScale cores. -// -//========================================================================== -//####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with eCos; if not, write to the Free Software Foundation, Inc., -// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -// -// As a special exception, if other files instantiate templates or use macros -// or inline functions from this file, or you compile this file and link it -// with other works to produce a work based on this file, this file does not -// by itself cause the resulting work to be covered by the GNU General Public -// License. However the source code for this file must still be made available -// in accordance with section (3) of the GNU General Public License. -// -// This exception does not invalidate any other reasons why a work based on -// this file might be covered by the GNU General Public License. -// -// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. -// at http://sources.redhat.com/ecos/ecos-license/ -// ------------------------------------------- -//####ECOSGPLCOPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): msalter -// Contributors: msalter -// Date: 2002-10-18 -// Purpose: XScale core stub support -// Description: Implementations of HW debugging support. -// -//####DESCRIPTIONEND#### -// -//========================================================================*/ - -#include <pkgconf/hal.h> -#include <pkgconf/system.h> -#include <cyg/infra/diag.h> -#include <cyg/hal/hal_stub.h> // Stub macros - -#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS -/*------------------------------------------------------------------------*/ -// HW Debug support - -// Define this to support two watchpoints. If not defined, one watchpoint with -// a power of two range is supported. -#define USE_TWO_WATCHPOINTS 1 - -static inline void set_ibcr0(unsigned x) -{ - asm volatile ("mcr p15,0,%0,c14,c8,0" : : "r"(x) ); -} - -static inline unsigned get_ibcr0(void) -{ - unsigned x; - asm volatile ("mrc p15,0,%0,c14,c8,0" : "=r"(x) : ); - return x; -} - -static inline void set_ibcr1(unsigned x) -{ - asm volatile ("mcr p15,0,%0,c14,c9,0" : : "r"(x) ); -} - -static inline unsigned get_ibcr1(void) -{ - unsigned x; - asm volatile ("mrc p15,0,%0,c14,c9,0" : "=r"(x) : ); - return x; -} - -static inline void set_dbr0(unsigned x) -{ - asm volatile ("mcr p15,0,%0,c14,c0,0" : : "r"(x) ); -} - -static inline unsigned get_dbr0(void) -{ - unsigned x; - asm volatile ("mrc p15,0,%0,c14,c0,0" : "=r"(x) : ); - return x; -} - -static inline void set_dbr1(unsigned x) -{ - asm volatile ("mcr p15,0,%0,c14,c3,0" : : "r"(x) ); -} - -static inline unsigned get_dbr1(void) -{ - unsigned x; - asm volatile ("mrc p15,0,%0,c14,c3,0" : "=r"(x) : ); - return x; -} - -static inline void set_dbcon(unsigned x) -{ - asm volatile ("mcr p15,0,%0,c14,c4,0" : : "r"(x) ); -} - -static inline unsigned get_dbcon(void) -{ - unsigned x; - asm volatile ("mrc p15,0,%0,c14,c4,0" : "=r"(x) : ); - return x; -} - -static inline void set_dcsr(unsigned x) -{ - asm volatile ("mcr p14,0,%0,c10,c0,0" : : "r"(x) ); -} - -static inline unsigned get_dcsr(void) -{ - unsigned x; - asm volatile ("mrc p14,0,%0,c10,c0,0" : "=r"(x) : ); - return x; -} - -int cyg_hal_plf_hw_breakpoint(int setflag, void *vaddr, int len) -{ - unsigned int addr = (unsigned)vaddr; - - if (setflag) { - if (!(get_ibcr0() & 1)) - set_ibcr0(addr | 1); - else if (!(get_ibcr1() & 1)) - set_ibcr1(addr | 1); - else - return -1; - } else { - unsigned x = (addr | 1); - if (get_ibcr0() == x) - set_ibcr0(0); - else if (get_ibcr1() == x) - set_ibcr1(0); - else - return -1; - } - - return 0; -} - -#define WATCH_MODE_NONE 0 -#define WATCH_MODE_WRITE 1 -#define WATCH_MODE_ACCESS 2 -#define WATCH_MODE_READ 3 - -#ifndef HAL_STUB_HW_WATCHPOINT_LIST_SIZE -#error -#endif - -int cyg_hal_plf_hw_watchpoint(int setflag, void *vaddr, int len, int type) -{ - unsigned int mode, addr = (unsigned)vaddr; - unsigned dbcon = get_dbcon(); -#if HAL_STUB_HW_WATCHPOINT_LIST_SIZE == 1 - unsigned int mask, bit_nr; - - mask = 0x80000000; - bit_nr = 31; - while (bit_nr) { - if (len & mask) - break; - bit_nr--; - mask >>= 1; - } - mask = ~(0xffffffff << bit_nr); -#endif - - if (setflag) { - /* set a watchpoint */ - if (type == 2) - mode = WATCH_MODE_WRITE; // break on write - else if (type == 3) - mode = WATCH_MODE_READ; // break on read - else if (type == 4) - mode = WATCH_MODE_ACCESS; // break on any access - else - return 1; - -#if HAL_STUB_HW_WATCHPOINT_LIST_SIZE == 1 - mode |= 0x100; -#endif - - if (!(dbcon & 3)) { - set_dbr0(addr); -#if HAL_STUB_HW_WATCHPOINT_LIST_SIZE == 1 - set_dbr1(mask); -#endif - set_dbcon(dbcon | mode); -#if HAL_STUB_HW_WATCHPOINT_LIST_SIZE == 2 - } else if (!(dbcon & (3 << 2))) { - set_dbr1(addr); - set_dbcon(dbcon | (mode << 2)); -#endif - } else - return 1; - - } else { - /* clear a watchpoint */ - if ((dbcon & 3) && get_dbr0() == addr) - set_dbcon(dbcon & ~3); -#if HAL_STUB_HW_WATCHPOINT_LIST_SIZE == 2 - else if ((dbcon & (3 << 2)) && get_dbr1() == addr) - set_dbcon(dbcon & ~(3 << 2)); -#endif - else - return 1; - } - return 0; -} - -#if HAL_STUB_HW_WATCHPOINT_LIST_SIZE == 2 - -// The XScale hardware does not provide a way of positively identinfying -// which of the two watchpoints triggered and exception. The following -// code makes a best effort at determining this by decoding the opcode -// of the instruction which caused the watchpoint trigger. It is *not* -// 100% reliable. - -// Some bits common to most ld/st instructions. -#define I_bit (1 << 25) -#define P_bit (1 << 24) -#define U_bit (1 << 23) -#define B_bit (1 << 22) -#define W_bit (1 << 21) -#define L_bit (1 << 20) - -// Return non-zero if opcode at given PC is a store instruction for -// purposes of triggering watchpoints. -static int -is_store_insn(unsigned pc) -{ - unsigned opcode = *(unsigned *)pc; - - if ((opcode & 0x0fb00ff0) == 0x01000090) { - // SWP xxxx 0001 0B00 _Rn_ _Rd_ 0000 1001 _Rm_ - return 1; - } - - if ((opcode & 0x0c000000) == 0x04000000) { - // LDR/STR xxxx 010P UBWL _Rn_ _Rd_ iiii iiii iiii - // LDR/STR xxxx 011P UBWL _Rn_ _Rd_ ssss sSh0 _Rm_ - // Addressing mode 2, Load/Store word or unsigned byte - return (opcode & L_bit) == 0; - } - - if ((opcode & 0x0e000090) == 0x00000090 && - (opcode & 0x00000060) && - ((opcode & (1 << 22)) || (opcode & 0x00000f00) == 0) && - ((opcode & (P_bit | W_bit)) != W_bit)) { - // LDR/STR xxxx 000P U1WL _Rn_ _Rd_ iiii 1SH1 iiii - // LDR/STR xxxx 000P U0WL _Rn_ _Rd_ 0000 1SH1 _Rm_ - // Addressing Mode 3, Load/Store halfword, load signed byte - return (opcode & L_bit) == 0; - } - - if ((opcode & 0x0e000000) == 0x08000000) { - // LDM/STM xxxx 100P USWL _Rn_ rrrr rrrr rrrr rrrr - return (opcode & L_bit) == 0; - } - - if ((opcode & 0x0e000000) == 0x0c000000) { - // LDC/STC xxxx 110P UNWL _Rn_ CRd_ CP#_ iiii iiii - return (opcode & L_bit) == 0; - } - - return 0; -} - -static int -is_thumb_store_insn(unsigned pc) -{ - unsigned short opcode = *(unsigned short *)pc; - - opcode &= 0xfe00; - - if (opcode == 0xb400) - return 1; // PUSH - if (opcode == 0x5000) - return 1; // STR Rd, [Rn, Rm] - if (opcode == 0x5400) - return 1; // STRB Rd, [Rn, Rm] - if (opcode == 0x5200) - return 1; // STRH Rd, [Rn, Rm] - - opcode &= 0xf800; - if (opcode == 0xc000) - return 1; // STM - if (opcode == 0x6000) - return 1; // STR Rd, [Rn, #5bit_offset] - if (opcode == 0x9000) - return 1; // STR Rd, [SP, #8bit_offset] - if (opcode == 0x7000) - return 1; // STRB Rd, [Rn, #5bit_offset] - if (opcode == 0x8000) - return 1; // STRH Rd, [Rn, #5bit_offset] - - return 0; -} - -// Return non-zero if given waddr matches an access at addr. -static int -waddr_match(unsigned waddr, unsigned addr, int size) -{ - if (addr <= waddr && waddr < (addr + size)) - return 1; - return 0; -} - -// Return non-zero if given value matches value at watchpoint address. -static int -wval_match(unsigned waddr, unsigned val, int size) -{ - unsigned wval = *(unsigned *)(waddr & ~3); - int i; - - if (size == 4) - return (wval == val); - if (size == 2) { - val &= 0xffff; - return ((wval & 0xffff) == val || ((wval >> 16) == val)); - } - if (size == 1) { - val &= 0xff; - for (i = 0; i < 4; i++) { - if ((wval & 0xff) == val) - return 1; - wval >>= 8; - } - } - return 0; -} - -static char _sztab[8] = { 4, 2, 1, 1, 4, 2, 1, 2 }; - -// Given the watch addresses and watch modes for each of the enabled -// watchpoints, figure out which one triggered the current exception. -static unsigned -find_thumb_watch_address(unsigned wa0, int mode0, unsigned wa1, int mode1) -{ - unsigned pc = get_register(PC) - 4; - unsigned short opcode = *(unsigned short *)pc; - unsigned short opcode_f8, opcode_fe; - unsigned val, wd0, wd1, addr = 0; - int is_store, use_val, i, offset, size, Rn, Rd, Rm; - - opcode_f8 = opcode & 0xf800; - opcode_fe = opcode & 0xfe00; - - size = 0; - is_store = 0; - val = use_val = 0; - - switch (opcode_f8) { - case 0xc000: // STMIA Rn!, <list> - is_store = 1; - case 0xc800: // LDMIA Rn!, <list> - Rn = (opcode >> 8) & 7; - is_store = (opcode & 0x800) == 0; - for (i = 0; i < 8; i++) - if (opcode & (1 << i)) - size += 4; - if (!is_store && (opcode & (1 << Rn))) { - // We can't reconstruct address from opcode because base - // was destroyed. Best we can do is try to match data at - // watchpoint addresses with data in one of the registers. - wd0 = *(unsigned *)(wa0 & ~3); - wd1 = *(unsigned *)(wa1 & ~3); - if (wd0 != wd1) { - for (i = size = 0; i < 8; i++) { - if (opcode & (1 << i)) { - val = get_register(i); - if (val == wd0) - return wa0; - else if (val == wd1) - return wa1; - } - } - } - return wa0; // 50% chance of being right - } else - addr = get_register(Rn) - size; - break; - case 0x6000: // STR Rd, [Rn, #5bit] - case 0x7000: // STRB Rd, [Rn, #5bit] - case 0x8000: // STRH Rd, [Rn, #5bit] - is_store = 1; - case 0x6800: // LDR Rd, [Rn, #5bit] - case 0x7800: // LDRB Rd, [Rn, #5bit] - case 0x8800: // LDRH Rd, [Rn, #5bit] - Rd = opcode & 7; - Rn = (opcode >> 3) & 7; - if ((opcode & 0xf000) == 0x6000) - size = 4; - else if ((opcode & 0xf000) == 0x8000) - size = 2; - else - size = 1; - if (!is_store && Rd == Rn) { - // We can't reconstruct address from opcode because base - // or offset register was destroyed. Best we can do is try - // to match data at watchpoint addresses with data in Rd. - use_val = 1; - val = get_register(Rd); - } else { - offset = ((opcode >> 6) & 0x1f) * size; - addr = get_register(Rn) + offset; - } - break; - case 0x4800: // LDR Rd, [PC, #8bit] - size = 4; - addr = pc + 4 + ((opcode & 0xff) * 4); - break; - case 0x9000: // STR Rd, [SP, #8bit] - is_store = 1; - case 0x9800: // LDR Rd, [SP, #8bit] - size = 4; - addr = get_register(SP) + ((opcode & 0xff) * 4); - break; - default: - switch (opcode_fe) { - case 0x5000: // STR Rd, [Rn, Rm] - case 0x5400: // STRB Rd, [Rn, Rm] - case 0x5200: // STRH Rd, [Rn, Rm] - is_store = 1; - case 0x5600: // LDRSB Rd, [Rn, Rm] - case 0x5800: // LDR Rd, [Rn, Rm] - case 0x5c00: // LDRB Rd, [Rn, Rm] - case 0x5a00: // LDRH Rd, [Rn, Rm] - case 0x5e00: // LDRSH Rd, [Rn, Rm] - Rd = opcode & 7; - Rn = (opcode >> 3) & 7; - Rm = (opcode >> 6) & 7; - size = _sztab[(opcode >> 9) & 7]; - if (!is_store && (Rd == Rn || Rd == Rm)) { - // We can't reconstruct address from opcode because base - // or offset register was destroyed. Best we can do is try - // to match data at watchpoint addresses with data in Rd. - use_val = 1; - val = get_register(Rd); - } else - addr = Rn + Rm; - break; - case 0xb400: // PUSH - is_store = 1; - case 0xbc00: // POP - for (i = 0; i < 9; i++) - if (opcode & (1 << i)) - size += 4; - addr = get_register(SP); - if (!is_store) - addr -= size; - break; - } - break; - } - if (use_val) { - // We can read from watchpoint addresses and compare against - // whatever is in the Rd from a load. This is not perfect, - // but its the best we can do. - if (wval_match(wa0, val, size)) - return wa0; - if (wval_match(wa1, val, size)) - return wa1; - } else if (size) { - if (waddr_match(wa0, addr, size)) - return wa0; - if (waddr_match(wa1, addr, size)) - return wa1; - } - return wa0; // should never happen, but return valid address -} - -// Given the watch addresses and watch modes for each of the enabled -// watchpoints, figure out which one triggered the current exception. -static unsigned -find_watch_address(unsigned wa0, int mode0, unsigned wa1, int mode1) -{ - unsigned pc = get_register(PC) - 4; - unsigned cpsr = get_register(PS); - unsigned opcode, Rn, Rd, Rm, base, addr, val, wd0, wd1; - int is_store, use_val, i, offset, shift, size; - - if (cpsr & CPSR_THUMB_ENABLE) - is_store = is_thumb_store_insn(pc); - else - is_store = is_store_insn(pc); - - // First try the easy cases where all we need to know is whether or - // not the instruction is a load or store. - if ((mode0 == WATCH_MODE_READ && mode1 == WATCH_MODE_WRITE) || - (mode1 == WATCH_MODE_READ && mode0 == WATCH_MODE_WRITE)) { - if (is_store) - return (mode0 == WATCH_MODE_WRITE) ? wa0 : wa1; - else - return (mode0 == WATCH_MODE_READ) ? wa0 : wa1; - } - if ((mode0 == WATCH_MODE_READ && is_store) || - (mode0 == WATCH_MODE_WRITE && !is_store)) - return wa1; - if ((mode1 == WATCH_MODE_READ && is_store) || - (mode1 == WATCH_MODE_WRITE && !is_store)) - return wa0; - - // Okay. Now try to figure out address by decoding the opcode. - - if (cpsr & CPSR_THUMB_ENABLE) - return find_thumb_watch_address(wa0, mode0, wa1, mode1); - - opcode = *(unsigned *)pc; - Rn = (opcode >> 16) & 15; - Rd = (opcode >> 12) & 15; - Rm = opcode & 15; - - size = use_val = 0; - addr = 0; - - if ((opcode & 0x0fb00ff0) == 0x01000090) { - // SWP xxxx 0001 0B00 _Rn_ _Rd_ 0000 1001 _Rm_ - addr = get_register(Rn); - size = (opcode & B_bit) ? 1 : 4; - } else if ((opcode & 0x0c000000) == 0x04000000) { - // LDR/STR xxxx 010P UBWL _Rn_ _Rd_ iiii iiii iiii - // LDR/STR xxxx 011P UBWL _Rn_ _Rd_ ssss sSh0 _Rm_ - // Addressing mode 2, Load/Store word or unsigned byte - - size = (opcode & B_bit) ? 1 : 4; - - if ((opcode & (P_bit | W_bit)) == (P_bit | W_bit)) { - // This is easy because address is written back to Rn - addr = get_register(Rn); - } else if (!is_store && - (Rd == Rn || ((opcode & I_bit) && Rd == Rm))) { - // We can't reconstruct address from opcode because base - // or offset register was destroyed. Best we can do is try - // to match data at watchpoint addresses with data in Rd. - use_val = 1; - val = get_register(Rd); - } else { - if (opcode & I_bit) { - shift = (opcode >> 7) & 0x1f; - offset = get_register(Rm); - switch ((opcode >> 5) & 3) { - case 0: - offset <<= shift; - break; - case 1: - offset >>= shift; - offset &= (0xffffffffU >> shift); - break; - case 2: - offset >>= shift; - break; - case 3: - if (shift) { - for (i = 0; i < shift; i++) - offset = ((offset >> 1) & 0x7fffffff) | ((offset & 1) << 31); - } else { - offset >>= 1; - offset &= 0x80000000; - offset |= ((cpsr & 0x20000000) << 2); - } - break; - } - } else - offset = opcode & 0xfff; - - if ((opcode & U_bit) == 0) - offset = -offset; - - if (Rn == 15) - base = pc + 8; - else - base = get_register(Rn); - - if (opcode & P_bit) - addr = base + offset; // pre-index - else - addr = base - offset; // post-index writeback - - size = (opcode & B_bit) ? 1 : 4; - } - } else if ((opcode & 0x0e000090) == 0x00000090 && - (opcode & 0x00000060) && - ((opcode & (1 << 22)) || (opcode & 0x00000f00) == 0) && - ((opcode & (P_bit | W_bit)) != W_bit)) { - // LDR/STR xxxx 000P U1WL _Rn_ _Rd_ iiii 1SH1 iiii - // LDR/STR xxxx 000P U0WL _Rn_ _Rd_ 0000 1SH1 _Rm_ - // Addressing Mode 3, Load/Store halfword, load signed byte - - size = (opcode & (1 << 5)) ? 2 : 1; - - if ((opcode & (P_bit | W_bit)) == (P_bit | W_bit)) { - // This is easy because address is written back to Rn - addr = get_register(Rn); - } if (!is_store && - (Rd == Rn || ((opcode & (1 << 22)) && Rd == Rm))) { - // We can't reconstruct address from opcode because base - // or offset register was destroyed. Best we can do is try - // to match data at watchpoint addresses with data in Rd. - use_val = 1; - val = get_register(Rd); - } else { - if (opcode & (1 << 22)) - offset = ((opcode >> 4) & 0xf0) | (opcode & 0x0f); - else - offset = get_register(opcode & 15); - - if ((opcode & U_bit) == 0) - offset = -offset; - - if (Rn == 15) - base = pc + 8; - else - base = get_register(Rn); - - if (opcode & P_bit) - addr = base + offset; // pre-index - else - addr = base - offset; // post-index writeback - } - } else if ((opcode & 0x0e000000) == 0x08000000) { - // LDM/STM xxxx 100P USWL _Rn_ rrrr rrrr rrrr rrrr - for (i = size = 0; i < 16; i++) - if (opcode & (1 << i)) - size += 4; - - base = get_register(Rn); - if (!is_store && (opcode & (1 << Rn))) { - // We can't reconstruct address from opcode because base - // was destroyed. Best we can do is try to match data at - // watchpoint addresses with data in one of the registers. - wd0 = *(unsigned *)(wa0 & ~3); - wd1 = *(unsigned *)(wa1 & ~3); - if (wd0 != wd1) { - for (i = size = 0; i < 16; i++) { - if (opcode & (1 << i)) { - val = get_register(i); - if (val == wd0) - return wa0; - else if (val == wd1) - return wa1; - } - } - } - return wa0; // 50% chance of being right - } else { - if (opcode & U_bit){ - if (opcode & W_bit) - addr = base - size; - else - addr = base; - if (opcode & P_bit) - addr += 4; - } else { - if (opcode & W_bit) - addr = base; - else - addr = base - size; - if ((opcode & P_bit) == 0) - addr += 4; - } - } - } else if ((opcode & 0x0e000000) == 0x0c000000) { - // LDC/STC xxxx 110P UNWL _Rn_ CRd_ CP#_ iiii iiii - size = 4; - offset = (opcode & 0xff) * 4; - if ((opcode & U_bit) == 0) - offset = -offset; - if ((opcode & P_bit) && (opcode & W_bit)) - addr = get_register(Rn); - else - addr = get_register(Rn) + offset; - } - - if (use_val) { - // We can read from watchpoint addresses and compare against - // whatever is in the Rd from a load. This is not perfect, - // but its the best we can do. - if (wval_match(wa0, val, size)) - return wa0; - if (wval_match(wa1, val, size)) - return wa1; - } else { - if (waddr_match(wa0, addr, size)) - return wa0; - if (waddr_match(wa1, addr, size)) - return wa1; - } - return wa0; // should never happen, but return valid address -} -#endif - -// Return indication of whether or not we stopped because of a -// watchpoint or hardware breakpoint. If stopped by a watchpoint, -// also set '*data_addr_p' to the data address which triggered the -// watchpoint. -int cyg_hal_plf_is_stopped_by_hardware(void **data_addr_p) -{ - unsigned fsr, dcsr, dbcon, kind = 0; - - // Check for debug event - asm volatile ("mrc p15,0,%0,c5,c0,0" : "=r"(fsr) : ); - if ((fsr & 0x200) == 0) - return HAL_STUB_HW_STOP_NONE; - - // There was a debug event. Check the MOE for details - dcsr = get_dcsr(); - switch ((dcsr >> 2) & 7) { - case 1: // HW breakpoint - case 3: // BKPT breakpoint - return HAL_STUB_HW_STOP_BREAK; - case 2: // Watchpoint - dbcon = get_dbcon(); -#if HAL_STUB_HW_WATCHPOINT_LIST_SIZE == 2 - if (dbcon & 0x100) { -#endif - if ((kind = (dbcon & 3)) != WATCH_MODE_NONE) - *data_addr_p = (void *)get_dbr0(); -#if HAL_STUB_HW_WATCHPOINT_LIST_SIZE == 2 - } else { - // This can get tricky because the debug unit offers no way to - // tell which watchpoint triggered. - if ((kind = (dbcon & 3)) == WATCH_MODE_NONE) { - if ((kind = ((dbcon >> 2) & 3)) != WATCH_MODE_NONE) - *data_addr_p = (void *)get_dbr1(); - } else if ((kind = ((dbcon >> 2) & 3)) == WATCH_MODE_NONE) { - if ((kind = (dbcon & 3)) != WATCH_MODE_NONE) - *data_addr_p = (void *)get_dbr0(); - } else { - // This is the tricky part. We have to look at the trapping - // opcode (which has already issued) to try to see if we can - // tell which watchpoint triggered. Turn off watchpoints while - // we figure this out. - set_dcsr(dcsr & ~0x80000000); - *data_addr_p = (void *)find_watch_address(get_dbr0(), dbcon & 3, - get_dbr1(), (dbcon >> 2) & 3); - set_dcsr(dcsr); - - if (*data_addr_p == (void *)get_dbr0()) - kind = dbcon & 3; - else if (*data_addr_p == (void *)get_dbr1()) - kind = (dbcon >> 2) & 3; - else - kind = WATCH_MODE_NONE; - } - } -#endif - if (kind == WATCH_MODE_WRITE) - return HAL_STUB_HW_STOP_WATCH; - if (kind == WATCH_MODE_ACCESS) - return HAL_STUB_HW_STOP_AWATCH; - if (kind == WATCH_MODE_READ) - return HAL_STUB_HW_STOP_RWATCH; - // should never get here - break; - } - return HAL_STUB_HW_STOP_NONE; -} -#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS - -/*------------------------------------------------------------------------*/ -// EOF xscale_stub.c -
new file mode 100644 --- /dev/null +++ b/packages/hal/arm/xscale/cores/current/ChangeLog @@ -0,0 +1,48 @@ +2002-09-23 Mark Salter <msalter@redhat.com> + + * include/hal_cache.h: Remove mmap-related externs which don't belong + here. + +2002-09-20 Mark Salter <msalter@redhat.com> + + * src/xscale_stub.c: Fill in holes in logic used to decide which + of two watchpoints caused exception. + +2002-09-19 Mark Salter <msalter@redhat.com> + + * Initial checkin. + +//=========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//===========================================================================
new file mode 100644 --- /dev/null +++ b/packages/hal/arm/xscale/cores/current/cdl/hal_arm_xscale_core.cdl @@ -0,0 +1,65 @@ +# ==================================================================== +# +# hal_arm_xscale_core.cdl +# +# Intel XScale architectural HAL package configuration data +# +# ==================================================================== +#####ECOSGPLCOPYRIGHTBEGIN#### +## ------------------------------------------- +## This file is part of eCos, the Embedded Configurable Operating System. +## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +## +## eCos is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free +## Software Foundation; either version 2 or (at your option) any later version. +## +## eCos is distributed in the hope that it will be useful, but WITHOUT ANY +## WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +## for more details. +## +## You should have received a copy of the GNU General Public License along +## with eCos; if not, write to the Free Software Foundation, Inc., +## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +## +## As a special exception, if other files instantiate templates or use macros +## or inline functions from this file, or you compile this file and link it +## with other works to produce a work based on this file, this file does not +## by itself cause the resulting work to be covered by the GNU General Public +## License. However the source code for this file must still be made available +## in accordance with section (3) of the GNU General Public License. +## +## This exception does not invalidate any other reasons why a work based on +## this file might be covered by the GNU General Public License. +## +## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +## at http://sources.redhat.com/ecos/ecos-license/ +## ------------------------------------------- +#####ECOSGPLCOPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): msalter +# Original data: msalter +# Contributors: +# Date: 2002-10-18 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== +cdl_package CYGPKG_HAL_ARM_XSCALE_CORE { + display "Intel XScale Core Support" + parent CYGPKG_HAL_ARM + hardware + include_dir cyg/hal + define_header hal_arm_xscale_core.h + description " + This HAL variant package provides generic support common + to Intel XScale CPU cores. It is also necessary to select + a specific target platform and CPU HAL package." + + implements CYGINT_HAL_ARM_ARCH_XSCALE + + compile xscale_misc.c xscale_stub.c +}
new file mode 100644 --- /dev/null +++ b/packages/hal/arm/xscale/cores/current/include/hal_cache.h @@ -0,0 +1,387 @@ +#ifndef CYGONCE_HAL_CACHE_H +#define CYGONCE_HAL_CACHE_H + +//============================================================================= +// +// hal_cache.h +// +// HAL cache control API +// +//============================================================================= +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): msalter +// Contributors: +// Date: 2001-12-03 +// Purpose: Cache control API +// Description: The macros defined here provide the HAL APIs for handling +// cache control operations. +// Usage: +// #include <cyg/hal/hal_cache.h> +// ... +// +// +//####DESCRIPTIONEND#### +// +//============================================================================= + +#include <pkgconf/system.h> // System-wide configuration info +#include <cyg/hal/hal_io.h> // DCACHE_FLUSH_AREA +#include <cyg/infra/cyg_type.h> +#include CYGBLD_HAL_VAR_H +#include <cyg/hal/hal_mmu.h> + +//----------------------------------------------------------------------------- +// Cache dimensions + +#define HAL_DCACHE_SIZE 0x8000 // Size of data cache in bytes +#define HAL_DCACHE_LINE_SIZE 32 // Size of a data cache line +#define HAL_DCACHE_WAYS 32 // Associativity of the cache +#define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS)) + +#define HAL_ICACHE_SIZE 0x8000 // Size of icache in bytes +#define HAL_ICACHE_LINE_SIZE 32 // Size of ins cache line +#define HAL_ICACHE_WAYS 32 // Associativity of the cache +#define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS)) + +//----------------------------------------------------------------------------- +// Global control of Instruction cache + +// Enable the instruction cache +#define HAL_ICACHE_ENABLE() \ +CYG_MACRO_START \ + asm volatile ( \ + "mrc p15,0,r1,c1,c0,0;" \ + "orr r1,r1,#0x1000;" /* enable ICache */ \ + "mcr p15,0,r1,c1,c0,0;" \ + : \ + : \ + : "r1" /* Clobber list */ \ + ); \ +CYG_MACRO_END + +// Disable the instruction cache (and invalidate it, required semanitcs) +#define HAL_ICACHE_DISABLE() \ +CYG_MACRO_START \ + asm volatile ( \ + "mrc p15,0,r1,c1,c0,0;" \ + "bic r1,r1,#0x1000;" /* disable Icache */ \ + "mcr p15,0,r1,c1,c0,0;" \ + "mcr p15,0,r1,c7,c5,0;" /* invalidate instruction cache */ \ + "nop;" /* next few instructions may be via cache */ \ + "nop;" \ + "nop;" \ + "nop;" \ + "nop;" \ + "nop" \ + : \ + : \ + : "r1" /* Clobber list */ \ + ); \ +CYG_MACRO_END + +// Query the state of the instruction cache +#define HAL_ICACHE_IS_ENABLED(_state_) \ +CYG_MACRO_START \ + register cyg_uint32 reg; \ + asm volatile ("mrc p15,0,%0,c1,c0,0" \ + : "=r"(reg) \ + : \ + ); \ + (_state_) = (0 != (0x1000 & reg)); /* Bit 12 is ICache enable */ \ +CYG_MACRO_END + +// Invalidate the entire cache +#define HAL_ICACHE_INVALIDATE_ALL() \ +CYG_MACRO_START \ + asm volatile ( \ + "mcr p15,0,r1,c7,c5,0;" /* clear instruction cache */ \ + "mcr p15,0,r1,c8,c5,0;" /* flush I TLB only */ \ + /* cpuwait */ \ + "mrc p15,0,r1,c2,c0,0;" /* arbitrary read */ \ + "mov r1,r1;" \ + "sub pc,pc,#4;" \ + "nop;" /* next few instructions may be via cache */ \ + "nop;" \ + "nop;" \ + "nop;" \ + "nop;" \ + "nop" \ + : \ + : \ + : "r1" /* Clobber list */ \ + ); \ +CYG_MACRO_END + +// Synchronize the contents of the cache with memory. +// (which includes flushing out pending writes) +#define HAL_ICACHE_SYNC() \ +CYG_MACRO_START \ + HAL_DCACHE_SYNC(); /* ensure data gets to RAM */ \ + HAL_ICACHE_INVALIDATE_ALL(); /* forget all we know */ \ +CYG_MACRO_END + +// Set the instruction cache refill burst size +//#define HAL_ICACHE_BURST_SIZE(_size_) +// This feature is not available on the SA11X0. + +// Load the contents of the given address range into the instruction cache +// and then lock the cache so that it stays there. +//#define HAL_ICACHE_LOCK(_base_, _size_) +// This feature is not available on the SA11X0. + +// Undo a previous lock operation +//#define HAL_ICACHE_UNLOCK(_base_, _size_) +// This feature is not available on the SA11X0. + +// Unlock entire cache +//#define HAL_ICACHE_UNLOCK_ALL() +// This feature is not available on the SA11X0. + +//----------------------------------------------------------------------------- +// Instruction cache line control + +// Invalidate cache lines in the given range without writing to memory. +//#define HAL_ICACHE_INVALIDATE( _base_ , _size_ ) +// This feature is not available on the SA11X0. + +//----------------------------------------------------------------------------- +// Global control of data cache + +// Enable the data cache +#define HAL_DCACHE_ENABLE() \ +CYG_MACRO_START \ + asm volatile ( \ + "mrc p15,0,r1,c7,c10,4;" /* drain write buffer */ \ + "mrc p15,0,r1,c1,c0,0;" \ + "orr r1,r1,#0x0007;" /* enable DCache (also ensures the */ \ + /* MMU and alignment faults are */ \ + /* enabled) */ \ + "mcr p15,0,r1,c1,c0,0;" \ + "mrc p15,0,r1,c1,c0,1;" \ + "bic r1,r1,#1;" \ + "mcr p15,0,r1,c1,c0,1;" \ + : \ + : \ + : "r1" /* Clobber list */ \ + ); \ +CYG_MACRO_END + +// Disable the data cache (and invalidate it, required semanitcs) +#define HAL_DCACHE_DISABLE() \ +CYG_MACRO_START \ + asm volatile ( \ + "mrc p15,0,r1,c1,c0,0;" /* disable cache */ \ + "bic r1,r1,#4;" \ + "mcr p15,0,r1,c1,c0,0;" \ + "mrc p15,0,r1,c1,c0,1;" /* disable coalescing */ \ + "orr r1,r1,#1;" \ + "mcr p15,0,r1,c1,c0,1;" \ + "mcr p15,0,r1,c7,c6,0;" /* invalidate data cache */ \ + /* cpuwait */ \ + "mrc p15,0,r1,c2,c0,0;" /* arbitrary read */ \ + "mov r1,r1;" \ + "sub pc,pc,#4;" \ + : \ + : \ + : "r1" /* Clobber list */ \ + ); \ +CYG_MACRO_END + +// Query the state of the data cache +#define HAL_DCACHE_IS_ENABLED(_state_) \ +CYG_MACRO_START \ + register int reg; \ + asm volatile ("mrc p15,0,%0,c1,c0,0" \ + : "=r"(reg) \ + : \ + /*:*/ \ + ); \ + (_state_) = (0 != (4 & reg)); /* Bit 2 is DCache enable */ \ +CYG_MACRO_END + +// Flush the entire dcache (and then both TLBs, just in case) +#define HAL_DCACHE_INVALIDATE_ALL() \ +CYG_MACRO_START /* this macro can discard dirty cache lines. */ \ + /* this macro can discard dirty cache lines. */ \ + asm volatile ( \ + "mcr p15,0,r1,c7,c6,0;" /* invalidate data cache */ \ + "mcr p15,0,r1,c8,c7,0;" /* flush I+D TLBs */ \ + : \ + : \ + : "r1" /* Clobber list */ \ + ); \ +CYG_MACRO_END + + +// Synchronize the contents of the cache with memory. +#define HAL_DCACHE_SYNC() \ +CYG_MACRO_START \ + /* The best way to evict a dirty line is by using the */ \ + /* line allocate operation on non-existent memory. */ \ + asm volatile ( \ + "mov r0, %0;" /* cache flush region */ \ + "add r1, r0, #0x8800;" /* 32KB main + 2KB mini cache */ \ + "667: " \ + "mcr p15,0,r0,c7,c2,5;" /* allocate a line */ \ + "add r0, r0, #32;" /* 32 bytes/line */ \ + "teq r1, r0;" \ + "bne 667b;" \ + "mcr p15,0,r0,c7,c6,0;" /* invalidate data cache */ \ + /* cpuwait */ \ + "mrc p15,0,r1,c2,c0,0;" /* arbitrary read */ \ + "mov r1,r1;" \ + "sub pc,pc,#4;" \ + "mcr p15,0,r0,c7,c10,4;" /* and drain the write buffer */ \ + /* cpuwait */ \ + "mrc p15,0,r1,c2,c0,0;" /* arbitrary read */ \ + "mov r1,r1;" \ + "sub pc,pc,#4;" \ + "nop" \ + : \ + : "i" (DCACHE_FLUSH_AREA) \ + : "r0","r1" /* Clobber list */ \ + ); \ +CYG_MACRO_END + +// Set the data cache refill burst size +//#define HAL_DCACHE_BURST_SIZE(_size_) +// This feature is not available on the SA11X0. + +// Set the data cache write mode +//#define HAL_DCACHE_WRITE_MODE( _mode_ ) +// This feature is not available on the SA11X0. + +#define HAL_DCACHE_WRITETHRU_MODE 0 +#define HAL_DCACHE_WRITEBACK_MODE 1 + +// Get the current writeback mode - or only writeback mode if fixed +#define HAL_DCACHE_QUERY_WRITE_MODE( _mode_ ) CYG_MACRO_START \ + _mode_ = HAL_DCACHE_WRITEBACK_MODE; \ +CYG_MACRO_END + +// Load the contents of the given address range into the data cache +// and then lock the cache so that it stays there. +//#define HAL_DCACHE_LOCK(_base_, _size_) +// This feature is not available on the SA11X0. + +// Undo a previous lock operation +//#define HAL_DCACHE_UNLOCK(_base_, _size_) +// This feature is not available on the SA11X0. + +// Unlock entire cache +//#define HAL_DCACHE_UNLOCK_ALL() +// This feature is not available on the SA11X0. + +//----------------------------------------------------------------------------- +// Data cache line control + +// Allocate cache lines for the given address range without reading its +// contents from memory. +//#define HAL_DCACHE_ALLOCATE( _base_ , _size_ ) +// This feature is not available on the SA11X0. + +// Write dirty cache lines to memory and invalidate the cache entries +// for the given address range. +#define HAL_DCACHE_FLUSH( _base_ , _size_ ) \ +CYG_MACRO_START \ + HAL_DCACHE_STORE( _base_ , _size_ ); \ + HAL_DCACHE_INVALIDATE( _base_ , _size_ ); \ +CYG_MACRO_END + +// Invalidate cache lines in the given range without writing to memory. +#define HAL_DCACHE_INVALIDATE( _base_ , _size_ ) \ +CYG_MACRO_START \ + register int addr, enda; \ + for ( addr = (~(HAL_DCACHE_LINE_SIZE - 1)) & (int)(_base_), \ + enda = (int)(_base_) + (_size_); \ + addr < enda ; \ + addr += HAL_DCACHE_LINE_SIZE ) \ + { \ + asm volatile ( \ + "mcr p15,0,%0,c7,c6,1;" /* flush entry away */ \ + : \ + : "r"(addr) \ + : "memory" \ + ); \ + } \ +CYG_MACRO_END + +// Write dirty cache lines to memory for the given address range. +#define HAL_DCACHE_STORE( _base_ , _size_ ) \ +CYG_MACRO_START \ + register int addr, enda; \ + for ( addr = (~(HAL_DCACHE_LINE_SIZE - 1)) & (int)(_base_), \ + enda = (int)(_base_) + (_size_); \ + addr < enda ; \ + addr += HAL_DCACHE_LINE_SIZE ) \ + { \ + asm volatile ("mcr p15,0,%0,c7,c10,1;" /* push entry to RAM */ \ + : \ + : "r"(addr) \ + : "memory" \ + ); \ + } \ + /* and also drain the write buffer */ \ + asm volatile ( \ + "mov r1,#0;" \ + "mcr p15,0,r1,c7,c10,4;" \ + : \ + : \ + : "r1", "memory" /* Clobber list */ \ + ); \ +CYG_MACRO_END + +// Preread the given range into the cache with the intention of reading +// from it later. +//#define HAL_DCACHE_READ_HINT( _base_ , _size_ ) +// This feature is available on the SA11X0, but due to tricky +// coherency issues with the read buffer (see SA11X0 developer's +// manual page 6-7) we don't bother to implement it here. + +// Preread the given range into the cache with the intention of writing +// to it later. +//#define HAL_DCACHE_WRITE_HINT( _base_ , _size_ ) +// This feature is not available on the SA11X0. + +// Allocate and zero the cache lines associated with the given range. +//#define HAL_DCACHE_ZERO( _base_ , _size_ ) +// This feature is not available on the SA11X0. + + +//----------------------------------------------------------------------------- +#endif // ifndef CYGONCE_HAL_CACHE_H +// End of hal_cache.h
new file mode 100644 --- /dev/null +++ b/packages/hal/arm/xscale/cores/current/include/hal_mm.h @@ -0,0 +1,230 @@ +#ifndef CYGONCE_HAL_MM_H +#define CYGONCE_HAL_MM_H + +//============================================================================= +// +// hal_mm.h +// +// Intel XScale MM common definitions +// +//============================================================================= +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): msalter +// Contributors: gthomas +// Date: 2001-12-03 +// Purpose: Intel XScale MM common definitions +// Description: The macros defined here provide common definitions for +// memory management initialization. +// Usage: +// #include <cyg/hal/hal_mm.h> +// ... +// +// +//####DESCRIPTIONEND#### +// +//============================================================================= + +#define PTE_SECTION_FLASH ((3 << 10) | (1 << 3) | 2) +#define PTE_SECTION_RAM ((1 << 12) | (3 << 10) | (1 << 3) | (1 << 2) | 2) +#define PTE_SECTION_UNCACHED ((3 << 10) | 2) + +#ifdef __ASSEMBLER__ + +// form a first-level section entry +.macro FL_SECTION_ENTRY base,x,ap,p,d,c,b +.word (\base << 20) | (\x << 12) | (\ap << 10) | (\p << 9) |\ + (\d << 5) | (\c << 3) | (\b << 2) | 2 +.endm + +// form a first-level page table entry +.macro FL_PT_ENTRY base,p,d +// I wanted to use logical operations here, but since I am using symbols later +// to fill in the parameters, I had to use addition to force the assembler to +// do it right +.word \base + (\p << 9) + (\d << 5) + 1 +.endm + +// form a second level small page entry +.macro SL_SMPAGE_ENTRY base,ap3,ap2,ap1,ap0,c,b +.word (\base << 12) | (\ap3 << 10) | (\ap2 << 8) | (\ap1 << 6) |\ + (\ap0 << 4) | (\c << 3) | (\b << 2) | 2 +.endm + +// form a second level extended small page entry +.macro SL_XSMPAGE_ENTRY base,x,ap,c,b +.word (\base << 12) | (\x << 6) | (\ap << 4) | (\c << 3) | (\b << 2) | 3 +.endm + +#else + +// ------------------------------------------------------------------------- +// MMU initialization: +// +// These structures are laid down in memory to define the translation +// table. +// + +/* + * XScale Translation Table Base Bit Masks + */ +#define ARM_TRANSLATION_TABLE_MASK 0xFFFFC000 + +/* + * XScale Domain Access Control Bit Masks + */ +#define ARM_ACCESS_TYPE_NO_ACCESS(domain_num) (0x0 << (domain_num)*2) +#define ARM_ACCESS_TYPE_CLIENT(domain_num) (0x1 << (domain_num)*2) +#define ARM_ACCESS_TYPE_MANAGER(domain_num) (0x3 << (domain_num)*2) + +struct ARM_MMU_FIRST_LEVEL_FAULT { + unsigned int id : 2; + unsigned int sbz : 30; +}; +#define ARM_MMU_FIRST_LEVEL_FAULT_ID 0x0 + +struct ARM_MMU_FIRST_LEVEL_PAGE_TABLE { + unsigned int id : 2; + unsigned int imp : 2; + unsigned int domain : 4; + unsigned int p : 1; + unsigned int base_address : 23; +}; +#define ARM_MMU_FIRST_LEVEL_PAGE_TABLE_ID 0x1 + +struct ARM_MMU_FIRST_LEVEL_SECTION { + unsigned int id : 2; + unsigned int b : 1; + unsigned int c : 1; + unsigned int imp : 1; + unsigned int domain : 4; + unsigned int p : 1; + unsigned int ap : 2; + unsigned int tex : 8; + unsigned int base_address : 12; +}; +#define ARM_MMU_FIRST_LEVEL_SECTION_ID 0x2 + +struct ARM_MMU_FIRST_LEVEL_RESERVED { + unsigned int id : 2; + unsigned int sbz : 30; +}; +#define ARM_MMU_FIRST_LEVEL_RESERVED_ID 0x3 + +#define ARM_MMU_FIRST_LEVEL_DESCRIPTOR_ADDRESS(ttb_base, table_index) \ + (unsigned long *)((unsigned long)(ttb_base) + ((table_index) << 2)) + +#define ARM_FIRST_LEVEL_PAGE_TABLE_SIZE 0x4000 + +#define ARM_MMU_SECTION(ttb_base, actual_base, virtual_base, \ + cacheable, bufferable, perm) \ + CYG_MACRO_START \ + register union ARM_MMU_FIRST_LEVEL_DESCRIPTOR desc; \ + \ + desc.word = 0; \ + desc.section.id = ARM_MMU_FIRST_LEVEL_SECTION_ID; \ + desc.section.domain = 0; \ + desc.section.c = (cacheable); \ + desc.section.b = (bufferable); \ + desc.section.ap = (perm); \ + desc.section.base_address = (actual_base); \ + *ARM_MMU_FIRST_LEVEL_DESCRIPTOR_ADDRESS(ttb_base, (virtual_base)) \ + = desc.word; \ + CYG_MACRO_END + +#define X_ARM_MMU_SECTION(abase,vbase,size,cache,buff,access) \ + { int i; int j = abase; int k = vbase; \ + for (i = size; i > 0 ; i--,j++,k++) \ + { \ + ARM_MMU_SECTION(ttb_base, j, k, cache, buff, access); \ + } \ + } + +union ARM_MMU_FIRST_LEVEL_DESCRIPTOR { + unsigned long word; + struct ARM_MMU_FIRST_LEVEL_FAULT fault; + struct ARM_MMU_FIRST_LEVEL_PAGE_TABLE page_table; + struct ARM_MMU_FIRST_LEVEL_SECTION section; + struct ARM_MMU_FIRST_LEVEL_RESERVED reserved; +}; + +#define ARM_UNCACHEABLE 0 +#define ARM_CACHEABLE 1 +#define ARM_UNBUFFERABLE 0 +#define ARM_BUFFERABLE 1 + +#define ARM_ACCESS_PERM_NONE_NONE 0 +#define ARM_ACCESS_PERM_RO_NONE 0 +#define ARM_ACCESS_PERM_RO_RO 0 +#define ARM_ACCESS_PERM_RW_NONE 1 +#define ARM_ACCESS_PERM_RW_RO 2 +#define ARM_ACCESS_PERM_RW_RW 3 + +/* + * Initialization for the Domain Access Control Register + */ +#define ARM_ACCESS_DACR_DEFAULT ( \ + ARM_ACCESS_TYPE_MANAGER(0) | \ + ARM_ACCESS_TYPE_NO_ACCESS(1) | \ + ARM_ACCESS_TYPE_NO_ACCESS(2) | \ + ARM_ACCESS_TYPE_NO_ACCESS(3) | \ + ARM_ACCESS_TYPE_NO_ACCESS(4) | \ + ARM_ACCESS_TYPE_NO_ACCESS(5) | \ + ARM_ACCESS_TYPE_NO_ACCESS(6) | \ + ARM_ACCESS_TYPE_NO_ACCESS(7) | \ + ARM_ACCESS_TYPE_NO_ACCESS(8) | \ + ARM_ACCESS_TYPE_NO_ACCESS(9) | \ + ARM_ACCESS_TYPE_NO_ACCESS(10) | \ + ARM_ACCESS_TYPE_NO_ACCESS(11) | \ + ARM_ACCESS_TYPE_NO_ACCESS(12) | \ + ARM_ACCESS_TYPE_NO_ACCESS(13) | \ + ARM_ACCESS_TYPE_NO_ACCESS(14) | \ + ARM_ACCESS_TYPE_NO_ACCESS(15) ) + +#endif // ifdef __ASSEMBLER__ + +// ------------------------------------------------------------------------ +// XScale extras. +#define MMU_Control_BTB 0x800 + + +#endif // ifndef CYGONCE_HAL_MM_H +// End of hal_mm.h + + + + +
new file mode 100644 --- /dev/null +++ b/packages/hal/arm/xscale/cores/current/include/hal_xscale.h @@ -0,0 +1,122 @@ +/*============================================================================= +// +// hal_xscale.h +// +// XScale Core I/O module support. +// +//============================================================================= +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): msalter +// Contributors: msalter +// Date: 2002-10-18 +// Purpose: +// Description: XScale core I/O modules support. +// Usage: #include <cyg/hal/hal_xscale.h> +// +//####DESCRIPTIONEND#### +// +//===========================================================================*/ +#ifndef CYGONCE_HAL_ARM_XSCALE_HAL_XSCALE_H +#define CYGONCE_HAL_ARM_XSCALE_HAL_XSCALE_H + +#include <pkgconf/system.h> + +#ifdef __ASSEMBLER__ + // Useful CPU macros + + // Delay a bit + .macro DELAY_FOR cycles, reg0 + ldr \reg0, =\cycles + subs \reg0, \reg0, #1 + subne pc, pc, #0xc + .endm + + // wait for coprocessor write complete + .macro CPWAIT reg + mrc p15,0,\reg,c2,c0,0 + mov \reg,\reg + sub pc,pc,#4 + .endm + + // Enable the BTB + .macro BTB_INIT reg + mrc p15, 0, \reg, c1, c0, 0 + orr \reg, \reg, #MMU_Control_BTB + mcr p15, 0, \reg, c1, c0, 0 + CPWAIT \reg + .endm +#else +static inline void CPWAIT(void) { + cyg_uint32 tmp; + asm volatile ("mrc p15,0,%0,c2,c0,0\n" + "mov %0,%0\n" + "sub pc,pc,#4" : "=r" (tmp)); +} +#endif + +// Override the default MMU off code. This is intended +// to be included in an inline asm statement. +#define CYGARC_HAL_MMU_OFF(__paddr__) \ + " mrc p15,0,r0,c1,c0,0\n" \ + " bic r0,r0,#0x05\n" \ + " b 99f\n" \ + " .p2align 5\n" \ + "99:\n" \ + " mcr p15,0,r0,c1,c0,0\n" \ + " mrc p15,0,r0,c2,c0,0\n" \ + " mov r0,r0\n" \ + " sub pc,pc,#4\n" \ + " mov pc," #__paddr__ "\n" + +#ifdef __ASSEMBLER__ + +#define REG8(a,b) (b) +#define REG16(a,b) (b) +#define REG32(a,b) (b) + +#else /* __ASSEMBLER__ */ + +#define REG8(a,b) ((volatile unsigned char *)((a)+(b))) +#define REG16(a,b) ((volatile unsigned short *)((a)+(b))) +#define REG32(a,b) ((volatile unsigned int *)((a)+(b))) + +extern void hal_xscale_core_init(void); +#endif /* __ASSEMBLER__ */ + +//-------------------------------------------------------------- +#endif // CYGONCE_HAL_ARM_XSCALE_HAL_XSCALE_H +// EOF hal_xscale.h
new file mode 100644 --- /dev/null +++ b/packages/hal/arm/xscale/cores/current/include/plf_stub.h @@ -0,0 +1,98 @@ +#ifndef CYGONCE_HAL_PLF_STUB_H +#define CYGONCE_HAL_PLF_STUB_H + +//============================================================================= +// +// plf_stub.h +// +// Platform header for GDB stub support. +// +//============================================================================= +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors:jskov +// Travis C. Furrer <furrer@mit.edu> +// Date: 2000-05-08 +// Purpose: Platform HAL stub support for Intel XScale boards. +// Usage: #include <cyg/hal/plf_stub.h> +// +//####DESCRIPTIONEND#### +// +//============================================================================= + +#include <pkgconf/hal.h> +#include <cyg/infra/cyg_type.h> // CYG_UNUSED_PARAM +#include CYGBLD_HAL_VAR_H // registers +#include <cyg/hal/hal_io.h> // IO macros +#include <cyg/hal/hal_intr.h> // Interrupt macros +#include <cyg/hal/arm_stub.h> // architecture stub support + +#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS +//---------------------------------------------------------------------------- +// Define some platform specific communication details. This is mostly +// handled by hal_if now, but we need to make sure the comms tables are +// properly initialized. + +externC void cyg_hal_plf_comms_init(void); + +#define HAL_STUB_PLATFORM_INIT_SERIAL() cyg_hal_plf_comms_init() +#define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int, (baud)) +#define HAL_STUB_PLATFORM_INTERRUPTIBLE 0 + +//---------------------------------------------------------------------------- +// Stub initializer. +#define HAL_STUB_PLATFORM_INIT() CYG_EMPTY_STATEMENT + +extern int cyg_hal_plf_hw_breakpoint(int setflag, void *addr, int len); +extern int cyg_hal_plf_hw_watchpoint(int setflag, void *addr, int len, int type); +extern int cyg_hal_plf_is_stopped_by_hardware(void **paddr); + +#define HAL_STUB_HW_BREAKPOINT_LIST_SIZE 2 +#define HAL_STUB_HW_WATCHPOINT_LIST_SIZE 2 + +#define HAL_STUB_HW_BREAKPOINT(f,a,l) cyg_hal_plf_hw_breakpoint((f),(a),(l)) +#define HAL_STUB_HW_WATCHPOINT(f,a,l,t) cyg_hal_plf_hw_watchpoint((f),(a),(l),(t)) +#define HAL_STUB_IS_STOPPED_BY_HARDWARE(p) cyg_hal_plf_is_stopped_by_hardware(&(p)) + +#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS + +// start-sanitize-xscale +externC cyg_uint32 cyg_hal_iwmmxt_coprocessor_id(void); +// end-sanitize-xscale +//----------------------------------------------------------------------------- +#endif // CYGONCE_HAL_PLF_STUB_H +// End of plf_stub.h
new file mode 100644 --- /dev/null +++ b/packages/hal/arm/xscale/cores/current/src/xscale_misc.c @@ -0,0 +1,88 @@ +//========================================================================== +// +// xscale_misc.c +// +// HAL misc support code for Intel XScale cores. +// +//========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): msalter +// Contributors: msalter +// Date: 2002-10-18 +// Purpose: XScale core HAL support +// Description: Implementations of HAL interfaces +// +//####DESCRIPTIONEND#### +// +//========================================================================*/ + +#include <pkgconf/hal.h> +#include <pkgconf/system.h> +#include CYGBLD_HAL_PLATFORM_H +#include CYGHWR_MEMORY_LAYOUT_H + +void +hal_xscale_core_init(void) +{ + // Initialize debug control unit to sane state + asm volatile ("mov r0,#0\n" + "mcr p15,0,r0,c14,c8,0\n" // ibcr0 + "mcr p15,0,r0,c14,c9,0\n" // ibcr1 + "mcr p15,0,r0,c14,c4,0\n" // dbcon + "mov r0,#0x80000000\n" + "mcr p14,0,r0,c10,c0,0\n" // dcsr + : /* no outputs */ + : /* no inputs */ + : "r0" ); +} + +// start-sanitize-xscale +// Read IWMMXT Coprocessor ID register +#ifdef CYGHWR_HAL_ARM_IWMMXT +cyg_uint32 +cyg_hal_iwmmxt_coprocessor_id(void) +{ + cyg_uint32 val; + asm volatile ("tmcr wcid,%0\n" : "=r"(val) : ); + return val; +} +#endif // CYGHWR_HAL_ARM_IWMMXT + +// end-sanitize-xscale +/*------------------------------------------------------------------------*/ +// EOF xscale_misc.c +
new file mode 100644 --- /dev/null +++ b/packages/hal/arm/xscale/cores/current/src/xscale_stub.c @@ -0,0 +1,784 @@ +//========================================================================== +// +// xscale_stub.c +// +// HAL stub support code for Intel XScale cores. +// +//========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): msalter +// Contributors: msalter +// Date: 2002-10-18 +// Purpose: XScale core stub support +// Description: Implementations of HW debugging support. +// +//####DESCRIPTIONEND#### +// +//========================================================================*/ + +#include <pkgconf/hal.h> +#include <pkgconf/system.h> +#include <cyg/infra/diag.h> +#include <cyg/hal/hal_stub.h> // Stub macros + +#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS +/*------------------------------------------------------------------------*/ +// HW Debug support + +// Define this to support two watchpoints. If not defined, one watchpoint with +// a power of two range is supported. +#define USE_TWO_WATCHPOINTS 1 + +static inline void set_ibcr0(unsigned x) +{ + asm volatile ("mcr p15,0,%0,c14,c8,0" : : "r"(x) ); +} + +static inline unsigned get_ibcr0(void) +{ + unsigned x; + asm volatile ("mrc p15,0,%0,c14,c8,0" : "=r"(x) : ); + return x; +} + +static inline void set_ibcr1(unsigned x) +{ + asm volatile ("mcr p15,0,%0,c14,c9,0" : : "r"(x) ); +} + +static inline unsigned get_ibcr1(void) +{ + unsigned x; + asm volatile ("mrc p15,0,%0,c14,c9,0" : "=r"(x) : ); + return x; +} + +static inline void set_dbr0(unsigned x) +{ + asm volatile ("mcr p15,0,%0,c14,c0,0" : : "r"(x) ); +} + +static inline unsigned get_dbr0(void) +{ + unsigned x; + asm volatile ("mrc p15,0,%0,c14,c0,0" : "=r"(x) : ); + return x; +} + +static inline void set_dbr1(unsigned x) +{ + asm volatile ("mcr p15,0,%0,c14,c3,0" : : "r"(x) ); +} + +static inline unsigned get_dbr1(void) +{ + unsigned x; + asm volatile ("mrc p15,0,%0,c14,c3,0" : "=r"(x) : ); + return x; +} + +static inline void set_dbcon(unsigned x) +{ + asm volatile ("mcr p15,0,%0,c14,c4,0" : : "r"(x) ); +} + +static inline unsigned get_dbcon(void) +{ + unsigned x; + asm volatile ("mrc p15,0,%0,c14,c4,0" : "=r"(x) : ); + return x; +} + +static inline void set_dcsr(unsigned x) +{ + asm volatile ("mcr p14,0,%0,c10,c0,0" : : "r"(x) ); +} + +static inline unsigned get_dcsr(void) +{ + unsigned x; + asm volatile ("mrc p14,0,%0,c10,c0,0" : "=r"(x) : ); + return x; +} + +int cyg_hal_plf_hw_breakpoint(int setflag, void *vaddr, int len) +{ + unsigned int addr = (unsigned)vaddr; + + if (setflag) { + if (!(get_ibcr0() & 1)) + set_ibcr0(addr | 1); + else if (!(get_ibcr1() & 1)) + set_ibcr1(addr | 1); + else + return -1; + } else { + unsigned x = (addr | 1); + if (get_ibcr0() == x) + set_ibcr0(0); + else if (get_ibcr1() == x) + set_ibcr1(0); + else + return -1; + } + + return 0; +} + +#define WATCH_MODE_NONE 0 +#define WATCH_MODE_WRITE 1 +#define WATCH_MODE_ACCESS 2 +#define WATCH_MODE_READ 3 + +#ifndef HAL_STUB_HW_WATCHPOINT_LIST_SIZE +#error +#endif + +int cyg_hal_plf_hw_watchpoint(int setflag, void *vaddr, int len, int type) +{ + unsigned int mode, addr = (unsigned)vaddr; + unsigned dbcon = get_dbcon(); +#if HAL_STUB_HW_WATCHPOINT_LIST_SIZE == 1 + unsigned int mask, bit_nr; + + mask = 0x80000000; + bit_nr = 31; + while (bit_nr) { + if (len & mask) + break; + bit_nr--; + mask >>= 1; + } + mask = ~(0xffffffff << bit_nr); +#endif + + if (setflag) { + /* set a watchpoint */ + if (type == 2) + mode = WATCH_MODE_WRITE; // break on write + else if (type == 3) + mode = WATCH_MODE_READ; // break on read + else if (type == 4) + mode = WATCH_MODE_ACCESS; // break on any access + else + return 1; + +#if HAL_STUB_HW_WATCHPOINT_LIST_SIZE == 1 + mode |= 0x100; +#endif + + if (!(dbcon & 3)) { + set_dbr0(addr); +#if HAL_STUB_HW_WATCHPOINT_LIST_SIZE == 1 + set_dbr1(mask); +#endif + set_dbcon(dbcon | mode); +#if HAL_STUB_HW_WATCHPOINT_LIST_SIZE == 2 + } else if (!(dbcon & (3 << 2))) { + set_dbr1(addr); + set_dbcon(dbcon | (mode << 2)); +#endif + } else + return 1; + + } else { + /* clear a watchpoint */ + if ((dbcon & 3) && get_dbr0() == addr) + set_dbcon(dbcon & ~3); +#if HAL_STUB_HW_WATCHPOINT_LIST_SIZE == 2 + else if ((dbcon & (3 << 2)) && get_dbr1() == addr) + set_dbcon(dbcon & ~(3 << 2)); +#endif + else + return 1; + } + return 0; +} + +#if HAL_STUB_HW_WATCHPOINT_LIST_SIZE == 2 + +// The XScale hardware does not provide a way of positively identinfying +// which of the two watchpoints triggered and exception. The following +// code makes a best effort at determining this by decoding the opcode +// of the instruction which caused the watchpoint trigger. It is *not* +// 100% reliable. + +// Some bits common to most ld/st instructions. +#define I_bit (1 << 25) +#define P_bit (1 << 24) +#define U_bit (1 << 23) +#define B_bit (1 << 22) +#define W_bit (1 << 21) +#define L_bit (1 << 20) + +// Return non-zero if opcode at given PC is a store instruction for +// purposes of triggering watchpoints. +static int +is_store_insn(unsigned pc) +{ + unsigned opcode = *(unsigned *)pc; + + if ((opcode & 0x0fb00ff0) == 0x01000090) { + // SWP xxxx 0001 0B00 _Rn_ _Rd_ 0000 1001 _Rm_ + return 1; + } + + if ((opcode & 0x0c000000) == 0x04000000) { + // LDR/STR xxxx 010P UBWL _Rn_ _Rd_ iiii iiii iiii + // LDR/STR xxxx 011P UBWL _Rn_ _Rd_ ssss sSh0 _Rm_ + // Addressing mode 2, Load/Store word or unsigned byte + return (opcode & L_bit) == 0; + } + + if ((opcode & 0x0e000090) == 0x00000090 && + (opcode & 0x00000060) && + ((opcode & (1 << 22)) || (opcode & 0x00000f00) == 0) && + ((opcode & (P_bit | W_bit)) != W_bit)) { + // LDR/STR xxxx 000P U1WL _Rn_ _Rd_ iiii 1SH1 iiii + // LDR/STR xxxx 000P U0WL _Rn_ _Rd_ 0000 1SH1 _Rm_ + // Addressing Mode 3, Load/Store halfword, load signed byte + return (opcode & L_bit) == 0; + } + + if ((opcode & 0x0e000000) == 0x08000000) { + // LDM/STM xxxx 100P USWL _Rn_ rrrr rrrr rrrr rrrr + return (opcode & L_bit) == 0; + } + + if ((opcode & 0x0e000000) == 0x0c000000) { + // LDC/STC xxxx 110P UNWL _Rn_ CRd_ CP#_ iiii iiii + return (opcode & L_bit) == 0; + } + + return 0; +} + +static int +is_thumb_store_insn(unsigned pc) +{ + unsigned short opcode = *(unsigned short *)pc; + + opcode &= 0xfe00; + + if (opcode == 0xb400) + return 1; // PUSH + if (opcode == 0x5000) + return 1; // STR Rd, [Rn, Rm] + if (opcode == 0x5400) + return 1; // STRB Rd, [Rn, Rm] + if (opcode == 0x5200) + return 1; // STRH Rd, [Rn, Rm] + + opcode &= 0xf800; + if (opcode == 0xc000) + return 1; // STM + if (opcode == 0x6000) + return 1; // STR Rd, [Rn, #5bit_offset] + if (opcode == 0x9000) + return 1; // STR Rd, [SP, #8bit_offset] + if (opcode == 0x7000) + return 1; // STRB Rd, [Rn, #5bit_offset] + if (opcode == 0x8000) + return 1; // STRH Rd, [Rn, #5bit_offset] + + return 0; +} + +// Return non-zero if given waddr matches an access at addr. +static int +waddr_match(unsigned waddr, unsigned addr, int size) +{ + if (addr <= waddr && waddr < (addr + size)) + return 1; + return 0; +} + +// Return non-zero if given value matches value at watchpoint address. +static int +wval_match(unsigned waddr, unsigned val, int size) +{ + unsigned wval = *(unsigned *)(waddr & ~3); + int i; + + if (size == 4) + return (wval == val); + if (size == 2) { + val &= 0xffff; + return ((wval & 0xffff) == val || ((wval >> 16) == val)); + } + if (size == 1) { + val &= 0xff; + for (i = 0; i < 4; i++) { + if ((wval & 0xff) == val) + return 1; + wval >>= 8; + } + } + return 0; +} + +static char _sztab[8] = { 4, 2, 1, 1, 4, 2, 1, 2 }; + +// Given the watch addresses and watch modes for each of the enabled +// watchpoints, figure out which one triggered the current exception. +static unsigned +find_thumb_watch_address(unsigned wa0, int mode0, unsigned wa1, int mode1) +{ + unsigned pc = get_register(PC) - 4; + unsigned short opcode = *(unsigned short *)pc; + unsigned short opcode_f8, opcode_fe; + unsigned val, wd0, wd1, addr = 0; + int is_store, use_val, i, offset, size, Rn, Rd, Rm; + + opcode_f8 = opcode & 0xf800; + opcode_fe = opcode & 0xfe00; + + size = 0; + is_store = 0; + val = use_val = 0; + + switch (opcode_f8) { + case 0xc000: // STMIA Rn!, <list> + is_store = 1; + case 0xc800: // LDMIA Rn!, <list> + Rn = (opcode >> 8) & 7; + is_store = (opcode & 0x800) == 0; + for (i = 0; i < 8; i++) + if (opcode & (1 << i)) + size += 4; + if (!is_store && (opcode & (1 << Rn))) { + // We can't reconstruct address from opcode because base + // was destroyed. Best we can do is try to match data at + // watchpoint addresses with data in one of the registers. + wd0 = *(unsigned *)(wa0 & ~3); + wd1 = *(unsigned *)(wa1 & ~3); + if (wd0 != wd1) { + for (i = size = 0; i < 8; i++) { + if (opcode & (1 << i)) { + val = get_register(i); + if (val == wd0) + return wa0; + else if (val == wd1) + return wa1; + } + } + } + return wa0; // 50% chance of being right + } else + addr = get_register(Rn) - size; + break; + case 0x6000: // STR Rd, [Rn, #5bit] + case 0x7000: // STRB Rd, [Rn, #5bit] + case 0x8000: // STRH Rd, [Rn, #5bit] + is_store = 1; + case 0x6800: // LDR Rd, [Rn, #5bit] + case 0x7800: // LDRB Rd, [Rn, #5bit] + case 0x8800: // LDRH Rd, [Rn, #5bit] + Rd = opcode & 7; + Rn = (opcode >> 3) & 7; + if ((opcode & 0xf000) == 0x6000) + size = 4; + else if ((opcode & 0xf000) == 0x8000) + size = 2; + else + size = 1; + if (!is_store && Rd == Rn) { + // We can't reconstruct address from opcode because base + // or offset register was destroyed. Best we can do is try + // to match data at watchpoint addresses with data in Rd. + use_val = 1; + val = get_register(Rd); + } else { + offset = ((opcode >> 6) & 0x1f) * size; + addr = get_register(Rn) + offset; + } + break; + case 0x4800: // LDR Rd, [PC, #8bit] + size = 4; + addr = pc + 4 + ((opcode & 0xff) * 4); + break; + case 0x9000: // STR Rd, [SP, #8bit] + is_store = 1; + case 0x9800: // LDR Rd, [SP, #8bit] + size = 4; + addr = get_register(SP) + ((opcode & 0xff) * 4); + break; + default: + switch (opcode_fe) { + case 0x5000: // STR Rd, [Rn, Rm] + case 0x5400: // STRB Rd, [Rn, Rm] + case 0x5200: // STRH Rd, [Rn, Rm] + is_store = 1; + case 0x5600: // LDRSB Rd, [Rn, Rm] + case 0x5800: // LDR Rd, [Rn, Rm] + case 0x5c00: // LDRB Rd, [Rn, Rm] + case 0x5a00: // LDRH Rd, [Rn, Rm] + case 0x5e00: // LDRSH Rd, [Rn, Rm] + Rd = opcode & 7; + Rn = (opcode >> 3) & 7; + Rm = (opcode >> 6) & 7; + size = _sztab[(opcode >> 9) & 7]; + if (!is_store && (Rd == Rn || Rd == Rm)) { + // We can't reconstruct address from opcode because base + // or offset register was destroyed. Best we can do is try + // to match data at watchpoint addresses with data in Rd. + use_val = 1; + val = get_register(Rd); + } else + addr = Rn + Rm; + break; + case 0xb400: // PUSH + is_store = 1; + case 0xbc00: // POP + for (i = 0; i < 9; i++) + if (opcode & (1 << i)) + size += 4; + addr = get_register(SP); + if (!is_store) + addr -= size; + break; + } + break; + } + if (use_val) { + // We can read from watchpoint addresses and compare against + // whatever is in the Rd from a load. This is not perfect, + // but its the best we can do. + if (wval_match(wa0, val, size)) + return wa0; + if (wval_match(wa1, val, size)) + return wa1; + } else if (size) { + if (waddr_match(wa0, addr, size)) + return wa0; + if (waddr_match(wa1, addr, size)) + return wa1; + } + return wa0; // should never happen, but return valid address +} + +// Given the watch addresses and watch modes for each of the enabled +// watchpoints, figure out which one triggered the current exception. +static unsigned +find_watch_address(unsigned wa0, int mode0, unsigned wa1, int mode1) +{ + unsigned pc = get_register(PC) - 4; + unsigned cpsr = get_register(PS); + unsigned opcode, Rn, Rd, Rm, base, addr, val, wd0, wd1; + int is_store, use_val, i, offset, shift, size; + + if (cpsr & CPSR_THUMB_ENABLE) + is_store = is_thumb_store_insn(pc); + else + is_store = is_store_insn(pc); + + // First try the easy cases where all we need to know is whether or + // not the instruction is a load or store. + if ((mode0 == WATCH_MODE_READ && mode1 == WATCH_MODE_WRITE) || + (mode1 == WATCH_MODE_READ && mode0 == WATCH_MODE_WRITE)) { + if (is_store) + return (mode0 == WATCH_MODE_WRITE) ? wa0 : wa1; + else + return (mode0 == WATCH_MODE_READ) ? wa0 : wa1; + } + if ((mode0 == WATCH_MODE_READ && is_store) || + (mode0 == WATCH_MODE_WRITE && !is_store)) + return wa1; + if ((mode1 == WATCH_MODE_READ && is_store) || + (mode1 == WATCH_MODE_WRITE && !is_store)) + return wa0; + + // Okay. Now try to figure out address by decoding the opcode. + + if (cpsr & CPSR_THUMB_ENABLE) + return find_thumb_watch_address(wa0, mode0, wa1, mode1); + + opcode = *(unsigned *)pc; + Rn = (opcode >> 16) & 15; + Rd = (opcode >> 12) & 15; + Rm = opcode & 15; + + size = use_val = 0; + addr = 0; + + if ((opcode & 0x0fb00ff0) == 0x01000090) { + // SWP xxxx 0001 0B00 _Rn_ _Rd_ 0000 1001 _Rm_ + addr = get_register(Rn); + size = (opcode & B_bit) ? 1 : 4; + } else if ((opcode & 0x0c000000) == 0x04000000) { + // LDR/STR xxxx 010P UBWL _Rn_ _Rd_ iiii iiii iiii + // LDR/STR xxxx 011P UBWL _Rn_ _Rd_ ssss sSh0 _Rm_ + // Addressing mode 2, Load/Store word or unsigned byte + + size = (opcode & B_bit) ? 1 : 4; + + if ((opcode & (P_bit | W_bit)) == (P_bit | W_bit)) { + // This is easy because address is written back to Rn + addr = get_register(Rn); + } else if (!is_store && + (Rd == Rn || ((opcode & I_bit) && Rd == Rm))) { + // We can't reconstruct address from opcode because base + // or offset register was destroyed. Best we can do is try + // to match data at watchpoint addresses with data in Rd. + use_val = 1; + val = get_register(Rd); + } else { + if (opcode & I_bit) { + shift = (opcode >> 7) & 0x1f; + offset = get_register(Rm); + switch ((opcode >> 5) & 3) { + case 0: + offset <<= shift; + break; + case 1: + offset >>= shift; + offset &= (0xffffffffU >> shift); + break; + case 2: + offset >>= shift; + break; + case 3: + if (shift) { + for (i = 0; i < shift; i++) + offset = ((offset >> 1) & 0x7fffffff) | ((offset & 1) << 31); + } else { + offset >>= 1; + offset &= 0x80000000; + offset |= ((cpsr & 0x20000000) << 2); + } + break; + } + } else + offset = opcode & 0xfff; + + if ((opcode & U_bit) == 0) + offset = -offset; + + if (Rn == 15) + base = pc + 8; + else + base = get_register(Rn); + + if (opcode & P_bit) + addr = base + offset; // pre-index + else + addr = base - offset; // post-index writeback + + size = (opcode & B_bit) ? 1 : 4; + } + } else if ((opcode & 0x0e000090) == 0x00000090 && + (opcode & 0x00000060) && + ((opcode & (1 << 22)) || (opcode & 0x00000f00) == 0) && + ((opcode & (P_bit | W_bit)) != W_bit)) { + // LDR/STR xxxx 000P U1WL _Rn_ _Rd_ iiii 1SH1 iiii + // LDR/STR xxxx 000P U0WL _Rn_ _Rd_ 0000 1SH1 _Rm_ + // Addressing Mode 3, Load/Store halfword, load signed byte + + size = (opcode & (1 << 5)) ? 2 : 1; + + if ((opcode & (P_bit | W_bit)) == (P_bit | W_bit)) { + // This is easy because address is written back to Rn + addr = get_register(Rn); + } if (!is_store && + (Rd == Rn || ((opcode & (1 << 22)) && Rd == Rm))) { + // We can't reconstruct address from opcode because base + // or offset register was destroyed. Best we can do is try + // to match data at watchpoint addresses with data in Rd. + use_val = 1; + val = get_register(Rd); + } else { + if (opcode & (1 << 22)) + offset = ((opcode >> 4) & 0xf0) | (opcode & 0x0f); + else + offset = get_register(opcode & 15); + + if ((opcode & U_bit) == 0) + offset = -offset; + + if (Rn == 15) + base = pc + 8; + else + base = get_register(Rn); + + if (opcode & P_bit) + addr = base + offset; // pre-index + else + addr = base - offset; // post-index writeback + } + } else if ((opcode & 0x0e000000) == 0x08000000) { + // LDM/STM xxxx 100P USWL _Rn_ rrrr rrrr rrrr rrrr + for (i = size = 0; i < 16; i++) + if (opcode & (1 << i)) + size += 4; + + base = get_register(Rn); + if (!is_store && (opcode & (1 << Rn))) { + // We can't reconstruct address from opcode because base + // was destroyed. Best we can do is try to match data at + // watchpoint addresses with data in one of the registers. + wd0 = *(unsigned *)(wa0 & ~3); + wd1 = *(unsigned *)(wa1 & ~3); + if (wd0 != wd1) { + for (i = size = 0; i < 16; i++) { + if (opcode & (1 << i)) { + val = get_register(i); + if (val == wd0) + return wa0; + else if (val == wd1) + return wa1; + } + } + } + return wa0; // 50% chance of being right + } else { + if (opcode & U_bit){ + if (opcode & W_bit) + addr = base - size; + else + addr = base; + if (opcode & P_bit) + addr += 4; + } else { + if (opcode & W_bit) + addr = base; + else + addr = base - size; + if ((opcode & P_bit) == 0) + addr += 4; + } + } + } else if ((opcode & 0x0e000000) == 0x0c000000) { + // LDC/STC xxxx 110P UNWL _Rn_ CRd_ CP#_ iiii iiii + size = 4; + offset = (opcode & 0xff) * 4; + if ((opcode & U_bit) == 0) + offset = -offset; + if ((opcode & P_bit) && (opcode & W_bit)) + addr = get_register(Rn); + else + addr = get_register(Rn) + offset; + } + + if (use_val) { + // We can read from watchpoint addresses and compare against + // whatever is in the Rd from a load. This is not perfect, + // but its the best we can do. + if (wval_match(wa0, val, size)) + return wa0; + if (wval_match(wa1, val, size)) + return wa1; + } else { + if (waddr_match(wa0, addr, size)) + return wa0; + if (waddr_match(wa1, addr, size)) + return wa1; + } + return wa0; // should never happen, but return valid address +} +#endif + +// Return indication of whether or not we stopped because of a +// watchpoint or hardware breakpoint. If stopped by a watchpoint, +// also set '*data_addr_p' to the data address which triggered the +// watchpoint. +int cyg_hal_plf_is_stopped_by_hardware(void **data_addr_p) +{ + unsigned fsr, dcsr, dbcon, kind = 0; + + // Check for debug event + asm volatile ("mrc p15,0,%0,c5,c0,0" : "=r"(fsr) : ); + if ((fsr & 0x200) == 0) + return HAL_STUB_HW_STOP_NONE; + + // There was a debug event. Check the MOE for details + dcsr = get_dcsr(); + switch ((dcsr >> 2) & 7) { + case 1: // HW breakpoint + case 3: // BKPT breakpoint + return HAL_STUB_HW_STOP_BREAK; + case 2: // Watchpoint + dbcon = get_dbcon(); +#if HAL_STUB_HW_WATCHPOINT_LIST_SIZE == 2 + if (dbcon & 0x100) { +#endif + if ((kind = (dbcon & 3)) != WATCH_MODE_NONE) + *data_addr_p = (void *)get_dbr0(); +#if HAL_STUB_HW_WATCHPOINT_LIST_SIZE == 2 + } else { + // This can get tricky because the debug unit offers no way to + // tell which watchpoint triggered. + if ((kind = (dbcon & 3)) == WATCH_MODE_NONE) { + if ((kind = ((dbcon >> 2) & 3)) != WATCH_MODE_NONE) + *data_addr_p = (void *)get_dbr1(); + } else if ((kind = ((dbcon >> 2) & 3)) == WATCH_MODE_NONE) { + if ((kind = (dbcon & 3)) != WATCH_MODE_NONE) + *data_addr_p = (void *)get_dbr0(); + } else { + // This is the tricky part. We have to look at the trapping + // opcode (which has already issued) to try to see if we can + // tell which watchpoint triggered. Turn off watchpoints while + // we figure this out. + set_dcsr(dcsr & ~0x80000000); + *data_addr_p = (void *)find_watch_address(get_dbr0(), dbcon & 3, + get_dbr1(), (dbcon >> 2) & 3); + set_dcsr(dcsr); + + if (*data_addr_p == (void *)get_dbr0()) + kind = dbcon & 3; + else if (*data_addr_p == (void *)get_dbr1()) + kind = (dbcon >> 2) & 3; + else + kind = WATCH_MODE_NONE; + } + } +#endif + if (kind == WATCH_MODE_WRITE) + return HAL_STUB_HW_STOP_WATCH; + if (kind == WATCH_MODE_ACCESS) + return HAL_STUB_HW_STOP_AWATCH; + if (kind == WATCH_MODE_READ) + return HAL_STUB_HW_STOP_RWATCH; + // should never get here + break; + } + return HAL_STUB_HW_STOP_NONE; +} +#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS + +/*------------------------------------------------------------------------*/ +// EOF xscale_stub.c +
