source: rtems/c/src/lib/libbsp/powerpc/shared/vme/vme_universe.c @ 9b4c770

4.104.114.95
Last change on this file since 9b4c770 was 2398f74, checked in by Till Straumann <strauman@…>, on 12/09/07 at 07:17:16

2007-12-08 Till Straumann <strauman@…>

  • shared/vme/vme_universe.c: fixed wrong initialization routine when using Tsi148 driver.
  • Property mode set to 100644
File size: 11.1 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        int                             (*install_irq_mgr)(int, int, int, ...);
104        int             irq_mgr_flags;
105} VMEOpsRec, *VMEOps;
106
107/* two separate 'ops' structs for historic reasons */
108typedef struct DmaOpsRec_ {
109        int                             (*setup)(int, uint32_t, uint32_t, void *);
110        int                             (*start)(int, uint32_t, uint32_t, uint32_t);
111        uint32_t                (*status)(int);
112        VMEDmaListClass listClass;
113        int                             nChannels;
114        int                             *vectors;
115} DmaOpsRec, *DmaOps;
116
117#ifdef _VME_DRIVER_UNIVERSE
118static VMEOpsRec uniOpsRec = {
119        xlate_adrs:             vmeUniverseXlateAddr,
120        install_isr:            vmeUniverseInstallISR,
121        remove_isr:             vmeUniverseRemoveISR,
122        get_isr:                        vmeUniverseISRGet,
123        enable_int_lvl:         vmeUniverseIntEnable,
124        disable_int_lvl:        vmeUniverseIntDisable,
125        outbound_p_cfg:         vmeUniverseMasterPortCfg,
126        inbound_p_cfg:          vmeUniverseSlavePortCfg,
127        outbound_p_show:        vmeUniverseMasterPortsShow,
128        inbound_p_show:         vmeUniverseSlavePortsShow,
129        install_irq_mgr:        vmeUniverseInstallIrqMgrAlt,
130        irq_mgr_flags:      VMEUNIVERSE_IRQ_MGR_FLAG_SHARED |
131                            VMEUNIVERSE_IRQ_MGR_FLAG_PW_WORKAROUND,
132};
133
134static int uniVecs[] = { UNIV_DMA_INT_VEC };
135
136static DmaOpsRec uniDmaOpsRec = {
137        setup:                          vmeUniverseDmaSetup,
138        start:                          vmeUniverseDmaStart,
139        status:                         vmeUniverseDmaStatus,
140        listClass:                      &vmeUniverseDmaListClass,
141        nChannels:                      1,
142        vectors:                        uniVecs,
143};
144#endif
145
146#ifdef _VME_DRIVER_TSI148
147static VMEOpsRec tsiOpsRec = {
148        xlate_adrs:             vmeTsi148XlateAddr,
149        install_isr:            vmeTsi148InstallISR,
150        remove_isr:             vmeTsi148RemoveISR,
151        get_isr:                        vmeTsi148ISRGet,
152        enable_int_lvl:         vmeTsi148IntEnable,
153        disable_int_lvl:        vmeTsi148IntDisable,
154        outbound_p_cfg:         vmeTsi148OutboundPortCfg,
155        inbound_p_cfg:          vmeTsi148InboundPortCfg,
156        outbound_p_show:        vmeTsi148OutboundPortsShow,
157        inbound_p_show:         vmeTsi148InboundPortsShow,
158        install_irq_mgr:        vmeTsi148InstallIrqMgrAlt,
159        irq_mgr_flags:      VMETSI148_IRQ_MGR_FLAG_SHARED,
160};
161
162static int tsiVecs[] = {
163        TSI_DMA_INT_VEC,
164        TSI_DMA1_INT_VEC,
165};
166
167static DmaOpsRec tsiDmaOpsRec = {
168        setup:                          vmeTsi148DmaSetup,
169        start:                          vmeTsi148DmaStart,
170        status:                         vmeTsi148DmaStatus,
171        listClass:                      &vmeTsi148DmaListClass,
172        nChannels:                      2,
173        vectors:                        tsiVecs,
174};
175#endif
176
177static VMEOps theOps    = 0;
178static DmaOps theDmaOps = 0;
179
180int
181BSP_vme2local_adrs(unsigned long am, unsigned long vmeaddr, unsigned long *plocaladdr)
182{
183int rval=theOps->xlate_adrs(1,0,am,vmeaddr,plocaladdr);
184        *plocaladdr+=PCI_MEM_BASE;
185        return rval;
186}
187
188int
189BSP_local2vme_adrs(unsigned long am, unsigned long localaddr, unsigned long *pvmeaddr)
190{
191        return theOps->xlate_adrs(0, 0, am,localaddr+PCI_DRAM_OFFSET,pvmeaddr);
192}
193
194int
195BSP_installVME_isr(unsigned long vector, BSP_VME_ISR_t handler, void *arg)
196{
197        return theOps->install_isr(vector, handler, arg);
198}
199
200int
201BSP_removeVME_isr(unsigned long vector, BSP_VME_ISR_t handler, void *arg)
202{
203        return theOps->remove_isr(vector, handler, arg);
204}
205
206/* retrieve the currently installed ISR for a given vector */
207BSP_VME_ISR_t
208BSP_getVME_isr(unsigned long vector, void **parg)
209{
210        return theOps->get_isr(vector, parg);
211}
212
213int
214BSP_enableVME_int_lvl(unsigned int level)
215{
216        return theOps->enable_int_lvl(level);
217}
218
219int
220BSP_disableVME_int_lvl(unsigned int level)
221{
222        return theOps->disable_int_lvl(level);
223}
224
225int
226BSP_VMEOutboundPortCfg(
227        unsigned long port,
228        unsigned long address_space,
229        unsigned long vme_address,
230        unsigned long pci_address,
231        unsigned long size)
232{
233        return theOps->outbound_p_cfg(port, address_space, vme_address, pci_address, size);
234}
235
236int
237BSP_VMEInboundPortCfg(
238        unsigned long port,
239        unsigned long address_space,
240        unsigned long vme_address,
241        unsigned long pci_address,
242        unsigned long size)
243{
244        return theOps->inbound_p_cfg(port, address_space, vme_address, pci_address, size);
245}
246
247void
248BSP_VMEOutboundPortsShow(FILE *f)
249{
250        theOps->outbound_p_show(f);
251}
252
253void
254BSP_VMEInboundPortsShow(FILE *f)
255{
256        theOps->inbound_p_show(f);
257}
258
259int
260BSP_VMEDmaSetup(int channel, uint32_t bus_mode, uint32_t xfer_mode, void *custom_setup)
261{
262        return theDmaOps->setup(channel, bus_mode, xfer_mode, custom_setup);
263}
264
265int
266BSP_VMEDmaStart(int channel, uint32_t pci_addr, uint32_t vme_addr, uint32_t n_bytes)
267{
268        return theDmaOps->start(channel, pci_addr, vme_addr, n_bytes);
269}
270
271uint32_t
272BSP_VMEDmaStatus(int channel)
273{
274        return theDmaOps->status(channel);
275}
276
277BSP_VMEDmaListDescriptor
278BSP_VMEDmaListDescriptorSetup(
279                BSP_VMEDmaListDescriptor d,
280                uint32_t                 attr_mask,
281                uint32_t                                 xfer_mode,
282                uint32_t                 pci_addr,
283                uint32_t                 vme_addr,
284                uint32_t                 n_bytes)
285{
286VMEDmaListClass pc;
287
288        if ( !d ) {
289
290                pc = theDmaOps->listClass;
291
292                return BSP_VMEDmaListDescriptorNewTool(
293                                        pc,
294                                        attr_mask,
295                                        xfer_mode,
296                                        pci_addr,
297                                        vme_addr,
298                                        n_bytes);
299                                       
300        }
301
302        return BSP_VMEDmaListDescriptorSetupTool(d, attr_mask, xfer_mode, pci_addr, vme_addr, n_bytes);
303}
304
305int
306BSP_VMEDmaListStart(int channel, BSP_VMEDmaListDescriptor list)
307{
308        return BSP_VMEDmaListDescriptorStartTool(0, channel, list);
309}
310
311/* NOT thread safe! */
312int
313BSP_VMEDmaInstallISR(int channel, BSP_VMEDmaIRQCallback cb, void *usr_arg)
314{
315int vec;
316BSP_VME_ISR_t curr;
317void          *carg;
318
319        if ( channel < 0 || channel >= theDmaOps->nChannels )
320                return -1;
321
322        vec = theDmaOps->vectors[channel];
323
324        curr = BSP_getVME_isr(vec, &carg);
325
326        if ( cb && curr ) {
327                /* IRQ currently in use */
328                return -1;
329        }
330
331        if ( !cb && !curr ) {
332                /* Allow uninstall if no handler is currently installed;
333                 * just make sure IRQ is disabled
334                 */
335                BSP_disableVME_int_lvl(vec);
336                return 0;
337        }
338       
339        if ( cb ) {
340                if ( BSP_installVME_isr(vec, (BSP_VME_ISR_t)cb, usr_arg) )
341                        return -4;
342                BSP_enableVME_int_lvl(vec);
343        } else {
344                BSP_disableVME_int_lvl(vec);
345                if ( BSP_removeVME_isr(vec, curr, carg) )
346                        return -4;
347        }
348        return 0;
349}
350
351#if defined(_VME_DRIVER_TSI148) && !defined(VME_CLEAR_BRIDGE_ERRORS)
352static unsigned short
353tsi_clear_errors(int quiet)
354{
355unsigned long   v;
356unsigned short  rval;
357        v = vmeTsi148ClearVMEBusErrors(0);
358
359        /* return bits 8..23 of VEAT; set bit 15 to make sure rval is nonzero on error */
360        rval =  v ? ((v>>8) & 0xffff) | (1<<15) : 0;
361        return rval;
362}
363
364#define VME_CLEAR_BRIDGE_ERRORS tsi_clear_errors
365#endif
366
367int BSP_VMEInit()
368{
369#if defined(_VME_DRIVER_UNIVERSE)
370  if ( 0 == vmeUniverseInit() ) {
371        theOps    = &uniOpsRec;
372        theDmaOps = &uniDmaOpsRec;
373        vmeUniverseReset();
374  }
375#endif
376#if defined(_VME_DRIVER_UNIVERSE) && defined(_VME_DRIVER_TSI148)
377        else
378#endif
379#if defined(_VME_DRIVER_TSI148)
380  if ( 0 == vmeTsi148Init() ) {
381        theOps    = &tsiOpsRec;
382        theDmaOps = &tsiDmaOpsRec;
383        vmeTsi148Reset();
384#ifdef VME_CLEAR_BRIDGE_ERRORS
385        {
386        extern unsigned short (*_BSP_clear_vmebridge_errors)();
387
388          _BSP_clear_vmebridge_errors = VME_CLEAR_BRIDGE_ERRORS;
389
390        }
391#endif
392  }
393#endif
394    else
395          /*  maybe no VME at all - or no universe/tsi148 ... */
396          return -1;
397
398  return 0;
399}
400
401int BSP_VMEIrqMgrInstall()
402{
403int err;
404#ifndef BSP_VME_INSTALL_IRQ_MGR
405  /* No map; use first line only and obtain PIC wire from PCI config */
406  err = theOps->install_irq_mgr(
407        theOps->irq_mgr_flags, /* use shared IRQs */
408        0, -1,  /* Universe/Tsi148 pin0 -> PIC line from config space */
409        -1      /* terminate list  */
410  );
411#else
412  BSP_VME_INSTALL_IRQ_MGR(err);
413#endif
414
415  if ( err )
416        return err;
417
418/* This feature is only supported by the Universe driver (not Tsi148) */
419#if defined(BSP_PCI_VME_DRIVER_DOES_EOI) && defined(BSP_PIC_DO_EOI)
420#ifdef  _VME_DRIVER_TSI148
421#error  "BSP_PCI_VME_DRIVER_DOES_EOI/BSP_PIC_DO_EOI feature can only be used with vmeUniverse"
422#endif
423  if ( vmeUniverse0PciIrqLine < 0 )
424        BSP_panic("Unable to get universe interrupt line info from PCI config");
425  _BSP_vme_bridge_irq = vmeUniverse0PciIrqLine;
426#endif
427  return 0;
428}
Note: See TracBrowser for help on using the repository browser.