1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <boot/coreboot_tables.h>
4 #include <commonlib/coreboot_tables.h>
5 #include <drivers/option/cfr_frontend.h>
6 #include <intelblocks/pmclib.h>
15 static void update_rt_perf(const struct sm_object
*obj
, struct sm_object
*new)
17 const bool rt_perf
= get_emi_eeprom_vpd()->profile
== ATLAS_PROF_REALTIME_PERFORMANCE
;
22 if (obj
->kind
== SM_OBJ_BOOL
) {
23 new->sm_bool
.flags
= CFR_OPTFLAG_SUPPRESS
;
24 new->sm_bool
.default_value
= false;
25 } else if (obj
->kind
== SM_OBJ_ENUM
) {
26 new->sm_enum
.flags
= CFR_OPTFLAG_SUPPRESS
;
27 new->sm_enum
.default_value
= 0;
31 static void update_bad_profile(const struct sm_object
*obj
, struct sm_object
*new)
33 const bool pf_ok
= get_emi_eeprom_vpd()->profile
!= 0;
37 new->sm_comment
.flags
|= CFR_OPTFLAG_SUPPRESS
;
40 static void update_serial(const struct sm_object
*obj
, struct sm_object
*new)
42 new->sm_varchar
.default_value
= get_emi_eeprom_vpd()->serial_number
;
45 static void update_part_number(const struct sm_object
*obj
, struct sm_object
*new)
47 new->sm_varchar
.default_value
= get_emi_eeprom_vpd()->part_number
;
50 static void update_profile(const struct sm_object
*obj
, struct sm_object
*new)
52 new->sm_number
.default_value
= get_emi_eeprom_vpd()->profile
;
55 /* TODO: Suppress option if carrier board is known to not have a RTC battery */
56 static const struct sm_enum_value pwr_after_g3_values
[] = {
57 { "Power off (S5)", MAINBOARD_POWER_STATE_OFF
},
58 { "Power on (S0)", MAINBOARD_POWER_STATE_ON
},
59 /* No support for previous/last power state */
63 static const struct sm_object power_on_after_fail
= SM_DECLARE_ENUM({
64 .opt_name
= "power_on_after_fail",
65 .ui_name
= "Restore AC Power Loss",
66 .ui_helptext
= "Specify what to do when power is re-applied "
67 "after a power loss. This option has no effect "
68 "on systems without a RTC battery.",
69 .default_value
= CONFIG_MAINBOARD_POWER_FAILURE_STATE
,
70 .values
= pwr_after_g3_values
,
73 static const struct sm_enum_value primary_display_values
[] = {
75 { "CPU PEG dGPU", 1 },
76 { "PCH PCIe dGPU", 2 },
81 static const struct sm_object primary_display
= SM_DECLARE_ENUM({
82 .opt_name
= "primary_display",
83 .ui_name
= "Primary display device",
84 .ui_helptext
= "Specify which display device to use as primary.",
85 .default_value
= CONFIG(ONBOARD_VGA_IS_PRIMARY
) ? 0 : 3,
86 .values
= primary_display_values
,
89 static const struct sm_enum_value pkg_c_state_limit_values
[] = {
104 static const struct sm_object turbo_mode
= SM_DECLARE_BOOL({
105 .opt_name
= "turbo_mode",
106 .ui_name
= "Turbo Boost",
108 .default_value
= true,
111 static const struct sm_object vmx
= SM_DECLARE_BOOL({
113 .ui_name
= "Intel Virtualization Technology (VT-x)",
115 .default_value
= false,
118 static const struct sm_object vtd
= SM_DECLARE_BOOL({
120 .ui_name
= "Intel Virtualization Technology for Directed I/O (VT-d)",
122 .default_value
= false,
125 static const struct sm_object ibecc
= SM_DECLARE_BOOL({
127 .ui_name
= "In-Band ECC",
128 .ui_helptext
= "Specify whether In-Band error checking and "
129 "correction is to be enabled. Enabling this "
130 "option will reduce the amount of available "
131 "RAM because some memory is needed to store "
133 .default_value
= false,
136 static const struct sm_object serial_number
= SM_DECLARE_VARCHAR({
137 .flags
= CFR_OPTFLAG_READONLY
| CFR_OPTFLAG_VOLATILE
,
138 .opt_name
= "serial_number",
139 .ui_name
= "Serial Number",
140 }, WITH_CALLBACK(update_serial
));
142 static const struct sm_object part_number
= SM_DECLARE_VARCHAR({
143 .flags
= CFR_OPTFLAG_READONLY
| CFR_OPTFLAG_VOLATILE
,
144 .opt_name
= "part_number",
145 .ui_name
= "Part Number",
146 }, WITH_CALLBACK(update_part_number
));
148 static const struct sm_object bad_profile
= SM_DECLARE_COMMENT({
149 .flags
= CFR_OPTFLAG_READONLY
,
150 .ui_name
= "WARNING: Profile code is invalid",
151 }, WITH_CALLBACK(update_bad_profile
));
153 static const struct sm_object profile
= SM_DECLARE_NUMBER({
154 .flags
= CFR_OPTFLAG_READONLY
| CFR_OPTFLAG_VOLATILE
,
155 .opt_name
= "profile",
156 .ui_name
= "Profile code",
157 .ui_helptext
= "The profile code obtained from the EEPROM",
158 }, WITH_CALLBACK(update_profile
));
160 static const struct sm_object energy_eff_turbo
= SM_DECLARE_BOOL({
162 .opt_name
= "energy_eff_turbo",
163 .ui_name
= "Energy Efficient Turbo",
165 .default_value
= false,
166 }, WITH_CALLBACK(update_rt_perf
));
168 static const struct sm_object pkg_c_state_limit
= SM_DECLARE_ENUM({
170 .opt_name
= "pkg_c_state_limit",
171 .ui_name
= "Package C-state limit",
172 .ui_helptext
= "", /* TODO: write something */
173 .default_value
= 255,
174 .values
= pkg_c_state_limit_values
,
175 }, WITH_CALLBACK(update_rt_perf
));
177 #define NUM_PCIE_SSC_SETTINGS 21
178 static struct sm_enum_value pch_pm_pcie_pll_ssc_values
[] = {
179 [NUM_PCIE_SSC_SETTINGS
] = { "Auto", 0xff },
183 static void update_pll_ssc_values(const struct sm_object
*obj
, struct sm_object
*new)
185 for (size_t i
= 0; i
< NUM_PCIE_SSC_SETTINGS
; i
++) {
187 snprintf(buffer
, sizeof(buffer
), "%u.%u%%", i
/ 10, i
% 10);
188 pch_pm_pcie_pll_ssc_values
[i
].ui_name
= strdup(buffer
);
189 pch_pm_pcie_pll_ssc_values
[i
].value
= i
;
193 static const struct sm_object pch_pcie_pll_ssc
= SM_DECLARE_ENUM({
194 .opt_name
= "pch_pcie_pll_ssc",
195 .ui_name
= "PCH PCIe PLL Spread Spectrum Clocking",
197 .default_value
= 0xff,
198 .values
= pch_pm_pcie_pll_ssc_values
,
199 }, WITH_CALLBACK(update_pll_ssc_values
));
201 static const struct sm_object c_states
= SM_DECLARE_BOOL({
203 .opt_name
= "c_states",
204 .ui_name
= "CPU power states (C-states)",
205 .ui_helptext
= "Specify whether C-states are supported.",
206 .default_value
= true,
207 }, WITH_CALLBACK(update_rt_perf
));
209 static const struct sm_object hyper_threading
= SM_DECLARE_BOOL({
211 .opt_name
= "hyper_threading",
212 .ui_name
= "Hyper-Threading Technology",
214 .default_value
= true,
215 }, WITH_CALLBACK(update_rt_perf
));
217 static struct sm_obj_form cpu
= {
219 .obj_list
= (const struct sm_object
*[]) {
230 static struct sm_obj_form main
= {
232 .obj_list
= (const struct sm_object
*[]) {
237 &power_on_after_fail
,
246 static struct sm_obj_form
*sm_root
[] = {
253 * TODO: Writing this by hand is extremely tedious. Introducing a DSL
254 * (Domain-Specific Language) to describe options which is translated
255 * into code at build time may be the way to go. Maybe expand SCONFIG
256 * so that these can be devicetree options?
258 void lb_board(struct lb_header
*header
)
260 char *current
= (char *)lb_new_record(header
);
261 struct lb_cfr
*cfr_root
= (struct lb_cfr
*)current
;
263 cfr_write_setup_menu(cfr_root
, sm_root
);