mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-11 09:56:29 +00:00
134 lines
3.5 KiB
C
134 lines
3.5 KiB
C
#include<stdio.h>
|
|
#include<stdint.h>
|
|
#include<string.h>
|
|
#include<assert.h>
|
|
|
|
/* Register contents after executing an TRTT insn */
|
|
typedef struct {
|
|
uint64_t srcaddr;
|
|
uint64_t len;
|
|
uint64_t desaddr;
|
|
uint64_t tabaddr;
|
|
uint16_t testbyte;
|
|
uint64_t cc;
|
|
} trtt_regs;
|
|
|
|
uint16_t tran_table[40] = {
|
|
0xaaaa,0xcccc,0xcccc,0xdddd,0xffff,0xdada,0xbcbc,0xabab,0xcaca,0xeaea,
|
|
0xbbbb,0xeeee
|
|
};
|
|
|
|
uint16_t src[40] = {
|
|
0x4,0x03,0x04,0x02,0x07,0x08,0x06,0x02,0x05,0x09,0xa
|
|
};
|
|
|
|
uint16_t des[20];
|
|
|
|
trtt_regs tr(uint16_t *addr, uint16_t *codepage, uint16_t *dest, uint64_t len,
|
|
uint16_t test)
|
|
{
|
|
trtt_regs regs;
|
|
register uint64_t test_byte asm("0") = test;
|
|
register uint64_t length asm("3") = len;
|
|
register uint64_t srcaddr asm("4") = (uint64_t)addr;
|
|
register uint64_t codepage2 asm("1") = (uint64_t)codepage;
|
|
register uint64_t desaddr asm("2") = (uint64_t)dest;
|
|
register uint64_t cc asm("5");
|
|
|
|
cc = 2; /* cc result will never be 2 */
|
|
asm volatile(
|
|
" trtt %1,%2\n"
|
|
" ipm %0\n"
|
|
" srl %0,28\n"
|
|
: "=d"(cc),"+d"(desaddr),"+d"(srcaddr)
|
|
: "d"(test_byte),"d" (codepage2),"d"(length)
|
|
: "memory" );
|
|
|
|
regs.srcaddr = srcaddr;
|
|
regs.len = length;
|
|
regs.desaddr = desaddr;
|
|
regs.tabaddr = codepage2;
|
|
regs.testbyte = test_byte;
|
|
regs.cc = cc;
|
|
|
|
return regs;
|
|
}
|
|
|
|
int run_test(void *srcaddr, void *tableaddr, void *desaddr, uint64_t len,
|
|
uint16_t testbyte)
|
|
{
|
|
trtt_regs regs;
|
|
int i;
|
|
|
|
assert(len <= sizeof src);
|
|
|
|
if ((testbyte & 0xffff) != testbyte)
|
|
printf("testbyte should be 2 byte only\n");
|
|
|
|
regs = tr(srcaddr, tableaddr, desaddr, len, testbyte);
|
|
|
|
if ((uint64_t)tableaddr != regs.tabaddr)
|
|
printf("translation table address changed\n");
|
|
if ((uint64_t)srcaddr + (len - regs.len) != regs.srcaddr)
|
|
printf("source address/length not updated properly\n");
|
|
if ((uint64_t)desaddr + (len - regs.len) != regs.desaddr)
|
|
printf("destination address/length not updated properly\n");
|
|
if (regs.cc == 0 && regs.len != 0)
|
|
printf("length is not zero but cc is zero\n");
|
|
printf("%u bytes translated\n", ((unsigned)(len - regs.len))/2);
|
|
printf("the translated values is");
|
|
for (i = 0; i < len/2; i++) {
|
|
printf(" %hx", des[i]);
|
|
}
|
|
printf("\n");
|
|
|
|
return regs.cc;
|
|
}
|
|
|
|
|
|
int main()
|
|
{
|
|
int cc;
|
|
|
|
assert(sizeof des <= sizeof src);
|
|
|
|
/* Test 1 : len == 0 */
|
|
cc = run_test(NULL, NULL, NULL, 0, 0x0);
|
|
if (cc != 0)
|
|
printf("cc not updated properly:%d", cc);
|
|
|
|
cc = run_test(&src, &tran_table, &des, 0, 0x0);
|
|
if (cc != 0)
|
|
printf("cc not updated properly:%d",cc);
|
|
|
|
cc = run_test(&src, &tran_table, &des, 0, 0xcaca);
|
|
if (cc != 0)
|
|
printf("cc not updated properly:%d",cc);
|
|
|
|
/* Test 2 : len > 0, testbyte not matching */
|
|
cc = run_test(&src, &tran_table, &des, 4, 0xdada);
|
|
if (cc != 0)
|
|
printf("cc not updated properly:%d",cc);
|
|
|
|
cc = run_test(&src, &tran_table, &des, 10, 0x00);
|
|
if (cc != 0)
|
|
printf("cc not updated properly:%d",cc);
|
|
|
|
memset((uint16_t *)&des, 0, 10);
|
|
|
|
/* Test 3 : len > 0 , testbyte matching */
|
|
cc = run_test(&src, &tran_table, &des, 10, 0xffff);
|
|
if (cc != 1)
|
|
printf("cc not updated properly:%d",cc);
|
|
|
|
cc = run_test(&src, &tran_table, &des, 10, 0xcccc);
|
|
if (cc != 1)
|
|
printf("cc not updated properly:%d",cc);
|
|
|
|
cc = run_test(&src, &tran_table, &des, 20, 0xeaea);
|
|
if (cc != 1)
|
|
printf("cc not updated properly:%d",cc);
|
|
|
|
return 0;
|
|
}
|