UEFI Simple Pointer Protocol

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
ronsor
Member
Member
Posts: 27
Joined: Wed Jan 25, 2017 5:31 pm
Libera.chat IRC: Ronsor

UEFI Simple Pointer Protocol

Post by ronsor »

I am trying to use the UEFI Simple Pointer Protocol but I always get the "EFI_NOT_READY" error:

Code: Select all

	EFI_SIMPLE_POINTER_PROTOCOL* spp;
	EFI_SIMPLE_POINTER_STATE ps;
void InitMouse() {
	EFI_GUID sppg = EFI_SIMPLE_POINTER_PROTOCOL_GUID;
        EFI_HANDLE* handle_buffer;
	UINTN handle_count = 0;
        EFI_STATUS statusx = BS->LocateHandleBuffer( ByProtocol,
                                      &sppg,
                                      NULL,
                                      &handle_count,
                                      &handle_buffer );
	if ( EFI_ERROR(statusx) ) panic("UEFI broken");
        EFI_STATUS status = BS->HandleProtocol( handle_buffer[0],
                                  &sppg,
                                  (VOID **)&spp );
	if (EFI_ERROR(status)) {
		panic("Mouse required!");
	}
	EFI_STATUS xx = spp->Reset(spp, FALSE);
	if ( EFI_ERROR(xx) ) {
		panic("Failed to initialize pointy I/O");
	}
	
}
void UpdateMouse() {
	WaitForSingleEvent(spp->WaitForInput, 0);
	EFI_STATUS x = spp->GetState(spp, &ps);
	printf("%d, %d, %d\n", ps.RelativeMovementX, ps.RelativeMovementY, ps.RelativeMovementZ);
	if ( x == EFI_NOT_READY ) printf("Not ready");
	if ( x == EFI_DEVICE_ERROR ) panic("Error");
}
/*
 void panic(char *msg) -- Print error and halt
 int printf(char *format, ...) -- Standard printf implementation
*/
User avatar
zaval
Member
Member
Posts: 659
Joined: Fri Feb 17, 2017 4:01 pm
Location: Ukraine, Bachmut
Contact:

Re: UEFI Simple Pointer Protocol

Post by zaval »

What's WaitForSingleEvent()? I can't find it among UEFI BS. Anyway, you should check its return value. You had to use WaitForEvent() service, checking its retrun value. You omit this and that could be a problem.
Next, the spec says this:
If the state of the pointer device has not changed since the last call to GetState(), then EFI_NOT_READY is returned.
So maybe you didn't move it move it. lol. Probably you check not what you think it is. Your init and "update" sequence looks incomplete. Are you sure you have connected to the mouse handle? How many handles are returned by LocateHandleProtocol()? You just take first.
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).
ronsor
Member
Member
Posts: 27
Joined: Wed Jan 25, 2017 5:31 pm
Libera.chat IRC: Ronsor

Re: UEFI Simple Pointer Protocol

Post by ronsor »

zaval wrote:What's WaitForSingleEvent()? I can't find it among UEFI BS. Anyway, you should check its return value. You had to use WaitForEvent() service, checking its retrun value. You omit this and that could be a problem.
Next, the spec says this:
If the state of the pointer device has not changed since the last call to GetState(), then EFI_NOT_READY is returned.
So maybe you didn't move it move it. lol. Probably you check not what you think it is. Your init and "update" sequence looks incomplete. Are you sure you have connected to the mouse handle? How many handles are returned by LocateHandleProtocol()? You just take first.
Only one handle is returned (I checked); honestly I have no examples for this so I'm not even sure if I'm missing something. And I did move the mouse.
User avatar
zaval
Member
Member
Posts: 659
Joined: Fri Feb 17, 2017 4:01 pm
Location: Ukraine, Bachmut
Contact:

Re: UEFI Simple Pointer Protocol

Post by zaval »

What about WaitForEvent() function? Does it return EFI_SUCCESS?
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).
ronsor
Member
Member
Posts: 27
Joined: Wed Jan 25, 2017 5:31 pm
Libera.chat IRC: Ronsor

Re: UEFI Simple Pointer Protocol

Post by ronsor »

zaval wrote:What about WaitForEvent() function? Does it return EFI_SUCCESS?
WaitForSingleEvent with a '0' timeout just calls WaitForEvent; I have tested both functions and neither returns -- ever. It keeps waiting for a mouse event.
User avatar
zaval
Member
Member
Posts: 659
Joined: Fri Feb 17, 2017 4:01 pm
Location: Ukraine, Bachmut
Contact:

Re: UEFI Simple Pointer Protocol

Post by zaval »

Then it seems not working properly.
Check its Mode structure. What it reports. Maybe there are only zeros, meaning basically lack of support.
Also you might take a look at EFI_DEVICE_PATH_PROTOCOL instance installed on the same handle as the EFI_SIMPLE_POINTER_PROTOCOL instance. It should be installed. And should match the type of mouse (PS/2, USB, serial).
Probably mouse handling is broken at your UEFI fw.
Also, you might try to ConnectController(), in your init routine, on the handle, returned by LocateDevicePath() with the device path obtained from your handle. Probably the driver installed the protocol, but actually never was connected (its Supported/Start routines never were called and thus initialization didn't occur).
Follow this example (version 2.4, page 181)

Code: Select all

EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
EFI_HANDLE Handle;

do {
//
// Find the handle that best matches the Device Path. If it is only a
// partial match the remaining part of the device path is returned in
// RemainingDevicePath.
//
RemainingDevicePath = DevicePath;
Status = gBS->LocateDevicePath (
&gEfiDevicePathProtocolGuid,
&RemainingDevicePath,
&Handle
);
if (EFI_ERROR(Status)) {
return EFI_NOT_FOUND;
}
//
// Connect all drivers that apply to Handle and RemainingDevicePath
// If no drivers are connected Handle, then return EFI_NOT_FOUND
// The Recursive flag is FALSE so only one level will be expanded.
//
Status = gBS->ConnectController (
Handle,
NULL,
RemainingDevicePath,
FALSE
);
if (EFI_ERROR(Status)) {
return EFI_NOT_FOUND;
}
// Loop until RemainingDevicePath is an empty device path
//
} while (!IsDevicePathEnd (RemainingDevicePath));
//
// A handle with DevicePath exists in the handle database
//
return EFI_SUCCESS;
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).
ronsor
Member
Member
Posts: 27
Joined: Wed Jan 25, 2017 5:31 pm
Libera.chat IRC: Ronsor

Re: UEFI Simple Pointer Protocol

Post by ronsor »

The mode structure reports "65535" for maximum resolution for X, Y, Z and for the left/right buttons "1"
User avatar
zaval
Member
Member
Posts: 659
Joined: Fri Feb 17, 2017 4:01 pm
Location: Ukraine, Bachmut
Contact:

Re: UEFI Simple Pointer Protocol

Post by zaval »

Well, I only can repeat the suggestion to go through ConnectController() burden, see above. Because probably, somehow, the appropriate driver for mouse was loaded and it installed the needed protocol on the handle, but never have been connected to the controller. Try to connect it in your init function, as described in the example. Read carefully the second example in the ConnectController() desciption. It's page 181 in the 2.4 version of the spec.
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).
ronsor
Member
Member
Posts: 27
Joined: Wed Jan 25, 2017 5:31 pm
Libera.chat IRC: Ronsor

Re: UEFI Simple Pointer Protocol

Post by ronsor »

I have concluded QEMU OVMF TIANOCORE UEFI firmware does not support the simple pointer protocol.
Post Reply