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.
ron