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