1663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include<stdio.h> 2663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include<stdlib.h> 3663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include<stdint.h> 4663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include<inttypes.h> 5663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include<string.h> 6663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "table.h" 7663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 8663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Register contents after executing an TRE insn */ 9663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef struct { 10663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng uint64_t addr; 11663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng uint64_t len; 12663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng uint64_t tabaddr; 13663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng uint8_t testbyte; 14663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng uint64_t cc; 15663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} tre_regs; 16663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 17663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chenguint8_t buff[40]; 18663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 19663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtre_regs tre(uint8_t *codepage, uint8_t *addr, uint64_t len, uint8_t test_byte) 20663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 21663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int cc; 22663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tre_regs regs; 23663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 24663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng register uint64_t param asm("0") = test_byte; 25663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng register uint64_t a2 asm ("4") = (uint64_t)codepage; 26663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng register uint64_t a1 asm ("2") = (uint64_t)addr; 27663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng register uint64_t l1 asm ("3") = len; 28663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 29663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng asm volatile( 30663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng " tre %1,%2\n" 31663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng " ipm %0\n" 32663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng " srl %0,28\n" 33663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng :"=d"(cc),"+&d"(a1) 34663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng :"d"(a2),"d"(param),"d"(l1),"d"(test_byte): "memory" ); 35663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 36663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng regs.addr = a1; 37663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng regs.len = l1; 38663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng regs.tabaddr = a2; 39663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng regs.testbyte = param; 40663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng regs.cc = cc; 41663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 42663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return regs; 43663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 44663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 45663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid run_test(void *tran_table, void *srcaddr, uint64_t len, uint8_t test) 46663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 47663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tre_regs regs; 48663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int i; 49663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 50663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng regs = tre(tran_table, srcaddr, len, test); 51663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 52663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if ((uint64_t)tran_table != regs.tabaddr) 53663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("translation table address changed\n"); 54663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (test != regs.testbyte) 55663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("test byte changed\n"); 56663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if ((uint64_t)srcaddr + (len - regs.len) != regs.addr) 57663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("source address/length not updated properly\n"); 58663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 59663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("Resulting cc is %"PRIu64" and the string is ", regs.cc); 60663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for ( i = 0; i < len; i++) { 61663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("%c", buff[i]); 62663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 63663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 64663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("\n"); 65663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 66663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 67663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengint main() 68663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 69663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 70663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Test 1: length = 0 */ 71663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng run_test(NULL, NULL, 0, 0x0); 72663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng run_test((char *)&touppercase, &buff, 0, 0x0); 73663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng run_test((char *)&touppercase, &buff, 0, 'b'); 74663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 75663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Test 2 : length > 0 */ 76663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng memset(buff, 'a', 1); 77663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng run_test((char *)&touppercase, &buff, 1, 'a'); //cc = 1 78663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng run_test((char *)&touppercase, &buff, 1, 'b'); 79663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 80663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng memcpy(buff, "abcdefgh", 8); 81663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng run_test((char *)&touppercase, &buff, 3, 'a'); //cc = 1 82663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng run_test((char *)&touppercase, &buff, 3, 'f'); //cc = 0 83663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng run_test((char *)&touppercase, &buff, 8, 'l'); //cc = 0 84663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 85663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng memcpy(buff, "ABCDEFGH", 8); 86663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng run_test((char *)&tolowercase, &buff, 3, 'A'); // cc = 1 87663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng run_test((char *)&tolowercase, &buff, 3, 'C'); // cc = 0 88663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng run_test((char *)&tolowercase, &buff, 8, 0x0); // cc = 0 89663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 90663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng memcpy(buff, "01234567", 8); 91663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng run_test((char *)&touppercase, &buff, 8, 'A'); 92663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng run_test((char *)&tolowercase, &buff, 8, 'A'); 93663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return 0; 94663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 95