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 -----------------------------------------------------------------------