This would be a great GSOC project to finish it up. 

Really nice work!

ro

On Tue Jan 20 2015 at 9:09:12 PM Scott Duplichan <scott@notabs.org> wrote:
ron minnich [mailto:rminnich@gmail.com] wrote:

]Sent: Sunday, August 10, 2014 06:34 PM
]To: Marc Jones
]Cc: Scott Duplichan; coreboot
]Subject: Re: [coreboot] why is firmware 32 bit as opposed to 64 bit
]
]I understand the arguments.
]
]It's worth remembering that coreboot has to date run on 5 different
]architectures. 4 of those used paging. The x86 has always been the
]outlier. Lack of paging has costs not discussed much. Rmodules would
]be a lot simpler if we had paging. We could make the code space
]readonly, which we should be doing anyway. We would have less fighting
]with the granularity and alignment restrictions of MTRRs. We could
]catch NULL pointers in hardware. These are clear benefits. And they
]all apply to the ramstage as well as other stages.
]
]As to 64 bit ramstage, I see lots of benefits for my use cases, but I
]may be the only one.
]
]In any event, this is all stuff that can be measured, and I propose to
]implement and measure it. Then we can see. I'm not convinced that a
]few percent either way on code size is a showstopper.

Certainly true about code size. Until coreboot starts using gcc link
time optimization, any talk of code size is out of place. By the way,
gcc link time optimization is finally working well. I got it working
with UEFI for x86, ARM, and AARCH64 (though boot testing on real
hardware was limited to x86). Gcc link time optimization should be
simpler to enable on coreboot than UEFI. This is because coreboot
doesn't replace libgcc.a like UEFI does. Here some notes on using
gcc link time optimization with UEFI: http://notabs.org/uefi/gcc-lto.htm.
I abandoned the idea of submitting a UEFI patch due to lack of interest.

Another reason to convert coreboot x86 to 64-bit mode is to avoid
negative comparisons to UEFI by those who don't know better. UEFI x86
uses 32-bit code for the first part of execution and then 64-bit for
the remainder. Some might say "x86 UEFI is 64-bit, why not coreboot?"

A big negative of using 64-bit execution is lack of source code needed
for recompile. What's the chance of getting Intel to support 64-bit
binaries for reference code? Zero, unless the UEFI guys decide to move
reference code execution to 64 bit mode.

I wanted to do an experimental proof of concept port of x86 coreboot to
64 bit mode. I was hoping to switch to 64-bit mode immediately. Running
romstage before the x64 switch is too much like UEFI, in that a whole
lot of execution runs in 32-bit mode.

I chose ASRock E350M1 for the experiment because I have the board and
the reference code is built from source. I did the conversion and got
it working on simnow. But it failed on real hardware. It turns out the
processor (and possibly all AMD processors) can't handle rom-based page
tables. I tried presetting dirty and accessed bits, along with every
MTRR cache setting. Nothing worked. It is possible Intel processors can
use rom based page tables. But I have not bothered to test that because
of lack of needed Intel reference code source.

Someone with some clout needs to request a solution from Intel and AMD.
While 32-bit mode includes built-in identity mapped paging, x64 mode
does not. Why did AMD leave this feature out of the original x64 design?
I imagine rom developers at the time (1999 or 2000) didn't object to its
omission. If AMD and Intel would add this feature, both UEFI and coreboot
could switch to 64-bit mode right out of the reset vector.

I almost scrapped the experiment after finding rom based page tables
couldn't be used. But I did try the next best thing, cache as ram page
tables. This works and the board boots all the way to SeaBIOS. So cache
as ram initialization runs in 32-bit mode as before, but agesa, cimx, and
everything until payload launch runs in x64 mode.

I put the experimental conversion here: http://notabs.org/coreboot/e350m1-x64.7z.
This is not a patch or submission. It is a proof of concept experiment only.
Only ASRock E350M1 builds. Because I am not good with makefiles, I hard-coded
the changes rather than make a 32/64 selection option. I took a lot of short-
cuts because the experiment is only intended to see if anything unexpected
would be encountered. Only features I needed are ported. I did not port
option rom execution for example. There are some inconsistent line endings.
Here is a summary of changes:

Switch compiler code generation from 32-bit to 64-bit. Switch asm code too,
except for cache as ram. Yes, I have some .intel_syntax in there. I have to
write it that way then convert afterwards.

Change GDB_DEBUG flag from -O0 to -Og to support source level debugging
without such a drastic code size increase.

Switch back to 32-bit mode for payload execution.

Add x64 code segment to GDTs and do some 64-bit changes. I skipped the
IDT to save time because it is not essential for this board.

Fix definitions like intptr_t and UINT32 to give the sizes needed for
x64 compile.

flag_is_changeable_p was not ported because it is not needed for this
test.

Fix integer overflow problem in rom_media.c. Not sure if I got it right,
but it is good enough for this test.

Work around some section alignment related problems. I did not use a good
solution because I was in a hurry.

There are a couple of small changes to simplify simnow testing. Those
changes are marked and are not needed when booting on real hardware.

A very few changes were needed in order to get the GDB_DEBUG (-Og) build
to compile. Both the normal and GDB_DEBUG builds boot on real hardware.

A hack was made to agesa ExecuteFinalHltInstruction so that the cache
as ram page tables do not disappear before shadowed to RAM.

Made the AMD NMI handler compatible with -Og debug build.

Increased cache as ram for AP cores from 4 to 8 KB to make room for
cache as ram page tables.

There are lots of 64-bit pointer truncations left. Some work would be
needed in order to run the code about 4GB.

I used 2GB pages to minimize cache as ram usage. Those are left in
place for the whole boot, but could easily be replaced once ram is
initialized.

Builds were done with Windows 7 and win-build-env-015.7z from:
http://sourceforge.net/projects/coreboot-tools-for-windows/
It will most likely build on linux without change.

The archive contains the git files. Hopefully this will make
it easier to diff. The archive also contains the build directory.

Thanks,
Scott


]ron
]
]--