Beispiel #1
0
/**
  Get mouse packet . Only care first 3 bytes

  @param MouseAbsolutePointerDev  Pointer to PS2 Absolute Pointer Simulation Device Private Data Structure 

  @retval EFI_NOT_READY  Mouse Device not ready to input data packet, or some error happened during getting the packet
  @retval EFI_SUCCESS    The data packet is gotten successfully.

**/
EFI_STATUS
PS2MouseGetPacket (
  PS2_MOUSE_ABSOLUTE_POINTER_DEV     *MouseAbsolutePointerDev
  )

{
  EFI_STATUS  Status;
  BOOLEAN     KeyboardEnable;
  UINT8       Packet[PS2_PACKET_LENGTH];
  UINT8       Data;
  UINTN       Count;
  UINTN       State;
  INT16       RelativeMovementX;
  INT16       RelativeMovementY;
  BOOLEAN     LButton;
  BOOLEAN     RButton;

  KeyboardEnable  = FALSE;
  Count           = 1;
  State           = PS2_READ_BYTE_ONE;

  //
  // State machine to get mouse packet
  //
  while (1) {

    switch (State) {
    case PS2_READ_BYTE_ONE:
      //
      // Read mouse first byte data, if failed, immediately return
      //
      KbcDisableAux (MouseAbsolutePointerDev->IsaIo);
      Status = PS2MouseRead (MouseAbsolutePointerDev->IsaIo, &Data, &Count, State);
      if (EFI_ERROR (Status)) {
        KbcEnableAux (MouseAbsolutePointerDev->IsaIo);
        return EFI_NOT_READY;
      }

      if (Count != 1) {
        KbcEnableAux (MouseAbsolutePointerDev->IsaIo);
        return EFI_NOT_READY;
      }

      if (IS_PS2_SYNC_BYTE (Data)) {
        Packet[0] = Data;
        State     = PS2_READ_DATA_BYTE;

        CheckKbStatus (MouseAbsolutePointerDev->IsaIo, &KeyboardEnable);
        KbcDisableKb (MouseAbsolutePointerDev->IsaIo);
        KbcEnableAux (MouseAbsolutePointerDev->IsaIo);
      }
      break;

    case PS2_READ_DATA_BYTE:
      Count   = 2;
      Status  = PS2MouseRead (MouseAbsolutePointerDev->IsaIo, (Packet + 1), &Count, State);
      if (EFI_ERROR (Status)) {
        if (KeyboardEnable) {
          KbcEnableKb (MouseAbsolutePointerDev->IsaIo);
        }

        return EFI_NOT_READY;
      }

      if (Count != 2) {
        if (KeyboardEnable) {
          KbcEnableKb (MouseAbsolutePointerDev->IsaIo);
        }

        return EFI_NOT_READY;
      }

      State = PS2_PROCESS_PACKET;
      break;

    case PS2_PROCESS_PACKET:
      if (KeyboardEnable) {
        KbcEnableKb (MouseAbsolutePointerDev->IsaIo);
      }
      //
      // Decode the packet
      //
      RelativeMovementX = Packet[1];
      RelativeMovementY = Packet[2];
      //
      //               Bit 7   |    Bit 6   |    Bit 5   |   Bit 4    |   Bit 3  |   Bit 2    |   Bit 1   |   Bit 0 
      //  Byte 0  | Y overflow | X overflow | Y sign bit | X sign bit | Always 1 | Middle Btn | Right Btn | Left Btn 
      //  Byte 1  |                                           8 bit X Movement 
      //  Byte 2  |                                           8 bit Y Movement 
      // 
      // X sign bit + 8 bit X Movement : 9-bit signed twos complement integer that presents the relative displacement of the device in the X direction since the last data transmission.
      // Y sign bit + 8 bit Y Movement : Same as X sign bit + 8 bit X Movement.
      //
      //
      // First, Clear X and Y high 8 bits
      //
      RelativeMovementX = (INT16) (RelativeMovementX & 0xFF); 
      RelativeMovementY = (INT16) (RelativeMovementY & 0xFF); 
      //
      // Second, if the 9-bit signed twos complement integer is negative, set the high 8 bit 0xff
      //
      if ((Packet[0] & 0x10) != 0) {
        RelativeMovementX = (INT16) (RelativeMovementX | 0xFF00);
      }
      if ((Packet[0] & 0x20) != 0) {
        RelativeMovementY = (INT16) (RelativeMovementY | 0xFF00);
      }

      
      RButton           = (UINT8) (Packet[0] & 0x2);
      LButton           = (UINT8) (Packet[0] & 0x1);

      //
      // Update mouse state
      //
      MouseAbsolutePointerDev->State.CurrentX += RelativeMovementX;
      MouseAbsolutePointerDev->State.CurrentY -= RelativeMovementY;
      MouseAbsolutePointerDev->State.CurrentZ = 0;
      MouseAbsolutePointerDev->State.ActiveButtons = (UINT8) (LButton || RButton) & 0x3;
      MouseAbsolutePointerDev->StateChanged      = TRUE;

      return EFI_SUCCESS;
    }
  }
}
Beispiel #2
0
/**
  Reset the Mouse and do BAT test for it, if ExtendedVerification is TRUE and
  there is a mouse device connectted to system.

  @param This                 - Pointer of simple pointer Protocol.
  @param ExtendedVerification - Whether configure mouse parameters. True: do; FALSE: skip.


  @retval EFI_SUCCESS         - The command byte is written successfully.
  @retval EFI_DEVICE_ERROR    - Errors occurred during reseting keyboard.

**/
EFI_STATUS
EFIAPI
MouseReset (
  IN EFI_SIMPLE_POINTER_PROTOCOL    *This,
  IN BOOLEAN                        ExtendedVerification
  )
{
  EFI_STATUS    Status;
  PS2_MOUSE_DEV *MouseDev;
  EFI_TPL       OldTpl;
  BOOLEAN       KeyboardEnable;
  UINT8         Data;

  MouseDev = PS2_MOUSE_DEV_FROM_THIS (This);

  //
  // Report reset progress code
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET,
    MouseDev->DevicePath
    );

  KeyboardEnable = FALSE;

  //
  // Raise TPL to avoid keyboard operation impact
  //
  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);

  ZeroMem (&MouseDev->State, sizeof (EFI_SIMPLE_POINTER_STATE));
  MouseDev->StateChanged = FALSE;

  //
  // Exhaust input data
  //
  Status = EFI_SUCCESS;
  while (!EFI_ERROR (Status)) {
    Status = In8042Data (&Data);
  }

  CheckKbStatus (&KeyboardEnable);

  KbcDisableKb ();

  //
  // if there's data block on KBC data port, read it out
  //
  if ((IoRead8 (KBC_CMD_STS_PORT) & KBC_OUTB) == KBC_OUTB) {
    IoRead8 (KBC_DATA_PORT);
  }

  Status = EFI_SUCCESS;
  //
  // The PS2 mouse driver reset behavior is always successfully return no matter wheater or not there is mouse connected to system.
  // This behavior is needed by performance speed. The following mouse command only succeessfully finish when mouse device is
  // connected to system, so if PS2 mouse device not connect to system or user not ask for, we skip the mouse configuration and enabling
  //
  if (ExtendedVerification && CheckMouseConnect (MouseDev)) {
    //
    // Send mouse reset command and set mouse default configure
    //
    Status = PS2MouseReset ();
    if (EFI_ERROR (Status)) {
      Status = EFI_DEVICE_ERROR;
      goto Exit;
    }

    Status = PS2MouseSetSampleRate (MouseDev->SampleRate);
    if (EFI_ERROR (Status)) {
      Status = EFI_DEVICE_ERROR;
      goto Exit;
    }

    Status = PS2MouseSetResolution (MouseDev->Resolution);
    if (EFI_ERROR (Status)) {
      Status = EFI_DEVICE_ERROR;
      goto Exit;
    }

    Status = PS2MouseSetScaling (MouseDev->Scaling);
    if (EFI_ERROR (Status)) {
      Status = EFI_DEVICE_ERROR;
      goto Exit;
    }

    Status = PS2MouseEnable ();
    if (EFI_ERROR (Status)) {
      Status = EFI_DEVICE_ERROR;
      goto Exit;
    }
  }
Exit:
  gBS->RestoreTPL (OldTpl);

  if (KeyboardEnable) {
    KbcEnableKb ();
  }

  return Status;
}