cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

load_align.c (12559B)


      1/*
      2 *  Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
      3 *
      4 *  This program is free software; you can redistribute it and/or modify
      5 *  it under the terms of the GNU General Public License as published by
      6 *  the Free Software Foundation; either version 2 of the License, or
      7 *  (at your option) any later version.
      8 *
      9 *  This program is distributed in the hope that it will be useful,
     10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 *  GNU General Public License for more details.
     13 *
     14 *  You should have received a copy of the GNU General Public License
     15 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
     16 */
     17
     18/*
     19 * Test load align instructions
     20 *
     21 * Example
     22 *     r1:0 = memh_fifo(r1+#0)
     23 * loads a half word from memory, shifts the destination register
     24 * right by one half word and inserts the loaded value into the high
     25 * half word of the destination.
     26 *
     27 * There are 8 addressing modes and byte and half word variants, for a
     28 * total of 16 instructions to test
     29 */
     30
     31#include <stdio.h>
     32#include <string.h>
     33
     34int err;
     35
     36char buf[16] __attribute__((aligned(1 << 16)));
     37
     38void init_buf(void)
     39{
     40    int i;
     41    for (i = 0; i < 16; i++) {
     42        buf[i] = i + 1;
     43    }
     44}
     45
     46void __check(int line, long long result, long long expect)
     47{
     48    if (result != expect) {
     49        printf("ERROR at line %d: 0x%016llx != 0x%016llx\n",
     50               line, result, expect);
     51        err++;
     52    }
     53}
     54
     55#define check(RES, EXP) __check(__LINE__, RES, EXP)
     56
     57void __checkp(int line, void *p, void *expect)
     58{
     59    if (p != expect) {
     60        printf("ERROR at line %d: 0x%p != 0x%p\n", line, p, expect);
     61        err++;
     62    }
     63}
     64
     65#define checkp(RES, EXP) __checkp(__LINE__, RES, EXP)
     66
     67/*
     68 ****************************************************************************
     69 * _io addressing mode (addr + offset)
     70 */
     71#define LOAD_io(SZ, RES, ADDR, OFF) \
     72    __asm__( \
     73        "%0 = mem" #SZ "_fifo(%1+#" #OFF ")\n\t" \
     74        : "+r"(RES) \
     75        : "r"(ADDR))
     76#define LOAD_io_b(RES, ADDR, OFF) \
     77    LOAD_io(b, RES, ADDR, OFF)
     78#define LOAD_io_h(RES, ADDR, OFF) \
     79    LOAD_io(h, RES, ADDR, OFF)
     80
     81#define TEST_io(NAME, SZ, SIZE, EXP1, EXP2, EXP3, EXP4) \
     82void test_##NAME(void) \
     83{ \
     84    long long result = ~0LL; \
     85    LOAD_io_##SZ(result, buf, 0 * (SIZE)); \
     86    check(result, (EXP1)); \
     87    LOAD_io_##SZ(result, buf, 1 * (SIZE)); \
     88    check(result, (EXP2)); \
     89    LOAD_io_##SZ(result, buf, 2 * (SIZE)); \
     90    check(result, (EXP3)); \
     91    LOAD_io_##SZ(result, buf, 3 * (SIZE)); \
     92    check(result, (EXP4)); \
     93}
     94
     95TEST_io(loadalignb_io, b, 1,
     96        0x01ffffffffffffffLL, 0x0201ffffffffffffLL,
     97        0x030201ffffffffffLL, 0x04030201ffffffffLL)
     98TEST_io(loadalignh_io, h, 2,
     99        0x0201ffffffffffffLL, 0x04030201ffffffffLL,
    100        0x060504030201ffffLL, 0x0807060504030201LL)
    101
    102/*
    103 ****************************************************************************
    104 * _ur addressing mode (index << offset + base)
    105 */
    106#define LOAD_ur(SZ, RES, SHIFT, IDX) \
    107    __asm__( \
    108        "%0 = mem" #SZ "_fifo(%1<<#" #SHIFT " + ##buf)\n\t" \
    109        : "+r"(RES) \
    110        : "r"(IDX))
    111#define LOAD_ur_b(RES, SHIFT, IDX) \
    112    LOAD_ur(b, RES, SHIFT, IDX)
    113#define LOAD_ur_h(RES, SHIFT, IDX) \
    114    LOAD_ur(h, RES, SHIFT, IDX)
    115
    116#define TEST_ur(NAME, SZ, SHIFT, RES1, RES2, RES3, RES4) \
    117void test_##NAME(void) \
    118{ \
    119    long long result = ~0LL; \
    120    LOAD_ur_##SZ(result, (SHIFT), 0); \
    121    check(result, (RES1)); \
    122    LOAD_ur_##SZ(result, (SHIFT), 1); \
    123    check(result, (RES2)); \
    124    LOAD_ur_##SZ(result, (SHIFT), 2); \
    125    check(result, (RES3)); \
    126    LOAD_ur_##SZ(result, (SHIFT), 3); \
    127    check(result, (RES4)); \
    128}
    129
    130TEST_ur(loadalignb_ur, b, 1,
    131        0x01ffffffffffffffLL, 0x0301ffffffffffffLL,
    132        0x050301ffffffffffLL, 0x07050301ffffffffLL)
    133TEST_ur(loadalignh_ur, h, 1,
    134        0x0201ffffffffffffLL, 0x04030201ffffffffLL,
    135        0x060504030201ffffLL, 0x0807060504030201LL)
    136
    137/*
    138 ****************************************************************************
    139 * _ap addressing mode (addr = base)
    140 */
    141#define LOAD_ap(SZ, RES, PTR, ADDR) \
    142    __asm__(  \
    143        "%0 = mem" #SZ "_fifo(%1 = ##" #ADDR ")\n\t" \
    144        : "+r"(RES), "=r"(PTR))
    145#define LOAD_ap_b(RES, PTR, ADDR) \
    146    LOAD_ap(b, RES, PTR, ADDR)
    147#define LOAD_ap_h(RES, PTR, ADDR) \
    148    LOAD_ap(h, RES, PTR, ADDR)
    149
    150#define TEST_ap(NAME, SZ, SIZE, RES1, RES2, RES3, RES4) \
    151void test_##NAME(void) \
    152{ \
    153    long long result = ~0LL; \
    154    void *ptr; \
    155    LOAD_ap_##SZ(result, ptr, (buf + 0 * (SIZE))); \
    156    check(result, (RES1)); \
    157    checkp(ptr, &buf[0 * (SIZE)]); \
    158    LOAD_ap_##SZ(result, ptr, (buf + 1 * (SIZE))); \
    159    check(result, (RES2)); \
    160    checkp(ptr, &buf[1 * (SIZE)]); \
    161    LOAD_ap_##SZ(result, ptr, (buf + 2 * (SIZE))); \
    162    check(result, (RES3)); \
    163    checkp(ptr, &buf[2 * (SIZE)]); \
    164    LOAD_ap_##SZ(result, ptr, (buf + 3 * (SIZE))); \
    165    check(result, (RES4)); \
    166    checkp(ptr, &buf[3 * (SIZE)]); \
    167}
    168
    169TEST_ap(loadalignb_ap, b, 1,
    170        0x01ffffffffffffffLL, 0x0201ffffffffffffLL,
    171        0x030201ffffffffffLL, 0x04030201ffffffffLL)
    172TEST_ap(loadalignh_ap, h, 2,
    173        0x0201ffffffffffffLL, 0x04030201ffffffffLL,
    174        0x060504030201ffffLL, 0x0807060504030201LL)
    175
    176/*
    177 ****************************************************************************
    178 * _rp addressing mode (addr ++ modifer-reg)
    179 */
    180#define LOAD_pr(SZ, RES, PTR, INC) \
    181    __asm__( \
    182        "m0 = %2\n\t" \
    183        "%0 = mem" #SZ "_fifo(%1++m0)\n\t" \
    184        : "+r"(RES), "+r"(PTR) \
    185        : "r"(INC) \
    186        : "m0")
    187#define LOAD_pr_b(RES, PTR, INC) \
    188    LOAD_pr(b, RES, PTR, INC)
    189#define LOAD_pr_h(RES, PTR, INC) \
    190    LOAD_pr(h, RES, PTR, INC)
    191
    192#define TEST_pr(NAME, SZ, SIZE, RES1, RES2, RES3, RES4) \
    193void test_##NAME(void) \
    194{ \
    195    long long result = ~0LL; \
    196    void *ptr = buf; \
    197    LOAD_pr_##SZ(result, ptr, (SIZE)); \
    198    check(result, (RES1)); \
    199    checkp(ptr, &buf[1 * (SIZE)]); \
    200    LOAD_pr_##SZ(result, ptr, (SIZE)); \
    201    check(result, (RES2)); \
    202    checkp(ptr, &buf[2 * (SIZE)]); \
    203    LOAD_pr_##SZ(result, ptr, (SIZE)); \
    204    check(result, (RES3)); \
    205    checkp(ptr, &buf[3 * (SIZE)]); \
    206    LOAD_pr_##SZ(result, ptr, (SIZE)); \
    207    check(result, (RES4)); \
    208    checkp(ptr, &buf[4 * (SIZE)]); \
    209}
    210
    211TEST_pr(loadalignb_pr, b, 1,
    212        0x01ffffffffffffffLL, 0x0201ffffffffffffLL,
    213        0x030201ffffffffffLL, 0x04030201ffffffffLL)
    214TEST_pr(loadalignh_pr, h, 2,
    215        0x0201ffffffffffffLL, 0x04030201ffffffffLL,
    216        0x060504030201ffffLL, 0x0807060504030201LL)
    217
    218/*
    219 ****************************************************************************
    220 * _pbr addressing mode (addr ++ modifer-reg:brev)
    221 */
    222#define LOAD_pbr(SZ, RES, PTR) \
    223    __asm__( \
    224        "r4 = #(1 << (16 - 3))\n\t" \
    225        "m0 = r4\n\t" \
    226        "%0 = mem" #SZ "_fifo(%1++m0:brev)\n\t" \
    227        : "+r"(RES), "+r"(PTR) \
    228        : \
    229        : "r4", "m0")
    230#define LOAD_pbr_b(RES, PTR) \
    231    LOAD_pbr(b, RES, PTR)
    232#define LOAD_pbr_h(RES, PTR) \
    233    LOAD_pbr(h, RES, PTR)
    234
    235#define TEST_pbr(NAME, SZ, RES1, RES2, RES3, RES4) \
    236void test_##NAME(void) \
    237{ \
    238    long long result = ~0LL; \
    239    void *ptr = buf; \
    240    LOAD_pbr_##SZ(result, ptr); \
    241    check(result, (RES1)); \
    242    LOAD_pbr_##SZ(result, ptr); \
    243    check(result, (RES2)); \
    244    LOAD_pbr_##SZ(result, ptr); \
    245    check(result, (RES3)); \
    246    LOAD_pbr_##SZ(result, ptr); \
    247    check(result, (RES4)); \
    248}
    249
    250TEST_pbr(loadalignb_pbr, b,
    251    0x01ffffffffffffffLL, 0x0501ffffffffffffLL,
    252    0x030501ffffffffffLL, 0x07030501ffffffffLL)
    253TEST_pbr(loadalignh_pbr, h,
    254    0x0201ffffffffffffLL, 0x06050201ffffffffLL,
    255    0x040306050201ffffLL, 0x0807040306050201LL)
    256
    257/*
    258 ****************************************************************************
    259 * _pi addressing mode (addr ++ inc)
    260 */
    261#define LOAD_pi(SZ, RES, PTR, INC) \
    262    __asm__( \
    263        "%0 = mem" #SZ "_fifo(%1++#" #INC ")\n\t" \
    264        : "+r"(RES), "+r"(PTR))
    265#define LOAD_pi_b(RES, PTR, INC) \
    266    LOAD_pi(b, RES, PTR, INC)
    267#define LOAD_pi_h(RES, PTR, INC) \
    268    LOAD_pi(h, RES, PTR, INC)
    269
    270#define TEST_pi(NAME, SZ, INC, RES1, RES2, RES3, RES4) \
    271void test_##NAME(void) \
    272{ \
    273    long long result = ~0LL; \
    274    void *ptr = buf; \
    275    LOAD_pi_##SZ(result, ptr, (INC)); \
    276    check(result, (RES1)); \
    277    checkp(ptr, &buf[1 * (INC)]); \
    278    LOAD_pi_##SZ(result, ptr, (INC)); \
    279    check(result, (RES2)); \
    280    checkp(ptr, &buf[2 * (INC)]); \
    281    LOAD_pi_##SZ(result, ptr, (INC)); \
    282    check(result, (RES3)); \
    283    checkp(ptr, &buf[3 * (INC)]); \
    284    LOAD_pi_##SZ(result, ptr, (INC)); \
    285    check(result, (RES4)); \
    286    checkp(ptr, &buf[4 * (INC)]); \
    287}
    288
    289TEST_pi(loadalignb_pi, b, 1,
    290        0x01ffffffffffffffLL, 0x0201ffffffffffffLL,
    291        0x030201ffffffffffLL, 0x04030201ffffffffLL)
    292TEST_pi(loadalignh_pi, h, 2,
    293        0x0201ffffffffffffLL, 0x04030201ffffffffLL,
    294        0x060504030201ffffLL, 0x0807060504030201LL)
    295
    296/*
    297 ****************************************************************************
    298 * _pci addressing mode (addr ++ inc:circ)
    299 */
    300#define LOAD_pci(SZ, RES, PTR, START, LEN, INC) \
    301    __asm__( \
    302        "r4 = %3\n\t" \
    303        "m0 = r4\n\t" \
    304        "cs0 = %2\n\t" \
    305        "%0 = mem" #SZ "_fifo(%1++#" #INC ":circ(m0))\n\t" \
    306        : "+r"(RES), "+r"(PTR) \
    307        : "r"(START), "r"(LEN) \
    308        : "r4", "m0", "cs0")
    309#define LOAD_pci_b(RES, PTR, START, LEN, INC) \
    310    LOAD_pci(b, RES, PTR, START, LEN, INC)
    311#define LOAD_pci_h(RES, PTR, START, LEN, INC) \
    312    LOAD_pci(h, RES, PTR, START, LEN, INC)
    313
    314#define TEST_pci(NAME, SZ, LEN, INC, RES1, RES2, RES3, RES4) \
    315void test_##NAME(void) \
    316{ \
    317    long long result = ~0LL; \
    318    void *ptr = buf; \
    319    LOAD_pci_##SZ(result, ptr, buf, (LEN), (INC)); \
    320    check(result, (RES1)); \
    321    checkp(ptr, &buf[(1 * (INC)) % (LEN)]); \
    322    LOAD_pci_##SZ(result, ptr, buf, (LEN), (INC)); \
    323    check(result, (RES2)); \
    324    checkp(ptr, &buf[(2 * (INC)) % (LEN)]); \
    325    LOAD_pci_##SZ(result, ptr, buf, (LEN), (INC)); \
    326    check(result, (RES3)); \
    327    checkp(ptr, &buf[(3 * (INC)) % (LEN)]); \
    328    LOAD_pci_##SZ(result, ptr, buf, (LEN), (INC)); \
    329    check(result, (RES4)); \
    330    checkp(ptr, &buf[(4 * (INC)) % (LEN)]); \
    331}
    332
    333TEST_pci(loadalignb_pci, b, 2, 1,
    334    0x01ffffffffffffffLL, 0x0201ffffffffffffLL,
    335    0x010201ffffffffffLL, 0x02010201ffffffffLL)
    336TEST_pci(loadalignh_pci, h, 4, 2,
    337    0x0201ffffffffffffLL, 0x04030201ffffffffLL,
    338    0x020104030201ffffLL, 0x0403020104030201LL)
    339
    340/*
    341 ****************************************************************************
    342 * _pcr addressing mode (addr ++ I:circ(modifier-reg))
    343 */
    344#define LOAD_pcr(SZ, RES, PTR, START, LEN, INC) \
    345    __asm__( \
    346        "r4 = %2\n\t" \
    347        "m1 = r4\n\t" \
    348        "cs1 = %3\n\t" \
    349        "%0 = mem" #SZ "_fifo(%1++I:circ(m1))\n\t" \
    350        : "+r"(RES), "+r"(PTR) \
    351        : "r"((((INC) & 0x7f) << 17) | ((LEN) & 0x1ffff)), \
    352          "r"(START) \
    353        : "r4", "m1", "cs1")
    354#define LOAD_pcr_b(RES, PTR, START, LEN, INC) \
    355    LOAD_pcr(b, RES, PTR, START, LEN, INC)
    356#define LOAD_pcr_h(RES, PTR, START, LEN, INC) \
    357    LOAD_pcr(h, RES, PTR, START, LEN, INC)
    358
    359#define TEST_pcr(NAME, SZ, SIZE, LEN, INC, RES1, RES2, RES3, RES4) \
    360void test_##NAME(void) \
    361{ \
    362    long long result = ~0LL; \
    363    void *ptr = buf; \
    364    LOAD_pcr_##SZ(result, ptr, buf, (LEN), (INC)); \
    365    check(result, (RES1)); \
    366    checkp(ptr, &buf[(1 * (INC) * (SIZE)) % (LEN)]); \
    367    LOAD_pcr_##SZ(result, ptr, buf, (LEN), (INC)); \
    368    check(result, (RES2)); \
    369    checkp(ptr, &buf[(2 * (INC) * (SIZE)) % (LEN)]); \
    370    LOAD_pcr_##SZ(result, ptr, buf, (LEN), (INC)); \
    371    check(result, (RES3)); \
    372    checkp(ptr, &buf[(3 * (INC) * (SIZE)) % (LEN)]); \
    373    LOAD_pcr_##SZ(result, ptr, buf, (LEN), (INC)); \
    374    check(result, (RES4)); \
    375    checkp(ptr, &buf[(4 * (INC) * (SIZE)) % (LEN)]); \
    376}
    377
    378TEST_pcr(loadalignb_pcr, b, 1, 2, 1,
    379    0x01ffffffffffffffLL, 0x0201ffffffffffffLL,
    380    0x010201ffffffffffLL, 0x02010201ffffffffLL)
    381TEST_pcr(loadalignh_pcr, h, 2, 4, 1,
    382    0x0201ffffffffffffLL, 0x04030201ffffffffLL,
    383    0x020104030201ffffLL, 0x0403020104030201LL)
    384
    385int main()
    386{
    387    init_buf();
    388
    389    test_loadalignb_io();
    390    test_loadalignh_io();
    391
    392    test_loadalignb_ur();
    393    test_loadalignh_ur();
    394
    395    test_loadalignb_ap();
    396    test_loadalignh_ap();
    397
    398    test_loadalignb_pr();
    399    test_loadalignh_pr();
    400
    401    test_loadalignb_pbr();
    402    test_loadalignh_pbr();
    403
    404    test_loadalignb_pi();
    405    test_loadalignh_pi();
    406
    407    test_loadalignb_pci();
    408    test_loadalignh_pci();
    409
    410    test_loadalignb_pcr();
    411    test_loadalignh_pcr();
    412
    413    puts(err ? "FAIL" : "PASS");
    414    return err ? 1 : 0;
    415}