summaryrefslogtreecommitdiffstats
path: root/src/soc/intel/xeon_sp/spr/soc_util.c
blob: 344fa5b3399c1de850a90948cea64f6fecbdcfa9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/* SPDX-License-Identifier: GPL-2.0-only */

#include <assert.h>
#include <device/device.h>
#include <device/pci.h>
#include <hob_cxlnode.h>
#include <intelblocks/cpulib.h>
#include <soc/msr.h>
#include <soc/numa.h>
#include <soc/pci_devs.h>
#include <soc/soc_util.h>
#include <soc/util.h>
#include <stdlib.h>
#include <string.h>
#include <pc80/mc146818rtc.h>

const EWL_PRIVATE_DATA *get_ewl_hob(void)
{
	size_t hob_size;
	static const EWL_PRIVATE_DATA *hob;
	const uint8_t ewl_id_hob_guid[16] = FSP_HOB_EWLID_GUID;

	if (hob != NULL)
		return hob;

	hob = fsp_find_extension_hob_by_guid(ewl_id_hob_guid, &hob_size);
	assert(hob != NULL && hob_size != 0);
	return hob;
}

const SYSTEM_INFO_VAR *get_system_info_hob(void)
{
	size_t hob_size;
	static const SYSTEM_INFO_VAR *hob;
	const uint8_t system_info_hob_guid[16] = FSP_HOB_SYSTEMINFO_GUID;

	if (hob != NULL)
		return hob;

	hob = fsp_find_extension_hob_by_guid(system_info_hob_guid, &hob_size);
	assert(hob != NULL && hob_size != 0);
	return hob;
}

const struct SystemMemoryMapHob *get_system_memory_map(void)
{
	size_t hob_size;
	const uint8_t mem_hob_guid[16] = FSP_SYSTEM_MEMORYMAP_HOB_GUID;
	const struct SystemMemoryMapHob **memmap_addr;

	memmap_addr = (const struct SystemMemoryMapHob **)fsp_find_extension_hob_by_guid(
		mem_hob_guid, &hob_size);
	/* hob_size is the size of the 8-byte address not the hob data */
	assert(memmap_addr != NULL && hob_size != 0);
	/* assert the pointer to the hob is not NULL */
	assert(*memmap_addr != NULL);

	return *memmap_addr;
}

const struct SystemMemoryMapElement *get_system_memory_map_elment(uint8_t *num)
{
	const struct SystemMemoryMapHob *hob = get_system_memory_map();
	if (!hob)
		return NULL;

	*num = hob->numberEntries;
	return hob->Element;
}

bool is_pcie_iio_stack_res(const STACK_RES *res)
{
	return res->Personality == TYPE_UBOX_IIO;
}

bool is_ubox_stack_res(const STACK_RES *res)
{
	return res->Personality == TYPE_UBOX;
}

bool is_ioat_iio_stack_res(const STACK_RES *res)
{
	return res->Personality == TYPE_DINO;
}

/*
 * Given a stack resource, figure out whether the corresponding stack has
 * CXL device.
 * It goes through pds (proximity domains) structure to see if there is any
 * generic initiator has device with bus # falls between bus base and
 * bus limit.
 */
bool is_iio_cxl_stack_res(const STACK_RES *res)
{
	for (uint8_t i = 0; i < pds.num_pds; i++) {
		if (pds.pds[i].pd_type == PD_TYPE_PROCESSOR)
			continue;

		uint32_t bus = PCI_BDF(pds.pds[i].dev) >> 20;
		if (bus >= res->BusBase && bus <= res->BusLimit)
			return true;
	}

	return false;
}

const CXL_NODE_SOCKET *get_cxl_node(void)
{
	size_t hob_size;
	static const CXL_NODE_SOCKET *hob;
	static bool hob_check = 0;
	const uint8_t fsp_hob_cxl_node_socket_guid[16] = FSP_HOB_CXLNODE_GUID;

	if (hob_check == 1)
		return hob;

	hob = fsp_find_extension_hob_by_guid(fsp_hob_cxl_node_socket_guid, &hob_size);
	hob_check = 1;
	if (hob == NULL || hob_size == 0)
		printk(BIOS_DEBUG,
		       "FSP_HOB_CXLNODE_GUID not found: CXL may not be installed\n");
	return hob;
}

uint8_t get_cxl_node_count(void)
{
	const CXL_NODE_SOCKET *hob = get_cxl_node();
	uint8_t count = 0;

	if (hob != NULL) {
		for (uint8_t skt_id = 0; skt_id < MAX_SOCKET; skt_id++)
			count += hob[skt_id].CxlNodeCount;
	}

	return count;
}

uint32_t get_socket_stack_busno(uint32_t socket, uint32_t stack)
{
	const IIO_UDS *hob = get_iio_uds();

	assert(socket < CONFIG_MAX_SOCKET && stack < MAX_LOGIC_IIO_STACK);

	return hob->PlatformData.IIO_resource[socket].StackRes[stack].BusBase;
}

uint32_t get_ubox_busno(uint32_t socket, uint8_t offset)
{
	const IIO_UDS *hob = get_iio_uds();

	assert(socket < CONFIG_MAX_SOCKET);
	for (int stack = 0; stack < MAX_LOGIC_IIO_STACK; ++stack) {
		if (hob->PlatformData.IIO_resource[socket].StackRes[stack].Personality
		    == TYPE_UBOX)
			return (hob->PlatformData.IIO_resource[socket].StackRes[stack].BusBase
				+ offset);
	}
	die("Unable to locate UBOX BUS NO");
}

uint32_t get_socket_ubox_busno(uint32_t socket)
{
	return get_ubox_busno(socket, UNCORE_BUS_1);
}

void bios_done_msr(void *unused)
{
	msr_t msr = rdmsr(MSR_BIOS_DONE);
	if (!(msr.lo & XEON_SP_ENABLE_IA_UNTRUSTED)) { /* if already locked skip update */
		msr.lo |= XEON_SP_ENABLE_IA_UNTRUSTED;
		wrmsr(MSR_BIOS_DONE, msr);
	}
}

void soc_set_mrc_cold_boot_flag(bool cold_boot_required)
{
	uint8_t mrc_status = cmos_read(CMOS_OFFSET_MRC_STATUS);
	uint8_t new_mrc_status = (mrc_status & 0xfe) | cold_boot_required;
	printk(BIOS_SPEW, "MRC status: 0x%02x want 0x%02x\n", mrc_status, new_mrc_status);
	if (new_mrc_status != mrc_status)
		cmos_write(new_mrc_status, CMOS_OFFSET_MRC_STATUS);

}