- added PCI ROM init code that copies to shadow RAM and use it for both VGA
and other boot ROMs - define and use PCI constants (patch by Sebastian Herbszt)
This commit is contained in:
parent
e312454851
commit
46d5caa98d
@ -225,6 +225,10 @@
|
||||
|
||||
#define PCI_DEVICES_MAX 64
|
||||
|
||||
#define PCI_CLASS_STORAGE_IDE 0x0101
|
||||
#define PCI_CLASS_DISPLAY_VGA 0x0300
|
||||
#define PCI_CLASS_SYSTEM_PIC 0x0800
|
||||
|
||||
#define PCI_VENDOR_ID 0x00 /* 16 bits */
|
||||
#define PCI_DEVICE_ID 0x02 /* 16 bits */
|
||||
#define PCI_COMMAND 0x04 /* 16 bits */
|
||||
@ -236,6 +240,11 @@
|
||||
#define PCI_MIN_GNT 0x3e /* 8 bits */
|
||||
#define PCI_MAX_LAT 0x3f /* 8 bits */
|
||||
|
||||
#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
|
||||
|
||||
#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
|
||||
#define PCI_ROM_ADDRESS_ENABLE 0x01
|
||||
|
||||
#define PCI_VENDOR_ID_INTEL 0x8086
|
||||
#define PCI_DEVICE_ID_INTEL_82441 0x1237
|
||||
#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
|
||||
|
@ -599,6 +599,7 @@ typedef struct PCIDevice {
|
||||
|
||||
static uint32_t pci_bios_io_addr;
|
||||
static uint32_t pci_bios_mem_addr;
|
||||
static uint32_t pci_bios_rom_start;
|
||||
/* host irqs corresponding to PCI irqs A-D */
|
||||
static uint8_t pci_irqs[4] = { 11, 9, 11, 9 };
|
||||
static PCIDevice i440_pcidev = {-1, -1};
|
||||
@ -645,10 +646,10 @@ static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
|
||||
uint32_t ofs, old_addr;
|
||||
|
||||
if ( region_num == PCI_ROM_SLOT ) {
|
||||
ofs = 0x30;
|
||||
addr |= 0x01;
|
||||
ofs = PCI_ROM_ADDRESS;
|
||||
addr |= PCI_ROM_ADDRESS_ENABLE;
|
||||
}else{
|
||||
ofs = 0x10 + region_num * 4;
|
||||
ofs = PCI_BASE_ADDRESS_0 + region_num * 4;
|
||||
}
|
||||
|
||||
old_addr = pci_config_readl(d, ofs);
|
||||
@ -659,11 +660,11 @@ static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
|
||||
/* enable memory mappings */
|
||||
cmd = pci_config_readw(d, PCI_COMMAND);
|
||||
if ( region_num == PCI_ROM_SLOT )
|
||||
cmd |= 2;
|
||||
cmd |= PCI_COMMAND_MEMORY;
|
||||
else if (old_addr & PCI_ADDRESS_SPACE_IO)
|
||||
cmd |= 1;
|
||||
cmd |= PCI_COMMAND_IO;
|
||||
else
|
||||
cmd |= 2;
|
||||
cmd |= PCI_COMMAND_MEMORY;
|
||||
pci_config_writew(d, PCI_COMMAND, cmd);
|
||||
}
|
||||
|
||||
@ -817,10 +818,55 @@ static void piix4_pm_enable(PCIDevice *d)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void pci_bios_init_pcirom(PCIDevice *d, uint32_t paddr)
|
||||
{
|
||||
PCIDevice d1, *i440fx = &d1;
|
||||
uint32_t tmpaddr, size;
|
||||
uint8_t reg, v;
|
||||
int copied, shift, tmpsize;
|
||||
|
||||
i440fx->bus = 0;
|
||||
i440fx->devfn = 0;
|
||||
if (paddr != 0) {
|
||||
size = readb((void *)(paddr + 2));
|
||||
if (size & 0x03) {
|
||||
size &= 0xfc;
|
||||
size += 0x04;
|
||||
}
|
||||
size <<= 9;
|
||||
if ((pci_bios_rom_start + size) > 0xe0000)
|
||||
return;
|
||||
tmpaddr = pci_bios_rom_start;
|
||||
copied = 0;
|
||||
do {
|
||||
tmpsize = 0x4000 - (tmpaddr & 0x3fff);
|
||||
if ((size - copied) < tmpsize) {
|
||||
tmpsize = size;
|
||||
}
|
||||
reg = 0x5a + (uint8_t)((tmpaddr >> 15) & 0x07);
|
||||
if (tmpaddr & 0x4000) {
|
||||
shift = 4;
|
||||
} else {
|
||||
shift = 0;
|
||||
}
|
||||
v = pci_config_readb(i440fx, reg);
|
||||
v = (v & (~(0x03 << shift))) | (0x02 << shift);
|
||||
pci_config_writeb(i440fx, reg, v);
|
||||
memcpy((void *)tmpaddr, (void *)(paddr + copied), tmpsize);
|
||||
v = (v & (~(0x03 << shift))) | (0x01 << shift);
|
||||
pci_config_writeb(i440fx, reg, v);
|
||||
tmpaddr += tmpsize;
|
||||
copied += tmpsize;
|
||||
} while (copied < size);
|
||||
BX_INFO("PCI ROM copied to 0x%05x (size=0x%05x)\n", pci_bios_rom_start, size);
|
||||
pci_bios_rom_start += size;
|
||||
}
|
||||
}
|
||||
|
||||
static void pci_bios_init_device(PCIDevice *d)
|
||||
{
|
||||
PCIDevice d1, *i440fx = &d1;
|
||||
int class, v;
|
||||
uint16_t class;
|
||||
uint32_t *paddr;
|
||||
int i, pin, pic_irq, vendor_id, device_id;
|
||||
|
||||
@ -832,7 +878,7 @@ static void pci_bios_init_device(PCIDevice *d)
|
||||
BX_INFO("PCI: bus=%d devfn=0x%02x: vendor_id=0x%04x device_id=0x%04x class=0x%04x\n",
|
||||
d->bus, d->devfn, vendor_id, device_id, class);
|
||||
switch(class) {
|
||||
case 0x0101: /* Mass storage controller - IDE interface */
|
||||
case PCI_CLASS_STORAGE_IDE:
|
||||
if (vendor_id == PCI_VENDOR_ID_INTEL &&
|
||||
(device_id == PCI_DEVICE_ID_INTEL_82371SB_1 ||
|
||||
device_id == PCI_DEVICE_ID_INTEL_82371AB)) {
|
||||
@ -848,7 +894,7 @@ static void pci_bios_init_device(PCIDevice *d)
|
||||
pci_set_io_region_addr(d, 3, 0x374);
|
||||
}
|
||||
break;
|
||||
case 0x0800: /* Generic system peripheral - PIC */
|
||||
case PCI_CLASS_SYSTEM_PIC:
|
||||
if (vendor_id == PCI_VENDOR_ID_IBM) {
|
||||
/* IBM */
|
||||
if (device_id == 0x0046 || device_id == 0xFFFF) {
|
||||
@ -872,10 +918,10 @@ static void pci_bios_init_device(PCIDevice *d)
|
||||
uint32_t val, size ;
|
||||
|
||||
if (i == PCI_ROM_SLOT) {
|
||||
ofs = 0x30;
|
||||
ofs = PCI_ROM_ADDRESS;
|
||||
pci_config_writel(d, ofs, 0xfffffffe);
|
||||
} else {
|
||||
ofs = 0x10 + i * 4;
|
||||
ofs = PCI_BASE_ADDRESS_0 + i * 4;
|
||||
pci_config_writel(d, ofs, 0xffffffff);
|
||||
}
|
||||
val = pci_config_readl(d, ofs);
|
||||
@ -887,21 +933,8 @@ static void pci_bios_init_device(PCIDevice *d)
|
||||
paddr = &pci_bios_mem_addr;
|
||||
*paddr = (*paddr + size - 1) & ~(size - 1);
|
||||
pci_set_io_region_addr(d, i, *paddr);
|
||||
if ((i == PCI_ROM_SLOT) && (class == 0x0300)) {
|
||||
v = pci_config_readb(i440fx, 0x5a);
|
||||
v = (v & 0xcc) | 0x22;
|
||||
pci_config_writeb(i440fx, 0x5a, v);
|
||||
memcpy((void *)0xc0000, (void *)*paddr, 0x8000);
|
||||
v = (v & 0xcc) | 0x11;
|
||||
pci_config_writeb(i440fx, 0x5a, v);
|
||||
if (size > 0x8000) {
|
||||
v = pci_config_readb(i440fx, 0x5b);
|
||||
v = (v & 0xcc) | 0x22;
|
||||
pci_config_writeb(i440fx, 0x5b, v);
|
||||
memcpy((void *)0xc8000, (void *)(*paddr + 0x8000), size - 0x8000);
|
||||
v = (v & 0xcc) | 0x11;
|
||||
pci_config_writeb(i440fx, 0x5b, v);
|
||||
}
|
||||
if ((i == PCI_ROM_SLOT) && (class == PCI_CLASS_DISPLAY_VGA)) {
|
||||
pci_bios_init_pcirom(d, *paddr);
|
||||
}
|
||||
*paddr += size;
|
||||
}
|
||||
@ -929,6 +962,18 @@ static void pci_bios_init_device(PCIDevice *d)
|
||||
}
|
||||
}
|
||||
|
||||
static void pci_bios_init_optrom(PCIDevice *d)
|
||||
{
|
||||
uint32_t paddr;
|
||||
uint16_t class;
|
||||
|
||||
class = pci_config_readw(d, PCI_CLASS_DEVICE);
|
||||
if (class != PCI_CLASS_DISPLAY_VGA) {
|
||||
paddr = pci_config_readl(d, PCI_ROM_ADDRESS) & 0xfffffc00;
|
||||
pci_bios_init_pcirom(d, paddr);
|
||||
}
|
||||
}
|
||||
|
||||
void pci_for_each_device(void (*init_func)(PCIDevice *d))
|
||||
{
|
||||
PCIDevice d1, *d = &d1;
|
||||
@ -952,10 +997,13 @@ void pci_bios_init(void)
|
||||
{
|
||||
pci_bios_io_addr = 0xc000;
|
||||
pci_bios_mem_addr = 0xc0000000;
|
||||
pci_bios_rom_start = 0xc0000;
|
||||
|
||||
pci_for_each_device(pci_bios_init_bridges);
|
||||
|
||||
pci_for_each_device(pci_bios_init_device);
|
||||
|
||||
pci_for_each_device(pci_bios_init_optrom);
|
||||
}
|
||||
|
||||
/****************************************************/
|
||||
|
Loading…
x
Reference in New Issue
Block a user