SMI Driver

1#
perseverance发表于 2009-5-3 19:55:40|只看该作者|倒序浏览|阅读模式
转载自:http://blogs.phoenix.com/phoenix_technologies_bios/2008/12/bios-undercover-writing-a-software-smi-handler.html
---Tim Lewis, Chief BIOS Architect; Cassie Liu, Senior Software Engineer

System Management Interrupts (SMIs) are the highest priority interrupts found on x86 processors. Software SMIs are SMIs generated in response to a software instruction, usually a write to an I/O port such as 0xb2 (the SMI Command Port). The BIOS uses these software SMIs to provide services during late POST and then in runtime.

Software writes a value (the SMICommand Value) to the SMI Command Port. Typically the south bridge detects the write to the SMI Command Port and asserts the SMI# pin or sends an SMI message. Each CPU core detects the SMI after the current instruction has been completed. Then, the CPU saves most of the CPU registers in a buffer, switches to System Management Mode (SMM, a variant of big-real mode) and jumps to a pre-defined entry point.
Once inside of SMM, an SMM driver for the south bridge detects the source of the SMI (in this case, the software SMI), and then calls the routine which was registered for the SMI Command Value. After the routine returns, the SMM driver clears the SMI status and performs a “resume” instruction. This instruction forces the CPU to reload the CPU registers from the buffer and return to the instruction after the one which generated the software SMI.

In fact, while it appears that the SMI services are invoked immediately after writing to the I/O port and before the next CPU instruction, in some systems, the delay in propagation of the interrupt to the CPU cores may allow the cores to execute further instructions before the SMI is actually detected. This happens because the detection of the I/O write is usually the function of another chip in the system (such as a south bridge) and this chip must then signal the CPU using the SMI# signal or using bus messages.

Also, in multi-core systems, although the SMI is propagated to all cores, they enter at slightly different times. This discrepancy occurs because SMIs are serviced in between execution of CPU instructions. Since CPU instructions require a different number of clock cycles, some will enter SMM sooner than others. Phoenix code waits for all cores to enter SMM and then, using a semaphore, allows exactly one core to enter the SMI processing loop.
When writing drivers which use software SMIs, there are three primary tasks:
1.
How To Register For Software SMI Notification
2.
How To Handle The Software SMI Notification
3.
How To Generate Software SMIs
STEP 1: How To Register For NotificationThe first task is to write an SMM driver which registers for notification when a certain SMI Command Value is written to the SMI Command Port.
Here is the typical entry point code which registers for a software SMI value.
1.
SMM drivers are similar to DXE drivers at the entry point, except they are launched twice. At the first launch, they act as DXE drivers. During the first launch, they call the EFI_SMM_BASE_PROTOCOL’s Register() function to launch the driver a second time in System Management RAM (SMRAM).
2.
The SMM library performs all of the steps required by the SMM CIS to re-launch this driver in System Management RAM (SMRAM). On return, the InSmm flag has been set to TRUE if this is the copy of the driver running in SMRAM or FALSE if this is the normal DXE copy.
3.
If this driver is running in SMRAM, then perform the following steps…
4.
Locate the PHOENIX_SMM_SW_SMI_PROTOCOL. This protocol is a Phoenix service which allocates unique SMI Command Values.

5.
The AllocateSwSmi() function returns the unique SMI Command Value associated with the specified GUID. If no SMI Command Value has previously been associated with the specified GUID (and SwContext.SwSmiInputValue is 0xFFFFFFFF), then a unique SMI Command Value is returned. If not 0xFFFFFFFF, then SwContext.SwSmIInputValue will become the SMI Command Value OR an error return if the SMI Command Value has previously been assigned.
6.
Locate the EFI_SMM_SW_DISPATCH_PROTOCOL. This protocol is produced by the south bridge driver to callback a function when a specific SMI Command Value was written to the SMI Command Port.
7.
The Register() function is used to register a callback function with a particular SMI Command Value. The SwHandle value returned can be used to later UnRegister() the callback.

EFI_SMM_SYSTEM_TABLE *mSmst;
UINT8
mSwSmiCommandValue;

UINT16
mSwSmiCommandPort;


EFI_GUID gSwSmiSampleDriverGuid = SW_SMI_SAMPLE_DRIVER_GUID;

EFI_DRIVER_ENTRY_POINT(SwSmiSampleDriverEntryPoint);

