diff mbox

[v2,10/18] nvdimm: init the address region used by DSM method

Message ID 1439563931-12352-11-git-send-email-guangrong.xiao@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Xiao Guangrong Aug. 14, 2015, 2:52 p.m. UTC
This memory range is used to transfer data between ACPI in guest and Qemu,
it occupies two pages:
- one is RAM-based used to save the input info of _DSM method and Qemu reuse
  it store output info

- another one is MMIO-based, ACPI write data to this page to transfer the
  control to Qemu

Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com>
---
 hw/mem/nvdimm/acpi.c      | 80 ++++++++++++++++++++++++++++++++++++++++++++++-
 hw/mem/nvdimm/internal.h  |  1 +
 hw/mem/nvdimm/pc-nvdimm.c |  2 +-
 3 files changed, 81 insertions(+), 2 deletions(-)

Comments

Stefan Hajnoczi Aug. 25, 2015, 4:11 p.m. UTC | #1
On Fri, Aug 14, 2015 at 10:52:03PM +0800, Xiao Guangrong wrote:
> @@ -257,14 +258,91 @@ static void build_nfit_table(GSList *device_list, char *buf)
>      }
>  }
>  
> +struct dsm_buffer {
> +    /* RAM page. */
> +    uint32_t handle;
> +    uint8_t arg0[16];
> +    uint32_t arg1;
> +    uint32_t arg2;
> +    union {
> +        char arg3[PAGE_SIZE - 3 * sizeof(uint32_t) - 16 * sizeof(uint8_t)];
> +    };
> +
> +    /* MMIO page. */
> +    union {
> +        uint32_t notify;
> +        char pedding[PAGE_SIZE];

s/pedding/padding/

> +    };
> +};
> +
> +static ram_addr_t dsm_addr;
> +static size_t dsm_size;
> +
> +static uint64_t dsm_read(void *opaque, hwaddr addr,
> +                         unsigned size)
> +{
> +    return 0;
> +}
> +
> +static void dsm_write(void *opaque, hwaddr addr,
> +                      uint64_t val, unsigned size)
> +{
> +}
> +
> +static const MemoryRegionOps dsm_ops = {
> +    .read = dsm_read,
> +    .write = dsm_write,
> +    .endianness = DEVICE_LITTLE_ENDIAN,
> +};
> +
> +static int build_dsm_buffer(void)
> +{
> +    MemoryRegion *dsm_ram_mr, *dsm_mmio_mr;
> +    ram_addr_t addr;;

s/;;/;/
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Xiao Guangrong Aug. 26, 2015, 10:41 a.m. UTC | #2
On 08/26/2015 12:11 AM, Stefan Hajnoczi wrote:
> On Fri, Aug 14, 2015 at 10:52:03PM +0800, Xiao Guangrong wrote:
>> @@ -257,14 +258,91 @@ static void build_nfit_table(GSList *device_list, char *buf)
>>       }
>>   }
>>
>> +struct dsm_buffer {
>> +    /* RAM page. */
>> +    uint32_t handle;
>> +    uint8_t arg0[16];
>> +    uint32_t arg1;
>> +    uint32_t arg2;
>> +    union {
>> +        char arg3[PAGE_SIZE - 3 * sizeof(uint32_t) - 16 * sizeof(uint8_t)];
>> +    };
>> +
>> +    /* MMIO page. */
>> +    union {
>> +        uint32_t notify;
>> +        char pedding[PAGE_SIZE];
>
> s/pedding/padding/

Will fix.

>
>> +    };
>> +};
>> +
>> +static ram_addr_t dsm_addr;
>> +static size_t dsm_size;
>> +
>> +static uint64_t dsm_read(void *opaque, hwaddr addr,
>> +                         unsigned size)
>> +{
>> +    return 0;
>> +}
>> +
>> +static void dsm_write(void *opaque, hwaddr addr,
>> +                      uint64_t val, unsigned size)
>> +{
>> +}
>> +
>> +static const MemoryRegionOps dsm_ops = {
>> +    .read = dsm_read,
>> +    .write = dsm_write,
>> +    .endianness = DEVICE_LITTLE_ENDIAN,
>> +};
>> +
>> +static int build_dsm_buffer(void)
>> +{
>> +    MemoryRegion *dsm_ram_mr, *dsm_mmio_mr;
>> +    ram_addr_t addr;;
>
> s/;;/;/

Will fix.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/hw/mem/nvdimm/acpi.c b/hw/mem/nvdimm/acpi.c
index f28752f..e0f2ad3 100644
--- a/hw/mem/nvdimm/acpi.c
+++ b/hw/mem/nvdimm/acpi.c
@@ -28,6 +28,7 @@ 
 
 #include "qemu-common.h"
 
+#include "exec/address-spaces.h"
 #include "hw/acpi/aml-build.h"
 #include "hw/mem/pc-nvdimm.h"
 
@@ -257,14 +258,91 @@  static void build_nfit_table(GSList *device_list, char *buf)
     }
 }
 
