1 #include "qemu/osdep.h"
3 #include "migration/vmstate.h"
4 #include "hw/acpi/cpu.h"
5 #include "qapi/error.h"
6 #include "qapi/qapi-events-misc.h"
8 #include "sysemu/numa.h"
10 #define ACPI_CPU_HOTPLUG_REG_LEN 12
11 #define ACPI_CPU_SELECTOR_OFFSET_WR 0
12 #define ACPI_CPU_FLAGS_OFFSET_RW 4
13 #define ACPI_CPU_CMD_OFFSET_WR 5
14 #define ACPI_CPU_CMD_DATA_OFFSET_RW 8
15 #define ACPI_CPU_CMD_DATA2_OFFSET_R 0
18 CPHP_GET_NEXT_CPU_WITH_EVENT_CMD
= 0,
19 CPHP_OST_EVENT_CMD
= 1,
20 CPHP_OST_STATUS_CMD
= 2,
21 CPHP_GET_CPU_ID_CMD
= 3,
25 static ACPIOSTInfo
*acpi_cpu_device_status(int idx
, AcpiCpuStatus
*cdev
)
27 ACPIOSTInfo
*info
= g_new0(ACPIOSTInfo
, 1);
29 info
->slot_type
= ACPI_SLOT_TYPE_CPU
;
30 info
->slot
= g_strdup_printf("%d", idx
);
31 info
->source
= cdev
->ost_event
;
32 info
->status
= cdev
->ost_status
;
34 DeviceState
*dev
= DEVICE(cdev
->cpu
);
36 info
->device
= g_strdup(dev
->id
);
37 info
->has_device
= true;
43 void acpi_cpu_ospm_status(CPUHotplugState
*cpu_st
, ACPIOSTInfoList
***list
)
47 for (i
= 0; i
< cpu_st
->dev_count
; i
++) {
48 ACPIOSTInfoList
*elem
= g_new0(ACPIOSTInfoList
, 1);
49 elem
->value
= acpi_cpu_device_status(i
, &cpu_st
->devs
[i
]);
56 static uint64_t cpu_hotplug_rd(void *opaque
, hwaddr addr
, unsigned size
)
59 CPUHotplugState
*cpu_st
= opaque
;
62 if (cpu_st
->selector
>= cpu_st
->dev_count
) {
66 cdev
= &cpu_st
->devs
[cpu_st
->selector
];
68 case ACPI_CPU_FLAGS_OFFSET_RW
: /* pack and return is_* fields */
69 val
|= cdev
->cpu
? 1 : 0;
70 val
|= cdev
->is_inserting
? 2 : 0;
71 val
|= cdev
->is_removing
? 4 : 0;
72 trace_cpuhp_acpi_read_flags(cpu_st
->selector
, val
);
74 case ACPI_CPU_CMD_DATA_OFFSET_RW
:
75 switch (cpu_st
->command
) {
76 case CPHP_GET_NEXT_CPU_WITH_EVENT_CMD
:
77 val
= cpu_st
->selector
;
79 case CPHP_GET_CPU_ID_CMD
:
80 val
= cdev
->arch_id
& 0xFFFFFFFF;
85 trace_cpuhp_acpi_read_cmd_data(cpu_st
->selector
, val
);
87 case ACPI_CPU_CMD_DATA2_OFFSET_R
:
88 switch (cpu_st
->command
) {
89 case CPHP_GET_NEXT_CPU_WITH_EVENT_CMD
:
92 case CPHP_GET_CPU_ID_CMD
:
93 val
= cdev
->arch_id
>> 32;
98 trace_cpuhp_acpi_read_cmd_data2(cpu_st
->selector
, val
);
106 static void cpu_hotplug_wr(void *opaque
, hwaddr addr
, uint64_t data
,
109 CPUHotplugState
*cpu_st
= opaque
;
113 assert(cpu_st
->dev_count
);
116 if (cpu_st
->selector
>= cpu_st
->dev_count
) {
117 trace_cpuhp_acpi_invalid_idx_selected(cpu_st
->selector
);
123 case ACPI_CPU_SELECTOR_OFFSET_WR
: /* current CPU selector */
124 cpu_st
->selector
= data
;
125 trace_cpuhp_acpi_write_idx(cpu_st
->selector
);
127 case ACPI_CPU_FLAGS_OFFSET_RW
: /* set is_* fields */
128 cdev
= &cpu_st
->devs
[cpu_st
->selector
];
129 if (data
& 2) { /* clear insert event */
130 cdev
->is_inserting
= false;
131 trace_cpuhp_acpi_clear_inserting_evt(cpu_st
->selector
);
132 } else if (data
& 4) { /* clear remove event */
133 cdev
->is_removing
= false;
134 trace_cpuhp_acpi_clear_remove_evt(cpu_st
->selector
);
135 } else if (data
& 8) {
136 DeviceState
*dev
= NULL
;
137 HotplugHandler
*hotplug_ctrl
= NULL
;
139 if (!cdev
->cpu
|| cdev
->cpu
== first_cpu
) {
140 trace_cpuhp_acpi_ejecting_invalid_cpu(cpu_st
->selector
);
144 trace_cpuhp_acpi_ejecting_cpu(cpu_st
->selector
);
145 dev
= DEVICE(cdev
->cpu
);
146 hotplug_ctrl
= qdev_get_hotplug_handler(dev
);
147 hotplug_handler_unplug(hotplug_ctrl
, dev
, NULL
);
148 object_unparent(OBJECT(dev
));
151 case ACPI_CPU_CMD_OFFSET_WR
:
152 trace_cpuhp_acpi_write_cmd(cpu_st
->selector
, data
);
153 if (data
< CPHP_CMD_MAX
) {
154 cpu_st
->command
= data
;
155 if (cpu_st
->command
== CPHP_GET_NEXT_CPU_WITH_EVENT_CMD
) {
156 uint32_t iter
= cpu_st
->selector
;
159 cdev
= &cpu_st
->devs
[iter
];
160 if (cdev
->is_inserting
|| cdev
->is_removing
) {
161 cpu_st
->selector
= iter
;
162 trace_cpuhp_acpi_cpu_has_events(cpu_st
->selector
,
163 cdev
->is_inserting
, cdev
->is_removing
);
166 iter
= iter
+ 1 < cpu_st
->dev_count
? iter
+ 1 : 0;
167 } while (iter
!= cpu_st
->selector
);
171 case ACPI_CPU_CMD_DATA_OFFSET_RW
:
172 switch (cpu_st
->command
) {
173 case CPHP_OST_EVENT_CMD
: {
174 cdev
= &cpu_st
->devs
[cpu_st
->selector
];
175 cdev
->ost_event
= data
;
176 trace_cpuhp_acpi_write_ost_ev(cpu_st
->selector
, cdev
->ost_event
);
179 case CPHP_OST_STATUS_CMD
: {
180 cdev
= &cpu_st
->devs
[cpu_st
->selector
];
181 cdev
->ost_status
= data
;
182 info
= acpi_cpu_device_status(cpu_st
->selector
, cdev
);
183 qapi_event_send_acpi_device_ost(info
);
184 qapi_free_ACPIOSTInfo(info
);
185 trace_cpuhp_acpi_write_ost_status(cpu_st
->selector
,
198 static const MemoryRegionOps cpu_hotplug_ops
= {
199 .read
= cpu_hotplug_rd
,
200 .write
= cpu_hotplug_wr
,
201 .endianness
= DEVICE_LITTLE_ENDIAN
,
203 .min_access_size
= 1,
204 .max_access_size
= 4,
208 void cpu_hotplug_hw_init(MemoryRegion
*as
, Object
*owner
,
209 CPUHotplugState
*state
, hwaddr base_addr
)
211 MachineState
*machine
= MACHINE(qdev_get_machine());
212 MachineClass
*mc
= MACHINE_GET_CLASS(machine
);
213 const CPUArchIdList
*id_list
;
216 assert(mc
->possible_cpu_arch_ids
);
217 id_list
= mc
->possible_cpu_arch_ids(machine
);
218 state
->dev_count
= id_list
->len
;
219 state
->devs
= g_new0(typeof(*state
->devs
), state
->dev_count
);
220 for (i
= 0; i
< id_list
->len
; i
++) {
221 state
->devs
[i
].cpu
= CPU(id_list
->cpus
[i
].cpu
);
222 state
->devs
[i
].arch_id
= id_list
->cpus
[i
].arch_id
;
224 memory_region_init_io(&state
->ctrl_reg
, owner
, &cpu_hotplug_ops
, state
,
225 "acpi-cpu-hotplug", ACPI_CPU_HOTPLUG_REG_LEN
);
226 memory_region_add_subregion(as
, base_addr
, &state
->ctrl_reg
);
229 static AcpiCpuStatus
*get_cpu_status(CPUHotplugState
*cpu_st
, DeviceState
*dev
)
231 CPUClass
*k
= CPU_GET_CLASS(dev
);
232 uint64_t cpu_arch_id
= k
->get_arch_id(CPU(dev
));
235 for (i
= 0; i
< cpu_st
->dev_count
; i
++) {
236 if (cpu_arch_id
== cpu_st
->devs
[i
].arch_id
) {
237 return &cpu_st
->devs
[i
];
243 void acpi_cpu_plug_cb(HotplugHandler
*hotplug_dev
,
244 CPUHotplugState
*cpu_st
, DeviceState
*dev
, Error
**errp
)
248 cdev
= get_cpu_status(cpu_st
, dev
);
253 cdev
->cpu
= CPU(dev
);
254 if (dev
->hotplugged
) {
255 cdev
->is_inserting
= true;
256 acpi_send_event(DEVICE(hotplug_dev
), ACPI_CPU_HOTPLUG_STATUS
);
260 void acpi_cpu_unplug_request_cb(HotplugHandler
*hotplug_dev
,
261 CPUHotplugState
*cpu_st
,
262 DeviceState
*dev
, Error
**errp
)
266 cdev
= get_cpu_status(cpu_st
, dev
);
271 cdev
->is_removing
= true;
272 acpi_send_event(DEVICE(hotplug_dev
), ACPI_CPU_HOTPLUG_STATUS
);
275 void acpi_cpu_unplug_cb(CPUHotplugState
*cpu_st
,
276 DeviceState
*dev
, Error
**errp
)
280 cdev
= get_cpu_status(cpu_st
, dev
);
288 static const VMStateDescription vmstate_cpuhp_sts
= {
289 .name
= "CPU hotplug device state",
291 .minimum_version_id
= 1,
292 .minimum_version_id_old
= 1,
293 .fields
= (VMStateField
[]) {
294 VMSTATE_BOOL(is_inserting
, AcpiCpuStatus
),
295 VMSTATE_BOOL(is_removing
, AcpiCpuStatus
),
296 VMSTATE_UINT32(ost_event
, AcpiCpuStatus
),
297 VMSTATE_UINT32(ost_status
, AcpiCpuStatus
),
298 VMSTATE_END_OF_LIST()
302 const VMStateDescription vmstate_cpu_hotplug
= {
303 .name
= "CPU hotplug state",
305 .minimum_version_id
= 1,
306 .minimum_version_id_old
= 1,
307 .fields
= (VMStateField
[]) {
308 VMSTATE_UINT32(selector
, CPUHotplugState
),
309 VMSTATE_UINT8(command
, CPUHotplugState
),
310 VMSTATE_STRUCT_VARRAY_POINTER_UINT32(devs
, CPUHotplugState
, dev_count
,
311 vmstate_cpuhp_sts
, AcpiCpuStatus
),
312 VMSTATE_END_OF_LIST()
316 #define CPU_NAME_FMT "C%.03X"
317 #define CPUHP_RES_DEVICE "PRES"
318 #define CPU_LOCK "CPLK"
319 #define CPU_STS_METHOD "CSTA"
320 #define CPU_SCAN_METHOD "CSCN"
321 #define CPU_NOTIFY_METHOD "CTFY"
322 #define CPU_EJECT_METHOD "CEJ0"
323 #define CPU_OST_METHOD "COST"
325 #define CPU_ENABLED "CPEN"
326 #define CPU_SELECTOR "CSEL"
327 #define CPU_COMMAND "CCMD"
328 #define CPU_DATA "CDAT"
329 #define CPU_INSERT_EVENT "CINS"
330 #define CPU_REMOVE_EVENT "CRMV"
331 #define CPU_EJECT_EVENT "CEJ0"
333 void build_cpus_aml(Aml
*table
, MachineState
*machine
, CPUHotplugFeatures opts
,
335 const char *res_root
,
336 const char *event_handler_method
)
343 Aml
*zero
= aml_int(0);
344 Aml
*one
= aml_int(1);
345 Aml
*sb_scope
= aml_scope("_SB");
346 MachineClass
*mc
= MACHINE_GET_CLASS(machine
);
347 const CPUArchIdList
*arch_ids
= mc
->possible_cpu_arch_ids(machine
);
348 char *cphp_res_path
= g_strdup_printf("%s." CPUHP_RES_DEVICE
, res_root
);
349 Object
*obj
= object_resolve_path_type("", TYPE_ACPI_DEVICE_IF
, NULL
);
350 AcpiDeviceIfClass
*adevc
= ACPI_DEVICE_IF_GET_CLASS(obj
);
351 AcpiDeviceIf
*adev
= ACPI_DEVICE_IF(obj
);
353 cpu_ctrl_dev
= aml_device("%s", cphp_res_path
);
357 aml_append(cpu_ctrl_dev
,
358 aml_name_decl("_HID", aml_eisaid("PNP0A06")));
359 aml_append(cpu_ctrl_dev
,
360 aml_name_decl("_UID", aml_string("CPU Hotplug resources")));
361 aml_append(cpu_ctrl_dev
, aml_mutex(CPU_LOCK
, 0));
363 crs
= aml_resource_template();
364 aml_append(crs
, aml_io(AML_DECODE16
, io_base
, io_base
, 1,
365 ACPI_CPU_HOTPLUG_REG_LEN
));
366 aml_append(cpu_ctrl_dev
, aml_name_decl("_CRS", crs
));
368 /* declare CPU hotplug MMIO region with related access fields */
369 aml_append(cpu_ctrl_dev
,
370 aml_operation_region("PRST", AML_SYSTEM_IO
, aml_int(io_base
),
371 ACPI_CPU_HOTPLUG_REG_LEN
));
373 field
= aml_field("PRST", AML_BYTE_ACC
, AML_NOLOCK
,
375 aml_append(field
, aml_reserved_field(ACPI_CPU_FLAGS_OFFSET_RW
* 8));
376 /* 1 if enabled, read only */
377 aml_append(field
, aml_named_field(CPU_ENABLED
, 1));
378 /* (read) 1 if has a insert event. (write) 1 to clear event */
379 aml_append(field
, aml_named_field(CPU_INSERT_EVENT
, 1));
380 /* (read) 1 if has a remove event. (write) 1 to clear event */
381 aml_append(field
, aml_named_field(CPU_REMOVE_EVENT
, 1));
382 /* initiates device eject, write only */
383 aml_append(field
, aml_named_field(CPU_EJECT_EVENT
, 1));
384 aml_append(field
, aml_reserved_field(4));
385 aml_append(field
, aml_named_field(CPU_COMMAND
, 8));
386 aml_append(cpu_ctrl_dev
, field
);
388 field
= aml_field("PRST", AML_DWORD_ACC
, AML_NOLOCK
, AML_PRESERVE
);
389 /* CPU selector, write only */
390 aml_append(field
, aml_named_field(CPU_SELECTOR
, 32));
391 /* flags + cmd + 2byte align */
392 aml_append(field
, aml_reserved_field(4 * 8));
393 aml_append(field
, aml_named_field(CPU_DATA
, 32));
394 aml_append(cpu_ctrl_dev
, field
);
396 if (opts
.has_legacy_cphp
) {
397 method
= aml_method("_INI", 0, AML_SERIALIZED
);
398 /* switch off legacy CPU hotplug HW and use new one,
399 * on reboot system is in new mode and writing 0
400 * in CPU_SELECTOR selects BSP, which is NOP at
401 * the time _INI is called */
402 aml_append(method
, aml_store(zero
, aml_name(CPU_SELECTOR
)));
403 aml_append(cpu_ctrl_dev
, method
);
406 aml_append(sb_scope
, cpu_ctrl_dev
);
408 cpus_dev
= aml_device("\\_SB.CPUS");
411 Aml
*ctrl_lock
= aml_name("%s.%s", cphp_res_path
, CPU_LOCK
);
412 Aml
*cpu_selector
= aml_name("%s.%s", cphp_res_path
, CPU_SELECTOR
);
413 Aml
*is_enabled
= aml_name("%s.%s", cphp_res_path
, CPU_ENABLED
);
414 Aml
*cpu_cmd
= aml_name("%s.%s", cphp_res_path
, CPU_COMMAND
);
415 Aml
*cpu_data
= aml_name("%s.%s", cphp_res_path
, CPU_DATA
);
416 Aml
*ins_evt
= aml_name("%s.%s", cphp_res_path
, CPU_INSERT_EVENT
);
417 Aml
*rm_evt
= aml_name("%s.%s", cphp_res_path
, CPU_REMOVE_EVENT
);
418 Aml
*ej_evt
= aml_name("%s.%s", cphp_res_path
, CPU_EJECT_EVENT
);
420 aml_append(cpus_dev
, aml_name_decl("_HID", aml_string("ACPI0010")));
421 aml_append(cpus_dev
, aml_name_decl("_CID", aml_eisaid("PNP0A05")));
423 method
= aml_method(CPU_NOTIFY_METHOD
, 2, AML_NOTSERIALIZED
);
424 for (i
= 0; i
< arch_ids
->len
; i
++) {
425 Aml
*cpu
= aml_name(CPU_NAME_FMT
, i
);
426 Aml
*uid
= aml_arg(0);
427 Aml
*event
= aml_arg(1);
429 ifctx
= aml_if(aml_equal(uid
, aml_int(i
)));
431 aml_append(ifctx
, aml_notify(cpu
, event
));
433 aml_append(method
, ifctx
);
435 aml_append(cpus_dev
, method
);
437 method
= aml_method(CPU_STS_METHOD
, 1, AML_SERIALIZED
);
439 Aml
*idx
= aml_arg(0);
440 Aml
*sta
= aml_local(0);
442 aml_append(method
, aml_acquire(ctrl_lock
, 0xFFFF));
443 aml_append(method
, aml_store(idx
, cpu_selector
));
444 aml_append(method
, aml_store(zero
, sta
));
445 ifctx
= aml_if(aml_equal(is_enabled
, one
));
447 aml_append(ifctx
, aml_store(aml_int(0xF), sta
));
449 aml_append(method
, ifctx
);
450 aml_append(method
, aml_release(ctrl_lock
));
451 aml_append(method
, aml_return(sta
));
453 aml_append(cpus_dev
, method
);
455 method
= aml_method(CPU_EJECT_METHOD
, 1, AML_SERIALIZED
);
457 Aml
*idx
= aml_arg(0);
459 aml_append(method
, aml_acquire(ctrl_lock
, 0xFFFF));
460 aml_append(method
, aml_store(idx
, cpu_selector
));
461 aml_append(method
, aml_store(one
, ej_evt
));
462 aml_append(method
, aml_release(ctrl_lock
));
464 aml_append(cpus_dev
, method
);
466 method
= aml_method(CPU_SCAN_METHOD
, 0, AML_SERIALIZED
);
470 Aml
*has_event
= aml_local(0);
471 Aml
*dev_chk
= aml_int(1);
472 Aml
*eject_req
= aml_int(3);
473 Aml
*next_cpu_cmd
= aml_int(CPHP_GET_NEXT_CPU_WITH_EVENT_CMD
);
475 aml_append(method
, aml_acquire(ctrl_lock
, 0xFFFF));
476 aml_append(method
, aml_store(one
, has_event
));
477 while_ctx
= aml_while(aml_equal(has_event
, one
));
479 /* clear loop exit condition, ins_evt/rm_evt checks
480 * will set it to 1 while next_cpu_cmd returns a CPU
482 aml_append(while_ctx
, aml_store(zero
, has_event
));
483 aml_append(while_ctx
, aml_store(next_cpu_cmd
, cpu_cmd
));
484 ifctx
= aml_if(aml_equal(ins_evt
, one
));
487 aml_call2(CPU_NOTIFY_METHOD
, cpu_data
, dev_chk
));
488 aml_append(ifctx
, aml_store(one
, ins_evt
));
489 aml_append(ifctx
, aml_store(one
, has_event
));
491 aml_append(while_ctx
, ifctx
);
492 else_ctx
= aml_else();
493 ifctx
= aml_if(aml_equal(rm_evt
, one
));
496 aml_call2(CPU_NOTIFY_METHOD
, cpu_data
, eject_req
));
497 aml_append(ifctx
, aml_store(one
, rm_evt
));
498 aml_append(ifctx
, aml_store(one
, has_event
));
500 aml_append(else_ctx
, ifctx
);
501 aml_append(while_ctx
, else_ctx
);
503 aml_append(method
, while_ctx
);
504 aml_append(method
, aml_release(ctrl_lock
));
506 aml_append(cpus_dev
, method
);
508 method
= aml_method(CPU_OST_METHOD
, 4, AML_SERIALIZED
);
510 Aml
*uid
= aml_arg(0);
511 Aml
*ev_cmd
= aml_int(CPHP_OST_EVENT_CMD
);
512 Aml
*st_cmd
= aml_int(CPHP_OST_STATUS_CMD
);
514 aml_append(method
, aml_acquire(ctrl_lock
, 0xFFFF));
515 aml_append(method
, aml_store(uid
, cpu_selector
));
516 aml_append(method
, aml_store(ev_cmd
, cpu_cmd
));
517 aml_append(method
, aml_store(aml_arg(1), cpu_data
));
518 aml_append(method
, aml_store(st_cmd
, cpu_cmd
));
519 aml_append(method
, aml_store(aml_arg(2), cpu_data
));
520 aml_append(method
, aml_release(ctrl_lock
));
522 aml_append(cpus_dev
, method
);
524 /* build Processor object for each processor */
525 for (i
= 0; i
< arch_ids
->len
; i
++) {
527 Aml
*uid
= aml_int(i
);
528 GArray
*madt_buf
= g_array_new(0, 1, 1);
529 int arch_id
= arch_ids
->cpus
[i
].arch_id
;
531 if (opts
.acpi_1_compatible
&& arch_id
< 255) {
532 dev
= aml_processor(i
, 0, 0, CPU_NAME_FMT
, i
);
534 dev
= aml_device(CPU_NAME_FMT
, i
);
535 aml_append(dev
, aml_name_decl("_HID", aml_string("ACPI0007")));
536 aml_append(dev
, aml_name_decl("_UID", uid
));
539 method
= aml_method("_STA", 0, AML_SERIALIZED
);
540 aml_append(method
, aml_return(aml_call1(CPU_STS_METHOD
, uid
)));
541 aml_append(dev
, method
);
543 /* build _MAT object */
544 assert(adevc
&& adevc
->madt_cpu
);
545 adevc
->madt_cpu(adev
, i
, arch_ids
, madt_buf
);
546 switch (madt_buf
->data
[0]) {
547 case ACPI_APIC_PROCESSOR
: {
548 AcpiMadtProcessorApic
*apic
= (void *)madt_buf
->data
;
549 apic
->flags
= cpu_to_le32(1);
552 case ACPI_APIC_LOCAL_X2APIC
: {
553 AcpiMadtProcessorX2Apic
*apic
= (void *)madt_buf
->data
;
554 apic
->flags
= cpu_to_le32(1);
560 aml_append(dev
, aml_name_decl("_MAT",
561 aml_buffer(madt_buf
->len
, (uint8_t *)madt_buf
->data
)));
562 g_array_free(madt_buf
, true);
564 if (CPU(arch_ids
->cpus
[i
].cpu
) != first_cpu
) {
565 method
= aml_method("_EJ0", 1, AML_NOTSERIALIZED
);
566 aml_append(method
, aml_call1(CPU_EJECT_METHOD
, uid
));
567 aml_append(dev
, method
);
570 method
= aml_method("_OST", 3, AML_SERIALIZED
);
572 aml_call4(CPU_OST_METHOD
, uid
, aml_arg(0),
573 aml_arg(1), aml_arg(2))
575 aml_append(dev
, method
);
577 /* Linux guests discard SRAT info for non-present CPUs
578 * as a result _PXM is required for all CPUs which might
579 * be hot-plugged. For simplicity, add it for all CPUs.
581 if (arch_ids
->cpus
[i
].props
.has_node_id
) {
582 aml_append(dev
, aml_name_decl("_PXM",
583 aml_int(arch_ids
->cpus
[i
].props
.node_id
)));
586 aml_append(cpus_dev
, dev
);
589 aml_append(sb_scope
, cpus_dev
);
590 aml_append(table
, sb_scope
);
592 method
= aml_method(event_handler_method
, 0, AML_NOTSERIALIZED
);
593 aml_append(method
, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD
));
594 aml_append(table
, method
);
596 g_free(cphp_res_path
);