From patchwork Fri Feb 10 09:04:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Lombard X-Patchwork-Id: 726445 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3vKTZ225mlz9s2G for ; Fri, 10 Feb 2017 20:05:46 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3vKTZ21MbGzDqJZ for ; Fri, 10 Feb 2017 20:05:46 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3vKTYF4kyhzDqGX for ; Fri, 10 Feb 2017 20:05:05 +1100 (AEDT) Received: from pps.filterd (m0098421.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id v1A8x3mP102961 for ; Fri, 10 Feb 2017 04:05:03 -0500 Received: from e06smtp08.uk.ibm.com (e06smtp08.uk.ibm.com [195.75.94.104]) by mx0a-001b2d01.pphosted.com with ESMTP id 28gxd2h4ea-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Fri, 10 Feb 2017 04:05:02 -0500 Received: from localhost by e06smtp08.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 10 Feb 2017 09:05:01 -0000 Received: from d06dlp03.portsmouth.uk.ibm.com (9.149.20.15) by e06smtp08.uk.ibm.com (192.168.101.138) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 10 Feb 2017 09:04:58 -0000 Received: from b06cxnps4076.portsmouth.uk.ibm.com (d06relay13.portsmouth.uk.ibm.com [9.149.109.198]) by d06dlp03.portsmouth.uk.ibm.com (Postfix) with ESMTP id 24BBA1B08067 for ; Fri, 10 Feb 2017 09:07:52 +0000 (GMT) Received: from d06av23.portsmouth.uk.ibm.com (d06av23.portsmouth.uk.ibm.com [9.149.105.59]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v1A94WTP9634290; Fri, 10 Feb 2017 09:04:32 GMT Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 93678A4065; Fri, 10 Feb 2017 09:04:28 +0000 (GMT) Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9320DA405D; Fri, 10 Feb 2017 09:04:27 +0000 (GMT) Received: from lombard-w520.ibm.com (unknown [9.164.182.111]) by d06av23.portsmouth.uk.ibm.com (Postfix) with ESMTP; Fri, 10 Feb 2017 09:04:27 +0000 (GMT) From: Christophe Lombard To: skiboot@lists.ozlabs.org, fbarrat@linux.vnet.ibm.com, imunsie@au1.ibm.com, andrew.donnellan@au1.ibm.com, christophe_lombard@fr.ibm.com Date: Fri, 10 Feb 2017 10:04:22 +0100 X-Mailer: git-send-email 2.7.4 In-Reply-To: <1486717462-5016-1-git-send-email-clombard@linux.vnet.ibm.com> References: <1486717462-5016-1-git-send-email-clombard@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 17021009-0032-0000-0000-0000071AA7E5 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17021009-0033-0000-0000-00002360D343 Message-Id: <1486717462-5016-5-git-send-email-clombard@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-02-10_03:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=2 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1612050000 definitions=main-1702100090 Subject: [Skiboot] [PATCH 4/4] capi: Load capp microcode for phb4 X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" CAPP microcode flash download and CAPP upload for PHB4. A new file 'capp.c' is created to receive common capp code for PHB3 and PHB4. Signed-off-by: Christophe Lombard Reviewed-by: Andrew Donnellan --- core/init.c | 2 +- hw/Makefile.inc | 2 +- hw/capp.c | 235 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/phb3.c | 212 ++++-------------------------------------------- hw/phb4.c | 15 ++++ include/capp.h | 18 ++++- include/skiboot.h | 3 +- 7 files changed, 283 insertions(+), 204 deletions(-) create mode 100644 hw/capp.c diff --git a/core/init.c b/core/init.c index 7bcb680..795746c 100644 --- a/core/init.c +++ b/core/init.c @@ -918,7 +918,7 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt) op_display(OP_LOG, OP_MOD_INIT, 0x0002); phb3_preload_vpd(); - phb3_preload_capp_ucode(); + preload_capp_ucode(); start_preload_kernel(); /* NX init */ diff --git a/hw/Makefile.inc b/hw/Makefile.inc index f2dc328..5a3fd39 100644 --- a/hw/Makefile.inc +++ b/hw/Makefile.inc @@ -6,7 +6,7 @@ HW_OBJS += nx.o nx-rng.o nx-crypto.o nx-842.o HW_OBJS += p7ioc.o p7ioc-inits.o p7ioc-phb.o HW_OBJS += phb3.o sfc-ctrl.o fake-rtc.o bt.o p8-i2c.o prd.o HW_OBJS += dts.o lpc-rtc.o npu.o npu-hw-procedures.o xive.o phb4.o -HW_OBJS += fake-nvram.o +HW_OBJS += fake-nvram.o capp.o HW=hw/built-in.o # FIXME hack this for now diff --git a/hw/capp.c b/hw/capp.c new file mode 100644 index 0000000..c7c359d --- /dev/null +++ b/hw/capp.c @@ -0,0 +1,235 @@ +/* Copyright 2013-2017 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 + +#define PHBERR(opal_id, chip_id, index, fmt, a...) \ + prlog(PR_ERR, "PHB#%04x[%d:%d]: " fmt, \ + opal_id, chip_id, \ + index, ## a) + +static struct { + uint32_t ec_level; + struct capp_lid_hdr *lid; + size_t size; + int load_result; +} capp_ucode_info = { 0, NULL, 0, false }; + +#define CAPP_UCODE_MAX_SIZE 0x20000 + +bool capp_ucode_loaded(struct proc_chip *chip, unsigned int index) +{ + return (chip->capp_ucode_loaded & (1 << index)); +} + +int preload_capp_ucode(void) +{ + struct dt_node *p; + struct proc_chip *chip; + uint32_t index; + uint64_t rc; + int ret; + + p = dt_find_compatible_node(dt_root, NULL, "ibm,power8-pbcq"); + + if (!p) { + p = dt_find_compatible_node(dt_root, NULL, "ibm,power9-pbcq"); + if (!p) { + printf("CAPI: WARNING: no compat thing found\n"); + return OPAL_SUCCESS; + } + } + + chip = get_chip(dt_get_chip_id(p)); + + rc = xscom_read_cfam_chipid(chip->id, &index); + if (rc) { + prerror("CAPP: Error reading cfam chip-id\n"); + ret = OPAL_HARDWARE; + return ret; + } + /* Keep ChipID and Major/Minor EC. Mask out the Location Code. */ + index = index & 0xf0fff; + + /* Assert that we're preloading */ + assert(capp_ucode_info.lid == NULL); + capp_ucode_info.load_result = OPAL_EMPTY; + + capp_ucode_info.ec_level = index; + + /* Is the ucode preloaded like for BML? */ + if (dt_has_node_property(p, "ibm,capp-ucode", NULL)) { + capp_ucode_info.lid = (struct capp_lid_hdr *)(u64) + dt_prop_get_u32(p, "ibm,capp-ucode"); + ret = OPAL_SUCCESS; + goto end; + } + /* If we successfully download the ucode, we leave it around forever */ + capp_ucode_info.size = CAPP_UCODE_MAX_SIZE; + capp_ucode_info.lid = malloc(CAPP_UCODE_MAX_SIZE); + if (!capp_ucode_info.lid) { + prerror("CAPP: Can't allocate space for ucode lid\n"); + ret = OPAL_NO_MEM; + goto end; + } + + printf("CAPI: Preloading ucode %x\n", capp_ucode_info.ec_level); + + ret = start_preload_resource(RESOURCE_ID_CAPP, index, + capp_ucode_info.lid, + &capp_ucode_info.size); + + if (ret != OPAL_SUCCESS) + prerror("CAPI: Failed to preload resource %d\n", ret); + +end: + return ret; +} + +static int64_t capp_lid_download(void) +{ + int64_t ret; + + if (capp_ucode_info.load_result != OPAL_EMPTY) + return capp_ucode_info.load_result; + + capp_ucode_info.load_result = wait_for_resource_loaded( + RESOURCE_ID_CAPP, + capp_ucode_info.ec_level); + + if (capp_ucode_info.load_result != OPAL_SUCCESS) { + prerror("CAPP: Error loading ucode lid. index=%x\n", + capp_ucode_info.ec_level); + ret = OPAL_RESOURCE; + free(capp_ucode_info.lid); + capp_ucode_info.lid = NULL; + goto end; + } + + ret = OPAL_SUCCESS; +end: + return ret; +} + +int64_t capp_load_ucode(unsigned int index, unsigned int chip_id, + unsigned int max_phb_index, u64 lidec, + uint32_t reg_offset, uint32_t opal_id, + uint64_t apc_master_addr, uint64_t apc_master_write, + uint64_t snp_array_addr, uint64_t snp_array_write) +{ + struct proc_chip *chip = get_chip(chip_id); + struct capp_ucode_lid *ucode; + struct capp_ucode_data *data; + struct capp_lid_hdr *lid; + uint64_t rc, val, addr; + uint32_t chunk_count, offset; + int i; + + if (capp_ucode_loaded(chip, index)) + return OPAL_SUCCESS; + + /* Return if PHB not attached to a CAPP unit */ + if (index > max_phb_index) + return OPAL_HARDWARE; + + rc = capp_lid_download(); + if (rc) + return rc; + + prlog(PR_INFO, "CHIP%i: CAPP ucode lid loaded at %p\n", + chip_id, capp_ucode_info.lid); + + lid = capp_ucode_info.lid; + /* + * If lid header is present (on FSP machines), it'll tell us where to + * find the ucode. Otherwise this is the ucode. + */ + ucode = (struct capp_ucode_lid *)lid; + /* PHB3: 'CAPPLIDH' in ASCII + * PHB4: 'CAPPPSLL' in ASCII + */ + if (be64_to_cpu(lid->eyecatcher) == lidec) { + if (be64_to_cpu(lid->version) != 0x1) { + PHBERR(opal_id, chip_id, index, + "capi ucode lid header invalid\n"); + return OPAL_HARDWARE; + } + ucode = (struct capp_ucode_lid *) + ((char *)ucode + be64_to_cpu(lid->ucode_offset)); + } + + /* 'CAPPULID' in ASCII */ + if ((be64_to_cpu(ucode->eyecatcher) != 0x43415050554C4944) || + (ucode->version != 1)) { + PHBERR(opal_id, chip_id, index, + "CAPP: ucode header invalid\n"); + return OPAL_HARDWARE; + } + + offset = 0; + while (offset < be64_to_cpu(ucode->data_size)) { + data = (struct capp_ucode_data *) + ((char *)&ucode->data + offset); + chunk_count = be32_to_cpu(data->hdr.chunk_count); + offset += sizeof(struct capp_ucode_data_hdr) + chunk_count * 8; + + /* 'CAPPUCOD' in ASCII */ + if (be64_to_cpu(data->hdr.eyecatcher) != 0x4341505055434F44) { + PHBERR(opal_id, chip_id, index, + "CAPP: ucode data header invalid:%i\n", + offset); + return OPAL_HARDWARE; + } + + switch (data->hdr.reg) { + case apc_master_cresp: + xscom_write(chip_id, apc_master_addr + reg_offset, + 0); + addr = apc_master_write; + break; + case apc_master_uop_table: + xscom_write(chip_id, apc_master_addr + reg_offset, + 0x180ULL << 52); + addr = apc_master_write; + break; + case snp_ttype: + xscom_write(chip_id, snp_array_addr + reg_offset, + 0x5000ULL << 48); + addr = snp_array_write; + break; + case snp_uop_table: + xscom_write(chip_id, snp_array_addr + reg_offset, + 0x4000ULL << 48); + addr = snp_array_write; + break; + default: + continue; + } + + for (i = 0; i < chunk_count; i++) { + val = be64_to_cpu(data->data[i]); + xscom_write(chip_id, addr + reg_offset, val); + } + } + + chip->capp_ucode_loaded |= (1 << index); + + return OPAL_SUCCESS; +} diff --git a/hw/phb3.c b/hw/phb3.c index f0e957c..0af20a6 100644 --- a/hw/phb3.c +++ b/hw/phb3.c @@ -2417,139 +2417,6 @@ static int64_t phb3_freset(struct pci_slot *slot) } struct lock capi_lock = LOCK_UNLOCKED; -static struct { - uint32_t ec_level; - struct capp_lid_hdr *lid; - size_t size; - int load_result; -} capp_ucode_info = { 0, NULL, 0, false }; - -#define CAPP_UCODE_MAX_SIZE 0x20000 - -#define CAPP_UCODE_LOADED(chip, p) \ - ((chip)->capp_ucode_loaded & (1 << (p)->index)) - -static int64_t capp_lid_download(void) -{ - int64_t ret; - - if (capp_ucode_info.load_result != OPAL_EMPTY) - return capp_ucode_info.load_result; - - capp_ucode_info.load_result = wait_for_resource_loaded( - RESOURCE_ID_CAPP, - capp_ucode_info.ec_level); - - if (capp_ucode_info.load_result != OPAL_SUCCESS) { - prerror("CAPP: Error loading ucode lid. index=%x\n", - capp_ucode_info.ec_level); - ret = OPAL_RESOURCE; - free(capp_ucode_info.lid); - capp_ucode_info.lid = NULL; - goto end; - } - - ret = OPAL_SUCCESS; -end: - return ret; -} - -static int64_t capp_load_ucode(struct phb3 *p) -{ - struct proc_chip *chip = get_chip(p->chip_id); - struct capp_ucode_lid *ucode; - struct capp_ucode_data *data; - struct capp_lid_hdr *lid; - uint64_t rc, val, addr; - uint32_t chunk_count, offset, reg_offset; - int i; - - if (CAPP_UCODE_LOADED(chip, p)) - return OPAL_SUCCESS; - - /* Return if PHB not attached to a CAPP unit */ - if (p->index > PHB3_CAPP_MAX_PHB_INDEX(p)) - return OPAL_HARDWARE; - - rc = capp_lid_download(); - if (rc) - return rc; - - prlog(PR_INFO, "CHIP%i: CAPP ucode lid loaded at %p\n", - p->chip_id, capp_ucode_info.lid); - lid = capp_ucode_info.lid; - /* - * If lid header is present (on FSP machines), it'll tell us where to - * find the ucode. Otherwise this is the ucode. - */ - ucode = (struct capp_ucode_lid *)lid; - if (be64_to_cpu(lid->eyecatcher) == 0x434150504c494448) { - if (be64_to_cpu(lid->version) != 0x1) { - PHBERR(p, "capi ucode lid header invalid\n"); - return OPAL_HARDWARE; - } - ucode = (struct capp_ucode_lid *) - ((char *)ucode + be64_to_cpu(lid->ucode_offset)); - } - - if ((be64_to_cpu(ucode->eyecatcher) != 0x43415050554C4944) || - (ucode->version != 1)) { - PHBERR(p, "CAPP: ucode header invalid\n"); - return OPAL_HARDWARE; - } - - reg_offset = PHB3_CAPP_REG_OFFSET(p); - offset = 0; - while (offset < be64_to_cpu(ucode->data_size)) { - data = (struct capp_ucode_data *) - ((char *)&ucode->data + offset); - chunk_count = be32_to_cpu(data->hdr.chunk_count); - offset += sizeof(struct capp_ucode_data_hdr) + chunk_count * 8; - - if (be64_to_cpu(data->hdr.eyecatcher) != 0x4341505055434F44) { - PHBERR(p, "CAPP: ucode data header invalid:%i\n", - offset); - return OPAL_HARDWARE; - } - - switch (data->hdr.reg) { - case apc_master_cresp: - xscom_write(p->chip_id, - CAPP_APC_MASTER_ARRAY_ADDR_REG + reg_offset, - 0); - addr = CAPP_APC_MASTER_ARRAY_WRITE_REG; - break; - case apc_master_uop_table: - xscom_write(p->chip_id, - CAPP_APC_MASTER_ARRAY_ADDR_REG + reg_offset, - 0x180ULL << 52); - addr = CAPP_APC_MASTER_ARRAY_WRITE_REG; - break; - case snp_ttype: - xscom_write(p->chip_id, - CAPP_SNP_ARRAY_ADDR_REG + reg_offset, - 0x5000ULL << 48); - addr = CAPP_SNP_ARRAY_WRITE_REG; - break; - case snp_uop_table: - xscom_write(p->chip_id, - CAPP_SNP_ARRAY_ADDR_REG + reg_offset, - 0x4000ULL << 48); - addr = CAPP_SNP_ARRAY_WRITE_REG; - break; - default: - continue; - } - - for (i = 0; i < chunk_count; i++) { - val = be64_to_cpu(data->data[i]); - xscom_write(p->chip_id, addr + reg_offset, val); - } - } - - chip->capp_ucode_loaded |= (1 << p->index); - return OPAL_SUCCESS; -} static void do_capp_recovery_scoms(struct phb3 *p) { @@ -2561,7 +2428,13 @@ static void do_capp_recovery_scoms(struct phb3 *p) offset = PHB3_CAPP_REG_OFFSET(p); /* disable snoops */ xscom_write(p->chip_id, SNOOP_CAPI_CONFIG + offset, 0); - capp_load_ucode(p); + capp_load_ucode(p->index, p->chip_id, PHB3_CAPP_MAX_PHB_INDEX(p), + 0x434150504c494448, PHB3_CAPP_REG_OFFSET(p), + p->phb.opal_id, + CAPP_APC_MASTER_ARRAY_ADDR_REG, + CAPP_APC_MASTER_ARRAY_WRITE_REG, + CAPP_SNP_ARRAY_ADDR_REG, + CAPP_SNP_ARRAY_WRITE_REG); /* clear err rpt reg*/ xscom_write(p->chip_id, CAPP_ERR_RPT_CLR + offset, 0); /* clear capp fir */ @@ -3596,7 +3469,7 @@ static int64_t phb3_set_capi_mode(struct phb *phb, uint64_t mode, uint32_t offset; u8 mask; - if (!CAPP_UCODE_LOADED(chip, p)) { + if (!capp_ucode_loaded(chip, p->index)) { PHBERR(p, "CAPP: ucode not loaded\n"); return OPAL_RESOURCE; } @@ -4624,7 +4497,13 @@ static void phb3_create(struct dt_node *np) phb3_init_hw(p, true); /* Load capp microcode into capp unit */ - capp_load_ucode(p); + capp_load_ucode(p->index, p->chip_id, PHB3_CAPP_MAX_PHB_INDEX(p), + 0x434150504c494448, PHB3_CAPP_REG_OFFSET(p), + p->phb.opal_id, + CAPP_APC_MASTER_ARRAY_ADDR_REG, + CAPP_APC_MASTER_ARRAY_WRITE_REG, + CAPP_SNP_ARRAY_ADDR_REG, + CAPP_SNP_ARRAY_WRITE_REG); /* Platform additional setup */ if (platform.pci_setup_phb) @@ -4817,67 +4696,6 @@ static void phb3_probe_pbcq(struct dt_node *pbcq) add_chip_dev_associativity(np); } -int phb3_preload_capp_ucode(void) -{ - struct dt_node *p; - struct proc_chip *chip; - uint32_t index; - uint64_t rc; - int ret; - - p = dt_find_compatible_node(dt_root, NULL, "ibm,power8-pbcq"); - - if (!p) { - printf("CAPI: WARNING: no compat thing found\n"); - return OPAL_SUCCESS; - } - - chip = get_chip(dt_get_chip_id(p)); - - rc = xscom_read_cfam_chipid(chip->id, &index); - if (rc) { - prerror("CAPP: Error reading cfam chip-id\n"); - ret = OPAL_HARDWARE; - return ret; - } - /* Keep ChipID and Major/Minor EC. Mask out the Location Code. */ - index = index & 0xf0fff; - - /* Assert that we're preloading */ - assert(capp_ucode_info.lid == NULL); - capp_ucode_info.load_result = OPAL_EMPTY; - - capp_ucode_info.ec_level = index; - - /* Is the ucode preloaded like for BML? */ - if (dt_has_node_property(p, "ibm,capp-ucode", NULL)) { - capp_ucode_info.lid = (struct capp_lid_hdr *)(u64) - dt_prop_get_u32(p, "ibm,capp-ucode"); - ret = OPAL_SUCCESS; - goto end; - } - /* If we successfully download the ucode, we leave it around forever */ - capp_ucode_info.size = CAPP_UCODE_MAX_SIZE; - capp_ucode_info.lid = malloc(CAPP_UCODE_MAX_SIZE); - if (!capp_ucode_info.lid) { - prerror("CAPP: Can't allocate space for ucode lid\n"); - ret = OPAL_NO_MEM; - goto end; - } - - printf("CAPI: Preloading ucode %x\n", capp_ucode_info.ec_level); - - ret = start_preload_resource(RESOURCE_ID_CAPP, index, - capp_ucode_info.lid, - &capp_ucode_info.size); - - if (ret != OPAL_SUCCESS) - prerror("CAPI: Failed to preload resource %d\n", ret); - -end: - return ret; -} - void phb3_preload_vpd(void) { const struct dt_property *prop; diff --git a/hw/phb4.c b/hw/phb4.c index 9858ad8..8b07590 100644 --- a/hw/phb4.c +++ b/hw/phb4.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -2592,6 +2593,11 @@ static int64_t phb4_set_capi_mode(struct phb *phb, uint64_t mode, uint64_t reg; uint32_t offset; + if (!capp_ucode_loaded(chip, p->index)) { + PHBERR(p, "CAPP: ucode not loaded\n"); + return OPAL_RESOURCE; + } + lock(&capi_lock); /* Only PHB0 and PHB3 have the PHB/CAPP I/F so CAPI Adapters can * be connected to whether PEC0 or PEC2. Single port CAPI adapter @@ -3505,6 +3511,15 @@ static void phb4_create(struct dt_node *np) /* Get the HW up and running */ phb4_init_hw(p, true); + /* Load capp microcode into capp unit */ + capp_load_ucode(p->index, p->chip_id, PHB4_CAPP_MAX_PHB_INDEX, + 0x4341505050534C4C, PHB4_CAPP_REG_OFFSET(p), + p->phb.opal_id, + CAPP_APC_MASTER_ARRAY_ADDR_REG, + CAPP_APC_MASTER_ARRAY_WRITE_REG, + CAPP_SNP_ARRAY_ADDR_REG, + CAPP_SNP_ARRAY_WRITE_REG); + /* Register all interrupt sources with XIVE */ xive_register_hw_source(p->base_msi, p->num_irqs - 8, 16, p->int_mmio, XIVE_SRC_SHIFT_BUG, diff --git a/include/capp.h b/include/capp.h index d0c28c9..82b08f2 100644 --- a/include/capp.h +++ b/include/capp.h @@ -17,8 +17,12 @@ #ifndef __CAPP_H #define __CAPP_H +/* + * eyecatcher PHB3: 'CAPPLIDH' in ASCII + * eyecatcher PHB4: 'CAPPPSLL' in ASCII + */ struct capp_lid_hdr { - be64 eyecatcher; /* 'CAPPLIDH' in ASCII */ + be64 eyecatcher; be64 version; be64 lid_no; be64 pad; @@ -27,7 +31,7 @@ struct capp_lid_hdr { }; struct capp_ucode_data_hdr { - be64 eyecatcher; /* 'CAPPUCOD' in ASCII */ + be64 eyecatcher; /* 'CAPPUCOD' in ASCII */ u8 version; u8 reg; u8 reserved[2]; @@ -47,7 +51,6 @@ struct capp_ucode_lid { struct capp_ucode_data data; /* This repeats */ }; - enum capp_reg { apc_master_cresp = 0x1, apc_master_uop_table = 0x2, @@ -62,4 +65,13 @@ enum capp_reg { apc_master_powerbus_ctrl = 0xB }; +struct proc_chip; +extern bool capp_ucode_loaded(struct proc_chip *chip, unsigned int index); + +extern int64_t capp_load_ucode(unsigned int index, unsigned int chip_id, + unsigned int max_phb_index, u64 lidec, + uint32_t reg_offset, uint32_t opal_id, + uint64_t apc_master_addr, uint64_t apc_master_write, + uint64_t snp_array_addr, uint64_t snp_array_write); + #endif /* __CAPP_H */ diff --git a/include/skiboot.h b/include/skiboot.h index 33447a4..30b8ade 100644 --- a/include/skiboot.h +++ b/include/skiboot.h @@ -210,9 +210,8 @@ extern void setup_reset_vector(void); extern void probe_p7ioc(void); extern void probe_phb3(void); extern void probe_phb4(void); -extern int phb3_preload_capp_ucode(void); extern void phb3_preload_vpd(void); -extern int phb4_preload_capp_ucode(void); +extern int preload_capp_ucode(void); extern void phb4_preload_vpd(void); extern void probe_npu(void); extern void uart_init(void);