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 TRTT 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 } trtt_regs;
     15 
     16 uint16_t tran_table[40] = {
     17    0xaaaa,0xcccc,0xcccc,0xdddd,0xffff,0xdada,0xbcbc,0xabab,0xcaca,0xeaea,
     18    0xbbbb,0xeeee
     19 };
     20 
     21 uint16_t src[40] = {
     22    0x4,0x03,0x04,0x02,0x07,0x08,0x06,0x02,0x05,0x09,0xa
     23 };
     24 
     25 uint16_t des[20];
     26 
     27 trtt_regs tr(uint16_t *addr, uint16_t *codepage, uint16_t *dest, uint64_t len,
     28              uint16_t test)
     29 {
     30    trtt_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                 " trtt  %1,%2\n"
     41                 " ipm   %0\n"
     42                 " srl   %0,28\n"
     43                 : "=d"(cc),"+d"(desaddr),"+d"(srcaddr)
     44                 : "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 
     54    return regs;
     55 }
     56 
     57 int run_test(void *srcaddr, void *tableaddr, void *desaddr, uint64_t len,
     58              uint16_t testbyte)
     59 {
     60    trtt_regs regs;
     61    int i;
     62 
     63    assert(len <= sizeof src);
     64 
     65    if ((testbyte & 0xffff) != testbyte)
     66       printf("testbyte should be 2 byte only\n");
     67 
     68    regs = tr(srcaddr, tableaddr, desaddr, len, testbyte);
     69 
     70    if ((uint64_t)tableaddr != regs.tabaddr)
     71       printf("translation table address changed\n");
     72    if ((uint64_t)srcaddr + (len - regs.len) != regs.srcaddr)
     73       printf("source address/length not updated properly\n");
     74    if ((uint64_t)desaddr + (len - regs.len) != regs.desaddr)
     75       printf("destination address/length not updated properly\n");
     76    if (regs.cc == 0  && regs.len != 0)
     77       printf("length is not zero but cc is zero\n");
     78    printf("%u bytes translated\n", ((unsigned)(len - regs.len))/2);
     79    printf("the translated values is");
     80    for (i = 0; i < len/2; i++) {
     81       printf(" %hx", des[i]);
     82    }
     83    printf("\n");
     84 
     85    return regs.cc;
     86 }
     87 
     88 
     89 int main()
     90 {
     91    int cc;
     92 
     93    assert(sizeof des <= sizeof src);
     94 
     95    /* Test 1 : len == 0 */
     96    cc = run_test(NULL, NULL, NULL, 0, 0x0);
     97    if (cc != 0)
     98       printf("cc not updated properly:%d", cc);
     99 
    100    cc = run_test(&src, &tran_table, &des, 0, 0x0);
    101    if (cc != 0)
    102       printf("cc not updated properly:%d",cc);
    103 
    104    cc = run_test(&src, &tran_table, &des, 0, 0xcaca);
    105    if (cc != 0)
    106       printf("cc not updated properly:%d",cc);
    107 
    108    /* Test 2 : len > 0, testbyte not matching */
    109    cc = run_test(&src, &tran_table, &des, 4, 0xdada);
    110    if (cc != 0)
    111       printf("cc not updated properly:%d",cc);
    112 
    113    cc = run_test(&src, &tran_table, &des, 10, 0x00);
    114    if (cc != 0)
    115       printf("cc not updated properly:%d",cc);
    116 
    117    memset((uint16_t *)&des, 0, 10);
    118 
    119    /* Test 3 : len > 0 , testbyte matching */
    120    cc = run_test(&src, &tran_table, &des, 10, 0xffff);
    121    if (cc != 1)
    122       printf("cc not updated properly:%d",cc);
    123 
    124    cc = run_test(&src, &tran_table, &des, 10, 0xcccc);
    125    if (cc != 1)
    126       printf("cc not updated properly:%d",cc);
    127 
    128    cc = run_test(&src, &tran_table, &des, 20, 0xeaea);
    129    if (cc != 1)
    130       printf("cc not updated properly:%d",cc);
    131 
    132    return 0;
    133 }
    134