]>
Commit | Line | Data |
---|---|---|
30bd0cf4 IM |
1 | /* |
2 | * Memory hotplug AML code of DSDT ACPI table | |
3 | * | |
4 | * Copyright (C) 2015 Red Hat Inc | |
5 | * | |
6 | * Author: Igor Mammedov <[email protected]> | |
7 | * | |
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. | |
10 | */ | |
11 | ||
12 | #include <stdbool.h> | |
13 | #include "hw/acpi/memory_hotplug.h" | |
14 | #include "include/hw/acpi/pc-hotplug.h" | |
15 | #include "hw/boards.h" | |
16 | ||
17 | void build_memory_hotplug_aml(Aml *ctx, uint32_t nr_mem, | |
18 | uint16_t io_base, uint16_t io_len) | |
19 | { | |
b2344f3e IM |
20 | Aml *ifctx; |
21 | Aml *method; | |
30bd0cf4 IM |
22 | Aml *pci_scope; |
23 | Aml *mem_ctrl_dev; | |
24 | ||
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)); | |
28 | { | |
e8f9db49 | 29 | Aml *one = aml_int(1); |
b2344f3e | 30 | Aml *zero = aml_int(0); |
b9840122 IM |
31 | Aml *ret_val = aml_local(0); |
32 | Aml *slot_arg0 = aml_arg(0); | |
b2344f3e | 33 | Aml *slots_nr = aml_name(stringify(MEMORY_SLOTS_NUMBER)); |
e8f9db49 IM |
34 | Aml *ctrl_lock = aml_name(stringify(MEMORY_SLOT_LOCK)); |
35 | Aml *slot_selector = aml_name(stringify(MEMORY_SLOT_SLECTOR)); | |
b2344f3e IM |
36 | |
37 | method = aml_method("_STA", 0, AML_NOTSERIALIZED); | |
38 | ifctx = aml_if(aml_equal(slots_nr, zero)); | |
39 | { | |
40 | aml_append(ifctx, aml_return(zero)); | |
41 | } | |
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); | |
12fdadb5 IM |
46 | |
47 | aml_append(mem_ctrl_dev, aml_mutex(stringify(MEMORY_SLOT_LOCK), 0)); | |
e8f9db49 IM |
48 | |
49 | method = aml_method(stringify(MEMORY_SLOT_SCAN_METHOD), 0, | |
50 | AML_NOTSERIALIZED); | |
51 | { | |
52 | Aml *else_ctx; | |
53 | Aml *while_ctx; | |
54 | Aml *idx = aml_local(0); | |
55 | Aml *eject_req = aml_int(3); | |
56 | Aml *dev_chk = aml_int(1); | |
57 | ||
58 | ifctx = aml_if(aml_equal(slots_nr, zero)); | |
59 | { | |
60 | aml_append(ifctx, aml_return(zero)); | |
61 | } | |
62 | aml_append(method, ifctx); | |
63 | ||
64 | aml_append(method, aml_store(zero, idx)); | |
65 | aml_append(method, aml_acquire(ctrl_lock, 0xFFFF)); | |
66 | /* build AML that: | |
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 | |
70 | * slot status. | |
71 | */ | |
72 | while_ctx = aml_while(aml_lless(idx, slots_nr)); | |
73 | { | |
74 | Aml *ins_evt = aml_name(stringify(MEMORY_SLOT_INSERT_EVENT)); | |
75 | Aml *rm_evt = aml_name(stringify(MEMORY_SLOT_REMOVE_EVENT)); | |
76 | ||
77 | aml_append(while_ctx, aml_store(idx, slot_selector)); | |
78 | ifctx = aml_if(aml_equal(ins_evt, one)); | |
79 | { | |
80 | aml_append(ifctx, | |
81 | aml_call2(stringify(MEMORY_SLOT_NOTIFY_METHOD), | |
82 | idx, dev_chk)); | |
83 | aml_append(ifctx, aml_store(one, ins_evt)); | |
84 | } | |
85 | aml_append(while_ctx, ifctx); | |
86 | ||
87 | else_ctx = aml_else(); | |
88 | ifctx = aml_if(aml_equal(rm_evt, one)); | |
89 | { | |
90 | aml_append(ifctx, | |
91 | aml_call2(stringify(MEMORY_SLOT_NOTIFY_METHOD), | |
92 | idx, eject_req)); | |
93 | aml_append(ifctx, aml_store(one, rm_evt)); | |
94 | } | |
95 | aml_append(else_ctx, ifctx); | |
96 | aml_append(while_ctx, else_ctx); | |
97 | ||
98 | aml_append(while_ctx, aml_add(idx, one, idx)); | |
99 | } | |
100 | aml_append(method, while_ctx); | |
101 | aml_append(method, aml_release(ctrl_lock)); | |
102 | aml_append(method, aml_return(one)); | |
103 | } | |
104 | aml_append(mem_ctrl_dev, method); | |
b9840122 IM |
105 | |
106 | method = aml_method(stringify(MEMORY_SLOT_STATUS_METHOD), 1, | |
107 | AML_NOTSERIALIZED); | |
108 | { | |
109 | Aml *slot_enabled = aml_name(stringify(MEMORY_SLOT_ENABLED)); | |
110 | ||
111 | aml_append(method, aml_store(zero, ret_val)); | |
112 | aml_append(method, aml_acquire(ctrl_lock, 0xFFFF)); | |
113 | aml_append(method, | |
114 | aml_store(aml_to_integer(slot_arg0), slot_selector)); | |
115 | ||
116 | ifctx = aml_if(aml_equal(slot_enabled, one)); | |
117 | { | |
118 | aml_append(ifctx, aml_store(aml_int(0xF), ret_val)); | |
119 | } | |
120 | aml_append(method, ifctx); | |
121 | ||
122 | aml_append(method, aml_release(ctrl_lock)); | |
123 | aml_append(method, aml_return(ret_val)); | |
124 | } | |
125 | aml_append(mem_ctrl_dev, method); | |
30bd0cf4 IM |
126 | } |
127 | aml_append(pci_scope, mem_ctrl_dev); | |
128 | aml_append(ctx, pci_scope); | |
129 | } |