summaryrefslogtreecommitdiff
path: root/Core/EM/KbcEmul/VirtualKbd.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/KbcEmul/VirtualKbd.c')
-rw-r--r--Core/EM/KbcEmul/VirtualKbd.c456
1 files changed, 456 insertions, 0 deletions
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