2 * Memory hotplug AML code of DSDT ACPI table
4 * Copyright (C) 2015 Red Hat Inc
6 * Author: Igor Mammedov <imammedo@redhat.com>
8 * This work is licensed under the terms of the GNU GPL, version 2 or later.
9 * See the COPYING file in the top-level directory.
13 #include "hw/acpi/memory_hotplug.h"
14 #include "include/hw/acpi/pc-hotplug.h"
15 #include "hw/boards.h"
17 void build_memory_hotplug_aml(Aml
*ctx
, uint32_t nr_mem
,
18 uint16_t io_base
, uint16_t io_len
)
25 /* scope for memory hotplug controller device node */
26 pci_scope
= aml_scope("_SB.PCI0");
27 mem_ctrl_dev
= aml_scope(stringify(MEMORY_HOTPLUG_DEVICE
));
29 Aml
*one
= aml_int(1);
30 Aml
*zero
= aml_int(0);
31 Aml
*ret_val
= aml_local(0);
32 Aml
*slot_arg0
= aml_arg(0);
33 Aml
*slots_nr
= aml_name(stringify(MEMORY_SLOTS_NUMBER
));
34 Aml
*ctrl_lock
= aml_name(stringify(MEMORY_SLOT_LOCK
));
35 Aml
*slot_selector
= aml_name(stringify(MEMORY_SLOT_SLECTOR
));
37 method
= aml_method("_STA", 0, AML_NOTSERIALIZED
);
38 ifctx
= aml_if(aml_equal(slots_nr
, zero
));
40 aml_append(ifctx
, aml_return(zero
));
42 aml_append(method
, ifctx
);
43 /* present, functioning, decoding, not shown in UI */
44 aml_append(method
, aml_return(aml_int(0xB)));
45 aml_append(mem_ctrl_dev
, method
);
47 aml_append(mem_ctrl_dev
, aml_mutex(stringify(MEMORY_SLOT_LOCK
), 0));
49 method
= aml_method(stringify(MEMORY_SLOT_SCAN_METHOD
), 0,
54 Aml
*idx
= aml_local(0);
55 Aml
*eject_req
= aml_int(3);
56 Aml
*dev_chk
= aml_int(1);
58 ifctx
= aml_if(aml_equal(slots_nr
, zero
));
60 aml_append(ifctx
, aml_return(zero
));
62 aml_append(method
, ifctx
);
64 aml_append(method
, aml_store(zero
, idx
));
65 aml_append(method
, aml_acquire(ctrl_lock
, 0xFFFF));
67 * loops over all slots and Notifies DIMMs with
68 * Device Check or Eject Request notifications if
69 * slot has corresponding status bit set and clears
72 while_ctx
= aml_while(aml_lless(idx
, slots_nr
));
74 Aml
*ins_evt
= aml_name(stringify(MEMORY_SLOT_INSERT_EVENT
));
75 Aml
*rm_evt
= aml_name(stringify(MEMORY_SLOT_REMOVE_EVENT
));
77 aml_append(while_ctx
, aml_store(idx
, slot_selector
));
78 ifctx
= aml_if(aml_equal(ins_evt
, one
));
81 aml_call2(stringify(MEMORY_SLOT_NOTIFY_METHOD
),
83 aml_append(ifctx
, aml_store(one
, ins_evt
));
85 aml_append(while_ctx
, ifctx
);
87 else_ctx
= aml_else();
88 ifctx
= aml_if(aml_equal(rm_evt
, one
));
91 aml_call2(stringify(MEMORY_SLOT_NOTIFY_METHOD
),
93 aml_append(ifctx
, aml_store(one
, rm_evt
));
95 aml_append(else_ctx
, ifctx
);
96 aml_append(while_ctx
, else_ctx
);
98 aml_append(while_ctx
, aml_add(idx
, one
, idx
));
100 aml_append(method
, while_ctx
);
101 aml_append(method
, aml_release(ctrl_lock
));
102 aml_append(method
, aml_return(one
));
104 aml_append(mem_ctrl_dev
, method
);
106 method
= aml_method(stringify(MEMORY_SLOT_STATUS_METHOD
), 1,
109 Aml
*slot_enabled
= aml_name(stringify(MEMORY_SLOT_ENABLED
));
111 aml_append(method
, aml_store(zero
, ret_val
));
112 aml_append(method
, aml_acquire(ctrl_lock
, 0xFFFF));
114 aml_store(aml_to_integer(slot_arg0
), slot_selector
));
116 ifctx
= aml_if(aml_equal(slot_enabled
, one
));
118 aml_append(ifctx
, aml_store(aml_int(0xF), ret_val
));
120 aml_append(method
, ifctx
);
122 aml_append(method
, aml_release(ctrl_lock
));
123 aml_append(method
, aml_return(ret_val
));
125 aml_append(mem_ctrl_dev
, method
);
127 method
= aml_method(stringify(MEMORY_SLOT_PROXIMITY_METHOD
), 1,
130 Aml
*proximity
= aml_name(stringify(MEMORY_SLOT_PROXIMITY
));
132 aml_append(method
, aml_acquire(ctrl_lock
, 0xFFFF));
133 aml_append(method
, aml_store(aml_to_integer(slot_arg0
),
135 aml_append(method
, aml_store(proximity
, ret_val
));
136 aml_append(method
, aml_release(ctrl_lock
));
137 aml_append(method
, aml_return(ret_val
));
139 aml_append(mem_ctrl_dev
, method
);
141 method
= aml_method(stringify(MEMORY_SLOT_OST_METHOD
), 4,
144 Aml
*ost_evt
= aml_name(stringify(MEMORY_SLOT_OST_EVENT
));
145 Aml
*ost_status
= aml_name(stringify(MEMORY_SLOT_OST_STATUS
));
147 aml_append(method
, aml_acquire(ctrl_lock
, 0xFFFF));
148 aml_append(method
, aml_store(aml_to_integer(slot_arg0
),
150 aml_append(method
, aml_store(aml_arg(1), ost_evt
));
151 aml_append(method
, aml_store(aml_arg(2), ost_status
));
152 aml_append(method
, aml_release(ctrl_lock
));
154 aml_append(mem_ctrl_dev
, method
);
156 aml_append(pci_scope
, mem_ctrl_dev
);
157 aml_append(ctx
, pci_scope
);