mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
The current K8 stack preservation code in disable_car() works by chance,
but that's not something we should rely on. The new code is entirely rewritten, fixes a few missing constraints in the asm and should be a lot more readable. However, the generated code is NOT identical. The old code was broken because of the missing ecx clobber constraint and it did not copy the stack back (ecx was zero at the beginning of the copy-back loop and so the loop executed exactly zero times). So this is a genuine bug fix. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Ron writes: wow! nice catch! Acked-by: Ronald G. Minnich <rminnich@gmail.com> We also need disable_car_and_halt, which only disables car and halts, for the APs (i.e. no need to copy stack back) git-svn-id: svn://coreboot.org/repository/coreboot-v3@858 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
parent
49e1879723
commit
ade1cd1f11
1 changed files with 22 additions and 11 deletions
|
@ -34,20 +34,31 @@
|
|||
*/
|
||||
void disable_car(void)
|
||||
{
|
||||
/* OK, here is the theory: we should be able to copy
|
||||
* the data back over itself, and the wbinvd should then
|
||||
* flush to memory. Let's see.
|
||||
*/
|
||||
/* nope.
|
||||
__asm__ __volatile__("cld; rep movsl" ::"D" (CONFIG_CARBASE), "S" (CONFIG_CARBASE), "c" (CONFIG_CARSIZE/4): "memory");
|
||||
*/
|
||||
/* call the inlined function */
|
||||
disable_cache_as_ram();
|
||||
|
||||
/* copy it down, wbinvd, copy it back? */
|
||||
__asm__ __volatile__("cld; rep movsl" ::"D" (0x88000), "S" (CONFIG_CARBASE), "c" (CONFIG_CARSIZE/4): "memory");
|
||||
__asm__ __volatile__ ("wbinvd\n");
|
||||
__asm__ __volatile__("cld; rep movsl" ::"D" (CONFIG_CARBASE), "S" (0x88000), "c" (CONFIG_CARSIZE/4): "memory");
|
||||
/* The BKDG says that a WBINVD will not flush CAR to RAM (because the
|
||||
* cache tags are not dirty).
|
||||
* Solution:
|
||||
* - Two subsequent memcpy in the same inline asm block, one from stack
|
||||
* to backup, one from backup to stack.
|
||||
* The solution for geode of using a inline asm memcpy of the stack
|
||||
* onto itself will not mark the cache tags as dirty on K8.
|
||||
*/
|
||||
__asm__ __volatile__(
|
||||
" movl %[carbase], %%esi \n"
|
||||
" movl %[backuplocation], %%edi \n"
|
||||
" movl %[carsizequads], %%ecx \n"
|
||||
" cld \n"
|
||||
" rep movsl \n"
|
||||
" wbinvd \n"
|
||||
" movl %[backuplocation], %%esi \n"
|
||||
" movl %[carbase], %%edi \n"
|
||||
" movl %[carsizequads], %%ecx \n"
|
||||
" rep movsl \n"
|
||||
:: [carbase] "i" (CONFIG_CARBASE), [backuplocation] "i" (0x88000),
|
||||
[carsizequads] "i" (CONFIG_CARSIZE/4)
|
||||
: "memory", "%edi", "%esi", "%ecx");
|
||||
banner(BIOS_DEBUG, "Disable_car: done wbinvd");
|
||||
banner(BIOS_DEBUG, "disable_car: done");
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue