1 #include<stdio.h> 2 #include<stdint.h> 3 #include<string.h> 4 #include<assert.h> 5 6 /* Register contents after executing an TRTT insn */ 7 typedef struct { 8 uint64_t srcaddr; 9 uint64_t len; 10 uint64_t desaddr; 11 uint64_t tabaddr; 12 uint16_t testbyte; 13 uint64_t cc; 14 } trtt_regs; 15 16 uint16_t tran_table[40] = { 17 0xaaaa,0xcccc,0xcccc,0xdddd,0xffff,0xdada,0xbcbc,0xabab,0xcaca,0xeaea, 18 0xbbbb,0xeeee 19 }; 20 21 uint16_t src[40] = { 22 0x4,0x03,0x04,0x02,0x07,0x08,0x06,0x02,0x05,0x09,0xa 23 }; 24 25 uint16_t des[20]; 26 27 trtt_regs tr(uint16_t *addr, uint16_t *codepage, uint16_t *dest, uint64_t len, 28 uint16_t test) 29 { 30 trtt_regs regs; 31 register uint64_t test_byte asm("0") = test; 32 register uint64_t length asm("3") = len; 33 register uint64_t srcaddr asm("4") = (uint64_t)addr; 34 register uint64_t codepage2 asm("1") = (uint64_t)codepage; 35 register uint64_t desaddr asm("2") = (uint64_t)dest; 36 register uint64_t cc asm("5"); 37 38 cc = 2; /* cc result will never be 2 */ 39 asm volatile( 40 " trtt %1,%2\n" 41 " ipm %0\n" 42 " srl %0,28\n" 43 : "=d"(cc),"+d"(desaddr),"+d"(srcaddr) 44 : "d"(test_byte),"d" (codepage2),"d"(length) 45 : "memory" ); 46 47 regs.srcaddr = srcaddr; 48 regs.len = length; 49 regs.desaddr = desaddr; 50 regs.tabaddr = codepage2; 51 regs.testbyte = test_byte; 52 regs.cc = cc; 53 54 return regs; 55 } 56 57 int run_test(void *srcaddr, void *tableaddr, void *desaddr, uint64_t len, 58 uint16_t testbyte) 59 { 60 trtt_regs regs; 61 int i; 62 63 assert(len <= sizeof src); 64 65 if ((testbyte & 0xffff) != testbyte) 66 printf("testbyte should be 2 byte only\n"); 67 68 regs = tr(srcaddr, tableaddr, desaddr, len, testbyte); 69 70 if ((uint64_t)tableaddr != regs.tabaddr) 71 printf("translation table address changed\n"); 72 if ((uint64_t)srcaddr + (len - regs.len) != regs.srcaddr) 73 printf("source address/length not updated properly\n"); 74 if ((uint64_t)desaddr + (len - regs.len) != regs.desaddr) 75 printf("destination address/length not updated properly\n"); 76 if (regs.cc == 0 && regs.len != 0) 77 printf("length is not zero but cc is zero\n"); 78 printf("%u bytes translated\n", ((unsigned)(len - regs.len))/2); 79 printf("the translated values is"); 80 for (i = 0; i < len/2; i++) { 81 printf(" %hx", des[i]); 82 } 83 printf("\n"); 84 85 return regs.cc; 86 } 87 88 89 int main() 90 { 91 int cc; 92 93 assert(sizeof des <= sizeof src); 94 95 /* Test 1 : len == 0 */ 96 cc = run_test(NULL, NULL, NULL, 0, 0x0); 97 if (cc != 0) 98 printf("cc not updated properly:%d", cc); 99 100 cc = run_test(&src, &tran_table, &des, 0, 0x0); 101 if (cc != 0) 102 printf("cc not updated properly:%d",cc); 103 104 cc = run_test(&src, &tran_table, &des, 0, 0xcaca); 105 if (cc != 0) 106 printf("cc not updated properly:%d",cc); 107 108 /* Test 2 : len > 0, testbyte not matching */ 109 cc = run_test(&src, &tran_table, &des, 4, 0xdada); 110 if (cc != 0) 111 printf("cc not updated properly:%d",cc); 112 113 cc = run_test(&src, &tran_table, &des, 10, 0x00); 114 if (cc != 0) 115 printf("cc not updated properly:%d",cc); 116 117 memset((uint16_t *)&des, 0, 10); 118 119 /* Test 3 : len > 0 , testbyte matching */ 120 cc = run_test(&src, &tran_table, &des, 10, 0xffff); 121 if (cc != 1) 122 printf("cc not updated properly:%d",cc); 123 124 cc = run_test(&src, &tran_table, &des, 10, 0xcccc); 125 if (cc != 1) 126 printf("cc not updated properly:%d",cc); 127 128 cc = run_test(&src, &tran_table, &des, 20, 0xeaea); 129 if (cc != 1) 130 printf("cc not updated properly:%d",cc); 131 132 return 0; 133 } 134