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