Au, I know, I must extract the base address from the returned value, represented by bits 15:7... Sorry.
Andon Tschauschev atschauschev@yahoo.com wrote: Hello,
If there is an operating system running, you should use the PCI enumeration API that the operating system provides. For Linux, look at libpci and/or pciutils.
OK, 0xCFC/0xCF8 is not so suitable, this time I'm using libpci: <start code> #include <stdio.h> #include <pci/pci.h>
int main(void) {
struct pci_access *pacc; struct pci_dev *LPCBridge; u32 pmbase_value, smi_en_offset, smi_sts_offset, smi_en_value, smi_sts_value;
pacc = pci_alloc(); pci_init(pacc);
LPCBridge = pci_get_dev(pacc, 0, 0, 0x1f, 0);
pmbase_value = pci_read_long(LPCBridge, 0x40); printf("Stored value in PMBASE: 0x%08x\n", pmbase_value);
smi_en_offset = pmbase_value + 0x30; smi_sts_offset = pmbase_value + 0x34; printf("Offset to SMI_EN (PMBASE + 0x30): 0x%08x\n", smi_en_offset); printf("Offset to SMI_STS (PMBASE + 0x34): 0x%08x\n", smi_sts_offset);
smi_en_value = pci_read_long(LPCBridge, smi_en_offset); smi_sts_value = pci_read_long(LPCBridge, smi_sts_offset); printf("Value in SMI_EN: 0x%08x\n", smi_en_value); printf("Value in SMI_STS: 0x%08x\n", smi_sts_value);
return 0; } <end code>
Compiling it and executing as root generates the output: <start output> Stored value in PMBASE: 0x00000801 Offset to SMI_EN (PMBASE + 0x30): 0x00000831 Offset to SMI_STS (PMBASE + 0x34): 0x00000835 pcilib: Unaligned read: pos=831, len=4 <end output>
Chipset is ICH3M.
Any suggestions?
Regards
Andon
Peter Stuge stuge-linuxbios@cdy.org wrote: On Mon, May 21, 2007 at 06:18:53AM -0700, Andon Tschauschev wrote:
- Did I understood correctly how this pci mechanism for accessing
registers works? If not, how can I access them?
Yes and no.
- Why does the system crash, since I'm accessing registers only
read-only (except "outl(0xCF8, address)")?
Because the operating system may also be doing PCI accesses and there may be a conflict between your program and the kernel.
Using ports cf8/cfc is one way that PCI registers can be accessed, but it is only suitable if you are certain that you will be the only process using it.
If there is an operating system running, you should use the PCI enumeration API that the operating system provides. For Linux, look at libpci and/or pciutils. The application setpci can be used to peek and poke values in PCI config space.
//Peter