blob: cb7fe1daf1b53b3b1a05206e962062a710beb471 [file] [log] [blame]
Jonathan Zhangd80e6f22023-01-25 11:35:03 -08001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <acpi/acpigen.h>
4#include <arch/smp/mpspec.h>
Felix Held97439ec2023-06-05 19:30:23 +02005#include <arch/vga.h>
Jonathan Zhangd80e6f22023-01-25 11:35:03 -08006#include <assert.h>
7#include <cbmem.h>
8#include <cpu/intel/turbo.h>
9#include <device/mmio.h>
10#include <device/pci.h>
11#include <intelblocks/acpi.h>
12#include <intelblocks/cpulib.h>
13#include <intelblocks/pmclib.h>
14#include <soc/acpi.h>
15#include <soc/iomap.h>
16#include <soc/msr.h>
17#include <soc/pci_devs.h>
18#include <soc/pm.h>
19#include <soc/soc_util.h>
20#include <soc/util.h>
21#include <hob_iiouds.h>
22
23int soc_madt_sci_irq_polarity(int sci)
24{
25 if (sci >= 20)
26 return MP_IRQ_POLARITY_LOW;
27 else
28 return MP_IRQ_POLARITY_HIGH;
29}
30
31uint32_t soc_read_sci_irq_select(void)
32{
33 /* PMC controller is hidden - hence PWRMBASE can't be accessbile using PCI cfg space */
34 uintptr_t pmc_bar = PCH_PWRM_BASE_ADDRESS;
35 return read32((void *)pmc_bar + PMC_ACPI_CNT);
36}
37
38void soc_fill_fadt(acpi_fadt_t *fadt)
39{
40 const uint16_t pmbase = ACPI_BASE_ADDRESS;
41
42 fadt->FADT_MinorVersion = 1;
43 fadt->pm_tmr_blk = pmbase + PM1_TMR;
44 fadt->pm_tmr_len = 4;
45 /* Clear flags set by common/block/acpi/acpi.c acpi_fill_fadt() */
46 fadt->flags &= ~ACPI_FADT_SEALED_CASE;
47
48 fadt->preferred_pm_profile = PM_ENTERPRISE_SERVER;
49 fadt->pm2_cnt_blk = pmbase + PM2_CNT;
50 fadt->pm2_cnt_len = 1;
Jonathan Zhangd80e6f22023-01-25 11:35:03 -080051
Kyösti Mälkki88decca2023-04-28 07:04:34 +030052 /* PM Extended Registers */
53 fill_fadt_extended_pm_io(fadt);
Jonathan Zhangd80e6f22023-01-25 11:35:03 -080054}
55
Patrick Rudolph6e6832d2023-04-04 09:37:30 +020056static void create_dsdt_iou_pci_resource(uint8_t socket, uint8_t stack, const STACK_RES *ri,
57 bool stack_enabled)
Jonathan Zhangd80e6f22023-01-25 11:35:03 -080058{
59 /*
60 Stacks 0 (TYPE_UBOX_IIO)
61 Scope: PC<socket><stack>, ResourceTemplate: P0RS
62 Stacks 1 .. 5 (TYPE_UBOX_IIO)
63 Scope: PC<socket><stack>, ResourceTemplate: RBRS
64 */
Arthur Heymanscd6fed22022-12-08 17:27:11 +010065 /* write _CRS scope */
Jonathan Zhangd80e6f22023-01-25 11:35:03 -080066 char tres[16];
Arthur Heymanscd6fed22022-12-08 17:27:11 +010067 snprintf(tres, sizeof(tres), "\\_SB.PC%d%X", socket, stack);
68 acpigen_write_scope(tres);
69 acpigen_write_name("_CRS");
Jonathan Zhangd80e6f22023-01-25 11:35:03 -080070
71 printk(BIOS_DEBUG, "\tCreating ResourceTemplate %s for socket: %d, stack: %d\n", tres,
72 socket, stack);
73
74 acpigen_write_resourcetemplate_header();
75
Jonathan Zhangd80e6f22023-01-25 11:35:03 -080076 /* Bus Resource */
77 if (stack_enabled) {
78 /* For stack with CXL device, the PCIe bus resource is BusBase only. */
79 if (is_iio_cxl_stack_res(ri))
80 acpigen_resource_word(2, 0xc, 0, 0, ri->BusBase, ri->BusBase, 0x0, 1);
81 else
82 acpigen_resource_word(2, 0xc, 0, 0, ri->BusBase, ri->BusLimit, 0x0,
83 (ri->BusLimit - ri->BusBase + 1));
84 } else {
85 acpigen_resource_word(2, 0, 0, 0, 0, 0, 0, 0);
86 }
87
88 /* Additional IO resources on socket 0 bus 0 */
89 if (socket == 0 && stack == 0) {
90 /* ACPI 6.4.2.5 I/O Port Descriptor */
91 acpigen_write_io16(0xCF8, 0xCFF, 0x1, 0x8, 1);
92
93 /* IO decode CF8-CFF */
94 acpigen_resource_word(1, 0xc, 0x3, 0, 0x0000, 0x03AF, 0, 0x03B0);
95 acpigen_resource_word(1, 0xc, 0x3, 0, 0x03E0, 0x0CF7, 0, 0x0918);
96 acpigen_resource_word(1, 0xc, 0x3, 0, 0x03B0, 0x03BB, 0, 0x000C);
97 acpigen_resource_word(1, 0xc, 0x3, 0, 0x03C0, 0x03DF, 0, 0x0020);
98 }
99
100 /* IO resource */
101 if (stack_enabled) {
102 acpigen_resource_word(1, 0xc, 0x3, 0, ri->PciResourceIoBase,
103 ri->PciResourceIoLimit, 0x0,
104 (ri->PciResourceIoLimit - ri->PciResourceIoBase + 1));
105
106 /* Additional Mem32 resources on socket 0 bus 0 */
107 if (socket == 0 && stack == 0) {
Felix Held97439ec2023-06-05 19:30:23 +0200108 acpigen_resource_dword(0, 0xc, 3, 0, VGA_MMIO_BASE,
109 VGA_MMIO_LIMIT, 0x0, VGA_MMIO_SIZE);
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800110 acpigen_resource_dword(0, 0xc, 1, 0, SPI_BASE_ADDRESS,
111 (SPI_BASE_ADDRESS + SPI_BASE_SIZE - 1), 0x0,
112 SPI_BASE_SIZE);
113 }
114
115 /* Mem32 resource */
116 acpigen_resource_dword(
117 0, 0xc, 1, 0, ri->PciResourceMem32Base, ri->PciResourceMem32Limit, 0x0,
118 (ri->PciResourceMem32Limit - ri->PciResourceMem32Base + 1));
119
120 /* Mem64 resource */
121 acpigen_resource_qword(
122 0, 0xc, 1, 0, ri->PciResourceMem64Base, ri->PciResourceMem64Limit, 0x0,
123 (ri->PciResourceMem64Limit - ri->PciResourceMem64Base + 1));
124 } else {
125 /* Zeroed IO resource */
126 acpigen_resource_word(1, 0, 3, 0, 0, 0, 0, 0);
127
128 /* Zeroed Mem32 resource */
129 acpigen_resource_dword(0, 0, 1, 0, 0, 0, 0, 0);
130
131 /* Zeroed Mem64 resource */
132 acpigen_resource_dword(0, 0, 1, 0, 0, 0, 0, 0);
133 }
134
135 acpigen_write_resourcetemplate_footer();
Arthur Heymanscd6fed22022-12-08 17:27:11 +0100136 acpigen_pop_len();
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800137}
138
Patrick Rudolph6e6832d2023-04-04 09:37:30 +0200139static void create_dsdt_iou_cxl_resource(uint8_t socket, uint8_t stack, const STACK_RES *ri, bool stack_enabled)
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800140{
141 /*
142 Stacks 1 .. 5 (TYPE_UBOX_IIO)
143 Scope: CX<socket><stack>, ResourceTemplate: RBRS
144 */
Arthur Heymanscd6fed22022-12-08 17:27:11 +0100145 /* write _CRS scope */
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800146 char tres[16];
Arthur Heymanscd6fed22022-12-08 17:27:11 +0100147 snprintf(tres, sizeof(tres), "\\_SB.CX%d%X", socket, stack);
148 acpigen_write_scope(tres);
149 acpigen_write_name("_CRS");
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800150
151 printk(BIOS_DEBUG, "\tCreating ResourceTemplate %s for socket: %d, stack: %d\n", tres,
152 socket, stack);
153
154 acpigen_write_resourcetemplate_header();
155
Patrick Rudolph6e6832d2023-04-04 09:37:30 +0200156 if (stack_enabled) {
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800157 /* bus resource, from (BusBase + 1) to BusLimit */
158 acpigen_resource_word(2, 0xc, 0, 0, ri->BusBase + 1, ri->BusLimit, 0x0,
159 (ri->BusLimit - ri->BusBase));
160
161 /* IO resource */
162 acpigen_resource_word(1, 0xc, 0x3, 0, ri->IoBase, ri->PciResourceIoBase - 1,
163 0x0, ri->PciResourceIoBase - ri->IoBase);
164
165 /* Mem32 resource */
166 acpigen_resource_dword(0, 0xc, 1, 0, ri->Mmio32Base,
167 ri->PciResourceMem32Base - 1, 0x0,
168 ri->PciResourceMem32Base - ri->Mmio32Base);
169
170 /* Mem64 resource */
171 acpigen_resource_qword(0, 0xc, 1, 0, ri->Mmio64Base,
172 ri->PciResourceMem64Base - 1, 0x0,
173 ri->PciResourceMem64Base - ri->Mmio64Base);
174 } else {
175 /* bus resource, from (BusBase + 1) to BusLimit */
176 acpigen_resource_word(2, 0, 0, 0, 0, 0, 0, 0);
177
178 /* IO resource */
179 acpigen_resource_word(1, 0, 3, 0, 0, 0, 0, 0);
180
181 /* Mem32 resource */
182 acpigen_resource_dword(0, 0, 1, 0, 0, 0, 0, 0);
183
184 /* Mem64 resource */
185 acpigen_resource_qword(0, 0, 1, 0, 0, 0, 0, 0);
186 }
187
188 acpigen_write_resourcetemplate_footer();
Arthur Heymanscd6fed22022-12-08 17:27:11 +0100189 acpigen_pop_len();
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800190}
191
Patrick Rudolph6e6832d2023-04-04 09:37:30 +0200192static void create_dsdt_dino_resource(uint8_t socket, uint8_t stack, const STACK_RES *ri, bool stack_enabled)
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800193{
Arthur Heymans550f55e2022-08-24 14:44:26 +0200194 if (!stack_enabled)
195 return;
196
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800197 /*
198 Stacks 8 .. B (TYPE_DINO)
199 Scope: DI<socket><stack> for DINO, ResourceTemplate: DT
200 Scope: CP<socket><stack> for CPM (i.e., QAT), ResourceTemplate: MT
201 Scope: HQ<socket><stack> for HQM (i.e., DLB), ResourceTemplate: HT
202 */
203
204 enum {
205 DSDT_DINO = 0,
206 DSDT_CPM,
207 DSDT_HQM,
208 DSDT_CPM1,
209 DSDT_HQM1
210 };
211 uint8_t rlist[] = {DSDT_DINO, DSDT_CPM, DSDT_HQM, DSDT_CPM1, DSDT_HQM1};
212
213 for (int i = 0; i < ARRAY_SIZE(rlist); ++i) {
214 uint8_t bus_base, bus_limit;
215 uint64_t mem64_base, mem64_limit;
216 char tres[16];
217
218 /* Note, This allocates the resources in a different order than
219 * coreboot (DINO base is last). This causes the kernel to
220 * reallocate the DINO BARs.
221 * TODO: Use the resource settings from coreboot */
222 if (rlist[i] == DSDT_DINO) {
223 bus_base = ri->BusBase;
224 bus_limit = ri->BusBase;
225 mem64_base = ri->PciResourceMem64Base + CPM_MMIO_SIZE + HQM_MMIO_SIZE
226 + CPM_MMIO_SIZE + HQM_MMIO_SIZE;
227 mem64_limit = ri->PciResourceMem64Limit;
Arthur Heymanscd6fed22022-12-08 17:27:11 +0100228 snprintf(tres, sizeof(tres), "\\_SB.DI%d%X", socket, stack);
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800229 } else if (rlist[i] == DSDT_CPM) {
230 bus_base = ri->BusBase + CPM_BUS_OFFSET;
231 bus_limit = bus_base + CPM_RESERVED_BUS;
232 mem64_base = ri->PciResourceMem64Base;
233 mem64_limit = mem64_base + CPM_MMIO_SIZE - 1;
Arthur Heymanscd6fed22022-12-08 17:27:11 +0100234 snprintf(tres, sizeof(tres), "\\_SB.PM%d%X", socket, stack);
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800235 } else if (rlist[i] == DSDT_HQM) {
236 bus_base = ri->BusBase + HQM_BUS_OFFSET;
237 bus_limit = bus_base + HQM_RESERVED_BUS;
238 mem64_base = ri->PciResourceMem64Base + CPM_MMIO_SIZE;
239 mem64_limit = mem64_base + HQM_MMIO_SIZE - 1;
Arthur Heymanscd6fed22022-12-08 17:27:11 +0100240 snprintf(tres, sizeof(tres), "\\_SB.HQ%d%X", socket, stack);
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800241 } else if (rlist[i] == DSDT_CPM1) {
242 bus_base = ri->BusBase + CPM1_BUS_OFFSET;
243 bus_limit = bus_base + CPM_RESERVED_BUS;
244 mem64_base = ri->PciResourceMem64Base + CPM_MMIO_SIZE + HQM_MMIO_SIZE;
245 mem64_limit = mem64_base + CPM_MMIO_SIZE - 1;
Arthur Heymanscd6fed22022-12-08 17:27:11 +0100246 snprintf(tres, sizeof(tres), "\\_SB.PN%d%X", socket, stack);
247 } else {
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800248 bus_base = ri->BusBase + HQM1_BUS_OFFSET;
249 bus_limit = bus_base + HQM_RESERVED_BUS;
250 mem64_base = ri->PciResourceMem64Base + CPM_MMIO_SIZE + HQM_MMIO_SIZE
251 + CPM_MMIO_SIZE;
252 mem64_limit = mem64_base + HQM_MMIO_SIZE - 1;
Arthur Heymanscd6fed22022-12-08 17:27:11 +0100253 snprintf(tres, sizeof(tres), "\\_SB.HR%d%X", socket, stack);
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800254 }
255
Arthur Heymans550f55e2022-08-24 14:44:26 +0200256 /* Note, some SKU doesn't provide CPM1 and HQM1 and owns smaller bus ranges
257 accordingly*/
258 if (bus_limit > ri->BusLimit)
259 continue;
260
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800261 printk(BIOS_DEBUG,
262 "\tCreating Dino ResourceTemplate %s for socket: %d, "
263 "stack: %d\n bus_base:0x%x, bus_limit:0x%x\n",
264 tres, socket, stack, bus_base, bus_limit);
265
Arthur Heymanscd6fed22022-12-08 17:27:11 +0100266 acpigen_write_scope(tres);
267 acpigen_write_name("_CRS");
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800268 acpigen_write_resourcetemplate_header();
269
Arthur Heymans550f55e2022-08-24 14:44:26 +0200270 acpigen_resource_word(2, 0xc, 0, 0, bus_base, bus_limit, 0x0,
271 (bus_limit - bus_base + 1));
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800272
Arthur Heymans550f55e2022-08-24 14:44:26 +0200273 /* Mem32 resource */
274 if (rlist[i] == DSDT_DINO)
275 acpigen_resource_dword(0, 0xc, 1, 0, ri->PciResourceMem32Base,
276 ri->PciResourceMem32Limit, 0x0,
277 (ri->PciResourceMem32Limit
278 - ri->PciResourceMem32Base + 1));
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800279
Arthur Heymans550f55e2022-08-24 14:44:26 +0200280 /* Mem64 resource */
281 acpigen_resource_qword(0, 0xc, 1, 0, mem64_base, mem64_limit, 0,
282 (mem64_limit - mem64_base + 1));
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800283
284 acpigen_write_resourcetemplate_footer();
Arthur Heymanscd6fed22022-12-08 17:27:11 +0100285 acpigen_pop_len();
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800286 }
287}
288
Patrick Rudolph6e6832d2023-04-04 09:37:30 +0200289static void create_dsdt_ubox_resource(uint8_t socket, uint8_t stack, const STACK_RES *ri, bool stack_enabled)
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800290{
291 /*
292 Stacks D .. E (TYPE_UBOX)
293 Scope: UC/UD<socket><0..1> for UBOX[1-2], ResourceTemplate: UT/UU
294 */
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800295 for (int i = 0; i < 2; ++i) {
296 char tres[16];
Arthur Heymanscd6fed22022-12-08 17:27:11 +0100297 /* write _CRS scope */
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800298 if (i == 0)
Arthur Heymanscd6fed22022-12-08 17:27:11 +0100299 snprintf(tres, sizeof(tres), "\\_SB.UC%d%X", socket, stack);
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800300 else
Arthur Heymanscd6fed22022-12-08 17:27:11 +0100301 snprintf(tres, sizeof(tres), "\\_SB.UD%d%X", socket, stack);
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800302
303 printk(BIOS_DEBUG, "\tCreating ResourceTemplate %s for socket: %d, stack: %d\n",
304 tres, socket, stack);
305
Arthur Heymanscd6fed22022-12-08 17:27:11 +0100306 acpigen_write_scope(tres);
307 acpigen_write_name("_CRS");
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800308 acpigen_write_resourcetemplate_header();
309
Patrick Rudolph6e6832d2023-04-04 09:37:30 +0200310 if (!stack_enabled)
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800311 acpigen_resource_word(2, 0, 0, 0, 0, 0, 0, 0);
312 else if (i == 0)
313 acpigen_resource_word(2, 0xc, 0, 0, ri->BusBase, ri->BusBase, 0x0, 1);
314 else
315 acpigen_resource_word(2, 0xc, 0, 0, ri->BusBase + 1, ri->BusBase + 1,
316 0x0, 1);
317
318 acpigen_write_resourcetemplate_footer();
Arthur Heymanscd6fed22022-12-08 17:27:11 +0100319 acpigen_pop_len();
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800320 }
321}
322
323
324/*
325 * Add a DSDT ACPI Name field for STACK enable setting.
326 * This is retrieved by the device _STA defined in iiostack.asl
327 */
Patrick Rudolph6e6832d2023-04-04 09:37:30 +0200328static void create_dsdt_stack_sta(uint8_t socket, uint8_t stack, const STACK_RES *ri, bool stack_enabled)
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800329{
330 char stack_sta[16];
331 snprintf(stack_sta, sizeof(stack_sta), "ST%d%X", socket, stack);
332
Patrick Rudolph6e6832d2023-04-04 09:37:30 +0200333 if (!stack_enabled)
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800334 acpigen_write_name_integer(stack_sta, ACPI_STATUS_DEVICE_ALL_OFF);
335 else
336 acpigen_write_name_integer(stack_sta, ACPI_STATUS_DEVICE_ALL_ON);
337}
338
Arthur Heymanscd6fed22022-12-08 17:27:11 +0100339void uncore_fill_ssdt(const struct device *device)
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800340{
Patrick Rudolph6e6832d2023-04-04 09:37:30 +0200341 bool stack_enabled;
342
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800343 /* Only add RTxx entries once. */
344 if (device->bus->secondary != 0)
345 return;
346
347 /*
348 Write stack scope - this needs to match RP ACPI scopes.
349 Stacks 0 (TYPE_UBOX_IIO)
350 Scope: PC<socket><stack>, ResourceTemplate: P0RS
351 Stacks 1 .. 5 (TYPE_UBOX_IIO)
352 Scope: PC<socket><stack> & CX<socket><stack>, ResourceTemplate: RBRS
353 Stacks 8 .. B (TYPE_DINO)
354 Scope: DI<socket><stack> for DINO, ResourceTemplate: RBRS
355 Scope: CP<socket><stack> for CPM (i.e., QAT), ResourceTemplate: RBRS
356 Scope: HQ<socket><stack> for HQM (i.e., DLB), ResourceTemplate: RBRS
357 Stacks D .. E (TYPE_UBOX)
358 Scope: UC<socket><0..1> for UBOX[1-2], ResourceTemplate: UNRS
359 */
360
361 printk(BIOS_DEBUG, "%s device: %s\n", __func__, dev_path(device));
362
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800363 /* The _CSR generation must match SPR iiostack.asl. */
364 const IIO_UDS *hob = get_iio_uds();
Patrick Rudolph6e6832d2023-04-04 09:37:30 +0200365 /* Iterate over CONFIG_MAX_SOCKET to keep ASL templates and DSDT injection in sync */
366 for (uint8_t socket = 0; socket < CONFIG_MAX_SOCKET; ++socket) {
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800367 for (int stack = 0; stack < MAX_LOGIC_IIO_STACK; ++stack) {
368 const STACK_RES *ri =
369 &hob->PlatformData.IIO_resource[socket].StackRes[stack];
370
Patrick Rudolphb096d622023-07-14 17:18:18 +0200371 stack_enabled = soc_cpu_is_enabled(socket) &&
Patrick Rudolph6e6832d2023-04-04 09:37:30 +0200372 ri->Personality < TYPE_RESERVED;
373
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800374 printk(BIOS_DEBUG, "%s processing socket: %d, stack: %d, type: %d\n",
375 __func__, socket, stack, ri->Personality);
376
377 if (stack <= IioStack5) { // TYPE_UBOX_IIO
Patrick Rudolph6e6832d2023-04-04 09:37:30 +0200378 create_dsdt_iou_pci_resource(socket, stack, ri, stack_enabled);
Shuo Liu27ce0ec2024-01-19 21:21:21 +0800379 if (is_iio_cxl_stack_res(ri))
380 create_dsdt_iou_cxl_resource(socket, stack, ri,
381 stack_enabled);
Patrick Rudolph6e6832d2023-04-04 09:37:30 +0200382 create_dsdt_stack_sta(socket, stack, ri, stack_enabled);
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800383 } else if (stack >= IioStack8 && stack <= IioStack11) { // TYPE_DINO
Patrick Rudolph6e6832d2023-04-04 09:37:30 +0200384 create_dsdt_dino_resource(socket, stack, ri, stack_enabled);
385 create_dsdt_stack_sta(socket, stack, ri, stack_enabled);
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800386 } else if (stack == IioStack13) { // TYPE_UBOX
Patrick Rudolph6e6832d2023-04-04 09:37:30 +0200387 create_dsdt_ubox_resource(socket, stack, ri, stack_enabled);
388 create_dsdt_stack_sta(socket, stack, ri, stack_enabled);
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800389 }
390 }
391 }
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800392}
393
394/* TODO: See if we can use the common generate_p_state_entries */
395void soc_power_states_generation(int core, int cores_per_package)
396{
397 int ratio_min, ratio_max, ratio_turbo, ratio_step;
398 int coord_type, power_max, power_unit, num_entries;
399 int ratio, power, clock, clock_max;
400 msr_t msr;
401
402 /* Determine P-state coordination type from MISC_PWR_MGMT[0] */
403 msr = rdmsr(MSR_MISC_PWR_MGMT);
404 if (msr.lo & MISC_PWR_MGMT_EIST_HW_DIS)
405 coord_type = SW_ANY;
406 else
407 coord_type = HW_ALL;
408
409 /* Get bus ratio limits and calculate clock speeds */
410 msr = rdmsr(MSR_PLATFORM_INFO);
411 ratio_min = (msr.hi >> (40 - 32)) & 0xff; /* Max Efficiency Ratio */
412
413 /* Determine if this CPU has configurable TDP */
414 if (cpu_config_tdp_levels()) {
415 /* Set max ratio to nominal TDP ratio */
416 msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
417 ratio_max = msr.lo & 0xff;
418 } else {
419 /* Max Non-Turbo Ratio */
420 ratio_max = (msr.lo >> 8) & 0xff;
421 }
422 clock_max = ratio_max * CONFIG_CPU_BCLK_MHZ;
423
424 /* Calculate CPU TDP in mW */
425 msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
426 power_unit = 2 << ((msr.lo & 0xf) - 1);
427 msr = rdmsr(MSR_PKG_POWER_SKU);
428 power_max = ((msr.lo & 0x7fff) / power_unit) * 1000;
429
430 /* Write _PCT indicating use of FFixedHW */
431 acpigen_write_empty_PCT();
432
433 /* Write _PPC with no limit on supported P-state */
434 acpigen_write_PPC_NVS();
435
436 /* Write PSD indicating configured coordination type */
437 acpigen_write_PSD_package(core, 1, coord_type);
438
439 /* Add P-state entries in _PSS table */
440 acpigen_write_name("_PSS");
441
442 /* Determine ratio points */
443 ratio_step = PSS_RATIO_STEP;
444 num_entries = ((ratio_max - ratio_min) / ratio_step) + 1;
445 if (num_entries > PSS_MAX_ENTRIES) {
446 ratio_step += 1;
447 num_entries = ((ratio_max - ratio_min) / ratio_step) + 1;
448 }
449
450 /* P[T] is Turbo state if enabled */
451 if (get_turbo_state() == TURBO_ENABLED) {
452 /* _PSS package count including Turbo */
453 acpigen_write_package(num_entries + 2);
454
455 msr = rdmsr(MSR_TURBO_RATIO_LIMIT);
456 ratio_turbo = msr.lo & 0xff;
457
458 /* Add entry for Turbo ratio */
459 acpigen_write_PSS_package(clock_max + 1, /* MHz */
460 power_max, /* mW */
461 PSS_LATENCY_TRANSITION, /* lat1 */
462 PSS_LATENCY_BUSMASTER, /* lat2 */
463 ratio_turbo << 8, /* control */
464 ratio_turbo << 8); /* status */
465 } else {
466 /* _PSS package count without Turbo */
467 acpigen_write_package(num_entries + 1);
468 }
469
470 /* First regular entry is max non-turbo ratio */
471 acpigen_write_PSS_package(clock_max, /* MHz */
472 power_max, /* mW */
473 PSS_LATENCY_TRANSITION, /* lat1 */
474 PSS_LATENCY_BUSMASTER, /* lat2 */
475 ratio_max << 8, /* control */
476 ratio_max << 8); /* status */
477
478 /* Generate the remaining entries */
479 for (ratio = ratio_min + ((num_entries - 1) * ratio_step); ratio >= ratio_min;
480 ratio -= ratio_step) {
481
482 /* Calculate power at this ratio */
483 power = common_calculate_power_ratio(power_max, ratio_max, ratio);
484 clock = ratio * CONFIG_CPU_BCLK_MHZ;
485 // clock = 1;
486 acpigen_write_PSS_package(clock, /* MHz */
487 power, /* mW */
488 PSS_LATENCY_TRANSITION, /* lat1 */
489 PSS_LATENCY_BUSMASTER, /* lat2 */
490 ratio << 8, /* control */
491 ratio << 8); /* status */
492 }
493
494 /* Fix package length */
495 acpigen_pop_len();
496}
497
498unsigned long xeonsp_acpi_create_madt_lapics(unsigned long current)
499{
500 struct device *cpu;
501 uint8_t num_cpus = 0;
502
503 for (cpu = all_devices; cpu; cpu = cpu->next) {
504 if ((cpu->path.type != DEVICE_PATH_APIC)
505 || (cpu->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER)) {
506 continue;
507 }
508 if (!cpu->enabled)
509 continue;
Kyösti Mälkki2e9f0d32023-04-07 23:05:46 +0300510 current = acpi_create_madt_one_lapic(current, num_cpus, cpu->path.apic.apic_id);
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800511 num_cpus++;
512 }
513
514 return current;
515}
516
517unsigned long acpi_fill_cedt(unsigned long current)
518{
519 const IIO_UDS *hob = get_iio_uds();
520 union uid {
521 uint32_t data;
522 struct {
523 uint8_t byte0;
524 uint8_t byte1;
525 uint8_t byte2;
526 uint8_t byte3;
527 };
528 } cxl_uid;
529 u32 cxl_ver;
530 u64 base;
531
532 cxl_uid.byte0 = 'C';
533 cxl_uid.byte1 = 'X';
534 /* Loop through all sockets and stacks, add CHBS for each CXL IIO stack */
Patrick Rudolphac028572023-07-14 17:44:33 +0200535 for (uint8_t socket = 0, iio = 0; iio < hob->PlatformData.numofIIO; ++socket) {
536 if (!soc_cpu_is_enabled(socket))
537 continue;
538 iio++;
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800539 for (int x = 0; x < MAX_LOGIC_IIO_STACK; ++x) {
Patrick Rudolphac028572023-07-14 17:44:33 +0200540 const STACK_RES *ri;
541 ri = &hob->PlatformData.IIO_resource[socket].StackRes[x];
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800542 if (!is_iio_cxl_stack_res(ri))
543 continue;
544 /* uid needs to match with ACPI CXL device ID, eg. acpi/iiostack.asl */
Patrick Rudolphac028572023-07-14 17:44:33 +0200545 cxl_uid.byte2 = socket + '0';
Jonathan Zhangd80e6f22023-01-25 11:35:03 -0800546 cxl_uid.byte3 = x + '0';
547 cxl_ver = ACPI_CEDT_CHBS_CXL_VER_1_1;
548 base = ri->Mmio32Base; /* DP RCRB base */
549 current += acpi_create_cedt_chbs((acpi_cedt_chbs_t *)current,
550 cxl_uid.data, cxl_ver, base);
551 }
552 }
553
554 return current;
555}