示例#1
0
文件: nvdimm.c 项目: AmesianX/panda
static void nvdimm_realize(PCDIMMDevice *dimm, Error **errp)
{
    MemoryRegion *mr = host_memory_backend_get_memory(dimm->hostmem, errp);
    NVDIMMDevice *nvdimm = NVDIMM(dimm);
    uint64_t align, pmem_size, size = memory_region_size(mr);

    align = memory_region_get_alignment(mr);

    pmem_size = size - nvdimm->label_size;
    nvdimm->label_data = memory_region_get_ram_ptr(mr) + pmem_size;
    pmem_size = QEMU_ALIGN_DOWN(pmem_size, align);

    if (size <= nvdimm->label_size || !pmem_size) {
        HostMemoryBackend *hostmem = dimm->hostmem;
        char *path = object_get_canonical_path_component(OBJECT(hostmem));

        error_setg(errp, "the size of memdev %s (0x%" PRIx64 ") is too "
                   "small to contain nvdimm label (0x%" PRIx64 ") and "
                   "aligned PMEM (0x%" PRIx64 ")",
                   path, memory_region_size(mr), nvdimm->label_size, align);
        g_free(path);
        return;
    }

    memory_region_init_alias(&nvdimm->nvdimm_mr, OBJECT(dimm),
                             "nvdimm-memory", mr, 0, pmem_size);
    nvdimm->nvdimm_mr.align = align;
}
示例#2
0
文件: nvdimm.c 项目: AmesianX/panda
static void nvdimm_set_label_size(Object *obj, Visitor *v, const char *name,
                                  void *opaque, Error **errp)
{
    NVDIMMDevice *nvdimm = NVDIMM(obj);
    Error *local_err = NULL;
    uint64_t value;

    if (memory_region_size(&nvdimm->nvdimm_mr)) {
        error_setg(&local_err, "cannot change property value");
        goto out;
    }

    visit_type_size(v, name, &value, &local_err);
    if (local_err) {
        goto out;
    }
    if (value < MIN_NAMESPACE_LABEL_SIZE) {
        error_setg(&local_err, "Property '%s.%s' (0x%" PRIx64 ") is required"
                   " at least 0x%lx", object_get_typename(obj),
                   name, value, MIN_NAMESPACE_LABEL_SIZE);
        goto out;
    }

    nvdimm->label_size = value;
out:
    error_propagate(errp, local_err);
}
示例#3
0
文件: nvdimm.c 项目: AmesianX/panda
static void nvdimm_get_label_size(Object *obj, Visitor *v, const char *name,
                                  void *opaque, Error **errp)
{
    NVDIMMDevice *nvdimm = NVDIMM(obj);
    uint64_t value = nvdimm->label_size;

    visit_type_size(v, name, &value, errp);
}
示例#4
0
文件: nvdimm.c 项目: Dovgalyuk/qemu
/*
 * ACPI 6.0: 5.2.25.2 Memory Device to System Physical Address Range Mapping
 * Structure
 */
static void
nvdimm_build_structure_memdev(GArray *structures, DeviceState *dev)
{
    NvdimmNfitMemDev *nfit_memdev;
    NVDIMMDevice *nvdimm = NVDIMM(OBJECT(dev));
    uint64_t size = object_property_get_uint(OBJECT(dev), PC_DIMM_SIZE_PROP,
                                             NULL);
    int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
                                            NULL);
    uint32_t handle = nvdimm_slot_to_handle(slot);

    nfit_memdev = acpi_data_push(structures, sizeof(*nfit_memdev));

    nfit_memdev->type = cpu_to_le16(1 /* Memory Device to System Address
                                         Range Map Structure*/);
    nfit_memdev->length = cpu_to_le16(sizeof(*nfit_memdev));
    nfit_memdev->nfit_handle = cpu_to_le32(handle);

    /*
     * associate memory device with System Physical Address Range
     * Structure.
     */
    nfit_memdev->spa_index = cpu_to_le16(nvdimm_slot_to_spa_index(slot));
    /* associate memory device with Control Region Structure. */
    nfit_memdev->dcr_index = cpu_to_le16(nvdimm_slot_to_dcr_index(slot));

    /* The memory region on the device. */
    nfit_memdev->region_len = cpu_to_le64(size);
    /* The device address starts from 0. */
    nfit_memdev->region_dpa = cpu_to_le64(0);

    /* Only one interleave for PMEM. */
    nfit_memdev->interleave_ways = cpu_to_le16(1);

    if (nvdimm->unarmed) {
        nfit_memdev->flags |= cpu_to_le16(ACPI_NFIT_MEM_NOT_ARMED);
    }
}
示例#5
0
文件: nvdimm.c 项目: AmesianX/panda
static MemoryRegion *nvdimm_get_memory_region(PCDIMMDevice *dimm)
{
    NVDIMMDevice *nvdimm = NVDIMM(dimm);

    return &nvdimm->nvdimm_mr;
}