source: rtems/c/src/lib/libbsp/powerpc/shared/vme/vme_universe.c @ 78912b5

4.104.114.9
Last change on this file since 78912b5 was 78912b5, checked in by Till Straumann <strauman@…>, on Aug 28, 2008 at 3:39:49 PM

2008-08-28 Till Straumann <strauman@…>

  • shared/vme/vme_universe.c: added implementation for BSP_VMEResetBus().
  • Property mode set to 100644
File size: 11.3 KB
Line 
1/*$Id$*/
2
3/* Implementation of the VME.h and VMEDMA.h APIs for the BSP using the
4 * vmeUniverse/vmeTsi148 drivers
5 *
6 * This file is named vme_universe.c for historic reasons.
7 */
8
9
10#include <rtems.h>
11#include <bsp.h>
12#include <bsp/VME.h>
13#include <bsp/VMEDMA.h>
14#include <bsp/VMEConfig.h>
15#include <bsp/irq.h>
16#include <stdio.h>
17
18#define __INSIDE_RTEMS_BSP__
19
20#if !defined(_VME_DRIVER_TSI148) && !defined(_VME_DRIVER_UNIVERSE)
21#define _VME_DRIVER_UNIVERSE
22#endif
23
24#if defined(_VME_DRIVER_TSI148)
25#define _VME_TSI148_DECLARE_SHOW_ROUTINES
26#include <bsp/vmeTsi148.h>
27#include <bsp/vmeTsi148DMA.h>
28#endif
29
30#if defined(_VME_DRIVER_UNIVERSE)
31#define _VME_UNIVERSE_DECLARE_SHOW_ROUTINES
32#include <bsp/vmeUniverse.h>
33#include <bsp/vmeUniverseDMA.h>
34#if     !defined(BSP_VME_INSTALL_IRQ_MGR) && defined(BSP_VME_UNIVERSE_INSTALL_IRQ_MGR)
35#define BSP_VME_INSTALL_IRQ_MGR BSP_VME_UNIVERSE_INSTALL_IRQ_MGR
36#endif
37#endif
38
39#include <bsp/bspVmeDmaList.h>
40
41/* Wrap BSP VME calls around driver calls - we do this so EPICS doesn't have to
42 * include bridge-specific headers. This file provides the necessary glue
43 * to make VME.h and vmeconfig.c independent of the bridge chip.
44 *
45 * This file is named 'vme_universe.c' for historical reasons.
46 */
47
48/*
49 * Authorship
50 * ----------
51 * This software was created by
52 *     Till Straumann <strauman@slac.stanford.edu>, 9/2005,
53 *         Stanford Linear Accelerator Center, Stanford University.
54 *
55 * Acknowledgement of sponsorship
56 * ------------------------------
57 * This software was produced by
58 *     the Stanford Linear Accelerator Center, Stanford University,
59 *         under Contract DE-AC03-76SFO0515 with the Department of Energy.
60 *
61 * Government disclaimer of liability
62 * ----------------------------------
63 * Neither the United States nor the United States Department of Energy,
64 * nor any of their employees, makes any warranty, express or implied, or
65 * assumes any legal liability or responsibility for the accuracy,
66 * completeness, or usefulness of any data, apparatus, product, or process
67 * disclosed, or represents that its use would not infringe privately owned
68 * rights.
69 *
70 * Stanford disclaimer of liability
71 * --------------------------------
72 * Stanford University makes no representations or warranties, express or
73 * implied, nor assumes any liability for the use of this software.
74 *
75 * Stanford disclaimer of copyright
76 * --------------------------------
77 * Stanford University, owner of the copyright, hereby disclaims its
78 * copyright and all other rights in this software.  Hence, anyone may
79 * freely use it for any purpose without restriction. 
80 *
81 * Maintenance of notices
82 * ----------------------
83 * In the interest of clarity regarding the origin and status of this
84 * SLAC software, this and all the preceding Stanford University notices
85 * are to remain affixed to any copy or derivative of this software made
86 * or distributed by the recipient and are to be affixed to any copy of
87 * software made or distributed by the recipient that contains a copy or
88 * derivative of this software.
89 *
90 * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
91 */ 
92typedef struct {
93        int                             (*xlate_adrs)(int, int, unsigned long, unsigned long, unsigned long *);
94        int                             (*install_isr)(unsigned long, BSP_VME_ISR_t, void *);
95        int                             (*remove_isr)(unsigned long, BSP_VME_ISR_t, void *);
96        BSP_VME_ISR_t   (*get_isr)(unsigned long vector, void **);
97        int                             (*enable_int_lvl)(unsigned int);
98        int                             (*disable_int_lvl)(unsigned int);
99        int                             (*outbound_p_cfg)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
100        int                             (*inbound_p_cfg) (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
101        void                    (*outbound_p_show)(FILE*);
102        void                    (*inbound_p_show) (FILE*);
103        void            (*reset_bus)(void);
104        int                             (*install_irq_mgr)(int, int, int, ...);
105        int             irq_mgr_flags;
106} VMEOpsRec, *VMEOps;
107
108/* two separate 'ops' structs for historic reasons */
109typedef struct DmaOpsRec_ {
110        int                             (*setup)(int, uint32_t, uint32_t, void *);
111        int                             (*start)(int, uint32_t, uint32_t, uint32_t);
112        uint32_t                (*status)(int);
113        VMEDmaListClass listClass;
114        int                             nChannels;
115        int                             *vectors;
116} DmaOpsRec, *DmaOps;
117
118#ifdef _VME_DRIVER_UNIVERSE
119static VMEOpsRec uniOpsRec = {
120        xlate_adrs:             vmeUniverseXlateAddr,
121        install_isr:            vmeUniverseInstallISR,
122        remove_isr:             vmeUniverseRemoveISR,
123        get_isr:                        vmeUniverseISRGet,
124        enable_int_lvl:         vmeUniverseIntEnable,
125        disable_int_lvl:        vmeUniverseIntDisable,
126        outbound_p_cfg:         vmeUniverseMasterPortCfg,
127        inbound_p_cfg:          vmeUniverseSlavePortCfg,
128        outbound_p_show:        vmeUniverseMasterPortsShow,
129        inbound_p_show:         vmeUniverseSlavePortsShow,
130        reset_bus:          vmeUniverseResetBus,
131        install_irq_mgr:        vmeUniverseInstallIrqMgrAlt,
132        irq_mgr_flags:      VMEUNIVERSE_IRQ_MGR_FLAG_SHARED |
133                            VMEUNIVERSE_IRQ_MGR_FLAG_PW_WORKAROUND,
134};
135
136static int uniVecs[] = { UNIV_DMA_INT_VEC };
137
138static DmaOpsRec uniDmaOpsRec = {
139        setup:                          vmeUniverseDmaSetup,
140        start:                          vmeUniverseDmaStart,
141        status:                         vmeUniverseDmaStatus,
142        listClass:                      &vmeUniverseDmaListClass,
143        nChannels:                      1,
144        vectors:                        uniVecs,
145};
146#endif
147
148#ifdef _VME_DRIVER_TSI148
149static VMEOpsRec tsiOpsRec = {
150        xlate_adrs:             vmeTsi148XlateAddr,
151        install_isr:            vmeTsi148InstallISR,
152        remove_isr:             vmeTsi148RemoveISR,
153        get_isr:                        vmeTsi148ISRGet,
154        enable_int_lvl:         vmeTsi148IntEnable,
155        disable_int_lvl:        vmeTsi148IntDisable,
156        outbound_p_cfg:         vmeTsi148OutboundPortCfg,
157        inbound_p_cfg:          vmeTsi148InboundPortCfg,
158        outbound_p_show:        vmeTsi148OutboundPortsShow,
159        inbound_p_show:         vmeTsi148InboundPortsShow,
160        reset_bus:          vmeTsi148ResetBus,
161        install_irq_mgr:        vmeTsi148InstallIrqMgrAlt,
162        irq_mgr_flags:      VMETSI148_IRQ_MGR_FLAG_SHARED,
163};
164
165static int tsiVecs[] = {
166        TSI_DMA_INT_VEC,
167        TSI_DMA1_INT_VEC,
168};
169
170static DmaOpsRec tsiDmaOpsRec = {
171        setup:                          vmeTsi148DmaSetup,
172        start:                          vmeTsi148DmaStart,
173        status:                         vmeTsi148DmaStatus,
174        listClass:                      &vmeTsi148DmaListClass,
175        nChannels:                      2,
176        vectors:                        tsiVecs,
177};
178#endif
179
180static VMEOps theOps    = 0;
181static DmaOps theDmaOps = 0;
182
183int
184BSP_vme2local_adrs(unsigned long am, unsigned long vmeaddr, unsigned long *plocaladdr)
185{
186int rval=theOps->xlate_adrs(1,0,am,vmeaddr,plocaladdr);
187        *plocaladdr+=PCI_MEM_BASE;
188        return rval;
189}
190
191int
192BSP_local2vme_adrs(unsigned long am, unsigned long localaddr, unsigned long *pvmeaddr)
193{
194        return theOps->xlate_adrs(0, 0, am,localaddr+PCI_DRAM_OFFSET,pvmeaddr);
195}
196
197int
198BSP_installVME_isr(unsigned long vector, BSP_VME_ISR_t handler, void *arg)
199{
200        return theOps->install_isr(vector, handler, arg);
201}
202
203int
204BSP_removeVME_isr(unsigned long vector, BSP_VME_ISR_t handler, void *arg)
205{
206        return theOps->remove_isr(vector, handler, arg);
207}
208
209/* retrieve the currently installed ISR for a given vector */
210BSP_VME_ISR_t
211BSP_getVME_isr(unsigned long vector, void **parg)
212{
213        return theOps->get_isr(vector, parg);
214}
215
216int
217BSP_enableVME_int_lvl(unsigned int level)
218{
219        return theOps->enable_int_lvl(level);
220}
221
222int
223BSP_disableVME_int_lvl(unsigned int level)
224{
225        return theOps->disable_int_lvl(level);
226}
227
228int
229BSP_VMEOutboundPortCfg(
230        unsigned long port,
231        unsigned long address_space,
232        unsigned long vme_address,
233        unsigned long pci_address,
234        unsigned long size)
235{
236        return theOps->outbound_p_cfg(port, address_space, vme_address, pci_address, size);
237}
238
239int
240BSP_VMEInboundPortCfg(
241        unsigned long port,
242        unsigned long address_space,
243        unsigned long vme_address,
244        unsigned long pci_address,
245        unsigned long size)
246{
247        return theOps->inbound_p_cfg(port, address_space, vme_address, pci_address, size);
248}
249
250void
251BSP_VMEOutboundPortsShow(FILE *f)
252{
253        theOps->outbound_p_show(f);
254}
255
256void
257BSP_VMEInboundPortsShow(FILE *f)
258{
259        theOps->inbound_p_show(f);
260}
261
262void
263BSP_VMEResetBus(void)
264{
265        theOps->reset_bus();
266}
267
268int
269BSP_VMEDmaSetup(int channel, uint32_t bus_mode, uint32_t xfer_mode, void *custom_setup)
270{
271        return theDmaOps->setup(channel, bus_mode, xfer_mode, custom_setup);
272}
273
274int
275BSP_VMEDmaStart(int channel, uint32_t pci_addr, uint32_t vme_addr, uint32_t n_bytes)
276{
277        return theDmaOps->start(channel, pci_addr, vme_addr, n_bytes);
278}
279
280uint32_t
281BSP_VMEDmaStatus(int channel)
282{
283        return theDmaOps->status(channel);
284}
285
286BSP_VMEDmaListDescriptor
287BSP_VMEDmaListDescriptorSetup(
288                BSP_VMEDmaListDescriptor d,
289                uint32_t                 attr_mask,
290                uint32_t                                 xfer_mode,
291                uint32_t                 pci_addr,
292                uint32_t                 vme_addr,
293                uint32_t                 n_bytes)
294{
295VMEDmaListClass pc;
296
297        if ( !d ) {
298
299                pc = theDmaOps->listClass;
300
301                return BSP_VMEDmaListDescriptorNewTool(
302                                        pc,
303                                        attr_mask,
304                                        xfer_mode,
305                                        pci_addr,
306                                        vme_addr,
307                                        n_bytes);
308                                       
309        }
310
311        return BSP_VMEDmaListDescriptorSetupTool(d, attr_mask, xfer_mode, pci_addr, vme_addr, n_bytes);
312}
313
314int
315BSP_VMEDmaListStart(int channel, BSP_VMEDmaListDescriptor list)
316{
317        return BSP_VMEDmaListDescriptorStartTool(0, channel, list);
318}
319
320/* NOT thread safe! */
321int
322BSP_VMEDmaInstallISR(int channel, BSP_VMEDmaIRQCallback cb, void *usr_arg)
323{
324int vec;
325BSP_VME_ISR_t curr;
326void          *carg;
327
328        if ( channel < 0 || channel >= theDmaOps->nChannels )
329                return -1;
330
331        vec = theDmaOps->vectors[channel];
332
333        curr = BSP_getVME_isr(vec, &carg);
334
335        if ( cb && curr ) {
336                /* IRQ currently in use */
337                return -1;
338        }
339
340        if ( !cb && !curr ) {
341                /* Allow uninstall if no handler is currently installed;
342                 * just make sure IRQ is disabled
343                 */
344                BSP_disableVME_int_lvl(vec);
345                return 0;
346        }
347       
348        if ( cb ) {
349                if ( BSP_installVME_isr(vec, (BSP_VME_ISR_t)cb, usr_arg) )
350                        return -4;
351                BSP_enableVME_int_lvl(vec);
352        } else {
353                BSP_disableVME_int_lvl(vec);
354                if ( BSP_removeVME_isr(vec, curr, carg) )
355                        return -4;
356        }
357        return 0;
358}
359
360#if defined(_VME_DRIVER_TSI148) && !defined(VME_CLEAR_BRIDGE_ERRORS)
361static unsigned short
362tsi_clear_errors(int quiet)
363{
364unsigned long   v;
365unsigned short  rval;
366        v = vmeTsi148ClearVMEBusErrors(0);
367
368        /* return bits 8..23 of VEAT; set bit 15 to make sure rval is nonzero on error */
369        rval =  v ? ((v>>8) & 0xffff) | (1<<15) : 0;
370        return rval;
371}
372
373#define VME_CLEAR_BRIDGE_ERRORS tsi_clear_errors
374#endif
375
376int BSP_VMEInit()
377{
378#if defined(_VME_DRIVER_UNIVERSE)
379  if ( 0 == vmeUniverseInit() ) {
380        theOps    = &uniOpsRec;
381        theDmaOps = &uniDmaOpsRec;
382        vmeUniverseReset();
383  }
384#endif
385#if defined(_VME_DRIVER_UNIVERSE) && defined(_VME_DRIVER_TSI148)
386        else
387#endif
388#if defined(_VME_DRIVER_TSI148)
389  if ( 0 == vmeTsi148Init() ) {
390        theOps    = &tsiOpsRec;
391        theDmaOps = &tsiDmaOpsRec;
392        vmeTsi148Reset();
393#ifdef VME_CLEAR_BRIDGE_ERRORS
394        {
395        extern unsigned short (*_BSP_clear_vmebridge_errors)();
396
397          _BSP_clear_vmebridge_errors = VME_CLEAR_BRIDGE_ERRORS;
398
399        }
400#endif
401  }
402#endif
403    else
404          /*  maybe no VME at all - or no universe/tsi148 ... */
405          return -1;
406
407  return 0;
408}
409
410int BSP_VMEIrqMgrInstall()
411{
412int err;
413#ifndef BSP_VME_INSTALL_IRQ_MGR
414  /* No map; use first line only and obtain PIC wire from PCI config */
415  err = theOps->install_irq_mgr(
416        theOps->irq_mgr_flags, /* use shared IRQs */
417        0, -1,  /* Universe/Tsi148 pin0 -> PIC line from config space */
418        -1      /* terminate list  */
419  );
420#else
421  BSP_VME_INSTALL_IRQ_MGR(err);
422#endif
423
424  if ( err )
425        return err;
426
427/* This feature is only supported by the Universe driver (not Tsi148) */
428#if defined(BSP_PCI_VME_DRIVER_DOES_EOI) && defined(BSP_PIC_DO_EOI)
429#ifdef  _VME_DRIVER_TSI148
430#error  "BSP_PCI_VME_DRIVER_DOES_EOI/BSP_PIC_DO_EOI feature can only be used with vmeUniverse"
431#endif
432  if ( vmeUniverse0PciIrqLine < 0 )
433        BSP_panic("Unable to get universe interrupt line info from PCI config");
434  _BSP_vme_bridge_irq = vmeUniverse0PciIrqLine;
435#endif
436  return 0;
437}
Note: See TracBrowser for help on using the repository browser.