From patchwork Sun Jun 18 12:35:38 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: maddy X-Patchwork-Id: 777443 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wrDCZ6S5lz9s3T for ; Sun, 18 Jun 2017 22:37:46 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3wrDCZ5htXzDr0Z for ; Sun, 18 Jun 2017 22:37:46 +1000 (AEST) 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 3wrDBF6FnszDqjH for ; Sun, 18 Jun 2017 22:36:37 +1000 (AEST) Received: from pps.filterd (m0098416.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id v5ICYJnu035740 for ; Sun, 18 Jun 2017 08:36:33 -0400 Received: from e23smtp06.au.ibm.com (e23smtp06.au.ibm.com [202.81.31.148]) by mx0b-001b2d01.pphosted.com with ESMTP id 2b5rvxs55h-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Sun, 18 Jun 2017 08:36:33 -0400 Received: from localhost by e23smtp06.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Sun, 18 Jun 2017 22:36:30 +1000 Received: from d23relay06.au.ibm.com (202.81.31.225) by e23smtp06.au.ibm.com (202.81.31.212) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Sun, 18 Jun 2017 22:36:28 +1000 Received: from d23av02.au.ibm.com (d23av02.au.ibm.com [9.190.235.138]) by d23relay06.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v5ICaRL42490844 for ; Sun, 18 Jun 2017 22:36:27 +1000 Received: from d23av02.au.ibm.com (localhost [127.0.0.1]) by d23av02.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id v5ICaIhS020940 for ; Sun, 18 Jun 2017 22:36:19 +1000 Received: from localhost.localdomain (sriharisrinidhi.in.ibm.com [9.182.104.211]) by d23av02.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id v5ICZmNG020488; Sun, 18 Jun 2017 22:36:17 +1000 From: Madhavan Srinivasan To: stewart@linux.vnet.ibm.com Date: Sun, 18 Jun 2017 18:05:38 +0530 X-Mailer: git-send-email 2.7.4 In-Reply-To: <1497789339-28819-1-git-send-email-maddy@linux.vnet.ibm.com> References: <1497789339-28819-1-git-send-email-maddy@linux.vnet.ibm.com> X-TM-AS-MML: disable x-cbid: 17061812-0040-0000-0000-000003304D14 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17061812-0041-0000-0000-00000CAAAC5C Message-Id: <1497789339-28819-9-git-send-email-maddy@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-06-18_09:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=13 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1703280000 definitions=main-1706180225 Subject: [Skiboot] [PATCH v13 8/9] skiboot: Add opal calls to init/start/stop IMC devices 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: , Cc: mikey@neuling.org, skiboot@lists.ozlabs.org MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" From: Anju T Sudhakar Add new opal calls to init, start and stop the IMC nest/core units. To initialize the core IMC counters, it takes a physical address per core as an input and writes that address to PDBAR[14:50] bits. It initializes the htm_mode and event_mask, where it selects the time interval at which the counter values must be posted to the given memory location and enables the counters to start running by setting the appropriate bits. To disable/enable the nest IMC counters (stop or resume counting), writes into "command" field of the nest control block in the reserve memory location. To disable/enable the core IMC counters (stop or resume counting), writes into appropriate bits of htm_mode to disable the counters. Signed-off-by: Hemant Kumar Signed-off-by: Anju T Sudhakar Signed-off-by: Madhavan Srinivasan --- hw/imc.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++++++++ include/imc.h | 9 +++ include/opal-api.h | 12 +++- 3 files changed, 228 insertions(+), 1 deletion(-) diff --git a/hw/imc.c b/hw/imc.c index 696805ae23d2..48c940f7ee99 100644 --- a/hw/imc.c +++ b/hw/imc.c @@ -94,6 +94,26 @@ static bool is_nest_mem_initialized(struct imc_chip_cb *ptr) return true; } +/* + * A Quad contains 4 cores in Power 9, and there are 4 addresses for + * the Core Hardware Trace Macro (CHTM) attached to each core. + * So, for core index 0 to core index 3, we have a sequential range of + * SCOM port addresses in the arrays below, each for Hardware Trace Macro (HTM) + * mode and PDBAR. + */ +unsigned int pdbar_scom_index[] = { + 0x1001220B, + 0x1001230B, + 0x1001260B, + 0x1001270B +}; +unsigned int htm_scom_index[] = { + 0x10012200, + 0x10012300, + 0x10012600, + 0x10012700 +}; + static struct imc_chip_cb *get_imc_cb(uint32_t chip_id) { struct proc_chip *chip = get_chip(chip_id); @@ -427,3 +447,191 @@ err: free(decompress_buf); free(compress_buf); } + +/* + * opal_imc_counters_init : This call initialize the IMC engine. + * + * For Nest IMC, this is no-op and returns OPAL_SUCCESS at this point. + * For Core IMC, this initializes core IMC Engine, by initializing + * these scoms "PDBAR", "HTM_MODE" and the "EVENT_MASK" in a given cpu. + */ +static int64_t opal_imc_counters_init(uint32_t type, uint64_t addr, uint64_t cpu_pir) +{ + struct cpu_thread *c = find_cpu_by_pir(cpu_pir); + struct proc_chip *chip; + int port_id, phys_core_id; + + switch (type) { + case OPAL_IMC_COUNTERS_NEST: + return OPAL_SUCCESS; + case OPAL_IMC_COUNTERS_CORE: + if (!c) + return OPAL_PARAMETER; + + chip = get_chip(c->chip_id); + if (chip) + return OPAL_PARAMETER; + + /* + * Core IMC hardware mandates setting of htm_mode and + * pdbar in specific scom ports. port_id are in + * pdbar_scom_index[] and htm_scom_index[]. + */ + phys_core_id = cpu_get_core_index(c); + port_id = phys_core_id % 4; + + /* + * Core IMC hardware mandate initing of three scoms + * to enbale or disable of the Core IMC engine. + * + * PDBAR: Scom contains the real address to store per-core + * counter data in memory along with other bits. + * + * EventMask: Scom contain bits to denote event to multiplex + * at different MSR[HV PR] values, along with bits for + * sampling duration. + * + * HTM Scom: scom to enable counter data movement to memory. + */ + if (xscom_write(chip->id, + XSCOM_ADDR_P9_EP(phys_core_id, + pdbar_scom_index[port_id]), + (u64)(CORE_IMC_PDBAR_MASK & addr))) { + prerror("IMC: error in xscom_write for pdbar\n"); + return OPAL_HARDWARE; + } + + if (xscom_write(chip->id, + XSCOM_ADDR_P9_EC(phys_core_id, + CORE_IMC_EVENT_MASK_ADDR), + (u64)CORE_IMC_EVENT_MASK)) { + prerror("IMC: error in xscom_write for event mask\n"); + return OPAL_HARDWARE; + } + + if (xscom_write(chip->id, + XSCOM_ADDR_P9_EP(phys_core_id, + htm_scom_index[port_id]), + (u64)CORE_IMC_HTM_MODE_DISABLE)) { + prerror("IMC: error in xscom_write for htm mode\n"); + return OPAL_HARDWARE; + } + return OPAL_SUCCESS; + } + + return OPAL_SUCCESS; +} +opal_call(OPAL_IMC_COUNTERS_INIT, opal_imc_counters_init, 3); + +/* opal_imc_counters_control_start: This call starts the nest/core imc engine. */ +static int64_t opal_imc_counters_start(uint32_t type, uint64_t cpu_pir) +{ + u64 op; + struct cpu_thread *c = find_cpu_by_pir(cpu_pir); + struct imc_chip_cb *cb; + struct proc_chip *chip; + int port_id, phys_core_id; + + if (!c) + return OPAL_PARAMETER; + + chip = get_chip(c->chip_id); + if (chip) + return OPAL_PARAMETER; + + switch (type) { + case OPAL_IMC_COUNTERS_NEST: + /* Fetch the IMC control block structure */ + cb = get_imc_cb(chip->id); + + /* Set the run command */ + op = NEST_IMC_ENABLE; + + /* Write the command to the control block now */ + cb->imc_chip_command = cpu_to_be64(op); + + return OPAL_SUCCESS; + case OPAL_IMC_COUNTERS_CORE: + /* + * Core IMC hardware mandates setting of htm_mode in specific + * scom ports (port_id are in htm_scom_index[]) + */ + phys_core_id = cpu_get_core_index(c); + port_id = phys_core_id % 4; + + /* + * Enables the core imc engine by appropriately setting + * bits 4-9 of the HTM_MODE scom port. No initialization + * is done in this call. This just enables the the counters + * to count with the previous initialization. + */ + if (xscom_write(chip->id, + XSCOM_ADDR_P9_EP(phys_core_id, + htm_scom_index[port_id]), + (u64)CORE_IMC_HTM_MODE_ENABLE)) { + prerror("IMC OPAL_start: error in xscom_write for htm_mode\n"); + return OPAL_HARDWARE; + } + + return OPAL_SUCCESS; + } + + return OPAL_SUCCESS; +} +opal_call(OPAL_IMC_COUNTERS_START, opal_imc_counters_start, 2); + +/* opal_imc_counters_control_stop: This call stops the nest imc engine. */ +static int64_t opal_imc_counters_stop(uint32_t type, uint64_t cpu_pir) +{ + u64 op; + struct imc_chip_cb *cb; + struct cpu_thread *c = find_cpu_by_pir(cpu_pir); + struct proc_chip *chip; + int port_id, phys_core_id; + + if (!c) + return OPAL_PARAMETER; + + chip = get_chip(c->chip_id); + if (chip) + return OPAL_PARAMETER; + + switch (type) { + case OPAL_IMC_COUNTERS_NEST: + /* Fetch the IMC control block structure */ + cb = get_imc_cb(chip->id); + + /* Set the run command */ + op = NEST_IMC_DISABLE; + + /* Write the command to the control block */ + cb->imc_chip_command = cpu_to_be64(op); + + return OPAL_SUCCESS; + + case OPAL_IMC_COUNTERS_CORE: + /* + * Core IMC hardware mandates setting of htm_mode in specific + * scom ports (port_id are in htm_scom_index[]) + */ + phys_core_id = cpu_get_core_index(c); + port_id = phys_core_id % 4; + + /* + * Disables the core imc engine by clearing + * bits 4-9 of the HTM_MODE scom port. + */ + if (xscom_write(chip->id, + XSCOM_ADDR_P9_EP(phys_core_id, + htm_scom_index[port_id]), + (u64) CORE_IMC_HTM_MODE_DISABLE)) { + prerror("IMC: error in xscom_write for htm_mode\n"); + return OPAL_HARDWARE; + } + + return OPAL_SUCCESS; + } + + return OPAL_SUCCESS; +} +opal_call(OPAL_IMC_COUNTERS_STOP, opal_imc_counters_stop, 2); diff --git a/include/imc.h b/include/imc.h index fcd220d1b316..d4381bb2adae 100644 --- a/include/imc.h +++ b/include/imc.h @@ -121,6 +121,15 @@ struct imc_chip_cb #define MAX_NEST_UNITS 48 +/* + * Core IMC SCOMs + */ +#define CORE_IMC_EVENT_MASK_ADDR 0x20010AA8ull +#define CORE_IMC_EVENT_MASK 0x0001020000000000ull +#define CORE_IMC_PDBAR_MASK 0x0003ffffffffe000ull +#define CORE_IMC_HTM_MODE_ENABLE 0xE800000000000000ull +#define CORE_IMC_HTM_MODE_DISABLE 0xE000000000000000ull + void imc_init(void); void imc_catalog_preload(void); #endif /* __IMC_H */ diff --git a/include/opal-api.h b/include/opal-api.h index 80033c6fa77f..6497c94cd46a 100644 --- a/include/opal-api.h +++ b/include/opal-api.h @@ -204,7 +204,10 @@ #define OPAL_NPU_INIT_CONTEXT 146 #define OPAL_NPU_DESTROY_CONTEXT 147 #define OPAL_NPU_MAP_LPAR 148 -#define OPAL_LAST 148 +#define OPAL_IMC_COUNTERS_INIT 149 +#define OPAL_IMC_COUNTERS_START 150 +#define OPAL_IMC_COUNTERS_STOP 151 +#define OPAL_LAST 151 /* Device tree flags */ @@ -1215,6 +1218,13 @@ enum { XIVE_DUMP_EMU_STATE = 5, }; +/* Operation argument to IMC Microcode */ +enum { + OPAL_IMC_COUNTERS_NEST = 1, + OPAL_IMC_COUNTERS_CORE = 2, +}; + + #endif /* __ASSEMBLY__ */ #endif /* __OPAL_API_H */