On 08/28/14 19:35, Andrew Fish wrote:
> 
> On Aug 28, 2014, at 8:46 AM, Laszlo Ersek <[email protected]> wrote:
> 
>> On 08/28/14 17:17, Peter Maydell wrote:
>>> On 28 August 2014 16:16, Laszlo Ersek <[email protected]> wrote:
>>>> On 08/28/14 16:59, Ard Biesheuvel wrote:
>>>>> However, putting a vector table in that particular place is
>>>>> troublesome, as the whole point of having the region is to avoid
>>>>> putting a Firmware Volume (FV) there. And having to code the whole
>>>>> vector table in hex inside the DATA = { } is not a great prospect
>>>>> either.
>>>
>>> This just seems like a flaw in UEFI to me. You really need to
>>> be able to write bits of custom assembly and data to low memory.
>>
> 

> It is the ARM architecture that places the reset vector at
> exception/vector zero. In x86 it is at the magic address, 0xFFFFFFF0,
> and not associated with exceptions/interrupts.
> 
> The PI spec reserves the 1st 16 bytes of the FV, the ZeroVector[],
> for use by the build system if needed for the ARM reset vector.
> 
> The edk2 system will patch a branch to the entry point of the SEC
> module into the ZeroVector of the FV header if the FV contains a SEC
> module.
> 
> When you have memory, or temporary PEI memory. Having memory is also
> known as you are able to run C code. At this point you can relocate
> the vectors and handle exceptions.
> 
> You can always offset the FV into the FD, and make the beginning of
> the FD a vector table. As long as the reset vector branches to the
> start of the FV (which will branch to the start of SEC) it will work
> just fine.
> 

>> I think I can agree that this may be a limitation of the edk2 build
>> system (not "UEFI" in general). I have read complaints before that DATA
>> = { } regions in FDF files are a pain to format, especially in an
>> automated way.
>>
>> As a workaround, sometimes people write Python scripts (which they
>> commit to the tree) that process custom source files (which they also
>> commit to the tree). These source files can be assembly language files
>> that are not covered by the normal edk2 build process. The python
>> script(s) can invoke custom assemblers, binutils, hexdump as well, and
>> the output can be some FDF.inc file (which is also committed to the tree).
>>
>> The "main" FDF file can then !include this generated FDF.inc.
>>
>> In these cases the development process goes like:
>> - if you need to update your custom code, update the assembly file,
>> - regenerate the FDF.inc by manually re-running the python script,
>> - commit the changes together (changed assembly src + FDF.inc),
>> - the next build will pick up the new FDF.inc.
>>
> 

> I don’t really understand what all this is for? If some one could
> explain the requirements we could probably add a feature to the edk2
> build system to fix this.
> 
> To see what the build system does today look at:
> https://svn.code.sf.net/p/edk2/code/trunk/edk2/BaseTools/Source/C/GenFv/GenFvInternalLib.c
> 
> EFI_STATUS
> UpdateArmResetVectorIfNeeded (
>   IN MEMORY_FILE            *FvImage,
>   IN FV_INFO                *FvInfo
>   )
> /*++
> 
> Routine Description:
>   This parses the FV looking for SEC and patches that address into the 
>   beginning of the FV header.
> 
>   For ARM32 the reset vector is at 0x00000000 or 0xFFFF0000.
>   For AArch64 the reset vector is at 0x00000000.
> 
>   This would commonly map to the first entry in the ROM. 
>   ARM32 Exceptions:
>   Reset            +0    
>   Undefined        +4
>   SWI              +8
>   Prefetch Abort   +12
>   Data Abort       +16
>   IRQ              +20
>   FIQ              +24
> 
>   We support two schemes on ARM.
>   1) Beginning of the FV is the reset vector
>   2) Reset vector is data bytes FDF file and that code branches to reset 
> vector 
>     in the beginning of the FV (fixed size offset).
> 
>   Need to have the jump for the reset vector at location zero.
>   We also need to store the address or PEI (if it exists).
>   We stub out a return from interrupt in case the debugger 
>    is using SWI (not done for AArch64, not enough space in struct).
>   The optional entry to the common exception handler is 
>    to support full featured exception handling from ROM and is currently 
>     not support by this tool.

The FDF under review follows exactly scheme 2. The FD starts with a DATA
region that starts with a manually encoded branch instruction to 0x1000.
The DATA region encodes this branch instruction in 4 bytes, and the rest
(4092 byes) come from the ErasePolarity-matching padding.

The FV is indeed offset into the FD with 0x1000 bytes, starting right
after the DATA region.

As you say, the build system (apparently) patches the start of the FV
itself (which is located at offset 0x1000 in the FD) so that it branches
to the SEC entry point. Hence I think this "double trampoline" that you
described is exactly the case.

What Peter suggested (I think) is that we build a complete exception
vector table in those 4092 bytes, past the 4-byte long reset vector at
0x0. And, in addition to the exception vector table, even a simple
exception handler routine should be implemented there (in assembly of
course), referenced by the vectors, that dumps the exception details to
the virtual serial port (or some QEMU-specific MMIO debug register etc).

Since encoding such stuff manually in a DATA = { ... } region in the FDF
file is messy, I proposed a python script that assembles (with external
tools of course) a standalone assembly file (which implements the vector
table and the exception handler), hexdumps the binary output, wraps it
in a DATA = { ... } "shell", and saves the output in an FDF include
file. Then, the main FDF file would not contain the current DATA = { ...
} block (with just the 4-byte b insn to 0x1000), it would include the
complete DATA block from the include file that the python script
generated, and that contains the hexdump of the complete vector table +
the assembled exception handler.

This would allow (very basic) exception handling while running from NOR
flash.

Of course temporary RAM becomes available very soon, so the vector table
could be set up in that temporary RAM quite early. (... Perhaps in code
that is shared by all of the ARM platforms.)

... I think such a feature is useful to investigate, but very much out
of scope for this series.

Thanks,
Laszlo


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to