4 * Copyright (C) 2021 Intel Corporation
7 * Yang Zhong<yang.zhong@intel.com>
8 * Sean Christopherson <sean.j.christopherson@intel.com>
10 * This work is licensed under the terms of the GNU GPL, version 2 or later.
11 * See the COPYING file in the top-level directory.
13 #include "qemu/osdep.h"
14 #include "hw/i386/pc.h"
15 #include "hw/i386/sgx-epc.h"
16 #include "hw/mem/memory-device.h"
17 #include "monitor/qdev.h"
18 #include "qapi/error.h"
19 #include "exec/address-spaces.h"
20 #include "hw/i386/sgx.h"
22 SGXInfo
*sgx_get_info(Error
**errp
)
25 X86MachineState
*x86ms
;
26 PCMachineState
*pcms
=
27 (PCMachineState
*)object_dynamic_cast(qdev_get_machine(),
30 error_setg(errp
, "SGX is only supported on PC machines");
34 x86ms
= X86_MACHINE(pcms
);
35 if (!x86ms
->sgx_epc_list
) {
36 error_setg(errp
, "No EPC regions defined, SGX not available");
40 SGXEPCState
*sgx_epc
= &pcms
->sgx_epc
;
41 info
= g_new0(SGXInfo
, 1);
47 info
->section_size
= sgx_epc
->size
;
52 int sgx_epc_get_section(int section_nr
, uint64_t *addr
, uint64_t *size
)
54 PCMachineState
*pcms
= PC_MACHINE(qdev_get_machine());
57 if (pcms
->sgx_epc
.size
== 0 || pcms
->sgx_epc
.nr_sections
<= section_nr
) {
61 epc
= pcms
->sgx_epc
.sections
[section_nr
];
64 *size
= memory_device_get_region_size(MEMORY_DEVICE(epc
), &error_fatal
);
69 void pc_machine_init_sgx_epc(PCMachineState
*pcms
)
71 SGXEPCState
*sgx_epc
= &pcms
->sgx_epc
;
72 X86MachineState
*x86ms
= X86_MACHINE(pcms
);
73 SgxEPCList
*list
= NULL
;
76 memset(sgx_epc
, 0, sizeof(SGXEPCState
));
77 if (!x86ms
->sgx_epc_list
) {
81 sgx_epc
->base
= 0x100000000ULL
+ x86ms
->above_4g_mem_size
;
83 memory_region_init(&sgx_epc
->mr
, OBJECT(pcms
), "sgx-epc", UINT64_MAX
);
84 memory_region_add_subregion(get_system_memory(), sgx_epc
->base
,
87 for (list
= x86ms
->sgx_epc_list
; list
; list
= list
->next
) {
88 obj
= object_new("sgx-epc");
90 /* set the memdev link with memory backend */
91 object_property_parse(obj
, SGX_EPC_MEMDEV_PROP
, list
->value
->memdev
,
93 object_property_set_bool(obj
, "realized", true, &error_fatal
);
97 if ((sgx_epc
->base
+ sgx_epc
->size
) < sgx_epc
->base
) {
98 error_report("Size of all 'sgx-epc' =0x%"PRIu64
" causes EPC to wrap",
103 memory_region_set_size(&sgx_epc
->mr
, sgx_epc
->size
);