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 */
7 typedef 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 
16 uint8_t tran_table[40] = {
17    0xaa,0xbb,0xcc,0xdd,0xff,0xdd,0xbc,0xab,0xca,0xea,0xbb,0xee
18 };
19 
20 int16_t src[40] = {
21    0x2,0x03,0x04,0x02,0x07,0x08,0x06,0x02,0x05,0x09
22 };
23 
24 uint8_t des[20];
25 
tr(uint16_t * addr,uint16_t * codepage,uint8_t * dest,uint64_t len,uint8_t test)26 trto_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 
run_test(void * srcaddr,void * tableaddr,void * desaddr,uint64_t len,uint8_t testbyte)55 int 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 
main()86 int 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