summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/sparc/shared/spw/grspw_pci.c
blob: fce2fa8b368ebf5e5e7a14b64591903603201078 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <ambapp.h>
#include <rtems/libio.h>
#include <grspw_pci.h>

/* Select PCI driver */
#define GRSPW_PCI

#undef GRSPW_MAXDEVS
#undef DEBUG_SPACEWIRE_ONOFF

/* Only Malloced memory supported
 */
#undef GRSPW_LOCAL_MEM

/* memory must be aligned to a 128k boundary */
unsigned int grspwpci_memarea_address;
#define GRSPW_LOCAL_MEM_ADR grspwpci_memarea_address

/* We have custom address tranlation for HW addresses */
#define GRSPW_ADR_TO

/* MEMAREA=>CPU used when reading descriptor buffer pointers,
 * they need to be translated from adresses used by GRSPW HW
 * into CPU readable addresses.
 *
 * NOT NEEDED AS GRSPW DRIVER USES INDEXES TO GET DESCRIPTOR
 * DATA POINTER ADDRESSES.
 */
#undef GRSPW_ADR_FROM

/* Set registered device name */
#define GRSPW_DEVNAME "/dev/grspwpci0"
#define GRSPW_DEVNAME_NO(devstr,no) ((devstr)[13]='0'+(no))

/* Any non-static function will begin with */
#define GRSPW_PREFIX(name) grspwpci##name

/* do nothing, assume that the interrupt handler is called
 * setup externally calling b1553_interrupt_handler.
 */
#define GRSPW_REG_INT(handler,irq,arg) \
 if ( grspw_pci_int_reg ) \
   grspw_pci_int_reg(handler,irq,arg);

void (*grspw_pci_int_reg)(void *handler, int irq, void *arg) = 0;


#ifdef GRSPW_ADR_TO
/* Translate an address within the Memory Region (memarea) into an Hardware
 * device address. This address is put into hardware registers or descriptors
 * so that the hardware can access the Memory Region.
 * Example:
 * A local AMBA access at 0xe0000000 will translate into PCI address 0x40000000,
 * the PCI address 0x40000000 will translate into LEON-AMBA address 0x40000000.
 */
unsigned int grspwpci_hw_address;
static inline unsigned int memarea_to_hw(unsigned int addr) {
		/* don't translate? */
		if ( grspwpci_hw_address == 0xffffffff )
			return addr;
    return ((addr & 0x0fffffff) | grspwpci_hw_address);
}
#endif

/* not used since BRM Core work with offsets */
#ifdef GRSPW_ADR_FROM
unsigned int grspwpci_cpu_access_address;
static inline unsigned int hw_to_cpu(unsigned int addr) {
		/* don't translate? */
		if ( grspwpci_cpu_address == 0xffffffff )
			return addr;
    return ((addr & 0x0fffffff) | grspwpci_cpu_address);
}
#endif

int grspwpci_interrupt_handler(int irq, void *arg);

#include "grspw.c"

/*
 *
 * memarea     = preallocated memory somewhere, pointer to start of memory.
 * hw_address  = how to translate a memarea address into an HW device AMBA address.
 */

int grspw_pci_register(
 struct ambapp_bus *bus,
 unsigned int memarea,
 unsigned int hw_address
 )
{
	/* Setup configuration */

	/* if zero the malloc will be used */
	grspwpci_memarea_address = memarea;

	grspwpci_hw_address = hw_address;

#ifdef GRSPW_ADR_FROM
	grspwpci_cpu_address = memarea & 0xf0000000;
#endif

	/* Register the driver */
	return GRSPW_PREFIX(_register)(bus);
}

/* Call this from PCI interrupt handler
 * irq = the irq number of the HW device local to that IRQMP controller
 *
 */
int grspwpci_interrupt_handler(int irq, void *arg){
	grspw_interrupt( (GRSPW_DEV *)arg );
  return 0;
}

#if 0
int grspw_pci_interrupt_handler(int irqmask){
	int i;
	unsigned int mask=0;
	/* find minor */
	for(i=0; i<spw_cores; i++){
		if ( (1<<SPW_PARAM(i).irq) & irqmask ){
			mask |= 1<<SPW_PARAM(i).irq;
			grspw_interrupt(i);
			/* more interrupts to scan for? */
			if ( irqmask & ~mask )
				return mask; /* handled */
		}
	}
	return mask;
}
#endif