From patchwork Tue Aug 20 05:19:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amitay Isaacs X-Patchwork-Id: 1149780 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 46CJxs2R2mz9sML for ; Tue, 20 Aug 2019 15:19:29 +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.b="gqBLuUOu"; 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 46CJxs0cQ0zDqqJ for ; Tue, 20 Aug 2019 15:19:29 +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) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 46CJxd6fddzDqpf for ; Tue, 20 Aug 2019 15:19:17 +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.b="gqBLuUOu"; 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 46CJxd03BSz9sML; Tue, 20 Aug 2019 15:19:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ozlabs.org; s=201707; t=1566278357; bh=yC1bFPAVCU6yQrUwKxStqxw/asejmb16fReA6V+glyg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gqBLuUOuukubhQLFYzDEtUTlbaJRXGVbzW7qI1+pPb1Ry259vrBBl6/KOiIKVwt7F U7YYO1DAuqVOk1QLmoMoK+D3qVH/jFpBEoI2hzaTYcSYx9Ak8pCqxveqNri8ps+cZn DXD0zj08iyNbddGWtas0aQ9HhjdJa0Ff94HQDohIwRIo/zqlQ/KIb44Ukl0ekGtUmt JWEsbg/Gk0o4fUrLEzox/chmIoL0bdIlzfN0Scw7JbGvkLybrJ9bg5ylLY0jKOXUcG 8VeJUqTmqeVDSmDhqYPpI6SA+/rU3B+owm5BbxAk++dr3o7t4svQIRU4lrSj3YEWL7 jjWIPOqk5tEkw== From: Amitay Isaacs To: pdbg@lists.ozlabs.org Date: Tue, 20 Aug 2019 15:19:11 +1000 Message-Id: <20190820051913.17295-2-amitay@ozlabs.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190820051913.17295-1-amitay@ozlabs.org> References: <20190820051913.17295-1-amitay@ozlabs.org> MIME-Version: 1.0 Subject: [Pdbg] [PATCH 1/3] libsbefifo: Add a library to talk to sbefifo 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: , Cc: Amitay Isaacs Errors-To: pdbg-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Pdbg" Signed-off-by: Amitay Isaacs --- Makefile.am | 18 ++- libsbefifo/cmd_array.c | 100 ++++++++++++++ libsbefifo/cmd_control.c | 50 +++++++ libsbefifo/cmd_generic.c | 169 ++++++++++++++++++++++++ libsbefifo/cmd_instruction.c | 54 ++++++++ libsbefifo/cmd_memory.c | 243 +++++++++++++++++++++++++++++++++++ libsbefifo/cmd_mpipl.c | 102 +++++++++++++++ libsbefifo/cmd_register.c | 115 +++++++++++++++++ libsbefifo/cmd_ring.c | 119 +++++++++++++++++ libsbefifo/cmd_scom.c | 147 +++++++++++++++++++++ libsbefifo/connect.c | 74 +++++++++++ libsbefifo/ffdc.c | 151 ++++++++++++++++++++++ libsbefifo/libsbefifo.h | 116 +++++++++++++++++ libsbefifo/operation.c | 149 +++++++++++++++++++++ libsbefifo/sbefifo_private.h | 88 +++++++++++++ 15 files changed, 1694 insertions(+), 1 deletion(-) create mode 100644 libsbefifo/cmd_array.c create mode 100644 libsbefifo/cmd_control.c create mode 100644 libsbefifo/cmd_generic.c create mode 100644 libsbefifo/cmd_instruction.c create mode 100644 libsbefifo/cmd_memory.c create mode 100644 libsbefifo/cmd_mpipl.c create mode 100644 libsbefifo/cmd_register.c create mode 100644 libsbefifo/cmd_ring.c create mode 100644 libsbefifo/cmd_scom.c create mode 100644 libsbefifo/connect.c create mode 100644 libsbefifo/ffdc.c create mode 100644 libsbefifo/libsbefifo.h create mode 100644 libsbefifo/operation.c create mode 100644 libsbefifo/sbefifo_private.h diff --git a/Makefile.am b/Makefile.am index 011e686..f850a29 100644 --- a/Makefile.am +++ b/Makefile.am @@ -129,7 +129,7 @@ pdbg_LDADD = libpdbg.la libccan.a \ pdbg_LDFLAGS = -Wl,--whole-archive,-lpdbg,--no-whole-archive lib_LTLIBRARIES = libpdbg.la -noinst_LTLIBRARIES = libcronus.la +noinst_LTLIBRARIES = libcronus.la libsbefifo.la libcronus_la_SOURCES = \ libcronus/buffer.c \ @@ -142,6 +142,22 @@ libcronus_la_SOURCES = \ libcronus/request.c \ libcronus/scom.c +libsbefifo_la_SOURCES = \ + libsbefifo/cmd_array.c \ + libsbefifo/cmd_control.c \ + libsbefifo/cmd_generic.c \ + libsbefifo/cmd_instruction.c \ + libsbefifo/cmd_memory.c \ + libsbefifo/cmd_mpipl.c \ + libsbefifo/cmd_register.c \ + libsbefifo/cmd_ring.c \ + libsbefifo/cmd_scom.c \ + libsbefifo/connect.c \ + libsbefifo/ffdc.c \ + libsbefifo/libsbefifo.h \ + libsbefifo/operation.c \ + libsbefifo/sbefifo_private.h + libpdbg_la_SOURCES = \ $(DT_sources) \ libpdbg/adu.c \ diff --git a/libsbefifo/cmd_array.c b/libsbefifo/cmd_array.c new file mode 100644 index 0000000..c5f5eec --- /dev/null +++ b/libsbefifo/cmd_array.c @@ -0,0 +1,100 @@ +/* Copyright 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 "libsbefifo.h" +#include "sbefifo_private.h" + +int sbefifo_control_fast_array(struct sbefifo_context *sctx, uint16_t target_type, uint8_t chiplet_id, uint8_t mode, uint64_t clock_cycle) +{ + uint8_t *out; + uint32_t msg[3]; + uint32_t cmd, out_len; + uint32_t target; + int rc; + + cmd = SBEFIFO_CMD_CLASS_ARRAY | SBEFIFO_CMD_FAST_ARRAY; + target = ((uint32_t)target_type << 16) | + ((uint32_t)chiplet_id << 8) | + ((uint32_t)(mode & 0x3)); + + msg[0] = htobe32(3); // number of words + msg[1] = htobe32(cmd); + msg[2] = htobe32(target); + + out_len = 0; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 3 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != 0) { + free(out); + return EPROTO; + } + + return 0; +} + +int sbefifo_control_trace_array(struct sbefifo_context *sctx, uint16_t target_type, uint8_t chiplet_id, uint16_t array_id, uint16_t operation, uint8_t **trace_data, uint32_t *trace_data_len) +{ + uint8_t *out; + uint32_t msg[4]; + uint32_t cmd, out_len; + uint32_t target, oper; + int rc; + + cmd = SBEFIFO_CMD_CLASS_ARRAY | SBEFIFO_CMD_TRACE_ARRAY; + target = ((uint32_t)target_type << 16) | ((uint32_t)chiplet_id); + oper = ((uint32_t)array_id << 16) | ((uint32_t)operation); + + msg[0] = htobe32(4); // number of words + msg[1] = htobe32(cmd); + msg[2] = htobe32(target); + msg[3] = htobe32(oper); + + out_len = 16 * 4; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 4 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len < 4) { + free(out); + return EPROTO; + } + + *trace_data_len = 4 * be32toh(*(uint32_t *) &out[out_len-4]); + + if (out_len != *trace_data_len + 4) { + free(out); + return EPROTO; + } + + *trace_data = malloc(*trace_data_len); + if (! *trace_data) { + free(out); + return ENOMEM; + } + + memcpy(*trace_data, out, *trace_data_len); + + free(out); + return 0; +} diff --git a/libsbefifo/cmd_control.c b/libsbefifo/cmd_control.c new file mode 100644 index 0000000..abbfd73 --- /dev/null +++ b/libsbefifo/cmd_control.c @@ -0,0 +1,50 @@ +/* Copyright 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 "libsbefifo.h" +#include "sbefifo_private.h" + +int sbefifo_istep_execute(struct sbefifo_context *sctx, uint8_t major, uint8_t minor) +{ + uint8_t *out; + uint32_t msg[3]; + uint32_t cmd, step, out_len; + int rc; + + cmd = SBEFIFO_CMD_CLASS_CONTROL | SBEFIFO_CMD_EXECUTE_ISTEP; + step = (major << 16) | minor; + + msg[0] = htobe32(3); // number of words + msg[1] = htobe32(cmd); + msg[2] = htobe32(step); + + out_len = 0; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 3 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != 0) { + free(out); + return EPROTO; + } + + return 0; +} diff --git a/libsbefifo/cmd_generic.c b/libsbefifo/cmd_generic.c new file mode 100644 index 0000000..f912e92 --- /dev/null +++ b/libsbefifo/cmd_generic.c @@ -0,0 +1,169 @@ +/* Copyright 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 "libsbefifo.h" +#include "sbefifo_private.h" + +int sbefifo_get_ffdc(struct sbefifo_context *sctx, uint8_t **ffdc, uint32_t *ffdc_len) +{ + uint8_t *out; + uint32_t msg[2]; + uint32_t cmd, out_len; + int rc; + + cmd = SBEFIFO_CMD_CLASS_GENERIC | SBEFIFO_CMD_GET_FFDC; + + msg[0] = htobe32(2); // number of words + msg[1] = htobe32(cmd); + + /* We don't know how much data to expect, let's assume it's less than 32K */ + out_len = 0x8000; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 2 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + *ffdc_len = out_len; + if (out_len > 0) { + *ffdc = malloc(out_len); + if (! *ffdc) { + free(out); + return ENOMEM; + } + memcpy(*ffdc, out, out_len); + + free(out); + } else { + *ffdc = NULL; + } + + return 0; +} + +int sbefifo_get_capabilities(struct sbefifo_context *sctx, uint32_t *version, char **commit_id, uint32_t **caps, uint32_t *caps_count) +{ + uint8_t *out; + uint32_t msg[2]; + uint32_t cmd, out_len; + uint32_t i; + int rc; + + cmd = SBEFIFO_CMD_CLASS_GENERIC | SBEFIFO_CMD_GET_CAPABILITY; + + msg[0] = htobe32(2); // number of words + msg[1] = htobe32(cmd); + + out_len = 23 * 4; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 2 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != 23 * 4) { + free(out); + return EPROTO; + } + + *version = be32toh(*(uint32_t *) &out[0]); + + *commit_id = malloc(9); + if (! *commit_id) { + free(out); + return ENOMEM; + } + memcpy(*commit_id, &out[4], 8); + (*commit_id)[8] = '\0'; + + *caps = malloc(20 * 4); + if (! *caps) { + free(out); + return ENOMEM; + } + + *caps_count = 20; + for (i=0; i<20; i++) + (*caps)[i] = be32toh(*(uint32_t *) &out[12+i*4]); + + free(out); + return 0; +} + +int sbefifo_get_frequencies(struct sbefifo_context *sctx, uint32_t **freq, uint32_t *freq_count) +{ + uint8_t *out; + uint32_t msg[2]; + uint32_t cmd, out_len; + int rc; + + cmd = SBEFIFO_CMD_CLASS_GENERIC | SBEFIFO_CMD_GET_FREQUENCY; + + msg[0] = htobe32(2); // number of words + msg[1] = htobe32(cmd); + + out_len = 8 * 4; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 2 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + *freq_count = out_len / 4; + if (*freq_count > 0) { + uint32_t i; + + *freq = malloc(*freq_count * 4); + if (! *freq) { + free(out); + return ENOMEM; + } + + for (i=0; i<*freq_count; i++) + (*freq)[i] = be32toh(*(uint32_t *) &out[i*4]); + + free(out); + } else { + *freq = NULL; + } + + return 0; +} + +int sbefifo_quiesce(struct sbefifo_context *sctx) +{ + uint8_t *out; + uint32_t msg[2]; + uint32_t cmd, out_len; + int rc; + + cmd = SBEFIFO_CMD_CLASS_GENERIC | SBEFIFO_CMD_GET_FREQUENCY; + + msg[0] = htobe32(2); // number of words + msg[1] = htobe32(cmd); + + out_len = 0; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 2 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != 0) { + free(out); + return EPROTO; + } + + return 0; +} diff --git a/libsbefifo/cmd_instruction.c b/libsbefifo/cmd_instruction.c new file mode 100644 index 0000000..5185982 --- /dev/null +++ b/libsbefifo/cmd_instruction.c @@ -0,0 +1,54 @@ +/* Copyright 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 "libsbefifo.h" +#include "sbefifo_private.h" + +int sbefifo_control_insn(struct sbefifo_context *sctx, uint8_t core_id, uint8_t thread_id, uint8_t thread_op, uint8_t mode) +{ + uint8_t *out; + uint32_t msg[3]; + uint32_t cmd, out_len; + uint32_t oper; + int rc; + + cmd = SBEFIFO_CMD_CLASS_INSTRUCTION | SBEFIFO_CMD_CONTROL_INSN; + oper = ((uint32_t)(mode & 0xf) << 16) | + ((uint32_t)(core_id & 0xff) << 8) | + ((uint32_t)(thread_id & 0xf) << 4) | + ((uint32_t)(thread_op & 0xf)); + + msg[0] = htobe32(3); // number of words + msg[1] = htobe32(cmd); + msg[2] = htobe32(oper); + + out_len = 0; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 3 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != 0) { + free(out); + return EPROTO; + } + + return 0; +} diff --git a/libsbefifo/cmd_memory.c b/libsbefifo/cmd_memory.c new file mode 100644 index 0000000..b20767f --- /dev/null +++ b/libsbefifo/cmd_memory.c @@ -0,0 +1,243 @@ +/* Copyright 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 + +#include "libsbefifo.h" +#include "sbefifo_private.h" + +int sbefifo_mem_get(struct sbefifo_context *sctx, uint64_t addr, uint32_t size, uint16_t flags, uint8_t **data) +{ + uint8_t *out; + uint64_t start_addr, end_addr; + uint32_t msg[6]; + uint32_t cmd, out_len; + uint32_t align, offset, len, extra_bytes, i, j; + int rc; + bool do_tag = false, do_ecc = false; + + if (flags & SBEFIFO_MEMORY_FLAG_PROC) { + align = 8; + + if (flags & SBEFIFO_MEMORY_FLAG_ECC_REQ) + do_ecc = true; + + if (flags & SBEFIFO_MEMORY_FLAG_TAG_REQ) + do_tag = true; + + } else if (flags & SBEFIFO_MEMORY_FLAG_PBA) { + align = 128; + } else { + return EINVAL; + } + + start_addr = addr & (~(uint64_t)(align-1)); + end_addr = (addr + size + (align-1)) & (~(uint64_t)(align-1)); + + if (end_addr - start_addr > 0xffffffff) + return EINVAL; + + offset = addr - start_addr; + len = end_addr - start_addr; + + extra_bytes = 0; + if (do_tag) + extra_bytes = len / 8; + + if (do_ecc) + extra_bytes = len / 8; + + cmd = SBEFIFO_CMD_CLASS_MEMORY | SBEFIFO_CMD_GET_MEMORY; + + msg[0] = htobe32(6); // number of words + msg[1] = htobe32(cmd); + msg[2] = htobe32(flags); + msg[3] = htobe32(start_addr >> 32); + msg[4] = htobe32(start_addr & 0xffffffff); + msg[5] = htobe32(len); + + out_len = len + extra_bytes + 4; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 6 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != len + extra_bytes + 4) { + free(out); + return EPROTO; + } + + len = be32toh(*(uint32_t *) &out[out_len-4]); + *data = malloc(len); + if (! *data) { + free(out); + return ENOMEM; + } + + i = 0; + j = 0; + while (i < len) { + memcpy((void *)&(*data)[j], (void *)&out[i], 8); + i += 8; + j += 8; + + if (do_tag) + i++; + + if (do_ecc) + i++; + } + if (i < len) + memcpy((void *)&(*data)[j], (void *)&out[i], len - i); + + memmove(*data, *data + offset, size); + + free(out); + return 0; +} + +int sbefifo_mem_put(struct sbefifo_context *sctx, uint64_t addr, uint8_t *data, uint32_t data_len, uint16_t flags) +{ + uint8_t *out; + uint32_t nwords = (data_len+3)/4; + uint32_t msg[6+nwords]; + uint32_t cmd, out_len; + uint32_t align; + int rc; + + if (flags & SBEFIFO_MEMORY_FLAG_PROC) + align = 8; + else if (flags & SBEFIFO_MEMORY_FLAG_PBA) + align = 128; + else + return EINVAL; + + if (addr & (align-1)) + return EINVAL; + + cmd = SBEFIFO_CMD_CLASS_MEMORY | SBEFIFO_CMD_PUT_MEMORY; + + msg[0] = htobe32(6 + nwords); // number of words + msg[1] = htobe32(cmd); + msg[2] = htobe32(flags); + msg[3] = htobe32(addr >> 32); + msg[4] = htobe32(addr & 0xffffffff); + msg[5] = htobe32(data_len); + memcpy(&msg[6], data, data_len); + + out_len = 1 * 4; + rc = sbefifo_operation(sctx, (uint8_t *)msg, (6+nwords) * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != 4) { + free(out); + return EPROTO; + } + + free(out); + return 0; +} + +int sbefifo_occsram_get(struct sbefifo_context *sctx, uint32_t addr, uint32_t size, uint8_t mode, uint8_t **data, uint32_t *data_len) +{ + uint8_t *out; + uint32_t start_addr, end_addr; + uint32_t msg[5]; + uint32_t cmd, out_len; + uint32_t align, offset, len; + int rc; + + align = 8; + start_addr = addr & (~(uint32_t)(align-1)); + end_addr = (addr + size + (align-1)) & (~(uint32_t)(align-1)); + + offset = addr - start_addr; + len = end_addr - start_addr; + + cmd = SBEFIFO_CMD_CLASS_MEMORY | SBEFIFO_CMD_GET_OCCSRAM; + + msg[0] = htobe32(5); // number of words + msg[1] = htobe32(cmd); + msg[2] = htobe32(mode); + msg[3] = htobe32(start_addr); + msg[4] = htobe32(len); + + out_len = len + 4; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 5 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != len + 4) { + free(out); + return EPROTO; + } + + *data_len = be32toh(*(uint32_t *) &out[out_len-4]); + *data = malloc(*data_len); + if (! *data) { + free(out); + return ENOMEM; + } + memcpy(*data, out + offset, size); + + free(out); + return 0; +} + +int sbefifo_occsram_put(struct sbefifo_context *sctx, uint32_t addr, uint8_t *data, uint32_t data_len, uint8_t mode) +{ + uint8_t *out; + uint32_t nwords = (data_len+3)/4; + uint32_t msg[5+nwords]; + uint32_t cmd, out_len; + uint32_t align; + int rc; + + align = 8; + + if (addr & (align-1)) + return EINVAL; + + if (data_len & (align-1)) + return EINVAL; + + cmd = SBEFIFO_CMD_CLASS_MEMORY | SBEFIFO_CMD_PUT_OCCSRAM; + + msg[0] = htobe32(5 + nwords); // number of words + msg[1] = htobe32(cmd); + msg[2] = htobe32(mode); + msg[3] = htobe32(addr); + msg[4] = htobe32(data_len); + memcpy(&msg[6], data, data_len); + + out_len = 4; + rc = sbefifo_operation(sctx, (uint8_t *)msg, (5+nwords) * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != 4) { + free(out); + return EPROTO; + } + + free(out); + return 0; +} diff --git a/libsbefifo/cmd_mpipl.c b/libsbefifo/cmd_mpipl.c new file mode 100644 index 0000000..b5f9ea5 --- /dev/null +++ b/libsbefifo/cmd_mpipl.c @@ -0,0 +1,102 @@ +/* Copyright 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 "libsbefifo.h" +#include "sbefifo_private.h" + +int sbefifo_mpipl_enter(struct sbefifo_context *sctx) +{ + uint8_t *out; + uint32_t msg[2]; + uint32_t cmd, out_len; + int rc; + + cmd = SBEFIFO_CMD_CLASS_MPIPL | SBEFIFO_CMD_ENTER_MPIPL; + + msg[0] = htobe32(2); // number of words + msg[1] = htobe32(cmd); + + out_len = 0; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 2 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != 0) { + free(out); + return EPROTO; + } + + return 0; +} + +int sbefifo_mpipl_continue(struct sbefifo_context *sctx) +{ + uint8_t *out; + uint32_t msg[2]; + uint32_t cmd, out_len; + int rc; + + cmd = SBEFIFO_CMD_CLASS_MPIPL | SBEFIFO_CMD_CONTINUE_MPIPL; + + msg[0] = htobe32(2); // number of words + msg[1] = htobe32(cmd); + + out_len = 0; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 2 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != 0) { + free(out); + return EPROTO; + } + + return 0; +} + +int sbefifo_mpipl_stopclocks(struct sbefifo_context *sctx, uint16_t target_type, uint8_t chiplet_id) +{ + uint8_t *out; + uint32_t msg[3]; + uint32_t cmd, out_len; + uint32_t target; + int rc; + + cmd = SBEFIFO_CMD_CLASS_GENERIC | SBEFIFO_CMD_STOP_CLOCKS; + target = ((uint32_t)target_type << 16) | chiplet_id; + + msg[0] = htobe32(3); // number of words + msg[1] = htobe32(cmd); + msg[2] = htobe32(target); + + out_len = 0; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 3 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != 0) { + free(out); + return EPROTO; + } + + return 0; +} diff --git a/libsbefifo/cmd_register.c b/libsbefifo/cmd_register.c new file mode 100644 index 0000000..201ceb5 --- /dev/null +++ b/libsbefifo/cmd_register.c @@ -0,0 +1,115 @@ +/* Copyright 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 "libsbefifo.h" +#include "sbefifo_private.h" + +int sbefifo_register_get(struct sbefifo_context *sctx, uint8_t core_id, uint8_t thread_id, uint8_t reg_type, uint8_t *reg_id, uint8_t reg_count, uint64_t **value) +{ + uint8_t *out; + uint32_t msg[3+reg_count]; + uint32_t cmd, out_len; + uint32_t r, i; + int rc; + + if (reg_count == 0 || reg_count > 64) + return EINVAL; + + cmd = SBEFIFO_CMD_CLASS_REGISTER | SBEFIFO_CMD_GET_REGISTER; + r = ((uint32_t)(core_id & 0xff) << 16) | + ((uint32_t)(thread_id & 0x3) << 12) | + ((uint32_t)(reg_type & 0x3) << 8) | + ((uint32_t)(reg_count & 0xff)); + + msg[0] = htobe32(3+reg_count); // number of words + msg[1] = htobe32(cmd); + msg[2] = htobe32(r); + for (i=0; i 64) + return EINVAL; + + cmd = SBEFIFO_CMD_CLASS_REGISTER | SBEFIFO_CMD_PUT_REGISTER; + r = ((uint32_t)(core_id & 0xff) << 16) | + ((uint32_t)(thread_id & 0x3) << 12) | + ((uint32_t)(reg_type & 0x3) << 8) | + ((uint32_t)(reg_count & 0xff)); + + msg[0] = htobe32(3 + 3*reg_count); // number of words + msg[1] = htobe32(cmd); + msg[2] = htobe32(r); + for (i=0; i> 32); + msg[3+i*3+2] = htobe32(value[i] & 0xffffffff); + } + + out_len = 0; + rc = sbefifo_operation(sctx, (uint8_t *)msg, (3+3*reg_count) * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != 0) { + free(out); + return EPROTO; + } + + return 0; +} diff --git a/libsbefifo/cmd_ring.c b/libsbefifo/cmd_ring.c new file mode 100644 index 0000000..70478e3 --- /dev/null +++ b/libsbefifo/cmd_ring.c @@ -0,0 +1,119 @@ +/* Copyright 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 "libsbefifo.h" +#include "sbefifo_private.h" + +int sbefifo_ring_get(struct sbefifo_context *sctx, uint32_t ring_addr, uint32_t ring_len_bits, uint16_t flags, uint8_t **ring_data, uint32_t *ring_len) +{ + uint8_t *out; + uint32_t msg[5]; + uint32_t cmd, out_len; + int rc; + + cmd = SBEFIFO_CMD_CLASS_RING | SBEFIFO_CMD_GET_RING; + + msg[0] = htobe32(5); // number of words + msg[1] = htobe32(cmd); + msg[2] = htobe32(ring_addr); + msg[3] = htobe32(ring_len_bits); + msg[4] = htobe32(flags); + + /* multiples of 64 bits */ + out_len = (ring_len_bits + 63) / 8; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 5 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len*8 < ring_len_bits) { + free(out); + return EPROTO; + } + + *ring_len = be32toh(*(uint32_t *) &out[out_len-4]); + *ring_data = malloc(*ring_len); + if (! *ring_data) { + free(out); + return ENOMEM; + } + memcpy(*ring_data, out, *ring_len); + + free(out); + return 0; +} + +int sbefifo_ring_put(struct sbefifo_context *sctx, uint16_t ring_mode, uint8_t *ring_data, uint32_t ring_data_len) +{ + uint8_t *out; + uint32_t nwords = (ring_data_len + 3) / 4; + uint32_t msg[3+nwords]; + uint32_t cmd, out_len; + int rc; + + cmd = SBEFIFO_CMD_CLASS_RING | SBEFIFO_CMD_PUT_RING; + + msg[0] = htobe32(3 + nwords); // number of words + msg[1] = htobe32(cmd); + msg[2] = htobe32(ring_mode); + memcpy(&msg[3], ring_data, ring_data_len); + + out_len = 0; + rc = sbefifo_operation(sctx, (uint8_t *)msg, (3+nwords) * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != 0) { + free(out); + return EPROTO; + } + + return 0; +} + +int sbefifo_ring_put_from_image(struct sbefifo_context *sctx, uint16_t target, uint8_t chiplet_id, uint16_t ring_id, uint16_t ring_mode) +{ + uint8_t *out; + uint32_t msg[3]; + uint32_t cmd, out_len; + uint32_t target_word, ring_word; + int rc; + + cmd = SBEFIFO_CMD_CLASS_RING | SBEFIFO_CMD_PUT_RING_IMAGE; + target_word = ((uint32_t)target << 16) | (uint32_t)chiplet_id; + ring_word = ((uint32_t)ring_id << 16) | (uint32_t)ring_mode; + + msg[0] = htobe32(3); // number of words + msg[1] = htobe32(target_word); + msg[2] = htobe32(ring_word); + + out_len = 0; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 3 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != 0) { + free(out); + return EPROTO; + } + + return 0; +} diff --git a/libsbefifo/cmd_scom.c b/libsbefifo/cmd_scom.c new file mode 100644 index 0000000..cc236ca --- /dev/null +++ b/libsbefifo/cmd_scom.c @@ -0,0 +1,147 @@ +/* Copyright 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 "libsbefifo.h" +#include "sbefifo_private.h" + +int sbefifo_scom_get(struct sbefifo_context *sctx, uint64_t addr, uint64_t *value) +{ + uint8_t *out; + uint32_t msg[4]; + uint32_t cmd, out_len; + uint32_t val1, val2; + int rc; + + cmd = SBEFIFO_CMD_CLASS_SCOM | SBEFIFO_CMD_GET_SCOM; + + msg[0] = htobe32(4); // number of words + msg[1] = htobe32(cmd); + msg[2] = htobe32(addr >> 32); + msg[3] = htobe32(addr & 0xffffffff); + + out_len = 2 * 4; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 4 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != 2 * 4) { + free(out); + return EPROTO; + } + + val1 = be32toh(*(uint32_t *) &out[0]); + val2 = be32toh(*(uint32_t *) &out[4]); + free(out); + + *value = ((uint64_t)val1 << 32) | (uint64_t)val2; + + return 0; +} + +int sbefifo_scom_put(struct sbefifo_context *sctx, uint64_t addr, uint64_t value) +{ + uint8_t *out; + uint32_t msg[6]; + uint32_t cmd, out_len; + int rc; + + cmd = SBEFIFO_CMD_CLASS_SCOM | SBEFIFO_CMD_PUT_SCOM; + + msg[0] = htobe32(6); // number of words + msg[1] = htobe32(cmd); + msg[2] = htobe32(addr >> 32); + msg[3] = htobe32(addr & 0xffffffff); + msg[2] = htobe32(value >> 32); + msg[3] = htobe32(value & 0xffffffff); + + out_len = 0; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 6 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != 0) { + free(out); + return EPROTO; + } + + return 0; +} + +int sbefifo_scom_modify(struct sbefifo_context *sctx, uint64_t addr, uint64_t value, uint8_t operand) +{ + uint8_t *out; + uint32_t msg[7]; + uint32_t cmd, out_len; + int rc; + + cmd = SBEFIFO_CMD_CLASS_SCOM | SBEFIFO_CMD_MODIFY_SCOM; + + msg[0] = htobe32(7); // number of words + msg[1] = htobe32(cmd); + msg[2] = htobe32(operand); + msg[3] = htobe32(addr >> 32); + msg[4] = htobe32(addr & 0xffffffff); + msg[5] = htobe32(value >> 32); + msg[6] = htobe32(value & 0xffffffff); + + out_len = 0; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 7 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != 0) { + free(out); + return EPROTO; + } + + return 0; +} + +int sbefifo_scom_put_mask(struct sbefifo_context *sctx, uint64_t addr, uint64_t value, uint64_t mask) +{ + uint8_t *out; + uint32_t msg[8]; + uint32_t cmd, out_len; + int rc; + + cmd = SBEFIFO_CMD_CLASS_SCOM | SBEFIFO_CMD_PUT_SCOM_MASK; + + msg[0] = htobe32(8); // number of words + msg[1] = htobe32(cmd); + msg[2] = htobe32(addr >> 32); + msg[3] = htobe32(addr & 0xffffffff); + msg[4] = htobe32(value >> 32); + msg[5] = htobe32(value & 0xffffffff); + msg[6] = htobe32(mask >> 32); + msg[7] = htobe32(mask & 0xffffffff); + + out_len = 0; + rc = sbefifo_operation(sctx, (uint8_t *)msg, 8 * 4, cmd, &out, &out_len); + if (rc) + return rc; + + if (out_len != 0) { + free(out); + return EPROTO; + } + + return 0; +} diff --git a/libsbefifo/connect.c b/libsbefifo/connect.c new file mode 100644 index 0000000..08194e1 --- /dev/null +++ b/libsbefifo/connect.c @@ -0,0 +1,74 @@ +/* Copyright 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 + +#include "libsbefifo.h" +#include "sbefifo_private.h" + +int sbefifo_connect(const char *fifo_path, struct sbefifo_context **out) +{ + struct sbefifo_context *sctx; + int fd, rc; + + sctx = malloc(sizeof(struct sbefifo_context)); + if (!sctx) { + fprintf(stderr, "Memory allocation error\n"); + return ENOMEM; + } + + *sctx = (struct sbefifo_context) { + .fd = -1, + }; + + fd = open(fifo_path, O_RDWR | O_SYNC); + if (fd < 0) { + rc = errno; + fprintf(stderr, "Error opening fifo %s\n", fifo_path); + free(sctx); + return rc; + } + + sctx->fd = fd; + + *out = sctx; + return 0; +} + +void sbefifo_disconnect(struct sbefifo_context *sctx) +{ + if (sctx->fd != -1) + close(sctx->fd); + + if (sctx->ffdc) + free(sctx->ffdc); + + free(sctx); +} + +void sbefifo_debug(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} diff --git a/libsbefifo/ffdc.c b/libsbefifo/ffdc.c new file mode 100644 index 0000000..f29afc1 --- /dev/null +++ b/libsbefifo/ffdc.c @@ -0,0 +1,151 @@ +/* Copyright 2016 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 "sbefifo_private.h" + +void sbefifo_ffdc_clear(struct sbefifo_context *sctx) +{ + sctx->status = 0; + + if (sctx->ffdc) { + free(sctx->ffdc); + sctx->ffdc = NULL; + sctx->ffdc_len = 0; + } +} + +void sbefifo_ffdc_set(struct sbefifo_context *sctx, uint32_t status, uint8_t *ffdc, uint32_t ffdc_len) +{ + sctx->status = status; + + sctx->ffdc = malloc(ffdc_len); + if (!sctx->ffdc) { + fprintf(stderr, "Memory allocation error\n"); + return; + } + + memcpy(sctx->ffdc, ffdc, ffdc_len); + sctx->ffdc_len = ffdc_len; +} + +uint32_t sbefifo_ffdc_get(struct sbefifo_context *sctx, const uint8_t **ffdc, uint32_t *ffdc_len) +{ + *ffdc = sctx->ffdc; + *ffdc_len = sctx->ffdc_len; + + return sctx->status; +} + +static int sbefifo_ffdc_get_uint32(struct sbefifo_context *sctx, uint32_t offset, uint32_t *value) +{ + uint32_t v; + + if (offset + 4 > sctx->ffdc_len) + return -1; + + memcpy(&v, sctx->ffdc + offset, 4); + *value = be32toh(v); + + return 0; +} + +static int sbefifo_ffdc_dump_pkg(struct sbefifo_context *sctx, uint32_t offset) +{ + uint32_t offset2 = offset; + uint32_t header, value; + uint16_t magic, len_words; + int i, rc; + + rc = sbefifo_ffdc_get_uint32(sctx, offset2, &header); + if (rc < 0) + return -1; + offset2 += 4; + + /* + * FFDC package structure + * + * +----------+----------+----------+----------+ + * | Byte 0 | Byte 1 | Byte 2 | Byte 3 | + * +----------+----------+----------+----------+----------+ + * | word 0 | magic | length in words (N) | + * +----------+---------------------+---------------------+ + * | word 1 | sequence id | command | + * +----------+---------------------+---------------------+ + * | word 2 | return code | + * +----------+-------------------------------------------+ + * | word 3 | FFDC Data - word 0 | + * +----------+-------------------------------------------+ + * | word 4 | FFDC Data - word 1 | + * +----------+-------------------------------------------+ + * | ... | ... | + * +----------+-------------------------------------------+ + * | word N | FFDC Data - word N-3 | + * +----------+----------+----------+----------+----------+ + */ + + magic = header >> 16; + if (magic != 0xffdc) { + fprintf(stderr, "sbefifo: ffdc expected 0xffdc, got 0x%04x\n", magic); + return -1; + } + + len_words = header & 0xffff; + + rc = sbefifo_ffdc_get_uint32(sctx, offset2, &value); + if (rc < 0) + return -1; + offset2 += 4; + + printf("FFDC: Sequence = %u\n", value >> 16); + printf("FFDC: Command = 0x%08x\n", value & 0xffff); + + rc = sbefifo_ffdc_get_uint32(sctx, offset2, &value); + if (rc < 0) + return -1; + offset2 += 4; + + printf("FFDC: RC = 0x%08x\n", value); + + for (i=0; iffdc_len) { + int n; + + n = sbefifo_ffdc_dump_pkg(sctx, offset); + if (n <= 0) + break; + + offset += n; + } +} diff --git a/libsbefifo/libsbefifo.h b/libsbefifo/libsbefifo.h new file mode 100644 index 0000000..84b0169 --- /dev/null +++ b/libsbefifo/libsbefifo.h @@ -0,0 +1,116 @@ +/* Copyright 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. + */ + +#ifndef __LIBSBEFIFO_H__ +#define __LIBSBEFIFO_H__ + +#include + +#define SBEFIFO_PRI_SUCCESS 0x00000000 +#define SBEFIFO_PRI_INVALID_COMMAND 0x00010000 +#define SBEFIFO_PRI_INVALID_DATA 0x00020000 +#define SBEFIFO_PRI_SEQUENCE_ERROR 0x00030000 +#define SBEFIFO_PRI_INTERNAL_ERROR 0x00040000 +#define SBEFIFO_PRI_UNKNOWN_ERROR 0x00FE0000 + +#define SBEFIFO_SEC_SUCCESS 0x0000 +#define SBEFIFO_SEC_INVALID_CMD_CLASS 0x0001 +#define SBEFIFO_SEC_INVALID_CMD 0x0002 +#define SBEFIFO_SEC_INVALID_ADDRESS 0x0003 +#define SBEFIFO_SEC_INVALID_TARGET 0x0004 +#define SBEFIFO_SEC_INVALID_CHIPLET 0x0005 +#define SBEFIFO_SEC_TARGET_NOT_PRESENT 0x0006 +#define SBEFIFO_SEC_TARGET_NOT_FUNCTIONAL 0x0007 +#define SBEFIFO_SEC_CMD_NOT_ALLOWED 0x0008 +#define SBEFIFO_SEC_INVALID_FUNCTION 0x0009 +#define SBEFIFO_SEC_GENERIC_FAILURE 0x000A +#define SBEFIFO_SEC_INVALID_ACCESS 0x000B +#define SBEFIFO_SEC_SBE_OS_FAIL 0x000C +#define SBEFIFO_SEC_SBE_ACCESS_FAIL 0x000D +#define SBEFIFO_SEC_MISSING_DATA 0x000E +#define SBEFIFO_SEC_EXTRA_DATA 0x000F +#define SBEFIFO_SEC_HW_TIMEOUT 0x0010 +#define SBEFIFO_SEC_PIB_ERROR 0x0011 +#define SBEFIFO_SEC_PARITY_ERROR 0x0012 + +struct sbefifo_context; + +int sbefifo_connect(const char *fifo_path, struct sbefifo_context **out); +void sbefifo_disconnect(struct sbefifo_context *sctx); + +uint32_t sbefifo_ffdc_get(struct sbefifo_context *sctx, const uint8_t **ffdc, uint32_t *ffdc_len); +void sbefifo_ffdc_dump(struct sbefifo_context *sctx); + +int sbefifo_istep_execute(struct sbefifo_context *sctx, uint8_t major, uint8_t minor); + +#define SBEFIFO_SCOM_OPERAND_NONE 0 +#define SBEFIFO_SCOM_OPERAND_OR 1 +#define SBEFIFO_SCOM_OPERAND_AND 2 +#define SBEFIFO_SCOM_OPERAND_XOR 3 + +int sbefifo_scom_get(struct sbefifo_context *sctx, uint64_t addr, uint64_t *value); +int sbefifo_scom_put(struct sbefifo_context *sctx, uint64_t addr, uint64_t value); +int sbefifo_scom_modify(struct sbefifo_context *sctx, uint64_t addr, uint64_t value, uint8_t operand); +int sbefifo_scom_put_mask(struct sbefifo_context *sctx, uint64_t addr, uint64_t value, uint64_t mask); + +int sbefifo_ring_get(struct sbefifo_context *sctx, uint32_t ring_addr, uint32_t ring_len_bits, uint16_t flags, uint8_t **ring_data, uint32_t *ring_len); +int sbefifo_ring_put(struct sbefifo_context *sctx, uint16_t ring_mode, uint8_t *ring_data, uint32_t ring_data_len); +int sbefifo_ring_put_from_image(struct sbefifo_context *sctx, uint16_t target, uint8_t chiplet_id, uint16_t ring_id, uint16_t ring_mode); + +#define SBEFIFO_MEMORY_FLAG_PROC 0x0001 +#define SBEFIFO_MEMORY_FLAG_PBA 0x0002 +#define SBEFIFO_MEMORY_FLAG_AUTO_INCR 0x0004 +#define SBEFIFO_MEMORY_FLAG_ECC_REQ 0x0008 +#define SBEFIFO_MEMORY_FLAG_TAG_REQ 0x0010 +#define SBEFIFO_MEMORY_FLAG_FAST_MODE 0x0020 +#define SBEFIFO_MEMORY_FLAG_LCO_MODE 0x0040 // only for mem_put +#define SBEFIFO_MEMORY_FLAG_CI 0x0080 +#define SBEFIFO_MEMORY_FLAG_PASSTHRU 0x0100 +#define SBEFIFO_MEMORY_FLAG_CACHEINJECT 0x0200 // only for mem_put + +int sbefifo_mem_get(struct sbefifo_context *sctx, uint64_t addr, uint32_t size, uint16_t flags, uint8_t **data); +int sbefifo_mem_put(struct sbefifo_context *sctx, uint64_t addr, uint8_t *data, uint32_t len, uint16_t flags); +int sbefifo_occsram_get(struct sbefifo_context *sctx, uint32_t addr, uint32_t size, uint8_t mode, uint8_t **data, uint32_t *data_len); +int sbefifo_occsram_put(struct sbefifo_context *sctx, uint32_t addr, uint8_t *data, uint32_t data_len, uint8_t mode); + +#define SBEFIFO_REGISTER_TYPE_GPR 0x0 +#define SBEFIFO_REGISTER_TYPE_SPR 0x1 +#define SBEFIFO_REGISTER_TYPE_FPR 0x2 + +int sbefifo_register_get(struct sbefifo_context *sctx, uint8_t core_id, uint8_t thread_id, uint8_t reg_type, uint8_t *reg_id, uint8_t reg_count, uint64_t **value); +int sbefifo_register_put(struct sbefifo_context *sctx, uint8_t core_id, uint8_t thread_id, uint8_t reg_type, uint8_t *reg_id, uint8_t reg_count, uint64_t *value); + +int sbefifo_control_fast_array(struct sbefifo_context *sctx, uint16_t target_type, uint8_t chiplet_id, uint8_t mode, uint64_t clock_cycle); +int sbefifo_control_trace_array(struct sbefifo_context *sctx, uint16_t target_type, uint8_t chiplet_id, uint16_t array_id, uint16_t operation, uint8_t **trace_data, uint32_t *trace_data_len); + +#define SBEFIFO_INSN_OP_START 0x0 +#define SBEFIFO_INSN_OP_STOP 0x1 +#define SBEFIFO_INSN_OP_STEP 0x2 +#define SBEFIFO_INSN_OP_SRESET 0x3 + +int sbefifo_control_insn(struct sbefifo_context *sctx, uint8_t core_id, uint8_t thread_id, uint8_t thread_op, uint8_t mode); + +int sbefifo_get_ffdc(struct sbefifo_context *sctx, uint8_t **ffdc, uint32_t *ffdc_len); +int sbefifo_get_capabilities(struct sbefifo_context *sctx, uint32_t *version, char **commit_id, uint32_t **caps, uint32_t *caps_count); +int sbefifo_get_frequencies(struct sbefifo_context *sctx, uint32_t **freq, uint32_t *freq_count); +int sbefifo_quiesce(struct sbefifo_context *sctx); + +int sbefifo_mpipl_enter(struct sbefifo_context *sctx); +int sbefifo_mpipl_continue(struct sbefifo_context *sctx); +int sbefifo_mpipl_stopclocks(struct sbefifo_context *sctx, uint16_t target_type, uint8_t chiplet_id); + + +#endif /* __LIBSBEFIFO_H__ */ diff --git a/libsbefifo/operation.c b/libsbefifo/operation.c new file mode 100644 index 0000000..43418a1 --- /dev/null +++ b/libsbefifo/operation.c @@ -0,0 +1,149 @@ +/* Copyright 2016 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 "sbefifo_private.h" + +static int sbefifo_read(struct sbefifo_context *sctx, void *buf, size_t *buflen) +{ + ssize_t n; + + assert(*buflen > 0); + + n = read(sctx->fd, buf, *buflen); + if (n < 0) + return errno; + + *buflen = n; + return 0; +} + +static int sbefifo_write(struct sbefifo_context *sctx, void *buf, size_t buflen) +{ + ssize_t n; + + assert(buflen > 0); + + n = write(sctx->fd, buf, buflen); + if (n < 0) + return errno; + + if (n != buflen) + return EIO; + + return 0; +} + +int sbefifo_operation(struct sbefifo_context *sctx, + uint8_t *msg, uint32_t msg_len, uint16_t cmd, + uint8_t **out, uint32_t *out_len) +{ + uint8_t *buf; + size_t buflen; + uint32_t offset_word, header_word, status_word; + uint32_t offset; + int rc; + + assert(msg); + assert(msg_len > 0); + + sbefifo_ffdc_clear(sctx); + + /* + * Allocate extra memory for FFDC (SBEFIFO_MAX_FFDC_SIZE = 0x2000) + * Use *out_len as a hint to expected reply length + */ + buflen = (*out_len + 0x2000 + 3) & ~(uint32_t)3; + buf = malloc(buflen); + if (!buf) + return ENOMEM; + + LOG("request: cmd=%08x, len=%u\n", cmd, msg_len); + + rc = sbefifo_write(sctx, msg, msg_len); + if (rc) { + LOG("write: cmd=%08x, rc=%d\n", cmd, rc); + return rc; + } + + rc = sbefifo_read(sctx, buf, &buflen); + if (rc) { + LOG("read: cmd=%08x, buflen=%zu, rc=%d\n", cmd, buflen, rc); + return rc; + } + + /* + * At least 3 words are expected in response + * - header word + * - status word + * - header offset word + */ + if (buflen < 3 * 4) { + LOG("reply: cmd=%08x, len=%u\n", cmd, buflen); + rc = EPROTO; + goto fail; + } + + /* Last word is header offset (in words) */ + offset_word = be32toh(*(uint32_t *) &buf[buflen-4]); + offset = buflen - (offset_word * 4); + + *out_len = offset; + + header_word = be32toh(*(uint32_t *) &buf[offset]); + offset += 4; + + status_word = be32toh(*(uint32_t *) &buf[offset]); + offset += 4; + + if (header_word != (0xc0de0000 | cmd)) { + LOG("reply: cmd=%08x, len=%u, header=%08x\n", cmd, buflen, header_word); + rc = EPROTO; + goto fail; + } + + LOG("reply: cmd=%08x, len=%u, status=%08x\n", cmd, buflen, status_word); + + if (status_word) { + sbefifo_ffdc_set(sctx, status_word, buf + offset, buflen - offset-4); + rc = 201; + goto fail; + } + + if (*out_len > 0) { + *out = malloc(*out_len); + if (! *out) { + rc = ENOMEM; + goto fail; + } + memcpy(*out, buf, *out_len); + } else { + *out = NULL; + } + + free(buf); + return 0; + +fail: + free(buf); + return rc; +} diff --git a/libsbefifo/sbefifo_private.h b/libsbefifo/sbefifo_private.h new file mode 100644 index 0000000..87416b7 --- /dev/null +++ b/libsbefifo/sbefifo_private.h @@ -0,0 +1,88 @@ +/* Copyright 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. + */ + +#ifndef __SBEFIFO_PRIVATE_H__ +#define __SBEFIFO_PRIVATE_H__ + +#include + +#define SBEFIFO_CMD_CLASS_CONTROL 0xA100 +#define SBEFIFO_CMD_EXECUTE_ISTEP 0x01 + +#define SBEFIFO_CMD_CLASS_SCOM 0xA200 +#define SBEFIFO_CMD_GET_SCOM 0x01 +#define SBEFIFO_CMD_PUT_SCOM 0x02 +#define SBEFIFO_CMD_MODIFY_SCOM 0x03 +#define SBEFIFO_CMD_PUT_SCOM_MASK 0x04 +#define SBEFIFO_CMD_MULTI_SCOM 0x05 + +#define SBEFIFO_CMD_CLASS_RING 0xA300 +#define SBEFIFO_CMD_GET_RING 0x01 +#define SBEFIFO_CMD_PUT_RING 0x02 +#define SBEFIFO_CMD_PUT_RING_IMAGE 0x03 + +#define SBEFIFO_CMD_CLASS_MEMORY 0xA400 +#define SBEFIFO_CMD_GET_MEMORY 0x01 +#define SBEFIFO_CMD_PUT_MEMORY 0x02 +#define SBEFIFO_CMD_GET_OCCSRAM 0x03 +#define SBEFIFO_CMD_PUT_OCCSRAM 0x04 + +#define SBEFIFO_CMD_CLASS_REGISTER 0xA500 +#define SBEFIFO_CMD_GET_REGISTER 0x01 +#define SBEFIFO_CMD_PUT_REGISTER 0x02 + +#define SBEFIFO_CMD_CLASS_ARRAY 0xA600 +#define SBEFIFO_CMD_FAST_ARRAY 0x01 +#define SBEFIFO_CMD_TRACE_ARRAY 0x02 + +#define SBEFIFO_CMD_CLASS_INSTRUCTION 0xA700 +#define SBEFIFO_CMD_CONTROL_INSN 0x01 + +#define SBEFIFO_CMD_CLASS_GENERIC 0xA800 +#define SBEFIFO_CMD_GET_FFDC 0x01 +#define SBEFIFO_CMD_GET_CAPABILITY 0x02 +#define SBEFIFO_CMD_GET_FREQUENCY 0x03 +#define SBEFIFO_CMD_QUIESCE 0x05 + +#define SBEFIFO_CMD_CLASS_MPIPL 0xA900 +#define SBEFIFO_CMD_ENTER_MPIPL 0x01 +#define SBEFIFO_CMD_CONTINUE_MPIPL 0x02 +#define SBEFIFO_CMD_STOP_CLOCKS 0x03 + +struct sbefifo_context { + int fd; + + uint32_t status; + uint8_t *ffdc; + uint32_t ffdc_len; +}; + +void sbefifo_debug(const char *fmt, ...); + +void sbefifo_ffdc_clear(struct sbefifo_context *sctx); +void sbefifo_ffdc_set(struct sbefifo_context *sctx, uint32_t status, uint8_t *ffdc, uint32_t ffdc_len); + +int sbefifo_operation(struct sbefifo_context *sctx, + uint8_t *msg, uint32_t msg_len, uint16_t cmd, + uint8_t **out, uint32_t *out_len); + +#ifdef LIBSBEFIFO_DEBUG +#define LOG(fmt, args...) sbefifo_debug(fmt, ##args) +#else +#define LOG(fmt, args...) +#endif + +#endif /* __SBEFIFO_PRIVATE_H__ */ From patchwork Tue Aug 20 05:19:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amitay Isaacs X-Patchwork-Id: 1149781 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.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 46CJxv6dk8z9sN1 for ; Tue, 20 Aug 2019 15:19:31 +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.b="GbsUL0JM"; 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 46CJxv2vpVzDqsw for ; Tue, 20 Aug 2019 15:19:31 +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 46CJxf0dGFzDqq8 for ; Tue, 20 Aug 2019 15:19:18 +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.b="GbsUL0JM"; 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 46CJxd1Wdgz9sN1; Tue, 20 Aug 2019 15:19:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ozlabs.org; s=201707; t=1566278357; bh=6V3InPEWdnegXR8HCvlqPNOob7ie/CbObqdg+YkyaFU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GbsUL0JM0m/dQtceUTwMYdY+yrsiDli5BjGfmiafAWIl6pBlCTI9lTO4YWTWfUPYY xxRC0TIY3OkU8shf30N8jNGFl35lkF8Y0j7hK6SfDQ+ldahjGes9U3amSo8WyIJ0gz mu/T7F6FzeJXf5GkiJU5Yjz4PHm7Y5+ZF3RO2BCZLpnopTtDvwfcgIdwjpJAraiy8K BBeloBdQzgL2LrtNCdf0ru8IIpIKbMbehnrpprX6N8jcFXxNJ26OimIhDPofS2ox8s x1aPETtBBjwjwKb/UU+2osmTuVRo0jfFhZ3IvMQ+qR6oc3f9VNGOv3WJZK8IGjq+tr 3saX0WnMQbvtg== From: Amitay Isaacs To: pdbg@lists.ozlabs.org Date: Tue, 20 Aug 2019 15:19:12 +1000 Message-Id: <20190820051913.17295-3-amitay@ozlabs.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190820051913.17295-1-amitay@ozlabs.org> References: <20190820051913.17295-1-amitay@ozlabs.org> MIME-Version: 1.0 Subject: [Pdbg] [PATCH 2/3] libpdbg: Drop sbe_chipop api for generic chip-op 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: , Cc: Amitay Isaacs Errors-To: pdbg-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Pdbg" Signed-off-by: Amitay Isaacs --- libpdbg/hwunit.h | 1 - libpdbg/libpdbg.h | 1 - libpdbg/sbefifo.c | 33 --------------------------------- libpdbg/target.c | 11 ----------- 4 files changed, 46 deletions(-) diff --git a/libpdbg/hwunit.h b/libpdbg/hwunit.h index 1bfb872..501ec74 100644 --- a/libpdbg/hwunit.h +++ b/libpdbg/hwunit.h @@ -74,7 +74,6 @@ struct sbefifo { int (*thread_stop)(struct sbefifo *, uint32_t core_id, uint32_t thread_id); int (*thread_step)(struct sbefifo *, uint32_t core_id, uint32_t thread_id); int (*thread_sreset)(struct sbefifo *, uint32_t core_id, uint32_t thread_id); - int (*chipop)(struct sbefifo *, uint32_t *, uint32_t, uint8_t **, uint32_t *, uint32_t *); uint32_t (*ffdc_get)(struct sbefifo *, const uint8_t **, uint32_t *); int fd; uint32_t status; diff --git a/libpdbg/libpdbg.h b/libpdbg/libpdbg.h index e752681..235ff85 100644 --- a/libpdbg/libpdbg.h +++ b/libpdbg/libpdbg.h @@ -244,7 +244,6 @@ int opb_read(struct pdbg_target *target, uint32_t addr, uint32_t *data); int opb_write(struct pdbg_target *target, uint32_t addr, uint32_t data); int sbe_istep(struct pdbg_target *target, uint32_t major, uint32_t minor); -int sbe_chipop(struct pdbg_target *target, uint32_t *msg, uint32_t msg_len, uint8_t **out, uint32_t *out_len, uint32_t *status); uint32_t sbe_ffdc_get(struct pdbg_target *target, const uint8_t **ffdc, uint32_t *ffdc_len); typedef void (*pdbg_progress_tick_t)(uint64_t cur, uint64_t end); diff --git a/libpdbg/sbefifo.c b/libpdbg/sbefifo.c index 784db32..92f8220 100644 --- a/libpdbg/sbefifo.c +++ b/libpdbg/sbefifo.c @@ -435,38 +435,6 @@ static int sbefifo_op_thread_sreset(struct sbefifo *sbefifo, return sbefifo_op_control(sbefifo, core_id, thread_id, SBEFIFO_INSN_OP_SRESET); } -static int sbefifo_op_chipop(struct sbefifo *sbefifo, - uint32_t *msg, uint32_t msg_len, - uint8_t **out, uint32_t *out_len, uint32_t *status) -{ - uint32_t len, cmd, op; - int rc; - - assert(msg_len > 3); - - len = be32toh(msg[0]); - cmd = be32toh(msg[1]); - op = be32toh(msg[2]); - - PR_NOTICE("sbefifo: chipop command=%u, op=%u\n", cmd, op); - - if (len != msg_len) { - PR_ERROR("sbefifo: chipop: Invalid msg length, expected %u, got %u\n", - len, msg_len); - return -1; - } - - /* Limit the expected data to 64K */ - if (*out_len > 0x10000) - *out_len = 0x10000; - - rc = sbefifo_op(sbefifo, msg, msg_len, cmd, out, out_len, status); - if (rc) - return rc; - - return 0; -} - static int sbefifo_probe(struct pdbg_target *target) { struct sbefifo *sf = target_to_sbefifo(target); @@ -498,7 +466,6 @@ struct sbefifo kernel_sbefifo = { .thread_stop = sbefifo_op_thread_stop, .thread_step = sbefifo_op_thread_step, .thread_sreset = sbefifo_op_thread_sreset, - .chipop = sbefifo_op_chipop, .ffdc_get = sbefifo_ffdc_get, .fd = -1, }; diff --git a/libpdbg/target.c b/libpdbg/target.c index 1436f7f..f71dcee 100644 --- a/libpdbg/target.c +++ b/libpdbg/target.c @@ -323,17 +323,6 @@ int sbe_istep(struct pdbg_target *target, uint32_t major, uint32_t minor) return sbefifo->istep(sbefifo, major, minor); } -int sbe_chipop(struct pdbg_target *target, uint32_t *msg, uint32_t msg_len, uint8_t **out, uint32_t *out_len, uint32_t *status) -{ - struct sbefifo *sbefifo; - - sbefifo = pib_to_sbefifo(target); - if (!sbefifo) - return -1; - - return sbefifo->chipop(sbefifo, msg, msg_len, out, out_len, status); -} - uint32_t sbe_ffdc_get(struct pdbg_target *target, const uint8_t **ffdc, uint32_t *ffdc_len) { struct sbefifo *sbefifo; From patchwork Tue Aug 20 05:19:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amitay Isaacs X-Patchwork-Id: 1149779 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.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 ozlabs.org (Postfix) with ESMTPS id 46CJxm1jt3z9sML for ; Tue, 20 Aug 2019 15:19:24 +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.b="jrsRaQdJ"; 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 46CJxm0SW3zDqs1 for ; Tue, 20 Aug 2019 15:19:24 +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 46CJxf0gQZzDqqD for ; Tue, 20 Aug 2019 15:19:18 +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.b="jrsRaQdJ"; 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 46CJxd3GMVz9sN4; Tue, 20 Aug 2019 15:19:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ozlabs.org; s=201707; t=1566278357; bh=t1q1ONEKDWOZ06clK0gq+8gWbYKDD689a6dMu9VB6ws=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jrsRaQdJwBKJyrvsyZZYbJu1KYYaY3A0xpTpEK59i5FZHVOKywZ0GMjn2J9XsZ7bc QV2cGDAN3xlBz7td11sQUr0aocuwIMSZERR8Al4TFrRSOnXpajrGAq2IaSiBbE2D2b 41XI0jSeegVSfhbDDSlHcReqZdJoxbTG8xm8mD9YVxQfFetpEWzOfZ9u+BU46+TS7d RwWkks29rIpvM1atEatc+lsnvR4dkNKQ3deG8mIhJcl6xxDKEjGCtIa2J9ep83mjQ8 JILMCH7+9uag2mA6PDk0C/VQB+x94SVRQ51ZeLWA46kEchcpElm77AnkEaAlpMqcGY 97RFI8EvuukCg== From: Amitay Isaacs To: pdbg@lists.ozlabs.org Date: Tue, 20 Aug 2019 15:19:13 +1000 Message-Id: <20190820051913.17295-4-amitay@ozlabs.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190820051913.17295-1-amitay@ozlabs.org> References: <20190820051913.17295-1-amitay@ozlabs.org> MIME-Version: 1.0 Subject: [Pdbg] [PATCH 3/3] sbefifo: Switch to using libsbefifo api 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: , Cc: Amitay Isaacs Errors-To: pdbg-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Pdbg" Signed-off-by: Amitay Isaacs --- Makefile.am | 2 +- libpdbg/hwunit.h | 5 +- libpdbg/sbefifo.c | 316 ++++------------------------------------------ 3 files changed, 24 insertions(+), 299 deletions(-) diff --git a/Makefile.am b/Makefile.am index f850a29..f5e7ded 100644 --- a/Makefile.am +++ b/Makefile.am @@ -191,7 +191,7 @@ libpdbg_la_SOURCES = \ libpdbg/xbus.c libpdbg_la_CFLAGS = -Wall -Werror -libpdbg_la_LIBADD = libcronus.la +libpdbg_la_LIBADD = libcronus.la libsbefifo.la if BUILD_LIBFDT libpdbg_la_CFLAGS += -I$(top_srcdir)/libfdt diff --git a/libpdbg/hwunit.h b/libpdbg/hwunit.h index 501ec74..37c7661 100644 --- a/libpdbg/hwunit.h +++ b/libpdbg/hwunit.h @@ -75,10 +75,7 @@ struct sbefifo { int (*thread_step)(struct sbefifo *, uint32_t core_id, uint32_t thread_id); int (*thread_sreset)(struct sbefifo *, uint32_t core_id, uint32_t thread_id); uint32_t (*ffdc_get)(struct sbefifo *, const uint8_t **, uint32_t *); - int fd; - uint32_t status; - uint8_t *ffdc; - uint32_t ffdc_len; + struct sbefifo_context *sf_ctx; }; #define target_to_sbefifo(x) container_of(x, struct sbefifo, target) diff --git a/libpdbg/sbefifo.c b/libpdbg/sbefifo.c index 92f8220..249f115 100644 --- a/libpdbg/sbefifo.c +++ b/libpdbg/sbefifo.c @@ -20,228 +20,22 @@ #include #include +#include + #include "hwunit.h" #include "debug.h" -#define SBEFIFO_CMD_CLASS_CONTROL 0xA100 -#define SBEFIFO_CMD_EXECUTE_ISTEP 0x0001 - -#define SBEFIFO_CMD_CLASS_MEMORY 0xA400 -#define SBEFIFO_CMD_GET_MEMORY 0x0001 -#define SBEFIFO_CMD_PUT_MEMORY 0x0002 - -#define SBEFIFO_CMD_CLASS_INSTRUCTION 0xA700 -#define SBEFIFO_CMD_CONTROL_INSN 0x0001 - -#define SBEFIFO_MEMORY_FLAG_PROC 0x0001 -#define SBEFIFO_MEMORY_FLAG_PBA 0x0002 -#define SBEFIFO_MEMORY_FLAG_AUTO_INCR 0x0004 -#define SBEFIFO_MEMORY_FLAG_ECC_REQ 0x0008 -#define SBEFIFO_MEMORY_FLAG_TAG_REQ 0x0010 -#define SBEFIFO_MEMORY_FLAG_FAST_MODE 0x0020 -#define SBEFIFO_MEMORY_FLAG_LCO_MODE 0x0040 // only for putmem -#define SBEFIFO_MEMORY_FLAG_CI 0x0080 -#define SBEFIFO_MEMORY_FLAG_PASSTHRU 0x0100 -#define SBEFIFO_MEMORY_FLAG_CACHEINJECT 0x0200 // only for putmem - -#define SBEFIFO_INSN_OP_START 0x0 -#define SBEFIFO_INSN_OP_STOP 0x1 -#define SBEFIFO_INSN_OP_STEP 0x2 -#define SBEFIFO_INSN_OP_SRESET 0x3 - -static void sbefifo_op_dump(const char *prefix, uint8_t *buf, size_t buflen) -{ - int i; - - if (!prefix) - prefix = ""; - - for (i=0; i 0); - - n = read(sbefifo->fd, buf, *buflen); - if (n < 0) { - PR_ERROR("sbefifo: Failed to read, errno=%d\n", errno); - return -1; - } - *buflen = n; - - return 0; -} - -static int sbefifo_op_write(struct sbefifo *sbefifo, void *buf, size_t buflen) -{ - ssize_t n; - - n = write(sbefifo->fd, buf, buflen); - if (n < 0) { - PR_ERROR("sbefifo: Failed to write, errno=%d\n", errno); - return -1; - } - if (n != buflen) { - PR_ERROR("sbefifo: Short write %zi of %zi bytes\n", n, buflen); - return -1; - } - - return 0; -} - -static void sbefifo_ffdc_clear(struct sbefifo *sbefifo) -{ - sbefifo->status = 0; - if (sbefifo->ffdc) { - free(sbefifo->ffdc); - sbefifo->ffdc = NULL; - sbefifo->ffdc_len = 0; - } -} - -static void sbefifo_ffdc_set(struct sbefifo *sbefifo, uint8_t *buf, uint32_t buflen, uint32_t status) -{ - sbefifo->status = status; - - sbefifo->ffdc = malloc(buflen); - if (!sbefifo->ffdc) { - PR_ERROR("sbefifo: Failed to store FFDC data\n"); - return; - } - - memcpy(sbefifo->ffdc, buf, buflen); - sbefifo->ffdc_len = buflen; -} - -static uint32_t sbefifo_ffdc_get(struct sbefifo *sbefifo, const uint8_t **ffdc, uint32_t *ffdc_len) -{ - *ffdc = sbefifo->ffdc; - *ffdc_len = sbefifo->ffdc_len; - - return sbefifo->status; -} - -static int sbefifo_op(struct sbefifo *sbefifo, - uint32_t *msg, uint32_t msg_len, uint16_t cmd, - uint8_t **out, uint32_t *out_len, uint32_t *status) -{ - uint8_t *buf; - uint32_t resp[2]; - size_t buflen; - uint32_t word_offset, offset; - uint16_t value; - int rc; - - sbefifo_ffdc_clear(sbefifo); - - assert(msg_len > 0); - - /* - * Allocate extra memory for FFDC (SBEFIFO_MAX_FFDC_SIZE = 0x2000) - * Use *out_len as a hint to expected reply length - */ - buflen = (*out_len + 0x2000 + 3) & (uint32_t)~3; - buf = malloc(buflen); - assert(buf); - - rc = sbefifo_op_write(sbefifo, msg, msg_len); - if (rc) - goto fail; - - rc = sbefifo_op_read(sbefifo, buf, &buflen); - if (rc) - goto fail; - - /* - * At least 3 words are expected in the response - * header word, status word, header offset word - */ - if (buflen < 3 * 4) { - PR_ERROR("sbefifo: Short read, got %zu\n", buflen); - sbefifo_op_dump("DATA:", buf, buflen); - goto fail; - } - - word_offset = be32toh(*(uint32_t *)(buf + buflen - 4)); - PR_INFO("sbefifo: status header word offset = %u\n", word_offset); - - offset = buflen - (word_offset * 4); - *out_len = offset; - - resp[0] = be32toh(*(uint32_t *)(buf + offset)); - offset += 4; - - resp[1] = be32toh(*(uint32_t *)(buf + offset)); - offset += 4; - - PR_INFO("sbefifo: response %08x %08x\n", resp[0], resp[1]); - - value = resp[0] >> 16; - if (value != 0xc0de) { - PR_ERROR("sbefifo: Expected magic 0xc0de, got 0x%04x\n", value); - goto fail; - } - - value = resp[0] & 0xffff; - if (value != cmd) { - PR_ERROR("sbefifo: Expected command 0x%04x, got 0x%04x\n", cmd, value); - goto fail; - } - - *status = resp[1]; - if (resp[1] != 0) { - PR_ERROR("sbefifo: Operation failed, response=0x%08x\n", resp[1]); - sbefifo_ffdc_set(sbefifo, buf + offset, buflen - offset - 4, resp[1]); - free(buf); - return 1; - } - - if (*out_len > 0) { - *out = malloc(*out_len); - assert(*out); - - memcpy(*out, buf, *out_len); - } else { - *out = NULL; - } - - free(buf); - return 0; - -fail: - free(buf); - return -1; + return sbefifo_ffdc_get(sbefifo->sf_ctx, ffdc, ffdc_len); } static int sbefifo_op_istep(struct sbefifo *sbefifo, uint32_t major, uint32_t minor) { - uint8_t *out; - uint32_t msg[3]; - uint32_t cmd, step, out_len, status; - int rc; - PR_NOTICE("sbefifo: istep %u.%u\n", major, minor); - cmd = SBEFIFO_CMD_CLASS_CONTROL | SBEFIFO_CMD_EXECUTE_ISTEP; - step = (major & 0xff) << 16 | (minor & 0xff); - - msg[0] = htobe32(3); // number of words - msg[1] = htobe32(cmd); - msg[2] = htobe32(step); - - out_len = 0; - rc = sbefifo_op(sbefifo, msg, sizeof(msg), cmd, &out, &out_len, &status); - if (rc) - return rc; - - return 0; + return sbefifo_istep_execute(sbefifo->sf_ctx, major & 0xff, minor & 0xff); } static int sbefifo_op_getmem(struct sbefifo *sbefifo, @@ -250,9 +44,8 @@ static int sbefifo_op_getmem(struct sbefifo *sbefifo, { uint8_t *out; uint64_t start_addr, end_addr; - uint32_t align, offset, len, out_len, status; - uint32_t msg[6]; - uint32_t cmd, flags; + uint32_t align, offset, len; + uint16_t flags; int rc; align = ci ? 8 : 128; @@ -271,33 +64,18 @@ static int sbefifo_op_getmem(struct sbefifo *sbefifo, PR_NOTICE("sbefifo: getmem addr=0x%016" PRIx64 ", len=%u\n", start_addr, len); - cmd = SBEFIFO_CMD_CLASS_MEMORY | SBEFIFO_CMD_GET_MEMORY; if (ci) flags = SBEFIFO_MEMORY_FLAG_PROC | SBEFIFO_MEMORY_FLAG_CI; else flags = SBEFIFO_MEMORY_FLAG_PBA; - msg[0] = htobe32(6); // number of words - msg[1] = htobe32(cmd); - msg[2] = htobe32(flags); - msg[3] = htobe32(start_addr >> 32); - msg[4] = htobe32(start_addr & 0xffffffff); - msg[5] = htobe32(len); + rc = sbefifo_mem_get(sbefifo->sf_ctx, start_addr, len, flags, &out); + + pdbg_progress_tick(len, len); - out_len = len + 4; - rc = sbefifo_op(sbefifo, msg, sizeof(msg), cmd, &out, &out_len, &status); if (rc) return rc; - pdbg_progress_tick(len + 4, out_len); - - if (out_len != size + 4) { - PR_ERROR("sbefifo: getmem error got %u, expected %"PRIu64"\n", out_len, size + 4); - if (out_len > 0) - free(out); - return -1; - } - memcpy(data, out+offset, size); free(out); @@ -308,10 +86,8 @@ static int sbefifo_op_putmem(struct sbefifo *sbefifo, uint64_t addr, uint8_t *data, uint64_t size, bool ci) { - uint8_t *out; - uint32_t *msg; - uint32_t align, len, msg_len, out_len, status; - uint32_t cmd, flags, count; + uint32_t align, len; + uint16_t flags; int rc; align = ci ? 8 : 128; @@ -332,59 +108,26 @@ static int sbefifo_op_putmem(struct sbefifo *sbefifo, } len = size & 0xffffffff; - msg_len = 6 * 4 + len; - msg = (uint32_t *)malloc(msg_len); - assert(msg); PR_NOTICE("sbefifo: putmem addr=0x%016"PRIx64", len=%u\n", addr, len); - cmd = SBEFIFO_CMD_CLASS_MEMORY | SBEFIFO_CMD_PUT_MEMORY; if (ci) flags = SBEFIFO_MEMORY_FLAG_PROC | SBEFIFO_MEMORY_FLAG_CI; else flags = SBEFIFO_MEMORY_FLAG_PBA; - msg[0] = htobe32(msg_len/4); // number of words - msg[1] = htobe32(cmd); - msg[2] = htobe32(flags); - msg[3] = htobe32(addr >> 32); - msg[4] = htobe32(addr & 0xffffffff); - msg[5] = htobe32(len); - memcpy(&msg[6], data, len); + rc = sbefifo_mem_put(sbefifo->sf_ctx, addr, data, len, flags); - out_len = 4; - rc = sbefifo_op(sbefifo, msg, msg_len, cmd, &out, &out_len, &status); - if (rc) - return rc; - - pdbg_progress_tick(4, out_len); - - if (out_len != 4) { - PR_ERROR("sbefifo: putmem error got %u, expected 4\n", out_len); - if (out_len > 0) - free(out); - return -1; - } - - count = be32toh(*(uint32_t *)out); - free(out); - - if (count != len) { - PR_ERROR("sbefifo: putmem wrote %u bytes of %u\n", count, len); - return -1; - } + pdbg_progress_tick(len, len); - return 0; + return rc; } static int sbefifo_op_control(struct sbefifo *sbefifo, uint32_t core_id, uint32_t thread_id, uint32_t oper) { - uint8_t *out; - uint32_t msg[3]; - uint32_t cmd, op, out_len, status, mode = 0; - int rc; + uint8_t mode = 0; /* Enforce special-wakeup for thread stop and sreset */ if ((oper & 0xf) == SBEFIFO_INSN_OP_STOP || @@ -393,22 +136,7 @@ static int sbefifo_op_control(struct sbefifo *sbefifo, PR_NOTICE("sbefifo: control c:0x%x, t:0x%x, op:%u mode:%u\n", core_id, thread_id, oper, mode); - op = (mode << 16) | ((core_id & 0xff) << 8) | ((thread_id & 0x0f) << 4) | (oper & 0x0f); - cmd = SBEFIFO_CMD_CLASS_INSTRUCTION | SBEFIFO_CMD_CONTROL_INSN; - - msg[0] = htobe32(3); // number of words - msg[1] = htobe32(cmd); - msg[2] = htobe32(op); - - out_len = 0; - rc = sbefifo_op(sbefifo, msg, sizeof(msg), cmd, &out, &out_len, &status); - if (rc) - return rc; - - if (out_len > 0) - free(out); - - return 0; + return sbefifo_control_insn(sbefifo->sf_ctx, core_id & 0xff, thread_id & 0xff, oper & 0xff, mode); } static int sbefifo_op_thread_start(struct sbefifo *sbefifo, @@ -439,14 +167,15 @@ static int sbefifo_probe(struct pdbg_target *target) { struct sbefifo *sf = target_to_sbefifo(target); const char *sbefifo_path; + int rc; sbefifo_path = pdbg_target_property(target, "device-path", NULL); assert(sbefifo_path); - sf->fd = open(sbefifo_path, O_RDWR | O_SYNC); - if (sf->fd < 0) { + rc = sbefifo_connect(sbefifo_path, &sf->sf_ctx); + if (rc) { PR_ERROR("Unable to open sbefifo driver %s\n", sbefifo_path); - return -1; + return rc; } return 0; @@ -466,8 +195,7 @@ struct sbefifo kernel_sbefifo = { .thread_stop = sbefifo_op_thread_stop, .thread_step = sbefifo_op_thread_step, .thread_sreset = sbefifo_op_thread_sreset, - .ffdc_get = sbefifo_ffdc_get, - .fd = -1, + .ffdc_get = sbefifo_op_ffdc_get, }; DECLARE_HW_UNIT(kernel_sbefifo);