On Thu, Apr 3, 2014 at 12:45 PM, Marc Jones marcj303@gmail.com wrote:
H Aaron,
On Wed, Apr 2, 2014 at 1:30 PM, Aaron Durbin adurbin@chromium.org wrote:
Hi Folks,
Some of you may know I have lots of ideas floating around in my head for technical changes within coreboot. I'd like to layout many of those ideas so that 1. it's written down 2. people can discuss the merit. I plan on pursuing each of these changes, but I am not sure in what way (personal playground?). Many of these proposed may be x86-centric at first glance, but I feel that is reflective of the current code base. Solving some of the generic/infrastructure issues inherently will impact x86 systems. Also note that some of these ideas aren't fully fleshed out, however I believe the underlying problems still need to be addressed in some form.
Availability Features/Subsystems
There is currently quite a bit of code using macro guards around code based on __PRE_RAM__, for example, to imply what stage a compilation unit is being compiled for. While some of these heuristics may have been true in the past it's definitely not true any longer -- especially with the introduction of coreboot supporting some of the ARM SoC's. However, here is also a runtime component to feature availability -- not just static or compile time.
Kyösti Mälkki has started to address the compile-time component: http://review.coreboot.org/#/c/5410/ I think we should take it further by having notions of "has devicetree", for example. The runtime notion of availability of features is also important. Trying to unify romstage (see below) will rely on having common points that can be used to piggy back infrastructure changes. To that end a construct of "mode" seems logical. The mode of the system would include current stage as well as features (read: flags). During the process of booting flags would be turned on triggering action. For example, after main memory is available that flag would be flipped and action could thus be taken (setting up cbmem, e.g.). The notion of "is this boot a resume boot?" comes to mind as well.
On an ABI change front, I think it's important to pass this information on the next corresponding change (romstage -> ramstage, e.g.). x86's bootblock would not have such a notion since it currently has no memory to work with. Passing information directly to the next stage will provide direct dissemination of previous knowledge (e.g. where is cbmem?).
This sounds good. Since CBFS and coreboot stage loading is basicly elf based, we could support standard argument passing, for example: --cbmem 0x<cbmem_address>. This would allow different architectures pass some specific data as well as generic or common data. Could this be useful for a payload that accepts command line options. Is this a good idea?
Such an approach could be useful for a payload as well as for stages. However, I was thinking of going in the opposite direction for stages in that they would be more tightly coupled. Currently each stage is a standalone program w/ 0 information sharing. I'm suggesting providing a more direct way of passing information between each stage -- that's a tighter coupling between the stages. I'm of the thinking that stages are currently unnecessarily decoupled. In other words, I think it is fine to *not* support adding an stage into a build that was built from a completely different set of source code than the other stages were built. Payloads are a different beast in that they are fairly black box and out of coreboot's control.
Taming the Wild West of Romstage
Many people who have ventured into making changes that impact romstage may know that there isn't a consistent framework/path. On x86, the entry point is typically some assembly code that sets up cache-as-ram then calls into a chipset specific C code. Memory is trained, cbmem is brought up, exit back to assembly, cache-as-ram is torn down, then call back into C code to locate and load ramstage. All of that typically happens within the confines of a chipset. That means when needing to make changes to APIs and/or assumptions in the infrastructure the task is very high-touch affecting quite many boards. On the other side of the spectrum the ARM SoCs have their own romstage paths that sit entirely in C code. Thus, I think it's important to solidify on a consistent API for booting through romstage like we have for ramstage. It wouldn't be like ramstage's hardwaremain.c, but it would provide a set of functions that should be called/implemented. Extending that concept further, the same constructs could be employed on more forgiving architectures' bootblock code.
Q: What about such and such? It doesn't do things like that. A: I think we need to start conforming boards/chipsets into using the common infrastructure. It should provide consistency as well easier development cost in the long run for code changes.
x86-specific Romstage Changes
The above changes to romstage flow could be quite a big change for each chipset transitioning over. However, there's a lot of duplication w.r.t. setting up MTRRs and obtaining the stack location after cache-as-ram is torn down. A set of common functions should be introduced to manage the MTRRs and choosing stack location. This approach is utilized in the haswell and baytrail code although the code is essentially duplicated. Either through C code or some common assembler the new stack would be processed after tearing down cache-as-ram to initialize the new MTRR values and enable caching.
What makes this work even more worthwhile is the carrot dangling in front of us at this point. Utilizing Ron Minnich's paging work (http://review.coreboot.org/5354) we can get rid of CAR_GLOBAL. The objects placed in CAR_GLOBAL currently would just live in the BSS section. Just before tearing down cache-as-ram that region would be copied into memory and page tables would be set up to map the address space occupied by cache-as-ram to point to memory. All other physical regions are identity mapped. The implication is that cache-as-ram is not a first class citizen that always needs to be thought about.
However, that does require that x86 systems that utilize cache-as-ram need tp set up cbmem, but that's not too bad because that assumption was already being carried with some of the romstage unification. Removing CAR_GLOBAL should allow for having a richer (or maybe not as clumsy) APIs within the core infrastructure. Currently, x86 is holding other architectures back in this regard.
x86 Assumptions
It's not surprising that there are some x86-isms that have crept into the core components/libraries. One of the main issues that has been talked about as of late is the access pattern and APIs surrounding CBFS access patterns. The good news on that front is that there is a GSoC proposal to attack that problem. To take that one step further the medium on which CBFS resides can be used for other purposes aside from CBFS. ChromeOS devices very much use this: memory training data, event log, and verified boot. The regions patch (http://review.coreboot.org/5394), as implemented, is a first-pass at not just rectifying CBFS access patterns but also providing an abstraction to the underlying medium into a single interface. That allowed for a unified way to access the SPI flash. One of the nicer things the regions support allows is to easily ship in-memory CBFS updates as well as have the ability to carve out subregions while still utilizing the underlying medium-access implementation.
Path Forward
I plan on working on the above things with a few boards. I have haswell and baytrail boards. I should be getting some cubie paraphernalia this week to have both an x86 and arm environment. Yes, some of the proposals are somewhat soft and fluffy so there will be some exploration involved, but most of these things are quite doable in a small amount of time. Stealing Patrick's word, the hard part will be "dragging" other systems forward.
All great points. I agree with the needs that you have identified.
I think that we should have an unstable development branch where this work is done. I expect that there could be a lot of breakage with these changes. We should still use gerrit and jenkins to maintain the process and inform us of the general health of the branch.
Marc