| /* | |
| * hibernate_asm.S: Hibernaton support specific for sparc64. | |
| * | |
| * Copyright (C) 2013 Kirill V Tkhai (tkhai@yandex.ru) | |
| */ | |
| #include <linux/linkage.h> | |
| #include <asm/asm-offsets.h> | |
| #include <asm/cpudata.h> | |
| #include <asm/page.h> | |
| ENTRY(swsusp_arch_suspend) | |
| save %sp, -128, %sp | |
| save %sp, -128, %sp | |
| flushw | |
| setuw saved_context, %g3 | |
| /* Save window regs */ | |
| rdpr %cwp, %g2 | |
| stx %g2, [%g3 + SC_REG_CWP] | |
| rdpr %wstate, %g2 | |
| stx %g2, [%g3 + SC_REG_WSTATE] | |
| stx %fp, [%g3 + SC_REG_FP] | |
| /* Save state regs */ | |
| rdpr %tick, %g2 | |
| stx %g2, [%g3 + SC_REG_TICK] | |
| rdpr %pstate, %g2 | |
| stx %g2, [%g3 + SC_REG_PSTATE] | |
| /* Save global regs */ | |
| stx %g4, [%g3 + SC_REG_G4] | |
| stx %g5, [%g3 + SC_REG_G5] | |
| stx %g6, [%g3 + SC_REG_G6] | |
| call swsusp_save | |
| nop | |
| mov %o0, %i0 | |
| restore | |
| mov %o0, %i0 | |
| ret | |
| restore | |
| ENTRY(swsusp_arch_resume) | |
| /* Write restore_pblist to %l0 */ | |
| sethi %hi(restore_pblist), %l0 | |
| ldx [%l0 + %lo(restore_pblist)], %l0 | |
| call __flush_tlb_all | |
| nop | |
| /* Write PAGE_OFFSET to %g7 */ | |
| sethi %hi(PAGE_OFFSET), %g7 | |
| ldx [%g7 + %lo(PAGE_OFFSET)], %g7 | |
| setuw (PAGE_SIZE-8), %g3 | |
| /* Use MMU Bypass */ | |
| rd %asi, %g1 | |
| wr %g0, ASI_PHYS_USE_EC, %asi | |
| ba fill_itlb | |
| nop | |
| pbe_loop: | |
| cmp %l0, %g0 | |
| be restore_ctx | |
| sub %l0, %g7, %l0 | |
| ldxa [%l0 ] %asi, %l1 /* address */ | |
| ldxa [%l0 + 8] %asi, %l2 /* orig_address */ | |
| /* phys addr */ | |
| sub %l1, %g7, %l1 | |
| sub %l2, %g7, %l2 | |
| mov %g3, %l3 /* PAGE_SIZE-8 */ | |
| copy_loop: | |
| ldxa [%l1 + %l3] ASI_PHYS_USE_EC, %g2 | |
| stxa %g2, [%l2 + %l3] ASI_PHYS_USE_EC | |
| cmp %l3, %g0 | |
| bne copy_loop | |
| sub %l3, 8, %l3 | |
| /* next pbe */ | |
| ba pbe_loop | |
| ldxa [%l0 + 16] %asi, %l0 | |
| restore_ctx: | |
| setuw saved_context, %g3 | |
| /* Restore window regs */ | |
| wrpr %g0, 0, %canrestore | |
| wrpr %g0, 0, %otherwin | |
| wrpr %g0, 6, %cansave | |
| wrpr %g0, 0, %cleanwin | |
| ldxa [%g3 + SC_REG_CWP] %asi, %g2 | |
| wrpr %g2, %cwp | |
| ldxa [%g3 + SC_REG_WSTATE] %asi, %g2 | |
| wrpr %g2, %wstate | |
| ldxa [%g3 + SC_REG_FP] %asi, %fp | |
| /* Restore state regs */ | |
| ldxa [%g3 + SC_REG_PSTATE] %asi, %g2 | |
| wrpr %g2, %pstate | |
| ldxa [%g3 + SC_REG_TICK] %asi, %g2 | |
| wrpr %g2, %tick | |
| /* Restore global regs */ | |
| ldxa [%g3 + SC_REG_G4] %asi, %g4 | |
| ldxa [%g3 + SC_REG_G5] %asi, %g5 | |
| ldxa [%g3 + SC_REG_G6] %asi, %g6 | |
| wr %g1, %g0, %asi | |
| restore | |
| restore | |
| wrpr %g0, 14, %pil | |
| retl | |
| mov %g0, %o0 | |
| fill_itlb: | |
| ba pbe_loop | |
| wrpr %g0, 15, %pil |