Mail Archives: djgpp/1998/10/09/12:33:12
From: | waa AT codex DOT cis DOT upenn DOT edu (William A. Arbaugh)
|
Newsgroups: | comp.os.msdos.djgpp
|
Subject: | Mapping a PCI Expansion ROM - Problems
|
Date: | 9 Oct 1998 16:24:45 GMT
|
Organization: | University of Pennsylvania
|
Lines: | 93
|
Message-ID: | <6vldcd$2vo$1@netnews.upenn.edu>
|
NNTP-Posting-Host: | codex.cis.upenn.edu
|
X-Newsreader: | TIN [version 1.2 PL2-upenn1.3]
|
To: | djgpp AT delorie DOT com
|
DJ-Gateway: | from newsgroup comp.os.msdos.djgpp
|
Reply-To: | djgpp AT delorie DOT com
|
I have a real mode program written in MASM that maps in the expansion ROM
of a PCI card. It works fine. I've tried to convert that program into a
C version using DJGPP for a number of reasons. Unfortunately, when I map
the address into a high address I get a SEGV. I assume because there is
no memory there (I am using near ptrs BTW). When I map the ROM low
(0x70000), I don't get the SEGV but the ROM isn't mapped either. I'm
very confused as to why this isn't working. I've attached some code
below that tries to do the mapping. Any and all help is greatly appreciated.
Thanks, Bill
I have included nearptr.h and pc.h. The IO port commands are macros for
the DJGPP versions.
void
Map(struct pci_config_reg *pcr)
{
unsigned long ulConfigCmd;
unsigned long ulPrevROM = pcr->_baserom;
unsigned long ulMapAddr;
unsigned char *pucMemAddr;
// The steps performed here are taken from PCI Hardware
// and Software Architecture and Design by Solari and Willse:
// ISBN 0-929392-32-9. I indicate the page number where appropriate.
// The original code incorrectly determines the baserom address.
// The value found above could be the uncleared value SET by the
// BIOS rather than the actual valid range. We do it right, p. 723.
ulConfigCmd = PCI_EN | (pcr->_pcibuses[pcr->_pcibusidx]<<16) |
(pcr->_cardnum<<11);
PCIWriteDWORD(ulConfigCmd | 0x30, 0xFFFFFFFE); // step 1a, p.723
pcr->_baserom = inl(PCI_DATA); // 1b
if (pcr->_baserom == 0) { // 1c
printf("Error: Base ROM not really supported\n");
return;
}
// We'll just use the baserom given since nothing in DOS should be
// up there anyway. Begin by enabling the memory space
// bit of the command register (b1 of offset 4). step 3, p. 723
PCIWriteDWORD(ulConfigCmd | 0x04, pcr->_status_command | 2); // write it out
// with b1 set
// Now enable the expansion ROM address decode enable bit.
// b0 offset 0x30, step 4, p. 724.
PCIWriteDWORD(ulConfigCmd | 0x30, 0x70001);
// CHECK TO SEE IF THINGS ARE SET UP PROPERLY
outl(PCI_INDEX, ulConfigCmd | 0x04); ulMapAddr = inl(PCI_DATA);
printf ("Status command is 0x%08X\n", ulMapAddr);
outl(PCI_INDEX, ulConfigCmd | 0x30); ulMapAddr = inl(PCI_DATA);
printf ("Base is 0x%08X\n", ulMapAddr);
// Now check to ensure the mapping worked correctly.
// First we need to enable the proper segment selector limit (4GB).
if (__djgpp_nearptr_enable() == 0) {
// This isn't likely to happen.
printf("DJGPP ERROR setting data segment selector offset\n");
return;
}
// Now look for the ROM id 0xAA55
pucMemAddr = (unsigned char *)0x70000 + __djgpp_conventional_base;
if (*((unsigned short *)pucMemAddr) == 0xAA55) {
printf ("ROM mapped correctly.\n");
} else {
printf ("ROM mapped incorrectly.\n");
}
__djgpp_nearptr_disable();
// Disable the ROM decode by writing the old baserom
// Base address register (offset 0x30), step 14 p. 725.
PCIWriteDWORD(ulConfigCmd | 0x30, pcr->_baserom); // ROM unmapped
PCIWriteDWORD(ulConfigCmd | 0x4, pcr->_status_command);
return;
}
--
-----------------------------------------------------------------------
Bill Arbaugh
email: waa AT dsl DOT cis DOT upenn DOT edu
-----------------------------------------------------------------------
- Raw text -