From patchwork Thu Jun 17 15:58:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 462765 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, MSGID_FROM_MTA_HEADER, SPF_HELO_NONE, SPF_PASS,UNWANTED_LANGUAGE_BODY,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E7745C49EA2 for ; Thu, 17 Jun 2021 16:04:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BD5C261351 for ; Thu, 17 Jun 2021 16:04:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233631AbhFQQGV (ORCPT ); Thu, 17 Jun 2021 12:06:21 -0400 Received: from mail-eopbgr140040.outbound.protection.outlook.com ([40.107.14.40]:17172 "EHLO EUR01-VE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S233629AbhFQQGG (ORCPT ); Thu, 17 Jun 2021 12:06:06 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=hYtd12ranB87O95Rw6UveMOHZ7mWe/M4OMwQ5ZtmQO6sySi285ab1S+IhL7LX3l3efMrPfn7xvzFxFT84629oX21KFqRjR+6kd00wwCu3OL2e4kXygRcwqiwDFNlhqez2cFjf4Y+2iGq2sgfd/pqFNdJyHm/Vs2jqcJYlEz8EgbDeOsKX0HhPlXuXTJDsyjqlT1TWOyLlhoyyoG0+CRLgRsPgE/mVaJyOOOP8V+RT6syxfFuZBqj79NJNee/9I/aQQuwh3TEUa7SDM8jXFcCjVRJAVMvawUTpoazJt+n2w50ytIMhSXeUljo62VUVkf57HrrAC+szvZXxrzY/+zyeA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=lx1Vni1dJuPhx24MSwcONUq6aLZxbJZu/piE5fSdh9g=; b=Z0/pyHqWkFrZxcUghcSHu2Gd10vKmu8FQYUCM3f4iOTIOyNZUatAhiV+gWSSsqy7jvvv1h2WbDi/GkMgXp3nq6Yuxhkpsj4WxO6kFK9pxd5kZ6xx+Wy53VV/JxCpfBarg6CK9TtOir4D1nweIAReCsoQAORANtHZ4OsX5orcdQsV8OgYXZ/cCleyjsahhsZSy7vm48TixTAUU9QSlRNGTd2Xt+1ke8cBmD+otUI94eBgMoVtuHvnDOrBp7T7Y2o6g84NgojZLGiYmJrVYA2FUIeGs+ok0wPa95di7tQzmV97NKt1G+cXwKUtuxI1kx3IpPKYpF5uM5UtLzjkP0Fe2A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=lx1Vni1dJuPhx24MSwcONUq6aLZxbJZu/piE5fSdh9g=; b=nUbG7B0KaMJA0LIv5Jimk1WdLN3zPkYVki1m984y7tCepktd5g9+NCi6be9dKtKAFOTb7sx3H0866QNqbhBX6c0Jb24Fr+ThDCSQm2sYyvpQmkEior6YlaVvKfUeuek3TrBMSHbIt1gJliOyXaLfzQCSRAyD8u27+uyHhU6fw0w= Authentication-Results: vger.kernel.org; dkim=none (message not signed) header.d=none; vger.kernel.org; dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM9P192MB1234.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:388::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4242.16; Thu, 17 Jun 2021 16:03:45 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::1847:5583:4db7:102f]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::1847:5583:4db7:102f%4]) with mapi id 15.20.4242.021; Thu, 17 Jun 2021 16:03:45 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v1 052/256] cl8k: add dbgfile.c Date: Thu, 17 Jun 2021 15:58:59 +0000 Message-Id: <20210617160223.160998-53-viktor.barna@celeno.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210617160223.160998-1-viktor.barna@celeno.com> References: <20210617160223.160998-1-viktor.barna@celeno.com> X-Originating-IP: [62.216.42.54] X-ClientProxiedBy: PR3PR09CA0018.eurprd09.prod.outlook.com (2603:10a6:102:b7::23) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from localhost.localdomain (62.216.42.54) by PR3PR09CA0018.eurprd09.prod.outlook.com (2603:10a6:102:b7::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4242.18 via Frontend Transport; Thu, 17 Jun 2021 16:03:30 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: a70c3f7c-4088-4c63-4b28-08d931a9739a X-MS-TrafficTypeDiagnostic: AM9P192MB1234: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:133; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Z2o+UOROSWj5QqnQ2Pyf6Z8jf71TU1FitNOFgsUn0pWSB1MSIq9Wh42XgchWDUNzB53RiH/YRKMuEx0kASo8v6on7qoIzKfivR3e1y3YJzwEtvjQ6CM8BNbKtGxNZjs3Y8kN4vkLoDP9KyKSDzOeQK7Dch2pqag0XFVArWmyFbteEiitiDzniX56JMY1kXq/E3lzXO+dJbPP5VU8HSFBC2GE1kZIB2piklruUJOVdvkG0wRQpj9XHaSjabZzSVSf8ZVxipoxM3WhO0YsJxSHRPZ2bpUVAoKkKt/TK7QwwU0hqpEtrrUs9C8wNhaiHdP9NVYnyDKOu2l1TCshvGFBPjBNU7UsMHwo9mLtFf3otVO92AdunQJzaAim0cw2DKy0YUedY1P0NIswN6BnHaIZYHBuHVZk0CtPxuy5FQqKMzM06NBK0drofUVIlV+dPvQa65b/Ehm1tCMqRYca+q2inJ2D/I+vMJfIFhf8tULzmAi/ltk7eYMNnhg/IJjVVSaz12pPlC8AsibIloWNSDAHU/dLQFOza1EJNZgvUbmQJsVNUZ6s+hZzkPE3jTpuRuXBrg/YPU+ZUSLvIuyXFOv9Sb9rGo8PGGnhQnaOBHtjUX2Y3ycHr7P+sq8Rsyck+L1k+Es+Yf9gFIZGZDq4Z/aVoxb1ixErvYSTmmCoTay3DVux+NeziU3PHDHhRxpG7+oMnSZgZU8CwiDSw0TyADSuLQ== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(376002)(366004)(136003)(346002)(396003)(39850400004)(6666004)(107886003)(36756003)(956004)(66476007)(66556008)(2616005)(66946007)(30864003)(6916009)(2906002)(26005)(9686003)(1076003)(6512007)(6486002)(16526019)(6506007)(38100700002)(52116002)(86362001)(8936002)(316002)(38350700002)(186003)(55236004)(54906003)(8676002)(5660300002)(508600001)(83380400001)(4326008)(69590400013)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: DvQ028GU7VXPTthhP9RiKYgijmXdzyKc3x51HDC4otsY1fUCvS9N2RQvbIx8UGpi1nCL2LG7wwhn+VByKbCFTJLbInjiATh77jKmIvfm64UdY34j785PN0P8PoccsGf0cs1dgvPhrhMyj0QQ5p1eVTlFjZ+WGa+EDOWLQphprhSmiuQCRqjiHTLikGTq9H1nGMvfLAOSOTX0XgOScJbQiC6JwOl6NyHg/e4hYxHrqrC5U7yt4A0o0wOH12tR0AjVNkvJSGeZJitnmLStMfzMABWdd0awzyPq01RpNTC8dt62jL1nQviFB1jTerm1huJu/Y3NncnRPlBUdu0b+ojjKB6+r/ZbhYqFjwZawkyfW/YQbBMM2aPxlsMCg2vFcv2U+pS34d8Ei06Dg05d7W1Bdllfcu/MEAu56PNdm6jtu2osyR7zu34F5mgXWNO9iXuoDbgNPdoTg8dcZEgiuA7SQTLE4Z1GAzTlWhn9Bv9BF6sEUph/jv0G2PODUEg4Z59Jm3NvsJnJ/O399YC0gKzpIgsROQVmUX8gRC2XdEQ41uM02UDYvGgcyv+XocW+xfWgQZkt0HyF91aIaEVdaZSTY/Mn86x8ImVAXr1i1SHi8+r2i80B5+LjZ3eo0q9rr14jcnIRl+SerbyJ+5VXdL/HXWANrAFEoE+JO8L7hxuv4r2NX0h2R4Gg4ipHUmKQyMKuVnMHAA1b7XLkPCmJS1+mRkRiNCrtFgiflNot3Tv4+wI6o9gZbeDzlYo/huulqMbtqEc2+LHBb+/uuU1vAZPlZVD2sl8XrLbCtNaRmVppOdapSeevAhTQ+lfvZR1pnm7HDQMMXmQZu1Juwwm9rigf80vL6GiUCtBdHEZoKO+DObUbJdeXR7tHUlUkNpXsxGimrTSNijB+F+zd/BGIaZvkPpLcLhMvsdmwcwGRTOLn1jVzE5hhzZfyNDhjDeJ/IxL8rL2ag9wpX4pEYoRuCwC0rNcPjC7UFcZ255oc/U8BxGs72ib1+tMVUlGd0LQQCQTapUHhML9sZVUqR7xe+imOXM6bW1nPzxLb0irUy9I+TUbHpovKURYaDf5gVMtZnLMjoR6afZpPtY6pTcOVl4YCRGnm+BBg62NKklL+2Ime20OY8xmJbwX9xOa5oEZtEiIxDDhPda7ML48AHxlj0Md1Z7FORMWSr1ROqSbjfGKTTEDTm+NYkXcrESZ1Bc5CbCwYJoNWGlV6WxPaQ4SWqZ/kv8DaHotNGJ4ySW+Q2vIfJ5iSCyIZklw7wQoh7HM6lwAvr4N+7SUHReoOrgbInz5979jtkUwf1iG2U6nC5eECRxFV3ZnhqL0aVo4s6sf0L6GO X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: a70c3f7c-4088-4c63-4b28-08d931a9739a X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jun 2021 16:03:31.0293 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: x5r54cEFvgdrV2arz3O1kbXR8v6wIDQZE1BHg3QL+rCJzhzCVcuE+dnOydxyHHAYBQQPbyTify3MzKaw3Hcbsw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM9P192MB1234 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/dbgfile.c | 438 +++++++++++++++++++++ 1 file changed, 438 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/dbgfile.c -- 2.30.0 diff --git a/drivers/net/wireless/celeno/cl8k/dbgfile.c b/drivers/net/wireless/celeno/cl8k/dbgfile.c new file mode 100644 index 000000000000..1e8aebbe91f4 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/dbgfile.c @@ -0,0 +1,438 @@ +// SPDX-License-Identifier: MIT +/* Copyright(c) 2019-2021, Celeno Communications Ltd. */ + +#include +#include "dbgfile.h" +#include "reg/reg_access.h" +#include "utils/utils.h" +#include "dbgfile.h" + +const char *cl_dbgfile_get_msg_txt(struct cl_dbg_data *dbg_data, int file_id, int line) +{ + /* Get the message text from the .dbg file by fileid & line number */ + int remaining_bytes = dbg_data->size; + const char *str = dbg_data->str; + char id_str[32]; + int idstr_len; + + if (!str || 0 == remaining_bytes) + return NULL; + + idstr_len = snprintf(id_str, sizeof(id_str), "%hu:%hu:", file_id, line); + + /* Skip hash */ + while (*str++ != '\n') + ; + + remaining_bytes -= (str - (char *)dbg_data->str); + + while (remaining_bytes > 0) { + if (strncmp(id_str, str, idstr_len) == 0) { + str += idstr_len; + while (*str == ' ') + ++str; + return (const char *)str; + } + + str += strnlen(str, 512) + 1; + remaining_bytes = dbg_data->size - (str - (char *)dbg_data->str); + } + + /* No match found */ + pr_err("error: file_id=%d line=%d not found in debug print file\n", file_id, line); + return NULL; +} + +void cl_dbgfile_parse(struct cl_hw *cl_hw, void *edata, u32 esize) +{ + /* Parse & store the firmware debug file */ + struct cl_dbg_data *dbg_data = &cl_hw->dbg_data; + + dbg_data->size = esize; + dbg_data->str = edata; +} + +void cl_dbgfile_release_mem(struct cl_dbg_data *dbg_data, + struct cl_str_offload_env *str_offload_env) +{ + dbg_data->str = NULL; + + str_offload_env->enabled = false; + str_offload_env->block1 = NULL; + str_offload_env->block2 = NULL; +} + +/* + * Store debug print offload data + * - part 1: offloaded block that does not exist on target + * - part 2: resident block that remains on target [optional] + */ +int cl_dbgfile_store_offload_data(struct cl_chip *chip, struct cl_hw *cl_hw, + void *data1, u32 size1, u32 base1, + void *data2, u32 size2, u32 base2, + void *data3, u32 size3, u32 base3) +{ + u32 u = size1; + struct cl_str_offload_env *str_offload_env = &cl_hw->str_offload_env; + + if (u > 200000) + goto err_too_big; + + /* TODO we modify offload data! if caller checks integrity, make a copy? */ + str_offload_env->block1 = data1; + str_offload_env->size1 = size1; + str_offload_env->base1 = base1; + + str_offload_env->block2 = data2; + str_offload_env->size2 = size2; + str_offload_env->base2 = base2; + + str_offload_env->block3 = data3; + str_offload_env->size3 = size3; + str_offload_env->base3 = base3; + + str_offload_env->enabled = true; + + cl_dbg_info(cl_hw, "%cmac%u: FW prints offload memory use = %uK\n", + cl_hw->fw_prefix, chip->idx, (size1 + size2 + 1023) / 1024); + + return 0; + +err_too_big: + pr_err("%s: size too big: %u\n", __func__, u); + return 1; +} + +static void do_print_n(struct cl_hw *cl_hw, const char *str, int n) +{ + /* Print formatted string with "band" prefix */ + if (n < 0 || n > 256) { + cl_dbg_err(cl_hw, "%cmac%u: *** FW PRINT - BAD SIZE: %d\n", + cl_hw->fw_prefix, cl_hw->chip->idx, n); + return; + } + + cl_dbg_verbose(cl_hw, "%cmac%u: %.*s\n", cl_hw->fw_prefix, cl_hw->chip->idx, n, str); +} + +static void do_hex_dump_bytes(struct cl_hw *cl_hw, u32 addr, void *data, u32 count) +{ + cl_dbg_verbose(cl_hw, "%cmac%u: hex dump:\n", cl_hw->fw_prefix, cl_hw->chip->idx); + cl_hex_dump(NULL, data, count, addr, true); +} + +#define MAGIC_PRINT_OFFLOAD 0xFA /* 1st (low) byte of signature */ +/* 2-nd signature byte */ +#define MAGIC_PRINT_OFF_XDUMP 0xD0 /* Hex dump, by bytes */ +#define MAGIC_PRINT_OFF_LIT 0x01 /* Literal/preformatted string */ +#define MAGIC_PRINT_OFF_PRINT 0x02 /* Print with 'virtual' format string */ + +#define MAX_PRINT_OFF_PARAMS 20 + +static int offload_print(struct cl_str_offload_env *str_offload_env, char *fmt, const char *params) +{ + static char buf[1024] = {0}; + const char *cur_prm = params; + char tmp; + char *fmt_end = fmt; + size_t size = sizeof(int); + int len = 0; + + union v { + u32 val32; + u64 val64; + ptrdiff_t str; + } v; + + while ((fmt_end = strchr(fmt_end, '%'))) { + fmt_end++; + + /* Skip '%%'. */ + if (*fmt_end == '%') { + fmt_end++; + continue; + } + + /* Skip flags. */ + while (strchr("-+ 0#", *fmt_end)) + fmt_end++; + + /* Skip width. */ + while (isdigit(*fmt_end)) + fmt_end++; + + /* Skip precision. */ + if (*fmt_end == '.') { + while (*fmt_end == '-' || *fmt_end == '+') + fmt_end++; + + while (isdigit(*fmt_end)) + fmt_end++; + } + + /* Get size. */ + if (*fmt_end == 'z') { + /* Remove 'z' from %zu, %zd, %zx and %zX, + * because sizeof(size_t) == 4 in the firmware. + * 'z' can only appear in front of 'd', 'u', 'x' or 'X'. + */ + if (!strchr("duxX", *(fmt_end + 1))) + return -1; + + fmt_end++; + size = 4; + } else if (*fmt_end == 'l') { + fmt_end++; + + if (*fmt_end == 'l') { + fmt_end++; + size = sizeof(long long); + } else { + size = sizeof(long); + } + + if (*fmt_end == 'p') /* %p can't get 'l' or 'll' modifiers. */ + return -1; + } else { + size = 4; + } + + /* Get parameter. */ + switch (*fmt_end) { + case 'p': /* Replace %p with %x, because the firmware's pointers are 32 bit wide */ + *fmt_end = 'x'; + fallthrough; + case 'd': + case 'u': + case 'x': + case 'X': + if (size == 4) + v.val32 = __le32_to_cpu(*(__le32 *)cur_prm); + else + v.val64 = __le64_to_cpu(*(__le64 *)cur_prm); + cur_prm += size; + break; + case 's': + v.str = __le32_to_cpu(*(__le32 *)cur_prm); + cur_prm += 4; + size = sizeof(ptrdiff_t); + + if (v.str >= str_offload_env->base3 && + v.str < str_offload_env->base3 + str_offload_env->size3) { + v.str -= str_offload_env->base3; + v.str += (ptrdiff_t)str_offload_env->block3; + } else if (v.str >= str_offload_env->base2 && + v.str < str_offload_env->base2 + str_offload_env->size2) { + v.str -= str_offload_env->base2; + v.str += (ptrdiff_t)str_offload_env->block2; + } else + return -1; + + break; + default: + return -1; + } + + /* Print into buffer. */ + fmt_end++; + tmp = *fmt_end; /* Truncate the format to the current point and then restore. */ + *fmt_end = 0; + len += snprintf(buf + len, sizeof(buf) - len, fmt, size == 4 ? v.val32 : v.val64); + *fmt_end = tmp; + fmt = fmt_end; + } + + snprintf(buf + len, sizeof(buf) - len, "%s", fmt); + + pr_debug("%s", buf); + + return 0; +} + +struct pr_off_desc { + u8 file_id; + u8 flag; + __le16 line_num; + char fmt[]; +}; + +char *strreplace(char *s, char old, char new) +{ + for (; *s; ++s) + if (*s == old) + *s = new; + return s; +} + +static int do_dprint(struct cl_hw *cl_hw, u32 fmtaddr, u32 nparams, u32 *params) +{ + /* + * fmtaddr - virtual address of format descriptor in firmware, + * must be in the offloaded segment + * nparams - size of parameters array in u32; min=0, max=MAX_PRINT_OFF_PARAMS + * params - array of parameters[nparams] + */ + struct cl_str_offload_env *str_offload_env = &cl_hw->str_offload_env; + struct pr_off_desc *pfmt = NULL; + + if (!str_offload_env->enabled) + return -1; + + if (fmtaddr & 0x3) + cl_dbg_warn(cl_hw, "FW PRINT - format not aligned on 4? %8.8X\n", fmtaddr); + + if (fmtaddr > str_offload_env->base1 && + fmtaddr < (str_offload_env->base1 + str_offload_env->size1)) { + pfmt = (void *)((fmtaddr - str_offload_env->base1) + str_offload_env->block1); + } else { + cl_dbg_err(cl_hw, "FW PRINT - format not in allowed area %8.8X\n", fmtaddr); + return -1; + } + + /* + * Current string sent by firmware is #mac@ where # is '253' and @ is '254' + * Replace '253' with 'l' or 's' according to the fw_prefix. + * Replace '254' with '0' or '1' according to chip index. + */ + strreplace(pfmt->fmt, (char)253, cl_hw->fw_prefix); + strreplace(pfmt->fmt, (char)254, (cl_hw->chip->idx == CHIP0) ? '0' : '1'); + + if (offload_print(str_offload_env, pfmt->fmt, (char *)params) == -1) { + cl_dbg_err(cl_hw, "FW PRINT - ERROR in format! (file %u:%u)\n", + pfmt->file_id, pfmt->line_num); + /* $$$ dbg dump the struct */ + cl_hex_dump(NULL, (void *)pfmt, 48, fmtaddr, true); + return -1; + } + + return 0; +} + +static int do_offload(struct cl_hw *cl_hw, u8 *data, int bytes_remaining) +{ + u8 magic2 = data[1]; + u32 nb = data[2] + (data[3] << 8); /* Following size in bytes */ + /* DATA IS UNALIGNED! REVISE if alignment required or BIG ENDIAN! */ + __le32 *dp = (__le32 *)data; + int bytes_consumed = 4; /* 1 + 1 + 2 */ + + /* Data: [0] u8 magic1, u8 magic2, u16 following size in bytes */ + if (bytes_remaining < 8) { + cl_dbg_err(cl_hw, "*** FW PRINT - OFFLOAD PACKET TOO SHORT: %d\n", + bytes_remaining); + return bytes_remaining; + } + + if (bytes_remaining < (nb + bytes_consumed)) { + cl_dbg_err(cl_hw, "*** FW PRINT - OFFLOAD PACKET %u > remainder %d??\n", + nb, bytes_remaining); + return bytes_remaining; + } + + switch (magic2) { + case MAGIC_PRINT_OFF_PRINT: { + /* + * [1] u32 format descriptor ptr + * [2] u32[] parameters + */ + u32 fmtp = dp[1]; + u32 np = (nb - 4) / 4; /* Number of printf parameters */ + + if (nb < 4 || nb & 3) { + cl_dbg_err(cl_hw, "*** FW PRINT - bad pkt size: %u\n", nb); + goto err; + } + + do_dprint(cl_hw, fmtp, np, &dp[2]); + + bytes_consumed += nb; /* Already padded to 4 bytes */ + } + break; + + case MAGIC_PRINT_OFF_LIT: { + /* [1] Remaining bytes: literal string */ + do_print_n(cl_hw, (char *)&dp[1], nb); + bytes_consumed += ((nb + 3) / 4) * 4; /* Padding to 4 bytes */ + } + break; + + case MAGIC_PRINT_OFF_XDUMP: + /* [1] bytes[nb] */ + if (nb >= 1) + do_hex_dump_bytes(cl_hw, 0, &dp[1], nb); + + bytes_consumed += ((nb + 3) / 4) * 4; /* Padding to 4 bytes */ + break; + + default: + cl_dbg_err(cl_hw, "*** FW PRINT - BAD TYPE: %4.4X\n", magic2); + goto err; + } + + return bytes_consumed; + +err: + return bytes_remaining; /* Skip all */ +} + +void cl_dbgfile_print_fw_str(struct cl_hw *cl_hw, u8 *str, int max_size) +{ + /* Handler for firmware debug prints */ + int bytes_remaining = max_size; + int i; + u8 delim = 0; + + while (bytes_remaining > 0) { + /* Scan for normal print data: */ + for (i = 0; i < bytes_remaining; i++) { + if (str[i] < ' ' || str[i] >= 0x7F) { + if (str[i] == '\t') + continue; + delim = str[i]; + break; + } + } + + if (i > 0) { + if (delim == '\n') { + bytes_remaining -= i + 1; + do_print_n(cl_hw, str, i); + str += i + 1; + continue; + } + + if (delim != MAGIC_PRINT_OFFLOAD) { + do_print_n(cl_hw, str, i); + bytes_remaining -= i; + return; /* Better stop parsing this */ + } + /* Found offload packet but previous string not terminated: */ + do_print_n(cl_hw, str, i); + cl_dbg_err(cl_hw, "*** FW PRINT - NO LINE END2\n"); + bytes_remaining -= i; + str += i; + continue; + } + + /* Delimiter at offset 0 */ + switch (delim) { + case '\n': + do_print_n(cl_hw, " ", 1); /* Print empty line */ + str++; + bytes_remaining--; + continue; + case 0: + return; + case MAGIC_PRINT_OFFLOAD: + i = do_offload(cl_hw, str, bytes_remaining); + bytes_remaining -= i; + str += i; + break; + default: + cl_dbg_err(cl_hw, "*** FW PRINT - BAD BYTE=%2.2X ! rem=%d\n", + delim, bytes_remaining); + return; /* Better stop parsing this */ + } + } +} +