1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright IBM Corp. 2017 4 * Author(s): Claudio Imbrenda <imbrenda@linux.vnet.ibm.com> 5 */ 6 7 #ifndef PAGE_STATES_H 8 #define PAGE_STATES_H 9 10 #include <asm/sections.h> 11 #include <asm/page.h> 12 13 #define ESSA_GET_STATE 0 14 #define ESSA_SET_STABLE 1 15 #define ESSA_SET_UNUSED 2 16 #define ESSA_SET_VOLATILE 3 17 #define ESSA_SET_POT_VOLATILE 4 18 #define ESSA_SET_STABLE_RESIDENT 5 19 #define ESSA_SET_STABLE_IF_RESIDENT 6 20 #define ESSA_SET_STABLE_NODAT 7 21 22 #define ESSA_MAX ESSA_SET_STABLE_NODAT 23 24 extern int __bootdata_preserved(cmma_flag); 25 26 static __always_inline unsigned long essa(unsigned long paddr, unsigned char cmd) 27 { 28 unsigned long rc; 29 30 asm volatile( 31 " .insn rrf,0xb9ab0000,%[rc],%[paddr],%[cmd],0" 32 : [rc] "=d" (rc) 33 : [paddr] "d" (paddr), 34 [cmd] "i" (cmd)); 35 return rc; 36 } 37 38 static __always_inline void __set_page_state(void *addr, unsigned long num_pages, unsigned char cmd) 39 { 40 unsigned long paddr = __pa(addr) & PAGE_MASK; 41 42 while (num_pages--) { 43 essa(paddr, cmd); 44 paddr += PAGE_SIZE; 45 } 46 } 47 48 static inline void __set_page_unused(void *addr, unsigned long num_pages) 49 { 50 __set_page_state(addr, num_pages, ESSA_SET_UNUSED); 51 } 52 53 static inline void __set_page_stable_dat(void *addr, unsigned long num_pages) 54 { 55 __set_page_state(addr, num_pages, ESSA_SET_STABLE); 56 } 57 58 static inline void __set_page_stable_nodat(void *addr, unsigned long num_pages) 59 { 60 __set_page_state(addr, num_pages, ESSA_SET_STABLE_NODAT); 61 } 62 63 static inline void __arch_set_page_nodat(void *addr, unsigned long num_pages) 64 { 65 if (!cmma_flag) 66 return; 67 if (cmma_flag < 2) 68 __set_page_stable_dat(addr, num_pages); 69 else 70 __set_page_stable_nodat(addr, num_pages); 71 } 72 73 static inline void __arch_set_page_dat(void *addr, unsigned long num_pages) 74 { 75 if (!cmma_flag) 76 return; 77 __set_page_stable_dat(addr, num_pages); 78 } 79 80 #endif 81