1 /* SPDX-License-Identifier: GPL-2.0-or-later */
4 #include <console/console.h>
5 #include <cpu/x86/mtrr.h>
7 #include <mode_switch.h>
11 struct fsp_notify_phase_data
{
12 enum fsp_notify_phase notify_phase
;
14 uint8_t post_code_before
;
15 uint8_t post_code_after
;
16 enum timestamp_id timestamp_before
;
17 enum timestamp_id timestamp_after
;
20 static const struct fsp_notify_phase_data notify_data
[] = {
22 .notify_phase
= AFTER_PCI_ENUM
,
23 .skip
= !CONFIG(USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM
),
24 .post_code_before
= POST_FSP_NOTIFY_BEFORE_ENUMERATE
,
25 .post_code_after
= POST_FSP_NOTIFY_AFTER_ENUMERATE
,
26 .timestamp_before
= TS_FSP_BEFORE_ENUMERATE
,
27 .timestamp_after
= TS_FSP_AFTER_ENUMERATE
,
30 .notify_phase
= READY_TO_BOOT
,
31 .skip
= !CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT
),
32 .post_code_before
= POST_FSP_NOTIFY_BEFORE_FINALIZE
,
33 .post_code_after
= POST_FSP_NOTIFY_AFTER_FINALIZE
,
34 .timestamp_before
= TS_FSP_BEFORE_FINALIZE
,
35 .timestamp_after
= TS_FSP_AFTER_FINALIZE
,
38 .notify_phase
= END_OF_FIRMWARE
,
39 .skip
= !CONFIG(USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE
),
40 .post_code_before
= POST_FSP_NOTIFY_BEFORE_END_OF_FIRMWARE
,
41 .post_code_after
= POST_FSP_NOTIFY_AFTER_END_OF_FIRMWARE
,
42 .timestamp_before
= TS_FSP_BEFORE_END_OF_FIRMWARE
,
43 .timestamp_after
= TS_FSP_AFTER_END_OF_FIRMWARE
,
47 static const struct fsp_notify_phase_data
*get_notify_phase_data(enum fsp_notify_phase phase
)
49 for (size_t i
= 0; i
< ARRAY_SIZE(notify_data
); i
++) {
50 if (notify_data
[i
].notify_phase
== phase
)
51 return ¬ify_data
[i
];
53 die("Unknown FSP notify phase %u\n", phase
);
56 static void fsp_notify(enum fsp_notify_phase phase
)
58 const struct fsp_notify_phase_data
*data
= get_notify_phase_data(phase
);
59 struct fsp_notify_params notify_params
= { .phase
= phase
};
60 fsp_notify_fn fspnotify
;
64 printk(BIOS_INFO
, "coreboot skipped calling FSP notify phase: %08x.\n", phase
);
68 if (!fsps_hdr
.notify_phase_entry_offset
)
69 die("Notify_phase_entry_offset is zero!\n");
71 fspnotify
= (void *)(uintptr_t)(fsps_hdr
.image_base
+
72 fsps_hdr
.notify_phase_entry_offset
);
73 fsp_before_debug_notify(fspnotify
, ¬ify_params
);
75 timestamp_add_now(data
->timestamp_before
);
76 post_code(data
->post_code_before
);
78 if (ENV_X86_64
&& CONFIG(PLATFORM_USES_FSP2_X86_32
))
79 ret
= protected_mode_call_1arg(fspnotify
, (uintptr_t)¬ify_params
);
81 ret
= fspnotify(¬ify_params
);
83 timestamp_add_now(data
->timestamp_after
);
84 post_code(data
->post_code_after
);
86 fsp_debug_after_notify(ret
);
88 /* Handle any errors returned by FspNotify */
89 fsp_handle_reset(ret
);
90 if (ret
!= FSP_SUCCESS
)
91 die("FspNotify returned with error 0x%08x!\n", ret
);
93 /* Allow the platform to run something after FspNotify */
94 platform_fsp_notify_status(phase
);
97 static void fsp_notify_dummy(void *arg
)
99 enum fsp_notify_phase phase
= (uint32_t)(uintptr_t)arg
;
104 if (phase
== READY_TO_BOOT
)
105 fsp_notify(END_OF_FIRMWARE
);
108 BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE
, BS_ON_ENTRY
, fsp_notify_dummy
, (void *)AFTER_PCI_ENUM
);
109 BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD
, BS_ON_EXIT
, fsp_notify_dummy
, (void *)READY_TO_BOOT
);
110 BOOT_STATE_INIT_ENTRY(BS_OS_RESUME
, BS_ON_ENTRY
, fsp_notify_dummy
, (void *)READY_TO_BOOT
);
112 __weak
void platform_fsp_notify_status(enum fsp_notify_phase phase
)