diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /Core/EM/KbcEmul/LegacyMouse.c | |
download | zprj-master.tar.xz |
Diffstat (limited to 'Core/EM/KbcEmul/LegacyMouse.c')
-rw-r--r-- | Core/EM/KbcEmul/LegacyMouse.c | 553 |
1 files changed, 553 insertions, 0 deletions
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 ** +//** ** +//********************************************************************** +//********************************************************************** |