EFI_STATUS
SwSmiSampleDriverEntryPoint(

IN EFI_HANDLE
ImageHandle,


IN EFI_SYSTEM_TABLE
*SystemTable

)
{

EFI_STATUS
Status;


BOOLEAN
InSmm;


EFI_SMM_SW_DISPATCH_PROTOCOL
*SwDispatch;


PHOENIX_SMM_SW_SMI_PROTOCOL
*SwSmiAlloc;


EFI_SMM_SW_DISPATCH_CONTEXT
SwContext;



EfiInitializeSmmDriverLib (ImageHandle,SystemTable,&InSmm);


if (InSmm) {


gSMM->GetSmstLocation(gSMM,&mSmst);



Status = gBS->LocateProtocol (


&gEfiPhoenixSmmSwSmiProtocolGuid,


NULL,


(VOID**) &SwSmiAlloc


);


ASSERT_EFI_ERROR (Status);



SwContext.SwSmiInputValue = 0xFFFFFFFF;


Status = SwSmiAlloc->AllocateSwSmi (


&gSwSmiSampleDriverGuid,


&SwContext.SwSmiInputValue


);


ASSERT_EFI_ERROR (Status);


mSwSmiCommandValue = (UINT16) SwContext.SwSmiInputValue;


mSwSmiCommandPort
= SwSmiAlloc->SwSmiCommandPort;



Status = gBS->LocateProtocol (


&gEfiSmmSwDispatchProtocolGuid,


NULL,


&SwDispatch


);


ASSERT_EFI_ERROR (Status);



Status = SwDispatch->Register (


SwDispatch,


SwSmiSampleDriverCallback,


&SwContext,


&SwHandle


);


ASSERT_EFI_ERROR (Status);



..other initialization…


}



return EFI_SUCCESS;

}

Some coding purists may be worried about the use of the ASSERT_EFI_ERROR macro, which detects an error only on debug versions. Why not always check for the error condition? The real reasons are: 1) it makes the code smaller and 2) it makes the code easier to read. But what about the risk?
In two cases, the macro is used with LocateProtocol(). In this case, the risk is very low because the GUIDs for these protocols are listed in the driver’s dependency expression (see SwSmiSampleDriver.dxs), so the driver won’t be launched unless the driver is actually present. In the third case, the macro is used with the Phoenix SMI Allocation protocol, which, in real life, would only fail if the system were out of memory, which is extremely unlikely in the pre-OS environment.
STEP 2: How To Handle The Software SMI NotificationOne the non-SMM code writes the SMI Command Value to the SMI Command Port, eventually control is transferred to the callback function (SwSmiSampleDriverCallback) which was registered during Step 1, above. Typically, Software SMI callbacks need to retrieve and change at the contents of CPU registers, examine the contents of memory, perform their service and then exit.
Reading CPU RegistersMost of the general-purpose registers are saved in a special buffer called the Save State Area when each CPU enters SMM. Other registers are not saved at all. For example, floating-point, XMM and MSRs are not saved.
The callback can read the current values of the general-purpose registers for any of the CPU cores. Since we are interested in the current values of the CPU core which generated the software SMI, we need to figure out which core that is.
Here are the steps:
1.
Determine which CPU core actually generated the software SMI, since all we care about are the CPU registers on that CPU.
2.
Once we have determined which CPU generated the software SMI, we can then access the CPU registers. In this case, we read EAX using ReadSaveState().
3.
Then we can perform our service, perhaps switching services based on the contents of AL.
4.
Finally, we put a signature back into the EAX register using WriteSaveState().

VOID
SwSmiSampleDriverCallback (

IN
EFI_HANDLE
DispatchHandle,


IN
EFI_SMM_SW_DISPATCH_CONTEXT
*DispatchContext


)

