Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2196443/?format=api
{ "id": 2196443, "url": "http://patchwork.ozlabs.org/api/patches/2196443/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/20260213225254.2544596-5-raymondmaoca@gmail.com/", "project": { "id": 18, "url": "http://patchwork.ozlabs.org/api/projects/18/?format=api", "name": "U-Boot", "link_name": "uboot", "list_id": "u-boot.lists.denx.de", "list_email": "u-boot@lists.denx.de", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260213225254.2544596-5-raymondmaoca@gmail.com>", "list_archive_url": null, "date": "2026-02-13T22:52:49", "name": "[v6,4/6] smbios: add support for dynamic generation of Type 17 table", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "e7f8e6ec6e7d8d2599d04fd9921b1c2f4e909ed3", "submitter": { "id": 91989, "url": "http://patchwork.ozlabs.org/api/people/91989/?format=api", "name": "Raymond Mao", "email": "raymondmaoca@gmail.com" }, "delegate": { "id": 3651, "url": "http://patchwork.ozlabs.org/api/users/3651/?format=api", "username": "trini", "first_name": "Tom", "last_name": "Rini", "email": "trini@ti.com" }, "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/20260213225254.2544596-5-raymondmaoca@gmail.com/mbox/", "series": [ { "id": 492145, "url": "http://patchwork.ozlabs.org/api/series/492145/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=492145", "date": "2026-02-13T22:52:45", "name": "Implement all missing SMBIOS types required by distro tooling", "version": 6, "mbox": "http://patchwork.ozlabs.org/series/492145/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2196443/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2196443/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<u-boot-bounces@lists.denx.de>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20230601 header.b=EJUhNxCE;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=85.214.62.61; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)", "phobos.denx.de;\n dmarc=pass (p=none dis=none) header.from=gmail.com", "phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de", "phobos.denx.de;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.b=\"EJUhNxCE\";\n\tdkim-atps=neutral", "phobos.denx.de;\n dmarc=pass (p=none dis=none) header.from=gmail.com", "phobos.denx.de;\n spf=pass smtp.mailfrom=raymondmaoca@gmail.com" ], "Received": [ "from phobos.denx.de (phobos.denx.de [85.214.62.61])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fCSC42qlsz1xvS\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 14 Feb 2026 09:53:52 +1100 (AEDT)", "from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id 7C3E583E16;\n\tFri, 13 Feb 2026 23:53:37 +0100 (CET)", "by phobos.denx.de (Postfix, from userid 109)\n id 3EF3083015; Fri, 13 Feb 2026 23:53:36 +0100 (CET)", "from mail-qt1-x835.google.com (mail-qt1-x835.google.com\n [IPv6:2607:f8b0:4864:20::835])\n (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id 78E8283E16\n for <u-boot@lists.denx.de>; Fri, 13 Feb 2026 23:53:33 +0100 (CET)", "by mail-qt1-x835.google.com with SMTP id\n d75a77b69052e-506a019a7f3so16166871cf.3\n for <u-boot@lists.denx.de>; Fri, 13 Feb 2026 14:53:33 -0800 (PST)", "from ubuntu.localdomain (174-138-202-16.cpe.distributel.net.\n [174.138.202.16]) by smtp.gmail.com with ESMTPSA id\n d75a77b69052e-506847ed9c4sm72845731cf.8.2026.02.13.14.53.31\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Fri, 13 Feb 2026 14:53:31 -0800 (PST)" ], "X-Spam-Checker-Version": "SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de", "X-Spam-Level": "", "X-Spam-Status": "No, score=-1.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FORGED_GMAIL_RCVD,FREEMAIL_FROM,\n RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=no\n autolearn_force=no version=3.4.2", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20230601; t=1771023212; x=1771628012; darn=lists.denx.de;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=zpy2giGMXM3jmYZl1QFqlJM7ueAaLRWB/BD7KwPHdak=;\n b=EJUhNxCEW/IBPcgqRjyN4eP+tAz96MndMErtRskFKVqdMa84lc5EvIStGCiWxSC3kd\n 7aV/RnXB8ajgTL8IofuW3H4dEg/bXdGEKVoEfNmgMFFORW6zBzG0gCssIAgXKQsR6RKl\n EjKZXU0fxh+HxroJ77NR5urf7bzMu6Z1rFkHOLYyTmFIwYWUOQ3NHNuPh9llpjJNUxaU\n 9UW9/9QtKActahFuxaoh6ZM1Ui7fnKkuJ+pV5O3OBsiXWcjYeP7yBFZAKTy+Xrk2ooQ+\n dBNqCeubrsHrGCZqcwgF4tznZbYbq+g0q38Vy/nkNilqa770zsjyDlqlccLYBCY2TGnz\n PFdg==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1771023212; x=1771628012;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=zpy2giGMXM3jmYZl1QFqlJM7ueAaLRWB/BD7KwPHdak=;\n b=k1nZ1CwK1teOzLg85G4n44iwF4J/EK0Bpcn/Njn9YP+dLTvGADaKu0ruv0ilmXy6US\n OX9SNrodY4u8cHc0Uk89M5cBqwarrgysgf7xponDP4tzDBKwp+cjXlV7yo8CHJKnXSxq\n UscuBgeVngj/I6+Kpvw88/ymIep4nSj0/1FkcyOS/yKXWPF6LTVJ4K+qlPj63B2jQ1lK\n O4cYYIVqV4NtDM6uQUZqBAf4cWkcISDItsiFVmrFcG3ICqcOgELurK9H3CLmWQPeswjg\n 3/zQ5lQanRydBYSiEKFIPfI+x7/TbKwtdUXXgBLmd0nI7j1ExdNWMw08cJMLMrlBuKan\n Xfvg==", "X-Gm-Message-State": "AOJu0Yz+dFlxTRt2UQrNk71VXsvOEI1CyZwNL49pkqe2cc/ySAh9K1mw\n BI8kQeX4LeyeDaOOKwmpu6IChHwZU6QactxVglE5+Vmh5YhYxV/ySue5ZI7BIQ==", "X-Gm-Gg": "AZuq6aIVKP3QO9wByUKHbEn1nq3edGvnSgb+Hjb3xxf35MzhkGJ3Nu0jw0E9IIGKcr3\n 3XE9dVEsbWc+/+/MaXbg8Ev/+V5aDiKVpiaFKopTL17v33PqhgFMWR7i9U0JBPU7k1bjecosG7Y\n EvH4HCrcJGM3M9Buis/0LaRzSFJ75QVvBkitGL0tDVNH0nkNXIn5tA1wTJFw6L5yATSeJIAgIsw\n 9LdCjesNGzWwx/VpqB6PWUT2eWNHCrMQEtYIC4881eDe24/ndHbZWGdE/5680G+Munro7HQYtXS\n Vur1LXmPe82PfO4r9uOzSvjbHuQDQUMVJfJXtGKS2uqwi1yBLFXEwjAbGscG+qg9yvmbWd9Ytrj\n cybcVln1p1ADxt+xqn7TGXOpxf4VlZvEIqnns6miaDrlPzZ5+s++ogE/Hm9IeQ7rGwV1h0x0ZZC\n mgMFuV5VQEZjzunx1Zp6oFKG/mWkUFrZVzL1suLs38n/u2nZaZb4m7OZXZvtL7A8g1IddCJdSgr\n gjL/bnv9Sk=", "X-Received": "by 2002:a05:622a:15c3:b0:502:984a:ff19 with SMTP id\n d75a77b69052e-506b400036dmr16453731cf.43.1771023212035;\n Fri, 13 Feb 2026 14:53:32 -0800 (PST)", "From": "Raymond Mao <raymondmaoca@gmail.com>", "To": "u-boot@lists.denx.de", "Cc": "Raymond Mao <raymondmaoca@gmail.com>, Tom Rini <trini@konsulko.com>,\n Heinrich Schuchardt <xypron.glpk@gmx.de>,\n Mark Kettenis <kettenis@openbsd.org>,\n Ilias Apalodimas <ilias.apalodimas@linaro.org>,\n Baocheng Su <baocheng.su@siemens.com>,\n Li Hua Qian <huaqian.li@siemens.com>, Jan Kiszka <jan.kiszka@siemens.com>,\n Samuel Holland <samuel.holland@sifive.com>", "Subject": "[PATCH v6 4/6] smbios: add support for dynamic generation of Type 17\n table", "Date": "Fri, 13 Feb 2026 17:52:49 -0500", "Message-Id": "<20260213225254.2544596-5-raymondmaoca@gmail.com>", "X-Mailer": "git-send-email 2.25.1", "In-Reply-To": "<20260213225254.2544596-1-raymondmaoca@gmail.com>", "References": "<20260213225254.2544596-1-raymondmaoca@gmail.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-BeenThere": "u-boot@lists.denx.de", "X-Mailman-Version": "2.1.39", "Precedence": "list", "List-Id": "U-Boot discussion <u-boot.lists.denx.de>", "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>", "List-Archive": "<https://lists.denx.de/pipermail/u-boot/>", "List-Post": "<mailto:u-boot@lists.denx.de>", "List-Help": "<mailto:u-boot-request@lists.denx.de?subject=help>", "List-Subscribe": "<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>", "Errors-To": "u-boot-bounces@lists.denx.de", "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>", "X-Virus-Scanned": "clamav-milter 0.103.8 at phobos.denx.de", "X-Virus-Status": "Clean" }, "content": "This commit implements SMBIOS Type 17 (Memory Device) generation with a\nhybrid approach supporting both:\n\n1. Explicit definition via Device Tree 'smbios' node:\n Child node under '/smbios/smbios/memory-device' will be used to\n populate as individual Type 17 structure directly.\n - Properties follow SMBIOS field names with lowercase letters and\n hyphen-separated words (e.g., 'physical-memory-array-handle',\n ' memory-error-information-handle', 'configured-memory-speed', etc.).\n - This method supports precise platform-defined overrides and system\n descriptions.\n\n2. Fallback to automatic DT-based discovery:\n If child node under '/smbios/smbios/memory-device' does not exist,\n the implementation will:\n - Scan all top-level 'memory@' nodes to populate Type 17 structure with\n inferred size and location data.\n - Scan nodes named or marked as 'memory-controller' and parse\n associated 'dimm@' subnodes (if present) to extract DIMM sizes and\n map them accordingly.\n\nThis dual-mode support enables flexible firmware SMBIOS reporting while\naligning with spec-compliant naming and runtime-detected memory topology.\n\nType 17 support is under GENERATE_SMBIOS_TABLE_VERBOSE to avoid\nincreasing rom size for those platforms which only require basic SMBIOS\nsupport.\n\nSigned-off-by: Raymond Mao <raymondmaoca@gmail.com>\n---\nChanges in v4:\n- Initial patch.\nChanges in v5:\n- None.\nChanges in v6:\n- Fixed mis-aligned type17 structure.\n- Remove a duplicated line of setting type17 data width.\n\n arch/arm/dts/smbios_generic.dtsi | 3 +\n cmd/smbios.c | 126 +++++++++++\n include/smbios.h | 45 ++++\n include/smbios_def.h | 127 +++++++++++\n lib/smbios.c | 376 +++++++++++++++++++++++++++++++\n 5 files changed, 677 insertions(+)", "diff": "diff --git a/arch/arm/dts/smbios_generic.dtsi b/arch/arm/dts/smbios_generic.dtsi\nindex 1a9adfaa409..fd2df8d02e0 100644\n--- a/arch/arm/dts/smbios_generic.dtsi\n+++ b/arch/arm/dts/smbios_generic.dtsi\n@@ -83,6 +83,9 @@\n \n \t\t\tmemory-array {\n \t\t\t};\n+\n+\t\t\tmemory-device {\n+\t\t\t};\n \t\t};\n \t};\n };\ndiff --git a/cmd/smbios.c b/cmd/smbios.c\nindex 3f7dd21f92e..39c9c44a28e 100644\n--- a/cmd/smbios.c\n+++ b/cmd/smbios.c\n@@ -194,6 +194,74 @@ static const struct str_lookup_table ma_err_corr_strings[] = {\n \t{ SMBIOS_MA_ERRCORR_CRC,\t\"CRC\" },\n };\n \n+static const struct str_lookup_table md_form_factor_strings[] = {\n+\t{ SMBIOS_MD_FF_OTHER,\t\t\"Other\" },\n+\t{ SMBIOS_MD_FF_UNKNOWN,\t\t\"Unknown\" },\n+\t{ SMBIOS_MD_FF_SIMM,\t\t\"SIMM\" },\n+\t{ SMBIOS_MD_FF_SIP,\t\t\"SIP\" },\n+\t{ SMBIOS_MD_FF_CHIP,\t\t\"Chip\" },\n+\t{ SMBIOS_MD_FF_DIP,\t\t\"DIP\" },\n+\t{ SMBIOS_MD_FF_ZIP,\t\t\"ZIP\" },\n+\t{ SMBIOS_MD_FF_PROPCARD,\t\"Proprietary Card\" },\n+\t{ SMBIOS_MD_FF_DIMM,\t\t\"DIMM\" },\n+\t{ SMBIOS_MD_FF_TSOP,\t\t\"TSOP\" },\n+\t{ SMBIOS_MD_FF_ROC,\t\t\"Row of chips\" },\n+\t{ SMBIOS_MD_FF_RIMM,\t\t\"RIMM\" },\n+\t{ SMBIOS_MD_FF_SODIMM,\t\t\"SODIMM\" },\n+\t{ SMBIOS_MD_FF_SRIMM,\t\t\"SRIMM\" },\n+\t{ SMBIOS_MD_FF_FBDIMM,\t\t\"FB-DIMM\" },\n+\t{ SMBIOS_MD_FF_DIE,\t\t\"Die\" },\n+};\n+\n+static const struct str_lookup_table md_type_strings[] = {\n+\t{ SMBIOS_MD_TYPE_OTHER,\t\t\"Other\" },\n+\t{ SMBIOS_MD_TYPE_UNKNOWN,\t\"Unknown\" },\n+\t{ SMBIOS_MD_TYPE_DRAM,\t\t\"DRAM\" },\n+\t{ SMBIOS_MD_TYPE_EDRAM,\t\t\"EDRAM\" },\n+\t{ SMBIOS_MD_TYPE_VRAM,\t\t\"VRAM\" },\n+\t{ SMBIOS_MD_TYPE_SRAM,\t\t\"SRAM\" },\n+\t{ SMBIOS_MD_TYPE_RAM,\t\t\"RAM\" },\n+\t{ SMBIOS_MD_TYPE_ROM,\t\t\"ROM\" },\n+\t{ SMBIOS_MD_TYPE_FLASH,\t\t\"FLASH\" },\n+\t{ SMBIOS_MD_TYPE_EEPROM,\t\"EEPROM\" },\n+\t{ SMBIOS_MD_TYPE_FEPROM,\t\"FEPROM\" },\n+\t{ SMBIOS_MD_TYPE_EPROM,\t\t\"EPROM\" },\n+\t{ SMBIOS_MD_TYPE_CDRAM,\t\t\"CDRAM\" },\n+\t{ SMBIOS_MD_TYPE_3DRAM,\t\t\"3DRAM\" },\n+\t{ SMBIOS_MD_TYPE_SDRAM,\t\t\"SDRAM\" },\n+\t{ SMBIOS_MD_TYPE_SGRAM,\t\t\"SGRAM\" },\n+\t{ SMBIOS_MD_TYPE_RDRAM,\t\t\"RDRAM\" },\n+\t{ SMBIOS_MD_TYPE_DDR,\t\t\"DDR\" },\n+\t{ SMBIOS_MD_TYPE_DDR2,\t\t\"DDR2\" },\n+\t{ SMBIOS_MD_TYPE_DDR2FBD,\t\"DDR2 FB-DIMM\" },\n+\t{ SMBIOS_MD_TYPE_RSVD1,\t\t\"Reserved\" },\n+\t{ SMBIOS_MD_TYPE_RSVD2,\t\t\"Reserved\" },\n+\t{ SMBIOS_MD_TYPE_DSVD3,\t\t\"Reserved\" },\n+\t{ SMBIOS_MD_TYPE_DDR3,\t\t\"DDR3\" },\n+\t{ SMBIOS_MD_TYPE_FBD2,\t\t\"FBD2\" },\n+\t{ SMBIOS_MD_TYPE_DDR4,\t\t\"DDR4\" },\n+\t{ SMBIOS_MD_TYPE_LPDDR,\t\t\"LPDDR\" },\n+\t{ SMBIOS_MD_TYPE_LPDDR2,\t\"LPDDR2\" },\n+\t{ SMBIOS_MD_TYPE_LPDDR3,\t\"LPDDR3\" },\n+\t{ SMBIOS_MD_TYPE_LPDDR4,\t\"LPDDR4\" },\n+\t{ SMBIOS_MD_TYPE_LNVD,\t\t\"Logical non-volatile device\" },\n+\t{ SMBIOS_MD_TYPE_HBM,\t\t\"HBM\" },\n+\t{ SMBIOS_MD_TYPE_HBM2,\t\t\"HBM2\" },\n+\t{ SMBIOS_MD_TYPE_DDR5,\t\t\"DDR5\" },\n+\t{ SMBIOS_MD_TYPE_LPDDR5,\t\"LPDDR5\" },\n+\t{ SMBIOS_MD_TYPE_HBM3,\t\t\"HBM3\" },\n+};\n+\n+static const struct str_lookup_table md_tech_strings[] = {\n+\t{ SMBIOS_MD_TECH_OTHER,\t\t\"Other\" },\n+\t{ SMBIOS_MD_TECH_UNKNOWN,\t\"Unknown\" },\n+\t{ SMBIOS_MD_TECH_DRAM,\t\t\"DRAM\" },\n+\t{ SMBIOS_MD_TECH_NVDIMMN,\t\"NVDIMM-N\" },\n+\t{ SMBIOS_MD_TECH_NVDIMMF,\t\"NVDIMM-F\" },\n+\t{ SMBIOS_MD_TECH_NVDIMMP,\t\"NVDIMM-P\" },\n+\t{ SMBIOS_MD_TECH_OPTANE,\t\"Intel Optane persistent memory\" },\n+};\n+\n /**\n * smbios_get_string() - get SMBIOS string from table\n *\n@@ -557,6 +625,61 @@ static void smbios_print_type16(struct smbios_type16 *table)\n \tprintf(\"\\tExtended Maximum Capacity: 0x%016llx\\n\", table->ext_max_cap);\n }\n \n+static void smbios_print_type17(struct smbios_type17 *table)\n+{\n+\tprintf(\"Memory Device:\\n\");\n+\tprintf(\"\\tPhysical Memory Array Handle: 0x%04x\\n\",\n+\t table->phy_mem_array_hdl);\n+\tprintf(\"\\tMemory Error Information Handle: 0x%04x\\n\",\n+\t table->mem_err_info_hdl);\n+\tprintf(\"\\tTotal Width: 0x%04x\\n\", table->total_width);\n+\tprintf(\"\\tData Width: 0x%04x\\n\", table->data_width);\n+\tprintf(\"\\tSize: 0x%04x\\n\", table->size);\n+\tsmbios_print_lookup_str(md_form_factor_strings, table->form_factor,\n+\t\t\t\tARRAY_SIZE(md_form_factor_strings),\n+\t\t\t\t\"Form Factor\");\n+\tprintf(\"\\tDevice Set: 0x%04x\\n\", table->dev_set);\n+\tsmbios_print_str(\"Device Locator\", table, table->dev_locator);\n+\tsmbios_print_str(\"Bank Locator\", table, table->bank_locator);\n+\tsmbios_print_lookup_str(md_type_strings, table->mem_type,\n+\t\t\t\tARRAY_SIZE(md_type_strings), \"Memory Type\");\n+\tprintf(\"\\tType Detail: 0x%04x\\n\", table->type_detail);\n+\tprintf(\"\\tSpeed: 0x%04x\\n\", table->speed);\n+\tsmbios_print_str(\"Manufacturer\", table, table->manufacturer);\n+\tsmbios_print_str(\"Serial Number\", table, table->serial_number);\n+\tsmbios_print_str(\"Asset Tag\", table, table->asset_tag);\n+\tsmbios_print_str(\"Part Number\", table, table->part_number);\n+\tprintf(\"\\tAttributes: 0x%04x\\n\", table->attributes);\n+\tprintf(\"\\tExtended Size: 0x%08x\\n\", table->ext_size);\n+\tprintf(\"\\tConfigured Memory Speed: 0x%04x\\n\", table->config_mem_speed);\n+\tprintf(\"\\tMinimum voltage: 0x%04x\\n\", table->min_voltage);\n+\tprintf(\"\\tMaximum voltage: 0x%04x\\n\", table->max_voltage);\n+\tprintf(\"\\tConfigured voltage: 0x%04x\\n\", table->config_voltage);\n+\tsmbios_print_lookup_str(md_tech_strings, table->mem_tech,\n+\t\t\t\tARRAY_SIZE(md_tech_strings),\n+\t\t\t\t\"Memory Technology\");\n+\tprintf(\"\\tMemory Operating Mode Capability: 0x%04x\\n\",\n+\t table->mem_op_mode_cap);\n+\tsmbios_print_str(\"Firmware Version\", table, table->fw_ver);\n+\tprintf(\"\\tModule Manufacturer ID: 0x%04x\\n\", table->module_man_id);\n+\tprintf(\"\\tModule Product ID: 0x%04x\\n\", table->module_prod_id);\n+\tprintf(\"\\tMemory Subsystem Controller Manufacturer ID: 0x%04x\\n\",\n+\t table->mem_subsys_con_man_id);\n+\tprintf(\"\\tMemory Subsystem Controller Product ID: 0x%04x\\n\",\n+\t table->mem_subsys_con_prod_id);\n+\tprintf(\"\\tNon-volatile Size: 0x%016llx\\n\", table->nonvolatile_size);\n+\tprintf(\"\\tVolatile Size: 0x%016llx\\n\", table->volatile_size);\n+\tprintf(\"\\tCache Size: 0x%016llx\\n\", table->cache_size);\n+\tprintf(\"\\tLogical Size: 0x%016llx\\n\", table->logical_size);\n+\tprintf(\"\\tExtended Speed: 0x%04x\\n\", table->ext_speed);\n+\tprintf(\"\\tExtended Configured Memory Speed: 0x%04x\\n\",\n+\t table->ext_config_mem_speed);\n+\tprintf(\"\\tPMIC0 Manufacturer ID: 0x%04x\\n\", table->pmic0_man_id);\n+\tprintf(\"\\tPMIC0 Revision Number: 0x%04x\\n\", table->pmic0_rev_num);\n+\tprintf(\"\\tRCD Manufacturer ID: 0x%04x\\n\", table->rcd_man_id);\n+\tprintf(\"\\tRCD Revision Number: 0x%04x\\n\", table->rcd_rev_num);\n+}\n+\n static void smbios_print_type127(struct smbios_type127 *table)\n {\n \tprintf(\"End Of Table\\n\");\n@@ -642,6 +765,9 @@ static int do_smbios(struct cmd_tbl *cmdtp, int flag, int argc,\n \t\tcase SMBIOS_PHYS_MEMORY_ARRAY:\n \t\t\tsmbios_print_type16((struct smbios_type16 *)pos);\n \t\t\tbreak;\n+\t\tcase SMBIOS_MEMORY_DEVICE:\n+\t\t\tsmbios_print_type17((struct smbios_type17 *)pos);\n+\t\t\tbreak;\n \t\tcase SMBIOS_END_OF_TABLE:\n \t\t\tsmbios_print_type127((struct smbios_type127 *)pos);\n \t\t\tbreak;\ndiff --git a/include/smbios.h b/include/smbios.h\nindex 293d6795cf3..2deafea9aa1 100644\n--- a/include/smbios.h\n+++ b/include/smbios.h\n@@ -327,6 +327,51 @@ struct __packed smbios_type16 {\n \tu64 ext_max_cap;\n \tchar eos[SMBIOS_STRUCT_EOS_BYTES];\n };\n+\n+struct __packed smbios_type17 {\n+\tstruct smbios_header hdr;\n+\tu16 phy_mem_array_hdl;\n+\tu16 mem_err_info_hdl;\n+\tu16 total_width;\n+\tu16 data_width;\n+\tu16 size;\n+\tu8 form_factor;\n+\tu8 dev_set;\n+\tu8 dev_locator;\n+\tu8 bank_locator;\n+\tu8 mem_type;\n+\tu16 type_detail;\n+\tu16 speed;\n+\tu8 manufacturer;\n+\tu8 serial_number;\n+\tu8 asset_tag;\n+\tu8 part_number;\n+\tu8 attributes;\n+\tu32 ext_size;\n+\tu16 config_mem_speed;\n+\tu16 min_voltage;\n+\tu16 max_voltage;\n+\tu16 config_voltage;\n+\tu8 mem_tech;\n+\tu16 mem_op_mode_cap;\n+\tu8 fw_ver;\n+\tu16 module_man_id;\n+\tu16 module_prod_id;\n+\tu16 mem_subsys_con_man_id;\n+\tu16 mem_subsys_con_prod_id;\n+\tu64 nonvolatile_size;\n+\tu64 volatile_size;\n+\tu64 cache_size;\n+\tu64 logical_size;\n+\tu32 ext_speed;\n+\tu32 ext_config_mem_speed;\n+\tu16 pmic0_man_id;\n+\tu16 pmic0_rev_num;\n+\tu16 rcd_man_id;\n+\tu16 rcd_rev_num;\n+\tchar eos[SMBIOS_STRUCT_EOS_BYTES];\n+};\n+\n struct __packed smbios_type32 {\n \tu8 type;\n \tu8 length;\ndiff --git a/include/smbios_def.h b/include/smbios_def.h\nindex c6850a5d6f5..ce913f2f32a 100644\n--- a/include/smbios_def.h\n+++ b/include/smbios_def.h\n@@ -309,4 +309,131 @@\n #define SMBIOS_MA_ERRINFO_NONE\t\t0xFFFE\n #define SMBIOS_MA_ERRINFO_NOERR\t\t0xFFFF\n \n+/* Memory Device */\n+\n+/* Size */\n+\n+#define SMBIOS_MD_SIZE_UNKNOWN\t0xFFFF\n+#define SMBIOS_MD_SIZE_EXT\t0x7FFF\n+\n+/* Form Factor */\n+#define SMBIOS_MD_FF_OTHER\t1\n+#define SMBIOS_MD_FF_UNKNOWN\t2\n+#define SMBIOS_MD_FF_SIMM\t3\n+#define SMBIOS_MD_FF_SIP\t4\n+#define SMBIOS_MD_FF_CHIP\t5\n+#define SMBIOS_MD_FF_DIP\t6\n+#define SMBIOS_MD_FF_ZIP\t7\n+#define SMBIOS_MD_FF_PROPCARD\t8\n+#define SMBIOS_MD_FF_DIMM\t9\n+#define SMBIOS_MD_FF_TSOP\t10\n+#define SMBIOS_MD_FF_ROC\t11\n+#define SMBIOS_MD_FF_RIMM\t12\n+#define SMBIOS_MD_FF_SODIMM\t13\n+#define SMBIOS_MD_FF_SRIMM\t14\n+#define SMBIOS_MD_FF_FBDIMM\t15\n+#define SMBIOS_MD_FF_DIE\t16\n+\n+/* Device set */\n+#define SMBIOS_MD_DEVSET_NONE\t\t0\n+#define SMBIOS_MD_DEVSET_UNKNOWN\t0xFF\n+\n+/* Speed */\n+#define SMBIOS_MD_SPEED_UNKNOWN\t0\n+#define SMBIOS_MD_SPEED_EXT\t0xFFFF\n+\n+/* Attributes */\n+#define SMBIOS_MD_ATTR_RANK_UNKNOWN\t0\n+\n+/* Configured Memory Speed */\n+#define SMBIOS_MD_CONFSPEED_UNKNOWN\t0\n+#define SMBIOS_MD_CONFSPEED_EXT\t\t0xFFFF\n+\n+/* Voltage */\n+#define SMBIOS_MD_VOLTAGE_UNKNOWN\t0\n+\n+/* Type */\n+#define SMBIOS_MD_TYPE_OTHER\t1\n+#define SMBIOS_MD_TYPE_UNKNOWN\t2\n+#define SMBIOS_MD_TYPE_DRAM\t3\n+#define SMBIOS_MD_TYPE_EDRAM\t4\n+#define SMBIOS_MD_TYPE_VRAM\t5\n+#define SMBIOS_MD_TYPE_SRAM\t6\n+#define SMBIOS_MD_TYPE_RAM\t7\n+#define SMBIOS_MD_TYPE_ROM\t8\n+#define SMBIOS_MD_TYPE_FLASH\t9\n+#define SMBIOS_MD_TYPE_EEPROM\t10\n+#define SMBIOS_MD_TYPE_FEPROM\t11\n+#define SMBIOS_MD_TYPE_EPROM\t12\n+#define SMBIOS_MD_TYPE_CDRAM\t13\n+#define SMBIOS_MD_TYPE_3DRAM\t14\n+#define SMBIOS_MD_TYPE_SDRAM\t15\n+#define SMBIOS_MD_TYPE_SGRAM\t16\n+#define SMBIOS_MD_TYPE_RDRAM\t17\n+#define SMBIOS_MD_TYPE_DDR\t18\n+#define SMBIOS_MD_TYPE_DDR2\t19\n+#define SMBIOS_MD_TYPE_DDR2FBD\t20\n+#define SMBIOS_MD_TYPE_RSVD1\t21\n+#define SMBIOS_MD_TYPE_RSVD2\t22\n+#define SMBIOS_MD_TYPE_DSVD3\t23\n+#define SMBIOS_MD_TYPE_DDR3\t24\n+#define SMBIOS_MD_TYPE_FBD2\t25\n+#define SMBIOS_MD_TYPE_DDR4\t26\n+#define SMBIOS_MD_TYPE_LPDDR\t27\n+#define SMBIOS_MD_TYPE_LPDDR2\t28\n+#define SMBIOS_MD_TYPE_LPDDR3\t29\n+#define SMBIOS_MD_TYPE_LPDDR4\t30\n+#define SMBIOS_MD_TYPE_LNVD\t31\n+#define SMBIOS_MD_TYPE_HBM\t32\n+#define SMBIOS_MD_TYPE_HBM2\t33\n+#define SMBIOS_MD_TYPE_DDR5\t34\n+#define SMBIOS_MD_TYPE_LPDDR5\t35\n+#define SMBIOS_MD_TYPE_HBM3\t36\n+\n+/* Type Detail */\n+#define SMBIOS_MD_TD_RSVD\t1 /* BIT(0), set to 0 */\n+#define SMBIOS_MD_TD_OTHER\t2 /* BIT(1) */\n+#define SMBIOS_MD_TD_UNKNOWN\t4 /* BIT(2) */\n+#define SMBIOS_MD_TD_FP\t\t8 /* BIT(3) */\n+#define SMBIOS_MD_TD_SC\t\t0x10 /* BIT(4) */\n+#define SMBIOS_MD_TD_PS\t\t0x20 /* BIT(5) */\n+#define SMBIOS_MD_TD_RAMBUS\t0x40 /* BIT(6) */\n+#define SMBIOS_MD_TD_SYNC\t0x80 /* BIT(7) */\n+#define SMBIOS_MD_TD_CMOS\t0x100 /* BIT(8) */\n+#define SMBIOS_MD_TD_EDO\t0x200 /* BIT(9) */\n+#define SMBIOS_MD_TD_WINDRAM\t0x400 /* BIT(10) */\n+#define SMBIOS_MD_TD_CACHEDRAM\t0x800 /* BIT(11) */\n+#define SMBIOS_MD_TD_NV\t\t0x1000 /* BIT(12) */\n+#define SMBIOS_MD_TD_RGSTD\t0x2000 /* BIT(13) */\n+#define SMBIOS_MD_TD_UNRGSTD\t0x4000 /* BIT(14) */\n+#define SMBIOS_MD_TD_LRDIMM\t0x8000 /* BIT(15) */\n+\n+/* Technology */\n+#define SMBIOS_MD_TECH_OTHER\t1\n+#define SMBIOS_MD_TECH_UNKNOWN\t2\n+#define SMBIOS_MD_TECH_DRAM\t3\n+#define SMBIOS_MD_TECH_NVDIMMN\t4\n+#define SMBIOS_MD_TECH_NVDIMMF\t5\n+#define SMBIOS_MD_TECH_NVDIMMP\t6\n+#define SMBIOS_MD_TECH_OPTANE\t7\n+\n+/* Operating Mode Capability */\n+#define SMBIOS_MD_OPMC_RSVD\t1 /* BIT(0), set to 0 */\n+#define SMBIOS_MD_OPMC_OTHER\t2 /* BIT(1) */\n+#define SMBIOS_MD_OPMC_UNKNOWN\t4 /* BIT(2) */\n+#define SMBIOS_MD_OPMC_VM\t8 /* BIT(3) */\n+#define SMBIOS_MD_OPMC_BYTEAPM\t0x10 /* BIT(4) */\n+#define SMBIOS_MD_OPMC_BLKAPM\t0x20 /* BIT(5) */\n+/* Bit 6:15 Reserved, set to 0 */\n+\n+/* Non-volatile / Volatile / Cache / Logical portion Size */\n+#define SMBIOS_MD_PORT_SIZE_NONE\t0\n+#define SMBIOS_MD_PORT_SIZE_UNKNOWN_HI\t0xFFFFFFFF\n+#define SMBIOS_MD_PORT_SIZE_UNKNOWN_LO\t0xFFFFFFFF\n+#define SMBIOS_MS_PORT_SIZE_UNKNOWN\t0xFFFFFFFFFFFFFFFF\n+\n+/* Error Information Handle */\n+#define SMBIOS_MD_ERRINFO_NONE\t\t0xFFFE\n+#define SMBIOS_MD_ERRINFO_NOERR\t\t0xFFFF\n+\n #endif /* _SMBIOS_DEF_H_ */\ndiff --git a/lib/smbios.c b/lib/smbios.c\nindex 27c9c975cf2..7c6ad63b1c7 100644\n--- a/lib/smbios.c\n+++ b/lib/smbios.c\n@@ -135,6 +135,14 @@ typedef int (*smbios_write_subnode)(ulong *current, int handle,\n \t\t\t\t struct smbios_ctx *ctx, int idx,\n \t\t\t\t int type);\n \n+typedef int (*smbios_write_memnode)(ulong *current, int handle,\n+\t\t\t\t struct smbios_ctx *ctx, int idx,\n+\t\t\t\t int type);\n+\n+typedef int (*smbios_write_memctrlnode)(ulong *current, int handle,\n+\t\t\t\t struct smbios_ctx *ctx, int idx,\n+\t\t\t\t u64 base, u64 sz);\n+\n /**\n * Function prototype to write a specific type of SMBIOS structure\n *\n@@ -1432,6 +1440,373 @@ static int smbios_write_type16(ulong *current, int *handle,\n \treturn len;\n }\n \n+static void smbios_pop_type17_general_si(struct smbios_ctx *ctx,\n+\t\t\t\t\t struct smbios_type17 *t)\n+{\n+\tt->mem_err_info_hdl =\n+\t\tsmbios_get_val_si(ctx, \"memory-error-information-handle\",\n+\t\t\t\t SYSID_NONE, SMBIOS_MD_ERRINFO_NONE);\n+\tt->total_width = smbios_get_val_si(ctx, \"total-width\", SYSID_NONE, 0);\n+\tt->data_width = smbios_get_val_si(ctx, \"data-width\", SYSID_NONE, 0);\n+\tt->form_factor = smbios_get_val_si(ctx, \"form-factor\",\n+\t\t\t\t\t SYSID_NONE, SMBIOS_MD_FF_UNKNOWN);\n+\tt->dev_set = smbios_get_val_si(ctx, \"device-set\", SYSID_NONE,\n+\t\t\t\t SMBIOS_MD_DEVSET_UNKNOWN);\n+\tt->dev_locator = smbios_add_prop_si(ctx, \"device-locator\", SYSID_NONE,\n+\t\t\t\t\t NULL);\n+\tt->bank_locator = smbios_add_prop_si(ctx, \"bank-locator\", SYSID_NONE,\n+\t\t\t\t\t NULL);\n+\tt->mem_type = smbios_get_val_si(ctx, \"memory-type\",\n+\t\t\t\t\tSYSID_NONE, SMBIOS_MD_TYPE_UNKNOWN);\n+\tt->type_detail = smbios_get_val_si(ctx, \"type-detail\",\n+\t\t\t\t\t SYSID_NONE, SMBIOS_MD_TD_UNKNOWN);\n+\tt->speed = smbios_get_val_si(ctx, \"speed\", SYSID_NONE,\n+\t\t\t\t SMBIOS_MD_SPEED_UNKNOWN);\n+\tt->manufacturer = smbios_add_prop_si(ctx, \"manufacturer\", SYSID_NONE,\n+\t\t\t\t\t NULL);\n+\tt->serial_number = smbios_add_prop_si(ctx, \"serial-number\", SYSID_NONE,\n+\t\t\t\t\t NULL);\n+\tt->asset_tag = smbios_add_prop_si(ctx, \"asset-tag\", SYSID_NONE, NULL);\n+\tt->part_number = smbios_add_prop_si(ctx, \"part-number\", SYSID_NONE,\n+\t\t\t\t\t NULL);\n+\tt->attributes = smbios_get_val_si(ctx, \"attributes\", SYSID_NONE,\n+\t\t\t\t\t SMBIOS_MD_ATTR_RANK_UNKNOWN);\n+\tt->config_mem_speed = smbios_get_val_si(ctx, \"configured-memory-speed\",\n+\t\t\t\t\t\tSYSID_NONE,\n+\t\t\t\t\t\tSMBIOS_MD_CONFSPEED_UNKNOWN);\n+\tt->min_voltage = smbios_get_val_si(ctx, \"minimum-voltage\", SYSID_NONE,\n+\t\t\t\t\t SMBIOS_MD_VOLTAGE_UNKNOWN);\n+\tt->max_voltage = smbios_get_val_si(ctx, \"maximum-voltage\", SYSID_NONE,\n+\t\t\t\t\t SMBIOS_MD_VOLTAGE_UNKNOWN);\n+\tt->config_voltage = smbios_get_val_si(ctx, \"configured-voltage\",\n+\t\t\t\t\t SYSID_NONE,\n+\t\t\t\t\t SMBIOS_MD_VOLTAGE_UNKNOWN);\n+\tt->mem_tech = smbios_get_val_si(ctx, \"memory-technology\",\n+\t\t\t\t\tSYSID_NONE, SMBIOS_MD_TECH_UNKNOWN);\n+\tt->mem_op_mode_cap =\n+\t\tsmbios_get_val_si(ctx, \"memory-operating-mode-capability\",\n+\t\t\t\t SYSID_NONE, SMBIOS_MD_OPMC_UNKNOWN);\n+\tt->fw_ver = smbios_add_prop_si(ctx, \"firmware-version\", SYSID_NONE,\n+\t\t\t\t NULL);\n+\tt->module_man_id = smbios_get_val_si(ctx, \"module-manufacturer-id\",\n+\t\t\t\t\t SYSID_NONE, 0);\n+\tt->module_prod_id = smbios_get_val_si(ctx, \"module-product-id\",\n+\t\t\t\t\t SYSID_NONE, 0);\n+\tt->mem_subsys_con_man_id =\n+\t\tsmbios_get_val_si(ctx,\n+\t\t\t\t \"memory-subsystem-controller-manufacturer-id\",\n+\t\t\t\t SYSID_NONE, 0);\n+\tt->mem_subsys_con_prod_id =\n+\t\tsmbios_get_val_si(ctx,\n+\t\t\t\t \"memory-subsystem-controller-product-id\",\n+\t\t\t\t SYSID_NONE, 0);\n+\tt->nonvolatile_size = smbios_get_u64_si(ctx, \"non-volatile-size\",\n+\t\t\t\t\t\tSYSID_NONE,\n+\t\t\t\t\t\tSMBIOS_MS_PORT_SIZE_UNKNOWN);\n+\tt->volatile_size = smbios_get_u64_si(ctx, \"volatile-size\",\n+\t\t\t\t\t SYSID_NONE,\n+\t\t\t\t\t SMBIOS_MS_PORT_SIZE_UNKNOWN);\n+\tt->cache_size = smbios_get_u64_si(ctx, \"cache-size\",\n+\t\t\t\t\t SYSID_NONE,\n+\t\t\t\t\t SMBIOS_MS_PORT_SIZE_UNKNOWN);\n+\tt->logical_size = smbios_get_u64_si(ctx, \"logical-size\",\n+\t\t\t\t\t SYSID_NONE,\n+\t\t\t\t\t SMBIOS_MS_PORT_SIZE_UNKNOWN);\n+\tt->ext_speed = smbios_get_val_si(ctx, \"extended-speed\", SYSID_NONE, 0);\n+\tt->ext_config_mem_speed =\n+\t\tsmbios_get_val_si(ctx, \"extended-configured-memory-speed\",\n+\t\t\t\t SYSID_NONE, 0);\n+\tt->pmic0_man_id = smbios_get_val_si(ctx, \"pmic0-manufacturer-id\",\n+\t\t\t\t\t SYSID_NONE, 0);\n+\tt->pmic0_rev_num = smbios_get_val_si(ctx, \"pmic0-revision-number\",\n+\t\t\t\t\t SYSID_NONE, 0);\n+\tt->rcd_man_id = smbios_get_val_si(ctx, \"rcd-manufacturer-id\",\n+\t\t\t\t\t SYSID_NONE, 0);\n+\tt->rcd_rev_num = smbios_get_val_si(ctx, \"rcd-revision-number\",\n+\t\t\t\t\t SYSID_NONE, 0);\n+}\n+\n+static void\n+smbios_pop_type17_size_from_memory_node(ofnode node, struct smbios_type17 *t)\n+{\n+\tconst fdt32_t *reg;\n+\tint len;\n+\tu64 sz;\n+\tu32 size_mb;\n+\n+\t/* Read property 'reg' from the node */\n+\treg = ofnode_read_prop(node, \"reg\", &len);\n+\tif (!reg || len < sizeof(fdt32_t) * 4 || len % sizeof(fdt32_t))\n+\t\treturn;\n+\n+\t/* Combine hi/lo for size (typically 64-bit) */\n+\tsz = ((u64)fdt32_to_cpu(reg[2]) << 32) | fdt32_to_cpu(reg[3]);\n+\n+\t/* Convert size to MB */\n+\tsize_mb = (u32)(sz >> 20); /* 1 MB = 2^20 */\n+\tif (size_mb < SMBIOS_MD_SIZE_EXT) {\n+\t\tt->size = cpu_to_le16(size_mb);\n+\t\tt->ext_size = 0;\n+\t\treturn;\n+\t}\n+\n+\tt->size = cpu_to_le16(SMBIOS_MD_SIZE_EXT); /* Signal extended used */\n+\tt->ext_size = cpu_to_le32((u32)(sz >> 10)); /* In KB */\n+}\n+\n+static void smbios_pop_type17_size_si(struct smbios_ctx *ctx,\n+\t\t\t\t struct smbios_type17 *t)\n+{\n+\tt->size = smbios_get_val_si(ctx, \"size\", SYSID_NONE,\n+\t\t\t\t SMBIOS_MD_SIZE_UNKNOWN);\n+\tt->ext_size = smbios_get_val_si(ctx, \"extended-size\", SYSID_NONE, 0);\n+}\n+\n+static int\n+smbios_scan_memctrl_subnode(ulong *current, int *handle, struct smbios_ctx *ctx,\n+\t\t\t int idx, smbios_write_memctrlnode cb)\n+{\n+\tint total_len = 0;\n+\tofnode child;\n+\tint i = 0;\n+\tint hdl_base = *handle;\n+\tu64 base = 0;\n+\n+\t/*\n+\t * Enumerate all subnodes of 'memory-controller' that contain 'size'\n+\t * property and generate one instance for each.\n+\t */\n+\tfor (child = ofnode_first_subnode(ctx->node); ofnode_valid(child);\n+\t child = ofnode_next_subnode(child)) {\n+\t\tu64 sz = 0;\n+\t\tconst fdt32_t *size;\n+\t\tint proplen;\n+\n+\t\tsize = ofnode_read_prop(child, \"size\", &proplen);\n+\t\tif (!size || proplen < sizeof(fdt32_t) ||\n+\t\t proplen % sizeof(fdt32_t))\n+\t\t\tcontinue;\n+\n+\t\t/* 64-bit size: <hi lo> or 32-bit size */\n+\t\tif (proplen >= sizeof(fdt32_t) * 2)\n+\t\t\tsz = ((u64)fdt32_to_cpu(size[0]) << 32) |\n+\t\t\t fdt32_to_cpu(size[1]);\n+\t\telse\n+\t\t\tsz = fdt32_to_cpu(size[0]);\n+\n+\t\t*handle = hdl_base + i;\n+\t\ttotal_len += cb(current, *handle, ctx, idx, base, sz);\n+\t\tbase += sz;\n+\t\ti++;\n+\t}\n+\n+\treturn total_len;\n+}\n+\n+static int\n+smbios_write_type17_from_memctrl_node(ulong *current, int handle,\n+\t\t\t\t struct smbios_ctx *ctx, int idx,\n+\t\t\t\t u64 __maybe_unused base, u64 sz)\n+{\n+\tstruct smbios_type17 *t;\n+\tint len;\n+\tu8 *eos_addr;\n+\tu32 size_mb;\n+\tvoid *hdl;\n+\tsize_t hdl_size;\n+\n+\tlen = sizeof(*t);\n+\tt = map_sysmem(*current, len);\n+\tmemset(t, 0, len);\n+\n+\tfill_smbios_header(t, SMBIOS_MEMORY_DEVICE, len, handle);\n+\n+\t/* eos is at the end of the structure */\n+\teos_addr = (u8 *)t + len - sizeof(t->eos);\n+\tsmbios_set_eos(ctx, eos_addr);\n+\n+\t/* Read the memory array handles */\n+\tif (!sysinfo_get_data(ctx->dev, SYSID_SM_MEMARRAY_HANDLE, &hdl,\n+\t\t\t &hdl_size) &&\n+\t\thdl_size == SYSINFO_MEM_HANDLE_MAX * sizeof(u16))\n+\t\tt->phy_mem_array_hdl = *((u16 *)hdl + idx);\n+\n+\t/* Convert to MB */\n+\tsize_mb = (u32)(sz >> 20);\n+\tif (size_mb < SMBIOS_MD_SIZE_EXT) {\n+\t\t/* Use 16-bit size field */\n+\t\tt->size = cpu_to_le16(size_mb); /* In MB */\n+\t\tt->ext_size = cpu_to_le32(0);\n+\t} else {\n+\t\t/* Signal use of extended size field */\n+\t\tt->size = cpu_to_le16(SMBIOS_MD_SIZE_EXT);\n+\t\tt->ext_size = cpu_to_le32((u32)(sz >> 10)); /* In KB */\n+\t}\n+\n+\t/* Write other general fields */\n+\tsmbios_pop_type17_general_si(ctx, t);\n+\n+\tlen = t->hdr.length + smbios_string_table_len(ctx);\n+\t*current += len;\n+\tunmap_sysmem(t);\n+\n+\treturn len;\n+}\n+\n+static int smbios_write_type17_mem(ulong *current, int handle,\n+\t\t\t\t struct smbios_ctx *ctx, int idx,\n+\t\t\t\t int type)\n+{\n+\tstruct smbios_type17 *t;\n+\tint len;\n+\tu8 *eos_addr;\n+\tvoid *hdl;\n+\tsize_t hdl_size;\n+\n+\tlen = sizeof(*t);\n+\tt = map_sysmem(*current, len);\n+\tmemset(t, 0, len);\n+\n+\tfill_smbios_header(t, SMBIOS_MEMORY_DEVICE, len, handle);\n+\n+\t/* eos is at the end of the structure */\n+\teos_addr = (u8 *)t + len - sizeof(t->eos);\n+\tsmbios_set_eos(ctx, eos_addr);\n+\n+\tif (type == SMBIOS_MEM_CUSTOM) {\n+\t\tsmbios_pop_type17_size_si(ctx, t);\n+\n+\t\tt->phy_mem_array_hdl =\n+\t\t\tsmbios_get_val_si(ctx, \"physical-memory-array-handle\",\n+\t\t\t\t\t SYSID_NONE, 0);\n+\t} else if (type == SMBIOS_MEM_FDT_MEM_NODE) {\n+\t\tsmbios_pop_type17_size_from_memory_node(ctx->node, t);\n+\n+\t\t/* Read the memory array handles */\n+\t\tif (!sysinfo_get_data(ctx->dev, SYSID_SM_MEMARRAY_HANDLE, &hdl,\n+\t\t\t\t &hdl_size) &&\n+\t\t hdl_size == SYSINFO_MEM_HANDLE_MAX * sizeof(u16))\n+\t\t\tt->phy_mem_array_hdl = *((u16 *)hdl + idx);\n+\t}\n+\n+\t/* Write other general fields */\n+\tsmbios_pop_type17_general_si(ctx, t);\n+\n+\tlen = t->hdr.length + smbios_string_table_len(ctx);\n+\t*current += len;\n+\tunmap_sysmem(t);\n+\n+\treturn len;\n+}\n+\n+static int smbios_scan_mem_nodes(ulong *current, int *handle,\n+\t\t\t\t struct smbios_ctx *ctx,\n+\t\t\t\t smbios_write_memnode mem_cb,\n+\t\t\t\t int *idx)\n+{\n+\tint len = 0;\n+\tstruct smbios_ctx ctx_bak;\n+\tofnode child;\n+\tint hdl_base = *handle;\n+\n+\tmemcpy(&ctx_bak, ctx, sizeof(ctx_bak));\n+\n+\tfor (child = ofnode_first_subnode(ofnode_root());\n+\t ofnode_valid(child); child = ofnode_next_subnode(child)) {\n+\t\tconst char *str;\n+\n+\t\t/* Look up for 'device_type = \"memory\"' */\n+\t\tstr = ofnode_read_string(child, \"device_type\");\n+\t\tif (!str || strcmp(str, \"memory\"))\n+\t\t\tcontinue;\n+\n+\t\tctx->node = child;\n+\t\t*handle = hdl_base + *idx;\n+\t\t/* Generate one instance for each 'memory' node */\n+\t\tlen += mem_cb(current, *handle, ctx, *idx,\n+\t\t\t SMBIOS_MEM_FDT_MEM_NODE);\n+\t\tmemcpy(ctx, &ctx_bak, sizeof(*ctx));\n+\t\t(*idx)++;\n+\t}\n+\n+\treturn len;\n+}\n+\n+static int smbios_scan_mctrl_subnodes(ulong *current, int *handle,\n+\t\t\t\t struct smbios_ctx *ctx,\n+\t\t\t\t smbios_write_memctrlnode mctrl_wcb,\n+\t\t\t\t int *idx)\n+{\n+\tint len = 0;\n+\tstruct smbios_ctx ctx_bak;\n+\tofnode child;\n+\n+\tmemcpy(&ctx_bak, ctx, sizeof(ctx_bak));\n+\n+\tfor (child = ofnode_first_subnode(ofnode_root());\n+\t ofnode_valid(child); child = ofnode_next_subnode(child)) {\n+\t\tconst char *compat;\n+\t\tconst char *name;\n+\n+\t\t/*\n+\t\t * Look up for node with name or property 'compatible'\n+\t\t * containing 'memory-controller'.\n+\t\t */\n+\t\tname = ofnode_get_name(child);\n+\t\tcompat = ofnode_read_string(child, \"compatible\");\n+\t\tif ((!compat || !strstr(compat, \"memory-controller\")) &&\n+\t\t (!name || !strstr(name, \"memory-controller\")))\n+\t\t\tcontinue;\n+\n+\t\t(*handle)++;\n+\t\tctx->node = child;\n+\t\t/*\n+\t\t * Generate one instance for each subnode of\n+\t\t * 'memory-controller' which contains property 'size'.\n+\t\t */\n+\t\tlen += smbios_scan_memctrl_subnode(current, handle, ctx,\n+\t\t\t\t\t\t *idx, mctrl_wcb);\n+\t\tmemcpy(ctx, &ctx_bak, sizeof(*ctx));\n+\t\t(*idx)++;\n+\t}\n+\treturn len;\n+}\n+\n+static int smbios_write_type1719(ulong *current, int *handle,\n+\t\t\t\t struct smbios_ctx *ctx,\n+\t\t\t\t smbios_write_memnode mem_cb,\n+\t\t\t\t smbios_write_memctrlnode mctrl_wcb)\n+{\n+\tint len = 0;\n+\tint idx;\n+\n+\tif (!IS_ENABLED(CONFIG_OF_CONTROL))\n+\t\treturn 0;\t/* Error, return 0-length */\n+\n+\t/* Step 1: Scan any subnode exists */\n+\tlen = smbios_scan_subnodes(current, ctx, handle, mem_cb,\n+\t\t\t\t SMBIOS_MEM_CUSTOM);\n+\tif (len)\n+\t\treturn len;\n+\n+\t/* Step 2: Scan 'memory' node from the entire FDT */\n+\tidx = 0;\n+\tlen += smbios_scan_mem_nodes(current, handle, ctx, mem_cb, &idx);\n+\n+\t/* Step 3: Scan 'memory-controller' node from the entire FDT */\n+\tlen += smbios_scan_mctrl_subnodes(current, handle, ctx, mctrl_wcb, &idx);\n+\n+\treturn len;\n+}\n+\n+static int smbios_write_type17(ulong *current, int *handle,\n+\t\t\t struct smbios_ctx *ctx)\n+{\n+\treturn smbios_write_type1719(current, handle, ctx,\n+\t\t\t\t smbios_write_type17_mem,\n+\t\t\t\t smbios_write_type17_from_memctrl_node);\n+}\n+\n #endif /* #if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLE_VERBOSE) */\n \n static int smbios_write_type32(ulong *current, int *handle,\n@@ -1481,6 +1856,7 @@ static struct smbios_write_method smbios_write_funcs[] = {\n #if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLE_VERBOSE)\n \t{ smbios_write_type9, \"system-slot\"},\n \t{ smbios_write_type16, \"memory-array\"},\n+\t{ smbios_write_type17, \"memory-device\"},\n #endif\n \t{ smbios_write_type32, },\n \t{ smbios_write_type127 },\n", "prefixes": [ "v6", "4/6" ] }