void pam_update(PAMMemoryRegion *pam, int idx, uint8_t val) { assert(0 <= idx && idx <= 12); memory_region_set_enabled(&pam->alias[pam->current], false); pam->current = (val >> ((!(idx & 1)) * 4)) & PAM_ATTR_MASK; memory_region_set_enabled(&pam->alias[pam->current], true); }
static void rpu_rpu_glbl_cntl_postw(RegisterInfo *reg, uint64_t val64) { RPU *s = XILINX_RPU(reg->opaque); bool tcm_comb = AF_EX32(s->regs, RPU_GLBL_CNTL, TCM_COMB); bool sls_split = AF_EX32(s->regs, RPU_GLBL_CNTL, SLSPLIT); memory_region_set_enabled(s->atcm1_for_rpu0, tcm_comb); memory_region_set_enabled(s->btcm1_for_rpu0, tcm_comb); memory_region_set_enabled(s->icache_for_rpu1, sls_split); memory_region_set_enabled(s->dcache_for_rpu1, sls_split); memory_region_set_enabled(s->ddr, sls_split); }
static int mch_init(PCIDevice *d) { int i; MCHPCIState *mch = MCH_PCI_DEVICE(d); /* setup pci memory mapping */ pc_pci_as_mapping_init(OBJECT(mch), mch->system_memory, mch->pci_address_space); /* smram */ cpu_smm_register(&mch_set_smm, mch); memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region", mch->pci_address_space, 0xa0000, 0x20000); memory_region_add_subregion_overlap(mch->system_memory, 0xa0000, &mch->smram_region, 1); memory_region_set_enabled(&mch->smram_region, false); init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space, &mch->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE); for (i = 0; i < 12; ++i) { init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space, &mch->pam_regions[i+1], PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE); } /* Intel IOMMU (VT-d) */ if (qemu_opt_get_bool(qemu_get_machine_opts(), "iommu", false)) { mch_init_dmar(mch); } return 0; }
static void integratorcm_do_remap(integratorcm_state *s) { /* Sync memory region state with CM_CTRL REMAP bit: * bit 0 => flash at address 0; bit 1 => RAM */ memory_region_set_enabled(&s->flash, !(s->cm_ctrl & 4)); }
static void mem_ctrl_pwr_hlt_cntrl(void *opaque) { DeviceState *dev = DEVICE(opaque); MemCtrl *s = MEM_CTRL(opaque); memory_region_set_enabled(&s->pwrddown, !dev->ps.active); }
static void xilinx_pcie_root_config_write(PCIDevice *d, uint32_t address, uint32_t val, int len) { XilinxPCIEHost *s = XILINX_PCIE_HOST(OBJECT(d)->parent); switch (address) { case ROOTCFG_INTDEC: xilinx_pcie_update_intr(s, 0, val); break; case ROOTCFG_INTMASK: s->intr_mask = val; xilinx_pcie_update_intr(s, 0, 0); break; case ROOTCFG_RPSCR: s->rpscr &= ~ROOTCFG_RPSCR_BRIDGEEN; s->rpscr |= val & ROOTCFG_RPSCR_BRIDGEEN; memory_region_set_enabled(&s->mmio, val & ROOTCFG_RPSCR_BRIDGEEN); if (val & ROOTCFG_INTMASK_INTX) { s->rpscr &= ~ROOTCFG_INTMASK_INTX; } break; case ROOTCFG_RPIFR1: case ROOTCFG_RPIFR2: if (s->intr_fifo_w == s->intr_fifo_r) { /* FIFO empty */ return; } else { s->intr_fifo_r = (s->intr_fifo_r + 1) % ARRAY_SIZE(s->intr_fifo); } break; default: pci_default_write_config(d, address, val, len); break; } }
static void xilinx_pcie_host_realize(DeviceState *dev, Error **errp) { PCIHostState *pci = PCI_HOST_BRIDGE(dev); XilinxPCIEHost *s = XILINX_PCIE_HOST(dev); SysBusDevice *sbd = SYS_BUS_DEVICE(dev); PCIExpressHost *pex = PCIE_HOST_BRIDGE(dev); snprintf(s->name, sizeof(s->name), "pcie%u", s->bus_nr); /* PCI configuration space */ pcie_host_mmcfg_init(pex, s->cfg_size); /* MMIO region */ memory_region_init(&s->mmio, OBJECT(s), "mmio", UINT64_MAX); memory_region_set_enabled(&s->mmio, false); /* dummy PCI I/O region (not visible to the CPU) */ memory_region_init(&s->io, OBJECT(s), "io", 16); /* interrupt out */ qdev_init_gpio_out_named(dev, &s->irq, "interrupt_out", 1); sysbus_init_mmio(sbd, &pex->mmio); sysbus_init_mmio(sbd, &s->mmio); pci->bus = pci_register_root_bus(dev, s->name, xilinx_pcie_set_irq, pci_swizzle_map_irq_fn, s, &s->mmio, &s->io, 0, 4, TYPE_PCIE_BUS); qdev_set_parent_bus(DEVICE(&s->root), BUS(pci->bus)); qdev_init_nofail(DEVICE(&s->root)); }
void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, qemu_irq sci_irq) { memory_region_init(&pm->io, OBJECT(lpc_pci), "ich9-pm", ICH9_PMIO_SIZE); memory_region_set_enabled(&pm->io, false); memory_region_add_subregion(pci_address_space_io(lpc_pci), 0, &pm->io); acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io); acpi_pm1_evt_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io); acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io, pm->disable_s3, pm->disable_s4, pm->s4_val); acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN); memory_region_init_io(&pm->io_gpe, OBJECT(lpc_pci), &ich9_gpe_ops, pm, "acpi-gpe0", ICH9_PMIO_GPE0_LEN); memory_region_add_subregion(&pm->io, ICH9_PMIO_GPE0_STS, &pm->io_gpe); memory_region_init_io(&pm->io_smi, OBJECT(lpc_pci), &ich9_smi_ops, pm, "acpi-smi", 8); memory_region_add_subregion(&pm->io, ICH9_PMIO_SMI_EN, &pm->io_smi); pm->irq = sci_irq; qemu_register_reset(pm_reset, pm); pm->powerdown_notifier.notify = pm_powerdown_req; qemu_register_powerdown_notifier(&pm->powerdown_notifier); acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci), &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE); if (pm->acpi_memory_hotplug.is_enabled) { acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci), &pm->acpi_memory_hotplug); } }
void init_pam(DeviceState *dev, MemoryRegion *ram_memory, MemoryRegion *system_memory, MemoryRegion *pci_address_space, PAMMemoryRegion *mem, uint32_t start, uint32_t size) { int i; /* RAM */ memory_region_init_alias(&mem->alias[3], OBJECT(dev), "pam-ram", ram_memory, start, size); /* ROM (XXX: not quite correct) */ memory_region_init_alias(&mem->alias[1], OBJECT(dev), "pam-rom", ram_memory, start, size); memory_region_set_readonly(&mem->alias[1], true); /* XXX: should distinguish read/write cases */ memory_region_init_alias(&mem->alias[0], OBJECT(dev), "pam-pci", pci_address_space, start, size); memory_region_init_alias(&mem->alias[2], OBJECT(dev), "pam-pci", ram_memory, start, size); for (i = 0; i < 4; ++i) { memory_region_set_enabled(&mem->alias[i], false); memory_region_add_subregion_overlap(system_memory, start, &mem->alias[i], 1); } mem->current = 0; }
void smram_update(MemoryRegion *smram_region, uint8_t smram, uint8_t smm_enabled) { bool smram_enabled; smram_enabled = ((smm_enabled && (smram & SMRAM_G_SMRAME)) || (smram & SMRAM_D_OPEN)); memory_region_set_enabled(smram_region, !smram_enabled); }
void cpu_smm_update(X86CPU *cpu) { CPUX86State *env = &cpu->env; bool smm_enabled = (env->hflags & HF_SMM_MASK); if (cpu->smram) { memory_region_set_enabled(cpu->smram, smm_enabled); } }
static void mch_realize(PCIDevice *d, Error **errp) { int i; MCHPCIState *mch = MCH_PCI_DEVICE(d); /* setup pci memory mapping */ pc_pci_as_mapping_init(OBJECT(mch), mch->system_memory, mch->pci_address_space); /* if *disabled* show SMRAM to all CPUs */ memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region", mch->pci_address_space, 0xa0000, 0x20000); memory_region_add_subregion_overlap(mch->system_memory, 0xa0000, &mch->smram_region, 1); memory_region_set_enabled(&mch->smram_region, true); memory_region_init_alias(&mch->open_high_smram, OBJECT(mch), "smram-open-high", mch->ram_memory, 0xa0000, 0x20000); memory_region_add_subregion_overlap(mch->system_memory, 0xfeda0000, &mch->open_high_smram, 1); memory_region_set_enabled(&mch->open_high_smram, false); /* smram, as seen by SMM CPUs */ memory_region_init(&mch->smram, OBJECT(mch), "smram", 1ull << 32); memory_region_set_enabled(&mch->smram, true); memory_region_init_alias(&mch->low_smram, OBJECT(mch), "smram-low", mch->ram_memory, 0xa0000, 0x20000); memory_region_set_enabled(&mch->low_smram, true); memory_region_add_subregion(&mch->smram, 0xa0000, &mch->low_smram); memory_region_init_alias(&mch->high_smram, OBJECT(mch), "smram-high", mch->ram_memory, 0xa0000, 0x20000); memory_region_set_enabled(&mch->high_smram, true); memory_region_add_subregion(&mch->smram, 0xfeda0000, &mch->high_smram); memory_region_init_io(&mch->tseg_blackhole, OBJECT(mch), &tseg_blackhole_ops, NULL, "tseg-blackhole", 0); memory_region_set_enabled(&mch->tseg_blackhole, false); memory_region_add_subregion_overlap(mch->system_memory, mch->below_4g_mem_size, &mch->tseg_blackhole, 1); memory_region_init_alias(&mch->tseg_window, OBJECT(mch), "tseg-window", mch->ram_memory, mch->below_4g_mem_size, 0); memory_region_set_enabled(&mch->tseg_window, false); memory_region_add_subregion(&mch->smram, mch->below_4g_mem_size, &mch->tseg_window); object_property_add_const_link(qdev_get_machine(), "smram", OBJECT(&mch->smram), &error_abort); init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space, &mch->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE); for (i = 0; i < 12; ++i) { init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space, &mch->pam_regions[i+1], PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE); } }
static void smbus_io_space_update(PIIX4PMState *s) { s->smb_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x90)); s->smb_io_base &= 0xffc0; memory_region_transaction_begin(); memory_region_set_enabled(&s->smb.io, s->dev.config[0xd2] & 1); memory_region_set_address(&s->smb.io, s->smb_io_base); memory_region_transaction_commit(); }
static void rs6000mc_realize(DeviceState *dev, Error **errp) { RS6000MCState *s = RS6000MC_DEVICE(dev); int socket = 0; unsigned int ram_size = s->ram_size / MiB; while (socket < 6) { if (ram_size >= 64) { s->simm_size[socket] = 32; s->simm_size[socket + 1] = 32; ram_size -= 64; } else if (ram_size >= 16) { s->simm_size[socket] = 8; s->simm_size[socket + 1] = 8; ram_size -= 16; } else { /* Not enough memory */ break; } socket += 2; } for (socket = 0; socket < 6; socket++) { if (s->simm_size[socket]) { char name[] = "simm.?"; name[5] = socket + '0'; memory_region_allocate_system_memory(&s->simm[socket], OBJECT(dev), name, s->simm_size[socket] * MiB); memory_region_add_subregion_overlap(get_system_memory(), 0, &s->simm[socket], socket); } } if (ram_size) { /* unable to push all requested RAM in SIMMs */ error_setg(errp, "RAM size incompatible with this board. " "Try again with something else, like %" PRId64 " MB", s->ram_size / MiB - ram_size); return; } if (s->autoconfigure) { uint32_t start_address = 0; for (socket = 0; socket < 6; socket++) { if (s->simm_size[socket]) { memory_region_set_enabled(&s->simm[socket], true); memory_region_set_address(&s->simm[socket], start_address); start_address += memory_region_size(&s->simm[socket]); } } } isa_register_portio_list(ISA_DEVICE(dev), &s->portio, 0x0, rs6000mc_port_list, s, "rs6000mc"); }
static inline void update_cpc_base(MIPSGCRState *gcr, uint64_t val) { if (is_cpc_connected(gcr)) { gcr->cpc_base = val & GCR_CPC_BASE_MSK; memory_region_transaction_begin(); memory_region_set_address(gcr->cpc_mr, gcr->cpc_base & GCR_CPC_BASE_CPCBASE_MSK); memory_region_set_enabled(gcr->cpc_mr, gcr->cpc_base & GCR_CPC_BASE_CPCEN_MSK); memory_region_transaction_commit(); } }
static void pm_io_space_update(PIIX4PMState *s) { PCIDevice *d = PCI_DEVICE(s); s->io_base = le32_to_cpu(*(uint32_t *)(d->config + 0x40)); s->io_base &= 0xffc0; memory_region_transaction_begin(); memory_region_set_enabled(&s->io, d->config[0x80] & 1); memory_region_set_address(&s->io, s->io_base); memory_region_transaction_commit(); }
static void pm_io_space_update(PIIX4PMState *s) { uint32_t pm_io_base; pm_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x40)); pm_io_base &= 0xffc0; memory_region_transaction_begin(); memory_region_set_enabled(&s->io, s->dev.config[0x80] & 1); memory_region_set_address(&s->io, pm_io_base); memory_region_transaction_commit(); }
void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base) { ICH9_DEBUG("to 0x%x\n", pm_io_base); assert((pm_io_base & ICH9_PMIO_MASK) == 0); pm->pm_io_base = pm_io_base; memory_region_transaction_begin(); memory_region_set_enabled(&pm->io, pm->pm_io_base != 0); memory_region_set_address(&pm->io, pm->pm_io_base); memory_region_transaction_commit(); }
static int mch_init(PCIDevice *d) { int i; hwaddr pci_hole64_size; MCHPCIState *mch = MCH_PCI_DEVICE(d); /* Leave enough space for the biggest MCFG BAR */ /* TODO: this matches current bios behaviour, but * it's not a power of two, which means an MTRR * can't cover it exactly. */ mch->guest_info->pci_info.w32.begin = MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT + MCH_HOST_BRIDGE_PCIEXBAR_MAX; /* setup pci memory regions */ memory_region_init_alias(&mch->pci_hole, OBJECT(mch), "pci-hole", mch->pci_address_space, mch->below_4g_mem_size, 0x100000000ULL - mch->below_4g_mem_size); memory_region_add_subregion(mch->system_memory, mch->below_4g_mem_size, &mch->pci_hole); pci_hole64_size = (sizeof(hwaddr) == 4 ? 0 : ((uint64_t)1 << 62)); memory_region_init_alias(&mch->pci_hole_64bit, OBJECT(mch), "pci-hole64", mch->pci_address_space, 0x100000000ULL + mch->above_4g_mem_size, pci_hole64_size); if (pci_hole64_size) { memory_region_add_subregion(mch->system_memory, 0x100000000ULL + mch->above_4g_mem_size, &mch->pci_hole_64bit); } /* smram */ cpu_smm_register(&mch_set_smm, mch); memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region", mch->pci_address_space, 0xa0000, 0x20000); memory_region_add_subregion_overlap(mch->system_memory, 0xa0000, &mch->smram_region, 1); memory_region_set_enabled(&mch->smram_region, false); init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space, &mch->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE); for (i = 0; i < 12; ++i) { init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space, &mch->pam_regions[i+1], PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE); } return 0; }
static void itc_reconfigure(MIPSITUState *tag) { uint64_t *am = &tag->ITCAddressMap[0]; MemoryRegion *mr = &tag->storage_io; hwaddr address = am[0] & ITC_AM0_BASE_ADDRESS_MASK; uint64_t size = (1 << 10) + (am[1] & ITC_AM1_ADDR_MASK_MASK); bool is_enabled = (am[0] & ITC_AM0_EN_MASK) != 0; memory_region_transaction_begin(); if (!(size & (size - 1))) { memory_region_set_size(mr, size); } memory_region_set_address(mr, address); memory_region_set_enabled(mr, is_enabled); memory_region_transaction_commit(); }
static int mch_init(PCIDevice *d) { int i; MCHPCIState *mch = MCH_PCI_DEVICE(d); uint64_t pci_hole64_size; /* setup pci memory regions */ memory_region_init_alias(&mch->pci_hole, OBJECT(mch), "pci-hole", mch->pci_address_space, mch->below_4g_mem_size, 0x100000000ULL - mch->below_4g_mem_size); memory_region_add_subregion(mch->system_memory, mch->below_4g_mem_size, &mch->pci_hole); pci_hole64_size = pci_host_get_hole64_size(mch->pci_hole64_size); pc_init_pci64_hole(&mch->pci_info, 0x100000000ULL + mch->above_4g_mem_size, pci_hole64_size); memory_region_init_alias(&mch->pci_hole_64bit, OBJECT(mch), "pci-hole64", mch->pci_address_space, mch->pci_info.w64.begin, pci_hole64_size); if (pci_hole64_size) { memory_region_add_subregion(mch->system_memory, mch->pci_info.w64.begin, &mch->pci_hole_64bit); } /* smram */ cpu_smm_register(&mch_set_smm, mch); memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region", mch->pci_address_space, 0xa0000, 0x20000); memory_region_add_subregion_overlap(mch->system_memory, 0xa0000, &mch->smram_region, 1); memory_region_set_enabled(&mch->smram_region, false); init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space, &mch->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE); for (i = 0; i < 12; ++i) { init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space, &mch->pam_regions[i+1], PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE); } return 0; }
static void rs6000mc_port0820_write(void *opaque, uint32_t addr, uint32_t val) { RS6000MCState *s = opaque; uint8_t socket = val >> 5; uint32_t end_address = val & 0x1f; trace_rs6000mc_size_write(addr, val); s->end_address[socket] = end_address; if (socket > 0 && socket < 7) { if (s->simm_size[socket - 1]) { uint32_t size; uint32_t start_address = 0; if (socket > 1) { start_address = s->end_address[socket - 1]; } size = end_address - start_address; memory_region_set_enabled(&s->simm[socket - 1], size != 0); memory_region_set_address(&s->simm[socket - 1], start_address * 8 * MiB); } } }
/* SMRAM */ static void mch_update_smram(MCHPCIState *mch) { PCIDevice *pd = PCI_DEVICE(mch); bool h_smrame = (pd->config[MCH_HOST_BRIDGE_ESMRAMC] & MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME); uint32_t tseg_size; /* implement SMRAM.D_LCK */ if (pd->config[MCH_HOST_BRIDGE_SMRAM] & MCH_HOST_BRIDGE_SMRAM_D_LCK) { pd->config[MCH_HOST_BRIDGE_SMRAM] &= ~MCH_HOST_BRIDGE_SMRAM_D_OPEN; pd->wmask[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_WMASK_LCK; pd->wmask[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_WMASK_LCK; } memory_region_transaction_begin(); if (pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_D_OPEN) { /* Hide (!) low SMRAM if H_SMRAME = 1 */ memory_region_set_enabled(&mch->smram_region, h_smrame); /* Show high SMRAM if H_SMRAME = 1 */ memory_region_set_enabled(&mch->open_high_smram, h_smrame); } else { /* Hide high SMRAM and low SMRAM */ memory_region_set_enabled(&mch->smram_region, true); memory_region_set_enabled(&mch->open_high_smram, false); } if (pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_G_SMRAME) { memory_region_set_enabled(&mch->low_smram, !h_smrame); memory_region_set_enabled(&mch->high_smram, h_smrame); } else { memory_region_set_enabled(&mch->low_smram, false); memory_region_set_enabled(&mch->high_smram, false); } if (pd->config[MCH_HOST_BRIDGE_ESMRAMC] & MCH_HOST_BRIDGE_ESMRAMC_T_EN) { switch (pd->config[MCH_HOST_BRIDGE_ESMRAMC] & MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK) { case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_1MB: tseg_size = 1024 * 1024; break; case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_2MB: tseg_size = 1024 * 1024 * 2; break; case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_8MB: tseg_size = 1024 * 1024 * 8; break; default: tseg_size = 0; break; } } else { tseg_size = 0; } memory_region_del_subregion(mch->system_memory, &mch->tseg_blackhole); memory_region_set_enabled(&mch->tseg_blackhole, tseg_size); memory_region_set_size(&mch->tseg_blackhole, tseg_size); memory_region_add_subregion_overlap(mch->system_memory, mch->below_4g_mem_size - tseg_size, &mch->tseg_blackhole, 1); memory_region_set_enabled(&mch->tseg_window, tseg_size); memory_region_set_size(&mch->tseg_window, tseg_size); memory_region_set_address(&mch->tseg_window, mch->below_4g_mem_size - tseg_size); memory_region_set_alias_offset(&mch->tseg_window, mch->below_4g_mem_size - tseg_size); memory_region_transaction_commit(); }
static void rpu_realize(DeviceState *dev, Error **errp) { RPU *s = XILINX_RPU(dev); const char *prefix = object_get_canonical_path(OBJECT(dev)); unsigned int i; for (i = 0; i < ARRAY_SIZE(rpu_regs_info); ++i) { RegisterInfo *r = &s->regs_info[rpu_regs_info[i].decode.addr/4]; *r = (RegisterInfo) { .data = (uint8_t *)&s->regs[ rpu_regs_info[i].decode.addr/4], .data_size = sizeof(uint32_t), .access = &rpu_regs_info[i], .debug = XILINX_RPU_ERR_DEBUG, .prefix = prefix, .opaque = s, }; register_init(r); qdev_pass_all_gpios(DEVICE(r), dev); } if (!s->atcm1_for_rpu0) { error_set(errp, QERR_MISSING_PARAMETER, "atcm1-for-rpu0"); return; } if (!s->btcm1_for_rpu0) { error_set(errp, QERR_MISSING_PARAMETER, "btcm1-for-rpu0"); return; } if (!s->icache_for_rpu1) { error_set(errp, QERR_MISSING_PARAMETER, "icache-for-rpu1"); return; } if (!s->dcache_for_rpu1) { error_set(errp, QERR_MISSING_PARAMETER, "dcache-for-rpu1"); return; } if (!s->ddr) { error_set(errp, QERR_MISSING_PARAMETER, "ddr-mem-for-rpu"); return; } /* RPUs starts in lockstep mode, so the rpu1 caches are not accessible. */ memory_region_set_enabled(s->icache_for_rpu1, false); memory_region_set_enabled(s->dcache_for_rpu1, false); memory_region_set_enabled(s->ddr, false); } static void rpu_init(Object *obj) { RPU *s = XILINX_RPU(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); memory_region_init_io(&s->iomem, obj, &rpu_ops, s, TYPE_XILINX_RPU, R_MAX * 4); sysbus_init_mmio(sbd, &s->iomem); sysbus_init_irq(sbd, &s->irq_rpu_1); sysbus_init_irq(sbd, &s->irq_rpu_0); /* xtcm1-for-rpu0 are the aliases for the tcm in lockstep mode. * This link allows to enable/disable those aliases when we are in * lock-step/normal mode. */ object_property_add_link(obj, "atcm1-for-rpu0", TYPE_MEMORY_REGION, (Object **)&s->atcm1_for_rpu0, qdev_prop_allow_set_link_before_realize, OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort); object_property_add_link(obj, "btcm1-for-rpu0", TYPE_MEMORY_REGION, (Object **)&s->btcm1_for_rpu0, qdev_prop_allow_set_link_before_realize, OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort); object_property_add_link(obj, "rpu1-for-main-bus", TYPE_MEMORY_REGION, (Object **)&s->atcm1_for_rpu0, qdev_prop_allow_set_link_before_realize, OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort); /* This link allows to enable/disable those memory region when we are in * lock-step/normal mode. */ object_property_add_link(obj, "icache-for-rpu1", TYPE_MEMORY_REGION, (Object **)&s->icache_for_rpu1, qdev_prop_allow_set_link_before_realize, OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort); object_property_add_link(obj, "dcache-for-rpu1", TYPE_MEMORY_REGION, (Object **)&s->dcache_for_rpu1, qdev_prop_allow_set_link_before_realize, OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort); /* Link to the second part of the DDR which is enabled in split mode and * disabled in lockstep mode. */ object_property_add_link(obj, "ddr-mem-for-rpu", TYPE_MEMORY_REGION, (Object **)&s->ddr, qdev_prop_allow_set_link_before_realize, OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort); /* wfi_out is used to connect to PMU GPIs. */ qdev_init_gpio_out_named(DEVICE(obj), s->wfi_out, "wfi_out", 2); /* wfi_in is used as input from CPUs as wfi request. */ qdev_init_gpio_in_named(DEVICE(obj), zynqmp_rpu_0_handle_wfi, "wfi_in_0", 1); qdev_init_gpio_in_named(DEVICE(obj), zynqmp_rpu_1_handle_wfi, "wfi_in_1", 1); }