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