xref: /qemu/hw/ppc/ppc440_uc.c (revision 0a57fbee209f9d799f53dbcd77f3062649b61b08)
158d5b22bSBALATON Zoltan /*
258d5b22bSBALATON Zoltan  * QEMU PowerPC 440 embedded processors emulation
358d5b22bSBALATON Zoltan  *
458d5b22bSBALATON Zoltan  * Copyright (c) 2012 François Revol
558d5b22bSBALATON Zoltan  * Copyright (c) 2016-2018 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 */
484*0a57fbeeSBALATON 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];
492*0a57fbeeSBALATON 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 /* XXX: TOFIX: some patches have made this code become inconsistent:
50958d5b22bSBALATON Zoltan  *      there are type inconsistencies, mixing hwaddr, target_ulong
51058d5b22bSBALATON Zoltan  *      and uint32_t
51158d5b22bSBALATON Zoltan  */
51258d5b22bSBALATON Zoltan static uint32_t sdram_bcr(hwaddr ram_base, hwaddr ram_size)
51358d5b22bSBALATON Zoltan {
51458d5b22bSBALATON Zoltan     uint32_t bcr;
51558d5b22bSBALATON Zoltan 
51658d5b22bSBALATON Zoltan     switch (ram_size) {
517d23b6caaSPhilippe Mathieu-Daudé     case (8 * MiB):
51858d5b22bSBALATON Zoltan         bcr = 0xffc0;
51958d5b22bSBALATON Zoltan         break;
520d23b6caaSPhilippe Mathieu-Daudé     case (16 * MiB):
52158d5b22bSBALATON Zoltan         bcr = 0xff80;
52258d5b22bSBALATON Zoltan         break;
523d23b6caaSPhilippe Mathieu-Daudé     case (32 * MiB):
52458d5b22bSBALATON Zoltan         bcr = 0xff00;
52558d5b22bSBALATON Zoltan         break;
526d23b6caaSPhilippe Mathieu-Daudé     case (64 * MiB):
52758d5b22bSBALATON Zoltan         bcr = 0xfe00;
52858d5b22bSBALATON Zoltan         break;
529d23b6caaSPhilippe Mathieu-Daudé     case (128 * MiB):
53058d5b22bSBALATON Zoltan         bcr = 0xfc00;
53158d5b22bSBALATON Zoltan         break;
532d23b6caaSPhilippe Mathieu-Daudé     case (256 * MiB):
53358d5b22bSBALATON Zoltan         bcr = 0xf800;
53458d5b22bSBALATON Zoltan         break;
535d23b6caaSPhilippe Mathieu-Daudé     case (512 * MiB):
53658d5b22bSBALATON Zoltan         bcr = 0xf000;
53758d5b22bSBALATON Zoltan         break;
538d23b6caaSPhilippe Mathieu-Daudé     case (1 * GiB):
53958d5b22bSBALATON Zoltan         bcr = 0xe000;
54058d5b22bSBALATON Zoltan         break;
54158d5b22bSBALATON Zoltan     default:
54258d5b22bSBALATON Zoltan         error_report("invalid RAM size " TARGET_FMT_plx, ram_size);
54358d5b22bSBALATON Zoltan         return 0;
54458d5b22bSBALATON Zoltan     }
54558d5b22bSBALATON Zoltan     bcr |= ram_base & 0xFF800000;
54658d5b22bSBALATON Zoltan     bcr |= 1;
54758d5b22bSBALATON Zoltan 
54858d5b22bSBALATON Zoltan     return bcr;
54958d5b22bSBALATON Zoltan }
55058d5b22bSBALATON Zoltan 
55158d5b22bSBALATON Zoltan static inline hwaddr sdram_base(uint32_t bcr)
55258d5b22bSBALATON Zoltan {
55358d5b22bSBALATON Zoltan     return bcr & 0xFF800000;
55458d5b22bSBALATON Zoltan }
55558d5b22bSBALATON Zoltan 
55658d5b22bSBALATON Zoltan static target_ulong sdram_size(uint32_t bcr)
55758d5b22bSBALATON Zoltan {
55858d5b22bSBALATON Zoltan     target_ulong size;
55958d5b22bSBALATON Zoltan     int sh;
56058d5b22bSBALATON Zoltan 
56158d5b22bSBALATON Zoltan     sh = 1024 - ((bcr >> 6) & 0x3ff);
562d23b6caaSPhilippe Mathieu-Daudé     size = 8 * MiB * sh;
56358d5b22bSBALATON Zoltan 
56458d5b22bSBALATON Zoltan     return size;
56558d5b22bSBALATON Zoltan }
56658d5b22bSBALATON Zoltan 
567*0a57fbeeSBALATON Zoltan static void sdram_set_bcr(ppc440_sdram_t *sdram,
56858d5b22bSBALATON Zoltan                           uint32_t *bcrp, uint32_t bcr, int enabled)
56958d5b22bSBALATON Zoltan {
57058d5b22bSBALATON Zoltan     unsigned n = bcrp - sdram->bcr;
57158d5b22bSBALATON Zoltan 
57258d5b22bSBALATON Zoltan     if (*bcrp & 1) {
57358d5b22bSBALATON Zoltan         /* Unmap RAM */
57458d5b22bSBALATON Zoltan         memory_region_del_subregion(get_system_memory(),
57558d5b22bSBALATON Zoltan                                     &sdram->containers[n]);
57658d5b22bSBALATON Zoltan         memory_region_del_subregion(&sdram->containers[n],
57758d5b22bSBALATON Zoltan                                     &sdram->ram_memories[n]);
57858d5b22bSBALATON Zoltan         object_unparent(OBJECT(&sdram->containers[n]));
57958d5b22bSBALATON Zoltan     }
58058d5b22bSBALATON Zoltan     *bcrp = bcr & 0xFFDEE001;
58158d5b22bSBALATON Zoltan     if (enabled && (bcr & 1)) {
58258d5b22bSBALATON Zoltan         memory_region_init(&sdram->containers[n], NULL, "sdram-containers",
58358d5b22bSBALATON Zoltan                            sdram_size(bcr));
58458d5b22bSBALATON Zoltan         memory_region_add_subregion(&sdram->containers[n], 0,
58558d5b22bSBALATON Zoltan                                     &sdram->ram_memories[n]);
58658d5b22bSBALATON Zoltan         memory_region_add_subregion(get_system_memory(),
58758d5b22bSBALATON Zoltan                                     sdram_base(bcr),
58858d5b22bSBALATON Zoltan                                     &sdram->containers[n]);
58958d5b22bSBALATON Zoltan     }
59058d5b22bSBALATON Zoltan }
59158d5b22bSBALATON Zoltan 
592*0a57fbeeSBALATON 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) {
59858d5b22bSBALATON Zoltan             sdram_set_bcr(sdram,
59958d5b22bSBALATON Zoltan                           &sdram->bcr[i],
60058d5b22bSBALATON Zoltan                           sdram_bcr(sdram->ram_bases[i], sdram->ram_sizes[i]),
60158d5b22bSBALATON Zoltan                           1);
60258d5b22bSBALATON Zoltan         } else {
60358d5b22bSBALATON Zoltan             sdram_set_bcr(sdram, &sdram->bcr[i], 0, 0);
60458d5b22bSBALATON Zoltan         }
60558d5b22bSBALATON Zoltan     }
60658d5b22bSBALATON Zoltan }
60758d5b22bSBALATON Zoltan 
60858d5b22bSBALATON Zoltan static uint32_t dcr_read_sdram(void *opaque, int dcrn)
60958d5b22bSBALATON Zoltan {
610*0a57fbeeSBALATON Zoltan     ppc440_sdram_t *sdram = opaque;
61158d5b22bSBALATON Zoltan     uint32_t ret = 0;
61258d5b22bSBALATON Zoltan 
61358d5b22bSBALATON Zoltan     switch (dcrn) {
61458d5b22bSBALATON Zoltan     case SDRAM_R0BAS:
61558d5b22bSBALATON Zoltan     case SDRAM_R1BAS:
61658d5b22bSBALATON Zoltan     case SDRAM_R2BAS:
61758d5b22bSBALATON Zoltan     case SDRAM_R3BAS:
61858d5b22bSBALATON Zoltan         ret = sdram_bcr(sdram->ram_bases[dcrn - SDRAM_R0BAS],
61958d5b22bSBALATON Zoltan                         sdram->ram_sizes[dcrn - SDRAM_R0BAS]);
62058d5b22bSBALATON Zoltan         break;
62158d5b22bSBALATON Zoltan     case SDRAM_CONF1HB:
62258d5b22bSBALATON Zoltan     case SDRAM_CONF1LL:
62358d5b22bSBALATON Zoltan     case SDRAM_CONFPATHB:
62458d5b22bSBALATON Zoltan     case SDRAM_PLBADDULL:
62558d5b22bSBALATON Zoltan     case SDRAM_PLBADDUHB:
62658d5b22bSBALATON Zoltan         break;
62758d5b22bSBALATON Zoltan     case SDRAM0_CFGADDR:
62858d5b22bSBALATON Zoltan         ret = sdram->addr;
62958d5b22bSBALATON Zoltan         break;
63058d5b22bSBALATON Zoltan     case SDRAM0_CFGDATA:
63158d5b22bSBALATON Zoltan         switch (sdram->addr) {
63258d5b22bSBALATON Zoltan         case 0x14: /* SDRAM_MCSTAT (405EX) */
63358d5b22bSBALATON Zoltan         case 0x1F:
63458d5b22bSBALATON Zoltan             ret = 0x80000000;
63558d5b22bSBALATON Zoltan             break;
63658d5b22bSBALATON Zoltan         case 0x21: /* SDRAM_MCOPT2 */
63758d5b22bSBALATON Zoltan             ret = 0x08000000;
63858d5b22bSBALATON Zoltan             break;
63958d5b22bSBALATON Zoltan         case 0x40: /* SDRAM_MB0CF */
64058d5b22bSBALATON Zoltan             ret = 0x00008001;
64158d5b22bSBALATON Zoltan             break;
64258d5b22bSBALATON Zoltan         case 0x7A: /* SDRAM_DLCR */
64358d5b22bSBALATON Zoltan             ret = 0x02000000;
64458d5b22bSBALATON Zoltan             break;
64558d5b22bSBALATON Zoltan         case 0xE1: /* SDR0_DDR0 */
64658d5b22bSBALATON Zoltan             ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1;
64758d5b22bSBALATON Zoltan             break;
64858d5b22bSBALATON Zoltan         default:
64958d5b22bSBALATON Zoltan             break;
65058d5b22bSBALATON Zoltan         }
65158d5b22bSBALATON Zoltan         break;
65258d5b22bSBALATON Zoltan     default:
65358d5b22bSBALATON Zoltan         break;
65458d5b22bSBALATON Zoltan     }
65558d5b22bSBALATON Zoltan 
65658d5b22bSBALATON Zoltan     return ret;
65758d5b22bSBALATON Zoltan }
65858d5b22bSBALATON Zoltan 
65958d5b22bSBALATON Zoltan static void dcr_write_sdram(void *opaque, int dcrn, uint32_t val)
66058d5b22bSBALATON Zoltan {
661*0a57fbeeSBALATON Zoltan     ppc440_sdram_t *sdram = opaque;
66258d5b22bSBALATON Zoltan 
66358d5b22bSBALATON Zoltan     switch (dcrn) {
66458d5b22bSBALATON Zoltan     case SDRAM_R0BAS:
66558d5b22bSBALATON Zoltan     case SDRAM_R1BAS:
66658d5b22bSBALATON Zoltan     case SDRAM_R2BAS:
66758d5b22bSBALATON Zoltan     case SDRAM_R3BAS:
66858d5b22bSBALATON Zoltan     case SDRAM_CONF1HB:
66958d5b22bSBALATON Zoltan     case SDRAM_CONF1LL:
67058d5b22bSBALATON Zoltan     case SDRAM_CONFPATHB:
67158d5b22bSBALATON Zoltan     case SDRAM_PLBADDULL:
67258d5b22bSBALATON Zoltan     case SDRAM_PLBADDUHB:
67358d5b22bSBALATON Zoltan         break;
67458d5b22bSBALATON Zoltan     case SDRAM0_CFGADDR:
67558d5b22bSBALATON Zoltan         sdram->addr = val;
67658d5b22bSBALATON Zoltan         break;
67758d5b22bSBALATON Zoltan     case SDRAM0_CFGDATA:
67858d5b22bSBALATON Zoltan         switch (sdram->addr) {
67958d5b22bSBALATON Zoltan         case 0x00: /* B0CR */
68058d5b22bSBALATON Zoltan             break;
68158d5b22bSBALATON Zoltan         default:
68258d5b22bSBALATON Zoltan             break;
68358d5b22bSBALATON Zoltan         }
68458d5b22bSBALATON Zoltan         break;
68558d5b22bSBALATON Zoltan     default:
68658d5b22bSBALATON Zoltan         break;
68758d5b22bSBALATON Zoltan     }
68858d5b22bSBALATON Zoltan }
68958d5b22bSBALATON Zoltan 
69058d5b22bSBALATON Zoltan static void sdram_reset(void *opaque)
69158d5b22bSBALATON Zoltan {
692*0a57fbeeSBALATON Zoltan     ppc440_sdram_t *sdram = opaque;
69358d5b22bSBALATON Zoltan 
69458d5b22bSBALATON Zoltan     sdram->addr = 0;
69558d5b22bSBALATON Zoltan }
69658d5b22bSBALATON Zoltan 
69758d5b22bSBALATON Zoltan void ppc440_sdram_init(CPUPPCState *env, int nbanks,
69858d5b22bSBALATON Zoltan                        MemoryRegion *ram_memories,
69958d5b22bSBALATON Zoltan                        hwaddr *ram_bases, hwaddr *ram_sizes,
70058d5b22bSBALATON Zoltan                        int do_init)
70158d5b22bSBALATON Zoltan {
702*0a57fbeeSBALATON Zoltan     ppc440_sdram_t *sdram;
70358d5b22bSBALATON Zoltan 
70458d5b22bSBALATON Zoltan     sdram = g_malloc0(sizeof(*sdram));
70558d5b22bSBALATON Zoltan     sdram->nbanks = nbanks;
70658d5b22bSBALATON Zoltan     sdram->ram_memories = ram_memories;
70758d5b22bSBALATON Zoltan     memcpy(sdram->ram_bases, ram_bases, nbanks * sizeof(hwaddr));
70858d5b22bSBALATON Zoltan     memcpy(sdram->ram_sizes, ram_sizes, nbanks * sizeof(hwaddr));
70958d5b22bSBALATON Zoltan     qemu_register_reset(&sdram_reset, sdram);
71058d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM0_CFGADDR,
71158d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
71258d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM0_CFGDATA,
71358d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
71458d5b22bSBALATON Zoltan     if (do_init) {
71558d5b22bSBALATON Zoltan         sdram_map_bcr(sdram);
71658d5b22bSBALATON Zoltan     }
71758d5b22bSBALATON Zoltan 
71858d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_R0BAS,
71958d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
72058d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_R1BAS,
72158d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
72258d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_R2BAS,
72358d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
72458d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_R3BAS,
72558d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
72658d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_CONF1HB,
72758d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
72858d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_PLBADDULL,
72958d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
73058d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_CONF1LL,
73158d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
73258d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_CONFPATHB,
73358d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
73458d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDRAM_PLBADDUHB,
73558d5b22bSBALATON Zoltan                      sdram, &dcr_read_sdram, &dcr_write_sdram);
73658d5b22bSBALATON Zoltan }
73758d5b22bSBALATON Zoltan 
73858d5b22bSBALATON Zoltan /*****************************************************************************/
73958d5b22bSBALATON Zoltan /* PLB to AHB bridge */
74058d5b22bSBALATON Zoltan enum {
74158d5b22bSBALATON Zoltan     AHB_TOP    = 0xA4,
74258d5b22bSBALATON Zoltan     AHB_BOT    = 0xA5,
74358d5b22bSBALATON Zoltan };
74458d5b22bSBALATON Zoltan 
74558d5b22bSBALATON Zoltan typedef struct ppc4xx_ahb_t {
74658d5b22bSBALATON Zoltan     uint32_t top;
74758d5b22bSBALATON Zoltan     uint32_t bot;
74858d5b22bSBALATON Zoltan } ppc4xx_ahb_t;
74958d5b22bSBALATON Zoltan 
75058d5b22bSBALATON Zoltan static uint32_t dcr_read_ahb(void *opaque, int dcrn)
75158d5b22bSBALATON Zoltan {
75258d5b22bSBALATON Zoltan     ppc4xx_ahb_t *ahb = opaque;
75358d5b22bSBALATON Zoltan     uint32_t ret = 0;
75458d5b22bSBALATON Zoltan 
75558d5b22bSBALATON Zoltan     switch (dcrn) {
75658d5b22bSBALATON Zoltan     case AHB_TOP:
75758d5b22bSBALATON Zoltan         ret = ahb->top;
75858d5b22bSBALATON Zoltan         break;
75958d5b22bSBALATON Zoltan     case AHB_BOT:
76058d5b22bSBALATON Zoltan         ret = ahb->bot;
76158d5b22bSBALATON Zoltan         break;
76258d5b22bSBALATON Zoltan     default:
76358d5b22bSBALATON Zoltan         break;
76458d5b22bSBALATON Zoltan     }
76558d5b22bSBALATON Zoltan 
76658d5b22bSBALATON Zoltan     return ret;
76758d5b22bSBALATON Zoltan }
76858d5b22bSBALATON Zoltan 
76958d5b22bSBALATON Zoltan static void dcr_write_ahb(void *opaque, int dcrn, uint32_t val)
77058d5b22bSBALATON Zoltan {
77158d5b22bSBALATON Zoltan     ppc4xx_ahb_t *ahb = opaque;
77258d5b22bSBALATON Zoltan 
77358d5b22bSBALATON Zoltan     switch (dcrn) {
77458d5b22bSBALATON Zoltan     case AHB_TOP:
77558d5b22bSBALATON Zoltan         ahb->top = val;
77658d5b22bSBALATON Zoltan         break;
77758d5b22bSBALATON Zoltan     case AHB_BOT:
77858d5b22bSBALATON Zoltan         ahb->bot = val;
77958d5b22bSBALATON Zoltan         break;
78058d5b22bSBALATON Zoltan     }
78158d5b22bSBALATON Zoltan }
78258d5b22bSBALATON Zoltan 
78358d5b22bSBALATON Zoltan static void ppc4xx_ahb_reset(void *opaque)
78458d5b22bSBALATON Zoltan {
78558d5b22bSBALATON Zoltan     ppc4xx_ahb_t *ahb = opaque;
78658d5b22bSBALATON Zoltan 
78758d5b22bSBALATON Zoltan     /* No error */
78858d5b22bSBALATON Zoltan     ahb->top = 0;
78958d5b22bSBALATON Zoltan     ahb->bot = 0;
79058d5b22bSBALATON Zoltan }
79158d5b22bSBALATON Zoltan 
79258d5b22bSBALATON Zoltan void ppc4xx_ahb_init(CPUPPCState *env)
79358d5b22bSBALATON Zoltan {
79458d5b22bSBALATON Zoltan     ppc4xx_ahb_t *ahb;
79558d5b22bSBALATON Zoltan 
79658d5b22bSBALATON Zoltan     ahb = g_malloc0(sizeof(*ahb));
79758d5b22bSBALATON Zoltan     ppc_dcr_register(env, AHB_TOP, ahb, &dcr_read_ahb, &dcr_write_ahb);
79858d5b22bSBALATON Zoltan     ppc_dcr_register(env, AHB_BOT, ahb, &dcr_read_ahb, &dcr_write_ahb);
79958d5b22bSBALATON Zoltan     qemu_register_reset(ppc4xx_ahb_reset, ahb);
80058d5b22bSBALATON Zoltan }
80158d5b22bSBALATON Zoltan 
80258d5b22bSBALATON Zoltan /*****************************************************************************/
8033c409c19SBALATON Zoltan /* DMA controller */
8043c409c19SBALATON Zoltan 
8053c409c19SBALATON Zoltan #define DMA0_CR_CE  (1 << 31)
8063c409c19SBALATON Zoltan #define DMA0_CR_PW  (1 << 26 | 1 << 25)
8073c409c19SBALATON Zoltan #define DMA0_CR_DAI (1 << 24)
8083c409c19SBALATON Zoltan #define DMA0_CR_SAI (1 << 23)
8093c409c19SBALATON Zoltan #define DMA0_CR_DEC (1 << 2)
8103c409c19SBALATON Zoltan 
8113c409c19SBALATON Zoltan enum {
8123c409c19SBALATON Zoltan     DMA0_CR  = 0x00,
8133c409c19SBALATON Zoltan     DMA0_CT,
8143c409c19SBALATON Zoltan     DMA0_SAH,
8153c409c19SBALATON Zoltan     DMA0_SAL,
8163c409c19SBALATON Zoltan     DMA0_DAH,
8173c409c19SBALATON Zoltan     DMA0_DAL,
8183c409c19SBALATON Zoltan     DMA0_SGH,
8193c409c19SBALATON Zoltan     DMA0_SGL,
8203c409c19SBALATON Zoltan 
8213c409c19SBALATON Zoltan     DMA0_SR  = 0x20,
8223c409c19SBALATON Zoltan     DMA0_SGC = 0x23,
8233c409c19SBALATON Zoltan     DMA0_SLP = 0x25,
8243c409c19SBALATON Zoltan     DMA0_POL = 0x26,
8253c409c19SBALATON Zoltan };
8263c409c19SBALATON Zoltan 
8273c409c19SBALATON Zoltan typedef struct {
8283c409c19SBALATON Zoltan     uint32_t cr;
8293c409c19SBALATON Zoltan     uint32_t ct;
8303c409c19SBALATON Zoltan     uint64_t sa;
8313c409c19SBALATON Zoltan     uint64_t da;
8323c409c19SBALATON Zoltan     uint64_t sg;
8333c409c19SBALATON Zoltan } PPC4xxDmaChnl;
8343c409c19SBALATON Zoltan 
8353c409c19SBALATON Zoltan typedef struct {
8363c409c19SBALATON Zoltan     int base;
8373c409c19SBALATON Zoltan     PPC4xxDmaChnl ch[4];
8383c409c19SBALATON Zoltan     uint32_t sr;
8393c409c19SBALATON Zoltan } PPC4xxDmaState;
8403c409c19SBALATON Zoltan 
8413c409c19SBALATON Zoltan static uint32_t dcr_read_dma(void *opaque, int dcrn)
8423c409c19SBALATON Zoltan {
8433c409c19SBALATON Zoltan     PPC4xxDmaState *dma = opaque;
8443c409c19SBALATON Zoltan     uint32_t val = 0;
8453c409c19SBALATON Zoltan     int addr = dcrn - dma->base;
8463c409c19SBALATON Zoltan     int chnl = addr / 8;
8473c409c19SBALATON Zoltan 
8483c409c19SBALATON Zoltan     switch (addr) {
8493c409c19SBALATON Zoltan     case 0x00 ... 0x1f:
8503c409c19SBALATON Zoltan         switch (addr % 8) {
8513c409c19SBALATON Zoltan         case DMA0_CR:
8523c409c19SBALATON Zoltan             val = dma->ch[chnl].cr;
8533c409c19SBALATON Zoltan             break;
8543c409c19SBALATON Zoltan         case DMA0_CT:
8553c409c19SBALATON Zoltan             val = dma->ch[chnl].ct;
8563c409c19SBALATON Zoltan             break;
8573c409c19SBALATON Zoltan         case DMA0_SAH:
8583c409c19SBALATON Zoltan             val = dma->ch[chnl].sa >> 32;
8593c409c19SBALATON Zoltan             break;
8603c409c19SBALATON Zoltan         case DMA0_SAL:
8613c409c19SBALATON Zoltan             val = dma->ch[chnl].sa;
8623c409c19SBALATON Zoltan             break;
8633c409c19SBALATON Zoltan         case DMA0_DAH:
8643c409c19SBALATON Zoltan             val = dma->ch[chnl].da >> 32;
8653c409c19SBALATON Zoltan             break;
8663c409c19SBALATON Zoltan         case DMA0_DAL:
8673c409c19SBALATON Zoltan             val = dma->ch[chnl].da;
8683c409c19SBALATON Zoltan             break;
8693c409c19SBALATON Zoltan         case DMA0_SGH:
8703c409c19SBALATON Zoltan             val = dma->ch[chnl].sg >> 32;
8713c409c19SBALATON Zoltan             break;
8723c409c19SBALATON Zoltan         case DMA0_SGL:
8733c409c19SBALATON Zoltan             val = dma->ch[chnl].sg;
8743c409c19SBALATON Zoltan             break;
8753c409c19SBALATON Zoltan         }
8763c409c19SBALATON Zoltan         break;
8773c409c19SBALATON Zoltan     case DMA0_SR:
8783c409c19SBALATON Zoltan         val = dma->sr;
8793c409c19SBALATON Zoltan         break;
8803c409c19SBALATON Zoltan     default:
8813c409c19SBALATON Zoltan         qemu_log_mask(LOG_UNIMP, "%s: unimplemented register %x (%d, %x)\n",
8823c409c19SBALATON Zoltan                       __func__, dcrn, chnl, addr);
8833c409c19SBALATON Zoltan     }
8843c409c19SBALATON Zoltan 
8853c409c19SBALATON Zoltan     return val;
8863c409c19SBALATON Zoltan }
8873c409c19SBALATON Zoltan 
8883c409c19SBALATON Zoltan static void dcr_write_dma(void *opaque, int dcrn, uint32_t val)
8893c409c19SBALATON Zoltan {
8903c409c19SBALATON Zoltan     PPC4xxDmaState *dma = opaque;
8913c409c19SBALATON Zoltan     int addr = dcrn - dma->base;
8923c409c19SBALATON Zoltan     int chnl = addr / 8;
8933c409c19SBALATON Zoltan 
8943c409c19SBALATON Zoltan     switch (addr) {
8953c409c19SBALATON Zoltan     case 0x00 ... 0x1f:
8963c409c19SBALATON Zoltan         switch (addr % 8) {
8973c409c19SBALATON Zoltan         case DMA0_CR:
8983c409c19SBALATON Zoltan             dma->ch[chnl].cr = val;
8993c409c19SBALATON Zoltan             if (val & DMA0_CR_CE) {
9003c409c19SBALATON Zoltan                 int count = dma->ch[chnl].ct & 0xffff;
9013c409c19SBALATON Zoltan 
9023c409c19SBALATON Zoltan                 if (count) {
9033c409c19SBALATON Zoltan                     int width, i, sidx, didx;
9043c409c19SBALATON Zoltan                     uint8_t *rptr, *wptr;
9053c409c19SBALATON Zoltan                     hwaddr rlen, wlen;
9063c409c19SBALATON Zoltan 
9073c409c19SBALATON Zoltan                     sidx = didx = 0;
9083c409c19SBALATON Zoltan                     width = 1 << ((val & DMA0_CR_PW) >> 25);
9093c409c19SBALATON Zoltan                     rptr = cpu_physical_memory_map(dma->ch[chnl].sa, &rlen, 0);
9103c409c19SBALATON Zoltan                     wptr = cpu_physical_memory_map(dma->ch[chnl].da, &wlen, 1);
9113c409c19SBALATON Zoltan                     if (rptr && wptr) {
9123c409c19SBALATON Zoltan                         if (!(val & DMA0_CR_DEC) &&
9133c409c19SBALATON Zoltan                             val & DMA0_CR_SAI && val & DMA0_CR_DAI) {
9143c409c19SBALATON Zoltan                             /* optimise common case */
9153c409c19SBALATON Zoltan                             memmove(wptr, rptr, count * width);
9163c409c19SBALATON Zoltan                             sidx = didx = count * width;
9173c409c19SBALATON Zoltan                         } else {
9183c409c19SBALATON Zoltan                             /* do it the slow way */
9193c409c19SBALATON Zoltan                             for (sidx = didx = i = 0; i < count; i++) {
9203c409c19SBALATON Zoltan                                 uint64_t v = ldn_le_p(rptr + sidx, width);
9213c409c19SBALATON Zoltan                                 stn_le_p(wptr + didx, width, v);
9223c409c19SBALATON Zoltan                                 if (val & DMA0_CR_SAI) {
9233c409c19SBALATON Zoltan                                     sidx += width;
9243c409c19SBALATON Zoltan                                 }
9253c409c19SBALATON Zoltan                                 if (val & DMA0_CR_DAI) {
9263c409c19SBALATON Zoltan                                     didx += width;
9273c409c19SBALATON Zoltan                                 }
9283c409c19SBALATON Zoltan                             }
9293c409c19SBALATON Zoltan                         }
9303c409c19SBALATON Zoltan                     }
9313c409c19SBALATON Zoltan                     if (wptr) {
9323c409c19SBALATON Zoltan                         cpu_physical_memory_unmap(wptr, wlen, 1, didx);
9333c409c19SBALATON Zoltan                     }
9347aeb1e51SPhilippe Mathieu-Daudé                     if (rptr) {
9353c409c19SBALATON Zoltan                         cpu_physical_memory_unmap(rptr, rlen, 0, sidx);
9363c409c19SBALATON Zoltan                     }
9373c409c19SBALATON Zoltan                 }
9383c409c19SBALATON Zoltan             }
9393c409c19SBALATON Zoltan             break;
9403c409c19SBALATON Zoltan         case DMA0_CT:
9413c409c19SBALATON Zoltan             dma->ch[chnl].ct = val;
9423c409c19SBALATON Zoltan             break;
9433c409c19SBALATON Zoltan         case DMA0_SAH:
9443c409c19SBALATON Zoltan             dma->ch[chnl].sa &= 0xffffffffULL;
9453c409c19SBALATON Zoltan             dma->ch[chnl].sa |= (uint64_t)val << 32;
9463c409c19SBALATON Zoltan             break;
9473c409c19SBALATON Zoltan         case DMA0_SAL:
9483c409c19SBALATON Zoltan             dma->ch[chnl].sa &= 0xffffffff00000000ULL;
9493c409c19SBALATON Zoltan             dma->ch[chnl].sa |= val;
9503c409c19SBALATON Zoltan             break;
9513c409c19SBALATON Zoltan         case DMA0_DAH:
9523c409c19SBALATON Zoltan             dma->ch[chnl].da &= 0xffffffffULL;
9533c409c19SBALATON Zoltan             dma->ch[chnl].da |= (uint64_t)val << 32;
9543c409c19SBALATON Zoltan             break;
9553c409c19SBALATON Zoltan         case DMA0_DAL:
9563c409c19SBALATON Zoltan             dma->ch[chnl].da &= 0xffffffff00000000ULL;
9573c409c19SBALATON Zoltan             dma->ch[chnl].da |= val;
9583c409c19SBALATON Zoltan             break;
9593c409c19SBALATON Zoltan         case DMA0_SGH:
9603c409c19SBALATON Zoltan             dma->ch[chnl].sg &= 0xffffffffULL;
9613c409c19SBALATON Zoltan             dma->ch[chnl].sg |= (uint64_t)val << 32;
9623c409c19SBALATON Zoltan             break;
9633c409c19SBALATON Zoltan         case DMA0_SGL:
9643c409c19SBALATON Zoltan             dma->ch[chnl].sg &= 0xffffffff00000000ULL;
9653c409c19SBALATON Zoltan             dma->ch[chnl].sg |= val;
9663c409c19SBALATON Zoltan             break;
9673c409c19SBALATON Zoltan         }
9683c409c19SBALATON Zoltan         break;
9693c409c19SBALATON Zoltan     case DMA0_SR:
9703c409c19SBALATON Zoltan         dma->sr &= ~val;
9713c409c19SBALATON Zoltan         break;
9723c409c19SBALATON Zoltan     default:
9733c409c19SBALATON Zoltan         qemu_log_mask(LOG_UNIMP, "%s: unimplemented register %x (%d, %x)\n",
9743c409c19SBALATON Zoltan                       __func__, dcrn, chnl, addr);
9753c409c19SBALATON Zoltan     }
9763c409c19SBALATON Zoltan }
9773c409c19SBALATON Zoltan 
9783c409c19SBALATON Zoltan static void ppc4xx_dma_reset(void *opaque)
9793c409c19SBALATON Zoltan {
9803c409c19SBALATON Zoltan     PPC4xxDmaState *dma = opaque;
9813c409c19SBALATON Zoltan     int dma_base = dma->base;
9823c409c19SBALATON Zoltan 
9833c409c19SBALATON Zoltan     memset(dma, 0, sizeof(*dma));
9843c409c19SBALATON Zoltan     dma->base = dma_base;
9853c409c19SBALATON Zoltan }
9863c409c19SBALATON Zoltan 
9873c409c19SBALATON Zoltan void ppc4xx_dma_init(CPUPPCState *env, int dcr_base)
9883c409c19SBALATON Zoltan {
9893c409c19SBALATON Zoltan     PPC4xxDmaState *dma;
9903c409c19SBALATON Zoltan     int i;
9913c409c19SBALATON Zoltan 
9923c409c19SBALATON Zoltan     dma = g_malloc0(sizeof(*dma));
9933c409c19SBALATON Zoltan     dma->base = dcr_base;
9943c409c19SBALATON Zoltan     qemu_register_reset(&ppc4xx_dma_reset, dma);
9953c409c19SBALATON Zoltan     for (i = 0; i < 4; i++) {
9963c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CR,
9973c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
9983c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CT,
9993c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
10003c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAH,
10013c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
10023c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAL,
10033c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
10043c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAH,
10053c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
10063c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAL,
10073c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
10083c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGH,
10093c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
10103c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGL,
10113c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
10123c409c19SBALATON Zoltan     }
10133c409c19SBALATON Zoltan     ppc_dcr_register(env, dcr_base + DMA0_SR,
10143c409c19SBALATON Zoltan                      dma, &dcr_read_dma, &dcr_write_dma);
10153c409c19SBALATON Zoltan     ppc_dcr_register(env, dcr_base + DMA0_SGC,
10163c409c19SBALATON Zoltan                      dma, &dcr_read_dma, &dcr_write_dma);
10173c409c19SBALATON Zoltan     ppc_dcr_register(env, dcr_base + DMA0_SLP,
10183c409c19SBALATON Zoltan                      dma, &dcr_read_dma, &dcr_write_dma);
10193c409c19SBALATON Zoltan     ppc_dcr_register(env, dcr_base + DMA0_POL,
10203c409c19SBALATON Zoltan                      dma, &dcr_read_dma, &dcr_write_dma);
10213c409c19SBALATON Zoltan }
10223c409c19SBALATON Zoltan 
10233c409c19SBALATON Zoltan /*****************************************************************************/
102458d5b22bSBALATON Zoltan /* PCI Express controller */
102558d5b22bSBALATON Zoltan /* FIXME: This is not complete and does not work, only implemented partially
102658d5b22bSBALATON Zoltan  * to allow firmware and guests to find an empty bus. Cards should use PCI.
102758d5b22bSBALATON Zoltan  */
102858d5b22bSBALATON Zoltan #include "hw/pci/pcie_host.h"
102958d5b22bSBALATON Zoltan 
103058d5b22bSBALATON Zoltan #define TYPE_PPC460EX_PCIE_HOST "ppc460ex-pcie-host"
103158d5b22bSBALATON Zoltan #define PPC460EX_PCIE_HOST(obj) \
103258d5b22bSBALATON Zoltan     OBJECT_CHECK(PPC460EXPCIEState, (obj), TYPE_PPC460EX_PCIE_HOST)
103358d5b22bSBALATON Zoltan 
103458d5b22bSBALATON Zoltan typedef struct PPC460EXPCIEState {
103558d5b22bSBALATON Zoltan     PCIExpressHost host;
103658d5b22bSBALATON Zoltan 
103758d5b22bSBALATON Zoltan     MemoryRegion iomem;
103858d5b22bSBALATON Zoltan     qemu_irq irq[4];
103958d5b22bSBALATON Zoltan     int32_t dcrn_base;
104058d5b22bSBALATON Zoltan 
104158d5b22bSBALATON Zoltan     uint64_t cfg_base;
104258d5b22bSBALATON Zoltan     uint32_t cfg_mask;
104358d5b22bSBALATON Zoltan     uint64_t msg_base;
104458d5b22bSBALATON Zoltan     uint32_t msg_mask;
104558d5b22bSBALATON Zoltan     uint64_t omr1_base;
104658d5b22bSBALATON Zoltan     uint64_t omr1_mask;
104758d5b22bSBALATON Zoltan     uint64_t omr2_base;
104858d5b22bSBALATON Zoltan     uint64_t omr2_mask;
104958d5b22bSBALATON Zoltan     uint64_t omr3_base;
105058d5b22bSBALATON Zoltan     uint64_t omr3_mask;
105158d5b22bSBALATON Zoltan     uint64_t reg_base;
105258d5b22bSBALATON Zoltan     uint32_t reg_mask;
105358d5b22bSBALATON Zoltan     uint32_t special;
105458d5b22bSBALATON Zoltan     uint32_t cfg;
105558d5b22bSBALATON Zoltan } PPC460EXPCIEState;
105658d5b22bSBALATON Zoltan 
105758d5b22bSBALATON Zoltan #define DCRN_PCIE0_BASE 0x100
105858d5b22bSBALATON Zoltan #define DCRN_PCIE1_BASE 0x120
105958d5b22bSBALATON Zoltan 
106058d5b22bSBALATON Zoltan enum {
106158d5b22bSBALATON Zoltan     PEGPL_CFGBAH = 0x0,
106258d5b22bSBALATON Zoltan     PEGPL_CFGBAL,
106358d5b22bSBALATON Zoltan     PEGPL_CFGMSK,
106458d5b22bSBALATON Zoltan     PEGPL_MSGBAH,
106558d5b22bSBALATON Zoltan     PEGPL_MSGBAL,
106658d5b22bSBALATON Zoltan     PEGPL_MSGMSK,
106758d5b22bSBALATON Zoltan     PEGPL_OMR1BAH,
106858d5b22bSBALATON Zoltan     PEGPL_OMR1BAL,
106958d5b22bSBALATON Zoltan     PEGPL_OMR1MSKH,
107058d5b22bSBALATON Zoltan     PEGPL_OMR1MSKL,
107158d5b22bSBALATON Zoltan     PEGPL_OMR2BAH,
107258d5b22bSBALATON Zoltan     PEGPL_OMR2BAL,
107358d5b22bSBALATON Zoltan     PEGPL_OMR2MSKH,
107458d5b22bSBALATON Zoltan     PEGPL_OMR2MSKL,
107558d5b22bSBALATON Zoltan     PEGPL_OMR3BAH,
107658d5b22bSBALATON Zoltan     PEGPL_OMR3BAL,
107758d5b22bSBALATON Zoltan     PEGPL_OMR3MSKH,
107858d5b22bSBALATON Zoltan     PEGPL_OMR3MSKL,
107958d5b22bSBALATON Zoltan     PEGPL_REGBAH,
108058d5b22bSBALATON Zoltan     PEGPL_REGBAL,
108158d5b22bSBALATON Zoltan     PEGPL_REGMSK,
108258d5b22bSBALATON Zoltan     PEGPL_SPECIAL,
108358d5b22bSBALATON Zoltan     PEGPL_CFG,
108458d5b22bSBALATON Zoltan };
108558d5b22bSBALATON Zoltan 
108658d5b22bSBALATON Zoltan static uint32_t dcr_read_pcie(void *opaque, int dcrn)
108758d5b22bSBALATON Zoltan {
108858d5b22bSBALATON Zoltan     PPC460EXPCIEState *state = opaque;
108958d5b22bSBALATON Zoltan     uint32_t ret = 0;
109058d5b22bSBALATON Zoltan 
109158d5b22bSBALATON Zoltan     switch (dcrn - state->dcrn_base) {
109258d5b22bSBALATON Zoltan     case PEGPL_CFGBAH:
109358d5b22bSBALATON Zoltan         ret = state->cfg_base >> 32;
109458d5b22bSBALATON Zoltan         break;
109558d5b22bSBALATON Zoltan     case PEGPL_CFGBAL:
109658d5b22bSBALATON Zoltan         ret = state->cfg_base;
109758d5b22bSBALATON Zoltan         break;
109858d5b22bSBALATON Zoltan     case PEGPL_CFGMSK:
109958d5b22bSBALATON Zoltan         ret = state->cfg_mask;
110058d5b22bSBALATON Zoltan         break;
110158d5b22bSBALATON Zoltan     case PEGPL_MSGBAH:
110258d5b22bSBALATON Zoltan         ret = state->msg_base >> 32;
110358d5b22bSBALATON Zoltan         break;
110458d5b22bSBALATON Zoltan     case PEGPL_MSGBAL:
110558d5b22bSBALATON Zoltan         ret = state->msg_base;
110658d5b22bSBALATON Zoltan         break;
110758d5b22bSBALATON Zoltan     case PEGPL_MSGMSK:
110858d5b22bSBALATON Zoltan         ret = state->msg_mask;
110958d5b22bSBALATON Zoltan         break;
111058d5b22bSBALATON Zoltan     case PEGPL_OMR1BAH:
111158d5b22bSBALATON Zoltan         ret = state->omr1_base >> 32;
111258d5b22bSBALATON Zoltan         break;
111358d5b22bSBALATON Zoltan     case PEGPL_OMR1BAL:
111458d5b22bSBALATON Zoltan         ret = state->omr1_base;
111558d5b22bSBALATON Zoltan         break;
111658d5b22bSBALATON Zoltan     case PEGPL_OMR1MSKH:
111758d5b22bSBALATON Zoltan         ret = state->omr1_mask >> 32;
111858d5b22bSBALATON Zoltan         break;
111958d5b22bSBALATON Zoltan     case PEGPL_OMR1MSKL:
112058d5b22bSBALATON Zoltan         ret = state->omr1_mask;
112158d5b22bSBALATON Zoltan         break;
112258d5b22bSBALATON Zoltan     case PEGPL_OMR2BAH:
112358d5b22bSBALATON Zoltan         ret = state->omr2_base >> 32;
112458d5b22bSBALATON Zoltan         break;
112558d5b22bSBALATON Zoltan     case PEGPL_OMR2BAL:
112658d5b22bSBALATON Zoltan         ret = state->omr2_base;
112758d5b22bSBALATON Zoltan         break;
112858d5b22bSBALATON Zoltan     case PEGPL_OMR2MSKH:
112958d5b22bSBALATON Zoltan         ret = state->omr2_mask >> 32;
113058d5b22bSBALATON Zoltan         break;
113158d5b22bSBALATON Zoltan     case PEGPL_OMR2MSKL:
113258d5b22bSBALATON Zoltan         ret = state->omr3_mask;
113358d5b22bSBALATON Zoltan         break;
113458d5b22bSBALATON Zoltan     case PEGPL_OMR3BAH:
113558d5b22bSBALATON Zoltan         ret = state->omr3_base >> 32;
113658d5b22bSBALATON Zoltan         break;
113758d5b22bSBALATON Zoltan     case PEGPL_OMR3BAL:
113858d5b22bSBALATON Zoltan         ret = state->omr3_base;
113958d5b22bSBALATON Zoltan         break;
114058d5b22bSBALATON Zoltan     case PEGPL_OMR3MSKH:
114158d5b22bSBALATON Zoltan         ret = state->omr3_mask >> 32;
114258d5b22bSBALATON Zoltan         break;
114358d5b22bSBALATON Zoltan     case PEGPL_OMR3MSKL:
114458d5b22bSBALATON Zoltan         ret = state->omr3_mask;
114558d5b22bSBALATON Zoltan         break;
114658d5b22bSBALATON Zoltan     case PEGPL_REGBAH:
114758d5b22bSBALATON Zoltan         ret = state->reg_base >> 32;
114858d5b22bSBALATON Zoltan         break;
114958d5b22bSBALATON Zoltan     case PEGPL_REGBAL:
115058d5b22bSBALATON Zoltan         ret = state->reg_base;
115158d5b22bSBALATON Zoltan         break;
115258d5b22bSBALATON Zoltan     case PEGPL_REGMSK:
115358d5b22bSBALATON Zoltan         ret = state->reg_mask;
115458d5b22bSBALATON Zoltan         break;
115558d5b22bSBALATON Zoltan     case PEGPL_SPECIAL:
115658d5b22bSBALATON Zoltan         ret = state->special;
115758d5b22bSBALATON Zoltan         break;
115858d5b22bSBALATON Zoltan     case PEGPL_CFG:
115958d5b22bSBALATON Zoltan         ret = state->cfg;
116058d5b22bSBALATON Zoltan         break;
116158d5b22bSBALATON Zoltan     }
116258d5b22bSBALATON Zoltan 
116358d5b22bSBALATON Zoltan     return ret;
116458d5b22bSBALATON Zoltan }
116558d5b22bSBALATON Zoltan 
116658d5b22bSBALATON Zoltan static void dcr_write_pcie(void *opaque, int dcrn, uint32_t val)
116758d5b22bSBALATON Zoltan {
116858d5b22bSBALATON Zoltan     PPC460EXPCIEState *s = opaque;
116958d5b22bSBALATON Zoltan     uint64_t size;
117058d5b22bSBALATON Zoltan 
117158d5b22bSBALATON Zoltan     switch (dcrn - s->dcrn_base) {
117258d5b22bSBALATON Zoltan     case PEGPL_CFGBAH:
117358d5b22bSBALATON Zoltan         s->cfg_base = ((uint64_t)val << 32) | (s->cfg_base & 0xffffffff);
117458d5b22bSBALATON Zoltan         break;
117558d5b22bSBALATON Zoltan     case PEGPL_CFGBAL:
117658d5b22bSBALATON Zoltan         s->cfg_base = (s->cfg_base & 0xffffffff00000000ULL) | val;
117758d5b22bSBALATON Zoltan         break;
117858d5b22bSBALATON Zoltan     case PEGPL_CFGMSK:
117958d5b22bSBALATON Zoltan         s->cfg_mask = val;
118058d5b22bSBALATON Zoltan         size = ~(val & 0xfffffffe) + 1;
118158d5b22bSBALATON Zoltan         qemu_mutex_lock_iothread();
118258d5b22bSBALATON Zoltan         pcie_host_mmcfg_update(PCIE_HOST_BRIDGE(s), val & 1, s->cfg_base, size);
118358d5b22bSBALATON Zoltan         qemu_mutex_unlock_iothread();
118458d5b22bSBALATON Zoltan         break;
118558d5b22bSBALATON Zoltan     case PEGPL_MSGBAH:
118658d5b22bSBALATON Zoltan         s->msg_base = ((uint64_t)val << 32) | (s->msg_base & 0xffffffff);
118758d5b22bSBALATON Zoltan         break;
118858d5b22bSBALATON Zoltan     case PEGPL_MSGBAL:
118958d5b22bSBALATON Zoltan         s->msg_base = (s->msg_base & 0xffffffff00000000ULL) | val;
119058d5b22bSBALATON Zoltan         break;
119158d5b22bSBALATON Zoltan     case PEGPL_MSGMSK:
119258d5b22bSBALATON Zoltan         s->msg_mask = val;
119358d5b22bSBALATON Zoltan         break;
119458d5b22bSBALATON Zoltan     case PEGPL_OMR1BAH:
119558d5b22bSBALATON Zoltan         s->omr1_base = ((uint64_t)val << 32) | (s->omr1_base & 0xffffffff);
119658d5b22bSBALATON Zoltan         break;
119758d5b22bSBALATON Zoltan     case PEGPL_OMR1BAL:
119858d5b22bSBALATON Zoltan         s->omr1_base = (s->omr1_base & 0xffffffff00000000ULL) | val;
119958d5b22bSBALATON Zoltan         break;
120058d5b22bSBALATON Zoltan     case PEGPL_OMR1MSKH:
120158d5b22bSBALATON Zoltan         s->omr1_mask = ((uint64_t)val << 32) | (s->omr1_mask & 0xffffffff);
120258d5b22bSBALATON Zoltan         break;
120358d5b22bSBALATON Zoltan     case PEGPL_OMR1MSKL:
120458d5b22bSBALATON Zoltan         s->omr1_mask = (s->omr1_mask & 0xffffffff00000000ULL) | val;
120558d5b22bSBALATON Zoltan         break;
120658d5b22bSBALATON Zoltan     case PEGPL_OMR2BAH:
120758d5b22bSBALATON Zoltan         s->omr2_base = ((uint64_t)val << 32) | (s->omr2_base & 0xffffffff);
120858d5b22bSBALATON Zoltan         break;
120958d5b22bSBALATON Zoltan     case PEGPL_OMR2BAL:
121058d5b22bSBALATON Zoltan         s->omr2_base = (s->omr2_base & 0xffffffff00000000ULL) | val;
121158d5b22bSBALATON Zoltan         break;
121258d5b22bSBALATON Zoltan     case PEGPL_OMR2MSKH:
121358d5b22bSBALATON Zoltan         s->omr2_mask = ((uint64_t)val << 32) | (s->omr2_mask & 0xffffffff);
121458d5b22bSBALATON Zoltan         break;
121558d5b22bSBALATON Zoltan     case PEGPL_OMR2MSKL:
121658d5b22bSBALATON Zoltan         s->omr2_mask = (s->omr2_mask & 0xffffffff00000000ULL) | val;
121758d5b22bSBALATON Zoltan         break;
121858d5b22bSBALATON Zoltan     case PEGPL_OMR3BAH:
121958d5b22bSBALATON Zoltan         s->omr3_base = ((uint64_t)val << 32) | (s->omr3_base & 0xffffffff);
122058d5b22bSBALATON Zoltan         break;
122158d5b22bSBALATON Zoltan     case PEGPL_OMR3BAL:
122258d5b22bSBALATON Zoltan         s->omr3_base = (s->omr3_base & 0xffffffff00000000ULL) | val;
122358d5b22bSBALATON Zoltan         break;
122458d5b22bSBALATON Zoltan     case PEGPL_OMR3MSKH:
122558d5b22bSBALATON Zoltan         s->omr3_mask = ((uint64_t)val << 32) | (s->omr3_mask & 0xffffffff);
122658d5b22bSBALATON Zoltan         break;
122758d5b22bSBALATON Zoltan     case PEGPL_OMR3MSKL:
122858d5b22bSBALATON Zoltan         s->omr3_mask = (s->omr3_mask & 0xffffffff00000000ULL) | val;
122958d5b22bSBALATON Zoltan         break;
123058d5b22bSBALATON Zoltan     case PEGPL_REGBAH:
123158d5b22bSBALATON Zoltan         s->reg_base = ((uint64_t)val << 32) | (s->reg_base & 0xffffffff);
123258d5b22bSBALATON Zoltan         break;
123358d5b22bSBALATON Zoltan     case PEGPL_REGBAL:
123458d5b22bSBALATON Zoltan         s->reg_base = (s->reg_base & 0xffffffff00000000ULL) | val;
123558d5b22bSBALATON Zoltan         break;
123658d5b22bSBALATON Zoltan     case PEGPL_REGMSK:
123758d5b22bSBALATON Zoltan         s->reg_mask = val;
123858d5b22bSBALATON Zoltan         /* FIXME: how is size encoded? */
123958d5b22bSBALATON Zoltan         size = (val == 0x7001 ? 4096 : ~(val & 0xfffffffe) + 1);
124058d5b22bSBALATON Zoltan         break;
124158d5b22bSBALATON Zoltan     case PEGPL_SPECIAL:
124258d5b22bSBALATON Zoltan         s->special = val;
124358d5b22bSBALATON Zoltan         break;
124458d5b22bSBALATON Zoltan     case PEGPL_CFG:
124558d5b22bSBALATON Zoltan         s->cfg = val;
124658d5b22bSBALATON Zoltan         break;
124758d5b22bSBALATON Zoltan     }
124858d5b22bSBALATON Zoltan }
124958d5b22bSBALATON Zoltan 
125058d5b22bSBALATON Zoltan static void ppc460ex_set_irq(void *opaque, int irq_num, int level)
125158d5b22bSBALATON Zoltan {
125258d5b22bSBALATON Zoltan        PPC460EXPCIEState *s = opaque;
125358d5b22bSBALATON Zoltan        qemu_set_irq(s->irq[irq_num], level);
125458d5b22bSBALATON Zoltan }
125558d5b22bSBALATON Zoltan 
125658d5b22bSBALATON Zoltan static void ppc460ex_pcie_realize(DeviceState *dev, Error **errp)
125758d5b22bSBALATON Zoltan {
125858d5b22bSBALATON Zoltan     PPC460EXPCIEState *s = PPC460EX_PCIE_HOST(dev);
125958d5b22bSBALATON Zoltan     PCIHostState *pci = PCI_HOST_BRIDGE(dev);
126058d5b22bSBALATON Zoltan     int i, id;
126158d5b22bSBALATON Zoltan     char buf[16];
126258d5b22bSBALATON Zoltan 
126358d5b22bSBALATON Zoltan     switch (s->dcrn_base) {
126458d5b22bSBALATON Zoltan     case DCRN_PCIE0_BASE:
126558d5b22bSBALATON Zoltan         id = 0;
126658d5b22bSBALATON Zoltan         break;
126758d5b22bSBALATON Zoltan     case DCRN_PCIE1_BASE:
126858d5b22bSBALATON Zoltan         id = 1;
126958d5b22bSBALATON Zoltan         break;
1270ff22e0ebSBALATON Zoltan     default:
1271ff22e0ebSBALATON Zoltan         error_setg(errp, "invalid PCIe DCRN base");
1272ff22e0ebSBALATON Zoltan         return;
127358d5b22bSBALATON Zoltan     }
127458d5b22bSBALATON Zoltan     snprintf(buf, sizeof(buf), "pcie%d-io", id);
127558d5b22bSBALATON Zoltan     memory_region_init(&s->iomem, OBJECT(s), buf, UINT64_MAX);
127658d5b22bSBALATON Zoltan     for (i = 0; i < 4; i++) {
127758d5b22bSBALATON Zoltan         sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[i]);
127858d5b22bSBALATON Zoltan     }
127958d5b22bSBALATON Zoltan     snprintf(buf, sizeof(buf), "pcie.%d", id);
128058d5b22bSBALATON Zoltan     pci->bus = pci_register_root_bus(DEVICE(s), buf, ppc460ex_set_irq,
128158d5b22bSBALATON Zoltan                                 pci_swizzle_map_irq_fn, s, &s->iomem,
128258d5b22bSBALATON Zoltan                                 get_system_io(), 0, 4, TYPE_PCIE_BUS);
128358d5b22bSBALATON Zoltan }
128458d5b22bSBALATON Zoltan 
128558d5b22bSBALATON Zoltan static Property ppc460ex_pcie_props[] = {
128658d5b22bSBALATON Zoltan     DEFINE_PROP_INT32("dcrn-base", PPC460EXPCIEState, dcrn_base, -1),
128758d5b22bSBALATON Zoltan     DEFINE_PROP_END_OF_LIST(),
128858d5b22bSBALATON Zoltan };
128958d5b22bSBALATON Zoltan 
129058d5b22bSBALATON Zoltan static void ppc460ex_pcie_class_init(ObjectClass *klass, void *data)
129158d5b22bSBALATON Zoltan {
129258d5b22bSBALATON Zoltan     DeviceClass *dc = DEVICE_CLASS(klass);
129358d5b22bSBALATON Zoltan 
129458d5b22bSBALATON Zoltan     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
129558d5b22bSBALATON Zoltan     dc->realize = ppc460ex_pcie_realize;
129658d5b22bSBALATON Zoltan     dc->props = ppc460ex_pcie_props;
129758d5b22bSBALATON Zoltan     dc->hotpluggable = false;
129858d5b22bSBALATON Zoltan }
129958d5b22bSBALATON Zoltan 
130058d5b22bSBALATON Zoltan static const TypeInfo ppc460ex_pcie_host_info = {
130158d5b22bSBALATON Zoltan     .name = TYPE_PPC460EX_PCIE_HOST,
130258d5b22bSBALATON Zoltan     .parent = TYPE_PCIE_HOST_BRIDGE,
130358d5b22bSBALATON Zoltan     .instance_size = sizeof(PPC460EXPCIEState),
130458d5b22bSBALATON Zoltan     .class_init = ppc460ex_pcie_class_init,
130558d5b22bSBALATON Zoltan };
130658d5b22bSBALATON Zoltan 
130758d5b22bSBALATON Zoltan static void ppc460ex_pcie_register(void)
130858d5b22bSBALATON Zoltan {
130958d5b22bSBALATON Zoltan     type_register_static(&ppc460ex_pcie_host_info);
131058d5b22bSBALATON Zoltan }
131158d5b22bSBALATON Zoltan 
131258d5b22bSBALATON Zoltan type_init(ppc460ex_pcie_register)
131358d5b22bSBALATON Zoltan 
131458d5b22bSBALATON Zoltan static void ppc460ex_pcie_register_dcrs(PPC460EXPCIEState *s, CPUPPCState *env)
131558d5b22bSBALATON Zoltan {
131658d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGBAH, s,
131758d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
131858d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGBAL, s,
131958d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
132058d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGMSK, s,
132158d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
132258d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGBAH, s,
132358d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
132458d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGBAL, s,
132558d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
132658d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGMSK, s,
132758d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
132858d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1BAH, s,
132958d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
133058d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1BAL, s,
133158d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
133258d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1MSKH, s,
133358d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
133458d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1MSKL, s,
133558d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
133658d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2BAH, s,
133758d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
133858d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2BAL, s,
133958d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
134058d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2MSKH, s,
134158d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
134258d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2MSKL, s,
134358d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
134458d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3BAH, s,
134558d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
134658d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3BAL, s,
134758d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
134858d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3MSKH, s,
134958d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
135058d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3MSKL, s,
135158d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
135258d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_REGBAH, s,
135358d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
135458d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_REGBAL, s,
135558d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
135658d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_REGMSK, s,
135758d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
135858d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_SPECIAL, s,
135958d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
136058d5b22bSBALATON Zoltan     ppc_dcr_register(env, s->dcrn_base + PEGPL_CFG, s,
136158d5b22bSBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie);
136258d5b22bSBALATON Zoltan }
136358d5b22bSBALATON Zoltan 
136458d5b22bSBALATON Zoltan void ppc460ex_pcie_init(CPUPPCState *env)
136558d5b22bSBALATON Zoltan {
136658d5b22bSBALATON Zoltan     DeviceState *dev;
136758d5b22bSBALATON Zoltan 
136858d5b22bSBALATON Zoltan     dev = qdev_create(NULL, TYPE_PPC460EX_PCIE_HOST);
136958d5b22bSBALATON Zoltan     qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE0_BASE);
137058d5b22bSBALATON Zoltan     qdev_init_nofail(dev);
137158d5b22bSBALATON Zoltan     object_property_set_bool(OBJECT(dev), true, "realized", NULL);
137258d5b22bSBALATON Zoltan     ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), env);
137358d5b22bSBALATON Zoltan 
137458d5b22bSBALATON Zoltan     dev = qdev_create(NULL, TYPE_PPC460EX_PCIE_HOST);
137558d5b22bSBALATON Zoltan     qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE1_BASE);
137658d5b22bSBALATON Zoltan     qdev_init_nofail(dev);
137758d5b22bSBALATON Zoltan     object_property_set_bool(OBJECT(dev), true, "realized", NULL);
137858d5b22bSBALATON Zoltan     ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), env);
137958d5b22bSBALATON Zoltan }
1380