├── .gitattributes ├── README.md ├── cbtable ├── resource.h ├── cbtable.rc ├── trace.h ├── cbtable.inf ├── driver.h ├── cbtable.h ├── cbtable.vcxproj └── cbtable.c ├── LICENSE.txt ├── cbtable.sln ├── .gitignore └── cbtable Package └── cbtable Package.vcxproj /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Coreboot table 2 | 3 | This driver can be used to access debug info from Windows on a device running coreboot. 4 | 5 | You'll want to unhide the ACPI\BOOT0000 device. 6 | -------------------------------------------------------------------------------- /cbtable/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by cbtable.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2022 CoolStar 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /cbtable/cbtable.rc: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation All Rights Reserved 4 | 5 | Module Name: 6 | 7 | cbtable.rc 8 | 9 | Abstract: 10 | 11 | --*/ 12 | 13 | #include 14 | 15 | #define VER_FILETYPE VFT_DRV 16 | #define VER_FILESUBTYPE VFT2_DRV_SYSTEM 17 | #define VER_FILEDESCRIPTION_STR "Coreboot Table" 18 | #define VER_INTERNALNAME_STR "cbtable.sys" 19 | #define VER_ORIGINALFILENAME_STR "cbtable.sys" 20 | 21 | #define VER_LEGALCOPYRIGHT_YEARS "2023" 22 | #define VER_LEGALCOPYRIGHT_STR "Copyright (C) " VER_LEGALCOPYRIGHT_YEARS " CoolStar." 23 | 24 | #define VER_FILEVERSION 1,0,0,0 25 | #define VER_PRODUCTVERSION_STR "1.0.0.0" 26 | #define VER_PRODUCTVERSION 1,0,0,0 27 | #define LVER_PRODUCTVERSION_STR L"1.0.0.0" 28 | 29 | #define VER_FILEFLAGSMASK (VS_FF_DEBUG | VS_FF_PRERELEASE) 30 | #ifdef DEBUG 31 | #define VER_FILEFLAGS (VS_FF_DEBUG) 32 | #else 33 | #define VER_FILEFLAGS (0) 34 | #endif 35 | 36 | #define VER_FILEOS VOS_NT_WINDOWS32 37 | 38 | #define VER_COMPANYNAME_STR "CoolStar" 39 | #define VER_PRODUCTNAME_STR "Coreboot Table" 40 | 41 | #include "common.ver" -------------------------------------------------------------------------------- /cbtable/trace.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef _TRACE_H_ 4 | #define _TRACE_H_ 5 | 6 | extern "C" 7 | { 8 | // 9 | // Tracing Definitions: 10 | // 11 | // Control GUID: 12 | // {73e3b785-f5fb-423e-94a9-56627fea9053} 13 | // 14 | 15 | #define WPP_CONTROL_GUIDS \ 16 | WPP_DEFINE_CONTROL_GUID( \ 17 | SpbTestToolTraceGuid, \ 18 | (73e3b785,f5fb,423e,94a9,56627fea9053), \ 19 | WPP_DEFINE_BIT(TRACE_FLAG_WDFLOADING) \ 20 | WPP_DEFINE_BIT(TRACE_FLAG_SPBAPI) \ 21 | WPP_DEFINE_BIT(TRACE_FLAG_OTHER) \ 22 | ) 23 | } 24 | 25 | #define WPP_LEVEL_FLAGS_LOGGER(level,flags) WPP_LEVEL_LOGGER(flags) 26 | #define WPP_LEVEL_FLAGS_ENABLED(level, flags) (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= level) 27 | 28 | #define Trace CyapaPrint 29 | #define FuncEntry 30 | #define FuncExit 31 | #define WPP_INIT_TRACING 32 | #define WPP_CLEANUP 33 | #define TRACE_FLAG_SPBAPI 0 34 | #define TRACE_FLAG_WDFLOADING 0 35 | 36 | // begin_wpp config 37 | // FUNC FuncEntry{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS); 38 | // FUNC FuncExit{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS); 39 | // USEPREFIX(FuncEntry, "%!STDPREFIX! [%!FUNC!] --> entry"); 40 | // USEPREFIX(FuncExit, "%!STDPREFIX! [%!FUNC!] <--"); 41 | // end_wpp 42 | 43 | #endif _TRACE_H_ 44 | -------------------------------------------------------------------------------- /cbtable/cbtable.inf: -------------------------------------------------------------------------------- 1 | ;/*++ 2 | ; 3 | ;Copyright (c) CoolStar. All rights reserved. 4 | ; 5 | ;Module Name: 6 | ; cbtable.inf 7 | ; 8 | ;Abstract: 9 | ; INF file for installing the Coreboot Table Driver 10 | ; 11 | ; 12 | ;--*/ 13 | 14 | [Version] 15 | Signature = "$WINDOWS NT$" 16 | Class = System 17 | ClassGuid = {4d36e97d-e325-11ce-bfc1-08002be10318} 18 | Provider = CoolStar 19 | DriverVer = 10/9/2022,1.0.0 20 | CatalogFile = cbtable.cat 21 | PnpLockdown = 1 22 | 23 | [DestinationDirs] 24 | DefaultDestDir = 12 25 | 26 | ; ================= Class section ===================== 27 | 28 | [SourceDisksNames] 29 | 1 = %DiskId1%,,,"" 30 | 31 | [SourceDisksFiles] 32 | cbtable.sys = 1,, 33 | 34 | ;***************************************** 35 | ; cbtable Install Section 36 | ;***************************************** 37 | 38 | [Manufacturer] 39 | %StdMfg%=Standard,NT$ARCH$ 40 | 41 | ; Decorated model section take precedence over undecorated 42 | ; ones on XP and later. 43 | [Standard.NT$ARCH$] 44 | %cbtable.DeviceDesc%=cbtable_Device, ACPI\BOOT0000 45 | 46 | [cbtable_Device.NT] 47 | CopyFiles=Drivers_Dir 48 | 49 | [cbtable_Device.NT.HW] 50 | AddReg=cbtable_AddReg 51 | 52 | [Drivers_Dir] 53 | cbtable.sys 54 | 55 | [cbtable_AddReg] 56 | ; Set to 1 to connect the first interrupt resource found, 0 to leave disconnected 57 | HKR,Settings,"ConnectInterrupt",0x00010001,0 58 | 59 | ;-------------- Service installation 60 | [cbtable_Device.NT.Services] 61 | AddService = cbtable,%SPSVCINST_ASSOCSERVICE%, cbtable_Service_Inst 62 | 63 | ; -------------- cbtable driver install sections 64 | [cbtable_Service_Inst] 65 | DisplayName = %cbtable.SVCDESC% 66 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 67 | StartType = 3 ; SERVICE_DEMAND_START 68 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 69 | ServiceBinary = %12%\cbtable.sys 70 | LoadOrderGroup = Base 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | StdMfg = "CoolStar" 75 | DiskId1 = "Coreboot Table Installation Disk #1" 76 | cbtable.DeviceDesc = "Coreboot Table" 77 | cbtable.SVCDESC = "Coreboot Table Service" 78 | -------------------------------------------------------------------------------- /cbtable/driver.h: -------------------------------------------------------------------------------- 1 | #if !defined(_CBTABLE_H_) 2 | #define _CBTABLE_H_ 3 | 4 | #pragma warning(disable:4200) // suppress nameless struct/union warning 5 | #pragma warning(disable:4201) // suppress nameless struct/union warning 6 | #pragma warning(disable:4214) // suppress bit field types other than int warning 7 | #include 8 | #include 9 | 10 | #pragma warning(default:4200) 11 | #pragma warning(default:4201) 12 | #pragma warning(default:4214) 13 | #include 14 | 15 | #include "cbtable.h" 16 | 17 | // 18 | // String definitions 19 | // 20 | 21 | #define DRIVERNAME "crosecbus.sys: " 22 | 23 | #define CBTABLE_POOL_TAG (ULONG) 'CBTB' 24 | #define CBTABLE_HARDWARE_IDS L"CoolStar\\BOOT0000\0\0" 25 | #define CBTABLE_HARDWARE_IDS_LENGTH sizeof(CBTABLE_HARDWARE_IDS) 26 | 27 | #define NTDEVICE_NAME_STRING L"\\Device\\BOOT0000" 28 | #define SYMBOLIC_NAME_STRING L"\\DosDevices\\BOOT0000" 29 | 30 | #define true 1 31 | #define false 0 32 | 33 | typedef struct MEMMAPPING { 34 | BOOLEAN mapped; 35 | PHYSICAL_ADDRESS physAddr; 36 | PVOID virtAddr; 37 | size_t sz; 38 | } MemMapping, PMemMapping; 39 | 40 | enum NextRequest { 41 | NextRequestConsole, 42 | NextRequestTimestamps, 43 | NextRequestRoot, 44 | NextRequestTcpa, 45 | NextRequestReserved 46 | }; 47 | 48 | typedef struct _CBTABLE_CONTEXT 49 | { 50 | 51 | // 52 | // Handle back to the WDFDEVICE 53 | // 54 | 55 | WDFDEVICE FxDevice; 56 | 57 | WDFQUEUE CmdQueue; 58 | 59 | MemMapping rootMapping; 60 | MemMapping consoleMapping; 61 | MemMapping timestampMapping; 62 | MemMapping tcpaMapping; 63 | 64 | enum NextRequest nextRequest; 65 | 66 | UINT32 entryCount; 67 | 68 | } CBTABLE_CONTEXT, *PCBTABLE_CONTEXT; 69 | 70 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(CBTABLE_CONTEXT, GetDeviceContext) 71 | 72 | // 73 | // Function definitions 74 | // 75 | 76 | DRIVER_INITIALIZE DriverEntry; 77 | 78 | EVT_WDF_DRIVER_UNLOAD CBTableDriverUnload; 79 | 80 | EVT_WDF_DRIVER_DEVICE_ADD CBTableEvtDeviceAdd; 81 | 82 | EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL CBTableEvtInternalDeviceControl; 83 | 84 | // 85 | // Helper macros 86 | // 87 | 88 | #define DEBUG_LEVEL_ERROR 1 89 | #define DEBUG_LEVEL_INFO 2 90 | #define DEBUG_LEVEL_VERBOSE 3 91 | 92 | #define DBG_INIT 1 93 | #define DBG_PNP 2 94 | #define DBG_IOCTL 4 95 | 96 | #if 1 97 | #define CBTablePrint(dbglevel, dbgcatagory, fmt, ...) { \ 98 | if (CBTableDebugLevel >= dbglevel && \ 99 | (CBTableDebugCatagories && dbgcatagory)) \ 100 | { \ 101 | DbgPrint(DRIVERNAME); \ 102 | DbgPrint(fmt, __VA_ARGS__); \ 103 | } \ 104 | } 105 | #else 106 | #define CBTablePrint(dbglevel, fmt, ...) { \ 107 | } 108 | #endif 109 | #endif -------------------------------------------------------------------------------- /cbtable.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31829.152 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cbtable", "cbtable\cbtable.vcxproj", "{B3E71397-9BE4-492B-AAED-4D056E59CB1F}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cbtable Package", "cbtable Package\cbtable Package.vcxproj", "{EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F} = {B3E71397-9BE4-492B-AAED-4D056E59CB1F} 11 | EndProjectSection 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|Win32 = Debug|Win32 16 | Debug|x64 = Debug|x64 17 | Release|Win32 = Release|Win32 18 | Release|x64 = Release|x64 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Debug|Win32.ActiveCfg = Debug|Win32 22 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Debug|Win32.Build.0 = Debug|Win32 23 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Debug|Win32.Deploy.0 = Debug|Win32 24 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Debug|x64.ActiveCfg = Debug|x64 25 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Debug|x64.Build.0 = Debug|x64 26 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Debug|x64.Deploy.0 = Debug|x64 27 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Release|Win32.ActiveCfg = Release|Win32 28 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Release|Win32.Build.0 = Release|Win32 29 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Release|Win32.Deploy.0 = Release|Win32 30 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Release|x64.ActiveCfg = Release|x64 31 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Release|x64.Build.0 = Release|x64 32 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Release|x64.Deploy.0 = Release|x64 33 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Debug|Win32.ActiveCfg = Debug|Win32 34 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Debug|Win32.Build.0 = Debug|Win32 35 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Debug|Win32.Deploy.0 = Debug|Win32 36 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Debug|x64.ActiveCfg = Debug|x64 37 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Debug|x64.Build.0 = Debug|x64 38 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Debug|x64.Deploy.0 = Debug|x64 39 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Release|Win32.ActiveCfg = Release|Win32 40 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Release|Win32.Build.0 = Release|Win32 41 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Release|Win32.Deploy.0 = Release|Win32 42 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Release|x64.ActiveCfg = Release|x64 43 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Release|x64.Build.0 = Release|x64 44 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Release|x64.Deploy.0 = Release|x64 45 | EndGlobalSection 46 | GlobalSection(SolutionProperties) = preSolution 47 | HideSolutionNode = FALSE 48 | EndGlobalSection 49 | GlobalSection(ExtensibilityGlobals) = postSolution 50 | SolutionGuid = {86D249D6-FF1E-41F4-AA9B-3813428D6C1A} 51 | EndGlobalSection 52 | EndGlobal 53 | -------------------------------------------------------------------------------- /cbtable/cbtable.h: -------------------------------------------------------------------------------- 1 | #ifndef __CBTABLE_H__ 2 | #define __CBTABLE_H__ 3 | 4 | /* The coreboot table information is for conveying information 5 | * from the firmware to the loaded OS image. Primarily this 6 | * is expected to be information that cannot be discovered by 7 | * other means, such as querying the hardware directly. 8 | * 9 | * All of the information should be Position Independent Data. 10 | * That is it should be safe to relocated any of the information 11 | * without it's meaning/correctness changing. For table that 12 | * can reasonably be used on multiple architectures the data 13 | * size should be fixed. This should ease the transition between 14 | * 32 bit and 64 bit architectures etc. 15 | * 16 | * The completeness test for the information in this table is: 17 | * - Can all of the hardware be detected? 18 | * - Are the per motherboard constants available? 19 | * - Is there enough to allow a kernel to run that was written before 20 | * a particular motherboard is constructed? (Assuming the kernel 21 | * has drivers for all of the hardware but it does not have 22 | * assumptions on how the hardware is connected together). 23 | * 24 | * With this test it should be straight forward to determine if a 25 | * table entry is required or not. This should remove much of the 26 | * long term compatibility burden as table entries which are 27 | * irrelevant or have been replaced by better alternatives may be 28 | * dropped. Of course it is polite and expedite to include extra 29 | * table entries and be backwards compatible, but it is not required. 30 | */ 31 | 32 | enum { 33 | LB_TAG_UNUSED = 0x0000, 34 | LB_TAG_MEMORY = 0x0001, 35 | LB_TAG_HWRPB = 0x0002, 36 | LB_TAG_MAINBOARD = 0x0003, 37 | LB_TAG_VERSION = 0x0004, 38 | LB_TAG_EXTRA_VERSION = 0x0005, 39 | LB_TAG_BUILD = 0x0006, 40 | LB_TAG_COMPILE_TIME = 0x0007, 41 | LB_TAG_COMPILE_BY = 0x0008, 42 | LB_TAG_COMPILE_HOST = 0x0009, 43 | LB_TAG_COMPILE_DOMAIN = 0x000a, 44 | LB_TAG_COMPILER = 0x000b, 45 | LB_TAG_LINKER = 0x000c, 46 | LB_TAG_ASSEMBLER = 0x000d, 47 | LB_TAG_SERIAL = 0x000f, 48 | LB_TAG_CONSOLE = 0x0010, 49 | LB_TAG_FORWARD = 0x0011, 50 | LB_TAG_FRAMEBUFFER = 0x0012, 51 | LB_TAG_GPIO = 0x0013, 52 | LB_TAG_TIMESTAMPS = 0x0016, 53 | LB_TAG_CBMEM_CONSOLE = 0x0017, 54 | LB_TAG_MRC_CACHE = 0x0018, 55 | LB_TAG_VBNV = 0x0019, 56 | LB_TAG_VBOOT_HANDOFF = 0x0020, /* deprecated */ 57 | LB_TAG_X86_ROM_MTRR = 0x0021, 58 | LB_TAG_DMA = 0x0022, 59 | LB_TAG_RAM_OOPS = 0x0023, 60 | LB_TAG_ACPI_GNVS = 0x0024, 61 | LB_TAG_BOARD_ID = 0x0025, /* deprecated */ 62 | LB_TAG_VERSION_TIMESTAMP = 0x0026, 63 | LB_TAG_WIFI_CALIBRATION = 0x0027, 64 | LB_TAG_RAM_CODE = 0x0028, /* deprecated */ 65 | LB_TAG_SPI_FLASH = 0x0029, 66 | LB_TAG_SERIALNO = 0x002a, 67 | LB_TAG_MTC = 0x002b, 68 | LB_TAG_VPD = 0x002c, 69 | LB_TAG_SKU_ID = 0x002d, /* deprecated */ 70 | LB_TAG_BOOT_MEDIA_PARAMS = 0x0030, 71 | LB_TAG_CBMEM_ENTRY = 0x0031, 72 | LB_TAG_TSC_INFO = 0x0032, 73 | LB_TAG_MAC_ADDRS = 0x0033, 74 | LB_TAG_VBOOT_WORKBUF = 0x0034, 75 | LB_TAG_MMC_INFO = 0x0035, 76 | LB_TAG_TCPA_LOG = 0x0036, 77 | LB_TAG_FMAP = 0x0037, 78 | LB_TAG_PLATFORM_BLOB_VERSION = 0x0038, 79 | LB_TAG_SMMSTOREV2 = 0x0039, 80 | LB_TAG_TPM_PPI_HANDOFF = 0x003a, 81 | LB_TAG_BOARD_CONFIG = 0x0040, 82 | LB_TAG_ACPI_CNVS = 0x0041, 83 | LB_TAG_TYPE_C_INFO = 0x0042, 84 | LB_TAG_ACPI_RSDP = 0x0043, 85 | LB_TAG_PCIE = 0x0044, 86 | /* The following options are CMOS-related */ 87 | LB_TAG_CMOS_OPTION_TABLE = 0x00c8, 88 | LB_TAG_OPTION = 0x00c9, 89 | LB_TAG_OPTION_ENUM = 0x00ca, 90 | LB_TAG_OPTION_DEFAULTS = 0x00cb, 91 | LB_TAG_OPTION_CHECKSUM = 0x00cc, 92 | }; 93 | 94 | /* Coreboot table header structure */ 95 | struct coreboot_table_header { 96 | char signature[4]; 97 | UINT32 header_bytes; 98 | UINT32 header_checksum; 99 | UINT32 table_bytes; 100 | UINT32 table_checksum; 101 | UINT32 table_entries; 102 | }; 103 | 104 | /* List of coreboot entry structures that is used */ 105 | /* Generic */ 106 | struct coreboot_table_entry { 107 | UINT32 tag; 108 | UINT32 size; 109 | }; 110 | 111 | /* Points to a CBMEM entry */ 112 | struct lb_cbmem_ref { 113 | UINT32 tag; 114 | UINT32 size; 115 | 116 | UINT64 cbmem_addr; 117 | }; 118 | 119 | struct cbmem_console { 120 | UINT32 size; 121 | UINT32 cursor; 122 | }; 123 | #define CBMC_CURSOR_MASK ((1 << 28) - 1) 124 | #define CBMC_OVERFLOW (1 << 31) 125 | 126 | #include 127 | struct timestamp_entry { 128 | UINT32 entry_id; 129 | INT64 entry_stamp; 130 | }; 131 | 132 | struct timestamp_table { 133 | UINT64 base_time; 134 | UINT16 max_entries; 135 | UINT16 tick_freq_mhz; 136 | UINT32 num_entries; 137 | struct timestamp_entry entries[1]; /* Variable number of entries */ 138 | }; 139 | 140 | #define MAX_TCPA_LOG_ENTRIES 50 141 | #define TCPA_DIGEST_MAX_LENGTH 64 142 | #define TCPA_PCR_HASH_NAME 50 143 | #define TCPA_PCR_HASH_LEN 10 144 | /* Assumption of 2K TCPA log size reserved for CAR/SRAM */ 145 | #define MAX_PRERAM_TCPA_LOG_ENTRIES 15 146 | 147 | struct tcpa_entry { 148 | UINT32 pcr; 149 | char digest_type[TCPA_PCR_HASH_LEN]; 150 | UINT8 digest[TCPA_DIGEST_MAX_LENGTH]; 151 | UINT32 digest_length; 152 | char name[TCPA_PCR_HASH_NAME]; 153 | }; 154 | 155 | struct tcpa_table { 156 | UINT16 max_entries; 157 | UINT16 num_entries; 158 | struct tcpa_entry entries[0]; /* Variable number of entries */ 159 | }; 160 | 161 | #include 162 | 163 | #endif /* __CBTABLE_H__ */ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | [Ll]og/ 27 | 28 | # Visual Studio 2015/2017 cache/options directory 29 | .vs/ 30 | # Uncomment if you have tasks that create the project's static files in wwwroot 31 | #wwwroot/ 32 | 33 | # Visual Studio 2017 auto generated files 34 | Generated\ Files/ 35 | 36 | # MSTest test Results 37 | [Tt]est[Rr]esult*/ 38 | [Bb]uild[Ll]og.* 39 | 40 | # NUNIT 41 | *.VisualState.xml 42 | TestResult.xml 43 | 44 | # Build Results of an ATL Project 45 | [Dd]ebugPS/ 46 | [Rr]eleasePS/ 47 | dlldata.c 48 | 49 | # Benchmark Results 50 | BenchmarkDotNet.Artifacts/ 51 | 52 | # .NET Core 53 | project.lock.json 54 | project.fragment.lock.json 55 | artifacts/ 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_h.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *_wpftmp.csproj 81 | *.log 82 | *.vspscc 83 | *.vssscc 84 | .builds 85 | *.pidb 86 | *.svclog 87 | *.scc 88 | 89 | # Chutzpah Test files 90 | _Chutzpah* 91 | 92 | # Visual C++ cache files 93 | ipch/ 94 | *.aps 95 | *.ncb 96 | *.opendb 97 | *.opensdf 98 | *.sdf 99 | *.cachefile 100 | *.VC.db 101 | *.VC.VC.opendb 102 | 103 | # Visual Studio profiler 104 | *.psess 105 | *.vsp 106 | *.vspx 107 | *.sap 108 | 109 | # Visual Studio Trace Files 110 | *.e2e 111 | 112 | # TFS 2012 Local Workspace 113 | $tf/ 114 | 115 | # Guidance Automation Toolkit 116 | *.gpState 117 | 118 | # ReSharper is a .NET coding add-in 119 | _ReSharper*/ 120 | *.[Rr]e[Ss]harper 121 | *.DotSettings.user 122 | 123 | # JustCode is a .NET coding add-in 124 | .JustCode 125 | 126 | # TeamCity is a build add-in 127 | _TeamCity* 128 | 129 | # DotCover is a Code Coverage Tool 130 | *.dotCover 131 | 132 | # AxoCover is a Code Coverage Tool 133 | .axoCover/* 134 | !.axoCover/settings.json 135 | 136 | # Visual Studio code coverage results 137 | *.coverage 138 | *.coveragexml 139 | 140 | # NCrunch 141 | _NCrunch_* 142 | .*crunch*.local.xml 143 | nCrunchTemp_* 144 | 145 | # MightyMoose 146 | *.mm.* 147 | AutoTest.Net/ 148 | 149 | # Web workbench (sass) 150 | .sass-cache/ 151 | 152 | # Installshield output folder 153 | [Ee]xpress/ 154 | 155 | # DocProject is a documentation generator add-in 156 | DocProject/buildhelp/ 157 | DocProject/Help/*.HxT 158 | DocProject/Help/*.HxC 159 | DocProject/Help/*.hhc 160 | DocProject/Help/*.hhk 161 | DocProject/Help/*.hhp 162 | DocProject/Help/Html2 163 | DocProject/Help/html 164 | 165 | # Click-Once directory 166 | publish/ 167 | 168 | # Publish Web Output 169 | *.[Pp]ublish.xml 170 | *.azurePubxml 171 | # Note: Comment the next line if you want to checkin your web deploy settings, 172 | # but database connection strings (with potential passwords) will be unencrypted 173 | *.pubxml 174 | *.publishproj 175 | 176 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 177 | # checkin your Azure Web App publish settings, but sensitive information contained 178 | # in these scripts will be unencrypted 179 | PublishScripts/ 180 | 181 | # NuGet Packages 182 | *.nupkg 183 | # The packages folder can be ignored because of Package Restore 184 | **/[Pp]ackages/* 185 | # except build/, which is used as an MSBuild target. 186 | !**/[Pp]ackages/build/ 187 | # Uncomment if necessary however generally it will be regenerated when needed 188 | #!**/[Pp]ackages/repositories.config 189 | # NuGet v3's project.json files produces more ignorable files 190 | *.nuget.props 191 | *.nuget.targets 192 | 193 | # Microsoft Azure Build Output 194 | csx/ 195 | *.build.csdef 196 | 197 | # Microsoft Azure Emulator 198 | ecf/ 199 | rcf/ 200 | 201 | # Windows Store app package directories and files 202 | AppPackages/ 203 | BundleArtifacts/ 204 | Package.StoreAssociation.xml 205 | _pkginfo.txt 206 | *.appx 207 | 208 | # Visual Studio cache files 209 | # files ending in .cache can be ignored 210 | *.[Cc]ache 211 | # but keep track of directories ending in .cache 212 | !*.[Cc]ache/ 213 | 214 | # Others 215 | ClientBin/ 216 | ~$* 217 | *~ 218 | *.dbmdl 219 | *.dbproj.schemaview 220 | *.jfm 221 | *.pfx 222 | *.publishsettings 223 | orleans.codegen.cs 224 | 225 | # Including strong name files can present a security risk 226 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 227 | #*.snk 228 | 229 | # Since there are multiple workflows, uncomment next line to ignore bower_components 230 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 231 | #bower_components/ 232 | 233 | # RIA/Silverlight projects 234 | Generated_Code/ 235 | 236 | # Backup & report files from converting an old project file 237 | # to a newer Visual Studio version. Backup files are not needed, 238 | # because we have git ;-) 239 | _UpgradeReport_Files/ 240 | Backup*/ 241 | UpgradeLog*.XML 242 | UpgradeLog*.htm 243 | ServiceFabricBackup/ 244 | *.rptproj.bak 245 | 246 | # SQL Server files 247 | *.mdf 248 | *.ldf 249 | *.ndf 250 | 251 | # Business Intelligence projects 252 | *.rdl.data 253 | *.bim.layout 254 | *.bim_*.settings 255 | *.rptproj.rsuser 256 | 257 | # Microsoft Fakes 258 | FakesAssemblies/ 259 | 260 | # GhostDoc plugin setting file 261 | *.GhostDoc.xml 262 | 263 | # Node.js Tools for Visual Studio 264 | .ntvs_analysis.dat 265 | node_modules/ 266 | 267 | # Visual Studio 6 build log 268 | *.plg 269 | 270 | # Visual Studio 6 workspace options file 271 | *.opt 272 | 273 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 274 | *.vbw 275 | 276 | # Visual Studio LightSwitch build output 277 | **/*.HTMLClient/GeneratedArtifacts 278 | **/*.DesktopClient/GeneratedArtifacts 279 | **/*.DesktopClient/ModelManifest.xml 280 | **/*.Server/GeneratedArtifacts 281 | **/*.Server/ModelManifest.xml 282 | _Pvt_Extensions 283 | 284 | # Paket dependency manager 285 | .paket/paket.exe 286 | paket-files/ 287 | 288 | # FAKE - F# Make 289 | .fake/ 290 | 291 | # JetBrains Rider 292 | .idea/ 293 | *.sln.iml 294 | 295 | # CodeRush personal settings 296 | .cr/personal 297 | 298 | # Python Tools for Visual Studio (PTVS) 299 | __pycache__/ 300 | *.pyc 301 | 302 | # Cake - Uncomment if you are using it 303 | # tools/** 304 | # !tools/packages.config 305 | 306 | # Tabs Studio 307 | *.tss 308 | 309 | # Telerik's JustMock configuration file 310 | *.jmconfig 311 | 312 | # BizTalk build output 313 | *.btp.cs 314 | *.btm.cs 315 | *.odx.cs 316 | *.xsd.cs 317 | 318 | # OpenCover UI analysis results 319 | OpenCover/ 320 | 321 | # Azure Stream Analytics local run output 322 | ASALocalRun/ 323 | 324 | # MSBuild Binary and Structured Log 325 | *.binlog 326 | 327 | # NVidia Nsight GPU debugger configuration file 328 | *.nvuser 329 | 330 | # MFractors (Xamarin productivity tool) working folder 331 | .mfractor/ 332 | 333 | # Local History for Visual Studio 334 | .localhistory/ 335 | -------------------------------------------------------------------------------- /cbtable Package/cbtable Package.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B} 23 | {4605da2c-74a5-4865-98e1-152ef136825f} 24 | v4.5 25 | 11.0 26 | Win8.1 Debug 27 | Win32 28 | cbtable_Package 29 | 10.0.22000.0 30 | cbtable Package 31 | 32 | 33 | 34 | WindowsV6.3 35 | true 36 | WindowsKernelModeDriver10.0 37 | Utility 38 | Package 39 | true 40 | 41 | 42 | WindowsV6.3 43 | false 44 | WindowsKernelModeDriver10.0 45 | Utility 46 | Package 47 | true 48 | 49 | 50 | WindowsV6.3 51 | true 52 | WindowsKernelModeDriver10.0 53 | Utility 54 | Package 55 | true 56 | 57 | 58 | WindowsV6.3 59 | false 60 | WindowsKernelModeDriver10.0 61 | Utility 62 | Package 63 | true 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | DbgengKernelDebugger 75 | False 76 | True 77 | 78 | 79 | 80 | False 81 | False 82 | True 83 | 84 | 133563 85 | 86 | 87 | DbgengKernelDebugger 88 | False 89 | True 90 | 91 | 92 | 93 | False 94 | False 95 | True 96 | 97 | 133563 98 | 99 | 100 | DbgengKernelDebugger 101 | False 102 | True 103 | 104 | 105 | 106 | False 107 | False 108 | True 109 | 110 | 133563 111 | 112 | 113 | DbgengKernelDebugger 114 | False 115 | True 116 | 117 | 118 | 119 | False 120 | False 121 | True 122 | 123 | 133563 124 | 125 | 126 | 127 | SHA256 128 | 129 | 130 | 131 | 132 | SHA256 133 | 134 | 135 | 136 | 137 | SHA256 138 | 139 | 140 | 141 | 142 | SHA256 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | {b3e71397-9be4-492b-aaed-4d056e59cb1f} 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /cbtable/cbtable.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F} 23 | {1bc93793-694f-48fe-9372-81e2b05556fd} 24 | v4.5 25 | 11.0 26 | Win8.1 Debug 27 | Win32 28 | cbtable 29 | 10.0.22000.0 30 | cbtable 31 | 32 | 33 | 34 | 35 | 36 | true 37 | WindowsKernelModeDriver10.0 38 | Driver 39 | KMDF 40 | 41 | 42 | 43 | 44 | false 45 | WindowsKernelModeDriver10.0 46 | Driver 47 | KMDF 48 | 49 | 50 | 51 | 52 | true 53 | WindowsKernelModeDriver10.0 54 | Driver 55 | KMDF 56 | 57 | 58 | 59 | 60 | false 61 | WindowsKernelModeDriver10.0 62 | Driver 63 | KMDF 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | DbgengKernelDebugger 75 | 76 | 77 | DbgengKernelDebugger 78 | 79 | 80 | DbgengKernelDebugger 81 | 82 | 83 | DbgengKernelDebugger 84 | 85 | 86 | 87 | true 88 | trace.h 89 | true 90 | false 91 | 92 | 93 | 1.0.0 94 | 95 | 96 | SHA256 97 | 98 | 99 | 100 | 101 | true 102 | trace.h 103 | true 104 | false 105 | 106 | 107 | 1.0.0 108 | 109 | 110 | SHA256 111 | 112 | 113 | 114 | 115 | true 116 | trace.h 117 | true 118 | false 119 | 120 | 121 | 1.0.0 122 | 123 | 124 | SHA256 125 | 126 | 127 | 128 | 129 | true 130 | trace.h 131 | true 132 | false 133 | 134 | 135 | 1.0.0 136 | 137 | 138 | SHA256 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /cbtable/cbtable.c: -------------------------------------------------------------------------------- 1 | #include "driver.h" 2 | #include "stdint.h" 3 | 4 | static ULONG CBTableDebugLevel = 100; 5 | static ULONG CBTableDebugCatagories = DBG_INIT || DBG_PNP || DBG_IOCTL; 6 | 7 | NTSTATUS 8 | DriverEntry( 9 | __in PDRIVER_OBJECT DriverObject, 10 | __in PUNICODE_STRING RegistryPath 11 | ) 12 | { 13 | NTSTATUS status = STATUS_SUCCESS; 14 | WDF_DRIVER_CONFIG config; 15 | WDF_OBJECT_ATTRIBUTES attributes; 16 | 17 | CBTablePrint(DEBUG_LEVEL_INFO, DBG_INIT, 18 | "Driver Entry\n"); 19 | 20 | WDF_DRIVER_CONFIG_INIT(&config, CBTableEvtDeviceAdd); 21 | 22 | WDF_OBJECT_ATTRIBUTES_INIT(&attributes); 23 | 24 | // 25 | // Create a framework driver object to represent our driver. 26 | // 27 | 28 | status = WdfDriverCreate(DriverObject, 29 | RegistryPath, 30 | &attributes, 31 | &config, 32 | WDF_NO_HANDLE 33 | ); 34 | 35 | if (!NT_SUCCESS(status)) 36 | { 37 | CBTablePrint(DEBUG_LEVEL_ERROR, DBG_INIT, 38 | "WdfDriverCreate failed with status 0x%x\n", status); 39 | } 40 | 41 | return status; 42 | } 43 | 44 | NTSTATUS 45 | OnPrepareHardware( 46 | _In_ WDFDEVICE FxDevice, 47 | _In_ WDFCMRESLIST FxResourcesRaw, 48 | _In_ WDFCMRESLIST FxResourcesTranslated 49 | ) 50 | /*++ 51 | 52 | Routine Description: 53 | 54 | This routine caches the SPB resource connection ID. 55 | 56 | Arguments: 57 | 58 | FxDevice - a handle to the framework device object 59 | FxResourcesRaw - list of translated hardware resources that 60 | the PnP manager has assigned to the device 61 | FxResourcesTranslated - list of raw hardware resources that 62 | the PnP manager has assigned to the device 63 | 64 | Return Value: 65 | 66 | Status 67 | 68 | --*/ 69 | { 70 | PCBTABLE_CONTEXT pDevice = GetDeviceContext(FxDevice); 71 | NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES; 72 | 73 | UNREFERENCED_PARAMETER(FxResourcesRaw); 74 | 75 | // 76 | // Parse resources. 77 | // 78 | 79 | ULONG resourceCount = WdfCmResourceListGetCount(FxResourcesTranslated); 80 | 81 | for (ULONG i = 0; i < resourceCount; i++) 82 | { 83 | PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor; 84 | 85 | pDescriptor = WdfCmResourceListGetDescriptor( 86 | FxResourcesTranslated, i); 87 | 88 | switch (pDescriptor->Type) 89 | { 90 | case CmResourceTypeMemory: 91 | pDevice->rootMapping.physAddr = pDescriptor->u.Memory.Start; 92 | pDevice->rootMapping.sz = pDescriptor->u.Memory.Length; 93 | 94 | status = STATUS_SUCCESS; 95 | break; 96 | default: 97 | // 98 | // Ignoring all other resource types. 99 | // 100 | break; 101 | } 102 | } 103 | 104 | if (!NT_SUCCESS(status)) 105 | return status; 106 | 107 | pDevice->rootMapping.virtAddr = MmMapIoSpace(pDevice->rootMapping.physAddr, pDevice->rootMapping.sz, MmCached); 108 | if (!pDevice->rootMapping.virtAddr) 109 | return STATUS_NO_MEMORY; 110 | 111 | pDevice->rootMapping.mapped = TRUE; 112 | 113 | return status; 114 | } 115 | 116 | NTSTATUS 117 | OnReleaseHardware( 118 | _In_ WDFDEVICE FxDevice, 119 | _In_ WDFCMRESLIST FxResourcesTranslated 120 | ) 121 | /*++ 122 | 123 | Routine Description: 124 | 125 | Arguments: 126 | 127 | FxDevice - a handle to the framework device object 128 | FxResourcesTranslated - list of raw hardware resources that 129 | the PnP manager has assigned to the device 130 | 131 | Return Value: 132 | 133 | Status 134 | 135 | --*/ 136 | { 137 | NTSTATUS status = STATUS_SUCCESS; 138 | 139 | PCBTABLE_CONTEXT pDevice = GetDeviceContext(FxDevice); 140 | UNREFERENCED_PARAMETER(FxResourcesTranslated); 141 | 142 | if (pDevice->rootMapping.virtAddr) { 143 | MmUnmapIoSpace(pDevice->rootMapping.virtAddr, pDevice->rootMapping.sz); 144 | } 145 | 146 | return status; 147 | } 148 | 149 | VOID 150 | OnIoRead( 151 | _In_ WDFQUEUE FxQueue, 152 | _In_ WDFREQUEST FxRequest, 153 | _In_ size_t Length 154 | ) 155 | { 156 | WDFDEVICE device; 157 | PCBTABLE_CONTEXT pDevice; 158 | 159 | device = WdfIoQueueGetDevice(FxQueue); 160 | pDevice = GetDeviceContext(device); 161 | 162 | NTSTATUS status; 163 | 164 | PVOID Buffer; 165 | size_t BufLen; 166 | 167 | status = WdfRequestRetrieveOutputBuffer(FxRequest, Length, &Buffer, &BufLen); 168 | if (!NT_SUCCESS(status)) { 169 | DbgPrint("Failed to get output buffer\n"); 170 | goto exit; 171 | } 172 | 173 | RtlZeroMemory(Buffer, BufLen); 174 | 175 | MemMapping* mapping; 176 | switch (pDevice->nextRequest) { 177 | case NextRequestRoot: 178 | mapping = &pDevice->rootMapping; 179 | break; 180 | case NextRequestTcpa: 181 | mapping = &pDevice->tcpaMapping; 182 | break; 183 | case NextRequestTimestamps: 184 | mapping = &pDevice->timestampMapping; 185 | break; 186 | case NextRequestConsole: 187 | default: 188 | mapping = &pDevice->consoleMapping; 189 | break; 190 | } 191 | 192 | if (!mapping->mapped) { 193 | status = STATUS_DEVICE_NOT_READY; 194 | DbgPrint("Requested mapping not present\n"); 195 | } 196 | else { 197 | RtlCopyMemory(Buffer, mapping->virtAddr, min(BufLen, mapping->sz)); 198 | 199 | WdfRequestSetInformation(FxRequest, min(BufLen, mapping->sz)); 200 | } 201 | 202 | pDevice->nextRequest = NextRequestConsole; 203 | 204 | exit: 205 | WdfRequestComplete(FxRequest, status); 206 | } 207 | 208 | VOID 209 | OnTopLevelIoDefault( 210 | _In_ WDFQUEUE FxQueue, 211 | _In_ WDFREQUEST FxRequest 212 | ) 213 | /*++ 214 | Routine Description: 215 | Accepts all incoming requests and pends or forwards appropriately. 216 | Arguments: 217 | FxQueue - Handle to the framework queue object that is associated with the 218 | I/O request. 219 | FxRequest - Handle to a framework request object. 220 | Return Value: 221 | None. 222 | --*/ 223 | { 224 | UNREFERENCED_PARAMETER(FxQueue); 225 | 226 | WDFDEVICE device; 227 | PCBTABLE_CONTEXT pDevice; 228 | WDF_REQUEST_PARAMETERS params; 229 | NTSTATUS status; 230 | 231 | device = WdfIoQueueGetDevice(FxQueue); 232 | pDevice = GetDeviceContext(device); 233 | 234 | WDF_REQUEST_PARAMETERS_INIT(¶ms); 235 | 236 | WdfRequestGetParameters(FxRequest, ¶ms); 237 | 238 | status = WdfRequestForwardToIoQueue(FxRequest, pDevice->CmdQueue); 239 | 240 | if (!NT_SUCCESS(status)) 241 | { 242 | CBTablePrint(DEBUG_LEVEL_INFO, DBG_PNP, 243 | "Failed to forward WDFREQUEST %p to SPB queue %p - 0x%x", 244 | FxRequest, 245 | pDevice->CmdQueue, 246 | status); 247 | 248 | WdfRequestComplete(FxRequest, status); 249 | } 250 | } 251 | 252 | VOID 253 | OnIoWrite( 254 | _In_ WDFQUEUE FxQueue, 255 | _In_ WDFREQUEST FxRequest, 256 | _In_ size_t Length 257 | ) 258 | { 259 | WDFDEVICE device; 260 | PCBTABLE_CONTEXT pDevice; 261 | 262 | device = WdfIoQueueGetDevice(FxQueue); 263 | pDevice = GetDeviceContext(device); 264 | 265 | NTSTATUS status; 266 | 267 | PVOID Buffer; 268 | size_t BufLen; 269 | 270 | status = WdfRequestRetrieveInputBuffer(FxRequest, Length, &Buffer, &BufLen); 271 | if (!NT_SUCCESS(status)) { 272 | DbgPrint("Failed to get input buffer\n"); 273 | goto exit; 274 | } 275 | 276 | if (BufLen < sizeof(pDevice->nextRequest)) { 277 | DbgPrint("Input buffer too small\n"); 278 | status = STATUS_INVALID_PARAMETER; 279 | } 280 | else { 281 | enum NextRequest param = ((enum NextRequest *)Buffer)[0]; 282 | if (param < NextRequestConsole || param >= NextRequestReserved) { 283 | status = STATUS_INVALID_PARAMETER; 284 | } 285 | else { 286 | pDevice->nextRequest = param; 287 | } 288 | } 289 | 290 | exit: 291 | WdfRequestComplete(FxRequest, status); 292 | } 293 | 294 | /* 295 | * calculate ip checksum (16 bit quantities) on a passed in buffer. In case 296 | * the buffer length is odd last byte is excluded from the calculation 297 | */ 298 | static UINT16 ipchcksum(const void* addr, unsigned size) 299 | { 300 | const UINT16* p = addr; 301 | unsigned i, n = size / 2; /* don't expect odd sized blocks */ 302 | UINT32 sum = 0; 303 | 304 | for (i = 0; i < n; i++) 305 | sum += p[i]; 306 | 307 | sum = (sum >> 16) + (sum & 0xffff); 308 | sum += (sum >> 16); 309 | sum = ~sum & 0xffff; 310 | return (UINT16)sum; 311 | } 312 | 313 | static void mapConsole(PCBTABLE_CONTEXT pDevice) { 314 | struct cbmem_console* console_p; 315 | size_t size, cursor; 316 | 317 | size = sizeof(*console_p); 318 | 319 | size_t lastMapping = size; 320 | console_p = MmMapIoSpace(pDevice->consoleMapping.physAddr, lastMapping, MmCached); 321 | if (!console_p) 322 | return; 323 | 324 | cursor = console_p->cursor & CBMC_CURSOR_MASK; 325 | if (!(console_p->cursor & CBMC_OVERFLOW) && cursor < console_p->size) 326 | size = cursor; 327 | else 328 | size = console_p->size; 329 | MmUnmapIoSpace(console_p, lastMapping); 330 | 331 | lastMapping = size + sizeof(*console_p); 332 | console_p = MmMapIoSpace(pDevice->consoleMapping.physAddr, lastMapping, MmCached); 333 | if (!console_p) 334 | return; 335 | 336 | pDevice->consoleMapping.virtAddr = console_p; 337 | pDevice->consoleMapping.sz = lastMapping; 338 | pDevice->consoleMapping.mapped = TRUE; 339 | } 340 | 341 | static void mapTimestamps(PCBTABLE_CONTEXT pDevice) { 342 | struct timestamp_table* timestamp_p; 343 | size_t size, cursor; 344 | 345 | size = sizeof(*timestamp_p); 346 | 347 | size_t lastMapping = size; 348 | timestamp_p = MmMapIoSpace(pDevice->timestampMapping.physAddr, lastMapping, MmCached); 349 | if (!timestamp_p) 350 | return; 351 | 352 | size += timestamp_p->num_entries * sizeof(timestamp_p->entries[0]); 353 | MmUnmapIoSpace(timestamp_p, lastMapping); 354 | 355 | lastMapping = size; 356 | timestamp_p = MmMapIoSpace(pDevice->timestampMapping.physAddr, lastMapping, MmCached); 357 | if (!timestamp_p) 358 | return; 359 | 360 | pDevice->timestampMapping.virtAddr = timestamp_p; 361 | pDevice->timestampMapping.sz = lastMapping; 362 | pDevice->timestampMapping.mapped = TRUE; 363 | } 364 | 365 | static void mapTcpa(PCBTABLE_CONTEXT pDevice) { 366 | struct tcpa_table* tcpa_p; 367 | size_t size, cursor; 368 | 369 | size = sizeof(*tcpa_p); 370 | 371 | size_t lastMapping = size; 372 | tcpa_p = MmMapIoSpace(pDevice->tcpaMapping.physAddr, lastMapping, MmCached); 373 | if (!tcpa_p) 374 | return; 375 | 376 | size += tcpa_p->num_entries * sizeof(tcpa_p->entries[0]); 377 | MmUnmapIoSpace(tcpa_p, lastMapping); 378 | 379 | lastMapping = size; 380 | tcpa_p = MmMapIoSpace(pDevice->tcpaMapping.physAddr, lastMapping, MmCached); 381 | if (!tcpa_p) 382 | return; 383 | 384 | pDevice->tcpaMapping.virtAddr = tcpa_p; 385 | pDevice->tcpaMapping.sz = lastMapping; 386 | pDevice->tcpaMapping.mapped = TRUE; 387 | } 388 | 389 | NTSTATUS 390 | OnD0Entry( 391 | _In_ WDFDEVICE FxDevice, 392 | _In_ WDF_POWER_DEVICE_STATE FxPreviousState 393 | ) 394 | /*++ 395 | 396 | Routine Description: 397 | 398 | This routine allocates objects needed by the driver. 399 | 400 | Arguments: 401 | 402 | FxDevice - a handle to the framework device object 403 | FxPreviousState - previous power state 404 | 405 | Return Value: 406 | 407 | Status 408 | 409 | --*/ 410 | { 411 | UNREFERENCED_PARAMETER(FxPreviousState); 412 | NTSTATUS status = STATUS_SUCCESS; 413 | 414 | PCBTABLE_CONTEXT pDevice = GetDeviceContext(FxDevice); 415 | 416 | struct coreboot_table_header* hdr = pDevice->rootMapping.virtAddr; 417 | if (memcmp(hdr->signature, "LBIO", 4) != 0) { 418 | DbgPrint("Invalid coreboot table\n"); 419 | return STATUS_INVALID_DEVICE_STATE; 420 | } 421 | 422 | UINT32 checksum = ipchcksum((UINT8*)hdr + hdr->header_bytes, hdr->table_bytes); 423 | if (hdr->table_checksum != checksum) { 424 | DbgPrint("Invalid cbmem checksum 0x%x vs 0x%x\n", hdr->table_checksum, checksum); 425 | return STATUS_INVALID_DEVICE_STATE; 426 | } 427 | 428 | UINT8* entryStart = (UINT8 *)hdr + hdr->header_bytes; 429 | for (int i = 0; i < hdr->table_entries; i++) { 430 | struct coreboot_table_entry* entry = entryStart; 431 | 432 | if (entry->tag == LB_TAG_CBMEM_CONSOLE) { 433 | struct lb_cbmem_ref* console = entry; 434 | DbgPrint("Found cbmem console at 0x%llx\n", console->cbmem_addr); 435 | 436 | pDevice->consoleMapping.physAddr.QuadPart = console->cbmem_addr; 437 | 438 | mapConsole(pDevice); 439 | } else if (entry->tag == LB_TAG_TIMESTAMPS) { 440 | struct lb_cbmem_ref* timestamps = entry; 441 | DbgPrint("Found cbmem timestamps at 0x%llx\n", timestamps->cbmem_addr); 442 | 443 | pDevice->timestampMapping.physAddr.QuadPart = timestamps->cbmem_addr; 444 | 445 | mapTimestamps(pDevice); 446 | } else if (entry->tag == LB_TAG_TCPA_LOG) { 447 | struct lb_cbmem_ref* tcpa_log = entry; 448 | DbgPrint("Found cbmem tcpa at 0x%llx\n", tcpa_log->cbmem_addr); 449 | 450 | pDevice->tcpaMapping.physAddr.QuadPart = tcpa_log->cbmem_addr; 451 | 452 | mapTcpa(pDevice); 453 | } 454 | 455 | entryStart += entry->size; 456 | } 457 | 458 | return status; 459 | } 460 | 461 | NTSTATUS 462 | OnD0Exit( 463 | _In_ WDFDEVICE FxDevice, 464 | _In_ WDF_POWER_DEVICE_STATE FxTargetState 465 | ) 466 | /*++ 467 | 468 | Routine Description: 469 | 470 | This routine destroys objects needed by the driver. 471 | 472 | Arguments: 473 | 474 | FxDevice - a handle to the framework device object 475 | FxTargetState - target power state 476 | 477 | Return Value: 478 | 479 | Status 480 | 481 | --*/ 482 | { 483 | UNREFERENCED_PARAMETER(FxTargetState); 484 | 485 | NTSTATUS status = STATUS_SUCCESS; 486 | 487 | PCBTABLE_CONTEXT pDevice = GetDeviceContext(FxDevice); 488 | if (pDevice->consoleMapping.mapped) { 489 | MmUnmapIoSpace(pDevice->consoleMapping.virtAddr, pDevice->consoleMapping.sz); 490 | } 491 | 492 | if (pDevice->timestampMapping.mapped) { 493 | MmUnmapIoSpace(pDevice->timestampMapping.virtAddr, pDevice->timestampMapping.sz); 494 | } 495 | 496 | if (pDevice->tcpaMapping.mapped) { 497 | MmUnmapIoSpace(pDevice->tcpaMapping.virtAddr, pDevice->tcpaMapping.sz); 498 | } 499 | 500 | return status; 501 | } 502 | 503 | NTSTATUS 504 | CBTableEvtDeviceAdd( 505 | IN WDFDRIVER Driver, 506 | IN PWDFDEVICE_INIT DeviceInit 507 | ) 508 | { 509 | NTSTATUS status = STATUS_SUCCESS; 510 | WDF_OBJECT_ATTRIBUTES attributes; 511 | WDFDEVICE device; 512 | UCHAR minorFunction; 513 | PCBTABLE_CONTEXT devContext; 514 | WDF_QUERY_INTERFACE_CONFIG qiConfig; 515 | 516 | UNREFERENCED_PARAMETER(Driver); 517 | 518 | PAGED_CODE(); 519 | 520 | CBTablePrint(DEBUG_LEVEL_INFO, DBG_PNP, 521 | "CBTableEvtDeviceAdd called\n"); 522 | 523 | { 524 | WDF_PNPPOWER_EVENT_CALLBACKS pnpCallbacks; 525 | WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpCallbacks); 526 | 527 | pnpCallbacks.EvtDevicePrepareHardware = OnPrepareHardware; 528 | pnpCallbacks.EvtDeviceReleaseHardware = OnReleaseHardware; 529 | pnpCallbacks.EvtDeviceD0Entry = OnD0Entry; 530 | pnpCallbacks.EvtDeviceD0Exit = OnD0Exit; 531 | 532 | WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpCallbacks); 533 | } 534 | 535 | // 536 | // Prepare for file object handling. 537 | // 538 | 539 | { 540 | WDF_FILEOBJECT_CONFIG fileObjectConfig; 541 | 542 | WDF_FILEOBJECT_CONFIG_INIT( 543 | &fileObjectConfig, 544 | NULL, 545 | NULL, 546 | NULL); 547 | 548 | WDF_OBJECT_ATTRIBUTES fileObjectAttributes; 549 | WDF_OBJECT_ATTRIBUTES_INIT(&fileObjectAttributes); 550 | 551 | WdfDeviceInitSetFileObjectConfig( 552 | DeviceInit, 553 | &fileObjectConfig, 554 | &fileObjectAttributes); 555 | } 556 | 557 | // 558 | // Setup the device context 559 | // 560 | 561 | WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, CBTABLE_CONTEXT); 562 | 563 | // 564 | // Create a framework device object.This call will in turn create 565 | // a WDM device object, attach to the lower stack, and set the 566 | // appropriate flags and attributes. 567 | // 568 | 569 | status = WdfDeviceCreate(&DeviceInit, &attributes, &device); 570 | 571 | if (!NT_SUCCESS(status)) 572 | { 573 | CBTablePrint(DEBUG_LEVEL_ERROR, DBG_PNP, 574 | "WdfDeviceCreate failed with status code 0x%x\n", status); 575 | 576 | return status; 577 | } 578 | 579 | devContext = GetDeviceContext(device); 580 | devContext->FxDevice = device; 581 | 582 | WDF_IO_QUEUE_CONFIG queueConfig; 583 | WDFQUEUE queue; 584 | 585 | // 586 | // Top-level queue 587 | // 588 | 589 | WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE( 590 | &queueConfig, 591 | WdfIoQueueDispatchParallel); 592 | queueConfig.EvtIoDefault = OnTopLevelIoDefault; 593 | queueConfig.PowerManaged = WdfFalse; 594 | 595 | status = WdfIoQueueCreate( 596 | devContext->FxDevice, 597 | &queueConfig, 598 | WDF_NO_OBJECT_ATTRIBUTES, 599 | &queue 600 | ); 601 | 602 | if (!NT_SUCCESS(status)) 603 | { 604 | CBTablePrint(DEBUG_LEVEL_ERROR, DBG_PNP, 605 | "Error creating top-level IO queue - 0x%x", 606 | status); 607 | 608 | return status; 609 | } 610 | 611 | // 612 | // Create I/O queue 613 | // 614 | WDF_IO_QUEUE_CONFIG_INIT( 615 | &queueConfig, 616 | WdfIoQueueDispatchSequential); 617 | 618 | queueConfig.EvtIoRead = OnIoRead; 619 | queueConfig.EvtIoWrite = OnIoWrite; 620 | //queueConfig.EvtIoDeviceControl = OnIoDeviceControl; 621 | queueConfig.PowerManaged = WdfFalse; 622 | 623 | status = WdfIoQueueCreate( 624 | devContext->FxDevice, 625 | &queueConfig, 626 | WDF_NO_OBJECT_ATTRIBUTES, 627 | &devContext->CmdQueue 628 | ); 629 | if (!NT_SUCCESS(status)) 630 | { 631 | CBTablePrint(DEBUG_LEVEL_ERROR, DBG_PNP, 632 | "WdfIoQueueCreate failed 0x%x\n", status); 633 | 634 | return status; 635 | } 636 | 637 | DECLARE_CONST_UNICODE_STRING(dosDeviceName, SYMBOLIC_NAME_STRING); 638 | 639 | status = WdfDeviceCreateSymbolicLink(device, 640 | &dosDeviceName 641 | ); 642 | if (!NT_SUCCESS(status)) { 643 | CBTablePrint(DEBUG_LEVEL_ERROR, DBG_PNP, 644 | "WdfDeviceCreateSymbolicLink failed 0x%x\n", status); 645 | return status; 646 | } 647 | 648 | return status; 649 | } 650 | --------------------------------------------------------------------------------