From 03b8abedf4f4965e7e9e0d4f92877c42c07ce19f Mon Sep 17 00:00:00 2001 From: Frederic Barrat Date: Sun, 3 Sep 2017 20:15:13 +0200 Subject: cxl: Enable global TLBIs for cxl contexts The PSL and nMMU need to see all TLB invalidations for the memory contexts used on the adapter. For the hash memory model, it is done by making all TLBIs global as soon as the cxl driver is in use. For radix, we need something similar, but we can refine and only convert to global the invalidations for contexts actually used by the device. The new mm_context_add_copro() API increments the 'active_cpus' count for the contexts attached to the cxl adapter. As soon as there's more than 1 active cpu, the TLBIs for the context become global. Active cpu count must be decremented when detaching to restore locality if possible and to avoid overflowing the counter. The hash memory model support is somewhat limited, as we can't decrement the active cpus count when mm_context_remove_copro() is called, because we can't flush the TLB for a mm on hash. So TLBIs remain global on hash. Signed-off-by: Frederic Barrat Fixes: f24be42aab37 ("cxl: Add psl9 specific code") Tested-by: Alistair Popple [mpe: Fold in updated comment on the barrier from Fred] Signed-off-by: Michael Ellerman --- drivers/misc/cxl/api.c | 16 +++++++++++++--- drivers/misc/cxl/context.c | 3 +++ drivers/misc/cxl/file.c | 24 ++++++++++++++++++++++-- 3 files changed, 38 insertions(+), 5 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c index a0c44d16bf30..7c11bad5cded 100644 --- a/drivers/misc/cxl/api.c +++ b/drivers/misc/cxl/api.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "cxl.h" @@ -331,9 +332,12 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed, /* ensure this mm_struct can't be freed */ cxl_context_mm_count_get(ctx); - /* decrement the use count */ - if (ctx->mm) + if (ctx->mm) { + /* decrement the use count from above */ mmput(ctx->mm); + /* make TLBIs for this context global */ + mm_context_add_copro(ctx->mm); + } } /* @@ -342,13 +346,19 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed, */ cxl_ctx_get(); + /* See the comment in afu_ioctl_start_work() */ + smp_mb(); + if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) { put_pid(ctx->pid); ctx->pid = NULL; cxl_adapter_context_put(ctx->afu->adapter); cxl_ctx_put(); - if (task) + if (task) { cxl_context_mm_count_put(ctx); + if (ctx->mm) + mm_context_remove_copro(ctx->mm); + } goto out; } diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c index 8c32040b9c09..12a41b2753f0 100644 --- a/drivers/misc/cxl/context.c +++ b/drivers/misc/cxl/context.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -267,6 +268,8 @@ int __detach_context(struct cxl_context *ctx) /* Decrease the mm count on the context */ cxl_context_mm_count_put(ctx); + if (ctx->mm) + mm_context_remove_copro(ctx->mm); ctx->mm = NULL; return 0; diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c index 4bfad9f6dc9f..76c0b0ca9388 100644 --- a/drivers/misc/cxl/file.c +++ b/drivers/misc/cxl/file.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -220,9 +221,12 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, /* ensure this mm_struct can't be freed */ cxl_context_mm_count_get(ctx); - /* decrement the use count */ - if (ctx->mm) + if (ctx->mm) { + /* decrement the use count from above */ mmput(ctx->mm); + /* make TLBIs for this context global */ + mm_context_add_copro(ctx->mm); + } /* * Increment driver use count. Enables global TLBIs for hash @@ -230,6 +234,20 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, */ cxl_ctx_get(); + /* + * A barrier is needed to make sure all TLBIs are global + * before we attach and the context starts being used by the + * adapter. + * + * Needed after mm_context_add_copro() for radix and + * cxl_ctx_get() for hash/p8. + * + * The barrier should really be mb(), since it involves a + * device. However, it's only useful when we have local + * vs. global TLBIs, i.e SMP=y. So keep smp_mb(). + */ + smp_mb(); + trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr); if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor, @@ -240,6 +258,8 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, ctx->pid = NULL; cxl_ctx_put(); cxl_context_mm_count_put(ctx); + if (ctx->mm) + mm_context_remove_copro(ctx->mm); goto out; } -- cgit From 8512bffd6226fea259f94fd23fc3b62ffe64baa1 Mon Sep 17 00:00:00 2001 From: Vaibhav Jain Date: Mon, 4 Sep 2017 14:18:25 +0530 Subject: cxl: Set the valid bit in PE for dedicated mode Make sure to set the valid-bit in software-state field of the populated PE. This was earlier missing for dedicated mode AFUs, hence was causing a PSL freeze when the AFU was activated. Signed-off-by: Vaibhav Jain Acked-by: Frederic Barrat Acked-by: Andrew Donnellan Signed-off-by: Michael Ellerman --- drivers/misc/cxl/native.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/misc') diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c index 4a82c313cf71..75df74d59527 100644 --- a/drivers/misc/cxl/native.c +++ b/drivers/misc/cxl/native.c @@ -897,6 +897,14 @@ int cxl_attach_dedicated_process_psl9(struct cxl_context *ctx, u64 wed, u64 amr) if (ctx->afu->adapter->native->sl_ops->update_dedicated_ivtes) afu->adapter->native->sl_ops->update_dedicated_ivtes(ctx); + ctx->elem->software_state = cpu_to_be32(CXL_PE_SOFTWARE_STATE_V); + /* + * Ideally we should do a wmb() here to make sure the changes to the + * PE are visible to the card before we call afu_enable. + * On ppc64 though all mmios are preceded by a 'sync' instruction hence + * we dont dont need one here. + */ + result = cxl_ops->afu_reset(afu); if (result) return result; -- cgit From 5632874311dbf432c698fcbe0cf7a49e01ebf324 Mon Sep 17 00:00:00 2001 From: Christophe Lombard Date: Fri, 8 Sep 2017 15:52:11 +0200 Subject: cxl: Add support for POWER9 DD2 The PSL initialization sequence has been updated to DD2. This patch adapts to the changes, retaining compatibility with DD1. The patch includes some changes to DD1 fix-ups as well. Tests performed on some of the old/new hardware. The function is_page_fault(), for POWER9, lists the Translation Checkout Responses where the page fault will be handled by copro_handle_mm_fault(). This list is too restrictive and not necessary. This patches removes this restriction and all page faults, whatever the reason, will be handled. In this case, the interruption is always acknowledged. The following features will be added soon: - phb reset when switching to capi mode. - cxllib update to support new functions. Signed-off-by: Christophe Lombard Acked-by: Frederic Barrat Reviewed-by: Vaibhav Jain Signed-off-by: Michael Ellerman --- drivers/misc/cxl/cxl.h | 2 ++ drivers/misc/cxl/fault.c | 15 ++------------- drivers/misc/cxl/pci.c | 47 ++++++++++++++++++++++++----------------------- 3 files changed, 28 insertions(+), 36 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index b1afeccbb97f..0167df81df62 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -100,6 +100,8 @@ static const cxl_p1_reg_t CXL_XSL_FEC = {0x0158}; static const cxl_p1_reg_t CXL_XSL_DSNCTL = {0x0168}; /* PSL registers - CAIA 2 */ static const cxl_p1_reg_t CXL_PSL9_CONTROL = {0x0020}; +static const cxl_p1_reg_t CXL_XSL9_INV = {0x0110}; +static const cxl_p1_reg_t CXL_XSL9_DEF = {0x0140}; static const cxl_p1_reg_t CXL_XSL9_DSNCTL = {0x0168}; static const cxl_p1_reg_t CXL_PSL9_FIR1 = {0x0300}; static const cxl_p1_reg_t CXL_PSL9_FIR2 = {0x0308}; diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c index f17f72ea0545..70dbb6de102c 100644 --- a/drivers/misc/cxl/fault.c +++ b/drivers/misc/cxl/fault.c @@ -220,22 +220,11 @@ static bool cxl_is_segment_miss(struct cxl_context *ctx, u64 dsisr) static bool cxl_is_page_fault(struct cxl_context *ctx, u64 dsisr) { - u64 crs; /* Translation Checkout Response Status */ - if ((cxl_is_power8()) && (dsisr & CXL_PSL_DSISR_An_DM)) return true; - if (cxl_is_power9()) { - crs = (dsisr & CXL_PSL9_DSISR_An_CO_MASK); - if ((crs == CXL_PSL9_DSISR_An_PF_SLR) || - (crs == CXL_PSL9_DSISR_An_PF_RGC) || - (crs == CXL_PSL9_DSISR_An_PF_RGP) || - (crs == CXL_PSL9_DSISR_An_PF_HRH) || - (crs == CXL_PSL9_DSISR_An_PF_STEG) || - (crs == CXL_PSL9_DSISR_An_URTCH)) { - return true; - } - } + if (cxl_is_power9()) + return true; return false; } diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index 3ba04f371380..b4ce9ea113a9 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c @@ -401,7 +401,8 @@ int cxl_calc_capp_routing(struct pci_dev *dev, u64 *chipid, *capp_unit_id = get_capp_unit_id(np, *phb_index); of_node_put(np); if (!*capp_unit_id) { - pr_err("cxl: invalid capp unit id\n"); + pr_err("cxl: invalid capp unit id (phb_index: %d)\n", + *phb_index); return -ENODEV; } @@ -475,37 +476,37 @@ static int init_implementation_adapter_regs_psl9(struct cxl *adapter, psl_fircntl |= 0x1ULL; /* ce_thresh */ cxl_p1_write(adapter, CXL_PSL9_FIR_CNTL, psl_fircntl); - /* vccredits=0x1 pcklat=0x4 */ - cxl_p1_write(adapter, CXL_PSL9_DSNDCTL, 0x0000000000001810ULL); - - /* - * For debugging with trace arrays. - * Configure RX trace 0 segmented mode. - * Configure CT trace 0 segmented mode. - * Configure LA0 trace 0 segmented mode. - * Configure LA1 trace 0 segmented mode. + /* Setup the PSL to transmit packets on the PCIe before the + * CAPP is enabled */ - cxl_p1_write(adapter, CXL_PSL9_TRACECFG, 0x8040800080000000ULL); - cxl_p1_write(adapter, CXL_PSL9_TRACECFG, 0x8040800080000003ULL); - cxl_p1_write(adapter, CXL_PSL9_TRACECFG, 0x8040800080000005ULL); - cxl_p1_write(adapter, CXL_PSL9_TRACECFG, 0x8040800080000006ULL); + cxl_p1_write(adapter, CXL_PSL9_DSNDCTL, 0x0001001000002A10ULL); /* * A response to an ASB_Notify request is returned by the * system as an MMIO write to the address defined in - * the PSL_TNR_ADDR register + * the PSL_TNR_ADDR register. + * keep the Reset Value: 0x00020000E0000000 */ - /* PSL_TNR_ADDR */ - /* NORST */ - cxl_p1_write(adapter, CXL_PSL9_DEBUG, 0x8000000000000000ULL); + /* Enable XSL rty limit */ + cxl_p1_write(adapter, CXL_XSL9_DEF, 0x51F8000000000005ULL); + + /* Change XSL_INV dummy read threshold */ + cxl_p1_write(adapter, CXL_XSL9_INV, 0x0000040007FFC200ULL); + + if (phb_index == 3) { + /* disable machines 31-47 and 20-27 for DMA */ + cxl_p1_write(adapter, CXL_PSL9_APCDEDTYPE, 0x40000FF3FFFF0000ULL); + } - /* allocate the apc machines */ - cxl_p1_write(adapter, CXL_PSL9_APCDEDTYPE, 0x40000003FFFF0000ULL); + /* Snoop machines */ + cxl_p1_write(adapter, CXL_PSL9_APCDEDALLOC, 0x800F000200000000ULL); - /* Disable vc dd1 fix */ - if (cxl_is_power9_dd1()) - cxl_p1_write(adapter, CXL_PSL9_GP_CT, 0x0400000000000001ULL); + if (cxl_is_power9_dd1()) { + /* Disabling deadlock counter CAR */ + cxl_p1_write(adapter, CXL_PSL9_GP_CT, 0x0020000000000001ULL); + } else + cxl_p1_write(adapter, CXL_PSL9_DEBUG, 0x4000000000000000ULL); return 0; } -- cgit From 8f6a90421c7637984fb352da079fb13172176bfd Mon Sep 17 00:00:00 2001 From: Vaibhav Jain Date: Mon, 9 Oct 2017 23:26:27 +0530 Subject: cxl: Rename register PSL9_FIR2 to PSL9_FIR_MASK PSL9 doesn't have a FIR2 register as was the case with PSL8. However currently the register definitions in 'cxl.h' have a definition for PSL9_FIR2 that actually points to PSL9_FIR_MASK register in the P1 area at offset 0x308. So this patch renames the def PSL9_FIR2 to PSL9_FIR_MASK and updates the references in the code to point to the new identifier. It also removes the code to dump contents of FIR2 (FIR_MASK actually) in cxl_native_irq_dump_regs_psl9(). Fixes: f24be42aab37 ("cxl: Add psl9 specific code") Reported-by: Frederic Barrat Signed-off-by: Vaibhav Jain Acked-by: Frederic Barrat Signed-off-by: Michael Ellerman --- drivers/misc/cxl/cxl.h | 2 +- drivers/misc/cxl/debugfs.c | 3 ++- drivers/misc/cxl/native.c | 4 +--- 3 files changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index 0167df81df62..252373c2b861 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -104,7 +104,7 @@ static const cxl_p1_reg_t CXL_XSL9_INV = {0x0110}; static const cxl_p1_reg_t CXL_XSL9_DEF = {0x0140}; static const cxl_p1_reg_t CXL_XSL9_DSNCTL = {0x0168}; static const cxl_p1_reg_t CXL_PSL9_FIR1 = {0x0300}; -static const cxl_p1_reg_t CXL_PSL9_FIR2 = {0x0308}; +static const cxl_p1_reg_t CXL_PSL9_FIR_MASK = {0x0308}; static const cxl_p1_reg_t CXL_PSL9_Timebase = {0x0310}; static const cxl_p1_reg_t CXL_PSL9_DEBUG = {0x0320}; static const cxl_p1_reg_t CXL_PSL9_FIR_CNTL = {0x0348}; diff --git a/drivers/misc/cxl/debugfs.c b/drivers/misc/cxl/debugfs.c index eae9d749f967..52e3d97db114 100644 --- a/drivers/misc/cxl/debugfs.c +++ b/drivers/misc/cxl/debugfs.c @@ -62,7 +62,8 @@ static struct dentry *debugfs_create_io_x64(const char *name, umode_t mode, void cxl_debugfs_add_adapter_regs_psl9(struct cxl *adapter, struct dentry *dir) { debugfs_create_io_x64("fir1", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL9_FIR1)); - debugfs_create_io_x64("fir2", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL9_FIR2)); + debugfs_create_io_x64("fir_mask", 0400, dir, + _cxl_p1_addr(adapter, CXL_PSL9_FIR_MASK)); debugfs_create_io_x64("fir_cntl", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL9_FIR_CNTL)); debugfs_create_io_x64("trace", S_IRUSR | S_IWUSR, dir, _cxl_p1_addr(adapter, CXL_PSL9_TRACECFG)); } diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c index 75df74d59527..6cd57c756927 100644 --- a/drivers/misc/cxl/native.c +++ b/drivers/misc/cxl/native.c @@ -1085,13 +1085,11 @@ static int native_get_irq_info(struct cxl_afu *afu, struct cxl_irq_info *info) void cxl_native_irq_dump_regs_psl9(struct cxl_context *ctx) { - u64 fir1, fir2, serr; + u64 fir1, serr; fir1 = cxl_p1_read(ctx->afu->adapter, CXL_PSL9_FIR1); - fir2 = cxl_p1_read(ctx->afu->adapter, CXL_PSL9_FIR2); dev_crit(&ctx->afu->dev, "PSL_FIR1: 0x%016llx\n", fir1); - dev_crit(&ctx->afu->dev, "PSL_FIR2: 0x%016llx\n", fir2); if (ctx->afu->adapter->native->sl_ops->register_serr_irq) { serr = cxl_p1n_read(ctx->afu, CXL_PSL_SERR_An); cxl_afu_decode_psl_serr(ctx->afu, serr); -- cgit From 990f19ae6feefb4a6e718355719cde5f6ba18ff6 Mon Sep 17 00:00:00 2001 From: Vaibhav Jain Date: Wed, 11 Oct 2017 11:44:41 +0530 Subject: cxl: Dump PSL_FIR register on PSL9 error irq For PSL9 currently we aren't dumping the PSL FIR register when a PSL error interrupt is triggered. Contents of this register are useful in debugging AFU issues. This patch fixes issue by adding a new service_layer_ops callback cxl_native_err_irq_dump_regs_psl9() to dump the PSL_FIR registers on a PSL error interrupt thereby bringing the behavior in line with PSL on POWER-8. Also the existing service_layer_ops callback for PSL8 has been renamed to cxl_native_err_irq_dump_regs_psl8(). Signed-off-by: Vaibhav Jain Acked-by: Frederic Barrat Acked-by: Andrew Donnellan Signed-off-by: Michael Ellerman --- drivers/misc/cxl/cxl.h | 3 ++- drivers/misc/cxl/native.c | 15 ++++++++++++--- drivers/misc/cxl/pci.c | 3 ++- 3 files changed, 16 insertions(+), 5 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index 252373c2b861..111c689b1771 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -1072,7 +1072,8 @@ u64 cxl_calculate_sr(bool master, bool kernel, bool real_mode, bool p9); void cxl_native_irq_dump_regs_psl9(struct cxl_context *ctx); void cxl_native_irq_dump_regs_psl8(struct cxl_context *ctx); -void cxl_native_err_irq_dump_regs(struct cxl *adapter); +void cxl_native_err_irq_dump_regs_psl8(struct cxl *adapter); +void cxl_native_err_irq_dump_regs_psl9(struct cxl *adapter); int cxl_pci_vphb_add(struct cxl_afu *afu); void cxl_pci_vphb_remove(struct cxl_afu *afu); void cxl_release_mapping(struct cxl_context *ctx); diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c index 6cd57c756927..02b6b45b4c20 100644 --- a/drivers/misc/cxl/native.c +++ b/drivers/misc/cxl/native.c @@ -1263,14 +1263,23 @@ static irqreturn_t native_slice_irq_err(int irq, void *data) return IRQ_HANDLED; } -void cxl_native_err_irq_dump_regs(struct cxl *adapter) +void cxl_native_err_irq_dump_regs_psl9(struct cxl *adapter) +{ + u64 fir1; + + fir1 = cxl_p1_read(adapter, CXL_PSL9_FIR1); + dev_crit(&adapter->dev, "PSL_FIR: 0x%016llx\n", fir1); +} + +void cxl_native_err_irq_dump_regs_psl8(struct cxl *adapter) { u64 fir1, fir2; fir1 = cxl_p1_read(adapter, CXL_PSL_FIR1); fir2 = cxl_p1_read(adapter, CXL_PSL_FIR2); - - dev_crit(&adapter->dev, "PSL_FIR1: 0x%016llx\nPSL_FIR2: 0x%016llx\n", fir1, fir2); + dev_crit(&adapter->dev, + "PSL_FIR1: 0x%016llx\nPSL_FIR2: 0x%016llx\n", + fir1, fir2); } static irqreturn_t native_irq_err(int irq, void *data) diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index b4ce9ea113a9..d185b47eb536 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c @@ -1763,6 +1763,7 @@ static const struct cxl_service_layer_ops psl9_ops = { .debugfs_add_adapter_regs = cxl_debugfs_add_adapter_regs_psl9, .debugfs_add_afu_regs = cxl_debugfs_add_afu_regs_psl9, .psl_irq_dump_registers = cxl_native_irq_dump_regs_psl9, + .err_irq_dump_registers = cxl_native_err_irq_dump_regs_psl9, .debugfs_stop_trace = cxl_stop_trace_psl9, .write_timebase_ctrl = write_timebase_ctrl_psl9, .timebase_read = timebase_read_psl9, @@ -1786,7 +1787,7 @@ static const struct cxl_service_layer_ops psl8_ops = { .debugfs_add_adapter_regs = cxl_debugfs_add_adapter_regs_psl8, .debugfs_add_afu_regs = cxl_debugfs_add_afu_regs_psl8, .psl_irq_dump_registers = cxl_native_irq_dump_regs_psl8, - .err_irq_dump_registers = cxl_native_err_irq_dump_regs, + .err_irq_dump_registers = cxl_native_err_irq_dump_regs_psl8, .debugfs_stop_trace = cxl_stop_trace_psl8, .write_timebase_ctrl = write_timebase_ctrl_psl8, .timebase_read = timebase_read_psl8, -- cgit From 1cafc629408d1883a00c9f656e3de5a677460a88 Mon Sep 17 00:00:00 2001 From: Vaibhav Jain Date: Wed, 20 Sep 2017 11:53:22 +0530 Subject: cxl: Provide debugfs access to PSL_DEBUG/XSL_DEBUG registers Access to PSL/XSL_DEBUG registers on the adapter provides easy access to the debug facilities provided by PSL/XSL. So this patch adds two new files (debug, xsl-debug) to the cxl-adapter specific debugfs folder located at /sys/kernel/debugfs/cxl/card, which will provide direct r/w access to corrosponding debug registers in the adapter config-space. Signed-off-by: Vaibhav Jain Acked-by: Andrew Donnellan Acked-by: Frederic Barrat Signed-off-by: Michael Ellerman --- drivers/misc/cxl/cxl.h | 1 + drivers/misc/cxl/debugfs.c | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'drivers/misc') diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index 111c689b1771..fc98f6ad1616 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -101,6 +101,7 @@ static const cxl_p1_reg_t CXL_XSL_DSNCTL = {0x0168}; /* PSL registers - CAIA 2 */ static const cxl_p1_reg_t CXL_PSL9_CONTROL = {0x0020}; static const cxl_p1_reg_t CXL_XSL9_INV = {0x0110}; +static const cxl_p1_reg_t CXL_XSL9_DBG = {0x0130}; static const cxl_p1_reg_t CXL_XSL9_DEF = {0x0140}; static const cxl_p1_reg_t CXL_XSL9_DSNCTL = {0x0168}; static const cxl_p1_reg_t CXL_PSL9_FIR1 = {0x0300}; diff --git a/drivers/misc/cxl/debugfs.c b/drivers/misc/cxl/debugfs.c index 52e3d97db114..dbb9b58077f6 100644 --- a/drivers/misc/cxl/debugfs.c +++ b/drivers/misc/cxl/debugfs.c @@ -66,6 +66,10 @@ void cxl_debugfs_add_adapter_regs_psl9(struct cxl *adapter, struct dentry *dir) _cxl_p1_addr(adapter, CXL_PSL9_FIR_MASK)); debugfs_create_io_x64("fir_cntl", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL9_FIR_CNTL)); debugfs_create_io_x64("trace", S_IRUSR | S_IWUSR, dir, _cxl_p1_addr(adapter, CXL_PSL9_TRACECFG)); + debugfs_create_io_x64("debug", 0600, dir, + _cxl_p1_addr(adapter, CXL_PSL9_DEBUG)); + debugfs_create_io_x64("xsl-debug", 0600, dir, + _cxl_p1_addr(adapter, CXL_XSL9_DBG)); } void cxl_debugfs_add_adapter_regs_psl8(struct cxl *adapter, struct dentry *dir) -- cgit From cbb55eeb49b116bb3880137661ad8ce1ed45d672 Mon Sep 17 00:00:00 2001 From: Vaibhav Jain Date: Wed, 11 Oct 2017 18:00:20 +0530 Subject: cxl: Rework the implementation of cxl_stop_trace_psl9() Presently the PSL9 specific cxl_stop_trace_psl9() only stops the RX0 traces on the CXL adapter when a PSL error irq is triggered. The patch updates the function to stop all the traces arrays and move them to the FIN state. The implementation issues the mmio to TRACECFG register to stop the trace array iff it already not in FIN state. This prevents the issue of trace data being reset in case of multiple stop mmio issued for a single trace array. Also the patch does some refactoring of existing cxl_stop_trace_psl9() and cxl_stop_trace_psl8() functions by moving them to 'pci.c' from 'debugfs.c' file and marking them as static. Signed-off-by: Vaibhav Jain Acked-by: Frederic Barrat Signed-off-by: Michael Ellerman --- drivers/misc/cxl/cxl.h | 14 ++++---------- drivers/misc/cxl/debugfs.c | 22 ---------------------- drivers/misc/cxl/pci.c | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 32 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index fc98f6ad1616..e46a4062904a 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -115,6 +115,7 @@ static const cxl_p1_reg_t CXL_PSL9_TRACECFG = {0x0368}; static const cxl_p1_reg_t CXL_PSL9_APCDEDALLOC = {0x0378}; static const cxl_p1_reg_t CXL_PSL9_APCDEDTYPE = {0x0380}; static const cxl_p1_reg_t CXL_PSL9_TNR_ADDR = {0x0388}; +static const cxl_p1_reg_t CXL_PSL9_CTCCFG = {0x0390}; static const cxl_p1_reg_t CXL_PSL9_GP_CT = {0x0398}; static const cxl_p1_reg_t CXL_XSL9_IERAT = {0x0588}; static const cxl_p1_reg_t CXL_XSL9_ILPP = {0x0590}; @@ -417,6 +418,9 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0}; #define CXL_CARD_MINOR(adapter) (adapter->adapter_num * CXL_DEV_MINORS) #define CXL_DEVT_ADAPTER(dev) (MINOR(dev) / CXL_DEV_MINORS) +#define CXL_PSL9_TRACEID_MAX 0xAU +#define CXL_PSL9_TRACESTATE_FIN 0x3U + enum cxl_context_status { CLOSED, OPENED, @@ -941,8 +945,6 @@ int cxl_debugfs_adapter_add(struct cxl *adapter); void cxl_debugfs_adapter_remove(struct cxl *adapter); int cxl_debugfs_afu_add(struct cxl_afu *afu); void cxl_debugfs_afu_remove(struct cxl_afu *afu); -void cxl_stop_trace_psl9(struct cxl *cxl); -void cxl_stop_trace_psl8(struct cxl *cxl); void cxl_debugfs_add_adapter_regs_psl9(struct cxl *adapter, struct dentry *dir); void cxl_debugfs_add_adapter_regs_psl8(struct cxl *adapter, struct dentry *dir); void cxl_debugfs_add_adapter_regs_xsl(struct cxl *adapter, struct dentry *dir); @@ -978,14 +980,6 @@ static inline void cxl_debugfs_afu_remove(struct cxl_afu *afu) { } -static inline void cxl_stop_trace_psl9(struct cxl *cxl) -{ -} - -static inline void cxl_stop_trace_psl8(struct cxl *cxl) -{ -} - static inline void cxl_debugfs_add_adapter_regs_psl9(struct cxl *adapter, struct dentry *dir) { diff --git a/drivers/misc/cxl/debugfs.c b/drivers/misc/cxl/debugfs.c index dbb9b58077f6..1643850d2302 100644 --- a/drivers/misc/cxl/debugfs.c +++ b/drivers/misc/cxl/debugfs.c @@ -15,28 +15,6 @@ static struct dentry *cxl_debugfs; -void cxl_stop_trace_psl9(struct cxl *adapter) -{ - /* Stop the trace */ - cxl_p1_write(adapter, CXL_PSL9_TRACECFG, 0x4480000000000000ULL); -} - -void cxl_stop_trace_psl8(struct cxl *adapter) -{ - int slice; - - /* Stop the trace */ - cxl_p1_write(adapter, CXL_PSL_TRACE, 0x8000000000000017LL); - - /* Stop the slice traces */ - spin_lock(&adapter->afu_list_lock); - for (slice = 0; slice < adapter->slices; slice++) { - if (adapter->afu[slice]) - cxl_p1n_write(adapter->afu[slice], CXL_PSL_SLICE_TRACE, 0x8000000000000000LL); - } - spin_unlock(&adapter->afu_list_lock); -} - /* Helpers to export CXL mmaped IO registers via debugfs */ static int debugfs_io_u64_get(void *data, u64 *val) { diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index d185b47eb536..bb7fd3f4edab 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c @@ -1747,6 +1747,44 @@ static void cxl_deconfigure_adapter(struct cxl *adapter) pci_disable_device(pdev); } +static void cxl_stop_trace_psl9(struct cxl *adapter) +{ + int traceid; + u64 trace_state, trace_mask; + struct pci_dev *dev = to_pci_dev(adapter->dev.parent); + + /* read each tracearray state and issue mmio to stop them is needed */ + for (traceid = 0; traceid <= CXL_PSL9_TRACEID_MAX; ++traceid) { + trace_state = cxl_p1_read(adapter, CXL_PSL9_CTCCFG); + trace_mask = (0x3ULL << (62 - traceid * 2)); + trace_state = (trace_state & trace_mask) >> (62 - traceid * 2); + dev_dbg(&dev->dev, "cxl: Traceid-%d trace_state=0x%0llX\n", + traceid, trace_state); + + /* issue mmio if the trace array isn't in FIN state */ + if (trace_state != CXL_PSL9_TRACESTATE_FIN) + cxl_p1_write(adapter, CXL_PSL9_TRACECFG, + 0x8400000000000000ULL | traceid); + } +} + +static void cxl_stop_trace_psl8(struct cxl *adapter) +{ + int slice; + + /* Stop the trace */ + cxl_p1_write(adapter, CXL_PSL_TRACE, 0x8000000000000017LL); + + /* Stop the slice traces */ + spin_lock(&adapter->afu_list_lock); + for (slice = 0; slice < adapter->slices; slice++) { + if (adapter->afu[slice]) + cxl_p1n_write(adapter->afu[slice], CXL_PSL_SLICE_TRACE, + 0x8000000000000000LL); + } + spin_unlock(&adapter->afu_list_lock); +} + static const struct cxl_service_layer_ops psl9_ops = { .adapter_regs_init = init_implementation_adapter_regs_psl9, .invalidate_all = cxl_invalidate_all_psl9, -- cgit