xref: /qemu/hw/ppc/ppc440_uc.c (revision 4d641f36)
158d5b22bSBALATON Zoltan /*
258d5b22bSBALATON Zoltan  * QEMU PowerPC 440 embedded processors emulation
358d5b22bSBALATON Zoltan  *
458d5b22bSBALATON Zoltan  * Copyright (c) 2012 François Revol
56a9938a3SBALATON 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 "qapi/error.h"
143c409c19SBALATON Zoltan #include "qemu/log.h"
1564552b6bSMarkus Armbruster #include "hw/irq.h"
1686269823SBALATON Zoltan #include "hw/ppc/ppc4xx.h"
17*4d641f36SPhilippe Mathieu-Daudé #include "hw/pci-host/ppc4xx.h"
18a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h"
1958d5b22bSBALATON Zoltan #include "hw/pci/pci.h"
2071e8a915SMarkus Armbruster #include "sysemu/reset.h"
21339d13ceSBALATON Zoltan #include "cpu.h"
2272a56a1fSMichael S. Tsirkin #include "ppc440.h"
2358d5b22bSBALATON Zoltan 
2458d5b22bSBALATON Zoltan /*****************************************************************************/
2558d5b22bSBALATON Zoltan /* L2 Cache as SRAM */
2658d5b22bSBALATON Zoltan /* FIXME:fix names */
2758d5b22bSBALATON Zoltan enum {
2858d5b22bSBALATON Zoltan     DCR_L2CACHE_BASE  = 0x30,
2958d5b22bSBALATON Zoltan     DCR_L2CACHE_CFG   = DCR_L2CACHE_BASE,
3058d5b22bSBALATON Zoltan     DCR_L2CACHE_CMD,
3158d5b22bSBALATON Zoltan     DCR_L2CACHE_ADDR,
3258d5b22bSBALATON Zoltan     DCR_L2CACHE_DATA,
3358d5b22bSBALATON Zoltan     DCR_L2CACHE_STAT,
3458d5b22bSBALATON Zoltan     DCR_L2CACHE_CVER,
3558d5b22bSBALATON Zoltan     DCR_L2CACHE_SNP0,
3658d5b22bSBALATON Zoltan     DCR_L2CACHE_SNP1,
3758d5b22bSBALATON Zoltan     DCR_L2CACHE_END   = DCR_L2CACHE_SNP1,
3858d5b22bSBALATON Zoltan };
3958d5b22bSBALATON Zoltan 
4058d5b22bSBALATON Zoltan /* base is 460ex-specific, cf. U-Boot, ppc4xx-isram.h */
4158d5b22bSBALATON Zoltan enum {
4258d5b22bSBALATON Zoltan     DCR_ISRAM0_BASE   = 0x20,
4358d5b22bSBALATON Zoltan     DCR_ISRAM0_SB0CR  = DCR_ISRAM0_BASE,
4458d5b22bSBALATON Zoltan     DCR_ISRAM0_SB1CR,
4558d5b22bSBALATON Zoltan     DCR_ISRAM0_SB2CR,
4658d5b22bSBALATON Zoltan     DCR_ISRAM0_SB3CR,
4758d5b22bSBALATON Zoltan     DCR_ISRAM0_BEAR,
4858d5b22bSBALATON Zoltan     DCR_ISRAM0_BESR0,
4958d5b22bSBALATON Zoltan     DCR_ISRAM0_BESR1,
5058d5b22bSBALATON Zoltan     DCR_ISRAM0_PMEG,
5158d5b22bSBALATON Zoltan     DCR_ISRAM0_CID,
5258d5b22bSBALATON Zoltan     DCR_ISRAM0_REVID,
5358d5b22bSBALATON Zoltan     DCR_ISRAM0_DPC,
5458d5b22bSBALATON Zoltan     DCR_ISRAM0_END    = DCR_ISRAM0_DPC
5558d5b22bSBALATON Zoltan };
5658d5b22bSBALATON Zoltan 
5758d5b22bSBALATON Zoltan enum {
5858d5b22bSBALATON Zoltan     DCR_ISRAM1_BASE   = 0xb0,
5958d5b22bSBALATON Zoltan     DCR_ISRAM1_SB0CR  = DCR_ISRAM1_BASE,
6058d5b22bSBALATON Zoltan     /* single bank */
6158d5b22bSBALATON Zoltan     DCR_ISRAM1_BEAR   = DCR_ISRAM1_BASE + 0x04,
6258d5b22bSBALATON Zoltan     DCR_ISRAM1_BESR0,
6358d5b22bSBALATON Zoltan     DCR_ISRAM1_BESR1,
6458d5b22bSBALATON Zoltan     DCR_ISRAM1_PMEG,
6558d5b22bSBALATON Zoltan     DCR_ISRAM1_CID,
6658d5b22bSBALATON Zoltan     DCR_ISRAM1_REVID,
6758d5b22bSBALATON Zoltan     DCR_ISRAM1_DPC,
6858d5b22bSBALATON Zoltan     DCR_ISRAM1_END    = DCR_ISRAM1_DPC
6958d5b22bSBALATON Zoltan };
7058d5b22bSBALATON Zoltan 
7158d5b22bSBALATON Zoltan typedef struct ppc4xx_l2sram_t {
7258d5b22bSBALATON Zoltan     MemoryRegion bank[4];
7358d5b22bSBALATON Zoltan     uint32_t l2cache[8];
7458d5b22bSBALATON Zoltan     uint32_t isram0[11];
7558d5b22bSBALATON Zoltan } ppc4xx_l2sram_t;
7658d5b22bSBALATON Zoltan 
dcr_read_l2sram(void * opaque,int dcrn)7758d5b22bSBALATON Zoltan static uint32_t dcr_read_l2sram(void *opaque, int dcrn)
7858d5b22bSBALATON Zoltan {
7958d5b22bSBALATON Zoltan     ppc4xx_l2sram_t *l2sram = opaque;
8058d5b22bSBALATON Zoltan     uint32_t ret = 0;
8158d5b22bSBALATON Zoltan 
8258d5b22bSBALATON Zoltan     switch (dcrn) {
8358d5b22bSBALATON Zoltan     case DCR_L2CACHE_CFG:
8458d5b22bSBALATON Zoltan     case DCR_L2CACHE_CMD:
8558d5b22bSBALATON Zoltan     case DCR_L2CACHE_ADDR:
8658d5b22bSBALATON Zoltan     case DCR_L2CACHE_DATA:
8758d5b22bSBALATON Zoltan     case DCR_L2CACHE_STAT:
8858d5b22bSBALATON Zoltan     case DCR_L2CACHE_CVER:
8958d5b22bSBALATON Zoltan     case DCR_L2CACHE_SNP0:
9058d5b22bSBALATON Zoltan     case DCR_L2CACHE_SNP1:
9158d5b22bSBALATON Zoltan         ret = l2sram->l2cache[dcrn - DCR_L2CACHE_BASE];
9258d5b22bSBALATON Zoltan         break;
9358d5b22bSBALATON Zoltan 
9458d5b22bSBALATON Zoltan     case DCR_ISRAM0_SB0CR:
9558d5b22bSBALATON Zoltan     case DCR_ISRAM0_SB1CR:
9658d5b22bSBALATON Zoltan     case DCR_ISRAM0_SB2CR:
9758d5b22bSBALATON Zoltan     case DCR_ISRAM0_SB3CR:
9858d5b22bSBALATON Zoltan     case DCR_ISRAM0_BEAR:
9958d5b22bSBALATON Zoltan     case DCR_ISRAM0_BESR0:
10058d5b22bSBALATON Zoltan     case DCR_ISRAM0_BESR1:
10158d5b22bSBALATON Zoltan     case DCR_ISRAM0_PMEG:
10258d5b22bSBALATON Zoltan     case DCR_ISRAM0_CID:
10358d5b22bSBALATON Zoltan     case DCR_ISRAM0_REVID:
10458d5b22bSBALATON Zoltan     case DCR_ISRAM0_DPC:
10558d5b22bSBALATON Zoltan         ret = l2sram->isram0[dcrn - DCR_ISRAM0_BASE];
10658d5b22bSBALATON Zoltan         break;
10758d5b22bSBALATON Zoltan 
10858d5b22bSBALATON Zoltan     default:
10958d5b22bSBALATON Zoltan         break;
11058d5b22bSBALATON Zoltan     }
11158d5b22bSBALATON Zoltan 
11258d5b22bSBALATON Zoltan     return ret;
11358d5b22bSBALATON Zoltan }
11458d5b22bSBALATON Zoltan 
dcr_write_l2sram(void * opaque,int dcrn,uint32_t val)11558d5b22bSBALATON Zoltan static void dcr_write_l2sram(void *opaque, int dcrn, uint32_t val)
11658d5b22bSBALATON Zoltan {
11758d5b22bSBALATON Zoltan     /*ppc4xx_l2sram_t *l2sram = opaque;*/
11858d5b22bSBALATON Zoltan     /* FIXME: Actually handle L2 cache mapping */
11958d5b22bSBALATON Zoltan 
12058d5b22bSBALATON Zoltan     switch (dcrn) {
12158d5b22bSBALATON Zoltan     case DCR_L2CACHE_CFG:
12258d5b22bSBALATON Zoltan     case DCR_L2CACHE_CMD:
12358d5b22bSBALATON Zoltan     case DCR_L2CACHE_ADDR:
12458d5b22bSBALATON Zoltan     case DCR_L2CACHE_DATA:
12558d5b22bSBALATON Zoltan     case DCR_L2CACHE_STAT:
12658d5b22bSBALATON Zoltan     case DCR_L2CACHE_CVER:
12758d5b22bSBALATON Zoltan     case DCR_L2CACHE_SNP0:
12858d5b22bSBALATON Zoltan     case DCR_L2CACHE_SNP1:
12958d5b22bSBALATON Zoltan         /*l2sram->l2cache[dcrn - DCR_L2CACHE_BASE] = val;*/
13058d5b22bSBALATON Zoltan         break;
13158d5b22bSBALATON Zoltan 
13258d5b22bSBALATON Zoltan     case DCR_ISRAM0_SB0CR:
13358d5b22bSBALATON Zoltan     case DCR_ISRAM0_SB1CR:
13458d5b22bSBALATON Zoltan     case DCR_ISRAM0_SB2CR:
13558d5b22bSBALATON Zoltan     case DCR_ISRAM0_SB3CR:
13658d5b22bSBALATON Zoltan     case DCR_ISRAM0_BEAR:
13758d5b22bSBALATON Zoltan     case DCR_ISRAM0_BESR0:
13858d5b22bSBALATON Zoltan     case DCR_ISRAM0_BESR1:
13958d5b22bSBALATON Zoltan     case DCR_ISRAM0_PMEG:
14058d5b22bSBALATON Zoltan     case DCR_ISRAM0_CID:
14158d5b22bSBALATON Zoltan     case DCR_ISRAM0_REVID:
14258d5b22bSBALATON Zoltan     case DCR_ISRAM0_DPC:
14358d5b22bSBALATON Zoltan         /*l2sram->isram0[dcrn - DCR_L2CACHE_BASE] = val;*/
14458d5b22bSBALATON Zoltan         break;
14558d5b22bSBALATON Zoltan 
14658d5b22bSBALATON Zoltan     case DCR_ISRAM1_SB0CR:
14758d5b22bSBALATON Zoltan     case DCR_ISRAM1_BEAR:
14858d5b22bSBALATON Zoltan     case DCR_ISRAM1_BESR0:
14958d5b22bSBALATON Zoltan     case DCR_ISRAM1_BESR1:
15058d5b22bSBALATON Zoltan     case DCR_ISRAM1_PMEG:
15158d5b22bSBALATON Zoltan     case DCR_ISRAM1_CID:
15258d5b22bSBALATON Zoltan     case DCR_ISRAM1_REVID:
15358d5b22bSBALATON Zoltan     case DCR_ISRAM1_DPC:
15458d5b22bSBALATON Zoltan         /*l2sram->isram1[dcrn - DCR_L2CACHE_BASE] = val;*/
15558d5b22bSBALATON Zoltan         break;
15658d5b22bSBALATON Zoltan     }
15758d5b22bSBALATON Zoltan }
15858d5b22bSBALATON Zoltan 
l2sram_reset(void * opaque)15958d5b22bSBALATON Zoltan static void l2sram_reset(void *opaque)
16058d5b22bSBALATON Zoltan {
16158d5b22bSBALATON Zoltan     ppc4xx_l2sram_t *l2sram = opaque;
16258d5b22bSBALATON Zoltan 
16358d5b22bSBALATON Zoltan     memset(l2sram->l2cache, 0, sizeof(l2sram->l2cache));
16458d5b22bSBALATON Zoltan     l2sram->l2cache[DCR_L2CACHE_STAT - DCR_L2CACHE_BASE] = 0x80000000;
16558d5b22bSBALATON Zoltan     memset(l2sram->isram0, 0, sizeof(l2sram->isram0));
16658d5b22bSBALATON Zoltan }
16758d5b22bSBALATON Zoltan 
ppc4xx_l2sram_init(CPUPPCState * env)16858d5b22bSBALATON Zoltan void ppc4xx_l2sram_init(CPUPPCState *env)
16958d5b22bSBALATON Zoltan {
17058d5b22bSBALATON Zoltan     ppc4xx_l2sram_t *l2sram;
17158d5b22bSBALATON Zoltan 
17258d5b22bSBALATON Zoltan     l2sram = g_malloc0(sizeof(*l2sram));
17358d5b22bSBALATON Zoltan     /* XXX: Size is 4*64kB for 460ex, cf. U-Boot, ppc4xx-isram.h */
17458d5b22bSBALATON Zoltan     memory_region_init_ram(&l2sram->bank[0], NULL, "ppc4xx.l2sram_bank0",
175d23b6caaSPhilippe Mathieu-Daudé                            64 * KiB, &error_abort);
17658d5b22bSBALATON Zoltan     memory_region_init_ram(&l2sram->bank[1], NULL, "ppc4xx.l2sram_bank1",
177d23b6caaSPhilippe Mathieu-Daudé                            64 * KiB, &error_abort);
17858d5b22bSBALATON Zoltan     memory_region_init_ram(&l2sram->bank[2], NULL, "ppc4xx.l2sram_bank2",
179d23b6caaSPhilippe Mathieu-Daudé                            64 * KiB, &error_abort);
18058d5b22bSBALATON Zoltan     memory_region_init_ram(&l2sram->bank[3], NULL, "ppc4xx.l2sram_bank3",
181d23b6caaSPhilippe Mathieu-Daudé                            64 * KiB, &error_abort);
18258d5b22bSBALATON Zoltan     qemu_register_reset(&l2sram_reset, l2sram);
18358d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_L2CACHE_CFG,
18458d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
18558d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_L2CACHE_CMD,
18658d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
18758d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_L2CACHE_ADDR,
18858d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
18958d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_L2CACHE_DATA,
19058d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
19158d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_L2CACHE_STAT,
19258d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
19358d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_L2CACHE_CVER,
19458d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
19558d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_L2CACHE_SNP0,
19658d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
19758d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_L2CACHE_SNP1,
19858d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
19958d5b22bSBALATON Zoltan 
20058d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM0_SB0CR,
20158d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
20258d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM0_SB1CR,
20358d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
20458d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM0_SB2CR,
20558d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
20658d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM0_SB3CR,
20758d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
20858d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM0_PMEG,
20958d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
21058d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM0_DPC,
21158d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
21258d5b22bSBALATON Zoltan 
21358d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM1_SB0CR,
21458d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
21558d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM1_PMEG,
21658d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
21758d5b22bSBALATON Zoltan     ppc_dcr_register(env, DCR_ISRAM1_DPC,
21858d5b22bSBALATON Zoltan                      l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
21958d5b22bSBALATON Zoltan }
22058d5b22bSBALATON Zoltan 
22158d5b22bSBALATON Zoltan /*****************************************************************************/
22258d5b22bSBALATON Zoltan /* Clocking Power on Reset */
22358d5b22bSBALATON Zoltan enum {
22458d5b22bSBALATON Zoltan     CPR0_CFGADDR = 0xC,
22558d5b22bSBALATON Zoltan     CPR0_CFGDATA = 0xD,
22658d5b22bSBALATON Zoltan 
22758d5b22bSBALATON Zoltan     CPR0_PLLD = 0x060,
22858d5b22bSBALATON Zoltan     CPR0_PLBED = 0x080,
22958d5b22bSBALATON Zoltan     CPR0_OPBD = 0x0C0,
23058d5b22bSBALATON Zoltan     CPR0_PERD = 0x0E0,
23158d5b22bSBALATON Zoltan     CPR0_AHBD = 0x100,
23258d5b22bSBALATON Zoltan };
23358d5b22bSBALATON Zoltan 
23458d5b22bSBALATON Zoltan typedef struct ppc4xx_cpr_t {
23558d5b22bSBALATON Zoltan     uint32_t addr;
23658d5b22bSBALATON Zoltan } ppc4xx_cpr_t;
23758d5b22bSBALATON Zoltan 
dcr_read_cpr(void * opaque,int dcrn)23858d5b22bSBALATON Zoltan static uint32_t dcr_read_cpr(void *opaque, int dcrn)
23958d5b22bSBALATON Zoltan {
24058d5b22bSBALATON Zoltan     ppc4xx_cpr_t *cpr = opaque;
24158d5b22bSBALATON Zoltan     uint32_t ret = 0;
24258d5b22bSBALATON Zoltan 
24358d5b22bSBALATON Zoltan     switch (dcrn) {
24458d5b22bSBALATON Zoltan     case CPR0_CFGADDR:
24558d5b22bSBALATON Zoltan         ret = cpr->addr;
24658d5b22bSBALATON Zoltan         break;
24758d5b22bSBALATON Zoltan     case CPR0_CFGDATA:
24858d5b22bSBALATON Zoltan         switch (cpr->addr) {
24958d5b22bSBALATON Zoltan         case CPR0_PLLD:
25058d5b22bSBALATON Zoltan             ret = (0xb5 << 24) | (1 << 16) | (9 << 8);
25158d5b22bSBALATON Zoltan             break;
25258d5b22bSBALATON Zoltan         case CPR0_PLBED:
25358d5b22bSBALATON Zoltan             ret = (5 << 24);
25458d5b22bSBALATON Zoltan             break;
25558d5b22bSBALATON Zoltan         case CPR0_OPBD:
25658d5b22bSBALATON Zoltan             ret = (2 << 24);
25758d5b22bSBALATON Zoltan             break;
25858d5b22bSBALATON Zoltan         case CPR0_PERD:
25958d5b22bSBALATON Zoltan         case CPR0_AHBD:
26058d5b22bSBALATON Zoltan             ret = (1 << 24);
26158d5b22bSBALATON Zoltan             break;
26258d5b22bSBALATON Zoltan         default:
26358d5b22bSBALATON Zoltan             break;
26458d5b22bSBALATON Zoltan         }
26558d5b22bSBALATON Zoltan         break;
26658d5b22bSBALATON Zoltan     default:
26758d5b22bSBALATON Zoltan         break;
26858d5b22bSBALATON Zoltan     }
26958d5b22bSBALATON Zoltan 
27058d5b22bSBALATON Zoltan     return ret;
27158d5b22bSBALATON Zoltan }
27258d5b22bSBALATON Zoltan 
dcr_write_cpr(void * opaque,int dcrn,uint32_t val)27358d5b22bSBALATON Zoltan static void dcr_write_cpr(void *opaque, int dcrn, uint32_t val)
27458d5b22bSBALATON Zoltan {
27558d5b22bSBALATON Zoltan     ppc4xx_cpr_t *cpr = opaque;
27658d5b22bSBALATON Zoltan 
27758d5b22bSBALATON Zoltan     switch (dcrn) {
27858d5b22bSBALATON Zoltan     case CPR0_CFGADDR:
27958d5b22bSBALATON Zoltan         cpr->addr = val;
28058d5b22bSBALATON Zoltan         break;
28158d5b22bSBALATON Zoltan     case CPR0_CFGDATA:
28258d5b22bSBALATON Zoltan         break;
28358d5b22bSBALATON Zoltan     default:
28458d5b22bSBALATON Zoltan         break;
28558d5b22bSBALATON Zoltan     }
28658d5b22bSBALATON Zoltan }
28758d5b22bSBALATON Zoltan 
ppc4xx_cpr_reset(void * opaque)28858d5b22bSBALATON Zoltan static void ppc4xx_cpr_reset(void *opaque)
28958d5b22bSBALATON Zoltan {
29058d5b22bSBALATON Zoltan     ppc4xx_cpr_t *cpr = opaque;
29158d5b22bSBALATON Zoltan 
29258d5b22bSBALATON Zoltan     cpr->addr = 0;
29358d5b22bSBALATON Zoltan }
29458d5b22bSBALATON Zoltan 
ppc4xx_cpr_init(CPUPPCState * env)29558d5b22bSBALATON Zoltan void ppc4xx_cpr_init(CPUPPCState *env)
29658d5b22bSBALATON Zoltan {
29758d5b22bSBALATON Zoltan     ppc4xx_cpr_t *cpr;
29858d5b22bSBALATON Zoltan 
29958d5b22bSBALATON Zoltan     cpr = g_malloc0(sizeof(*cpr));
30058d5b22bSBALATON Zoltan     ppc_dcr_register(env, CPR0_CFGADDR, cpr, &dcr_read_cpr, &dcr_write_cpr);
30158d5b22bSBALATON Zoltan     ppc_dcr_register(env, CPR0_CFGDATA, cpr, &dcr_read_cpr, &dcr_write_cpr);
30258d5b22bSBALATON Zoltan     qemu_register_reset(ppc4xx_cpr_reset, cpr);
30358d5b22bSBALATON Zoltan }
30458d5b22bSBALATON Zoltan 
30558d5b22bSBALATON Zoltan /*****************************************************************************/
30658d5b22bSBALATON Zoltan /* System DCRs */
30758d5b22bSBALATON Zoltan typedef struct ppc4xx_sdr_t ppc4xx_sdr_t;
30858d5b22bSBALATON Zoltan struct ppc4xx_sdr_t {
30958d5b22bSBALATON Zoltan     uint32_t addr;
31058d5b22bSBALATON Zoltan };
31158d5b22bSBALATON Zoltan 
31258d5b22bSBALATON Zoltan enum {
31358d5b22bSBALATON Zoltan     SDR0_CFGADDR = 0x00e,
31458d5b22bSBALATON Zoltan     SDR0_CFGDATA,
31558d5b22bSBALATON Zoltan     SDR0_STRP0 = 0x020,
31658d5b22bSBALATON Zoltan     SDR0_STRP1,
31758d5b22bSBALATON Zoltan     SDR0_102 = 0x66,
31858d5b22bSBALATON Zoltan     SDR0_103,
31958d5b22bSBALATON Zoltan     SDR0_128 = 0x80,
32058d5b22bSBALATON Zoltan     SDR0_ECID3 = 0x083,
32158d5b22bSBALATON Zoltan     SDR0_DDR0 = 0x0e1,
32258d5b22bSBALATON Zoltan     SDR0_USB0 = 0x320,
32358d5b22bSBALATON Zoltan };
32458d5b22bSBALATON Zoltan 
32558d5b22bSBALATON Zoltan enum {
32658d5b22bSBALATON Zoltan     PESDR0_LOOP = 0x303,
32758d5b22bSBALATON Zoltan     PESDR0_RCSSET,
32858d5b22bSBALATON Zoltan     PESDR0_RCSSTS,
32958d5b22bSBALATON Zoltan     PESDR0_RSTSTA = 0x310,
33058d5b22bSBALATON Zoltan     PESDR1_LOOP = 0x343,
33158d5b22bSBALATON Zoltan     PESDR1_RCSSET,
33258d5b22bSBALATON Zoltan     PESDR1_RCSSTS,
33358d5b22bSBALATON Zoltan     PESDR1_RSTSTA = 0x365,
33458d5b22bSBALATON Zoltan };
33558d5b22bSBALATON Zoltan 
dcr_read_sdr(void * opaque,int dcrn)33658d5b22bSBALATON Zoltan static uint32_t dcr_read_sdr(void *opaque, int dcrn)
33758d5b22bSBALATON Zoltan {
33858d5b22bSBALATON Zoltan     ppc4xx_sdr_t *sdr = opaque;
33958d5b22bSBALATON Zoltan     uint32_t ret = 0;
34058d5b22bSBALATON Zoltan 
34158d5b22bSBALATON Zoltan     switch (dcrn) {
34258d5b22bSBALATON Zoltan     case SDR0_CFGADDR:
34358d5b22bSBALATON Zoltan         ret = sdr->addr;
34458d5b22bSBALATON Zoltan         break;
34558d5b22bSBALATON Zoltan     case SDR0_CFGDATA:
34658d5b22bSBALATON Zoltan         switch (sdr->addr) {
34758d5b22bSBALATON Zoltan         case SDR0_STRP0:
348f8815532SBALATON Zoltan             ret = (0xb5 << 8) | (1 << 4) | 9;
34958d5b22bSBALATON Zoltan             break;
35058d5b22bSBALATON Zoltan         case SDR0_STRP1:
35158d5b22bSBALATON Zoltan             ret = (5 << 29) | (2 << 26) | (1 << 24);
35258d5b22bSBALATON Zoltan             break;
35358d5b22bSBALATON Zoltan         case SDR0_ECID3:
35458d5b22bSBALATON Zoltan             ret = 1 << 20; /* No Security/Kasumi support */
35558d5b22bSBALATON Zoltan             break;
35658d5b22bSBALATON Zoltan         case SDR0_DDR0:
35758d5b22bSBALATON Zoltan             ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1;
35858d5b22bSBALATON Zoltan             break;
35958d5b22bSBALATON Zoltan         case PESDR0_RCSSET:
36058d5b22bSBALATON Zoltan         case PESDR1_RCSSET:
36158d5b22bSBALATON Zoltan             ret = (1 << 24) | (1 << 16);
36258d5b22bSBALATON Zoltan             break;
36358d5b22bSBALATON Zoltan         case PESDR0_RCSSTS:
36458d5b22bSBALATON Zoltan         case PESDR1_RCSSTS:
36558d5b22bSBALATON Zoltan             ret = (1 << 16) | (1 << 12);
36658d5b22bSBALATON Zoltan             break;
36758d5b22bSBALATON Zoltan         case PESDR0_RSTSTA:
36858d5b22bSBALATON Zoltan         case PESDR1_RSTSTA:
36958d5b22bSBALATON Zoltan             ret = 1;
37058d5b22bSBALATON Zoltan             break;
37158d5b22bSBALATON Zoltan         case PESDR0_LOOP:
37258d5b22bSBALATON Zoltan         case PESDR1_LOOP:
37358d5b22bSBALATON Zoltan             ret = 1 << 12;
37458d5b22bSBALATON Zoltan             break;
37558d5b22bSBALATON Zoltan         default:
37658d5b22bSBALATON Zoltan             break;
37758d5b22bSBALATON Zoltan         }
37858d5b22bSBALATON Zoltan         break;
37958d5b22bSBALATON Zoltan     default:
38058d5b22bSBALATON Zoltan         break;
38158d5b22bSBALATON Zoltan     }
38258d5b22bSBALATON Zoltan 
38358d5b22bSBALATON Zoltan     return ret;
38458d5b22bSBALATON Zoltan }
38558d5b22bSBALATON Zoltan 
dcr_write_sdr(void * opaque,int dcrn,uint32_t val)38658d5b22bSBALATON Zoltan static void dcr_write_sdr(void *opaque, int dcrn, uint32_t val)
38758d5b22bSBALATON Zoltan {
38858d5b22bSBALATON Zoltan     ppc4xx_sdr_t *sdr = opaque;
38958d5b22bSBALATON Zoltan 
39058d5b22bSBALATON Zoltan     switch (dcrn) {
39158d5b22bSBALATON Zoltan     case SDR0_CFGADDR:
39258d5b22bSBALATON Zoltan         sdr->addr = val;
39358d5b22bSBALATON Zoltan         break;
39458d5b22bSBALATON Zoltan     case SDR0_CFGDATA:
39558d5b22bSBALATON Zoltan         switch (sdr->addr) {
39658d5b22bSBALATON Zoltan         case 0x00: /* B0CR */
39758d5b22bSBALATON Zoltan             break;
39858d5b22bSBALATON Zoltan         default:
39958d5b22bSBALATON Zoltan             break;
40058d5b22bSBALATON Zoltan         }
40158d5b22bSBALATON Zoltan         break;
40258d5b22bSBALATON Zoltan     default:
40358d5b22bSBALATON Zoltan         break;
40458d5b22bSBALATON Zoltan     }
40558d5b22bSBALATON Zoltan }
40658d5b22bSBALATON Zoltan 
sdr_reset(void * opaque)40758d5b22bSBALATON Zoltan static void sdr_reset(void *opaque)
40858d5b22bSBALATON Zoltan {
40958d5b22bSBALATON Zoltan     ppc4xx_sdr_t *sdr = opaque;
41058d5b22bSBALATON Zoltan 
41158d5b22bSBALATON Zoltan     sdr->addr = 0;
41258d5b22bSBALATON Zoltan }
41358d5b22bSBALATON Zoltan 
ppc4xx_sdr_init(CPUPPCState * env)41458d5b22bSBALATON Zoltan void ppc4xx_sdr_init(CPUPPCState *env)
41558d5b22bSBALATON Zoltan {
41658d5b22bSBALATON Zoltan     ppc4xx_sdr_t *sdr;
41758d5b22bSBALATON Zoltan 
41858d5b22bSBALATON Zoltan     sdr = g_malloc0(sizeof(*sdr));
41958d5b22bSBALATON Zoltan     qemu_register_reset(&sdr_reset, sdr);
42058d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDR0_CFGADDR,
42158d5b22bSBALATON Zoltan                      sdr, &dcr_read_sdr, &dcr_write_sdr);
42258d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDR0_CFGDATA,
42358d5b22bSBALATON Zoltan                      sdr, &dcr_read_sdr, &dcr_write_sdr);
42458d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDR0_102,
42558d5b22bSBALATON Zoltan                      sdr, &dcr_read_sdr, &dcr_write_sdr);
42658d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDR0_103,
42758d5b22bSBALATON Zoltan                      sdr, &dcr_read_sdr, &dcr_write_sdr);
42858d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDR0_128,
42958d5b22bSBALATON Zoltan                      sdr, &dcr_read_sdr, &dcr_write_sdr);
43058d5b22bSBALATON Zoltan     ppc_dcr_register(env, SDR0_USB0,
43158d5b22bSBALATON Zoltan                      sdr, &dcr_read_sdr, &dcr_write_sdr);
43258d5b22bSBALATON Zoltan }
43358d5b22bSBALATON Zoltan 
43458d5b22bSBALATON Zoltan /*****************************************************************************/
43558d5b22bSBALATON Zoltan /* PLB to AHB bridge */
43658d5b22bSBALATON Zoltan enum {
43758d5b22bSBALATON Zoltan     AHB_TOP    = 0xA4,
43858d5b22bSBALATON Zoltan     AHB_BOT    = 0xA5,
43958d5b22bSBALATON Zoltan };
44058d5b22bSBALATON Zoltan 
44158d5b22bSBALATON Zoltan typedef struct ppc4xx_ahb_t {
44258d5b22bSBALATON Zoltan     uint32_t top;
44358d5b22bSBALATON Zoltan     uint32_t bot;
44458d5b22bSBALATON Zoltan } ppc4xx_ahb_t;
44558d5b22bSBALATON Zoltan 
dcr_read_ahb(void * opaque,int dcrn)44658d5b22bSBALATON Zoltan static uint32_t dcr_read_ahb(void *opaque, int dcrn)
44758d5b22bSBALATON Zoltan {
44858d5b22bSBALATON Zoltan     ppc4xx_ahb_t *ahb = opaque;
44958d5b22bSBALATON Zoltan     uint32_t ret = 0;
45058d5b22bSBALATON Zoltan 
45158d5b22bSBALATON Zoltan     switch (dcrn) {
45258d5b22bSBALATON Zoltan     case AHB_TOP:
45358d5b22bSBALATON Zoltan         ret = ahb->top;
45458d5b22bSBALATON Zoltan         break;
45558d5b22bSBALATON Zoltan     case AHB_BOT:
45658d5b22bSBALATON Zoltan         ret = ahb->bot;
45758d5b22bSBALATON Zoltan         break;
45858d5b22bSBALATON Zoltan     default:
45958d5b22bSBALATON Zoltan         break;
46058d5b22bSBALATON Zoltan     }
46158d5b22bSBALATON Zoltan 
46258d5b22bSBALATON Zoltan     return ret;
46358d5b22bSBALATON Zoltan }
46458d5b22bSBALATON Zoltan 
dcr_write_ahb(void * opaque,int dcrn,uint32_t val)46558d5b22bSBALATON Zoltan static void dcr_write_ahb(void *opaque, int dcrn, uint32_t val)
46658d5b22bSBALATON Zoltan {
46758d5b22bSBALATON Zoltan     ppc4xx_ahb_t *ahb = opaque;
46858d5b22bSBALATON Zoltan 
46958d5b22bSBALATON Zoltan     switch (dcrn) {
47058d5b22bSBALATON Zoltan     case AHB_TOP:
47158d5b22bSBALATON Zoltan         ahb->top = val;
47258d5b22bSBALATON Zoltan         break;
47358d5b22bSBALATON Zoltan     case AHB_BOT:
47458d5b22bSBALATON Zoltan         ahb->bot = val;
47558d5b22bSBALATON Zoltan         break;
47658d5b22bSBALATON Zoltan     }
47758d5b22bSBALATON Zoltan }
47858d5b22bSBALATON Zoltan 
ppc4xx_ahb_reset(void * opaque)47958d5b22bSBALATON Zoltan static void ppc4xx_ahb_reset(void *opaque)
48058d5b22bSBALATON Zoltan {
48158d5b22bSBALATON Zoltan     ppc4xx_ahb_t *ahb = opaque;
48258d5b22bSBALATON Zoltan 
48358d5b22bSBALATON Zoltan     /* No error */
48458d5b22bSBALATON Zoltan     ahb->top = 0;
48558d5b22bSBALATON Zoltan     ahb->bot = 0;
48658d5b22bSBALATON Zoltan }
48758d5b22bSBALATON Zoltan 
ppc4xx_ahb_init(CPUPPCState * env)48858d5b22bSBALATON Zoltan void ppc4xx_ahb_init(CPUPPCState *env)
48958d5b22bSBALATON Zoltan {
49058d5b22bSBALATON Zoltan     ppc4xx_ahb_t *ahb;
49158d5b22bSBALATON Zoltan 
49258d5b22bSBALATON Zoltan     ahb = g_malloc0(sizeof(*ahb));
49358d5b22bSBALATON Zoltan     ppc_dcr_register(env, AHB_TOP, ahb, &dcr_read_ahb, &dcr_write_ahb);
49458d5b22bSBALATON Zoltan     ppc_dcr_register(env, AHB_BOT, ahb, &dcr_read_ahb, &dcr_write_ahb);
49558d5b22bSBALATON Zoltan     qemu_register_reset(ppc4xx_ahb_reset, ahb);
49658d5b22bSBALATON Zoltan }
49758d5b22bSBALATON Zoltan 
49858d5b22bSBALATON Zoltan /*****************************************************************************/
4993c409c19SBALATON Zoltan /* DMA controller */
5003c409c19SBALATON Zoltan 
5013c409c19SBALATON Zoltan #define DMA0_CR_CE  (1 << 31)
5023c409c19SBALATON Zoltan #define DMA0_CR_PW  (1 << 26 | 1 << 25)
5033c409c19SBALATON Zoltan #define DMA0_CR_DAI (1 << 24)
5043c409c19SBALATON Zoltan #define DMA0_CR_SAI (1 << 23)
5053c409c19SBALATON Zoltan #define DMA0_CR_DEC (1 << 2)
5063c409c19SBALATON Zoltan 
5073c409c19SBALATON Zoltan enum {
5083c409c19SBALATON Zoltan     DMA0_CR  = 0x00,
5093c409c19SBALATON Zoltan     DMA0_CT,
5103c409c19SBALATON Zoltan     DMA0_SAH,
5113c409c19SBALATON Zoltan     DMA0_SAL,
5123c409c19SBALATON Zoltan     DMA0_DAH,
5133c409c19SBALATON Zoltan     DMA0_DAL,
5143c409c19SBALATON Zoltan     DMA0_SGH,
5153c409c19SBALATON Zoltan     DMA0_SGL,
5163c409c19SBALATON Zoltan 
5173c409c19SBALATON Zoltan     DMA0_SR  = 0x20,
5183c409c19SBALATON Zoltan     DMA0_SGC = 0x23,
5193c409c19SBALATON Zoltan     DMA0_SLP = 0x25,
5203c409c19SBALATON Zoltan     DMA0_POL = 0x26,
5213c409c19SBALATON Zoltan };
5223c409c19SBALATON Zoltan 
5233c409c19SBALATON Zoltan typedef struct {
5243c409c19SBALATON Zoltan     uint32_t cr;
5253c409c19SBALATON Zoltan     uint32_t ct;
5263c409c19SBALATON Zoltan     uint64_t sa;
5273c409c19SBALATON Zoltan     uint64_t da;
5283c409c19SBALATON Zoltan     uint64_t sg;
5293c409c19SBALATON Zoltan } PPC4xxDmaChnl;
5303c409c19SBALATON Zoltan 
5313c409c19SBALATON Zoltan typedef struct {
5323c409c19SBALATON Zoltan     int base;
5333c409c19SBALATON Zoltan     PPC4xxDmaChnl ch[4];
5343c409c19SBALATON Zoltan     uint32_t sr;
5353c409c19SBALATON Zoltan } PPC4xxDmaState;
5363c409c19SBALATON Zoltan 
dcr_read_dma(void * opaque,int dcrn)5373c409c19SBALATON Zoltan static uint32_t dcr_read_dma(void *opaque, int dcrn)
5383c409c19SBALATON Zoltan {
5393c409c19SBALATON Zoltan     PPC4xxDmaState *dma = opaque;
5403c409c19SBALATON Zoltan     uint32_t val = 0;
5413c409c19SBALATON Zoltan     int addr = dcrn - dma->base;
5423c409c19SBALATON Zoltan     int chnl = addr / 8;
5433c409c19SBALATON Zoltan 
5443c409c19SBALATON Zoltan     switch (addr) {
5453c409c19SBALATON Zoltan     case 0x00 ... 0x1f:
5463c409c19SBALATON Zoltan         switch (addr % 8) {
5473c409c19SBALATON Zoltan         case DMA0_CR:
5483c409c19SBALATON Zoltan             val = dma->ch[chnl].cr;
5493c409c19SBALATON Zoltan             break;
5503c409c19SBALATON Zoltan         case DMA0_CT:
5513c409c19SBALATON Zoltan             val = dma->ch[chnl].ct;
5523c409c19SBALATON Zoltan             break;
5533c409c19SBALATON Zoltan         case DMA0_SAH:
5543c409c19SBALATON Zoltan             val = dma->ch[chnl].sa >> 32;
5553c409c19SBALATON Zoltan             break;
5563c409c19SBALATON Zoltan         case DMA0_SAL:
5573c409c19SBALATON Zoltan             val = dma->ch[chnl].sa;
5583c409c19SBALATON Zoltan             break;
5593c409c19SBALATON Zoltan         case DMA0_DAH:
5603c409c19SBALATON Zoltan             val = dma->ch[chnl].da >> 32;
5613c409c19SBALATON Zoltan             break;
5623c409c19SBALATON Zoltan         case DMA0_DAL:
5633c409c19SBALATON Zoltan             val = dma->ch[chnl].da;
5643c409c19SBALATON Zoltan             break;
5653c409c19SBALATON Zoltan         case DMA0_SGH:
5663c409c19SBALATON Zoltan             val = dma->ch[chnl].sg >> 32;
5673c409c19SBALATON Zoltan             break;
5683c409c19SBALATON Zoltan         case DMA0_SGL:
5693c409c19SBALATON Zoltan             val = dma->ch[chnl].sg;
5703c409c19SBALATON Zoltan             break;
5713c409c19SBALATON Zoltan         }
5723c409c19SBALATON Zoltan         break;
5733c409c19SBALATON Zoltan     case DMA0_SR:
5743c409c19SBALATON Zoltan         val = dma->sr;
5753c409c19SBALATON Zoltan         break;
5763c409c19SBALATON Zoltan     default:
5773c409c19SBALATON Zoltan         qemu_log_mask(LOG_UNIMP, "%s: unimplemented register %x (%d, %x)\n",
5783c409c19SBALATON Zoltan                       __func__, dcrn, chnl, addr);
5793c409c19SBALATON Zoltan     }
5803c409c19SBALATON Zoltan 
5813c409c19SBALATON Zoltan     return val;
5823c409c19SBALATON Zoltan }
5833c409c19SBALATON Zoltan 
dcr_write_dma(void * opaque,int dcrn,uint32_t val)5843c409c19SBALATON Zoltan static void dcr_write_dma(void *opaque, int dcrn, uint32_t val)
5853c409c19SBALATON Zoltan {
5863c409c19SBALATON Zoltan     PPC4xxDmaState *dma = opaque;
5873c409c19SBALATON Zoltan     int addr = dcrn - dma->base;
5883c409c19SBALATON Zoltan     int chnl = addr / 8;
5893c409c19SBALATON Zoltan 
5903c409c19SBALATON Zoltan     switch (addr) {
5913c409c19SBALATON Zoltan     case 0x00 ... 0x1f:
5923c409c19SBALATON Zoltan         switch (addr % 8) {
5933c409c19SBALATON Zoltan         case DMA0_CR:
5943c409c19SBALATON Zoltan             dma->ch[chnl].cr = val;
5953c409c19SBALATON Zoltan             if (val & DMA0_CR_CE) {
5963c409c19SBALATON Zoltan                 int count = dma->ch[chnl].ct & 0xffff;
5973c409c19SBALATON Zoltan 
5983c409c19SBALATON Zoltan                 if (count) {
5993c409c19SBALATON Zoltan                     int width, i, sidx, didx;
6003c409c19SBALATON Zoltan                     uint8_t *rptr, *wptr;
6013c409c19SBALATON Zoltan                     hwaddr rlen, wlen;
602eda3f17bSPeter Maydell                     hwaddr xferlen;
6033c409c19SBALATON Zoltan 
6043c409c19SBALATON Zoltan                     sidx = didx = 0;
6053c409c19SBALATON Zoltan                     width = 1 << ((val & DMA0_CR_PW) >> 25);
606eda3f17bSPeter Maydell                     xferlen = count * width;
607eda3f17bSPeter Maydell                     wlen = rlen = xferlen;
60885eb7c18SPhilippe Mathieu-Daudé                     rptr = cpu_physical_memory_map(dma->ch[chnl].sa, &rlen,
60985eb7c18SPhilippe Mathieu-Daudé                                                    false);
61085eb7c18SPhilippe Mathieu-Daudé                     wptr = cpu_physical_memory_map(dma->ch[chnl].da, &wlen,
61185eb7c18SPhilippe Mathieu-Daudé                                                    true);
612eda3f17bSPeter Maydell                     if (rptr && rlen == xferlen && wptr && wlen == xferlen) {
6133c409c19SBALATON Zoltan                         if (!(val & DMA0_CR_DEC) &&
6143c409c19SBALATON Zoltan                             val & DMA0_CR_SAI && val & DMA0_CR_DAI) {
6153c409c19SBALATON Zoltan                             /* optimise common case */
6163c409c19SBALATON Zoltan                             memmove(wptr, rptr, count * width);
6173c409c19SBALATON Zoltan                             sidx = didx = count * width;
6183c409c19SBALATON Zoltan                         } else {
6193c409c19SBALATON Zoltan                             /* do it the slow way */
6203c409c19SBALATON Zoltan                             for (sidx = didx = i = 0; i < count; i++) {
6213c409c19SBALATON Zoltan                                 uint64_t v = ldn_le_p(rptr + sidx, width);
6223c409c19SBALATON Zoltan                                 stn_le_p(wptr + didx, width, v);
6233c409c19SBALATON Zoltan                                 if (val & DMA0_CR_SAI) {
6243c409c19SBALATON Zoltan                                     sidx += width;
6253c409c19SBALATON Zoltan                                 }
6263c409c19SBALATON Zoltan                                 if (val & DMA0_CR_DAI) {
6273c409c19SBALATON Zoltan                                     didx += width;
6283c409c19SBALATON Zoltan                                 }
6293c409c19SBALATON Zoltan                             }
6303c409c19SBALATON Zoltan                         }
6313c409c19SBALATON Zoltan                     }
6323c409c19SBALATON Zoltan                     if (wptr) {
6333c409c19SBALATON Zoltan                         cpu_physical_memory_unmap(wptr, wlen, 1, didx);
6343c409c19SBALATON Zoltan                     }
6357aeb1e51SPhilippe Mathieu-Daudé                     if (rptr) {
6363c409c19SBALATON Zoltan                         cpu_physical_memory_unmap(rptr, rlen, 0, sidx);
6373c409c19SBALATON Zoltan                     }
6383c409c19SBALATON Zoltan                 }
6393c409c19SBALATON Zoltan             }
6403c409c19SBALATON Zoltan             break;
6413c409c19SBALATON Zoltan         case DMA0_CT:
6423c409c19SBALATON Zoltan             dma->ch[chnl].ct = val;
6433c409c19SBALATON Zoltan             break;
6443c409c19SBALATON Zoltan         case DMA0_SAH:
6453c409c19SBALATON Zoltan             dma->ch[chnl].sa &= 0xffffffffULL;
6463c409c19SBALATON Zoltan             dma->ch[chnl].sa |= (uint64_t)val << 32;
6473c409c19SBALATON Zoltan             break;
6483c409c19SBALATON Zoltan         case DMA0_SAL:
6493c409c19SBALATON Zoltan             dma->ch[chnl].sa &= 0xffffffff00000000ULL;
6503c409c19SBALATON Zoltan             dma->ch[chnl].sa |= val;
6513c409c19SBALATON Zoltan             break;
6523c409c19SBALATON Zoltan         case DMA0_DAH:
6533c409c19SBALATON Zoltan             dma->ch[chnl].da &= 0xffffffffULL;
6543c409c19SBALATON Zoltan             dma->ch[chnl].da |= (uint64_t)val << 32;
6553c409c19SBALATON Zoltan             break;
6563c409c19SBALATON Zoltan         case DMA0_DAL:
6573c409c19SBALATON Zoltan             dma->ch[chnl].da &= 0xffffffff00000000ULL;
6583c409c19SBALATON Zoltan             dma->ch[chnl].da |= val;
6593c409c19SBALATON Zoltan             break;
6603c409c19SBALATON Zoltan         case DMA0_SGH:
6613c409c19SBALATON Zoltan             dma->ch[chnl].sg &= 0xffffffffULL;
6623c409c19SBALATON Zoltan             dma->ch[chnl].sg |= (uint64_t)val << 32;
6633c409c19SBALATON Zoltan             break;
6643c409c19SBALATON Zoltan         case DMA0_SGL:
6653c409c19SBALATON Zoltan             dma->ch[chnl].sg &= 0xffffffff00000000ULL;
6663c409c19SBALATON Zoltan             dma->ch[chnl].sg |= val;
6673c409c19SBALATON Zoltan             break;
6683c409c19SBALATON Zoltan         }
6693c409c19SBALATON Zoltan         break;
6703c409c19SBALATON Zoltan     case DMA0_SR:
6713c409c19SBALATON Zoltan         dma->sr &= ~val;
6723c409c19SBALATON Zoltan         break;
6733c409c19SBALATON Zoltan     default:
6743c409c19SBALATON Zoltan         qemu_log_mask(LOG_UNIMP, "%s: unimplemented register %x (%d, %x)\n",
6753c409c19SBALATON Zoltan                       __func__, dcrn, chnl, addr);
6763c409c19SBALATON Zoltan     }
6773c409c19SBALATON Zoltan }
6783c409c19SBALATON Zoltan 
ppc4xx_dma_reset(void * opaque)6793c409c19SBALATON Zoltan static void ppc4xx_dma_reset(void *opaque)
6803c409c19SBALATON Zoltan {
6813c409c19SBALATON Zoltan     PPC4xxDmaState *dma = opaque;
6823c409c19SBALATON Zoltan     int dma_base = dma->base;
6833c409c19SBALATON Zoltan 
6843c409c19SBALATON Zoltan     memset(dma, 0, sizeof(*dma));
6853c409c19SBALATON Zoltan     dma->base = dma_base;
6863c409c19SBALATON Zoltan }
6873c409c19SBALATON Zoltan 
ppc4xx_dma_init(CPUPPCState * env,int dcr_base)6883c409c19SBALATON Zoltan void ppc4xx_dma_init(CPUPPCState *env, int dcr_base)
6893c409c19SBALATON Zoltan {
6903c409c19SBALATON Zoltan     PPC4xxDmaState *dma;
6913c409c19SBALATON Zoltan     int i;
6923c409c19SBALATON Zoltan 
6933c409c19SBALATON Zoltan     dma = g_malloc0(sizeof(*dma));
6943c409c19SBALATON Zoltan     dma->base = dcr_base;
6953c409c19SBALATON Zoltan     qemu_register_reset(&ppc4xx_dma_reset, dma);
6963c409c19SBALATON Zoltan     for (i = 0; i < 4; i++) {
6973c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CR,
6983c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
6993c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CT,
7003c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
7013c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAH,
7023c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
7033c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAL,
7043c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
7053c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAH,
7063c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
7073c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAL,
7083c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
7093c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGH,
7103c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
7113c409c19SBALATON Zoltan         ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGL,
7123c409c19SBALATON Zoltan                          dma, &dcr_read_dma, &dcr_write_dma);
7133c409c19SBALATON Zoltan     }
7143c409c19SBALATON Zoltan     ppc_dcr_register(env, dcr_base + DMA0_SR,
7153c409c19SBALATON Zoltan                      dma, &dcr_read_dma, &dcr_write_dma);
7163c409c19SBALATON Zoltan     ppc_dcr_register(env, dcr_base + DMA0_SGC,
7173c409c19SBALATON Zoltan                      dma, &dcr_read_dma, &dcr_write_dma);
7183c409c19SBALATON Zoltan     ppc_dcr_register(env, dcr_base + DMA0_SLP,
7193c409c19SBALATON Zoltan                      dma, &dcr_read_dma, &dcr_write_dma);
7203c409c19SBALATON Zoltan     ppc_dcr_register(env, dcr_base + DMA0_POL,
7213c409c19SBALATON Zoltan                      dma, &dcr_read_dma, &dcr_write_dma);
7223c409c19SBALATON Zoltan }
7233c409c19SBALATON Zoltan 
7243c409c19SBALATON Zoltan /*****************************************************************************/
72558d5b22bSBALATON Zoltan /* PCI Express controller */
72695e22932SBALATON Zoltan /*
72795e22932SBALATON Zoltan  * FIXME: This is not complete and does not work, only implemented partially
72858d5b22bSBALATON Zoltan  * to allow firmware and guests to find an empty bus. Cards should use PCI.
72958d5b22bSBALATON Zoltan  */
73058d5b22bSBALATON Zoltan #include "hw/pci/pcie_host.h"
73158d5b22bSBALATON Zoltan 
7328063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(PPC460EXPCIEState, PPC460EX_PCIE_HOST)
73358d5b22bSBALATON Zoltan 
734db1015e9SEduardo Habkost struct PPC460EXPCIEState {
73548bb07fbSBALATON Zoltan     PCIExpressHost parent_obj;
73658d5b22bSBALATON Zoltan 
737088b61bcSBALATON Zoltan     MemoryRegion busmem;
73858d5b22bSBALATON Zoltan     MemoryRegion iomem;
73958d5b22bSBALATON Zoltan     qemu_irq irq[4];
7406ef62c59SBALATON Zoltan     int32_t num;
74158d5b22bSBALATON Zoltan     int32_t dcrn_base;
742256f0666SBALATON Zoltan     PowerPCCPU *cpu;
74358d5b22bSBALATON Zoltan 
74458d5b22bSBALATON Zoltan     uint64_t cfg_base;
74558d5b22bSBALATON Zoltan     uint32_t cfg_mask;
74658d5b22bSBALATON Zoltan     uint64_t msg_base;
74758d5b22bSBALATON Zoltan     uint32_t msg_mask;
74858d5b22bSBALATON Zoltan     uint64_t omr1_base;
74958d5b22bSBALATON Zoltan     uint64_t omr1_mask;
75058d5b22bSBALATON Zoltan     uint64_t omr2_base;
75158d5b22bSBALATON Zoltan     uint64_t omr2_mask;
75258d5b22bSBALATON Zoltan     uint64_t omr3_base;
75358d5b22bSBALATON Zoltan     uint64_t omr3_mask;
75458d5b22bSBALATON Zoltan     uint64_t reg_base;
75558d5b22bSBALATON Zoltan     uint32_t reg_mask;
75658d5b22bSBALATON Zoltan     uint32_t special;
75758d5b22bSBALATON Zoltan     uint32_t cfg;
758db1015e9SEduardo Habkost };
75958d5b22bSBALATON Zoltan 
76058d5b22bSBALATON Zoltan enum {
76158d5b22bSBALATON Zoltan     PEGPL_CFGBAH = 0x0,
76258d5b22bSBALATON Zoltan     PEGPL_CFGBAL,
76358d5b22bSBALATON Zoltan     PEGPL_CFGMSK,
76458d5b22bSBALATON Zoltan     PEGPL_MSGBAH,
76558d5b22bSBALATON Zoltan     PEGPL_MSGBAL,
76658d5b22bSBALATON Zoltan     PEGPL_MSGMSK,
76758d5b22bSBALATON Zoltan     PEGPL_OMR1BAH,
76858d5b22bSBALATON Zoltan     PEGPL_OMR1BAL,
76958d5b22bSBALATON Zoltan     PEGPL_OMR1MSKH,
77058d5b22bSBALATON Zoltan     PEGPL_OMR1MSKL,
77158d5b22bSBALATON Zoltan     PEGPL_OMR2BAH,
77258d5b22bSBALATON Zoltan     PEGPL_OMR2BAL,
77358d5b22bSBALATON Zoltan     PEGPL_OMR2MSKH,
77458d5b22bSBALATON Zoltan     PEGPL_OMR2MSKL,
77558d5b22bSBALATON Zoltan     PEGPL_OMR3BAH,
77658d5b22bSBALATON Zoltan     PEGPL_OMR3BAL,
77758d5b22bSBALATON Zoltan     PEGPL_OMR3MSKH,
77858d5b22bSBALATON Zoltan     PEGPL_OMR3MSKL,
77958d5b22bSBALATON Zoltan     PEGPL_REGBAH,
78058d5b22bSBALATON Zoltan     PEGPL_REGBAL,
78158d5b22bSBALATON Zoltan     PEGPL_REGMSK,
78258d5b22bSBALATON Zoltan     PEGPL_SPECIAL,
78358d5b22bSBALATON Zoltan     PEGPL_CFG,
78458d5b22bSBALATON Zoltan };
78558d5b22bSBALATON Zoltan 
dcr_read_pcie(void * opaque,int dcrn)78658d5b22bSBALATON Zoltan static uint32_t dcr_read_pcie(void *opaque, int dcrn)
78758d5b22bSBALATON Zoltan {
788b5d2ad84SBALATON Zoltan     PPC460EXPCIEState *s = opaque;
78958d5b22bSBALATON Zoltan     uint32_t ret = 0;
79058d5b22bSBALATON Zoltan 
791b5d2ad84SBALATON Zoltan     switch (dcrn - s->dcrn_base) {
79258d5b22bSBALATON Zoltan     case PEGPL_CFGBAH:
793b5d2ad84SBALATON Zoltan         ret = s->cfg_base >> 32;
79458d5b22bSBALATON Zoltan         break;
79558d5b22bSBALATON Zoltan     case PEGPL_CFGBAL:
796b5d2ad84SBALATON Zoltan         ret = s->cfg_base;
79758d5b22bSBALATON Zoltan         break;
79858d5b22bSBALATON Zoltan     case PEGPL_CFGMSK:
799b5d2ad84SBALATON Zoltan         ret = s->cfg_mask;
80058d5b22bSBALATON Zoltan         break;
80158d5b22bSBALATON Zoltan     case PEGPL_MSGBAH:
802b5d2ad84SBALATON Zoltan         ret = s->msg_base >> 32;
80358d5b22bSBALATON Zoltan         break;
80458d5b22bSBALATON Zoltan     case PEGPL_MSGBAL:
805b5d2ad84SBALATON Zoltan         ret = s->msg_base;
80658d5b22bSBALATON Zoltan         break;
80758d5b22bSBALATON Zoltan     case PEGPL_MSGMSK:
808b5d2ad84SBALATON Zoltan         ret = s->msg_mask;
80958d5b22bSBALATON Zoltan         break;
81058d5b22bSBALATON Zoltan     case PEGPL_OMR1BAH:
811b5d2ad84SBALATON Zoltan         ret = s->omr1_base >> 32;
81258d5b22bSBALATON Zoltan         break;
81358d5b22bSBALATON Zoltan     case PEGPL_OMR1BAL:
814b5d2ad84SBALATON Zoltan         ret = s->omr1_base;
81558d5b22bSBALATON Zoltan         break;
81658d5b22bSBALATON Zoltan     case PEGPL_OMR1MSKH:
817b5d2ad84SBALATON Zoltan         ret = s->omr1_mask >> 32;
81858d5b22bSBALATON Zoltan         break;
81958d5b22bSBALATON Zoltan     case PEGPL_OMR1MSKL:
820b5d2ad84SBALATON Zoltan         ret = s->omr1_mask;
82158d5b22bSBALATON Zoltan         break;
82258d5b22bSBALATON Zoltan     case PEGPL_OMR2BAH:
823b5d2ad84SBALATON Zoltan         ret = s->omr2_base >> 32;
82458d5b22bSBALATON Zoltan         break;
82558d5b22bSBALATON Zoltan     case PEGPL_OMR2BAL:
826b5d2ad84SBALATON Zoltan         ret = s->omr2_base;
82758d5b22bSBALATON Zoltan         break;
82858d5b22bSBALATON Zoltan     case PEGPL_OMR2MSKH:
829b5d2ad84SBALATON Zoltan         ret = s->omr2_mask >> 32;
83058d5b22bSBALATON Zoltan         break;
83158d5b22bSBALATON Zoltan     case PEGPL_OMR2MSKL:
832b5d2ad84SBALATON Zoltan         ret = s->omr3_mask;
83358d5b22bSBALATON Zoltan         break;
83458d5b22bSBALATON Zoltan     case PEGPL_OMR3BAH:
835b5d2ad84SBALATON Zoltan         ret = s->omr3_base >> 32;
83658d5b22bSBALATON Zoltan         break;
83758d5b22bSBALATON Zoltan     case PEGPL_OMR3BAL:
838b5d2ad84SBALATON Zoltan         ret = s->omr3_base;
83958d5b22bSBALATON Zoltan         break;
84058d5b22bSBALATON Zoltan     case PEGPL_OMR3MSKH:
841b5d2ad84SBALATON Zoltan         ret = s->omr3_mask >> 32;
84258d5b22bSBALATON Zoltan         break;
84358d5b22bSBALATON Zoltan     case PEGPL_OMR3MSKL:
844b5d2ad84SBALATON Zoltan         ret = s->omr3_mask;
84558d5b22bSBALATON Zoltan         break;
84658d5b22bSBALATON Zoltan     case PEGPL_REGBAH:
847b5d2ad84SBALATON Zoltan         ret = s->reg_base >> 32;
84858d5b22bSBALATON Zoltan         break;
84958d5b22bSBALATON Zoltan     case PEGPL_REGBAL:
850b5d2ad84SBALATON Zoltan         ret = s->reg_base;
85158d5b22bSBALATON Zoltan         break;
85258d5b22bSBALATON Zoltan     case PEGPL_REGMSK:
853b5d2ad84SBALATON Zoltan         ret = s->reg_mask;
85458d5b22bSBALATON Zoltan         break;
85558d5b22bSBALATON Zoltan     case PEGPL_SPECIAL:
856b5d2ad84SBALATON Zoltan         ret = s->special;
85758d5b22bSBALATON Zoltan         break;
85858d5b22bSBALATON Zoltan     case PEGPL_CFG:
859b5d2ad84SBALATON Zoltan         ret = s->cfg;
86058d5b22bSBALATON Zoltan         break;
86158d5b22bSBALATON Zoltan     }
86258d5b22bSBALATON Zoltan 
86358d5b22bSBALATON Zoltan     return ret;
86458d5b22bSBALATON Zoltan }
86558d5b22bSBALATON Zoltan 
dcr_write_pcie(void * opaque,int dcrn,uint32_t val)86658d5b22bSBALATON Zoltan static void dcr_write_pcie(void *opaque, int dcrn, uint32_t val)
86758d5b22bSBALATON Zoltan {
86858d5b22bSBALATON Zoltan     PPC460EXPCIEState *s = opaque;
86958d5b22bSBALATON Zoltan     uint64_t size;
87058d5b22bSBALATON Zoltan 
87158d5b22bSBALATON Zoltan     switch (dcrn - s->dcrn_base) {
87258d5b22bSBALATON Zoltan     case PEGPL_CFGBAH:
87358d5b22bSBALATON Zoltan         s->cfg_base = ((uint64_t)val << 32) | (s->cfg_base & 0xffffffff);
87458d5b22bSBALATON Zoltan         break;
87558d5b22bSBALATON Zoltan     case PEGPL_CFGBAL:
87658d5b22bSBALATON Zoltan         s->cfg_base = (s->cfg_base & 0xffffffff00000000ULL) | val;
87758d5b22bSBALATON Zoltan         break;
87858d5b22bSBALATON Zoltan     case PEGPL_CFGMSK:
87958d5b22bSBALATON Zoltan         s->cfg_mask = val;
88058d5b22bSBALATON Zoltan         size = ~(val & 0xfffffffe) + 1;
881453eb94cSMichael S. Tsirkin         /*
882453eb94cSMichael S. Tsirkin          * Firmware sets this register to E0000001. Why we are not sure,
883453eb94cSMichael S. Tsirkin          * but the current guess is anything above PCIE_MMCFG_SIZE_MAX is
884453eb94cSMichael S. Tsirkin          * ignored.
885453eb94cSMichael S. Tsirkin          */
886453eb94cSMichael S. Tsirkin         if (size > PCIE_MMCFG_SIZE_MAX) {
887453eb94cSMichael S. Tsirkin             size = PCIE_MMCFG_SIZE_MAX;
888453eb94cSMichael S. Tsirkin         }
88958d5b22bSBALATON Zoltan         pcie_host_mmcfg_update(PCIE_HOST_BRIDGE(s), val & 1, s->cfg_base, size);
89058d5b22bSBALATON Zoltan         break;
89158d5b22bSBALATON Zoltan     case PEGPL_MSGBAH:
89258d5b22bSBALATON Zoltan         s->msg_base = ((uint64_t)val << 32) | (s->msg_base & 0xffffffff);
89358d5b22bSBALATON Zoltan         break;
89458d5b22bSBALATON Zoltan     case PEGPL_MSGBAL:
89558d5b22bSBALATON Zoltan         s->msg_base = (s->msg_base & 0xffffffff00000000ULL) | val;
89658d5b22bSBALATON Zoltan         break;
89758d5b22bSBALATON Zoltan     case PEGPL_MSGMSK:
89858d5b22bSBALATON Zoltan         s->msg_mask = val;
89958d5b22bSBALATON Zoltan         break;
90058d5b22bSBALATON Zoltan     case PEGPL_OMR1BAH:
90158d5b22bSBALATON Zoltan         s->omr1_base = ((uint64_t)val << 32) | (s->omr1_base & 0xffffffff);
90258d5b22bSBALATON Zoltan         break;
90358d5b22bSBALATON Zoltan     case PEGPL_OMR1BAL:
90458d5b22bSBALATON Zoltan         s->omr1_base = (s->omr1_base & 0xffffffff00000000ULL) | val;
90558d5b22bSBALATON Zoltan         break;
90658d5b22bSBALATON Zoltan     case PEGPL_OMR1MSKH:
90758d5b22bSBALATON Zoltan         s->omr1_mask = ((uint64_t)val << 32) | (s->omr1_mask & 0xffffffff);
90858d5b22bSBALATON Zoltan         break;
90958d5b22bSBALATON Zoltan     case PEGPL_OMR1MSKL:
91058d5b22bSBALATON Zoltan         s->omr1_mask = (s->omr1_mask & 0xffffffff00000000ULL) | val;
91158d5b22bSBALATON Zoltan         break;
91258d5b22bSBALATON Zoltan     case PEGPL_OMR2BAH:
91358d5b22bSBALATON Zoltan         s->omr2_base = ((uint64_t)val << 32) | (s->omr2_base & 0xffffffff);
91458d5b22bSBALATON Zoltan         break;
91558d5b22bSBALATON Zoltan     case PEGPL_OMR2BAL:
91658d5b22bSBALATON Zoltan         s->omr2_base = (s->omr2_base & 0xffffffff00000000ULL) | val;
91758d5b22bSBALATON Zoltan         break;
91858d5b22bSBALATON Zoltan     case PEGPL_OMR2MSKH:
91958d5b22bSBALATON Zoltan         s->omr2_mask = ((uint64_t)val << 32) | (s->omr2_mask & 0xffffffff);
92058d5b22bSBALATON Zoltan         break;
92158d5b22bSBALATON Zoltan     case PEGPL_OMR2MSKL:
92258d5b22bSBALATON Zoltan         s->omr2_mask = (s->omr2_mask & 0xffffffff00000000ULL) | val;
92358d5b22bSBALATON Zoltan         break;
92458d5b22bSBALATON Zoltan     case PEGPL_OMR3BAH:
92558d5b22bSBALATON Zoltan         s->omr3_base = ((uint64_t)val << 32) | (s->omr3_base & 0xffffffff);
92658d5b22bSBALATON Zoltan         break;
92758d5b22bSBALATON Zoltan     case PEGPL_OMR3BAL:
92858d5b22bSBALATON Zoltan         s->omr3_base = (s->omr3_base & 0xffffffff00000000ULL) | val;
92958d5b22bSBALATON Zoltan         break;
93058d5b22bSBALATON Zoltan     case PEGPL_OMR3MSKH:
93158d5b22bSBALATON Zoltan         s->omr3_mask = ((uint64_t)val << 32) | (s->omr3_mask & 0xffffffff);
93258d5b22bSBALATON Zoltan         break;
93358d5b22bSBALATON Zoltan     case PEGPL_OMR3MSKL:
93458d5b22bSBALATON Zoltan         s->omr3_mask = (s->omr3_mask & 0xffffffff00000000ULL) | val;
93558d5b22bSBALATON Zoltan         break;
93658d5b22bSBALATON Zoltan     case PEGPL_REGBAH:
93758d5b22bSBALATON Zoltan         s->reg_base = ((uint64_t)val << 32) | (s->reg_base & 0xffffffff);
93858d5b22bSBALATON Zoltan         break;
93958d5b22bSBALATON Zoltan     case PEGPL_REGBAL:
94058d5b22bSBALATON Zoltan         s->reg_base = (s->reg_base & 0xffffffff00000000ULL) | val;
94158d5b22bSBALATON Zoltan         break;
94258d5b22bSBALATON Zoltan     case PEGPL_REGMSK:
94358d5b22bSBALATON Zoltan         s->reg_mask = val;
94458d5b22bSBALATON Zoltan         /* FIXME: how is size encoded? */
94558d5b22bSBALATON Zoltan         size = (val == 0x7001 ? 4096 : ~(val & 0xfffffffe) + 1);
94658d5b22bSBALATON Zoltan         break;
94758d5b22bSBALATON Zoltan     case PEGPL_SPECIAL:
94858d5b22bSBALATON Zoltan         s->special = val;
94958d5b22bSBALATON Zoltan         break;
95058d5b22bSBALATON Zoltan     case PEGPL_CFG:
95158d5b22bSBALATON Zoltan         s->cfg = val;
95258d5b22bSBALATON Zoltan         break;
95358d5b22bSBALATON Zoltan     }
95458d5b22bSBALATON Zoltan }
95558d5b22bSBALATON Zoltan 
ppc460ex_set_irq(void * opaque,int irq_num,int level)95658d5b22bSBALATON Zoltan static void ppc460ex_set_irq(void *opaque, int irq_num, int level)
95758d5b22bSBALATON Zoltan {
95858d5b22bSBALATON Zoltan        PPC460EXPCIEState *s = opaque;
95958d5b22bSBALATON Zoltan        qemu_set_irq(s->irq[irq_num], level);
96058d5b22bSBALATON Zoltan }
96158d5b22bSBALATON Zoltan 
962ca1ae343SBALATON Zoltan #define PPC440_PCIE_DCR(s, dcrn) \
963ca1ae343SBALATON Zoltan     ppc_dcr_register(&(s)->cpu->env, (s)->dcrn_base + (dcrn), (s), \
964ca1ae343SBALATON Zoltan                      &dcr_read_pcie, &dcr_write_pcie)
965ca1ae343SBALATON Zoltan 
966ca1ae343SBALATON Zoltan 
ppc460ex_pcie_register_dcrs(PPC460EXPCIEState * s)967256f0666SBALATON Zoltan static void ppc460ex_pcie_register_dcrs(PPC460EXPCIEState *s)
96858d5b22bSBALATON Zoltan {
969ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_CFGBAH);
970ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_CFGBAL);
971ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_CFGMSK);
972ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_MSGBAH);
973ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_MSGBAL);
974ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_MSGMSK);
975ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_OMR1BAH);
976ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_OMR1BAL);
977ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_OMR1MSKH);
978ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_OMR1MSKL);
979ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_OMR2BAH);
980ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_OMR2BAL);
981ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_OMR2MSKH);
982ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_OMR2MSKL);
983ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_OMR3BAH);
984ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_OMR3BAL);
985ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_OMR3MSKH);
986ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_OMR3MSKL);
987ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_REGBAH);
988ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_REGBAL);
989ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_REGMSK);
990ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_SPECIAL);
991ca1ae343SBALATON Zoltan     PPC440_PCIE_DCR(s, PEGPL_CFG);
99258d5b22bSBALATON Zoltan }
99358d5b22bSBALATON Zoltan 
ppc460ex_pcie_realize(DeviceState * dev,Error ** errp)994256f0666SBALATON Zoltan static void ppc460ex_pcie_realize(DeviceState *dev, Error **errp)
995256f0666SBALATON Zoltan {
996256f0666SBALATON Zoltan     PPC460EXPCIEState *s = PPC460EX_PCIE_HOST(dev);
997256f0666SBALATON Zoltan     PCIHostState *pci = PCI_HOST_BRIDGE(dev);
9986ef62c59SBALATON Zoltan     int i;
9996ef62c59SBALATON Zoltan     char buf[20];
1000256f0666SBALATON Zoltan 
1001256f0666SBALATON Zoltan     if (!s->cpu) {
1002256f0666SBALATON Zoltan         error_setg(errp, "cpu link property must be set");
1003256f0666SBALATON Zoltan         return;
1004256f0666SBALATON Zoltan     }
10056ef62c59SBALATON Zoltan     if (s->num < 0 || s->dcrn_base < 0) {
10066ef62c59SBALATON Zoltan         error_setg(errp, "busnum and dcrn-base properties must be set");
1007256f0666SBALATON Zoltan         return;
1008256f0666SBALATON Zoltan     }
10096ef62c59SBALATON Zoltan     snprintf(buf, sizeof(buf), "pcie%d-mem", s->num);
1010088b61bcSBALATON Zoltan     memory_region_init(&s->busmem, OBJECT(s), buf, UINT64_MAX);
10116ef62c59SBALATON Zoltan     snprintf(buf, sizeof(buf), "pcie%d-io", s->num);
1012088b61bcSBALATON Zoltan     memory_region_init(&s->iomem, OBJECT(s), buf, 64 * KiB);
1013256f0666SBALATON Zoltan     for (i = 0; i < 4; i++) {
1014256f0666SBALATON Zoltan         sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[i]);
1015256f0666SBALATON Zoltan     }
10166ef62c59SBALATON Zoltan     snprintf(buf, sizeof(buf), "pcie.%d", s->num);
1017256f0666SBALATON Zoltan     pci->bus = pci_register_root_bus(DEVICE(s), buf, ppc460ex_set_irq,
1018088b61bcSBALATON Zoltan                                 pci_swizzle_map_irq_fn, s, &s->busmem,
1019088b61bcSBALATON Zoltan                                 &s->iomem, 0, 4, TYPE_PCIE_BUS);
1020256f0666SBALATON Zoltan     ppc460ex_pcie_register_dcrs(s);
1021256f0666SBALATON Zoltan }
1022256f0666SBALATON Zoltan 
1023256f0666SBALATON Zoltan static Property ppc460ex_pcie_props[] = {
10246ef62c59SBALATON Zoltan     DEFINE_PROP_INT32("busnum", PPC460EXPCIEState, num, -1),
1025256f0666SBALATON Zoltan     DEFINE_PROP_INT32("dcrn-base", PPC460EXPCIEState, dcrn_base, -1),
1026256f0666SBALATON Zoltan     DEFINE_PROP_LINK("cpu", PPC460EXPCIEState, cpu, TYPE_POWERPC_CPU,
1027256f0666SBALATON Zoltan                      PowerPCCPU *),
1028256f0666SBALATON Zoltan     DEFINE_PROP_END_OF_LIST(),
1029256f0666SBALATON Zoltan };
1030256f0666SBALATON Zoltan 
ppc460ex_pcie_class_init(ObjectClass * klass,void * data)1031256f0666SBALATON Zoltan static void ppc460ex_pcie_class_init(ObjectClass *klass, void *data)
1032256f0666SBALATON Zoltan {
1033256f0666SBALATON Zoltan     DeviceClass *dc = DEVICE_CLASS(klass);
1034256f0666SBALATON Zoltan 
1035256f0666SBALATON Zoltan     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
1036256f0666SBALATON Zoltan     dc->realize = ppc460ex_pcie_realize;
1037256f0666SBALATON Zoltan     device_class_set_props(dc, ppc460ex_pcie_props);
1038256f0666SBALATON Zoltan     dc->hotpluggable = false;
1039256f0666SBALATON Zoltan }
1040256f0666SBALATON Zoltan 
1041256f0666SBALATON Zoltan static const TypeInfo ppc460ex_pcie_host_info = {
1042256f0666SBALATON Zoltan     .name = TYPE_PPC460EX_PCIE_HOST,
1043256f0666SBALATON Zoltan     .parent = TYPE_PCIE_HOST_BRIDGE,
1044256f0666SBALATON Zoltan     .instance_size = sizeof(PPC460EXPCIEState),
1045256f0666SBALATON Zoltan     .class_init = ppc460ex_pcie_class_init,
1046256f0666SBALATON Zoltan };
1047256f0666SBALATON Zoltan 
ppc460ex_pcie_register(void)1048256f0666SBALATON Zoltan static void ppc460ex_pcie_register(void)
1049256f0666SBALATON Zoltan {
1050256f0666SBALATON Zoltan     type_register_static(&ppc460ex_pcie_host_info);
1051256f0666SBALATON Zoltan }
1052256f0666SBALATON Zoltan 
1053256f0666SBALATON Zoltan type_init(ppc460ex_pcie_register)
1054