Skip to content

Commit 624686a

Browse files
committed
- Allow pci read/writes during proving BAR's size operation (fixes a read/write of 0xFFFFFF.. memory addresses).
svn path=/branches/olpc/; revision=28448
1 parent b7f3741 commit 624686a

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

hal/halx86/generic/olpcpci.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ static ULONG ff_loc = ~0;
172172
static ULONG zero_loc = 0;
173173

174174
static int bar_probing = 0; /* Set after a write of ~0 to a BAR */
175+
static ULONG bar_offset = 0; /* what bar */
175176

176177
static ULONG *hdr_addr(const ULONG *hdr, int reg)
177178
{
@@ -188,15 +189,24 @@ static ULONG *hdr_addr(const ULONG *hdr, int reg)
188189
* BAR0), and don't skip the size mask area.
189190
*/
190191

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+
}
192203

193204
if ( ((ULONG)addr - (ULONG)hdr) >= 0x90 )
194205
{
195206
DPRINT1("WARNING: out of bounds access: 0x%x, bar_probing %d, offset 0x%x\n",
196207
(ULONG)addr - (ULONG)hdr, bar_probing, reg);
197208
}
198209

199-
bar_probing = 0;
200210
return (ULONG *)addr;
201211
}
202212

@@ -261,7 +271,7 @@ pci_olpc_read(ULONG bus, PCI_SLOT_NUMBER devfn, ULONG reg, ULONG len, PUCHAR val
261271
}
262272
}
263273

264-
ASSERT(len == 1 || len == 2 || len == 4)
274+
ASSERT(len == 1 || len == 2 || len == 4);
265275
RtlCopyMemory(value, addr, len);
266276
}
267277

@@ -274,21 +284,27 @@ pci_olpc_write(ULONG bus, PCI_SLOT_NUMBER devfn, ULONG reg, ULONG len, PUCHAR va
274284
* Mostly we just discard writes, but if the write is a size probe
275285
* (i.e. writing ~0 to a BAR), we remember it and arrange to return
276286
* 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.
279289
*/
280290

281291
if ((reg >= 0x10) && (reg < 0x2c)) {
282292
/* Write is to a BAR */
283293
if (*(PULONG)value == ~0)
294+
{
295+
//DbgPrint("OLPC PCI: Probing bar size, devfn %x, reg %x\n", devfn.u.AsULONG, reg);
284296
bar_probing = 1;
297+
bar_offset = reg;
298+
}
285299
} else {
286300
/*
287301
* No warning on writes to ROM BAR, CMD, LATENCY_TIMER,
288302
* CACHE_LINE_SIZE, or PM registers.
289303
*/
290304
if ((reg != 0x30) && (reg != 0x04) && (reg != 0x0d) &&
291305
(reg != 0x0c) && (reg != 0x44))
306+
{
292307
DbgPrint("OLPC PCI: Config write to devfn %x reg %x value %x\n", devfn, reg, *value);
308+
}
293309
}
294310
}

0 commit comments

Comments
 (0)