/* * Copyright (c) 2007-2017 Allwinnertech Co., Ltd. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #include #include "pm_types.h" #include "./pm.h" void save_mmu_state(struct mmu_state *saved_mmu_state) { /* CR0 */ asm volatile ("mrc p15, 2, %0, c0, c0, 0" : "=r" (saved_mmu_state->cssr)); /* CR1 */ asm volatile ("mrc p15, 0, %0, c1, c0, 2" : "=r" (saved_mmu_state->cacr)); /* CR3 */ asm volatile ("mrc p15, 0, %0, c3, c0, 0" : "=r" (saved_mmu_state->dacr)); /* save ttb */ /* CR2 */ /* busy_waiting(); */ asm volatile ("mrc p15, 0, %0, c2, c0, 0" : "=r" (saved_mmu_state->ttb_0r)); asm volatile ("mrc p15, 0, %0, c2, c0, 1" : "=r" (saved_mmu_state->ttb_1r)); asm volatile ("mrc p15, 0, %0, c2, c0, 2" : "=r" (saved_mmu_state->ttbcr)); /* CR1 */ /* busy_waiting(); */ asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r" (saved_mmu_state->cr)); /* will effect visible addr space */ return; } void restore_secure_mmu_state(struct mmu_state *saved_mmu_state) { /* busy_waiting(); */ /* CR0 */ asm volatile ("mcr p15, 2, %0, c0, c0, 0" : : "r" (saved_mmu_state->cssr)); /* CR1 */ asm volatile ("mcr p15, 0, %0, c1, c0, 2" : : "r" (saved_mmu_state->cacr)); /* CR3 */ asm volatile ("mcr p15, 0, %0, c3, c0, 0" : : "r" (saved_mmu_state->dacr)); /* CR2 */ /*when translate 0x0000,0000, use ttb0, while ttb0 shoudbe the same with ttb1 */ asm volatile ("mcr p15, 0, %0, c2, c0, 0" : : "r" (saved_mmu_state->ttb_0r)); asm volatile ("mcr p15, 0, %0, c2, c0, 1" : : "r" (saved_mmu_state->ttb_1r)); asm volatile ("mcr p15, 0, %0, c2, c0, 2" : : "r" (saved_mmu_state->ttbcr)); /* CR1 */ /*cr: will effect visible addr space */ #ifndef CONFIG_SUNXI_TRUSTZONE asm volatile ("mcr p15, 0, %0, c1, c0, 0" : : "r" (saved_mmu_state->cr)); #endif /*read id reg */ asm volatile ("mrc p15, 0, r3, c0, c0, 0" : : ); asm("mov r3, r3"); asm("mov r3, r3"); asm("isb"); return; } void restore_mmu_state(struct mmu_state *saved_mmu_state) { /* busy_waiting(); */ /* CR0 */ asm volatile ("mcr p15, 2, %0, c0, c0, 0" : : "r" (saved_mmu_state->cssr)); /* CR1 */ asm volatile ("mcr p15, 0, %0, c1, c0, 2" : : "r" (saved_mmu_state->cacr)); /* CR3 */ asm volatile ("mcr p15, 0, %0, c3, c0, 0" : : "r" (saved_mmu_state->dacr)); /* CR2 */ /*when translate 0x0000,0000, use ttb0, while ttb0 shoudbe the same with ttb1 */ asm volatile ("mcr p15, 0, %0, c2, c0, 0" : : "r" (saved_mmu_state->ttb_1r)); asm volatile ("mcr p15, 0, %0, c2, c0, 1" : : "r" (saved_mmu_state->ttb_1r)); asm volatile ("mcr p15, 0, %0, c2, c0, 2" : : "r" (saved_mmu_state->ttbcr)); asm("b __turn_mmu_on"); asm(".align 5"); asm(".type __turn_mmu_on, %function"); asm("__turn_mmu_on:"); asm("mov r0, r0"); /* CR1 */ /*cr: will effect visible addr space */ asm volatile ("mcr p15, 0, %0, c1, c0, 0" : : "r" (saved_mmu_state->cr)); /*read id reg */ asm volatile ("mrc p15, 0, r3, c0, c0, 0" : : ); asm("mov r3, r3"); asm("mov r3, r3"); asm("isb"); return; } #if 0 void disable_mmu(void) { __u32 c1format = 0; asm volatile ("mrc p15,0,%0,c1,c0,0" : "=r" (c1format) : ); c1format &= ~0x1007; c1format |= 0; asm volatile ("mcr p15,0,%0,c1,c0,0" : : "r" (c1format)); /*read id reg */ asm volatile ("mrc p15, 0, r3, c0, c0, 0" : : ); asm("mov r3, r3"); asm("mov r3, r3"); asm("isb"); return; } #endif /* */ /* void jump_to_resume(void* pointer) */ /* { */ /* asm("mov lr, r0"); */ /* asm("mov pc, lr"); */ /* return; */ /* } */