@@ -172,6 +172,7 @@ static ULONG ff_loc = ~0;
172
172
static ULONG zero_loc = 0 ;
173
173
174
174
static int bar_probing = 0 ; /* Set after a write of ~0 to a BAR */
175
+ static ULONG bar_offset = 0 ; /* what bar */
175
176
176
177
static ULONG * hdr_addr (const ULONG * hdr , int reg )
177
178
{
@@ -188,15 +189,24 @@ static ULONG *hdr_addr(const ULONG *hdr, int reg)
188
189
* BAR0), and don't skip the size mask area.
189
190
*/
190
191
191
- addr = (ULONG )hdr + reg + (bar_probing ? -0x10 : 0x20 );
192
+ if (bar_probing && (bar_offset == reg ))
193
+ {
194
+ addr = (ULONG )hdr + reg + (bar_probing ? -0x10 : 0x20 );
195
+
196
+ /* Reset probing for this bar */
197
+ bar_probing = 0 ;
198
+ }
199
+ else
200
+ {
201
+ addr = (ULONG )hdr + reg + 0x20 ;
202
+ }
192
203
193
204
if ( ((ULONG )addr - (ULONG )hdr ) >= 0x90 )
194
205
{
195
206
DPRINT1 ("WARNING: out of bounds access: 0x%x, bar_probing %d, offset 0x%x\n" ,
196
207
(ULONG )addr - (ULONG )hdr , bar_probing , reg );
197
208
}
198
209
199
- bar_probing = 0 ;
200
210
return (ULONG * )addr ;
201
211
}
202
212
@@ -261,7 +271,7 @@ pci_olpc_read(ULONG bus, PCI_SLOT_NUMBER devfn, ULONG reg, ULONG len, PUCHAR val
261
271
}
262
272
}
263
273
264
- ASSERT (len == 1 || len == 2 || len == 4 )
274
+ ASSERT (len == 1 || len == 2 || len == 4 );
265
275
RtlCopyMemory (value , addr , len );
266
276
}
267
277
@@ -274,21 +284,27 @@ pci_olpc_write(ULONG bus, PCI_SLOT_NUMBER devfn, ULONG reg, ULONG len, PUCHAR va
274
284
* Mostly we just discard writes, but if the write is a size probe
275
285
* (i.e. writing ~0 to a BAR), we remember it and arrange to return
276
286
* the appropriate size mask on the next read. This is cheating
277
- * to some extent, because it depends on the fact that the next
278
- * access after such a write will always be a read to the same BAR .
287
+ * to some extent, but it's possible to do intermediate read/writes
288
+ * when probing BAR's size now .
279
289
*/
280
290
281
291
if ((reg >= 0x10 ) && (reg < 0x2c )) {
282
292
/* Write is to a BAR */
283
293
if (* (PULONG )value == ~0 )
294
+ {
295
+ //DbgPrint("OLPC PCI: Probing bar size, devfn %x, reg %x\n", devfn.u.AsULONG, reg);
284
296
bar_probing = 1 ;
297
+ bar_offset = reg ;
298
+ }
285
299
} else {
286
300
/*
287
301
* No warning on writes to ROM BAR, CMD, LATENCY_TIMER,
288
302
* CACHE_LINE_SIZE, or PM registers.
289
303
*/
290
304
if ((reg != 0x30 ) && (reg != 0x04 ) && (reg != 0x0d ) &&
291
305
(reg != 0x0c ) && (reg != 0x44 ))
306
+ {
292
307
DbgPrint ("OLPC PCI: Config write to devfn %x reg %x value %x\n" , devfn , reg , * value );
308
+ }
293
309
}
294
310
}
0 commit comments