From 6d3ff66f7a7480edabac28dece38f3381460b99f Mon Sep 17 00:00:00 2001 From: Till Straumann Date: Fri, 4 Nov 2005 08:10:42 +0000 Subject: 2005-11-03 Till Straumann * shared/vme/README, shared/vme/vme_universe.c: New files. * Makefile.am, motorola_powerpc/Makefile.am, mvme5500/vme/vmeconfig.c, shared/vme/VME.h, shared/vme/VMEConfig.h, shared/vme/vmeconfig.c: Several VME related upgrades and fixes, hopefully addressing PR#835: Separated API, API-implementation by a specific VME bridge driver and BSP-specific configuration of the driver into different files, describing their purpose in a README. All of these changes use the upgraded vmeUniverse.c driver. --- c/src/lib/libbsp/powerpc/Makefile.am | 1 + .../libbsp/powerpc/motorola_powerpc/Makefile.am | 6 + c/src/lib/libbsp/powerpc/mvme5500/vme/vmeconfig.c | 2 +- c/src/lib/libbsp/powerpc/shared/vme/README | 9 ++ c/src/lib/libbsp/powerpc/shared/vme/VME.h | 127 ++++++++------------- c/src/lib/libbsp/powerpc/shared/vme/VMEConfig.h | 66 +++++++++++ c/src/lib/libbsp/powerpc/shared/vme/vme_universe.c | 125 ++++++++++++++++++++ c/src/lib/libbsp/powerpc/shared/vme/vmeconfig.c | 56 +++------ 8 files changed, 275 insertions(+), 117 deletions(-) create mode 100644 c/src/lib/libbsp/powerpc/shared/vme/README create mode 100644 c/src/lib/libbsp/powerpc/shared/vme/vme_universe.c (limited to 'c') diff --git a/c/src/lib/libbsp/powerpc/Makefile.am b/c/src/lib/libbsp/powerpc/Makefile.am index 5f115574e8..4b1efc7dcd 100644 --- a/c/src/lib/libbsp/powerpc/Makefile.am +++ b/c/src/lib/libbsp/powerpc/Makefile.am @@ -63,6 +63,7 @@ EXTRA_DIST += shared/vectors/vectors_init.c shared/vectors/vectors.S ## shared/vme EXTRA_DIST += shared/vme/vmeconfig.c shared/vme/VMEConfig.h shared/vme/VME.h + shared/vme/README shared/vme/vme_universe.c include $(top_srcdir)/../../../automake/subdirs.am include $(top_srcdir)/../../../automake/local.am diff --git a/c/src/lib/libbsp/powerpc/motorola_powerpc/Makefile.am b/c/src/lib/libbsp/powerpc/motorola_powerpc/Makefile.am index 63ea700075..19564d419b 100644 --- a/c/src/lib/libbsp/powerpc/motorola_powerpc/Makefile.am +++ b/c/src/lib/libbsp/powerpc/motorola_powerpc/Makefile.am @@ -138,7 +138,9 @@ include_bsp_HEADERS += ../../shared/vmeUniverse/vmeUniverse.h \ noinst_PROGRAMS += vme.rel vme_rel_SOURCES = ../../shared/vmeUniverse/vmeUniverse.c \ ../../shared/vmeUniverse/vmeUniverse.h \ + ../../shared/vmeUniverse/vme_am_defs.h \ ../../powerpc/shared/vme/vmeconfig.c \ + ../../powerpc/shared/vme/vme_universe.c \ ../../powerpc/shared/vme/VMEConfig.h ../../powerpc/shared/vme/VME.h vme_rel_CPPFLAGS = $(AM_CPPFLAGS) vme_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) @@ -260,6 +262,10 @@ $(PROJECT_INCLUDE)/bsp/vmeUniverse.h: ../../shared/vmeUniverse/vmeUniverse.h $(P $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vmeUniverse.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vmeUniverse.h +$(PROJECT_INCLUDE)/bsp/vme_am_defs.h: ../../shared/vmeUniverse/vme_am_defs.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vme_am_defs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vme_am_defs.h + $(PROJECT_INCLUDE)/bsp/VMEConfig.h: ../../powerpc/shared/vme/VMEConfig.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/VMEConfig.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/VMEConfig.h diff --git a/c/src/lib/libbsp/powerpc/mvme5500/vme/vmeconfig.c b/c/src/lib/libbsp/powerpc/mvme5500/vme/vmeconfig.c index 436f89643f..50c40c0f4e 100644 --- a/c/src/lib/libbsp/powerpc/mvme5500/vme/vmeconfig.c +++ b/c/src/lib/libbsp/powerpc/mvme5500/vme/vmeconfig.c @@ -76,7 +76,7 @@ __BSP_default_vme_config(void) vmeUniverseSlavePortsShow(0); /* install the VME insterrupt manager */ - vmeUniverseInstallIrqMgr(0,12,1,13); + vmeUniverseInstallIrqMgr(0,64+12,1,64+13); if (vmeUniverse0PciIrqLine<0) BSP_panic("Unable to get interrupt line info from PCI config"); _BSP_vme_bridge_irq= BSP_GPP_IRQ_LOWEST_OFFSET+vmeUniverse0PciIrqLine; diff --git a/c/src/lib/libbsp/powerpc/shared/vme/README b/c/src/lib/libbsp/powerpc/shared/vme/README new file mode 100644 index 0000000000..c4737c3fa8 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/shared/vme/README @@ -0,0 +1,9 @@ +VME.h: VME API; BSP and bridge-chip independent +VMEConfig.h: defines BSP specific constants for VME configuration +vmeconfig.c configures the VME bridge using the VME.h API calls + and BSP specific constants from VMEConfig.h. + Independent of the bridge chip, however. +vme_universe.c: implements VME.h for the vmeUniverse driver. + +o other universe BSP --> use its own vmeConfig.h; may reuse vmeconfig.c, vme_universe.c +o other non-universe BSP --> use its own VMEConfig.h and vme_xxx.c; may reuse vmeconfig.c diff --git a/c/src/lib/libbsp/powerpc/shared/vme/VME.h b/c/src/lib/libbsp/powerpc/shared/vme/VME.h index a7aea8a3bd..6b2e1bba84 100644 --- a/c/src/lib/libbsp/powerpc/shared/vme/VME.h +++ b/c/src/lib/libbsp/powerpc/shared/vme/VME.h @@ -1,98 +1,69 @@ -#ifndef RTEMS_BSP_VME_UNIVERSE_H -#define RTEMS_BSP_VME_UNIVERSE_H +#ifndef RTEMS_BSP_VME_API_H +#define RTEMS_BSP_VME_API_H /* $Id$ */ /* SVGM et al. BSP's VME support */ /* Author: Till Straumann, */ -/* pull in bsp.h */ -#include -/* our VME bridge */ -#include -/* our address space configuration */ -#include +#include + +/* address modifiers & friends */ +#include /* VME related declarations */ -/* how to map a VME address to the CPU local bus. - * Note that this traverses two bridges: - * the grackle and the universe. For the - * Universe, there is a lookup procedure while - * we assume a 1:1 mapping for the grackle... - */ -/* NOTE about the fast mapping macros: - * using these macros is only safe if the user app - * does _NOT_ change the universe mappings! - * While changing the PCI windows probably doesn't - * make much sense (involves changing the MMU/DBATs as well), - * The user might wish to change the VME address - * layout, i.e. by remapping _VME_A32_WIN0_ON_VME - * and _VME_DRAM_OFFSET... - * Hence, using the A24 and A16 macros is probably safe. +/* + * BSP-specific configuration routine; sets up + * VME windows and installs the VME interrupt manager. */ - -#define BSP_vme_init() \ - vmeUniverseInit +void BSP_vme_config() __attribute__((weak)); /* translate through host bridge and vme master window of vme bridge */ -static inline int -BSP_vme2local_adrs(unsigned am, unsigned long vmeaddr, unsigned long *plocaladdr) -{ -int rval=vmeUniverseXlateAddr(1,0,am,vmeaddr,plocaladdr); - *plocaladdr+=PCI_MEM_BASE; - return rval; -} - -/* when using this macro, the universe setup MUST NOT BE - * CHANGED by the application... - */ -#define BSP_vme2local_A32_fast(vmeaddr) \ - ((vmeaddr)-_VME_A32_WIN0_ON_VME + _VME_A32_WIN0_ON_PCI + PCI_MEM_BASE) -#define BSP_vme2local_A24_fast(vmeaddr) \ - (((vmeaddr)&0x7ffffff)+_VME_A24_ON_PCI + PCI_MEM_BASE) -#define BSP_vme2local_A16_fast(vmeaddr) \ - (((vmeaddr)&0xffff)+_VME_A16_ON_PCI + PCI_MEM_BASE) - -/* how a CPU address is mapped to the VME bus (if at all) - */ -static inline int -BSP_local2vme_adrs(unsigned am, unsigned long localaddr, unsigned long *pvmeaddr) -{ -return vmeUniverseXlateAddr(0, 0, am,localaddr+PCI_DRAM_OFFSET,pvmeaddr); -} +int +BSP_vme2local_adrs(unsigned long am, unsigned long vmeaddr, unsigned long *plocaladdr); -#define BSP_localdram2vme_fast(localaddr) \ - ((localaddr)+_VME_DRAM_OFFSET) +/* how a CPU address is mapped to the VME bus (if at all) */ +int +BSP_local2vme_adrs(unsigned long am, unsigned long localaddr, unsigned long *pvmeaddr); /* interrupt handlers and levels */ typedef void (*BSP_VME_ISR_t)(void *usrArg, unsigned long vector); -#define BSP_installVME_isr(vector, handler, arg) \ - vmeUniverseInstallISR(vector, handler, arg) - -#define BSP_removeVME_isr(vector, handler, arg) \ - vmeUniverseRemoveISR(vector, handler, arg) +int +BSP_installVME_isr(unsigned long vector, BSP_VME_ISR_t handler, void *arg); +int +BSP_removeVME_isr(unsigned long vector, BSP_VME_ISR_t handler, void *arg); /* retrieve the currently installed ISR for a given vector */ -#define BSP_getVME_isr(vector, parg) \ - vmeUniverseISRGet(vector, parg) - -#define BSP_enableVME_int_lvl(level) \ - vmeUniverseIntEnable(level) - -#define BSP_disableVME_int_lvl(level) \ - vmeUniverseIntDisable(level) - -/* Tell the interrupt manager that the universe driver - * already called openpic_eoi() and that this step hence - * must be omitted. - */ -#define BSP_PCI_VME_DRIVER_DOES_EOI -extern int _BSP_vme_bridge_irq; -/* don't reference vmeUniverse0PciIrqLine directly here - leave it up to - * bspstart() to set BSP_vme_bridge_irq. That way, we can generate variants - * of the BSP with / without the universe driver... - */ -#define BSP_PCI_VME_BRIDGE_IRQ _BSP_vme_bridge_irq +BSP_VME_ISR_t +BSP_getVME_isr(unsigned long vector, void **parg); + +int +BSP_enableVME_int_lvl(unsigned int level); + +int +BSP_disableVME_int_lvl(unsigned int level); + +int +BSP_VMEOutboundPortCfg( + unsigned long port, + unsigned long address_space, + unsigned long vme_address, + unsigned long pci_address, + unsigned long size); + +int +BSP_VMEInboundPortCfg( + unsigned long port, + unsigned long address_space, + unsigned long vme_address, + unsigned long pci_address, + unsigned long size); + +void +BSP_VMEOutboundPortsShow(FILE *f); + +void +BSP_VMEInboundPortsShow(FILE *f); #endif diff --git a/c/src/lib/libbsp/powerpc/shared/vme/VMEConfig.h b/c/src/lib/libbsp/powerpc/shared/vme/VMEConfig.h index 6f89457273..4633f806e1 100644 --- a/c/src/lib/libbsp/powerpc/shared/vme/VMEConfig.h +++ b/c/src/lib/libbsp/powerpc/shared/vme/VMEConfig.h @@ -10,15 +10,24 @@ * NOTE: the BSP (startup/bspstart.c) uses * hardcoded window lengths that match this * layout: + * + * BSP_VME_BAT_IDX defines + * which BAT to use for mapping the VME bus. + * If this is undefined, no extra BAT will be + * configured and VME has to share the available + * PCI address space with PCI devices. */ + #if defined(mvme2100) #define _VME_A32_WIN0_ON_PCI 0x90000000 #define _VME_A24_ON_PCI 0x9f000000 #define _VME_A16_ON_PCI 0x9fff0000 +#define BSP_VME_BAT_IDX 1 #else #define _VME_A32_WIN0_ON_PCI 0x10000000 #define _VME_A24_ON_PCI 0x1f000000 #define _VME_A16_ON_PCI 0x1fff0000 +#define BSP_VME_BAT_IDX 0 #endif /* start of the A32 window on the VME bus @@ -32,4 +41,61 @@ */ #define _VME_DRAM_OFFSET 0xc0000000 +/* Tell the interrupt manager that the universe driver + * already called openpic_eoi() and that this step hence + * must be omitted. + */ + +#define BSP_PCI_VME_DRIVER_DOES_EOI +/* don't reference vmeUniverse0PciIrqLine directly here - leave it up to + * bspstart() to set BSP_vme_bridge_irq. That way, we can generate variants + * of the BSP with / without the universe driver... + */ +extern int _BSP_vme_bridge_irq; + +extern int BSP_VMEInit(); +extern int BSP_VMEIrqMgrInstall(); + +#include +#include + +#define BSP_VME_UNIVERSE_INSTALL_IRQ_MGR \ +do { \ +int bus, dev, i = 0, j; \ +const struct _int_map *bspmap; \ + /* install the VME interrupt manager; \ + * if there's a bsp route map, use it to \ + * configure additional lines... \ + */ \ + if (0 == pci_find_device(0x10e3, 0x0000, 0, &bus, &dev, &i)){ \ + if ( (bspmap = motorolaIntMap(currentBoard)) ) { \ + for ( i=0; bspmap[i].bus >= 0; i++ ) { \ + if ( bspmap[i].bus == bus && bspmap[i].slot == dev ) { \ + int pins[5], names[4]; \ + /* found it; use info here... */ \ + /* copy up to 4 entries; terminated with -1 pin */ \ + for ( j=0; \ + j<5 && (pins[j]=bspmap[i].pin_route[j].pin-1)>=0; \ + j++) { \ + names[j] = bspmap[i].pin_route[j].int_name[0]; \ + } \ + pins[4] = -1; \ + if ( 0 == vmeUniverseInstallIrqMgrAlt( \ + 1, /* shared IRQs */ \ + pins[0], names[0], \ + pins[1], names[1], \ + pins[2], names[2], \ + pins[3], names[3], \ + -1) ) { \ + i = -1; \ + break; \ + } \ + } \ + } \ + } \ + if ( i >= 0 ) \ + vmeUniverseInstallIrqMgrAlt(1,0,-1,-1); \ + } \ +} while (0) + #endif diff --git a/c/src/lib/libbsp/powerpc/shared/vme/vme_universe.c b/c/src/lib/libbsp/powerpc/shared/vme/vme_universe.c new file mode 100644 index 0000000000..c4f791ea8b --- /dev/null +++ b/c/src/lib/libbsp/powerpc/shared/vme/vme_universe.c @@ -0,0 +1,125 @@ +/*$Id$*/ + +#include +#include +#include +#include +#include +#include + +/* Wrap BSP VME calls around driver calls - we do this so EPICS doesn't have to + * include bridge-specific headers. This file provides the necessary glue + * to make VME.h and vmeconfig.c independent of the bridge chip. + */ + +/* Author: Till Straumann , 9/2005 */ + +int +BSP_vme2local_adrs(unsigned long am, unsigned long vmeaddr, unsigned long *plocaladdr) +{ +int rval=vmeUniverseXlateAddr(1,0,am,vmeaddr,plocaladdr); + *plocaladdr+=PCI_MEM_BASE; + return rval; +} + +int +BSP_local2vme_adrs(unsigned long am, unsigned long localaddr, unsigned long *pvmeaddr) +{ + return vmeUniverseXlateAddr(0, 0, am,localaddr+PCI_DRAM_OFFSET,pvmeaddr); +} + + +int +BSP_installVME_isr(unsigned long vector, BSP_VME_ISR_t handler, void *arg) +{ + return vmeUniverseInstallISR(vector, handler, arg); +} + +int +BSP_removeVME_isr(unsigned long vector, BSP_VME_ISR_t handler, void *arg) +{ + return vmeUniverseRemoveISR(vector, handler, arg); +} + +/* retrieve the currently installed ISR for a given vector */ +BSP_VME_ISR_t +BSP_getVME_isr(unsigned long vector, void **parg) +{ + return vmeUniverseISRGet(vector, parg); +} + +int +BSP_enableVME_int_lvl(unsigned int level) +{ + return vmeUniverseIntEnable(level); +} + +int +BSP_disableVME_int_lvl(unsigned int level) +{ + return vmeUniverseIntDisable(level); +} + +int +BSP_VMEOutboundPortCfg( + unsigned long port, + unsigned long address_space, + unsigned long vme_address, + unsigned long pci_address, + unsigned long size) +{ + return vmeUniverseMasterPortCfg(port, address_space, vme_address, pci_address, size); +} + +int +BSP_VMEInboundPortCfg( + unsigned long port, + unsigned long address_space, + unsigned long vme_address, + unsigned long pci_address, + unsigned long size) +{ + return vmeUniverseSlavePortCfg(port, address_space, vme_address, pci_address, size); +} + +void +BSP_VMEOutboundPortsShow(FILE *f) +{ + vmeUniverseMasterPortsShow(f); +} + +void +BSP_VMEInboundPortsShow(FILE *f) +{ + vmeUniverseSlavePortsShow(f); +} + + +int BSP_VMEInit() +{ + if ( vmeUniverseInit() ) { + /* maybe no VME at all - or no universe ... */ + return -1; + } + vmeUniverseReset(); + return 0; +} + +int BSP_VMEIrqMgrInstall() +{ +#ifndef BSP_VME_UNIVERSE_INSTALL_IRQ_MGR + /* No map; use first line only and obtain PIC wire from PCI config */ + vmeUniverseInstallIrqMgrAlt( + 1, /* use shared IRQs */ + 0, -1, /* Universe pin0 -> PIC line from config space */ + -1 /* terminate list */ + ); + +#else + BSP_VME_UNIVERSE_INSTALL_IRQ_MGR; +#endif + if (vmeUniverse0PciIrqLine<0) + BSP_panic("Unable to get universe interrupt line info from PCI config"); + _BSP_vme_bridge_irq = vmeUniverse0PciIrqLine; + return 0; +} diff --git a/c/src/lib/libbsp/powerpc/shared/vme/vmeconfig.c b/c/src/lib/libbsp/powerpc/shared/vme/vmeconfig.c index 15baf84d15..e951acf51c 100644 --- a/c/src/lib/libbsp/powerpc/shared/vme/vmeconfig.c +++ b/c/src/lib/libbsp/powerpc/shared/vme/vmeconfig.c @@ -1,15 +1,16 @@ /* $Id$ */ -/* Standard VME bridge configuration for VGM type boards */ +/* Default VME bridge configuration - note that this file + * is independent of the bridge driver/chip + */ /* Author: Till Straumann , 3/2002 */ #include #include -#include +#include #include -#include -#include +#include /* Use a weak alias for the VME configuration. * This permits individual applications to override @@ -24,50 +25,38 @@ void BSP_vme_config(void) __attribute__ (( weak, alias("__BSP_default_vme_config") )); -SPR_RO(DBAT0U) - void __BSP_default_vme_config(void) { -union { - struct _BATU bat; - unsigned long batbits; -} dbat0u; - - vmeUniverseInit(); - vmeUniverseReset(); - /* setup a PCI area to map the VME bus */ - dbat0u.batbits = _read_DBAT0U(); - - /* if we have page tables, BAT0 is available */ - if (dbat0u.bat.vs || dbat0u.bat.vp) { - printk("WARNING: BAT0 is taken (no pagetables?); " - "VME bridge must share PCI range for VME access\n" - "Skipping VME initialization...\n"); + if ( BSP_VMEInit() ) { + printk("Skipping VME initialization...\n"); return; } - setdbat(0, +#ifdef BSP_VME_BAT_IDX + /* setup a PCI area to map the VME bus */ + setdbat(BSP_VME_BAT_IDX, PCI_MEM_BASE + _VME_A32_WIN0_ON_PCI, PCI_MEM_BASE + _VME_A32_WIN0_ON_PCI, 0x10000000, IO_PAGE); +#endif /* map VME address ranges */ - vmeUniverseMasterPortCfg( + BSP_VMEOutboundPortCfg( 0, VME_AM_EXT_SUP_DATA, _VME_A32_WIN0_ON_VME, _VME_A32_WIN0_ON_PCI, 0x0F000000); - vmeUniverseMasterPortCfg( + BSP_VMEOutboundPortCfg( 1, VME_AM_STD_SUP_DATA, 0x00000000, _VME_A24_ON_PCI, 0x00ff0000); - vmeUniverseMasterPortCfg( + BSP_VMEOutboundPortCfg( 2, VME_AM_SUP_SHORT_IO, 0x00000000, @@ -76,26 +65,17 @@ union { #ifdef _VME_DRAM_OFFSET /* map our memory to VME */ - vmeUniverseSlavePortCfg( + BSP_VMEInboundPortCfg( 0, VME_AM_EXT_SUP_DATA, _VME_DRAM_OFFSET, PCI_DRAM_OFFSET, BSP_mem_size); - - /* make sure the host bridge PCI master is enabled */ - vmeUniverseWriteReg( - vmeUniverseReadReg(UNIV_REGOFF_PCI_CSR) | UNIV_PCI_CSR_BM, - UNIV_REGOFF_PCI_CSR); #endif /* stdio is not yet initialized; the driver will revert to printk */ - vmeUniverseMasterPortsShow(0); - vmeUniverseSlavePortsShow(0); + BSP_VMEOutboundPortsShow(0); + BSP_VMEInboundPortsShow(0); - /* install the VME insterrupt manager */ - vmeUniverseInstallIrqMgr(0,5,1,6); - if (vmeUniverse0PciIrqLine<0) - BSP_panic("Unable to get interrupt line info from PCI config"); - _BSP_vme_bridge_irq=BSP_PCI_IRQ_LOWEST_OFFSET+vmeUniverse0PciIrqLine; + BSP_VMEIrqMgrInstall(); } -- cgit v1.2.3