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 
tr(uint16_t * addr,uint16_t * codepage,uint16_t * dest,uint64_t len,uint16_t test)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 
run_test(void * srcaddr,void * tableaddr,void * desaddr,uint64_t len,uint16_t testbyte)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 
main()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