summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2000-06-13 21:53:38 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2000-06-13 21:53:38 +0000
commitcf1f72ea339287cf6f780b2e34b8092ce08da6b0 (patch)
tree3b6eee762364ef5304ebae3bf5da4e9296eafa29 /c/src/lib/libcpu
parentAdded .cvsignore. (diff)
downloadrtems-cf1f72ea339287cf6f780b2e34b8092ce08da6b0.tar.bz2
Moved i386 and m68k cache management code to libcpu. Everything
now is an implementation of the prototypes in rtems/rtems/cache.h. The libcpu/i386/wrapup directory is no longer needed. The PowerPC needs this done to it.
Diffstat (limited to 'c/src/lib/libcpu')
-rw-r--r--c/src/lib/libcpu/i386/Makefile.am28
-rw-r--r--c/src/lib/libcpu/i386/cache.c99
-rw-r--r--c/src/lib/libcpu/i386/cache_.h16
-rw-r--r--c/src/lib/libcpu/i386/idtr.S (renamed from c/src/lib/libcpu/i386/cpu_asm.S)0
-rw-r--r--c/src/lib/libcpu/m68k/Makefile.am10
-rw-r--r--c/src/lib/libcpu/m68k/configure.in9
-rw-r--r--c/src/lib/libcpu/m68k/shared/Makefile.am10
-rw-r--r--c/src/lib/libcpu/m68k/shared/cache/Makefile.am38
-rw-r--r--c/src/lib/libcpu/m68k/shared/cache/cache.c192
-rw-r--r--c/src/lib/libcpu/m68k/shared/cache/cache_.h29
-rw-r--r--c/src/lib/libcpu/shared/include/cache.h32
-rw-r--r--c/src/lib/libcpu/shared/src/cache_aligned_malloc.c43
-rw-r--r--c/src/lib/libcpu/shared/src/cache_manager.c292
13 files changed, 781 insertions, 17 deletions
diff --git a/c/src/lib/libcpu/i386/Makefile.am b/c/src/lib/libcpu/i386/Makefile.am
index 90e2d0bc8b..361711a181 100644
--- a/c/src/lib/libcpu/i386/Makefile.am
+++ b/c/src/lib/libcpu/i386/Makefile.am
@@ -5,15 +5,15 @@
AUTOMAKE_OPTIONS = foreign 1.4
ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal
-LIBNAME = libcpu
-LIB = $(ARCH)/$(LIBNAME).a
+VPATH = @srcdir@:@srcdir@/../shared/src
-C_FILES = cpu.c displayCpu.c page.c
+C_FILES = cache.c cache_aligned_malloc.c cache_manager.c displayCpu.c idt.c page.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
-H_FILES = cpu.h registers.h cpuModel.h
+H_FILES = cache_.h
+INSTALLED_H_FILES = cpu.h registers.h cpuModel.h
-S_FILES = cpu_asm.S cpuModel.S
+S_FILES = cpuModel.S idtr.S
S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.o)
OBJS = $(C_O_FILES) $(S_O_FILES)
@@ -21,8 +21,7 @@ OBJS = $(C_O_FILES) $(S_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../automake/lib.am
-$(LIB): $(OBJS)
- $(make-library)
+AM_CPPFLAGS += -I$(srcdir)
$(PROJECT_INCLUDE)/libcpu:
$(mkinstalldirs) $@
@@ -30,19 +29,16 @@ $(PROJECT_INCLUDE)/libcpu:
$(PROJECT_INCLUDE)/libcpu/%.h: %.h
$(INSTALL_DATA) $< $@
-$(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a: $(LIB)
+$(PROJECT_INCLUDE)/libcpu/cache.h: $(top_srcdir)/../shared/include/cache.h
$(INSTALL_DATA) $< $@
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu \
- $(H_FILES:%=$(PROJECT_INCLUDE)/libcpu/%)
+ $(PROJECT_INCLUDE)/libcpu/cache.h \
+ $(INSTALLED_H_FILES:%=$(PROJECT_INCLUDE)/libcpu/%)
-TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a
+all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS)
-all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB) $(TMPINSTALL_FILES)
-
-.PRECIOUS: $(LIB)
-
-EXTRA_DIST = cpu.c cpu.h cpuModel.S cpuModel.h cpu_asm.S displayCpu.c page.c \
- registers.h
+EXTRA_DIST = cache.c cache_.h cpu.h cpuModel.S cpuModel.h \
+ displayCpu.c idt.c idtr.S page.c registers.h
include $(top_srcdir)/../../../../../automake/local.am
diff --git a/c/src/lib/libcpu/i386/cache.c b/c/src/lib/libcpu/i386/cache.c
new file mode 100644
index 0000000000..f462b58a1b
--- /dev/null
+++ b/c/src/lib/libcpu/i386/cache.c
@@ -0,0 +1,99 @@
+/*
+ * Cache Management Support Routines for the i386
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <libcpu/registers.h>
+#include "cache_.h"
+
+void _CPU_disable_cache() {
+ cr0 regCr0;
+
+ regCr0.i = i386_get_cr0();
+ regCr0.cr0.page_level_cache_disable = 1;
+ regCr0.cr0.no_write_through = 1;
+ i386_set_cr0( regCr0.i );
+ rtems_flush_entire_data_cache();
+}
+
+/*
+ * Enable the entire cache
+ */
+
+void _CPU_enable_cache() {
+ cr0 regCr0;
+
+ regCr0.i = i386_get_cr0();
+ regCr0.cr0.page_level_cache_disable = 0;
+ regCr0.cr0.no_write_through = 0;
+ i386_set_cr0( regCr0.i );
+ /*rtems_flush_entire_data_cache();*/
+}
+
+/*
+ * CACHE MANAGER: The following functions are CPU-specific.
+ * They provide the basic implementation for the rtems_* cache
+ * management routines. If a given function has no meaning for the CPU,
+ * it does nothing by default.
+ *
+ * FIXME: Definitions for I386_CACHE_ALIGNMENT are missing above for
+ * each CPU. The routines below should be implemented per CPU,
+ * to accomodate the capabilities of each.
+ */
+
+/* FIXME: I don't belong here. */
+#define I386_CACHE_ALIGNMENT 16
+
+#if defined(I386_CACHE_ALIGNMENT)
+#define _CPU_DATA_CACHE_ALIGNMENT I386_CACHE_ALIGNMENT
+#define _CPU_INST_CACHE_ALIGNEMNT I386_CACHE_ALIGNMENT
+
+void _CPU_flush_1_data_cache_line(const void *d_addr) {}
+void _CPU_invalidate_1_data_cache_line(const void *d_addr) {}
+void _CPU_freeze_data_cache(void) {}
+void _CPU_unfreeze_data_cache(void) {}
+void _CPU_invalidate_1_inst_cache_line ( const void *d_addr ) {}
+void _CPU_freeze_inst_cache(void) {}
+void _CPU_unfreeze_inst_cache(void) {}
+
+void _CPU_flush_entire_data_cache(
+ const void * d_addr
+)
+{
+ asm volatile ("wbinvd");
+}
+void _CPU_invalidate_entire_data_cache(
+ const void * d_addr
+)
+{
+ asm volatile ("invd");
+}
+
+void _CPU_enable_data_cache(void)
+{
+ _CPU_enable_cache();
+}
+
+void _CPU_disable_data_cache(void)
+{
+ _CPU_disable_cache();
+}
+
+void _CPU_invalidate_entire_inst_cache(void)
+{
+ asm volatile ("invd");
+}
+
+void _CPU_enable_inst_cache(void)
+{
+ _CPU_enable_cache();
+}
+
+void _CPU_disable_inst_cache( void )
+{
+ _CPU_disable_cache();
+}
+#endif
+
diff --git a/c/src/lib/libcpu/i386/cache_.h b/c/src/lib/libcpu/i386/cache_.h
new file mode 100644
index 0000000000..03ad537025
--- /dev/null
+++ b/c/src/lib/libcpu/i386/cache_.h
@@ -0,0 +1,16 @@
+/*
+ * i386 Cache Manager Wrapper
+ */
+
+#ifndef __i386_CACHE_h
+#define __i386_CACHE_h
+
+#define I386_CACHE_ALIGNMENT 16
+#define _CPU_DATA_CACHE_ALIGNMENT I386_CACHE_ALIGNMENT
+#define _CPU_INST_CACHE_ALIGNEMNT I386_CACHE_ALIGNMENT
+
+#include <libcpu/cache_.h>
+
+#endif
+/* end of include file */
+
diff --git a/c/src/lib/libcpu/i386/cpu_asm.S b/c/src/lib/libcpu/i386/idtr.S
index 38dc7318ae..38dc7318ae 100644
--- a/c/src/lib/libcpu/i386/cpu_asm.S
+++ b/c/src/lib/libcpu/i386/idtr.S
diff --git a/c/src/lib/libcpu/m68k/Makefile.am b/c/src/lib/libcpu/m68k/Makefile.am
index 6e9cd33d32..7db5310a4b 100644
--- a/c/src/lib/libcpu/m68k/Makefile.am
+++ b/c/src/lib/libcpu/m68k/Makefile.am
@@ -5,7 +5,15 @@
AUTOMAKE_OPTIONS = foreign 1.4
ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal
-SUBDIRS = m68040
+if shared
+SHARED_LIB = shared
+endif
+
+if m68040
+CPU_SUBDIR = m68040
+endif
+
+SUBDIRS = $(SHARED_LIB) $(CPU_SUBDIR)
include $(top_srcdir)/../../../../../automake/subdirs.am
include $(top_srcdir)/../../../../../automake/local.am
diff --git a/c/src/lib/libcpu/m68k/configure.in b/c/src/lib/libcpu/m68k/configure.in
index efcd7c5b7e..808e02c0ba 100644
--- a/c/src/lib/libcpu/m68k/configure.in
+++ b/c/src/lib/libcpu/m68k/configure.in
@@ -26,10 +26,19 @@ RTEMS_CANONICALIZE_TOOLS
RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP)
RTEMS_CHECK_BSP_CACHE(RTEMS_BSP)
+AM_CONDITIONAL(shared, test "$RTEMS_CPU_MODEL" = "m68020" \
+|| test "$RTEMS_CPU_MODEL" = "m68020" \
+|| test "$RTEMS_CPU_MODEL" = "m68030" \
+|| test "$RTEMS_CPU_MODEL" = "m68lc040" \
+|| test "$RTEMS_CPU_MODEL" = "m68040" \
+|| test "$RTEMS_CPU_MODEL" = "m68060" )
+
AM_CONDITIONAL(m68040, test "$RTEMS_CPU_MODEL" = "m68040")
# Explicitly list all Makefiles here
AC_OUTPUT(
Makefile
+shared/Makefile
+shared/cache/Makefile
m68040/Makefile
m68040/fpsp/Makefile)
diff --git a/c/src/lib/libcpu/m68k/shared/Makefile.am b/c/src/lib/libcpu/m68k/shared/Makefile.am
new file mode 100644
index 0000000000..3f7ad1d7a6
--- /dev/null
+++ b/c/src/lib/libcpu/m68k/shared/Makefile.am
@@ -0,0 +1,10 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+SUBDIRS = cache
+
+include $(top_srcdir)/../../../../../automake/subdirs.am
+include $(top_srcdir)/../../../../../automake/local.am
diff --git a/c/src/lib/libcpu/m68k/shared/cache/Makefile.am b/c/src/lib/libcpu/m68k/shared/cache/Makefile.am
new file mode 100644
index 0000000000..d94c4388c9
--- /dev/null
+++ b/c/src/lib/libcpu/m68k/shared/cache/Makefile.am
@@ -0,0 +1,38 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal
+
+VPATH = @srcdir@:@srcdir@/../../../shared/src
+
+C_FILES = cache.c cache_aligned_malloc.c cache_manager.c
+C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
+
+H_FILES = cache_.h
+INSTALLED_H_FILES =
+
+OBJS = $(C_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../../../../../automake/lib.am
+
+AM_CPPFLAGS += -I$(srcdir)
+
+$(PROJECT_INCLUDE)/libcpu:
+ $(mkinstalldirs) $@
+
+$(PROJECT_INCLUDE)/libcpu/%.h: %.h
+ $(INSTALL_DATA) $< $@
+
+$(PROJECT_INCLUDE)/libcpu/cache.h: $(top_srcdir)/../shared/include/cache.h
+ $(INSTALL_DATA) $< $@
+
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu $(PROJECT_INCLUDE)/libcpu/cache.h
+
+all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS)
+
+EXTRA_DIST = cache.c cache_.h
+
+include $(top_srcdir)/../../../../../automake/local.am
diff --git a/c/src/lib/libcpu/m68k/shared/cache/cache.c b/c/src/lib/libcpu/m68k/shared/cache/cache.c
new file mode 100644
index 0000000000..ce98f006c6
--- /dev/null
+++ b/c/src/lib/libcpu/m68k/shared/cache/cache.c
@@ -0,0 +1,192 @@
+/*
+ * Cache Management Support Routines for the MC68040
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include "cache_.h"
+
+/*
+ * Since the cacr is common to all mc680x0, provide macros
+ * for masking values in that register.
+ */
+
+/*
+ * Used to clear bits in the cacr.
+ */
+#define _CPU_CACR_AND(mask) \
+ { \
+ register unsigned long _value = mask; \
+ register unsigned long _ctl = 0; \
+ asm volatile ( "movec %%cacr, %0; /* read the cacr */ \
+ andl %2, %0; /* and with _val */ \
+ movec %1, %%cacr" /* write the cacr */ \
+ : "=d" (_ctl) : "0" (_ctl), "d" (_value) : "%%cc" ); \
+ }
+
+
+/*
+ * Used to set bits in the cacr.
+ */
+#define _CPU_CACR_OR(mask) \
+ { \
+ register unsigned long _value = mask; \
+ register unsigned long _ctl = 0; \
+ asm volatile ( "movec %%cacr, %0; /* read the cacr */ \
+ orl %2, %0; /* or with _val */ \
+ movec %1, %%cacr" /* write the cacr */ \
+ : "=d" (_ctl) : "0" (_ctl), "d" (_value) : "%%cc" ); \
+ }
+
+
+/*
+ * CACHE MANAGER: The following functions are CPU-specific.
+ * They provide the basic implementation for the rtems_* cache
+ * management routines. If a given function has no meaning for the CPU,
+ * it does nothing by default.
+ */
+#if ( defined(__mc68020__) || defined(__mc68030__) )
+
+#if defined(__mc68030__)
+
+/* Only the mc68030 has a data cache; it is writethrough only. */
+
+void _CPU_flush_1_data_cache_line ( const void * d_addr ) {}
+void _CPU_flush_entire_data_cache ( const void * d_addr ) {}
+
+void _CPU_invalidate_1_data_cache_line (
+ const void * d_addr )
+{
+ void * p_address = (void *) _CPU_virtual_to_physical( d_addr );
+ asm volatile ( "movec %0, %%caar" :: "a" (p_address) ); /* write caar */
+ _CPU_CACR_OR(0x00000400);
+}
+
+void _CPU_invalidate_entire_data_cache ( void )
+{
+ _CPU_CACR_OR( 0x00000800 );
+}
+
+void _CPU_freeze_data_cache ( void )
+{
+ _CPU_CACR_OR( 0x00000200 );
+}
+
+void _CPU_unfreeze_data_cache ( void )
+{
+ _CPU_CACR_AND( 0xFFFFFDFF );
+}
+
+void _CPU_enable_data_cache ( void )
+{
+ _CPU_CACR_OR( 0x00000100 );
+}
+void _CPU_disable_data_cache ( void )
+{
+ _CPU_CACR_AND( 0xFFFFFEFF );
+}
+#endif
+
+
+/* Both the 68020 and 68030 have instruction caches */
+
+void _CPU_invalidate_1_inst_cache_line (
+ const void * d_addr )
+{
+ void * p_address = (void *) _CPU_virtual_to_physical( d_addr );
+ asm volatile ( "movec %0, %%caar" :: "a" (p_address) ); /* write caar */
+ _CPU_CACR_OR( 0x00000004 );
+}
+
+void _CPU_invalidate_entire_inst_cache ( void )
+{
+ _CPU_CACR_OR( 0x00000008 );
+}
+
+void _CPU_freeze_inst_cache ( void )
+{
+ _CPU_CACR_OR( 0x00000002);
+}
+
+void _CPU_unfreeze_inst_cache ( void )
+{
+ _CPU_CACR_AND( 0xFFFFFFFD );
+}
+
+void _CPU_enable_inst_cache ( void )
+{
+ _CPU_CACR_OR( 0x00000001 );
+}
+
+void _CPU_disable_inst_cache ( void )
+{
+ _CPU_CACR_AND( 0xFFFFFFFE );
+}
+
+
+#elif ( defined(__mc68040__) || defined (__mc68060__) )
+
+/* Cannot be frozen */
+void _CPU_freeze_data_cache ( void ) {}
+void _CPU_unfreeze_data_cache ( void ) {}
+void _CPU_freeze_inst_cache ( void ) {}
+void _CPU_unfreeze_inst_cache ( void ) {}
+
+void _CPU_flush_1_data_cache_line (
+ const void * d_addr )
+{
+ void * p_address = (void *) _CPU_virtual_to_physical( d_addr );
+ asm volatile ( "cpushl %%dc,(%0)" :: "a" (p_address) );
+}
+
+void _CPU_invalidate_1_data_cache_line (
+ const void * d_addr )
+{
+ void * p_address = (void *) _CPU_virtual_to_physical( d_addr );
+ asm volatile ( "cinvl %%dc,(%0)" :: "a" (p_address) );
+}
+
+void _CPU_flush_entire_data_cache ( void )
+{
+ asm volatile ( "cpusha %%dc" :: );
+}
+
+void _CPU_invalidate_entire_data_cache ( void )
+{
+ asm volatile ( "cinva %%dc" :: );
+}
+
+void _CPU_enable_data_cache ( void )
+{
+ _CPU_CACR_OR( 0x80000000 );
+}
+
+void _CPU_disable_data_cache ( void )
+{
+ _CPU_CACR_AND( 0x7FFFFFFF );
+}
+
+void _CPU_invalidate_1_inst_cache_line (
+ const void * i_addr )
+{
+ void * p_address = (void *) _CPU_virtual_to_physical( i_addr );
+ asm volatile ( "cinvl %%ic,(%0)" :: "a" (p_address) );
+}
+
+void _CPU_invalidate_entire_inst_cache ( void )
+{
+ asm volatile ( "cinva %%ic" :: );
+}
+
+void _CPU_enable_inst_cache ( void )
+{
+ _CPU_CACR_OR( 0x00008000 );
+}
+
+void _CPU_disable_inst_cache ( void )
+{
+ _CPU_CACR_AND( 0xFFFF7FFF );
+}
+#endif
+/* end of file */
diff --git a/c/src/lib/libcpu/m68k/shared/cache/cache_.h b/c/src/lib/libcpu/m68k/shared/cache/cache_.h
new file mode 100644
index 0000000000..13406b3c49
--- /dev/null
+++ b/c/src/lib/libcpu/m68k/shared/cache/cache_.h
@@ -0,0 +1,29 @@
+/*
+ * M68K Cache Manager Support
+ */
+
+#ifndef __M68K_CACHE_h
+#define __M68K_CACHE_h
+
+#if defined(__mc68020__)
+#define M68K_INST_CACHE_ALIGNMENT 16
+#elif defined(__mc68030__)
+#define M68K_INST_CACHE_ALIGNMENT 16
+#define M68K_DATA_CACHE_ALIGNMENT 16
+#elif ( defined(__mc68040__) || defined (__mc68060__) )
+#define M68K_INST_CACHE_ALIGNMENT 16
+#define M68K_DATA_CACHE_ALIGNMENT 16
+#endif
+
+#if defined(M68K_DATA_CACHE_ALIGNMENT)
+#define _CPU_DATA_CACHE_ALIGNMENT M68K_DATA_CACHE_ALIGNMENT
+#endif
+
+#if defined(M68K_INST_CACHE_ALIGNMENT)
+#define _CPU_INST_CACHE_ALIGNMENT M68K_INST_CACHE_ALIGNMENT
+#endif
+
+#include <libcpu/cache.h>
+
+#endif
+/* end of include file */
diff --git a/c/src/lib/libcpu/shared/include/cache.h b/c/src/lib/libcpu/shared/include/cache.h
new file mode 100644
index 0000000000..d2ec92686d
--- /dev/null
+++ b/c/src/lib/libcpu/shared/include/cache.h
@@ -0,0 +1,32 @@
+/*
+ * libcpu Cache Manager Support
+ *
+ * $Id$
+ */
+
+#ifndef __LIBCPU_CACHE_h
+#define __LIBCPU_CACHE_h
+
+#include <sys/types.h>
+
+void _CPU_disable_cache();
+void _CPU_enable_cache();
+
+void _CPU_flush_1_data_cache_line(const void *d_addr);
+void _CPU_invalidate_1_data_cache_line(const void *d_addr);
+void _CPU_freeze_data_cache(void);
+void _CPU_unfreeze_data_cache(void);
+void _CPU_invalidate_1_inst_cache_line(const void *d_addr);
+void _CPU_freeze_inst_cache(void);
+void _CPU_unfreeze_inst_cache(void);
+
+void _CPU_flush_entire_data_cache(void);
+void _CPU_invalidate_entire_data_cache(void);
+void _CPU_enable_data_cache(void);
+void _CPU_disable_data_cache(void);
+void _CPU_invalidate_entire_inst_cache(void);
+void _CPU_enable_inst_cache(void);
+void _CPU_disable_inst_cache(void);
+
+#endif
+/* end of include file */
diff --git a/c/src/lib/libcpu/shared/src/cache_aligned_malloc.c b/c/src/lib/libcpu/shared/src/cache_aligned_malloc.c
new file mode 100644
index 0000000000..3289317132
--- /dev/null
+++ b/c/src/lib/libcpu/shared/src/cache_aligned_malloc.c
@@ -0,0 +1,43 @@
+/*
+ * RTEMS Cache Aligned Malloc
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <cache_.h>
+
+/*
+ * rtems_cache_aligned_malloc
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to allocate storage that spans an
+ * integral number of cache blocks.
+ */
+
+void *rtems_cache_aligned_malloc (
+ size_t nbytes
+)
+{
+ /*
+ * Arrange to have the user storage start on the first cache
+ * block beyond the header.
+ */
+#if defined(_CPU_DATA_CACHE_ALIGNMENT)
+ return (void *) ((((unsigned long)
+ malloc( nbytes + _CPU_DATA_CACHE_ALIGNMENT - 1 ))
+ + _CPU_DATA_CACHE_ALIGNMENT - 1 ) &(~(_CPU_DATA_CACHE_ALIGNMENT - 1)) );
+#else
+ return malloc( nbytes );
+#endif
+}
+
diff --git a/c/src/lib/libcpu/shared/src/cache_manager.c b/c/src/lib/libcpu/shared/src/cache_manager.c
new file mode 100644
index 0000000000..e55cf7ea05
--- /dev/null
+++ b/c/src/lib/libcpu/shared/src/cache_manager.c
@@ -0,0 +1,292 @@
+/*
+ * Cache Manager
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ *
+ * The functions in this file implement the API to the RTEMS Cache Manager and
+ * are divided into data cache and instruction cache functions. Data cache
+ * functions are only declared if a data cache is supported. Instruction
+ * cache functions are only declared if an instruction cache is supported.
+ * Support for a particular cache exists only if _CPU_x_CACHE_ALIGNMENT is
+ * defined, where x E {DATA, INST}. These definitions are found in the CPU
+ * dependent source files in the supercore, often
+ *
+ * rtems/c/src/exec/score/cpu/CPU/rtems/score/CPU.h
+ *
+ * The functions below are implemented with CPU dependent inline routines
+ * also found in the above file. In the event that a CPU does not support a
+ * specific function, the CPU dependent routine does nothing (but does exist).
+ *
+ * At this point, the Cache Manager makes no considerations, and provides no
+ * support for BSP specific issues such as a secondary cache. In such a system,
+ * the CPU dependent routines would have to be modified, or a BSP layer added
+ * to this Manager.
+ */
+
+#include <rtems.h>
+#include <sys/types.h>
+#include <libcpu/cache.h>
+#include "cache_.h"
+
+
+/*
+ * THESE FUNCTIONS ONLY HAVE BODIES IF WE HAVE A DATA CACHE
+ */
+
+/*
+ * This function is called to flush the data cache by performing cache
+ * copybacks. It must determine how many cache lines need to be copied
+ * back and then perform the copybacks.
+ */
+void
+rtems_flush_multiple_data_cache_lines( const void * d_addr, size_t n_bytes )
+{
+#if defined(_CPU_DATA_CACHE_ALIGNMENT)
+ const void * final_address;
+
+ /*
+ * Set d_addr to the beginning of the cache line; final_address indicates
+ * the last address_t which needs to be pushed. Increment d_addr and push
+ * the resulting line until final_address is passed.
+ */
+
+ final_address = (void *)((size_t)d_addr + n_bytes - 1);
+ d_addr = (void *)((size_t)d_addr & ~(_CPU_DATA_CACHE_ALIGNMENT - 1));
+ while( d_addr <= final_address ) {
+ _CPU_flush_1_data_cache_line( d_addr );
+ d_addr = (void *)((size_t)d_addr + _CPU_DATA_CACHE_ALIGNMENT);
+ }
+#endif
+}
+
+
+/*
+ * This function is responsible for performing a data cache invalidate.
+ * It must determine how many cache lines need to be invalidated and then
+ * perform the invalidations.
+ */
+
+void
+rtems_invalidate_multiple_data_cache_lines( const void * d_addr, size_t n_bytes )
+{
+#if defined(_CPU_DATA_CACHE_ALIGNMENT)
+ const void * final_address;
+
+ /*
+ * Set d_addr to the beginning of the cache line; final_address indicates
+ * the last address_t which needs to be invalidated. Increment d_addr and
+ * invalidate the resulting line until final_address is passed.
+ */
+
+ final_address = (void *)((size_t)d_addr + n_bytes - 1);
+ d_addr = (void *)((size_t)d_addr & ~(_CPU_DATA_CACHE_ALIGNMENT - 1));
+ while( final_address > d_addr ) {
+ _CPU_invalidate_1_data_cache_line( d_addr );
+ d_addr = (void *)((size_t)d_addr + _CPU_DATA_CACHE_ALIGNMENT);
+ }
+#endif
+}
+
+
+/*
+ * This function is responsible for performing a data cache flush.
+ * It flushes the entire cache.
+ */
+void
+rtems_flush_entire_data_cache( void )
+{
+#if defined(_CPU_DATA_CACHE_ALIGNMENT)
+ /*
+ * Call the CPU-specific routine
+ */
+ _CPU_flush_entire_data_cache();
+#endif
+}
+
+
+/*
+ * This function is responsible for performing a data cache
+ * invalidate. It invalidates the entire cache.
+ */
+void
+rtems_invalidate_entire_data_cache( void )
+{
+#if defined(_CPU_DATA_CACHE_ALIGNMENT)
+ /*
+ * Call the CPU-specific routine
+ */
+
+ _CPU_invalidate_entire_data_cache();
+#endif
+}
+
+
+/*
+ * This function returns the data cache granularity.
+ */
+int
+rtems_get_data_cache_line_size( void )
+{
+#if defined(_CPU_DATA_CACHE_ALIGNMENT)
+ return _CPU_DATA_CACHE_ALIGNMENT;
+#else
+ return 0;
+#endif
+}
+
+
+/*
+ * This function freezes the data cache; cache lines
+ * are not replaced.
+ */
+void
+rtems_freeze_data_cache( void )
+{
+#if defined(_CPU_DATA_CACHE_ALIGNMENT)
+ _CPU_freeze_data_cache();
+#endif
+}
+
+
+/*
+ * This function unfreezes the instruction cache.
+ */
+void rtems_unfreeze_data_cache( void )
+{
+#if defined(_CPU_DATA_CACHE_ALIGNMENT)
+ _CPU_unfreeze_data_cache();
+#endif
+}
+
+
+/* Turn on the data cache. */
+void
+rtems_enable_data_cache( void )
+{
+#if defined(_CPU_DATA_CACHE_ALIGNMENT)
+ _CPU_enable_data_cache();
+#endif
+}
+
+
+/* Turn off the data cache. */
+void
+rtems_disable_data_cache( void )
+{
+#if defined(_CPU_DATA_CACHE_ALIGNMENT)
+ _CPU_disable_data_cache();
+#endif
+}
+
+
+
+/*
+ * THESE FUNCTIONS ONLY HAVE BODIES IF WE HAVE AN INSTRUCTION CACHE
+ */
+
+/*
+ * This function is responsible for performing an instruction cache
+ * invalidate. It must determine how many cache lines need to be invalidated
+ * and then perform the invalidations.
+ */
+void
+rtems_invalidate_multiple_inst_cache_lines( const void * i_addr, size_t n_bytes )
+{
+#if defined(_CPU_INST_CACHE_ALIGNMENT)
+ const void * final_address;
+
+ /*
+ * Set i_addr to the beginning of the cache line; final_address indicates
+ * the last address_t which needs to be invalidated. Increment i_addr and
+ * invalidate the resulting line until final_address is passed.
+ */
+
+ final_address = (void *)((size_t)i_addr + n_bytes - 1);
+ i_addr = (void *)((size_t)i_addr & ~(_CPU_INST_CACHE_ALIGNMENT - 1));
+ while( final_address > i_addr ) {
+ _CPU_invalidate_1_inst_cache_line( i_addr );
+ i_addr = (void *)((size_t)i_addr + _CPU_INST_CACHE_ALIGNMENT);
+ }
+#endif
+}
+
+
+/*
+ * This function is responsible for performing an instruction cache
+ * invalidate. It invalidates the entire cache.
+ */
+void
+rtems_invalidate_entire_inst_cache( void )
+{
+#if defined(_CPU_INST_CACHE_ALIGNMENT)
+ /*
+ * Call the CPU-specific routine
+ */
+
+ _CPU_invalidate_entire_inst_cache();
+#endif
+}
+
+
+/*
+ * This function returns the instruction cache granularity.
+ */
+int
+rtems_get_inst_cache_line_size( void )
+{
+#if defined(_CPU_INST_CACHE_ALIGNMENT)
+ return _CPU_INST_CACHE_ALIGNMENT;
+#else
+ return 0;
+#endif
+}
+
+
+/*
+ * This function freezes the instruction cache; cache lines
+ * are not replaced.
+ */
+void
+rtems_freeze_inst_cache( void )
+{
+#if defined(_CPU_INST_CACHE_ALIGNMENT)
+ _CPU_freeze_inst_cache();
+#endif
+}
+
+
+/*
+ * This function unfreezes the instruction cache.
+ */
+void rtems_unfreeze_inst_cache( void )
+{
+#if defined(_CPU_INST_CACHE_ALIGNMENT)
+ _CPU_unfreeze_inst_cache();
+#endif
+}
+
+
+/* Turn on the instruction cache. */
+void
+rtems_enable_inst_cache( void )
+{
+#if defined(_CPU_INST_CACHE_ALIGNMENT)
+ _CPU_enable_inst_cache();
+#endif
+}
+
+
+/* Turn off the instruction cache. */
+void
+rtems_disable_inst_cache( void )
+{
+#if defined(_CPU_INST_CACHE_ALIGNMENT)
+ _CPU_disable_inst_cache();
+#endif
+}