PowerPC prep/chrp/pmac support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@863 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
a2a444d6e0
commit
77d4bc349a
300
hw/pci.c
300
hw/pci.c
|
@ -470,6 +470,259 @@ void piix3_init(void)
|
||||||
piix3_reset(d);
|
piix3_reset(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* PREP pci init */
|
||||||
|
|
||||||
|
static inline void set_config(PCIBridge *s, target_phys_addr_t addr)
|
||||||
|
{
|
||||||
|
int devfn, i;
|
||||||
|
|
||||||
|
for(i = 0; i < 11; i++) {
|
||||||
|
if ((addr & (1 << (11 + i))) != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
devfn = ((addr >> 8) & 7) | (i << 3);
|
||||||
|
s->config_reg = 0x80000000 | (addr & 0xfc) | (devfn << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PPC_PCIIO_writeb (target_phys_addr_t addr, uint32_t val)
|
||||||
|
{
|
||||||
|
PCIBridge *s = &pci_bridge;
|
||||||
|
set_config(s, addr);
|
||||||
|
pci_data_write(s, addr, val, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PPC_PCIIO_writew (target_phys_addr_t addr, uint32_t val)
|
||||||
|
{
|
||||||
|
PCIBridge *s = &pci_bridge;
|
||||||
|
set_config(s, addr);
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap16(val);
|
||||||
|
#endif
|
||||||
|
pci_data_write(s, addr, val, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PPC_PCIIO_writel (target_phys_addr_t addr, uint32_t val)
|
||||||
|
{
|
||||||
|
PCIBridge *s = &pci_bridge;
|
||||||
|
set_config(s, addr);
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap32(val);
|
||||||
|
#endif
|
||||||
|
pci_data_write(s, addr, val, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t PPC_PCIIO_readb (target_phys_addr_t addr)
|
||||||
|
{
|
||||||
|
PCIBridge *s = &pci_bridge;
|
||||||
|
uint32_t val;
|
||||||
|
set_config(s, addr);
|
||||||
|
val = pci_data_read(s, addr, 1);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t PPC_PCIIO_readw (target_phys_addr_t addr)
|
||||||
|
{
|
||||||
|
PCIBridge *s = &pci_bridge;
|
||||||
|
uint32_t val;
|
||||||
|
set_config(s, addr);
|
||||||
|
val = pci_data_read(s, addr, 2);
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap16(val);
|
||||||
|
#endif
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t PPC_PCIIO_readl (target_phys_addr_t addr)
|
||||||
|
{
|
||||||
|
PCIBridge *s = &pci_bridge;
|
||||||
|
uint32_t val;
|
||||||
|
set_config(s, addr);
|
||||||
|
val = pci_data_read(s, addr, 4);
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap32(val);
|
||||||
|
#endif
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CPUWriteMemoryFunc *PPC_PCIIO_write[] = {
|
||||||
|
&PPC_PCIIO_writeb,
|
||||||
|
&PPC_PCIIO_writew,
|
||||||
|
&PPC_PCIIO_writel,
|
||||||
|
};
|
||||||
|
|
||||||
|
static CPUReadMemoryFunc *PPC_PCIIO_read[] = {
|
||||||
|
&PPC_PCIIO_readb,
|
||||||
|
&PPC_PCIIO_readw,
|
||||||
|
&PPC_PCIIO_readl,
|
||||||
|
};
|
||||||
|
|
||||||
|
void pci_prep_init(void)
|
||||||
|
{
|
||||||
|
PCIDevice *d;
|
||||||
|
int PPC_io_memory;
|
||||||
|
|
||||||
|
PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read, PPC_PCIIO_write);
|
||||||
|
cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory);
|
||||||
|
|
||||||
|
d = pci_register_device("PREP PCI Bridge", sizeof(PCIDevice), 0, 0,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
/* XXX: put correct IDs */
|
||||||
|
d->config[0x00] = 0x11; // vendor_id
|
||||||
|
d->config[0x01] = 0x10;
|
||||||
|
d->config[0x02] = 0x26; // device_id
|
||||||
|
d->config[0x03] = 0x00;
|
||||||
|
d->config[0x08] = 0x02; // revision
|
||||||
|
d->config[0x0a] = 0x04; // class_sub = pci2pci
|
||||||
|
d->config[0x0b] = 0x06; // class_base = PCI_bridge
|
||||||
|
d->config[0x0e] = 0x01; // header_type
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* pmac pci init */
|
||||||
|
|
||||||
|
static void pci_pmac_config_writel (target_phys_addr_t addr, uint32_t val)
|
||||||
|
{
|
||||||
|
PCIBridge *s = &pci_bridge;
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap32(val);
|
||||||
|
#endif
|
||||||
|
s->config_reg = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t pci_pmac_config_readl (target_phys_addr_t addr)
|
||||||
|
{
|
||||||
|
PCIBridge *s = &pci_bridge;
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
val = s->config_reg;
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap32(val);
|
||||||
|
#endif
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CPUWriteMemoryFunc *pci_pmac_config_write[] = {
|
||||||
|
&pci_pmac_config_writel,
|
||||||
|
&pci_pmac_config_writel,
|
||||||
|
&pci_pmac_config_writel,
|
||||||
|
};
|
||||||
|
|
||||||
|
static CPUReadMemoryFunc *pci_pmac_config_read[] = {
|
||||||
|
&pci_pmac_config_readl,
|
||||||
|
&pci_pmac_config_readl,
|
||||||
|
&pci_pmac_config_readl,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void pci_pmac_writeb (target_phys_addr_t addr, uint32_t val)
|
||||||
|
{
|
||||||
|
PCIBridge *s = &pci_bridge;
|
||||||
|
pci_data_write(s, addr, val, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pci_pmac_writew (target_phys_addr_t addr, uint32_t val)
|
||||||
|
{
|
||||||
|
PCIBridge *s = &pci_bridge;
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap16(val);
|
||||||
|
#endif
|
||||||
|
pci_data_write(s, addr, val, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pci_pmac_writel (target_phys_addr_t addr, uint32_t val)
|
||||||
|
{
|
||||||
|
PCIBridge *s = &pci_bridge;
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap32(val);
|
||||||
|
#endif
|
||||||
|
pci_data_write(s, addr, val, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t pci_pmac_readb (target_phys_addr_t addr)
|
||||||
|
{
|
||||||
|
PCIBridge *s = &pci_bridge;
|
||||||
|
uint32_t val;
|
||||||
|
val = pci_data_read(s, addr, 1);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t pci_pmac_readw (target_phys_addr_t addr)
|
||||||
|
{
|
||||||
|
PCIBridge *s = &pci_bridge;
|
||||||
|
uint32_t val;
|
||||||
|
val = pci_data_read(s, addr, 2);
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap16(val);
|
||||||
|
#endif
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t pci_pmac_readl (target_phys_addr_t addr)
|
||||||
|
{
|
||||||
|
PCIBridge *s = &pci_bridge;
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
val = pci_data_read(s, addr, 4);
|
||||||
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
|
val = bswap32(val);
|
||||||
|
#endif
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CPUWriteMemoryFunc *pci_pmac_write[] = {
|
||||||
|
&pci_pmac_writeb,
|
||||||
|
&pci_pmac_writew,
|
||||||
|
&pci_pmac_writel,
|
||||||
|
};
|
||||||
|
|
||||||
|
static CPUReadMemoryFunc *pci_pmac_read[] = {
|
||||||
|
&pci_pmac_readb,
|
||||||
|
&pci_pmac_readw,
|
||||||
|
&pci_pmac_readl,
|
||||||
|
};
|
||||||
|
|
||||||
|
void pci_pmac_init(void)
|
||||||
|
{
|
||||||
|
PCIDevice *d;
|
||||||
|
int pci_mem_config, pci_mem_data;
|
||||||
|
|
||||||
|
pci_mem_config = cpu_register_io_memory(0, pci_pmac_config_read,
|
||||||
|
pci_pmac_config_write);
|
||||||
|
pci_mem_data = cpu_register_io_memory(0, pci_pmac_read, pci_pmac_write);
|
||||||
|
|
||||||
|
cpu_register_physical_memory(0xfec00000, 0x1000, pci_mem_config);
|
||||||
|
cpu_register_physical_memory(0xfee00000, 0x1000, pci_mem_data);
|
||||||
|
|
||||||
|
d = pci_register_device("MPC106", sizeof(PCIDevice), 0, 0,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
/* same values as PearPC - check this */
|
||||||
|
d->config[0x00] = 0x11; // vendor_id
|
||||||
|
d->config[0x01] = 0x10;
|
||||||
|
d->config[0x02] = 0x26; // device_id
|
||||||
|
d->config[0x03] = 0x00;
|
||||||
|
d->config[0x08] = 0x02; // revision
|
||||||
|
d->config[0x0a] = 0x04; // class_sub = pci2pci
|
||||||
|
d->config[0x0b] = 0x06; // class_base = PCI_bridge
|
||||||
|
d->config[0x0e] = 0x01; // header_type
|
||||||
|
|
||||||
|
d->config[0x18] = 0x0; // primary_bus
|
||||||
|
d->config[0x19] = 0x1; // secondary_bus
|
||||||
|
d->config[0x1a] = 0x1; // subordinate_bus
|
||||||
|
d->config[0x1c] = 0x10; // io_base
|
||||||
|
d->config[0x1d] = 0x20; // io_limit
|
||||||
|
|
||||||
|
d->config[0x20] = 0x80; // memory_base
|
||||||
|
d->config[0x21] = 0x80;
|
||||||
|
d->config[0x22] = 0x90; // memory_limit
|
||||||
|
d->config[0x23] = 0x80;
|
||||||
|
|
||||||
|
d->config[0x24] = 0x00; // prefetchable_memory_base
|
||||||
|
d->config[0x25] = 0x84;
|
||||||
|
d->config[0x26] = 0x00; // prefetchable_memory_limit
|
||||||
|
d->config[0x27] = 0x85;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
/* generic PCI irq support */
|
/* generic PCI irq support */
|
||||||
|
|
||||||
|
@ -484,6 +737,11 @@ static inline int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 0 <= irq_num <= 3. level must be 0 or 1 */
|
/* 0 <= irq_num <= 3. level must be 0 or 1 */
|
||||||
|
#ifdef TARGET_PPC
|
||||||
|
void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#else
|
||||||
void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
|
void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
|
||||||
{
|
{
|
||||||
int irq_index, shift, pic_irq, pic_level;
|
int irq_index, shift, pic_irq, pic_level;
|
||||||
|
@ -519,6 +777,7 @@ void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
|
||||||
pic_set_irq(pic_irq, pic_level);
|
pic_set_irq(pic_irq, pic_level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
/* monitor info on PCI */
|
/* monitor info on PCI */
|
||||||
|
@ -780,3 +1039,44 @@ void pci_bios_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function initializes the PCI devices as a normal PCI BIOS
|
||||||
|
* would do. It is provided just in case the BIOS has no support for
|
||||||
|
* PCI.
|
||||||
|
*/
|
||||||
|
void pci_ppc_bios_init(void)
|
||||||
|
{
|
||||||
|
PCIBridge *s = &pci_bridge;
|
||||||
|
PCIDevice **bus;
|
||||||
|
int bus_num, devfn, i, irq;
|
||||||
|
uint8_t elcr[2];
|
||||||
|
|
||||||
|
pci_bios_io_addr = 0xc000;
|
||||||
|
pci_bios_mem_addr = 0xc0000000;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* activate IRQ mappings */
|
||||||
|
elcr[0] = 0x00;
|
||||||
|
elcr[1] = 0x00;
|
||||||
|
for(i = 0; i < 4; i++) {
|
||||||
|
irq = pci_irqs[i];
|
||||||
|
/* set to trigger level */
|
||||||
|
elcr[irq >> 3] |= (1 << (irq & 7));
|
||||||
|
/* activate irq remapping in PIIX */
|
||||||
|
pci_config_writeb((PCIDevice *)piix3_state, 0x60 + i, irq);
|
||||||
|
}
|
||||||
|
isa_outb(elcr[0], 0x4d0);
|
||||||
|
isa_outb(elcr[1], 0x4d1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(bus_num = 0; bus_num < 256; bus_num++) {
|
||||||
|
bus = s->pci_bus[bus_num];
|
||||||
|
if (bus) {
|
||||||
|
for(devfn = 0; devfn < 256; devfn++) {
|
||||||
|
if (bus[devfn])
|
||||||
|
pci_bios_init_device(bus[devfn]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
20
vl.c
20
vl.c
|
@ -93,8 +93,11 @@ extern void __sigaction();
|
||||||
#define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024)
|
#define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef TARGET_PPC
|
||||||
|
#define DEFAULT_RAM_SIZE 144
|
||||||
|
#else
|
||||||
#define DEFAULT_RAM_SIZE 32
|
#define DEFAULT_RAM_SIZE 32
|
||||||
|
#endif
|
||||||
/* in ms */
|
/* in ms */
|
||||||
#define GUI_REFRESH_INTERVAL 30
|
#define GUI_REFRESH_INTERVAL 30
|
||||||
|
|
||||||
|
@ -125,6 +128,7 @@ QEMUTimer *gui_timer;
|
||||||
int vm_running;
|
int vm_running;
|
||||||
int audio_enabled = 0;
|
int audio_enabled = 0;
|
||||||
int pci_enabled = 0;
|
int pci_enabled = 0;
|
||||||
|
int prep_enabled = 0;
|
||||||
|
|
||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
/* x86 ISA bus support */
|
/* x86 ISA bus support */
|
||||||
|
@ -876,12 +880,17 @@ int serial_open_device(void)
|
||||||
/* use console for serial port */
|
/* use console for serial port */
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
#if 0
|
||||||
|
/* Not satisfying */
|
||||||
if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
|
if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
|
||||||
fprintf(stderr, "warning: could not create pseudo terminal for serial port\n");
|
fprintf(stderr, "warning: could not create pseudo terminal for serial port\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "Serial port redirected to %s\n", slave_name);
|
fprintf(stderr, "Serial port redirected to %s\n", slave_name);
|
||||||
return master_fd;
|
return master_fd;
|
||||||
|
#else
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2005,6 +2014,7 @@ enum {
|
||||||
QEMU_OPTION_L,
|
QEMU_OPTION_L,
|
||||||
QEMU_OPTION_no_code_copy,
|
QEMU_OPTION_no_code_copy,
|
||||||
QEMU_OPTION_pci,
|
QEMU_OPTION_pci,
|
||||||
|
QEMU_OPTION_prep,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct QEMUOption {
|
typedef struct QEMUOption {
|
||||||
|
@ -2049,7 +2059,12 @@ const QEMUOption qemu_options[] = {
|
||||||
{ "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
|
{ "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
|
||||||
{ "L", HAS_ARG, QEMU_OPTION_L },
|
{ "L", HAS_ARG, QEMU_OPTION_L },
|
||||||
{ "no-code-copy", 0, QEMU_OPTION_no_code_copy },
|
{ "no-code-copy", 0, QEMU_OPTION_no_code_copy },
|
||||||
|
|
||||||
|
/* temporary options */
|
||||||
{ "pci", 0, QEMU_OPTION_pci },
|
{ "pci", 0, QEMU_OPTION_pci },
|
||||||
|
#ifdef TARGET_PPC
|
||||||
|
{ "prep", 0, QEMU_OPTION_prep },
|
||||||
|
#endif
|
||||||
{ NULL },
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2323,6 +2338,9 @@ int main(int argc, char **argv)
|
||||||
case QEMU_OPTION_pci:
|
case QEMU_OPTION_pci:
|
||||||
pci_enabled = 1;
|
pci_enabled = 1;
|
||||||
break;
|
break;
|
||||||
|
case QEMU_OPTION_prep:
|
||||||
|
prep_enabled = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
22
vl.h
22
vl.h
|
@ -429,6 +429,11 @@ void piix3_init(void);
|
||||||
void pci_bios_init(void);
|
void pci_bios_init(void);
|
||||||
void pci_info(void);
|
void pci_info(void);
|
||||||
|
|
||||||
|
/* temporary: will be moved in platform specific file */
|
||||||
|
void pci_prep_init(void);
|
||||||
|
void pci_pmac_init(void);
|
||||||
|
void pci_ppc_bios_init(void);
|
||||||
|
|
||||||
/* vga.c */
|
/* vga.c */
|
||||||
|
|
||||||
#define VGA_RAM_SIZE (4096 * 1024)
|
#define VGA_RAM_SIZE (4096 * 1024)
|
||||||
|
@ -580,6 +585,23 @@ void ppc_init (int ram_size, int vga_ram_size, int boot_device,
|
||||||
DisplayState *ds, const char **fd_filename, int snapshot,
|
DisplayState *ds, const char **fd_filename, int snapshot,
|
||||||
const char *kernel_filename, const char *kernel_cmdline,
|
const char *kernel_filename, const char *kernel_cmdline,
|
||||||
const char *initrd_filename);
|
const char *initrd_filename);
|
||||||
|
void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
|
||||||
|
DisplayState *ds, const char **fd_filename, int snapshot,
|
||||||
|
const char *kernel_filename, const char *kernel_cmdline,
|
||||||
|
const char *initrd_filename);
|
||||||
|
void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
|
||||||
|
DisplayState *ds, const char **fd_filename, int snapshot,
|
||||||
|
const char *kernel_filename, const char *kernel_cmdline,
|
||||||
|
const char *initrd_filename);
|
||||||
|
ppc_tb_t *cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq);
|
||||||
|
struct sysctrl_t;
|
||||||
|
int prep_NVRAM_init (struct sysctrl_t *sysctrl, uint32_t RAM_size,
|
||||||
|
uint32_t BIOS_size, int boot_device,
|
||||||
|
uint32_t kernel_image);
|
||||||
|
|
||||||
|
extern CPUWriteMemoryFunc *PPC_io_write[];
|
||||||
|
extern CPUReadMemoryFunc *PPC_io_read[];
|
||||||
|
extern int prep_enabled;
|
||||||
|
|
||||||
/* monitor.c */
|
/* monitor.c */
|
||||||
void monitor_init(void);
|
void monitor_init(void);
|
||||||
|
|
Loading…
Reference in New Issue