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 */
7typedef 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
16uint16_t tran_table[40] = {
17   0xaaaa,0xbbbb,0xcccc,0xccdd,0xffff,0xdada,0xbcbc,0xabab,0xcaca,0xeaea,
18   0xbbbb,0xeeee
19};
20
21uint8_t src[40] = {
22   0x01,0x03,0x04,0x02,0x07,0x08,0x06,0x02,0x05,0x09
23};
24
25uint16_t des[40];
26
27trot_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
56int 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
88int 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