2 pcboot - bootable PC demo/game kernel
3 Copyright (C) 2018 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY, without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
26 #define CONFIG_ADDR_PORT 0xcf8
27 #define CONFIG_DATA_PORT 0xcfc
29 #define ADDR_ENABLE 0x80000000
30 #define ADDR_BUSID(x) (((uint32_t)(x) & 0xff) << 16)
31 #define ADDR_DEVID(x) (((uint32_t)(x) & 0x1f) << 11)
32 #define ADDR_FUNC(x) (((uint32_t)(x) & 3) << 8)
34 /* signature returned in edx by the PCI BIOS present function: FOURCC "PCI " */
35 #define PCI_SIG 0x20494350
37 static uint16_t cfg_read32_acc1(int bus, int dev, int func, int reg);
38 static uint16_t cfg_read32_acc2(int bus, int dev, int func, int reg);
40 static uint16_t (*cfg_read32)(int, int, int, int);
44 struct int86regs regs;
46 memset(®s, 0, sizeof regs);
50 /* PCI BIOS present if CF=0, AH=0, and EDX has the "PCI " sig FOURCC */
51 if((regs.flags & FLAGS_CARRY) || (regs.eax & 0xff00) || regs.edx != PCI_SIG) {
52 printf("No PCI BIOS present\n");
56 printf("PCI BIOS v%x.%x found\n", (regs.ebx & 0xff00) >> 8, regs.ebx & 0xff);
58 cfg_read32 = cfg_read32_acc1;
61 printf("Failed to find supported PCI access mechanism\n");
64 printf("PCI access mechanism #1 unsupported, falling back to mechanism #2\n");
65 cfg_read32 = cfg_read32_acc2;
69 static uint16_t cfg_read32_acc1(int bus, int dev, int func, int reg)
71 uint32_t addr = ADDR_ENABLE | ADDR_BUSID(bus) | ADDR_DEVID(dev) |
72 ADDR_FUNC(func) | reg;
74 outl(addr, CONFIG_ADDR_PORT);
75 return inl(CONFIG_DATA_PORT);
78 static uint16_t cfg_read32_acc2(int bus, int dev, int func, int reg)
80 panic("BUG: PCI access mechanism #2 not implemented yet!");