diff options
author | Ric Claus <claus@slac.stanford.edu> | 2012-11-30 15:58:32 -0800 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-12-01 09:04:20 +0100 |
commit | 655bd396762cfce47959f019f8524974eb4d0983 (patch) | |
tree | d675863c2b027c7c719aa8bcbc022fa5b56c461b /c/src/lib/libbsp/powerpc/virtex5 | |
parent | Virtex4 BSP: Various updates and improvements. (diff) | |
download | rtems-655bd396762cfce47959f019f8524974eb4d0983.tar.bz2 |
Virtex5 BSP: Various updates and improvements.
This BSP now uses the MPC6xx clock driver instead of a modified PPC403 clock
driver. Support for the MMU has been added, but is not enabled by default.
Diffstat (limited to 'c/src/lib/libbsp/powerpc/virtex5')
-rw-r--r-- | c/src/lib/libbsp/powerpc/virtex5/Makefile.am | 14 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/virtex5/README | 86 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/virtex5/console/dummy_console.c | 102 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/virtex5/include/irq.h | 4 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/virtex5/include/mmu.h | 287 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/virtex5/irq/irq_init.c | 37 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/virtex5/mmu/mmu.c | 581 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/virtex5/preinstall.am | 4 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/virtex5/startup/bspstart.c | 104 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/virtex5/startup/linkcmds | 11 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/virtex5/startup/start.S | 101 |
11 files changed, 1121 insertions, 210 deletions
diff --git a/c/src/lib/libbsp/powerpc/virtex5/Makefile.am b/c/src/lib/libbsp/powerpc/virtex5/Makefile.am index 31d39878cb..0781369a12 100644 --- a/c/src/lib/libbsp/powerpc/virtex5/Makefile.am +++ b/c/src/lib/libbsp/powerpc/virtex5/Makefile.am @@ -35,14 +35,14 @@ libbsp_a_SOURCES = startup/bspclean.c \ startup/bspstart.c \ ../../shared/bootcard.c \ ../../shared/sbrk.c \ - ../../shared/gnatinstallhandler.c + ../../shared/gnatinstallhandler.c \ + ../shared/src/memcpy.c # start libbsp_a_SOURCES += startup/start.S # clock & timer -libbsp_a_SOURCES += ../../../libcpu/@RTEMS_CPU@/ppc403/clock/clock.c -libbsp_a_SOURCES += ../../../libcpu/@RTEMS_CPU@/ppc403/timer/timer.c +libbsp_a_SOURCES += ../../powerpc/shared/clock/p_clock.c # console libbsp_a_SOURCES += startup/dummy_console.c \ @@ -52,6 +52,10 @@ libbsp_a_SOURCES += startup/dummy_console.c \ include_bsp_HEADERS += include/irq.h libbsp_a_SOURCES += irq/irq_init.c +# mmu +include_bsp_HEADERS += include/mmu.h +libbsp_a_SOURCES += mmu/mmu.c + #vectors include_bsp_HEADERS += ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/vectors.h include_bsp_HEADERS += ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/irq_supp.h @@ -59,7 +63,9 @@ include_bsp_HEADERS += ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/irq_s libbsp_a_LIBADD = ../../../libcpu/@RTEMS_CPU@/@exceptions@/rtems-cpu.rel \ ../../../libcpu/@RTEMS_CPU@/@exceptions@/exc_bspsupport.rel \ ../../../libcpu/@RTEMS_CPU@/shared/cache.rel \ - ../../../libcpu/@RTEMS_CPU@/shared/cpuIdent.rel + ../../../libcpu/@RTEMS_CPU@/shared/cpuIdent.rel \ + ../../../libcpu/@RTEMS_CPU@/e500/clock.rel \ + ../../../libcpu/@RTEMS_CPU@/e500/timer.rel EXTRA_DIST = times diff --git a/c/src/lib/libbsp/powerpc/virtex5/README b/c/src/lib/libbsp/powerpc/virtex5/README new file mode 100644 index 0000000000..a68bd23838 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/virtex5/README @@ -0,0 +1,86 @@ +# Adapted from virtex BSP + +BSP NAME: virtex5 +BOARD: N/A +BUS: N/A +CPU FAMILY: ppc +CPU: PowerPC 440x5 +COPROCESSORS: N/A +MODE: 32 bit mode + +DEBUG MONITOR: + +PERIPHERALS +=========== +TIMERS: 440 internal +SERIAL PORTS: none +REAL-TIME CLOCK: none +DMA: Xilinx virtex internal +VIDEO: none +SCSI: none +NETWORKING: none + +DRIVER INFORMATION +================== +CLOCK DRIVER: PPC Decrementer +IOSUPP DRIVER: N/A +SHMSUPP: N/A +TIMER DRIVER: N/A +TTY DRIVER: N/A + +STDIO +===== +PORT: N/A +ELECTRICAL: N/A +BAUD: N/A +BITS PER CHARACTER: N/A +PARITY: N/A +STOP BITS: N/A + +Notes +===== + +Board description +----------------- +clock rate: 465 MHz +ROM: N/A +RAM: 4GByte DRAM + +Virtex only supports single processor operations. + +Porting +------- +This board support package is written for a naked Virtex 5/PPC FPGA +system. The rough features of such a board are described above. +The BSP itself makes no assumptions on what is loaded in the FPGA, +other than that the CPU has access to some memory, either on-board +or external, from which code can be run. + +This BSP has been constructed so that an application of both firmware +and software can be layered on top of it by supplying implementations +for the various 'weak' symbols. These symbols are prefaced with the +term 'app_'. Applications can thus be built outside of the RTEMS +directory tree by linking with the appropriate libraries. + +The linkcmds file describes the memory layout. Included in this +definition is a section of memory named MsgArea. Output sent to +stdout is recorded in this area and can be dumped using the JTAG +interface, for example. + +For adapting this BSP to other boards, the following files should be +modified: + +- c/src/lib/libbsp/powerpc/virtex5/startup/linkcmds + for the memory layout required + +- c/src/lib/libbsp/powerpc/virtex5/startup/bspstart.c + Here you can select the clock source for the timers and the + serial interface (system clock or external clock pin), the + clock rates, etc. + +- c/src/lib/libbsp/powerpc/virtex5/include/bsp.h + some BSP-related constants + +- c/src/lib/libbsp/powerpc/virtex5/* + well, they should be generic, so there _should_ be no reason + to mess around there (but who knows...) diff --git a/c/src/lib/libbsp/powerpc/virtex5/console/dummy_console.c b/c/src/lib/libbsp/powerpc/virtex5/console/dummy_console.c deleted file mode 100644 index 048133d1c2..0000000000 --- a/c/src/lib/libbsp/powerpc/virtex5/console/dummy_console.c +++ /dev/null @@ -1,102 +0,0 @@ -#include <rtems.h> -#include <rtems/libio.h> - -#include <string.h> - -ssize_t app_memory_write(int minor, const char* buf, size_t len) -__attribute__(( weak, alias("__bsp_memory_write") )); - -ssize_t __bsp_memory_write(int minor, const char* buf, size_t len); -rtems_device_driver console_initialize(rtems_device_major_number major, - rtems_device_minor_number minor, - void* arg); -rtems_device_driver console_open(rtems_device_major_number major, - rtems_device_minor_number minor, - void* arg); -rtems_device_driver console_close(rtems_device_major_number major, - rtems_device_minor_number minor, - void* arg); -rtems_device_driver console_read(rtems_device_major_number major, - rtems_device_minor_number minor, - void* arg); -rtems_device_driver console_write(rtems_device_major_number major, - rtems_device_minor_number minor, - void* arg); -rtems_device_driver console_control(rtems_device_major_number major, - rtems_device_minor_number minor, - void* arg); - - -ssize_t __bsp_memory_write(int minor, const char* buf, size_t len) -{ - const char* const last = buf+len; - while (buf < last) - { - BSP_output_char(*buf++); - } - return len; -} - -static rtems_termios_callbacks gMemCallbacks = { - 0, /* firstOpen */ - 0, /* lastClose */ - 0, /* PollRead */ - app_memory_write, /* write */ - 0, /* SetAttr */ - 0, /* stopRemoteTx */ - 0, /* startRemoteTx */ - 0 /* outputUsesInterrupts */ -}; - -rtems_device_driver console_initialize(rtems_device_major_number major, - rtems_device_minor_number minor, - void* arg) -{ - rtems_status_code status; - - rtems_termios_initialize(); - - status = rtems_io_register_name("/dev/console", major, 0); - - if (status != RTEMS_SUCCESSFUL) rtems_fatal_error_occurred (status); - return RTEMS_SUCCESSFUL; -} - -rtems_device_driver console_open(rtems_device_major_number major, - rtems_device_minor_number minor, - void* arg) -{ - rtems_status_code sc; - - sc = rtems_termios_open (major, minor, arg, &gMemCallbacks); - - return sc; -} - -rtems_device_driver console_close(rtems_device_major_number major, - rtems_device_minor_number minor, - void* arg) -{ - return rtems_termios_close(arg); -} - -rtems_device_driver console_read(rtems_device_major_number major, - rtems_device_minor_number minor, - void* arg) -{ - return rtems_termios_read(arg); -} - -rtems_device_driver console_write(rtems_device_major_number major, - rtems_device_minor_number minor, - void* arg) -{ - return rtems_termios_write(arg); -} - -rtems_device_driver console_control(rtems_device_major_number major, - rtems_device_minor_number minor, - void* arg) -{ - return rtems_termios_ioctl(arg); -} diff --git a/c/src/lib/libbsp/powerpc/virtex5/include/irq.h b/c/src/lib/libbsp/powerpc/virtex5/include/irq.h index 2edf6aa917..a87562fdd2 100644 --- a/c/src/lib/libbsp/powerpc/virtex5/include/irq.h +++ b/c/src/lib/libbsp/powerpc/virtex5/include/irq.h @@ -71,6 +71,10 @@ extern "C" { #ifdef __cplusplus } + +#define BSP_DEC BSP_PIT +#define BSP_DECREMENTER BSP_PIT + #endif #endif /* ASM */ diff --git a/c/src/lib/libbsp/powerpc/virtex5/include/mmu.h b/c/src/lib/libbsp/powerpc/virtex5/include/mmu.h new file mode 100644 index 0000000000..a3fb32b662 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/virtex5/include/mmu.h @@ -0,0 +1,287 @@ +#ifndef RTEMS_VIRTEX5_MMU_H +#define RTEMS_VIRTEX5_MMU_H +/** + * @file + * + * @ingroup Virtex5MMU + * + * @brief Routines to manipulate the PPC 440 MMU. + */ +/* + * Authorship + * ---------- + * This software was created by + * Till Straumann <strauman@slac.stanford.edu>, 2005-2007, + * Stanford Linear Accelerator Center, Stanford University. + * and was transcribed for the PPC 440 by + * R. Claus <claus@slac.stanford.edu>, 2012, + * Stanford Linear Accelerator Center, Stanford University, + * + * Acknowledgement of sponsorship + * ------------------------------ + * This software was produced by + * the Stanford Linear Accelerator Center, Stanford University, + * under Contract DE-AC03-76SFO0515 with the Department of Energy. + * + * Government disclaimer of liability + * ---------------------------------- + * Neither the United States nor the United States Department of Energy, + * nor any of their employees, makes any warranty, express or implied, or + * assumes any legal liability or responsibility for the accuracy, + * completeness, or usefulness of any data, apparatus, product, or process + * disclosed, or represents that its use would not infringe privately owned + * rights. + * + * Stanford disclaimer of liability + * -------------------------------- + * Stanford University makes no representations or warranties, express or + * implied, nor assumes any liability for the use of this software. + * + * Stanford disclaimer of copyright + * -------------------------------- + * Stanford University, owner of the copyright, hereby disclaims its + * copyright and all other rights in this software. Hence, anyone may + * freely use it for any purpose without restriction. + * + * Maintenance of notices + * ---------------------- + * In the interest of clarity regarding the origin and status of this + * SLAC software, this and all the preceding Stanford University notices + * are to remain affixed to any copy or derivative of this software made + * or distributed by the recipient and are to be affixed to any copy of + * software made or distributed by the recipient that contains a copy or + * derivative of this software. + * + * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 + */ + +#include <rtems.h> +#include <inttypes.h> +#include <stdio.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup Virtex5MMU Virtex 5 - MMU Support + * + * @ingroup Virtex5 + * + * @brief MMU support. + * + * @{ + */ + +/* Some routines require or return an index 'key'. + */ +typedef int bsp_tlb_idx_t; + +/* Cache the relevant TLB entries so that we can make sure the user cannot + * create conflicting (overlapping) entries. Keep them public for informational + * purposes. + */ +typedef struct { + struct { + uint32_t pad:24; + uint32_t tid:8; /** Translation ID */ + } id; + struct { + uint32_t epn:22; /** Effective page number */ + uint32_t v:1; /** Valid */ + uint32_t ts:1; /** Translation Address Space */ + uint32_t size:4; /** Page size */ + uint32_t tpar:4; /** Tag parity */ + } w0; + struct { + uint32_t rpn:22; /** The real (translated) page number. */ + uint32_t par1:2; /** For matching the TLB array parity */ + uint32_t pad:4; + uint32_t erpn:4; /** Extended Real Page Number */ + } w1; + struct { + uint32_t par2:2; /** Parity for TLB word 2 */ + uint32_t pad1:14; + uint32_t att:4; /** User-defined attributes */ + uint32_t wimge:5; /** Write-Through/Caching Inhibited/Memory Coherent/Guarded/Endian */ + uint32_t pad2:1; + uint32_t perm:6; /** User-State Executable/Writeable/Readable Supervisor-State Executable/Writeable/Readable */ + } w2; +} bsp_tlb_entry_t; + +#define NTLBS 64 + +extern bsp_tlb_entry_t* bsp_mmu_cache; + +// These constants will have to be shifted right by 20 bits before +// being inserted the high word of the TLB. + +#define MMU_M_SIZE_1K (0x00000000U) +#define MMU_M_SIZE_4K (0x08000000U) +#define MMU_M_SIZE_16K (0x10000000U) +#define MMU_M_SIZE_64K (0x18000000U) +#define MMU_M_SIZE_256K (0x20000000U) +#define MMU_M_SIZE_1M (0x28000000U) +#define MMU_M_SIZE_16M (0x38000000U) +#define MMU_M_SIZE_256M (0x48000000U) +#define MMU_M_SIZE_MIN (MMU_M_SIZE_1K) +#define MMU_M_SIZE_MAX (MMU_M_SIZE_256M) +#define MMU_M_SIZE (0x78000000U) +#define MMU_V_SIZE (27) + +// These constants have the same bit positions they'll occupy +// in low word of the TLB. + +#define MMU_M_ATTR_USER0 (0x00010000U) +#define MMU_M_ATTR_USER1 (0x00008000U) +#define MMU_M_ATTR_USER2 (0x00004000U) +#define MMU_M_ATTR_USER3 (0x00002000U) +#define MMU_M_ATTR (0x0001e000U) +#define MMU_V_ATTR (13) + +#define MMU_M_PROP_WRITE_THROUGH (0x00001000U) +#define MMU_M_PROP_UNCACHED (0x00000800U) +#define MMU_M_PROP_MEM_COHERENT (0x00000400U) +#define MMU_M_PROP_GUARDED (0x00000200U) +#define MMU_M_PROP_LITTLE_ENDIAN (0x00000100U) +#define MMU_M_PROP (0x00000f00U) +#define MMU_V_PROP (8) + +#define MMU_M_PERM_USER_EXEC (0x00000020U) +#define MMU_M_PERM_USER_WRITE (0x00000010U) +#define MMU_M_PERM_USER_READ (0x00000008U) +#define MMU_M_PERM_SUPER_EXEC (0x00000004U) +#define MMU_M_PERM_SUPER_WRITE (0x00000002U) +#define MMU_M_PERM_SUPER_READ (0x00000001U) +#define MMU_M_PERM (0x0000003fU) +#define MMU_V_PERM (0) + + +/* + * Dump (cleartext) content info from cached TLB entries + * to a file (stdout if f==NULL). + */ +void +bsp_mmu_dump_cache(FILE *f); + +/* Read a TLB entry from the hardware and store the settings in the + * bsp_mmu_cache[] structure. + * + * The routine can perform this operation quietly or + * print information to a file. + * + * 'key': TLB entry index. + * 'quiet': perform operation silently (no info printed) if nonzero. + * 'f': open FILE where to print information. May be NULL, in + * which case 'stdout' is used. + * + * RETURNS: + * 0: success; TLB entry is VALID + * +1: success but TLB entry is INVALID + * < 0: error (-1: invalid argument) + * (-2: driver not initialized) + */ +int +bsp_mmu_update(bsp_tlb_idx_t key, bool quiet, FILE *f); + +/* Initialize cache. Should be done only once although this is not enforced. + * + * RETURNS: zero on success, nonzero on error; in this case the driver will + * refuse to change TLB entries (other than disabling them). + */ +int +bsp_mmu_initialize(void); + +/* Find first free TLB entry by examining all entries' valid bit. The first + * entry without the valid bit set is returned. + * + * RETURNS: A free TLB entry number. -1 if no entry can be found. + */ +bsp_tlb_idx_t +bsp_mmu_find_first_free(void); + +/* Write a TLB entry (can also be used to disable an entry). + * + * The routine checks against the cached data in bsp_mmu_cache[] + * to prevent the user from generating overlapping entries. + * + * 'idx': TLB entry # to manipulate + * 'ea': Effective address (must be page aligned) + * 'pa': Physical address (must be page aligned) + * 'sz': Page size selector; page size is 1024 * 2^(2*sz) bytes. + * 'sz' may also be one of the following: + * - page size in bytes ( >= 1024 ); the selector + * value is then computed by this routine. + * However, 'sz' must be a valid page size + * or -1 will be returned. + * - a value < 0 to invalidate/disable the + * TLB entry. + * 'flgs': Page's User-defined flags, permissions and WIMGE page attributes + * 'tid': Translation ID + * 'ts': Translation Space + * 'erpn': Extended Real Page Number + * + * RETURNS: 0 on success, nonzero on error: + * + * >0: requested mapping would overlap with + * existing mapping in another entry. Return + * value gives conflicting entry + 1; i.e., + * if a value of 4 is returned then the request + * conflicts with existing mapping in entry 3. + * -1: invalid argument + * -3: driver not initialized (or initialization failed). + * <0: other error + */ +bsp_tlb_idx_t +bsp_mmu_write(bsp_tlb_idx_t idx, uint32_t ea, uint32_t pa, int sz, + uint32_t flgs, uint32_t tid, uint32_t ts, uint32_t erpn); + +/* Check if a ea/tid/ts/sz mapping overlaps with an existing entry. + * + * 'ea': The Effective Address to match against + * 'sz': The 'logarithmic' size selector; the page size + * is 1024*2^(2*sz). + * 'tid': Translation ID + * 'ts': Translation Space + * + * RETURNS: + * >= 0: index of TLB entry that already provides a mapping + * which overlaps within the ea range. + * -1: SUCCESS (no conflicting entry found) + * <=-2: ERROR (invalid input) + */ +bsp_tlb_idx_t +bsp_mmu_match(uint32_t ea, int sz, uint32_t tid, uint32_t ts); + +/* Find TLB index that maps 'ea/tid/ts' combination + * + * 'ea': Effective address to match against + * 'tid': Translation ID + * 'ts': Translation Space + * + * RETURNS: index 'key'; i.e., the index number. + * + * On error (no mapping) -1 is returned. + */ +bsp_tlb_idx_t +bsp_mmu_find(uint32_t ea, uint32_t tid, uint32_t ts); + +/* Mark TLB entry as invalid ('disabled'). + * + * 'key': TLB entry index. + * + * RETURNS: zero on success, nonzero on error (TLB unchanged). + * + * NOTE: If a TLB entry is disabled the associated + * entry in bsp_tlb_cache[] is also marked as disabled. + */ +int +bsp_mmu_invalidate(bsp_tlb_idx_t key); + +/** @} */ + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/c/src/lib/libbsp/powerpc/virtex5/irq/irq_init.c b/c/src/lib/libbsp/powerpc/virtex5/irq/irq_init.c index ffcfe4ca11..70965128a6 100644 --- a/c/src/lib/libbsp/powerpc/virtex5/irq/irq_init.c +++ b/c/src/lib/libbsp/powerpc/virtex5/irq/irq_init.c @@ -35,21 +35,21 @@ rtems_irq_global_settings* BSP_rtems_irq_config; * these functions just do nothing fulfill the semantic * requirements to enable/disable a certain interrupt or exception */ -void BSP_irq_nop_func(const rtems_irq_connect_data *unused) +static void BSP_irq_nop_func(const rtems_irq_connect_data *unused) { /* * nothing to do */ } -void BSP_irq_nop_hdl(void *hdl) +static void BSP_irq_nop_hdl(void *hdl) { /* * nothing to do */ } -int BSP_irq_isOn_func(const rtems_irq_connect_data *unused) +static int BSP_irq_isOn_func(const rtems_irq_connect_data *unused) { /* * nothing to do @@ -64,7 +64,7 @@ int BSP_irq_isOn_func(const rtems_irq_connect_data *unused) /*********************************************************** * functions to enable/disable/query external/critical interrupts */ -void BSP_irqexc_on_fnc(rtems_irq_connect_data *conn_data) +void BSP_irqexc_on_fnc(const rtems_irq_connect_data *conn_data) { uint32_t msr_value; /* @@ -76,7 +76,7 @@ void BSP_irqexc_on_fnc(rtems_irq_connect_data *conn_data) _CPU_MSR_SET(msr_value); } -void BSP_irqexc_off_fnc(rtems_irq_connect_data *unused) +void BSP_irqexc_off_fnc(const rtems_irq_connect_data *unused) { uint32_t msr_value; /* @@ -88,6 +88,20 @@ void BSP_irqexc_off_fnc(rtems_irq_connect_data *unused) _CPU_MSR_SET(msr_value); } +SPR_RW(BOOKE_TSR) + +int C_dispatch_dec_handler (BSP_Exception_frame *frame, unsigned int excNum) +{ + /* Acknowledge the interrupt */ + _write_BOOKE_TSR( BOOKE_TSR_DIS ); + + /* Handle the interrupt */ + BSP_rtems_irq_tbl[BSP_DEC].hdl(BSP_rtems_irq_tbl[BSP_DEC].handle); + + return 0; +} + + /*********************************************************** * High level IRQ handler called from shared_raw_irq_code_entry */ @@ -100,9 +114,12 @@ int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum) case ASM_EXT_VECTOR: BSP_rtems_irq_tbl[BSP_EXT].hdl(BSP_rtems_irq_tbl[BSP_EXT].handle); break; +#if 0 /* Dealt with by C_dispatch_dec_handler(), above */ case ASM_BOOKE_DEC_VECTOR: - BSP_rtems_irq_tbl[BSP_PIT].hdl(BSP_rtems_irq_tbl[BSP_PIT].handle); + _write_BOOKE_TSR( BOOKE_TSR_DIS ); + BSP_rtems_irq_tbl[BSP_DEC].hdl(BSP_rtems_irq_tbl[BSP_DEC].handle); break; +#endif #if 0 /* Critical interrupts not yet supported */ case ASM_BOOKE_CRIT_VECTOR: BSP_rtems_irq_tbl[BSP_CRIT].hdl(BSP_rtems_irq_tbl[BSP_CRIT].handle); @@ -275,7 +292,7 @@ int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config) * dummy for an empty IRQ handler entry */ static rtems_irq_connect_data emptyIrq = { - 0, /* Irq Name */ + 0, /* IRQ Name */ BSP_irq_nop_hdl, /* handler function */ NULL, /* handle passed to handler */ BSP_irq_nop_func, /* on function */ @@ -284,8 +301,8 @@ static rtems_irq_connect_data emptyIrq = { }; static rtems_irq_global_settings initialConfig = { - BSP_IRQ_NUMBER, /* irqNb */ - { 0, /* Irq Name */ + BSP_IRQ_NUMBER, /* IRQ number */ + { 0, /* IRQ Name */ BSP_irq_nop_hdl, /* handler function */ NULL, /* handle passed to handler */ BSP_irq_nop_func, /* on function */ @@ -305,7 +322,7 @@ void BSP_rtems_irq_mngt_init(unsigned cpuId) * connect all exception vectors needed */ ppc_exc_set_handler(ASM_EXT_VECTOR, C_dispatch_irq_handler); - ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, C_dispatch_irq_handler); + ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, C_dispatch_dec_handler); /* * setup interrupt handlers table diff --git a/c/src/lib/libbsp/powerpc/virtex5/mmu/mmu.c b/c/src/lib/libbsp/powerpc/virtex5/mmu/mmu.c new file mode 100644 index 0000000000..990cb99bd0 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/virtex5/mmu/mmu.c @@ -0,0 +1,581 @@ +/** + * @file + * + * @ingroup Virtex5MMU + * + * @brief Implementation of routines to manipulate the PPC 440 MMU. + * + * Since this is a real-time OS we want to stay away from + * software TLB replacement. + */ +/* + * Authorship + * ---------- + * This software was created by + * Till Straumann <strauman@slac.stanford.edu>, 2005-2007, + * Stanford Linear Accelerator Center, Stanford University. + * and was transcribed for the PPC 440 by + * R. Claus <claus@slac.stanford.edu>, 2012, + * Stanford Linear Accelerator Center, Stanford University, + * + * Acknowledgement of sponsorship + * ------------------------------ + * This software was produced by + * the Stanford Linear Accelerator Center, Stanford University, + * under Contract DE-AC03-76SFO0515 with the Department of Energy. + * + * Government disclaimer of liability + * ---------------------------------- + * Neither the United States nor the United States Department of Energy, + * nor any of their employees, makes any warranty, express or implied, or + * assumes any legal liability or responsibility for the accuracy, + * completeness, or usefulness of any data, apparatus, product, or process + * disclosed, or represents that its use would not infringe privately owned + * rights. + * + * Stanford disclaimer of liability + * -------------------------------- + * Stanford University makes no representations or warranties, express or + * implied, nor assumes any liability for the use of this software. + * + * Stanford disclaimer of copyright + * -------------------------------- + * Stanford University, owner of the copyright, hereby disclaims its + * copyright and all other rights in this software. Hence, anyone may + * freely use it for any purpose without restriction. + * + * Maintenance of notices + * ---------------------- + * In the interest of clarity regarding the origin and status of this + * SLAC software, this and all the preceding Stanford University notices + * are to remain affixed to any copy or derivative of this software made + * or distributed by the recipient and are to be affixed to any copy of + * software made or distributed by the recipient that contains a copy or + * derivative of this software. + * + * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 + */ + +/* 440 MSR definitions; note that there are *substantial* differences + * compared to classic powerpc; in particular, IS/DS are *different* + * from IR/DR; the ppc440 MMU cannot be switched off! + * + * Also: To disable/enable all external interrupts, CE and EE must both be + * controlled. + */ +#include <rtems.h> +#include <rtems/bspIo.h> +#include <rtems/powerpc/powerpc.h> +#include <inttypes.h> +#include <stdio.h> + +#include <bsp/mmu.h> + + +#ifdef DEBUG +#define STATIC +#else +#define STATIC static +#endif + + +bsp_tlb_entry_t* bsp_mmu_cache = 0; + + +/* Since it is likely that these routines are used during + * early initialization when stdio is not available yet + * we provide a helper that resorts to 'printk()' + */ +static void +myprintf(FILE *f, char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + + if (!f || !_impure_ptr->__sdidinit) { + /* Might be called at an early stage when stdio is not yet initialized. */ + vprintk(fmt,ap); + } else { + vfprintf(f,fmt,ap); + } + va_end(ap); +} + + +void +bsp_mmu_dump_cache(FILE *f) +{ + bsp_tlb_idx_t idx; + if ( !bsp_mmu_cache ) { + myprintf(stderr,"MMU TLB cache not initialized\n"); + return; + } + for ( idx=0; idx<NTLBS; idx++ ) { + bsp_tlb_entry_t *tlb = bsp_mmu_cache + idx; + if ( !tlb->w0.v ) + continue; + myprintf(f, "#%2i: EA 0x%08x .. 0x%08x, TID 0x%03x, TS %i\n", + idx, + tlb->w0.epn<<10, + (tlb->w0.epn<<10) + (1024<<(2*tlb->w0.size))-1, + tlb->id.tid, + tlb->w0.ts); + myprintf(f, " PA 0x%08"PRIx32", U0-3 0x%01x, WIMGE 0x%02x, PERM 0x%03x\n", + tlb->w1.rpn<<10, + tlb->w2.att, + tlb->w2.wimge, + tlb->w2.perm); + } +} + +static void +fetch(bsp_tlb_idx_t key, bsp_tlb_entry_t* tlb) +{ + register uint32_t tmp; + __asm__ volatile ("mfpid %[tmp] \n\t" + "stw %[tmp],0(%[tlb]) \n\t" + "tlbre %[tmp],%[key],0 \n\t" + "stw %[tmp],4(%[tlb]) \n\t" + "tlbre %[tmp],%[key],1 \n\t" + "stw %[tmp],8(%[tlb]) \n\t" + "tlbre %[tmp],%[key],2 \n\t" + "stw %[tmp],12(%[tlb]) \n\t" + "sync \n\t" + : [tmp]"=&r"(tmp) + : [key]"r"(key), + [tlb]"b"(tlb) + ); +} + + +static void +store(bsp_tlb_idx_t key, bsp_tlb_entry_t* tlb) +{ + register uint32_t tmp; + __asm__ volatile ("lwz %[tmp],0(%[tlb]) \n\t" + "mtpid %[tmp] \n\t" + "lwz %[tmp],4(%[tlb]) \n\t" + "tlbwe %[tmp],%[idx],0 \n\t" + "lwz %[tmp],8(%[tlb]) \n\t" + "tlbwe %[tmp],%[idx],1 \n\t" + "lwz %[tmp],12(%[tlb]) \n\t" + "tlbwe %[tmp],%[idx],2 \n\t" + : [tmp]"=&r"(tmp) + : [tlb]"b"(tlb), + [idx]"r"(key) + ); +} + + +static void +commit(void) +{ + __asm__ volatile("isync \n\t"); +} + + +/* + * Read a TLB entry from the hardware store the current settings in the + * bsp_mmu_cache[] structure. + * + * The routine can perform this operation quietly or + * print information to a file. + * + * 'idx': which TLB entry to access. + * 'quiet': perform operation silently (no info printed) + * if nonzero. + * 'f': open FILE where to print information. May be + * NULL in which case 'stdout' is used. + * + * RETURNS: + * 0: success; TLB entry is VALID + * +1: success but TLB entry is INVALID + * < 0: error (-1: invalid argument) + * (-2: driver not initialized) + */ +int +bsp_mmu_update(bsp_tlb_idx_t key, bool quiet, FILE *f) +{ + rtems_interrupt_level lvl; + bsp_tlb_entry_t* tlb; + int idx; + + idx = key; + + if ( idx < 0 || idx > NTLBS-1 ) + return -1; + + if (!bsp_mmu_cache) + return -2; + + tlb = bsp_mmu_cache + idx; + + rtems_interrupt_disable(lvl); + + fetch(idx, tlb); + + rtems_interrupt_enable(lvl); + + if ( tlb->w0.v ) { + if ( !quiet ) { +/* + "TLB Entry # 0 spans EA range 0x00000000 - 0x00000000 + "Mapping: VA [TS 0 / TID 0x00 / EPN 0x00000] -> RPN 0x00000" + "Size: TSIZE 0x0 (4^sz KB = 000000 KB = 0x00000000 B) + "Attributes: PERM 0x000 (ux/uw/ur/sx/sw/sr) WIMGE 0x00 U0-3 0x0" +*/ + myprintf(f, + "TLB Entry # %2d spans EA range 0x%08x - 0x%08x\n", + idx, + (tlb->w0.epn << 10), + (tlb->w0.epn << 10) + (1024<<(2*tlb->w0.size)) - 1 + ); + + myprintf(f, + "Mapping: VA [TS %d / TID 0x%02x / EPN 0x%05x] -> RPN 0x%05"PRIx32"\n", + tlb->w0.ts, tlb->id.tid, tlb->w0.epn, tlb->w1.rpn + ); + myprintf(f, + "Size: TSIZE 0x%x (4^sz KB = %6d KB = 0x%08x B)\n", + tlb->w0.size, (1<<(2*tlb->w0.size)), (1024<<(2*tlb->w0.size)) + ); + myprintf(f, + "Properties: PERM 0x%03x (ux/uw/ur/sx/sw/sr) WIMGE 0x%02x U0-3 0x%01x\n", + tlb->w2.perm, tlb->w2.wimge, tlb->w2.att + ); + } + } else { + if ( !quiet ) { + myprintf(f, "TLB Entry # %2d <OFF> (size 0x%x = 0x%xb)\n", + idx, tlb->w0.size, (1024<<(2*tlb->w0.size))); + } + return 1; + } + return 0; +} + +/* Initialize cache. Should be done only once although this is not enforced. + * + * RETURNS: zero on success, nonzero on error; in this case the driver will + * refuse to change TLB entries (other than disabling them). + */ +int +bsp_mmu_initialize() +{ + static bsp_tlb_entry_t mmu_cache[NTLBS]; + bsp_tlb_entry_t* tlb = mmu_cache; /* Should malloc if it's not too early */ + rtems_interrupt_level lvl; + + bsp_tlb_idx_t idx; + rtems_interrupt_disable(lvl); + for (idx=0; idx<NTLBS; tlb++, idx++) + { + fetch(idx, tlb); + } + rtems_interrupt_enable(lvl); + + bsp_mmu_cache = mmu_cache; + return 0; +} + +/* Find first free TLB entry by examining all entries' valid bit. The first + * entry without the valid bit set is returned. + * + * RETURNS: A free TLB entry number. -1 if no entry can be found. + */ +bsp_tlb_idx_t +bsp_mmu_find_first_free() +{ + bsp_tlb_idx_t idx; + bsp_tlb_entry_t entry; + + for (idx=0; idx<NTLBS; idx++) { + register uint32_t tmp; + __asm__ volatile ("tlbre %[tmp],%[idx],0 \n\t" + "stw %[tmp],4(%[tlb]) \n\t" /* entry.w0 */ + "sync \n\t" + : [tmp]"=&r"(tmp) + : [idx]"r"(idx), + [tlb]"b"(&entry) + : "memory" + ); + if (!(entry.w0.v)) + break; + } + return (idx < NTLBS) ? idx : -1; +} + +/* + * Write TLB entry (can also be used to disable an entry). + * + * The routine checks against the cached data in + * bsp_mmu_cache[] to prevent the user from generating + * overlapping entries. + * + * 'idx': TLB entry # to manipulate + * 'ea': Effective address (must be page aligned) + * 'pa': Physical address (must be page aligned) + * 'sz': Page size selector; page size is + * 1024 * 2^(2*sz) bytes. + * 'sz' may also be one of the following: + * - page size in bytes ( >= 1024 ); the selector + * value is then computed by this routine. + * However, 'sz' must be a valid page size + * or -1 will be returned. + * - a value < 0 to invalidate/disable the + * TLB entry. + * 'flgs': Page's User-defined flags, permissions and WIMGE page attributes + * 'tid': Translation ID + * 'ts': Translation Space + * 'erpn': Extended Real Page Number + * + * RETURNS: 0 on success, nonzero on error: + * + * >0: requested mapping would overlap with + * existing mapping in other entry. Return + * value gives conflicting entry + 1; i.e., + * if a value of 4 is returned then the request + * conflicts with existing mapping in entry 3. + * -1: invalid argument + * -3: driver not initialized (or initialization failed). + * <0: other error + */ +bsp_tlb_idx_t +bsp_mmu_write(bsp_tlb_idx_t idx, uint32_t ea, uint32_t pa, int sz, + uint32_t flgs, uint32_t tid, uint32_t ts, uint32_t erpn) +{ + bsp_tlb_entry_t tlb; + uint32_t msk; + bsp_tlb_idx_t lkup; + rtems_interrupt_level lvl; + + if ( sz >= 1024 ) { + /* Assume they literally specify a size */ + msk = sz; + sz = 0; + while ( msk != (1024<<(sz+sz)) ) { + if ( ++sz > 15 ) { + return -1; + } + } + /* OK, acceptable */ + } + + msk = sz > 0 ? (1024<<(sz+sz)) - 1 : 0; + + if ( !bsp_mmu_cache && sz > 0 ) { + myprintf(stderr,"MMU driver not initialized; refusing to enable any entry\n"); + return -3; + } + + if ( (ea & msk) || (pa & msk) ) { + myprintf(stderr,"Misaligned EA (%08x) or PA (%08x) (mask is %08x)\n", ea, pa, msk); + return -1; + } + + if ( idx < 0 || idx > NTLBS-1 ) + return -1; + + /* Not all 16 possible sizes are supported */ + if ( sz == 6 || sz == 8 || sz > 9 ) { + myprintf(stderr,"Invalid size %u = %08x = %u KB\n", sz, 1024<<(sz+sz), (1024<<(sz+sz))/1024); + return -1; + } + + if ( sz >=0 ) { + lkup = bsp_mmu_match(ea, sz, tid, ts); + + if ( lkup < -1 ) { + /* some error */ + return lkup; + } + + if ( lkup >= 0 && lkup != idx && (bsp_mmu_cache[lkup].w0.v != 0) ) { + myprintf(stderr,"TLB #%i overlaps with requested mapping\n", lkup); + bsp_mmu_update( lkup, false, stderr); + return lkup+1; + } + } + + /* OK to proceed */ + tlb.id.tid = tid; + tlb.w0.v = sz >= 0; + tlb.w0.ts = ts; + tlb.w0.size = sz; + tlb.w0.epn = (ea & (0xfffffc00 << (sz+sz))) >> 10; + if (sz < 11) { + tlb.w1.rpn = (pa & (0xfffffc00 << (sz+sz))) >> 10; + tlb.w1.erpn = erpn; + } + else { + sz -= 11; + tlb.w1.rpn = 0; + tlb.w1.erpn = (erpn & (0xf << (sz+sz))) & 0xf; + } + tlb.w2.att = (flgs & MMU_M_ATTR) >> MMU_V_ATTR; + tlb.w2.wimge = (flgs & MMU_M_PROP) >> MMU_V_PROP; + tlb.w2.perm = (flgs & MMU_M_PERM) >> MMU_V_PERM; + + rtems_interrupt_disable(lvl); + + store(idx, &tlb); + + commit(); + + rtems_interrupt_enable(lvl); + + /* update cache */ + bsp_mmu_update(idx, true, 0); + + return 0; +} + +/* + * Check if a ea/tid/ts/sz mapping overlaps with an existing entry. + * + * 'ea': The Effective Address to match against + * 'sz': The 'logarithmic' size selector; the page size + * is 1024*2^(2*sz). + * 'tid': Translation ID + * 'ts': Translation Space + * + * RETURNS: + * >= 0: index of the TLB entry that already provides a mapping + * which overlaps within the ea range. + * -1: SUCCESS (no conflicting entry found) + * <=-2: ERROR (invalid input) + */ +bsp_tlb_idx_t +bsp_mmu_match(uint32_t ea, int sz, uint32_t tid, uint32_t ts) +{ + bsp_tlb_idx_t idx; + uint32_t m,a; + bsp_tlb_entry_t* tlb; + + if ( sz < 0 || sz == 6 || sz == 8 || sz > 9 ) + return -4; + + sz = (1024<<(2*sz)); + + if ( !bsp_mmu_cache ) { + /* cache not initialized */ + return -3; + } + + if ( ea & (sz-1) ) { + /* misaligned ea */ + return -2; + } + + for ( idx=0, tlb=bsp_mmu_cache; idx<NTLBS; idx++, tlb++ ) { + if ( ! tlb->w0.v ) + continue; + if ( tlb->id.tid && tlb->id.tid != tid ) + continue; + if ( tlb->w0.ts != ts ) + continue; + /* TID and TS match a valid entry */ + m = (1024<<(2*tlb->w0.size)) - 1; + /* calculate starting address of this entry */ + a = tlb->w0.epn<<10; + if ( ea <= a + m && ea + sz -1 >= a ) { + /* overlap */ + return idx; + } + } + return -1; +} + +/* Find TLB index that maps 'ea/tid/ts' combination + * + * 'ea': Effective address to match against + * 'tid': Translation ID + * 'ts': Translation Space + * + * RETURNS: index 'key' which indicates whether + * the mapping was found. + * + * On error (no mapping) -1 is returned. + */ +bsp_tlb_idx_t +bsp_mmu_find(uint32_t ea, uint32_t tid, uint32_t ts) +{ + rtems_interrupt_level lvl; + register uint32_t mmucr; + register bsp_tlb_idx_t idx; + register int failure; + + rtems_interrupt_disable(lvl); + + __asm__ volatile ("mfspr %[mmucr],0x3b2 \n\t" /* Save MMUCR */ + : [mmucr]"=r"(mmucr) + ); + __asm__ volatile ("mtspr 0x3b2,%[tid] \n\t" + "tlbsx. %[idx],0,%[ea] \n\t" /* Failure changes the index reg randomly. */ + "mfcr %[failure] \n\t" + "mtspr 0x3b2,%[mmucr] \n\t" /* Restore MMUCR */ + : [idx]"=&r"(idx), + [failure]"=&r"(failure) + : [tid]"r"((mmucr & 0xfffeff00) | (ts << 16) | tid), + [ea]"r"(ea), + [mmucr]"r"(mmucr) + : "cc" + ); + + rtems_interrupt_enable(lvl); + + return (failure & 0x20000000) ? idx : -1; +} + +/* Mark TLB entry as invalid ('disabled'). + * + * 'key': TLB entry (index). + * + * RETURNS: zero on success, nonzero on error (TLB unchanged). + * + * NOTE: If a TLB entry is disabled the associated + * entry in bsp_mmu_cache[] is also + * marked as disabled. + */ +int +bsp_mmu_invalidate(bsp_tlb_idx_t key) +{ + bsp_tlb_idx_t k0; + rtems_interrupt_level lvl; + bsp_tlb_entry_t tlb; + + /* minimal guard against bad key */ + if ( key < 0 || key > NTLBS-1 ) + return -1; + + /* Must not invalidate page 0 which holds vectors, text etc... */ + k0 = bsp_mmu_find(0, 0, 0); + if ( -1 == k0 ) { + myprintf(stderr,"No mapping for address 0 found\n"); + return -2; + } + + /* NOTE: we assume PID is ignored */ + if ( k0 == key ) { + myprintf(stderr,"Cannot invalidate page holding address 0 (always needed)\n"); + return -3; + } + + rtems_interrupt_disable(lvl); + + fetch(key, &tlb); + + /* Invalidate old entries */ + tlb.w0.v = 0; + + store(key, &tlb); + + commit(); + + /* Update cache */ + bsp_mmu_cache[ key ].w0.v = tlb.w0.v; + + rtems_interrupt_enable(lvl); + + return 0; +} diff --git a/c/src/lib/libbsp/powerpc/virtex5/preinstall.am b/c/src/lib/libbsp/powerpc/virtex5/preinstall.am index 34b03f177c..e441f38b08 100644 --- a/c/src/lib/libbsp/powerpc/virtex5/preinstall.am +++ b/c/src/lib/libbsp/powerpc/virtex5/preinstall.am @@ -69,6 +69,10 @@ $(PROJECT_INCLUDE)/bsp/irq.h: include/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h +$(PROJECT_INCLUDE)/bsp/mmu.h: include/mmu.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/mmu.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/mmu.h + $(PROJECT_INCLUDE)/bsp/vectors.h: ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/vectors.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vectors.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vectors.h diff --git a/c/src/lib/libbsp/powerpc/virtex5/startup/bspstart.c b/c/src/lib/libbsp/powerpc/virtex5/startup/bspstart.c index 8847dc8b90..4aa89f7bdf 100644 --- a/c/src/lib/libbsp/powerpc/virtex5/startup/bspstart.c +++ b/c/src/lib/libbsp/powerpc/virtex5/startup/bspstart.c @@ -54,20 +54,23 @@ * Modifications for PPC405GP by Dennis Ehlin * Modifications for Virtex5 by Richard Claus <claus@slac.stanford.edu> */ - -#include <string.h> -#include <fcntl.h> - -#include <bsp.h> -#include <bsp/irq.h> -#include <bsp/vectors.h> +#include <rtems.h> +#include <rtems/config.h> #include <rtems/bspIo.h> #include <rtems/libio.h> #include <rtems/libcsupport.h> -#include <rtems/sptables.h> /* for RTEMS_VERSION */ + #include <libcpu/cpuIdent.h> #include <libcpu/spr.h> +#include <bsp.h> +#include <bsp/vectors.h> +#include <bsp/bootcard.h> +#include <bsp/irq.h> + +#include <string.h> +#include <fcntl.h> + #define DO_DOWN_ALIGN(x,a) ((x) & ~((a)-1)) #define DO_UP_ALIGN(x,a) DO_DOWN_ALIGN(((x) + (a) - 1 ),a) @@ -76,13 +79,6 @@ #define CPU_UP_ALIGN(x) DO_UP_ALIGN(x, CPU_ALIGNMENT) -/* Expected by clock.c */ -uint32_t bsp_clicks_per_usec; -bool bsp_timer_internal_clock; /* true, when timer runs with CPU clk */ -uint32_t bsp_timer_least_valid; -uint32_t bsp_timer_average_overhead; - - /* Defined in linkcmds linker script */ LINKER_SYMBOL(RamBase); LINKER_SYMBOL(RamSize); @@ -96,35 +92,37 @@ LINKER_SYMBOL(WorkAreaBase); LINKER_SYMBOL(MsgAreaBase); LINKER_SYMBOL(MsgAreaSize); LINKER_SYMBOL(__phy_ram_end); +LINKER_SYMBOL(bsp_exc_vector_base); +/* Expected by clock.c */ +uint32_t bsp_clicks_per_usec; +bool bsp_timer_internal_clock; /* true, when timer runs with CPU clk */ +uint32_t bsp_timer_least_valid; +uint32_t bsp_timer_average_overhead; + /* - * Provide weak aliases so that RTEMS distribution builds + * Bus Frequency */ -static void _noopfun(void) {} -static void _bsp_start(void) -{ - uintptr_t intrStackStart = CPU_UP_ALIGN((uint32_t)__bsp_ram_start); - uintptr_t intrStackSize = rtems_configuration_get_interrupt_stack_size(); +unsigned int BSP_bus_frequency; +/* + * processor clock frequency + */ +unsigned int BSP_processor_frequency; - /* - * Initialize default raw exception handlers. - * - * This BSP does not assume anything about firmware possibly loaded in the - * FPGA, so the external interrupt should not be enabled in order to avoid - * spurious interrupts. - */ - ppc_exc_initialize(PPC_INTERRUPT_DISABLE_MASK_DEFAULT & ~MSR_EE, - intrStackStart, - intrStackSize); +/* + * Time base divisior (bus freq / TB clock) + */ +unsigned int BSP_time_base_divisor; - /* Install our own set of exception vectors */ - BSP_rtems_irq_mngt_init(0); -} +/* + * Provide weak aliases so that RTEMS distribution builds + */ +static void _noopfun(void) {} void app_bsp_start(void) -__attribute__(( weak, alias("_bsp_start") )); +__attribute__(( weak, alias("_noopfun") )); void app_bsp_pretasking_hook(void) __attribute__(( weak, alias("_noopfun") )); @@ -147,20 +145,31 @@ static void __bsp_outchar_to_memory(char c) void BSP_ask_for_reset(void) { printk("\nSystem stopped, issue RESET"); + for(;;); } void BSP_panic(char *s) { - printk("\n%s PANIC %s\n", _RTEMS_version, s); + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + + printk("\n%s PANIC %s\n", rtems_get_version_string(), s); + BSP_ask_for_reset(); } void _BSP_Fatal_error(unsigned int v) { - printk("\n%s FATAL ERROR %x\n", _RTEMS_version, v); + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + + printk("\n%s FATAL ERROR %x\n", rtems_get_version_string(), v); + BSP_ask_for_reset(); } @@ -176,13 +185,14 @@ void bsp_start(void) { uintptr_t intrStackStart; uintptr_t intrStackSize; + ppc_cpu_id_t myCpu; ppc_cpu_revision_t myCpuRevision; /* Set the character output function; The application may override this */ BSP_output_char = __bsp_outchar_to_memory; - printk("\nWelcome to RTEMS %s\n", _RTEMS_version ); + printk("RTEMS %s\n", rtems_get_version_string()); /* * Get CPU identification dynamically. Note that the get_ppc_cpu_type() @@ -197,8 +207,13 @@ void bsp_start(void) * Initialize the device driver parameters */ + /* For mpc6xx clock driver: */ + BSP_bus_frequency = 465000000; + BSP_processor_frequency = 465000000; /* Measured with a DPM 440 2012/8/13 */ + BSP_time_base_divisor = 1000; + /* Timebase register ticks/microsecond; The application may override these */ - bsp_clicks_per_usec = 450; + bsp_clicks_per_usec = BSP_bus_frequency/(BSP_time_base_divisor * 1000); bsp_timer_internal_clock = true; bsp_timer_average_overhead = 2; bsp_timer_least_valid = 3; @@ -208,6 +223,12 @@ void bsp_start(void) */ intrStackStart = CPU_UP_ALIGN((uint32_t)__bsp_ram_start); intrStackSize = rtems_configuration_get_interrupt_stack_size(); + + ppc_exc_initialize(PPC_INTERRUPT_DISABLE_MASK_DEFAULT, + intrStackStart, + intrStackSize); + + /* Let the user know what parameters we were compiled with */ printk(" Base/Start End Size\n" "RAM: 0x%08x 0x%x\n" "RTEMS: 0x%08x\n" @@ -224,6 +245,11 @@ void bsp_start(void) (uint32_t)MsgAreaBase, (uint32_t)MsgAreaSize, (uint32_t)__phy_ram_end); + /* + * Initialize RTEMS IRQ system + */ + BSP_rtems_irq_mngt_init(0); + /* Continue with application-specific initialization */ app_bsp_start(); } diff --git a/c/src/lib/libbsp/powerpc/virtex5/startup/linkcmds b/c/src/lib/libbsp/powerpc/virtex5/startup/linkcmds index 20d4095d41..a92d9a1e5e 100644 --- a/c/src/lib/libbsp/powerpc/virtex5/startup/linkcmds +++ b/c/src/lib/libbsp/powerpc/virtex5/startup/linkcmds @@ -20,16 +20,17 @@ HeapSize = DEFINED(HeapSize) ? HeapSize : 0; /* 0=Use def */ MEMORY { - VECTORS : ORIGIN = 0x00000000, LENGTH = 8K - RAM : ORIGIN = 0x00002000, LENGTH = 2048M - 8K + VECTORS : ORIGIN = 0x00000000, LENGTH = 512 + RAM : ORIGIN = 0x00000200, LENGTH = 2048M - 512 } SECTIONS { - __exeentry = download_entry; - __exestart = 0x100; - .vectors __exestart : { *(.vectors) } > VECTORS + bsp_exc_vector_base = 0; + __exeentry = download_entry; + __exestart = bsp_exc_vector_base; + .vectors bsp_exc_vector_base : { *(.vectors) } > VECTORS /* Read-only sections, merged into text segment: */ .interp : { *(.interp) } > RAM diff --git a/c/src/lib/libbsp/powerpc/virtex5/startup/start.S b/c/src/lib/libbsp/powerpc/virtex5/startup/start.S index 1afa587ab3..40938e55ab 100644 --- a/c/src/lib/libbsp/powerpc/virtex5/startup/start.S +++ b/c/src/lib/libbsp/powerpc/virtex5/startup/start.S @@ -61,6 +61,7 @@ #include <rtems/asm.h> #include <rtems/powerpc/powerpc.h> +#include <rtems/powerpc/registers.h> #define V_TS_SZ_I 0x0290 // V,TS=0(Inst),SIZE=9,TID=0 #define V_TS_SZ_D 0x0390 // V,TS=1(Data),SIZE=9,TID=0 @@ -154,43 +155,44 @@ first: li r0,0 // Clear r0 /*------------------------------------------------------------------ * Set Core Configuration Register 0 as follows: - * sum: 0x00200000 + * sum: 0x00206000 * bit 1 off Parity Recovery Enable * bit 4 off Cache Read Parity Enable * bit 10 on Disable Store Gathering * bit 11 off Disable APU Instruction Broadcast * bit 16 off Disable Trace Broadcast - * bit 17:18 off Specifies behaviour of icbt,dcbt/dcbtst insts + * bit 17:18 on Specifies behaviour of icbt,dcbt/dcbtst insts * bit 23 off Force Load/Store Alignment * bit 28:29 off Instruction Cache Speculative Line Count * bit 30:31 off Instruction Cache Speculative Line Threshold * NB: UG200/pg 21: Spec. prefetching must be disabled *------------------------------------------------------------------*/ - lis r2,0x0020 // 7. Set CCR0: DSTG - mtccr0 r2 // Configure CCR0 + lis r2, 0x00206000@h // 7. Set CCR0: DSTG + ori r2,r2,0x00206000@l // Set CCR0: GDCBT, GICBT + mtccr0 r2 // Configure CCR0 - mtspr ccr1,r0 // 8. Clear CCR1 + mtspr PPC440_CCR1,r0 // 8. Clear CCR1 /*------------------------------------------------------------------ * 9. Configure cache regions *------------------------------------------------------------------*/ - mtspr inv0,r0 - mtspr inv1,r0 - mtspr inv2,r0 - mtspr inv3,r0 - mtspr dnv0,r0 - mtspr dnv1,r0 - mtspr dnv2,r0 - mtspr dnv3,r0 - mtspr itv0,r0 - mtspr itv1,r0 - mtspr itv2,r0 - mtspr itv3,r0 - mtspr dtv0,r0 - mtspr dtv1,r0 - mtspr dtv2,r0 - mtspr dtv3,r0 + mtspr PPC440_INV0,r0 + mtspr PPC440_INV1,r0 + mtspr PPC440_INV2,r0 + mtspr PPC440_INV3,r0 + mtspr PPC440_DNV0,r0 + mtspr PPC440_DNV1,r0 + mtspr PPC440_DNV2,r0 + mtspr PPC440_DNV3,r0 + mtspr PPC440_ITV0,r0 + mtspr PPC440_ITV1,r0 + mtspr PPC440_ITV2,r0 + mtspr PPC440_ITV3,r0 + mtspr PPC440_DTV0,r0 + mtspr PPC440_DTV1,r0 + mtspr PPC440_DTV2,r0 + mtspr PPC440_DTV3,r0 /*------------------------------------------------------------------ * Cache victim limits @@ -198,8 +200,8 @@ first: li r0,0 // Clear r0 *------------------------------------------------------------------*/ lis r2, 0x0001f800@h ori r2,r2,0x0001f800@l - mtspr ivlim,r2 - mtspr dvlim,r2 + mtspr PPC440_IVLIM,r2 + mtspr PPC440_DVLIM,r2 /*------------------------------------------------------------------ * Configure instruction and data cache regions: @@ -241,7 +243,7 @@ first: li r0,0 // Clear r0 * 31 SR 1 1 Supervisor State Read Enable *------------------------------------------------------------------*/ - mtspr mmucr,r0 // 10a. Clear MMUCR + mtspr PPC440_MMUCR,r0 // 10a. Clear MMUCR li r7,WIMG_U_S_1 // Word 2: Pages are NOT cache inhibited lis r6, PAGE_SZ@h // Page size constant ori r6,r6,PAGE_SZ@l @@ -255,9 +257,9 @@ first: li r0,0 // Clear r0 * Select whether Wait Enable, interrupts/exceptions and which address * spaces should be enabled when application starts *------------------------------------------------------------------*/ - lis r0, 0x00000000@h // 10d. MSR[IS]=0 MSR[DS]=0 - ori r0,r0,0x00000000@l - mtsrr1 r0 + lis r3, 0x00000000@h // 10d. MSR[IS]=0 MSR[DS]=0 + ori r3,r3,0x00000000@l + mtsrr1 r3 mtsrr0 r28 // Return address rfi // Context synchronize to invalidate shadow TLB contents @@ -275,43 +277,43 @@ startupDL: * 11. Tell the processor where the exception vector table will be *------------------------------------------------------------------*/ .extern SYM(__vectors) - lis r2, __vectors@h /* set EVPR exc. vector prefix */ - mtspr ivpr,r2 + lis r1, __vectors@h /* set EVPR exc. vector prefix */ + mtspr BOOKE_IVPR,r1 /*------------------------------------------------------------------ * Set up default exception and interrupt vectors *------------------------------------------------------------------*/ - li r1,0x100 + li r1,0 mtivor0 r1 - addi r1,r1,0x100 + addi r1,r1,0x10 mtivor1 r1 - addi r1,r1,0x100 + addi r1,r1,0x10 mtivor2 r1 - addi r1,r1,0x100 + addi r1,r1,0x10 mtivor3 r1 - addi r1,r1,0x100 + addi r1,r1,0x10 mtivor4 r1 - addi r1,r1,0x100 + addi r1,r1,0x10 mtivor5 r1 - addi r1,r1,0x100 + addi r1,r1,0x10 mtivor6 r1 - addi r1,r1,0x100 + addi r1,r1,0x10 mtivor7 r1 - addi r1,r1,0x100 + addi r1,r1,0x10 mtivor8 r1 - addi r1,r1,0x100 + addi r1,r1,0x10 mtivor9 r1 - addi r1,r1,0x100 + addi r1,r1,0x10 mtivor10 r1 - addi r1,r1,0x100 + addi r1,r1,0x10 mtivor11 r1 - addi r1,r1,0x100 + addi r1,r1,0x10 mtivor12 r1 - addi r1,r1,0x100 + addi r1,r1,0x10 mtivor13 r1 - addi r1,r1,0x100 + addi r1,r1,0x10 mtivor14 r1 - addi r1,r1,0x100 + addi r1,r1,0x10 mtivor15 r1 /*------------------------------------------------------------------ @@ -336,16 +338,15 @@ startupDL: * 13. Configure timer facilities *------------------------------------------------------------------*/ mtdec r0 // Clear Decrementer to prevent exception - mttbu r0 // Clear Timebase to prevent Fixed Interval.. - mttbl r0 // ..timer and Watchdog Timer exceptions + mttbl r0 // Clear Timebase to prevent Fixed Interval.. + mttbu r0 // ..timer and Watchdog Timer exceptions mtpit r0 // Programmable interval timer - li r1,-1 // -1 to clear TSR - mttsr r1 // Timer status register + li r2,-1 // -1 to clear TSR + mttsr r2 // Timer status register /*------------------------------------------------------------------- * Clear out stale values in certain registers to avoid confusion *------------------------------------------------------------------*/ - li r0,0 mtcrf 0xff,r0 // Need for simulation mtctr r0 // Counter register mtxer r0 // Fixed-point exception register |