| /* SPDX-License-Identifier: GPL-2.0 */ |
| /* |
| * 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 |