From patchwork Thu Sep 24 04:42:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amitay Isaacs X-Patchwork-Id: 1370274 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Bxj936SFmz9sTH for ; Thu, 24 Sep 2020 14:43:19 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=ozlabs.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=ozlabs.org header.i=@ozlabs.org header.a=rsa-sha256 header.s=201707 header.b=vMMciNS2; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4Bxj935Br3zDqZ2 for ; Thu, 24 Sep 2020 14:43:19 +1000 (AEST) X-Original-To: pdbg@lists.ozlabs.org Delivered-To: pdbg@lists.ozlabs.org Received: from ozlabs.org (bilbo.ozlabs.org [IPv6:2401:3900:2:1::2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4Bxj8V4C4CzDqYq for ; Thu, 24 Sep 2020 14:42:50 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=ozlabs.org Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=ozlabs.org header.i=@ozlabs.org header.a=rsa-sha256 header.s=201707 header.b=vMMciNS2; dkim-atps=neutral Received: from authenticated.ozlabs.org (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mail.ozlabs.org (Postfix) with ESMTPSA id 4Bxj8T5x05z9sTQ; Thu, 24 Sep 2020 14:42:49 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ozlabs.org; s=201707; t=1600922570; bh=J34+e5PP7r8+1/mG/ggJwncresD/E2uXCQoD3LrwQyI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vMMciNS2NswsTWAE65Pviw6LAuwoSrM7XefrxqcQRq9hVyrucafac7cM36DOwmyyl cI92NGJqN+4JwcXoyDJU+pRuHML8lZZ6lSJz/u18iA7K2NdGybUUsTGUAUYBmLdqZh 8XspffAgcQfmiuGU85oyfRnTfUd4Q5LcuntsJH/biBuLVtLP4hGyc3FkNfR10UH47m PCdySr1HcXi/338Pk2LVDJ25IiotjsBZhqtTr/gxkJGcR9EcrFQGG8xh48+vZGk6LW JdkU0XaJqOzzLTteUqudO5kRnYY5AXDa6kJS1EPryWoReULhxhpxI+4azMVUZ2C+vl t6xCNtrIAqbmQ== From: Amitay Isaacs To: pdbg@lists.ozlabs.org Date: Thu, 24 Sep 2020 14:42:22 +1000 Message-Id: <20200924044236.130586-5-amitay@ozlabs.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200924044236.130586-1-amitay@ozlabs.org> References: <20200924044236.130586-1-amitay@ozlabs.org> MIME-Version: 1.0 Subject: [Pdbg] [PATCH 04/18] libpdbg: Introduce p10 FAPI targets and address translation X-BeenThere: pdbg@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "mailing list for https://github.com/open-power/pdbg development" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: pdbg-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Pdbg" From: Alistair Popple Signed-off-by: Alistair Popple --- Makefile.am | 2 + libpdbg/hwunit.h | 14 + libpdbg/p10_fapi_targets.c | 583 +++++++++++++++++++++++++++++++++++++ libpdbg/p10_scom_addr.h | 133 +++++++++ 4 files changed, 732 insertions(+) create mode 100644 libpdbg/p10_fapi_targets.c create mode 100644 libpdbg/p10_scom_addr.h diff --git a/Makefile.am b/Makefile.am index d4f7dc1..779c52c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -180,6 +180,8 @@ libpdbg_la_SOURCES = \ libpdbg/p9chip.c \ libpdbg/p9_fapi_targets.c \ libpdbg/p9_scom_addr.h \ + libpdbg/p10_fapi_targets.c \ + libpdbg/p10_scom_addr.h \ libpdbg/sbefifo.c \ libpdbg/sprs.h \ libpdbg/target.c \ diff --git a/libpdbg/hwunit.h b/libpdbg/hwunit.h index ee825bb..52fdaf0 100644 --- a/libpdbg/hwunit.h +++ b/libpdbg/hwunit.h @@ -306,4 +306,18 @@ struct capp { }; #define target_to_capp(x) container_of(x, struct capp, target) +struct omi { + struct pdbg_target target; +}; +#define target_to_omi(x) container_of(x, struct omi, target) + +struct omic { + struct pdbg_target target; +}; +#define target_to_omic(x) container_of(x, struct omic, target) + +struct mcc { + struct pdbg_target target; +}; +#define target_to_mcc(x) container_of(x, struct mcc, target) #endif /* __HWUNIT_H */ diff --git a/libpdbg/p10_fapi_targets.c b/libpdbg/p10_fapi_targets.c new file mode 100644 index 0000000..76299f5 --- /dev/null +++ b/libpdbg/p10_fapi_targets.c @@ -0,0 +1,583 @@ +/* Copyright 2020 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 + +#include "hwunit.h" +#include "bitutils.h" +#include "p10_scom_addr.h" + +#define t(x) (&(x)->target) + +static uint64_t p10_eq_translate(struct eq *eq, uint64_t addr) +{ + addr = set_chiplet_id(addr, EQ0_CHIPLET_ID + pdbg_target_index(t(eq))); + + return addr; +} + +struct eq p10_eq = { + .target = { + .name = "POWER10 eq", + .compatible = "ibm,power10-eq", + .class = "eq", + .translate = translate_cast(p10_eq_translate), + }, +}; +DECLARE_HW_UNIT(p10_eq); + +#define NUM_CORES_PER_EQ 4 +static uint64_t p10_core_translate(struct core *c, uint64_t addr) +{ + int region = 0; + int chip_unitnum = pdbg_target_index(t(c)); + + switch(chip_unitnum % NUM_CORES_PER_EQ) { + case 0: + region = 8; + break; + case 1: + region = 4; + break; + case 2: + region = 2; + break; + case 3: + region = 1; + break; + } + addr = set_chiplet_id(addr, EQ0_CHIPLET_ID + pdbg_target_index(t(c)) / 4); + addr &= 0xFFFFFFFFFFFF0FFFULL; + addr |= ((region & 0xF) << 12); + + return addr; +} + +struct core p10_core = { + .target = { + .name = "POWER10 core", + .compatible = "ibm,power10-core", + .class = "core", + .translate = translate_cast(p10_core_translate), + }, +}; +DECLARE_HW_UNIT(p10_core); + +static uint64_t p10_pec_translate(struct pec *pec, uint64_t addr) +{ + int chip_unitnum = pdbg_target_index(t(pec)); + + if (get_chiplet_id(addr) >= N0_CHIPLET_ID && + get_chiplet_id(addr) <= N1_CHIPLET_ID) + return set_chiplet_id(addr, + chip_unitnum ? N0_CHIPLET_ID : N1_CHIPLET_ID ); + else + return set_chiplet_id(addr, PCI0_CHIPLET_ID + pdbg_target_index(t(pec))); +} + +struct pec p10_pec = { + .target = { + .name = "POWER10 pec", + .compatible = "ibm,power10-pec", + .class = "pec", + .translate = translate_cast(p10_pec_translate), + }, +}; +DECLARE_HW_UNIT(p10_pec); + +static uint64_t p10_phb_translate(struct phb *phb, uint64_t addr) +{ + int chip_unitnum = pdbg_target_index(t(phb)); + + if (get_chiplet_id(addr) >= N0_CHIPLET_ID && get_chiplet_id(addr) <= N1_CHIPLET_ID) { + addr = set_chiplet_id(addr, chip_unitnum / 3 ? N0_CHIPLET_ID : N1_CHIPLET_ID); + return set_sat_id(addr, 1 + chip_unitnum % 3); + } else { + addr = set_chiplet_id(addr, chip_unitnum / 3 + PCI0_CHIPLET_ID); + if (get_ring_id(addr) == 2) { + if (get_sat_id(addr) >= 1 && get_sat_id(addr) <= 3) + return set_sat_id(addr, 1 + chip_unitnum % 3); + else + return set_sat_id(addr, 4 + chip_unitnum % 3); + } + } + + /* We'll never get here due to the assert but gcc complains */ + return addr; +} + +struct phb p10_phb = { + .target = { + .name = "POWER10 phb", + .compatible = "ibm,power10-phb", + .class = "phb", + .translate = translate_cast(p10_phb_translate), + }, +}; +DECLARE_HW_UNIT(p10_phb); + +static uint64_t p10_nmmu_translate(struct nmmu *nmmu, uint64_t addr) +{ + return set_chiplet_id(addr, pdbg_target_index(t(nmmu)) + N0_CHIPLET_ID); +} + +struct nmmu p10_nmmu = { + .target = { + .name = "POWER10 nmmu", + .compatible = "ibm,power10-nmmu", + .class = "nmmu", + .translate = translate_cast(p10_nmmu_translate), + }, +}; +DECLARE_HW_UNIT(p10_nmmu); + +static uint64_t p10_iohs_translate(struct iohs *iohs, uint64_t addr) +{ + int chip_unitnum = pdbg_target_index(t(iohs)); + + if (get_chiplet_id(addr) >= AXON0_CHIPLET_ID && + get_chiplet_id(addr) <= AXON7_CHIPLET_ID) + addr = set_chiplet_id(addr, AXON0_CHIPLET_ID + chip_unitnum); + else if (get_chiplet_id(addr) >= PAU0_CHIPLET_ID && + get_chiplet_id(addr) <= PAU3_CHIPLET_ID) { + addr = set_chiplet_id(addr, chip_unitnum/2 + PAU0_CHIPLET_ID); + } else + /* We should bail here with an assert but it makes testing hard and we + * should never hit it anyway as all code will have been validated + * through the EKB CI process (LOL). */ + assert(1); + + if (get_chiplet_id(addr) >= PAU0_CHIPLET_ID && + get_chiplet_id(addr) <= PAU3_CHIPLET_ID) { + if (chip_unitnum % 2) + addr = set_io_group_addr(addr, 0x1); + else + addr = set_io_group_addr(addr, 0x0); + } + + return addr; +} + +struct iohs p10_iohs = { + .target = { + .name = "POWER10 iohs", + .compatible = "ibm,power10-iohs", + .class = "iohs", + .translate = translate_cast(p10_iohs_translate), + }, +}; +DECLARE_HW_UNIT(p10_iohs); + +/* We take a struct pdbg_target and avoid the casting here as the translation is + * the same for both target types. */ +static uint64_t p10_mimc_translate(struct pdbg_target *mimc, uint64_t addr) +{ + return set_chiplet_id(addr, pdbg_target_index(mimc) + MC0_CHIPLET_ID); +} + +struct mi p10_mi = { + .target = { + .name = "POWER10 mi", + .compatible = "ibm,power10-mi", + .class = "mi", + .translate = p10_mimc_translate, + }, +}; +DECLARE_HW_UNIT(p10_mi); + +struct mc p10_mc = { + .target = { + .name = "POWER10 mc", + .compatible = "ibm,power10-mc", + .class = "mc", + .translate = p10_mimc_translate, + }, +}; +DECLARE_HW_UNIT(p10_mc); + +static uint64_t p10_mcc_translate(struct mcc *mcc, uint64_t addr) +{ + int chip_unitnum = pdbg_target_index(t(mcc)); + uint8_t offset = get_sat_offset(addr); + + addr = set_chiplet_id(addr, chip_unitnum/2 + MC0_CHIPLET_ID); + if (chip_unitnum % 2) { + switch (get_sat_id(addr)) { + case 0x4: + addr = set_sat_id(addr, 0x5); + break; + case 0x8: + addr = set_sat_id(addr, 0x9); + break; + case 0x0: + if (offset >= 0x22 && offset <= 0x2b) + addr = set_sat_offset(addr, offset + 0x10); + break; + case 0xd: + if (offset >= 0x00 && offset <= 0x1f) + addr = set_sat_offset(addr, offset + 0x20); + break; + } + } else { + switch (get_sat_id(addr)) { + case 0x5: + addr = set_sat_id(addr, 0x4); + break; + case 0x9: + addr = set_sat_id(addr, 0x8); + break; + case 0x0: + if (offset >= 0x32 && offset <= 0x3b) + addr = set_sat_offset(addr, offset - 0x10); + break; + case 0xd: + if (offset >= 0x20 && offset <= 0x3f) + addr = set_sat_offset(addr, offset - 0x20); + break; + } + } + + return addr; +} + +struct mcc p10_mcc = { + .target = { + .name = "POWER10 mcc", + .compatible = "ibm,power10-mcc", + .class = "mcc", + .translate = translate_cast(p10_mcc_translate), + }, +}; +DECLARE_HW_UNIT(p10_mcc); + +static uint64_t p10_omic_translate(struct omic *omic, uint64_t addr) +{ + int chip_unitnum = pdbg_target_index(t(omic)); + int chiplet_id = get_chiplet_id(addr); + + if (chiplet_id >= PAU0_CHIPLET_ID && chiplet_id <= PAU3_CHIPLET_ID) { + if (chip_unitnum == 0 || chip_unitnum == 1) + addr = set_chiplet_id(addr, PAU0_CHIPLET_ID); + else if (chip_unitnum == 2 || chip_unitnum == 3) + addr = set_chiplet_id(addr, PAU2_CHIPLET_ID); + else if (chip_unitnum == 4 || chip_unitnum == 5) + addr = set_chiplet_id(addr, PAU1_CHIPLET_ID); + else if (chip_unitnum == 6 || chip_unitnum == 7) + addr = set_chiplet_id(addr, PAU3_CHIPLET_ID); + else + assert(0); + + if (chip_unitnum % 2) + addr = set_io_group_addr(addr, 0x3); + else + addr = set_io_group_addr(addr, 0x2); + } else { + addr = set_chiplet_id(addr, chip_unitnum/2 + MC0_CHIPLET_ID); + + if (chip_unitnum % 2) + addr = set_ring_id(addr, 0x6); + else + addr = set_ring_id(addr, 0x5); + } + + return addr; +} + +static struct omic p10_omic = { + .target = { + .name = "POWER10 omic", + .compatible = "ibm,power10-omic", + .class = "omic", + .translate = translate_cast(p10_omic_translate), + }, +}; +DECLARE_HW_UNIT(p10_omic); + +static uint64_t p10_omi_translate(struct omi *omi, uint64_t addr) +{ + int chip_unitnum = pdbg_target_index(t(omi)); + int chiplet_id = get_chiplet_id(addr); + + if (chiplet_id >= PAU0_CHIPLET_ID && chiplet_id <= PAU3_CHIPLET_ID) { + if (chip_unitnum >= 0 && chip_unitnum <= 3) + addr = set_chiplet_id(addr, PAU0_CHIPLET_ID); + else if (chip_unitnum >= 4 && chip_unitnum <= 7) + addr = set_chiplet_id(addr, PAU2_CHIPLET_ID); + else if (chip_unitnum >= 8 && chip_unitnum <= 11) + addr = set_chiplet_id(addr, PAU1_CHIPLET_ID); + else if (chip_unitnum >= 12 && chip_unitnum <= 15) + addr = set_chiplet_id(addr, PAU3_CHIPLET_ID); + else + assert(0); + + if (chip_unitnum % 2) + addr = set_io_lane(addr, 8 + get_io_lane(addr) % 8); + else + addr = set_io_lane(addr, get_io_lane(addr) % 8); + + if ((chip_unitnum / 2) % 2) + addr = set_io_group_addr(addr, 0x3); + else + addr = set_io_group_addr(addr, 0x2); + } else { + addr = set_chiplet_id(addr, chip_unitnum/4 + MC0_CHIPLET_ID); + + if (get_sat_offset(addr) >= 16 && get_sat_offset(addr) <= 47) { + if (chip_unitnum % 2) + addr = set_sat_offset(addr, 32 + get_sat_offset(addr) % 16); + else + addr = set_sat_offset(addr, 16 + get_sat_offset(addr) % 16); + } else { + if (chip_unitnum % 2) + addr = set_sat_offset(addr, 56 + get_sat_offset(addr) % 4); + else + addr = set_sat_offset(addr, 48 + get_sat_offset(addr) % 4); + } + + if ((chip_unitnum / 2) %2) + addr = set_ring_id(addr, 0x6); + else + addr = set_ring_id(addr, 0x5); + } + + return addr; +} + +static struct omi p10_omi = { + .target = { + .name = "POWER10 omi", + .compatible = "ibm,power10-omi", + .class = "omi", + .translate = translate_cast(p10_omi_translate), + }, +}; +DECLARE_HW_UNIT(p10_omi); + +static uint64_t p10_pauc_translate(struct pauc *pauc, uint64_t addr) +{ + return set_chiplet_id(addr, pdbg_target_index(t(pauc)) + PAU0_CHIPLET_ID); +} + +static struct pauc p10_pauc = { + .target = { + .name = "POWER10 pauc", + .compatible = "ibm,power10-pauc", + .class = "pauc", + .translate = translate_cast(p10_pauc_translate), + }, +}; +DECLARE_HW_UNIT(p10_pauc); + +static uint64_t p10_pau_translate(struct pau *pau, uint64_t addr) +{ + int chip_unitnum = pdbg_target_index(t(pau)); + + addr = set_chiplet_id(addr, chip_unitnum/2 + PAU0_CHIPLET_ID); + + switch (chip_unitnum) { + case 0: + case 3: + case 4: + case 6: + if (get_ring_id(addr) == 0x4) + addr = set_ring_id(addr, 0x2); + else if (get_ring_id(addr) == 0x5) + addr = set_ring_id(addr, 0x3); + break; + + case 1: + case 2: + case 5: + case 7: + if (get_ring_id(addr) == 0x2) + addr = set_ring_id(addr, 0x4); + else if (get_ring_id(addr) == 0x3) + addr = set_ring_id(addr, 0x5); + break; + } + + return addr; +} + +struct pau p10_pau = { + .target = { + .name = "POWER10 pau", + .compatible = "ibm,power10-pau", + .class = "pau", + .translate = translate_cast(p10_pau_translate), + }, +}; +DECLARE_HW_UNIT(p10_pau); + +#define HEADER_CHECK_DATA ((uint64_t) 0xc0ffee03 << 32) + +static int p10_chiplet_getring(struct chiplet *chiplet, uint64_t ring_addr, int64_t ring_len, uint32_t result[]) +{ + uint64_t scan_type_addr; + uint64_t scan_data_addr; + uint64_t scan_header_addr; + uint64_t scan_type_data; + uint64_t set_pulse = 1; + uint64_t bits = 32; + uint64_t data; + + /* We skip the first word in the results so we can write it later as it + * should contain the header read out at the end */ + int i = 0; + + scan_type_addr = (ring_addr & 0x7fff0000) | 0x7; + scan_data_addr = (scan_type_addr & 0xffff0000) | 0x8000; + scan_header_addr = scan_data_addr & 0xffffe000; + + scan_type_data = (ring_addr & 0xfff0) << 13; + scan_type_data |= 0x800 >> (ring_addr & 0xf); + scan_type_data <<= 32; + + pib_write(&chiplet->target, scan_type_addr, scan_type_data); + pib_write(&chiplet->target, scan_header_addr, HEADER_CHECK_DATA); + + /* The final 32 bit read is the header which we do at the end */ + ring_len -= 32; + i = 1; + + while (ring_len > 0) { + ring_len -= bits; + if (set_pulse) { + scan_data_addr |= 0x4000; + set_pulse = 0; + } else + scan_data_addr &= ~0x4000ULL; + + scan_data_addr &= ~0xffull; + scan_data_addr |= bits; + pib_read(&chiplet->target, scan_data_addr, &data); + + /* Discard lower 32 bits */ + /* TODO: We always read 64-bits from the ring on P9 so we could + * optimise here by reading 64-bits at a time, but I'm not + * confident I've figured that out and 32-bits is what Hostboot + * does and seems to work. */ + data >>= 32; + + /* Left-align data */ + data <<= 32 - bits; + result[i++] = data; + if (ring_len > 0 && (ring_len < bits)) + bits = ring_len; + } + + pib_read(&chiplet->target, scan_header_addr | 0x20, &data); + data &= 0xffffffff00000000; + result[0] = data >> 32; + if (data != HEADER_CHECK_DATA) + printf("WARNING: Header check failed. Make sure you specified the right ring length!\n" + "Ring data is probably corrupt now.\n"); + + return 0; +} + +#define NET_CTRL0 0xf0040 +#define NET_CTRL0_CHIPLET_ENABLE PPC_BIT(0) +static int p10_chiplet_probe(struct pdbg_target *target) +{ + uint64_t value; + + if (pib_read(target, NET_CTRL0, &value)) + return -1; + + if (!(value & NET_CTRL0_CHIPLET_ENABLE)) + return -1; + + return 0; +} + +static uint64_t p10_chiplet_translate(struct chiplet *chiplet, uint64_t addr) +{ + return set_chiplet_id(addr, pdbg_target_index(t(chiplet))); +} + +static struct chiplet p10_chiplet = { + .target = { + .name = "POWER10 Chiplet", + .compatible = "ibm,power10-chiplet", + .class = "chiplet", + .probe = p10_chiplet_probe, + .translate = translate_cast(p10_chiplet_translate), + }, + .getring = p10_chiplet_getring, +}; +DECLARE_HW_UNIT(p10_chiplet); + +static int p10_thread_probe(struct pdbg_target *target) +{ + struct thread *thread = target_to_thread(target); + + thread->id = pdbg_target_index(target); + + return 0; +} + +static struct thread p10_thread = { + .target = { + .name = "POWER10 Thread", + .compatible = "ibm,power10-thread", + .class = "thread", + .probe = p10_thread_probe, + }, +}; +DECLARE_HW_UNIT(p10_thread); + +static uint64_t no_translate(struct pdbg_target *target, uint64_t addr) +{ + /* No translation performed */ + return 0; +} + +static struct fc p10_fc = { + .target = { + .name = "POWER10 Fused Core", + .compatible = "ibm,power10-fc", + .class = "fc", + .translate = no_translate, + }, +}; +DECLARE_HW_UNIT(p10_fc); + +__attribute__((constructor)) +static void register_p10_fapi_targets(void) +{ + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_eq_hw_unit); + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_core_hw_unit); + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_pec_hw_unit); + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_phb_hw_unit); + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_nmmu_hw_unit); + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_pau_hw_unit); + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_iohs_hw_unit); + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_mi_hw_unit); + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_mc_hw_unit); + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_mcc_hw_unit); + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_omic_hw_unit); + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_omi_hw_unit); + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_pauc_hw_unit); + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_pau_hw_unit); + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_chiplet_hw_unit); + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_thread_hw_unit); + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_fc_hw_unit); +} diff --git a/libpdbg/p10_scom_addr.h b/libpdbg/p10_scom_addr.h new file mode 100644 index 0000000..f307e46 --- /dev/null +++ b/libpdbg/p10_scom_addr.h @@ -0,0 +1,133 @@ +/* Copyright 2018 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. + */ + +#ifndef LIBPDBG_SCOM_ADDR +#define LIBPDBG_SCOM_ADDR + +/* Helpers and defines from the ekb. See p10_scom_addr.H */ + +/* P10 Chiplet ID enumeration */ +enum { + PIB_CHIPLET_ID = 0x00, ///< PIB chiplet (FSI) + PERV_CHIPLET_ID = 0x01, ///< TP chiplet + + N0_CHIPLET_ID = 0x02, ///< Nest0 (North) chiplet + N1_CHIPLET_ID = 0x03, ///< Nest1 (South) chiplet + + PCI0_CHIPLET_ID = 0x08, ///< PCIe0 chiplet + PCI1_CHIPLET_ID = 0x09, ///< PCIe1 chiplet + + MC0_CHIPLET_ID = 0x0C, ///< MC0 chiplet + MC1_CHIPLET_ID = 0x0D, ///< MC1 chiplet + MC2_CHIPLET_ID = 0x0E, ///< MC2 chiplet + MC3_CHIPLET_ID = 0x0F, ///< MC3 chiplet + + PAU0_CHIPLET_ID = 0x10, ///< PAU0 chiplet + PAU1_CHIPLET_ID = 0x11, ///< PAU1 chiplet + PAU2_CHIPLET_ID = 0x12, ///< PAU2 chiplet + PAU3_CHIPLET_ID = 0x13, ///< PAU3 chiplet + + AXON0_CHIPLET_ID = 0x18, ///< AXON0 chiplet (high speed io) + AXON1_CHIPLET_ID = 0x19, ///< AXON1 chiplet (high speed io) + AXON2_CHIPLET_ID = 0x1A, ///< AXON2 chiplet (high speed io) + AXON3_CHIPLET_ID = 0x1B, ///< AXON3 chiplet (high speed io) + AXON4_CHIPLET_ID = 0x1C, ///< AXON4 chiplet (high speed io) + AXON5_CHIPLET_ID = 0x1D, ///< AXON5 chiplet (high speed io) + AXON6_CHIPLET_ID = 0x1E, ///< AXON6 chiplet (high speed io) + AXON7_CHIPLET_ID = 0x1F, ///< AXON7 chiplet (high speed io) + + EQ0_CHIPLET_ID = 0x20, ///< Quad0 chiplet (super chiplet) + EQ1_CHIPLET_ID = 0x21, ///< Quad1 chiplet (super chiplet) + EQ2_CHIPLET_ID = 0x22, ///< Quad2 chiplet (super chiplet) + EQ3_CHIPLET_ID = 0x23, ///< Quad3 chiplet (super chiplet) + EQ4_CHIPLET_ID = 0x24, ///< Quad4 chiplet (super chiplet) + EQ5_CHIPLET_ID = 0x25, ///< Quad5 chiplet (super chiplet) + EQ6_CHIPLET_ID = 0x26, ///< Quad6 chiplet (super chiplet) + EQ7_CHIPLET_ID = 0x27, ///< Quad7 chiplet (super chiplet) +}; + +/* Extract pervasive chiplet ID from SCOM address */ +static uint8_t get_chiplet_id(uint64_t addr) +{ + return ((addr >> 24) & 0x3F); +} + +/* Modify SCOM address to update pervasive chiplet ID */ +static uint64_t set_chiplet_id(uint64_t addr, uint8_t chiplet_id) +{ + addr &= 0xFFFFFFFFC0FFFFFFULL; + addr |= ((chiplet_id & 0x3F) << 24); + return addr; +} + +static uint8_t get_ring_id(uint64_t addr) +{ + return (addr >> 10) & 0xF; +} + +static uint64_t set_ring_id(uint64_t addr, uint64_t ring) +{ + addr &= 0xFFFFFFFFFFFF03FFULL; + addr |= ((ring & 0x3F) << 10); + return addr; +} + +static uint32_t get_io_lane(uint64_t addr) +{ + return (addr >> 32) & 0x1F; +} + +static uint64_t set_io_lane(uint64_t addr, uint64_t lane) +{ + addr &= 0xFFFFFFE0FFFFFFFFULL; + addr |= (lane & 0x1F) << 32; + return addr; +} + +static uint8_t get_sat_id(uint64_t addr) +{ + return ((addr >> 6) & 0xF); +} + +/* Modify SCOM address to update satellite ID field */ +static uint64_t set_sat_id(uint64_t addr, uint8_t sat_id) +{ + addr &= 0xFFFFFFFFFFFFFC3FULL; + addr |= ((sat_id & 0xF) << 6); + return addr; +} + +static uint8_t get_sat_offset(uint64_t addr) +{ + return addr & 0x3F; +} + +static uint64_t set_sat_offset(uint64_t addr, uint8_t sat_offset) +{ + addr &= 0xFFFFFFFFFFFFFFC0ULL; + addr |= (sat_offset & 0x3F); + return addr; +} + +static uint64_t set_io_group_addr(uint64_t addr, uint64_t group_addr) +{ + addr &= 0xFFFFFC1FFFFFFFFFULL; + addr |= (group_addr & 0x1F) << 37; + + return addr; +} + +#endif