+struct dsm_buffer {
+    /* RAM page. */
+    uint32_t handle;
+    uint8_t arg0[16];
+    uint32_t arg1;
+    uint32_t arg2;
+    union {
+        char arg3[PAGE_SIZE - 3 * sizeof(uint32_t) - 16 * sizeof(uint8_t)];
+    };
+
+    /* MMIO page. */
+    union {
+        uint32_t notify;
+        char pedding[PAGE_SIZE];
+    };
+};
+
+static ram_addr_t dsm_addr;
+static size_t dsm_size;
+
+static uint64_t dsm_read(void *opaque, hwaddr addr,
+                         unsigned size)
+{
+    return 0;
+}
+
+static void dsm_write(void *opaque, hwaddr addr,
+                      uint64_t val, unsigned size)
+{
+}
+
+static const MemoryRegionOps dsm_ops = {
+    .read = dsm_read,
+    .write = dsm_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static int build_dsm_buffer(void)
+{
+    MemoryRegion *dsm_ram_mr, *dsm_mmio_mr;
+    ram_addr_t addr;;
+
+    QEMU_BUILD_BUG_ON(PAGE_SIZE * 2 != sizeof(struct dsm_buffer));
+
+    /* DSM buffer has already been built. */
+    if (dsm_addr) {
+        return 0;
+    }
+
+    addr = reserved_range_push(2 * PAGE_SIZE);
+    if (!addr) {
+        return -1;
+    }
+
+    dsm_addr = addr;
+    dsm_size = PAGE_SIZE * 2;
+
+    dsm_ram_mr = g_new(MemoryRegion, 1);
+    memory_region_init_ram(dsm_ram_mr, NULL, "dsm_ram", PAGE_SIZE,
+                           &error_abort);
+    vmstate_register_ram_global(dsm_ram_mr);
+    memory_region_add_subregion(get_system_memory(), addr, dsm_ram_mr);
+
+    dsm_mmio_mr = g_new(MemoryRegion, 1);
+    memory_region_init_io(dsm_mmio_mr, NULL, &dsm_ops, dsm_ram_mr,
+                          "dsm_mmio", PAGE_SIZE);
+    memory_region_add_subregion(get_system_memory(), addr + PAGE_SIZE,
+                                dsm_mmio_mr);
+    return 0;
+}
+
 void pc_nvdimm_build_nfit_table(GArray *table_offsets, GArray *table_data,
                                 GArray *linker)
 {
-    GSList *list = get_nvdimm_built_list();
+    GSList *list;
     size_t total;
     char *buf;
     int nfit_start, nr;
 
+    if (build_dsm_buffer()) {
+        fprintf(stderr, "do not have enough space for DSM buffer.\n");
+        return;
+    }
+
+    list = get_nvdimm_built_list();
     nr = get_nvdimm_device_number(list);
     total = get_nfit_total_size(nr);
 
diff --git a/hw/mem/nvdimm/internal.h b/hw/mem/nvdimm/internal.h
index 252a222..90d54dc 100644
--- a/hw/mem/nvdimm/internal.h
+++ b/hw/mem/nvdimm/internal.h
@@ -26,4 +26,5 @@  typedef struct {
     (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } })
 
 GSList *get_nvdimm_built_list(void);
+ram_addr_t reserved_range_push(uint64_t size);
 #endif
diff --git a/hw/mem/nvdimm/pc-nvdimm.c b/hw/mem/nvdimm/pc-nvdimm.c
index 2a6cfa2..752842a 100644
--- a/hw/mem/nvdimm/pc-nvdimm.c
+++ b/hw/mem/nvdimm/pc-nvdimm.c
@@ -45,7 +45,7 @@  void pc_nvdimm_reserve_range(ram_addr_t offset)
     nvdimms_info.current_addr = offset;
 }
 
-static ram_addr_t reserved_range_push(uint64_t size)
+ram_addr_t reserved_range_push(uint64_t size)
 {
     uint64_t current;