Revision 802670e6 hw/ppc405_uc.c
b/hw/ppc405_uc.c | ||
---|---|---|
164 | 164 |
plb->besr = 0x00000000; |
165 | 165 |
} |
166 | 166 |
|
167 |
void ppc4xx_plb_init (CPUState *env)
|
|
167 |
static void ppc4xx_plb_init(CPUState *env)
|
|
168 | 168 |
{ |
169 | 169 |
ppc4xx_plb_t *plb; |
170 | 170 |
|
... | ... | |
241 | 241 |
pob->besr[1] = 0x0000000; |
242 | 242 |
} |
243 | 243 |
|
244 |
void ppc4xx_pob_init (CPUState *env)
|
|
244 |
static void ppc4xx_pob_init(CPUState *env)
|
|
245 | 245 |
{ |
246 | 246 |
ppc4xx_pob_t *pob; |
247 | 247 |
|
... | ... | |
250 | 250 |
ppc_dcr_register(env, POB0_BESR0, pob, &dcr_read_pob, &dcr_write_pob); |
251 | 251 |
ppc_dcr_register(env, POB0_BESR1, pob, &dcr_read_pob, &dcr_write_pob); |
252 | 252 |
qemu_register_reset(ppc4xx_pob_reset, pob); |
253 |
ppc4xx_pob_reset(env);
|
|
253 |
ppc4xx_pob_reset(pob);
|
|
254 | 254 |
} |
255 | 255 |
|
256 | 256 |
/*****************************************************************************/ |
257 | 257 |
/* OPB arbitrer */ |
258 | 258 |
typedef struct ppc4xx_opba_t ppc4xx_opba_t; |
259 | 259 |
struct ppc4xx_opba_t { |
260 |
target_phys_addr_t base; |
|
261 | 260 |
uint8_t cr; |
262 | 261 |
uint8_t pr; |
263 | 262 |
}; |
... | ... | |
271 | 270 |
printf("%s: addr " PADDRX "\n", __func__, addr); |
272 | 271 |
#endif |
273 | 272 |
opba = opaque; |
274 |
switch (addr - opba->base) {
|
|
273 |
switch (addr) { |
|
275 | 274 |
case 0x00: |
276 | 275 |
ret = opba->cr; |
277 | 276 |
break; |
... | ... | |
295 | 294 |
printf("%s: addr " PADDRX " val %08" PRIx32 "\n", __func__, addr, value); |
296 | 295 |
#endif |
297 | 296 |
opba = opaque; |
298 |
switch (addr - opba->base) {
|
|
297 |
switch (addr) { |
|
299 | 298 |
case 0x00: |
300 | 299 |
opba->cr = value & 0xF8; |
301 | 300 |
break; |
... | ... | |
374 | 373 |
opba->pr = 0x11; |
375 | 374 |
} |
376 | 375 |
|
377 |
void ppc4xx_opba_init (CPUState *env, ppc4xx_mmio_t *mmio, |
|
378 |
target_phys_addr_t offset) |
|
376 |
static void ppc4xx_opba_init(target_phys_addr_t base) |
|
379 | 377 |
{ |
380 | 378 |
ppc4xx_opba_t *opba; |
379 |
int io; |
|
381 | 380 |
|
382 | 381 |
opba = qemu_mallocz(sizeof(ppc4xx_opba_t)); |
383 |
opba->base = offset; |
|
384 | 382 |
#ifdef DEBUG_OPBA |
385 |
printf("%s: offset " PADDRX "\n", __func__, offset);
|
|
383 |
printf("%s: offset " PADDRX "\n", __func__, base);
|
|
386 | 384 |
#endif |
387 |
ppc4xx_mmio_register(env, mmio, offset, 0x002, |
|
388 |
opba_read, opba_write, opba); |
|
389 |
qemu_register_reset(ppc4xx_opba_reset, opba); |
|
385 |
io = cpu_register_io_memory(opba_read, opba_write, opba); |
|
386 |
cpu_register_physical_memory(base, 0x002, io); |
|
390 | 387 |
ppc4xx_opba_reset(opba); |
388 |
qemu_register_reset(ppc4xx_opba_reset, opba); |
|
391 | 389 |
} |
392 | 390 |
|
393 | 391 |
/*****************************************************************************/ |
... | ... | |
574 | 572 |
ebc->cfg = 0x80400000; |
575 | 573 |
} |
576 | 574 |
|
577 |
void ppc405_ebc_init (CPUState *env)
|
|
575 |
static void ppc405_ebc_init(CPUState *env)
|
|
578 | 576 |
{ |
579 | 577 |
ppc4xx_ebc_t *ebc; |
580 | 578 |
|
... | ... | |
665 | 663 |
dma->pol = 0x00000000; |
666 | 664 |
} |
667 | 665 |
|
668 |
void ppc405_dma_init (CPUState *env, qemu_irq irqs[4])
|
|
666 |
static void ppc405_dma_init(CPUState *env, qemu_irq irqs[4])
|
|
669 | 667 |
{ |
670 | 668 |
ppc405_dma_t *dma; |
671 | 669 |
|
... | ... | |
727 | 725 |
/* GPIO */ |
728 | 726 |
typedef struct ppc405_gpio_t ppc405_gpio_t; |
729 | 727 |
struct ppc405_gpio_t { |
730 |
target_phys_addr_t base; |
|
731 | 728 |
uint32_t or; |
732 | 729 |
uint32_t tcr; |
733 | 730 |
uint32_t osrh; |
... | ... | |
829 | 826 |
gpio = opaque; |
830 | 827 |
} |
831 | 828 |
|
832 |
void ppc405_gpio_init (CPUState *env, ppc4xx_mmio_t *mmio, |
|
833 |
target_phys_addr_t offset) |
|
829 |
static void ppc405_gpio_init(target_phys_addr_t base) |
|
834 | 830 |
{ |
835 | 831 |
ppc405_gpio_t *gpio; |
832 |
int io; |
|
836 | 833 |
|
837 | 834 |
gpio = qemu_mallocz(sizeof(ppc405_gpio_t)); |
838 |
gpio->base = offset; |
|
839 |
ppc405_gpio_reset(gpio); |
|
840 |
qemu_register_reset(&ppc405_gpio_reset, gpio); |
|
841 | 835 |
#ifdef DEBUG_GPIO |
842 |
printf("%s: offset " PADDRX "\n", __func__, offset); |
|
843 |
#endif |
|
844 |
ppc4xx_mmio_register(env, mmio, offset, 0x038, |
|
845 |
ppc405_gpio_read, ppc405_gpio_write, gpio); |
|
846 |
} |
|
847 |
|
|
848 |
/*****************************************************************************/ |
|
849 |
/* Serial ports */ |
|
850 |
static CPUReadMemoryFunc *serial_mm_read[] = { |
|
851 |
&serial_mm_readb, |
|
852 |
&serial_mm_readw, |
|
853 |
&serial_mm_readl, |
|
854 |
}; |
|
855 |
|
|
856 |
static CPUWriteMemoryFunc *serial_mm_write[] = { |
|
857 |
&serial_mm_writeb, |
|
858 |
&serial_mm_writew, |
|
859 |
&serial_mm_writel, |
|
860 |
}; |
|
861 |
|
|
862 |
void ppc405_serial_init (CPUState *env, ppc4xx_mmio_t *mmio, |
|
863 |
target_phys_addr_t offset, qemu_irq irq, |
|
864 |
CharDriverState *chr) |
|
865 |
{ |
|
866 |
void *serial; |
|
867 |
|
|
868 |
#ifdef DEBUG_SERIAL |
|
869 |
printf("%s: offset " PADDRX "\n", __func__, offset); |
|
836 |
printf("%s: offset " PADDRX "\n", __func__, base); |
|
870 | 837 |
#endif |
871 |
serial = serial_mm_init(offset, 0, irq, 399193, chr, 0); |
|
872 |
ppc4xx_mmio_register(env, mmio, offset, 0x008, |
|
873 |
serial_mm_read, serial_mm_write, serial); |
|
838 |
io = cpu_register_io_memory(ppc405_gpio_read, ppc405_gpio_write, gpio); |
|
839 |
cpu_register_physical_memory(base, 0x038, io); |
|
840 |
ppc405_gpio_reset(gpio); |
|
841 |
qemu_register_reset(&ppc405_gpio_reset, gpio); |
|
874 | 842 |
} |
875 | 843 |
|
876 | 844 |
/*****************************************************************************/ |
... | ... | |
1021 | 989 |
ocm->dsacntl = dsacntl; |
1022 | 990 |
} |
1023 | 991 |
|
1024 |
void ppc405_ocm_init (CPUState *env)
|
|
992 |
static void ppc405_ocm_init(CPUState *env)
|
|
1025 | 993 |
{ |
1026 | 994 |
ppc405_ocm_t *ocm; |
1027 | 995 |
|
... | ... | |
1043 | 1011 |
/* I2C controller */ |
1044 | 1012 |
typedef struct ppc4xx_i2c_t ppc4xx_i2c_t; |
1045 | 1013 |
struct ppc4xx_i2c_t { |
1046 |
target_phys_addr_t base; |
|
1047 | 1014 |
qemu_irq irq; |
1048 | 1015 |
uint8_t mdata; |
1049 | 1016 |
uint8_t lmadr; |
... | ... | |
1071 | 1038 |
printf("%s: addr " PADDRX "\n", __func__, addr); |
1072 | 1039 |
#endif |
1073 | 1040 |
i2c = opaque; |
1074 |
switch (addr - i2c->base) {
|
|
1041 |
switch (addr) { |
|
1075 | 1042 |
case 0x00: |
1076 | 1043 |
// i2c_readbyte(&i2c->mdata); |
1077 | 1044 |
ret = i2c->mdata; |
... | ... | |
1138 | 1105 |
printf("%s: addr " PADDRX " val %08" PRIx32 "\n", __func__, addr, value); |
1139 | 1106 |
#endif |
1140 | 1107 |
i2c = opaque; |
1141 |
switch (addr - i2c->base) {
|
|
1108 |
switch (addr) { |
|
1142 | 1109 |
case 0x00: |
1143 | 1110 |
i2c->mdata = value; |
1144 | 1111 |
// i2c_sendbyte(&i2c->mdata); |
... | ... | |
1266 | 1233 |
i2c->directcntl = 0x0F; |
1267 | 1234 |
} |
1268 | 1235 |
|
1269 |
void ppc405_i2c_init (CPUState *env, ppc4xx_mmio_t *mmio, |
|
1270 |
target_phys_addr_t offset, qemu_irq irq) |
|
1236 |
static void ppc405_i2c_init(target_phys_addr_t base, qemu_irq irq) |
|
1271 | 1237 |
{ |
1272 | 1238 |
ppc4xx_i2c_t *i2c; |
1239 |
int io; |
|
1273 | 1240 |
|
1274 | 1241 |
i2c = qemu_mallocz(sizeof(ppc4xx_i2c_t)); |
1275 |
i2c->base = offset; |
|
1276 | 1242 |
i2c->irq = irq; |
1277 |
ppc4xx_i2c_reset(i2c); |
|
1278 | 1243 |
#ifdef DEBUG_I2C |
1279 |
printf("%s: offset " PADDRX "\n", __func__, offset);
|
|
1244 |
printf("%s: offset " PADDRX "\n", __func__, base);
|
|
1280 | 1245 |
#endif |
1281 |
ppc4xx_mmio_register(env, mmio, offset, 0x011, |
|
1282 |
i2c_read, i2c_write, i2c); |
|
1246 |
io = cpu_register_io_memory(i2c_read, i2c_write, i2c); |
|
1247 |
cpu_register_physical_memory(base, 0x011, io); |
|
1248 |
ppc4xx_i2c_reset(i2c); |
|
1283 | 1249 |
qemu_register_reset(ppc4xx_i2c_reset, i2c); |
1284 | 1250 |
} |
1285 | 1251 |
|
... | ... | |
1287 | 1253 |
/* General purpose timers */ |
1288 | 1254 |
typedef struct ppc4xx_gpt_t ppc4xx_gpt_t; |
1289 | 1255 |
struct ppc4xx_gpt_t { |
1290 |
target_phys_addr_t base; |
|
1291 | 1256 |
int64_t tb_offset; |
1292 | 1257 |
uint32_t tb_freq; |
1293 | 1258 |
struct QEMUTimer *timer; |
... | ... | |
1399 | 1364 |
printf("%s: addr " PADDRX "\n", __func__, addr); |
1400 | 1365 |
#endif |
1401 | 1366 |
gpt = opaque; |
1402 |
switch (addr - gpt->base) {
|
|
1367 |
switch (addr) { |
|
1403 | 1368 |
case 0x00: |
1404 | 1369 |
/* Time base counter */ |
1405 | 1370 |
ret = muldiv64(qemu_get_clock(vm_clock) + gpt->tb_offset, |
... | ... | |
1428 | 1393 |
break; |
1429 | 1394 |
case 0x80 ... 0x90: |
1430 | 1395 |
/* Compare timer */ |
1431 |
idx = ((addr - gpt->base) - 0x80) >> 2;
|
|
1396 |
idx = (addr - 0x80) >> 2;
|
|
1432 | 1397 |
ret = gpt->comp[idx]; |
1433 | 1398 |
break; |
1434 | 1399 |
case 0xC0 ... 0xD0: |
1435 | 1400 |
/* Compare mask */ |
1436 |
idx = ((addr - gpt->base) - 0xC0) >> 2;
|
|
1401 |
idx = (addr - 0xC0) >> 2;
|
|
1437 | 1402 |
ret = gpt->mask[idx]; |
1438 | 1403 |
break; |
1439 | 1404 |
default: |
... | ... | |
1454 | 1419 |
printf("%s: addr " PADDRX " val %08" PRIx32 "\n", __func__, addr, value); |
1455 | 1420 |
#endif |
1456 | 1421 |
gpt = opaque; |
1457 |
switch (addr - gpt->base) {
|
|
1422 |
switch (addr) { |
|
1458 | 1423 |
case 0x00: |
1459 | 1424 |
/* Time base counter */ |
1460 | 1425 |
gpt->tb_offset = muldiv64(value, ticks_per_sec, gpt->tb_freq) |
... | ... | |
1492 | 1457 |
break; |
1493 | 1458 |
case 0x80 ... 0x90: |
1494 | 1459 |
/* Compare timer */ |
1495 |
idx = ((addr - gpt->base) - 0x80) >> 2;
|
|
1460 |
idx = (addr - 0x80) >> 2;
|
|
1496 | 1461 |
gpt->comp[idx] = value & 0xF8000000; |
1497 | 1462 |
ppc4xx_gpt_compute_timer(gpt); |
1498 | 1463 |
break; |
1499 | 1464 |
case 0xC0 ... 0xD0: |
1500 | 1465 |
/* Compare mask */ |
1501 |
idx = ((addr - gpt->base) - 0xC0) >> 2;
|
|
1466 |
idx = (addr - 0xC0) >> 2;
|
|
1502 | 1467 |
gpt->mask[idx] = value & 0xF8000000; |
1503 | 1468 |
ppc4xx_gpt_compute_timer(gpt); |
1504 | 1469 |
break; |
... | ... | |
1545 | 1510 |
} |
1546 | 1511 |
} |
1547 | 1512 |
|
1548 |
void ppc4xx_gpt_init (CPUState *env, ppc4xx_mmio_t *mmio, |
|
1549 |
target_phys_addr_t offset, qemu_irq irqs[5]) |
|
1513 |
static void ppc4xx_gpt_init(target_phys_addr_t base, qemu_irq irqs[5]) |
|
1550 | 1514 |
{ |
1551 | 1515 |
ppc4xx_gpt_t *gpt; |
1552 | 1516 |
int i; |
1517 |
int io; |
|
1553 | 1518 |
|
1554 | 1519 |
gpt = qemu_mallocz(sizeof(ppc4xx_gpt_t)); |
1555 |
gpt->base = offset; |
|
1556 |
for (i = 0; i < 5; i++) |
|
1520 |
for (i = 0; i < 5; i++) { |
|
1557 | 1521 |
gpt->irqs[i] = irqs[i]; |
1522 |
} |
|
1558 | 1523 |
gpt->timer = qemu_new_timer(vm_clock, &ppc4xx_gpt_cb, gpt); |
1559 |
ppc4xx_gpt_reset(gpt); |
|
1560 | 1524 |
#ifdef DEBUG_GPT |
1561 |
printf("%s: offset " PADDRX "\n", __func__, offset);
|
|
1525 |
printf("%s: offset " PADDRX "\n", __func__, base);
|
|
1562 | 1526 |
#endif |
1563 |
ppc4xx_mmio_register(env, mmio, offset, 0x0D4,
|
|
1564 |
gpt_read, gpt_write, gpt);
|
|
1527 |
io = cpu_register_io_memory(gpt_read, gpt_write, gpt);
|
|
1528 |
cpu_register_physical_memory(base, 0x0d4, io);
|
|
1565 | 1529 |
qemu_register_reset(ppc4xx_gpt_reset, gpt); |
1530 |
ppc4xx_gpt_reset(gpt); |
|
1566 | 1531 |
} |
1567 | 1532 |
|
1568 | 1533 |
/*****************************************************************************/ |
... | ... | |
1778 | 1743 |
mal->txeobisr = 0x00000000; |
1779 | 1744 |
} |
1780 | 1745 |
|
1781 |
void ppc405_mal_init (CPUState *env, qemu_irq irqs[4])
|
|
1746 |
static void ppc405_mal_init(CPUState *env, qemu_irq irqs[4])
|
|
1782 | 1747 |
{ |
1783 | 1748 |
ppc40x_mal_t *mal; |
1784 | 1749 |
int i; |
... | ... | |
2183 | 2148 |
clk_setup_t clk_setup[PPC405CR_CLK_NB]; |
2184 | 2149 |
qemu_irq dma_irqs[4]; |
2185 | 2150 |
CPUState *env; |
2186 |
ppc4xx_mmio_t *mmio; |
|
2187 | 2151 |
qemu_irq *pic, *irqs; |
2188 | 2152 |
|
2189 | 2153 |
memset(clk_setup, 0, sizeof(clk_setup)); |
2190 | 2154 |
env = ppc4xx_init("405cr", &clk_setup[PPC405CR_CPU_CLK], |
2191 | 2155 |
&clk_setup[PPC405CR_TMR_CLK], sysclk); |
2192 | 2156 |
/* Memory mapped devices registers */ |
2193 |
mmio = ppc4xx_mmio_init(env, 0xEF600000); |
|
2194 | 2157 |
/* PLB arbitrer */ |
2195 | 2158 |
ppc4xx_plb_init(env); |
2196 | 2159 |
/* PLB to OPB bridge */ |
2197 | 2160 |
ppc4xx_pob_init(env); |
2198 | 2161 |
/* OBP arbitrer */ |
2199 |
ppc4xx_opba_init(env, mmio, 0x600);
|
|
2162 |
ppc4xx_opba_init(0xef600600);
|
|
2200 | 2163 |
/* Universal interrupt controller */ |
2201 | 2164 |
irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB); |
2202 | 2165 |
irqs[PPCUIC_OUTPUT_INT] = |
... | ... | |
2217 | 2180 |
ppc405_dma_init(env, dma_irqs); |
2218 | 2181 |
/* Serial ports */ |
2219 | 2182 |
if (serial_hds[0] != NULL) { |
2220 |
ppc405_serial_init(env, mmio, 0x300, pic[0], serial_hds[0]); |
|
2183 |
serial_mm_init(0xef600300, 0, pic[0], PPC_SERIAL_MM_BAUDBASE, |
|
2184 |
serial_hds[0], 1); |
|
2221 | 2185 |
} |
2222 | 2186 |
if (serial_hds[1] != NULL) { |
2223 |
ppc405_serial_init(env, mmio, 0x400, pic[1], serial_hds[1]); |
|
2187 |
serial_mm_init(0xef600400, 0, pic[1], PPC_SERIAL_MM_BAUDBASE, |
|
2188 |
serial_hds[1], 1); |
|
2224 | 2189 |
} |
2225 | 2190 |
/* IIC controller */ |
2226 |
ppc405_i2c_init(env, mmio, 0x500, pic[2]);
|
|
2191 |
ppc405_i2c_init(0xef600500, pic[2]);
|
|
2227 | 2192 |
/* GPIO */ |
2228 |
ppc405_gpio_init(env, mmio, 0x700);
|
|
2193 |
ppc405_gpio_init(0xef600700);
|
|
2229 | 2194 |
/* CPU control */ |
2230 | 2195 |
ppc405cr_cpc_init(env, clk_setup, sysclk); |
2231 | 2196 |
|
... | ... | |
2528 | 2493 |
clk_setup_t clk_setup[PPC405EP_CLK_NB], tlb_clk_setup; |
2529 | 2494 |
qemu_irq dma_irqs[4], gpt_irqs[5], mal_irqs[4]; |
2530 | 2495 |
CPUState *env; |
2531 |
ppc4xx_mmio_t *mmio; |
|
2532 | 2496 |
qemu_irq *pic, *irqs; |
2533 | 2497 |
|
2534 | 2498 |
memset(clk_setup, 0, sizeof(clk_setup)); |
... | ... | |
2539 | 2503 |
clk_setup[PPC405EP_CPU_CLK].opaque = tlb_clk_setup.opaque; |
2540 | 2504 |
/* Internal devices init */ |
2541 | 2505 |
/* Memory mapped devices registers */ |
2542 |
mmio = ppc4xx_mmio_init(env, 0xEF600000); |
|
2543 | 2506 |
/* PLB arbitrer */ |
2544 | 2507 |
ppc4xx_plb_init(env); |
2545 | 2508 |
/* PLB to OPB bridge */ |
2546 | 2509 |
ppc4xx_pob_init(env); |
2547 | 2510 |
/* OBP arbitrer */ |
2548 |
ppc4xx_opba_init(env, mmio, 0x600);
|
|
2511 |
ppc4xx_opba_init(0xef600600);
|
|
2549 | 2512 |
/* Universal interrupt controller */ |
2550 | 2513 |
irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB); |
2551 | 2514 |
irqs[PPCUIC_OUTPUT_INT] = |
... | ... | |
2566 | 2529 |
dma_irqs[3] = pic[8]; |
2567 | 2530 |
ppc405_dma_init(env, dma_irqs); |
2568 | 2531 |
/* IIC controller */ |
2569 |
ppc405_i2c_init(env, mmio, 0x500, pic[2]);
|
|
2532 |
ppc405_i2c_init(0xef600500, pic[2]);
|
|
2570 | 2533 |
/* GPIO */ |
2571 |
ppc405_gpio_init(env, mmio, 0x700);
|
|
2534 |
ppc405_gpio_init(0xef600700);
|
|
2572 | 2535 |
/* Serial ports */ |
2573 | 2536 |
if (serial_hds[0] != NULL) { |
2574 |
ppc405_serial_init(env, mmio, 0x300, pic[0], serial_hds[0]); |
|
2537 |
serial_mm_init(0xef600300, 0, pic[0], PPC_SERIAL_MM_BAUDBASE, |
|
2538 |
serial_hds[0], 1); |
|
2575 | 2539 |
} |
2576 | 2540 |
if (serial_hds[1] != NULL) { |
2577 |
ppc405_serial_init(env, mmio, 0x400, pic[1], serial_hds[1]); |
|
2541 |
serial_mm_init(0xef600400, 0, pic[1], PPC_SERIAL_MM_BAUDBASE, |
|
2542 |
serial_hds[1], 1); |
|
2578 | 2543 |
} |
2579 | 2544 |
/* OCM */ |
2580 | 2545 |
ppc405_ocm_init(env); |
... | ... | |
2584 | 2549 |
gpt_irqs[2] = pic[21]; |
2585 | 2550 |
gpt_irqs[3] = pic[22]; |
2586 | 2551 |
gpt_irqs[4] = pic[23]; |
2587 |
ppc4xx_gpt_init(env, mmio, 0x000, gpt_irqs);
|
|
2552 |
ppc4xx_gpt_init(0xef600000, gpt_irqs);
|
|
2588 | 2553 |
/* PCI */ |
2589 | 2554 |
/* Uses pic[3], pic[16], pic[18] */ |
2590 | 2555 |
/* MAL */ |
Also available in: Unified diff