Mysql_窗口函数_OVER()的分组参数PARTITION BY

TCP模拟三次握手

  返回  

ctl+alt+del三键重启情景分析

2021/8/21 19:51:54 浏览:
    if(NvmeShutdownEvent == NULL) {
        Status = gBS->CreateEventEx(
                         EVT_NOTIFY_SIGNAL,
                         TPL_CALLBACK,
                         NvmeShutdown,
                         NULL,
                         &gResetSystemEventGuid,
                         &NvmeShutdownEvent);
    }

在bios 的setup 界面,按下cll alt del 会由相应的handler 函数处理,也就是:

/**
  Function which is called when the Ctrl-Alt-Delete key sequence is detected. This function
  will cause the system to reset by calling the runtime services table's ResetSystem.

  @param KeyData Pointer to the key data that was read and caused this function to be called

  @return EFI_STATUS The status of the function
  @retval EFI_SUCCESS This function exited, instead of causing a reset.
**/
EFI_STATUS EFIAPI HandleCtrlAltDel(IN EFI_KEY_DATA *KeyData)
{
    if (HasCtrlAltDelBeenReplaced(KeyData))
    {
        return EFI_SUCCESS;
    }
    
    if(CurrentStdInStatus == FALSE)
        pRS->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
    return EFI_SUCCESS;
}

也就是会立马跳转到pRS->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);

首先找到pRS 赋值的地方

	if (pST) return;
	pST = SystemTable;
	pBS = pST->BootServices;
	pRS = pST->RuntimeServices;
    TheImageHandle = ImageHandle;

也就是SystemTable 传过来的。

接下来搜索ResetSystem 的函数实现:

ResetSystem  属于SystemTable的RuntimeService.于是搜索:

SystemTable->RuntimeServices->ResetSystem

搜索到的结果为:

  ///
  /// Hook the runtime service table
  ///
  SystemTable->RuntimeServices->ResetSystem = PlatformResetSystem;

 关机之前

