UniNorth PCI bridge support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@955 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
611493d966
commit
f2aa58c6f4
453
hw/pci.c
453
hw/pci.c
@ -45,7 +45,7 @@ typedef struct PCIBridge {
|
|||||||
PCIDevice **pci_bus[256];
|
PCIDevice **pci_bus[256];
|
||||||
} PCIBridge;
|
} PCIBridge;
|
||||||
|
|
||||||
static PCIBridge pci_bridge;
|
static PCIBridge pci_bridge[3];
|
||||||
target_phys_addr_t pci_mem_base;
|
target_phys_addr_t pci_mem_base;
|
||||||
static int pci_irq_index;
|
static int pci_irq_index;
|
||||||
static uint32_t pci_irq_levels[4][PCI_IRQ_WORDS];
|
static uint32_t pci_irq_levels[4][PCI_IRQ_WORDS];
|
||||||
@ -56,7 +56,7 @@ PCIDevice *pci_register_device(const char *name, int instance_size,
|
|||||||
PCIConfigReadFunc *config_read,
|
PCIConfigReadFunc *config_read,
|
||||||
PCIConfigWriteFunc *config_write)
|
PCIConfigWriteFunc *config_write)
|
||||||
{
|
{
|
||||||
PCIBridge *s = &pci_bridge;
|
PCIBridge *s = &pci_bridge[0];
|
||||||
PCIDevice *pci_dev, **bus;
|
PCIDevice *pci_dev, **bus;
|
||||||
|
|
||||||
if (pci_irq_index >= PCI_DEVICES_MAX)
|
if (pci_irq_index >= PCI_DEVICES_MAX)
|
||||||
@ -70,6 +70,10 @@ PCIDevice *pci_register_device(const char *name, int instance_size,
|
|||||||
bus = s->pci_bus[bus_num];
|
bus = s->pci_bus[bus_num];
|
||||||
if (devfn < 0) {
|
if (devfn < 0) {
|
||||||
for(devfn = 0 ; devfn < 256; devfn += 8) {
|
for(devfn = 0 ; devfn < 256; devfn += 8) {
|
||||||
|
#ifdef TARGET_PPC
|
||||||
|
if ((devfn >> 3) < 11)
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
if (!bus[devfn])
|
if (!bus[devfn])
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
@ -425,7 +429,7 @@ static uint32_t pci_data_readl(void* opaque, uint32_t addr)
|
|||||||
|
|
||||||
void i440fx_init(void)
|
void i440fx_init(void)
|
||||||
{
|
{
|
||||||
PCIBridge *s = &pci_bridge;
|
PCIBridge *s = &pci_bridge[0];
|
||||||
PCIDevice *d;
|
PCIDevice *d;
|
||||||
|
|
||||||
register_ioport_write(0xcf8, 4, 4, pci_addr_writel, s);
|
register_ioport_write(0xcf8, 4, 4, pci_addr_writel, s);
|
||||||
@ -604,7 +608,7 @@ static CPUReadMemoryFunc *PPC_PCIIO_read[] = {
|
|||||||
|
|
||||||
void pci_prep_init(void)
|
void pci_prep_init(void)
|
||||||
{
|
{
|
||||||
PCIBridge *s = &pci_bridge;
|
PCIBridge *s = &pci_bridge[0];
|
||||||
PCIDevice *d;
|
PCIDevice *d;
|
||||||
int PPC_io_memory;
|
int PPC_io_memory;
|
||||||
|
|
||||||
@ -629,7 +633,9 @@ void pci_prep_init(void)
|
|||||||
|
|
||||||
/* pmac pci init */
|
/* pmac pci init */
|
||||||
|
|
||||||
static void pci_pmac_config_writel (void *opaque, target_phys_addr_t addr, uint32_t val)
|
/* Grackle PCI host */
|
||||||
|
static void pci_grackle_config_writel (void *opaque, target_phys_addr_t addr,
|
||||||
|
uint32_t val)
|
||||||
{
|
{
|
||||||
PCIBridge *s = opaque;
|
PCIBridge *s = opaque;
|
||||||
#ifdef TARGET_WORDS_BIGENDIAN
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
@ -638,7 +644,7 @@ static void pci_pmac_config_writel (void *opaque, target_phys_addr_t addr, uint3
|
|||||||
s->config_reg = val;
|
s->config_reg = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t pci_pmac_config_readl (void *opaque, target_phys_addr_t addr)
|
static uint32_t pci_grackle_config_readl (void *opaque, target_phys_addr_t addr)
|
||||||
{
|
{
|
||||||
PCIBridge *s = opaque;
|
PCIBridge *s = opaque;
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
@ -650,25 +656,27 @@ static uint32_t pci_pmac_config_readl (void *opaque, target_phys_addr_t addr)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPUWriteMemoryFunc *pci_pmac_config_write[] = {
|
static CPUWriteMemoryFunc *pci_grackle_config_write[] = {
|
||||||
&pci_pmac_config_writel,
|
&pci_grackle_config_writel,
|
||||||
&pci_pmac_config_writel,
|
&pci_grackle_config_writel,
|
||||||
&pci_pmac_config_writel,
|
&pci_grackle_config_writel,
|
||||||
};
|
};
|
||||||
|
|
||||||
static CPUReadMemoryFunc *pci_pmac_config_read[] = {
|
static CPUReadMemoryFunc *pci_grackle_config_read[] = {
|
||||||
&pci_pmac_config_readl,
|
&pci_grackle_config_readl,
|
||||||
&pci_pmac_config_readl,
|
&pci_grackle_config_readl,
|
||||||
&pci_pmac_config_readl,
|
&pci_grackle_config_readl,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pci_pmac_writeb (void *opaque, target_phys_addr_t addr, uint32_t val)
|
static void pci_grackle_writeb (void *opaque, target_phys_addr_t addr,
|
||||||
|
uint32_t val)
|
||||||
{
|
{
|
||||||
PCIBridge *s = opaque;
|
PCIBridge *s = opaque;
|
||||||
pci_data_write(s, addr, val, 1);
|
pci_data_write(s, addr, val, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pci_pmac_writew (void *opaque, target_phys_addr_t addr, uint32_t val)
|
static void pci_grackle_writew (void *opaque, target_phys_addr_t addr,
|
||||||
|
uint32_t val)
|
||||||
{
|
{
|
||||||
PCIBridge *s = opaque;
|
PCIBridge *s = opaque;
|
||||||
#ifdef TARGET_WORDS_BIGENDIAN
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
@ -677,7 +685,8 @@ static void pci_pmac_writew (void *opaque, target_phys_addr_t addr, uint32_t val
|
|||||||
pci_data_write(s, addr, val, 2);
|
pci_data_write(s, addr, val, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pci_pmac_writel (void *opaque, target_phys_addr_t addr, uint32_t val)
|
static void pci_grackle_writel (void *opaque, target_phys_addr_t addr,
|
||||||
|
uint32_t val)
|
||||||
{
|
{
|
||||||
PCIBridge *s = opaque;
|
PCIBridge *s = opaque;
|
||||||
#ifdef TARGET_WORDS_BIGENDIAN
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
@ -686,7 +695,7 @@ static void pci_pmac_writel (void *opaque, target_phys_addr_t addr, uint32_t val
|
|||||||
pci_data_write(s, addr, val, 4);
|
pci_data_write(s, addr, val, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t pci_pmac_readb (void *opaque, target_phys_addr_t addr)
|
static uint32_t pci_grackle_readb (void *opaque, target_phys_addr_t addr)
|
||||||
{
|
{
|
||||||
PCIBridge *s = opaque;
|
PCIBridge *s = opaque;
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
@ -694,7 +703,7 @@ static uint32_t pci_pmac_readb (void *opaque, target_phys_addr_t addr)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t pci_pmac_readw (void *opaque, target_phys_addr_t addr)
|
static uint32_t pci_grackle_readw (void *opaque, target_phys_addr_t addr)
|
||||||
{
|
{
|
||||||
PCIBridge *s = opaque;
|
PCIBridge *s = opaque;
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
@ -705,7 +714,7 @@ static uint32_t pci_pmac_readw (void *opaque, target_phys_addr_t addr)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t pci_pmac_readl (void *opaque, target_phys_addr_t addr)
|
static uint32_t pci_grackle_readl (void *opaque, target_phys_addr_t addr)
|
||||||
{
|
{
|
||||||
PCIBridge *s = opaque;
|
PCIBridge *s = opaque;
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
@ -717,34 +726,367 @@ static uint32_t pci_pmac_readl (void *opaque, target_phys_addr_t addr)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPUWriteMemoryFunc *pci_pmac_write[] = {
|
static CPUWriteMemoryFunc *pci_grackle_write[] = {
|
||||||
&pci_pmac_writeb,
|
&pci_grackle_writeb,
|
||||||
&pci_pmac_writew,
|
&pci_grackle_writew,
|
||||||
&pci_pmac_writel,
|
&pci_grackle_writel,
|
||||||
};
|
};
|
||||||
|
|
||||||
static CPUReadMemoryFunc *pci_pmac_read[] = {
|
static CPUReadMemoryFunc *pci_grackle_read[] = {
|
||||||
&pci_pmac_readb,
|
&pci_grackle_readb,
|
||||||
&pci_pmac_readw,
|
&pci_grackle_readw,
|
||||||
&pci_pmac_readl,
|
&pci_grackle_readl,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Uninorth PCI host (for all Mac99 and newer machines */
|
||||||
|
static void pci_unin_main_config_writel (void *opaque, target_phys_addr_t addr,
|
||||||
|
uint32_t val)
|
||||||
|
{
|
||||||
|
PCIBridge *s = opaque;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap32(val);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (i = 11; i < 32; i++) {
|
||||||
|
if ((val & (1 << i)) != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
s->config_reg = 0x80000000 | (1 << 16) | (val & 0x7FC) | (i << 11);
|
||||||
|
#else
|
||||||
|
s->config_reg = 0x80000000 | (0 << 16) | (val & 0x7FC) | (i << 11);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t pci_unin_main_config_readl (void *opaque,
|
||||||
|
target_phys_addr_t addr)
|
||||||
|
{
|
||||||
|
PCIBridge *s = opaque;
|
||||||
|
uint32_t val;
|
||||||
|
int devfn;
|
||||||
|
|
||||||
|
devfn = (s->config_reg >> 8) & 0xFF;
|
||||||
|
val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap32(val);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CPUWriteMemoryFunc *pci_unin_main_config_write[] = {
|
||||||
|
&pci_unin_main_config_writel,
|
||||||
|
&pci_unin_main_config_writel,
|
||||||
|
&pci_unin_main_config_writel,
|
||||||
|
};
|
||||||
|
|
||||||
|
static CPUReadMemoryFunc *pci_unin_main_config_read[] = {
|
||||||
|
&pci_unin_main_config_readl,
|
||||||
|
&pci_unin_main_config_readl,
|
||||||
|
&pci_unin_main_config_readl,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void pci_unin_main_writeb (void *opaque, target_phys_addr_t addr,
|
||||||
|
uint32_t val)
|
||||||
|
{
|
||||||
|
PCIBridge *s = opaque;
|
||||||
|
pci_data_write(s, addr & 7, val, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pci_unin_main_writew (void *opaque, target_phys_addr_t addr,
|
||||||
|
uint32_t val)
|
||||||
|
{
|
||||||
|
PCIBridge *s = opaque;
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap16(val);
|
||||||
|
#endif
|
||||||
|
pci_data_write(s, addr & 7, val, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pci_unin_main_writel (void *opaque, target_phys_addr_t addr,
|
||||||
|
uint32_t val)
|
||||||
|
{
|
||||||
|
PCIBridge *s = opaque;
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap32(val);
|
||||||
|
#endif
|
||||||
|
pci_data_write(s, addr & 7, val, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t pci_unin_main_readb (void *opaque, target_phys_addr_t addr)
|
||||||
|
{
|
||||||
|
PCIBridge *s = opaque;
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
val = pci_data_read(s, addr & 7, 1);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t pci_unin_main_readw (void *opaque, target_phys_addr_t addr)
|
||||||
|
{
|
||||||
|
PCIBridge *s = opaque;
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
val = pci_data_read(s, addr & 7, 2);
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap16(val);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t pci_unin_main_readl (void *opaque, target_phys_addr_t addr)
|
||||||
|
{
|
||||||
|
PCIBridge *s = opaque;
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
val = pci_data_read(s, addr, 4);
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap32(val);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CPUWriteMemoryFunc *pci_unin_main_write[] = {
|
||||||
|
&pci_unin_main_writeb,
|
||||||
|
&pci_unin_main_writew,
|
||||||
|
&pci_unin_main_writel,
|
||||||
|
};
|
||||||
|
|
||||||
|
static CPUReadMemoryFunc *pci_unin_main_read[] = {
|
||||||
|
&pci_unin_main_readb,
|
||||||
|
&pci_unin_main_readw,
|
||||||
|
&pci_unin_main_readl,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void pci_unin_config_writel (void *opaque, target_phys_addr_t addr,
|
||||||
|
uint32_t val)
|
||||||
|
{
|
||||||
|
PCIBridge *s = opaque;
|
||||||
|
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap32(val);
|
||||||
|
#endif
|
||||||
|
s->config_reg = 0x80000000 | (val & ~0x00000001);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t pci_unin_config_readl (void *opaque,
|
||||||
|
target_phys_addr_t addr)
|
||||||
|
{
|
||||||
|
PCIBridge *s = opaque;
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
val = (s->config_reg | 0x00000001) & ~0x80000000;
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap32(val);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CPUWriteMemoryFunc *pci_unin_config_write[] = {
|
||||||
|
&pci_unin_config_writel,
|
||||||
|
&pci_unin_config_writel,
|
||||||
|
&pci_unin_config_writel,
|
||||||
|
};
|
||||||
|
|
||||||
|
static CPUReadMemoryFunc *pci_unin_config_read[] = {
|
||||||
|
&pci_unin_config_readl,
|
||||||
|
&pci_unin_config_readl,
|
||||||
|
&pci_unin_config_readl,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void pci_unin_writeb (void *opaque, target_phys_addr_t addr,
|
||||||
|
uint32_t val)
|
||||||
|
{
|
||||||
|
PCIBridge *s = opaque;
|
||||||
|
pci_data_write(s, addr & 3, val, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pci_unin_writew (void *opaque, target_phys_addr_t addr,
|
||||||
|
uint32_t val)
|
||||||
|
{
|
||||||
|
PCIBridge *s = opaque;
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap16(val);
|
||||||
|
#endif
|
||||||
|
pci_data_write(s, addr & 3, val, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pci_unin_writel (void *opaque, target_phys_addr_t addr,
|
||||||
|
uint32_t val)
|
||||||
|
{
|
||||||
|
PCIBridge *s = opaque;
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap32(val);
|
||||||
|
#endif
|
||||||
|
pci_data_write(s, addr & 3, val, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t pci_unin_readb (void *opaque, target_phys_addr_t addr)
|
||||||
|
{
|
||||||
|
PCIBridge *s = opaque;
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
val = pci_data_read(s, addr & 3, 1);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t pci_unin_readw (void *opaque, target_phys_addr_t addr)
|
||||||
|
{
|
||||||
|
PCIBridge *s = opaque;
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
val = pci_data_read(s, addr & 3, 2);
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap16(val);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t pci_unin_readl (void *opaque, target_phys_addr_t addr)
|
||||||
|
{
|
||||||
|
PCIBridge *s = opaque;
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
val = pci_data_read(s, addr & 3, 4);
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap32(val);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CPUWriteMemoryFunc *pci_unin_write[] = {
|
||||||
|
&pci_unin_writeb,
|
||||||
|
&pci_unin_writew,
|
||||||
|
&pci_unin_writel,
|
||||||
|
};
|
||||||
|
|
||||||
|
static CPUReadMemoryFunc *pci_unin_read[] = {
|
||||||
|
&pci_unin_readb,
|
||||||
|
&pci_unin_readw,
|
||||||
|
&pci_unin_readl,
|
||||||
};
|
};
|
||||||
|
|
||||||
void pci_pmac_init(void)
|
void pci_pmac_init(void)
|
||||||
{
|
{
|
||||||
PCIBridge *s = &pci_bridge;
|
PCIBridge *s;
|
||||||
PCIDevice *d;
|
PCIDevice *d;
|
||||||
int pci_mem_config, pci_mem_data;
|
int pci_mem_config, pci_mem_data;
|
||||||
|
|
||||||
pci_mem_config = cpu_register_io_memory(0, pci_pmac_config_read,
|
/* Use values found on a real PowerMac */
|
||||||
pci_pmac_config_write, s);
|
/* Uninorth main bus */
|
||||||
pci_mem_data = cpu_register_io_memory(0, pci_pmac_read, pci_pmac_write, s);
|
s = &pci_bridge[0];
|
||||||
|
pci_mem_config = cpu_register_io_memory(0, pci_unin_main_config_read,
|
||||||
|
pci_unin_main_config_write, s);
|
||||||
|
pci_mem_data = cpu_register_io_memory(0, pci_unin_main_read,
|
||||||
|
pci_unin_main_write, s);
|
||||||
|
cpu_register_physical_memory(0xf2800000, 0x1000, pci_mem_config);
|
||||||
|
cpu_register_physical_memory(0xf2c00000, 0x1000, pci_mem_data);
|
||||||
|
|
||||||
cpu_register_physical_memory(0xfec00000, 0x1000, pci_mem_config);
|
d = pci_register_device("Uni-north main", sizeof(PCIDevice), 0, 11 << 3,
|
||||||
cpu_register_physical_memory(0xfee00000, 0x1000, pci_mem_data);
|
|
||||||
|
|
||||||
d = pci_register_device("MPC106", sizeof(PCIDevice), 0, 0,
|
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
d->config[0x00] = 0x6b; // vendor_id : Apple
|
||||||
|
d->config[0x01] = 0x10;
|
||||||
|
d->config[0x02] = 0x1F; // device_id
|
||||||
|
d->config[0x03] = 0x00;
|
||||||
|
d->config[0x08] = 0x00; // revision
|
||||||
|
d->config[0x0A] = 0x00; // class_sub = pci host
|
||||||
|
d->config[0x0B] = 0x06; // class_base = PCI_bridge
|
||||||
|
d->config[0x0C] = 0x08; // cache_line_size
|
||||||
|
d->config[0x0D] = 0x10; // latency_timer
|
||||||
|
d->config[0x0E] = 0x00; // header_type
|
||||||
|
d->config[0x34] = 0x00; // capabilities_pointer
|
||||||
|
|
||||||
|
#if 0 // XXX: not activated as PPC BIOS doesn't handle mutiple buses properly
|
||||||
|
/* pci-to-pci bridge */
|
||||||
|
d = pci_register_device("Uni-north bridge", sizeof(PCIDevice), 0, 13 << 3,
|
||||||
|
NULL, NULL);
|
||||||
|
d->config[0x00] = 0x11; // vendor_id : TI
|
||||||
|
d->config[0x01] = 0x10;
|
||||||
|
d->config[0x02] = 0x26; // device_id
|
||||||
|
d->config[0x03] = 0x00;
|
||||||
|
d->config[0x08] = 0x05; // revision
|
||||||
|
d->config[0x0A] = 0x04; // class_sub = pci2pci
|
||||||
|
d->config[0x0B] = 0x06; // class_base = PCI_bridge
|
||||||
|
d->config[0x0C] = 0x08; // cache_line_size
|
||||||
|
d->config[0x0D] = 0x20; // latency_timer
|
||||||
|
d->config[0x0E] = 0x01; // header_type
|
||||||
|
|
||||||
|
d->config[0x18] = 0x01; // primary_bus
|
||||||
|
d->config[0x19] = 0x02; // secondary_bus
|
||||||
|
d->config[0x1A] = 0x02; // subordinate_bus
|
||||||
|
d->config[0x1B] = 0x20; // secondary_latency_timer
|
||||||
|
d->config[0x1C] = 0x11; // io_base
|
||||||
|
d->config[0x1D] = 0x01; // io_limit
|
||||||
|
d->config[0x20] = 0x00; // memory_base
|
||||||
|
d->config[0x21] = 0x80;
|
||||||
|
d->config[0x22] = 0x00; // memory_limit
|
||||||
|
d->config[0x23] = 0x80;
|
||||||
|
d->config[0x24] = 0x01; // prefetchable_memory_base
|
||||||
|
d->config[0x25] = 0x80;
|
||||||
|
d->config[0x26] = 0xF1; // prefectchable_memory_limit
|
||||||
|
d->config[0x27] = 0x7F;
|
||||||
|
// d->config[0x34] = 0xdc // capabilities_pointer
|
||||||
|
#endif
|
||||||
|
#if 0 // XXX: not needed for now
|
||||||
|
/* Uninorth AGP bus */
|
||||||
|
s = &pci_bridge[1];
|
||||||
|
pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read,
|
||||||
|
pci_unin_config_write, s);
|
||||||
|
pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
|
||||||
|
pci_unin_write, s);
|
||||||
|
cpu_register_physical_memory(0xf0800000, 0x1000, pci_mem_config);
|
||||||
|
cpu_register_physical_memory(0xf0c00000, 0x1000, pci_mem_data);
|
||||||
|
|
||||||
|
d = pci_register_device("Uni-north AGP", sizeof(PCIDevice), 0, 11 << 3,
|
||||||
|
NULL, NULL);
|
||||||
|
d->config[0x00] = 0x6b; // vendor_id : Apple
|
||||||
|
d->config[0x01] = 0x10;
|
||||||
|
d->config[0x02] = 0x20; // device_id
|
||||||
|
d->config[0x03] = 0x00;
|
||||||
|
d->config[0x08] = 0x00; // revision
|
||||||
|
d->config[0x0A] = 0x00; // class_sub = pci host
|
||||||
|
d->config[0x0B] = 0x06; // class_base = PCI_bridge
|
||||||
|
d->config[0x0C] = 0x08; // cache_line_size
|
||||||
|
d->config[0x0D] = 0x10; // latency_timer
|
||||||
|
d->config[0x0E] = 0x00; // header_type
|
||||||
|
// d->config[0x34] = 0x80; // capabilities_pointer
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0 // XXX: not needed for now
|
||||||
|
/* Uninorth internal bus */
|
||||||
|
s = &pci_bridge[2];
|
||||||
|
pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read,
|
||||||
|
pci_unin_config_write, s);
|
||||||
|
pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
|
||||||
|
pci_unin_write, s);
|
||||||
|
cpu_register_physical_memory(0xf4800000, 0x1000, pci_mem_config);
|
||||||
|
cpu_register_physical_memory(0xf4c00000, 0x1000, pci_mem_data);
|
||||||
|
|
||||||
|
d = pci_register_device("Uni-north internal", sizeof(PCIDevice),
|
||||||
|
3, 11 << 3, NULL, NULL);
|
||||||
|
d->config[0x00] = 0x6b; // vendor_id : Apple
|
||||||
|
d->config[0x01] = 0x10;
|
||||||
|
d->config[0x02] = 0x1E; // device_id
|
||||||
|
d->config[0x03] = 0x00;
|
||||||
|
d->config[0x08] = 0x00; // revision
|
||||||
|
d->config[0x0A] = 0x00; // class_sub = pci host
|
||||||
|
d->config[0x0B] = 0x06; // class_base = PCI_bridge
|
||||||
|
d->config[0x0C] = 0x08; // cache_line_size
|
||||||
|
d->config[0x0D] = 0x10; // latency_timer
|
||||||
|
d->config[0x0E] = 0x00; // header_type
|
||||||
|
d->config[0x34] = 0x00; // capabilities_pointer
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0 // Grackle ?
|
||||||
/* same values as PearPC - check this */
|
/* same values as PearPC - check this */
|
||||||
d->config[0x00] = 0x11; // vendor_id
|
d->config[0x00] = 0x11; // vendor_id
|
||||||
d->config[0x01] = 0x10;
|
d->config[0x01] = 0x10;
|
||||||
@ -770,6 +1112,7 @@ void pci_pmac_init(void)
|
|||||||
d->config[0x25] = 0x84;
|
d->config[0x25] = 0x84;
|
||||||
d->config[0x26] = 0x00; // prefetchable_memory_limit
|
d->config[0x26] = 0x00; // prefetchable_memory_limit
|
||||||
d->config[0x27] = 0x85;
|
d->config[0x27] = 0x85;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
@ -878,7 +1221,7 @@ static void pci_info_device(PCIDevice *d)
|
|||||||
|
|
||||||
void pci_info(void)
|
void pci_info(void)
|
||||||
{
|
{
|
||||||
PCIBridge *s = &pci_bridge;
|
PCIBridge *s = &pci_bridge[0];
|
||||||
PCIDevice **bus;
|
PCIDevice **bus;
|
||||||
int bus_num, devfn;
|
int bus_num, devfn;
|
||||||
|
|
||||||
@ -928,7 +1271,7 @@ static void isa_outl(uint32_t val, uint32_t addr)
|
|||||||
|
|
||||||
static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
|
static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
|
||||||
{
|
{
|
||||||
PCIBridge *s = &pci_bridge;
|
PCIBridge *s = &pci_bridge[0];
|
||||||
s->config_reg = 0x80000000 | (d->bus_num << 16) |
|
s->config_reg = 0x80000000 | (d->bus_num << 16) |
|
||||||
(d->devfn << 8) | addr;
|
(d->devfn << 8) | addr;
|
||||||
pci_data_write(s, 0, val, 4);
|
pci_data_write(s, 0, val, 4);
|
||||||
@ -936,7 +1279,7 @@ static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
|
|||||||
|
|
||||||
static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
|
static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
|
||||||
{
|
{
|
||||||
PCIBridge *s = &pci_bridge;
|
PCIBridge *s = &pci_bridge[0];
|
||||||
s->config_reg = 0x80000000 | (d->bus_num << 16) |
|
s->config_reg = 0x80000000 | (d->bus_num << 16) |
|
||||||
(d->devfn << 8) | (addr & ~3);
|
(d->devfn << 8) | (addr & ~3);
|
||||||
pci_data_write(s, addr & 3, val, 2);
|
pci_data_write(s, addr & 3, val, 2);
|
||||||
@ -944,7 +1287,7 @@ static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
|
|||||||
|
|
||||||
static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
|
static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
|
||||||
{
|
{
|
||||||
PCIBridge *s = &pci_bridge;
|
PCIBridge *s = &pci_bridge[0];
|
||||||
s->config_reg = 0x80000000 | (d->bus_num << 16) |
|
s->config_reg = 0x80000000 | (d->bus_num << 16) |
|
||||||
(d->devfn << 8) | (addr & ~3);
|
(d->devfn << 8) | (addr & ~3);
|
||||||
pci_data_write(s, addr & 3, val, 1);
|
pci_data_write(s, addr & 3, val, 1);
|
||||||
@ -952,7 +1295,7 @@ static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
|
|||||||
|
|
||||||
static uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
|
static uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
|
||||||
{
|
{
|
||||||
PCIBridge *s = &pci_bridge;
|
PCIBridge *s = &pci_bridge[0];
|
||||||
s->config_reg = 0x80000000 | (d->bus_num << 16) |
|
s->config_reg = 0x80000000 | (d->bus_num << 16) |
|
||||||
(d->devfn << 8) | addr;
|
(d->devfn << 8) | addr;
|
||||||
return pci_data_read(s, 0, 4);
|
return pci_data_read(s, 0, 4);
|
||||||
@ -960,7 +1303,7 @@ static uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
|
|||||||
|
|
||||||
static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
|
static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
|
||||||
{
|
{
|
||||||
PCIBridge *s = &pci_bridge;
|
PCIBridge *s = &pci_bridge[0];
|
||||||
s->config_reg = 0x80000000 | (d->bus_num << 16) |
|
s->config_reg = 0x80000000 | (d->bus_num << 16) |
|
||||||
(d->devfn << 8) | (addr & ~3);
|
(d->devfn << 8) | (addr & ~3);
|
||||||
return pci_data_read(s, addr & 3, 2);
|
return pci_data_read(s, addr & 3, 2);
|
||||||
@ -968,7 +1311,7 @@ static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
|
|||||||
|
|
||||||
static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
|
static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
|
||||||
{
|
{
|
||||||
PCIBridge *s = &pci_bridge;
|
PCIBridge *s = &pci_bridge[0];
|
||||||
s->config_reg = 0x80000000 | (d->bus_num << 16) |
|
s->config_reg = 0x80000000 | (d->bus_num << 16) |
|
||||||
(d->devfn << 8) | (addr & ~3);
|
(d->devfn << 8) | (addr & ~3);
|
||||||
return pci_data_read(s, addr & 3, 1);
|
return pci_data_read(s, addr & 3, 1);
|
||||||
@ -1036,8 +1379,21 @@ static void pci_bios_init_device(PCIDevice *d)
|
|||||||
/* VGA: map frame buffer to default Bochs VBE address */
|
/* VGA: map frame buffer to default Bochs VBE address */
|
||||||
pci_set_io_region_addr(d, 0, 0xE0000000);
|
pci_set_io_region_addr(d, 0, 0xE0000000);
|
||||||
break;
|
break;
|
||||||
|
case 0x0800:
|
||||||
|
/* PIC */
|
||||||
|
vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
|
||||||
|
device_id = pci_config_readw(d, PCI_DEVICE_ID);
|
||||||
|
if (vendor_id == 0x1014) {
|
||||||
|
/* IBM */
|
||||||
|
if (device_id == 0x0046 || device_id == 0xFFFF) {
|
||||||
|
/* MPIC & MPIC2 */
|
||||||
|
pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 0xff00:
|
case 0xff00:
|
||||||
if (vendor_id == 0x0106b && device_id == 0x0017) {
|
if (vendor_id == 0x0106b &&
|
||||||
|
(device_id == 0x0017 || device_id == 0x0022)) {
|
||||||
/* macio bridge */
|
/* macio bridge */
|
||||||
pci_set_io_region_addr(d, 0, 0x80800000);
|
pci_set_io_region_addr(d, 0, 0x80800000);
|
||||||
}
|
}
|
||||||
@ -1076,7 +1432,7 @@ static void pci_bios_init_device(PCIDevice *d)
|
|||||||
*/
|
*/
|
||||||
void pci_bios_init(void)
|
void pci_bios_init(void)
|
||||||
{
|
{
|
||||||
PCIBridge *s = &pci_bridge;
|
PCIBridge *s = &pci_bridge[0];
|
||||||
PCIDevice **bus;
|
PCIDevice **bus;
|
||||||
int bus_num, devfn, i, irq;
|
int bus_num, devfn, i, irq;
|
||||||
uint8_t elcr[2];
|
uint8_t elcr[2];
|
||||||
@ -1115,10 +1471,13 @@ void pci_bios_init(void)
|
|||||||
*/
|
*/
|
||||||
void pci_ppc_bios_init(void)
|
void pci_ppc_bios_init(void)
|
||||||
{
|
{
|
||||||
PCIBridge *s = &pci_bridge;
|
PCIBridge *s = &pci_bridge[0];
|
||||||
PCIDevice **bus;
|
PCIDevice **bus;
|
||||||
int bus_num, devfn, i, irq;
|
int bus_num, devfn;
|
||||||
|
#if 0
|
||||||
|
int i, irq;
|
||||||
uint8_t elcr[2];
|
uint8_t elcr[2];
|
||||||
|
#endif
|
||||||
|
|
||||||
pci_bios_io_addr = 0xc000;
|
pci_bios_io_addr = 0xc000;
|
||||||
pci_bios_mem_addr = 0xc0000000;
|
pci_bios_mem_addr = 0xc0000000;
|
||||||
|
Loading…
Reference in New Issue
Block a user