crossgcc: Upgrade CMake from 3.29.3 to 3.30.2
[coreboot.git] / src / vendorcode / amd / opensil / genoa_poc / memmap.c
blob6261ad026047d06b9770e6f37d5bd1dbb2a21e4b
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <bootstate.h>
4 #include <stdint.h>
5 #include <stdbool.h>
6 #include <SilCommon.h>
7 #include <Sil-api.h> // needed above ApobCmn.h
8 #include <ApobCmn.h>
9 #include <device/device.h>
10 #include <xPRF-api.h>
11 #include <cpu/amd/mtrr.h>
12 #include <cbmem.h>
13 #include <amdblocks/memmap.h>
15 #include "opensil.h"
17 static const char *hole_info_type(MEMORY_HOLE_TYPES type)
19 const struct hole_type {
20 MEMORY_HOLE_TYPES type;
21 const char *string;
22 } types[] = {
23 {UMA, "UMA"},
24 {MMIO, "MMIO"},
25 {PrivilegedDRAM, "PrivilegedDRAM"},
26 {Reserved1TbRemap, "Reserved1TbRemap"},
27 {ReservedSLink, "ReservedSLink"},
28 {ReservedSLinkAlignment, "ReservedSLinkAlignment"},
29 {ReservedDrtm, "ReservedDrtm"},
30 {ReservedCvip, "ReservedCvip"},
31 {ReservedSmuFeatures, "ReservedSmuFeatures"},
32 {ReservedFwtpm, "ReservedFwtpm"},
33 {ReservedMpioC20, "ReservedMpioC20"},
34 {ReservedNbif, "ReservedNbif"},
35 {ReservedCxl, "ReservedCxl"},
36 {ReservedCxlAlignment, "ReservedCxlAlignment"},
37 {ReservedCpuTmr, "ReservedCpuTmr"},
38 {ReservedRasEinj, "ReservedRasEinj"},
39 {MaxMemoryHoleTypes, "MaxMemoryHoleTypes"},
42 int i;
43 for (i = 0; i < ARRAY_SIZE(types); i++)
44 if (type == types[i].type)
45 break;
46 if (i == ARRAY_SIZE(types))
47 return "Unknown type";
48 return types[i].string;
51 static uint64_t top_of_mem;
52 static uint32_t n_holes;
53 static MEMORY_HOLE_DESCRIPTOR *hole_info;
55 static void get_hole_info(void)
57 static bool done;
58 if (done)
59 return;
60 SIL_STATUS status = xPrfGetSystemMemoryMap(&n_holes, &top_of_mem, (void **)&hole_info);
61 SIL_STATUS_report("xPrfGetSystemMemoryMap", status);
62 // Make sure hole_info does not get initialized to something odd by xPRF on failure
63 if (status != SilPass)
64 hole_info = NULL;
65 done = true;
69 static void print_memory_holes(void *unused)
71 get_hole_info();
72 if (hole_info == NULL)
73 return;
75 printk(BIOS_DEBUG, "APOB: top of memory 0x%016llx\n", top_of_mem);
76 printk(BIOS_DEBUG, "The following holes are reported in APOB\n");
77 for (int hole = 0; hole < n_holes; hole++) {
78 printk(BIOS_DEBUG, " Base: 0x%016llx, Size: 0x%016llx, Type: %02d:%s\n",
79 hole_info[hole].Base, hole_info[hole].Size, hole_info[hole].Type,
80 hole_info_type(hole_info[hole].Type));
84 BOOT_STATE_INIT_ENTRY(BS_DEV_RESOURCES, BS_ON_ENTRY, print_memory_holes, NULL);
86 // This assumes holes are allocated
87 void add_opensil_memmap(struct device *dev, unsigned long *idx)
89 // Account for UMA and TSEG
90 const uint32_t mem_usable = cbmem_top();
91 const uint32_t top_mem = ALIGN_DOWN(get_top_of_mem_below_4gb(), 1 * MiB);
92 if (mem_usable != top_mem)
93 reserved_ram_from_to(dev, (*idx)++, mem_usable, top_mem);
95 // Check if we're done
96 if (top_of_mem <= 4ULL * GiB)
97 return;
99 // Holes in upper DRAM
100 // This assumes all the holes in upper DRAM are continuous
101 get_hole_info();
102 if (hole_info == NULL)
103 return;
104 uint64_t lowest_upper_hole_base = top_of_mem;
105 uint64_t highest_upper_hole_end = 4ULL * GiB;
106 for (int hole = 0; hole < n_holes; hole++) {
107 if (hole_info[hole].Type == MMIO)
108 continue;
109 if (hole_info[hole].Base < 4ULL * GiB)
110 continue;
111 lowest_upper_hole_base = MIN(lowest_upper_hole_base, hole_info[hole].Base);
112 highest_upper_hole_end = MAX(highest_upper_hole_end, hole_info[hole].Base + hole_info[hole].Size);
113 if (hole_info[hole].Type == UMA)
114 mmio_range(dev, (*idx)++, hole_info[hole].Base, hole_info[hole].Size);
115 else
116 reserved_ram_range(dev, (*idx)++, hole_info[hole].Base, hole_info[hole].Size);
119 ram_from_to(dev, (*idx)++, 4ULL * GiB, lowest_upper_hole_base);
121 // Do we need this?
122 if (top_of_mem > highest_upper_hole_end)
123 ram_from_to(dev, (*idx)++, highest_upper_hole_end, top_of_mem);