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