xref: /qemu/hw/ppc/ppc440_uc.c (revision 6a9938a3797a6008ee54bf4ec9b41973c1efc3b9)
158d5b22bSBALATON Zoltan /*
258d5b22bSBALATON Zoltan  * QEMU PowerPC 440 embedded processors emulation
358d5b22bSBALATON Zoltan  *
458d5b22bSBALATON Zoltan  * Copyright (c) 2012 François Revol
5*6a9938a3SBALATON Zoltan  * Copyright (c) 2016-2019 BALATON Zoltan
658d5b22bSBALATON Zoltan  *
758d5b22bSBALATON Zoltan  * This work is licensed under the GNU GPL license version 2 or later.
858d5b22bSBALATON Zoltan  *
958d5b22bSBALATON Zoltan  */
1058d5b22bSBALATON Zoltan 
1158d5b22bSBALATON Zoltan #include "qemu/osdep.h"
12fc6b3cf9SPhilippe Mathieu-Daudé #include "qemu/units.h"
1358d5b22bSBALATON Zoltan #include "qemu-common.h"
1458d5b22bSBALATON Zoltan #include "qemu/error-report.h"
1558d5b22bSBALATON Zoltan #include "qapi/error.h"
163c409c19SBALATON Zoltan #include "qemu/log.h"
1758d5b22bSBALATON Zoltan #include "cpu.h"
1858d5b22bSBALATON Zoltan #include "hw/hw.h"
1958d5b22bSBALATON Zoltan #include "exec/address-spaces.h"
2058d5b22bSBALATON Zoltan #include "exec/memory.h"
2158d5b22bSBALATON Zoltan #include "hw/ppc/ppc.h"
2258d5b22bSBALATON Zoltan #include "hw/pci/pci.h"
2358d5b22bSBALATON Zoltan #include "sysemu/block-backend.h"
2472a56a1fSMichael S. Tsirkin #include "ppc440.h"
2558d5b22bSBALATON Zoltan 
2658d5b22bSBALATON Zoltan /*****************************************************************************/
2758d5b22bSBALATON Zoltan /* L2 Cache as SRAM */
2858d5b22bSBALATON Zoltan /* FIXME:fix names */
2958d5b22bSBALATON Zoltan enum {
3058d5b22bSBALATON Zoltan     DCR_L2CACHE_BASE  = 0x30,
3158d5b22bSBALATON Zoltan     DCR_L2CACHE_CFG   = DCR_L2CACHE_BASE,
3258d5b22bSBALATON Zoltan     DCR_L2CACHE_CMD,
3358d5b22bSBALATON Zoltan     DCR_L2CACHE_ADDR,
3458d5b22bSBALATON Zoltan     DCR_L2CACHE_DATA,
3558d5b22bSBALATON Zoltan     DCR_L2CACHE_STAT,
3658d5b22bSBALATON Zoltan     DCR_L2CACHE_CVER,
3758d5b22bSBALATON Zoltan     DCR_L2CACHE_SNP0,
3858d5b22bSBALATON Zoltan     DCR_L2CACHE_SNP1,
3958d5b22bSBALATON Zoltan     DCR_L2CACHE_END   = DCR_L2CACHE_SNP1,
4058d5b22bSBALATON Zoltan };
4158d5b22bSBALATON Zoltan 
4258d5b22bSBALATON Zoltan /* base is 460ex-specific, cf. U-Boot, ppc4xx-isram.h */
4358d5b22bSBALATON Zoltan enum {
4458d5b22bSBALATON Zoltan     DCR_ISRAM0_BASE   = 0x20,
4558d5b22bSBALATON Zoltan     DCR_ISRAM0_SB0CR  = DCR_ISRAM0_BASE,
4658d5b22bSBALATON Zoltan     DCR_ISRAM0_SB1CR,
4758d5b22bSBALATON Zoltan     DCR_ISRAM0_SB2CR,
4858d5b22bSBALATON Zoltan     DCR_ISRAM0_SB3CR,
4958d5b22bSBALATON Zoltan     DCR_ISRAM0_BEAR,
5058d5b22bSBALATON Zoltan     DCR_ISRAM0_BESR0,
5158d5b22bSBALATON Zoltan     DCR_ISRAM0_BESR1,
5258d5b22bSBALATON Zoltan     DCR_ISRAM0_PMEG,
5358d5b22bSBALATON Zoltan     DCR_ISRAM0_CID,
5458d5b22bSBALATON Zoltan     DCR_ISRAM0_REVID,
5558d5b22bSBALATON Zoltan     DCR_ISRAM0_DPC,
5658d5b22bSBALATON Zoltan     DCR_ISRAM0_END    = DCR_ISRAM0_DPC
5758d5b22bSBALATON Zoltan };
5858d5b22bSBALATON Zoltan 
5958d5b22bSBALATON Zoltan enum {
6058d5b22bSBALATON Zoltan     DCR_ISRAM1_BASE   = 0xb0,
6158d5b22bSBALATON Zoltan     DCR_ISRAM1_SB0CR  = DCR_ISRAM1_BASE,
6258d5b22bSBALATON Zoltan     /* single bank */
6358d5b22bSBALATON Zoltan     DCR_ISRAM1_BEAR   = DCR_ISRAM1_BASE + 0x04,
6458d5b22bSBALATON Zoltan     DCR_ISRAM1_BESR0,
6558d5b22bSBALATON Zoltan     DCR_ISRAM1_BESR1,
6658d5b22bSBALATON Zoltan     DCR_ISRAM1_PMEG,
6758d5b22bSBALATON Zoltan     DCR_ISRAM1_CID,
6858d5b22bSBALATON Zoltan     DCR_ISRAM1_REVID,
6958d5b22bSBALATON Zoltan     DCR_ISRAM1_DPC,
7058d5b22bSBALATON Zoltan     DCR_ISRAM1_END    = DCR_ISRAM1_DPC
7158d5b22bSBALATON Zoltan };
7258d5b22bSBALATON Zoltan 
7358d5b22bSBALATON Zoltan typedef struct ppc4xx_l2sram_t {
7458d5b22bSBALATON Zoltan     MemoryRegion bank[4];
7558d5b22bSBALATON Zoltan     uint32_t l2cache[8];
7658d5b22bSBALATON Zoltan     uint32_t isram0[11];
7758d5b22bSBALATON Zoltan } ppc4xx_l2sram_t;
7858d5b22bSBALATON Zoltan 
7958d5b22bSBALATON Zoltan #ifdef MAP_L2SRAM
8058d5b22bSBALATON Zoltan static void l2sram_update_mappings(ppc4xx_l2sram_t *l2sram,
8158d5b22bSBALATON Zoltan                                    uint32_t isarc, uint32_t isacntl,
8258d5b22bSBALATON Zoltan                                    uint32_t dsarc, uint32_t dsacntl)
8358d5b22bSBALATON Zoltan {
8458d5b22bSBALATON Zoltan     if (l2sram->isarc != isarc ||
8558d5b22bSBALATON Zoltan         (l2sram->isacntl & 0x80000000) != (isacntl & 0x80000000)) {
8658d5b22bSBALATON Zoltan         if (l2sram->isacntl & 0x80000000) {
8758d5b22bSBALATON Zoltan             /* Unmap previously assigned memory region */
8858d5b22bSBALATON Zoltan             memory_region_del_subregion(get_system_memory(),
8958d5b22bSBALATON Zoltan                                         &l2sram->isarc_ram);
9058d5b22bSBALATON Zoltan         }
9158d5b22bSBALATON Zoltan         if (isacntl & 0x80000000) {
9258d5b22bSBALATON Zoltan             /* Map new instruction memory region */
9358d5b22bSBALATON Zoltan             memory_region_add_subregion(get_system_memory(), isarc,
9458d5b22bSBALATON Zoltan                                         &l2sram->isarc_ram);
9558d5b22bSBALATON Zoltan         }
9658d5b22bSBALATON Zoltan     }
9758d5b22bSBALATON Zoltan     if (l2sram->dsarc != dsarc ||
9858d5b22bSBALATON Zoltan         (l2sram->dsacntl & 0x80000000) != (dsacntl & 0x80000000)) {
9958d5b22bSBALATON Zoltan         if (l2sram->dsacntl & 0x80000000) {
10058d5b22bSBALATON Zoltan             /* Beware not to unmap the region we just mapped */
10158d5b22bSBALATON Zoltan             if (!(isacntl & 0x80000000) || l2sram->dsarc != isarc) {
10258d5b22bSBALATON Zoltan                 /* Unmap previously assigned memory region */
10358d5b22bSBALATON Zoltan                 memory_region_del_subregion(get_system_memory(),
10458d5b22bSBALATON Zoltan                                             &l2sram->dsarc_ram);
10558d5b22bSBALATON Zoltan             }
10658d5b22bSBALATON Zoltan         }
10758d5b22bSBALATON Zoltan         if (dsacntl & 0x80000000) {
10858d5b22bSBALATON Zoltan             /* Beware not to remap the region we just mapped */
10958d5b22bSBALATON Zoltan             if (!(isacntl & 0x80000000) || dsarc != isarc) {
11058d5b22bSBALATON Zoltan                 /* Map new data memory region */
11158d5b22bSBALATON Zoltan                 memory_region_add_subregion(get_system_memory(), dsarc,
11258d5b22bSBALATON Zoltan                                             &l2sram->dsarc_ram);
11358d5b22bSBALATON Zoltan             }
11458d5b22bSBALATON Zoltan         }
11558d5b22bSBALATON Zoltan     }
11658d5b22bSBALATON Zoltan }
11758d5b22bSBALATON Zoltan #endif
11858d5b22bSBALATON Zoltan 
11958d5b22bSBALATON Zoltan static uint32_t dcr_read_l2sram(void *opaque, int dcrn)
12058d5b22bSBALATON Zoltan {
12158d5b22bSBALATON Zoltan     ppc4xx_l2sram_t *l2sram = opaque;
12258d5b22bSBALATON Zoltan     uint32_t ret = 0;
12358d5b22bSBALATON Zoltan 
12458d5b22bSBALATON Zoltan     switch (dcrn) {
12558d5b22bSBALATON Zoltan     case DCR_L2CACHE_CFG:
12658d5b22bSBALATON Zoltan     case DCR_L2CACHE_CMD:
12758d5b22bSBALATON Zoltan     case DCR_L2CACHE_ADDR:
12858d5b22bSBALATON Zoltan     case DCR_L2CACHE_DATA:
12958d5b22bSBALATON Zoltan     case DCR_L2CACHE_STAT:
13058d5b22bSBALATON Zoltan     case DCR_L2CACHE_CVER:
13158d5b22bSBALATON Zoltan     case DCR_L2CACHE_SNP0:
13258d5b22bSBALATON Zoltan     case DCR_L2CACHE_SNP1:
13358d5b22bSBALATON Zoltan         ret = l2sram->l2cache[dcrn - DCR_L2CACHE_BASE];
13458d5b22bSBALATON Zoltan         break;
13558d5b22bSBALATON Zoltan 
13658d5b22bSBALATON Zoltan     case DCR_ISRAM0_SB0CR:
13758d5b22bSBALATON Zoltan     case DCR_ISRAM0_SB1CR:
13858d5b22bSBALATON Zoltan     case DCR_ISRAM0_SB2CR:
13958d5b22bSBALATON Zoltan     case DCR_ISRAM0_SB3CR:
14058d5b22bSBALATON Zoltan     case DCR_ISRAM0_BEAR:
14158d5b22bSBALATON Zoltan     case DCR_ISRAM0_BESR0:
14258d5b22bSBALATON Zoltan     case DCR_ISRAM0_BESR1:
14358d5b22bSBALATON Zoltan     case DCR_ISRAM0_PMEG:
14458d5b22bSBALATON Zoltan     case DCR_ISRAM0_CID:
14558d5b22bSBALATON Zoltan     case DCR_ISRAM0_REVID:
14658d5b22bSBALATON Zoltan     case DCR_ISRAM0_DPC:
14758d5b22bSBALATON Zoltan         ret = l2sram->isram0[dcrn - DCR_ISRAM0_BASE];
14858d5b22bSBALATON Zoltan         break;
14958d5b22bSBALATON Zoltan 
15058d5b22bSBALATON Zoltan     default:
15158d5b22bSBALATON Zoltan         break;
15258d5b22bSBALATON Zoltan     }
15358d5b22bSBALATON Zoltan 
15458d5b22bSBALATON Zoltan     return ret;
15558d5b22bSBALATON Zoltan }
15658d5b22bSBALATON Zoltan 
15758d5b22bSBALATON Zoltan static void dcr_write_l2sram(void *opaque, int dcrn, uint32_t val)
15858d5b22bSBALATON Zoltan {
15958d5b22bSBALATON Zoltan     /*ppc4xx_l2sram_t *l2sram = opaque;*/
16058d5b22bSBALATON Zoltan     /* FIXME: Actually handle L2 cache mapping */
16158d5b22bSBALATON Zoltan 
16258d5b22bSBALATON Zoltan     switch (dcrn) {
16358d5b22bSBALATON Zoltan     case DCR_L2CACHE_CFG:
16458d5b22bSBALATON Zoltan     case DCR_L2CACHE_CMD:
16558d5b22bSBALATON Zoltan     case DCR_L2CACHE_ADDR:
16658d5b22bSBALATON Zoltan     case DCR_L2CACHE_DATA:
16758d5b22bSBALATON Zoltan     case DCR_L2CACHE_STAT:
16858d5b22bSBALATON Zoltan     case DCR_L2CACHE_CVER:
16958d5b22bSBALATON Zoltan     case DCR_L2CACHE_SNP0:
17058d5b22bSBALATON Zoltan     case DCR_L2CACHE_SNP1:
17158d5b22bSBALATON Zoltan         /*l2sram->l2cache[dcrn - DCR_L2CACHE_BASE] = val;*/
17258d5b22bSBALATON Zoltan         break;
17358d5b22bSBALATON Zoltan 
17458d5b22bSBALATON Zoltan     case DCR_ISRAM0_SB0CR:
17558d5b22bSBALATON Zoltan     case DCR_ISRAM0_SB1CR:
17658d5b22bSBALATON Zoltan     case DCR_ISRAM0_SB2CR:
17758d5b22bSBALATON Zoltan     case DCR_ISRAM0_SB3CR:
17858d5b22bSBALATON Zoltan     case DCR_ISRAM0_BEAR:
17958d5b22bSBALATON Zoltan     case DCR_ISRAM0_BESR0:
18058d5b22bSBALATON Zoltan     case DCR_ISRAM0_BESR1:
18158d5b22bSBALATON Zoltan     case DCR_ISRAM0_PMEG:
18258d5b22bSBALATON Zoltan     case DCR_ISRAM0_CID:
18358d5b22bSBALATON Zoltan     case DCR_ISRAM0_REVID:
18458d5b22bSBALATON Zoltan     case DCR_ISRAM0_DPC:
18558d5b22bSBALATON Zoltan         /*l2sram->isram0[dcrn - DCR_L2CACHE_BASE] = val;*/
18658d5b22bSBALATON Zoltan         break;
18758d5b22bSBALATON Zoltan 
18858d5b22bSBALATON Zoltan     case DCR_ISRAM1_SB0CR:
18958d5b22bSBALATON Zoltan     case DCR_ISRAM1_BEAR:
19058d5b22bSBALATON Zoltan     case DCR_ISRAM1_BESR0:
19158d5b22bSBALATON Zoltan     case DCR_ISRAM1_BESR1:
19258d5b22bSBALATON Zoltan     case DCR_ISRAM1_PMEG:
19358d5b22bSBALATON Zoltan     case DCR_ISRAM1_CID:
19458d5b22bSBALATON Zoltan     case DCR_ISRAM1_REVID:
19558d5b22bSBALATON Zoltan     case DCR_ISRAM1_DPC:
19658d5b22bSBALATON Zoltan         /*l2sram->isram1[dcrn - DCR_L2CACHE_BASE] = val;*/
19758d5b22bSBALATON Zoltan         break;
19858d5b22bSBALATON Zoltan     }
19958d5b22bSBALATON Zoltan     /*l2sram_update_mappings(l2sram, isarc, isacntl, dsarc, dsacntl);*/
20058d5b22bSBALATON Zoltan }
20158d5b22bSBALATON Zoltan 
20258d5b22bSBALATON Zoltan static void l2sram_reset(void *opaque)
20358d5b22bSBALATON Zoltan {
20458d5b22bSBALATON Zoltan     ppc4xx_l2sram_t *l2sram = opaque;
20558d5b22bSBALATON Zoltan 
20658d5b22bSBALATON Zoltan     memset(l2sram->l2cache, 0, sizeof(l2sram->l2cache));
20758d5b22bSBALATON Zoltan     l2sram->l2cache[DCR_L2CACHE_STAT - DCR_L2CACHE_BASE] = 0x80000000;
20858d5b22bSBALATON Zoltan     memset(l2sram->isram0, 0, sizeof(l2sram->isram0));
20958d5b22bSBALATON Zoltan     /*l2sram_update_mappings(l2sram, isarc, isacntl, dsarc, dsacntl);*/
21058d5b22bSBALATON Zoltan }
21158d5b22bSBALATON Zoltan 
21258d5b22bSBALATON Zoltan void ppc4xx_l2sram_init(CPUPPCState *env)
21358d5b22bSBALATON Zoltan {
21458d5b22bSBALATON Zoltan     ppc4xx_l2sram_t *l2sram;
21558d5b22bSBALATON Zoltan 
21658d5b22bSBALATON Zoltan     l2sram = g_malloc0(sizeof(*l2sram));
21758d5b22bSBALATON Zoltan     /* XXX: Size is 4*64kB for 460ex, cf. U-Boot, ppc4xx-isram.h */
21858d5b22bSBALATON Zoltan     memory_region_init_ram(&l2sram->bank[0], NULL, "ppc4xx.l2sram_bank0",
219d23b6caaSPhilippe Mathieu-Daudé                            64 * KiB, &error_abort);
22058d5b22bSBALATON Zoltan     memory_region_init_ram(&l2sram->bank[1], NULL, "ppc4xx.l2sram_bank1",
221d23b6caaSPhilippe Mathieu-Daudé                            64 * KiB, &error_abort);
22258d5b22bSBALATON Zoltan     memory_region_init_ram(&l2sram->bank[2], NULL, "ppc4xx.l2sram_bank2",
223d23b6caaSPhilippe Mathieu-Daudé                            64 * KiB, &error_abort);
22458d5b22bSBALATON Zoltan     memory_region_init_ram(&l2sram->bank[3], NULL, "ppc4xx.l2sram_bank3",
225d23b6caaSPhilippe Mathieu-Daudé                            64 * KiB, &error_abort);
22658d5b22bSBALATON Zoltan     qemu_register_reset(&l2sram_reset, l2sram);
22758d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_L2CACHE_CFG,
22858d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
22958d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_L2CACHE_CMD,
23058d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
23158d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_L2CACHE_ADDR,
23258d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
23358d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_L2CACHE_DATA,
23458d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
23558d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_L2CACHE_STAT,
23658d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
23758d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_L2CACHE_CVER,
23858d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
23958d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_L2CACHE_SNP0,
24058d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
24158d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_L2CACHE_SNP1,
24258d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
24358d5b22bSBALATON Zoltan 
24458d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM0_SB0CR,
24558d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
24658d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM0_SB1CR,
24758d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
24858d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM0_SB2CR,
24958d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
25058d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM0_SB3CR,
25158d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
25258d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM0_PMEG,
25358d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
25458d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM0_DPC,
25558d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
25658d5b22bSBALATON Zoltan 
25758d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM1_SB0CR,
25858d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
25958d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM1_PMEG,
26058d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
26158d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM1_DPC,
26258d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
26358d5b22bSBALATON Zoltan }
26458d5b22bSBALATON Zoltan 
26558d5b22bSBALATON Zoltan /*****************************************************************************/
26658d5b22bSBALATON Zoltan /* Clocking Power on Reset */
26758d5b22bSBALATON Zoltan enum {
26858d5b22bSBALATON Zoltan     CPR0_CFGADDR = 0xC,
26958d5b22bSBALATON Zoltan     CPR0_CFGDATA = 0xD,
27058d5b22bSBALATON Zoltan 
27158d5b22bSBALATON Zoltan     CPR0_PLLD = 0x060,
27258d5b22bSBALATON Zoltan     CPR0_PLBED = 0x080,
27358d5b22bSBALATON Zoltan     CPR0_OPBD = 0x0C0,
27458d5b22bSBALATON Zoltan     CPR0_PERD = 0x0E0,
27558d5b22bSBALATON Zoltan     CPR0_AHBD = 0x100,
27658d5b22bSBALATON Zoltan };
27758d5b22bSBALATON Zoltan 
27858d5b22bSBALATON Zoltan typedef struct ppc4xx_cpr_t {
27958d5b22bSBALATON Zoltan     uint32_t addr;
28058d5b22bSBALATON Zoltan } ppc4xx_cpr_t;
28158d5b22bSBALATON Zoltan 
28258d5b22bSBALATON Zoltan static uint32_t dcr_read_cpr(void *opaque, int dcrn)
28358d5b22bSBALATON Zoltan {
28458d5b22bSBALATON Zoltan     ppc4xx_cpr_t *cpr = opaque;
28558d5b22bSBALATON Zoltan     uint32_t ret = 0;
28658d5b22bSBALATON Zoltan 
28758d5b22bSBALATON Zoltan     switch (dcrn) {
28858d5b22bSBALATON Zoltan     case CPR0_CFGADDR:
28958d5b22bSBALATON Zoltan         ret = cpr->addr;
29058d5b22bSBALATON Zoltan         break;
29158d5b22bSBALATON Zoltan     case CPR0_CFGDATA:
29258d5b22bSBALATON Zoltan         switch (cpr->addr) {
29358d5b22bSBALATON Zoltan         case CPR0_PLLD:
29458d5b22bSBALATON Zoltan             ret = (0xb5 << 24) | (1 << 16) | (9 << 8);
29558d5b22bSBALATON Zoltan             break;
29658d5b22bSBALATON Zoltan         case CPR0_PLBED:
29758d5b22bSBALATON Zoltan             ret = (5 << 24);
29858d5b22bSBALATON Zoltan             break;
29958d5b22bSBALATON Zoltan         case CPR0_OPBD:
30058d5b22bSBALATON Zoltan             ret = (2 << 24);
30158d5b22bSBALATON Zoltan             break;
30258d5b22bSBALATON Zoltan         case CPR0_PERD:
30358d5b22bSBALATON Zoltan         case CPR0_AHBD:
30458d5b22bSBALATON Zoltan             ret = (1 << 24);
30558d5b22bSBALATON Zoltan             break;
30658d5b22bSBALATON Zoltan         default:
30758d5b22bSBALATON Zoltan             break;
30858d5b22bSBALATON Zoltan         }
30958d5b22bSBALATON Zoltan         break;
31058d5b22bSBALATON Zoltan     default:
31158d5b22bSBALATON Zoltan         break;
31258d5b22bSBALATON Zoltan     }
31358d5b22bSBALATON Zoltan 
31458d5b22bSBALATON Zoltan     return ret;
31558d5b22bSBALATON Zoltan }
31658d5b22bSBALATON Zoltan 
31758d5b22bSBALATON Zoltan static void dcr_write_cpr(void *opaque, int dcrn, uint32_t val)
31858d5b22bSBALATON Zoltan {
31958d5b22bSBALATON Zoltan     ppc4xx_cpr_t *cpr = opaque;
32058d5b22bSBALATON Zoltan 
32158d5b22bSBALATON Zoltan     switch (dcrn) {
32258d5b22bSBALATON Zoltan     case CPR0_CFGADDR:
32358d5b22bSBALATON Zoltan         cpr->addr = val;
32458d5b22bSBALATON Zoltan         break;
32558d5b22bSBALATON Zoltan     case CPR0_CFGDATA:
32658d5b22bSBALATON Zoltan         break;
32758d5b22bSBALATON Zoltan     default:
32858d5b22bSBALATON Zoltan         break;
32958d5b22bSBALATON Zoltan     }
33058d5b22bSBALATON Zoltan }
33158d5b22bSBALATON Zoltan 
33258d5b22bSBALATON Zoltan static void ppc4xx_cpr_reset(void *opaque)
33358d5b22bSBALATON Zoltan {
33458d5b22bSBALATON Zoltan     ppc4xx_cpr_t *cpr = opaque;
33558d5b22bSBALATON Zoltan 
33658d5b22bSBALATON Zoltan     cpr->addr = 0;
33758d5b22bSBALATON Zoltan }
33858d5b22bSBALATON Zoltan 
33958d5b22bSBALATON Zoltan void ppc4xx_cpr_init(CPUPPCState *env)
34058d5b22bSBALATON Zoltan {
34158d5b22bSBALATON Zoltan     ppc4xx_cpr_t *cpr;
34258d5b22bSBALATON Zoltan 
34358d5b22bSBALATON Zoltan     cpr = g_malloc0(sizeof(*cpr));
34458d5b22bSBALATON Zoltan     ppc_dcr_register(env, CPR0_CFGADDR, cpr, &dcr_read_cpr, &dcr_write_cpr);
34558d5b22bSBALATON Zoltan     ppc_dcr_register(env, CPR0_CFGDATA, cpr, &dcr_read_cpr, &dcr_write_cpr);
34658d5b22bSBALATON Zoltan     qemu_register_reset(ppc4xx_cpr_reset, cpr);
34758d5b22bSBALATON Zoltan }
34858d5b22bSBALATON Zoltan 
34958d5b22bSBALATON Zoltan /*****************************************************************************/
35058d5b22bSBALATON Zoltan /* System DCRs */
35158d5b22bSBALATON Zoltan typedef struct ppc4xx_sdr_t ppc4xx_sdr_t;
35258d5b22bSBALATON Zoltan struct ppc4xx_sdr_t {
35358d5b22bSBALATON Zoltan     uint32_t addr;
35458d5b22bSBALATON Zoltan };
35558d5b22bSBALATON Zoltan 
35658d5b22bSBALATON Zoltan enum {
35758d5b22bSBALATON Zoltan     SDR0_CFGADDR = 0x00e,
35858d5b22bSBALATON Zoltan     SDR0_CFGDATA,
35958d5b22bSBALATON Zoltan     SDR0_STRP0 = 0x020,
36058d5b22bSBALATON Zoltan     SDR0_STRP1,
36158d5b22bSBALATON Zoltan     SDR0_102 = 0x66,
36258d5b22bSBALATON Zoltan     SDR0_103,
36358d5b22bSBALATON Zoltan     SDR0_128 = 0x80,
36458d5b22bSBALATON Zoltan     SDR0_ECID3 = 0x083,
36558d5b22bSBALATON Zoltan     SDR0_DDR0 = 0x0e1,
36658d5b22bSBALATON Zoltan     SDR0_USB0 = 0x320,
36758d5b22bSBALATON Zoltan };
36858d5b22bSBALATON Zoltan 
36958d5b22bSBALATON Zoltan enum {
37058d5b22bSBALATON Zoltan     PESDR0_LOOP = 0x303,
37158d5b22bSBALATON Zoltan     PESDR0_RCSSET,
37258d5b22bSBALATON Zoltan     PESDR0_RCSSTS,
37358d5b22bSBALATON Zoltan     PESDR0_RSTSTA = 0x310,
37458d5b22bSBALATON Zoltan     PESDR1_LOOP = 0x343,
37558d5b22bSBALATON Zoltan     PESDR1_RCSSET,
37658d5b22bSBALATON Zoltan     PESDR1_RCSSTS,
37758d5b22bSBALATON Zoltan     PESDR1_RSTSTA = 0x365,
37858d5b22bSBALATON Zoltan };
37958d5b22bSBALATON Zoltan 
38058d5b22bSBALATON Zoltan #define SDR0_DDR0_DDRM_ENCODE(n)  ((((unsigned long)(n)) & 0x03) << 29)
38158d5b22bSBALATON Zoltan #define SDR0_DDR0_DDRM_DDR1       0x20000000
38258d5b22bSBALATON Zoltan #define SDR0_DDR0_DDRM_DDR2       0x40000000
38358d5b22bSBALATON Zoltan 
38458d5b22bSBALATON Zoltan static uint32_t dcr_read_sdr(void *opaque, int dcrn)
38558d5b22bSBALATON Zoltan {
38658d5b22bSBALATON Zoltan     ppc4xx_sdr_t *sdr = opaque;
38758d5b22bSBALATON Zoltan     uint32_t ret = 0;
38858d5b22bSBALATON Zoltan 
38958d5b22bSBALATON Zoltan     switch (dcrn) {
39058d5b22bSBALATON Zoltan     case SDR0_CFGADDR:
39158d5b22bSBALATON Zoltan         ret = sdr->addr;
39258d5b22bSBALATON Zoltan         break;
39358d5b22bSBALATON Zoltan     case SDR0_CFGDATA:
39458d5b22bSBALATON Zoltan         switch (sdr->addr) {
39558d5b22bSBALATON Zoltan         case SDR0_STRP0:
396f8815532SBALATON Zoltan             ret = (0xb5 << 8) | (1 << 4) | 9;
39758d5b22bSBALATON Zoltan             break;
39858d5b22bSBALATON Zoltan         case SDR0_STRP1:
39958d5b22bSBALATON Zoltan             ret = (5 << 29) | (2 << 26) | (1 << 24);
40058d5b22bSBALATON Zoltan             break;
40158d5b22bSBALATON Zoltan         case SDR0_ECID3:
40258d5b22bSBALATON Zoltan             ret = 1 << 20; /* No Security/Kasumi support */
40358d5b22bSBALATON Zoltan             break;
40458d5b22bSBALATON Zoltan         case SDR0_DDR0:
40558d5b22bSBALATON Zoltan             ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1;
40658d5b22bSBALATON Zoltan             break;
40758d5b22bSBALATON Zoltan         case PESDR0_RCSSET:
40858d5b22bSBALATON Zoltan         case PESDR1_RCSSET:
40958d5b22bSBALATON Zoltan             ret = (1 << 24) | (1 << 16);
41058d5b22bSBALATON Zoltan             break;
41158d5b22bSBALATON Zoltan         case PESDR0_RCSSTS:
41258d5b22bSBALATON Zoltan         case PESDR1_RCSSTS:
41358d5b22bSBALATON Zoltan             ret = (1 << 16) | (1 << 12);
41458d5b22bSBALATON Zoltan             break;
41558d5b22bSBALATON Zoltan         case PESDR0_RSTSTA:
41658d5b22bSBALATON Zoltan         case PESDR1_RSTSTA:
41758d5b22bSBALATON Zoltan             ret = 1;
41858d5b22bSBALATON Zoltan             break;
41958d5b22bSBALATON Zoltan         case PESDR0_LOOP:
42058d5b22bSBALATON Zoltan         case PESDR1_LOOP:
42158d5b22bSBALATON Zoltan             ret = 1 << 12;
42258d5b22bSBALATON Zoltan             break;
42358d5b22bSBALATON Zoltan         default:
42458d5b22bSBALATON Zoltan             break;
42558d5b22bSBALATON Zoltan         }
42658d5b22bSBALATON Zoltan         break;
42758d5b22bSBALATON Zoltan     default:
42858d5b22bSBALATON Zoltan         break;
42958d5b22bSBALATON Zoltan     }
43058d5b22bSBALATON Zoltan 
43158d5b22bSBALATON Zoltan     return ret;
43258d5b22bSBALATON Zoltan }
43358d5b22bSBALATON Zoltan 
43458d5b22bSBALATON Zoltan static void dcr_write_sdr(void *opaque, int dcrn, uint32_t val)
43558d5b22bSBALATON Zoltan {
43658d5b22bSBALATON Zoltan     ppc4xx_sdr_t *sdr = opaque;
43758d5b22bSBALATON Zoltan 
43858d5b22bSBALATON Zoltan     switch (dcrn) {
43958d5b22bSBALATON Zoltan     case SDR0_CFGADDR:
44058d5b22bSBALATON Zoltan         sdr->addr = val;
44158d5b22bSBALATON Zoltan         break;
44258d5b22bSBALATON Zoltan     case SDR0_CFGDATA:
44358d5b22bSBALATON Zoltan         switch (sdr->addr) {
44458d5b22bSBALATON Zoltan         case 0x00: /* B0CR */
44558d5b22bSBALATON Zoltan             break;
44658d5b22bSBALATON Zoltan         default:
44758d5b22bSBALATON Zoltan             break;
44858d5b22bSBALATON Zoltan         }
44958d5b22bSBALATON Zoltan         break;
45058d5b22bSBALATON Zoltan     default:
45158d5b22bSBALATON Zoltan         break;
45258d5b22bSBALATON Zoltan     }
45358d5b22bSBALATON Zoltan }
45458d5b22bSBALATON Zoltan 
45558d5b22bSBALATON Zoltan static void sdr_reset(void *opaque)
45658d5b22bSBALATON Zoltan {
45758d5b22bSBALATON Zoltan     ppc4xx_sdr_t *sdr = opaque;
45858d5b22bSBALATON Zoltan 
45958d5b22bSBALATON Zoltan     sdr->addr = 0;
46058d5b22bSBALATON Zoltan }
46158d5b22bSBALATON Zoltan 
46258d5b22bSBALATON Zoltan void ppc4xx_sdr_init(CPUPPCState *env)
46358d5b22bSBALATON Zoltan {
46458d5b22bSBALATON Zoltan     ppc4xx_sdr_t *sdr;
46558d5b22bSBALATON Zoltan 
46658d5b22bSBALATON Zoltan     sdr = g_malloc0(sizeof(*sdr));
46758d5b22bSBALATON Zoltan     qemu_register_reset(&sdr_reset, sdr);
46858d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDR0_CFGADDR,
46958d5b22bSBALATON Zoltan                      sdr, &dcr_read_sdr, &dcr_write_sdr);
47058d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDR0_CFGDATA,
47158d5b22bSBALATON Zoltan                      sdr, &dcr_read_sdr, &dcr_write_sdr);
47258d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDR0_102,
47358d5b22bSBALATON Zoltan                      sdr, &dcr_read_sdr, &dcr_write_sdr);
47458d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDR0_103,
47558d5b22bSBALATON Zoltan                      sdr, &dcr_read_sdr, &dcr_write_sdr);
47658d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDR0_128,
47758d5b22bSBALATON Zoltan                      sdr, &dcr_read_sdr, &dcr_write_sdr);
47858d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDR0_USB0,
47958d5b22bSBALATON Zoltan                      sdr, &dcr_read_sdr, &dcr_write_sdr);
48058d5b22bSBALATON Zoltan }
48158d5b22bSBALATON Zoltan 
48258d5b22bSBALATON Zoltan /*****************************************************************************/
48358d5b22bSBALATON Zoltan /* SDRAM controller */
4840a57fbeeSBALATON Zoltan typedef struct ppc440_sdram_t {
48558d5b22bSBALATON Zoltan     uint32_t addr;
48658d5b22bSBALATON Zoltan     int nbanks;
48758d5b22bSBALATON Zoltan     MemoryRegion containers[4]; /* used for clipping */
48858d5b22bSBALATON Zoltan     MemoryRegion *ram_memories;
48958d5b22bSBALATON Zoltan     hwaddr ram_bases[4];
49058d5b22bSBALATON Zoltan     hwaddr ram_sizes[4];
49158d5b22bSBALATON Zoltan     uint32_t bcr[4];
4920a57fbeeSBALATON Zoltan } ppc440_sdram_t;
49358d5b22bSBALATON Zoltan 
49458d5b22bSBALATON Zoltan enum {
49558d5b22bSBALATON Zoltan     SDRAM0_CFGADDR = 0x10,
49658d5b22bSBALATON Zoltan     SDRAM0_CFGDATA,
49758d5b22bSBALATON Zoltan     SDRAM_R0BAS = 0x40,
49858d5b22bSBALATON Zoltan     SDRAM_R1BAS,
49958d5b22bSBALATON Zoltan     SDRAM_R2BAS,
50058d5b22bSBALATON Zoltan     SDRAM_R3BAS,
50158d5b22bSBALATON Zoltan     SDRAM_CONF1HB = 0x45,
50258d5b22bSBALATON Zoltan     SDRAM_PLBADDULL = 0x4a,
50358d5b22bSBALATON Zoltan     SDRAM_CONF1LL = 0x4b,
50458d5b22bSBALATON Zoltan     SDRAM_CONFPATHB = 0x4f,
50558d5b22bSBALATON Zoltan     SDRAM_PLBADDUHB = 0x50,
50658d5b22bSBALATON Zoltan };
50758d5b22bSBALATON Zoltan 
50858d5b22bSBALATON Zoltan static uint32_t sdram_bcr(hwaddr ram_base, hwaddr ram_size)
50958d5b22bSBALATON Zoltan {
51058d5b22bSBALATON Zoltan     uint32_t bcr;
51158d5b22bSBALATON Zoltan 
51258d5b22bSBALATON Zoltan     switch (ram_size) {
513d23b6caaSPhilippe Mathieu-Daudé     case (8 * MiB):
51458d5b22bSBALATON Zoltan         bcr = 0xffc0;
51558d5b22bSBALATON Zoltan         break;
516d23b6caaSPhilippe Mathieu-Daudé     case (16 * MiB):
51758d5b22bSBALATON Zoltan         bcr = 0xff80;
51858d5b22bSBALATON Zoltan         break;
519d23b6caaSPhilippe Mathieu-Daudé     case (32 * MiB):
52058d5b22bSBALATON Zoltan         bcr = 0xff00;
52158d5b22bSBALATON Zoltan         break;
522d23b6caaSPhilippe Mathieu-Daudé     case (64 * MiB):
52358d5b22bSBALATON Zoltan         bcr = 0xfe00;
52458d5b22bSBALATON Zoltan         break;
525d23b6caaSPhilippe Mathieu-Daudé     case (128 * MiB):
52658d5b22bSBALATON Zoltan         bcr = 0xfc00;
52758d5b22bSBALATON Zoltan         break;
528d23b6caaSPhilippe Mathieu-Daudé     case (256 * MiB):
52958d5b22bSBALATON Zoltan         bcr = 0xf800;
53058d5b22bSBALATON Zoltan         break;
531d23b6caaSPhilippe Mathieu-Daudé     case (512 * MiB):
53258d5b22bSBALATON Zoltan         bcr = 0xf000;
53358d5b22bSBALATON Zoltan         break;
534d23b6caaSPhilippe Mathieu-Daudé     case (1 * GiB):
53558d5b22bSBALATON Zoltan         bcr = 0xe000;
53658d5b22bSBALATON Zoltan         break;
537*6a9938a3SBALATON Zoltan     case (2 * GiB):
538*6a9938a3SBALATON Zoltan         bcr = 0xc000;
539*6a9938a3SBALATON Zoltan         break;
540*6a9938a3SBALATON Zoltan     case (4 * GiB):
541*6a9938a3SBALATON Zoltan         bcr = 0x8000;
542*6a9938a3SBALATON Zoltan         break;
54358d5b22bSBALATON Zoltan     default:
54458d5b22bSBALATON Zoltan         error_report("invalid RAM size " TARGET_FMT_plx, ram_size);
54558d5b22bSBALATON Zoltan         return 0;
54658d5b22bSBALATON Zoltan     }
547*6a9938a3SBALATON Zoltan     bcr |= ram_base >> 2 & 0xffe00000;
54858d5b22bSBALATON Zoltan     bcr |= 1;
54958d5b22bSBALATON Zoltan 
55058d5b22bSBALATON Zoltan     return bcr;
55158d5b22bSBALATON Zoltan }
55258d5b22bSBALATON Zoltan 
55358d5b22bSBALATON Zoltan static inline hwaddr sdram_base(uint32_t bcr)
55458d5b22bSBALATON Zoltan {
555*6a9938a3SBALATON Zoltan     return (bcr & 0xffe00000) << 2;
55658d5b22bSBALATON Zoltan }
55758d5b22bSBALATON Zoltan 
558*6a9938a3SBALATON Zoltan static uint64_t sdram_size(uint32_t bcr)
55958d5b22bSBALATON Zoltan {
560*6a9938a3SBALATON Zoltan     uint64_t size;
56158d5b22bSBALATON Zoltan     int sh;
56258d5b22bSBALATON Zoltan 
56358d5b22bSBALATON Zoltan     sh = 1024 - ((bcr >> 6) & 0x3ff);
564d23b6caaSPhilippe Mathieu-Daudé     size = 8 * MiB * sh;
56558d5b22bSBALATON Zoltan 
56658d5b22bSBALATON Zoltan     return size;
56758d5b22bSBALATON Zoltan }
56858d5b22bSBALATON Zoltan 
56970812bf7SBALATON Zoltan static void sdram_set_bcr(ppc440_sdram_t *sdram, int i,
57070812bf7SBALATON Zoltan                           uint32_t bcr, int enabled)
57158d5b22bSBALATON Zoltan {
57270812bf7SBALATON Zoltan     if (sdram->bcr[i] & 1) {
57370812bf7SBALATON Zoltan         /* First unmap RAM if enabled */
57458d5b22bSBALATON Zoltan         memory_region_del_subregion(get_system_memory(),
57570812bf7SBALATON Zoltan                                     &sdram->containers[i]);
57670812bf7SBALATON Zoltan         memory_region_del_subregion(&sdram->containers[i],
57770812bf7SBALATON Zoltan                                     &sdram->ram_memories[i]);
57870812bf7SBALATON Zoltan         object_unparent(OBJECT(&sdram->containers[i]));
57958d5b22bSBALATON Zoltan     }
580*6a9938a3SBALATON Zoltan     sdram->bcr[i] = bcr & 0xffe0ffc1;
58158d5b22bSBALATON Zoltan     if (enabled && (bcr & 1)) {
58270812bf7SBALATON Zoltan         memory_region_init(&sdram->containers[i], NULL, "sdram-containers",
58358d5b22bSBALATON Zoltan                            sdram_size(bcr));
58470812bf7SBALATON Zoltan         memory_region_add_subregion(&sdram->containers[i], 0,
58570812bf7SBALATON Zoltan                                     &sdram->ram_memories[i]);
58658d5b22bSBALATON Zoltan         memory_region_add_subregion(get_system_memory(),
58758d5b22bSBALATON Zoltan                                     sdram_base(bcr),
58870812bf7SBALATON Zoltan                                     &sdram->containers[i]);
58958d5b22bSBALATON Zoltan     }
59058d5b22bSBALATON Zoltan }
59158d5b22bSBALATON Zoltan 
5920a57fbeeSBALATON Zoltan static void sdram_map_bcr(ppc440_sdram_t *sdram)
59358d5b22bSBALATON Zoltan {
59458d5b22bSBALATON Zoltan     int i;
59558d5b22bSBALATON Zoltan 
59658d5b22bSBALATON Zoltan     for (i = 0; i < sdram->nbanks; i++) {
59758d5b22bSBALATON Zoltan         if (sdram->ram_sizes[i] != 0) {
59870812bf7SBALATON Zoltan             sdram_set_bcr(sdram, i, sdram_bcr(sdram->ram_bases[i],
59970812bf7SBALATON Zoltan                                               sdram->ram_sizes[i]), 1);
60058d5b22bSBALATON Zoltan         } else {
60170812bf7SBALATON Zoltan             sdram_set_bcr(sdram, i, 0, 0);
60258d5b22bSBALATON Zoltan         }
60358d5b22bSBALATON Zoltan     }
60458d5b22bSBALATON Zoltan }
60558d5b22bSBALATON Zoltan 
60658d5b22bSBALATON Zoltan static uint32_t dcr_read_sdram(void *opaque, int dcrn)
60758d5b22bSBALATON Zoltan {
6080a57fbeeSBALATON Zoltan     ppc440_sdram_t *sdram = opaque;
60958d5b22bSBALATON Zoltan     uint32_t ret = 0;
61058d5b22bSBALATON Zoltan 
61158d5b22bSBALATON Zoltan     switch (dcrn) {
61258d5b22bSBALATON Zoltan     case SDRAM_R0BAS:
61358d5b22bSBALATON Zoltan     case SDRAM_R1BAS:
61458d5b22bSBALATON Zoltan     case SDRAM_R2BAS:
61558d5b22bSBALATON Zoltan     case SDRAM_R3BAS:
61658d5b22bSBALATON Zoltan         ret = sdram_bcr(sdram->ram_bases[dcrn - SDRAM_R0BAS],
61758d5b22bSBALATON Zoltan                         sdram->ram_sizes[dcrn - SDRAM_R0BAS]);
61858d5b22bSBALATON Zoltan         break;
61958d5b22bSBALATON Zoltan     case SDRAM_CONF1HB:
62058d5b22bSBALATON Zoltan     case SDRAM_CONF1LL:
62158d5b22bSBALATON Zoltan     case SDRAM_CONFPATHB:
62258d5b22bSBALATON Zoltan     case SDRAM_PLBADDULL:
62358d5b22bSBALATON Zoltan     case SDRAM_PLBADDUHB:
62458d5b22bSBALATON Zoltan         break;
62558d5b22bSBALATON Zoltan     case SDRAM0_CFGADDR:
62658d5b22bSBALATON Zoltan         ret = sdram->addr;
62758d5b22bSBALATON Zoltan         break;
62858d5b22bSBALATON Zoltan     case SDRAM0_CFGDATA:
62958d5b22bSBALATON Zoltan         switch (sdram->addr) {
63058d5b22bSBALATON Zoltan         case 0x14: /* SDRAM_MCSTAT (405EX) */
63158d5b22bSBALATON Zoltan         case 0x1F:
63258d5b22bSBALATON Zoltan             ret = 0x80000000;
63358d5b22bSBALATON Zoltan             break;
63458d5b22bSBALATON Zoltan         case 0x21: /* SDRAM_MCOPT2 */
63558d5b22bSBALATON Zoltan             ret = 0x08000000;
63658d5b22bSBALATON Zoltan             break;
63758d5b22bSBALATON Zoltan         case 0x40: /* SDRAM_MB0CF */
63858d5b22bSBALATON Zoltan             ret = 0x00008001;
63958d5b22bSBALATON Zoltan             break;
64058d5b22bSBALATON Zoltan         case 0x7A: /* SDRAM_DLCR */
64158d5b22bSBALATON Zoltan             ret = 0x02000000;
64258d5b22bSBALATON Zoltan             break;
64358d5b22bSBALATON Zoltan         case 0xE1: /* SDR0_DDR0 */
64458d5b22bSBALATON Zoltan             ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1;
64558d5b22bSBALATON Zoltan             break;
64658d5b22bSBALATON Zoltan         default:
64758d5b22bSBALATON Zoltan             break;
64858d5b22bSBALATON Zoltan         }
64958d5b22bSBALATON Zoltan         break;
65058d5b22bSBALATON Zoltan     default:
65158d5b22bSBALATON Zoltan         break;
65258d5b22bSBALATON Zoltan     }
65358d5b22bSBALATON Zoltan 
65458d5b22bSBALATON Zoltan     return ret;
65558d5b22bSBALATON Zoltan }
65658d5b22bSBALATON Zoltan 
65758d5b22bSBALATON Zoltan static void dcr_write_sdram(void *opaque, int dcrn, uint32_t val)
65858d5b22bSBALATON Zoltan {
6590a57fbeeSBALATON Zoltan     ppc440_sdram_t *sdram = opaque;
66058d5b22bSBALATON Zoltan 
66158d5b22bSBALATON Zoltan     switch (dcrn) {
66258d5b22bSBALATON Zoltan     case SDRAM_R0BAS:
66358d5b22bSBALATON Zoltan     case SDRAM_R1BAS:
66458d5b22bSBALATON Zoltan     case SDRAM_R2BAS:
66558d5b22bSBALATON Zoltan     case SDRAM_R3BAS:
66658d5b22bSBALATON Zoltan     case SDRAM_CONF1HB:
66758d5b22bSBALATON Zoltan     case SDRAM_CONF1LL:
66858d5b22bSBALATON Zoltan     case SDRAM_CONFPATHB:
66958d5b22bSBALATON Zoltan     case SDRAM_PLBADDULL:
67058d5b22bSBALATON Zoltan     case SDRAM_PLBADDUHB:
67158d5b22bSBALATON Zoltan         break;
67258d5b22bSBALATON Zoltan     case SDRAM0_CFGADDR:
67358d5b22bSBALATON Zoltan         sdram->addr = val;
67458d5b22bSBALATON Zoltan         break;
67558d5b22bSBALATON Zoltan     case SDRAM0_CFGDATA:
67658d5b22bSBALATON Zoltan         switch (sdram->addr) {
67758d5b22bSBALATON Zoltan         case 0x00: /* B0CR */
67858d5b22bSBALATON Zoltan             break;
67958d5b22bSBALATON Zoltan         default:
68058d5b22bSBALATON Zoltan             break;
68158d5b22bSBALATON Zoltan         }
68258d5b22bSBALATON Zoltan         break;
68358d5b22bSBALATON Zoltan     default:
68458d5b22bSBALATON Zoltan         break;
68558d5b22bSBALATON Zoltan     }
68658d5b22bSBALATON Zoltan }
68758d5b22bSBALATON Zoltan 
68858d5b22bSBALATON Zoltan static void sdram_reset(void *opaque)
68958d5b22bSBALATON Zoltan {
6900a57fbeeSBALATON Zoltan     ppc440_sdram_t *sdram = opaque;
69158d5b22bSBALATON Zoltan 
69258d5b22bSBALATON Zoltan     sdram->addr = 0;
69358d5b22bSBALATON Zoltan }
69458d5b22bSBALATON Zoltan 
69558d5b22bSBALATON Zoltan void ppc440_sdram_init(CPUPPCState *env, int nbanks,
69658d5b22bSBALATON Zoltan                        MemoryRegion *ram_memories,
69758d5b22bSBALATON Zoltan                        hwaddr *ram_bases, hwaddr *ram_sizes,
69858d5b22bSBALATON Zoltan                        int do_init)
69958d5b22bSBALATON Zoltan {
7000a57fbeeSBALATON Zoltan     ppc440_sdram_t *sdram;
70158d5b22bSBALATON Zoltan 
70258d5b22bSBALATON Zoltan     sdram = g_malloc0(sizeof(*sdram));
70358d5b22bSBALATON Zoltan     sdram->nbanks = nbanks;
70458d5b22bSBALATON Zoltan     sdram->ram_memories = ram_memories;
70558d5b22bSBALATON Zoltan     memcpy(sdram->ram_bases, ram_bases, nbanks * sizeof(hwaddr));
70658d5b22bSBALATON Zoltan     memcpy(sdram->ram_sizes, ram_sizes, nbanks * sizeof(hwaddr));
70758d5b22bSBALATON Zoltan     qemu_register_reset(&sdram_reset, sdram);
70858d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM0_CFGADDR,
70958d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
71058d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM0_CFGDATA,
71158d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
71258d5b22bSBALATON Zoltan     if (do_init) {
71358d5b22bSBALATON Zoltan         sdram_map_bcr(sdram);
71458d5b22bSBALATON Zoltan     }
71558d5b22bSBALATON Zoltan 
71658d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_R0BAS,
71758d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
71858d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_R1BAS,
71958d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
72058d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_R2BAS,
72158d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
72258d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_R3BAS,
72358d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
72458d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_CONF1HB,
72558d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
72658d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_PLBADDULL,
72758d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
72858d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_CONF1LL,
72958d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
73058d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_CONFPATHB,
73158d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
73258d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_PLBADDUHB,
73358d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
73458d5b22bSBALATON Zoltan }
73558d5b22bSBALATON Zoltan 
73658d5b22bSBALATON Zoltan /*****************************************************************************/
73758d5b22bSBALATON Zoltan /* PLB to AHB bridge */
73858d5b22bSBALATON Zoltan enum {
73958d5b22bSBALATON Zoltan     AHB_TOP    = 0xA4,
74058d5b22bSBALATON Zoltan     AHB_BOT    = 0xA5,
74158d5b22bSBALATON Zoltan };
74258d5b22bSBALATON Zoltan 
74358d5b22bSBALATON Zoltan typedef struct ppc4xx_ahb_t {
74458d5b22bSBALATON Zoltan     uint32_t top;
74558d5b22bSBALATON Zoltan     uint32_t bot;
74658d5b22bSBALATON Zoltan } ppc4xx_ahb_t;
74758d5b22bSBALATON Zoltan 
74858d5b22bSBALATON Zoltan static uint32_t dcr_read_ahb(void *opaque, int dcrn)
74958d5b22bSBALATON Zoltan {
75058d5b22bSBALATON Zoltan     ppc4xx_ahb_t *ahb = opaque;
75158d5b22bSBALATON Zoltan     uint32_t ret = 0;
75258d5b22bSBALATON Zoltan 
75358d5b22bSBALATON Zoltan     switch (dcrn) {
75458d5b22bSBALATON Zoltan     case AHB_TOP:
75558d5b22bSBALATON Zoltan         ret = ahb->top;
75658d5b22bSBALATON Zoltan         break;
75758d5b22bSBALATON Zoltan     case AHB_BOT:
75858d5b22bSBALATON Zoltan         ret = ahb->bot;
75958d5b22bSBALATON Zoltan         break;
76058d5b22bSBALATON Zoltan     default:
76158d5b22bSBALATON Zoltan         break;
76258d5b22bSBALATON Zoltan     }
76358d5b22bSBALATON Zoltan 
76458d5b22bSBALATON Zoltan     return ret;
76558d5b22bSBALATON Zoltan }
76658d5b22bSBALATON Zoltan 
76758d5b22bSBALATON Zoltan static void dcr_write_ahb(void *opaque, int dcrn, uint32_t val)
76858d5b22bSBALATON Zoltan {
76958d5b22bSBALATON Zoltan     ppc4xx_ahb_t *ahb = opaque;
77058d5b22bSBALATON Zoltan 
77158d5b22bSBALATON Zoltan     switch (dcrn) {
77258d5b22bSBALATON Zoltan     case AHB_TOP:
77358d5b22bSBALATON Zoltan         ahb->top = val;
77458d5b22bSBALATON Zoltan         break;
77558d5b22bSBALATON Zoltan     case AHB_BOT:
77658d5b22bSBALATON Zoltan         ahb->bot = val;
77758d5b22bSBALATON Zoltan         break;
77858d5b22bSBALATON Zoltan     }
77958d5b22bSBALATON Zoltan }
78058d5b22bSBALATON Zoltan 
78158d5b22bSBALATON Zoltan static void ppc4xx_ahb_reset(void *opaque)
78258d5b22bSBALATON Zoltan {
78358d5b22bSBALATON Zoltan     ppc4xx_ahb_t *ahb = opaque;
78458d5b22bSBALATON Zoltan 
78558d5b22bSBALATON Zoltan     /* No error */
78658d5b22bSBALATON Zoltan     ahb->top = 0;
78758d5b22bSBALATON Zoltan     ahb->bot = 0;
78858d5b22bSBALATON Zoltan }
78958d5b22bSBALATON Zoltan 
79058d5b22bSBALATON Zoltan void ppc4xx_ahb_init(CPUPPCState *env)
79158d5b22bSBALATON Zoltan {
79258d5b22bSBALATON Zoltan     ppc4xx_ahb_t *ahb;
79358d5b22bSBALATON Zoltan 
79458d5b22bSBALATON Zoltan     ahb = g_malloc0(sizeof(*ahb));
79558d5b22bSBALATON Zoltan     ppc_dcr_register(env, AHB_TOP, ahb, &dcr_read_ahb, &dcr_write_ahb);
79658d5b22bSBALATON Zoltan     ppc_dcr_register(env, AHB_BOT, ahb, &dcr_read_ahb, &dcr_write_ahb);
79758d5b22bSBALATON Zoltan     qemu_register_reset(ppc4xx_ahb_reset, ahb);
79858d5b22bSBALATON Zoltan }
79958d5b22bSBALATON Zoltan 
80058d5b22bSBALATON Zoltan /*****************************************************************************/
8013c409c19SBALATON Zoltan /* DMA controller */
8023c409c19SBALATON Zoltan 
8033c409c19SBALATON Zoltan #define DMA0_CR_CE  (1 << 31)
8043c409c19SBALATON Zoltan #define DMA0_CR_PW  (1 << 26 | 1 << 25)
8053c409c19SBALATON Zoltan #define DMA0_CR_DAI (1 << 24)
8063c409c19SBALATON Zoltan #define DMA0_CR_SAI (1 << 23)
8073c409c19SBALATON Zoltan #define DMA0_CR_DEC (1 << 2)
8083c409c19SBALATON Zoltan 
8093c409c19SBALATON Zoltan enum {
8103c409c19SBALATON Zoltan     DMA0_CR  = 0x00,
8113c409c19SBALATON Zoltan     DMA0_CT,
8123c409c19SBALATON Zoltan     DMA0_SAH,
8133c409c19SBALATON Zoltan     DMA0_SAL,
8143c409c19SBALATON Zoltan     DMA0_DAH,
8153c409c19SBALATON Zoltan     DMA0_DAL,
8163c409c19SBALATON Zoltan     DMA0_SGH,
8173c409c19SBALATON Zoltan     DMA0_SGL,
8183c409c19SBALATON Zoltan 
8193c409c19SBALATON Zoltan     DMA0_SR  = 0x20,
8203c409c19SBALATON Zoltan     DMA0_SGC = 0x23,
8213c409c19SBALATON Zoltan     DMA0_SLP = 0x25,
8223c409c19SBALATON Zoltan     DMA0_POL = 0x26,
8233c409c19SBALATON Zoltan };
8243c409c19SBALATON Zoltan 
8253c409c19SBALATON Zoltan typedef struct {
8263c409c19SBALATON Zoltan     uint32_t cr;
8273c409c19SBALATON Zoltan     uint32_t ct;
8283c409c19SBALATON Zoltan     uint64_t sa;
8293c409c19SBALATON Zoltan     uint64_t da;
8303c409c19SBALATON Zoltan     uint64_t sg;
8313c409c19SBALATON Zoltan } PPC4xxDmaChnl;
8323c409c19SBALATON Zoltan 
8333c409c19SBALATON Zoltan typedef struct {
8343c409c19SBALATON Zoltan     int base;
8353c409c19SBALATON Zoltan     PPC4xxDmaChnl ch[4];
8363c409c19SBALATON Zoltan     uint32_t sr;
8373c409c19SBALATON Zoltan } PPC4xxDmaState;
8383c409c19SBALATON Zoltan 
8393c409c19SBALATON Zoltan static uint32_t dcr_read_dma(void *opaque, int dcrn)
8403c409c19SBALATON Zoltan {
8413c409c19SBALATON Zoltan     PPC4xxDmaState *dma = opaque;
8423c409c19SBALATON Zoltan     uint32_t val = 0;
8433c409c19SBALATON Zoltan     int addr = dcrn - dma->base;
8443c409c19SBALATON Zoltan     int chnl = addr / 8;
8453c409c19SBALATON Zoltan 
8463c409c19SBALATON Zoltan     switch (addr) {
8473c409c19SBALATON Zoltan     case 0x00 ... 0x1f:
8483c409c19SBALATON Zoltan         switch (addr % 8) {
8493c409c19SBALATON Zoltan         case DMA0_CR:
8503c409c19SBALATON Zoltan             val = dma->ch[chnl].cr;
8513c409c19SBALATON Zoltan             break;
8523c409c19SBALATON Zoltan         case DMA0_CT:
8533c409c19SBALATON Zoltan             val = dma->ch[chnl].ct;
8543c409c19SBALATON Zoltan             break;
8553c409c19SBALATON Zoltan         case DMA0_SAH:
8563c409c19SBALATON Zoltan             val = dma->ch[chnl].sa >> 32;
8573c409c19SBALATON Zoltan             break;
8583c409c19SBALATON Zoltan         case DMA0_SAL:
8593c409c19SBALATON Zoltan             val = dma->ch[chnl].sa;
8603c409c19SBALATON Zoltan             break;
8613c409c19SBALATON Zoltan         case DMA0_DAH:
8623c409c19SBALATON Zoltan             val = dma->ch[chnl].da >> 32;
8633c409c19SBALATON Zoltan             break;
8643c409c19SBALATON Zoltan         case DMA0_DAL:
8653c409c19SBALATON Zoltan             val = dma->ch[chnl].da;
8663c409c19SBALATON Zoltan             break;
8673c409c19SBALATON Zoltan         case DMA0_SGH:
8683c409c19SBALATON Zoltan             val = dma->ch[chnl].sg >> 32;
8693c409c19SBALATON Zoltan             break;
8703c409c19SBALATON Zoltan         case DMA0_SGL:
8713c409c19SBALATON Zoltan             val = dma->ch[chnl].sg;
8723c409c19SBALATON Zoltan             break;
8733c409c19SBALATON Zoltan         }
8743c409c19SBALATON Zoltan         break;
8753c409c19SBALATON Zoltan     case DMA0_SR:
8763c409c19SBALATON Zoltan         val = dma->sr;
8773c409c19SBALATON Zoltan         break;
8783c409c19SBALATON Zoltan     default:
8793c409c19SBALATON Zoltan         qemu_log_mask(LOG_UNIMP, "%s: unimplemented register %x (%d, %x)\n",
8803c409c19SBALATON Zoltan                       __func__, dcrn, chnl, addr);
8813c409c19SBALATON Zoltan     }
8823c409c19SBALATON Zoltan 
8833c409c19SBALATON Zoltan     return val;
8843c409c19SBALATON Zoltan }
8853c409c19SBALATON Zoltan 
8863c409c19SBALATON Zoltan static void dcr_write_dma(void *opaque, int dcrn, uint32_t val)
8873c409c19SBALATON Zoltan {
8883c409c19SBALATON Zoltan     PPC4xxDmaState *dma = opaque;
8893c409c19SBALATON Zoltan     int addr = dcrn - dma->base;
8903c409c19SBALATON Zoltan     int chnl = addr / 8;
8913c409c19SBALATON Zoltan 
8923c409c19SBALATON Zoltan     switch (addr) {
8933c409c19SBALATON Zoltan     case 0x00 ... 0x1f:
8943c409c19SBALATON Zoltan         switch (addr % 8) {
8953c409c19SBALATON Zoltan         case DMA0_CR:
8963c409c19SBALATON Zoltan             dma->ch[chnl].cr = val;
8973c409c19SBALATON Zoltan             if (val & DMA0_CR_CE) {
8983c409c19SBALATON Zoltan                 int count = dma->ch[chnl].ct & 0xffff;
8993c409c19SBALATON Zoltan 
9003c409c19SBALATON Zoltan                 if (count) {
9013c409c19SBALATON Zoltan                     int width, i, sidx, didx;
9023c409c19SBALATON Zoltan                     uint8_t *rptr, *wptr;
9033c409c19SBALATON Zoltan                     hwaddr rlen, wlen;
9043c409c19SBALATON Zoltan 
9053c409c19SBALATON Zoltan                     sidx = didx = 0;
9063c409c19SBALATON Zoltan                     width = 1 << ((val & DMA0_CR_PW) >> 25);
9073c409c19SBALATON Zoltan                     rptr = cpu_physical_memory_map(dma->ch[chnl].sa, &rlen, 0);
9083c409c19SBALATON Zoltan                     wptr = cpu_physical_memory_map(dma->ch[chnl].da, &wlen, 1);
9093c409c19SBALATON Zoltan                     if (rptr && wptr) {
9103c409c19SBALATON Zoltan                         if (!(val & DMA0_CR_DEC) &&
9113c409c19SBALATON Zoltan                             val & DMA0_CR_SAI && val & DMA0_CR_DAI) {
9123c409c19SBALATON Zoltan                             /* optimise common case */
9133c409c19SBALATON Zoltan                             memmove(wptr, rptr, count * width);
9143c409c19SBALATON Zoltan                             sidx = didx = count * width;
9153c409c19SBALATON Zoltan                         } else {
9163c409c19SBALATON Zoltan                             /* do it the slow way */
9173c409c19SBALATON Zoltan                             for (sidx = didx = i = 0; i < count; i++) {
9183c409c19SBALATON Zoltan                                 uint64_t v = ldn_le_p(rptr + sidx, width);
9193c409c19SBALATON Zoltan                                 stn_le_p(wptr + didx, width, v);
9203c409c19SBALATON Zoltan                                 if (val & DMA0_CR_SAI) {
9213c409c19SBALATON Zoltan                                     sidx += width;
9223c409c19SBALATON Zoltan                                 }
9233c409c19SBALATON Zoltan                                 if (val & DMA0_CR_DAI) {
9243c409c19SBALATON Zoltan                                     didx += width;
9253c409c19SBALATON Zoltan                                 }
9263c409c19SBALATON Zoltan                             }
9273c409c19SBALATON Zoltan                         }
9283c409c19SBALATON Zoltan                     }
9293c409c19SBALATON Zoltan                     if (wptr) {
9303c409c19SBALATON Zoltan                         cpu_physical_memory_unmap(wptr, wlen, 1, didx);
9313c409c19SBALATON Zoltan                     }
9327aeb1e51SPhilippe Mathieu-Daudé                     if (rptr) {
9333c409c19SBALATON Zoltan                         cpu_physical_memory_unmap(rptr, rlen, 0, sidx);
9343c409c19SBALATON Zoltan                     }
9353c409c19SBALATON Zoltan                 }
9363c409c19SBALATON Zoltan             }
9373c409c19SBALATON Zoltan             break;
9383c409c19SBALATON Zoltan         case DMA0_CT:
9393c409c19SBALATON Zoltan             dma->ch[chnl].ct = val;
9403c409c19SBALATON Zoltan             break;
9413c409c19SBALATON Zoltan         case DMA0_SAH:
9423c409c19SBALATON Zoltan             dma->ch[chnl].sa &= 0xffffffffULL;
9433c409c19SBALATON Zoltan             dma->ch[chnl].sa |= (uint64_t)val << 32;
9443c409c19SBALATON Zoltan             break;
9453c409c19SBALATON Zoltan         case DMA0_SAL:
9463c409c19SBALATON Zoltan             dma->ch[chnl].sa &= 0xffffffff00000000ULL;
9473c409c19SBALATON Zoltan             dma->ch[chnl].sa |= val;
9483c409c19SBALATON Zoltan             break;
9493c409c19SBALATON Zoltan         case DMA0_DAH:
9503c409c19SBALATON Zoltan             dma->ch[chnl].da &= 0xffffffffULL;
9513c409c19SBALATON Zoltan             dma->ch[chnl].da |= (uint64_t)val << 32;
9523c409c19SBALATON Zoltan             break;
9533c409c19SBALATON Zoltan         case DMA0_DAL:
9543c409c19SBALATON Zoltan             dma->ch[chnl].da &= 0xffffffff00000000ULL;
9553c409c19SBALATON Zoltan             dma->ch[chnl].da |= val;
9563c409c19SBALATON Zoltan             break;
9573c409c19SBALATON Zoltan         case DMA0_SGH:
9583c409c19SBALATON Zoltan             dma->ch[chnl].sg &= 0xffffffffULL;
9593c409c19SBALATON Zoltan             dma->ch[chnl].sg |= (uint64_t)val << 32;
9603c409c19SBALATON Zoltan             break;
9613c409c19SBALATON Zoltan         case DMA0_SGL:
9623c409c19SBALATON Zoltan             dma->ch[chnl].sg &= 0xffffffff00000000ULL;
9633c409c19SBALATON Zoltan             dma->ch[chnl].sg |= val;
9643c409c19SBALATON Zoltan             break;
9653c409c19SBALATON Zoltan         }
9663c409c19SBALATON Zoltan         break;
9673c409c19SBALATON Zoltan     case DMA0_SR:
9683c409c19SBALATON Zoltan         dma->sr &= ~val;
9693c409c19SBALATON Zoltan         break;
9703c409c19SBALATON Zoltan     default:
9713c409c19SBALATON Zoltan         qemu_log_mask(LOG_UNIMP, "%s: unimplemented register %x (%d, %x)\n",
9723c409c19SBALATON Zoltan                       __func__, dcrn, chnl, addr);
9733c409c19SBALATON Zoltan     }
9743c409c19SBALATON Zoltan }
9753c409c19SBALATON Zoltan 
9763c409c19SBALATON Zoltan static void ppc4xx_dma_reset(void *opaque)
9773c409c19SBALATON Zoltan {
9783c409c19SBALATON Zoltan     PPC4xxDmaState *dma = opaque;
9793c409c19SBALATON Zoltan     int dma_base = dma->base;
9803c409c19SBALATON Zoltan 
9813c409c19SBALATON Zoltan     memset(dma, 0, sizeof(*dma));
9823c409c19SBALATON Zoltan     dma->base = dma_base;
9833c409c19SBALATON Zoltan }
9843c409c19SBALATON Zoltan 
9853c409c19SBALATON Zoltan void ppc4xx_dma_init(CPUPPCState *env, int dcr_base)
9863c409c19SBALATON Zoltan {
9873c409c19SBALATON Zoltan     PPC4xxDmaState *dma;
9883c409c19SBALATON Zoltan     int i;
9893c409c19SBALATON Zoltan 
9903c409c19SBALATON Zoltan     dma = g_malloc0(sizeof(*dma));
9913c409c19SBALATON Zoltan     dma->base = dcr_base;
9923c409c19SBALATON Zoltan     qemu_register_reset(&ppc4xx_dma_reset, dma);
9933c409c19SBALATON Zoltan     for (i = 0; i < 4; i++) {
9943c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CR,
9953c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
9963c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CT,
9973c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
9983c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAH,
9993c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
10003c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAL,
10013c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
10023c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAH,
10033c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
10043c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAL,
10053c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
10063c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGH,
10073c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
10083c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGL,
10093c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
10103c409c19SBALATON Zoltan     }
10113c409c19SBALATON Zoltan     ppc_dcr_register(env, dcr_base + DMA0_SR,
10123c409c19SBALATON Zoltan                      dma, &dcr_read_dma, &dcr_write_dma);
10133c409c19SBALATON Zoltan     ppc_dcr_register(env, dcr_base + DMA0_SGC,
10143c409c19SBALATON Zoltan                      dma, &dcr_read_dma, &dcr_write_dma);
10153c409c19SBALATON Zoltan     ppc_dcr_register(env, dcr_base + DMA0_SLP,
10163c409c19SBALATON Zoltan                      dma, &dcr_read_dma, &dcr_write_dma);
10173c409c19SBALATON Zoltan     ppc_dcr_register(env, dcr_base + DMA0_POL,
10183c409c19SBALATON Zoltan                      dma, &dcr_read_dma, &dcr_write_dma);
10193c409c19SBALATON Zoltan }
10203c409c19SBALATON Zoltan 
10213c409c19SBALATON Zoltan /*****************************************************************************/
102258d5b22bSBALATON Zoltan /* PCI Express controller */
102358d5b22bSBALATON Zoltan /* FIXME: This is not complete and does not work, only implemented partially
102458d5b22bSBALATON Zoltan  * to allow firmware and guests to find an empty bus. Cards should use PCI.
102558d5b22bSBALATON Zoltan  */
102658d5b22bSBALATON Zoltan #include "hw/pci/pcie_host.h"
102758d5b22bSBALATON Zoltan 
102858d5b22bSBALATON Zoltan #define TYPE_PPC460EX_PCIE_HOST "ppc460ex-pcie-host"
102958d5b22bSBALATON Zoltan #define PPC460EX_PCIE_HOST(obj) \
103058d5b22bSBALATON Zoltan     OBJECT_CHECK(PPC460EXPCIEState, (obj), TYPE_PPC460EX_PCIE_HOST)
103158d5b22bSBALATON Zoltan 
103258d5b22bSBALATON Zoltan typedef struct PPC460EXPCIEState {
103358d5b22bSBALATON Zoltan     PCIExpressHost host;
103458d5b22bSBALATON Zoltan 
103558d5b22bSBALATON Zoltan     MemoryRegion iomem;
103658d5b22bSBALATON Zoltan     qemu_irq irq[4];
103758d5b22bSBALATON Zoltan     int32_t dcrn_base;
103858d5b22bSBALATON Zoltan 
103958d5b22bSBALATON Zoltan     uint64_t cfg_base;
104058d5b22bSBALATON Zoltan     uint32_t cfg_mask;
104158d5b22bSBALATON Zoltan     uint64_t msg_base;
104258d5b22bSBALATON Zoltan     uint32_t msg_mask;
104358d5b22bSBALATON Zoltan     uint64_t omr1_base;
104458d5b22bSBALATON Zoltan     uint64_t omr1_mask;
104558d5b22bSBALATON Zoltan     uint64_t omr2_base;
104658d5b22bSBALATON Zoltan     uint64_t omr2_mask;
104758d5b22bSBALATON Zoltan     uint64_t omr3_base;
104858d5b22bSBALATON Zoltan     uint64_t omr3_mask;
104958d5b22bSBALATON Zoltan     uint64_t reg_base;
105058d5b22bSBALATON Zoltan     uint32_t reg_mask;
105158d5b22bSBALATON Zoltan     uint32_t special;
105258d5b22bSBALATON Zoltan     uint32_t cfg;
105358d5b22bSBALATON Zoltan } PPC460EXPCIEState;
105458d5b22bSBALATON Zoltan 
105558d5b22bSBALATON Zoltan #define DCRN_PCIE0_BASE 0x100
105658d5b22bSBALATON Zoltan #define DCRN_PCIE1_BASE 0x120
105758d5b22bSBALATON Zoltan 
105858d5b22bSBALATON Zoltan enum {
105958d5b22bSBALATON Zoltan     PEGPL_CFGBAH = 0x0,
106058d5b22bSBALATON Zoltan     PEGPL_CFGBAL,
106158d5b22bSBALATON Zoltan     PEGPL_CFGMSK,
106258d5b22bSBALATON Zoltan     PEGPL_MSGBAH,
106358d5b22bSBALATON Zoltan     PEGPL_MSGBAL,
106458d5b22bSBALATON Zoltan     PEGPL_MSGMSK,
106558d5b22bSBALATON Zoltan     PEGPL_OMR1BAH,
106658d5b22bSBALATON Zoltan     PEGPL_OMR1BAL,
106758d5b22bSBALATON Zoltan     PEGPL_OMR1MSKH,
106858d5b22bSBALATON Zoltan     PEGPL_OMR1MSKL,
106958d5b22bSBALATON Zoltan     PEGPL_OMR2BAH,
107058d5b22bSBALATON Zoltan     PEGPL_OMR2BAL,
107158d5b22bSBALATON Zoltan     PEGPL_OMR2MSKH,
107258d5b22bSBALATON Zoltan     PEGPL_OMR2MSKL,
107358d5b22bSBALATON Zoltan     PEGPL_OMR3BAH,
107458d5b22bSBALATON Zoltan     PEGPL_OMR3BAL,
107558d5b22bSBALATON Zoltan     PEGPL_OMR3MSKH,
107658d5b22bSBALATON Zoltan     PEGPL_OMR3MSKL,
107758d5b22bSBALATON Zoltan     PEGPL_REGBAH,
107858d5b22bSBALATON Zoltan     PEGPL_REGBAL,
107958d5b22bSBALATON Zoltan     PEGPL_REGMSK,
108058d5b22bSBALATON Zoltan     PEGPL_SPECIAL,
108158d5b22bSBALATON Zoltan     PEGPL_CFG,
108258d5b22bSBALATON Zoltan };
108358d5b22bSBALATON Zoltan 
108458d5b22bSBALATON Zoltan static uint32_t dcr_read_pcie(void *opaque, int dcrn)
108558d5b22bSBALATON Zoltan {
108658d5b22bSBALATON Zoltan     PPC460EXPCIEState *state = opaque;
108758d5b22bSBALATON Zoltan     uint32_t ret = 0;
108858d5b22bSBALATON Zoltan 
108958d5b22bSBALATON Zoltan     switch (dcrn - state->dcrn_base) {
109058d5b22bSBALATON Zoltan     case PEGPL_CFGBAH:
109158d5b22bSBALATON Zoltan         ret = state->cfg_base >> 32;
109258d5b22bSBALATON Zoltan         break;
109358d5b22bSBALATON Zoltan     case PEGPL_CFGBAL:
109458d5b22bSBALATON Zoltan         ret = state->cfg_base;
109558d5b22bSBALATON Zoltan         break;
109658d5b22bSBALATON Zoltan     case PEGPL_CFGMSK:
109758d5b22bSBALATON Zoltan         ret = state->cfg_mask;
109858d5b22bSBALATON Zoltan         break;
109958d5b22bSBALATON Zoltan     case PEGPL_MSGBAH:
110058d5b22bSBALATON Zoltan         ret = state->msg_base >> 32;
110158d5b22bSBALATON Zoltan         break;
110258d5b22bSBALATON Zoltan     case PEGPL_MSGBAL:
110358d5b22bSBALATON Zoltan         ret = state->msg_base;
110458d5b22bSBALATON Zoltan         break;
110558d5b22bSBALATON Zoltan     case PEGPL_MSGMSK:
110658d5b22bSBALATON Zoltan         ret = state->msg_mask;
110758d5b22bSBALATON Zoltan         break;
110858d5b22bSBALATON Zoltan     case PEGPL_OMR1BAH:
110958d5b22bSBALATON Zoltan         ret = state->omr1_base >> 32;
111058d5b22bSBALATON Zoltan         break;
111158d5b22bSBALATON Zoltan     case PEGPL_OMR1BAL:
111258d5b22bSBALATON Zoltan         ret = state->omr1_base;
111358d5b22bSBALATON Zoltan         break;
111458d5b22bSBALATON Zoltan     case PEGPL_OMR1MSKH:
111558d5b22bSBALATON Zoltan         ret = state->omr1_mask >> 32;
111658d5b22bSBALATON Zoltan         break;
111758d5b22bSBALATON Zoltan     case PEGPL_OMR1MSKL:
111858d5b22bSBALATON Zoltan         ret = state->omr1_mask;
111958d5b22bSBALATON Zoltan         break;
112058d5b22bSBALATON Zoltan     case PEGPL_OMR2BAH:
112158d5b22bSBALATON Zoltan         ret = state->omr2_base >> 32;
112258d5b22bSBALATON Zoltan         break;
112358d5b22bSBALATON Zoltan     case PEGPL_OMR2BAL:
112458d5b22bSBALATON Zoltan         ret = state->omr2_base;
112558d5b22bSBALATON Zoltan         break;
112658d5b22bSBALATON Zoltan     case PEGPL_OMR2MSKH:
112758d5b22bSBALATON Zoltan         ret = state->omr2_mask >> 32;
112858d5b22bSBALATON Zoltan         break;
112958d5b22bSBALATON Zoltan     case PEGPL_OMR2MSKL:
113058d5b22bSBALATON Zoltan         ret = state->omr3_mask;
113158d5b22bSBALATON Zoltan         break;
113258d5b22bSBALATON Zoltan     case PEGPL_OMR3BAH:
113358d5b22bSBALATON Zoltan         ret = state->omr3_base >> 32;
113458d5b22bSBALATON Zoltan         break;
113558d5b22bSBALATON Zoltan     case PEGPL_OMR3BAL:
113658d5b22bSBALATON Zoltan         ret = state->omr3_base;
113758d5b22bSBALATON Zoltan         break;
113858d5b22bSBALATON Zoltan     case PEGPL_OMR3MSKH:
113958d5b22bSBALATON Zoltan         ret = state->omr3_mask >> 32;
114058d5b22bSBALATON Zoltan         break;
114158d5b22bSBALATON Zoltan     case PEGPL_OMR3MSKL:
114258d5b22bSBALATON Zoltan         ret = state->omr3_mask;
114358d5b22bSBALATON Zoltan         break;
114458d5b22bSBALATON Zoltan     case PEGPL_REGBAH:
114558d5b22bSBALATON Zoltan         ret = state->reg_base >> 32;
114658d5b22bSBALATON Zoltan         break;
114758d5b22bSBALATON Zoltan     case PEGPL_REGBAL:
114858d5b22bSBALATON Zoltan         ret = state->reg_base;
114958d5b22bSBALATON Zoltan         break;
115058d5b22bSBALATON Zoltan     case PEGPL_REGMSK:
115158d5b22bSBALATON Zoltan         ret = state->reg_mask;
115258d5b22bSBALATON Zoltan         break;
115358d5b22bSBALATON Zoltan     case PEGPL_SPECIAL:
115458d5b22bSBALATON Zoltan         ret = state->special;
115558d5b22bSBALATON Zoltan         break;
115658d5b22bSBALATON Zoltan     case PEGPL_CFG:
115758d5b22bSBALATON Zoltan         ret = state->cfg;
115858d5b22bSBALATON Zoltan         break;
115958d5b22bSBALATON Zoltan     }
116058d5b22bSBALATON Zoltan 
116158d5b22bSBALATON Zoltan     return ret;
116258d5b22bSBALATON Zoltan }
116358d5b22bSBALATON Zoltan 
116458d5b22bSBALATON Zoltan static void dcr_write_pcie(void *opaque, int dcrn, uint32_t val)
116558d5b22bSBALATON Zoltan {
116658d5b22bSBALATON Zoltan     PPC460EXPCIEState *s = opaque;
116758d5b22bSBALATON Zoltan     uint64_t size;
116858d5b22bSBALATON Zoltan 
116958d5b22bSBALATON Zoltan     switch (dcrn - s->dcrn_base) {
117058d5b22bSBALATON Zoltan     case PEGPL_CFGBAH:
117158d5b22bSBALATON Zoltan         s->cfg_base = ((uint64_t)val << 32) | (s->cfg_base & 0xffffffff);
117258d5b22bSBALATON Zoltan         break;
117358d5b22bSBALATON Zoltan     case PEGPL_CFGBAL:
117458d5b22bSBALATON Zoltan         s->cfg_base = (s->cfg_base & 0xffffffff00000000ULL) | val;
117558d5b22bSBALATON Zoltan         break;
117658d5b22bSBALATON Zoltan     case PEGPL_CFGMSK:
117758d5b22bSBALATON Zoltan         s->cfg_mask = val;
117858d5b22bSBALATON Zoltan         size = ~(val & 0xfffffffe) + 1;
117958d5b22bSBALATON Zoltan         qemu_mutex_lock_iothread();
118058d5b22bSBALATON Zoltan         pcie_host_mmcfg_update(PCIE_HOST_BRIDGE(s), val & 1, s->cfg_base, size);
118158d5b22bSBALATON Zoltan         qemu_mutex_unlock_iothread();
118258d5b22bSBALATON Zoltan         break;
118358d5b22bSBALATON Zoltan     case PEGPL_MSGBAH:
118458d5b22bSBALATON Zoltan         s->msg_base = ((uint64_t)val << 32) | (s->msg_base & 0xffffffff);
118558d5b22bSBALATON Zoltan         break;
118658d5b22bSBALATON Zoltan     case PEGPL_MSGBAL:
118758d5b22bSBALATON Zoltan         s->msg_base = (s->msg_base & 0xffffffff00000000ULL) | val;
118858d5b22bSBALATON Zoltan         break;
118958d5b22bSBALATON Zoltan     case PEGPL_MSGMSK:
119058d5b22bSBALATON Zoltan         s->msg_mask = val;
119158d5b22bSBALATON Zoltan         break;
119258d5b22bSBALATON Zoltan     case PEGPL_OMR1BAH:
119358d5b22bSBALATON Zoltan         s->omr1_base = ((uint64_t)val << 32) | (s->omr1_base & 0xffffffff);
119458d5b22bSBALATON Zoltan         break;
119558d5b22bSBALATON Zoltan     case PEGPL_OMR1BAL:
119658d5b22bSBALATON Zoltan         s->omr1_base = (s->omr1_base & 0xffffffff00000000ULL) | val;
119758d5b22bSBALATON Zoltan         break;
119858d5b22bSBALATON Zoltan     case PEGPL_OMR1MSKH:
119958d5b22bSBALATON Zoltan         s->omr1_mask = ((uint64_t)val << 32) | (s->omr1_mask & 0xffffffff);
120058d5b22bSBALATON Zoltan         break;
120158d5b22bSBALATON Zoltan     case PEGPL_OMR1MSKL:
120258d5b22bSBALATON Zoltan         s->omr1_mask = (s->omr1_mask & 0xffffffff00000000ULL) | val;
120358d5b22bSBALATON Zoltan         break;
120458d5b22bSBALATON Zoltan     case PEGPL_OMR2BAH:
120558d5b22bSBALATON Zoltan         s->omr2_base = ((uint64_t)val << 32) | (s->omr2_base & 0xffffffff);
120658d5b22bSBALATON Zoltan         break;
120758d5b22bSBALATON Zoltan     case PEGPL_OMR2BAL:
120858d5b22bSBALATON Zoltan         s->omr2_base = (s->omr2_base & 0xffffffff00000000ULL) | val;
120958d5b22bSBALATON Zoltan         break;
121058d5b22bSBALATON Zoltan     case PEGPL_OMR2MSKH:
121158d5b22bSBALATON Zoltan         s->omr2_mask = ((uint64_t)val << 32) | (s->omr2_mask & 0xffffffff);
121258d5b22bSBALATON Zoltan         break;
121358d5b22bSBALATON Zoltan     case PEGPL_OMR2MSKL:
121458d5b22bSBALATON Zoltan         s->omr2_mask = (s->omr2_mask & 0xffffffff00000000ULL) | val;
121558d5b22bSBALATON Zoltan         break;
121658d5b22bSBALATON Zoltan     case PEGPL_OMR3BAH:
121758d5b22bSBALATON Zoltan         s->omr3_base = ((uint64_t)val << 32) | (s->omr3_base & 0xffffffff);
121858d5b22bSBALATON Zoltan         break;
121958d5b22bSBALATON Zoltan     case PEGPL_OMR3BAL:
122058d5b22bSBALATON Zoltan         s->omr3_base = (s->omr3_base & 0xffffffff00000000ULL) | val;
122158d5b22bSBALATON Zoltan         break;
122258d5b22bSBALATON Zoltan     case PEGPL_OMR3MSKH:
122358d5b22bSBALATON Zoltan         s->omr3_mask = ((uint64_t)val << 32) | (s->omr3_mask & 0xffffffff);
122458d5b22bSBALATON Zoltan         break;
122558d5b22bSBALATON Zoltan     case PEGPL_OMR3MSKL:
122658d5b22bSBALATON Zoltan         s->omr3_mask = (s->omr3_mask & 0xffffffff00000000ULL) | val;
122758d5b22bSBALATON Zoltan         break;
122858d5b22bSBALATON Zoltan     case PEGPL_REGBAH:
122958d5b22bSBALATON Zoltan         s->reg_base = ((uint64_t)val << 32) | (s->reg_base & 0xffffffff);
123058d5b22bSBALATON Zoltan         break;
123158d5b22bSBALATON Zoltan     case PEGPL_REGBAL:
123258d5b22bSBALATON Zoltan         s->reg_base = (s->reg_base & 0xffffffff00000000ULL) | val;
123358d5b22bSBALATON Zoltan         break;
123458d5b22bSBALATON Zoltan     case PEGPL_REGMSK:
123558d5b22bSBALATON Zoltan         s->reg_mask = val;
123658d5b22bSBALATON Zoltan         /* FIXME: how is size encoded? */
123758d5b22bSBALATON Zoltan         size = (val == 0x7001 ? 4096 : ~(val & 0xfffffffe) + 1);
123858d5b22bSBALATON Zoltan         break;
123958d5b22bSBALATON Zoltan     case PEGPL_SPECIAL:
124058d5b22bSBALATON Zoltan         s->special = val;
124158d5b22bSBALATON Zoltan         break;
124258d5b22bSBALATON Zoltan     case PEGPL_CFG:
124358d5b22bSBALATON Zoltan         s->cfg = val;
124458d5b22bSBALATON Zoltan         break;
124558d5b22bSBALATON Zoltan     }
124658d5b22bSBALATON Zoltan }
124758d5b22bSBALATON Zoltan 
124858d5b22bSBALATON Zoltan static void ppc460ex_set_irq(void *opaque, int irq_num, int level)
124958d5b22bSBALATON Zoltan {
125058d5b22bSBALATON Zoltan        PPC460EXPCIEState *s = opaque;
125158d5b22bSBALATON Zoltan        qemu_set_irq(s->irq[irq_num], level);
125258d5b22bSBALATON Zoltan }
125358d5b22bSBALATON Zoltan 
125458d5b22bSBALATON Zoltan static void ppc460ex_pcie_realize(DeviceState *dev, Error **errp)
125558d5b22bSBALATON Zoltan {
125658d5b22bSBALATON Zoltan     PPC460EXPCIEState *s = PPC460EX_PCIE_HOST(dev);
125758d5b22bSBALATON Zoltan     PCIHostState *pci = PCI_HOST_BRIDGE(dev);
125858d5b22bSBALATON Zoltan     int i, id;
125958d5b22bSBALATON Zoltan     char buf[16];
126058d5b22bSBALATON Zoltan 
126158d5b22bSBALATON Zoltan     switch (s->dcrn_base) {
126258d5b22bSBALATON Zoltan     case DCRN_PCIE0_BASE:
126358d5b22bSBALATON Zoltan         id = 0;
126458d5b22bSBALATON Zoltan         break;
126558d5b22bSBALATON Zoltan     case DCRN_PCIE1_BASE:
126658d5b22bSBALATON Zoltan         id = 1;
126758d5b22bSBALATON Zoltan         break;
1268ff22e0ebSBALATON Zoltan     default:
1269ff22e0ebSBALATON Zoltan         error_setg(errp, "invalid PCIe DCRN base");
1270ff22e0ebSBALATON Zoltan         return;
127158d5b22bSBALATON Zoltan     }
127258d5b22bSBALATON Zoltan     snprintf(buf, sizeof(buf), "pcie%d-io", id);
127358d5b22bSBALATON Zoltan     memory_region_init(&s->iomem, OBJECT(s), buf, UINT64_MAX);
127458d5b22bSBALATON Zoltan     for (i = 0; i < 4; i++) {
127558d5b22bSBALATON Zoltan         sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[i]);
127658d5b22bSBALATON Zoltan     }
127758d5b22bSBALATON Zoltan     snprintf(buf, sizeof(buf), "pcie.%d", id);
127858d5b22bSBALATON Zoltan     pci->bus = pci_register_root_bus(DEVICE(s), buf, ppc460ex_set_irq,
127958d5b22bSBALATON Zoltan                                 pci_swizzle_map_irq_fn, s, &s->iomem,
128058d5b22bSBALATON Zoltan                                 get_system_io(), 0, 4, TYPE_PCIE_BUS);
128158d5b22bSBALATON Zoltan }
128258d5b22bSBALATON Zoltan 
128358d5b22bSBALATON Zoltan static Property ppc460ex_pcie_props[] = {
128458d5b22bSBALATON Zoltan     DEFINE_PROP_INT32("dcrn-base", PPC460EXPCIEState, dcrn_base, -1),
128558d5b22bSBALATON Zoltan     DEFINE_PROP_END_OF_LIST(),
128658d5b22bSBALATON Zoltan };
128758d5b22bSBALATON Zoltan 
128858d5b22bSBALATON Zoltan static void ppc460ex_pcie_class_init(ObjectClass *klass, void *data)
128958d5b22bSBALATON Zoltan {
129058d5b22bSBALATON Zoltan     DeviceClass *dc = DEVICE_CLASS(klass);
129158d5b22bSBALATON Zoltan 
129258d5b22bSBALATON Zoltan     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
129358d5b22bSBALATON Zoltan     dc->realize = ppc460ex_pcie_realize;
129458d5b22bSBALATON Zoltan     dc->props = ppc460ex_pcie_props;
129558d5b22bSBALATON Zoltan     dc->hotpluggable = false;
129658d5b22bSBALATON Zoltan }
129758d5b22bSBALATON Zoltan 
129858d5b22bSBALATON Zoltan static const TypeInfo ppc460ex_pcie_host_info = {
129958d5b22bSBALATON Zoltan     .name = TYPE_PPC460EX_PCIE_HOST,
130058d5b22bSBALATON Zoltan     .parent = TYPE_PCIE_HOST_BRIDGE,
130158d5b22bSBALATON Zoltan     .instance_size = sizeof(PPC460EXPCIEState),
130258d5b22bSBALATON Zoltan     .class_init = ppc460ex_pcie_class_init,
130358d5b22bSBALATON Zoltan };
130458d5b22bSBALATON Zoltan 
130558d5b22bSBALATON Zoltan static void ppc460ex_pcie_register(void)
130658d5b22bSBALATON Zoltan {
130758d5b22bSBALATON Zoltan     type_register_static(&ppc460ex_pcie_host_info);
130858d5b22bSBALATON Zoltan }
130958d5b22bSBALATON Zoltan 
131058d5b22bSBALATON Zoltan type_init(ppc460ex_pcie_register)
131158d5b22bSBALATON Zoltan 
131258d5b22bSBALATON Zoltan static void ppc460ex_pcie_register_dcrs(PPC460EXPCIEState *s, CPUPPCState *env)
131358d5b22bSBALATON Zoltan {
131458d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGBAH, s,
131558d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
131658d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGBAL, s,
131758d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
131858d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGMSK, s,
131958d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
132058d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGBAH, s,
132158d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
132258d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGBAL, s,
132358d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
132458d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGMSK, s,
132558d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
132658d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1BAH, s,
132758d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
132858d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1BAL, s,
132958d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
133058d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1MSKH, s,
133158d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
133258d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1MSKL, s,
133358d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
133458d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2BAH, s,
133558d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
133658d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2BAL, s,
133758d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
133858d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2MSKH, s,
133958d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
134058d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2MSKL, s,
134158d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
134258d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3BAH, s,
134358d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
134458d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3BAL, s,
134558d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
134658d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3MSKH, s,
134758d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
134858d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3MSKL, s,
134958d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
135058d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_REGBAH, s,
135158d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
135258d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_REGBAL, s,
135358d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
135458d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_REGMSK, s,
135558d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
135658d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_SPECIAL, s,
135758d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
135858d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_CFG, s,
135958d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
136058d5b22bSBALATON Zoltan }
136158d5b22bSBALATON Zoltan 
136258d5b22bSBALATON Zoltan void ppc460ex_pcie_init(CPUPPCState *env)
136358d5b22bSBALATON Zoltan {
136458d5b22bSBALATON Zoltan     DeviceState *dev;
136558d5b22bSBALATON Zoltan 
136658d5b22bSBALATON Zoltan     dev = qdev_create(NULL, TYPE_PPC460EX_PCIE_HOST);
136758d5b22bSBALATON Zoltan     qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE0_BASE);
136858d5b22bSBALATON Zoltan     qdev_init_nofail(dev);
136958d5b22bSBALATON Zoltan     object_property_set_bool(OBJECT(dev), true, "realized", NULL);
137058d5b22bSBALATON Zoltan     ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), env);
137158d5b22bSBALATON Zoltan 
137258d5b22bSBALATON Zoltan     dev = qdev_create(NULL, TYPE_PPC460EX_PCIE_HOST);
137358d5b22bSBALATON Zoltan     qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE1_BASE);
137458d5b22bSBALATON Zoltan     qdev_init_nofail(dev);
137558d5b22bSBALATON Zoltan     object_property_set_bool(OBJECT(dev), true, "realized", NULL);
137658d5b22bSBALATON Zoltan     ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), env);
137758d5b22bSBALATON Zoltan }
1378