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

brev.c (5517B)


      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#include <stdio.h>
     19#include <string.h>
     20
     21int err;
     22
     23#define NBITS          8
     24#define SIZE           (1 << NBITS)
     25
     26long long     dbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
     27int           wbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
     28short         hbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
     29unsigned char bbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
     30
     31/*
     32 * We use the C preporcessor to deal with the combinations of types
     33 */
     34
     35#define BREV_LOAD(SZ, RES, ADDR, INC) \
     36    __asm__( \
     37        "m0 = %2\n\t" \
     38        "%0 = mem" #SZ "(%1++m0:brev)\n\t" \
     39        : "=r"(RES), "+r"(ADDR) \
     40        : "r"(INC) \
     41        : "m0")
     42
     43#define BREV_LOAD_b(RES, ADDR, INC) \
     44    BREV_LOAD(b, RES, ADDR, INC)
     45#define BREV_LOAD_ub(RES, ADDR, INC) \
     46    BREV_LOAD(ub, RES, ADDR, INC)
     47#define BREV_LOAD_h(RES, ADDR, INC) \
     48    BREV_LOAD(h, RES, ADDR, INC)
     49#define BREV_LOAD_uh(RES, ADDR, INC) \
     50    BREV_LOAD(uh, RES, ADDR, INC)
     51#define BREV_LOAD_w(RES, ADDR, INC) \
     52    BREV_LOAD(w, RES, ADDR, INC)
     53#define BREV_LOAD_d(RES, ADDR, INC) \
     54    BREV_LOAD(d, RES, ADDR, INC)
     55
     56#define BREV_STORE(SZ, PART, ADDR, VAL, INC) \
     57    __asm__( \
     58        "m0 = %2\n\t" \
     59        "mem" #SZ "(%0++m0:brev) = %1" PART "\n\t" \
     60        : "+r"(ADDR) \
     61        : "r"(VAL), "r"(INC) \
     62        : "m0", "memory")
     63
     64#define BREV_STORE_b(ADDR, VAL, INC) \
     65    BREV_STORE(b, "", ADDR, VAL, INC)
     66#define BREV_STORE_h(ADDR, VAL, INC) \
     67    BREV_STORE(h, "", ADDR, VAL, INC)
     68#define BREV_STORE_f(ADDR, VAL, INC) \
     69    BREV_STORE(h, ".H", ADDR, VAL, INC)
     70#define BREV_STORE_w(ADDR, VAL, INC) \
     71    BREV_STORE(w, "", ADDR, VAL, INC)
     72#define BREV_STORE_d(ADDR, VAL, INC) \
     73    BREV_STORE(d, "", ADDR, VAL, INC)
     74
     75#define BREV_STORE_NEW(SZ, ADDR, VAL, INC) \
     76    __asm__( \
     77        "m0 = %2\n\t" \
     78        "{\n\t" \
     79        "    r5 = %1\n\t" \
     80        "    mem" #SZ "(%0++m0:brev) = r5.new\n\t" \
     81        "}\n\t" \
     82        : "+r"(ADDR) \
     83        : "r"(VAL), "r"(INC) \
     84        : "r5", "m0", "memory")
     85
     86#define BREV_STORE_bnew(ADDR, VAL, INC) \
     87    BREV_STORE_NEW(b, ADDR, VAL, INC)
     88#define BREV_STORE_hnew(ADDR, VAL, INC) \
     89    BREV_STORE_NEW(h, ADDR, VAL, INC)
     90#define BREV_STORE_wnew(ADDR, VAL, INC) \
     91    BREV_STORE_NEW(w, ADDR, VAL, INC)
     92
     93int bitreverse(int x)
     94{
     95    int result = 0;
     96    int i;
     97    for (i = 0; i < NBITS; i++) {
     98        result <<= 1;
     99        result |= x & 1;
    100        x >>= 1;
    101    }
    102    return result;
    103}
    104
    105int sext8(int x)
    106{
    107    return (x << 24) >> 24;
    108}
    109
    110void check(int i, long long result, long long expect)
    111{
    112    if (result != expect) {
    113        printf("ERROR(%d): 0x%04llx != 0x%04llx\n", i, result, expect);
    114        err++;
    115    }
    116}
    117
    118#define TEST_BREV_LOAD(SZ, TYPE, BUF, SHIFT, EXP) \
    119    do { \
    120        p = BUF; \
    121        for (i = 0; i < SIZE; i++) { \
    122            TYPE result; \
    123            BREV_LOAD_##SZ(result, p, 1 << (SHIFT - NBITS)); \
    124            check(i, result, EXP); \
    125        } \
    126    } while (0)
    127
    128#define TEST_BREV_STORE(SZ, TYPE, BUF, VAL, SHIFT) \
    129    do { \
    130        p = BUF; \
    131        memset(BUF, 0xff, sizeof(BUF)); \
    132        for (i = 0; i < SIZE; i++) { \
    133            BREV_STORE_##SZ(p, (TYPE)(VAL), 1 << (SHIFT - NBITS)); \
    134        } \
    135        for (i = 0; i < SIZE; i++) { \
    136            check(i, BUF[i], bitreverse(i)); \
    137        } \
    138    } while (0)
    139
    140#define TEST_BREV_STORE_NEW(SZ, BUF, SHIFT) \
    141    do { \
    142        p = BUF; \
    143        memset(BUF, 0xff, sizeof(BUF)); \
    144        for (i = 0; i < SIZE; i++) { \
    145            BREV_STORE_##SZ(p, i, 1 << (SHIFT - NBITS)); \
    146        } \
    147        for (i = 0; i < SIZE; i++) { \
    148            check(i, BUF[i], bitreverse(i)); \
    149        } \
    150    } while (0)
    151
    152/*
    153 * We'll set high_half[i] = i << 16 for use in the .H form of store
    154 * which stores from the high half of the word.
    155 */
    156int high_half[SIZE];
    157
    158int main()
    159{
    160    void *p;
    161    int i;
    162
    163    for (i = 0; i < SIZE; i++) {
    164        bbuf[i] = bitreverse(i);
    165        hbuf[i] = bitreverse(i);
    166        wbuf[i] = bitreverse(i);
    167        dbuf[i] = bitreverse(i);
    168        high_half[i] = i << 16;
    169    }
    170
    171    TEST_BREV_LOAD(b,  int,       bbuf, 16, sext8(i));
    172    TEST_BREV_LOAD(ub, int,       bbuf, 16, i);
    173    TEST_BREV_LOAD(h,  int,       hbuf, 15, i);
    174    TEST_BREV_LOAD(uh, int,       hbuf, 15, i);
    175    TEST_BREV_LOAD(w,  int,       wbuf, 14, i);
    176    TEST_BREV_LOAD(d,  long long, dbuf, 13, i);
    177
    178    TEST_BREV_STORE(b, int,       bbuf, i,            16);
    179    TEST_BREV_STORE(h, int,       hbuf, i,            15);
    180    TEST_BREV_STORE(f, int,       hbuf, high_half[i], 15);
    181    TEST_BREV_STORE(w, int,       wbuf, i,            14);
    182    TEST_BREV_STORE(d, long long, dbuf, i,            13);
    183
    184    TEST_BREV_STORE_NEW(bnew, bbuf, 16);
    185    TEST_BREV_STORE_NEW(hnew, hbuf, 15);
    186    TEST_BREV_STORE_NEW(wnew, wbuf, 14);
    187
    188    puts(err ? "FAIL" : "PASS");
    189    return err ? 1 : 0;
    190}