{

EFI_STATUS
Status;


UINTN
CpuIndex;


EFI_SMM_SAVE_STATE_IO_INFO IoInfo;




//


// Find the CPU that triggered the software SMI


//


for (CpuIndex = 0; CpuIndex < mSmst->NumberOfCpus; CpuIndex++) {


Status = mCpu->ReadSaveState(


mCpu,


sizeof(IoInfo),


EFI_SMM_SAVE_STATE_REGISTER_IO,


(VOID*) &IoInfo


);


if (Status EFI_SUCCESS &&


IoInfo->IoWidth EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 &&


IoInfo->IoPort (UINT16) mSwSmiCommandPort &&


* (UINT8*) IoInfo->IoData mSwSmiCommandValue


) {


break;


}


}


if (CpuIndex mSmst->NumberOfCpus) {


return;


}



UINT32 Eax;


Status = mCpu->ReadSaveState(


mCpu,


sizeof(Eax),


EFI_SMM_SAVE_STATE_REGISTER_RAX,


CpuIndex,


(VOID *) &Eax


);


ASSERT_EFI_ERROR(Status);



..other service code goes here..



Eax = 0xAA55AA55;


Status = mCpu->WriteSaveState(


mCpu,


sizeof(Eax),


EFI_SMM_SAVE_STATE_REGISTER_RAX,


CpuIndex,


(VOID *) &Eax


);

}
Reading System MemoryThe software SMI handler may need to read the contents of memory using the same context as the CPU which generated the software SMI. In many cases, the non-SMM code wants to pass a pointer to a buffer which will be used by the software SMI handler. But the non-SMM code may be executing with paging turned on or off and there may not be a 1-to-1 mapping between the linear and physical addresses. The software SMI handler, on the other hand, may be executing with paging turned on, but there is guaranteed to be a 1-to-1 mapping between linear and physical addresses. Adding to this, the buffer pointer may point to data which crosses a page boundary.
Phoenix provides a series of services which translate between physical and linear addresses. Phoenix also provides services which convert select/offset format addresses into linear addresses by looking them up in the GDT. These are encompassed in the PHOENIX_SMM_CPU_PAGE_PROTOCOL.
Let’s assume that the code which generates the software SMI passes a pointer to a 20-byte buffer using DS:ESI (x86) or DS:RSI (X64). We will reverse that buffer and pass it back. Here are the basic steps:
1.
Convert the value from DS:RSI to a linear address, using ConvertSegOffsetToLinear().
2.
Using this address, the 20 byte buffer is copied from system memory into a temporary buffer on the stack, taking page tables into account, using CopyFromLinear().
3.
The contents of the buffer are reversed.
4.
The 20 byte buffer is copied from the stack back into system memory, taking page tables into account using CopyToLinear().

EFI_VIRTUAL_ADDRESS Address;

Status = mCpuPage->ConvertSegOffsetRegToLinear(

CpuIndex,


EFI_SMM_SAVE_STATE_REGISTER_DS,


EFI_SMM_SAVE_STATE_REGISTER_RSI,


&Address


);

ASSERT_EFI_ERROR(Status);

UINT8 Buffer[20];
Status = mCpuPage->CopyFromLinear(

Address,


CpuIndex,


(EFI_PHYSICAL_ADDRESS) &Buffer,


sizeof(Buffer)


);

ASSERT_EFI_ERROR(Status);

for (i = 0; i < sizeof(Buffer)/2; i++) {

j = Buffer;


Buffer = Buffer[sizeof(Buffer) – i];


Buffer[sizeof(Buffer) – i] = j;

}

Status = mCpuPage->CopyToLinear(

(EFI_PHYSICAL_ADDRESS) &Buffer,


CpuIndex,


Address,


sizeof(Buffer)


);

ASSERT_EFI_ERROR(Status);


STEP 3: How To Generate The Software SMIFor applications which want to use the services created during the previous two steps, there are two important steps: first, find out the SMI Command Value and second, generate the software SMI.
Finding The SMI Command ValueThe SMI Command Value that was registered by the software SMI driver can be discovered using the QuerySwSmi() function in the PHOENIX_SMM_SW_SMI_PROTOCOL. Here are the steps.
1.
Find the PHOENIX_SMM_SW_SMI_PROTOCOL.
2.
Call QuerySwSmi() using the same GUID specified by the driver which allocated the SMI Command Value. The value returned in SwSmiCommandValue is the SMI Command Value.

UINT8 SwSmiCommandValue;
Status = gBS->LocateProtocol (

&gEfiPhoenixSmmSwSmiProtocolGuid,


NULL,


(VOID**) &SwSmiAlloc


);

ASSERT_EFI_ERROR (Status);


SwContext.SwSmiInputValue = 0xFFFFFFFF;
Status = SwSmiAlloc->QuerySwSmi (

&gSwSmiSampleDriverGuid,


&SwSmiCommandValue


);

ASSERT_EFI_ERROR (Status);

Generating The Software SMIThe SMI Command Port can be found in the same protocol and can be used to generate a software SMI with the right value:

_outp(mSwSmiCommandPort, mSwSmiCommandValue);

ConclusionWith this information, you can allocate a unique software SMI value and create new services which rely on either memory or register values. Next time, we will look at how to use the Phoenix SMM Services to “call” protocol functions inside of SMM securely.

上一篇:BIOS Undercover: Porting C/C++ To Phoenix UEFI (Part 4)
下一篇:BIOS Undercover: Detecting The Boot Mode
SMI, UEFI

相关帖子

  • • 自己寫的 BIOS Utility for UEFI Shell
  • • Attacks on UEFI securityFirmware
  • • 杭州华三通信 招聘 UEFI BIOS工程师(急聘)
  • • 在编译edk2的程序时为什么会出现error 7000: Failed to execute command
  • • 【官方】合肥联宝招聘BIOS工程师若干名
  • • Insyde 招聘BIOS 工程师
  • • 新手发帖
  • • 紧急招聘:BIOS工程师 + 性能调优工程师
  • • 3D机器人
-->

The first use of the Microsoft Standards-Based Storage Management service is in System Center 2012 Virtual Machine Manager (VMM). For Windows Server 2012, the Windows Standards-Based Storage Management Service is an optional component that supersedes the version supplied with VMM. Since VMM 2012 SP1 is compatible with Windows Server 2012, it uses the new storage service. Many new capabilities have been added for the Windows release and this document has been updated to reflect both versions. For simplicity, the term “storage service” will represent both products and differences are noted throughout the document.

ATI Automatic Driver Radeon HD 4350 Windows 7 32bit G31m3 L drivers. Easycap windows 8 x64 drivers? It and then ran the setup.exe in the driver folder but then the. Once inside of SMM, an SMM driver for the south bridge detects the source of the SMI (in this case, the software SMI), and then calls the routine which was registered for the SMI Command Value. After the routine returns, the SMM driver clears the SMI status and performs a “resume” instruction.

The storage service provides Discovery, Provisioning and Monitoring capabilities for use by applications. The intent of the storage service is to provide simplified access to SMI-S functionality without requiring much SMI-S knowledge on the part of the user. Typically, functionality is exposed to applications (such as VMM) and end-users through a set of PowerShell cmdlets, part of the Storage Management API (SMAPI) in Windows Server 2012. The full functionality is also exposed through the Windows Management Instrumentation (WMI) layer.

In many cases, the exposed interfaces will obfuscate industry-specific terms in favor of terms that are more user-friendly. However, wherever possible, the underlying implementation of the storage service is faithful to SMI-S.

This set of topics will not duplicate SMI-S documentation or DMTF MOFs. Therefore, it is assumed that the reader is familiar with those standards.

Audience

This documentation is aimed at SMI-S hardware provider developers. The intent is to identify the SMI-S capabilities being used in VMM 2012, VMM 2012 SP1, and Windows Server 2012. It is not a comprehensive guide to all the required CIM classes that a provider needs to implement. Rather, it gives insight into how Microsoft will use the SMI-S providers to implement recipes and functionality. Also note that Windows Server 2012 has greater capabilities than VMM. These differences are called out when applicable throughout the documentation.

Smi Driver For Windows 10

Devices

Input device driver download. Fibre Channel and iSCSI Storage arrays are supported in all versions. Support for SAS arrays and Host Hardware RAID (HHRC) controllers has been added for Windows Server 2012.

Windows Server 2012 also includes a passthrough capability allowing access to any CIM classes defined by an SMI-S provider. Applications can use this to extend management to FC fabrics, for example. Passthrough allows accessing all vendor-unique properties and classes in addition to the subset of SMI-S defined classes used by the storage service. VMM 2012 SP1 uses this capability in addition to the SMAPI interfaces.

Conformance to Standards

Full array functionality will require SMI-S 1.4 or later conformance – all references in this documentation refer to SMI-S 1.6 clauses unless otherwise noted. All references in this documentation refer to SMI-S 1.6 clauses unless otherwise noted. Although passage of the SNIA Provider Conformance Testing Program (CTP) is a desired goal, it is not sufficient to ensure that a particular SMI-S provider will function properly in this environment as the service requires some optional classes and properties and CTP tests do not enforce all the mandatory requirements. Tivo usb devices driver vga.

Additional standards that have been implemented include CIM-XML, CIM Operations over HTTP, Service Location Protocol (SLP) 2, CIM (2.29.1 Experimental, or in some cases, later MOFs) and SMI-S. (SMI-S often requires the Experimental DMTF MOFs; not the final MOFs.)

