[coreboot] the eternal pre-post car debate in v3

ron minnich rminnich at gmail.com
Thu Sep 11 17:42:44 CEST 2008

ok, here is one more proposal for the eternal pre/post car discussion.
I hope this covers all possibilities.
It will allow all current implementations to remain unchanged, which
is the nice part. But it sets a few simple
rules for the next CPUs, such as core 2.

To recap:  At some point stage1 needs to turn off CAR. The stack
(which includes sysinfo
and global variables) needs to be moved to RAM. We play a nice trick
on Geode and K8,
where there is RAM behind the CAR area: once it is time to turn off CAR,
we just "push" the CAR into that RAM location, and continue as though nothing
had happened. Although the K8 code is a bit more complex than this
simple description,
that is more or less what happens.

This trick is not 100% portable. On some systems (core 2) CAR is
located where there is
NEVER going to be any DRAM.

So, on some systems, once you disable CAR, the CAR data is gone, and so
is your stack and sysinfo struct. That CAR data has to be moved to DRAM, and
that data will be at a different address.

My concern has been that any pointers on the stack won't survive a stack move.
I don't want to get Clever and try to adjust
pointers on the stack because, in the limit, you can't distinguish
pointers from data.

So we make a rule or two:
1. stage1 never returns. Hence there will never be an issue with
stage1 returning to its caller.
   We need not worry about any stack being lost after stage 1 starts.
2. Stage 1 is the "outer loop". So any pointers in functions that
stage1 calls don't matter.
3. in stage1,  code should assume, post disable_car, that no pointers
used pre disable_car are valid. So you can
   use pointers in stage1, you just can not share them across the
disable_car boundary. Think of
   disable_car as a kind of "dead pointer zone" across which pointers
don't survive.
4. There shall be no pointers in sysinfo. This makes sysinfo
location-independent: the variables in sysinfo
   are valid no matter where sysinfo is locate. So, since sysinfo is
location-independent, there are no issues with it
   being relocated as part of disable_car.

Given these rules, here is how disable_car can work on core 2 and
others that don't back CAR with RAM.
1. compute a new stack area. The minimum size is the size of the
stack. Note that stack contains sysinfo (at its base).
   It is acceptable to copy only the "active" stack; it is acceptable
to copy all of CAR. It is acceptable
  to copy more data than the "active" stack and less data than all of
CAR. This flexibility makes
  writing disable_car easier.
2. copy the data to the new stack area in ram
3. disable CAR
4. adjust the return address on stack if needed (unlikely, since we're
executing from ROM, but who knows what the future may bring)
    and then return.

That's about it. This will work I think for core2. It requires zero
changes for K8 and geode. I think we can close this discussion.
We need to add comments to stage1 to explain proper pointer usage,
i.e. that pointers created before disable_car is called
must be adjusted or recomputed or not used after disable_car is called.


More information about the coreboot mailing list