summaryrefslogtreecommitdiffstats
path: root/hw/ppc405_uc.c
diff options
context:
space:
mode:
authorj_mayer2007-04-17 04:50:56 +0200
committerj_mayer2007-04-17 04:50:56 +0200
commit04f20795ac815cf3ad5d1fdc99462f60eb871f25 (patch)
tree0a76f74c3e36de1353597d3655b92889743e8f12 /hw/ppc405_uc.c
parentSupport it_shift for mmapped pckbd. (diff)
downloadqemu-04f20795ac815cf3ad5d1fdc99462f60eb871f25.tar.gz
qemu-04f20795ac815cf3ad5d1fdc99462f60eb871f25.tar.xz
qemu-04f20795ac815cf3ad5d1fdc99462f60eb871f25.zip
Move PowerPC 405 specific definitions into a separate file
Preliminary code for -kernel option support for PowerPC 405 boards Fix DBSR in case of PowerPC 405 chip reset Add enums for PowerPC 405 clocks. Fix IRQ numbers (IBM reversed bits numbering...) Fix SPRG4-7 read access right Fix MSR mask in CPU definitions git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2692 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/ppc405_uc.c')
-rw-r--r--hw/ppc405_uc.c162
1 files changed, 121 insertions, 41 deletions
diff --git a/hw/ppc405_uc.c b/hw/ppc405_uc.c
index 0b7ef12733..f5c1c31bd2 100644
--- a/hw/ppc405_uc.c
+++ b/hw/ppc405_uc.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
#include "vl.h"
+#include "ppc405.h"
extern int loglevel;
extern FILE *logfile;
@@ -66,6 +67,51 @@ CPUState *ppc405_init (const unsigned char *cpu_model,
return env;
}
+ram_addr_t ppc405_set_bootinfo (CPUState *env, ppc4xx_bd_info_t *bd)
+{
+ ram_addr_t bdloc;
+ int i, n;
+
+ /* We put the bd structure at the top of memory */
+ bdloc = bd->bi_memsize - sizeof(struct ppc4xx_bd_info_t);
+ stl_raw(phys_ram_base + bdloc + 0x00, bd->bi_memstart);
+ stl_raw(phys_ram_base + bdloc + 0x04, bd->bi_memsize);
+ stl_raw(phys_ram_base + bdloc + 0x08, bd->bi_flashstart);
+ stl_raw(phys_ram_base + bdloc + 0x0C, bd->bi_flashsize);
+ stl_raw(phys_ram_base + bdloc + 0x10, bd->bi_flashoffset);
+ stl_raw(phys_ram_base + bdloc + 0x14, bd->bi_sramstart);
+ stl_raw(phys_ram_base + bdloc + 0x18, bd->bi_sramsize);
+ stl_raw(phys_ram_base + bdloc + 0x1C, bd->bi_bootflags);
+ stl_raw(phys_ram_base + bdloc + 0x20, bd->bi_ipaddr);
+ for (i = 0; i < 6; i++)
+ stb_raw(phys_ram_base + bdloc + 0x24 + i, bd->bi_enetaddr[i]);
+ stw_raw(phys_ram_base + bdloc + 0x2A, bd->bi_ethspeed);
+ stl_raw(phys_ram_base + bdloc + 0x2C, bd->bi_intfreq);
+ stl_raw(phys_ram_base + bdloc + 0x30, bd->bi_busfreq);
+ stl_raw(phys_ram_base + bdloc + 0x34, bd->bi_baudrate);
+ for (i = 0; i < 4; i++)
+ stb_raw(phys_ram_base + bdloc + 0x38 + i, bd->bi_s_version[i]);
+ for (i = 0; i < 32; i++)
+ stb_raw(phys_ram_base + bdloc + 0x3C + i, bd->bi_s_version[i]);
+ stl_raw(phys_ram_base + bdloc + 0x5C, bd->bi_plb_busfreq);
+ stl_raw(phys_ram_base + bdloc + 0x60, bd->bi_pci_busfreq);
+ for (i = 0; i < 6; i++)
+ stb_raw(phys_ram_base + bdloc + 0x64 + i, bd->bi_pci_enetaddr[i]);
+ n = 0x6A;
+ if (env->spr[SPR_PVR] == CPU_PPC_405EP) {
+ for (i = 0; i < 6; i++)
+ stb_raw(phys_ram_base + bdloc + n++, bd->bi_pci_enetaddr2[i]);
+ }
+ stl_raw(phys_ram_base + bdloc + n, bd->bi_opbfreq);
+ n += 4;
+ for (i = 0; i < 2; i++) {
+ stl_raw(phys_ram_base + bdloc + n, bd->bi_iic_fast[i]);
+ n += 4;
+ }
+
+ return bdloc;
+}
+
/*****************************************************************************/
/* Shared peripherals */
@@ -960,6 +1006,10 @@ static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram)
int i;
for (i = 0; i < sdram->nbanks; i++) {
+#ifdef DEBUG_SDRAM
+ printf("%s: Unmap RAM area " ADDRX " " ADDRX "\n", __func__,
+ sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i]));
+#endif
cpu_register_physical_memory(sdram_base(sdram->bcr[i]),
sdram_size(sdram->bcr[i]),
IO_MEM_UNASSIGNED);
@@ -1141,7 +1191,8 @@ static void sdram_reset (void *opaque)
}
void ppc405_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
- target_ulong *ram_bases, target_ulong *ram_sizes)
+ target_ulong *ram_bases, target_ulong *ram_sizes,
+ int do_init)
{
ppc4xx_sdram_t *sdram;
@@ -1159,6 +1210,8 @@ void ppc405_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
sdram, &dcr_read_sdram, &dcr_write_sdram);
ppc_dcr_register(env, SDRAM0_CFGDATA,
sdram, &dcr_read_sdram, &dcr_write_sdram);
+ if (do_init)
+ sdram_map_bcr(sdram);
}
}
@@ -2079,7 +2132,7 @@ void ppc40x_chip_reset (CPUState *env)
/* XXX: TODO reset all internal peripherals */
dbsr = env->spr[SPR_40x_DBSR];
dbsr &= ~0x00000300;
- dbsr |= 0x00000100;
+ dbsr |= 0x00000200;
env->spr[SPR_40x_DBSR] = dbsr;
cpu_loop_exit();
}
@@ -2124,9 +2177,20 @@ enum {
PPC405CR_CPC0_SR = 0x0BB,
};
+enum {
+ PPC405CR_CPU_CLK = 0,
+ PPC405CR_TMR_CLK = 1,
+ PPC405CR_PLB_CLK = 2,
+ PPC405CR_SDRAM_CLK = 3,
+ PPC405CR_OPB_CLK = 4,
+ PPC405CR_EXT_CLK = 5,
+ PPC405CR_UART_CLK = 6,
+ PPC405CR_CLK_NB = 7,
+};
+
typedef struct ppc405cr_cpc_t ppc405cr_cpc_t;
struct ppc405cr_cpc_t {
- clk_setup_t clk_setup[7];
+ clk_setup_t clk_setup[PPC405CR_CLK_NB];
uint32_t sysclk;
uint32_t psr;
uint32_t cr0;
@@ -2175,19 +2239,19 @@ static void ppc405cr_clk_setup (ppc405cr_cpc_t *cpc)
D0 = ((cpc->cr0 >> 1) & 0x1F) + 1;
UART_clk = CPU_clk / D0;
/* Setup CPU clocks */
- clk_setup(&cpc->clk_setup[0], CPU_clk);
+ clk_setup(&cpc->clk_setup[PPC405CR_CPU_CLK], CPU_clk);
/* Setup time-base clock */
- clk_setup(&cpc->clk_setup[1], TMR_clk);
+ clk_setup(&cpc->clk_setup[PPC405CR_TMR_CLK], TMR_clk);
/* Setup PLB clock */
- clk_setup(&cpc->clk_setup[2], PLB_clk);
+ clk_setup(&cpc->clk_setup[PPC405CR_PLB_CLK], PLB_clk);
/* Setup SDRAM clock */
- clk_setup(&cpc->clk_setup[3], SDRAM_clk);
+ clk_setup(&cpc->clk_setup[PPC405CR_SDRAM_CLK], SDRAM_clk);
/* Setup OPB clock */
- clk_setup(&cpc->clk_setup[4], OPB_clk);
+ clk_setup(&cpc->clk_setup[PPC405CR_OPB_CLK], OPB_clk);
/* Setup external clock */
- clk_setup(&cpc->clk_setup[5], EXT_clk);
+ clk_setup(&cpc->clk_setup[PPC405CR_EXT_CLK], EXT_clk);
/* Setup UART clock */
- clk_setup(&cpc->clk_setup[6], UART_clk);
+ clk_setup(&cpc->clk_setup[PPC405CR_UART_CLK], UART_clk);
}
static target_ulong dcr_read_crcpc (void *opaque, int dcrn)
@@ -2357,7 +2421,8 @@ static void ppc405cr_cpc_init (CPUState *env, clk_setup_t clk_setup[7],
cpc = qemu_mallocz(sizeof(ppc405cr_cpc_t));
if (cpc != NULL) {
- memcpy(cpc->clk_setup, clk_setup, 7 * sizeof(clk_setup_t));
+ memcpy(cpc->clk_setup, clk_setup,
+ PPC405CR_CLK_NB * sizeof(clk_setup_t));
cpc->sysclk = sysclk;
cpc->jtagid = 0x42051049;
ppc_dcr_register(env, PPC405CR_CPC0_PSR, cpc,
@@ -2384,9 +2449,9 @@ static void ppc405cr_cpc_init (CPUState *env, clk_setup_t clk_setup[7],
CPUState *ppc405cr_init (target_ulong ram_bases[4], target_ulong ram_sizes[4],
uint32_t sysclk, qemu_irq **picp,
- ram_addr_t *offsetp)
+ ram_addr_t *offsetp, int do_init)
{
- clk_setup_t clk_setup[7];
+ clk_setup_t clk_setup[PPC405CR_CLK_NB];
qemu_irq dma_irqs[4];
CPUState *env;
ppc4xx_mmio_t *mmio;
@@ -2395,7 +2460,8 @@ CPUState *ppc405cr_init (target_ulong ram_bases[4], target_ulong ram_sizes[4],
int i;
memset(clk_setup, 0, sizeof(clk_setup));
- env = ppc405_init("405cr", &clk_setup[0], &clk_setup[1], sysclk);
+ env = ppc405_init("405cr", &clk_setup[PPC405CR_CPU_CLK],
+ &clk_setup[PPC405CR_TMR_CLK], sysclk);
/* Memory mapped devices registers */
mmio = ppc4xx_mmio_init(env, 0xEF600000);
/* PLB arbitrer */
@@ -2413,24 +2479,24 @@ CPUState *ppc405cr_init (target_ulong ram_bases[4], target_ulong ram_sizes[4],
pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
*picp = pic;
/* SDRAM controller */
- ppc405_sdram_init(env, pic[17], 1, ram_bases, ram_sizes);
+ ppc405_sdram_init(env, pic[14], 1, ram_bases, ram_sizes, do_init);
offset = 0;
for (i = 0; i < 4; i++)
offset += ram_sizes[i];
/* External bus controller */
ppc405_ebc_init(env);
/* DMA controller */
- dma_irqs[0] = pic[5];
- dma_irqs[1] = pic[6];
- dma_irqs[2] = pic[7];
- dma_irqs[3] = pic[8];
+ dma_irqs[0] = pic[26];
+ dma_irqs[1] = pic[25];
+ dma_irqs[2] = pic[24];
+ dma_irqs[3] = pic[23];
ppc405_dma_init(env, dma_irqs);
/* Serial ports */
if (serial_hds[0] != NULL) {
- ppc405_serial_init(env, mmio, 0x400, pic[0], serial_hds[0]);
+ ppc405_serial_init(env, mmio, 0x300, pic[31], serial_hds[0]);
}
if (serial_hds[1] != NULL) {
- ppc405_serial_init(env, mmio, 0x300, pic[1], serial_hds[1]);
+ ppc405_serial_init(env, mmio, 0x400, pic[30], serial_hds[1]);
}
/* IIC controller */
ppc405_i2c_init(env, mmio, 0x500);
@@ -2457,10 +2523,22 @@ enum {
PPC405EP_CPC0_PCI = 0x0F9,
};
+enum {
+ PPC405EP_CPU_CLK = 0,
+ PPC405EP_PLB_CLK = 1,
+ PPC405EP_OPB_CLK = 2,
+ PPC405EP_EBC_CLK = 3,
+ PPC405EP_MAL_CLK = 4,
+ PPC405EP_PCI_CLK = 5,
+ PPC405EP_UART0_CLK = 6,
+ PPC405EP_UART1_CLK = 7,
+ PPC405EP_CLK_NB = 8,
+};
+
typedef struct ppc405ep_cpc_t ppc405ep_cpc_t;
struct ppc405ep_cpc_t {
uint32_t sysclk;
- clk_setup_t clk_setup[8];
+ clk_setup_t clk_setup[PPC405EP_CLK_NB];
uint32_t boot;
uint32_t epctl;
uint32_t pllmr[2];
@@ -2548,21 +2626,21 @@ static void ppc405ep_compute_clocks (ppc405ep_cpc_t *cpc)
UART0_clk, UART1_clk);
#endif
/* Setup CPU clocks */
- clk_setup(&cpc->clk_setup[0], CPU_clk);
+ clk_setup(&cpc->clk_setup[PPC405EP_CPU_CLK], CPU_clk);
/* Setup PLB clock */
- clk_setup(&cpc->clk_setup[1], PLB_clk);
+ clk_setup(&cpc->clk_setup[PPC405EP_PLB_CLK], PLB_clk);
/* Setup OPB clock */
- clk_setup(&cpc->clk_setup[2], OPB_clk);
+ clk_setup(&cpc->clk_setup[PPC405EP_OPB_CLK], OPB_clk);
/* Setup external clock */
- clk_setup(&cpc->clk_setup[3], EBC_clk);
+ clk_setup(&cpc->clk_setup[PPC405EP_EBC_CLK], EBC_clk);
/* Setup MAL clock */
- clk_setup(&cpc->clk_setup[4], MAL_clk);
+ clk_setup(&cpc->clk_setup[PPC405EP_MAL_CLK], MAL_clk);
/* Setup PCI clock */
- clk_setup(&cpc->clk_setup[5], PCI_clk);
+ clk_setup(&cpc->clk_setup[PPC405EP_PCI_CLK], PCI_clk);
/* Setup UART0 clock */
- clk_setup(&cpc->clk_setup[6], UART0_clk);
+ clk_setup(&cpc->clk_setup[PPC405EP_UART0_CLK], UART0_clk);
/* Setup UART1 clock */
- clk_setup(&cpc->clk_setup[7], UART0_clk);
+ clk_setup(&cpc->clk_setup[PPC405EP_UART1_CLK], UART1_clk);
}
static target_ulong dcr_read_epcpc (void *opaque, int dcrn)
@@ -2664,7 +2742,8 @@ static void ppc405ep_cpc_init (CPUState *env, clk_setup_t clk_setup[8],
cpc = qemu_mallocz(sizeof(ppc405ep_cpc_t));
if (cpc != NULL) {
- memcpy(cpc->clk_setup, clk_setup, 7 * sizeof(clk_setup_t));
+ memcpy(cpc->clk_setup, clk_setup,
+ PPC405EP_CLK_NB * sizeof(clk_setup_t));
cpc->jtagid = 0x20267049;
cpc->sysclk = sysclk;
ppc405ep_cpc_reset(cpc);
@@ -2690,9 +2769,9 @@ static void ppc405ep_cpc_init (CPUState *env, clk_setup_t clk_setup[8],
CPUState *ppc405ep_init (target_ulong ram_bases[2], target_ulong ram_sizes[2],
uint32_t sysclk, qemu_irq **picp,
- ram_addr_t *offsetp)
+ ram_addr_t *offsetp, int do_init)
{
- clk_setup_t clk_setup[8];
+ clk_setup_t clk_setup[PPC405EP_CLK_NB];
qemu_irq dma_irqs[4];
CPUState *env;
ppc4xx_mmio_t *mmio;
@@ -2702,7 +2781,8 @@ CPUState *ppc405ep_init (target_ulong ram_bases[2], target_ulong ram_sizes[2],
memset(clk_setup, 0, sizeof(clk_setup));
/* init CPUs */
- env = ppc405_init("405ep", &clk_setup[0], &clk_setup[1], sysclk);
+ env = ppc405_init("405ep", &clk_setup[PPC405EP_CPU_CLK],
+ &clk_setup[PPC405EP_PLB_CLK], sysclk);
/* Internal devices init */
/* Memory mapped devices registers */
mmio = ppc4xx_mmio_init(env, 0xEF600000);
@@ -2721,17 +2801,17 @@ CPUState *ppc405ep_init (target_ulong ram_bases[2], target_ulong ram_sizes[2],
pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
*picp = pic;
/* SDRAM controller */
- ppc405_sdram_init(env, pic[17], 2, ram_bases, ram_sizes);
+ ppc405_sdram_init(env, pic[14], 2, ram_bases, ram_sizes, do_init);
offset = 0;
for (i = 0; i < 2; i++)
offset += ram_sizes[i];
/* External bus controller */
ppc405_ebc_init(env);
/* DMA controller */
- dma_irqs[0] = pic[5];
- dma_irqs[1] = pic[6];
- dma_irqs[2] = pic[7];
- dma_irqs[3] = pic[8];
+ dma_irqs[0] = pic[26];
+ dma_irqs[1] = pic[25];
+ dma_irqs[2] = pic[24];
+ dma_irqs[3] = pic[23];
ppc405_dma_init(env, dma_irqs);
/* IIC controller */
ppc405_i2c_init(env, mmio, 0x500);
@@ -2739,10 +2819,10 @@ CPUState *ppc405ep_init (target_ulong ram_bases[2], target_ulong ram_sizes[2],
ppc405_gpio_init(env, mmio, 0x700);
/* Serial ports */
if (serial_hds[0] != NULL) {
- ppc405_serial_init(env, mmio, 0x300, pic[0], serial_hds[0]);
+ ppc405_serial_init(env, mmio, 0x300, pic[31], serial_hds[0]);
}
if (serial_hds[1] != NULL) {
- ppc405_serial_init(env, mmio, 0x400, pic[1], serial_hds[1]);
+ ppc405_serial_init(env, mmio, 0x400, pic[30], serial_hds[1]);
}
/* OCM */
ppc405_ocm_init(env, ram_sizes[0] + ram_sizes[1]);