diff options
author | Arthur Heymans <arthur@aheymans.xyz> | 2023-07-14 19:42:40 +0200 |
---|---|---|
committer | Martin L Roth <gaumless@gmail.com> | 2023-12-06 18:32:58 +0000 |
commit | adee6a694509d61fef01a4a885842299f89b40e0 (patch) | |
tree | d9d039ed7cd5a404aff9e9e8bc63888400dc9074 /src/vendorcode | |
parent | 76e499319b0318ea685042f51d05ded696818973 (diff) |
vendorcode/amd/opensil: Add initial setup and API calls
- First a console is set up for opensil.
- After that a region in CBMEM is reserved and passed to opensil which
will use it as a buffer for input/output information.
- Finally opensil is called and the return value handled.
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Change-Id: I4833a5a86034a13e6be102a6b68c3bb54108bc9a
Reviewed-on: https://review.coreboot.org/c/coreboot/+/76515
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
Diffstat (limited to 'src/vendorcode')
-rw-r--r-- | src/vendorcode/amd/opensil/genoa_poc/Makefile.inc | 1 | ||||
-rw-r--r-- | src/vendorcode/amd/opensil/genoa_poc/ramstage.c | 89 |
2 files changed, 90 insertions, 0 deletions
diff --git a/src/vendorcode/amd/opensil/genoa_poc/Makefile.inc b/src/vendorcode/amd/opensil/genoa_poc/Makefile.inc index c5742b5992..6bfd95e264 100644 --- a/src/vendorcode/amd/opensil/genoa_poc/Makefile.inc +++ b/src/vendorcode/amd/opensil/genoa_poc/Makefile.inc @@ -7,6 +7,7 @@ romstage-y += opensil_console.c romstage-y += romstage.c ramstage-y += opensil_console.c +ramstage-y += ramstage.c $(obj)/romstage/vendorcode/amd/opensil/genoa_poc/opensil_console.o: CFLAGS_romstage += -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas $(obj)/romstage/vendorcode/amd/opensil/genoa_poc/romstage.o: CFLAGS_romstage += -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas diff --git a/src/vendorcode/amd/opensil/genoa_poc/ramstage.c b/src/vendorcode/amd/opensil/genoa_poc/ramstage.c new file mode 100644 index 0000000000..bde09f1e9e --- /dev/null +++ b/src/vendorcode/amd/opensil/genoa_poc/ramstage.c @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <amdblocks/reset.h> +#include <bootstate.h> +#include <cbmem.h> +#include <xSIM-api.h> +#include "opensil_console.h" + +static void SIL_STATUS_report(const char *function, const int status) +{ + const int log_level = status == SilPass ? BIOS_DEBUG : BIOS_ERR; + const char *error_string = "Unkown error"; + + const struct error_string_entry { + SIL_STATUS status; + const char *string; + } errors[] = { + {SilPass, "SilPass"}, + {SilUnsupportedHardware, "SilUnsupportedHardware"}, + {SilUnsupported, "SilUnsupported"}, + {SilInvalidParameter, "SilInvalidParameter"}, + {SilAborted, "SilAborted"}, + {SilOutOfResources, "SilOutOfResources"}, + {SilNotFound, "SilNotFound"}, + {SilOutOfBounds, "SilOutOfBounds"}, + {SilDeviceError, "SilDeviceError"}, + {SilResetRequestColdImm, "SilResetRequestColdImm"}, + {SilResetRequestColdDef, "SilResetRequestColdDef"}, + {SilResetRequestWarmImm, "SilResetRequestWarmImm"}, + {SilResetRequestWarmDef, "SilResetRequestWarmDef"}, + }; + + int i; + for (i = 0; i < ARRAY_SIZE(errors); i++) { + if (errors[i].status == status) + error_string = errors[i].string; + } + printk(log_level, "%s returned %d (%s)\n", function, status, error_string); +} + +static void setup_opensil(void *unused) +{ + const SIL_STATUS debug_ret = SilDebugSetup(HostDebugService); + SIL_STATUS_report("SilDebugSetup", debug_ret); + const size_t mem_req = xSimQueryMemoryRequirements(); + void *buf = cbmem_add(CBMEM_ID_AMD_OPENSIL, mem_req); + assert(buf); + /* We run all openSIL timepoints in the same stage so using TP1 as argument is fine. */ + const SIL_STATUS assign_mem_ret = xSimAssignMemoryTp1(buf, mem_req); + SIL_STATUS_report("xSimAssignMemory", assign_mem_ret); +} + +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_ENTRY, setup_opensil, NULL); + +static void opensil_entry(void *timepoint) +{ + SIL_STATUS ret; + SIL_TIMEPOINT tp = (uintptr_t)timepoint; + + switch (tp) { + case SIL_TP1: + ret = InitializeSiTp1(); + break; + case SIL_TP2: + ret = InitializeSiTp2(); + break; + case SIL_TP3: + ret = InitializeSiTp3(); + break; + default: + printk(BIOS_ERR, "Unknown opensil timepoint\n"); + return; + } + char opensil_function[16]; + snprintf(opensil_function, sizeof(opensil_function), "InitializeSiTp%d", tp); + SIL_STATUS_report(opensil_function, ret); + if (ret == SilResetRequestColdImm || ret == SilResetRequestColdDef) { + printk(BIOS_INFO, "openSil requested a cold reset"); + do_cold_reset(); + } else if (ret == SilResetRequestWarmImm || ret == SilResetRequestWarmDef) { + printk(BIOS_INFO, "openSil requested a warm reset"); + do_warm_reset(); + } +} + +/* TODO: look into calling these functions from some SoC device operations instead of using + * BOOT_STATE_INIT_ENTRY */ +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_EXIT, opensil_entry, (void *)SIL_TP1); +/* TODO add other timepoints later. Are they NOOP? */ |