Umax Driver Download for windows

Driver

Note If a provider advertises a profile or subprofile by registering it (CIM_RegisteredProfile), it will be assumed that the provider conforms to that profile's (and version) requirements. CTP does not enforce this and instead lets vendors advertise any profile but bypass conformance testing.

Passive or readonly providers are not supported.

SMI-S Architecture

In addition to the referenced books and profiles, Windows requires strict conformance to the SMI-S Architecture Book. Special attention must be paid to Clause 7: Correlatable and Durable Names. Failure to follow these requirements will prevent the SMI-S provider from working properly - particularly masking operations - and that provider will not be supported for use with Windows.

Transport Protocols

This implementation supports CIM/XML and WMI (Windows Management Instrumentation) transports only. While the service supports HTTP (except for indications), the preferred transport for CIM/XML is HTTPS.

Namespaces

All providers must support the interop or root/interop namespace for CIM-XML providers and rootinterop for WMI-based providers. The interop namespace is used to locate supported profiles, and from there, discovery of the vendor-specific namespaces(s) can be performed. See the SMI-S Architecture Book for more information.

The current implementation supports some well-known interop namespaces:

Msi Driver

NamespaceNotes
interopIt is expected that all standalone CIMXML providers will use this namespace. Indications are supported in this namespace only.
rootinteropUsed by WMI-based providers only.
root/PG_InterOpUsed by some older OpenPegasus-based providers.

Note A provider may advertise a different interop namespace through SLPv2. While the storage service will send an Attribute Request (AttrRqst) to the provider, it is the vendor's responsibility to ensure this request is received and responded to promptly.

Installation Requirements for SMI-S Proxy Providers

While a provider can be embedded or a proxy installed on a non-Windows system, the following requirements are in place for any provider that installs on Windows.

RequirementDescription
Provider must be installed as a serviceProvider must run as a Windows service (or as a daemon on *nix systems) and not as an interactive application, except for debugging purposes.
Provider running on Windows must install on supported current releases of Windows ServerWindows Server 2008, Windows Server 2008R2, and Windows Server 2012 are currently the only supported platforms. The provider must install properly for those versions of the operating system and, unless the provider requires inband FC or SAS access to the arrays, the provider must support running on a virtual machine. For inband access, Hyper-V passthrough devices may be used to enable a provider to run on a VM. In that case, Hyper-V must be configured to disable SCSI filtering for LUNs requiring access for the purpose of management. By default, this is enabled, blocking most SCSI CDBs. It is the vendor's responsibility to configure this properly as part of the installation routine for the provider.
Provider must install properly using Windows guidelinesIn addition to the Windows User Account Control (UAC) Guidelines, the provider should not require special Windows administrative accounts and all accounts in the Administrators group must be supported. Also note that customers frequently lock down systems by disabling or renaming the local administrator account.
FirewallAny application or service must not disable - or suggest that a user disable - the firewall. The application or service must work properly with the inbox firewall, which is a standard component installed by Windows. Rules must be added during installation for inbound and outbound traffic, but must be as specific as possible (scoped to the correct type of network, the specific program, specific ports, direction, and so on). A best practice is for the installer to instantiate the appropriate firewall rules. The installer should not assume that the firewall will allow outbound connections even if that is the default setting; explicit rules should be added.
IPv6All providers running on Windows must support IPv6 as well as IPv4 and 6to4 tunneling addresses without any additional configuration steps. Customers run in mixed and single dialect environments. Therefore, any HTTP or HTTPS listener must listen on all interfaces or be configurable to enable/disable any specific interface. URL formats for IPv6 are defined in RFC 2732 and providers must adhere to that specification.
IPsecIPsec policy may prevent a provider from being accessed by a management system and may prevent deliver of indications if the provider and the storage service are not in the same domain or are subject to different filtering policies.
Provider must support HTTPSThe recommended practice is to validate certificates. When a provider installs and creates a certificate for use by its HTTPS server, that certificate will be checked by the Storage Service. The service always checks for a valid date range and may be configured to check for a common name equivalent to the server name (optional). Support for TLSv1.2 is recommended.
Vendor must handle configuration of their providerExamples include being able to easily add and remove arrays, management of array credentials, management of security credentials (unless Windows native security is employed) and certificates, and configuration of any optional feature such as tracing and logging. The storage service will not add or remove arrays through the use of CIM instances.

Related topics

Comments are closed.