From acc25eec35e186abc118b9ca4f097e22fc6b4846 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 2 Dec 1999 14:31:19 +0000 Subject: Merged of mcp750 and mvme2307 BSP by Eric Valette . As part of this effort, the mpc750 libcpu code is now shared with the ppc6xx. --- c/src/lib/libcpu/powerpc/mpc6xx/Makefile.in | 25 +++ c/src/lib/libcpu/powerpc/mpc6xx/clock/Makefile.in | 68 +++++++ c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c | 208 +++++++++++++++++++ c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.h | 42 ++++ .../libcpu/powerpc/mpc6xx/exceptions/Makefile.in | 79 ++++++++ .../libcpu/powerpc/mpc6xx/exceptions/asm_utils.S | 65 ++++++ .../powerpc/mpc6xx/exceptions/raw_exception.c | 195 ++++++++++++++++++ .../powerpc/mpc6xx/exceptions/raw_exception.h | 168 ++++++++++++++++ c/src/lib/libcpu/powerpc/mpc6xx/mmu/Makefile.in | 79 ++++++++ c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.c | 64 ++++++ c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.h | 40 ++++ c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmuAsm.S | 224 +++++++++++++++++++++ c/src/lib/libcpu/powerpc/mpc6xx/wrapup/Makefile.in | 62 ++++++ 13 files changed, 1319 insertions(+) create mode 100644 c/src/lib/libcpu/powerpc/mpc6xx/Makefile.in create mode 100644 c/src/lib/libcpu/powerpc/mpc6xx/clock/Makefile.in create mode 100644 c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c create mode 100644 c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.h create mode 100644 c/src/lib/libcpu/powerpc/mpc6xx/exceptions/Makefile.in create mode 100644 c/src/lib/libcpu/powerpc/mpc6xx/exceptions/asm_utils.S create mode 100644 c/src/lib/libcpu/powerpc/mpc6xx/exceptions/raw_exception.c create mode 100644 c/src/lib/libcpu/powerpc/mpc6xx/exceptions/raw_exception.h create mode 100644 c/src/lib/libcpu/powerpc/mpc6xx/mmu/Makefile.in create mode 100644 c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.c create mode 100644 c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.h create mode 100644 c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmuAsm.S create mode 100644 c/src/lib/libcpu/powerpc/mpc6xx/wrapup/Makefile.in (limited to 'c/src/lib/libcpu/powerpc/mpc6xx') diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/Makefile.in b/c/src/lib/libcpu/powerpc/mpc6xx/Makefile.in new file mode 100644 index 0000000000..27fc592154 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc6xx/Makefile.in @@ -0,0 +1,25 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = ../.. +subdir = powerpc/mpc6xx + +RTEMS_ROOT = @RTEMS_ROOT@ +PROJECT_ROOT = @PROJECT_ROOT@ + +VPATH = @srcdir@ + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(RTEMS_ROOT)/make/directory.cfg + +INSTALL_CHANGE = @INSTALL_CHANGE@ + +SUBDIRS = exceptions mmu clock wrapup + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/clock/Makefile.in b/c/src/lib/libcpu/powerpc/mpc6xx/clock/Makefile.in new file mode 100644 index 0000000000..fc945cd304 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc6xx/clock/Makefile.in @@ -0,0 +1,68 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = ../../.. +subdir = powerpc/mpc6xx/clock + +RTEMS_ROOT = @RTEMS_ROOT@ +PROJECT_ROOT = @PROJECT_ROOT@ + +VPATH = @srcdir@ + +# C source names, if any, go here -- minus the .c +C_PIECES = c_clock +C_FILES = $(C_PIECES:%=%.c) +C_O_FILES = $(C_PIECES:%=${ARCH}/%.o) + +H_FILES = $(srcdir)/c_clock.h + +# Assembly source names, if any, go here -- minus the .S +S_PIECES = +S_FILES = $(S_PIECES:%=%.S) +S_O_FILES = $(S_FILES:%.S=${ARCH}/%.o) + +SRCS = $(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS = $(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +INSTALL_CHANGE = @INSTALL_CHANGE@ + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +all: ${ARCH} $(SRCS) preinstall $(OBJS) + +preinstall: $(INSTALLDIRS) $(H_FILES) + @$(INSTALL_CHANGE) -m 644 $(H_FILES) $(PROJECT_INCLUDE)/libcpu + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c b/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c new file mode 100644 index 0000000000..b3d93f8f34 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c @@ -0,0 +1,208 @@ +/* + * Clock Tick Device Driver + * + * This routine utilizes the Decrementer Register common to the PPC family. + * + * The tick frequency is directly programmed to the configured number of + * microseconds per tick. + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * Modified to support the MPC750. + * Modifications Copyright (c) 1999 Eric Valette valette@crf.canon.fr + * + * $Id$ + */ + +#include +#include +#include /* for atexit() */ +#include +#include +#include + +/* + * Clock ticks since initialization + */ + +volatile rtems_unsigned32 Clock_driver_ticks; + +/* + * This is the value programmed into the count down timer. + */ + +rtems_unsigned32 Clock_Decrementer_value; + +/* + * These are set by clock driver during its init + */ + +rtems_device_major_number rtems_clock_major = ~0; +rtems_device_minor_number rtems_clock_minor; + +void clockOff(void* unused) +{ + if (BSP_Configuration.ticks_per_timeslice) { + /* + * Nothing to do as we cannot disable all interrupts and + * the decrementer interrupt enable is MSR_EE + */ + } +} +void clockOn(void* unused) +{ + PPC_Set_decrementer( Clock_Decrementer_value ); +} + +/* + * Clock_isr + * + * This is the clock tick interrupt handler. + * + * Input parameters: + * vector - vector number + * + * Output parameters: NONE + * + * Return values: NONE + * + */ +void clockIsr() +{ + /* + * The driver has seen another tick. + */ + + PPC_Set_decrementer( Clock_Decrementer_value ); + + Clock_driver_ticks += 1; + + /* + * Real Time Clock counter/timer is set to automatically reload. + */ + + rtems_clock_tick(); +} + +int clockIsOn(void* unused) +{ + unsigned32 msr_value; + + _CPU_MSR_GET( msr_value ); + if (msr_value & MSR_EE) return 1; + return 0; +} + + +/* + * Clock_exit + * + * This routine allows the clock driver to exit by masking the interrupt and + * disabling the clock's counter. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: NONE + * + */ + +void Clock_exit( void ) +{ + if ( BSP_Configuration.ticks_per_timeslice ) { + (void) BSP_disconnect_clock_handler (); + } +} + +/* + * Clock_initialize + * + * This routine initializes the clock driver. + * + * Input parameters: + * major - clock device major number + * minor - clock device minor number + * parg - pointer to optional device driver arguments + * + * Output parameters: NONE + * + * Return values: + * rtems_device_driver status code + */ + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp +) +{ + Clock_Decrementer_value = (BSP_bus_frequency/4000)* + (BSP_Configuration.microseconds_per_tick/1000); + + if (!BSP_connect_clock_handler ()) { + printk("Unable to initialize system clock\n"); + rtems_fatal_error_occurred(1); + } + /* make major/minor avail to others such as shared memory driver */ + + rtems_clock_major = major; + rtems_clock_minor = minor; + + return RTEMS_SUCCESSFUL; +} /* Clock_initialize */ + +/* + * Clock_control + * + * This routine is the clock device driver control entry point. + * + * Input parameters: + * major - clock device major number + * minor - clock device minor number + * parg - pointer to optional device driver arguments + * + * Output parameters: NONE + * + * Return values: + * rtems_device_driver status code + */ + +rtems_device_driver Clock_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp +) +{ + rtems_libio_ioctl_args_t *args = pargp; + + if (args == 0) + goto done; + + Clock_Decrementer_value = (BSP_bus_frequency/4000)* + (BSP_Configuration.microseconds_per_tick/1000); + + if (args->command == rtems_build_name('I', 'S', 'R', ' ')) + clockIsr(); + else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) + { + if (!BSP_connect_clock_handler ()) { + printk("Error installing clock interrupt handler!\n"); + rtems_fatal_error_occurred(1); + } + } +done: + return RTEMS_SUCCESSFUL; +} + + + + + + diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.h b/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.h new file mode 100644 index 0000000000..237273f6f9 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.h @@ -0,0 +1,42 @@ +/* + * Clock Tick Device Driver + * + * This routine utilizes the Decrementer Register common to the PPC family. + * + * The tick frequency is directly programmed to the configured number of + * microseconds per tick. + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * Modified to support the MPC750. + * Modifications Copyright (c) 1999 Eric Valette valette@crf.canon.fr + * + * $Id$ + */ + +#ifndef _LIB_LIBCPU_C_CLOCK_H +#define _LIB_LIBCPU_C_CLOCK_H + +#include +#include + +/* + * Theses functions and variables represent the API exported by the CPU to the BSP + */ +extern void clockOff (void* unused); +extern void clockOn (void* unused); +extern void clockIsr (void); +extern int clockIsOn (void* unused); + +#endif + + + + + diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/exceptions/Makefile.in b/c/src/lib/libcpu/powerpc/mpc6xx/exceptions/Makefile.in new file mode 100644 index 0000000000..866432d3e9 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc6xx/exceptions/Makefile.in @@ -0,0 +1,79 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = ../../.. +subdir = powerpc/mpc6xx/exceptions + +RTEMS_ROOT = @RTEMS_ROOT@ +PROJECT_ROOT = @PROJECT_ROOT@ + +VPATH = @srcdir@ + +PGM = ${ARCH}/exceptions.rel + +# C source names, if any, go here -- minus the .c +C_PIECES = raw_exception +C_FILES = $(C_PIECES:%=%.c) +C_O_FILES = $(C_PIECES:%=${ARCH}/%.o) + +H_FILES = $(srcdir)/raw_exception.h + +# Assembly source names, if any, go here -- minus the .S +S_PIECES = asm_utils +S_FILES = $(S_PIECES:%=%.S) +S_O_FILES = $(S_FILES:%.S=${ARCH}/%.o) + +SRCS = $(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS = $(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +INSTALL_CHANGE = @INSTALL_CHANGE@ +mkinstalldirs = $(SHELL) $(top_srcdir)/@RTEMS_TOPdir@/mkinstalldirs + +INSTALLDIRS = $(PROJECT_INCLUDE)/libcpu + +$(INSTALLDIRS): + @$(mkinstalldirs) $(INSTALLDIRS) + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${OBJS} + $(make-rel) + +preinstall: $(INSTALLDIRS) $(H_FILES) + @$(INSTALL_CHANGE) -m 644 $(H_FILES) $(PROJECT_INCLUDE)/libcpu + +all: ${ARCH} $(SRCS) preinstall $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/exceptions/asm_utils.S b/c/src/lib/libcpu/powerpc/mpc6xx/exceptions/asm_utils.S new file mode 100644 index 0000000000..f046915404 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc6xx/exceptions/asm_utils.S @@ -0,0 +1,65 @@ +/* + * asm_utils.s + * + * $Id$ + * + * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr) + * + * This file contains the low-level support for moving exception + * exception code to appropriate location. + * + */ + +#include +#include +#include +#include "asm.h" + + .globl codemove +codemove: + .type codemove,@function +/* r3 dest, r4 src, r5 length in bytes, r6 cachelinesize */ + cmplw cr1,r3,r4 + addi r0,r5,3 + srwi. r0,r0,2 + beq cr1,4f /* In place copy is not necessary */ + beq 7f /* Protect against 0 count */ + mtctr r0 + bge cr1,2f + + la r8,-4(r4) + la r7,-4(r3) +1: lwzu r0,4(r8) + stwu r0,4(r7) + bdnz 1b + b 4f + +2: slwi r0,r0,2 + add r8,r4,r0 + add r7,r3,r0 +3: lwzu r0,-4(r8) + stwu r0,-4(r7) + bdnz 3b + +/* Now flush the cache: note that we must start from a cache aligned + * address. Otherwise we might miss one cache line. + */ +4: cmpwi r6,0 + add r5,r3,r5 + beq 7f /* Always flush prefetch queue in any case */ + subi r0,r6,1 + andc r3,r3,r0 + mr r4,r3 +5: cmplw r4,r5 + dcbst 0,r4 + add r4,r4,r6 + blt 5b + sync /* Wait for all dcbst to complete on bus */ + mr r4,r3 +6: cmplw r4,r5 + icbi 0,r4 + add r4,r4,r6 + blt 6b +7: sync /* Wait for all icbi to complete on bus */ + isync + blr diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/exceptions/raw_exception.c b/c/src/lib/libcpu/powerpc/mpc6xx/exceptions/raw_exception.c new file mode 100644 index 0000000000..cd8274e2e1 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc6xx/exceptions/raw_exception.c @@ -0,0 +1,195 @@ +/* + * raw_exception.c - This file contains implementation of C function to + * Instanciate 60x ppc primary exception entries. + * More detailled information can be found on motorola + * site and more precisely in the following book : + * + * MPC750 + * Risc Microporcessor User's Manual + * Motorola REF : MPC750UM/AD 8/97 + * + * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr) + * Canon Centre Recherche France. + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ +#include +#include +#include +#include +#include +#include + +static rtems_raw_except_connect_data* raw_except_table; +static rtems_raw_except_connect_data default_raw_except_entry; +static rtems_raw_except_global_settings* local_settings; + +int mpc750_vector_is_valid(rtems_vector vector) +{ + switch(vector) { + case ASM_RESET_VECTOR: /* fall through */ + case ASM_MACH_VECTOR: + case ASM_PROT_VECTOR: + case ASM_ISI_VECTOR: + case ASM_EXT_VECTOR: + case ASM_ALIGN_VECTOR: + case ASM_PROG_VECTOR: + case ASM_FLOAT_VECTOR: + case ASM_DEC_VECTOR: + case ASM_SYS_VECTOR: + case ASM_TRACE_VECTOR: + case ASM_ADDR_VECTOR: + case ASM_SYSMGMT_VECTOR: + case ASM_ITM_VECTOR: + return 1; + default: return 0; + } +} + +int mpc604_vector_is_valid(rtems_vector vector) +{ + /* + * Please fill this for MVME2307 + */ + printk("Please complete libcpu/powerpc/XXX/raw_exception.c\n"); + return 0; +} + +int mpc60x_set_exception (const rtems_raw_except_connect_data* except) +{ + unsigned int level; + + if (current_ppc_cpu == PPC_750) { + if (!mpc750_vector_is_valid(except->exceptIndex)){ + return 0; + } + goto exception_ok; + } + if (current_ppc_cpu == PPC_604) { + if (!mpc604_vector_is_valid(except->exceptIndex)){ + return 0; + } + goto exception_ok; + } + printk("Please complete libcpu/powerpc/XXX/raw_exception.c\n"); + return 0; + +exception_ok: + /* + * Check if default handler is actually connected. If not issue an error. + * You must first get the current handler via mpc60x_get_current_exception + * and then disconnect it using mpc60x_delete_exception. + * RATIONALE : to always have the same transition by forcing the user + * to get the previous handler before accepting to disconnect. + */ + if (memcmp(mpc60x_get_vector_addr(except->exceptIndex), (void*)default_raw_except_entry.hdl.raw_hdl,default_raw_except_entry.hdl.raw_hdl_size)) { + return 0; + } + + _CPU_ISR_Disable(level); + + raw_except_table [except->exceptIndex] = *except; + codemove((void*)mpc60x_get_vector_addr(except->exceptIndex), + except->hdl.raw_hdl, + except->hdl.raw_hdl_size, + PPC_CACHE_ALIGNMENT); + except->on(except); + + _CPU_ISR_Enable(level); + return 1; +} + +int mpc60x_get_current_exception (rtems_raw_except_connect_data* except) +{ + if (!mpc750_vector_is_valid(except->exceptIndex)){ + return 0; + } + + *except = raw_except_table [except->exceptIndex]; + + return 1; +} + +int mpc60x_delete_exception (const rtems_raw_except_connect_data* except) +{ + unsigned int level; + + if (!mpc750_vector_is_valid(except->exceptIndex)){ + return 0; + } + /* + * Check if handler passed is actually connected. If not issue an error. + * You must first get the current handler via mpc60x_get_current_exception + * and then disconnect it using mpc60x_delete_exception. + * RATIONALE : to always have the same transition by forcing the user + * to get the previous handler before accepting to disconnect. + */ + if (memcmp(mpc60x_get_vector_addr(except->exceptIndex), + (void*)except->hdl.raw_hdl, + except->hdl.raw_hdl_size)) { + return 0; + } + _CPU_ISR_Disable(level); + + except->off(except); + codemove((void*)mpc60x_get_vector_addr(except->exceptIndex), + default_raw_except_entry.hdl.raw_hdl, + default_raw_except_entry.hdl.raw_hdl_size, + PPC_CACHE_ALIGNMENT); + + + raw_except_table[except->exceptIndex] = default_raw_except_entry; + raw_except_table[except->exceptIndex].exceptIndex = except->exceptIndex; + + _CPU_ISR_Enable(level); + + return 1; +} + +/* + * Exception global init. + */ +int mpc60x_init_exceptions (rtems_raw_except_global_settings* config) +{ + unsigned i; + unsigned int level; + + /* + * store various accelerators + */ + raw_except_table = config->rawExceptHdlTbl; + local_settings = config; + default_raw_except_entry = config->defaultRawEntry; + + _CPU_ISR_Disable(level); + + for (i=0; i <= LAST_VALID_EXC; i++) { + if (!mpc750_vector_is_valid(i)){ + continue; + } + codemove((void*)mpc60x_get_vector_addr(i), + raw_except_table[i].hdl.raw_hdl, + raw_except_table[i].hdl.raw_hdl_size, + PPC_CACHE_ALIGNMENT); + if (raw_except_table[i].hdl.raw_hdl != default_raw_except_entry.hdl.raw_hdl) { + raw_except_table[i].on(&raw_except_table[i]); + } + else { + raw_except_table[i].off(&raw_except_table[i]); + } + } + _CPU_ISR_Enable(level); + + return 1; +} + +int mpc60x_get_exception_config (rtems_raw_except_global_settings** config) +{ + *config = local_settings; + return 1; +} + diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/exceptions/raw_exception.h b/c/src/lib/libcpu/powerpc/mpc6xx/exceptions/raw_exception.h new file mode 100644 index 0000000000..f6542b9dfe --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc6xx/exceptions/raw_exception.h @@ -0,0 +1,168 @@ +/* + * raw_execption.h + * + * This file contains implementation of C function to + * Instanciate 60x ppc primary exception entries. + * More detailled information can be found on motorola + * site and more precisely in the following book : + * + * MPC750 + * Risc Microporcessor User's Manual + * Mtorola REF : MPC750UM/AD 8/97 + * + * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr) + * Canon Centre Recherche France. + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#ifndef _LIBCPU_MCP750_EXCEPTION_RAW_EXCEPTION_H +#define _LIBCPU_MCP750_EXCEPTION_RAW_EXCEPTION_H + +/* + * Exception Vectors as defined in the MCP750 manual + */ + +#define ASM_RESET_VECTOR 0x01 +#define ASM_MACH_VECTOR 0x02 +#define ASM_PROT_VECTOR 0x03 +#define ASM_ISI_VECTOR 0x04 +#define ASM_EXT_VECTOR 0x05 +#define ASM_ALIGN_VECTOR 0x06 +#define ASM_PROG_VECTOR 0x07 +#define ASM_FLOAT_VECTOR 0x08 +#define ASM_DEC_VECTOR 0x09 +#define ASM_SYS_VECTOR 0x0C +#define ASM_TRACE_VECTOR 0x0D +#define ASM_ADDR_VECTOR 0x13 +#define ASM_SYSMGMT_VECTOR 0x14 +#define ASM_ITM_VECTOR 0x17 +#define LAST_VALID_EXC ASM_ITM_VECTOR + +/* + * Vector offsets as defined in the MCP750 manual + */ + +#define ASM_RESET_VECTOR_OFFSET (ASM_RESET_VECTOR << 8) +#define ASM_MACH_VECTOR_OFFSET (ASM_MACH_VECTOR << 8) +#define ASM_PROT_VECTOR_OFFSET (ASM_PROT_VECTOR << 8) +#define ASM_ISI_VECTOR_OFFSET (ASM_ISI_VECTOR << 8) +#define ASM_EXT_VECTOR_OFFSET (ASM_EXT_VECTOR << 8) +#define ASM_ALIGN_VECTOR_OFFSET (ASM_ALIGN_VECTOR << 8) +#define ASM_PROG_VECTOR_OFFSET (ASM_PROG_VECTOR << 8) +#define ASM_FLOAT_VECTOR_OFFSET (ASM_FLOAT_VECTOR << 8) +#define ASM_DEC_VECTOR_OFFSET (ASM_DEC_VECTOR << 8) +#define ASM_SYS_VECTOR_OFFSET (ASM_SYS_VECTOR << 8) +#define ASM_TRACE_VECTOR_OFFSET (ASM_TRACE_VECTOR << 8) +#define ASM_ADDR_VECTOR_OFFSET (ASM_ADDR_VECTOR << 8) +#define ASM_SYSMGMT_VECTOR_OFFSET (ASM_SYSMGMT_VECTOR << 8) +#define ASM_ITM_VECTOR_OFFSET (ASM_ITM_VECTOR << 8) + + +#ifndef ASM + +/* + * Type definition for raw exceptions. + */ + +typedef unsigned char rtems_vector; +struct __rtems_raw_except_connect_data__; +typedef void (*rtems_raw_except_func) (void); +typedef unsigned char rtems_raw_except_hdl_size; + +typedef struct { + rtems_vector vector; + rtems_raw_except_func raw_hdl; + rtems_raw_except_hdl_size raw_hdl_size; +}rtems_raw_except_hdl; + +typedef void (*rtems_raw_except_enable) (const struct __rtems_raw_except_connect_data__*); +typedef void (*rtems_raw_except_disable) (const struct __rtems_raw_except_connect_data__*); +typedef int (*rtems_raw_except_is_enabled) (const struct __rtems_raw_except_connect_data__*); + +typedef struct __rtems_raw_except_connect_data__{ + /* + * Exception vector (As defined in the manual) + */ + rtems_vector exceptIndex; + /* + * Exception raw handler. See comment on handler properties below in function prototype. + */ + rtems_raw_except_hdl hdl; + /* + * function for enabling raw exceptions. In order to be consistent + * with the fact that the raw connexion can defined in the + * libcpu library, this library should have no knowledge of + * board specific hardware to manage exceptions and thus the + * "on" routine must enable the except at processor level only. + * + */ + rtems_raw_except_enable on; + /* + * function for disabling raw exceptions. In order to be consistent + * with the fact that the raw connexion can defined in the + * libcpu library, this library should have no knowledge of + * board specific hardware to manage exceptions and thus the + * "on" routine must disable the except both at device and PIC level. + * + */ + rtems_raw_except_disable off; + /* + * function enabling to know what exception may currently occur + */ + rtems_raw_except_is_enabled isOn; +}rtems_raw_except_connect_data; + +typedef struct { + /* + * size of all the table fields (*Tbl) described below. + */ + unsigned int exceptSize; + /* + * Default handler used when disconnecting exceptions. + */ + rtems_raw_except_connect_data defaultRawEntry; + /* + * Table containing initials/current value. + */ + rtems_raw_except_connect_data* rawExceptHdlTbl; +}rtems_raw_except_global_settings; + +/* + * C callable function enabling to set up one raw idt entry + */ +extern int mpc60x_set_exception (const rtems_raw_except_connect_data*); + +/* + * C callable function enabling to get one current raw idt entry + */ +extern int mpc60x_get_current_exception (rtems_raw_except_connect_data*); + +/* + * C callable function enabling to remove one current raw idt entry + */ +extern int mpc60x_delete_exception (const rtems_raw_except_connect_data*); + +/* + * C callable function enabling to check if vector is valid + */ +extern int mpc750_vector_is_valid(rtems_vector vector); + +inline static void* mpc60x_get_vector_addr(rtems_vector vector) +{ + return ((void*) (((unsigned) vector) << 8)); +} +/* + * Exception global init. + */ +extern int mpc60x_init_exceptions (rtems_raw_except_global_settings* config); +extern int mpc60x_get_exception_config (rtems_raw_except_global_settings** config); + +# endif /* ASM */ + +#endif + diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/mmu/Makefile.in b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/Makefile.in new file mode 100644 index 0000000000..44278afbbc --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/Makefile.in @@ -0,0 +1,79 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = ../../.. +subdir = powerpc/mpc6xx/mmu + +RTEMS_ROOT = @RTEMS_ROOT@ +PROJECT_ROOT = @PROJECT_ROOT@ + +VPATH = @srcdir@ + +PGM = ${ARCH}/mmu.rel + +# C source names, if any, go here -- minus the .c +C_PIECES = bat +C_FILES = $(C_PIECES:%=%.c) +C_O_FILES = $(C_PIECES:%=${ARCH}/%.o) + +H_FILES = $(srcdir)/bat.h + +# Assembly source names, if any, go here -- minus the .S +S_PIECES = mmuAsm +S_FILES = $(S_PIECES:%=%.S) +S_O_FILES = $(S_FILES:%.S=${ARCH}/%.o) + +SRCS = $(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS = $(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +INSTALL_CHANGE = @INSTALL_CHANGE@ +mkinstalldirs = $(SHELL) $(top_srcdir)/@RTEMS_TOPdir@/mkinstalldirs + +INSTALLDIRS = $(PROJECT_INCLUDE)/libcpu + +$(INSTALLDIRS): + @$(mkinstalldirs) $(INSTALLDIRS) + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${OBJS} + $(make-rel) + +preinstall: $(INSTALLDIRS) $(H_FILES) + @$(INSTALL_CHANGE) -m 644 $(H_FILES) $(PROJECT_INCLUDE)/libcpu + +all: ${ARCH} $(SRCS) preinstall $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.c b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.c new file mode 100644 index 0000000000..e39ab96ec5 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.c @@ -0,0 +1,64 @@ +/* + * bat.c + * + * This file contains the implementation of C function to + * Instanciate 60x/7xx ppc Block Address Translation (BAT) registers. + * More detailled information can be found on motorola + * site and more precisely in the following book : + * + * MPC750 + * Risc Microporcessor User's Manual + * Mtorola REF : MPC750UM/AD 8/97 + * + * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr) + * Canon Centre Recherche France. + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include + +typedef union { /* BAT register values to be loaded */ + BAT bat; + unsigned int word[2]; +}ubat; + +typedef struct batrange { /* stores address ranges mapped by BATs */ + unsigned long start; + unsigned long limit; + unsigned long phys; +}batrange; + +batrange bat_addrs[4]; + +void setdbat(int bat_index, unsigned long virt, unsigned long phys, + unsigned int size, int flags) +{ + unsigned int bl; + int wimgxpp; + ubat bat; + + bl = (size >> 17) - 1; + /* 603, 604, etc. */ + wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE + | _PAGE_COHERENT | _PAGE_GUARDED); + wimgxpp |= (flags & _PAGE_RW)? BPP_RW: BPP_RX; + bat.word[0] = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */ + bat.word[1] = phys | wimgxpp; + if (flags & _PAGE_USER) + bat.bat.batu.vp = 1; + bat_addrs[bat_index].start = virt; + bat_addrs[bat_index].limit = virt + ((bl + 1) << 17) - 1; + bat_addrs[bat_index].phys = phys; + switch (bat_index) { + case 1 : asm_setdbat1(bat.word[0], bat.word[1]); break; + case 2 : asm_setdbat2(bat.word[0], bat.word[1]); break; + case 3 : asm_setdbat3(bat.word[0], bat.word[1]); break; + default: printk("bat.c : invalid BAT bat_index\n"); + } +} + diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.h b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.h new file mode 100644 index 0000000000..616f6182a4 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.h @@ -0,0 +1,40 @@ +/* + * bat.h + * + * This file contains declaration of C function to + * Instanciate 60x/7xx ppc Block Address Translation (BAT) registers. + * More detailled information can be found on motorola + * site and more precisely in the following book : + * + * MPC750 + * Risc Microporcessor User's Manual + * Mtorola REF : MPC750UM/AD 8/97 + * + * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr) + * Canon Centre Recherche France. + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#ifndef LIBCPU_MCP750_MMU_BAT_H +#define LIBCPU_MCP750_MMU_BAT_H + +#include +#include +#include + +#define IO_PAGE (_PAGE_NO_CACHE | _PAGE_GUARDED | _PAGE_RW) + +extern void setdbat(int bat_index, unsigned long virt, unsigned long phys, + unsigned int size, int flags); + +extern void asm_setdbat1(unsigned int uperPart, unsigned int lowerPart); +extern void asm_setdbat2(unsigned int uperPart, unsigned int lowerPart); +extern void asm_setdbat3(unsigned int uperPart, unsigned int lowerPart); +extern void asm_setdbat4(unsigned int uperPart, unsigned int lowerPart); + +#endif /* LIBCPU_MCP750_MMU_BAT_H */ diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmuAsm.S b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmuAsm.S new file mode 100644 index 0000000000..a0f298e5c3 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmuAsm.S @@ -0,0 +1,224 @@ +/* + * mmuAsm.S + * + * $Id$ + * + * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr) + * + * This file contains the low-level support for various MMU + * features. + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + */ + +#include +#include +#include +#include "asm.h" + + .globl asm_setdbat1 + .type asm_setdbat1,@function +asm_setdbat1: + mtspr DBAT1U, r3 + mtspr DBAT1L, r4 + SYNC + blr + + .globl asm_setdbat2 + .type asm_setdbat2,@function +asm_setdbat2: + mtspr DBAT2U, r3 + mtspr DBAT2L, r4 + SYNC + blr + + .globl asm_setdbat3 + .type asm_setdbat3,@function +asm_setdbat3: + mtspr DBAT3U, r3 + mtspr DBAT3L, r4 + SYNC + blr + + .globl L1_caches_enables + .type L1_caches_enables, @function + +L1_caches_enables: + /* + * Enable caches and 604-specific features if necessary. + */ + mfspr r9,PVR + rlwinm r9,r9,16,16,31 + cmpi 0,r9,1 + beq 4f /* not needed for 601 */ + mfspr r11,HID0 + andi. r0,r11,HID0_DCE + ori r11,r11,HID0_ICE|HID0_DCE + ori r8,r11,HID0_ICFI + bne 3f /* don't invalidate the D-cache */ + ori r8,r8,HID0_DCI /* unless it wasn't enabled */ +3: + sync + mtspr HID0,r8 /* enable and invalidate caches */ + sync + mtspr HID0,r11 /* enable caches */ + sync + isync + cmpi 0,r9,4 /* check for 604 */ + cmpi 1,r9,9 /* or 604e */ + cmpi 2,r9,10 /* or mach5 */ + cror 2,2,6 + cror 2,2,10 + bne 4f + ori r11,r11,HID0_SIED|HID0_BHTE /* for 604[e], enable */ + bne 2,5f + ori r11,r11,HID0_BTCD +5: mtspr HID0,r11 /* superscalar exec & br history tbl */ +4: + blr + + .globl get_L2CR + .type get_L2CR, @function +get_L2CR: + /* Make sure this is a 750 chip */ + mfspr r3,PVR + rlwinm r3,r3,16,16,31 + cmplwi r3,0x0008 + li r3,0 + bnelr + + /* Return the L2CR contents */ + mfspr r3,L2CR + blr + + .globl set_L2CR + .type set_L2CR, @function +set_L2CR: + /* Usage: + * When setting the L2CR register, you must do a few special things. + * If you are enabling the cache, you must perform a global invalidate. + * If you are disabling the cache, you must flush the cache contents first. + * This routine takes care of doing these things. When first + * enabling the cache, make sure you pass in the L2CR you want, as well as + * passing in the global invalidate bit set. A global invalidate will + * only be performed if the L2I bit is set in applyThis. When enabling + * the cache, you should also set the L2E bit in applyThis. If you + * want to modify the L2CR contents after the cache has been enabled, + * the recommended procedure is to first call __setL2CR(0) to disable + * the cache and then call it again with the new values for L2CR. Examples: + * + * _setL2CR(0) - disables the cache + * _setL2CR(0xb9A14000) - enables my G3 MCP750 card: + * - L2E set to turn on the cache + * - L2SIZ set to 1MB + * - L2CLK set to %2 + * - L2RAM set to pipelined syncronous late-write + * - L2I set to perform a global invalidation + * - L2OH set to 1 nS + * + * A similar call should work for your card. You need to know the correct + * setting for your card and then place them in the fields I have outlined + * above. Other fields support optional features, such as L2DO which caches + * only data, or L2TS which causes cache pushes from the L1 cache to go to + *the L2 cache instead of to main memory. + */ + + /* Make sure this is a 750 chip */ + mfspr r4,PVR + rlwinm r4,r4,16,16,31 + cmplwi r4,0x0008 + beq thisIs750 + li r3,-1 + blr + +thisIs750: + /* Get the current enable bit of the L2CR into r4 */ + mfspr r4,L2CR + rlwinm r4,r4,0,0,0 + + /* See if we want to perform a global inval this time. */ + rlwinm r6,r3,0,10,10 /* r6 contains the new invalidate bit */ + rlwinm. r5,r3,0,0,0 /* r5 contains the new enable bit */ + rlwinm r3,r3,0,11,9 /* Turn off the invalidate bit */ + rlwinm r3,r3,0,1,31 /* Turn off the enable bit */ + or r3,r3,r4 /* Keep the enable bit the same as it was for now. */ + bne dontDisableCache /* Only disable the cache if L2CRApply has the enable bit off */ + +disableCache: + /* Disable the cache. First, we turn off data relocation. */ + mfmsr r7 + rlwinm r4,r7,0,28,26 /* Turn off DR bit */ + rlwinm r4,r4,0,17,15 /* Turn off EE bit - an external exception while we are flushing + the cache is fatal (comment this line and see!) */ + sync + mtmsr r4 + sync + + /* + Now, read the first 2MB of memory to put new data in the cache. + (Actually we only need the size of the L2 cache plus + the size of the L1 cache, but 2MB will cover everything just to be safe). + */ + lis r4,0x0001 + mtctr r4 + li r4,0 +loadLoop: + lwzx r0,r0,r4 + addi r4,r4,0x0020 /* Go to start of next cache line */ + bdnz loadLoop + + /* Now, flush the first 2MB of memory */ + lis r4,0x0001 + mtctr r4 + li r4,0 + sync +flushLoop: + dcbf r0,r4 + addi r4,r4,0x0020 /* Go to start of next cache line */ + bdnz flushLoop + + /* Turn off the L2CR enable bit. */ + rlwinm r3,r3,0,1,31 + + /* Reenable data relocation. */ + sync + mtmsr r7 + sync + +dontDisableCache: + /* Set up the L2CR configuration bits */ + sync + mtspr L2CR,r3 + sync + cmplwi r6,0 + beq noInval + + /* Perform a global invalidation */ + oris r3,r3,0x0020 + sync + mtspr 1017,r3 + sync +invalCompleteLoop: /* Wait for the invalidation to complete */ + mfspr r3,1017 + rlwinm. r4,r3,0,31,31 + bne invalCompleteLoop + + rlwinm r3,r3,0,11,9; /* Turn off the L2I bit */ + sync + mtspr L2CR,r3 + sync + +noInval: + /* See if we need to enable the cache */ + cmplwi r5,0 + beqlr + +enableCache: + /* Enable the cache */ + oris r3,r3,0x8000 + mtspr L2CR,r3 + sync + blr diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/wrapup/Makefile.in b/c/src/lib/libcpu/powerpc/mpc6xx/wrapup/Makefile.in new file mode 100644 index 0000000000..577d6b09a6 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc6xx/wrapup/Makefile.in @@ -0,0 +1,62 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = ../../.. +subdir = powerpc/mpc6xx/wrapup + +RTEMS_ROOT = @RTEMS_ROOT@ +PROJECT_ROOT = @PROJECT_ROOT@ + +VPATH = @srcdir@ + +# PROC_SPECIFIC_O_PIECES = exceptions mmu clock +PROC_SPECIFIC_O_PIECES = exceptions mmu +GENERIC_PIECES = + +# bummer; have to use $foreach since % pattern subst rules only replace 1x +OBJS = $(foreach piece, $(PROC_SPECIFIC_O_PIECES), \ + ../../mpc6xx/$(piece)/$(ARCH)/*.o) $(foreach piece, \ + $(GENERIC_PIECES), ../../mpc6xx/$(piece)/$(ARCH)/*.o) +LIB = $(ARCH)/libcpuspec.a + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(RTEMS_ROOT)/make/lib.cfg + +INSTALL_CHANGE = @INSTALL_CHANGE@ + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +$(LIB): ${OBJS} + echo $(OBJ) + $(make-library) + cp $(LIB) .. + +all: ${ARCH} $(SRCS) $(LIB) + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status -- cgit v1.2.3