Discussion:
EFI callback workings...
Jarrod B Johnson
2011-08-16 17:49:56 UTC
Permalink
So I'm working on implementing support in netfs for IPXE download protocol,
if available.

The thing I'm hitting is that when iPXE goes to invoke the callback, the
argument list seems reversed. I know how to kind of brute force this
scenario, but was wondering if there was some more sane looking way to
cope.

For example, assume:
iPXE calls data callback with:
*context, *buffer, length, offset
0xaddf, 0xcdde, 1024, 0

And if I have elilo print out the arguments in order, I get:
0, 1024, 0xcdde, 0xaddf

I see quite a bit of dancing in gnu-efi to have code call into uefi
provided functions, but wasn't clear on the converse...
Jarrod B Johnson
2011-08-16 19:21:18 UTC
Permalink
Ok, figured it out through careful examination of uefi_call_wrapper and the
assembly that backed it.

It wasn't reversed, it was just that the 3rd and 4th arguments happened to
be zero and thus matched RDI and RSI, and gave the appearance of reversed
if you assume too easily.

So in GCC world, we seem to expect the caller to have done rdi, rsi, rdx,
rcx, r8, r9. However, in UEFI world the MS convention is king and so rdi
and rsi are meaningless, rdx and rcx are swapped, and r8 and r9 are in
order, just off by two. Thankfully, I don't need more than 4 arguments to
figure out the other magic.

Perusing through, I didn't see any documentation or facility for the
converse of uefi_call_wrapper to rearrange the stack in the way a gcc would
work. Any thoughts?



