@@ -390,15 +390,71 @@ struct NvdimmDsmOut {
390
390
} QEMU_PACKED ;
391
391
typedef struct NvdimmDsmOut NvdimmDsmOut ;
392
392
393
+ struct NvdimmDsmFunc0Out {
394
+ /* the size of buffer filled by QEMU. */
395
+ uint32_t len ;
396
+ uint32_t supported_func ;
397
+ } QEMU_PACKED ;
398
+ typedef struct NvdimmDsmFunc0Out NvdimmDsmFunc0Out ;
399
+
400
+ struct NvdimmDsmFuncNoPayloadOut {
401
+ /* the size of buffer filled by QEMU. */
402
+ uint32_t len ;
403
+ uint32_t func_ret_status ;
404
+ } QEMU_PACKED ;
405
+ typedef struct NvdimmDsmFuncNoPayloadOut NvdimmDsmFuncNoPayloadOut ;
406
+
393
407
static uint64_t
394
408
nvdimm_dsm_read (void * opaque , hwaddr addr , unsigned size )
395
409
{
410
+ nvdimm_debug ("BUG: we never read _DSM IO Port.\n" );
396
411
return 0 ;
397
412
}
398
413
399
414
static void
400
415
nvdimm_dsm_write (void * opaque , hwaddr addr , uint64_t val , unsigned size )
401
416
{
417
+ NvdimmDsmIn * in ;
418
+ hwaddr dsm_mem_addr = val ;
419
+
420
+ nvdimm_debug ("dsm memory address %#" HWADDR_PRIx ".\n" , dsm_mem_addr );
421
+
422
+ /*
423
+ * The DSM memory is mapped to guest address space so an evil guest
424
+ * can change its content while we are doing DSM emulation. Avoid
425
+ * this by copying DSM memory to QEMU local memory.
426
+ */
427
+ in = g_malloc (TARGET_PAGE_SIZE );
428
+ cpu_physical_memory_read (dsm_mem_addr , in , TARGET_PAGE_SIZE );
429
+
430
+ le32_to_cpus (& in -> revision );
431
+ le32_to_cpus (& in -> function );
432
+ le32_to_cpus (& in -> handle );
433
+
434
+ nvdimm_debug ("Revision %#x Handler %#x Function %#x.\n" , in -> revision ,
435
+ in -> handle , in -> function );
436
+
437
+ /*
438
+ * function 0 is called to inquire which functions are supported by
439
+ * OSPM
440
+ */
441
+ if (in -> function == 0 ) {
442
+ NvdimmDsmFunc0Out func0 = {
443
+ .len = cpu_to_le32 (sizeof (func0 )),
444
+ /* No function supported other than function 0 */
445
+ .supported_func = cpu_to_le32 (0 ),
446
+ };
447
+ cpu_physical_memory_write (dsm_mem_addr , & func0 , sizeof func0 );
448
+ } else {
449
+ /* No function except function 0 is supported yet. */
450
+ NvdimmDsmFuncNoPayloadOut out = {
451
+ .len = cpu_to_le32 (sizeof (out )),
452
+ .func_ret_status = cpu_to_le32 (1 ) /* Not Supported */ ,
453
+ };
454
+ cpu_physical_memory_write (dsm_mem_addr , & out , sizeof (out ));
455
+ }
456
+
457
+ g_free (in );
402
458
}
403
459
404
460
static const MemoryRegionOps nvdimm_dsm_ops = {
0 commit comments