1 /* 2 * QEMU model of the Xilinx eFuse core 3 * 4 * Copyright (c) 2015 Xilinx Inc. 5 * 6 * Written by Edgar E. Iglesias <edgari@xilinx.com> 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * of this software and associated documentation files (the "Software"), to deal 10 * in the Software without restriction, including without limitation the rights 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * copies of the Software, and to permit persons to whom the Software is 13 * furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included in 16 * all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 * THE SOFTWARE. 25 */ 26 27 #ifndef XLNX_EFUSE_H 28 #define XLNX_EFUSE_H 29 30 #include "sysemu/block-backend.h" 31 #include "hw/qdev-core.h" 32 33 #define TYPE_XLNX_EFUSE "xlnx,efuse" 34 OBJECT_DECLARE_SIMPLE_TYPE(XlnxEFuse, XLNX_EFUSE); 35 36 struct XlnxEFuse { 37 DeviceState parent_obj; 38 BlockBackend *blk; 39 bool blk_ro; 40 uint32_t *fuse32; 41 42 DeviceState *dev; 43 44 bool init_tbits; 45 46 uint8_t efuse_nr; 47 uint32_t efuse_size; 48 49 uint32_t *ro_bits; 50 uint32_t ro_bits_cnt; 51 }; 52 53 /** 54 * xlnx_efuse_calc_crc: 55 * @data: an array of 32-bit words for which the CRC should be computed 56 * @u32_cnt: the array size in number of 32-bit words 57 * @zpads: the number of 32-bit zeros prepended to @data before computation 58 * 59 * This function is used to compute the CRC for an array of 32-bit words, 60 * using a Xilinx-specific data padding. 61 * 62 * Returns: the computed 32-bit CRC 63 */ 64 uint32_t xlnx_efuse_calc_crc(const uint32_t *data, unsigned u32_cnt, 65 unsigned zpads); 66 67 /** 68 * xlnx_efuse_get_bit: 69 * @s: the efuse object 70 * @bit: the efuse bit-address to read the data 71 * 72 * Returns: the bit, 0 or 1, at @bit of object @s 73 */ 74 bool xlnx_efuse_get_bit(XlnxEFuse *s, unsigned int bit); 75 76 /** 77 * xlnx_efuse_set_bit: 78 * @s: the efuse object 79 * @bit: the efuse bit-address to be written a value of 1 80 * 81 * Returns: true on success, false on failure 82 */ 83 bool xlnx_efuse_set_bit(XlnxEFuse *s, unsigned int bit); 84 85 /** 86 * xlnx_efuse_k256_check: 87 * @s: the efuse object 88 * @crc: the 32-bit CRC to be compared with 89 * @start: the efuse bit-address (which must be multiple of 32) of the 90 * start of a 256-bit array 91 * 92 * This function computes the CRC of a 256-bit array starting at @start 93 * then compares to the given @crc 94 * 95 * Returns: true of @crc == computed, false otherwise 96 */ 97 bool xlnx_efuse_k256_check(XlnxEFuse *s, uint32_t crc, unsigned start); 98 99 /** 100 * xlnx_efuse_tbits_check: 101 * @s: the efuse object 102 * 103 * This function inspects a number of efuse bits at specific addresses 104 * to see if they match a validation pattern. Each pattern is a group 105 * of 4 bits, and there are 3 groups. 106 * 107 * Returns: a 3-bit mask, where a bit of '1' means the corresponding 108 * group has a valid pattern. 109 */ 110 uint32_t xlnx_efuse_tbits_check(XlnxEFuse *s); 111 112 /** 113 * xlnx_efuse_get_row: 114 * @s: the efuse object 115 * @bit: the efuse bit address for which a 32-bit value is read 116 * 117 * Returns: the entire 32 bits of the efuse, starting at a bit 118 * address that is multiple of 32 and contains the bit at @bit 119 */ 120 static inline uint32_t xlnx_efuse_get_row(XlnxEFuse *s, unsigned int bit) 121 { 122 if (!(s->fuse32)) { 123 return 0; 124 } else { 125 unsigned int row_idx = bit / 32; 126 127 assert(row_idx < (s->efuse_size * s->efuse_nr / 32)); 128 return s->fuse32[row_idx]; 129 } 130 } 131 132 #endif 133