1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright (c) 2017 Red Hat Inc 4 * 5 * Authors: 6 * Thomas Huth <thuth@redhat.com> 7 * David Hildenbrand <david@redhat.com> 8 */ 9 #include <libcflat.h> 10 #include <util.h> 11 #include <alloc.h> 12 #include <asm/interrupt.h> 13 #include <asm/barrier.h> 14 #include <asm/pgtable.h> 15 16 static void test_fp(void) 17 { 18 double a = 3.0; 19 double b = 2.0; 20 double c; 21 22 asm volatile( 23 " ddb %1, %2\n" 24 " std %1, %0\n" 25 : "=m" (c) : "f" (a), "m" (b)); 26 27 report(c == 1.5, "3.0/2.0 == 1.5"); 28 } 29 30 static void test_pgm_int(void) 31 { 32 expect_pgm_int(); 33 asm volatile(" .insn e,0x0000"); /* used for SW breakpoints in QEMU */ 34 check_pgm_int_code(PGM_INT_CODE_OPERATION); 35 36 expect_pgm_int(); 37 asm volatile(" stg %0,0(%0)\n" : : "a"(-1L)); 38 check_pgm_int_code(PGM_INT_CODE_ADDRESSING); 39 } 40 41 static void test_malloc(void) 42 { 43 int *tmp, *tmp2; 44 45 report_prefix_push("malloc"); 46 47 report_prefix_push("ptr_0"); 48 tmp = malloc(sizeof(int)); 49 report((uintptr_t)tmp & 0xf000000000000000ul, "allocated memory"); 50 *tmp = 123456789; 51 mb(); 52 report(*tmp == 123456789, "wrote allocated memory"); 53 report_prefix_pop(); 54 55 report_prefix_push("ptr_1"); 56 tmp2 = malloc(sizeof(int)); 57 report((uintptr_t)tmp2 & 0xf000000000000000ul, 58 "allocated memory"); 59 *tmp2 = 123456789; 60 mb(); 61 report((*tmp2 == 123456789), "wrote allocated memory"); 62 report_prefix_pop(); 63 64 report(tmp != tmp2, "allocated memory addresses differ"); 65 66 expect_pgm_int(); 67 disable_dat(); 68 *tmp = 987654321; 69 enable_dat(); 70 check_pgm_int_code(PGM_INT_CODE_ADDRESSING); 71 72 free(tmp); 73 free(tmp2); 74 report_prefix_pop(); 75 } 76 77 static void test_psw_mask(void) 78 { 79 uint64_t expected_key = 0xf; 80 struct psw test_psw = PSW(0, 0); 81 82 report_prefix_push("PSW mask"); 83 test_psw.mask = PSW_MASK_DAT; 84 report(test_psw.dat, "DAT matches expected=0x%016lx actual=0x%016lx", PSW_MASK_DAT, test_psw.mask); 85 86 test_psw.mask = PSW_MASK_IO; 87 report(test_psw.io, "IO matches expected=0x%016lx actual=0x%016lx", PSW_MASK_IO, test_psw.mask); 88 89 test_psw.mask = PSW_MASK_EXT; 90 report(test_psw.ext, "EXT matches expected=0x%016lx actual=0x%016lx", PSW_MASK_EXT, test_psw.mask); 91 92 test_psw.mask = expected_key << (63 - 11); 93 report(test_psw.key == expected_key, "PSW Key matches expected=0x%lx actual=0x%x", expected_key, test_psw.key); 94 95 test_psw.mask = 1UL << (63 - 13); 96 report(test_psw.mchk, "MCHK matches"); 97 98 test_psw.mask = PSW_MASK_WAIT; 99 report(test_psw.wait, "Wait matches expected=0x%016lx actual=0x%016lx", PSW_MASK_WAIT, test_psw.mask); 100 101 test_psw.mask = PSW_MASK_PSTATE; 102 report(test_psw.pstate, "Pstate matches expected=0x%016lx actual=0x%016lx", PSW_MASK_PSTATE, test_psw.mask); 103 104 test_psw.mask = PSW_MASK_64; 105 report(test_psw.ea && test_psw.ba, "BA/EA matches expected=0x%016lx actual=0x%016lx", PSW_MASK_64, test_psw.mask); 106 107 report_prefix_pop(); 108 } 109 110 int main(int argc, char**argv) 111 { 112 report_prefix_push("selftest"); 113 114 report_pass("true"); 115 report(argc == 3, "argc == 3"); 116 report(!strcmp(argv[0], "s390x/selftest.elf"), "argv[0] == PROGNAME"); 117 report(!strcmp(argv[1], "test"), "argv[1] == test"); 118 report(!strcmp(argv[2], "123"), "argv[2] == 123"); 119 120 setup_vm(); 121 122 test_fp(); 123 test_pgm_int(); 124 test_malloc(); 125 test_psw_mask(); 126 127 return report_summary(); 128 } 129