cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bman_test_api.c (4354B)


      1/* Copyright 2008 - 2016 Freescale Semiconductor, Inc.
      2 *
      3 * Redistribution and use in source and binary forms, with or without
      4 * modification, are permitted provided that the following conditions are met:
      5 *     * Redistributions of source code must retain the above copyright
      6 *	 notice, this list of conditions and the following disclaimer.
      7 *     * Redistributions in binary form must reproduce the above copyright
      8 *	 notice, this list of conditions and the following disclaimer in the
      9 *	 documentation and/or other materials provided with the distribution.
     10 *     * Neither the name of Freescale Semiconductor nor the
     11 *	 names of its contributors may be used to endorse or promote products
     12 *	 derived from this software without specific prior written permission.
     13 *
     14 * ALTERNATIVELY, this software may be distributed under the terms of the
     15 * GNU General Public License ("GPL") as published by the Free Software
     16 * Foundation, either version 2 of that License or (at your option) any
     17 * later version.
     18 *
     19 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
     20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     22 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
     23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 */
     30
     31#include "bman_test.h"
     32
     33#define NUM_BUFS	93
     34#define LOOPS		3
     35#define BMAN_TOKEN_MASK 0x00FFFFFFFFFFLLU
     36
     37static struct bman_pool *pool;
     38static struct bm_buffer bufs_in[NUM_BUFS] ____cacheline_aligned;
     39static struct bm_buffer bufs_out[NUM_BUFS] ____cacheline_aligned;
     40static int bufs_received;
     41
     42static void bufs_init(void)
     43{
     44	int i;
     45
     46	for (i = 0; i < NUM_BUFS; i++)
     47		bm_buffer_set64(&bufs_in[i], 0xfedc01234567LLU * i);
     48	bufs_received = 0;
     49}
     50
     51static inline int bufs_cmp(const struct bm_buffer *a, const struct bm_buffer *b)
     52{
     53	if (bman_ip_rev == BMAN_REV20 || bman_ip_rev == BMAN_REV21) {
     54
     55		/*
     56		 * On SoCs with BMan revison 2.0, BMan only respects the 40
     57		 * LS-bits of buffer addresses, masking off the upper 8-bits on
     58		 * release commands. The API provides for 48-bit addresses
     59		 * because some SoCs support all 48-bits. When generating
     60		 * garbage addresses for testing, we either need to zero the
     61		 * upper 8-bits when releasing to BMan (otherwise we'll be
     62		 * disappointed when the buffers we acquire back from BMan
     63		 * don't match), or we need to mask the upper 8-bits off when
     64		 * comparing. We do the latter.
     65		 */
     66		if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK) <
     67		    (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
     68			return -1;
     69		if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK) >
     70		    (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
     71			return 1;
     72	} else {
     73		if (bm_buffer_get64(a) < bm_buffer_get64(b))
     74			return -1;
     75		if (bm_buffer_get64(a) > bm_buffer_get64(b))
     76			return 1;
     77	}
     78
     79	return 0;
     80}
     81
     82static void bufs_confirm(void)
     83{
     84	int i, j;
     85
     86	for (i = 0; i < NUM_BUFS; i++) {
     87		int matches = 0;
     88
     89		for (j = 0; j < NUM_BUFS; j++)
     90			if (!bufs_cmp(&bufs_in[i], &bufs_out[j]))
     91				matches++;
     92		WARN_ON(matches != 1);
     93	}
     94}
     95
     96/* test */
     97void bman_test_api(void)
     98{
     99	int i, loops = LOOPS;
    100
    101	bufs_init();
    102
    103	pr_info("%s(): Starting\n", __func__);
    104
    105	pool = bman_new_pool();
    106	if (!pool) {
    107		pr_crit("bman_new_pool() failed\n");
    108		goto failed;
    109	}
    110
    111	/* Release buffers */
    112do_loop:
    113	i = 0;
    114	while (i < NUM_BUFS) {
    115		int num = 8;
    116
    117		if (i + num > NUM_BUFS)
    118			num = NUM_BUFS - i;
    119		if (bman_release(pool, bufs_in + i, num)) {
    120			pr_crit("bman_release() failed\n");
    121			goto failed;
    122		}
    123		i += num;
    124	}
    125
    126	/* Acquire buffers */
    127	while (i > 0) {
    128		int tmp, num = 8;
    129
    130		if (num > i)
    131			num = i;
    132		tmp = bman_acquire(pool, bufs_out + i - num, num);
    133		WARN_ON(tmp != num);
    134		i -= num;
    135	}
    136	i = bman_acquire(pool, NULL, 1);
    137	WARN_ON(i > 0);
    138
    139	bufs_confirm();
    140
    141	if (--loops)
    142		goto do_loop;
    143
    144	/* Clean up */
    145	bman_free_pool(pool);
    146	pr_info("%s(): Finished\n", __func__);
    147	return;
    148
    149failed:
    150	WARN_ON(1);
    151}