diff options
Diffstat (limited to 'Core/EM/KbcEmul')
29 files changed, 8575 insertions, 0 deletions
diff --git a/Core/EM/KbcEmul/Ap4x.c b/Core/EM/KbcEmul/Ap4x.c new file mode 100644 index 0000000..8a483ad --- /dev/null +++ b/Core/EM/KbcEmul/Ap4x.c @@ -0,0 +1,81 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Ap4x.c 3 2/10/11 1:09a Rameshr $ +// +// $Revision: 3 $ +// +// $Date: 2/10/11 1:09a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Ap4x.c $ +// +// 3 2/10/11 1:09a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 2 6/30/09 11:32a Rameshr +// Coding Standard and File header updated. +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//**************************************************************************** +// Name: Ap4x.c +// +// Description: It has the Aptio4.x compatibility function +// +//**************************************************************************** +//<AMI_FHDR_END> + +#include "KbcEmul.h" + +EFI_SMM_CPU_IO_INTERFACE* gCpuIo = 0; +EFI_SMM_BASE_PROTOCOL* gSMM = 0; +EFI_SMM_SYSTEM_TABLE* gSmst = 0; + +extern EFI_GUID gEfiSmmBaseProtocolGuid; + +initializeLib(IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable) +{ + + EfiInitializeSmmDriverLib (ImageHandle, SystemTable); + + gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, &gSMM); + gSMM->GetSmstLocation (gSMM, &gSmst); + gCpuIo = &gSmst->SmmIo; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/KbcEmul/Ap4x.h b/Core/EM/KbcEmul/Ap4x.h new file mode 100644 index 0000000..73caa7c --- /dev/null +++ b/Core/EM/KbcEmul/Ap4x.h @@ -0,0 +1,130 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Ap4x.h 7 1/06/12 3:50a Rameshr $ +// +// $Revision: 7 $ +// +// $Date: 1/06/12 3:50a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Ap4x.h $ +// +// 7 1/06/12 3:50a Rameshr +// [TAG] EIP78617 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] When KBCEmulation is enabled during OS runtime phase, +// system reboots +// [RootCause] if the SMI happens from AP, Kbcemulation driver unable to +// handle it. +// [Solution] Added logic in KbcCore.c to find the CPU that cause SMI +// and access the corresponding AL register. +// [Files] Ap4x.h, KbcCore.c +// +// 6 1/06/12 3:21a Rameshr +// EIP78617 check-in removed. +// +// 4 4/11/11 2:56a Rameshr +// [TAG]- EIP 57436 +// [Category]-IMPROVEMENT +// [Description]- PI1.1 Support. +// [Files]- Ap4x.h, KbcEmul.c +// +// 3 2/10/11 1:09a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 2 6/30/09 11:32a Rameshr +// Coding Standard and File header updated. +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//**************************************************************************** +// Name: Ap4x.h +// +// Description: It has the Aptio4.x compatibility include files and headers +// +//**************************************************************************** +//<AMI_FHDR_END> +#include <efi.h> +#include <AmiDxeLib.h> + +#include <Protocol\SmmBase.h> +#include <Protocol\SmmUsbDispatch.h> +#include <Protocol\LoadedImage.h> +#include <Protocol\Emul6064MsInput.h> +#include <Protocol\Emul6064KbdInput.h> +#include <Protocol\Emul6064Trap.h> + +extern EFI_GUID gEfiSmmUsbDispatchProtocolGuid; + +#define EFI_DRIVER_ENTRY_POINT(x) + + +#define EfiInitializeSmmDriverLib(ImageHandle, SystemTable) InitAmiLib(ImageHandle, SystemTable) +#define EfiInitializeDriverLib(ImageHandle, SystemTable) InitAmiLib(ImageHandle,SystemTable) +#define gBS pBS +#define gRT pRS +#define EfiDuplicateDevicePath DPCopy +#define AppendDevicePath DPAdd +#define dp_len(x) (x) +#define GET_CPUSAVESTATE_REG(x, y) gSmst->CpuSaveState[x].Ia32SaveState.y + +extern EFI_SMM_BASE_PROTOCOL* gSMM; +#define _CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field))) + +#define VA_LIST va_list +#define VA_START va_start +#define VA_ARG va_arg +#define VA_END va_end +#define EfiDebugVPrint(EFI_D_ERROR, Message, ArgList) PrintDebugMessageVaList(-1, Message, ArgList) + +#define USBDEVPATH_END 0xFF, 0xFF + +#ifdef TRACE +#undef TRACE +#endif + +#ifdef EFI_DEBUG +void PrintDebugMsg (char *, ...); +#define TRACE PrintDebugMsg +#else +void PrintDebugMsg (char *, ...); +#define TRACE 1?0:PrintDebugMsg +#endif + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/KbcEmul/Kbc.h b/Core/EM/KbcEmul/Kbc.h new file mode 100644 index 0000000..9ae5c9b --- /dev/null +++ b/Core/EM/KbcEmul/Kbc.h @@ -0,0 +1,195 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Kbc.h 5 2/10/11 1:01a Rameshr $ +// +// $Revision: 5 $ +// +// $Date: 2/10/11 1:01a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Kbc.h $ +// +// 5 2/10/11 1:01a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 4 12/23/09 1:30a Rameshr +// Symptom: KbcEmulation can't install FreeBSD +// Solution: Implemented command 0xAA (Controller self-test) and 0xAB +// (Keyboard interface test) +// EIP: 26451 +// +// 3 6/30/09 11:29a Rameshr +// Coding Standard and File header updated. +// +// 2 12/27/07 4:54p Rameshraju +// KBC reset command added +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//********************************************************************** +// +// Name: Kbc.h +// +// Description: KBC Header file has the structure defination for Virtual and Legacy devices +// +//********************************************************************** +//<AMI_FHDR_END> + +#ifndef __INC_KBC_H__ +#define __INC_KBC_H__ + +#ifdef FRAMEWORK_AP4 +#include "token.h" +#else +#include "tokens.h" +#endif + +typedef struct _KBC KBC; +typedef struct _PS2SINK PS2SINK; + +typedef enum { + PS2DEV_KBD = 0x0, + PS2DEV_MOUSE = 0x1, +} PS2DEV_TYPE; +#define KBC_SENDQUEUE_SIZE 15 + +struct _PS2SINK { + // + //notify about a command from application + // + void (*onCommand)(PS2SINK* dev, UINT8 cmd ); + + // + //notify that queue is empty; pull streaming data + // + void (*onQueueFree)(PS2SINK* dev); + + KBC* kbc; + BOOLEAN present_; + BOOLEAN presence_detected_; +}; + +struct _KBC{ + void (*kbc_write_command)(KBC* kbc, UINT8 cmd ); + void (*kbc_write_data)(KBC* kbc, UINT8 data ); + UINT8 (*kbc_read_status)(KBC* kbc ); + UINT8 (*kbc_read_data)(KBC* kbc ); + + BOOLEAN (*send_outb1)( KBC* kbc, PS2DEV_TYPE devtype, BOOLEAN ovrd, UINT8 data ); + UINT8 (*read_ccb)(KBC* kbc); + PS2SINK* mouse_dev; + PS2SINK* kbd_dev; + UINT8 send_queue[KBC_SENDQUEUE_SIZE]; + UINT8 send_queue_aux[KBC_SENDQUEUE_SIZE]; + UINT8* sqHead[2]; + UINT8* sqTail[2]; + + int nSeq; + UINT8 aux_en; // aux interface enabled/disabled (value is a KBC command) + UINT8 kbd_en; // kbd interface enabled/disabled (value is a KBC command) +}; + + +#define KBC_STATUS_REG 0x64 +#define KBC_COMMAND_REG 0x64 +#define KBC_DATA_REG 0x60 +#define KBCTIMEOUT 0x1000 +// +// KBC Status bits definition +// +#define KBC_STATUS_OBF 0x1 +#define KBC_STATUS_IBF 0x2 +#define KBC_STATUS_SYS 0x4 +#define KBC_STATUS_A2 0x8 +#define KBC_STATUS_INH 0x10 +#define KBC_STATUS_AUXB 0x20 +#define KBC_STATUS_TO 0x40 //Timeout detected +#define KBC_STATUS_PERR 0x80 //Parity error detected + +// +// KBC CCB bits definition +// +#define KBC_CCB_INT 0x01 +#define KBC_CCB_INT2 0x02 +#define KBC_CCB_SYS 0x04 +#define KBC_CCB_EN 0x10 +#define KBC_CCB_EN2 0x20 +#define KBC_CCB_XLAT 0x40 + + +// +//KBC output bits definition +// +#define CCB_KEYBOARD_DISABLED 0x10 +#define CCB_MOUSE_DISABLED 0x20 +#define CCB_TRANSLATE_SCAN_CODE_BIT_MASK 0x40 + + +// +// KBC Commands +// +#define KBCCMD_WriteAuxBuffer 0xD3 +#define KBCCMD_WriteKbdBuffer 0xD2 +#define KBCCMD_WriteAuxDev 0xD4 +#define KBCCMD_READ_CCB 0x20 +#define KBCCMD_WRITE_CCB 0x60 +#define KBCCMD_LOCK USB_SEND_COMMAND_TO_KBC +#define KBCCMD_AUXENBL 0xA8 +#define KBCCMD_AUXDSBL 0xA7 +#define KBCCMD_KBDENBL 0xAE +#define KBCCMD_KBDDSBL 0xAD +#define KBCCMD_CheckAux 0xA9 +#define KBCCMD_CheckKbd 0xAB +#define KBCCMD_SelfTest 0xAA +#define KBCCMD_ReadInPort 0xC0 +#define KBCCMD_ReadOutPortL 0xC1 +#define KBCCMD_ReadOutPortH 0xC2 +#define KBCCMD_ReadOutPort 0xD0 +#define KBCCMD_WriteOutPort 0xD1 +#define KBCCMD_ResetSystem 0xFE + +// +// KBC Command Status Response +// +#define KBCCMD_RES_SelfTestOk 0x55 +#define KBCCMD_RES_KBInterfaceOk 0 + + +#endif // __INC_KBC_H__ + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +//****************************************************************************
\ No newline at end of file diff --git a/Core/EM/KbcEmul/KbcDevEmul.h b/Core/EM/KbcEmul/KbcDevEmul.h new file mode 100644 index 0000000..d420aad --- /dev/null +++ b/Core/EM/KbcEmul/KbcDevEmul.h @@ -0,0 +1,193 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcDevEmul.h 7 9/30/11 12:45a Rameshr $ +// +// $Revision: 7 $ +// +// $Date: 9/30/11 12:45a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcDevEmul.h $ +// +// 7 9/30/11 12:45a Rameshr +// [TAG] EIP71408 +// [Category] Improvement +// [Description] Remove the customer name reference from the +// KbcEmulation module. +// [Files] KbcDevEmul.h,VirtualKbc.c +// +// 6 2/10/11 1:01a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 5 7/08/10 1:56a Rameshr +// Ohci Emulation support Added. +// EIP 39712 +// +// 4 2/03/10 1:14a Rameshr +// Install Netware6.5 SP8 Fail. +// EIP 28411 +// Single byte and two Byte command is identified properly and handled. +// +// 3 6/30/09 11:30a Rameshr +// Coding Standard and File header updated. +// +// 2 10/30/08 10:49a Rameshraju +// Keyboard & Mouse enable/disable command handled +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//********************************************************************** +// +// Name: KbcDevEmul.h +// +// Description: Devices header file +// +//********************************************************************** +//<AMI_FHDR_END> + +#ifndef __INC_VKBC_H__ +#define __INC_VKBC_H__ + +#include "Kbc.h" + +#define KBD_MOUSE_INTR_DISABLE 0x75 +#define MOUSE_INTR_DISABLE 0x65 +#define MOUSE_INTR_ENABLE 0x47 + +// +//Virtual KBC +// +typedef struct _VIRTKBC VIRTKBC; + +struct _VIRTKBC{ + KBC kbc; + UINT8 ccb_; + UINT8 kbc_command_; + UINT8 st_; + UINT8 outb_; + BOOLEAN TwoByteCmd; + BOOLEAN DelaySendingDataCmd; + BOOLEAN fCcb_loaded; +}; + +void InitVirtualKBC(VIRTKBC* vkbc, PS2SINK* kbd, PS2SINK* mouse ); + +// +//Legacy KBC. Keep both _VIRTKBC and _LEGACYKBC synced up till DelaySendingDataCmd +// +typedef struct _LEGACYKBC LEGACYKBC; + +struct _LEGACYKBC { + KBC kbc_; + UINT8 ccb_; + UINT8 kbc_command_; + UINT8 st_; + UINT8 outb_; + BOOLEAN TwoByteCmd; + BOOLEAN DelaySendingDataCmd; + BOOLEAN fCcb_loaded; +}; +void InitLegacyKBC(LEGACYKBC* kbc, PS2SINK* kbd, PS2SINK* mouse ); + +// +//Virtual KBD & Legacy KBD +// + +typedef struct _VIRTKBD VIRTKBD; +typedef struct _VIRTKBD LEGACYKBD; + +#define KBDQUEUE_SIZE 10 + +typedef struct _VIRTKBD{ + PS2SINK sink; + + EFI_EMUL6064KBDINPUT_PROTOCOL kbdInput_; + + UINT8 queue[KBDQUEUE_SIZE]; + UINT8* qhead; + UINT8* qtail; + + + UINT8* option_ptr; + UINT8 read_code_action; + UINT8 typematicRateDelay; + UINT8 scancodepage; + BOOLEAN Enabled; +}; + +void InitVirtualKbd(KBC* , VIRTKBD* ); +void InitLegacyKbd(KBC* , LEGACYKBD* ); + +// +//Virtual Mouse & Legacy Mouse +// + +#define MOUSE_PACKET_SIZE 3 + +typedef struct _VIRTMOUSE VIRTMOUSE; +typedef struct _VIRTMOUSE LEGACYMOUSE; + + +#define MOUSEQUEUE_SIZE 12 + +typedef struct _VIRTMOUSE{ + PS2SINK sink; + + EFI_EMUL6064MSINPUT_PROTOCOL msInput_; + + UINT8 queue[MOUSEQUEUE_SIZE]; + UINT8* qhead; + UINT8* qtail; + + UINT8* option_ptr; + UINT8 samplingRate_; + UINT8 resolution_; + + int x, y; + int fFreshPacket; + BOOLEAN Enabled; + int streaming; + PS2MouseData dataPacket; +}; + +void InitVirtualMouse(KBC* kbc, VIRTMOUSE* mouse ); +void InitLegacyMouse(KBC* kbc, LEGACYMOUSE* mouse ); + + +#endif // __INC_VKBC_H__ + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/KbcEmul/KbcEmul.c b/Core/EM/KbcEmul/KbcEmul.c new file mode 100644 index 0000000..ddcd165 --- /dev/null +++ b/Core/EM/KbcEmul/KbcEmul.c @@ -0,0 +1,481 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmul.c 14 12/04/14 12:49a Rajeshms $ +// +// $Revision: 14 $ +// +// $Date: 12/04/14 12:49a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmul.c $ +// +// 14 12/04/14 12:49a Rajeshms +// [TAG] EIP193601 +// [Category] New Feature +// [Description] Aptio4.x - Security Enhancement for SMIHandler in +// KbcEmulation module, Checks if BAR address access is inside SMRAM, if +// yes, return. +// [Files] KbcEmul.mak, KbcEmul.c, KbcOhci.c +// +// 13 9/16/13 6:50a Srikantakumarp +// [TAG] EIP135441 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Option ROM was not getting dispatched in AMD Platforms +// [RootCause] Setting the IRQ1 in the Entry Point of the KbcEmulation +// Driver +// [Solution] Setting the IRQ1 only if KbcEmulation is Enabled +// [Files] KbcEmul.c +// +// 12 1/09/12 1:24a Rameshr +// [TAG] EIP74128 +// [Category] Improvement +// [Description] Disable the KbcEmulation Smi’s on ACPI enable and +// Disable SMI call +// [Files] Kbccore.c, KbcEmuulAcpi.c, KbcEmul.c, KbcEmul.cif, +// KbcEmul.h, KbcEmul.sdl +// +// 11 5/02/11 12:16a Rameshr +// [TAG] - EIP 58434 +// [Category]- BUG FIX +// [Severity]- Major +// [Symptom] - IRQ1 not enabled on LegacyFree(No KBC) system while booting +// to Legacy OS. +// [RootCause]- As there is no KBC, IRQ1 not used by system and it's not +// enabled. +// [Solution] - When the Emulation module enabled, IRQ1 is added to the +// used IRQ list.So it's enabled while booting to Legacy OS. +// [Files] - KbcEmul.c +// +// 10 4/11/11 2:46a Rameshr +// [TAG]- EIP 57436 +// [Category]-IMPROVEMENT +// [Description]- PI1.1 Support. +// [Files]- Ap4x.h, KbcEmul.c +// +// 9 2/10/11 12:57a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 8 7/08/10 1:57a Rameshr +// Ohci Emulation support Added. +// EIP 39712 +// +// 7 6/30/09 11:28a Rameshr +// Coding Standard and File header updated. +// +// 6 2/05/09 9:37a Rameshr +// Symptom : With Latest CSM Emulation doesn't work. +// Solution: Added Emulation enable code in outside SMM. This is called +// from Uhcd.c when ever USB mode changes to Legacy +// EIP:18730 +// +// 5 10/24/08 11:55a Rameshraju +// KBC presence done only based on 0xFF value. +// +// 3 8/11/08 12:33p Vasudevans +// +// 4 8/07/08 10:21a Rameshraju +// Removed the IRQ1 changes +// +// 3 7/08/08 11:09a Rameshraju +// IRQ1 unmasked. +// +// 2 12/27/07 4:53p Rameshraju +// Detect the KBC presence by reading port 64 +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//**************************************************************************** +// Name: KbcEmul.c +// +// Description: KBC emulation driver entry point and initilize the SMI for port 6064 +//**************************************************************************** +//<AMI_FHDR_END> + +#include "KbcEmul.h" +#include "Kbc.h" +#include "KbcDevEmul.h" +#ifdef FRAMEWORK_AP4 +#include "token.h" +#include "protocol/usbpolicy.h" +#else +#include "tokens.h" +#endif + +#include <AmiBufferValidationLib.h> + +extern EFI_GUID gEfiLoadedImageProtocolGuid; +extern EFI_GUID gEfiDevicePathProtocolGuid; +extern EFI_GUID gEfiSetupGuid; + + +EFI_CPU_IO_PROTOCOL *CpuIo; +KBC* gVirtualKBC = NULL; +void Emulation_Init(); +void Smm_Register(); + +// +//KBC Emulation TRAP protocol. +// +BOOLEAN Emulation6064TrapEnable(EFI_EMUL6064TRAP_PROTOCOL *This); +BOOLEAN Emulation6064TrapDisable(EFI_EMUL6064TRAP_PROTOCOL *This); +UINT32 KbcEmulationFeature (EFI_EMUL6064TRAP_PROTOCOL * This); +BOOLEAN NonSmmEmulation6064TrapEnable(EFI_EMUL6064TRAP_PROTOCOL *This); +BOOLEAN NonSmmEmulation6064TrapDisable(EFI_EMUL6064TRAP_PROTOCOL *This); + +EFI_EMUL6064TRAP_PROTOCOL Emulation6064Trap= { + Emulation6064TrapEnable, + Emulation6064TrapDisable, + KbcEmulationFeature +}; + +EFI_EMUL6064TRAP_PROTOCOL NonSmmEmulation6064Trap= { + NonSmmEmulation6064TrapEnable, + NonSmmEmulation6064TrapDisable, + KbcEmulationFeature +}; + +EFI_HANDLE EmulationTrapHandle=NULL; + + +EFI_DRIVER_ENTRY_POINT(EmulationEntryPoint) + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: EmulationEntryPoint +// +// Description: Entry point for Emulation driver. If the port 6064 emulation enabled by setup +// it enables the SMI event for port 6064 and install the Trap handle protocol. +// +// +// Input: Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT +// +// Output: Status: EFI_SUCCESS = Success +// EFI_ERROR = Failure +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +EmulationEntryPoint( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + EFI_STATUS Status = 0; + UINTN VariableSize; + BOOLEAN InSmm = 0; + USB_SUPPORT_SETUP SetupData; + + // + // Initialize the EFI Runtime Library + // + initializeLib(ImageHandle, SystemTable); + + + // + //Check the setup option, if the emulation disabled in setup return with EFI_SUCCESS + // + VariableSize = sizeof(USB_SUPPORT_SETUP); + Status = pRS->GetVariable( L"UsbSupport", &gEfiSetupGuid, NULL, &VariableSize, &SetupData ); + + if (EFI_ERROR(Status) || (SetupData.UsbEmul6064 == 0)) { + return EFI_SUCCESS; + } + + // + // Save the system table pointer + // + gSMM->GetSmstLocation (gSMM, &gSmst); + + // + // Find out whether we're in SMM + // + gSMM->InSmm (gSMM, &InSmm); + + if (!InSmm) { + EFI_HANDLE hSmmCode = NULL; + EFI_DEVICE_PATH_PROTOCOL *FilePath; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath; + + // + // Load this driver's image to memory + // + + Status = gBS->HandleProtocol( + ImageHandle, &gEfiLoadedImageProtocolGuid, &LoadedImage); + if (EFI_ERROR(Status)) return Status; + + Status = gBS->HandleProtocol( + LoadedImage->DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID*)&ImageDevicePath + ); + if (EFI_ERROR(Status)) return Status; + + Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, &CpuIo); + + if (EFI_ERROR(Status)) return Status; + + gBS->InstallProtocolInterface(&EmulationTrapHandle, + &gNonSmmEmul6064TrapProtocolGuid,EFI_NATIVE_INTERFACE,&NonSmmEmulation6064Trap); + + FilePath = AppendDevicePath( + ImageDevicePath, LoadedImage->FilePath + ); + + // + // Load the image in memory to SMRAM; it will automatically generate SMI. + // + Status = gSMM->Register(gSMM, FilePath, NULL, 0, &hSmmCode, FALSE); + }else { + // + // We're now in SMM, registering all USB SMM callback functions + // +#if OHCI_EMUL_SUPPORT + InitAmiBufferValidationLib(ImageHandle, SystemTable); +#endif + Emulation_Init(); + + gBS->InstallProtocolInterface(&EmulationTrapHandle, + &gEmul6064TrapProtocolGuid,EFI_NATIVE_INTERFACE,&Emulation6064Trap); + RegisterAcpiEnableCallBack(); + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Emulation_Init +// +// Description: Initilize the Keyboard Controller, Keyboard and Mouse device.Regsiter the SMI for port 6064 +// access. +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void Emulation_Init() +{ + static VIRTKBC VirtualKBC; + static VIRTMOUSE VirtualMouse; + static VIRTKBD VirtualKbd; + static LEGACYKBC LegacyKbc; + static LEGACYKBD LegacyKbd; + static LEGACYMOUSE LegacyMouse; + BOOLEAN KbcPresent=FALSE; + UINT8 port64 = IoRead8(0x64); + + + // + //Detect the KBC presence by reading port 64. + // + KbcPresent = ((port64==0xFF))? 0 : 1; + + if(KbcPresent) { + + gVirtualKBC = &LegacyKbc.kbc_; + + // + //Initialize the Legacy Mouse Device + // + InitLegacyMouse(gVirtualKBC,&LegacyMouse); + + // + //Initialize the Legacy Keyboard Device + // + InitLegacyKbd(gVirtualKBC,&LegacyKbd); + + // + //Initialize the Legacy Keyboard Controller + // + InitLegacyKBC(&LegacyKbc,&LegacyKbd.sink,&LegacyMouse.sink); + + + } else { + + gVirtualKBC = &VirtualKBC.kbc; + + // + //Initialize the Virtual Mouse Device + // + InitVirtualMouse(gVirtualKBC,&VirtualMouse); + + // + //Initialize the Virtual Keyboard Device + // + InitVirtualKbd(gVirtualKBC,&VirtualKbd); + + // + //Initialize the Virtual Keyboard Controller + // + InitVirtualKBC(&VirtualKBC,&VirtualKbd.sink,&VirtualMouse.sink); + + } + + // + // Hardware specific SMM registration + Smm_Register(); + + return; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Emulation6064TrapEnable +// +// Description: Enable the SMI source for port 6064 +// +// Input: None +// +// Output: TRUE/FALSE +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN +Emulation6064TrapEnable ( + EFI_EMUL6064TRAP_PROTOCOL * This + ) +{ + return TrapEnable(TRUE); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Emulation6064TrapDisable +// +// Description: Disable the SMI source for port 6064 +// +// Input: None +// +// Output: TRUE/FALSE +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN +Emulation6064TrapDisable ( + EFI_EMUL6064TRAP_PROTOCOL * This + ) +{ + return TrapEnable(FALSE); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmEmulation6064TrapEnable +// +// Description: Enable the SMI source for port 6064 in Non SMM +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN +NonSmmEmulation6064TrapEnable ( + EFI_EMUL6064TRAP_PROTOCOL * This + ) +{ + UINT16 IrqMask; + EFI_STATUS Status; + + // + // Reserve IRQ1 if the Emulation enabled + // + Status=AmiIsaIrqMask(&IrqMask, TRUE); + + if(Status==EFI_NOT_FOUND){ + IrqMask=ISA_IRQ_MASK; + IrqMask |= 2; + AmiIsaIrqMask(&IrqMask, FALSE); + } else { + IrqMask |= 2; + AmiIsaIrqMask(&IrqMask, FALSE); + } + + return NonSmmTrapEnable(TRUE); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmEmulation6064TrapDisable +// +// Description: Disable the SMI source for port 6064 in Non SMM +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN +NonSmmEmulation6064TrapDisable ( + EFI_EMUL6064TRAP_PROTOCOL * This + ) +{ + return NonSmmTrapEnable(FALSE); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: KbcEmulationFeature +// +// Description: Returns all the feature supported by Emulation +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT32 +KbcEmulationFeature ( + EFI_EMUL6064TRAP_PROTOCOL * This + ) +{ + UINT32 KbcEmulFeature=0; + +#if IRQ_EMUL_SUPPORT + KbcEmulFeature |= IRQ_SUPPORTED; +#endif + return KbcEmulFeature; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/KbcEmul/KbcEmul.cif b/Core/EM/KbcEmul/KbcEmul.cif new file mode 100644 index 0000000..11ac603 --- /dev/null +++ b/Core/EM/KbcEmul/KbcEmul.cif @@ -0,0 +1,31 @@ +<component> + name = "KbcEmulation" + category = eModule + LocalRoot = "core\em\KbcEmul" + RefName = "KbcEmul" +[files] +"KbcEmul.sdl" +"KbcEmul.mak" +"KbcEmul.dxs" +"KbcEmul.c" +"KbcEmul.h" +"KbcEmulLib.h" +"KbcEmulLib.c" +"KbcEmulAcpi.c" +"Kbc.h" +"KbcDevEmul.h" +"Kbccore.c" +"Legacykbc.c" +"Legacykbd.c" +"LegacyMouse.c" +"VirtualKbc.c" +"VirtualKbd.c" +"VirtualMouse.c" +"Ap4x.h" +"Ap4x.c" +"KbcEmulation.chm" +[parts] +"KbcUhci" +"KbcEmulIrq" +"KbcOhci" +<endComponent> diff --git a/Core/EM/KbcEmul/KbcEmul.dxs b/Core/EM/KbcEmul/KbcEmul.dxs new file mode 100644 index 0000000..d73952f --- /dev/null +++ b/Core/EM/KbcEmul/KbcEmul.dxs @@ -0,0 +1,71 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmul.dxs 3 2/10/11 12:56a Rameshr $ +// +// $Revision: 3 $ +// +// $Date: 2/10/11 12:56a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmul.dxs $ +// +// 3 2/10/11 12:56a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 2 6/30/09 11:27a Rameshr +// Coding Standard and File header updated. +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: KbcEmul.dxs +// +// Description: DXS file for the Kbc Emulation +// +//<AMI_FHDR_END> +//********************************************************************** +#include <Protocol/SmmBase.h> +#include <Protocol/SmmUsbDispatch.h> +#include <Protocol/PciRootBridgeIo.h> + +DEPENDENCY_START + EFI_SMM_BASE_PROTOCOL_GUID AND + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID AND + EFI_SMM_USB_DISPATCH_PROTOCOL_GUID +DEPENDENCY_END + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/KbcEmul/KbcEmul.h b/Core/EM/KbcEmul/KbcEmul.h new file mode 100644 index 0000000..59d6484 --- /dev/null +++ b/Core/EM/KbcEmul/KbcEmul.h @@ -0,0 +1,129 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmul.h 6 1/09/12 1:25a Rameshr $ +// +// $Revision: 6 $ +// +// $Date: 1/09/12 1:25a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmul.h $ +// +// 6 1/09/12 1:25a Rameshr +// [TAG] EIP74128 +// [Category] Improvement +// [Description] Disable the KbcEmulation Smi’s on ACPI enable and +// Disable SMI call +// [Files] Kbccore.c, KbcEmuulAcpi.c, KbcEmul.c, KbcEmul.cif, +// KbcEmul.h, KbcEmul.sdl +// +// 5 2/10/11 12:58a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 4 7/08/10 1:57a Rameshr +// Ohci Emulation support Added. +// EIP 39712 +// +// 3 6/30/09 11:28a Rameshr +// Coding Standard and File header updated. +// +// 2 2/05/09 9:38a Rameshr +// Symptom : With Latest CSM Emulation doesn't work. +// Solution: Added Emulation enable code in outside SMM. This is called +// from Uhcd.c when ever USB mode changes to Legacy +// EIP:18730 +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//**************************************************************************** +// Name: KbcEmul.h +// +// Description: KBC emulation header file +//**************************************************************************** +//<AMI_FHDR_END> + +#ifdef FRAMEWORK_AP4 +#include "Ap4x.h" +#include "token.h" +#else +#include "Ap3x.h" +#include "tokens.h" +#endif + +#include <protocol\devicepath.h> +#include <Protocol\Cpuio.h> + +initializeLib(IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable); + + +#define MAX_DEBUG_LEVEL 8 + +#define DEBUG_LEVEL_8 8 +#define DEBUG_LEVEL_7 7 +#define DEBUG_LEVEL_6 6 +#define DEBUG_LEVEL_5 5 +#define DEBUG_LEVEL_4 4 +#define DEBUG_LEVEL_3 3 +#define DEBUG_LEVEL_2 2 +#define DEBUG_LEVEL_1 1 +#define DEBUG_LEVEL_0 0 + + +typedef struct _HC_DEV_STRUC { + UINT16 wPCIDev; + UINT16 wHCType; +} HC_DEV_STRUC; + +extern EFI_SMM_SYSTEM_TABLE *gSmst; +extern EFI_CPU_IO_PROTOCOL *CpuIo; + +// +//Checks if Trap status is set +// +BOOLEAN hasTrapStatus(); +BOOLEAN TrapEnable(BOOLEAN ); +BOOLEAN NonSmmTrapEnable(BOOLEAN ); + +#if OHCI_EMUL_SUPPORT == 1 +void SetHceOutput (UINT8); +#endif + +EFI_STATUS +RegisterAcpiEnableCallBack(); + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/KbcEmul/KbcEmul.mak b/Core/EM/KbcEmul/KbcEmul.mak new file mode 100644 index 0000000..87c282e --- /dev/null +++ b/Core/EM/KbcEmul/KbcEmul.mak @@ -0,0 +1,197 @@ +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2013, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** +# $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmul.mak 10 12/04/14 12:50a Rajeshms $ +# +# $Revision: 10 $ +# +# $Date: 12/04/14 12:50a $ +# +#**************************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmul.mak $ +# +# 10 12/04/14 12:50a Rajeshms +# [TAG] EIP193601 +# [Category] New Feature +# [Description] Aptio4.x - Security Enhancement for SMIHandler in +# KbcEmulation module, Checks if BAR address access is inside SMRAM, if +# yes, return. +# [Files] KbcEmul.mak, KbcEmul.c, KbcOhci.c +# +# 9 9/16/13 6:53a Srikantakumarp +# [TAG] EIP136515 +# [Category] Bug Fix +# [Severity] Normal +# [Symptom] Build error in AMD platform when enabling Emul6064_Support +# [RootCause] OHCI_EMUL_LIB was not inluded while making KbcEmulBin +# [Solution] Added OHCI_EMUL_LIB while making KbcEmulBin +# [Files] KbcEmul.mak +# +# 8 5/13/13 2:48a Rameshr +# [TAG] EIP119870 +# [Category] Improvement +# [Description] Build error with KbcEmulation module if update USB +# module label 4.6.3_USB_08.10.26 +# [Files] KbcEmul.Mak, KbcEmul.SDl, KbcUhci.c, KbcUhci.h, KbcOhci.c +# +# 7 2/10/11 12:55a Rameshr +# [TAG] EIP53687 +# [Category] Improvement +# [Description] AMI headers update for KbcEmulation Module +# [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +# EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +# use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +# KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +# +# 6 7/08/10 1:59a Rameshr +# Ohci Emulation support Added. +# EIP 39712 +# +# 5 8/19/09 2:25p Rameshr +# Sb module component created to support SB porting for Emulation module. +# EIP:25184 +# +# 4 6/30/09 11:27a Rameshr +# Coding Standard and File header updated. +# +# 3 6/01/09 10:01a Rameshr +# Added Emulation Support for RMH enable/Disable +# EIP 21131 +# +# 2 12/27/07 6:45p Rameshraju +# +# 1 12/14/07 10:26a Rameshraju +# Initial Check-in +#**************************************************************************** + +#********************************************************************** +#<AMI_FHDR_START> +# +# Name: KbcEmul.mak +# +# Description: Mak file the KBC Emulation +# +#<AMI_FHDR_END> +#********************************************************************** +!if $(UHCI_EMUL_SUPPORT) +UHCI_EMUL = KbcUhci +UHCI_EMUL_LIB= $(BUILD_DIR)\KbcUhciEmulBin.lib +!else +UHCI_EMUL = +UHCI_EMUL_LIB= +!endif + +!if $(OHCI_EMUL_SUPPORT) +OHCI_EMUL = KbcOhci +OHCI_EMUL_LIB= $(BUILD_DIR)\KbcOhciEmulBin.lib $(BUILD_DIR)\AmiBufferValidationLib.lib +!else +OHCI_EMUL = +OHCI_EMUL_LIB= +!endif +!if $(IRQ_EMUL_SUPPORT) +IRQ_EMUL = KbcEmulIrq +IRQ_EMUL_LIB = $(BUILD_DIR)\KbcEmulIrq.lib +!else +IRQ_EMUL = +IRQ_EMUL_LIB = +!endif + +all: $(IRQ_EMUL) $(UHCI_EMUL) $(OHCI_EMUL) KbcEmul + +#----------------------------------------------------------------------- +# Build script for IRQ Based Eumlation +#----------------------------------------------------------------------- +KbcEmulIrq : $(BUILD_DIR)\KbcEmulIrq.mak $(BUILD_DIR)\KbcEmulIrq.lib + +$(BUILD_DIR)\KbcEmulIrq.mak : $(KBCEMUL_DIR)\KbcEmulIrq.cif $(KBCEMUL_DIR)\KbcEmul.mak $(BUILD_RULES) + $(CIF2MAK) $(KBCEMUL_DIR)\KbcEmulIrq.cif $(CIF2MAK_DEFAULTS) + +$(BUILD_DIR)\KbcEmulIrq.lib : $(AMIDXELIB) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + "CFLAGS=$(CFLAGS) /I$(KBCEMUL_DIR) /DFRAMEWORK_AP4"\ + /f $(BUILD_DIR)\KbcEmulIrq.mak all\ + TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\KbcEmulIrq.lib + +#----------------------------------------------------------------------- +# Build script for Uhci Based Eumlation +#----------------------------------------------------------------------- +KbcUhci : $(BUILD_DIR)\KbcUhci.mak $(BUILD_DIR)\KbcUhciEmulBin.lib + +$(BUILD_DIR)\KbcUhci.mak : $(KBCEMUL_DIR)\KbcUhci.cif $(KBCEMUL_DIR)\KbcEmul.mak $(BUILD_RULES) + $(CIF2MAK) $(KBCEMUL_DIR)\KbcUhci.cif $(CIF2MAK_DEFAULTS) + +$(BUILD_DIR)\KbcUhciEmulBin.lib : $(AMIDXELIB) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + "CFLAGS=$(CFLAGS) /I$(KBCEMUL_DIR) /DFRAMEWORK_AP4"\ + /f $(BUILD_DIR)\KbcUhci.mak all\ + TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\KbcUhciEmulBin.lib + +#----------------------------------------------------------------------- +# Build script for Ohci Based Eumlation +#----------------------------------------------------------------------- +KbcOhci : $(BUILD_DIR)\KbcOhci.mak $(BUILD_DIR)\KbcOhciEmulBin.lib + +$(BUILD_DIR)\KbcOhci.mak : $(KBCEMUL_DIR)\KbcOhci.cif $(KBCEMUL_DIR)\KbcEmul.mak $(BUILD_RULES) + $(CIF2MAK) $(KBCEMUL_DIR)\KbcOhci.cif $(CIF2MAK_DEFAULTS) + +$(BUILD_DIR)\KbcOhciEmulBin.lib : $(AMIDXELIB) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + "CFLAGS=$(CFLAGS) /I$(KBCEMUL_DIR) /DFRAMEWORK_AP4"\ + /f $(BUILD_DIR)\KbcOhci.mak all\ + TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\KbcOhciEmulBin.lib + + +#----------------------------------------------------------------------- +# Build script for KBC Emulation +#----------------------------------------------------------------------- +KbcEmul : $(BUILD_DIR)\KbcEmul.mak KbcEmulBin + +$(BUILD_DIR)\KbcEmul.mak : $(KBCEMUL_DIR)\$(@B).cif $(KBCEMUL_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(KBCEMUL_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +$(BUILD_DIR)\KbcEmul.lib : $(BUILD_DIR)\debug.obj $(BUILD_DIR)\guids.obj + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\KbcEmul.mak all\ + "CFLAGS=$(CFLAGS) /I$(KBCEMUL_DIR) /DFRAMEWORK_AP4"\ + TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\KbcEmul.lib + +KbcEmulBin : $(AMIDXELIB) $(UHCI_EMUL_LIB) $(OHCI_EMUL_LIB) $(IRQ_EMUL_LIB) $(BUILD_DIR)\KbcEmul.lib + @set INCLUDE=%%INCLUDE%% + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\KbcEmul.mak all\ + GUID=3b24f79d-91a0-46ff-be29-458ae211fac5 \ + ENTRY_POINT=EmulationEntryPoint \ + "CFLAGS=$(CFLAGS) /I$(KBCEMUL_DIR) /DFRAMEWORK_AP4"\ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ + "EXT_HEADERS=$(EXT_HEADERS)"\ + TYPE=BS_DRIVER \ + COMPRESS=1\ + DEPEX1=$(KBCEMUL_DIR)\KbcEmul.dxs \ + +IMAGE_ENTRY_POINT = EmulationEntryPoint + +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2013, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** diff --git a/Core/EM/KbcEmul/KbcEmul.sdl b/Core/EM/KbcEmul/KbcEmul.sdl new file mode 100644 index 0000000..996e149 --- /dev/null +++ b/Core/EM/KbcEmul/KbcEmul.sdl @@ -0,0 +1,102 @@ +TOKEN + Name = "EMUL6064_SUPPORT" + Value = "1" + Help = "Main switch to enable KBC Emulation support in Project" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes + Master = Yes + Token = "AMIUSB_SUPPORT" "=" "1" +End + +PATH + Name = "KBCEMUL_DIR" +End + +PATH + Name = "KBC_SB_BOARD_DIR" + Path = "Board\Em\KbcSbBoard\" +End + +MODULE + Help = "Includes Emul6064.mak into project" + File = "KbcEmul.mak" +End + +TOKEN + Name = "UHCI_EMUL_SUPPORT" + Value = "1" + Help = "Switch to enable UHCI based Emulation support in Project" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "UHCI_EMUL_PCI_DEVICES" + Help = "List of supported UHCI controllers in the following format: {dev1, ITF, SCC, BCC, offset}, {dev2, ITF, SCC, BCC, offset},...,{devN, ITF, SCC, BCC, offset}\dev represents the location of UHCI controller on PCI bus: dev = Bus << 8 + Dev << 3 + Func.\ITF represents the interface type of PCI device, for UHCI it must be 0.\SCC represents the sub class code of PCI device, for UHCI it must be 0x03.\BCC represents the base class code of PCI device, for UHCI it must be 0x0C.\offset represents the offset of legacy support register, for UHCI it must be 0xC0." + TokenType = Expression + TargetH = Yes + Token = "UHCI_EMUL_SUPPORT" "=" "1" +End + +TOKEN + Name = "OHCI_EMUL_SUPPORT" + Value = "0" + Help = "Switch to enable OHCI based Emulation support in Project" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "OHCI_EMUL_PCI_DEVICES" + Help = "List of supported OHCI controllers in the following format: {type1, dev1, addr1}, {type2, dev2, addr2},...,{typeN, devN, addrN}\type represents the device type of emulation device is PceDevice or FixedMemory.\dev represents the location of OHCI controller on PCI bus: dev = Bus << 8 + Dev << 3 + Func.\addr represents the address of emulation registers if type is FixedMemory." + TokenType = Expression + TargetH = Yes + Token = "OHCI_EMUL_SUPPORT" "=" "1" +End + +TOKEN + Name = "ICH10_WORKAROUND" + Value = "0" + Help = "Switch to enable ICH10 Workaround. Emulation enabled and one of the USB controller disabled, We must clear the SMI status on disabled USB controller also" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "IRQ_EMUL_SUPPORT" + Value = "1" + Help = "Switch to enable software method of IRQ generation in Project" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "SW_IRQ_GENERATION_REG" + Value = "$(PM_BASE_ADDRESS)+0x70" + Help = "Software IRQ generation regsiter from SB to generate the IRQ12 and IRQ1." + TokenType = Integer + TargetH = Yes + Token = "IRQ_EMUL_SUPPORT" "=" "1" + Token = "UHCI_EMUL_SUPPORT" "=" "1" +End + +TOKEN + Name = "EMULATION_ACPI_ENABLE_DISPATCH" + Value = "0" + Help = "1-Emulation SMI's will be disabled in the USB controller." + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +ELINK + Name = "$(BUILD_DIR)\KbcEmul.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + diff --git a/Core/EM/KbcEmul/KbcEmulAcpi.c b/Core/EM/KbcEmul/KbcEmulAcpi.c new file mode 100644 index 0000000..c926707 --- /dev/null +++ b/Core/EM/KbcEmul/KbcEmulAcpi.c @@ -0,0 +1,156 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmulAcpi.c 2 4/10/14 2:28a Rameshr $ +// +// $Revision: 2 $ +// +// $Date: 4/10/14 2:28a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmulAcpi.c $ +// +// 2 4/10/14 2:28a Rameshr +// [TAG] EIP160392 +// [Category] Improvement +// [Description] Junk Character from check-in History removed. +// [Files] KbcEmulAcpi.c +// +// 1 1/09/12 1:22a Rameshr +// [TAG] EIP74128 +// [Category] Improvement +// [Description] Disable the KbcEmulation Smis on ACPI enable and +// Disable SMI call +// [Files] Kbccore.c, KbcEmuulAcpi.c, KbcEmul.c, KbcEmul.cif, +// KbcEmul.h, KbcEmul.sdl +// +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: KbcEmulAcpi.c +// +// Description: This file contains Emulation SMI disable function on ACPI +// enable/Disable SMI +// +//<AMI_FHDR_END> +//************************************************************************* + +//---------------------------------------------------------------------------- +// Include(s) +//---------------------------------------------------------------------------- + +#include <Token.h> +#include <AmiDxeLib.h> +#include <AmiCspLib.h> +#include <Protocol\SmmSwDispatch.h> +#include "KbcEmul.h" + +#ifdef EMULATION_ACPI_ENABLE_DISPATCH +#include <Chipset\SB\AcpiModeEnable.h> +EFI_GUID gEfiAcpiEnDispatchProtocolGuid = EFI_ACPI_EN_DISPATCH_PROTOCOL_GUID; +EFI_GUID gEfiAcpiDisDispatchProtocolGuid = EFI_ACPI_DIS_DISPATCH_PROTOCOL_GUID; +#endif + +extern BOOLEAN AcpiEmulationDisable; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: KbcEmulationDisable +// +// Description: This routine will be called when ACPI enabled or disabled SMI happens. +// +// Input: DispatchHandle - Handle to the Dispatcher +// +// Output: None +// +// Notes: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID KbcEmulationDisable ( + IN EFI_HANDLE DispatchHandle +) +{ + AcpiEmulationDisable=TRUE; + TrapEnable(FALSE); + return; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RegisterAcpiEnableCallBack +// +// Description: This routine will be called by KbcEmulation Init +// to register the callback function on Acpi Enable/Disable SMI. +// +// Input: None +// +// Output: None +// +// Notes: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS +RegisterAcpiEnableCallBack( +) +{ +#ifdef EMULATION_ACPI_ENABLE_DISPATCH + EFI_STATUS Status; + EFI_HANDLE EnableHandle; + EFI_HANDLE DisableHandle; + EFI_ACPI_DISPATCH_PROTOCOL *AcpiEnDispatch; + EFI_ACPI_DISPATCH_PROTOCOL *AcpiDisDispatch; + + Status = pBS->LocateProtocol(&gEfiAcpiEnDispatchProtocolGuid, NULL, &AcpiEnDispatch); + if (EFI_ERROR(Status)) { + return Status; + } + + Status = AcpiEnDispatch->Register(AcpiEnDispatch, KbcEmulationDisable, &EnableHandle); + ASSERT_EFI_ERROR(Status); + + Status = pBS->LocateProtocol(&gEfiAcpiDisDispatchProtocolGuid, NULL, &AcpiDisDispatch); + if (EFI_ERROR(Status)) { + return Status; + } + + Status = AcpiDisDispatch->Register(AcpiDisDispatch, KbcEmulationDisable, &DisableHandle); + ASSERT_EFI_ERROR(Status); + + return Status; +#else + return EFI_SUCCESS; +#endif +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Core/EM/KbcEmul/KbcEmulIrq.c b/Core/EM/KbcEmul/KbcEmulIrq.c new file mode 100644 index 0000000..f43cbcc --- /dev/null +++ b/Core/EM/KbcEmul/KbcEmulIrq.c @@ -0,0 +1,178 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmulIrq.c 5 2/10/11 1:13a Rameshr $ +// +// $Revision: 5 $ +// +// $Date: 2/10/11 1:13a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmulIrq.c $ +// +// 5 2/10/11 1:13a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 4 7/08/10 2:00a Rameshr +// Ohci Emulation support Added. +// EIP 39712 +// +// 3 6/30/09 11:37a Rameshr +// Coding Standard and File header updated. +// +// 2 8/07/08 10:20a Rameshraju +// IRQ1 enabled before generating IRQ1 +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//**************************************************************************** +// Name: KbcEmulIrq.c +// +// Description: Handles the IRQ1 and IRQ12 generation +// +//**************************************************************************** +//<AMI_FHDR_END> + +#ifdef FRAMEWORK_AP4 +#include "token.h" +#else +#include "tokens.h" +#endif +#include "KbcEmul.h" +#include "KbcEmulLib.h" +#include "KbcDevEmul.h" +#if OHCI_EMUL_SUPPORT +#include "KbcOhci.h" +#endif + +VOID GenerateIRQ12(VIRTKBC*); +VOID GenerateIRQ1(VIRTKBC*); + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GenerateIRQ12 +// +// Description: Generate IRQ1 +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID +GenerateIRQ12(VIRTKBC* vkbc) +{ + +#if UHCI_EMUL_SUPPORT + UINT8 Value8; + + Value8=ByteReadIO(SW_IRQ_GENERATION_REG); + ByteWriteIO(SW_IRQ_GENERATION_REG, 0); + ByteWriteIO(SW_IRQ_GENERATION_REG, 2); + return; + +#else + + if (GetHceStatus() & HCE_STS_OUTPUTFULL ){ + SetHceControl((GetHceControl() | HCE_CNTRL_IRQ_ENABLE)); + } else { + SetHceStatus((GetHceStatus() | HCE_STS_OUTPUTFULL | HCE_STS_AUXOUTPUTFULL)); + SetHceControl((GetHceControl() | HCE_CNTRL_IRQ_ENABLE)); + } + return; +#endif + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GenerateIRQ1 +// +// Description: Generate IRQ1 +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID +GenerateIRQ1(VIRTKBC* vkbc) +{ + +#if UHCI_EMUL_SUPPORT + UINT8 Value8; + UINT8 IrqMask; + + // + //Enable IRQ1 before generating the IRQ1. + // + IrqMask = ByteReadIO(0x21); + if (IrqMask & 0x02) { + IrqMask &= 0xFD; + ByteWriteIO (0x21, IrqMask); + } + + Value8=ByteReadIO(SW_IRQ_GENERATION_REG); + ByteWriteIO(SW_IRQ_GENERATION_REG, 0); + ByteWriteIO(SW_IRQ_GENERATION_REG, 1); + return; + +#else + UINT8 IrqMask; + // + //Enable IRQ1 before generating the IRQ1. + // + IrqMask = ByteReadIO(0x21); + if (IrqMask & 0x02) { + IrqMask &= 0xFD; + ByteWriteIO (0x21, IrqMask); + } + + if (GetHceStatus() & HCE_STS_OUTPUTFULL ){ + SetHceControl((GetHceControl() | HCE_CNTRL_IRQ_ENABLE)); + } else { + vkbc->st_ |= KBC_STATUS_OBF; + SetHceStatus((GetHceStatus() | KBC_STATUS_OBF)); + SetHceControl((GetHceControl() | HCE_CNTRL_IRQ_ENABLE)); + } + return; +#endif + +} + +//**************************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/KbcEmul/KbcEmulIrq.cif b/Core/EM/KbcEmul/KbcEmulIrq.cif new file mode 100644 index 0000000..6a5fe4c --- /dev/null +++ b/Core/EM/KbcEmul/KbcEmulIrq.cif @@ -0,0 +1,8 @@ +<component> + name = "KbcEmulIrq" + category = ModulePart + LocalRoot = "core\em\KbcEmul" + RefName = "KbcEmulIrq" +[files] +"KbcEmulIrq.c" +<endComponent> diff --git a/Core/EM/KbcEmul/KbcEmulLib.c b/Core/EM/KbcEmul/KbcEmulLib.c new file mode 100644 index 0000000..8e84535 --- /dev/null +++ b/Core/EM/KbcEmul/KbcEmulLib.c @@ -0,0 +1,572 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmulLib.c 4 2/10/11 1:00a Rameshr $ +// +// $Revision: 4 $ +// +// $Date: 2/10/11 1:00a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmulLib.c $ +// +// 4 2/10/11 1:00a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 3 6/30/09 11:29a Rameshr +// Coding Standard and File header updated. +// +// 2 2/05/09 9:40a Rameshr +// Symptom : With Latest CSM Emulation doesn't work. +// Solution: Added Emulation enable code in outside SMM. This is called +// from Uhcd.c when ever USB mode changes to Legacy +// EIP:18730 +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//********************************************************************** +// Name: KbcEmullib.c +// +// Description: KBC emulation lib file that used in other files +// +//********************************************************************** +//<AMI_FHDR_END> + +#include "KbcEmul.h" +#include "KbcEmulLib.h" + +UINT16 WritePCIConfig(UINT16, UINT8); + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ByteReadIO +// +// Description: This routine reads a Byte from the specified IO address +// +// Input: wIOAddr I/O address to read +// +// Output: Value read +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT8 +ByteReadIO(UINT16 wIOAddr) +{ + UINT8 value; + gSmst->SmmIo.Io.Read(&gSmst->SmmIo, SMM_IO_UINT8, (UINT64)wIOAddr, 1, &value); + return value; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ByteWriteIO +// +// Description: This routine writes a byte to the specified IO address +// +// Input: wIOAddr I/O address to write +// bValue Byte value to write +// +// Output: None +// +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +void +ByteWriteIO (UINT16 wIOAddr, UINT8 bValue) +{ + gSmst->SmmIo.Io.Write(&gSmst->SmmIo, SMM_IO_UINT8, (UINT64)wIOAddr, 1, &bValue); +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: WordReadIO +// +// Description: This routine reads a Word from the specified IO address +// +// Input: wIOAddr I/O address to read +// +// Output: Value read +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT16 +WordReadIO(UINT16 wIOAddr) +{ + UINT16 value; + gSmst->SmmIo.Io.Read(&gSmst->SmmIo, SMM_IO_UINT16, (UINT64)wIOAddr, 1, &value); + return value; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: WordWriteIO +// +// Description: This routine writes a word to the specified IO address +// +// Input: wIOAddr I/O address to write +// wValue Word value to write +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +void +WordWriteIO (UINT16 wIOAddr, UINT16 wValue) +{ + gSmst->SmmIo.Io.Write(&gSmst->SmmIo, SMM_IO_UINT16, (UINT64)wIOAddr, 1, &wValue); +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DwordReadIO +// +// Description: This routine reads a dword from the specified IO address +// +// Input: wIOAddr I/O address to read +// +// Output: Value read +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT32 +DwordReadIO(UINT16 wIOAddr) +{ + UINT32 value; + gSmst->SmmIo.Io.Read(&gSmst->SmmIo, SMM_IO_UINT32, (UINT64)wIOAddr, 1, &value); + return value; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DwordWriteIO +// +// Description: This routine writes a double word to the specified IO address +// +// Input: wIOAddr I/O address to write +// dValue Double word value to write +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +void +DwordWriteIO(UINT16 wIOAddr, UINT32 dValue) +{ + gSmst->SmmIo.Io.Write(&gSmst->SmmIo, SMM_IO_UINT32, (UINT64)wIOAddr, 1, &dValue); +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ReadPCIConfig +// +// Description: This routine reads from the PCI configuration space register +// the value can be typecasted to 8bits - 32bits +// +// Input: BusDevFunc - Bus, device & function number of the PCI device +// Register - Register offset to read +// +// Output: Value read +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT32 +ReadPCIConfig(UINT16 BusDevFunc, UINT8 Register) +{ + UINT32 data; + DwordWriteIO(0xCF8, (UINT32)(0x80000000 | (BusDevFunc<<8) | (Register & 0xFC))); + data = DwordReadIO(0xCFC); + return (data >> ((Register & 3) << 3)); // Adjust uneven register + +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ByteWritePCIConfig +// +// Description: This routine writes a byte value to the PCI configuration +// register space +// +// Input: BusDevFunc - Bus, device & function number of the PCI device +// Register - Register offset to read +// Value - Value to write +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +void +ByteWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT8 Value) +{ + UINT16 wIOAddr; + wIOAddr = WritePCIConfig(BusDevFunc, Register); + ByteWriteIO (wIOAddr, Value); +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: WordWritePCIConfig +// +// Description: This routine writes a byte value to the PCI configuration +// register space +// +// Input: BusDevFunc - Bus, device & function number of the PCI device +// Register - Register offset to read +// Value - Value to write +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +void +WordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT16 Value) +{ + UINT16 wIOAddr; + wIOAddr = WritePCIConfig(BusDevFunc, Register); + WordWriteIO (wIOAddr, Value); +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DwordWritePCIConfig +// +// Description: This routine writes a Dword value to the PCI configuration +// register space +// +// Input: BusDevFunc - Bus, device & function number of the PCI device +// Register - Register offset to read +// Value - Value to write +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +void +DwordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT32 Value) +{ + UINT16 wIOAddr; + wIOAddr = WritePCIConfig(BusDevFunc, Register); + DwordWriteIO (wIOAddr, Value); +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: WritePCIConfig +// +// Description: This function opens PCI configuration for a given register +// +// Input: wBDF - Bus, device and function number +// bReg - Register number to read +// +// Output: IO register to write the value +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT16 +WritePCIConfig(UINT16 wBDF, UINT8 bReg) +{ + DwordWriteIO(0xCF8, (UINT32)(0x80000000 | (wBDF<<8) | (bReg & 0xFC))); + return (UINT16)(0xCFC+(bReg & 3)); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmByteReadIO +// +// Description: This routine reads a Byte from the specified IO address +// +// Input: wIOAddr I/O address to read +// +// Output: Value read +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT8 +NonSmmByteReadIO(UINT16 wIOAddr) +{ + UINT8 value; + CpuIo->Io.Read(CpuIo, EfiCpuIoWidthUint8, wIOAddr, 1, &value); + return value; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmByteWriteIO +// +// Description: This routine writes a byte to the specified IO address +// +// Input: wIOAddr I/O address to write +// bValue Byte value to write +// +// Output: None +// +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +void +NonSmmByteWriteIO (UINT16 wIOAddr, UINT8 bValue) +{ + CpuIo->Io.Write(CpuIo, EfiCpuIoWidthUint8, wIOAddr, 1, &bValue); +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmWordReadIO +// +// Description: This routine reads a Word from the specified IO address +// +// Input: wIOAddr I/O address to read +// +// Output: Value read +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT16 +NonSmmWordReadIO(UINT16 wIOAddr) +{ + UINT16 value; + CpuIo->Io.Read(CpuIo, EfiCpuIoWidthUint16, wIOAddr, 1, &value); + return value; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmWordWriteIO +// +// Description: This routine writes a word to the specified IO address +// +// Input: wIOAddr I/O address to write +// wValue Word value to write +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +void +NonSmmWordWriteIO (UINT16 wIOAddr, UINT16 wValue) +{ + CpuIo->Io.Write(CpuIo, EfiCpuIoWidthUint16, wIOAddr, 1, &wValue); +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmDwordReadIO +// +// Description: This routine reads a dword from the specified IO address +// +// Input: wIOAddr I/O address to read +// +// Output: Value read +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT32 +NonSmmDwordReadIO(UINT16 wIOAddr) +{ + UINT32 value; + CpuIo->Io.Read(CpuIo, EfiCpuIoWidthUint32, wIOAddr, 1, &value); + return value; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmDwordWriteIO +// +// Description: This routine writes a double word to the specified IO address +// +// Input: wIOAddr I/O address to write +// dValue Double word value to write +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +void +NonSmmDwordWriteIO(UINT16 wIOAddr, UINT32 dValue) +{ + CpuIo->Io.Write(CpuIo, EfiCpuIoWidthUint32, wIOAddr, 1, &dValue); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmWritePCIConfig +// +// Description: This function opens PCI configuration for a given register +// +// Input: wBDF - Bus, device and function number +// bReg - Register number to read +// +// Output: IO register to write the value +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT16 +NonSmmWritePCIConfig(UINT16 wBDF, UINT8 bReg) +{ + NonSmmDwordWriteIO(0xCF8, (UINT32)(0x80000000 | (wBDF<<8) | (bReg & 0xFC))); + return (UINT16)(0xCFC+(bReg & 3)); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmReadPCIConfig +// +// Description: This routine reads from the PCI configuration space register +// the value can be typecasted to 8bits - 32bits +// +// Input: BusDevFunc - Bus, device & function number of the PCI device +// Register - Register offset to read +// +// Output: Value read +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT32 +NonSmmReadPCIConfig(UINT16 BusDevFunc, UINT8 Register) +{ + UINT32 data; + NonSmmDwordWriteIO(0xCF8, (UINT32)(0x80000000 | (BusDevFunc<<8) | (Register & 0xFC))); + data = NonSmmDwordReadIO(0xCFC); + return (data >> ((Register & 3) << 3)); // Adjust uneven register + +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmByteWritePCIConfig +// +// Description: This routine writes a byte value to the PCI configuration +// register space +// +// Input: BusDevFunc - Bus, device & function number of the PCI device +// Register - Register offset to read +// Value - Value to write +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +void +NonSmmByteWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT8 Value) +{ + UINT16 wIOAddr; + wIOAddr = NonSmmWritePCIConfig(BusDevFunc, Register); + NonSmmByteWriteIO (wIOAddr, Value); +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmWordWritePCIConfig +// +// Description: This routine writes a word value to the PCI configuration +// register space +// +// Input: BusDevFunc - Bus, device & function number of the PCI device +// Register - Register offset to write +// Value - Value to write +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +void +NonSmmWordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT16 Value) +{ + UINT16 wIOAddr; + wIOAddr = NonSmmWritePCIConfig(BusDevFunc, Register); + NonSmmWordWriteIO (wIOAddr, Value); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmDwordWritePCIConfig +// +// Description: This routine writes a Dword value to the PCI configuration +// register space +// +// Input: BusDevFunc - Bus, device & function number of the PCI device +// Register - Register offset to read +// Value - Value to write +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +void +NonSmmDwordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT32 Value) +{ + UINT16 wIOAddr; + wIOAddr = NonSmmWritePCIConfig(BusDevFunc, Register); + NonSmmDwordWriteIO (wIOAddr, Value); +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/KbcEmul/KbcEmulLib.h b/Core/EM/KbcEmul/KbcEmulLib.h new file mode 100644 index 0000000..edd5a4e --- /dev/null +++ b/Core/EM/KbcEmul/KbcEmulLib.h @@ -0,0 +1,96 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmulLib.h 4 2/10/11 12:59a Rameshr $ +// +// $Revision: 4 $ +// +// $Date: 2/10/11 12:59a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmulLib.h $ +// +// 4 2/10/11 12:59a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 3 6/30/09 11:29a Rameshr +// Coding Standard and File header updated. +// +// 2 2/05/09 9:41a Rameshr +// Symptom : With Latest CSM Emulation doesn't work. +// Solution: Added Emulation enable code in outside SMM. This is called +// from Uhcd.c when ever USB mode changes to Legacy +// EIP:18730 +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//********************************************************************** +// Name: KbcEmullib.h +// +// Description: KBC emulation Lib header file used in other files +// +//********************************************************************** +//<AMI_FHDR_END> + +#ifndef _EMUL6064LIB_H_INC_ + +UINT8 ByteReadIO(UINT16 wIOAddr); +void ByteWriteIO (UINT16 wIOAddr, UINT8 bValue); +UINT16 WordReadIO(UINT16 wIOAddr); +void WordWriteIO (UINT16 wIOAddr, UINT16 wValue); +UINT32 DwordReadIO(UINT16 wIOAddr); +void DwordWriteIO(UINT16 wIOAddr, UINT32 dValue); +UINT32 ReadPCIConfig(UINT16 BusDevFunc, UINT8 Register); +void ByteWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT8 Value); +void WordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT16 Value); +void DwordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT32 Value); +UINT32 ReadPCIConfig(UINT16 BusDevFunc, UINT8 Register); + +UINT8 NonSmmByteReadIO(UINT16 wIOAddr); +void NonSmmByteWriteIO (UINT16 wIOAddr, UINT8 bValue); +UINT16 NonSmmWordReadIO(UINT16 wIOAddr); +void NonSmmWordWriteIO (UINT16 wIOAddr, UINT16 wValue); +UINT32 NonSmmDwordReadIO(UINT16 wIOAddr); +void NonSmmDwordWriteIO(UINT16 wIOAddr, UINT32 dValue); +UINT32 NonSmmReadPCIConfig(UINT16 BusDevFunc, UINT8 Register); +void NonSmmByteWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT8 Value); +void NonSmmWordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT16 Value); +void NonSmmDwordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT32 Value); +UINT32 NonSmmReadPCIConfig(UINT16 BusDevFunc, UINT8 Register); + +#endif + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/KbcEmul/KbcEmulation.chm b/Core/EM/KbcEmul/KbcEmulation.chm Binary files differnew file mode 100644 index 0000000..c229519 --- /dev/null +++ b/Core/EM/KbcEmul/KbcEmulation.chm diff --git a/Core/EM/KbcEmul/KbcOhci.c b/Core/EM/KbcEmul/KbcOhci.c new file mode 100644 index 0000000..05f82b3 --- /dev/null +++ b/Core/EM/KbcEmul/KbcOhci.c @@ -0,0 +1,1051 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcOhci.c 7 12/04/14 12:51a Rajeshms $ +// +// $Revision: 7 $ +// +// $Date: 12/04/14 12:51a $ +// +//*********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcOhci.c $ +// +// 7 12/04/14 12:51a Rajeshms +// [TAG] EIP193601 +// [Category] New Feature +// [Description] Aptio4.x - Security Enhancement for SMIHandler in +// KbcEmulation module, Checks if BAR address access is inside SMRAM, if +// yes, return. +// [Files] KbcEmul.mak, KbcEmul.c, KbcOhci.c +// +// 6 12/05/13 12:46a Srikantakumarp +// [TAG] EIP145881 +// [Category] Improvement +// [Description] Ohci Emulation support needs to be extended for the +// chipset , where the HCE registers defined in some fixed Memory for +// Aptio 4.x +// [Files] KbcEmul.sdl, KbcOhci.c, KbcOhci.h +// +// 5 5/13/13 2:52a Rameshr +// [TAG] EIP119870 +// [Category] Improvement +// [Description] Build error with KbcEmulation module if update USB +// module label 4.6.3_USB_08.10.26 +// [Files] KbcEmul.Mak, KbcEmul.SDl, KbcUhci.c, KbcUhci.h, KbcOhci.c +// +// 4 2/02/12 12:36a Rameshr +// [TAG] EIP80605 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] It can not boot to DOS, If to disable 1st TOKEN report OHCI +// by setup on legacy free system(must add KBC Emulation module). +// [RootCause] gOHCIBar gets value from disabled controller and its not +// valid value +// [Solution] Added condition to check to have valid value in gOHCIBar +// [Files] KbcOhci.c +// +// 3 7/14/11 12:28a Rameshr +// [TAG] - EIP 62672 +// [Category]- BUG FIX +// [Severity]- Minor +// [Symptom] - USB PEI (enable KBC emulation) can't boot from USB +// [RootCause]- KbcEmulation gets the wrong BAR address that was +// initilized by USB PEI driver +// [Solution] - Ohci Base address reading should be done after the PCIbus +// driver allocates the resource for the OHCI controller +// [Files] - KbcOhci.c +// +// 2 2/10/11 1:14a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 1 7/08/10 2:07a Rameshr +// Ohci Emulation support Added. +// EIP 39712 +// +// Initial Check-in +// +//********************************************************************** + +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: KbcOhci.c +// +// Description: Handles the SMI events for port 60/64 +// +//<AMI_FHDR_END> +//********************************************************************** + +#ifdef FRAMEWORK_AP4 +#include "token.h" +#else +#include "tokens.h" +#endif +#include "KbcEmul.h" +#include "KbcDevEmul.h" +#include "KbcOhci.h" +#include "KbcEmulLib.h" +#include "Kbc.h" + +#include <AmiBufferValidationLib.h> + +extern KBC* gVirtualKBC; + +//Carries the LEGKEY status information saved before enable/disable trapping from outside trap handler is +//performed; The saving of the status allows recovering legacy I/O accesss event in case when multiple +//sources are serviced at signle SMI# ( legacy I/O and USB keyboard interupt, for example) + +static BOOLEAN gInTrapHandler = FALSE; +BOOLEAN KBDDisabled = FALSE; + +OHCI_EMUL_DEVICE Ohci_Hc_Array[] = { OHCI_EMUL_PCI_DEVICES }; +UINTN Ohci_Hc_Array_Size = sizeof(Ohci_Hc_Array) / sizeof(Ohci_Hc_Array[0]); + +volatile OHCI_LEG_SUP_REGS *gLegSupRegs = NULL; + +void DisableLegKeyRegs(); +void trap64w(); +void trap60w(); +void trap64r(); +void trap60r(); +UINT8 GetHceInput(); +void SetHceOutput (UINT8 Data); +BOOLEAN KBC_WaitForOutputBufferToBeFilled(); +BOOLEAN CheckPS2KBDMouseIRQEnabled(); +void CheckNumberofResponseBytes (); +void WaitForOBFSMM(); +void SerialOutput (UINT8 Data); +BOOLEAN gClearCharacterPending = FALSE; +BOOLEAN MouseCmdInProgress = FALSE; + +// cmd, response, cmd, response ... 0 +UINT8 KBDCmdResponse[] = {0xF2, 3, 0xFF, 2, 0xF0, 1, 0xF3, 1, 0xF4, 1, 0xF5, 1, 0xF6, 1, 0xF7, 1, 0xF8, 1, 0xF9, 1, 0xFA, 1, 0xFB, 1, 0xFC, 1, 0xFD, 1, 0}; +UINT8 MouseCmdResponse[] = {0xFF, 3, 0xF2, 2, 0xE9, 4, 0xEb, 4, 0xE6, 1, 0xE7, 1, 0xE8, 1, 0xEA, 1, 0xEE, 1, 0xF0, 1, 0xF3, 1, 0xF4, 1, 0xF5, 1, 0}; +UINT8 ResponseBytes = 0; + +//status bits for SMI#, parenthesis is needed for ~ or other conversion +#define OHCI_TRAPBY_MASK (HCE_CNTRL_EMULATION_INTERRUPT) + +//enable bits for traps +#define OHCI_TRAPEN_MASK (HCE_CNTRL_EMULATION_ENABLE | HCE_CNTRL_EXT_IRQ_ENABLE) + +void Trap6064_Handler ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_USB_DISPATCH_CONTEXT * DispatchContext + ); + +void Trap6064_Handler_LegFree ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_USB_DISPATCH_CONTEXT * DispatchContext + ); + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Smm_Register +// +// Description: Enable the SMI for port 6064 access. +// +// Input: None +// +// Output: None +// +// Note : Called inside SMM +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void Smm_Register() +{ + EFI_SMM_USB_DISPATCH_CONTEXT context; + EFI_SMM_USB_DISPATCH_PROTOCOL* pDispatch; + EFI_HANDLE hDisp; + EFI_STATUS Status; + static FULL_USB_DEVICE_PATH hc_dp = USB1_1_DEVICE_PATH; + UINTN OhciCount; + + // + // Register the USB HW SMI handler + // + Status = gBS->LocateProtocol(&gEfiSmmUsbDispatchProtocolGuid, NULL, &pDispatch); + ASSERT_EFI_ERROR(Status); + + // + // SMI registration routines will install the handlers, set enable bit + // and clear status in PM IO space. + // + for( OhciCount = 0; OhciCount < Ohci_Hc_Array_Size; ++OhciCount ){ + hc_dp.pci.Device=(Ohci_Hc_Array[OhciCount].BusDevFunc >> 3); + hc_dp.pci.Function=(Ohci_Hc_Array[OhciCount].BusDevFunc & 07); + context.Type = UsbLegacy; + context.Device = (EFI_DEVICE_PATH_PROTOCOL *)&hc_dp; + if (IoRead8(0x64) == 0xFF) { + Status = pDispatch->Register(pDispatch,Trap6064_Handler_LegFree, &context, &hDisp); + } else { + Status = pDispatch->Register(pDispatch,Trap6064_Handler, &context, &hDisp); + } + } + + //The SMI source for the port6064 is disabled. it will be enabled when we are in legacy enviorment. + //EFI enviorment Emulation is Disabled. + DisableLegKeyRegs(); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DisableLegKeyRegs +// +// Description: Disable the port6064 SMI source based on the Trap enable mask. +// +// Input: None +// +// Output: None +// +// Note : Called inside SMM +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void DisableLegKeyRegs() +{ + + if (gLegSupRegs != NULL) { + gLegSupRegs->HceControl = 0; + } + + return; + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: HandleGA20Sequence +// +// Description: SMI triggered becauase of GA20 sequence change +// +// Input: None +// +// Output: None +// +// Note : Called inside SMM +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID HandleGA20Sequence() +{ + UINT8 Data; + + if (IoRead8(0x64) == 0xFF) { + // + //Legacy Free system. Handle it using PORT 92 + // + Data = GetHceInput(); + IoWrite8(0x92, (IoRead8(0x92) & 0xFD) | (Data & 0x2)); + SetHceControl(GetHceControl() & 0xFFFFFE3F | ((Data & 0x2) << 7)); + } + else { + // + //Legacy Free system. Handle it using PORT 92. Maybe need to be chnaged if KBC needs to be used. + // + Data = GetHceInput(); + IoWrite8(0x92, (IoRead8(0x92) & 0xFD) | (Data & 0x2)); + SetHceControl(GetHceControl() & 0xFFFFFE3F | ((Data & 0x2) << 7)); + } + ((VIRTKBC* )gVirtualKBC)->st_ = 0x1c; + + return; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Trap6064_Handler_LegFree +// +// Description: SMI handler to handle the 64write, 64read, 60 write and 60 read SMI. +// +// Input: DispatchHandle - EFI Handle +// DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT + +// Output: None +// +// Note : Called inside SMM +// Used only when KBC is NOT present on the system +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void Trap6064_Handler_LegFree ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_USB_DISPATCH_CONTEXT * DispatchContext + ) +{ + UINT8 LegacyStatus; + UINTN OhciCount; + volatile EFI_PHYSICAL_ADDRESS OHCIBar = 0; + VIRTKBD* kbd = (VIRTKBD*)gVirtualKBC->kbd_dev; + VIRTMOUSE* mouse = (VIRTMOUSE*)gVirtualKBC->mouse_dev; + + ((VIRTKBC* )gVirtualKBC)->DelaySendingDataCmd = FALSE; + + // + // check if gOHCIBar has a valid address + // + if (gLegSupRegs == NULL) { + for( OhciCount = 0; OhciCount < Ohci_Hc_Array_Size; ++OhciCount ){ + if (Ohci_Hc_Array[OhciCount].Type == PciDevice) { + OHCIBar = ReadPCIConfig( Ohci_Hc_Array[OhciCount].BusDevFunc, 0x10) ; + if (OHCIBar != 0xFFFFFFFF && OHCIBar != 0) { + gLegSupRegs = (OHCI_LEG_SUP_REGS*)((OHCIBar & 0xFFFFFF00) + OHCI_HCE_CONTROL); + break; + } + } else if (Ohci_Hc_Array[OhciCount].Type == FixedMemory) { + gLegSupRegs = (OHCI_LEG_SUP_REGS*)Ohci_Hc_Array[OhciCount].MemAddr; + break; + } + } + if (gLegSupRegs == NULL) { + return; + } else { + // Check if MMIO address space of Legacy Support registers resides in SMRAM region. If yes, don't proceed. + if( AmiValidateMemoryBuffer( (VOID*)gLegSupRegs, sizeof(OHCI_LEG_SUP_REGS) ) ) { + return; + } + } + } + + // + // Check emulation is enabled if not exit. + // + if ((GetHceControl() & (HCE_CNTRL_EMULATION_ENABLE | HCE_CNTRL_EMULATION_INTERRUPT)) != + (HCE_CNTRL_EMULATION_ENABLE | HCE_CNTRL_EMULATION_INTERRUPT)) { + return; + } + + LegacyStatus = GetHceStatus(); + + + // + // Set the variable that we are processing the Trap + // + gInTrapHandler = TRUE; + + // + // Disable Emulation ( in responce to i/o handler can try to access a real KBC) + // + SetHceControl(GetHceControl() & (~(HCE_CNTRL_EMULATION_ENABLE | HCE_CNTRL_IRQ_ENABLE))); + + // + // if Character Pending interrupt is enabled and OBF is not set, handle Port read 60 + // + if (GetHceControl() & HCE_CNTRL_CHARACTER_PENDING && !(LegacyStatus & HCE_STS_OUTPUTFULL)){ + trap60r(); + } else { + // + //Clear OBF in internal structure + // + ((VIRTKBC*)gVirtualKBC)->st_ &= (~(KBC_STATUS_OBF | KBC_STATUS_AUXB)); + // OBF is not full, clear AUX BUF also + if (!(LegacyStatus & KBC_STATUS_OBF)) { + LegacyStatus &= ~KBC_STATUS_AUXB; + } + // + // Update the Internal stucture with the correct value + // + ((VIRTKBC*)gVirtualKBC)->st_ |= LegacyStatus & (KBC_STATUS_OBF | KBC_STATUS_AUXB); + } + + // + //Check for GA20 Sequence change + // + if ((LegacyStatus & HCE_STS_INPUTFULL) && GetHceControl() & HCE_CNTRL_GA20_SEQ){ + HandleGA20Sequence(); + } else { + // Dispatch the interrupt depending on saved status + if (LegacyStatus & HCE_STS_INPUTFULL) { + if (LegacyStatus & HCE_STS_CMDDATA) { + trap64w(); + } else { + trap60w(); + } + } + } + + // Update Status + SetHceStatus(((VIRTKBC* )gVirtualKBC)->st_); + + // If more data needs to be sent set Character Pending interrupt + if (kbd->qhead != kbd->qtail || mouse->qhead != mouse->qtail) { + SetHceControl(GetHceControl() | HCE_CNTRL_CHARACTER_PENDING); + gClearCharacterPending = FALSE; + } else { + if (gClearCharacterPending == TRUE){ + SetHceControl(GetHceControl() & (~HCE_CNTRL_CHARACTER_PENDING)); + gClearCharacterPending = FALSE; + } else { + // Clear Character Pending bit and OBF in next SMI + gClearCharacterPending = TRUE; + } + } + + // + // Enable Traps + // + SetHceControl(GetHceControl() | HCE_CNTRL_EMULATION_ENABLE); + gInTrapHandler = FALSE; + + return; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Trap6064_Handler +// +// Description: SMI handler to handle the 64write, 64read, 60 write and 60 read SMI. +// +// Input: DispatchHandle - EFI Handle +// DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT + +// Output: None +// +// Note : Called inside SMM +// Used only when KBC is present on the system +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void Trap6064_Handler ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_USB_DISPATCH_CONTEXT * DispatchContext + ) +{ + UINT8 EmulationStatus; + UINTN OhciCount; + volatile EFI_PHYSICAL_ADDRESS OHCIBar = 0; + UINT8 Data; + VIRTMOUSE* mouse = (VIRTMOUSE*)gVirtualKBC->mouse_dev; + + // + // check if gOHCIBar has a valid address + // + if (gLegSupRegs == NULL) { + for( OhciCount = 0; OhciCount < Ohci_Hc_Array_Size; ++OhciCount ){ + if (Ohci_Hc_Array[OhciCount].Type == PciDevice) { + OHCIBar = ReadPCIConfig( Ohci_Hc_Array[OhciCount].BusDevFunc, 0x10) ; + if (OHCIBar != 0xFFFFFFFF && OHCIBar != 0) { + gLegSupRegs = (OHCI_LEG_SUP_REGS*)((OHCIBar & 0xFFFFFF00) + OHCI_HCE_CONTROL); + break; + } + } else if (Ohci_Hc_Array[OhciCount].Type == FixedMemory) { + gLegSupRegs = (OHCI_LEG_SUP_REGS*)Ohci_Hc_Array[OhciCount].MemAddr; + break; + } + } + if (gLegSupRegs == NULL) { + return; + } else { + // Check if MMIO address space of Legacy Support registers resides in SMRAM region. If yes, don't proceed. + if( AmiValidateMemoryBuffer( (VOID*)gLegSupRegs, sizeof(OHCI_LEG_SUP_REGS) ) ) { + return; + } + } + } + + // + // Check emulation is enabled if not exit. + // + if (!( GetHceControl() & HCE_CNTRL_EMULATION_ENABLE)) { + return; + } + + ((VIRTKBC*)gVirtualKBC)->st_ = EmulationStatus = GetHceStatus(); + + // Set the variable that we are processing the Trap + gInTrapHandler = TRUE; + + // + // Disable Emulation ( in response to i/o handler can try to access a real KBC) + // + SetHceControl(GetHceControl() & (~(HCE_CNTRL_EMULATION_ENABLE | HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE))); + + // + // Check if IRQ1 and IRQ12 is active + // + if (GetHceControl() & (HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE )){ + + // Update Status + Data = ByteReadIO(KBC_STATUS_REG); + + if (Data & (KBC_STATUS_OBF | KBC_STATUS_AUXB)) { + // Update Data + SetHceOutput(ByteReadIO(KBC_DATA_REG)); + ((VIRTKBC* )gVirtualKBC)->DelaySendingDataCmd = TRUE; + SerialOutput(GetHceOutput()); + } else { + // No data but only IRQ, then use emulation status + Data = EmulationStatus; + } + + // + // Clear the IRQ12/IRQ1 Active bit. Enable IRQEn only if data is pending + // + if ((Data & (KBC_STATUS_OBF | KBC_STATUS_AUXB)) == (KBC_STATUS_OBF | KBC_STATUS_AUXB)) { + SetHceControl (GetHceControl() | HCE_CNTRL_IRQ12_ACTIVE | HCE_CNTRL_IRQ_ENABLE); + } else if ((Data & (KBC_STATUS_OBF | KBC_STATUS_AUXB)) == KBC_STATUS_OBF ) { + SetHceControl (GetHceControl() | HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ_ENABLE); + } + + // + // This is a catch all condition. If IRQ generatd with out data just clear the status. + // + if (!(Data & KBC_STATUS_OBF)) { + SetHceControl (GetHceControl() | HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE | HCE_CNTRL_IRQ_ENABLE); + } + + SetHceStatus(Data); + SerialOutput(Data); + } else { + + // + // Enable HCE_CNTRL_EXT_IRQ_ENABLE + // + SetHceControl(GetHceControl() & ~(HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE | HCE_CNTRL_IRQ_ENABLE) | HCE_CNTRL_EXT_IRQ_ENABLE); + ((VIRTKBC* )gVirtualKBC)->DelaySendingDataCmd = FALSE; + + + // + // if Character Pending interrupt is enabled and OBF is not set, handle Port read 60 + // + if (GetHceControl() & HCE_CNTRL_CHARACTER_PENDING && !(EmulationStatus & HCE_STS_OUTPUTFULL)){ + if (ResponseBytes){ + if (!mouse->sink.present_) { + trap60r(); + } else { + WaitForOBFSMM(); + } + } + Data=ByteReadIO(KBC_STATUS_REG); + if (Data & KBC_STATUS_OBF) { + ResponseBytes--; + SetHceOutput(ByteReadIO(KBC_DATA_REG)); + SerialOutput(GetHceOutput()); + ((VIRTKBC* )gVirtualKBC)->st_ = Data; + } + } + + //Check for GA20 Sequence change + if ((EmulationStatus & HCE_STS_INPUTFULL) && GetHceControl() & HCE_CNTRL_GA20_SEQ){ + HandleGA20Sequence(); + // Clear the i/p full bit once the cmd/data is processed + ((VIRTKBC*)gVirtualKBC)->st_ = ((VIRTKBC*)gVirtualKBC)->st_ & ~(HCE_STS_INPUTFULL); + } else { + // Dispatch the interrupt depending on saved status + if (EmulationStatus & HCE_STS_INPUTFULL) { + if (EmulationStatus & HCE_STS_CMDDATA) { + MouseCmdInProgress = FALSE; + if (GetHceInput() == 0xD4) { + MouseCmdInProgress = TRUE; + } + SerialOutput(GetHceInput()); + trap64w(); + } else { + SerialOutput(GetHceInput()); + trap60w(); + CheckNumberofResponseBytes(); + if (!CheckPS2KBDMouseIRQEnabled() && ResponseBytes) { + WaitForOBFSMM(); + } + MouseCmdInProgress = FALSE; + Data=ByteReadIO(KBC_STATUS_REG); + if (!(Data & KBC_STATUS_OBF)) { + ResponseBytes = 0; + } + // + // if no data in emulation o/p register then update it + // + if (!(GetHceStatus() & KBC_STATUS_OBF) && (Data & KBC_STATUS_OBF)){ + // Update Data + SetHceOutput(ByteReadIO(KBC_DATA_REG)); + SerialOutput(GetHceOutput()); + ((VIRTKBC* )gVirtualKBC)->st_ = Data; + if (ResponseBytes) { + ResponseBytes--; + } + } + } + // Clear the i/p full bit once the cmd/data is processed + ((VIRTKBC*)gVirtualKBC)->st_ = ((VIRTKBC*)gVirtualKBC)->st_ & ~(HCE_STS_INPUTFULL); + } + } + + // Update Status + SetHceStatus(((VIRTKBC* )gVirtualKBC)->st_); + + if (ResponseBytes) { + SetHceControl(GetHceControl() & ~(HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE) | HCE_CNTRL_CHARACTER_PENDING); + } else { + SetHceControl(GetHceControl() & ~(HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE) & (~HCE_CNTRL_CHARACTER_PENDING)); + } + } + + // + // Enable Traps + // + SetHceControl(GetHceControl() & ~(HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE) | HCE_CNTRL_EMULATION_ENABLE); + gInTrapHandler = FALSE; + + return; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Ohci_TrapEnable +// +// Description: Enable/Disable traping in OHCI HC. +// +// Input: Boolean +// +// Output: TRUE/FALSE +// +// Note : Called inside SMM +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN Ohci_TrapEnable(BOOLEAN TrapEnable) +{ + UINTN OhciCount; + volatile EFI_PHYSICAL_ADDRESS OHCIBar = 0; + + if(gInTrapHandler) + return FALSE; + + // The idea is, since data has not been pushed, don't let USB module to send more data. By keeping emulation enabled + // emulation status will be sent, which will return O/P full so next byte will not be sent from USB + if (GetHceStatus() & KBC_STATUS_OBF) { + return FALSE; + } + + if (gLegSupRegs == NULL) { + for( OhciCount = 0; OhciCount < Ohci_Hc_Array_Size; ++OhciCount ){ + if (Ohci_Hc_Array[OhciCount].Type == PciDevice) { + OHCIBar = ReadPCIConfig( Ohci_Hc_Array[OhciCount].BusDevFunc, 0x10) ; + if (OHCIBar != 0xFFFFFFFF && OHCIBar != 0) { + gLegSupRegs = (OHCI_LEG_SUP_REGS*)((OHCIBar & 0xFFFFFF00) + OHCI_HCE_CONTROL); + break; + } + } else if (Ohci_Hc_Array[OhciCount].Type == FixedMemory) { + gLegSupRegs = (OHCI_LEG_SUP_REGS*)Ohci_Hc_Array[OhciCount].MemAddr; + break; + } + } + if (gLegSupRegs == NULL) { + return FALSE; + } else { + // Check if MMIO address space of Legacy Support registers resides in SMRAM region. If yes, don't proceed. + if( AmiValidateMemoryBuffer( (VOID*)gLegSupRegs, sizeof(OHCI_LEG_SUP_REGS) ) ) { + return FALSE; + } + } + } + + if(TrapEnable){ + // + // Enable Traps + // + SetHceControl(GetHceControl() & ~(HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE) | HCE_CNTRL_EMULATION_ENABLE); + } else { + // + // Disable Traps; + // + SetHceControl((GetHceControl() & ~HCE_CNTRL_EMULATION_ENABLE) | HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE); + } + return TRUE; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Ohci_HasTrapStatus +// +// Description: Return whether Emulation Interrupt has been generated or not +// +// Input: None +// +// Output: BOOLEAN +// +// Note : Called inside SMM. No usage for now. Present for compatible reason with OHCI. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN Ohci_HasTrapStatus() +{ + return FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmOhci_TrapEnable +// +// Description: Enable/Disable traping in OHCI HC. +// +// Input: Boolean +// +// Output: TRUE/FALSE +// +// Note: Called outside SMM +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN NonSmmOhci_TrapEnable(BOOLEAN TrapEnable) +{ + UINTN OhciCount; + volatile EFI_PHYSICAL_ADDRESS OHCIBar = 0; + EFI_TPL OldTpl; + + if (gLegSupRegs == NULL) { + for( OhciCount = 0; OhciCount < Ohci_Hc_Array_Size; ++OhciCount ){ + if (Ohci_Hc_Array[OhciCount].Type == PciDevice) { + OHCIBar = NonSmmReadPCIConfig( Ohci_Hc_Array[OhciCount].BusDevFunc, 0x10) ; + if (OHCIBar != 0xFFFFFFFF && OHCIBar != 0) { + gLegSupRegs = (OHCI_LEG_SUP_REGS*)((OHCIBar & 0xFFFFFF00) + OHCI_HCE_CONTROL); + break; + } + } else if (Ohci_Hc_Array[OhciCount].Type == FixedMemory) { + gLegSupRegs = (OHCI_LEG_SUP_REGS*)Ohci_Hc_Array[OhciCount].MemAddr; + break; + } + } + if (gLegSupRegs == NULL) { + return FALSE; + } + } + + OldTpl = pBS->RaiseTPL(TPL_HIGH_LEVEL); + + if (TrapEnable) { + // Initialize the status to default value + gLegSupRegs->HceStatus = 0x1C; + + // Enable Traps and clear status(es) that might be asserted by our handlers + if (IoRead8(0x64) == 0xFF) { + gLegSupRegs->HceControl = HCE_CNTRL_EMULATION_ENABLE | HCE_CNTRL_A20_STATE; + } else { + gLegSupRegs->HceControl = OHCI_TRAPEN_MASK | HCE_CNTRL_A20_STATE; + } + } else { + // Disable Traps; Clear the status + gLegSupRegs->HceControl &= ~OHCI_TRAPEN_MASK; + } + pBS->RestoreTPL(OldTpl); + + return TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GetHceInput +// +// Description: Reads the HceInput register which holds the data written to port 60/64 +// +// Input: None +// +// Output: UINT8 +// +// Note : Called only inside SMM +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 GetHceInput() +{ + return (UINT8)(gLegSupRegs->HceInput & 0xFF); + +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GetHceOutput +// +// Description: Reads the HceOutPut register in OHCI controller +// +// Input: None +// +// Output: UINT8 +// +// Note : Called only inside SMM +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 GetHceOutput() +{ + return (UINT8)(gLegSupRegs->HceOutput & 0xFF); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GetHceStatus +// +// Description: Reads the HceStatus register in OHCI controller +// +// Input: None +// +// Output: UINT8 +// +// Note : Called only inside SMM +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 GetHceStatus() +{ + return (UINT8)(gLegSupRegs->HceStatus & 0xFF); +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SetHceStatus +// +// Description: Writes to HceStatus in OHCI controller +// +// Input: UINT8 +// +// Output: None +// +// Note : Called only inside SMM +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void SetHceStatus (UINT8 Data) +{ + gLegSupRegs->HceStatus = (UINT32)Data; + return; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SetHceOutput +// +// Description: Writes to HceOutput which is returned on IO port 60h read +// +// Input: UINT8 +// +// Output: None +// +// Note : Called only inside SMM +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void SetHceOutput (UINT8 Data) +{ + gLegSupRegs->HceOutput = (UINT32)Data; + return; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SetHceControl +// +// Description: Writes to HceControl in OHCI controller +// +// Input: UINT8 +// +// Output: None +// +// Note : Called only inside SMM +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void SetHceControl (UINT16 Data) +{ + gLegSupRegs->HceControl = (UINT32)Data; + return; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SetHceControl +// +// Description: Reads the HceStatus register in OHCI controller +// +// Input: None +// +// Output: UINT8 +// +// Note : Called only inside SMM +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT16 GetHceControl() +{ + return (UINT16)(gLegSupRegs->HceControl & 0x1FF); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: WaitForOBFSMM +// +// Description: Wait till O/P buffer is full +// +// Input: None +// +// Output: None +// +// Note : Called only inside SMM +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void +WaitForOBFSMM() +{ + UINT8 bCount = 8; + UINT8 bStatus; + UINT32 wCount; + do { + wCount = 0xffff; + bStatus = (UINT8)(ByteReadIO(KBC_STATUS_REG) & BIT0); + while (!bStatus) { + if(wCount == 0) break; + bStatus = (UINT8)(ByteReadIO(KBC_STATUS_REG) & BIT0); + wCount--; + } + bCount--; + } while (bCount && (!bStatus)); + + return; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: CheckPS2KBDMousePresence +// +// Description: Check whether PS2 KBD/Mouse IRQ has been enabled or not +// +// Input: None +// +// Output: TRUE: if PS2 KBD/MOUSE IRQ enabled +// +// Note : Called only inside SMM +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN +CheckPS2KBDMouseIRQEnabled() +{ + + + LEGACYKBC* legkbc = _CR(gVirtualKBC,LEGACYKBC,kbc_); + + // If the device and IRQ is enabled in CCB return TRUE else return FALSE + // The idea being, we don't have to wait for the response after the cmd is issued to the device. + // IRQ will be generated when the response is ready. + + if (!legkbc->fCcb_loaded) { + return FALSE; + } + + if (MouseCmdInProgress){ + if (!(legkbc->ccb_ & KBC_CCB_EN2) && (legkbc->ccb_ & KBC_CCB_INT2)) { + return TRUE; + } + } else { + if (!(legkbc->ccb_ & KBC_CCB_EN) && (legkbc->ccb_ & KBC_CCB_INT)) { + return TRUE; + } + } + + return FALSE; + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: CheckNumberofResponseBytes +// +// Description: Based on KBD/Mouse cmd, determine how many response bytes should be provided +// +// Input: None +// +// Output: Updates ResponseBytes +// +// Note : Called only inside SMM +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void CheckNumberofResponseBytes () +{ + + UINT8 bData; + UINT8* CmdResponseArray; + + ResponseBytes = 0; + bData = GetHceInput(); + if (MouseCmdInProgress) { + ResponseBytes = 1; + CmdResponseArray = MouseCmdResponse; + } else { + CmdResponseArray = KBDCmdResponse; + } + + do { + if (*CmdResponseArray == bData) { + ResponseBytes = *(CmdResponseArray +1); + break; + } + CmdResponseArray+=2; + } while (*CmdResponseArray); + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SerialOutput +// +// Description: Directly writes to 3F8 COM port. Using this routine will be faster and +// debug output delay will have no impact on debugging time sensitive routines +// O/P the byte and give a space after that; +// +// Input: Byte to output +// +// Output: None +// +// Note : +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +// +void SerialOutput ( + UINT8 Data +) +{ +/* + UINT8 HigherNibble = Data >> 4; + UINT8 LowerBibble = Data & 0xF; + + HigherNibble = HigherNibble > 9 ? HigherNibble + 0x37 : HigherNibble + 0x30; + IoWrite8 (0x3f8, HigherNibble); + + LowerBibble = LowerBibble > 9 ? LowerBibble + 0x37 : LowerBibble + 0x30; + IoWrite8 (0x3f8, LowerBibble); + + // Space + IoWrite8 (0x3f8, 0x20); +*/ +} + + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/KbcEmul/KbcOhci.cif b/Core/EM/KbcEmul/KbcOhci.cif new file mode 100644 index 0000000..d7b8585 --- /dev/null +++ b/Core/EM/KbcEmul/KbcOhci.cif @@ -0,0 +1,9 @@ +<component> + name = "KbcOhci" + category = ModulePart + LocalRoot = "core\em\KbcEmul" + RefName = "KbcOhci" +[files] +"KbcOhci.c" +"KbcOhci.h" +<endComponent>
\ No newline at end of file diff --git a/Core/EM/KbcEmul/KbcOhci.h b/Core/EM/KbcEmul/KbcOhci.h new file mode 100644 index 0000000..fa8f0b6 --- /dev/null +++ b/Core/EM/KbcEmul/KbcOhci.h @@ -0,0 +1,184 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcOhci.h 3 12/05/13 12:46a Srikantakumarp $ +// +// $Revision: 3 $ +// +// $Date: 12/05/13 12:46a $ +// +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcOhci.h $ +// +// 3 12/05/13 12:46a Srikantakumarp +// [TAG] EIP145881 +// [Category] Improvement +// [Description] Ohci Emulation support needs to be extended for the +// chipset , where the HCE registers defined in some fixed Memory for +// Aptio 4.x +// [Files] KbcEmul.sdl, KbcOhci.c, KbcOhci.h +// +// 2 2/10/11 1:15a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 1 7/08/10 2:07a Rameshr +// Ohci Emulation support Added. +// EIP 39712 +// +// Initial Check-in +// +//********************************************************************** + +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: KbcOhci.h +// +// Description: Header file for OCHI controller for Emulation +// +//<AMI_FHDR_END> +//********************************************************************** + +typedef enum { + UNSUPPORTED = -1, + USB1_1 = 0, + USB1_2, + USB1_3, + USB1_4, + USB2_1, + NUMBER_USB_CONTROLLERS +} SUPPORTED_USB_CONTROLLERS; + +typedef enum { + PciDevice, + FixedMemory +} EMUL_DEV_TYPE; + +typedef struct { + EMUL_DEV_TYPE Type; + UINT16 BusDevFunc; + UINTN MemAddr; +} OHCI_EMUL_DEVICE; + +typedef struct _FULL_USB_DEVICE_PATH +{ + ACPI_HID_DEVICE_PATH acpi; + PCI_DEVICE_PATH pci; + EFI_DEVICE_PATH_PROTOCOL end; +} FULL_USB_DEVICE_PATH; + +#define ACPI_PATH_MACRO \ + {{ACPI_DEVICE_PATH,ACPI_DP,ACPI_DEVICE_PATH_LENGTH}, EISA_PNP_ID(0x0A03),0} + +#define PCI_PATH_MACRO(Device,Function) \ + {{HARDWARE_DEVICE_PATH, HW_PCI_DP, HW_PCI_DEVICE_PATH_LENGTH}, (Function),(Device)} + +#define END_PATH_MACRO \ + {END_DEVICE_PATH,END_ENTIRE_SUBTYPE,END_DEVICE_PATH_LENGTH} + +#define USB1_1_DEVICE_PATH \ + { ACPI_PATH_MACRO, PCI_PATH_MACRO(0x1d, 0), END_PATH_MACRO } + +// +// Trap Dispatcher +// +// +typedef struct _TRAPDISPATCH { + UINT16 status_bit; + void (* trap_function)(); +} TRAPDISPATCH; + + +#define PCIBUS(x) ( x << 16) +#define PCIDEV(x) ( x << 11) +#define PCIFUNC(x) ( x << 8) + + +#define PCIOFF_MASK 0x000000FF +#define PCIFUNC_MASK 0x0000FF00 +#define PCIDEV_MASK 0x00FF0000 +#define PCIBUS_MASK 0xFF000000 + +// OHCI emulation register equates +#define OHCI_HCE_CONTROL 0x100 +#define OHCI_HCE_INPUT 0x104 +#define OHCI_HCE_OUTPUT 0x108 +#define OHCI_HCE_STATUS 0x10C + +#pragma pack(push, 1) + +typedef struct { + UINT32 HceControl; + UINT32 HceInput; + UINT32 HceOutput; + UINT32 HceStatus; +} OHCI_LEG_SUP_REGS; + +#pragma pack(pop) + +// Bit definitions for emulation registers +#define HCE_CNTRL_EMULATION_ENABLE BIT0 +#define HCE_CNTRL_EMULATION_INTERRUPT BIT1 +#define HCE_CNTRL_CHARACTER_PENDING BIT2 +#define HCE_CNTRL_IRQ_ENABLE BIT3 +#define HCE_CNTRL_EXT_IRQ_ENABLE BIT4 +#define HCE_CNTRL_GA20_SEQ BIT5 +#define HCE_CNTRL_IRQ1_ACTIVE BIT6 +#define HCE_CNTRL_IRQ12_ACTIVE BIT7 +#define HCE_CNTRL_A20_STATE BIT8 + + +#define HCE_STS_OUTPUTFULL BIT0 +#define HCE_STS_INPUTFULL BIT1 +#define HCE_STS_FLAG BIT2 +#define HCE_STS_CMDDATA BIT3 +#define HCE_STS_INHIBIT_SWITCH BIT4 +#define HCE_STS_AUXOUTPUTFULL BIT5 +#define HCE_STS_TIMEOUT BIT6 +#define HCE_STS_PARITY BIT7 + + +BOOLEAN Ohci_HasTrapStatus(); +BOOLEAN Ohci_TrapEnable(BOOLEAN); +BOOLEAN NonSmmOhci_TrapEnable(BOOLEAN); +BOOLEAN GetRMhStatus (); + +UINT16 GetHceControl(); +void SetHceControl (UINT16); +void SetHceOutput (UINT8); +UINT8 GetHceOutput(); +UINT8 GetHceStatus(); +void SetHceStatus (UINT8); +UINT8 GetHceInput(); + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/KbcEmul/KbcUhci.c b/Core/EM/KbcEmul/KbcUhci.c new file mode 100644 index 0000000..98b9824 --- /dev/null +++ b/Core/EM/KbcEmul/KbcUhci.c @@ -0,0 +1,707 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcUhci.c 11 5/13/13 2:51a Rameshr $ +// +// $Revision: 11 $ +// +// $Date: 5/13/13 2:51a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcUhci.c $ +// +// 11 5/13/13 2:51a Rameshr +// [TAG] EIP119870 +// [Category] Improvement +// [Description] Build error with KbcEmulation module if update USB +// module label 4.6.3_USB_08.10.26 +// [Files] KbcEmul.Mak, KbcEmul.SDl, KbcUhci.c, KbcUhci.h, KbcOhci.c +// +// 10 2/10/11 1:10a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 9 7/12/10 7:38a Rameshr +// Ich10 Workaround added. +// +// 8 7/12/10 6:58a Rameshr +// Workaround added when the Emulation enabled and Another USB controller +// is disabled in ICH10. +// EIP 39755 +// +// 7 7/08/10 2:07a Rameshr +// Function Output parameter changed for OHCI emulation support. +// +// 6 2/02/10 4:28a Rameshr +// Before Regsiter the SMI call back for the USB PCI device, check the USB +// PCI device presence +// EIP 34601 +// +// 5 6/30/09 11:36a Rameshr +// Coding Standard and File header updated. +// +// 4 6/01/09 10:03a Rameshr +// Added Emulation Support for RMH enable/Disable +// EIP 21131 +// +// 3 2/05/09 9:44a Rameshr +// Symptom : With Latest CSM Emulation doesn't work. +// Solution: Added Emulation enable code in outside SMM. This is called +// from Uhcd.c when ever USB mode changes to Legacy +// EIP:18730 +// +// 2 8/07/08 10:21a Rameshraju +// All UHCI controller registed for the SMI handler +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//**************************************************************************** +// Name: KbcUhci.c +// +// Description: Handles the SMI events for port 60/64 +// +//**************************************************************************** +//<AMI_FHDR_END> +#ifdef FRAMEWORK_AP4 +#include "token.h" +#else +#include "tokens.h" +#endif +#include "KbcEmul.h" +#include "KbcUhci.h" +#include "KbcEmulLib.h" +#include "Kbc.h" + +extern KBC* gVirtualKBC; + +#if ICH10_WORKAROUND +EFI_STATUS EnableAllUhciController(); +EFI_STATUS RestoreUhciControllerStatus(); +#endif + +//Carries the LEGKEY status information saved before enable/disable trapping from outside trap handler is +//performed; The saving of the status allows recovering legacy I/O accesss event in case when multiple +//sources are serviced at signle SMI# ( legacy I/O and USB keyboard interupt, for example) + +static UINT16 SavedLegcyStatus = 0; + +static BOOLEAN gInTrapHandler = FALSE; + + +UHCI_EMUL_DEVICE Uhci_Hc_Array[] = { UHCI_EMUL_PCI_DEVICES }; +UINTN Uhci_Hc_Array_Size = sizeof(Uhci_Hc_Array) / sizeof(Uhci_Hc_Array[0]); + +void DisableLegKeyRegs(); +void trap64w(); +void trap60w(); +void trap64r(); +void trap60r(); + +TRAPDISPATCH trap_dispatcher[] = { + { UHCI_TRAPBY64W, trap64w }, + { UHCI_TRAPBY64R, trap64r }, + { UHCI_TRAPBY60W, trap60w }, + { UHCI_TRAPBY60R, trap60r }, +}; + +#define trap_dispatcher_size (sizeof(trap_dispatcher)/sizeof(trap_dispatcher[0])) + +//status bits for SMI#, parenthesis is needed for ~ or other conversion +#define UHCI_TRAPBY_MASK (UHCI_TRAPBY64W | UHCI_TRAPBY64R | UHCI_TRAPBY60W | UHCI_TRAPBY60R | UHCI_SMIBYENDPS) +//#define UHCI_TRAPBY_MASK (UHCI_TRAPBY64W | UHCI_TRAPBY60W | UHCI_TRAPBY60R | UHCI_SMIBYENDPS) + +//enable bits for traps +#define UHCI_TRAPEN_MASK (UHCI_64WEN | UHCI_60WEN | UHCI_64REN | UHCI_60REN | UHCI_A20PASSEN ) +//#define UHCI_TRAPEN_MASK (UHCI_64WEN | UHCI_60WEN | UHCI_60REN | UHCI_A20PASSEN ) + +void Trap6064_Handler ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_USB_DISPATCH_CONTEXT * DispatchContext + ); + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ValidateUhc +// +// Description: Validate the UHCI controller. +// +// Input: Boolean +// +// Output: Boolean +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN +ValidateUhc ( + UHCI_EMUL_DEVICE *Uhc +) +{ + UINT32 Data32 = 0; + + if (ReadPCIConfig (Uhc->BusDevFunc, 0) == 0xFFFFFFFF) { + return FALSE; + } + + Data32 = ReadPCIConfig (Uhc->BusDevFunc, 8) >> 8; + if (Data32 != (*((UINT32*)&Uhc->InterfaceType) & 0x00FFFFFF)) { + return FALSE; + } + + return TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Smm_Register +// +// Description: Enable the SMI for port 6064 access. +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void Smm_Register() +{ + EFI_SMM_USB_DISPATCH_CONTEXT context; + EFI_SMM_USB_DISPATCH_PROTOCOL* pDispatch; + EFI_HANDLE hDisp; + EFI_STATUS Status; + static FULL_USB_DEVICE_PATH hc_dp = USB1_1_DEVICE_PATH; + UINTN UhciCount; + + // + // Register the USB HW SMI handler + // + Status = gBS->LocateProtocol(&gEfiSmmUsbDispatchProtocolGuid, NULL, &pDispatch); + ASSERT_EFI_ERROR(Status); + // + // SMI registration routines will install the handlers, set enable bit + // and clear status in PM IO space. + // + for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){ + // + //Validate the PCI device before regsiter the SMI callback. + // + if (!ValidateUhc(&Uhci_Hc_Array[UhciCount])) { + continue; + } + hc_dp.pci.Device=(Uhci_Hc_Array[UhciCount].BusDevFunc >> 3); + hc_dp.pci.Function=(Uhci_Hc_Array[UhciCount].BusDevFunc & 07); + context.Type = UsbLegacy; + context.Device = (EFI_DEVICE_PATH_PROTOCOL *)&hc_dp; + Status = pDispatch->Register(pDispatch,Trap6064_Handler, &context, &hDisp); + } + + SavedLegcyStatus = 0; + // + //The SMI source for the port6064 is disabled. it will be enabled when we are in legacy enviorment. EFI enviorment Emulation is + //Disabled. + // + DisableLegKeyRegs(); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: WriteLegKeyReg +// +// Description: Write the Value in to all the UHCI controller Legacy Regsiters. +// +// Input: UINT8 Value +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void WriteLegKeyReg ( UINT16 Value) +{ + UINTN UhciCount; + for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){ + WordWritePCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc, + Uhci_Hc_Array[UhciCount].LegacyRegOffset, Value); + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ClearLegKeyStatusReg +// +// Description: Clear the Port6064 SMI Status Reg +// +// Input: UINT8 Value +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void ClearLegKeyStatusReg ( UINT16 Value) +{ + UINTN UhciCount; + +#if ICH10_WORKAROUND + // + // Enable all the UCHI controller + // In ICH10 chipset, we need to clear the Port 6064 SMI status in disabled controller + // also. Otherwise it's keep on generating SMI + // + EnableAllUhciController(); +#endif + + for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){ + WordWritePCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc, + Uhci_Hc_Array[UhciCount].LegacyRegOffset, Value); + } + + +#if ICH10_WORKAROUND + // + // Restore the UCHI controller's in RCBA Reg + // + RestoreUhciControllerStatus(); +#endif + +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DisableLegKeyRegs +// +// Description: Disable the port6064 SMI source based on the Trap enable mask. +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void DisableLegKeyRegs() +{ + UINT16 legkeyStatus; + UINTN UhciCount; + + for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){ + + // + // Skip for Invalid Pci Devices + // + if (!ValidateUhc(&Uhci_Hc_Array[UhciCount])) { + continue; + } + + // + //Read the Legacy Keyboard and mouse control register + // + legkeyStatus =(UINT16) ReadPCIConfig(Uhci_Hc_Array[UhciCount].BusDevFunc , + Uhci_Hc_Array[UhciCount].LegacyRegOffset ); // Read the status + + // + //Clear the enable bits + // + + WordWritePCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc , + Uhci_Hc_Array[UhciCount].LegacyRegOffset, legkeyStatus & ~UHCI_TRAPEN_MASK); + + // + //Disable the trap + // + WordWritePCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc, + Uhci_Hc_Array[UhciCount].LegacyRegOffset, legkeyStatus & (~UHCI_TRAPEN_MASK)); + } + return; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Trap6064_Handler +// +// Description: SMI handler to handle the 64write, 64read, 60 write and 60 read SMI. +// +// Input: DispatchHandle - EFI Handle +// DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT + +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void Trap6064_Handler ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_USB_DISPATCH_CONTEXT * DispatchContext + ) +{ + UINT16 LegcyKeyStatus; + UINT32 TrapFunCount; + UINTN UhciCount; + + for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){ + + if (!ValidateUhc(&Uhci_Hc_Array[UhciCount])) { + continue; + } + + // + // Read UHCI_PCI_LEGKEY + // + LegcyKeyStatus = (UINT16) ReadPCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc , + Uhci_Hc_Array[UhciCount].LegacyRegOffset ); + SavedLegcyStatus |= LegcyKeyStatus; + + if(SavedLegcyStatus==0xFFFF) { + SavedLegcyStatus=0; + continue; + } + + if( (SavedLegcyStatus & UHCI_TRAPBY_MASK) != 0 ) { + break; + } + + SavedLegcyStatus=0; + } + + if(UhciCount >=Uhci_Hc_Array_Size) { + return; + } + // + // External application has chaned UHCI trap enable configuration, exit + // + if ((LegcyKeyStatus & UHCI_TRAPEN_MASK) != UHCI_TRAPEN_MASK) + return; + + // + // Set the variable that we are processing the Trap + // + gInTrapHandler = TRUE; + + // + // Clear the status + // + ClearLegKeyStatusReg( LegcyKeyStatus | UHCI_TRAPBY_MASK); + + // + // Disable Traps ( in responce to i/o handler can try to access a real KBC) + // + WriteLegKeyReg( (LegcyKeyStatus & ~UHCI_TRAPEN_MASK)); + + // + // Dispatch the interrupt depending on saved status + // + for( TrapFunCount = 0; TrapFunCount < trap_dispatcher_size; ++TrapFunCount ){ + if( (LegcyKeyStatus & trap_dispatcher[TrapFunCount].status_bit ) != 0){ + (*trap_dispatcher[TrapFunCount].trap_function)(); + } + } + + // + // Clear the Status + // + ClearLegKeyStatusReg( LegcyKeyStatus | UHCI_TRAPBY_MASK); + + // + // Enable Traps + // + WriteLegKeyReg( LegcyKeyStatus | UHCI_TRAPEN_MASK); + + SavedLegcyStatus = 0; + gInTrapHandler = FALSE; + + return; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Uhci_HasTrapStatus +// +// Description: Check if trap status is set in UHCI HC. +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN Uhci_HasTrapStatus() +{ + UINT16 LegcyKeyStatus = 0; + UINTN UhciCount; + + for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){ + if (!ValidateUhc(&Uhci_Hc_Array[UhciCount])) { + continue; + } + + LegcyKeyStatus |= (UINT16) ReadPCIConfig(Uhci_Hc_Array[UhciCount].BusDevFunc, + Uhci_Hc_Array[UhciCount].LegacyRegOffset ); + } + return ((LegcyKeyStatus & UHCI_TRAPBY_MASK) != 0 ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Uhci_TrapEnable +// +// Description: Enable/Disable traping in UHCI HC. +// +// Input: Boolean +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN Uhci_TrapEnable(BOOLEAN TrapEnable) +{ + UINT16 LegcyKeyStatus; + UINTN UhciCount; + + if(gInTrapHandler) + return FALSE; + + for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){ + if (!ValidateUhc(&Uhci_Hc_Array[UhciCount])) { + continue; + } + + LegcyKeyStatus =(UINT16) ReadPCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc , + Uhci_Hc_Array[UhciCount].LegacyRegOffset ); + + // + //Record first time that trapping is disabled. Record only trap status bits handled by Trap handler + // + if( (LegcyKeyStatus & UHCI_TRAPEN_MASK)== UHCI_TRAPEN_MASK && + ( LegcyKeyStatus & UHCI_TRAPBY_MASK) != 0 ){ + //If legacy I/O caused SMI# and this is first time we are in uhci_trapEnable + //then trapping in LEGKEY reg must have been enabled and one trap status is set. + //Any port 60/64 operation within SMI# must be wrapped into + //enable/ disable&clear status. So subsequent trapEnable will not produce any + //trap statuses + SavedLegcyStatus |= LegcyKeyStatus; + } + if(TrapEnable){ + + // + //clear status(es) that might be asserted by our handlers + // + ClearLegKeyStatusReg( LegcyKeyStatus | UHCI_TRAPBY_MASK); + // + // Enable Traps + // + WriteLegKeyReg( LegcyKeyStatus | UHCI_TRAPEN_MASK); + } else { + + // + //clear status(es) that might be asserted by our handlers + // + ClearLegKeyStatusReg( LegcyKeyStatus | UHCI_TRAPBY_MASK); + // + // Disable Traps + // + WriteLegKeyReg( (LegcyKeyStatus & ~UHCI_TRAPEN_MASK) ); + } + } + return TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmValidateUhc +// +// Description: Validate the UHCI controller. +// +// Input: Boolean +// +// Output: Boolean +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN +NonSmmValidateUhc ( + UHCI_EMUL_DEVICE *Uhc +) +{ + UINT32 Data32 = 0; + + if (NonSmmReadPCIConfig (Uhc->BusDevFunc, 0) == 0xFFFFFFFF) { + return FALSE; + } + + Data32 = NonSmmReadPCIConfig (Uhc->BusDevFunc, 8) >> 8; + if (Data32 != (*((UINT32*)&Uhc->InterfaceType) & 0x00FFFFFF)) { + return FALSE; + } + + return TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmWriteLegKeyReg +// +// Description: Write the Value in to all the UHCI controller Legacy Regsiters. +// +// Input: UINT8 Value +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void NonSmmWriteLegKeyReg ( UINT16 Value) +{ + UINTN UhciCount; + + for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){ + if (!NonSmmValidateUhc(&Uhci_Hc_Array[UhciCount])) { + continue; + } + NonSmmWordWritePCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc, + Uhci_Hc_Array[UhciCount].LegacyRegOffset, Value); + } + return; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmClearLegKeyStatusReg +// +// Description: Clear the Port6064 SMI Status +// +// Input: UINT8 Value +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void NonSmmClearLegKeyStatusReg ( UINT16 Value) +{ + + UINTN UhciCount; + +#if ICH10_WORKAROUND + // + // Enable all the UCHI controller + // In ICH10 chipset, we need to clear the Port 6064 SMI status in disabled controller + // also. Otherwise it's keep on generating SMI + // + EnableAllUhciController(); +#endif + + for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){ + if (!NonSmmValidateUhc(&Uhci_Hc_Array[UhciCount])) { + continue; + } + NonSmmWordWritePCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc, + Uhci_Hc_Array[UhciCount].LegacyRegOffset, Value); + } + +#if ICH10_WORKAROUND + // + // Restore the UCHI controller's in RCBA Reg + // + RestoreUhciControllerStatus(); +#endif + + return; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmUhci_TrapEnable +// +// Description: Enable/Disable traping in UHCI HC. +// +// Input: Boolean +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN NonSmmUhci_TrapEnable(BOOLEAN TrapEnable) +{ + + UINT16 LegcyKeyStatus; + EFI_TPL OldTpl; + UINT16 UhciCount; + + for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){ + if (!NonSmmValidateUhc(&Uhci_Hc_Array[UhciCount])) { + continue; + } + + LegcyKeyStatus =(UINT16) NonSmmReadPCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc , + Uhci_Hc_Array[UhciCount].LegacyRegOffset ); + // + //Record first time that trapping is disabled. Record only trap status bits handled by Trap handler + // + if( (LegcyKeyStatus & UHCI_TRAPEN_MASK)== UHCI_TRAPEN_MASK && + ( LegcyKeyStatus & UHCI_TRAPBY_MASK) != 0 ){ + //If legacy I/O caused SMI# and this is first time we are in uhci_trapEnable + //then trapping in LEGKEY reg must have been enabled and one trap status is set. + //Any port 60/64 operation within SMI# must be wrapped into + //enable/ disable&clear status. So subsequent trapEnable will not produce any + //trap statuses + SavedLegcyStatus |= LegcyKeyStatus; + } + + OldTpl = pBS->RaiseTPL(TPL_HIGH_LEVEL); + + if(TrapEnable){ + // + // Clear the status + // + NonSmmClearLegKeyStatusReg(LegcyKeyStatus | UHCI_TRAPBY_MASK); + // + // Enable Traps + // + NonSmmWriteLegKeyReg( LegcyKeyStatus | UHCI_TRAPEN_MASK); + } else { + // + // Clear the status + // + NonSmmClearLegKeyStatusReg(LegcyKeyStatus | UHCI_TRAPBY_MASK); + + // + // Disable the Trap + // + NonSmmWriteLegKeyReg( (LegcyKeyStatus & ~UHCI_TRAPEN_MASK) ); + } + pBS->RestoreTPL(OldTpl); + } + + return TRUE; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/KbcEmul/KbcUhci.cif b/Core/EM/KbcEmul/KbcUhci.cif new file mode 100644 index 0000000..5665a8b --- /dev/null +++ b/Core/EM/KbcEmul/KbcUhci.cif @@ -0,0 +1,9 @@ +<component> + name = "KbcUhci" + category = ModulePart + LocalRoot = "core\em\KbcEmul" + RefName = "KbcUhci" +[files] +"KbcUhci.c" +"KbcUhci.h" +<endComponent> diff --git a/Core/EM/KbcEmul/KbcUhci.h b/Core/EM/KbcEmul/KbcUhci.h new file mode 100644 index 0000000..f584741 --- /dev/null +++ b/Core/EM/KbcEmul/KbcUhci.h @@ -0,0 +1,153 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcUhci.h 7 5/13/13 2:51a Rameshr $ +// +// $Revision: 7 $ +// +// $Date: 5/13/13 2:51a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcUhci.h $ +// +// 7 5/13/13 2:51a Rameshr +// [TAG] EIP119870 +// [Category] Improvement +// [Description] Build error with KbcEmulation module if update USB +// module label 4.6.3_USB_08.10.26 +// [Files] KbcEmul.Mak, KbcEmul.SDl, KbcUhci.c, KbcUhci.h, KbcOhci.c +// +// 6 2/10/11 1:11a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 5 7/08/10 2:07a Rameshr +// Function Output parameter changed for OHCI emulation support. +// +// 4 6/30/09 11:36a Rameshr +// Coding Standard and File header updated. +// +// 3 6/01/09 10:03a Rameshr +// Added Emulation Support for RMH enable/Disable +// EIP 21131 +// +// 2 2/05/09 9:44a Rameshr +// Symptom : With Latest CSM Emulation doesn't work. +// Solution: Added Emulation enable code in outside SMM. This is called +// from Uhcd.c when ever USB mode changes to Legacy +// EIP:18730 +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//**************************************************************************** +// Name: KbcUhci.c +// +// Description: Header file for UCHI controller for Emulation +// +//**************************************************************************** +//<AMI_FHDR_END> + +typedef enum { + UNSUPPORTED = -1, + USB1_1 = 0, + USB1_2, + USB1_3, + USB1_4, + USB2_1, + NUMBER_USB_CONTROLLERS +} SUPPORTED_USB_CONTROLLERS; + +typedef struct { + UINT16 BusDevFunc; + UINT8 InterfaceType; + UINT8 SubClassCode; + UINT8 BaseClassCode; + UINT8 LegacyRegOffset; +} UHCI_EMUL_DEVICE; + +typedef struct _FULL_USB_DEVICE_PATH +{ + ACPI_HID_DEVICE_PATH acpi; + PCI_DEVICE_PATH pci; + EFI_DEVICE_PATH_PROTOCOL end; +} FULL_USB_DEVICE_PATH; + +#define ACPI_PATH_MACRO \ + {{ACPI_DEVICE_PATH,ACPI_DP,ACPI_DEVICE_PATH_LENGTH}, EISA_PNP_ID(0x0A03),0} + +#define PCI_PATH_MACRO(Device,Function) \ + {{HARDWARE_DEVICE_PATH, HW_PCI_DP, HW_PCI_DEVICE_PATH_LENGTH}, (Function),(Device)} + +#define END_PATH_MACRO \ + {END_DEVICE_PATH,END_ENTIRE_SUBTYPE,END_DEVICE_PATH_LENGTH} + +#define USB1_1_DEVICE_PATH \ + { ACPI_PATH_MACRO, PCI_PATH_MACRO(0x1d, 0), END_PATH_MACRO } + +// +// Trap Dispatcher +// +// +typedef struct _TRAPDISPATCH { + UINT16 status_bit; + void (* trap_function)(); +} TRAPDISPATCH; + + +#define UHCI_SMIBYENDPS (UINT16)(1U << 15) +#define UHCI_USBPIRQEN (UINT16)(1U << 13) +#define UHCI_SMIBYUSB (UINT16)(1U << 12) +#define UHCI_TRAPBY64W (UINT16)(1U << 11) +#define UHCI_TRAPBY64R (UINT16)(1U << 10) +#define UHCI_TRAPBY60W (UINT16)(1U << 9) +#define UHCI_TRAPBY60R (UINT16)(1U << 8) +#define UHCI_SMIATENDPS (UINT16)(1U << 7) +#define UHCI_PSTATE (UINT16)(1U << 6) +#define UHCI_A20PASSEN (UINT16)(1U << 5) +#define UHCI_USBSMIEN (UINT16)(1U << 4) +#define UHCI_64WEN (UINT16)(1U << 3) +#define UHCI_64REN (UINT16)(1U << 2) +#define UHCI_60WEN (UINT16)(1U << 1) +#define UHCI_60REN (UINT16)(1U ) + +#define PCIBUS(x) ( x << 16) +#define PCIDEV(x) ( x << 11) +#define PCIFUNC(x) ( x << 8) + +BOOLEAN Uhci_HasTrapStatus(); +BOOLEAN Uhci_TrapEnable(BOOLEAN); +BOOLEAN NonSmmUhci_TrapEnable(BOOLEAN); + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/KbcEmul/Kbccore.c b/Core/EM/KbcEmul/Kbccore.c new file mode 100644 index 0000000..51516de --- /dev/null +++ b/Core/EM/KbcEmul/Kbccore.c @@ -0,0 +1,341 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Kbccore.c 9 1/09/12 1:30a Rameshr $ +// +// $Revision: 9 $ +// +// $Date: 1/09/12 1:30a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Kbccore.c $ +// +// 9 1/09/12 1:30a Rameshr +// [TAG] EIP74128 +// [Category] Improvement +// [Description] Disable the KbcEmulation Smi’s on ACPI enable and +// Disable SMI call +// [Files] Kbccore.c, KbcEmuulAcpi.c, KbcEmul.c, KbcEmul.cif, +// KbcEmul.h, KbcEmul.sdl +// +// 8 1/06/12 3:51a Rameshr +// [TAG] EIP78617 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] When KBCEmulation is enabled during OS runtime phase, +// system reboots +// [RootCause] if the SMI happens from AP, Kbcemulation driver unable to +// handle it. +// [Solution] Added logic in KbcCore.c to find the CPU that cause SMI +// and access the corresponding AL register. +// [Files] Ap4x.h, KbcCore.c +// +// 7 1/06/12 3:21a Rameshr +// EIP78617 check-in removed. +// +// 5 2/10/11 1:02a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 4 7/08/10 1:56a Rameshr +// Ohci Emulation support Added. +// EIP 39712 +// +// 3 6/30/09 11:30a Rameshr +// Coding Standard and File header updated. +// +// 2 2/05/09 9:35a Rameshr +// Symptom : With Latest CSM Emulation doesn't work. +// Solution: Added Emulation enable code in outside SMM. This is called +// from Uhcd.c when ever USB mode changes to Legacy +// EIP:18730 +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//********************************************************************** +// +// Name: Kbccore.c +// +// Description: It has function for port 60 read, 60 write, 64 read and 64 write +// +//********************************************************************** +//<AMI_FHDR_END> + +#include "KbcEmul.h" +#include "kbc.h" +#if UHCI_EMUL_SUPPORT +#include "KbcUhci.h" +#else +#include "KbcOhci.h" +#endif + +BOOLEAN AcpiEmulationDisable=FALSE; +extern KBC* gVirtualKBC; + +#define SYNC_SMI_BIT (1 << 0) + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: FindSMICpu +// +// Description: In a Multiprocessor environment, any logical CPU can generate +// the SMI. This function finds the CPU that generates SMI by accessing +// IO 60/64 Ports +// +// Input: None +// +// Output: UINT8 CpuIndex +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 FindSMICpu ( ) { + UINT8 CpuIndex; + UINT32 SmmIoMiscInfo; + UINT16 IOAddress; + UINT32 Smbase=0; + + for (CpuIndex = 0; CpuIndex < gSmst->NumberOfCpus; CpuIndex++) { + // + // Find which CPU caused the SMI + // + Smbase = gSmst->CpuSaveState[CpuIndex].Ia32SaveState.SMBASE; + SmmIoMiscInfo = *(UINT32 *) (((UINT8 *) (UINTN) Smbase) + 0x8000 + 0x7FA4); + IOAddress = SmmIoMiscInfo >> 16; + if (((IOAddress == 0x60) || (IOAddress == 0x64)) && (SmmIoMiscInfo & SYNC_SMI_BIT)) { + return CpuIndex; + } + } + + return 0xFF; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: getTrapAL +// +// Description: Get the port 60 or 64 input value from the CPU save reg +// +// Input: None +// +// Output: UINT8 Value +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 GetTrapAL() +{ + +#if UHCI_EMUL_SUPPORT + UINT8 CpuIndex; + + CpuIndex = FindSMICpu (); + ASSERT (CpuIndex != 0xFF); + return (UINT8)GET_CPUSAVESTATE_REG(CpuIndex, EAX); +#else + return GetHceInput(); +#endif + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: setTrapAL +// +// Description: Set the port 60 or 64 output value to the CPU save reg +// +// Input: UINT8 Data +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void SetTrapAL(UINT8 data) +{ + +#if UHCI_EMUL_SUPPORT + UINT8 CpuIndex; + + CpuIndex = FindSMICpu(); + ASSERT (CpuIndex != 0xFF); + *(UINT8*)&GET_CPUSAVESTATE_REG(CpuIndex, EAX) = data; +#endif + +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: trap64w +// +// Description: This function handles the Port64 write command +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +void trap64w() +{ + (*gVirtualKBC->kbc_write_command)( gVirtualKBC,GetTrapAL() ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: setTrapAL +// +// Description: This function handles the Port60 write command +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void trap60w() +{ + (*gVirtualKBC->kbc_write_data)( gVirtualKBC,GetTrapAL() ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: setTrapAL +// +// Description: This function handles the Port64 Read command +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void trap64r() +{ + SetTrapAL((*gVirtualKBC->kbc_read_status)(gVirtualKBC)); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: setTrapAL +// +// Description: This function handles the Port60 Read command +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void trap60r() +{ + SetTrapAL((*gVirtualKBC->kbc_read_data)(gVirtualKBC)); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: hasTrapStatus +// +// Description: return the port 6064 trap status +// +// Input: None +// +// Output: TRUE: Trab enabled for port 6064 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN hasTrapStatus() +{ + BOOLEAN TrapStatus=FALSE; +#if UHCI_EMUL_SUPPORT + TrapStatus=Uhci_HasTrapStatus(); +#endif +#if OHCI_EMUL_SUPPORT + TrapStatus=Ohci_HasTrapStatus(); +#endif + return TrapStatus; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: TrapEnable +// +// Description: Enable/disable the port6064 trap +// +// Input: TRUE : enable the trap. +// FALSE: Disable the trap. +// +// Output: TRUE : when suucessfully done else FALSE +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN TrapEnable(BOOLEAN b) +{ + + if(AcpiEmulationDisable) { + return FALSE; + } + +#if UHCI_EMUL_SUPPORT + return Uhci_TrapEnable(b); +#endif +#if OHCI_EMUL_SUPPORT + return Ohci_TrapEnable(b); +#endif + return TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: NonSmmTrapEnable +// +// Description: Enable/disable the port6064 trap in Non SMM +// +// Input: TRUE : enable the trap. +// FALSE: Disable the trap. +// +// Output: TRUE/FALSE +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN NonSmmTrapEnable(BOOLEAN b) +{ +#if UHCI_EMUL_SUPPORT + return NonSmmUhci_TrapEnable(b); +#endif +#if OHCI_EMUL_SUPPORT + return NonSmmOhci_TrapEnable(b); +#endif + return TRUE; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/KbcEmul/LegacyMouse.c b/Core/EM/KbcEmul/LegacyMouse.c new file mode 100644 index 0000000..3c8cef8 --- /dev/null +++ b/Core/EM/KbcEmul/LegacyMouse.c @@ -0,0 +1,553 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/LegacyMouse.c 6 2/16/11 4:05a Rameshr $ +// +// $Revision: 6 $ +// +// $Date: 2/16/11 4:05a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/LegacyMouse.c $ +// +// 6 2/16/11 4:05a Rameshr +// +// 5 2/10/11 1:05a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 4 7/08/10 2:01a Rameshr +// Ohci Emulation support Added. +// EIP 39712 +// +// 3 6/30/09 11:31a Rameshr +// Coding Standard and File header updated. +// +// 2 10/30/08 10:47a Rameshraju +// Keyboard & Mouse enable/disable command handled +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//**************************************************************************** +// Name: LegacyMouse.c +// +// Description: LegacyMouse functions +// +//**************************************************************************** +//<AMI_FHDR_END> + +#include "KbcEmul.h" +#include "KbcDevEmul.h" + +#define COUNTOF(x) (sizeof(x)/sizeof(x[0])) + +static UINT8 resetResp[] = {0xFA, 0xAA, 0x00 } ; +static UINT8 statusResp[] = {0xFA, 0x20, 0x02, 0x64 } ; +static UINT8 dataResp[] = {0xFA, 0x08, 0x00, 0x0 } ; +static UINT8 ackResp[] = {0xFA}; +static UINT8 idResp[] = {0xFA, 0}; +static UINT8 unknResp[] = {0xFE }; + +void Legacymouse_reciev_option(PS2SINK* mouse, UINT8 cmd ); +void Legacymouse_initParams(LEGACYMOUSE* mouse); +void Legacymouse_flushBuffer(LEGACYMOUSE* mouse); +void Legacymouse_send_resp(LEGACYMOUSE* mouse, UINT8* data, int count ); +void Legacymouse_echo(PS2SINK* mouse, UINT8 cmd ); +BOOLEAN SendLegacyMouseBuffer(LEGACYMOUSE* mouse, UINT8* packet, UINTN Count ); +void Legacymouse_pumpQueue(PS2SINK* ps2dev); +void KBC_WriteCommandByte(UINT8); +UINT8 KBC_ReadDataByte(); +void KBC_WriteSubCommandByte(UINT8); + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: mouse_idle +// +// Description: Handle commands sent from KBC to PS2 Mouse. Mouse idle, waiting for command or key +// +// Input: ps2dev - pointer to the Mouse structure +// Cmd - Data from the kbc buffer +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void Legacymouse_idle(PS2SINK* ps2dev, UINT8 cmd ) +{ + LEGACYMOUSE* mouse = (LEGACYMOUSE*)ps2dev; + UINT8 CCB; + + switch(cmd){ + // + //reset + // + case 0xFF: + Legacymouse_initParams(mouse); + Legacymouse_send_resp(mouse, resetResp,COUNTOF(resetResp)); + break; + // + //report status + // + case 0xE9: + Legacymouse_send_resp(mouse, statusResp,COUNTOF(statusResp)); + break; + // + //read data + // + case 0xEB: + MemCpy(dataResp+1,&mouse->dataPacket,sizeof(mouse->dataPacket)); + Legacymouse_flushBuffer(mouse); + Legacymouse_send_resp(mouse, dataResp,COUNTOF(dataResp)); + break; + // + //Enable Mouse + // + case 0xF4: + // + //if mouse is not present then atleast CCB needs to be enabled + // + if(!mouse->sink.present_ ){ + // + // Since mouse is not present, Update CCB to enable Mouse. KBC is present if control comes here. + // + KBC_WriteCommandByte(0x20); + CCB = KBC_ReadDataByte(); + CCB &= 0xDF; + KBC_WriteCommandByte(0x60); + KBC_WriteSubCommandByte(CCB); + } + mouse->Enabled = TRUE; + Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + break; + // + //Disable Mouse + // + case 0xF5: + if(!mouse->sink.present_ ){ + // + // Since mouse is not present, Update CCB to Disable Mouse. KBC is present if control comes here. + // + KBC_WriteCommandByte(0x20); + CCB = KBC_ReadDataByte(); + CCB = CCB | 0x20; + KBC_WriteCommandByte(0x60); + KBC_WriteSubCommandByte(CCB); + } + mouse->Enabled = TRUE; + Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + break; + // + //Set Streaming + // + case 0xEA: + mouse->streaming = 1; + Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + break; + // + //Set Remote + // + case 0xF0: + mouse->streaming = 0; + Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + break; + // + //Set Standard, Set Scaling and Reset Scaling + // + case 0xF6: + case 0xE6: + case 0xE7: + Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + break; + // + //Identify + // + case 0xF2: + Legacymouse_send_resp(mouse, idResp,COUNTOF(idResp)); + break; + + // + // set resolution + // + case 0xE8: + mouse->option_ptr = &mouse->resolution_; + ps2dev->onCommand = Legacymouse_reciev_option; + Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + break; + // + // set sampling rate + // + case 0xF3: + mouse->option_ptr = &mouse->samplingRate_; + ps2dev->onCommand = Legacymouse_reciev_option; + Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + break; + case 0xEE: + Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + ps2dev->onCommand = Legacymouse_echo; + break; + // + ////unknown command; send FE + // + default: + Legacymouse_send_resp(mouse, unknResp,COUNTOF(unknResp)); + break; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: mouse_echo +// +// Description: Mouse Echo command +// +// Input: ps2dev - pointer to the Mouse structure +// Cmd - Data from the kbc buffer +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void Legacymouse_echo(PS2SINK* ps2dev, UINT8 cmd ) +{ + LEGACYMOUSE* mouse = (LEGACYMOUSE*)ps2dev; + if( cmd == 0xEC ){ + ps2dev->onCommand = Legacymouse_idle; + Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + } else + Legacymouse_send_resp(mouse, &cmd,1); + +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: mouse_reciev_option +// +// Description: Mouse reciev command +// +// Input: ps2dev - pointer to the KBD structure +// Cmd - Data from the kbc buffer +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void Legacymouse_reciev_option(PS2SINK* ps2dev, UINT8 cmd ) +{ + LEGACYMOUSE* mouse = (LEGACYMOUSE*)ps2dev; + *(mouse->option_ptr) = cmd; + ps2dev->onCommand = Legacymouse_idle; + Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: msInput_Send +// +// Description: Mouse Input source sends data. Put the data into the buffer, attempt to send the first byte. +// The call comes outside of Trapping Leg access. Check that Trapping status will not be overriden +// +// Input: P - pointer to the Emulation Protocol +// Data - Ps2 mouse Data +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS EFIAPI LegacymsInput_Send( + IN EFI_EMUL6064MSINPUT_PROTOCOL * This, + IN PS2MouseData* data + ) +{ + LEGACYMOUSE* mouse = _CR(This,LEGACYMOUSE,msInput_); + + // + //clear all previous flags except overflow + // + mouse->dataPacket.flags &= (PS2MSFLAGS_XO|PS2MSFLAGS_YO); + // + //copy overflow and button flags from new packet + // + mouse->dataPacket.flags |= data->flags & ~(PS2MSFLAGS_XSIGN|PS2MSFLAGS_YSIGN); + mouse->dataPacket.flags |= 0x8; + if( (mouse->dataPacket.flags & PS2MSFLAGS_XO) == 0){ + if(data->flags & PS2MSFLAGS_XSIGN){ + mouse->x += (signed short)((UINT8)data->x | 0xFF00); + } else { + mouse->x += data->x; + } + mouse->dataPacket.x = (UINT8)(UINT32)(mouse->x); + if( mouse->x < 0 ){ + mouse->dataPacket.flags |= PS2MSFLAGS_XSIGN; + if( mouse->x < -256 ) + mouse->dataPacket.flags |= PS2MSFLAGS_XO; + } else { + if( mouse->x > 256 ) + mouse->dataPacket.flags |= PS2MSFLAGS_XO; + } + } + + if( (mouse->dataPacket.flags & PS2MSFLAGS_YO) == 0){ + if(data->flags & PS2MSFLAGS_YSIGN){ + mouse->y += (signed short)((UINT8)data->y | 0xFF00); + } else { + mouse->y += data->y; + } + mouse->dataPacket.y = (UINT8)(UINT32)(mouse->y); + if( mouse->y < 0 ){ + mouse->dataPacket.flags |= PS2MSFLAGS_YSIGN; + if( mouse->y < -256 ) + mouse->dataPacket.flags |= PS2MSFLAGS_YO; + } else{ + if( mouse->y > 256 ) + mouse->dataPacket.flags |= PS2MSFLAGS_YO; + } + } + + mouse->fFreshPacket = 1; + if( mouse->Enabled && mouse->streaming ){ + if( SendLegacyMouseBuffer(mouse,(UINT8*)&mouse->dataPacket,sizeof(mouse->dataPacket))) + { + Legacymouse_flushBuffer(mouse); + } + } + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SendLegacyMouseBuffer +// +// Description: Send the mouse packet to KBC +// +// Input: Mouse - pointer to the Mouse Structure +// Packetr - Mouse Data +// Count - Data Length +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN SendLegacyMouseBuffer(LEGACYMOUSE* mouse, UINT8* packet, UINTN Count ) +{ + UINTN FreeQueue = 0; + + // + // count of free items in the queue + // + if( mouse->qtail >= mouse->qhead ) + FreeQueue = MOUSEQUEUE_SIZE - (mouse->qtail - mouse->qhead); + else + FreeQueue = mouse->qhead - mouse->qtail; + + if(FreeQueue < Count ) + return TRUE; + + // + //place the Mouse data in mouse buffer + // + for( ; Count > 0; --Count ){ + *mouse->qtail++ = *packet++; + if(mouse->qtail >= mouse->queue+MOUSEQUEUE_SIZE) + mouse->qtail = mouse->queue; + } + + // + //Place the dummy 4th byte in mouse buffer, + // +// *mouse->qtail++ = 0; +// if(mouse->qtail >= mouse->queue+MOUSEQUEUE_SIZE) +// mouse->qtail = mouse->queue; + + // + // Disable trap to access real harware + // + TrapEnable(FALSE); + // + //Put the first byte in the KBC buffer + // + Legacymouse_pumpQueue(&mouse->sink); + // + // Enable trap back and clear statuses + // + TrapEnable(TRUE); + + return TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Legacymouse_pumpQueue +// +// Description: KBC has empty queue; Legacy I/O trapping is being processed.If mouse has data to push into KBC, +// now is a good time to do it +// +// Input: ps2dev - pointer to the Mouse structure +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void Legacymouse_pumpQueue(PS2SINK* ps2dev) +{ + LEGACYMOUSE* mouse = (LEGACYMOUSE*)ps2dev; + + // + //Put the data into KBC + // + if((mouse->qhead != mouse->qtail) && (ps2dev->kbc->send_outb1(ps2dev->kbc,PS2DEV_MOUSE,FALSE,*mouse->qhead))) { + if(++mouse->qhead >= mouse->queue+MOUSEQUEUE_SIZE) + mouse->qhead = mouse->queue; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Legacymouse_send_resp +// +// Description: Place the Responce bytes in the keyboard buffer. +// +// Input: Mousev - pointer to the Mouse structure +// Data - Pointer to the Data +// count - Length of the data +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void Legacymouse_send_resp(LEGACYMOUSE* mouse, UINT8* data, int count ) +{ + // + //When there is no PS2 mouse present in the system, Emulation should send the responce byte for the mouse command. + //If PS2 mouse present, it will send the responce to the KBC. So Emulation code doesn't need to responce it. + // + if(!mouse->sink.present_ ){ + // + // Emulation must provide the responce. Override any previos mouse data queued to KBC + // + mouse->qtail = mouse->qhead = mouse->queue; + for( ; count > 0; --count ){ + *mouse->qtail++ = *data++; + } + + /// + // push the first byte to the KBC + // + if( mouse->qhead != mouse->qtail && + mouse->sink.kbc->send_outb1(mouse->sink.kbc,PS2DEV_MOUSE,TRUE,*mouse->qhead)) + { + if(++mouse->qhead >= mouse->queue+MOUSEQUEUE_SIZE) + mouse->qhead = mouse->queue; + } + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Legacymouse_flushBuffer +// +// Description: Clear the mouse data buffer that tracks the mouse changes; after the data is cleared any data read +// will return zero (x,y) and current buttons state. +// +// Input: ps2dev - pointer to the KBD structure +// Cmd - Data from the kbc buffer +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void Legacymouse_flushBuffer(LEGACYMOUSE* mouse) +{ + mouse->x = mouse->y = 0; + mouse->dataPacket.x = mouse->dataPacket.y = 0; + mouse->dataPacket.flags &= (PS2MSFLAGS_LBUTTON|PS2MSFLAGS_RBUTTON); + mouse->fFreshPacket = 0; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: mouse_initParams +// +// Description: Initialize the mouse data +// +// Input: kbd - Pointer to the mouse structure +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void Legacymouse_initParams(LEGACYMOUSE* mouse) +{ + mouse->samplingRate_ = 0x64; + mouse->resolution_ = 2; + mouse->option_ptr = 0; + mouse->Enabled = FALSE; + mouse->streaming = 1; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: InitLegacyMouse +// +// Description: Initialize the Mouse data +// +// Input: kbc - pointer to the KBC Structure +// Mouse - Pointer to the Mouse structure +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void InitLegacyMouse(KBC* kbc, LEGACYMOUSE* mouse ) +{ + EFI_HANDLE hEmulationService = 0; + + mouse->qhead = mouse->qtail = mouse->queue; + mouse->sink.kbc = kbc; + mouse->sink.onCommand = Legacymouse_idle; + mouse->sink.onQueueFree = Legacymouse_pumpQueue; + mouse->msInput_.Send = LegacymsInput_Send; + mouse->x = mouse->y = 0; + mouse->dataPacket.flags = 0x8; + mouse->dataPacket.x = 0; + mouse->dataPacket.y = 0; + mouse->fFreshPacket = 0; + Legacymouse_initParams(mouse); + VERIFY_EFI_ERROR( + gBS->InstallProtocolInterface(&hEmulationService, + &gEmul6064MsInputProtocolGuid,EFI_NATIVE_INTERFACE,(void*)&mouse->msInput_)); +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/KbcEmul/Legacykbc.c b/Core/EM/KbcEmul/Legacykbc.c new file mode 100644 index 0000000..46e8f9f --- /dev/null +++ b/Core/EM/KbcEmul/Legacykbc.c @@ -0,0 +1,821 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Legacykbc.c 9 7/19/11 6:26a Rameshr $ +// +// $Revision: 9 $ +// +// $Date: 7/19/11 6:26a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Legacykbc.c $ +// +// 9 7/19/11 6:26a Rameshr +// +// +// [TAG] - EIP 58220 +// [Category]- BUG FIX +// [Severity]- Minor +// [Symptom] - Remote Keyboard doesn't work when the Ps2 Keyboard not +// attached in the system +// [RootCause]- Write Keyboard Data command D2 is not handled +// [Solution] - When the Ps2 device connected we are writting the data to +// data port. But when the device is not connected we are not sending the +// data. As this is KBC controller command data, we need to send the data +// even though device is not connected +// [Files] - LegacyKbc.c +// +// 8 2/10/11 1:03a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 7 10/14/10 12:45a Rameshr +// [TAG] - EIP 45498 +// [Category]- BUG FIX +// [Severity]- Minor +// [Symptom] - In KbcEmulation module, function kbc_kbd_wdata() of +// Legacykbc.c can cause system to hang in SMM. +// [RootCause]- For loop variable not decremented +// [Solution] - For loop variable decremented to avoid the deadloop +// [Files] - LegacyKbc.c +// +// 6 7/08/10 2:00a Rameshr +// Ohci Emulation support Added. +// EIP 39712 +// +// 5 12/23/09 5:08a Rameshr +// The Keyboard data wrongly pushed to Mouse device. That makes keyboard +// stops working. Corrected this problem. +// +// 4 6/30/09 11:30a Rameshr +// Coding Standard and File header updated. +// +// 3 2/05/09 9:44a Rameshr +// Symptom : With Latest CSM Emulation doesn't work. +// Solution: Added Emulation enable code in outside SMM. This is called +// from Uhcd.c when ever USB mode changes to Legacy +// EIP:18730 +// +// 2 10/30/08 10:48a Rameshraju +// Keyboard & Mouse enable/disable command handled +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//**************************************************************************** +// Name: LegacyKbc.c +// +// Description: LegacyKBC handles the with KBC model +// +//**************************************************************************** +//<AMI_FHDR_END> + +#include "KbcEmul.h" +#include "KbcDevEmul.h" +#include "Kbc.h" +#include "KbcEmulLib.h" + +#define AUXOBF (KBC_STATUS_AUXB|KBC_STATUS_OBF) + +void kbc_passthrough_wdata( KBC* kbc, UINT8 data ); +void kbc_mouse_wdata( KBC* kbc, UINT8 data ); +void kbc_wccb( KBC* kbc, UINT8 data ); +void on_kbc_write_command( KBC* kbc, UINT8 cmd ); +UINT8 kbc_passthrough_rstatus( KBC* kbc ); +void legkbc_updateCCB(LEGACYKBC* legkbc, UINT8 set, UINT8 mask ); +void kbc_kbd_wdata( KBC* kbc, UINT8 data ); + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: KBC_WaitForInputBufferToBeFree +// +// Description: This routine checks the input buffer free bit and waits till +// it is set by the keyboard controller +// +// Input: None +// +// Output: None +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN KBC_WaitForInputBufferToBeFree () +{ + UINT32 count ; + UINT8 status; + + for( count = KBCTIMEOUT, status = 1; status != 0 && count != 0; + status= ByteReadIO(KBC_STATUS_REG) & KBC_STATUS_IBF, --count ); + + return ( status & KBC_STATUS_IBF)==0; +} + + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: KBC_WaitForOutputBufferToBeFilled +// +// Description: This routine checks the output buffer full bit and waits till +// it is set by the keyboard controller +// +// Input: None +// +// Output: None +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN KBC_WaitForOutputBufferToBeFilled () +{ + UINT32 count ; + UINT8 status; + for( count = KBCTIMEOUT, status = 0; status == 0 && count != 0; + status = ByteReadIO(KBC_STATUS_REG) & KBC_STATUS_OBF, + --count ); + return ( status & KBC_STATUS_OBF)!=0; +} + + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: KBC_ReadDataByte +// +// Description: This routine till the keyboard controller sends a data byte +// +// Input: None +// +// Output: Data byte received from the keyboard controller +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT8 KBC_ReadDataByte () +{ + KBC_WaitForOutputBufferToBeFilled(); + return ByteReadIO(KBC_DATA_REG); +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: KBC_WriteCommandByte +// +// Description: This routine writes the command to the keyboard controller +// +// Input: KBC Command +// +// Output: None +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +void KBC_WriteCommandByte(UINT8 bCmd) +{ + KBC_WaitForInputBufferToBeFree(); + ByteWriteIO(KBC_COMMAND_REG, bCmd); + KBC_WaitForInputBufferToBeFree(); +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: KBC_WriteSubCommandByte +// +// Description: This routine writes the command to the keyboard controller +// +// Input: KBC Command +// +// Output: None +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +void KBC_WriteSubCommandByte(UINT8 bCmd) +{ + KBC_WaitForInputBufferToBeFree(); + ByteWriteIO(KBC_DATA_REG, bCmd); + KBC_WaitForInputBufferToBeFree(); +} + + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: KBC_WriteSubCommandByte +// +// Description: Return current CCB stored in KBC .Traping and tracking KBC ports I/O +// allow to cache the ccb value. Still at the initial value must be +// loaded by reading CCB from KBC (command 20). Care is taken not to +// damage whatever data is stored in KBC +// +// Input: KBC +// +// Output: CCB value +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 kegkbc_readCCB( KBC* kbc ) +{ + LEGACYKBC* legkbc = _CR(kbc,LEGACYKBC,kbc_); + UINT8 stSave; + UINT8 bSave; + + if( legkbc->fCcb_loaded ) + return legkbc->ccb_; + + // + //Call can come from outside of Trap handler (EFI protocol invoked).We must disable trapping for this case + // + TrapEnable(FALSE); + + // + // lock the KBC + // + KBC_WriteCommandByte(KBCCMD_LOCK); + + // + //Get the Status regsiter value and Data from Data register + // + stSave = ByteReadIO(KBC_STATUS_REG); + bSave = ByteReadIO(KBC_DATA_REG); + KBC_WriteCommandByte(KBCCMD_READ_CCB); + + // + //Get the CCB value and store it and set CCB has been read already. + // + legkbc->ccb_ = KBC_ReadDataByte(); + legkbc->fCcb_loaded = TRUE; + + // + //Push the Data to back to Keyboard Controller. + // + if(stSave & KBC_STATUS_OBF){ + if( stSave & KBC_STATUS_AUXB ) + KBC_WriteCommandByte(KBCCMD_WriteAuxBuffer); + else + KBC_WriteCommandByte(KBCCMD_WriteKbdBuffer); + ByteWriteIO(KBC_DATA_REG, bSave); + } + + // + //Enable the trap again. + // + TrapEnable(TRUE); + return legkbc->ccb_; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: kbc_mouse_wdata +// +// Description: Handle write to port 60. Previouse command written to port 64 was "Send to auxilary device" +// (0xD4). The data is passed to the Mouse emulation machine. +// Next state is: accepting keyboard data on port 60. +// +// Input: KBC, Mouse data +// +// Output: None +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +void kbc_mouse_wdata( KBC* kbc, UINT8 data ) +{ + LEGACYKBC* legkbc = _CR(kbc,LEGACYKBC,kbc_); + + // + //enable Aux interface + // + legkbc_updateCCB(legkbc,0,KBC_CCB_EN2); + + if(kbc->mouse_dev->present_) { + KBC_WaitForInputBufferToBeFree(); + ByteWriteIO( KBC_DATA_REG, data ); + } + + // + //Detect if real PS/2 mouse is present, Wait till responce comes + // + + if(!kbc->mouse_dev->presence_detected_) + { + int c; + UINT8 st; + UINT8 mouseData; + + // + //Mouse detection happens here + // + kbc->mouse_dev->presence_detected_= TRUE; + + KBC_WaitForInputBufferToBeFree(); + + for( st = 0,c = 0x10000; c != 0 && (st & AUXOBF )!= AUXOBF;c--){ + int c1; + st = ByteReadIO(KBC_STATUS_REG); + for( c1 = 0x10000; c1 != 0 && (st & AUXOBF) == KBC_STATUS_OBF; --c1 ) + st = ByteReadIO(KBC_STATUS_REG); + if((st & AUXOBF) == KBC_STATUS_OBF ){ + //not a mouse data; trash it (we can trash a keyboard key) + //TODO: a better detection alg. may be needed + //at least we can avoid trashing keyboard key: if non-mouse + //data is found (which must not accure for a correct application) + //get out of here assuming mouse present for the time (do not send) + //the responce; enable read port 64 and detect a mouse at the next + //trapped I/O + ByteReadIO(KBC_DATA_REG); + } + } + + kbc->mouse_dev->present_ = FALSE; + if( (st & AUXOBF )== AUXOBF ){ + // + //Mouse responce reached + // + mouseData = ByteReadIO(KBC_DATA_REG); + // + //Whatever command was it, good responce can not be 0xFE + // + kbc->mouse_dev->present_ = mouseData != 0xFE; + + if( kbc->mouse_dev->present_ ){ + //put the mouse responce back to KBC + KBC_WriteCommandByte( KBCCMD_WriteAuxBuffer); + ByteWriteIO(KBC_DATA_REG,mouseData); + KBC_WaitForInputBufferToBeFree(); + } + } + } + + (*kbc->mouse_dev->onCommand)(kbc->mouse_dev, data ); + + kbc->kbc_write_data = kbc_kbd_wdata; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: kbc_kbd_wdata +// +// Description: Handle write to port 60. The data is passed to the Keyboard emulation machine +// Next state is: accepting keyboard data on port 60. +// +// Input: KBC, Keyboard data +// +// Output: None +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +void kbc_kbd_wdata( KBC* kbc, UINT8 data ) +{ + LEGACYKBC* legkbc = _CR(kbc,LEGACYKBC,kbc_); + + legkbc_updateCCB(legkbc,0,KBC_CCB_EN); //enable KBD interface + + if(kbc->kbd_dev->present_) { + KBC_WaitForInputBufferToBeFree(); + ByteWriteIO( KBC_DATA_REG, data ); + } + + // + //Detect if real PS/2 Keyboard is present, Wait till responce comes + // + if(!kbc->kbd_dev->presence_detected_ && (data != 0xDD) && (data !=0xDF) ) + { + int c; + UINT8 st; + UINT8 kbdData; + + kbc->kbd_dev->presence_detected_= TRUE; + KBC_WaitForInputBufferToBeFree(); + + for( st = 0,c = 0x10000; c != 0 && (st & AUXOBF )!= KBC_STATUS_OBF;c-- ){ + st = ByteReadIO(KBC_STATUS_REG); + if( st & KBC_STATUS_TO ){ + break; + } + } + kbc->kbd_dev->present_ = FALSE; + if( (st & AUXOBF )== KBC_STATUS_OBF ){ + // + //Keyboard responce reached + // + kbdData = ByteReadIO(KBC_DATA_REG); + // + //Whatever command was it, good responce can not be 0xFE + // + kbc->kbd_dev->present_ = kbdData != 0xFE; + if( kbc->kbd_dev->present_ ){ + // + //put the responce back to KBC + // + KBC_WriteCommandByte( KBCCMD_WriteKbdBuffer); + ByteWriteIO(KBC_DATA_REG,kbdData); + KBC_WaitForInputBufferToBeFree(); + } + } + } + (*kbc->kbd_dev->onCommand)(kbc->kbd_dev, data ); + kbc->kbc_write_data = kbc_kbd_wdata; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: kbc_kbd_wdata2 +// +// Description: Handle write to port 60. This function handles the data specfic the +// KBC controller. Next state is: accepting keyboard data on port 60. +// +// Input: KBC, Keyboard data +// +// Output: None +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +void kbc_kbd_wdata2( KBC* kbc, UINT8 data ) +{ + + LEGACYKBC* legkbc = _CR(kbc,LEGACYKBC,kbc_); + BOOLEAN DeviceStatus; + UINT8 ccb; + + ccb = kegkbc_readCCB(kbc); + DeviceStatus = (ccb & KBC_CCB_EN); + + // + //If the device disable, don't put data in KBC + // + if(DeviceStatus) { + return ; + } + + KBC_WaitForInputBufferToBeFree(); + // + //Write the Keyboard Data. + // + ByteWriteIO( KBC_DATA_REG, data ); + + return; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: legkbc_updateCCB +// +// Description: Update cached CCB in responce to trapped KBC command.If CCB wasn't loaded before, the new CCB cache is +// still unkknown. +// +// Input: KBC, Set and Mask value +// +// Output: None +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +void legkbc_updateCCB(LEGACYKBC* legkbc, UINT8 set, UINT8 mask ) +{ + if(legkbc->fCcb_loaded){ + // + //CCB value + // + legkbc->ccb_ = (legkbc->ccb_ & ~mask ) | (set & mask); + } +} +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: kbc_wccb +// +// Description: Handle write to port 60. Previouse command written to port 64 was "Write CCB (60h)" +// The data is a new ccb. Next state is: accepting keyboard data on port 60. +// +// Input: KBC, CCB Data +// +// Output: None +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +void kbc_wccb( KBC* kbc, UINT8 data ) +{ + LEGACYKBC* legkbc = _CR(kbc,LEGACYKBC,kbc_); + + // TODO: wait for IBF? + // to accept a data as a new value of ccb we must be sure that + // KBC will take it. + // Alternative is to check that IBF is clear only once. If IBF is + // not clear then set fCcb_loaded = FALSE. That will force next + // legkbc_readCCB to read a value from KBC, but we will not spend + // time in SMI# (or delay this wait until CCB is needed for emulation) + for( ;(ByteReadIO(KBC_STATUS_REG) & KBC_STATUS_IBF ) != 0 ; ); + legkbc->ccb_ = data; + legkbc->fCcb_loaded = TRUE; + + // + //Send the CCB to KBC + // + ByteWriteIO( KBC_DATA_REG, data ); + kbc->kbc_write_data = kbc_kbd_wdata; + +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: on_kbc_write_command +// +// Description: Handle write to port 64. New command always aborts previous (no state dependency). This function +// will always get called on port 64 write.Parse the incomming command and change the state accoringly +// +// Input: KBC, Port 64 Command +// +// Output: None +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +void on_kbc_write_command( KBC* kbc, UINT8 cmd ) +{ + LEGACYKBC* legkbc = _CR(kbc,LEGACYKBC,kbc_); + LEGACYMOUSE* Mouse = (LEGACYMOUSE*)kbc->mouse_dev; + + ByteWriteIO(KBC_COMMAND_REG, cmd); + // + //If the command has data, it goes to Keyboard device + // + kbc->kbc_write_data = kbc_kbd_wdata; + switch(cmd){ + case KBCCMD_WriteAuxDev: + // + //next data is a mouse data. So send it to mouse device + // + kbc->kbc_write_data = kbc_mouse_wdata; + break; + case KBCCMD_AUXENBL: + Mouse->Enabled = TRUE; + legkbc_updateCCB( legkbc, 0, KBC_CCB_EN2); + break; + case KBCCMD_AUXDSBL: + Mouse->Enabled = FALSE; + legkbc_updateCCB( legkbc, KBC_CCB_EN2, KBC_CCB_EN2); + break; + case KBCCMD_KBDENBL: + legkbc_updateCCB( legkbc, 0, KBC_CCB_EN); + break; + case KBCCMD_KBDDSBL: + legkbc_updateCCB( legkbc, KBC_CCB_EN, KBC_CCB_EN); + break; + case KBCCMD_WRITE_CCB: + kbc->kbc_write_data = kbc_wccb; + break; + case KBCCMD_WriteKbdBuffer: + case KBCCMD_WriteAuxBuffer: + kbc->kbc_write_data = kbc_kbd_wdata2; + break; + default: + break; + } +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: kbc_passthrough_wdata +// +// Description: Handle write to port 60.The emulation doesn't process this write and the access is passed to the KBC +// +// Input: KBC, Port 60 Data +// +// Output: None +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +void kbc_passthrough_wdata( KBC* kbc, UINT8 data ) +{ + ByteWriteIO( KBC_DATA_REG, data ); +} +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: kbc_passthrough_wcmd +// +// Description: Handle write to port 64.The emulation doesn't process this write and +// the access is passed to the KBC +// +// Input: KBC, Port 64 command +// +// Output: None +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +void kbc_passthrough_wcmd( KBC* kbc, UINT8 data ) +{ + ByteWriteIO( KBC_STATUS_REG,data ); +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: kbc_passthrough_wcmd +// +// Description: Handle read from port 64.The emulation doesn't process this read and +// the access is passed to the KBC +// +// Input: KBC +// +// Output: KBC status +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 kbc_passthrough_rstatus( KBC* kbc ) +{ + return ByteReadIO( KBC_STATUS_REG ); +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: kbc_passthrough_wcmd +// +// Description: Handle read from port 60.The access is passed to the KBC. Emulation tracks the read to pump the +// KBC output buffer (in case if there is more data in the queue) + +// Input: KBC +// +// Output: KBC Data +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 kbc_passthrough_rdata( KBC* kbc ) +{ + UINT8 data; + + // + //Get the data from KBC + // + data = ByteReadIO( KBC_DATA_REG ); + + // + //Push the Keyboard Data to KBC if it has any + // + (*kbc->kbd_dev->onQueueFree)(kbc->kbd_dev); + + // + //Push the Mouse data to KBC , if it has any + // + (*kbc->mouse_dev->onQueueFree)(kbc->mouse_dev); + + return data; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: legkbc_sendout +// +// Description: Implementation of the "send_outb1" for the case of legacy KBC present. Data is put into output buffer +// of legacy KBC which sets OBF and generates IRQ. Application gets a chance to handle the interrupt and +// read the data from legacy KBC. +// +// Notes: condition is checked: OBF is cleard (previous data was processed) +// +// Input: KBC, Device type, Data or Reponce data, Data +// +// Output: None +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN legkbc_sendout(KBC* kbc, PS2DEV_TYPE devtype, BOOLEAN ovrd, UINT8 data) +{ + UINT8 ccb; + BOOLEAN DeviceStatus; + + ccb = kegkbc_readCCB(kbc); + DeviceStatus = (ccb & (devtype == PS2DEV_MOUSE ? KBC_CCB_EN2 : KBC_CCB_EN))==0; + + // + //If the device disable, don't put data in KBC + // + if(!DeviceStatus) + return FALSE; + + + if( KBC_WaitForInputBufferToBeFree()){ + UINT8 st; + + KBC_WriteCommandByte(KBCCMD_LOCK); // lock the KBC + st = ByteReadIO(KBC_STATUS_REG); + + // + //If the KBC , if already has data (OBF set) return, If it's free , then place data to KBC + // + if( ((st & KBC_STATUS_OBF) != 0) && !ovrd ){ + //Output buffer is full - it's not a time to push our data + + //unlock KBC by sending some command that doesn't trash the Output buffer + // since we see data from device, we assume that this interface is + //enabled in KBC. So there is no harm to enable it again. The exception to + //the rule is a sequence of data that emulation code is pushing into the KBC: + //to isolate sequence from asichncronose input from a real device, we disable + //the interface in KBC but still the data will appear in buffer. aux_en and kbd_en + //track the disabling/enabling interface by emulation code. + KBC_WriteCommandByte( (st & KBC_STATUS_AUXB) != 0? kbc->aux_en : kbc->kbd_en ); + return FALSE; + } + // + //OBF is not set and KBC is ready to get the data.\ + // + KBC_WriteCommandByte( devtype == PS2DEV_MOUSE ? KBCCMD_WriteAuxBuffer:KBCCMD_WriteKbdBuffer ); + ByteWriteIO(KBC_DATA_REG,data); + KBC_WaitForInputBufferToBeFree(); + return TRUE; + } + return FALSE; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: initLegacyKBC +// +// Description: Initilize the KBC structure +// +// Input: KBC, KBD and Mouse +// +// Output: None +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +void initLegacyKBC(KBC* kbc, PS2SINK* kbd, PS2SINK* mouse ) +{ + kbc->mouse_dev = mouse; + kbc->kbd_dev = kbd; + kbc->sqTail[PS2DEV_KBD] = kbc->sqHead[PS2DEV_KBD] = kbc->send_queue; + kbc->sqTail[PS2DEV_MOUSE] = kbc->sqHead[PS2DEV_MOUSE] = kbc->send_queue_aux; + kbc->aux_en = KBCCMD_AUXENBL; + kbc->kbd_en = KBCCMD_KBDENBL; + kbd->present_ = TRUE; + kbd->presence_detected_ = FALSE; + mouse->presence_detected_ = FALSE; + mouse->present_ = TRUE; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: initLegacyKBC +// +// Description: Initialize Legacy KBC object +// +// Input: KBC, KBD and Mouse +// +// Output: None +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +void InitLegacyKBC(LEGACYKBC* legkbc, PS2SINK* kbd, PS2SINK* mouse ) +{ + initLegacyKBC(&legkbc->kbc_,kbd,mouse); + legkbc->kbc_.kbc_write_command = on_kbc_write_command; + legkbc->kbc_.kbc_write_data = kbc_kbd_wdata; + legkbc->kbc_.kbc_read_status = kbc_passthrough_rstatus; + legkbc->kbc_.kbc_read_data = kbc_passthrough_rdata; + legkbc->kbc_.send_outb1 = legkbc_sendout; + legkbc->kbc_.read_ccb = kegkbc_readCCB; + legkbc->ccb_ = 0; + legkbc->fCcb_loaded = FALSE; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/KbcEmul/Legacykbd.c b/Core/EM/KbcEmul/Legacykbd.c new file mode 100644 index 0000000..3519098 --- /dev/null +++ b/Core/EM/KbcEmul/Legacykbd.c @@ -0,0 +1,479 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Legacykbd.c 4 6/27/12 1:30a Jittenkumarp $ +// +// $Revision: 4 $ +// +// $Date: 6/27/12 1:30a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Legacykbd.c $ +// +// 4 6/27/12 1:30a Jittenkumarp +// [TAG] EIP89838 +// [Category] Improvement +// [Description] KbcEmulation module can't changed NUM LOCK ,CAPS +// LOCK,Scroll lock LED. +// [Files] Legacykbd.c +// +// 3 2/10/11 1:04a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 2 6/30/09 11:31a Rameshr +// Coding Standard and File header updated. +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//**************************************************************************** +// Name: LegacyKbd.c +// +// Description: Legacy Keyboard functions +// +//**************************************************************************** +//<AMI_FHDR_END> + +#include "KbcEmul.h" +#include "KbcDevEmul.h" +#include "KbcEmulLib.h" + +void LegacyKbd_initParams(LEGACYKBD* kbd); +void LegacyKbd_read_codes(PS2SINK* ps2dev, UINT8 cmd ); +void LegacyKbd_read_option(PS2SINK* ps2dev, UINT8 cmd ); +void LegacyKbd_rw_scancode(PS2SINK* ps2dev, UINT8 cmd ); +void LegacyKbd_send_resp(LEGACYKBD* mouse, UINT8* data, int count ); + +BOOLEAN KBC_WaitForInputBufferToBeFree (); +BOOLEAN KBC_WaitForOutputBufferToBeFilled (); +UINT8 KBC_ReadDataByte (); +void KBC_WriteSubCommandByte(UINT8 bCmd); +void KBC_WriteCommandByte(UINT8 bCmd); + +#define COUNTOF(x) (sizeof(x)/sizeof(x[0])) + +static UINT8 ackResp[] = {0xFA}; +static UINT8 ResetResp[] = {0xFA,0xAA}; +static UINT8 IdResp[] = {0xFA,0xAB, 0x41}; +static UINT8 ScanCodePageResp[] = {0xFA, 0x00}; +static UINT8 CmdED = 0; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Legacykbd_scanning +// +// Description: Handle commands sent from KBC to PS2 Keyboard. Keyboard is scanning or idle, waiting for command +// or key +// +// Input: ps2dev - pointer to the KBD structure +// Cmd - Data from the kbc buffer +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void Legacykbd_scanning(PS2SINK* ps2dev, UINT8 cmd ) +{ + LEGACYKBD* kbd = _CR(ps2dev,LEGACYKBD,sink); + switch(cmd){ + case 0xFF: //reset + LegacyKbd_initParams(kbd); + LegacyKbd_send_resp(kbd, ResetResp,COUNTOF(ResetResp)); + break; + case 0xFD: + case 0xFC: + case 0xFB: + LegacyKbd_send_resp(kbd, ackResp,COUNTOF(ackResp)); + kbd->read_code_action = cmd; + kbd->sink.onCommand = LegacyKbd_read_codes; + break; + case 0xFA: + case 0xF9: + case 0xF8: + case 0xF7: + case 0xF6: + case 0xF5: //Disable + case 0xF4: //Enable + LegacyKbd_send_resp(kbd, ackResp,COUNTOF(ackResp)); + break; + case 0xF3: //Set Typeatic Rate/Delay + LegacyKbd_send_resp(kbd, ackResp,COUNTOF(ackResp)); + kbd->sink.onCommand = LegacyKbd_read_option; + kbd->option_ptr = &kbd->typematicRateDelay; + break; + case 0xF2: + LegacyKbd_send_resp(kbd, IdResp,COUNTOF(IdResp)); + break; + case 0xF0: + LegacyKbd_send_resp(kbd, ackResp,COUNTOF(ackResp)); + kbd->sink.onCommand = LegacyKbd_rw_scancode; + kbd->option_ptr = &kbd->scancodepage; + break; + + case 0xEE: //Echo + LegacyKbd_send_resp(kbd, &cmd,1); + break; + + case 0xED: //LED + LegacyKbd_send_resp(kbd, ackResp,COUNTOF(ackResp)); + kbd->sink.onCommand = LegacyKbd_read_option; + kbd->option_ptr = &kbd->typematicRateDelay; + CmdED = 1; + break; + } +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: LegacyKbd_read_codes +// +// Description: Keyboard Read Codes. +// +// Input: ps2dev - pointer to the KBD structure +// Cmd - Data from the kbc buffer +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void LegacyKbd_read_codes(PS2SINK* ps2dev, UINT8 cmd ) +{ + LEGACYKBD* kbd = _CR(ps2dev,LEGACYKBD,sink); + if( cmd >= 0xED ){ + kbd->sink.onCommand = Legacykbd_scanning; + Legacykbd_scanning(ps2dev,cmd); + } else + LegacyKbd_send_resp(kbd, ackResp,COUNTOF(ackResp)); +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: LegacyKbd_read_option +// +// Description: Keyboard Read option. +// +// Input: ps2dev - pointer to the KBD structure +// Cmd - Data from the kbc buffer +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void LegacyKbd_read_option(PS2SINK* ps2dev, UINT8 cmd ) +{ + LEGACYKBD* kbd = _CR(ps2dev,LEGACYKBD,sink); + UINT8* fPtr; + + kbd->sink.onCommand = Legacykbd_scanning; + + if (CmdED == 1) { + fPtr = (UINT8*)(UINTN)0x417; + *fPtr &= ~0x70; + *fPtr |= ((cmd & 0x07) << 4); + CmdED = 0; + LegacyKbd_send_resp(kbd, ackResp,COUNTOF(ackResp)); + } else { + if (cmd > 0xED) { + Legacykbd_scanning(ps2dev,cmd); + } else { + *(kbd->option_ptr) = cmd; + LegacyKbd_send_resp(kbd, ackResp,COUNTOF(ackResp)); + } + } +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: LegacyKbd_rw_scancode +// +// Description: Keyboard Read write Scan code. +// +// Input: ps2dev - pointer to the KBD structure +// Cmd - Data from the kbc buffer +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void LegacyKbd_rw_scancode(PS2SINK* ps2dev, UINT8 cmd ) +{ + LEGACYKBD* kbd = _CR(ps2dev,LEGACYKBD,sink); + if(cmd != 0 ) + LegacyKbd_read_option(ps2dev,cmd); + else { + kbd->sink.onCommand = Legacykbd_scanning; + ScanCodePageResp[1] = kbd->scancodepage; + LegacyKbd_send_resp(kbd, ScanCodePageResp,COUNTOF(ScanCodePageResp)); + } +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: LegacyKbd_send_resp +// +// Description: Place the Responce bytes in the keyboard buffer. +// +// Input: ps2dev - pointer to the KBD structure +// Data - Pointer to the Data +// count - Length of the data +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void LegacyKbd_send_resp(LEGACYKBD* kbd, UINT8* data, int count ) +{ + // + //When there is no PS2 Keyboard present in the system, Emulation should send the responce byte for the keyboard command. + //If PS2 Keyboard present, it will send the responce to the KBC. So Emulation code doesn't need to responce it. + // + if(!kbd->sink.present_ ){ + // + // Emulation must provide the responce. Override any previos kbd data queued to KBC + // + kbd->qtail = kbd->qhead = kbd->queue; + for( ; count > 0; --count ){ + *kbd->qtail++ = *data++; + } + + // + // push the first byte to the KBC + // + if( kbd->qhead != kbd->qtail && + kbd->sink.kbc->send_outb1(kbd->sink.kbc, + PS2DEV_KBD,TRUE,*kbd->qhead)) + { + if(++kbd->qhead >= kbd->queue+KBDQUEUE_SIZE) + kbd->qhead = kbd->queue; } + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: LegacyKbd_pumpQueue +// +// Description: KBC has empty queue; Legacy I/O trapping is being processed.If Kbd has data to push into KBC, +// now is a good time to do it +// +// Input: ps2dev - pointer to the KBD structure +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void LegacyKbd_pumpQueue(PS2SINK* ps2dev) +{ + LEGACYKBD* kbd = _CR(ps2dev,LEGACYKBD,sink); + // + //send the Keyboard data to the KBC + // + if( kbd->qhead != kbd->qtail && + ps2dev->kbc->send_outb1(ps2dev->kbc,PS2DEV_KBD,FALSE,*kbd->qhead)) + { + if(++kbd->qhead >= kbd->queue+KBDQUEUE_SIZE) + kbd->qhead = kbd->queue; + } + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: LegacykbdInput_Send +// +// Description: Keyboard Input source sends data. Put the data into the buffer, attempt to send the first byte. +// The call comes outside of Trapping Leg access. Check that Trapping status will not be overriden +// +// Input: P - pointer to the Emulation Protocol +// Buffer - Data buffer +// Count - Buffer Length +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS LegacykbdInput_Send(EFI_EMUL6064KBDINPUT_PROTOCOL* p, UINT8* buffer, UINT32 count) +{ + LEGACYKBD* kbd = _CR(p,LEGACYKBD,kbdInput_); + UINTN c = 0; + + // + // count of free items in the queue + // + if( kbd->qtail >= kbd->qhead ) + c = KBDQUEUE_SIZE - (kbd->qtail - kbd->qhead); + else + c = kbd->qhead - kbd->qtail -1; + + if(c < count ) + return EFI_NOT_AVAILABLE_YET; + + for( ; count > 0; --count ){ + *kbd->qtail++ = *buffer++; + if(kbd->qtail >= kbd->queue+KBDQUEUE_SIZE) + kbd->qtail = kbd->queue; + } + + // + // Disable trap to access real harware + // + TrapEnable(FALSE); + LegacyKbd_pumpQueue(&kbd->sink); + // + // Enable trap back and clear statuses + // + TrapEnable(TRUE); + + return EFI_SUCCESS; +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: LegacykbdInput_GetTranslation +// +// Description: KBC translation +// +// Input: P - pointer to the Emulation Protocol +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS LegacykbdInput_GetTranslation( + EFI_EMUL6064KBDINPUT_PROTOCOL* p, + OUT KBC_KBDTRANSLATION* outTrans ) +{ + LEGACYKBD* kbd = _CR(p,LEGACYKBD,kbdInput_); + *outTrans = (kbd->sink.kbc->read_ccb(kbd->sink.kbc) & KBC_CCB_XLAT) != 0? + KBC_KBDTRANS_PCXT : KBC_KBDTRANS_AT; + return EFI_SUCCESS; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: LegacykbdInput_updateLED +// +// Description: Update the keyboard LED's +// +// Input: P - pointer to the Emulation Protocol +// Data - LED data +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS LegacykbdInput_updateLED( + EFI_EMUL6064KBDINPUT_PROTOCOL* p, + IN UINT8 data ) +{ + UINT8 bKBData = 0; + UINT8 bSave; + + // + // Disable trap to access real harware + // + TrapEnable(FALSE); + // + // Wait for input buffer to be free + // + KBC_WaitForInputBufferToBeFree(); + KBC_WriteCommandByte(KBCCMD_LOCK); + bSave = ByteReadIO(KBC_STATUS_REG); + + // + // Data is pending. Read it in AL + // + if(bSave & KBC_STATUS_OBF) + { + bKBData = ByteReadIO(KBC_DATA_REG); + } + KBC_WriteCommandByte(0xAE); + KBC_WriteSubCommandByte(0xED); + KBC_ReadDataByte(); + KBC_WriteSubCommandByte(data); + KBC_ReadDataByte(); + + if(bSave & KBC_STATUS_OBF){ + KBC_WriteCommandByte(bSave & KBC_STATUS_AUXB? 0xD3: 0xD2); + KBC_WriteSubCommandByte(bKBData); + } + // + // Enable trap back and clear statuses + // + TrapEnable(TRUE); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: LegacyKbd_initParams +// +// Description: Initialize the KBD data +// +// Input: kbd - Pointer to the KBD structure +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void LegacyKbd_initParams(LEGACYKBD* kbd) +{ +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: InitLegacyKbd +// +// Description: Initialize the KBD data +// +// Input: kbc - pointer to the KBC Structure +// kbd - Pointer to the KBD structure +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void InitLegacyKbd(KBC* kbc, LEGACYKBD* kbd ) +{ + EFI_HANDLE hEmulationService = 0; + kbd->qhead = kbd->qtail = kbd->queue; + kbd->sink.kbc = kbc; + kbd->sink.onCommand = Legacykbd_scanning; + kbd->sink.onQueueFree = LegacyKbd_pumpQueue; + kbd->kbdInput_.Send = LegacykbdInput_Send; + kbd->kbdInput_.GetTranslation = LegacykbdInput_GetTranslation; + kbd->kbdInput_.UpdateLEDState = LegacykbdInput_updateLED; + VERIFY_EFI_ERROR( + gBS->InstallProtocolInterface(&hEmulationService, + &gEmul6064KbdInputProtocolGuid,EFI_NATIVE_INTERFACE,(void*)&kbd->kbdInput_)); +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/KbcEmul/VirtualKbc.c b/Core/EM/KbcEmul/VirtualKbc.c new file mode 100644 index 0000000..23f900e --- /dev/null +++ b/Core/EM/KbcEmul/VirtualKbc.c @@ -0,0 +1,639 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/VirtualKbc.c 14 2/11/13 12:45a Rameshr $ +// +// $Revision: 14 $ +// +// $Date: 2/11/13 12:45a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/VirtualKbc.c $ +// +// 14 2/11/13 12:45a Rameshr +// [TAG] EIP114926 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Write CCB command doesn't enable the keyboard interface +// [RootCause] Data bytes are not decoded properly. +// [Solution] Data bytes are decoded properly and device interface and +// IRQ state values are set properly. +// [Files] VirtualKbc.c +// +// 13 9/30/11 12:45a Rameshr +// [TAG] EIP71408 +// [Category] Improvement +// [Description] Remove the customer name reference from the +// KbcEmulation module. +// [Files] KbcDevEmul.h,VirtualKbc.c +// +// 12 2/10/11 1:06a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 11 1/19/11 4:45a Rameshr +// [TAG] - EIP 52171 +// [Category]- BUG FIX +// [Severity]- Minor +// [Symptom] - System gives Assert when Keyboard Reset Command issued. +// [RootCause]- KBC Emulation Module SMI handler is using EFI Runtime +// services for Reset() Instead of SMM RunTime Services +// [Solution] - Smm Runtime Services used to reset the system +// [Files] - VirtualKbc.c +// +// 10 7/08/10 2:01a Rameshr +// Ohci Emulation support Added. +// EIP 39712 +// +// 9 2/10/10 7:03p Davidd +// Corrected the USB KB stopped working in DOS after "net init" utility is +// run - EIP 33687. +// +// 8 2/03/10 1:16a Rameshr +// Install Netware6.5 SP8 Fail. +// EIP 28411 +// Single byte and two Byte command is identified properly and handled. +// +// 7 12/23/09 1:31a Rameshr +// Symptom: KbcEmulation can't install FreeBSD +// Solution: Implemented command 0xAA (Controller self-test) and 0xAB +// (Keyboard interface test) +// EIP: 26451 +// +// 6 6/30/09 11:31a Rameshr +// Coding Standard and File header updated. +// +// 5 10/30/08 10:45a Rameshraju +// Keyboard & Mouse enable/disable command handled +// +// 4 10/24/08 11:56a Rameshraju +// IRQ1 or IRQ12 generated again if there is pending data. +// +// 3 5/01/08 10:40a Rameshraju +// Keyboard command D2 support added +// +// 2 12/27/07 4:54p Rameshraju +// KBC reset command added +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//********************************************************************** +// Name: VirtualKbc.c +// +// Description: Handles the Virtual KBC(Without KBC system) function +// +//********************************************************************** +//<AMI_FHDR_END> + +#include "KbcEmul.h" +#include "KbcDevEmul.h" +#include "Kbc.h" + +void vkbc_write_command( KBC* kbc, UINT8 cmd ); +UINT8 vkbc_read_status( KBC* kbc ); +void vkbc_write_data( KBC* kbc, UINT8 cmd ); +UINT8 vkbc_read_data( KBC* kbc ); +BOOLEAN virtkbc_sendout(KBC* kbc, PS2DEV_TYPE devtype,BOOLEAN ovrd, UINT8 data); +void initKBC(KBC* kbc, PS2SINK* kbd, PS2SINK* mouse ); + +// +//Depend on the KBC command generate IRQ12 +// +BOOLEAN MouseIrq= TRUE; + +// +//Depend on the KBC command generate IRQ1 +// +BOOLEAN KeyboardIrq= TRUE; + +// +//To hold the keyboard outport Status. +// +UINT8 OutPortStatus= 0xDF; + +// +//To hold the number of Mouse byte already send +// +UINT8 PacketSize=00; + + +extern EFI_EMUL6064KBDINPUT_PROTOCOL *gKbdProtocol; + +#if IRQ_EMUL_SUPPORT +extern GenerateIRQ12(VIRTKBC*); +extern GenerateIRQ1(VIRTKBC*); +#endif + +#if OHCI_EMUL_SUPPORT +UINT8 GetHceStatus(void); +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: vkbc_write_command +// +// Description: Handle write to command port of virtual KBC +// +// Input: kbc - pointer to the KBC structure +// cmd - keyboard controller command +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void vkbc_write_command( KBC* kbc, UINT8 cmd ) +{ + VIRTKBC* vkbc = (VIRTKBC*)kbc; + VIRTMOUSE* Mouse = (VIRTMOUSE*)kbc->mouse_dev; + VIRTKBD* Kbd = (VIRTKBD*)kbc->kbd_dev; + EFI_RUNTIME_SERVICES *SmmRuntimeVar; + EFI_GUID SmmRsTableGuid = EFI_SMM_RUNTIME_SERVICES_TABLE_GUID; + UINT8 Index; + + SmmRuntimeVar = NULL; + + // + //Save the KBC command + // + vkbc->kbc_command_ = cmd; + vkbc->st_ |= KBC_STATUS_A2; + vkbc->TwoByteCmd = FALSE; + + // + //Process the KBC command + // + switch( vkbc->kbc_command_ ){ + case KBCCMD_READ_CCB: + //move ccb into the ouput buffer + virtkbc_sendout(kbc,PS2DEV_KBD,TRUE,vkbc->ccb_); + break; + case KBCCMD_KBDDSBL: + vkbc->ccb_|=CCB_KEYBOARD_DISABLED; + Kbd->Enabled= FALSE; + break; + case KBCCMD_KBDENBL: + vkbc->ccb_&=(~CCB_KEYBOARD_DISABLED); + Kbd->Enabled= TRUE; + break; + case KBCCMD_AUXDSBL: + vkbc->ccb_|=CCB_MOUSE_DISABLED; + Mouse->Enabled = FALSE; + break; + case KBCCMD_AUXENBL: + vkbc->ccb_&=(~CCB_MOUSE_DISABLED); + Mouse->Enabled = TRUE; + break; + case KBCCMD_ReadOutPort: + virtkbc_sendout(kbc,PS2DEV_KBD,TRUE,OutPortStatus); + break; + // + //Selft Test- Returns 0x55 if okay + // + case KBCCMD_SelfTest: + virtkbc_sendout(kbc,PS2DEV_KBD,TRUE,KBCCMD_RES_SelfTestOk); + break; + // + //Returns 0x00 if okay, 0x01 if Clock line stuck low, 0x02 if clock line stuck high, + //0x03 if data line stuck low, and 0x04 if data line stuck high + // + case KBCCMD_CheckKbd: + virtkbc_sendout(kbc,PS2DEV_KBD,TRUE,KBCCMD_RES_KBInterfaceOk); + break; + // + //Reset the System for KBC command 0xFE + // + case KBCCMD_ResetSystem: + + for (Index = 0; Index < gSmst->NumberOfTableEntries; ++Index) { + if (guidcmp(&gSmst->SmmConfigurationTable[Index].VendorGuid, \ + &SmmRsTableGuid) == 0) { + break; + } + } + if (Index != gSmst->NumberOfTableEntries) { + SmmRuntimeVar =(EFI_RUNTIME_SERVICES *) gSmst->SmmConfigurationTable[Index].VendorTable; + + } + if(SmmRuntimeVar){ + SmmRuntimeVar->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); + } + break; + // + //Below are 2 byte commands. Next byte expected in Port 60. + // + case KBCCMD_WriteAuxDev: + case KBCCMD_WRITE_CCB: + case KBCCMD_WriteAuxBuffer: + case KBCCMD_WriteKbdBuffer: + case KBCCMD_WriteOutPort: + vkbc->TwoByteCmd = TRUE; + break; + + default: + break; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: vkbc_read_status +// +// Description: Handle read from status port of virtual KBC +// +// Input: kbc - pointer to the KBC structure +// +// +// Output: Status - keyboard controller Status +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 vkbc_read_status( KBC* kbc ) +{ + VIRTKBC* vkbc = (VIRTKBC*)kbc; + + // + //If we send 1 byte of mouse already , then try to send the remaining 2 bytes of data first and process the keyboard data. + // + + if(PacketSize >0 && PacketSize < MOUSE_PACKET_SIZE) { + // + //Check the OBF, If it's empty , check Mouse queue , if it's has the data push the data to KBC. + // + if(!(vkbc->st_ & KBC_STATUS_OBF)) { + (*kbc->mouse_dev->onQueueFree)(kbc->mouse_dev); + } + + // + //Check the OBF, If it's empty , check KBD queue , if it's has the data push the data to KBC. + // + if(!(vkbc->st_ & KBC_STATUS_OBF)) { + (*kbc->kbd_dev->onQueueFree)(kbc->kbd_dev); + } + } else { + // + //Try to process the keyboard data first. + // + + PacketSize=0; + // + //Check the OBF, If it's empty , check KBD queue , if it's has the data push the data to KBC. + // + if(!(vkbc->st_ & KBC_STATUS_OBF)) { + (*kbc->kbd_dev->onQueueFree)(kbc->kbd_dev); + } + + // + //Check the OBF, If it's empty , check Mouse queue , if it's has the data push the data to KBC. + // + if(!(vkbc->st_ & KBC_STATUS_OBF)) { + (*kbc->mouse_dev->onQueueFree)(kbc->mouse_dev); + } + } + + return vkbc->st_; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: vkbc_write_data +// +// Description: Handle write to data port of virtual KBC +// +// Input: kbc - pointer to the KBC structure +// Data - keyboard controller Data +// +// Output: Status - keyboard controller Status +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void vkbc_write_data( KBC* kbc, UINT8 cmd ) +{ + VIRTKBC* vkbc = (VIRTKBC*)kbc; + VIRTMOUSE* Mouse = (VIRTMOUSE*)kbc->mouse_dev; + VIRTKBD* Kbd = (VIRTKBD*)kbc->kbd_dev; + + // + //Check that perviously we got command in port64, if yes then we got data byte for the pervious command + // + if (vkbc->TwoByteCmd) { + vkbc->TwoByteCmd = FALSE; + switch( vkbc->kbc_command_ ){ + case KBCCMD_WriteAuxDev: + if(kbc->mouse_dev) + (*kbc->mouse_dev->onCommand)(kbc->mouse_dev,cmd); + vkbc->st_ |= KBC_STATUS_AUXB | KBC_STATUS_OBF; + break; + case KBCCMD_WRITE_CCB: + KeyboardIrq = cmd & BIT0 ? TRUE : FALSE; + MouseIrq = cmd & BIT1 ? TRUE : FALSE; + Kbd->Enabled = cmd & BIT4 ? FALSE : TRUE; + Mouse->Enabled = cmd & BIT5 ? FALSE : TRUE; + vkbc->ccb_ = cmd; + break; + case KBCCMD_WriteAuxBuffer: + vkbc->st_ |= KBC_STATUS_AUXB | KBC_STATUS_OBF; + vkbc->outb_ = cmd; + break; + case KBCCMD_WriteKbdBuffer: + gKbdProtocol->Send(gKbdProtocol, (UINT8 *)&cmd,1); + break; + case KBCCMD_WriteOutPort: + OutPortStatus=cmd; + break; + default: + break; + } + } else { + // + // We got data byte here and process the data byte + // + if(kbc->kbd_dev) + (*kbc->kbd_dev->onCommand)(kbc->kbd_dev,cmd); + } + + // + //reset the command and status that command has been processed. + // + vkbc->kbc_command_ = 0; + vkbc->st_ &= ~KBC_STATUS_A2; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: vkbc_read_data +// +// Description: Handle read from data port of virtual KBC +// +// Input: kbc - pointer to the KBC structure +// +// +// Output: Data - Data from the keyboard controller +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 vkbc_read_data( KBC* kbc ) +{ + VIRTKBC* vkbc = (VIRTKBC*)kbc; + UINT8 Data; + + Data = vkbc->outb_; + + if(vkbc->st_ & KBC_STATUS_OBF) { + // + //Reset the OBF flag + // + vkbc->st_ &= (~(KBC_STATUS_AUXB | KBC_STATUS_OBF)); + } + + // + //If we send 1 byte of mouse already , then try to send the remaining 2 bytes of data first and process the keyboard data. + // + + if(PacketSize >0 && PacketSize < MOUSE_PACKET_SIZE) { + + // + //Check the OBF, If it's empty , check Mouse queue , if it's has the data push the data to KBC. + // + if(!(vkbc->st_ & KBC_STATUS_OBF)) { + (*kbc->mouse_dev->onQueueFree)(kbc->mouse_dev); + } + + // + //Check the OBF, If it's empty , check KBD queue , if it's has the data push the data to KBC. + // + if(!(vkbc->st_ & KBC_STATUS_OBF)) { + (*kbc->kbd_dev->onQueueFree)(kbc->kbd_dev); + } + } else { + // + //Try to process the keyboard data first. + // + + PacketSize=0; + // + //Check the OBF, If it's empty , check KBD queue , if it's has the data push the data to KBC. + // + if(!(vkbc->st_ & KBC_STATUS_OBF)) { + (*kbc->kbd_dev->onQueueFree)(kbc->kbd_dev); + } + + // + //Check the OBF, If it's empty , check Mouse queue , if it's has the data push the data to KBC. + // + if(!(vkbc->st_ & KBC_STATUS_OBF)) { + (*kbc->mouse_dev->onQueueFree)(kbc->mouse_dev); + } + } + + return Data; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: virtkbc_sendout +// +// Description: Keep the data in the output buffer and set the OBF bit set. Based on device set the status bit also. +// +// Input: kbc - pointer to the KBC structure +// Devtype - Data from which device (KBD or Mouse) +// orvd - +// Data - Data to the kbc buffer +// +// Output: True: Placed the data successfully. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN virtkbc_sendout(KBC* kbc, PS2DEV_TYPE devtype,BOOLEAN ovrd, UINT8 data) +{ + VIRTKBC* vkbc = (VIRTKBC*)kbc; + VIRTKBD* Kbd = (VIRTKBD*)kbc->kbd_dev; + +#if OHCI_EMUL_SUPPORT + // + // Actual OBF status is maintained by the OHCI controller. + // Update the internal structure + // + vkbc->st_ &= (~(KBC_STATUS_OBF | KBC_STATUS_AUXB)); + vkbc->st_ |= GetHceStatus() & (KBC_STATUS_OBF | KBC_STATUS_AUXB); +#endif + + if( vkbc->st_ & KBC_STATUS_OBF) { + if(vkbc->st_ & KBC_STATUS_AUXB) { + if(MouseIrq) { + #if IRQ_EMUL_SUPPORT + GenerateIRQ12(vkbc); + #endif + } + } else { + #if IRQ_EMUL_SUPPORT + GenerateIRQ1(vkbc); + #endif + } + // + //KBC already has the data. + // + return FALSE; + } + // + //Save the data in the KBC buffer + // + vkbc->outb_ = data; + + // + //Set the OBF full + // + vkbc->st_ |= KBC_STATUS_OBF; + +#if OHCI_EMUL_SUPPORT + // + // This is the write place to do. Code flow may take IRQ disabled path or + // Trap6064_Handler won't get control because of USB SMI + // + SetHceOutput(data); +#endif + // + //Set the device type ( from which device data is out) + // + if( devtype == PS2DEV_MOUSE) { + vkbc->st_ |= KBC_STATUS_AUXB; + // + //Generate the IRQ12, as AUX OBF is set. + // + if(MouseIrq) { +#if IRQ_EMUL_SUPPORT + GenerateIRQ12(vkbc); +#endif + // + //If the input is Mouse data, increment the Packet size, otherwise (responce byte) initlize to 0 + // + if(ovrd) + PacketSize=0; + else + PacketSize++; + } + }else { + vkbc->st_ &= ~KBC_STATUS_AUXB; + // + //Generate IRQ1 + // +#if IRQ_EMUL_SUPPORT + GenerateIRQ1(vkbc); +#endif + } + + return TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: vkbc_readCCB +// +// Description: Return the CCB data from the KBC buffer +// +// Input: kbc - pointer to the KBC structure +// +// Output: Data: CCB data +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 vkbc_readCCB(KBC* kbc) +{ + VIRTKBC* vkbc = (VIRTKBC*)kbc; + return vkbc->ccb_; +} + +// +// Initialize KBC structure +// +void initKBC(KBC* kbc, PS2SINK* kbd, PS2SINK* mouse ) +{ + kbc->mouse_dev = mouse; + kbc->kbd_dev = kbd; + kbc->sqTail[PS2DEV_KBD] = kbc->sqHead[PS2DEV_KBD] = kbc->send_queue; + kbc->sqTail[PS2DEV_MOUSE] = kbc->sqHead[PS2DEV_MOUSE] = kbc->send_queue_aux; + kbc->aux_en = KBCCMD_AUXENBL; + kbc->kbd_en = KBCCMD_KBDENBL; + kbd->present_ = TRUE; + kbd->presence_detected_ = FALSE; + mouse->presence_detected_ = FALSE; + mouse->present_ = TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: InitVirtualKBC +// +// Description: Initialize KBC structure. Set initial state of the emulated KBC +// +// Input: kbc - pointer to the KBC structure +// kbd - Pointer to the KBD structure +// mouse - Pointer to the Mouse Structure +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void InitVirtualKBC(VIRTKBC* vkbc, PS2SINK* kbd, PS2SINK* mouse ) +{ + initKBC(&vkbc->kbc,kbd,mouse); + + // + //Initialize the KBC Structure + // + vkbc->kbc.kbc_write_command = vkbc_write_command; + vkbc->kbc.kbc_write_data = vkbc_write_data; + vkbc->kbc.kbc_read_status = vkbc_read_status; + vkbc->kbc.kbc_read_data = vkbc_read_data; + vkbc->kbc.send_outb1 = virtkbc_sendout; + vkbc->kbc.read_ccb = vkbc_readCCB; + + // + //Initialize the CCB + // + vkbc->ccb_ = 0; + // + //Initialize the Port64 Status + // + vkbc->st_ = 0x1c; + // + //Initialize the Port64 command regsiter + // + vkbc->kbc_command_ = 0; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/KbcEmul/VirtualKbd.c b/Core/EM/KbcEmul/VirtualKbd.c new file mode 100644 index 0000000..48c4e35 --- /dev/null +++ b/Core/EM/KbcEmul/VirtualKbd.c @@ -0,0 +1,456 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/VirtualKbd.c 6 2/10/11 1:07a Rameshr $ +// +// $Revision: 6 $ +// +// $Date: 2/10/11 1:07a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/VirtualKbd.c $ +// +// 6 2/10/11 1:07a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 5 2/19/10 3:50p Davidd +// Corrected arrow keys not working properly during Netware 6.5 +// installation - EIP 28411 +// +// 4 6/30/09 11:31a Rameshr +// Coding Standard and File header updated. +// +// 3 10/30/08 10:47a Rameshraju +// Keyboard & Mouse enable/disable command handled +// +// 2 5/01/08 10:43a Rameshraju +// Keyboard command D2 support added +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//**************************************************************************** +// Name: VirtualKbd.c +// +// Description: Virtual keyboard functions +//**************************************************************************** +//<AMI_FHDR_END> + +#include "KbcEmul.h" +#include "KbcDevEmul.h" + +#define COUNTOF(x) (sizeof(x)/sizeof(x[0])) + +void vkbd_initParams(VIRTKBD* kbd); +void vkbd_read_codes(PS2SINK* ps2dev, UINT8 cmd ); +void vkbd_read_option(PS2SINK* ps2dev, UINT8 cmd ); +void vkbd_rw_scancode(PS2SINK* ps2dev, UINT8 cmd ); +void vkbd_send_resp(VIRTKBD* mouse, UINT8* data, int count ); + +static UINT8 ackResp[] = {0xFA}; +static UINT8 ResetResp[] = {0xFA,0xAA}; +static UINT8 IdResp[] = {0xFA,0xAB, 0x41}; +static UINT8 ScanCodePageResp[] = {0xFA, 0x00}; +EFI_EMUL6064KBDINPUT_PROTOCOL *gKbdProtocol=NULL; +static UINT8 CmdED = 0; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: kbd_scanning +// +// Description: Handle commands sent from KBC to PS2 Keyboard. Keyboard is scanning or idle, waiting for command or key +// +// Input: ps2dev - pointer to the KBD structure +// Cmd - Data from the kbc buffer +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void kbd_scanning(PS2SINK* ps2dev, UINT8 cmd ) +{ + VIRTKBD* kbd = _CR(ps2dev,VIRTKBD,sink); + + switch(cmd){ + // + //Reset + // + case 0xFF: + vkbd_initParams(kbd); + vkbd_send_resp(kbd, ResetResp,COUNTOF(ResetResp)); + break; + case 0xFD: + case 0xFC: + case 0xFB: + vkbd_send_resp(kbd, ackResp,COUNTOF(ackResp)); + kbd->read_code_action = cmd; + kbd->sink.onCommand = vkbd_read_codes; + break; + case 0xFA: + case 0xF9: + case 0xF8: + case 0xF7: + case 0xF6: + case 0xF5: + case 0xF4: //Enable + kbd->Enabled=TRUE; + vkbd_send_resp(kbd, ackResp,COUNTOF(ackResp)); + break; + // + //Set Typeatic Rate/Delay + // + case 0xF3: + vkbd_send_resp(kbd, ackResp,COUNTOF(ackResp)); + kbd->sink.onCommand = vkbd_read_option; + kbd->option_ptr = &kbd->typematicRateDelay; + break; + case 0xF2: + vkbd_send_resp(kbd, IdResp,COUNTOF(IdResp)); + break; + case 0xF0: + vkbd_send_resp(kbd, ackResp,COUNTOF(ackResp)); + kbd->sink.onCommand = vkbd_rw_scancode; + kbd->option_ptr = &kbd->scancodepage; + break; + // + //Ehco + // + case 0xEE: + vkbd_send_resp(kbd, &cmd, 1); + break; + + // + //Led + // + case 0xED: + vkbd_send_resp(kbd, ackResp, COUNTOF(ackResp)); + kbd->sink.onCommand = vkbd_read_option; + kbd->option_ptr = &kbd->typematicRateDelay; + CmdED = 1; + break; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: vkbd_read_codes +// +// Description: Keyboard Read Codes. +// +// Input: ps2dev - pointer to the KBD structure +// Cmd - Data from the kbc buffer +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void vkbd_read_codes(PS2SINK* ps2dev, UINT8 cmd ) +{ + VIRTKBD* kbd = _CR(ps2dev,VIRTKBD,sink); + if( cmd >= 0xED ){ + kbd->sink.onCommand = kbd_scanning; + kbd_scanning(ps2dev,cmd); + } else + vkbd_send_resp(kbd, ackResp,COUNTOF(ackResp)); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: vkbd_read_option +// +// Description: Keyboard Read option. +// +// Input: ps2dev - pointer to the KBD structure +// Cmd - Data from the kbc buffer +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void vkbd_read_option(PS2SINK* ps2dev, UINT8 cmd ) +{ + VIRTKBD* kbd = _CR(ps2dev,VIRTKBD,sink); + UINT8* fPtr; + + kbd->sink.onCommand = kbd_scanning; + + if (CmdED == 1) { + fPtr = (UINT8*)(UINTN)0x417; + *fPtr &= ~0x70; + *fPtr |= ((cmd & 0x07) << 4); + CmdED = 0; + vkbd_send_resp(kbd, ackResp,COUNTOF(ackResp)); + } + else { + if (cmd > 0xED) { + kbd_scanning(ps2dev,cmd); + } else { + *(kbd->option_ptr) = cmd; + vkbd_send_resp(kbd, ackResp,COUNTOF(ackResp)); + } + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: vkbd_rw_scancode +// +// Description: Keyboard Read write Scan code. +// +// Input: ps2dev - pointer to the KBD structure +// Cmd - Data from the kbc buffer +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void vkbd_rw_scancode(PS2SINK* ps2dev, UINT8 cmd ) +{ + VIRTKBD* kbd = _CR(ps2dev,VIRTKBD,sink); + if(cmd != 0 ) + vkbd_read_option(ps2dev,cmd); + else { + kbd->sink.onCommand = kbd_scanning; + ScanCodePageResp[1] = kbd->scancodepage; + vkbd_send_resp(kbd, ScanCodePageResp,COUNTOF(ScanCodePageResp)); + } +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: vkbd_send_resp +// +// Description: Place the Responce bytes in the keyboard buffer. +// +// Input: ps2dev - pointer to the KBD structure +// Data - Pointer to the Data +// count - Length of the data +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void vkbd_send_resp(VIRTKBD* kbd, UINT8* data, int count ) +{ + if( kbd->sink.present_ ){ + // + // Emulation must provide the responce. Override any pervious kbd data queued to KBC + // + kbd->qtail = kbd->qhead = kbd->queue; + for( ; count > 0; --count ){ + *kbd->qtail++ = *data++; + } + + // + // push the first byte to the KBC + // + if( kbd->qhead != kbd->qtail && + kbd->sink.kbc->send_outb1(kbd->sink.kbc, + PS2DEV_KBD,TRUE,*kbd->qhead)) + { + if(++kbd->qhead >= kbd->queue+KBDQUEUE_SIZE) + kbd->qhead = kbd->queue; + } + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: vkbd_pumpQueue +// +// Description: KBC has empty queue; Legacy I/O trapping is being processed.If Kbd has data to push into KBC, +// now is a good time to do it +// +// Input: ps2dev - pointer to the KBD structure +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +void vkbd_pumpQueue(PS2SINK* ps2dev) +{ + VIRTKBD* kbd = _CR(ps2dev,VIRTKBD,sink); + // + //send the Keyboard data to the KBC + // + if( kbd->qhead != kbd->qtail && + ps2dev->kbc->send_outb1(ps2dev->kbc,PS2DEV_KBD,FALSE,*kbd->qhead)) + { + if(++kbd->qhead >= kbd->queue+KBDQUEUE_SIZE) + kbd->qhead = kbd->queue; + } + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: kbdInput_Send +// +// Description: Keyboard Input source sends data. Put the data into the buffer, attempt to send the first byte. +// The call comes outside of Trapping Leg access. Check that Trapping status will not be overriden +// +// Input: P - pointer to the Emulation Protocol +// Buffer - Data buffer +// Count - Buffer Length +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS kbdInput_Send(EFI_EMUL6064KBDINPUT_PROTOCOL* p, UINT8* buffer, UINT32 count) +{ + VIRTKBD* kbd = _CR(p,VIRTKBD,kbdInput_); + UINTN c = 0; + + // + //Keyboard is disabled by KBC command + // + if(!kbd->Enabled) { + return EFI_DEVICE_ERROR; + } + + // + // count of free items in the queue + // + if( kbd->qtail >= kbd->qhead ) + c = KBDQUEUE_SIZE - (kbd->qtail - kbd->qhead); + else + c = kbd->qhead - kbd->qtail; + + if(c < count ) + return EFI_NOT_AVAILABLE_YET; + + for( ; count > 0; --count ){ + *kbd->qtail++ = *buffer++; + if(kbd->qtail >= kbd->queue+KBDQUEUE_SIZE) + kbd->qtail = kbd->queue; + } + // + //Place the first data into the KBC buffer + // + vkbd_pumpQueue(&kbd->sink); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: kbdInput_GetTranslation +// +// Description: KBC translation +// +// Input: P - pointer to the Emulation Protocol +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS kbdInput_GetTranslation( + EFI_EMUL6064KBDINPUT_PROTOCOL* p, + OUT KBC_KBDTRANSLATION* outTrans ) +{ + *outTrans=KBC_KBDTRANS_PCXT; + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: kbdInput_updateLED +// +// Description: Update the keyboard LED's +// +// Input: P - pointer to the Emulation Protocol +// Data - LED data +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS kbdInput_updateLED( + EFI_EMUL6064KBDINPUT_PROTOCOL* p, + IN UINT8 data ) +{ + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: vkbd_initParams +// +// Description: Initialize the KBD data +// +// Input: kbd - Pointer to the KBD structure +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void vkbd_initParams(VIRTKBD* Kbd) +{ + Kbd->Enabled = TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: InitVirtualKbd +// +// Description: Initialize the KBD data +// +// Input: kbc - pointer to the KBC Structure +// kbd - Pointer to the KBD structure +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void InitVirtualKbd(KBC* kbc, VIRTKBD* kbd ) +{ + EFI_HANDLE hEmulationService = 0; + kbd->qhead = kbd->qtail = kbd->queue; + kbd->sink.kbc = kbc; + kbd->sink.onCommand = kbd_scanning; + kbd->sink.onQueueFree = vkbd_pumpQueue; + kbd->kbdInput_.Send = kbdInput_Send; + kbd->kbdInput_.GetTranslation = kbdInput_GetTranslation; + kbd->kbdInput_.UpdateLEDState = kbdInput_updateLED; + gKbdProtocol=&kbd->kbdInput_; + vkbd_initParams(kbd); + VERIFY_EFI_ERROR( + gBS->InstallProtocolInterface(&hEmulationService, + &gEmul6064KbdInputProtocolGuid,EFI_NATIVE_INTERFACE,(void*)&kbd->kbdInput_)); +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/KbcEmul/VirtualMouse.c b/Core/EM/KbcEmul/VirtualMouse.c new file mode 100644 index 0000000..00af801 --- /dev/null +++ b/Core/EM/KbcEmul/VirtualMouse.c @@ -0,0 +1,553 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/VirtualMouse.c 6 3/04/14 6:19a Nimishsv $ +// +// $Revision: 6 $ +// +// $Date: 3/04/14 6:19a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/VirtualMouse.c $ +// +// 6 3/04/14 6:19a Nimishsv +// [TAG] EIP156041 +// [Category] Improvement +// [Description] Aptio 4.x, KbcEmulation: Send the mouse data to EBDA +// and only the last data through KBC +// [Files] VirtualMouse.c +// +// 5 2/10/11 1:08a Rameshr +// [TAG] EIP53687 +// [Category] Improvement +// [Description] AMI headers update for KbcEmulation Module +// +// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc +// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo +// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c, +// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h +// +// 4 7/08/10 2:02a Rameshr +// Ohci Emulation support Added. +// EIP 39712 +// +// 3 6/30/09 11:32a Rameshr +// Coding Standard and File header updated. +// +// 2 10/30/08 10:47a Rameshraju +// Keyboard & Mouse enable/disable command handled +// +// 1 12/14/07 10:26a Rameshraju +// Initial Check-in +//**************************************************************************** + +//<AMI_FHDR_START> +//**************************************************************************** +// Name: VirtualMouse.c +// +// Description: Handles the Virtual mouse functions +// +//**************************************************************************** +//<AMI_FHDR_END> +#include "KbcEmul.h" +#include "KbcDevEmul.h" + +#define COUNTOF(x) (sizeof(x)/sizeof(x[0])) + +static UINT8 resetResp[] = {0xFA, 0xAA, 0x00 } ; +static UINT8 statusResp[] = {0xFA, 0x20, 0x02, 0x64 } ; +static UINT8 dataResp[] = {0xFA, 0x08, 0x00, 0x0 } ; +static UINT8 ackResp[] = {0xFA}; +static UINT8 idResp[] = {0xFA, 0}; +static UINT8 unknResp[] = {0xFE }; + +void mouse_reciev_option(PS2SINK* mouse, UINT8 cmd ); +void mouse_initParams(VIRTMOUSE* mouse); +void vmouse_flushBuffer(VIRTMOUSE* mouse); +void vmouse_send_resp(VIRTMOUSE* mouse, UINT8* data, int count ); +void mouse_echo(PS2SINK* mouse, UINT8 cmd ); +BOOLEAN SendMouseBuffer(VIRTMOUSE* mouse, UINT8* packet, UINTN Count ); +void vmouse_pumpQueue(PS2SINK* ps2dev); +extern GenerateIRQ12(VIRTKBC*); + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: mouse_idle +// +// Description: Handle commands sent from KBC to PS2 Mouse. Mouse idle, waiting for command or key +// +// Input: ps2dev - pointer to the Mouse structure +// Cmd - Data from the kbc buffer +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void mouse_idle(PS2SINK* ps2dev, UINT8 cmd ) +{ + VIRTMOUSE* mouse = (VIRTMOUSE*)ps2dev; + + switch(cmd){ + // + //reset + // + case 0xFF: + mouse_initParams(mouse); + vmouse_send_resp(mouse, resetResp,COUNTOF(resetResp)); + break; + // + //report status + // + case 0xE9: + vmouse_send_resp(mouse, statusResp,COUNTOF(statusResp)); + break; + // + //read data + // + case 0xEB: + MemCpy(dataResp+1,&mouse->dataPacket,sizeof(mouse->dataPacket)); + vmouse_flushBuffer(mouse); + vmouse_send_resp(mouse, dataResp,COUNTOF(dataResp)); + break; + // + //Enable Mouse + // + case 0xF4: + mouse->Enabled = TRUE; + vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + break; + // + //Disable Mouse + // + case 0xF5: + mouse->Enabled = FALSE; + vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + break; + // + //Set Streaming + // + case 0xEA: + mouse->streaming = 1; + vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + break; + // + //Set Remote + // + case 0xF0: + mouse->streaming = 0; + vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + break; + // + //Set Standard, Set Scaling and Reset Scaling + // + case 0xF6: + case 0xE6: + case 0xE7: + vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + break; + // + //Identify + // + case 0xF2: + vmouse_send_resp(mouse, idResp,COUNTOF(idResp)); + break; + + // + // set resolution + // + case 0xE8: + mouse->option_ptr = &mouse->resolution_; + ps2dev->onCommand = mouse_reciev_option; + vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + break; + // + // set sampling rate + // + case 0xF3: + mouse->option_ptr = &mouse->samplingRate_; + ps2dev->onCommand = mouse_reciev_option; + vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + break; + case 0xEE: + vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + ps2dev->onCommand = mouse_echo; + break; + // + //unknown command; send FE + // + default: + vmouse_send_resp(mouse, unknResp,COUNTOF(unknResp)); + break; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: mouse_echo +// +// Description: Mouse Echo command +// +// Input: ps2dev - pointer to the Mouse structure +// Cmd - Data from the kbc buffer +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void mouse_echo(PS2SINK* ps2dev, UINT8 cmd ) +{ + VIRTMOUSE* mouse = (VIRTMOUSE*)ps2dev; + if( cmd == 0xEC ){ + ps2dev->onCommand = mouse_idle; + vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); + } else + vmouse_send_resp(mouse, &cmd,1); + +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: mouse_reciev_option +// +// Description: Mouse reciev command +// +// Input: ps2dev - pointer to the KBD structure +// Cmd - Data from the kbc buffer +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void mouse_reciev_option(PS2SINK* ps2dev, UINT8 cmd ) +{ + VIRTMOUSE* mouse = (VIRTMOUSE*)ps2dev; + *(mouse->option_ptr) = cmd; + ps2dev->onCommand = mouse_idle; + vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp)); +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: msInput_Send +// +// Description: Mouse Input source sends data. Put the data into the buffer, attempt to send the first byte. +// The call comes outside of Trapping Leg access. Check that Trapping status will not be overriden +// +// Input: P - pointer to the Emulation Protocol +// Data - Ps2 mouse Data +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS EFIAPI msInput_Send( + IN EFI_EMUL6064MSINPUT_PROTOCOL * This, + IN PS2MouseData* data + ) +{ + VIRTMOUSE* mouse = _CR(This,VIRTMOUSE,msInput_); +#if USB_MOUSE_UPDATE_EBDA_DATA + UINT16 ebdaSeg = *(UINT16*)0x40E; + UINT8 *ebda = (UINT8*)((UINTN)ebdaSeg<<4); + + // Return EFI NOT READY if EBDA has some data. + // Let USB resend the data if the EBDA is not empty + if ( 0 != ebda[0x26] ) { + return EFI_NOT_READY; + } +#endif + // + //clear all previous flags except overflow + // + mouse->dataPacket.flags &= (PS2MSFLAGS_XO|PS2MSFLAGS_YO); + // + //copy overflow and button flags from new packet + // + mouse->dataPacket.flags |= data->flags & ~(PS2MSFLAGS_XSIGN|PS2MSFLAGS_YSIGN); + mouse->dataPacket.flags |= 0x8; + if( (mouse->dataPacket.flags & PS2MSFLAGS_XO) == 0){ + if(data->flags & PS2MSFLAGS_XSIGN){ + mouse->x += (signed short)((UINT8)data->x | 0xFF00); + } else { + mouse->x += data->x; + } + mouse->dataPacket.x = (UINT8)(UINT32)(mouse->x); + if( mouse->x < 0 ){ + mouse->dataPacket.flags |= PS2MSFLAGS_XSIGN; + if( mouse->x < -256 ) + mouse->dataPacket.flags |= PS2MSFLAGS_XO; + } else { + if( mouse->x > 256 ) + mouse->dataPacket.flags |= PS2MSFLAGS_XO; + } + } + + if( (mouse->dataPacket.flags & PS2MSFLAGS_YO) == 0){ + if(data->flags & PS2MSFLAGS_YSIGN){ + mouse->y += (signed short)((UINT8)data->y | 0xFF00); + } else { + mouse->y += data->y; + } + mouse->dataPacket.y = (UINT8)(UINT32)(mouse->y); + if( mouse->y < 0 ){ + mouse->dataPacket.flags |= PS2MSFLAGS_YSIGN; + if( mouse->y < -256 ) + mouse->dataPacket.flags |= PS2MSFLAGS_YO; + } else{ + if( mouse->y > 256 ) + mouse->dataPacket.flags |= PS2MSFLAGS_YO; + } + } + + mouse->fFreshPacket = 1; + if( mouse->Enabled && mouse->streaming ){ + if( SendMouseBuffer(mouse,(UINT8*)&mouse->dataPacket,sizeof(mouse->dataPacket))) + { + vmouse_flushBuffer(mouse); + } + } + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SendMouseBuffer +// +// Description: Send the mouse packet to KBC +// +// Input: Mouse - pointer to the Mouse Structure +// Packetr - Mouse Data +// Count - Data Length +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN SendMouseBuffer(VIRTMOUSE* mouse, UINT8* packet, UINTN Count ) +{ + UINTN FreeQueue = 0; +#if USB_MOUSE_UPDATE_EBDA_DATA + UINT16 ebdaSeg = *(UINT16*)0x40E; + UINT8 *ebda = (UINT8*)((UINTN)ebdaSeg<<4); + UINT8 packageSize = ebda[0x27] & 7; + UINT8 index=0; +#endif + // + // count of free items in the queue + // + if( mouse->qtail >= mouse->qhead ) + FreeQueue = MOUSEQUEUE_SIZE - (mouse->qtail - mouse->qhead); + else + FreeQueue = mouse->qhead - mouse->qtail; + + if(FreeQueue < Count ) + return TRUE; + + // + //place the Mouse data in mouse buffer + // + for( ; Count > 0; --Count ){ + *mouse->qtail++ = *packet++; + if(mouse->qtail >= mouse->queue+MOUSEQUEUE_SIZE) + mouse->qtail = mouse->queue; + } + + // + //Place the dummy 4th byte in mouse buffer, + // +// *mouse->qtail++ = 0; +// if(mouse->qtail >= mouse->queue+MOUSEQUEUE_SIZE) +// mouse->qtail = mouse->queue; + +#if USB_MOUSE_UPDATE_EBDA_DATA + // Write the 1st two bytes of mouse packet to EBDA and last byte to KBC + for (; index<=packageSize; index++) { + if (index == 0) { + ebda[0x28+index] = *mouse->qhead; + ebda[0x26]++; + if(++mouse->qhead >= mouse->queue+MOUSEQUEUE_SIZE) + mouse->qhead = mouse->queue; + } + if (index == 1) { + ebda[0x28+index] = *mouse->qhead; + ebda[0x26]++; + if(++mouse->qhead >= mouse->queue+MOUSEQUEUE_SIZE) + mouse->qhead = mouse->queue; + } + if (index == 2) { + vmouse_pumpQueue(&mouse->sink); + } + } +#else + //Put the first byte in the KBC buffer + vmouse_pumpQueue(&mouse->sink); +#endif + + return TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: vmouse_pumpQueue +// +// Description: KBC has empty queue; Legacy I/O trapping is being processed.If mouse has data to push into KBC, +// now is a good time to do it +// +// Input: ps2dev - pointer to the Mouse structure +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void vmouse_pumpQueue(PS2SINK* ps2dev) +{ + VIRTMOUSE* mouse = (VIRTMOUSE*)ps2dev; + + // + //Put the data into KBC + // + if((mouse->qhead != mouse->qtail) && (ps2dev->kbc->send_outb1(ps2dev->kbc,PS2DEV_MOUSE,FALSE,*mouse->qhead))) { + if(++mouse->qhead >= mouse->queue+MOUSEQUEUE_SIZE) + mouse->qhead = mouse->queue; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: vmouse_send_resp +// +// Description: Place the Response bytes in the keyboard buffer. +// +// Input: Mousev - pointer to the Mouse structure +// Data - Pointer to the Data +// count - Length of the data +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void vmouse_send_resp(VIRTMOUSE* mouse, UINT8* data, int count ) +{ + if(mouse->sink.present_ ){ + // + // Emulation must provide the response. Override any previos mouse data queued to KBC + // + mouse->qtail = mouse->qhead = mouse->queue; + for( ; count > 0; --count ){ + *mouse->qtail++ = *data++; + } + + /// + // push the first byte to the KBC + // + if( mouse->qhead != mouse->qtail && + mouse->sink.kbc->send_outb1(mouse->sink.kbc, + PS2DEV_MOUSE,TRUE,*mouse->qhead)) + { + if(++mouse->qhead >= mouse->queue+MOUSEQUEUE_SIZE) + mouse->qhead = mouse->queue; } + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: vmouse_flushBuffer +// +// Description: Clear the mouse data buffer that tracks the mouse changes; after the data is cleared any data read +// will return zero (x,y) and current buttons state. +// +// Input: ps2dev - pointer to the KBD structure +// Cmd - Data from the kbc buffer +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void vmouse_flushBuffer(VIRTMOUSE* mouse) +{ + mouse->x = mouse->y = 0; + mouse->dataPacket.x = mouse->dataPacket.y = 0; + mouse->dataPacket.flags &= (PS2MSFLAGS_LBUTTON|PS2MSFLAGS_RBUTTON); + mouse->fFreshPacket = 0; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: mouse_initParams +// +// Description: Initialize the mouse data +// +// Input: kbd - Pointer to the mouse structure +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void mouse_initParams(VIRTMOUSE* mouse) +{ + mouse->samplingRate_ = 0x64; + mouse->resolution_ = 2; + mouse->option_ptr = 0; + mouse->Enabled = FALSE; + mouse->streaming = 1; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: InitVirtualMouse +// +// Description: Initialize the Mouse data +// +// Input: kbc - pointer to the KBC Structure +// Mouse - Pointer to the Mouse structure +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void InitVirtualMouse(KBC* kbc, VIRTMOUSE* mouse ) +{ + EFI_HANDLE hEmulationService = 0; + + mouse->qhead = mouse->qtail = mouse->queue; + mouse->sink.kbc = kbc; + mouse->sink.onCommand = mouse_idle; + mouse->sink.onQueueFree = vmouse_pumpQueue; + mouse->msInput_.Send = msInput_Send; + mouse->x = mouse->y = 0; + mouse->dataPacket.flags = 0x8; + mouse->dataPacket.x = 0; + mouse->dataPacket.y = 0; + mouse->fFreshPacket = 0; + mouse_initParams(mouse); + VERIFY_EFI_ERROR( + gBS->InstallProtocolInterface(&hEmulationService, + &gEmul6064MsInputProtocolGuid,EFI_NATIVE_INTERFACE,(void*)&mouse->msInput_)); +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** |