162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * hibernate_asm.S: Hibernaton support specific for sparc64. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2013 Kirill V Tkhai (tkhai@yandex.ru) 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/linkage.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <asm/asm-offsets.h> 1162306a36Sopenharmony_ci#include <asm/cpudata.h> 1262306a36Sopenharmony_ci#include <asm/page.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ciENTRY(swsusp_arch_suspend) 1562306a36Sopenharmony_ci save %sp, -128, %sp 1662306a36Sopenharmony_ci save %sp, -128, %sp 1762306a36Sopenharmony_ci flushw 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci setuw saved_context, %g3 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci /* Save window regs */ 2262306a36Sopenharmony_ci rdpr %cwp, %g2 2362306a36Sopenharmony_ci stx %g2, [%g3 + SC_REG_CWP] 2462306a36Sopenharmony_ci rdpr %wstate, %g2 2562306a36Sopenharmony_ci stx %g2, [%g3 + SC_REG_WSTATE] 2662306a36Sopenharmony_ci stx %fp, [%g3 + SC_REG_FP] 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci /* Save state regs */ 2962306a36Sopenharmony_ci rdpr %tick, %g2 3062306a36Sopenharmony_ci stx %g2, [%g3 + SC_REG_TICK] 3162306a36Sopenharmony_ci rdpr %pstate, %g2 3262306a36Sopenharmony_ci stx %g2, [%g3 + SC_REG_PSTATE] 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci /* Save global regs */ 3562306a36Sopenharmony_ci stx %g4, [%g3 + SC_REG_G4] 3662306a36Sopenharmony_ci stx %g5, [%g3 + SC_REG_G5] 3762306a36Sopenharmony_ci stx %g6, [%g3 + SC_REG_G6] 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci call swsusp_save 4062306a36Sopenharmony_ci nop 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci mov %o0, %i0 4362306a36Sopenharmony_ci restore 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci mov %o0, %i0 4662306a36Sopenharmony_ci ret 4762306a36Sopenharmony_ci restore 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ciENTRY(swsusp_arch_resume) 5062306a36Sopenharmony_ci /* Write restore_pblist to %l0 */ 5162306a36Sopenharmony_ci sethi %hi(restore_pblist), %l0 5262306a36Sopenharmony_ci ldx [%l0 + %lo(restore_pblist)], %l0 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci call __flush_tlb_all 5562306a36Sopenharmony_ci nop 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci /* Write PAGE_OFFSET to %g7 */ 5862306a36Sopenharmony_ci sethi %hi(PAGE_OFFSET), %g7 5962306a36Sopenharmony_ci ldx [%g7 + %lo(PAGE_OFFSET)], %g7 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci setuw (PAGE_SIZE-8), %g3 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci /* Use MMU Bypass */ 6462306a36Sopenharmony_ci rd %asi, %g1 6562306a36Sopenharmony_ci wr %g0, ASI_PHYS_USE_EC, %asi 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci ba fill_itlb 6862306a36Sopenharmony_ci nop 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cipbe_loop: 7162306a36Sopenharmony_ci cmp %l0, %g0 7262306a36Sopenharmony_ci be restore_ctx 7362306a36Sopenharmony_ci sub %l0, %g7, %l0 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci ldxa [%l0 ] %asi, %l1 /* address */ 7662306a36Sopenharmony_ci ldxa [%l0 + 8] %asi, %l2 /* orig_address */ 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci /* phys addr */ 7962306a36Sopenharmony_ci sub %l1, %g7, %l1 8062306a36Sopenharmony_ci sub %l2, %g7, %l2 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci mov %g3, %l3 /* PAGE_SIZE-8 */ 8362306a36Sopenharmony_cicopy_loop: 8462306a36Sopenharmony_ci ldxa [%l1 + %l3] ASI_PHYS_USE_EC, %g2 8562306a36Sopenharmony_ci stxa %g2, [%l2 + %l3] ASI_PHYS_USE_EC 8662306a36Sopenharmony_ci cmp %l3, %g0 8762306a36Sopenharmony_ci bne copy_loop 8862306a36Sopenharmony_ci sub %l3, 8, %l3 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci /* next pbe */ 9162306a36Sopenharmony_ci ba pbe_loop 9262306a36Sopenharmony_ci ldxa [%l0 + 16] %asi, %l0 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cirestore_ctx: 9562306a36Sopenharmony_ci setuw saved_context, %g3 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci /* Restore window regs */ 9862306a36Sopenharmony_ci wrpr %g0, 0, %canrestore 9962306a36Sopenharmony_ci wrpr %g0, 0, %otherwin 10062306a36Sopenharmony_ci wrpr %g0, 6, %cansave 10162306a36Sopenharmony_ci wrpr %g0, 0, %cleanwin 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci ldxa [%g3 + SC_REG_CWP] %asi, %g2 10462306a36Sopenharmony_ci wrpr %g2, %cwp 10562306a36Sopenharmony_ci ldxa [%g3 + SC_REG_WSTATE] %asi, %g2 10662306a36Sopenharmony_ci wrpr %g2, %wstate 10762306a36Sopenharmony_ci ldxa [%g3 + SC_REG_FP] %asi, %fp 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci /* Restore state regs */ 11062306a36Sopenharmony_ci ldxa [%g3 + SC_REG_PSTATE] %asi, %g2 11162306a36Sopenharmony_ci wrpr %g2, %pstate 11262306a36Sopenharmony_ci ldxa [%g3 + SC_REG_TICK] %asi, %g2 11362306a36Sopenharmony_ci wrpr %g2, %tick 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci /* Restore global regs */ 11662306a36Sopenharmony_ci ldxa [%g3 + SC_REG_G4] %asi, %g4 11762306a36Sopenharmony_ci ldxa [%g3 + SC_REG_G5] %asi, %g5 11862306a36Sopenharmony_ci ldxa [%g3 + SC_REG_G6] %asi, %g6 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci wr %g1, %g0, %asi 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci restore 12362306a36Sopenharmony_ci restore 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci wrpr %g0, 14, %pil 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci retl 12862306a36Sopenharmony_ci mov %g0, %o0 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_cifill_itlb: 13162306a36Sopenharmony_ci ba pbe_loop 13262306a36Sopenharmony_ci wrpr %g0, 15, %pil 133