From 45320bcbabfa9149f43a5beb4b9a4f108dd98929 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 27 Mar 2006 19:21:46 +1100 Subject: powerpc: Move swsusp.S over to arch/powerpc ... and rename it to swsusp_32.S, since it's 32-bit only at this stage. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/swsusp_32.S | 349 ++++++++++++++++++++++++++++++++++++++++ arch/ppc/kernel/Makefile | 2 - arch/ppc/kernel/swsusp.S | 349 ---------------------------------------- 3 files changed, 349 insertions(+), 351 deletions(-) create mode 100644 arch/powerpc/kernel/swsusp_32.S delete mode 100644 arch/ppc/kernel/swsusp.S diff --git a/arch/powerpc/kernel/swsusp_32.S b/arch/powerpc/kernel/swsusp_32.S new file mode 100644 index 000000000000..69773cc1a85f --- /dev/null +++ b/arch/powerpc/kernel/swsusp_32.S @@ -0,0 +1,349 @@ +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * Structure for storing CPU registers on the save area. + */ +#define SL_SP 0 +#define SL_PC 4 +#define SL_MSR 8 +#define SL_SDR1 0xc +#define SL_SPRG0 0x10 /* 4 sprg's */ +#define SL_DBAT0 0x20 +#define SL_IBAT0 0x28 +#define SL_DBAT1 0x30 +#define SL_IBAT1 0x38 +#define SL_DBAT2 0x40 +#define SL_IBAT2 0x48 +#define SL_DBAT3 0x50 +#define SL_IBAT3 0x58 +#define SL_TB 0x60 +#define SL_R2 0x68 +#define SL_CR 0x6c +#define SL_LR 0x70 +#define SL_R12 0x74 /* r12 to r31 */ +#define SL_SIZE (SL_R12 + 80) + + .section .data + .align 5 + +_GLOBAL(swsusp_save_area) + .space SL_SIZE + + + .section .text + .align 5 + +_GLOBAL(swsusp_arch_suspend) + + lis r11,swsusp_save_area@h + ori r11,r11,swsusp_save_area@l + + mflr r0 + stw r0,SL_LR(r11) + mfcr r0 + stw r0,SL_CR(r11) + stw r1,SL_SP(r11) + stw r2,SL_R2(r11) + stmw r12,SL_R12(r11) + + /* Save MSR & SDR1 */ + mfmsr r4 + stw r4,SL_MSR(r11) + mfsdr1 r4 + stw r4,SL_SDR1(r11) + + /* Get a stable timebase and save it */ +1: mftbu r4 + stw r4,SL_TB(r11) + mftb r5 + stw r5,SL_TB+4(r11) + mftbu r3 + cmpw r3,r4 + bne 1b + + /* Save SPRGs */ + mfsprg r4,0 + stw r4,SL_SPRG0(r11) + mfsprg r4,1 + stw r4,SL_SPRG0+4(r11) + mfsprg r4,2 + stw r4,SL_SPRG0+8(r11) + mfsprg r4,3 + stw r4,SL_SPRG0+12(r11) + + /* Save BATs */ + mfdbatu r4,0 + stw r4,SL_DBAT0(r11) + mfdbatl r4,0 + stw r4,SL_DBAT0+4(r11) + mfdbatu r4,1 + stw r4,SL_DBAT1(r11) + mfdbatl r4,1 + stw r4,SL_DBAT1+4(r11) + mfdbatu r4,2 + stw r4,SL_DBAT2(r11) + mfdbatl r4,2 + stw r4,SL_DBAT2+4(r11) + mfdbatu r4,3 + stw r4,SL_DBAT3(r11) + mfdbatl r4,3 + stw r4,SL_DBAT3+4(r11) + mfibatu r4,0 + stw r4,SL_IBAT0(r11) + mfibatl r4,0 + stw r4,SL_IBAT0+4(r11) + mfibatu r4,1 + stw r4,SL_IBAT1(r11) + mfibatl r4,1 + stw r4,SL_IBAT1+4(r11) + mfibatu r4,2 + stw r4,SL_IBAT2(r11) + mfibatl r4,2 + stw r4,SL_IBAT2+4(r11) + mfibatu r4,3 + stw r4,SL_IBAT3(r11) + mfibatl r4,3 + stw r4,SL_IBAT3+4(r11) + +#if 0 + /* Backup various CPU config stuffs */ + bl __save_cpu_setup +#endif + /* Call the low level suspend stuff (we should probably have made + * a stackframe... + */ + bl swsusp_save + + /* Restore LR from the save area */ + lis r11,swsusp_save_area@h + ori r11,r11,swsusp_save_area@l + lwz r0,SL_LR(r11) + mtlr r0 + + blr + + +/* Resume code */ +_GLOBAL(swsusp_arch_resume) + + /* Stop pending alitvec streams and memory accesses */ +BEGIN_FTR_SECTION + DSSALL +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) + sync + + /* Disable MSR:DR to make sure we don't take a TLB or + * hash miss during the copy, as our hash table will + * for a while be unuseable. For .text, we assume we are + * covered by a BAT. This works only for non-G5 at this + * point. G5 will need a better approach, possibly using + * a small temporary hash table filled with large mappings, + * disabling the MMU completely isn't a good option for + * performance reasons. + * (Note that 750's may have the same performance issue as + * the G5 in this case, we should investigate using moving + * BATs for these CPUs) + */ + mfmsr r0 + sync + rlwinm r0,r0,0,28,26 /* clear MSR_DR */ + mtmsr r0 + sync + isync + + /* Load ptr the list of pages to copy in r3 */ + lis r11,(pagedir_nosave - KERNELBASE)@h + ori r11,r11,pagedir_nosave@l + lwz r10,0(r11) + + /* Copy the pages. This is a very basic implementation, to + * be replaced by something more cache efficient */ +1: + tophys(r3,r10) + li r0,256 + mtctr r0 + lwz r11,pbe_address(r3) /* source */ + tophys(r5,r11) + lwz r10,pbe_orig_address(r3) /* destination */ + tophys(r6,r10) +2: + lwz r8,0(r5) + lwz r9,4(r5) + lwz r10,8(r5) + lwz r11,12(r5) + addi r5,r5,16 + stw r8,0(r6) + stw r9,4(r6) + stw r10,8(r6) + stw r11,12(r6) + addi r6,r6,16 + bdnz 2b + lwz r10,pbe_next(r3) + cmpwi 0,r10,0 + bne 1b + + /* Do a very simple cache flush/inval of the L1 to ensure + * coherency of the icache + */ + lis r3,0x0002 + mtctr r3 + li r3, 0 +1: + lwz r0,0(r3) + addi r3,r3,0x0020 + bdnz 1b + isync + sync + + /* Now flush those cache lines */ + lis r3,0x0002 + mtctr r3 + li r3, 0 +1: + dcbf 0,r3 + addi r3,r3,0x0020 + bdnz 1b + sync + + /* Ok, we are now running with the kernel data of the old + * kernel fully restored. We can get to the save area + * easily now. As for the rest of the code, it assumes the + * loader kernel and the booted one are exactly identical + */ + lis r11,swsusp_save_area@h + ori r11,r11,swsusp_save_area@l + tophys(r11,r11) + +#if 0 + /* Restore various CPU config stuffs */ + bl __restore_cpu_setup +#endif + /* Restore the BATs, and SDR1. Then we can turn on the MMU. + * This is a bit hairy as we are running out of those BATs, + * but first, our code is probably in the icache, and we are + * writing the same value to the BAT, so that should be fine, + * though a better solution will have to be found long-term + */ + lwz r4,SL_SDR1(r11) + mtsdr1 r4 + lwz r4,SL_SPRG0(r11) + mtsprg 0,r4 + lwz r4,SL_SPRG0+4(r11) + mtsprg 1,r4 + lwz r4,SL_SPRG0+8(r11) + mtsprg 2,r4 + lwz r4,SL_SPRG0+12(r11) + mtsprg 3,r4 + +#if 0 + lwz r4,SL_DBAT0(r11) + mtdbatu 0,r4 + lwz r4,SL_DBAT0+4(r11) + mtdbatl 0,r4 + lwz r4,SL_DBAT1(r11) + mtdbatu 1,r4 + lwz r4,SL_DBAT1+4(r11) + mtdbatl 1,r4 + lwz r4,SL_DBAT2(r11) + mtdbatu 2,r4 + lwz r4,SL_DBAT2+4(r11) + mtdbatl 2,r4 + lwz r4,SL_DBAT3(r11) + mtdbatu 3,r4 + lwz r4,SL_DBAT3+4(r11) + mtdbatl 3,r4 + lwz r4,SL_IBAT0(r11) + mtibatu 0,r4 + lwz r4,SL_IBAT0+4(r11) + mtibatl 0,r4 + lwz r4,SL_IBAT1(r11) + mtibatu 1,r4 + lwz r4,SL_IBAT1+4(r11) + mtibatl 1,r4 + lwz r4,SL_IBAT2(r11) + mtibatu 2,r4 + lwz r4,SL_IBAT2+4(r11) + mtibatl 2,r4 + lwz r4,SL_IBAT3(r11) + mtibatu 3,r4 + lwz r4,SL_IBAT3+4(r11) + mtibatl 3,r4 +#endif + +BEGIN_FTR_SECTION + li r4,0 + mtspr SPRN_DBAT4U,r4 + mtspr SPRN_DBAT4L,r4 + mtspr SPRN_DBAT5U,r4 + mtspr SPRN_DBAT5L,r4 + mtspr SPRN_DBAT6U,r4 + mtspr SPRN_DBAT6L,r4 + mtspr SPRN_DBAT7U,r4 + mtspr SPRN_DBAT7L,r4 + mtspr SPRN_IBAT4U,r4 + mtspr SPRN_IBAT4L,r4 + mtspr SPRN_IBAT5U,r4 + mtspr SPRN_IBAT5L,r4 + mtspr SPRN_IBAT6U,r4 + mtspr SPRN_IBAT6L,r4 + mtspr SPRN_IBAT7U,r4 + mtspr SPRN_IBAT7L,r4 +END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS) + + /* Flush all TLBs */ + lis r4,0x1000 +1: addic. r4,r4,-0x1000 + tlbie r4 + blt 1b + sync + + /* restore the MSR and turn on the MMU */ + lwz r3,SL_MSR(r11) + bl turn_on_mmu + tovirt(r11,r11) + + /* Restore TB */ + li r3,0 + mttbl r3 + lwz r3,SL_TB(r11) + lwz r4,SL_TB+4(r11) + mttbu r3 + mttbl r4 + + /* Kick decrementer */ + li r0,1 + mtdec r0 + + /* Restore the callee-saved registers and return */ + lwz r0,SL_CR(r11) + mtcr r0 + lwz r2,SL_R2(r11) + lmw r12,SL_R12(r11) + lwz r1,SL_SP(r11) + lwz r0,SL_LR(r11) + mtlr r0 + + // XXX Note: we don't really need to call swsusp_resume + + li r3,0 + blr + +/* FIXME:This construct is actually not useful since we don't shut + * down the instruction MMU, we could just flip back MSR-DR on. + */ +turn_on_mmu: + mflr r4 + mtsrr0 r4 + mtsrr1 r3 + sync + isync + rfi + diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index d6a4863d4e7c..8ac1dd958415 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -13,7 +13,6 @@ extra-y += vmlinux.lds obj-y := entry.o traps.o time.o misc.o \ setup.o \ ppc_htab.o -obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o obj-$(CONFIG_PCI) += pci.o @@ -32,7 +31,6 @@ endif # These are here while we do the architecture merge else -obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o obj-$(CONFIG_KGDB) += ppc-stub.o diff --git a/arch/ppc/kernel/swsusp.S b/arch/ppc/kernel/swsusp.S deleted file mode 100644 index 69773cc1a85f..000000000000 --- a/arch/ppc/kernel/swsusp.S +++ /dev/null @@ -1,349 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - - -/* - * Structure for storing CPU registers on the save area. - */ -#define SL_SP 0 -#define SL_PC 4 -#define SL_MSR 8 -#define SL_SDR1 0xc -#define SL_SPRG0 0x10 /* 4 sprg's */ -#define SL_DBAT0 0x20 -#define SL_IBAT0 0x28 -#define SL_DBAT1 0x30 -#define SL_IBAT1 0x38 -#define SL_DBAT2 0x40 -#define SL_IBAT2 0x48 -#define SL_DBAT3 0x50 -#define SL_IBAT3 0x58 -#define SL_TB 0x60 -#define SL_R2 0x68 -#define SL_CR 0x6c -#define SL_LR 0x70 -#define SL_R12 0x74 /* r12 to r31 */ -#define SL_SIZE (SL_R12 + 80) - - .section .data - .align 5 - -_GLOBAL(swsusp_save_area) - .space SL_SIZE - - - .section .text - .align 5 - -_GLOBAL(swsusp_arch_suspend) - - lis r11,swsusp_save_area@h - ori r11,r11,swsusp_save_area@l - - mflr r0 - stw r0,SL_LR(r11) - mfcr r0 - stw r0,SL_CR(r11) - stw r1,SL_SP(r11) - stw r2,SL_R2(r11) - stmw r12,SL_R12(r11) - - /* Save MSR & SDR1 */ - mfmsr r4 - stw r4,SL_MSR(r11) - mfsdr1 r4 - stw r4,SL_SDR1(r11) - - /* Get a stable timebase and save it */ -1: mftbu r4 - stw r4,SL_TB(r11) - mftb r5 - stw r5,SL_TB+4(r11) - mftbu r3 - cmpw r3,r4 - bne 1b - - /* Save SPRGs */ - mfsprg r4,0 - stw r4,SL_SPRG0(r11) - mfsprg r4,1 - stw r4,SL_SPRG0+4(r11) - mfsprg r4,2 - stw r4,SL_SPRG0+8(r11) - mfsprg r4,3 - stw r4,SL_SPRG0+12(r11) - - /* Save BATs */ - mfdbatu r4,0 - stw r4,SL_DBAT0(r11) - mfdbatl r4,0 - stw r4,SL_DBAT0+4(r11) - mfdbatu r4,1 - stw r4,SL_DBAT1(r11) - mfdbatl r4,1 - stw r4,SL_DBAT1+4(r11) - mfdbatu r4,2 - stw r4,SL_DBAT2(r11) - mfdbatl r4,2 - stw r4,SL_DBAT2+4(r11) - mfdbatu r4,3 - stw r4,SL_DBAT3(r11) - mfdbatl r4,3 - stw r4,SL_DBAT3+4(r11) - mfibatu r4,0 - stw r4,SL_IBAT0(r11) - mfibatl r4,0 - stw r4,SL_IBAT0+4(r11) - mfibatu r4,1 - stw r4,SL_IBAT1(r11) - mfibatl r4,1 - stw r4,SL_IBAT1+4(r11) - mfibatu r4,2 - stw r4,SL_IBAT2(r11) - mfibatl r4,2 - stw r4,SL_IBAT2+4(r11) - mfibatu r4,3 - stw r4,SL_IBAT3(r11) - mfibatl r4,3 - stw r4,SL_IBAT3+4(r11) - -#if 0 - /* Backup various CPU config stuffs */ - bl __save_cpu_setup -#endif - /* Call the low level suspend stuff (we should probably have made - * a stackframe... - */ - bl swsusp_save - - /* Restore LR from the save area */ - lis r11,swsusp_save_area@h - ori r11,r11,swsusp_save_area@l - lwz r0,SL_LR(r11) - mtlr r0 - - blr - - -/* Resume code */ -_GLOBAL(swsusp_arch_resume) - - /* Stop pending alitvec streams and memory accesses */ -BEGIN_FTR_SECTION - DSSALL -END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) - sync - - /* Disable MSR:DR to make sure we don't take a TLB or - * hash miss during the copy, as our hash table will - * for a while be unuseable. For .text, we assume we are - * covered by a BAT. This works only for non-G5 at this - * point. G5 will need a better approach, possibly using - * a small temporary hash table filled with large mappings, - * disabling the MMU completely isn't a good option for - * performance reasons. - * (Note that 750's may have the same performance issue as - * the G5 in this case, we should investigate using moving - * BATs for these CPUs) - */ - mfmsr r0 - sync - rlwinm r0,r0,0,28,26 /* clear MSR_DR */ - mtmsr r0 - sync - isync - - /* Load ptr the list of pages to copy in r3 */ - lis r11,(pagedir_nosave - KERNELBASE)@h - ori r11,r11,pagedir_nosave@l - lwz r10,0(r11) - - /* Copy the pages. This is a very basic implementation, to - * be replaced by something more cache efficient */ -1: - tophys(r3,r10) - li r0,256 - mtctr r0 - lwz r11,pbe_address(r3) /* source */ - tophys(r5,r11) - lwz r10,pbe_orig_address(r3) /* destination */ - tophys(r6,r10) -2: - lwz r8,0(r5) - lwz r9,4(r5) - lwz r10,8(r5) - lwz r11,12(r5) - addi r5,r5,16 - stw r8,0(r6) - stw r9,4(r6) - stw r10,8(r6) - stw r11,12(r6) - addi r6,r6,16 - bdnz 2b - lwz r10,pbe_next(r3) - cmpwi 0,r10,0 - bne 1b - - /* Do a very simple cache flush/inval of the L1 to ensure - * coherency of the icache - */ - lis r3,0x0002 - mtctr r3 - li r3, 0 -1: - lwz r0,0(r3) - addi r3,r3,0x0020 - bdnz 1b - isync - sync - - /* Now flush those cache lines */ - lis r3,0x0002 - mtctr r3 - li r3, 0 -1: - dcbf 0,r3 - addi r3,r3,0x0020 - bdnz 1b - sync - - /* Ok, we are now running with the kernel data of the old - * kernel fully restored. We can get to the save area - * easily now. As for the rest of the code, it assumes the - * loader kernel and the booted one are exactly identical - */ - lis r11,swsusp_save_area@h - ori r11,r11,swsusp_save_area@l - tophys(r11,r11) - -#if 0 - /* Restore various CPU config stuffs */ - bl __restore_cpu_setup -#endif - /* Restore the BATs, and SDR1. Then we can turn on the MMU. - * This is a bit hairy as we are running out of those BATs, - * but first, our code is probably in the icache, and we are - * writing the same value to the BAT, so that should be fine, - * though a better solution will have to be found long-term - */ - lwz r4,SL_SDR1(r11) - mtsdr1 r4 - lwz r4,SL_SPRG0(r11) - mtsprg 0,r4 - lwz r4,SL_SPRG0+4(r11) - mtsprg 1,r4 - lwz r4,SL_SPRG0+8(r11) - mtsprg 2,r4 - lwz r4,SL_SPRG0+12(r11) - mtsprg 3,r4 - -#if 0 - lwz r4,SL_DBAT0(r11) - mtdbatu 0,r4 - lwz r4,SL_DBAT0+4(r11) - mtdbatl 0,r4 - lwz r4,SL_DBAT1(r11) - mtdbatu 1,r4 - lwz r4,SL_DBAT1+4(r11) - mtdbatl 1,r4 - lwz r4,SL_DBAT2(r11) - mtdbatu 2,r4 - lwz r4,SL_DBAT2+4(r11) - mtdbatl 2,r4 - lwz r4,SL_DBAT3(r11) - mtdbatu 3,r4 - lwz r4,SL_DBAT3+4(r11) - mtdbatl 3,r4 - lwz r4,SL_IBAT0(r11) - mtibatu 0,r4 - lwz r4,SL_IBAT0+4(r11) - mtibatl 0,r4 - lwz r4,SL_IBAT1(r11) - mtibatu 1,r4 - lwz r4,SL_IBAT1+4(r11) - mtibatl 1,r4 - lwz r4,SL_IBAT2(r11) - mtibatu 2,r4 - lwz r4,SL_IBAT2+4(r11) - mtibatl 2,r4 - lwz r4,SL_IBAT3(r11) - mtibatu 3,r4 - lwz r4,SL_IBAT3+4(r11) - mtibatl 3,r4 -#endif - -BEGIN_FTR_SECTION - li r4,0 - mtspr SPRN_DBAT4U,r4 - mtspr SPRN_DBAT4L,r4 - mtspr SPRN_DBAT5U,r4 - mtspr SPRN_DBAT5L,r4 - mtspr SPRN_DBAT6U,r4 - mtspr SPRN_DBAT6L,r4 - mtspr SPRN_DBAT7U,r4 - mtspr SPRN_DBAT7L,r4 - mtspr SPRN_IBAT4U,r4 - mtspr SPRN_IBAT4L,r4 - mtspr SPRN_IBAT5U,r4 - mtspr SPRN_IBAT5L,r4 - mtspr SPRN_IBAT6U,r4 - mtspr SPRN_IBAT6L,r4 - mtspr SPRN_IBAT7U,r4 - mtspr SPRN_IBAT7L,r4 -END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS) - - /* Flush all TLBs */ - lis r4,0x1000 -1: addic. r4,r4,-0x1000 - tlbie r4 - blt 1b - sync - - /* restore the MSR and turn on the MMU */ - lwz r3,SL_MSR(r11) - bl turn_on_mmu - tovirt(r11,r11) - - /* Restore TB */ - li r3,0 - mttbl r3 - lwz r3,SL_TB(r11) - lwz r4,SL_TB+4(r11) - mttbu r3 - mttbl r4 - - /* Kick decrementer */ - li r0,1 - mtdec r0 - - /* Restore the callee-saved registers and return */ - lwz r0,SL_CR(r11) - mtcr r0 - lwz r2,SL_R2(r11) - lmw r12,SL_R12(r11) - lwz r1,SL_SP(r11) - lwz r0,SL_LR(r11) - mtlr r0 - - // XXX Note: we don't really need to call swsusp_resume - - li r3,0 - blr - -/* FIXME:This construct is actually not useful since we don't shut - * down the instruction MMU, we could just flip back MSR-DR on. - */ -turn_on_mmu: - mflr r4 - mtsrr0 r4 - mtsrr1 r3 - sync - isync - rfi - -- cgit v1.2.3