From 77b17098b41cd2b61b70db6d503243f3bac4786b Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Tue, 18 Jun 2019 17:29:21 +1000 Subject: Move FSP-specific VPD functionality to platforms/ibm-fsp/ Signed-off-by: Stewart Smith --- core/init.c | 1 - core/vpd.c | 143 ----------------------------------- hw/phb3.c | 3 +- hw/phb4.c | 3 +- include/platform.h | 8 ++ include/vpd.h | 3 - platforms/ibm-fsp/Makefile.inc | 2 +- platforms/ibm-fsp/common.c | 2 + platforms/ibm-fsp/firenze.c | 1 + platforms/ibm-fsp/fsp-vpd.c | 165 +++++++++++++++++++++++++++++++++++++++++ platforms/ibm-fsp/ibm-fsp.h | 5 ++ platforms/ibm-fsp/zz.c | 1 + 12 files changed, 187 insertions(+), 150 deletions(-) create mode 100644 platforms/ibm-fsp/fsp-vpd.c diff --git a/core/init.c b/core/init.c index c2b7b70..48533a0 100644 --- a/core/init.c +++ b/core/init.c @@ -1201,7 +1201,6 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt) pci_nvram_init(); - preload_io_vpd(); preload_capp_ucode(); start_preload_kernel(); diff --git a/core/vpd.c b/core/vpd.c index 054a708..f1b6495 100644 --- a/core/vpd.c +++ b/core/vpd.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #define CHECK_SPACE(_p, _n, _e) (((_e) - (_p)) >= (_n)) @@ -147,145 +146,3 @@ const void *vpd_find(const void *vpd, size_t vpd_size, p = vpd_find_keyword(p, rec_sz, keyword, sz); return p; } - -static void *vpd_lid; -static size_t vpd_lid_size; -static uint32_t vpd_lid_no; - -/* Helper to load a VPD LID. Pass a ptr to the corresponding LX keyword */ -static void *vpd_lid_preload(const uint8_t *lx) -{ - int rc; - - if (!fsp_present()) - return NULL; - - /* Now this is a guess game as we don't have the info from the - * pHyp folks. But basically, it seems to boil down to loading - * a LID whose name is 0x80e000yy where yy is the last 2 digits - * of the LX record in hex. - * - * [ Correction: After a chat with some folks, it looks like it's - * actually 4 digits, though the lid number is limited to fff - * so we weren't far off. ] - * - * For safety, we look for a matching LX record in an LXRn - * (n = lxrn argument) or in VINI if lxrn=0xff - */ - vpd_lid_no = 0x80e00000 | ((lx[6] & 0xf) << 8) | lx[7]; - - /* We don't quite know how to get to the LID directory so - * we don't know the size. Let's allocate 16K. All the VPD LIDs - * I've seen so far are much smaller. - */ -#define VPD_LID_MAX_SIZE 0x4000 - vpd_lid = malloc(VPD_LID_MAX_SIZE); - - if (!vpd_lid) { - prerror("VPD: Failed to allocate memory for LID\n"); - return NULL; - } - - /* Adjust LID number for flash side */ - vpd_lid_no = fsp_adjust_lid_side(vpd_lid_no); - printf("VPD: Trying to load VPD LID 0x%08x...\n", vpd_lid_no); - - vpd_lid_size = VPD_LID_MAX_SIZE; - - /* Load it from the FSP */ - rc = fsp_preload_lid(vpd_lid_no, vpd_lid, &vpd_lid_size); - if (rc) { - prerror("VPD: Error %d loading VPD LID\n", rc); - goto fail; - } - - return vpd_lid; - fail: - free(vpd_lid); - return NULL; -} - -void vpd_iohub_load(struct dt_node *hub_node) -{ - uint8_t record[4] = { 'L','X','R','0' }; /* not null terminated */ - const void *valid_lx; - uint8_t lx_size; - int r; - const uint32_t *p; - const uint8_t *lx; - unsigned int lxrn; - - if (!fsp_present()) - return; - - p = dt_prop_get_def(hub_node, "ibm,vpd-lx-info", NULL); - if (!p) - return; - - lxrn = p[0]; - lx = (const char *)&p[1]; - - /* verify the lid preload has started */ - if (!vpd_lid || !vpd_lid_no) { - prlog(PR_WARNING, "VPD: WARNING: Unable to load VPD lid"); - return; - } - - r = fsp_wait_lid_loaded(vpd_lid_no); - - if (r) - goto fail; - - /* Validate it */ - if (lxrn < 9) - record[3] = '0' + lxrn; - else - memcpy(record, "VINI", 4); - - valid_lx = vpd_find(vpd_lid, vpd_lid_size, record, "LX", &lx_size); - if (!valid_lx || lx_size != 8) { - prerror("VPD: Cannot find validation LX record\n"); - goto fail; - } - if (memcmp(valid_lx, lx, 8) != 0) { - prerror("VPD: LX record mismatch !\n"); - goto fail; - } - - printf("VPD: Loaded %zu bytes\n", vpd_lid_size); - - dt_add_property(hub_node, "ibm,io-vpd", vpd_lid, vpd_lid_size); - free(vpd_lid); - return; - -fail: - free(vpd_lid); - vpd_lid = NULL; - prerror("VPD: Failed to load VPD LID\n"); - return; -} - -void vpd_preload(struct dt_node *hub_node) -{ - const uint32_t *p; - const char *lxr; - - p = dt_prop_get_def(hub_node, "ibm,vpd-lx-info", NULL); - if (!p) - return; - - lxr = (const char *)&p[1]; - - vpd_lid = vpd_lid_preload(lxr); -} - -void preload_io_vpd(void) -{ - const struct dt_property *prop; - - prop = dt_find_property(dt_root, "ibm,io-vpd"); - if (!prop) { - /* LX VPD Lid not already loaded */ - vpd_preload(dt_root); - } -} diff --git a/hw/phb3.c b/hw/phb3.c index 3042c3e..f2792b6 100644 --- a/hw/phb3.c +++ b/hw/phb3.c @@ -4741,7 +4741,8 @@ static void phb3_create(struct dt_node *np) prop = dt_find_property(dt_root, "ibm,io-vpd"); if (!prop) { /* LX VPD Lid not already loaded */ - vpd_iohub_load(dt_root); + if (platform.vpd_iohub_load) + platform.vpd_iohub_load(dt_root); } /* Allocate the SkiBoot internal in-memory tables for the PHB */ diff --git a/hw/phb4.c b/hw/phb4.c index 9a38dc7..94726ef 100644 --- a/hw/phb4.c +++ b/hw/phb4.c @@ -5672,7 +5672,8 @@ static void phb4_create(struct dt_node *np) prop = dt_find_property(dt_root, "ibm,io-vpd"); if (!prop) { /* LX VPD Lid not already loaded */ - vpd_iohub_load(dt_root); + if (platform.vpd_iohub_load) + platform.vpd_iohub_load(dt_root); } /* Obtain informatin about the PHB from the hardware directly */ diff --git a/include/platform.h b/include/platform.h index 1a12718..966f704 100644 --- a/include/platform.h +++ b/include/platform.h @@ -77,6 +77,8 @@ struct platform_ocapi { * brick 1 lanes */ }; +struct dt_node; + /* * Each platform can provide a set of hooks * that can affect the generic code @@ -250,6 +252,12 @@ struct platform { */ void (*op_display)(enum op_severity sev, enum op_module mod, uint16_t code); + + /* + * VPD load. + * Currently FSP specific. + */ + void (*vpd_iohub_load)(struct dt_node *hub_node); }; extern struct platform __platforms_start; diff --git a/include/vpd.h b/include/vpd.h index 6889455..bf66a12 100644 --- a/include/vpd.h +++ b/include/vpd.h @@ -39,9 +39,6 @@ bool vpd_valid(const void *vvpd, size_t vpd_size); /* Add model property to dt_root */ void add_dtb_model(void); -void vpd_iohub_load(struct dt_node *hub_node); -void vpd_preload(struct dt_node *hub_node); - #define VPD_LOAD_LXRN_VINI 0xff diff --git a/platforms/ibm-fsp/Makefile.inc b/platforms/ibm-fsp/Makefile.inc index 1b751e5..fc8f033 100644 --- a/platforms/ibm-fsp/Makefile.inc +++ b/platforms/ibm-fsp/Makefile.inc @@ -1,6 +1,6 @@ SUBDIRS += $(PLATDIR)/ibm-fsp -IBM_FSP_OBJS = common.o lxvpd.o hostservices.o \ +IBM_FSP_OBJS = common.o lxvpd.o hostservices.o fsp-vpd.o \ firenze.o firenze-pci.o zz.o IBM_FSP = $(PLATDIR)/ibm-fsp/built-in.a $(IBM_FSP): $(IBM_FSP_OBJS:%=$(PLATDIR)/ibm-fsp/%) diff --git a/platforms/ibm-fsp/common.c b/platforms/ibm-fsp/common.c index 97fba33..3bcb458 100644 --- a/platforms/ibm-fsp/common.c +++ b/platforms/ibm-fsp/common.c @@ -170,6 +170,8 @@ void ibm_fsp_init(void) if (proc_gen >= proc_gen_p9) prd_init(); + + preload_io_vpd(); } void ibm_fsp_exit(void) diff --git a/platforms/ibm-fsp/firenze.c b/platforms/ibm-fsp/firenze.c index 578bd15..43f1af9 100644 --- a/platforms/ibm-fsp/firenze.c +++ b/platforms/ibm-fsp/firenze.c @@ -228,4 +228,5 @@ DECLARE_PLATFORM(firenze) = { .sensor_read = ibm_fsp_sensor_read, .terminate = ibm_fsp_terminate, .op_display = fsp_op_display, + .vpd_iohub_load = vpd_iohub_load, }; diff --git a/platforms/ibm-fsp/fsp-vpd.c b/platforms/ibm-fsp/fsp-vpd.c new file mode 100644 index 0000000..9871b32 --- /dev/null +++ b/platforms/ibm-fsp/fsp-vpd.c @@ -0,0 +1,165 @@ +/* Copyright 2013-2019 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include "ibm-fsp.h" + +static void *vpd_lid; +static size_t vpd_lid_size; +static uint32_t vpd_lid_no; + + +void vpd_iohub_load(struct dt_node *hub_node) +{ + uint8_t record[4] = { 'L','X','R','0' }; /* not null terminated */ + const void *valid_lx; + uint8_t lx_size; + int r; + const uint32_t *p; + const uint8_t *lx; + unsigned int lxrn; + + if (!fsp_present()) + return; + + p = dt_prop_get_def(hub_node, "ibm,vpd-lx-info", NULL); + if (!p) + return; + + lxrn = p[0]; + lx = (const char *)&p[1]; + + /* verify the lid preload has started */ + if (!vpd_lid || !vpd_lid_no) { + prlog(PR_WARNING, "VPD: WARNING: Unable to load VPD lid"); + return; + } + + r = fsp_wait_lid_loaded(vpd_lid_no); + + if (r) + goto fail; + + /* Validate it */ + if (lxrn < 9) + record[3] = '0' + lxrn; + else + memcpy(record, "VINI", 4); + + valid_lx = vpd_find(vpd_lid, vpd_lid_size, record, "LX", &lx_size); + if (!valid_lx || lx_size != 8) { + prerror("VPD: Cannot find validation LX record\n"); + goto fail; + } + if (memcmp(valid_lx, lx, 8) != 0) { + prerror("VPD: LX record mismatch !\n"); + goto fail; + } + + printf("VPD: Loaded %zu bytes\n", vpd_lid_size); + + dt_add_property(hub_node, "ibm,io-vpd", vpd_lid, vpd_lid_size); + free(vpd_lid); + return; + +fail: + free(vpd_lid); + vpd_lid = NULL; + prerror("VPD: Failed to load VPD LID\n"); + return; +} + +/* Helper to load a VPD LID. Pass a ptr to the corresponding LX keyword */ +static void *vpd_lid_preload(const uint8_t *lx) +{ + int rc; + + if (!fsp_present()) + return NULL; + + /* Now this is a guess game as we don't have the info from the + * pHyp folks. But basically, it seems to boil down to loading + * a LID whose name is 0x80e000yy where yy is the last 2 digits + * of the LX record in hex. + * + * [ Correction: After a chat with some folks, it looks like it's + * actually 4 digits, though the lid number is limited to fff + * so we weren't far off. ] + * + * For safety, we look for a matching LX record in an LXRn + * (n = lxrn argument) or in VINI if lxrn=0xff + */ + vpd_lid_no = 0x80e00000 | ((lx[6] & 0xf) << 8) | lx[7]; + + /* We don't quite know how to get to the LID directory so + * we don't know the size. Let's allocate 16K. All the VPD LIDs + * I've seen so far are much smaller. + */ +#define VPD_LID_MAX_SIZE 0x4000 + vpd_lid = malloc(VPD_LID_MAX_SIZE); + + if (!vpd_lid) { + prerror("VPD: Failed to allocate memory for LID\n"); + return NULL; + } + + /* Adjust LID number for flash side */ + vpd_lid_no = fsp_adjust_lid_side(vpd_lid_no); + printf("VPD: Trying to load VPD LID 0x%08x...\n", vpd_lid_no); + + vpd_lid_size = VPD_LID_MAX_SIZE; + + /* Load it from the FSP */ + rc = fsp_preload_lid(vpd_lid_no, vpd_lid, &vpd_lid_size); + if (rc) { + prerror("VPD: Error %d loading VPD LID\n", rc); + goto fail; + } + + return vpd_lid; + fail: + free(vpd_lid); + return NULL; +} + +void vpd_preload(struct dt_node *hub_node) +{ + const uint32_t *p; + const char *lxr; + + p = dt_prop_get_def(hub_node, "ibm,vpd-lx-info", NULL); + if (!p) + return; + + lxr = (const char *)&p[1]; + + vpd_lid = vpd_lid_preload(lxr); +} + +void preload_io_vpd(void) +{ + const struct dt_property *prop; + + prop = dt_find_property(dt_root, "ibm,io-vpd"); + if (!prop) { + /* LX VPD Lid not already loaded */ + vpd_preload(dt_root); + } +} diff --git a/platforms/ibm-fsp/ibm-fsp.h b/platforms/ibm-fsp/ibm-fsp.h index 6c19978..5466775 100644 --- a/platforms/ibm-fsp/ibm-fsp.h +++ b/platforms/ibm-fsp/ibm-fsp.h @@ -43,4 +43,9 @@ extern void firenze_pci_setup_phb(struct phb *phb, extern void firenze_pci_get_slot_info(struct phb *phb, struct pci_device *pd); +/* VPD support */ +void vpd_iohub_load(struct dt_node *hub_node); +void vpd_preload(struct dt_node *hub_node); + + #endif /* __IBM_FSP_COMMON_H */ diff --git a/platforms/ibm-fsp/zz.c b/platforms/ibm-fsp/zz.c index c5ce01e..ac3e1c9 100644 --- a/platforms/ibm-fsp/zz.c +++ b/platforms/ibm-fsp/zz.c @@ -92,4 +92,5 @@ DECLARE_PLATFORM(zz) = { .ocapi = &zz_ocapi, .npu2_device_detect = npu2_i2c_presence_detect, .op_display = fsp_op_display, + .vpd_iohub_load = vpd_iohub_load, }; -- cgit v1.1