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

conversion.c (2781B)


      1/*
      2 * Copyright 2012-15 Advanced Micro Devices, Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 *
     22 * Authors: AMD
     23 *
     24 */
     25
     26#include "dm_services.h"
     27#include "conversion.h"
     28
     29#define DIVIDER 10000
     30
     31/* S2D13 value in [-3.00...0.9999] */
     32#define S2D13_MIN (-3 * DIVIDER)
     33#define S2D13_MAX (3 * DIVIDER)
     34
     35uint16_t fixed_point_to_int_frac(
     36	struct fixed31_32 arg,
     37	uint8_t integer_bits,
     38	uint8_t fractional_bits)
     39{
     40	int32_t numerator;
     41	int32_t divisor = 1 << fractional_bits;
     42
     43	uint16_t result;
     44
     45	uint16_t d = (uint16_t)dc_fixpt_floor(
     46		dc_fixpt_abs(
     47			arg));
     48
     49	if (d <= (uint16_t)(1 << integer_bits) - (1 / (uint16_t)divisor))
     50		numerator = (uint16_t)dc_fixpt_round(
     51			dc_fixpt_mul_int(
     52				arg,
     53				divisor));
     54	else {
     55		numerator = dc_fixpt_floor(
     56			dc_fixpt_sub(
     57				dc_fixpt_from_int(
     58					1LL << integer_bits),
     59				dc_fixpt_recip(
     60					dc_fixpt_from_int(
     61						divisor))));
     62	}
     63
     64	if (numerator >= 0)
     65		result = (uint16_t)numerator;
     66	else
     67		result = (uint16_t)(
     68		(1 << (integer_bits + fractional_bits + 1)) + numerator);
     69
     70	if ((result != 0) && dc_fixpt_lt(
     71		arg, dc_fixpt_zero))
     72		result |= 1 << (integer_bits + fractional_bits);
     73
     74	return result;
     75}
     76/*
     77 * convert_float_matrix - This converts a double into HW register spec defined format S2D13.
     78 */
     79void convert_float_matrix(
     80	uint16_t *matrix,
     81	struct fixed31_32 *flt,
     82	uint32_t buffer_size)
     83{
     84	const struct fixed31_32 min_2_13 =
     85		dc_fixpt_from_fraction(S2D13_MIN, DIVIDER);
     86	const struct fixed31_32 max_2_13 =
     87		dc_fixpt_from_fraction(S2D13_MAX, DIVIDER);
     88	uint32_t i;
     89
     90	for (i = 0; i < buffer_size; ++i) {
     91		uint32_t reg_value =
     92				fixed_point_to_int_frac(
     93					dc_fixpt_clamp(
     94						flt[i],
     95						min_2_13,
     96						max_2_13),
     97						2,
     98						13);
     99
    100		matrix[i] = (uint16_t)reg_value;
    101	}
    102}