/** Read the Attach/Break-in symbols from the debug port. @param[in] Handle Pointer to Debug Port handle. @param[out] BreakSymbol Returned break symbol. @retval EFI_SUCCESS Read the symbol in BreakSymbol. @retval EFI_NOT_FOUND No read the break symbol. **/ EFI_STATUS DebugReadBreakFromDebugPort ( IN DEBUG_PORT_HANDLE Handle, OUT UINT8 *BreakSymbol ) { EFI_STATUS Status; DEBUG_PACKET_HEADER DebugHeader; UINT8 *Data8; *BreakSymbol = 0; // // If Debug Port buffer has data, read it till it was break symbol or Debug Port buffer empty. // Data8 = (UINT8 *) &DebugHeader; while (TRUE) { // // If start symbol is not received // if (!DebugPortPollBuffer (Handle)) { // // If no data in Debug Port, exit // break; } // // Try to read the start symbol // DebugPortReadBuffer (Handle, Data8, 1, 0); if (*Data8 == DEBUG_STARTING_SYMBOL_ATTACH) { DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Debug Timer attach symbol received %x", *Data8); *BreakSymbol = *Data8; return EFI_SUCCESS; } if (*Data8 == DEBUG_STARTING_SYMBOL_NORMAL) { Status = ReadRemainingBreakPacket (Handle, &DebugHeader); if (Status == EFI_SUCCESS) { DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Debug Timer break symbol received %x", DebugHeader.Command); *BreakSymbol = DebugHeader.Command; return EFI_SUCCESS; } if (Status == EFI_TIMEOUT) { break; } } else { // // Add to Terminal FIFO // DebugTerminalFifoAdd (&mSerialFifoForTerminal, *Data8); } } return EFI_NOT_FOUND; }
/** Break the other processor by send IPI. @param[in] CurrentProcessorIndex Current processor index value. **/ VOID HaltOtherProcessors ( IN UINT32 CurrentProcessorIndex ) { DebugAgentMsgPrint (DEBUG_AGENT_INFO, "processor[%x]:Try to halt other processors.\n", CurrentProcessorIndex); if (!IsBsp (CurrentProcessorIndex)) { SetIpiSentByApFlag (TRUE);; } mDebugMpContext.BreakAtCpuIndex = CurrentProcessorIndex; // // Set the debug viewpoint to the current breaking CPU. // SetDebugViewPoint (CurrentProcessorIndex); // // Send fixed IPI to other processors. // SendFixedIpiAllExcludingSelf (DEBUG_TIMER_VECTOR); }
/** Read the specified number of bytes from serial device. @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL. @param[in, out] BufferSize On input the size of Buffer, on output the amount of data returned in buffer. @param[out] Buffer The buffer to return the data into. @retval EFI_SUCCESS The data were read successfully. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_TIMEOUT The read operation was stopped due to timeout. **/ EFI_STATUS EFIAPI SerialRead ( IN EFI_SERIAL_IO_PROTOCOL *This, IN OUT UINTN *BufferSize, OUT VOID *Buffer ) { EFI_STATUS Status; UINTN Index; UINT8 *Uint8Buffer; BOOLEAN DebugTimerInterruptState; EFI_TPL Tpl; DEBUG_PORT_HANDLE Handle; DEBUG_PACKET_HEADER DebugHeader; UINT8 *Data8; // // Raise TPL to prevent recursion from EFI timer interrupts // Tpl = gBS->RaiseTPL (TPL_NOTIFY); // // Save and disable Debug Timer interrupt to avoid it to access Debug Port // DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (FALSE); Handle = GetDebugPortHandle (); Data8 = (UINT8 *) &DebugHeader; Uint8Buffer = (UINT8 *)Buffer; if ((mSerialIoMode.ControlMask & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) != 0) { if ((mLoopbackBuffer & SERIAL_PORT_LOOPBACK_BUFFER_FULL) == 0) { return EFI_TIMEOUT; } *Uint8Buffer = (UINT8)(mLoopbackBuffer & 0xff); mLoopbackBuffer = 0; *BufferSize = 1; } else { for (Index = 0; Index < *BufferSize; Index++) { // // Read input character from terminal FIFO firstly // Status = DebugTerminalFifoRemove (&mSerialFifoForTerminal, Data8); if (Status == EFI_SUCCESS) { *Uint8Buffer = *Data8; Uint8Buffer ++; continue; } // // Read the input character from Debug Port // if (!DebugPortPollBuffer (Handle)) { break; } DebugPortReadBuffer (Handle, Data8, 1, 0); if (*Data8 == DEBUG_STARTING_SYMBOL_ATTACH) { // // Add the debug symbol into Debug FIFO // DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Terminal Timer attach symbol received %x", *Data8); DebugTerminalFifoAdd (&mSerialFifoForDebug, *Data8); } else if (*Data8 == DEBUG_STARTING_SYMBOL_NORMAL) { Status = ReadRemainingBreakPacket (Handle, &DebugHeader); if (Status == EFI_SUCCESS) { DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Terminal Timer break symbol received %x", DebugHeader.Command); DebugTerminalFifoAdd (&mSerialFifoForDebug, DebugHeader.Command); } if (Status == EFI_TIMEOUT) { continue; } } else { *Uint8Buffer = *Data8; Uint8Buffer ++; } } *BufferSize = (UINTN)Uint8Buffer - (UINTN)Buffer; } // // Restore Debug Timer interrupt // SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState); // // Restore to original TPL // gBS->RestoreTPL (Tpl); return EFI_SUCCESS; }