From b83c269f46550bda18ad6b6cca106d2535054caf Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 9 Oct 2020 13:06:04 -0600 Subject: [PATCH 1/2] Add NVIDIA NBCI object dumping driver --- coreboot-collector-nvidia/Makefile | 8 + .../coreboot-collector-nvidia.c | 158 ++++++++++++++++++ coreboot-collector-nvidia/run.sh | 1 + 3 files changed, 167 insertions(+) create mode 100644 coreboot-collector-nvidia/Makefile create mode 100644 coreboot-collector-nvidia/coreboot-collector-nvidia.c create mode 100755 coreboot-collector-nvidia/run.sh diff --git a/coreboot-collector-nvidia/Makefile b/coreboot-collector-nvidia/Makefile new file mode 100644 index 0000000..ec3acdf --- /dev/null +++ b/coreboot-collector-nvidia/Makefile @@ -0,0 +1,8 @@ +obj-m := coreboot-collector-nvidia.o +KERNEL_DIR = /lib/modules/$(shell uname -r)/build + +all: + $(MAKE) -C "$(KERNEL_DIR)" M="$(PWD)" modules + +clean: + $(MAKE) -C "$(KERNEL_DIR)" M="$(PWD)" clean diff --git a/coreboot-collector-nvidia/coreboot-collector-nvidia.c b/coreboot-collector-nvidia/coreboot-collector-nvidia.c new file mode 100644 index 0000000..1b77159 --- /dev/null +++ b/coreboot-collector-nvidia/coreboot-collector-nvidia.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * System76 ACPI Driver + * + * Copyright (C) 2019 System76 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +static union acpi_object * dump_object(union acpi_object * obj) { + int i; + switch (obj->type) { + case ACPI_TYPE_INTEGER: + pr_info("Integer: 0x%llx\n", obj->integer.value); + break; + case ACPI_TYPE_STRING: + pr_info("String: '%s'\n", obj->string.pointer); + break; + case ACPI_TYPE_BUFFER: + pr_info("Buffer (0x%x) {", obj->buffer.length); + for (i = 0; i < obj->buffer.length; i++) { + if (i > 0) { + pr_cont(", "); + } + pr_cont("0x%02X", obj->buffer.pointer[i]); + } + pr_cont("}\n"); + break; + default: + pr_info("Unsupported type: 0x%x\n", obj->type); + break; + } + return obj; +} + +static union acpi_object * nvidia_dsm(acpi_handle handle, const guid_t * guid, u64 rev, u64 func, char arg[4]) { + union acpi_object argv4 = { + .buffer.type = ACPI_TYPE_BUFFER, + .buffer.length = 4, + .buffer.pointer = arg + }; + return acpi_evaluate_dsm( + handle, + guid, + rev, + func, + &argv4 + ); +} + +static const guid_t NBCI_DSM_GUID = GUID_INIT( + 0xD4A50B75, 0x65C7, 0x46F7, 0xBF, 0xB7, 0x41, 0x51, 0x4C, 0xEA, 0x02, 0x44 +); +#define NBCI_REVISION_ID 0x0102 +#define NBCI_FUNC_SUPPORT 0 +#define NBCI_FUNC_GETOBJBYTYPE 16 +static union acpi_object * nbci(acpi_handle handle, u64 func, char arg[4]) { + return nvidia_dsm( + handle, + &NBCI_DSM_GUID, + NBCI_REVISION_ID, + func, + arg + ); +} + +static void cbcnv_handle(acpi_handle handle) { + union acpi_object *obj = NULL; + char arg[4] = { 0, 0, 0, 0 }; + + pr_info("coreboot-collector-nvidia handle %p\n", handle); + + pr_info("NBCI_FUNC_SUPPORT\n"); + obj = nbci(handle, NBCI_FUNC_SUPPORT, arg); + if (obj) { + ACPI_FREE(dump_object(obj)); + obj = NULL; + } else { + acpi_handle_info(handle, "failed to execute\n"); + } + + arg[0] = 0; + arg[1] = 0; + arg[2] = 'R'; + arg[3] = 'D'; + pr_info("NBCI_FUNC_GETOBJBYTYPE '%c%c'\n", arg[3], arg[2]); + obj = nbci(handle, NBCI_FUNC_GETOBJBYTYPE, arg); + if (obj) { + ACPI_FREE(dump_object(obj)); + obj = NULL; + } else { + acpi_handle_info(handle, "failed to execute\n"); + } + + arg[0] = 0; + arg[1] = 0; + arg[2] = 'K'; + arg[3] = 'V'; + pr_info("NBCI_FUNC_GETOBJBYTYPE '%c%c'\n", arg[3], arg[2]); + obj = nbci(handle, NBCI_FUNC_GETOBJBYTYPE, arg); + if (obj) { + ACPI_FREE(dump_object(obj)); + obj = NULL; + } else { + acpi_handle_info(handle, "failed to execute\n"); + } +} + +static int __init cbcnv_init(void) { + struct pci_dev *pdev = NULL; + acpi_handle handle; + + pr_info("coreboot-collector-nvidia init\n"); + + while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { + int pci_class = pdev->class >> 8; + if (pci_class != PCI_CLASS_DISPLAY_VGA + && pci_class != PCI_CLASS_DISPLAY_3D) { + continue; + } + + if (pdev->vendor != PCI_VENDOR_ID_NVIDIA) { + continue; + } + + pr_info("NVIDIA GPU at '%s'\n", dev_name(&pdev->dev)); + + handle = ACPI_HANDLE(&pdev->dev); + if (!handle) { + pr_err("failed to find ACPI handle\n"); + continue; + } + + cbcnv_handle(handle); + } + + return 0; +} + +static void __exit cbcnv_exit(void) { + pr_info("coreboot-collector-nvidia exit\n"); +} + +module_init(cbcnv_init); +module_exit(cbcnv_exit); + +MODULE_DESCRIPTION("Coreboot Collector NVIDIA"); +MODULE_AUTHOR("Jeremy Soller "); +MODULE_LICENSE("GPL"); diff --git a/coreboot-collector-nvidia/run.sh b/coreboot-collector-nvidia/run.sh new file mode 100755 index 0000000..78f99ca --- /dev/null +++ b/coreboot-collector-nvidia/run.sh @@ -0,0 +1 @@ +sudo rmmod coreboot_collector_nvidia; make && sudo insmod coreboot-collector-nvidia.ko && dmesg -w From 4246d8716668cf4470894712bc0abcb8a4ab7949 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 9 Oct 2020 13:24:58 -0600 Subject: [PATCH 2/2] Improve buffer prints --- coreboot-collector-nvidia/coreboot-collector-nvidia.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/coreboot-collector-nvidia/coreboot-collector-nvidia.c b/coreboot-collector-nvidia/coreboot-collector-nvidia.c index 1b77159..1a96b62 100644 --- a/coreboot-collector-nvidia/coreboot-collector-nvidia.c +++ b/coreboot-collector-nvidia/coreboot-collector-nvidia.c @@ -29,11 +29,16 @@ static union acpi_object * dump_object(union acpi_object * obj) { pr_info("Buffer (0x%x) {", obj->buffer.length); for (i = 0; i < obj->buffer.length; i++) { if (i > 0) { - pr_cont(", "); + pr_cont(","); } - pr_cont("0x%02X", obj->buffer.pointer[i]); + if ((i % 8) == 0) { + pr_cont("\n"); + pr_info(" "); + } + pr_cont(" 0x%02X", obj->buffer.pointer[i]); } - pr_cont("}\n"); + pr_cont("\n"); + pr_info("}\n"); break; default: pr_info("Unsupported type: 0x%x\n", obj->type);