1663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include<stdio.h>
2663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include<stdint.h>
3663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include<string.h>
4663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include<assert.h>
5663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
6663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Register contents after executing an TRTT insn */
7663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef struct {
8663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   uint64_t srcaddr;
9663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   uint64_t len;
10663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   uint64_t desaddr;
11663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   uint64_t tabaddr;
12663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   uint16_t testbyte;
13663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   uint64_t cc;
14663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} trtt_regs;
15663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
16663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chenguint16_t tran_table[40] = {
17663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   0xaaaa,0xcccc,0xcccc,0xdddd,0xffff,0xdada,0xbcbc,0xabab,0xcaca,0xeaea,
18663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   0xbbbb,0xeeee
19663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng};
20663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
21663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chenguint16_t src[40] = {
22663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   0x4,0x03,0x04,0x02,0x07,0x08,0x06,0x02,0x05,0x09,0xa
23663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng};
24663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
25663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chenguint16_t des[20];
26663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
27663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtrtt_regs tr(uint16_t *addr, uint16_t *codepage, uint16_t *dest, uint64_t len,
28663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng             uint16_t test)
29663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
30663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   trtt_regs regs;
31663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   register uint64_t test_byte asm("0") = test;
32663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   register uint64_t length asm("3") = len;
33663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   register uint64_t srcaddr asm("4") = (uint64_t)addr;
34663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   register uint64_t codepage2 asm("1") = (uint64_t)codepage;
35663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   register uint64_t desaddr asm("2") = (uint64_t)dest;
36663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   register uint64_t cc asm("5");
37663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
38663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   cc = 2;  /* cc result will never be 2 */
39663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   asm volatile(
40663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                " trtt  %1,%2\n"
41663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                " ipm   %0\n"
42663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                " srl   %0,28\n"
43663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                : "=d"(cc),"+d"(desaddr),"+d"(srcaddr)
44663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                : "d"(test_byte),"d" (codepage2),"d"(length)
45663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                : "memory" );
46663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
47663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   regs.srcaddr = srcaddr;
48663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   regs.len = length;
49663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   regs.desaddr = desaddr;
50663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   regs.tabaddr = codepage2;
51663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   regs.testbyte = test_byte;
52663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   regs.cc = cc;
53663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
54663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return regs;
55663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
56663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
57663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengint run_test(void *srcaddr, void *tableaddr, void *desaddr, uint64_t len,
58663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng             uint16_t testbyte)
59663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
60663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   trtt_regs regs;
61663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   int i;
62663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
63663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   assert(len <= sizeof src);
64663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
65663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if ((testbyte & 0xffff) != testbyte)
66663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf("testbyte should be 2 byte only\n");
67663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
68663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   regs = tr(srcaddr, tableaddr, desaddr, len, testbyte);
69663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
70663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if ((uint64_t)tableaddr != regs.tabaddr)
71663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf("translation table address changed\n");
72663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if ((uint64_t)srcaddr + (len - regs.len) != regs.srcaddr)
73663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf("source address/length not updated properly\n");
74663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if ((uint64_t)desaddr + (len - regs.len) != regs.desaddr)
75663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf("destination address/length not updated properly\n");
76663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (regs.cc == 0  && regs.len != 0)
77663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf("length is not zero but cc is zero\n");
78663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   printf("%u bytes translated\n", ((unsigned)(len - regs.len))/2);
79663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   printf("the translated values is");
80663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   for (i = 0; i < len/2; i++) {
81663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf(" %hx", des[i]);
82663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
83663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   printf("\n");
84663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
85663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return regs.cc;
86663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
87663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
88663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
89663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengint main()
90663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
91663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   int cc;
92663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
93663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   assert(sizeof des <= sizeof src);
94663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
95663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* Test 1 : len == 0 */
96663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   cc = run_test(NULL, NULL, NULL, 0, 0x0);
97663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (cc != 0)
98663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf("cc not updated properly:%d", cc);
99663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   cc = run_test(&src, &tran_table, &des, 0, 0x0);
101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (cc != 0)
102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf("cc not updated properly:%d",cc);
103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   cc = run_test(&src, &tran_table, &des, 0, 0xcaca);
105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (cc != 0)
106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf("cc not updated properly:%d",cc);
107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* Test 2 : len > 0, testbyte not matching */
109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   cc = run_test(&src, &tran_table, &des, 4, 0xdada);
110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (cc != 0)
111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf("cc not updated properly:%d",cc);
112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   cc = run_test(&src, &tran_table, &des, 10, 0x00);
114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (cc != 0)
115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf("cc not updated properly:%d",cc);
116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   memset((uint16_t *)&des, 0, 10);
118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* Test 3 : len > 0 , testbyte matching */
120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   cc = run_test(&src, &tran_table, &des, 10, 0xffff);
121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (cc != 1)
122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf("cc not updated properly:%d",cc);
123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   cc = run_test(&src, &tran_table, &des, 10, 0xcccc);
125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (cc != 1)
126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf("cc not updated properly:%d",cc);
127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   cc = run_test(&src, &tran_table, &des, 20, 0xeaea);
129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (cc != 1)
130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf("cc not updated properly:%d",cc);
131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return 0;
133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
134