This cf8/cfc case is one where I wouldn’t hesitate demanding from hardware
manufacturers that violations of the state machine are thrown out on first
sight. If the chip is in the cfc state, throwing an i/o to its port cf8
should generate a handle-me-better-or-leave-me-alone interrupt. Or maybe
this is a case of actually using Peterson’s algorithm ?
Also, within the same processor, it’s a simple matter to use a
cli-cf8-cfc-sti sequence. Actually, that would have been one of the purposes
of the rep outs instruction, but alas, they allow interrupts within repeated
string instructions. They made an exception for the load ss/load esp
sequence, why can’t they make the same exception to two back-to-back in or
out instructions ? Imagine how uncool it would be to have to bracket an
lss/move-to-esp sequence with a call to an OS Spinlock API.
This would leave us only with the SMP issue to solve. Maybe someone should
get the PCI Sig to give us a mechanism that’s friendlier to multiprocessors
?
But I’m not sure whether the presence of a spinlock API is a deterrent to
ill behavior.
Alberto.
-----Original Message-----
From: Jake Oshins [mailto:xxxxx@windows.microsoft.com]
Sent: Wednesday, January 30, 2002 12:16 AM
To: NT Developers Interest List
Subject: [ntdev] RE: Reading PCI Registers
As others have pointed out, I skimmed over the fact that the original
question was about how to read PCI config space from DOS. But this has
brought the conversation back around to NT.
A test-and-set instruction doesn’t help you when access to the entire
PCI config space is through an indexed-pair port mechanism. In order to
read or write data from a device, you write the bus number, device
number, function number, offset and an enable bit to port 0xcf8. Then
you read or write a DWORD to port 0xcfc.
The problem here is that the address you write to 0xcf8 may be replaced
by another address before you do your read or write to 0xcfc by another
thread, an ISR, a DPC or the SMI BIOS. If it is replaced by another
address, then you’ll end up either reading the wrong data or clobbering
somebody else’s stuff.
The OS has a spinlock, which it takes whenever you call the APIs. That
protects you against everything except the SMI BIOS. The SMI BIOS, if
it’s written correctly, shoots down all processors and then reads the
contents of 0xcf8, when it restores before it releases the processors.
This works, modulo a few thousand bugs.
Also, while a driver certainly owns the hardware it drives, in the WDM
world, the underlying PCI bus driver is the entity that owns almost all
of the common config header.
-----Original Message-----
Subject: RE: Reading PCI Registers
From: “Moreira, Alberto”
Date: Tue, 29 Jan 2002 10:10:38 -0500
X-Message-Number: 22
The architecture has test and set instructions for that reason. If we’re
running at the lowest level and we need to talk to the hardware,
sometimes
it’s easier, more expedient, and even safer, to talk directly to the
hardware and not rely on OS mechanisms.
And I thought a driver was supposed to own the hardware it drives ?
Alberto.
-----Original Message-----
From: Jake Oshins [mailto:xxxxx@windows.microsoft.com]
Sent: Tuesday, January 29, 2002 1:53 AM
To: NT Developers Interest List
Subject: [ntdev] RE: Reading PCI Registers
If you go directly to the ports, then you’ll be bypassing the
OS-internal spinlock that guards them. This may cause (and, in many
cases, has caused) random data to be read or written from the PCI bus.
This can crash the machine and/or cause other random undefined behavior.
That’s why there are perfectly good mechansims for reading and writing
PCI config space built into the OS, which do take the spinlock before
any access. If you’re writing a WDM-compliant driver, then look into
using BUS_INTERFACE_STANDARD. If you’re writing a driver that has to
run on NT4, then use HalGet/SetBusData, or the miniport equivalent
versions of those.
If you just want to look at these things in the debugger, then use !pci.
The whole thread worries me a bit, though. There is a USB driver that
thinks it owns the ports that your grovelling around in. Again, you’ll
crash the machine if you try to use hardware that’s currently being
controlled by another driver.
- Jake
—
You are currently subscribed to ntdev as: xxxxx@compuware.com
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
—
You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com