source: rtems/c/src/lib/libbsp/powerpc/shared/vme/vme_universe.c @ 1c193a2

5
Last change on this file since 1c193a2 was 1c193a2, checked in by Sebastian Huber <sebastian.huber@…>, on 11/21/17 at 10:43:13

powerpc: Replace BSP_panic() with rtems_panic()

Due to a new rtems_panic() implementation, it is possible to replace the
PowerPC-specific BSP_panic() with rtems_panic(). Remove BSP_panic()
implementations.

Close #3245.

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