Notes for v3 ports
Note for those porting to v3
There are a lot of changes with v3, and they are basically good. I am doing the K8 port now, and I'd like to accumulate wisdom on this page. V3 really is very different and you don't realize it until you get into it.
The first thing to remember is that v2 is very much shaped by the romcc legacy. So you will see comments like this in v2 commits: "get more code compiling in both places" or some such.
What does this mean? It means, for example, that the function xyz(device_t) has to compile and work when device_t is a u32 (as in the ROM-based code that starts RAM) and as a struct device * (as in the RAM-based code). This schizophrenia pervades v2, even when it is not needed (as in v2 targets that can run with cache-as-ram). A lot of v2 code is still compiled twice.
This is especially true of the .h files with inlined functions. In v2, a lot of SMBUS functions are inlined, meaning they get compiled into the ROM and RAM code.
A dramatic change in v3 is that the ROM-based code can be called from the RAM-based code. This change in turn means that many support functions should be built into the ROM-based code, one example being the functions that support PCI config space.
Note: stage0 is very early assembly, and stage1 is ROM-based C code. For reasons of history the Makefiles call some code STAGE0, though we ought to call it STAGE1. Sorry.
What does this imply? In v3, you should plan to move code to stage1, and then mark certain functions as SHARED, so they can be called from stage2. Here's an example: there is code that calls die(). In the bad old days die was compiled in to several places. Now it just has to be callable from anywhere.
Die() is defined in include/console.h as:
void die(const char *mst);
We just change it:
SHARED(die, void, const char *msg);
Result: we only compile a lot of code once, with the same compiler, and it can be called from anywhere.