From: Jarrod B Johnson/Raleigh/***@IBMUS
To: elilo-discuss-5NWGOfrQmneRv+***@public.gmane.org
Date: 08/16/2011 01:51 PM
Subject: [elilo-discuss] EFI callback workings...



So I'm working on implementing support in netfs for IPXE download protocol,
if available.

The thing I'm hitting is that when iPXE goes to invoke the callback, the
argument list seems reversed. I know how to kind of brute force this
scenario, but was wondering if there was some more sane looking way to
cope.

For example, assume:
iPXE calls data callback with:
*context, *buffer, length, offset
0xaddf, 0xcdde, 1024, 0

And if I have elilo print out the arguments in order, I get:
0, 1024, 0xcdde, 0xaddf

I see quite a bit of dancing in gnu-efi to have code call into uefi
provided functions, but wasn't clear on the converse...
S***@public.gmane.org
2011-08-16 19:24:37 UTC
Permalink
The calling conventions are detailed here, in case it helps.

http://en.wikipedia.org/wiki/X86_calling_conventions



From: Jarrod B Johnson [mailto:jbjohnso-r/Jw6+rmf7HQT0dZR+***@public.gmane.org]
Sent: Tuesday, August 16, 2011 2:21 PM
To: Jarrod B Johnson
Cc: elilo-discuss-5NWGOfrQmneRv+***@public.gmane.org
Subject: Re: [elilo-discuss] EFI callback workings...


Ok, figured it out through careful examination of uefi_call_wrapper and the assembly that backed it.

It wasn't reversed, it was just that the 3rd and 4th arguments happened to be zero and thus matched RDI and RSI, and gave the appearance of reversed if you assume too easily.

So in GCC world, we seem to expect the caller to have done rdi, rsi, rdx, rcx, r8, r9. However, in UEFI world the MS convention is king and so rdi and rsi are meaningless, rdx and rcx are swapped, and r8 and r9 are in order, just off by two. Thankfully, I don't need more than 4 arguments to figure out the other magic.

Perusing through, I didn't see any documentation or facility for the converse of uefi_call_wrapper to rearrange the stack in the way a gcc would work. Any thoughts?

[cid:image001.gif-***@public.gmane.org]Jarrod B Johnson---08/16/2011 01:51:25 PM---So I'm working on implementing support in netfs for IPXE download protocol, if available.

From: Jarrod B Johnson/Raleigh/***@IBMUS
To: elilo-discuss-5NWGOfrQmneRv+***@public.gmane.org
Date: 08/16/2011 01:51 PM
Subject: [elilo-discuss] EFI callback workings...

________________________________



So I'm working on implementing support in netfs for IPXE download protocol, if available.

The thing I'm hitting is that when iPXE goes to invoke the callback, the argument list seems reversed. I know how to kind of brute force this scenario, but was wondering if there was some more sane looking way to cope.

For example, assume:
iPXE calls data callback with:
*context, *buffer, length, offset
0xaddf, 0xcdde, 1024, 0

And if I have elilo print out the arguments in order, I get:
0, 1024, 0xcdde, 0xaddf

I see quite a bit of dancing in gnu-efi to have code call into uefi provided functions, but wasn't clear on the converse...------------------------------------------------------------------------------
uberSVN's rich system and user administration capabilities and model
configuration take the hassle out of deploying and managing Subversion and
the tools developers use with it. Learn more about uberSVN and get a free
download at: http://p.sf.net/sfu/wandisco-dev2dev
Jarrod B Johnson
2011-08-16 19:29:42 UTC
Permalink
1. That is what I'm writing.
2. iPXE can load a linux kernel in 'DOS-like' mode, but if it is compiled
as an efi executable (e.g. the environment doesn't have INT13 and stuff),
it can't load a kernel.
3. I do that.
4. The "IPXE Download Protocol" is a new thing, it's a UEFI protocol that
attaches to the same device handle as PxeBaseCode. While Mtftp just does
tftp, this provides full http and other protocol support. It also
functions differently. Mtftp takes a pointer to some memory space and
plops it down in one shot (from elilo perspective). iPXE protocol instead
requests a pointer to a function to call to deliver each piece of the file
(as a buffer with length and offset into the file). *Here* is where things
get wonky. When elilo calls into uefi, uefi_call_wrapper makes life nice
and happy and performs the register swaps required to act like microsoft.
In this case, an elilo provided function is faced with the naked calling
convention of UEFI (RCX, RDX, R8,R9, stack with shadowing magic), but in
the C code expects sysv abi (RDI, RSI, RDX, RCX, R8,R9, stack).

I was looking for the gnu-efi list, which I'm now convinced is the right
place. I couldn't find it. As far as I can tell, I 'need' a converse for
uefi_call_wrapper if it exists, otherwise I'll just have a big comment
block to explain why the source code calling my function doesn't match the
source code being called.



From: jfly <fleischli-Rn4VEauK+AKRv+***@public.gmane.org>
To: Jarrod B Johnson/Raleigh/***@IBMUS
Cc: elilo-discuss-5NWGOfrQmneRv+***@public.gmane.org
Date: 08/16/2011 03:00 PM
Subject: Re: [elilo-discuss] EFI callback workings...



Hi Jarrod,

I'm confused about your post here wrt elilo.
The reasons are;
1. elilo has no specific iPXE support

2. iPXE has its own bootloader capability and can boot linux
"Although its basic role was to implement a PXE stack, iPXE can be
used as a full-featured network bootloader. It can fetch files from
multiple network protocols, such as TFTP, HTTP or,
and can boot PXE, ELF, Linux, FreeBSD, multiboot, EFI and Windows CE
images. In addition, it is scriptable and can load COMBOOT and COM32
SYSLINUX extensions. This allows for instance to build a graphical
menu for network boot."

3. you can chainload ipxe via pxe.
http://www.google.com/url?sa=t&source=web&cd=2&sqi=2&ved=0CB4QFjAB&url=http%3A%2F%2Fipxe.org%2Fhowto%2Fchainloading&rct=j&q=pxe%20vs%20ipxe&ei=27hKTvXmE-WGsgKnme3mCA&usg=AFQjCNE2JxoK98OhfwLD7zlVMAHL75vnOw&cad=rja


4. ALL UEFI callbacks are provided by gnu-efi. elilo simply calls into
them and does no reordering of the PXE data that I saw and anyway
the data types and order would be established by gnu-efi according
to the protocol handle that was passed in to UEFI of which elilo
only uses
./fs/netfs.c: netfs_start(EFI_PXE_BASE_CODE *pxe)
./fs/netfs.c: status = uefi_call_wrapper(BS->HandleProtocol, 3,
dev, &PxeBaseCodeProtocol, (VOID **)&pxe);.

Perhaps your query needs to go to the gnu-efi or ipxe project lists.
Hopefully this was helpful anyway.

Regards,
-jason
Post by Jarrod B Johnson
So I'm working on implementing support in netfs for IPXE download
protocol, if available.
The thing I'm hitting is that when iPXE goes to invoke the callback,
the argument list seems reversed. I know how to kind of brute force
this scenario, but was wondering if there was some more sane looking
way to cope.
*context, *buffer, length, offset
0xaddf, 0xcdde, 1024, 0
0, 1024, 0xcdde, 0xaddf
I see quite a bit of dancing in gnu-efi to have code call into uefi
provided functions, but wasn't clear on the converse...
------------------------------------------------------------------------------
Post by Jarrod B Johnson
uberSVN's rich system and user administration capabilities and model
configuration take the hassle out of deploying and managing Subversion
and
Post by Jarrod B Johnson
the tools developers use with it. Learn more about uberSVN and get a free
download at: http://p.sf.net/sfu/wandisco-dev2dev
_______________________________________________
elilo-discuss mailing list
https://lists.sourceforge.net/lists/listinfo/elilo-discuss
Loading...