1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <commonlib/bsd/helpers.h>
4 #include <cpu/x86/save_state.h>
5 #include <cpu/x86/smm.h>
8 /* These are weakly linked such that platforms can link only the save state
9 ops they actually require. */
10 const struct smm_save_state_ops
*legacy_ops __weak
= NULL
;
11 const struct smm_save_state_ops
*em64t100_ops __weak
= NULL
;
12 const struct smm_save_state_ops
*em64t101_ops __weak
= NULL
;
13 const struct smm_save_state_ops
*amd64_ops __weak
= NULL
;
15 static const struct smm_save_state_ops
*save_state
;
17 /* Returns -1 on failure, 0 on success */
18 static int init_save_state(void)
20 const uint32_t revision
= smm_revision();
22 static bool initialized
= false;
23 const struct smm_save_state_ops
*save_state_ops
[] = {
33 for (i
= 0; i
< ARRAY_SIZE(save_state_ops
); i
++) {
34 const struct smm_save_state_ops
*ops
= save_state_ops
[i
];
40 for (rev
= ops
->revision_table
; *rev
!= SMM_REV_INVALID
; rev
++)
41 if (*rev
== revision
) {
51 int get_apmc_node(u8 cmd
)
53 if (init_save_state())
56 return save_state
->apmc_node(cmd
);
59 int get_save_state_reg(const enum cpu_reg reg
, const int node
, void *out
, const uint8_t length
)
61 if (init_save_state())
64 if (node
> CONFIG_MAX_CPUS
)
67 return save_state
->get_reg(reg
, node
, out
, length
);
70 int set_save_state_reg(const enum cpu_reg reg
, const int node
, void *in
, const uint8_t length
)
72 if (init_save_state())
75 if (node
> CONFIG_MAX_CPUS
)
78 return save_state
->set_reg(reg
, node
, in
, length
);