1*47df95c7SJanosch Frank /* 2*47df95c7SJanosch Frank * Storage key removal facility tests 3*47df95c7SJanosch Frank * 4*47df95c7SJanosch Frank * Copyright (c) 2019 IBM Corp 5*47df95c7SJanosch Frank * 6*47df95c7SJanosch Frank * Authors: 7*47df95c7SJanosch Frank * Janosch Frank <frankja@linux.ibm.com> 8*47df95c7SJanosch Frank * 9*47df95c7SJanosch Frank * This code is free software; you can redistribute it and/or modify it 10*47df95c7SJanosch Frank * under the terms of the GNU General Public License version 2. 11*47df95c7SJanosch Frank */ 12*47df95c7SJanosch Frank #include <libcflat.h> 13*47df95c7SJanosch Frank #include <asm/asm-offsets.h> 14*47df95c7SJanosch Frank #include <asm/interrupt.h> 15*47df95c7SJanosch Frank #include <asm/page.h> 16*47df95c7SJanosch Frank #include <asm/facility.h> 17*47df95c7SJanosch Frank #include <asm/mem.h> 18*47df95c7SJanosch Frank 19*47df95c7SJanosch Frank static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2))); 20*47df95c7SJanosch Frank 21*47df95c7SJanosch Frank static void test_facilities(void) 22*47df95c7SJanosch Frank { 23*47df95c7SJanosch Frank report_prefix_push("facilities"); 24*47df95c7SJanosch Frank report("!10", !test_facility(10)); 25*47df95c7SJanosch Frank report("!14", !test_facility(14)); 26*47df95c7SJanosch Frank report("!66", !test_facility(66)); 27*47df95c7SJanosch Frank report("!145", !test_facility(145)); 28*47df95c7SJanosch Frank report("!149", !test_facility(140)); 29*47df95c7SJanosch Frank report_prefix_pop(); 30*47df95c7SJanosch Frank } 31*47df95c7SJanosch Frank 32*47df95c7SJanosch Frank static void test_skey(void) 33*47df95c7SJanosch Frank { 34*47df95c7SJanosch Frank report_prefix_push("sske"); 35*47df95c7SJanosch Frank expect_pgm_int(); 36*47df95c7SJanosch Frank set_storage_key(pagebuf, 0x30, 0); 37*47df95c7SJanosch Frank check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION); 38*47df95c7SJanosch Frank expect_pgm_int(); 39*47df95c7SJanosch Frank report_prefix_pop(); 40*47df95c7SJanosch Frank report_prefix_push("iske"); 41*47df95c7SJanosch Frank get_storage_key(pagebuf); 42*47df95c7SJanosch Frank check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION); 43*47df95c7SJanosch Frank report_prefix_pop(); 44*47df95c7SJanosch Frank } 45*47df95c7SJanosch Frank 46*47df95c7SJanosch Frank static void test_pfmf(void) 47*47df95c7SJanosch Frank { 48*47df95c7SJanosch Frank union pfmf_r1 r1; 49*47df95c7SJanosch Frank 50*47df95c7SJanosch Frank report_prefix_push("pfmf"); 51*47df95c7SJanosch Frank r1.val = 0; 52*47df95c7SJanosch Frank r1.reg.sk = 1; 53*47df95c7SJanosch Frank r1.reg.fsc = PFMF_FSC_4K; 54*47df95c7SJanosch Frank r1.reg.key = 0x30; 55*47df95c7SJanosch Frank expect_pgm_int(); 56*47df95c7SJanosch Frank pfmf(r1.val, pagebuf); 57*47df95c7SJanosch Frank check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION); 58*47df95c7SJanosch Frank report_prefix_pop(); 59*47df95c7SJanosch Frank } 60*47df95c7SJanosch Frank 61*47df95c7SJanosch Frank static void test_psw_key(void) 62*47df95c7SJanosch Frank { 63*47df95c7SJanosch Frank uint64_t psw_mask = extract_psw_mask() | 0xF0000000000000UL; 64*47df95c7SJanosch Frank 65*47df95c7SJanosch Frank report_prefix_push("psw key"); 66*47df95c7SJanosch Frank expect_pgm_int(); 67*47df95c7SJanosch Frank load_psw_mask(psw_mask); 68*47df95c7SJanosch Frank check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION); 69*47df95c7SJanosch Frank report_prefix_pop(); 70*47df95c7SJanosch Frank } 71*47df95c7SJanosch Frank 72*47df95c7SJanosch Frank static void test_mvcos(void) 73*47df95c7SJanosch Frank { 74*47df95c7SJanosch Frank uint64_t r3 = 64; 75*47df95c7SJanosch Frank uint8_t *src = pagebuf; 76*47df95c7SJanosch Frank uint8_t *dst = pagebuf + PAGE_SIZE; 77*47df95c7SJanosch Frank /* K bit set, as well as keys */ 78*47df95c7SJanosch Frank register unsigned long oac asm("0") = 0xf002f002; 79*47df95c7SJanosch Frank 80*47df95c7SJanosch Frank report_prefix_push("mvcos"); 81*47df95c7SJanosch Frank expect_pgm_int(); 82*47df95c7SJanosch Frank asm volatile("mvcos %[dst],%[src],%[len]" 83*47df95c7SJanosch Frank : [dst] "+Q" (*(dst)) 84*47df95c7SJanosch Frank : [src] "Q" (*(src)), [len] "d" (r3), "d" (oac) 85*47df95c7SJanosch Frank : "cc", "memory"); 86*47df95c7SJanosch Frank check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION); 87*47df95c7SJanosch Frank report_prefix_pop(); 88*47df95c7SJanosch Frank } 89*47df95c7SJanosch Frank 90*47df95c7SJanosch Frank static void test_spka(void) 91*47df95c7SJanosch Frank { 92*47df95c7SJanosch Frank report_prefix_push("spka"); 93*47df95c7SJanosch Frank expect_pgm_int(); 94*47df95c7SJanosch Frank asm volatile("spka 0xf0(0)\n"); 95*47df95c7SJanosch Frank check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION); 96*47df95c7SJanosch Frank report_prefix_pop(); 97*47df95c7SJanosch Frank } 98*47df95c7SJanosch Frank 99*47df95c7SJanosch Frank static void test_tprot(void) 100*47df95c7SJanosch Frank { 101*47df95c7SJanosch Frank report_prefix_push("tprot"); 102*47df95c7SJanosch Frank expect_pgm_int(); 103*47df95c7SJanosch Frank asm volatile("tprot %[addr],0xf0(0)\n" 104*47df95c7SJanosch Frank : : [addr] "a" (pagebuf) : ); 105*47df95c7SJanosch Frank check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION); 106*47df95c7SJanosch Frank report_prefix_pop(); 107*47df95c7SJanosch Frank } 108*47df95c7SJanosch Frank 109*47df95c7SJanosch Frank int main(void) 110*47df95c7SJanosch Frank { 111*47df95c7SJanosch Frank report_prefix_push("skrf"); 112*47df95c7SJanosch Frank if (!test_facility(169)) { 113*47df95c7SJanosch Frank report_skip("storage key removal facility not available\n"); 114*47df95c7SJanosch Frank goto done; 115*47df95c7SJanosch Frank } 116*47df95c7SJanosch Frank 117*47df95c7SJanosch Frank test_facilities(); 118*47df95c7SJanosch Frank test_skey(); 119*47df95c7SJanosch Frank test_pfmf(); 120*47df95c7SJanosch Frank test_psw_key(); 121*47df95c7SJanosch Frank test_mvcos(); 122*47df95c7SJanosch Frank test_spka(); 123*47df95c7SJanosch Frank test_tprot(); 124*47df95c7SJanosch Frank 125*47df95c7SJanosch Frank done: 126*47df95c7SJanosch Frank report_prefix_pop(); 127*47df95c7SJanosch Frank return report_summary(); 128*47df95c7SJanosch Frank } 129