-
Notifications
You must be signed in to change notification settings - Fork 1
/
README.memProbeAndPCI
153 lines (123 loc) · 5.75 KB
/
README.memProbeAndPCI
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
NOTE ABOUT MEMORY PROBING AND PCI CONFIGURATION SPACE SCANNING
--------------------------------------------------------------
Memory probing installs an exception handler to
catch machine check and data access exceptions
during a probe operation. Therefore, it runs
with the MCP interrupt enabled.
Note that this most likely raises exceptions
when trying to read from PCI configuration
space at unused slots (e.g. when scanning config
space for a particular device). Applications
which need both, memory probing (mostly used by
VME drivers) AND PCI config space scanning should
scan PCI once, prior to initializing libBspExt
and cache the vendor/deviceids found (e.g. as
done by my SVGM BSP).
PCI drivers loaded after initialization of memory
probing should then scan the cached info for
their device to avoid raising exceptions.
This is a better approach than using memory probing
on PCI config space due to the high overhead and
latency of memory probing.
Till Straumann, <strauman@slac.stanford.edu>, 2003/7
Here's more info -- answering a question (2004/11/3)
Eric Norum wrote:
> Here's a snippet of code from the SIS 3301 transient recorder driver:
>
> if(devReadProbe(4,a32+MODID,&probeValue)!=0) {
> printf("sisfadcConfig: no card at %p\n",a32);
> return(0);
> }
>
> MODID is defined to be 0x4.
>
> When this is run with a32=0x21000000, but with no VME device at location
> 0x21000000 I would expect the printf shown above to be executed.
> Instead the devReadProbe returns 0 and sets probeValue to -1.
>
> All this PCI/VME mapping
Boards with a tundra universe bridge usually access VME
from the CPU local bus (powerpc bus) traversing one or more PCI
busses. As each of these busses constitutes a separate address
space (VME itself featuring multiple address spaces..,),
a VME address must be translated into a CPU address.
The address to be used with devReadProbe() is a CPU address, hence
given a VME address you need to compute the correct CPU address
first (which is what devRegisterAddress() does).
devLibOSD.c [RTEMS] relies on the BSP to provide a routine or
macro 'BSP_vme2local_adrs()' for this translation [since managing
address spaces across busses is clearly a BSP area].
Kate, can you confirm that 0x21000000 is within the CPU
address range your BSP assigns to VME ? [looks a little fishy
to me, since on a CHRP board, 0x21000000 is not in the
PCI range]
E.g., on the SVGM, I map VME A32 0x20000000..0x2f000000 to
0xc0000000..0xcf000000 on PCI and the host bridge translates
this 1:1 (CHRP) to CPU space. Hence, I'd address
0x21000000 [VME A32] at 0xc1000000 [CPU]. The respective
translation is performed by svgm's BSP_vme2local_adrs().
> and probing is a mystery to me so please let me
> know if I'm doing something wrong.......
Probing an address is not quite trivial. This is also
why it is *NEVER* a good idea to use the 'probe' routine
for regular access to the device (as e.g., done by the
Hytec 'hotswap' drivers). In order to detect possible
misuse of the probe routines, libbspExt prints a warning
message about 'killing real-time performance'.
Write-probing an address is more difficult than read probing
because on some busses, writing data may be only loosely
coupled to the CPU side, i.e., an eventual bus error may
be raised long after the CPU posted the write operation
and is already executing in a different context.
Read-probing, OTOH must always wait for the read operation
to complete on the target bus and is therefore much more
predictable. libbspExt only implements read probing.
The actual probing algorithm has to deal with a variety of
scenarios that could go wrong when trying to read an address:
1) No mapping in MMU
2) Protection violation ["e.g., no read access in user mode"]
3) bus error [PPC, PCI, VME]
In 1 and 2, no address is ever generated by the CPU. Instead,
an exception is raised by the CPU and is properly handled
by libbspExt() itself.
3) is more involved: the CPU generates an address but the
read operation can fail at different levels: at the
host bridge, on the PCI bus or on the VME bus.
libbspExt() relies on the VME bridge somehow propagating
a bus error upstream to the host bridge where is can be
detected [this is a required BSP/board feature - the
universe VME master propagates a VME-BERR to a PCI target
abort which should be detected by the host bridge].
libbspExt() can handle two scenarios when a bus error is
encountered:
A) host bridge detects a bus error and pulls a hardware
line at the CPU (so called MCP or TEA line) which in
turn raises an exception that is properly handled by
libbspExt.
B) host bridge detects a bus error and has status available
in some register but does not generate any sort of interrupt.
libbspExt polls the host bridge after performing the read
operation to detect errors in B) [this requires disabling
interupts and scheduling during the entire probing algorithm!!]
For both scenarios, libbspExt needs a BSP provided routine
('_BSP_clear_hostbridge_errors()') which reports and resets
errors in the host bridge [this routine should catch ALL
errors: invalid address, PCI bus error].
The routine is also responsible for enabling the MCP and/or TEA
interrupts in the host bridge under scenario A.
In particular, the routine MUST report -1 (failure) when libbspExt
asks to enable the interrupts. This way, libbspExt knows
that it has to resort to scenario B.
A small fix to 'memProbe.c' is needed to properly handle
boards which don't support MCP/TEA interrupts (latest
version attached).
T.
>
> The actual printout is:
> drvSISfadcConfigure(5,80,0x21000000,0x88,3,0)
> Warning: bspExtMemProbe kills real-time performance.
> use only during driver initialization
>
> clear the 'bspExtVerbosity' variable to silence this warning
> Illegal sisType probeValue ffffffff
>