1331c31feSJanosch Frank /* 2331c31feSJanosch Frank * Store System Information tests 3331c31feSJanosch Frank * 4331c31feSJanosch Frank * Copyright (c) 2019 IBM Corp 5331c31feSJanosch Frank * 6331c31feSJanosch Frank * Authors: 7331c31feSJanosch Frank * Janosch Frank <frankja@linux.ibm.com> 8331c31feSJanosch Frank * 9331c31feSJanosch Frank * This code is free software; you can redistribute it and/or modify it 10331c31feSJanosch Frank * under the terms of the GNU Library General Public License version 2. 11331c31feSJanosch Frank */ 12331c31feSJanosch Frank 13331c31feSJanosch Frank #include <libcflat.h> 14331c31feSJanosch Frank #include <asm/page.h> 15331c31feSJanosch Frank #include <asm/asm-offsets.h> 16331c31feSJanosch Frank #include <asm/interrupt.h> 17331c31feSJanosch Frank 18331c31feSJanosch Frank static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2))); 19331c31feSJanosch Frank 20331c31feSJanosch Frank static void test_specs(void) 21331c31feSJanosch Frank { 22331c31feSJanosch Frank report_prefix_push("specification"); 23331c31feSJanosch Frank 24331c31feSJanosch Frank report_prefix_push("inv r0"); 25331c31feSJanosch Frank expect_pgm_int(); 26331c31feSJanosch Frank stsi(pagebuf, 0, 1 << 8, 0); 27331c31feSJanosch Frank check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); 28331c31feSJanosch Frank report_prefix_pop(); 29331c31feSJanosch Frank 30331c31feSJanosch Frank report_prefix_push("inv r1"); 31331c31feSJanosch Frank expect_pgm_int(); 32331c31feSJanosch Frank stsi(pagebuf, 1, 0, 1 << 16); 33331c31feSJanosch Frank check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); 34331c31feSJanosch Frank report_prefix_pop(); 35331c31feSJanosch Frank 36331c31feSJanosch Frank report_prefix_push("unaligned"); 37331c31feSJanosch Frank expect_pgm_int(); 38a1bed535SJanosch Frank stsi(pagebuf + 42, 1, 1, 1); 39331c31feSJanosch Frank check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); 40331c31feSJanosch Frank report_prefix_pop(); 41331c31feSJanosch Frank 42331c31feSJanosch Frank report_prefix_pop(); 43331c31feSJanosch Frank } 44331c31feSJanosch Frank 45331c31feSJanosch Frank static void test_priv(void) 46331c31feSJanosch Frank { 47331c31feSJanosch Frank report_prefix_push("privileged"); 48331c31feSJanosch Frank expect_pgm_int(); 49331c31feSJanosch Frank enter_pstate(); 50331c31feSJanosch Frank stsi(pagebuf, 0, 0, 0); 51331c31feSJanosch Frank check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION); 52331c31feSJanosch Frank report_prefix_pop(); 53331c31feSJanosch Frank } 54331c31feSJanosch Frank 55331c31feSJanosch Frank static inline unsigned long stsi_get_fc(void *addr) 56331c31feSJanosch Frank { 57331c31feSJanosch Frank register unsigned long r0 asm("0") = 0; 58331c31feSJanosch Frank register unsigned long r1 asm("1") = 0; 59331c31feSJanosch Frank int cc; 60331c31feSJanosch Frank 61331c31feSJanosch Frank asm volatile("stsi 0(%[addr])\n" 62331c31feSJanosch Frank "ipm %[cc]\n" 63331c31feSJanosch Frank "srl %[cc],28\n" 64331c31feSJanosch Frank : "+d" (r0), [cc] "=d" (cc) 65331c31feSJanosch Frank : "d" (r1), [addr] "a" (addr) 66331c31feSJanosch Frank : "cc", "memory"); 67331c31feSJanosch Frank assert(!cc); 68331c31feSJanosch Frank return r0 >> 28; 69331c31feSJanosch Frank } 70331c31feSJanosch Frank 71331c31feSJanosch Frank static void test_fc(void) 72331c31feSJanosch Frank { 73*a299895bSThomas Huth report(stsi(pagebuf, 7, 0, 0) == 3, "invalid fc"); 74*a299895bSThomas Huth report(stsi(pagebuf, 1, 0, 1) == 3, "invalid selector 1"); 75*a299895bSThomas Huth report(stsi(pagebuf, 1, 1, 0) == 3, "invalid selector 2"); 76*a299895bSThomas Huth report(stsi_get_fc(pagebuf) >= 2, "query fc >= 2"); 77331c31feSJanosch Frank } 78331c31feSJanosch Frank 79331c31feSJanosch Frank int main(void) 80331c31feSJanosch Frank { 81331c31feSJanosch Frank report_prefix_push("stsi"); 82331c31feSJanosch Frank test_priv(); 83331c31feSJanosch Frank test_specs(); 84331c31feSJanosch Frank test_fc(); 85331c31feSJanosch Frank return report_summary(); 86331c31feSJanosch Frank } 87