/**
    Perform the Shutdown Initialization Sequence for the Nvme Controller 

    1. Stop submitting any new I/O commands to the controller and allow any outstanding commands to complete.
    2. The host should delete all I/O Submission Queues, using the Delete I/O Submission Queue command. 
        A result of the successful completion of the Delete I/O Submission Queue command is that any 
        remaining commands outstanding are aborted.
    3. The host should delete all I/O Completion Queues, using the Delete 
        I/O Completion Queue command.
    4. The host should set the Shutdown Notification (CC.SHN) field to 01b to indicate a normal shutdown operation. 
        The controller indicates when shutdown processing is completed by updating 
        the Shutdown Status (CSTS.SHST) field to 10b.
        
    @param Event   - signaled event
    @param Context - pointer to event context

    @retval EFI_STATUS

**/
VOID
EFIAPI
NvmeShutdown (
    IN EFI_EVENT    Event,
    IN VOID         *Context 
)
{
 
    UINTN                           NvmeHandle;
    UINTN                           Index=0;
    EFI_HANDLE                      *NvmeControllerHandleBuffer;
    AMI_NVME_CONTROLLER_PROTOCOL    *NvmeController = NULL;
    NVME_DXE_SMM_DATA_AREA          *NvmeDxeSmmDataArea = NULL;
    NVME_COMMAND_WRAPPER            *NvmeCmdWrapper = NULL;
    COMPLETION_QUEUE_ENTRY          CompletionData;
    EFI_STATUS                      Status;
    UINT32                          Delay = 0;

   
    // Locate all the Nvme Controller Protocol
    Status = gBS->LocateHandleBuffer(
                         ByProtocol,
                         &gAmiNvmeControllerProtocolGuid,
                         NULL,
                         &NvmeHandle,
                         &NvmeControllerHandleBuffer
                         );
    if(EFI_ERROR(Status) || NvmeHandle == 0 ) {
        return ;
    }
    
    Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  sizeof(NVME_COMMAND_WRAPPER),
                  (VOID**)&NvmeCmdWrapper
                  );

    ASSERT_EFI_ERROR(Status);
    if(EFI_ERROR(Status)) {
        return ;
    }
    

    for (Index = 0; Index < NvmeHandle; Index++) {
    
        // Get the Nvme Controller Protocol Interface
        Status = gBS->HandleProtocol(
                                NvmeControllerHandleBuffer[Index],
                                &gAmiNvmeControllerProtocolGuid,
                                (VOID *)&NvmeController
                                );
                
        ASSERT_EFI_ERROR(Status);
        if(EFI_ERROR(Status)) {
            continue;
        }

        NvmeDxeSmmDataArea = NvmeController->NvmeDxeSmmDataArea;

        // Clear memory
        SetMem(NvmeCmdWrapper, sizeof(NVME_COMMAND_WRAPPER), 0);
        
        // Delete all I/O Submission Queues, using the Delete I/O Submission Queue command
        // Build NVME command to delete Submission queue
        NvmeCmdWrapper->NvmCmd.CMD0.Opcode = DELETE_IO_SUBMISSION_QUEUE;
        NvmeCmdWrapper->NvmCmd.CMD0.CommandIdentifier = NvmeDxeSmmDataArea->CommandIdentifierAdmin;
        NvmeCmdWrapper->NvmCmd.CDW10 = NvmeController->NVMQueueNumber;
        
        NvmeCmdWrapper->AdminOrNVMCmdSet = TRUE;
        NvmeCmdWrapper->SQIdentifier = 0;           // Queue 0 for Admin cmds
        NvmeCmdWrapper->CmdTimeOut = NVME_COMMAND_TIMEOUT * 1000;
        
        Status = ExecuteNvmeCmd (NvmeController, NvmeCmdWrapper, &CompletionData);
        if (EFI_ERROR(Status)) {
            continue;
        }

        // Clear memory
        SetMem(NvmeCmdWrapper, sizeof(NVME_COMMAND_WRAPPER), 0);

        // Delete all I/O Completion Queues, using the Delete I/O Completion Queue command
        // Build NVME command to delete Completion queue
        NvmeCmdWrapper->NvmCmd.CMD0.Opcode = DELETE_IO_COMPLETION_QUEUE;
        NvmeCmdWrapper->NvmCmd.CMD0.CommandIdentifier = NvmeDxeSmmDataArea->CommandIdentifierAdmin;
        NvmeCmdWrapper->NvmCmd.CDW10 = NvmeController->NVMQueueNumber;
        
        NvmeCmdWrapper->AdminOrNVMCmdSet = TRUE;
        NvmeCmdWrapper->SQIdentifier = 0;           // Queue 0 for Admin cmds
        NvmeCmdWrapper->CmdTimeOut = NVME_COMMAND_TIMEOUT * 1000;
        
        Status = ExecuteNvmeCmd (NvmeController, NvmeCmdWrapper, &CompletionData);
        if (EFI_ERROR(Status)) {
            continue;
        }
        
        // Set the Shutdown Notification (CC.SHN) field to 01b to indicate a normal shutdown operation
        CONTROLLER_REG32_OR(NvmeController, Offset_CC, 0x4000);
        
        if (NvmeController->IdentifyControllerData != NULL) {
            Delay = (NvmeController->IdentifyControllerData->RTD3E) / 1000;
            if (Delay != 0) {
                if (((NvmeController->IdentifyControllerData->RTD3E) % 1000) != 0 ) {
                    Delay ++;
                }
            }
        }
        if (Delay == 0) {
            Delay = NvmeController->TimeOut * 500;
        }
        
        // Check if the shutdown process is completed  
        do {
         
            if ((CONTROLLER_REG32(NvmeController, Offset_CSTS) & 0xC) == 8) {
                break;
            }
            gBS->Stall(1000); // 1msec delay
            
        }while (--Delay);
        
        if (!Delay) {
            ASSERT (FALSE);
        }
    }
    
    gBS->FreePool(NvmeCmdWrapper);
    gBS->FreePool(NvmeControllerHandleBuffer);
    
    return ;
}
        
        // Check if the shutdown process is completed  
        do {
         
            if ((CONTROLLER_REG32(NvmeController, Offset_CSTS) & 0xC) == 8) {
                break;
            }
            gBS->Stall(1000); // 1msec delay

查看Offset_CSTS 的值,很容易知道其值为Ox1C

 = #define Offset_CSTS     0x1C

CSTS 的意思是controller status

每个bit 所代表的意思定义在nvme spec revision 1.4 第50页

 

打开nvme spec:   我这里的截图取自revision 1.4

对于突然的关机,我们应该检查Shutdown Status ,看nvme 的shutdown 是否完成。

 

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号