1da27543e012f62e295a172da3014044dac076225florian#include<stdio.h> 2da27543e012f62e295a172da3014044dac076225florian#include<stdint.h> 3da27543e012f62e295a172da3014044dac076225florian#include<string.h> 4da27543e012f62e295a172da3014044dac076225florian#include<assert.h> 5da27543e012f62e295a172da3014044dac076225florian 6da27543e012f62e295a172da3014044dac076225florian/* Register contents after executing an TRTT insn */ 7da27543e012f62e295a172da3014044dac076225floriantypedef struct { 8da27543e012f62e295a172da3014044dac076225florian uint64_t srcaddr; 9da27543e012f62e295a172da3014044dac076225florian uint64_t len; 10da27543e012f62e295a172da3014044dac076225florian uint64_t desaddr; 11da27543e012f62e295a172da3014044dac076225florian uint64_t tabaddr; 12da27543e012f62e295a172da3014044dac076225florian uint16_t testbyte; 13da27543e012f62e295a172da3014044dac076225florian uint64_t cc; 14da27543e012f62e295a172da3014044dac076225florian} trtt_regs; 15da27543e012f62e295a172da3014044dac076225florian 16da27543e012f62e295a172da3014044dac076225florianuint16_t tran_table[40] = { 17da27543e012f62e295a172da3014044dac076225florian 0xaaaa,0xcccc,0xcccc,0xdddd,0xffff,0xdada,0xbcbc,0xabab,0xcaca,0xeaea, 18da27543e012f62e295a172da3014044dac076225florian 0xbbbb,0xeeee 19da27543e012f62e295a172da3014044dac076225florian}; 20da27543e012f62e295a172da3014044dac076225florian 21da27543e012f62e295a172da3014044dac076225florianuint16_t src[40] = { 22da27543e012f62e295a172da3014044dac076225florian 0x4,0x03,0x04,0x02,0x07,0x08,0x06,0x02,0x05,0x09,0xa 23da27543e012f62e295a172da3014044dac076225florian}; 24da27543e012f62e295a172da3014044dac076225florian 25da27543e012f62e295a172da3014044dac076225florianuint16_t des[20]; 26da27543e012f62e295a172da3014044dac076225florian 27da27543e012f62e295a172da3014044dac076225floriantrtt_regs tr(uint16_t *addr, uint16_t *codepage, uint16_t *dest, uint64_t len, 28da27543e012f62e295a172da3014044dac076225florian uint16_t test) 29da27543e012f62e295a172da3014044dac076225florian{ 30da27543e012f62e295a172da3014044dac076225florian trtt_regs regs; 31da27543e012f62e295a172da3014044dac076225florian register uint64_t test_byte asm("0") = test; 32da27543e012f62e295a172da3014044dac076225florian register uint64_t length asm("3") = len; 33da27543e012f62e295a172da3014044dac076225florian register uint64_t srcaddr asm("4") = (uint64_t)addr; 34da27543e012f62e295a172da3014044dac076225florian register uint64_t codepage2 asm("1") = (uint64_t)codepage; 35da27543e012f62e295a172da3014044dac076225florian register uint64_t desaddr asm("2") = (uint64_t)dest; 36da27543e012f62e295a172da3014044dac076225florian register uint64_t cc asm("5"); 37da27543e012f62e295a172da3014044dac076225florian 38da27543e012f62e295a172da3014044dac076225florian cc = 2; /* cc result will never be 2 */ 39da27543e012f62e295a172da3014044dac076225florian asm volatile( 40da27543e012f62e295a172da3014044dac076225florian " trtt %1,%2\n" 41da27543e012f62e295a172da3014044dac076225florian " ipm %0\n" 42da27543e012f62e295a172da3014044dac076225florian " srl %0,28\n" 43da27543e012f62e295a172da3014044dac076225florian : "=d"(cc),"+d"(desaddr),"+d"(srcaddr) 44da27543e012f62e295a172da3014044dac076225florian : "d"(test_byte),"d" (codepage2),"d"(length) 45da27543e012f62e295a172da3014044dac076225florian : "memory" ); 46da27543e012f62e295a172da3014044dac076225florian 47da27543e012f62e295a172da3014044dac076225florian regs.srcaddr = srcaddr; 48da27543e012f62e295a172da3014044dac076225florian regs.len = length; 49da27543e012f62e295a172da3014044dac076225florian regs.desaddr = desaddr; 50da27543e012f62e295a172da3014044dac076225florian regs.tabaddr = codepage2; 51da27543e012f62e295a172da3014044dac076225florian regs.testbyte = test_byte; 52da27543e012f62e295a172da3014044dac076225florian regs.cc = cc; 53da27543e012f62e295a172da3014044dac076225florian 54da27543e012f62e295a172da3014044dac076225florian return regs; 55da27543e012f62e295a172da3014044dac076225florian} 56da27543e012f62e295a172da3014044dac076225florian 57da27543e012f62e295a172da3014044dac076225florianint run_test(void *srcaddr, void *tableaddr, void *desaddr, uint64_t len, 58da27543e012f62e295a172da3014044dac076225florian uint16_t testbyte) 59da27543e012f62e295a172da3014044dac076225florian{ 60da27543e012f62e295a172da3014044dac076225florian trtt_regs regs; 61da27543e012f62e295a172da3014044dac076225florian int i; 62da27543e012f62e295a172da3014044dac076225florian 63da27543e012f62e295a172da3014044dac076225florian assert(len <= sizeof src); 64da27543e012f62e295a172da3014044dac076225florian 65da27543e012f62e295a172da3014044dac076225florian if ((testbyte & 0xffff) != testbyte) 66da27543e012f62e295a172da3014044dac076225florian printf("testbyte should be 2 byte only\n"); 67da27543e012f62e295a172da3014044dac076225florian 68da27543e012f62e295a172da3014044dac076225florian regs = tr(srcaddr, tableaddr, desaddr, len, testbyte); 69da27543e012f62e295a172da3014044dac076225florian 70da27543e012f62e295a172da3014044dac076225florian if ((uint64_t)tableaddr != regs.tabaddr) 71da27543e012f62e295a172da3014044dac076225florian printf("translation table address changed\n"); 72da27543e012f62e295a172da3014044dac076225florian if ((uint64_t)srcaddr + (len - regs.len) != regs.srcaddr) 73da27543e012f62e295a172da3014044dac076225florian printf("source address/length not updated properly\n"); 74da27543e012f62e295a172da3014044dac076225florian if ((uint64_t)desaddr + (len - regs.len) != regs.desaddr) 75da27543e012f62e295a172da3014044dac076225florian printf("destination address/length not updated properly\n"); 76da27543e012f62e295a172da3014044dac076225florian if (regs.cc == 0 && regs.len != 0) 77da27543e012f62e295a172da3014044dac076225florian printf("length is not zero but cc is zero\n"); 78da27543e012f62e295a172da3014044dac076225florian printf("%u bytes translated\n", ((unsigned)(len - regs.len))/2); 79da27543e012f62e295a172da3014044dac076225florian printf("the translated values is"); 80da27543e012f62e295a172da3014044dac076225florian for (i = 0; i < len/2; i++) { 81da27543e012f62e295a172da3014044dac076225florian printf(" %hx", des[i]); 82da27543e012f62e295a172da3014044dac076225florian } 83da27543e012f62e295a172da3014044dac076225florian printf("\n"); 84da27543e012f62e295a172da3014044dac076225florian 85da27543e012f62e295a172da3014044dac076225florian return regs.cc; 86da27543e012f62e295a172da3014044dac076225florian} 87da27543e012f62e295a172da3014044dac076225florian 88da27543e012f62e295a172da3014044dac076225florian 89da27543e012f62e295a172da3014044dac076225florianint main() 90da27543e012f62e295a172da3014044dac076225florian{ 91da27543e012f62e295a172da3014044dac076225florian int cc; 92da27543e012f62e295a172da3014044dac076225florian 93da27543e012f62e295a172da3014044dac076225florian assert(sizeof des <= sizeof src); 94da27543e012f62e295a172da3014044dac076225florian 95da27543e012f62e295a172da3014044dac076225florian /* Test 1 : len == 0 */ 96da27543e012f62e295a172da3014044dac076225florian cc = run_test(NULL, NULL, NULL, 0, 0x0); 97da27543e012f62e295a172da3014044dac076225florian if (cc != 0) 98da27543e012f62e295a172da3014044dac076225florian printf("cc not updated properly:%d", cc); 99da27543e012f62e295a172da3014044dac076225florian 100da27543e012f62e295a172da3014044dac076225florian cc = run_test(&src, &tran_table, &des, 0, 0x0); 101da27543e012f62e295a172da3014044dac076225florian if (cc != 0) 102da27543e012f62e295a172da3014044dac076225florian printf("cc not updated properly:%d",cc); 103da27543e012f62e295a172da3014044dac076225florian 104da27543e012f62e295a172da3014044dac076225florian cc = run_test(&src, &tran_table, &des, 0, 0xcaca); 105da27543e012f62e295a172da3014044dac076225florian if (cc != 0) 106da27543e012f62e295a172da3014044dac076225florian printf("cc not updated properly:%d",cc); 107da27543e012f62e295a172da3014044dac076225florian 108da27543e012f62e295a172da3014044dac076225florian /* Test 2 : len > 0, testbyte not matching */ 109da27543e012f62e295a172da3014044dac076225florian cc = run_test(&src, &tran_table, &des, 4, 0xdada); 110da27543e012f62e295a172da3014044dac076225florian if (cc != 0) 111da27543e012f62e295a172da3014044dac076225florian printf("cc not updated properly:%d",cc); 112da27543e012f62e295a172da3014044dac076225florian 113da27543e012f62e295a172da3014044dac076225florian cc = run_test(&src, &tran_table, &des, 10, 0x00); 114da27543e012f62e295a172da3014044dac076225florian if (cc != 0) 115da27543e012f62e295a172da3014044dac076225florian printf("cc not updated properly:%d",cc); 116da27543e012f62e295a172da3014044dac076225florian 117da27543e012f62e295a172da3014044dac076225florian memset((uint16_t *)&des, 0, 10); 118da27543e012f62e295a172da3014044dac076225florian 119da27543e012f62e295a172da3014044dac076225florian /* Test 3 : len > 0 , testbyte matching */ 120da27543e012f62e295a172da3014044dac076225florian cc = run_test(&src, &tran_table, &des, 10, 0xffff); 121da27543e012f62e295a172da3014044dac076225florian if (cc != 1) 122da27543e012f62e295a172da3014044dac076225florian printf("cc not updated properly:%d",cc); 123da27543e012f62e295a172da3014044dac076225florian 124da27543e012f62e295a172da3014044dac076225florian cc = run_test(&src, &tran_table, &des, 10, 0xcccc); 125da27543e012f62e295a172da3014044dac076225florian if (cc != 1) 126da27543e012f62e295a172da3014044dac076225florian printf("cc not updated properly:%d",cc); 127da27543e012f62e295a172da3014044dac076225florian 128da27543e012f62e295a172da3014044dac076225florian cc = run_test(&src, &tran_table, &des, 20, 0xeaea); 129da27543e012f62e295a172da3014044dac076225florian if (cc != 1) 130da27543e012f62e295a172da3014044dac076225florian printf("cc not updated properly:%d",cc); 131da27543e012f62e295a172da3014044dac076225florian 132da27543e012f62e295a172da3014044dac076225florian return 0; 133da27543e012f62e295a172da3014044dac076225florian} 134