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