The sparc64 cache flush implementation was wrong in so many ways. When you "save" you have to allocate at least a full register save area, which would be 128 bytes on sparc64. But we actually don't need a register window here, this is a leaf function and there are enough global and out registers available for what we need to do.
The 'flush' instruction is guarenteed to operate on at least 8 bytes, so we only need to flush as many 8 byte chunks as necessary after alignment. 2009-03-03 David S. Miller <da...@davemloft.net> * kern/sparc64/cache.S: Fix grub_arch_sync_caches implementation. --- kern/sparc64/cache.S | 22 +++++++++------------- 1 files changed, 9 insertions(+), 13 deletions(-) diff --git a/kern/sparc64/cache.S b/kern/sparc64/cache.S index 2ebb693..a8d3843 100644 --- a/kern/sparc64/cache.S +++ b/kern/sparc64/cache.S @@ -27,17 +27,13 @@ * void grub_arch_sync_caches (void *address, grub_size_t len) */ FUNCTION(grub_arch_sync_caches) - save %o6, -0xC, %o6 ! Get a new register window, - ! reserve space on stack for - ! %i0, %i1, %i2 - brz,pn %i0, return ! Return if address == 0. - nop - brz,pn %i1, return ! Return if len == 0. - clr %i2 ! index = 0. -loop: flush %i0 + %i2 ! Flush address + index. - cmp %i1, %i2 ! Compare len & index . - bpos,a,pt %xcc, loop ! If len > index, loop. - add %i2, 8, %i2 ! Go to next doubleword. -return: ret ! Restore caller's register - restore ! window and return. + brz,pn %o1, 2f + andn %o0, 7, %o0 + add %o1, 7, %o1 + andn %o1, 7, %o1 +1: subcc %o1, 8, %o1 + bne,pt %icc, 1b + flush %o0 + %o1 +2: retl + nop -- 1.6.1.2.253.ga34a _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel