Revision 04f20795 hw/ppc405_uc.c
b/hw/ppc405_uc.c | ||
---|---|---|
22 | 22 |
* THE SOFTWARE. |
23 | 23 |
*/ |
24 | 24 |
#include "vl.h" |
25 |
#include "ppc405.h" |
|
25 | 26 |
|
26 | 27 |
extern int loglevel; |
27 | 28 |
extern FILE *logfile; |
... | ... | |
66 | 67 |
return env; |
67 | 68 |
} |
68 | 69 |
|
70 |
ram_addr_t ppc405_set_bootinfo (CPUState *env, ppc4xx_bd_info_t *bd) |
|
71 |
{ |
|
72 |
ram_addr_t bdloc; |
|
73 |
int i, n; |
|
74 |
|
|
75 |
/* We put the bd structure at the top of memory */ |
|
76 |
bdloc = bd->bi_memsize - sizeof(struct ppc4xx_bd_info_t); |
|
77 |
stl_raw(phys_ram_base + bdloc + 0x00, bd->bi_memstart); |
|
78 |
stl_raw(phys_ram_base + bdloc + 0x04, bd->bi_memsize); |
|
79 |
stl_raw(phys_ram_base + bdloc + 0x08, bd->bi_flashstart); |
|
80 |
stl_raw(phys_ram_base + bdloc + 0x0C, bd->bi_flashsize); |
|
81 |
stl_raw(phys_ram_base + bdloc + 0x10, bd->bi_flashoffset); |
|
82 |
stl_raw(phys_ram_base + bdloc + 0x14, bd->bi_sramstart); |
|
83 |
stl_raw(phys_ram_base + bdloc + 0x18, bd->bi_sramsize); |
|
84 |
stl_raw(phys_ram_base + bdloc + 0x1C, bd->bi_bootflags); |
|
85 |
stl_raw(phys_ram_base + bdloc + 0x20, bd->bi_ipaddr); |
|
86 |
for (i = 0; i < 6; i++) |
|
87 |
stb_raw(phys_ram_base + bdloc + 0x24 + i, bd->bi_enetaddr[i]); |
|
88 |
stw_raw(phys_ram_base + bdloc + 0x2A, bd->bi_ethspeed); |
|
89 |
stl_raw(phys_ram_base + bdloc + 0x2C, bd->bi_intfreq); |
|
90 |
stl_raw(phys_ram_base + bdloc + 0x30, bd->bi_busfreq); |
|
91 |
stl_raw(phys_ram_base + bdloc + 0x34, bd->bi_baudrate); |
|
92 |
for (i = 0; i < 4; i++) |
|
93 |
stb_raw(phys_ram_base + bdloc + 0x38 + i, bd->bi_s_version[i]); |
|
94 |
for (i = 0; i < 32; i++) |
|
95 |
stb_raw(phys_ram_base + bdloc + 0x3C + i, bd->bi_s_version[i]); |
|
96 |
stl_raw(phys_ram_base + bdloc + 0x5C, bd->bi_plb_busfreq); |
|
97 |
stl_raw(phys_ram_base + bdloc + 0x60, bd->bi_pci_busfreq); |
|
98 |
for (i = 0; i < 6; i++) |
|
99 |
stb_raw(phys_ram_base + bdloc + 0x64 + i, bd->bi_pci_enetaddr[i]); |
|
100 |
n = 0x6A; |
|
101 |
if (env->spr[SPR_PVR] == CPU_PPC_405EP) { |
|
102 |
for (i = 0; i < 6; i++) |
|
103 |
stb_raw(phys_ram_base + bdloc + n++, bd->bi_pci_enetaddr2[i]); |
|
104 |
} |
|
105 |
stl_raw(phys_ram_base + bdloc + n, bd->bi_opbfreq); |
|
106 |
n += 4; |
|
107 |
for (i = 0; i < 2; i++) { |
|
108 |
stl_raw(phys_ram_base + bdloc + n, bd->bi_iic_fast[i]); |
|
109 |
n += 4; |
|
110 |
} |
|
111 |
|
|
112 |
return bdloc; |
|
113 |
} |
|
114 |
|
|
69 | 115 |
/*****************************************************************************/ |
70 | 116 |
/* Shared peripherals */ |
71 | 117 |
|
... | ... | |
960 | 1006 |
int i; |
961 | 1007 |
|
962 | 1008 |
for (i = 0; i < sdram->nbanks; i++) { |
1009 |
#ifdef DEBUG_SDRAM |
|
1010 |
printf("%s: Unmap RAM area " ADDRX " " ADDRX "\n", __func__, |
|
1011 |
sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i])); |
|
1012 |
#endif |
|
963 | 1013 |
cpu_register_physical_memory(sdram_base(sdram->bcr[i]), |
964 | 1014 |
sdram_size(sdram->bcr[i]), |
965 | 1015 |
IO_MEM_UNASSIGNED); |
... | ... | |
1141 | 1191 |
} |
1142 | 1192 |
|
1143 | 1193 |
void ppc405_sdram_init (CPUState *env, qemu_irq irq, int nbanks, |
1144 |
target_ulong *ram_bases, target_ulong *ram_sizes) |
|
1194 |
target_ulong *ram_bases, target_ulong *ram_sizes, |
|
1195 |
int do_init) |
|
1145 | 1196 |
{ |
1146 | 1197 |
ppc4xx_sdram_t *sdram; |
1147 | 1198 |
|
... | ... | |
1159 | 1210 |
sdram, &dcr_read_sdram, &dcr_write_sdram); |
1160 | 1211 |
ppc_dcr_register(env, SDRAM0_CFGDATA, |
1161 | 1212 |
sdram, &dcr_read_sdram, &dcr_write_sdram); |
1213 |
if (do_init) |
|
1214 |
sdram_map_bcr(sdram); |
|
1162 | 1215 |
} |
1163 | 1216 |
} |
1164 | 1217 |
|
... | ... | |
2079 | 2132 |
/* XXX: TODO reset all internal peripherals */ |
2080 | 2133 |
dbsr = env->spr[SPR_40x_DBSR]; |
2081 | 2134 |
dbsr &= ~0x00000300; |
2082 |
dbsr |= 0x00000100;
|
|
2135 |
dbsr |= 0x00000200;
|
|
2083 | 2136 |
env->spr[SPR_40x_DBSR] = dbsr; |
2084 | 2137 |
cpu_loop_exit(); |
2085 | 2138 |
} |
... | ... | |
2124 | 2177 |
PPC405CR_CPC0_SR = 0x0BB, |
2125 | 2178 |
}; |
2126 | 2179 |
|
2180 |
enum { |
|
2181 |
PPC405CR_CPU_CLK = 0, |
|
2182 |
PPC405CR_TMR_CLK = 1, |
|
2183 |
PPC405CR_PLB_CLK = 2, |
|
2184 |
PPC405CR_SDRAM_CLK = 3, |
|
2185 |
PPC405CR_OPB_CLK = 4, |
|
2186 |
PPC405CR_EXT_CLK = 5, |
|
2187 |
PPC405CR_UART_CLK = 6, |
|
2188 |
PPC405CR_CLK_NB = 7, |
|
2189 |
}; |
|
2190 |
|
|
2127 | 2191 |
typedef struct ppc405cr_cpc_t ppc405cr_cpc_t; |
2128 | 2192 |
struct ppc405cr_cpc_t { |
2129 |
clk_setup_t clk_setup[7];
|
|
2193 |
clk_setup_t clk_setup[PPC405CR_CLK_NB];
|
|
2130 | 2194 |
uint32_t sysclk; |
2131 | 2195 |
uint32_t psr; |
2132 | 2196 |
uint32_t cr0; |
... | ... | |
2175 | 2239 |
D0 = ((cpc->cr0 >> 1) & 0x1F) + 1; |
2176 | 2240 |
UART_clk = CPU_clk / D0; |
2177 | 2241 |
/* Setup CPU clocks */ |
2178 |
clk_setup(&cpc->clk_setup[0], CPU_clk);
|
|
2242 |
clk_setup(&cpc->clk_setup[PPC405CR_CPU_CLK], CPU_clk);
|
|
2179 | 2243 |
/* Setup time-base clock */ |
2180 |
clk_setup(&cpc->clk_setup[1], TMR_clk);
|
|
2244 |
clk_setup(&cpc->clk_setup[PPC405CR_TMR_CLK], TMR_clk);
|
|
2181 | 2245 |
/* Setup PLB clock */ |
2182 |
clk_setup(&cpc->clk_setup[2], PLB_clk);
|
|
2246 |
clk_setup(&cpc->clk_setup[PPC405CR_PLB_CLK], PLB_clk);
|
|
2183 | 2247 |
/* Setup SDRAM clock */ |
2184 |
clk_setup(&cpc->clk_setup[3], SDRAM_clk);
|
|
2248 |
clk_setup(&cpc->clk_setup[PPC405CR_SDRAM_CLK], SDRAM_clk);
|
|
2185 | 2249 |
/* Setup OPB clock */ |
2186 |
clk_setup(&cpc->clk_setup[4], OPB_clk);
|
|
2250 |
clk_setup(&cpc->clk_setup[PPC405CR_OPB_CLK], OPB_clk);
|
|
2187 | 2251 |
/* Setup external clock */ |
2188 |
clk_setup(&cpc->clk_setup[5], EXT_clk);
|
|
2252 |
clk_setup(&cpc->clk_setup[PPC405CR_EXT_CLK], EXT_clk);
|
|
2189 | 2253 |
/* Setup UART clock */ |
2190 |
clk_setup(&cpc->clk_setup[6], UART_clk);
|
|
2254 |
clk_setup(&cpc->clk_setup[PPC405CR_UART_CLK], UART_clk);
|
|
2191 | 2255 |
} |
2192 | 2256 |
|
2193 | 2257 |
static target_ulong dcr_read_crcpc (void *opaque, int dcrn) |
... | ... | |
2357 | 2421 |
|
2358 | 2422 |
cpc = qemu_mallocz(sizeof(ppc405cr_cpc_t)); |
2359 | 2423 |
if (cpc != NULL) { |
2360 |
memcpy(cpc->clk_setup, clk_setup, 7 * sizeof(clk_setup_t)); |
|
2424 |
memcpy(cpc->clk_setup, clk_setup, |
|
2425 |
PPC405CR_CLK_NB * sizeof(clk_setup_t)); |
|
2361 | 2426 |
cpc->sysclk = sysclk; |
2362 | 2427 |
cpc->jtagid = 0x42051049; |
2363 | 2428 |
ppc_dcr_register(env, PPC405CR_CPC0_PSR, cpc, |
... | ... | |
2384 | 2449 |
|
2385 | 2450 |
CPUState *ppc405cr_init (target_ulong ram_bases[4], target_ulong ram_sizes[4], |
2386 | 2451 |
uint32_t sysclk, qemu_irq **picp, |
2387 |
ram_addr_t *offsetp) |
|
2452 |
ram_addr_t *offsetp, int do_init)
|
|
2388 | 2453 |
{ |
2389 |
clk_setup_t clk_setup[7];
|
|
2454 |
clk_setup_t clk_setup[PPC405CR_CLK_NB];
|
|
2390 | 2455 |
qemu_irq dma_irqs[4]; |
2391 | 2456 |
CPUState *env; |
2392 | 2457 |
ppc4xx_mmio_t *mmio; |
... | ... | |
2395 | 2460 |
int i; |
2396 | 2461 |
|
2397 | 2462 |
memset(clk_setup, 0, sizeof(clk_setup)); |
2398 |
env = ppc405_init("405cr", &clk_setup[0], &clk_setup[1], sysclk); |
|
2463 |
env = ppc405_init("405cr", &clk_setup[PPC405CR_CPU_CLK], |
|
2464 |
&clk_setup[PPC405CR_TMR_CLK], sysclk); |
|
2399 | 2465 |
/* Memory mapped devices registers */ |
2400 | 2466 |
mmio = ppc4xx_mmio_init(env, 0xEF600000); |
2401 | 2467 |
/* PLB arbitrer */ |
... | ... | |
2413 | 2479 |
pic = ppcuic_init(env, irqs, 0x0C0, 0, 1); |
2414 | 2480 |
*picp = pic; |
2415 | 2481 |
/* SDRAM controller */ |
2416 |
ppc405_sdram_init(env, pic[17], 1, ram_bases, ram_sizes);
|
|
2482 |
ppc405_sdram_init(env, pic[14], 1, ram_bases, ram_sizes, do_init);
|
|
2417 | 2483 |
offset = 0; |
2418 | 2484 |
for (i = 0; i < 4; i++) |
2419 | 2485 |
offset += ram_sizes[i]; |
2420 | 2486 |
/* External bus controller */ |
2421 | 2487 |
ppc405_ebc_init(env); |
2422 | 2488 |
/* DMA controller */ |
2423 |
dma_irqs[0] = pic[5];
|
|
2424 |
dma_irqs[1] = pic[6];
|
|
2425 |
dma_irqs[2] = pic[7];
|
|
2426 |
dma_irqs[3] = pic[8];
|
|
2489 |
dma_irqs[0] = pic[26];
|
|
2490 |
dma_irqs[1] = pic[25];
|
|
2491 |
dma_irqs[2] = pic[24];
|
|
2492 |
dma_irqs[3] = pic[23];
|
|
2427 | 2493 |
ppc405_dma_init(env, dma_irqs); |
2428 | 2494 |
/* Serial ports */ |
2429 | 2495 |
if (serial_hds[0] != NULL) { |
2430 |
ppc405_serial_init(env, mmio, 0x400, pic[0], serial_hds[0]);
|
|
2496 |
ppc405_serial_init(env, mmio, 0x300, pic[31], serial_hds[0]);
|
|
2431 | 2497 |
} |
2432 | 2498 |
if (serial_hds[1] != NULL) { |
2433 |
ppc405_serial_init(env, mmio, 0x300, pic[1], serial_hds[1]);
|
|
2499 |
ppc405_serial_init(env, mmio, 0x400, pic[30], serial_hds[1]);
|
|
2434 | 2500 |
} |
2435 | 2501 |
/* IIC controller */ |
2436 | 2502 |
ppc405_i2c_init(env, mmio, 0x500); |
... | ... | |
2457 | 2523 |
PPC405EP_CPC0_PCI = 0x0F9, |
2458 | 2524 |
}; |
2459 | 2525 |
|
2526 |
enum { |
|
2527 |
PPC405EP_CPU_CLK = 0, |
|
2528 |
PPC405EP_PLB_CLK = 1, |
|
2529 |
PPC405EP_OPB_CLK = 2, |
|
2530 |
PPC405EP_EBC_CLK = 3, |
|
2531 |
PPC405EP_MAL_CLK = 4, |
|
2532 |
PPC405EP_PCI_CLK = 5, |
|
2533 |
PPC405EP_UART0_CLK = 6, |
|
2534 |
PPC405EP_UART1_CLK = 7, |
|
2535 |
PPC405EP_CLK_NB = 8, |
|
2536 |
}; |
|
2537 |
|
|
2460 | 2538 |
typedef struct ppc405ep_cpc_t ppc405ep_cpc_t; |
2461 | 2539 |
struct ppc405ep_cpc_t { |
2462 | 2540 |
uint32_t sysclk; |
2463 |
clk_setup_t clk_setup[8];
|
|
2541 |
clk_setup_t clk_setup[PPC405EP_CLK_NB];
|
|
2464 | 2542 |
uint32_t boot; |
2465 | 2543 |
uint32_t epctl; |
2466 | 2544 |
uint32_t pllmr[2]; |
... | ... | |
2548 | 2626 |
UART0_clk, UART1_clk); |
2549 | 2627 |
#endif |
2550 | 2628 |
/* Setup CPU clocks */ |
2551 |
clk_setup(&cpc->clk_setup[0], CPU_clk);
|
|
2629 |
clk_setup(&cpc->clk_setup[PPC405EP_CPU_CLK], CPU_clk);
|
|
2552 | 2630 |
/* Setup PLB clock */ |
2553 |
clk_setup(&cpc->clk_setup[1], PLB_clk);
|
|
2631 |
clk_setup(&cpc->clk_setup[PPC405EP_PLB_CLK], PLB_clk);
|
|
2554 | 2632 |
/* Setup OPB clock */ |
2555 |
clk_setup(&cpc->clk_setup[2], OPB_clk);
|
|
2633 |
clk_setup(&cpc->clk_setup[PPC405EP_OPB_CLK], OPB_clk);
|
|
2556 | 2634 |
/* Setup external clock */ |
2557 |
clk_setup(&cpc->clk_setup[3], EBC_clk);
|
|
2635 |
clk_setup(&cpc->clk_setup[PPC405EP_EBC_CLK], EBC_clk);
|
|
2558 | 2636 |
/* Setup MAL clock */ |
2559 |
clk_setup(&cpc->clk_setup[4], MAL_clk);
|
|
2637 |
clk_setup(&cpc->clk_setup[PPC405EP_MAL_CLK], MAL_clk);
|
|
2560 | 2638 |
/* Setup PCI clock */ |
2561 |
clk_setup(&cpc->clk_setup[5], PCI_clk);
|
|
2639 |
clk_setup(&cpc->clk_setup[PPC405EP_PCI_CLK], PCI_clk);
|
|
2562 | 2640 |
/* Setup UART0 clock */ |
2563 |
clk_setup(&cpc->clk_setup[6], UART0_clk);
|
|
2641 |
clk_setup(&cpc->clk_setup[PPC405EP_UART0_CLK], UART0_clk);
|
|
2564 | 2642 |
/* Setup UART1 clock */ |
2565 |
clk_setup(&cpc->clk_setup[7], UART0_clk);
|
|
2643 |
clk_setup(&cpc->clk_setup[PPC405EP_UART1_CLK], UART1_clk);
|
|
2566 | 2644 |
} |
2567 | 2645 |
|
2568 | 2646 |
static target_ulong dcr_read_epcpc (void *opaque, int dcrn) |
... | ... | |
2664 | 2742 |
|
2665 | 2743 |
cpc = qemu_mallocz(sizeof(ppc405ep_cpc_t)); |
2666 | 2744 |
if (cpc != NULL) { |
2667 |
memcpy(cpc->clk_setup, clk_setup, 7 * sizeof(clk_setup_t)); |
|
2745 |
memcpy(cpc->clk_setup, clk_setup, |
|
2746 |
PPC405EP_CLK_NB * sizeof(clk_setup_t)); |
|
2668 | 2747 |
cpc->jtagid = 0x20267049; |
2669 | 2748 |
cpc->sysclk = sysclk; |
2670 | 2749 |
ppc405ep_cpc_reset(cpc); |
... | ... | |
2690 | 2769 |
|
2691 | 2770 |
CPUState *ppc405ep_init (target_ulong ram_bases[2], target_ulong ram_sizes[2], |
2692 | 2771 |
uint32_t sysclk, qemu_irq **picp, |
2693 |
ram_addr_t *offsetp) |
|
2772 |
ram_addr_t *offsetp, int do_init)
|
|
2694 | 2773 |
{ |
2695 |
clk_setup_t clk_setup[8];
|
|
2774 |
clk_setup_t clk_setup[PPC405EP_CLK_NB];
|
|
2696 | 2775 |
qemu_irq dma_irqs[4]; |
2697 | 2776 |
CPUState *env; |
2698 | 2777 |
ppc4xx_mmio_t *mmio; |
... | ... | |
2702 | 2781 |
|
2703 | 2782 |
memset(clk_setup, 0, sizeof(clk_setup)); |
2704 | 2783 |
/* init CPUs */ |
2705 |
env = ppc405_init("405ep", &clk_setup[0], &clk_setup[1], sysclk); |
|
2784 |
env = ppc405_init("405ep", &clk_setup[PPC405EP_CPU_CLK], |
|
2785 |
&clk_setup[PPC405EP_PLB_CLK], sysclk); |
|
2706 | 2786 |
/* Internal devices init */ |
2707 | 2787 |
/* Memory mapped devices registers */ |
2708 | 2788 |
mmio = ppc4xx_mmio_init(env, 0xEF600000); |
... | ... | |
2721 | 2801 |
pic = ppcuic_init(env, irqs, 0x0C0, 0, 1); |
2722 | 2802 |
*picp = pic; |
2723 | 2803 |
/* SDRAM controller */ |
2724 |
ppc405_sdram_init(env, pic[17], 2, ram_bases, ram_sizes);
|
|
2804 |
ppc405_sdram_init(env, pic[14], 2, ram_bases, ram_sizes, do_init);
|
|
2725 | 2805 |
offset = 0; |
2726 | 2806 |
for (i = 0; i < 2; i++) |
2727 | 2807 |
offset += ram_sizes[i]; |
2728 | 2808 |
/* External bus controller */ |
2729 | 2809 |
ppc405_ebc_init(env); |
2730 | 2810 |
/* DMA controller */ |
2731 |
dma_irqs[0] = pic[5];
|
|
2732 |
dma_irqs[1] = pic[6];
|
|
2733 |
dma_irqs[2] = pic[7];
|
|
2734 |
dma_irqs[3] = pic[8];
|
|
2811 |
dma_irqs[0] = pic[26];
|
|
2812 |
dma_irqs[1] = pic[25];
|
|
2813 |
dma_irqs[2] = pic[24];
|
|
2814 |
dma_irqs[3] = pic[23];
|
|
2735 | 2815 |
ppc405_dma_init(env, dma_irqs); |
2736 | 2816 |
/* IIC controller */ |
2737 | 2817 |
ppc405_i2c_init(env, mmio, 0x500); |
... | ... | |
2739 | 2819 |
ppc405_gpio_init(env, mmio, 0x700); |
2740 | 2820 |
/* Serial ports */ |
2741 | 2821 |
if (serial_hds[0] != NULL) { |
2742 |
ppc405_serial_init(env, mmio, 0x300, pic[0], serial_hds[0]);
|
|
2822 |
ppc405_serial_init(env, mmio, 0x300, pic[31], serial_hds[0]);
|
|
2743 | 2823 |
} |
2744 | 2824 |
if (serial_hds[1] != NULL) { |
2745 |
ppc405_serial_init(env, mmio, 0x400, pic[1], serial_hds[1]);
|
|
2825 |
ppc405_serial_init(env, mmio, 0x400, pic[30], serial_hds[1]);
|
|
2746 | 2826 |
} |
2747 | 2827 |
/* OCM */ |
2748 | 2828 |
ppc405_ocm_init(env, ram_sizes[0] + ram_sizes[1]); |
Also available in: Unified diff