From patchwork Fri Feb 3 17:06:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Pagani X-Patchwork-Id: 52572 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp961953wrn; Fri, 3 Feb 2023 09:21:11 -0800 (PST) X-Google-Smtp-Source: AK7set+hGStbzmjRR5+Xgwi3sIjjwjpq3zxGVvCu85TsPT4LEwZeLyK7i4rSWKHtT41P7NnjmEEc X-Received: by 2002:a05:6a20:d2c9:b0:bf:7ae0:5faf with SMTP id ir9-20020a056a20d2c900b000bf7ae05fafmr8047731pzb.46.1675444871458; Fri, 03 Feb 2023 09:21:11 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675444871; cv=none; d=google.com; s=arc-20160816; b=bgGKkcoXgn1LCRQ+7lZvOkIyQ2Q2nuDUrkL0QlC1O4avlUIwlxmKq4ofx1LV+dk1gS 8qZ5Et8ZCz1385SCoy6bo2KlfI7IUvRdcucD0NpD+sQimthAplk++0AtPYlefEz9eq7y kNdnGEUPvTlcBhh7j/ZrzqI1V78vyf5r9TJ65EtvEWbxTfDzJsduPbvz0OkUFO5m+peL sbV4nG78d/Qdv67Hw/vDoJOO6Kr29+ggtAtFpFPXBMIBB7NU0t9c8Gd5xv8VJsxc+Kco r/I66eawZsMwvxhrkxmqenojZL49FTrmQI6ox6LnngsKx2Imlkr+zV6vNI2bUi0dS+oK N2YA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=QQmhmkEzd3xkaSu4HvpTV2rx3eqChwz0npZXZDCowYk=; b=khQXTU0Yzl9mxTZoyud9CDQ52YWzKglOuRAYiftB2xmvqWGE2q7aGIA1ywBGeiHOEt JuOzs4eFdPnBYM2u5AwEUAVgPA4gOUuqDYMURumYxdr9GpDTAXAOmqdxXzlwPQOvEItv oEOkMQR9xHmu4zCo6EGkxiaazRWqQuThOiXsLGBy2OdI/HnSc4ZxwCnGltwS6c+paF5m wUe1B1kyURzfbpekrU7BLBAqWDr/Z1hB/TFjXMMsgJRQKCSK0UvGkJF4h64EN857av0a yZitgHHN4ekIQAjkt8mc+eM5huK4o2egKz/ZbWWDYW3zQDOPH3JINA/153ZPdvlh9Nj1 vlyw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=S9i4U2qQ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id 12-20020a630d4c000000b004efd1529e26si3353078pgn.330.2023.02.03.09.20.58; Fri, 03 Feb 2023 09:21:11 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=S9i4U2qQ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233705AbjBCRIX (ORCPT + 99 others); Fri, 3 Feb 2023 12:08:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54132 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233039AbjBCRIL (ORCPT ); Fri, 3 Feb 2023 12:08:11 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 338C6A9104 for ; Fri, 3 Feb 2023 09:07:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1675444038; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QQmhmkEzd3xkaSu4HvpTV2rx3eqChwz0npZXZDCowYk=; b=S9i4U2qQ5Ir1g6CBxz5LWKY11qvlu8k1V7XZRpMSpmHop/GAM8rnaSg250xeI5B2115qug pLWAFQ7teKXJzvKPJVppCHqk0G8aycJvbFaOqgOVw2mUnXlsQ58xKCYgvT5NtPZ2MLYabn tRVJ2woXBJAs6lOgUiQ1L04h7mgGKvs= Received: from mail-qk1-f199.google.com (mail-qk1-f199.google.com [209.85.222.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-251-17xKA9r0P8KR3vxGXWiI7A-1; Fri, 03 Feb 2023 12:07:17 -0500 X-MC-Unique: 17xKA9r0P8KR3vxGXWiI7A-1 Received: by mail-qk1-f199.google.com with SMTP id ay10-20020a05620a178a00b0072db6346c39so2332004qkb.16 for ; Fri, 03 Feb 2023 09:07:17 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QQmhmkEzd3xkaSu4HvpTV2rx3eqChwz0npZXZDCowYk=; b=lPRNpwrSS8qk4M1XJT1UJVYGacIOpUkjgP/Wbczl4uwpTmVa7U8UbqjV6vNa+GLWrD MUp8z5fCpdSH8ThQ9qyeCgStUqr+wAx4E/qhBARCDZMyLym0KvUyr4FhAqF3JOYhBDkN skdJrHoqlodRdgj9W2IVHjI5rVwTGelYO+NjyYpEn0W+QTjcL5aS43gQFdnqL0RyeRFD 1Uwi6eTvJnaCKaAVbV2bttwTttNOUnrjVQ4lt2e6FznHh6ugiyU9/2e5M4qux7TMCFYB 2dGZtHCh3RJ5f1eYDNCRskHQqmjrTmk8DlNaucfHJaMYHVOaZLTU3XcYPGMJOKIxehyV 4sCA== X-Gm-Message-State: AO0yUKXT9GIIByaH/JMfC9gdUwcKxZBxdPZ8CQFvD3XkV9Qlj2I/FJLO UfGgD0pMH3ktTJ8Idf3f7uRegT+ZF9V9XfuQqkP34mA4Bnt7CzCQ+Q5FO16rn4bK2Wq3Ob3+277 zm54PQN7hLCuSlmIdxBBjOOs= X-Received: by 2002:a05:622a:14ca:b0:3b8:58d0:b4e4 with SMTP id u10-20020a05622a14ca00b003b858d0b4e4mr19562218qtx.33.1675444036417; Fri, 03 Feb 2023 09:07:16 -0800 (PST) X-Received: by 2002:a05:622a:14ca:b0:3b8:58d0:b4e4 with SMTP id u10-20020a05622a14ca00b003b858d0b4e4mr19562176qtx.33.1675444036095; Fri, 03 Feb 2023 09:07:16 -0800 (PST) Received: from klayman.redhat.com (net-2-34-30-183.cust.vodafonedsl.it. [2.34.30.183]) by smtp.gmail.com with ESMTPSA id b13-20020ac801cd000000b003a6a19ee4f0sm1884287qtg.33.2023.02.03.09.07.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Feb 2023 09:07:15 -0800 (PST) From: Marco Pagani To: Moritz Fischer , Wu Hao , Xu Yilun , Tom Rix Cc: Marco Pagani , linux-kernel@vger.kernel.org, linux-fpga@vger.kernel.org Subject: [RFC PATCH 1/4] fpga: add initial KUnit test suite Date: Fri, 3 Feb 2023 18:06:50 +0100 Message-Id: <20230203170653.414990-2-marpagan@redhat.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230203170653.414990-1-marpagan@redhat.com> References: <20230203170653.414990-1-marpagan@redhat.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1756831281678052070?= X-GMAIL-MSGID: =?utf-8?q?1756831281678052070?= Introduce an initial KUnit suite to test the core components of the FPGA subsystem. The test suite consists of two test cases. The first test case checks the programming of a static image on a fake FPGA with a single hardware bridge. The FPGA is first programmed using a test image stored in a buffer, and then with the same image linked to a single-entry scatter-gather list. The second test case models dynamic partial reconfiguration. The FPGA is first configured with a static image that implements a reconfigurable design containing a sub-region controlled by two soft bridges. Then, the reconfigurable sub-region is reconfigured using a fake partial bitstream image. After the reconfiguration, the test checks that the soft bridges have been correctly activated. Signed-off-by: Marco Pagani --- drivers/fpga/Kconfig | 2 + drivers/fpga/Makefile | 3 + drivers/fpga/tests/.kunitconfig | 5 + drivers/fpga/tests/Kconfig | 15 ++ drivers/fpga/tests/Makefile | 6 + drivers/fpga/tests/fpga-tests.c | 264 ++++++++++++++++++++++++++++++++ 6 files changed, 295 insertions(+) create mode 100644 drivers/fpga/tests/.kunitconfig create mode 100644 drivers/fpga/tests/Kconfig create mode 100644 drivers/fpga/tests/Makefile create mode 100644 drivers/fpga/tests/fpga-tests.c diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index 0a00763b9f28..2f689ac4ba3a 100644 --- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig @@ -276,4 +276,6 @@ config FPGA_MGR_LATTICE_SYSCONFIG_SPI FPGA manager driver support for Lattice FPGAs programming over slave SPI sysCONFIG interface. +source "drivers/fpga/tests/Kconfig" + endif # FPGA diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile index 72e554b4d2f7..352a2612623e 100644 --- a/drivers/fpga/Makefile +++ b/drivers/fpga/Makefile @@ -55,3 +55,6 @@ obj-$(CONFIG_FPGA_DFL_NIOS_INTEL_PAC_N3000) += dfl-n3000-nios.o # Drivers for FPGAs which implement DFL obj-$(CONFIG_FPGA_DFL_PCI) += dfl-pci.o + +# KUnit tests +obj-$(CONFIG_FPGA_KUNIT_TESTS) += tests/ diff --git a/drivers/fpga/tests/.kunitconfig b/drivers/fpga/tests/.kunitconfig new file mode 100644 index 000000000000..a1c2a2974c39 --- /dev/null +++ b/drivers/fpga/tests/.kunitconfig @@ -0,0 +1,5 @@ +CONFIG_KUNIT=y +CONFIG_FPGA=y +CONFIG_FPGA_REGION=y +CONFIG_FPGA_BRIDGE=y +CONFIG_FPGA_KUNIT_TESTS=y diff --git a/drivers/fpga/tests/Kconfig b/drivers/fpga/tests/Kconfig new file mode 100644 index 000000000000..5198e605b38d --- /dev/null +++ b/drivers/fpga/tests/Kconfig @@ -0,0 +1,15 @@ +config FPGA_KUNIT_TESTS + tristate "FPGA KUnit tests" if !KUNIT_ALL_TESTS + depends on FPGA && FPGA_REGION && FPGA_BRIDGE && KUNIT + default KUNIT_ALL_TESTS + help + Builds unit tests for the FPGA subsystem. This option + is not useful for distributions or general kernels, + but only for kernel developers working on the FPGA + subsystem and its associated drivers. + + For more information on KUnit and unit tests in general, + please refer to the KUnit documentation in + Documentation/dev-tools/kunit/. + + If in doubt, say "N". diff --git a/drivers/fpga/tests/Makefile b/drivers/fpga/tests/Makefile new file mode 100644 index 000000000000..74346ae62457 --- /dev/null +++ b/drivers/fpga/tests/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_FPGA_KUNIT_TESTS) += fake-fpga-mgr.o +obj-$(CONFIG_FPGA_KUNIT_TESTS) += fake-fpga-region.o +obj-$(CONFIG_FPGA_KUNIT_TESTS) += fake-fpga-bridge.o +obj-$(CONFIG_FPGA_KUNIT_TESTS) += fpga-tests.o diff --git a/drivers/fpga/tests/fpga-tests.c b/drivers/fpga/tests/fpga-tests.c new file mode 100644 index 000000000000..33f04079b32f --- /dev/null +++ b/drivers/fpga/tests/fpga-tests.c @@ -0,0 +1,264 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test suite for the FPGA subsystem + * + * Copyright (C) 2023 Red Hat, Inc. All rights reserved. + * + * Author: Marco Pagani + */ + +#include +#include +#include + +#include +#include +#include + +#include "fake-fpga-region.h" +#include "fake-fpga-bridge.h" +#include "fake-fpga-mgr.h" + +#define FAKE_BIT_BLOCKS 16 +#define FAKE_BIT_SIZE (FPGA_TEST_BIT_BLOCK * FAKE_BIT_BLOCKS) + +static u8 fake_bit[FAKE_BIT_SIZE]; + +static int init_sgt_bit(struct sg_table *sgt, void *bit, size_t len) +{ + int ret; + + ret = sg_alloc_table(sgt, 1, GFP_KERNEL); + if (ret) + return ret; + + sg_init_one(sgt->sgl, bit, len); + + return ret; +} + +static void free_sgt_bit(struct sg_table *sgt) +{ + if (sgt) + sg_free_table(sgt); +} + +static void fpga_build_base_sys(struct kunit *test, struct fake_fpga_mgr *mgr_ctx, + struct fake_fpga_bridge *bridge_ctx, + struct fake_fpga_region *region_ctx) +{ + int ret; + + ret = fake_fpga_mgr_register(mgr_ctx, test); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = fake_fpga_bridge_register(bridge_ctx, test); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = fake_fpga_region_register(region_ctx, mgr_ctx->mgr, test); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = fake_fpga_region_add_bridge(region_ctx, bridge_ctx->bridge); + KUNIT_ASSERT_EQ(test, ret, 0); +} + +static void fpga_free_base_sys(struct fake_fpga_mgr *mgr_ctx, + struct fake_fpga_bridge *bridge_ctx, + struct fake_fpga_region *region_ctx) +{ + if (region_ctx) + fake_fpga_region_unregister(region_ctx); + + if (bridge_ctx) + fake_fpga_bridge_unregister(bridge_ctx); + + if (region_ctx) + fake_fpga_mgr_unregister(mgr_ctx); +} + +static int fpga_suite_init(struct kunit_suite *suite) +{ + fake_fpga_mgr_fill_header(fake_bit); + + return 0; +} + +static void fpga_base_test(struct kunit *test) +{ + int ret; + + struct fake_fpga_mgr mgr_ctx; + struct fake_fpga_bridge base_bridge_ctx; + struct fake_fpga_region base_region_ctx; + + struct fpga_image_info *test_img_info; + + struct sg_table sgt_bit; + + fpga_build_base_sys(test, &mgr_ctx, &base_bridge_ctx, &base_region_ctx); + + /* Allocate a fake test image using a buffer */ + test_img_info = fpga_image_info_alloc(&mgr_ctx.pdev->dev); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, test_img_info); + + test_img_info->buf = fake_bit; + test_img_info->count = sizeof(fake_bit); + + kunit_info(test, "fake bitstream size: %zu\n", test_img_info->count); + + KUNIT_EXPECT_EQ(test, 0, fake_fpga_mgr_get_rcfg_count(&mgr_ctx)); + + KUNIT_EXPECT_EQ(test, 0, fake_fpga_bridge_get_state(&base_bridge_ctx)); + KUNIT_EXPECT_EQ(test, 0, fake_fpga_bridge_get_cycles_count(&base_bridge_ctx)); + + /* Program the fake FPGA using the image buffer */ + base_region_ctx.region->info = test_img_info; + ret = fpga_region_program_fpga(base_region_ctx.region); + KUNIT_ASSERT_EQ(test, ret, 0); + + fake_fpga_mgr_check_write_buf(&mgr_ctx); + + KUNIT_EXPECT_EQ(test, 1, fake_fpga_mgr_get_rcfg_count(&mgr_ctx)); + + KUNIT_EXPECT_EQ(test, 1, fake_fpga_bridge_get_state(&base_bridge_ctx)); + KUNIT_EXPECT_EQ(test, 1, fake_fpga_bridge_get_cycles_count(&base_bridge_ctx)); + + fpga_image_info_free(test_img_info); + + /* Allocate another fake test image using a scatter list */ + test_img_info = fpga_image_info_alloc(&mgr_ctx.pdev->dev); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, test_img_info); + + ret = init_sgt_bit(&sgt_bit, fake_bit, FAKE_BIT_SIZE); + KUNIT_ASSERT_EQ(test, ret, 0); + + test_img_info->sgt = &sgt_bit; + + /* Re-program the fake FPGA using the image scatter list */ + base_region_ctx.region->info = test_img_info; + ret = fpga_region_program_fpga(base_region_ctx.region); + KUNIT_ASSERT_EQ(test, ret, 0); + + fake_fpga_mgr_check_write_sg(&mgr_ctx); + + KUNIT_EXPECT_EQ(test, 2, fake_fpga_mgr_get_rcfg_count(&mgr_ctx)); + + KUNIT_EXPECT_EQ(test, 1, fake_fpga_bridge_get_state(&base_bridge_ctx)); + KUNIT_EXPECT_EQ(test, 2, fake_fpga_bridge_get_cycles_count(&base_bridge_ctx)); + + free_sgt_bit(&sgt_bit); + fpga_image_info_free(test_img_info); + fpga_free_base_sys(&mgr_ctx, &base_bridge_ctx, &base_region_ctx); +} + +static void fpga_pr_test(struct kunit *test) +{ + int ret; + + struct fake_fpga_mgr mgr_ctx; + struct fake_fpga_bridge base_bridge_ctx; + struct fake_fpga_region base_region_ctx; + + struct fake_fpga_bridge pr_bridge_0_ctx; + struct fake_fpga_bridge pr_bridge_1_ctx; + struct fake_fpga_region pr_region_ctx; + + struct fpga_image_info *test_static_img_info; + struct fpga_image_info *test_pr_img_info; + + fpga_build_base_sys(test, &mgr_ctx, &base_bridge_ctx, &base_region_ctx); + + /* Allocate a fake test image using a buffer */ + test_static_img_info = fpga_image_info_alloc(&mgr_ctx.pdev->dev); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, test_static_img_info); + + test_static_img_info->buf = fake_bit; + test_static_img_info->count = sizeof(fake_bit); + + kunit_info(test, "fake bitstream size: %zu\n", test_static_img_info->count); + + KUNIT_EXPECT_EQ(test, 0, fake_fpga_mgr_get_rcfg_count(&mgr_ctx)); + + KUNIT_EXPECT_EQ(test, 0, fake_fpga_bridge_get_state(&base_bridge_ctx)); + KUNIT_EXPECT_EQ(test, 0, fake_fpga_bridge_get_cycles_count(&base_bridge_ctx)); + + /* Program the fake FPGA using the image buffer */ + base_region_ctx.region->info = test_static_img_info; + ret = fpga_region_program_fpga(base_region_ctx.region); + KUNIT_ASSERT_EQ(test, ret, 0); + + fake_fpga_mgr_check_write_buf(&mgr_ctx); + + KUNIT_EXPECT_EQ(test, 1, fake_fpga_mgr_get_rcfg_count(&mgr_ctx)); + + KUNIT_EXPECT_EQ(test, 1, fake_fpga_bridge_get_state(&base_bridge_ctx)); + KUNIT_EXPECT_EQ(test, 1, fake_fpga_bridge_get_cycles_count(&base_bridge_ctx)); + + /* The static image contains a reconfigurable sub-region with two soft bridges */ + ret = fake_fpga_bridge_register(&pr_bridge_0_ctx, test); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = fake_fpga_bridge_register(&pr_bridge_1_ctx, test); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = fake_fpga_region_register(&pr_region_ctx, mgr_ctx.mgr, test); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = fake_fpga_region_add_bridge(&pr_region_ctx, pr_bridge_0_ctx.bridge); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = fake_fpga_region_add_bridge(&pr_region_ctx, pr_bridge_1_ctx.bridge); + KUNIT_ASSERT_EQ(test, ret, 0); + + /* Allocate a fake partial test image using a buffer */ + test_pr_img_info = fpga_image_info_alloc(&mgr_ctx.pdev->dev); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, test_pr_img_info); + + test_pr_img_info->buf = fake_bit; + test_pr_img_info->count = sizeof(fake_bit) / 2; + test_pr_img_info->flags = FPGA_MGR_PARTIAL_RECONFIG; + + kunit_info(test, "fake partial bitstream size: %zu\n", test_pr_img_info->count); + + /* Program the reconfigurable sub-region */ + pr_region_ctx.region->info = test_pr_img_info; + ret = fpga_region_program_fpga(pr_region_ctx.region); + KUNIT_ASSERT_EQ(test, ret, 0); + + fake_fpga_mgr_check_write_buf(&mgr_ctx); + + KUNIT_EXPECT_EQ(test, 2, fake_fpga_mgr_get_rcfg_count(&mgr_ctx)); + + KUNIT_EXPECT_EQ(test, 1, fake_fpga_bridge_get_state(&pr_bridge_0_ctx)); + KUNIT_EXPECT_EQ(test, 1, fake_fpga_bridge_get_cycles_count(&pr_bridge_0_ctx)); + + KUNIT_EXPECT_EQ(test, 1, fake_fpga_bridge_get_state(&pr_bridge_1_ctx)); + KUNIT_EXPECT_EQ(test, 1, fake_fpga_bridge_get_cycles_count(&pr_bridge_1_ctx)); + + /* Check that the base bridge has not been disabled */ + KUNIT_EXPECT_EQ(test, 1, fake_fpga_bridge_get_state(&base_bridge_ctx)); + KUNIT_EXPECT_EQ(test, 1, fake_fpga_bridge_get_cycles_count(&base_bridge_ctx)); + + fpga_image_info_free(test_pr_img_info); + fpga_image_info_free(test_static_img_info); + + fake_fpga_region_unregister(&pr_region_ctx); + fake_fpga_bridge_unregister(&pr_bridge_0_ctx); + fake_fpga_bridge_unregister(&pr_bridge_1_ctx); + + fpga_free_base_sys(&mgr_ctx, &base_bridge_ctx, &base_region_ctx); +} + +static struct kunit_case fpga_test_cases[] = { + KUNIT_CASE(fpga_base_test), + KUNIT_CASE(fpga_pr_test), + {}, +}; + +static struct kunit_suite fpga_test_suite = { + .name = "fpga-tests", + .suite_init = fpga_suite_init, + .test_cases = fpga_test_cases, +}; + +kunit_test_suite(fpga_test_suite); From patchwork Fri Feb 3 17:06:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Pagani X-Patchwork-Id: 52570 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp960488wrn; Fri, 3 Feb 2023 09:18:25 -0800 (PST) X-Google-Smtp-Source: AK7set/nB7EHW6KdWCwlJvJVYkhsDyl5DTZNNqjCJCqWpuXc5dAy8yfofNCgD0rIcbbG2glsAnl+ X-Received: by 2002:a17:902:ca8d:b0:198:e1b1:e8b4 with SMTP id v13-20020a170902ca8d00b00198e1b1e8b4mr1247565pld.41.1675444705445; Fri, 03 Feb 2023 09:18:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675444705; cv=none; d=google.com; s=arc-20160816; b=La2FJ61YI1ATlgFSOdu/GCfCmu6nedZhpneiR+wGuCFnB8dLOCSTX9+9vyyoJgXWjS UW7tCu6wnq7Keb7mTcqZGmOnpbHwhpZB1YCqxaYZB/+S695KwwZ2rjK+uHk3oe5O0HU3 X3sR1DorW1Rd/0MyVYzvzZMTu6SZqBWzD9WooEOE0pDyG5C/OJZwfDZfL/UHvGXiSbmO 8NgRhAP1BmQ7Cx6PziS5XuYjJ61RIfugCXZ89UbT+6nlCSw9vupcTFBjeVTdl9iad87+ ERAQ6X8Ax/X+tDEh052g4Svt17N77MxcpFeEiDD7D3rngc/yRbIMYQfBpYbMhPPiZ37t TP4A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=nXijhy+bLVt2oImSC5wDtd/ir3c5z1uIhiC8dhyhZro=; b=s95CYKv1ryMucoabRYuQ7qMcCUF2D1UHKdXd6qbhMbbQYOtME++DLWd9HydYbtN3vz L6hDWgrsC/O3bPurop6aW0y/eygiVuCKAVGgy3oYA7oh0T0EEUBxtgm5IoJVviLH8w5/ Wd6r46nd+Wn1yQ17Ca4lbROZ1NfiYgjxvP3z7kRaKWN0AE+g4zpXXMdllesoF7WRm13f e3OlSyEshvHXKyv9YJttN63Isp53xdheuB1KjWpwNz7tpyGOEoWn6rORlBEu+yraSTx5 6nU8HEkcUSyVV9gnF1NMS3SiNJP9s9GwESYTNH1gIIKEfAWHzcXV2AtKjL2X1+y9qJw/ w/QQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=X06ttQ8K; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id n4-20020a170902e54400b001930b177a04si3093048plf.323.2023.02.03.09.18.13; Fri, 03 Feb 2023 09:18:25 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=X06ttQ8K; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233395AbjBCRIR (ORCPT + 99 others); Fri, 3 Feb 2023 12:08:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54262 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232989AbjBCRIL (ORCPT ); Fri, 3 Feb 2023 12:08:11 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8B5C9A8A27 for ; Fri, 3 Feb 2023 09:07:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1675444039; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nXijhy+bLVt2oImSC5wDtd/ir3c5z1uIhiC8dhyhZro=; b=X06ttQ8KlPTVhyicR6iKpuLkV+4csxRITmp1NrJgQso21/MK8Fmw1m+a/UhTIkNXEDW14f Z1CEoat9igZFUTfHbgL7yKJxiStRsaWzb5u3D3hPcbdDpsyyKk4doMyEjkvDLyPqapZCT0 GQreuOCBV1vWdcZoetdzyT69LAuRtQ8= Received: from mail-qv1-f69.google.com (mail-qv1-f69.google.com [209.85.219.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-638-8tNwc5pmMHWQBakJH9TQUw-1; Fri, 03 Feb 2023 12:07:18 -0500 X-MC-Unique: 8tNwc5pmMHWQBakJH9TQUw-1 Received: by mail-qv1-f69.google.com with SMTP id c10-20020a05621401ea00b004c72d0e92bcso3032487qvu.12 for ; Fri, 03 Feb 2023 09:07:18 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nXijhy+bLVt2oImSC5wDtd/ir3c5z1uIhiC8dhyhZro=; b=kG6ft48wQxmyPe85AXDZxHa9ygKfKKB0M3mFh9Z1NjNRYUCFmPeipQgP649gpdHh4T neE+YYlnwicGvd0XSyxldajDTAvU2Re6eL3F7xDBe7CXYEDs7fp/I03QkcwOCXc6F2X6 YfzAD8xqq5EK7hKAKnPZMX97Bq3EgKNZOoSk6N73gEA0szPQMV4yhNEpMlD5ooxA9Myp x9I8ymUqTkEFXIFzNiAekC04A1S+wSUwyKHpNA8Nj2t1jqYElUQgtOkXxBrKI+GkCc+x 40KLq4vP9ITYWSxrvCjhO8lrz335G9oPmfX1KeMMHWTZ8hlf2nhVyvGqkpNeKaeNApuD ICew== X-Gm-Message-State: AO0yUKU+MJOrXim+5tJQhALqrod070zN76RsXELLg3g1u0vf3bXUEFPH ni1BGFCwwvxsPhbJQNY4cMXZs4vS/nYL5gjcnC3xhV94sP7Ut/+clRjLea6dODp9FK+0RudYDfg 1J7XOu35MXLYVSjleYn60O2c= X-Received: by 2002:a05:622a:24e:b0:3a9:8cc6:d4b2 with SMTP id c14-20020a05622a024e00b003a98cc6d4b2mr9749349qtx.5.1675444038085; Fri, 03 Feb 2023 09:07:18 -0800 (PST) X-Received: by 2002:a05:622a:24e:b0:3a9:8cc6:d4b2 with SMTP id c14-20020a05622a024e00b003a98cc6d4b2mr9749315qtx.5.1675444037771; Fri, 03 Feb 2023 09:07:17 -0800 (PST) Received: from klayman.redhat.com (net-2-34-30-183.cust.vodafonedsl.it. [2.34.30.183]) by smtp.gmail.com with ESMTPSA id b13-20020ac801cd000000b003a6a19ee4f0sm1884287qtg.33.2023.02.03.09.07.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Feb 2023 09:07:17 -0800 (PST) From: Marco Pagani To: Moritz Fischer , Wu Hao , Xu Yilun , Tom Rix Cc: Marco Pagani , linux-kernel@vger.kernel.org, linux-fpga@vger.kernel.org Subject: [RFC PATCH 2/4] fpga: add fake FPGA region Date: Fri, 3 Feb 2023 18:06:51 +0100 Message-Id: <20230203170653.414990-3-marpagan@redhat.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230203170653.414990-1-marpagan@redhat.com> References: <20230203170653.414990-1-marpagan@redhat.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1756831107670050756?= X-GMAIL-MSGID: =?utf-8?q?1756831107670050756?= Add fake FPGA region platform driver with support functions. This module is part of the KUnit test suite for the FPGA subsystem. Signed-off-by: Marco Pagani --- drivers/fpga/tests/fake-fpga-region.c | 186 ++++++++++++++++++++++++++ drivers/fpga/tests/fake-fpga-region.h | 37 +++++ 2 files changed, 223 insertions(+) create mode 100644 drivers/fpga/tests/fake-fpga-region.c create mode 100644 drivers/fpga/tests/fake-fpga-region.h diff --git a/drivers/fpga/tests/fake-fpga-region.c b/drivers/fpga/tests/fake-fpga-region.c new file mode 100644 index 000000000000..095397e41837 --- /dev/null +++ b/drivers/fpga/tests/fake-fpga-region.c @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for fake FPGA region + * + * Copyright (C) 2023 Red Hat, Inc. All rights reserved. + * + * Author: Marco Pagani + */ + +#include +#include +#include +#include +#include +#include + +#include "fake-fpga-region.h" + +#define FAKE_FPGA_REGION_DEV_NAME "fake_fpga_region" + +struct fake_region_priv { + int id; + struct kunit *test; +}; + +struct fake_region_data { + struct fpga_manager *mgr; + struct kunit *test; +}; + +/** + * fake_fpga_region_register - register a fake FPGA region + * @region_ctx: fake FPGA region context data structure. + * @test: KUnit test context object. + * + * Return: 0 if registration succeeded, an error code otherwise. + */ +int fake_fpga_region_register(struct fake_fpga_region *region_ctx, + struct fpga_manager *mgr, struct kunit *test) +{ + struct fake_region_data pdata; + struct fake_region_priv *priv; + int ret; + + pdata.mgr = mgr; + pdata.test = test; + + region_ctx->pdev = platform_device_alloc(FAKE_FPGA_REGION_DEV_NAME, + PLATFORM_DEVID_AUTO); + if (IS_ERR(region_ctx->pdev)) { + pr_err("Fake FPGA region device allocation failed\n"); + return -ENOMEM; + } + + platform_device_add_data(region_ctx->pdev, &pdata, sizeof(pdata)); + + ret = platform_device_add(region_ctx->pdev); + if (ret) { + pr_err("Fake FPGA region device add failed\n"); + platform_device_put(region_ctx->pdev); + return ret; + } + + region_ctx->region = platform_get_drvdata(region_ctx->pdev); + + if (test) { + priv = region_ctx->region->priv; + kunit_info(test, "Fake FPGA region %d registered\n", priv->id); + } + + return 0; +} +EXPORT_SYMBOL_GPL(fake_fpga_region_register); + +/** + * fake_fpga_region_unregister - unregister a fake FPGA region + * @region_ctx: fake FPGA region context data structure. + */ +void fake_fpga_region_unregister(struct fake_fpga_region *region_ctx) +{ + struct fake_region_priv *priv; + struct kunit *test; + int id; + + priv = region_ctx->region->priv; + test = priv->test; + id = priv->id; + + if (region_ctx->pdev) { + platform_device_unregister(region_ctx->pdev); + if (test) + kunit_info(test, "Fake FPGA region %d unregistered\n", id); + } +} +EXPORT_SYMBOL_GPL(fake_fpga_region_unregister); + +/** + * fake_fpga_region_add_bridge - add a bridge to a fake FPGA region + * @region_ctx: fake FPGA region context data structure. + * @bridge: FPGA bridge. + * + * Return: 0 if registration succeeded, an error code otherwise. + */ +int fake_fpga_region_add_bridge(struct fake_fpga_region *region_ctx, + struct fpga_bridge *bridge) +{ + struct fake_region_priv *priv; + int ret; + + priv = region_ctx->region->priv; + + ret = fpga_bridge_get_to_list(bridge->dev.parent, NULL, + ®ion_ctx->region->bridge_list); + + if (priv->test && !ret) + kunit_info(priv->test, "Bridge added to fake FPGA region %d\n", + priv->id); + + return ret; +} +EXPORT_SYMBOL_GPL(fake_fpga_region_add_bridge); + +static int fake_fpga_region_probe(struct platform_device *pdev) +{ + struct device *dev; + struct fpga_region *region; + struct fpga_manager *mgr; + struct fake_region_data *pdata; + struct fake_region_priv *priv; + static int id_count; + + dev = &pdev->dev; + pdata = dev_get_platdata(dev); + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + mgr = fpga_mgr_get(pdata->mgr->dev.parent); + if (IS_ERR(mgr)) + return PTR_ERR(mgr); + + /* + * No get_bridges() method since the bridges list is + * pre-built using fake_fpga_region_add_bridge() + */ + region = fpga_region_register(dev, mgr, NULL); + if (IS_ERR(region)) { + fpga_mgr_put(mgr); + return PTR_ERR(region); + } + + priv->test = pdata->test; + priv->id = id_count++; + region->priv = priv; + + platform_set_drvdata(pdev, region); + + return 0; +} + +static int fake_fpga_region_remove(struct platform_device *pdev) +{ + struct fpga_region *region = platform_get_drvdata(pdev); + struct fpga_manager *mgr = region->mgr; + + fpga_mgr_put(mgr); + fpga_bridges_put(®ion->bridge_list); + fpga_region_unregister(region); + + return 0; +} + +static struct platform_driver fake_fpga_region_drv = { + .driver = { + .name = FAKE_FPGA_REGION_DEV_NAME + }, + .probe = fake_fpga_region_probe, + .remove = fake_fpga_region_remove, +}; + +module_platform_driver(fake_fpga_region_drv); + +MODULE_AUTHOR("Marco Pagani "); +MODULE_DESCRIPTION("Fake FPGA Bridge"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/fpga/tests/fake-fpga-region.h b/drivers/fpga/tests/fake-fpga-region.h new file mode 100644 index 000000000000..55b2df3f04ba --- /dev/null +++ b/drivers/fpga/tests/fake-fpga-region.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Header file for fake FPGA region + * + * Copyright (C) 2023 Red Hat, Inc. All rights reserved. + * + * Author: Marco Pagani + */ + +#ifndef __FPGA_FAKE_RGN_H +#define __FPGA_FAKE_RGN_H + +#include +#include +#include +#include + +/** + * struct fake_fpga_region - fake FPGA region context data structure + * + * @region: FPGA region. + * @pdev: platform device of the FPGA region. + */ +struct fake_fpga_region { + struct fpga_region *region; + struct platform_device *pdev; +}; + +int fake_fpga_region_register(struct fake_fpga_region *region_ctx, + struct fpga_manager *mgr, struct kunit *test); + +int fake_fpga_region_add_bridge(struct fake_fpga_region *region_ctx, + struct fpga_bridge *bridge); + +void fake_fpga_region_unregister(struct fake_fpga_region *region_ctx); + +#endif /* __FPGA_FAKE_RGN_H */ From patchwork Fri Feb 3 17:06:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Pagani X-Patchwork-Id: 52571 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp961711wrn; Fri, 3 Feb 2023 09:20:41 -0800 (PST) X-Google-Smtp-Source: AK7set9xqJpIJyYG8NPI2oQvr/TweU4O8PTtss7UXvBiZ/o0L4U8nYilAWPxOqflYrVJW3lZnA2Y X-Received: by 2002:a05:6a20:699b:b0:b6:3e6e:af94 with SMTP id t27-20020a056a20699b00b000b63e6eaf94mr14232802pzk.32.1675444841546; Fri, 03 Feb 2023 09:20:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675444841; cv=none; d=google.com; s=arc-20160816; b=ICesuN4QJTTFZYG4MQu+iM7xHqwMOTxbs9+YVSe85jOIW5+FHMg+F/FVHB0HbNxtgj Q7PScicr/bYR3Ddj+0e6gBomLheU6icsX4ozmFj1MnaWoLUtr95uSWRnKMoYNiOZ5ojP fEBhSZeyO5T2I6dpYzQ4U+awfllY23c2/4LVic8CW+ycj2BAZ8MMzSNGeDAum+bsRLF+ 6kkTYRxflcOlJcLXEyfLg6cI4vOgDlsJ3fq6ge4jlRyY5+iGaQmefvu7CkJr5t4KtXuV puZAS+IyC8oaRxZGRP5+l0Omdc4JA9TNsndwEzJaZc5e91eODgYLD46l8rx/zexQEG7u YKIQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=n/LlZDn23HB324SQHQ+0J+ByiKAzljtqAhnLrmeqO/k=; b=sTeOlNhQ8dCudbLisUVF5IkyCooCsXSxsULJyThlbiPENUz/dj4aWj6zL7G8pB7ZSx SJGfxMp+1n3vqZiW2gqpRpOstc0L4ahHg9aWcOhn1SOV8UB66UHW7ukgC1zRJ/VSsnKv sVcWMHSELwGVjPHqSjC7RJWlhlv5glgOj0lsSOVPb0i8W4LVEZI6O8wdjs5aBq4dG0AS v7ZgUkasBNE6J24yxRlM8AXUfsWhQpjTYqK74pKVFkwlzxR0YvByUoTDj9fm9IrY9qa4 n0E9dx303uvS07ji0/USrnIAsh4Ystut1JCRE8hG5natqbCveOXBYyIy6bTnKPyXKFtp dCkg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="aG9n/SHA"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id i9-20020a639d09000000b004de7c3add77si3290499pgd.262.2023.02.03.09.20.28; Fri, 03 Feb 2023 09:20:41 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="aG9n/SHA"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233537AbjBCRIb (ORCPT + 99 others); Fri, 3 Feb 2023 12:08:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54286 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233560AbjBCRIT (ORCPT ); Fri, 3 Feb 2023 12:08:19 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6F2689EE32 for ; Fri, 3 Feb 2023 09:07:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1675444043; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=n/LlZDn23HB324SQHQ+0J+ByiKAzljtqAhnLrmeqO/k=; b=aG9n/SHA7uoUtxXw9jk8b7ulvjs0IHz/kUQQGQmPkttWutsh9St3s+6+j8KqwYYw60MpwI MSpt+EVK0pXns4ZYAdezkJ+tvGiVVJAE8juuLnwjRqYKTxroZjM2e2GJISDXmiouwcG+Ln FZ3PGwDDJkwFZJT5EujYoPZB/cX9ZrQ= Received: from mail-qk1-f199.google.com (mail-qk1-f199.google.com [209.85.222.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-616-sH77CVEjN_u_uPqCsapZMg-1; Fri, 03 Feb 2023 12:07:20 -0500 X-MC-Unique: sH77CVEjN_u_uPqCsapZMg-1 Received: by mail-qk1-f199.google.com with SMTP id x12-20020a05620a258c00b007051ae500a2so3645973qko.15 for ; Fri, 03 Feb 2023 09:07:20 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=n/LlZDn23HB324SQHQ+0J+ByiKAzljtqAhnLrmeqO/k=; b=slMfsejN8uxzBla0ipM0lAXxhgnPopU5th9gwEXyolDHGXphcGc1tU/JUeJVaLPvvF tOGZq4jpHlbxktg4jF8VuOjSDuunoaHd/XxAAiJrX1Ioz0uDyqKfzQQ2UMEohyVFVw8Z psdHfs18I9DpKRCsPHRHuqKdpRsQkUOTs7RlMuHept03xMEXsuHaDHpV2lEh18TsKnWj qWIBdwtmEmGVs8m+gP7I9bkZEOJRRsD4ZW8AavxvCwSxoumd71n11feUD8JnVTpOzjs/ lE44MO0nF4WP4kt9u1Z9BsMmwod1POND+leCVS8d8voGHXobbVumyZTNFUuz6ZVEKqaB 0d+w== X-Gm-Message-State: AO0yUKV5vGZj1pmMEzEBEBx/WGE7QKk9gEshC3BaEdX9Sc4syWBH/pfD 9sxGSjaDEoilehHPkA/P5dJN2S0ZGL4cTb92LDCRy2PWyGugGMc660ZkXRN3+iAYPARA6qdu3O8 B9+nfCb3AE5ulfbl40YQ03u0= X-Received: by 2002:a05:6214:411a:b0:56a:eea2:9361 with SMTP id kc26-20020a056214411a00b0056aeea29361mr1622135qvb.31.1675444039983; Fri, 03 Feb 2023 09:07:19 -0800 (PST) X-Received: by 2002:a05:6214:411a:b0:56a:eea2:9361 with SMTP id kc26-20020a056214411a00b0056aeea29361mr1622078qvb.31.1675444039544; Fri, 03 Feb 2023 09:07:19 -0800 (PST) Received: from klayman.redhat.com (net-2-34-30-183.cust.vodafonedsl.it. [2.34.30.183]) by smtp.gmail.com with ESMTPSA id b13-20020ac801cd000000b003a6a19ee4f0sm1884287qtg.33.2023.02.03.09.07.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Feb 2023 09:07:19 -0800 (PST) From: Marco Pagani To: Moritz Fischer , Wu Hao , Xu Yilun , Tom Rix Cc: Marco Pagani , linux-kernel@vger.kernel.org, linux-fpga@vger.kernel.org Subject: [RFC PATCH 3/4] fpga: add fake FPGA manager Date: Fri, 3 Feb 2023 18:06:52 +0100 Message-Id: <20230203170653.414990-4-marpagan@redhat.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230203170653.414990-1-marpagan@redhat.com> References: <20230203170653.414990-1-marpagan@redhat.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1756831250237027046?= X-GMAIL-MSGID: =?utf-8?q?1756831250237027046?= Add fake FPGA manager platform driver with support functions. The driver checks the programming sequence using KUnit expectations. This module is part of the KUnit test suite for the FPGA subsystem. Signed-off-by: Marco Pagani --- drivers/fpga/tests/fake-fpga-mgr.c | 365 +++++++++++++++++++++++++++++ drivers/fpga/tests/fake-fpga-mgr.h | 42 ++++ 2 files changed, 407 insertions(+) create mode 100644 drivers/fpga/tests/fake-fpga-mgr.c create mode 100644 drivers/fpga/tests/fake-fpga-mgr.h diff --git a/drivers/fpga/tests/fake-fpga-mgr.c b/drivers/fpga/tests/fake-fpga-mgr.c new file mode 100644 index 000000000000..9daf328353d8 --- /dev/null +++ b/drivers/fpga/tests/fake-fpga-mgr.c @@ -0,0 +1,365 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for fake FPGA manager + * + * Copyright (C) 2023 Red Hat, Inc. All rights reserved. + * + * Author: Marco Pagani + */ + +#include +#include +#include +#include +#include + +#include "fake-fpga-mgr.h" + +#define FAKE_FPGA_MGR_DEV_NAME "fake_fpga_mgr" + +#define FAKE_HEADER_BYTE 0x3f +#define FAKE_HEADER_SIZE FPGA_TEST_BIT_BLOCK + +struct fake_mgr_priv { + int rcfg_count; + bool op_parse_header; + bool op_write_init; + bool op_write; + bool op_write_sg; + bool op_write_complete; + struct kunit *test; +}; + +struct fake_mgr_data { + struct kunit *test; +}; + +static void check_header(struct kunit *test, const u8 *buf); + +static enum fpga_mgr_states op_state(struct fpga_manager *mgr) +{ + struct fake_mgr_priv *priv; + + priv = mgr->priv; + + if (priv->test) + kunit_info(priv->test, "Fake FPGA manager: state\n"); + + return FPGA_MGR_STATE_UNKNOWN; +} + +static u64 op_status(struct fpga_manager *mgr) +{ + struct fake_mgr_priv *priv; + + priv = mgr->priv; + + if (priv->test) + kunit_info(priv->test, "Fake FPGA manager: status\n"); + + return 0; +} + +static int op_parse_header(struct fpga_manager *mgr, struct fpga_image_info *info, + const char *buf, size_t count) +{ + struct fake_mgr_priv *priv; + + priv = mgr->priv; + + if (priv->test) { + kunit_info(priv->test, "Fake FPGA manager: parse_header\n"); + + KUNIT_EXPECT_EQ(priv->test, mgr->state, + FPGA_MGR_STATE_PARSE_HEADER); + + check_header(priv->test, buf); + } + + priv->op_parse_header = true; + + return 0; +} + +static int op_write_init(struct fpga_manager *mgr, struct fpga_image_info *info, + const char *buf, size_t count) +{ + struct fake_mgr_priv *priv; + + priv = mgr->priv; + + if (priv->test) { + kunit_info(priv->test, "Fake FPGA manager: write_init\n"); + + KUNIT_EXPECT_EQ(priv->test, mgr->state, + FPGA_MGR_STATE_WRITE_INIT); + } + + priv->op_write_init = true; + + return 0; +} + +static int op_write(struct fpga_manager *mgr, const char *buf, size_t count) +{ + struct fake_mgr_priv *priv; + + priv = mgr->priv; + + if (priv->test) { + kunit_info(priv->test, "Fake FPGA manager: write\n"); + + KUNIT_EXPECT_EQ(priv->test, mgr->state, + FPGA_MGR_STATE_WRITE); + } + + priv->op_write = true; + + return 0; +} + +static int op_write_sg(struct fpga_manager *mgr, struct sg_table *sgt) +{ + struct fake_mgr_priv *priv; + + priv = mgr->priv; + + if (priv->test) { + kunit_info(priv->test, "Fake FPGA manager: write_sg\n"); + + KUNIT_EXPECT_EQ(priv->test, mgr->state, + FPGA_MGR_STATE_WRITE); + } + + priv->op_write_sg = true; + + return 0; +} + +static int op_write_complete(struct fpga_manager *mgr, struct fpga_image_info *info) +{ + struct fake_mgr_priv *priv; + + priv = mgr->priv; + + if (priv->test) { + kunit_info(priv->test, "Fake FPGA manager: write_complete\n"); + + KUNIT_EXPECT_EQ(priv->test, mgr->state, + FPGA_MGR_STATE_WRITE_COMPLETE); + } + + priv->op_write_complete = true; + priv->rcfg_count++; + + return 0; +} + +static void op_fpga_remove(struct fpga_manager *mgr) +{ + struct fake_mgr_priv *priv; + + priv = mgr->priv; + + if (priv->test) + kunit_info(priv->test, "Fake FPGA manager: remove\n"); +} + +static const struct fpga_manager_ops fake_fpga_mgr_ops = { + .initial_header_size = FAKE_HEADER_SIZE, + .skip_header = false, + .state = op_state, + .status = op_status, + .parse_header = op_parse_header, + .write_init = op_write_init, + .write = op_write, + .write_sg = op_write_sg, + .write_complete = op_write_complete, + .fpga_remove = op_fpga_remove, +}; + +/** + * fake_fpga_mgr_register - register a fake FPGA manager + * @mgr_ctx: fake FPGA manager context data structure. + * @test: KUnit test context object. + * + * Return: 0 if registration succeeded, an error code otherwise. + */ +int fake_fpga_mgr_register(struct fake_fpga_mgr *mgr_ctx, struct kunit *test) +{ + struct fake_mgr_data pdata; + int ret; + + pdata.test = test; + + mgr_ctx->pdev = platform_device_alloc(FAKE_FPGA_MGR_DEV_NAME, + PLATFORM_DEVID_AUTO); + if (IS_ERR(mgr_ctx->pdev)) { + pr_err("Fake FPGA manager device allocation failed\n"); + return -ENOMEM; + } + + platform_device_add_data(mgr_ctx->pdev, &pdata, sizeof(pdata)); + + ret = platform_device_add(mgr_ctx->pdev); + if (ret) { + pr_err("Fake FPGA manager device add failed\n"); + platform_device_put(mgr_ctx->pdev); + return ret; + } + + mgr_ctx->mgr = platform_get_drvdata(mgr_ctx->pdev); + + if (test) + kunit_info(test, "Fake FPGA manager registered\n"); + + return 0; +} +EXPORT_SYMBOL_GPL(fake_fpga_mgr_register); + +/** + * fake_fpga_mgr_unregister - unregister a fake FPGA manager + * @mgr_ctx: fake FPGA manager context data structure. + */ +void fake_fpga_mgr_unregister(struct fake_fpga_mgr *mgr_ctx) +{ + struct fake_mgr_priv *priv; + struct kunit *test; + + priv = mgr_ctx->mgr->priv; + test = priv->test; + + if (mgr_ctx->pdev) { + platform_device_unregister(mgr_ctx->pdev); + if (test) + kunit_info(test, "Fake FPGA manager unregistered\n"); + } +} +EXPORT_SYMBOL_GPL(fake_fpga_mgr_unregister); + +/** + * fake_fpga_mgr_get_rcfg_count - get the number of reconfigurations + * @mgr_ctx: fake FPGA manager context data structure. + * + * Return: number of reconfigurations. + */ +int fake_fpga_mgr_get_rcfg_count(const struct fake_fpga_mgr *mgr_ctx) +{ + struct fake_mgr_priv *priv; + + priv = mgr_ctx->mgr->priv; + + return priv->rcfg_count; +} +EXPORT_SYMBOL_GPL(fake_fpga_mgr_get_rcfg_count); + +/** + * fake_fpga_mgr_fill_header - fill the bitstream buffer with the test header + * @mgr_ctx: fake FPGA manager context data structure. + */ +void fake_fpga_mgr_fill_header(u8 *buf) +{ + int i; + + for (i = 0; i < FAKE_HEADER_SIZE; i++) + buf[i] = FAKE_HEADER_BYTE; +} +EXPORT_SYMBOL_GPL(fake_fpga_mgr_fill_header); + +static void check_header(struct kunit *test, const u8 *buf) +{ + int i; + + for (i = 0; i < FAKE_HEADER_SIZE; i++) + KUNIT_EXPECT_EQ(test, buf[i], FAKE_HEADER_BYTE); +} + +static void clear_op_flags(struct fake_mgr_priv *priv) +{ + priv->op_parse_header = false; + priv->op_write_init = false; + priv->op_write = false; + priv->op_write_sg = false; + priv->op_write_complete = false; +} + +/** + * fake_fpga_mgr_check_write_buf - check if programming using a buffer succeeded + * @mgr_ctx: fake FPGA manager context data structure. + */ +void fake_fpga_mgr_check_write_buf(struct fake_fpga_mgr *mgr_ctx) +{ + struct fake_mgr_priv *priv; + + priv = mgr_ctx->mgr->priv; + + if (priv->test) { + KUNIT_EXPECT_EQ(priv->test, priv->op_parse_header, true); + KUNIT_EXPECT_EQ(priv->test, priv->op_write_init, true); + KUNIT_EXPECT_EQ(priv->test, priv->op_write, true); + KUNIT_EXPECT_EQ(priv->test, priv->op_write_complete, true); + } + + clear_op_flags(priv); +} +EXPORT_SYMBOL_GPL(fake_fpga_mgr_check_write_buf); + +/** + * fake_fpga_mgr_check_write_sg - check if programming using a s.g. table succeeded + * @mgr_ctx: fake FPGA manager context data structure. + */ +void fake_fpga_mgr_check_write_sg(struct fake_fpga_mgr *mgr_ctx) +{ + struct fake_mgr_priv *priv; + + priv = mgr_ctx->mgr->priv; + + if (priv->test) { + KUNIT_EXPECT_EQ(priv->test, priv->op_parse_header, true); + KUNIT_EXPECT_EQ(priv->test, priv->op_write_init, true); + KUNIT_EXPECT_EQ(priv->test, priv->op_write_sg, true); + KUNIT_EXPECT_EQ(priv->test, priv->op_write_complete, true); + } + + clear_op_flags(priv); +} +EXPORT_SYMBOL_GPL(fake_fpga_mgr_check_write_sg); + +static int fake_fpga_mgr_probe(struct platform_device *pdev) +{ + struct device *dev; + struct fake_mgr_priv *priv; + struct fake_mgr_data *pdata; + struct fpga_manager *mgr; + + dev = &pdev->dev; + pdata = dev_get_platdata(dev); + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->test = pdata->test; + + mgr = devm_fpga_mgr_register(dev, "Fake FPGA Manager", + &fake_fpga_mgr_ops, priv); + if (IS_ERR(mgr)) + return PTR_ERR(mgr); + + platform_set_drvdata(pdev, mgr); + + return 0; +} + +static struct platform_driver fake_fpga_mgr_drv = { + .driver = { + .name = FAKE_FPGA_MGR_DEV_NAME + }, + .probe = fake_fpga_mgr_probe, +}; + +module_platform_driver(fake_fpga_mgr_drv); + +MODULE_AUTHOR("Marco Pagani "); +MODULE_DESCRIPTION("Fake FPGA Manager"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/fpga/tests/fake-fpga-mgr.h b/drivers/fpga/tests/fake-fpga-mgr.h new file mode 100644 index 000000000000..5cecb6f646c9 --- /dev/null +++ b/drivers/fpga/tests/fake-fpga-mgr.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Header file for fake FPGA manager + * + * Copyright (C) 2023 Red Hat, Inc. All rights reserved. + * + * Author: Marco Pagani + */ + +#ifndef __FPGA_FAKE_MGR_H +#define __FPGA_FAKE_MGR_H + +#include +#include +#include + +#define FPGA_TEST_BIT_BLOCK 1024 + +/** + * struct fake_fpga_mgr - fake FPGA manager context data structure + * + * @mgr: FPGA manager. + * @pdev: platform device of the FPGA manager. + */ +struct fake_fpga_mgr { + struct fpga_manager *mgr; + struct platform_device *pdev; +}; + +int fake_fpga_mgr_register(struct fake_fpga_mgr *mgr_ctx, struct kunit *test); + +void fake_fpga_mgr_unregister(struct fake_fpga_mgr *mgr_ctx); + +int fake_fpga_mgr_get_rcfg_count(const struct fake_fpga_mgr *mgr_ctx); + +void fake_fpga_mgr_fill_header(u8 *buf); + +void fake_fpga_mgr_check_write_buf(struct fake_fpga_mgr *mgr_ctx); + +void fake_fpga_mgr_check_write_sg(struct fake_fpga_mgr *mgr_ctx); + +#endif /* __FPGA_FAKE_MGR_H */ From patchwork Fri Feb 3 17:06:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Pagani X-Patchwork-Id: 52569 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp958987wrn; Fri, 3 Feb 2023 09:15:45 -0800 (PST) X-Google-Smtp-Source: AK7set91rZfD2X9LlhF7XPR5W8Wi1a5Z34N66AbUm1M8pJP7BsCoNMLI9DCRHVTj52ecH/w3uUKR X-Received: by 2002:a17:907:cb20:b0:885:2eb5:68a2 with SMTP id um32-20020a170907cb2000b008852eb568a2mr9796962ejc.16.1675444545454; Fri, 03 Feb 2023 09:15:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675444545; cv=none; d=google.com; s=arc-20160816; b=WJgFhl9YJTDB3vvSRZjNwU6b4cEWTGVEmIQgXrYAQ/2bl+hwzkrPryutY81HBg9tne cveganQR+Et5nUPJ9Kj2eTZIcZg6+eR7pcQydzKcKouobbyZMVqW0UmgwvNDdtqblFiR xQajZY3O70ooidJO9cE/pU0qDS+k930Alq+WOdfCpjAoZ7tY/E7mrfw/TGAL7S2OHA7q Dcq7ifRW3kOdM1BRubbhU77ViLMqAwx+o+9pWjY061QOB/OR/SKVFM/OzPXrq814Tbqz y/ASH+VnKySCZuIIwosZPNc01D3Vqr5Rwk0zxksU4ir8xd1AdOb9P7TsdFkeMiiGfzSu YSpA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=aTqTPW1mDhdo6UVlHMTIqNJ0ko0wBmbKrV94jadhHOI=; b=D/oDNJ7ClvSLnGR3Bi7TxOjJ4FXNT2Kbvy+r5GU7cABKkKk6XtRfS72L6q9uUaZtk7 vft9UeLwbwmdArsiapAFxN3Jkjg/FRti9HyEvQRpBiXfoSWROSIQSRvZJx4JB361fdmA 1OQobVGxhbX5BiKdHeyOdP1QPvChkfJLRcnJAfXt3UkwoEDp25ubggQZrGJ97JBQDxBQ r7xoUmU8oqusWZpnrhDqSdpQKJf/MXtsdnwVo0VPpaEQ8sWUaYl3+SJLVTAyWlL+J1JW POxn6WfAsW6DUz9YQm6ZsYRs1/irsvBU+MXhkNS5jgfjp3ODF6P0c6Oqky49nHg9ZJ5S VeAA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=Gj0HKFF3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id fq18-20020a1709069d9200b008873dd1b69csi3306588ejc.286.2023.02.03.09.15.09; Fri, 03 Feb 2023 09:15:45 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=Gj0HKFF3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233573AbjBCRIO (ORCPT + 99 others); Fri, 3 Feb 2023 12:08:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54206 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232916AbjBCRIL (ORCPT ); Fri, 3 Feb 2023 12:08:11 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C7699D584 for ; Fri, 3 Feb 2023 09:07:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1675444043; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=aTqTPW1mDhdo6UVlHMTIqNJ0ko0wBmbKrV94jadhHOI=; b=Gj0HKFF3zF6JRpnsVgntsHbjvbNNZA64yv6w7bSc91FktN6Qe2bNb1aMharu9JMYzowpdO w+pidjd7IScqNHzd7D+OxIbuu6/VcKgDuYetFYH6P6tKgPLGp/DdsXOQpS1jbWQqGzzXVz 5rKgEALCewqY30bm2x+4/LI5022t62w= Received: from mail-qv1-f69.google.com (mail-qv1-f69.google.com [209.85.219.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-249-iS1N0yTmPXapMryzbrFgPw-1; Fri, 03 Feb 2023 12:07:22 -0500 X-MC-Unique: iS1N0yTmPXapMryzbrFgPw-1 Received: by mail-qv1-f69.google.com with SMTP id p15-20020a0cf54f000000b0054fc21ff275so3041376qvm.4 for ; Fri, 03 Feb 2023 09:07:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=aTqTPW1mDhdo6UVlHMTIqNJ0ko0wBmbKrV94jadhHOI=; b=64BFhvXZj+fMgg7OsoItOX7wTaCDAororhRNVCERTHwtIxaD1iZT8aq8AfdyYKjBV2 CxVBf8zV6CmcBfheB+BJ0rR+LPtI3hQBooYBlqRv93GeFIhg3Ktdru52OJt7WsHQI/f1 lRUsDzHC2ixLNISYp4SKT4ZkfXiRbrNnw1BWfrDaHWF527kbQPXnGkAAasOAPIL3CSHe WpiDiTfrbAVtxuOceWe4Ui53BvU+4IkRHK78hsD5ll4xq7ugDjCQkTVKpARB6P1Em0Pe GxuyhuX/fudRFPBEDy3NPYTCgSCxCNJLe0qPOLOOy6YLWxjLltrA9XTC7Zwp/bcV8+YW qEJw== X-Gm-Message-State: AO0yUKUaI9buOWzZN21Eu3qq8k9C+WQ9NqXd3rTRvYfRYra+hKxrVOtD SxivSSFFUhjzWULGBsYHiNLbeBEqD1D0KAKf3Eq/U2S0XrVFw4Gpg4Dva1bHSeA6kumbsjWuEVY RmNIFYt5ZPNFe6eWFSZku5gY= X-Received: by 2002:a05:6214:5ed2:b0:537:6aea:124b with SMTP id mn18-20020a0562145ed200b005376aea124bmr16953969qvb.16.1675444041611; Fri, 03 Feb 2023 09:07:21 -0800 (PST) X-Received: by 2002:a05:6214:5ed2:b0:537:6aea:124b with SMTP id mn18-20020a0562145ed200b005376aea124bmr16953943qvb.16.1675444041288; Fri, 03 Feb 2023 09:07:21 -0800 (PST) Received: from klayman.redhat.com (net-2-34-30-183.cust.vodafonedsl.it. [2.34.30.183]) by smtp.gmail.com with ESMTPSA id b13-20020ac801cd000000b003a6a19ee4f0sm1884287qtg.33.2023.02.03.09.07.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Feb 2023 09:07:21 -0800 (PST) From: Marco Pagani To: Moritz Fischer , Wu Hao , Xu Yilun , Tom Rix Cc: Marco Pagani , linux-kernel@vger.kernel.org, linux-fpga@vger.kernel.org Subject: [RFC PATCH 4/4] fpga: add fake FPGA bridge Date: Fri, 3 Feb 2023 18:06:53 +0100 Message-Id: <20230203170653.414990-5-marpagan@redhat.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230203170653.414990-1-marpagan@redhat.com> References: <20230203170653.414990-1-marpagan@redhat.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1756830939670686844?= X-GMAIL-MSGID: =?utf-8?q?1756830939670686844?= Add fake FPGA bridge driver with support functions. The driver includes a counter for the number of switching cycles. This module is part of the KUnit test suite for the FPGA subsystem. Signed-off-by: Marco Pagani --- drivers/fpga/tests/fake-fpga-bridge.c | 214 ++++++++++++++++++++++++++ drivers/fpga/tests/fake-fpga-bridge.h | 36 +++++ 2 files changed, 250 insertions(+) create mode 100644 drivers/fpga/tests/fake-fpga-bridge.c create mode 100644 drivers/fpga/tests/fake-fpga-bridge.h diff --git a/drivers/fpga/tests/fake-fpga-bridge.c b/drivers/fpga/tests/fake-fpga-bridge.c new file mode 100644 index 000000000000..1f3c8e4fbb6a --- /dev/null +++ b/drivers/fpga/tests/fake-fpga-bridge.c @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for fake FPGA bridge + * + * Copyright (C) 2023 Red Hat, Inc. All rights reserved. + * + * Author: Marco Pagani + */ + +#include +#include +#include +#include +#include + +#include "fake-fpga-bridge.h" + +#define FAKE_FPGA_BRIDGE_DEV_NAME "fake_fpga_bridge" + +struct fake_bridge_priv { + int id; + bool enable; + int cycles_count; + struct kunit *test; +}; + +struct fake_bridge_data { + struct kunit *test; +}; + +static int op_enable_show(struct fpga_bridge *bridge) +{ + struct fake_bridge_priv *priv; + + priv = bridge->priv; + + if (priv->test) + kunit_info(priv->test, "Fake FPGA bridge %d: enable_show\n", + priv->id); + + return priv->enable; +} + +static int op_enable_set(struct fpga_bridge *bridge, bool enable) +{ + struct fake_bridge_priv *priv; + + priv = bridge->priv; + + if (enable && !priv->enable) + priv->cycles_count++; + + priv->enable = enable; + + if (priv->test) + kunit_info(priv->test, "Fake FPGA bridge %d: enable_set: %d\n", + priv->id, enable); + + return 0; +} + +static void op_remove(struct fpga_bridge *bridge) +{ +} + +static const struct fpga_bridge_ops fake_fpga_bridge_ops = { + .enable_show = op_enable_show, + .enable_set = op_enable_set, + .fpga_bridge_remove = op_remove, +}; + +/** + * fake_fpga_bridge_register - register a fake FPGA bridge + * @bridge_ctx: fake FPGA bridge context data structure. + * @test: KUnit test context object. + * + * Return: 0 if registration succeeded, an error code otherwise. + */ +int fake_fpga_bridge_register(struct fake_fpga_bridge *bridge_ctx, + struct kunit *test) +{ + struct fake_bridge_data pdata; + struct fake_bridge_priv *priv; + int ret; + + pdata.test = test; + + bridge_ctx->pdev = platform_device_alloc(FAKE_FPGA_BRIDGE_DEV_NAME, + PLATFORM_DEVID_AUTO); + if (IS_ERR(bridge_ctx->pdev)) { + pr_err("Fake FPGA bridge device allocation failed\n"); + return -ENOMEM; + } + + platform_device_add_data(bridge_ctx->pdev, &pdata, sizeof(pdata)); + + ret = platform_device_add(bridge_ctx->pdev); + if (ret) { + pr_err("Fake FPGA bridge device add failed\n"); + platform_device_put(bridge_ctx->pdev); + return ret; + } + + bridge_ctx->bridge = platform_get_drvdata(bridge_ctx->pdev); + + if (test) { + priv = bridge_ctx->bridge->priv; + kunit_info(test, "Fake FPGA bridge %d registered\n", priv->id); + } + + return 0; +} +EXPORT_SYMBOL_GPL(fake_fpga_bridge_register); + +/** + * fake_fpga_bridge_unregister - unregister a fake FPGA bridge + * @bridge_ctx: fake FPGA bridge context data structure. + */ +void fake_fpga_bridge_unregister(struct fake_fpga_bridge *bridge_ctx) +{ + struct fake_bridge_priv *priv; + struct kunit *test; + int id; + + priv = bridge_ctx->bridge->priv; + test = priv->test; + id = priv->id; + + if (bridge_ctx->pdev) { + platform_device_unregister(bridge_ctx->pdev); + if (test) + kunit_info(test, "Fake FPGA bridge %d unregistered\n", id); + } +} +EXPORT_SYMBOL_GPL(fake_fpga_bridge_unregister); + +/** + * fake_fpga_bridge_get_state - get state of a fake FPGA bridge + * @bridge_ctx: fake FPGA bridge context data structure. + * + * Return: 1 if the bridge is enabled, 0 if disabled. + */ +int fake_fpga_bridge_get_state(const struct fake_fpga_bridge *bridge_ctx) +{ + return bridge_ctx->bridge->br_ops->enable_show(bridge_ctx->bridge); +} +EXPORT_SYMBOL_GPL(fake_fpga_bridge_get_state); + +/** + * fake_fpga_bridge_get_cycles_count - get the number of switching cycles + * @bridge_ctx: fake FPGA bridge context data structure. + * + * Return: number of switching cycles. + */ +int fake_fpga_bridge_get_cycles_count(const struct fake_fpga_bridge *bridge_ctx) +{ + struct fake_bridge_priv *priv; + + priv = bridge_ctx->bridge->priv; + + return priv->cycles_count; +} +EXPORT_SYMBOL_GPL(fake_fpga_bridge_get_cycles_count); + +static int fake_fpga_bridge_probe(struct platform_device *pdev) +{ + struct device *dev; + struct fpga_bridge *bridge; + struct fake_bridge_data *pdata; + struct fake_bridge_priv *priv; + static int id_count; + + dev = &pdev->dev; + pdata = dev_get_platdata(dev); + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->id = id_count++; + priv->test = pdata->test; + + bridge = fpga_bridge_register(dev, "Fake FPGA Bridge", + &fake_fpga_bridge_ops, priv); + if (IS_ERR(bridge)) + return PTR_ERR(bridge); + + platform_set_drvdata(pdev, bridge); + + return 0; +} + +static int fake_fpga_bridge_remove(struct platform_device *pdev) +{ + struct fpga_bridge *bridge = platform_get_drvdata(pdev); + + fpga_bridge_unregister(bridge); + + return 0; +} + +static struct platform_driver fake_fpga_bridge_drv = { + .driver = { + .name = FAKE_FPGA_BRIDGE_DEV_NAME + }, + .probe = fake_fpga_bridge_probe, + .remove = fake_fpga_bridge_remove, +}; + +module_platform_driver(fake_fpga_bridge_drv); + +MODULE_AUTHOR("Marco Pagani "); +MODULE_DESCRIPTION("Fake FPGA Bridge"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/fpga/tests/fake-fpga-bridge.h b/drivers/fpga/tests/fake-fpga-bridge.h new file mode 100644 index 000000000000..9de62d2f993b --- /dev/null +++ b/drivers/fpga/tests/fake-fpga-bridge.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Header file for fake FPGA bridge + * + * Copyright (C) 2023 Red Hat, Inc. All rights reserved. + * + * Author: Marco Pagani + */ + +#ifndef __FPGA_FAKE_BRIDGE_H +#define __FPGA_FAKE_BRIDGE_H + +#include +#include + +/** + * struct fake_fpga_bridge - fake FPGA bridge context data structure + * + * @bridge: FPGA bridge. + * @pdev: platform device of the FPGA bridge. + */ +struct fake_fpga_bridge { + struct fpga_bridge *bridge; + struct platform_device *pdev; +}; + +int fake_fpga_bridge_register(struct fake_fpga_bridge *bridge_ctx, + struct kunit *test); + +void fake_fpga_bridge_unregister(struct fake_fpga_bridge *bridge_ctx); + +int fake_fpga_bridge_get_state(const struct fake_fpga_bridge *bridge_ctx); + +int fake_fpga_bridge_get_cycles_count(const struct fake_fpga_bridge *bridge_ctx); + +#endif /* __FPGA_FAKE_BRIDGE_H */