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