177cb4d3eSLandon J. Fuller /*- 277cb4d3eSLandon J. Fuller * Copyright (c) 2015-2016 Landon Fuller <landonf@FreeBSD.org> 377cb4d3eSLandon J. Fuller * All rights reserved. 477cb4d3eSLandon J. Fuller * 577cb4d3eSLandon J. Fuller * Redistribution and use in source and binary forms, with or without 677cb4d3eSLandon J. Fuller * modification, are permitted provided that the following conditions 777cb4d3eSLandon J. Fuller * are met: 877cb4d3eSLandon J. Fuller * 1. Redistributions of source code must retain the above copyright 977cb4d3eSLandon J. Fuller * notice, this list of conditions and the following disclaimer, 1077cb4d3eSLandon J. Fuller * without modification. 1177cb4d3eSLandon J. Fuller * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1277cb4d3eSLandon J. Fuller * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 1377cb4d3eSLandon J. Fuller * redistribution must be conditioned upon including a substantially 1477cb4d3eSLandon J. Fuller * similar Disclaimer requirement for further binary redistribution. 1577cb4d3eSLandon J. Fuller * 1677cb4d3eSLandon J. Fuller * NO WARRANTY 1777cb4d3eSLandon J. Fuller * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1877cb4d3eSLandon J. Fuller * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1977cb4d3eSLandon J. Fuller * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 2077cb4d3eSLandon J. Fuller * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 2177cb4d3eSLandon J. Fuller * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 2277cb4d3eSLandon J. Fuller * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2377cb4d3eSLandon J. Fuller * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2477cb4d3eSLandon J. Fuller * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 2577cb4d3eSLandon J. Fuller * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2677cb4d3eSLandon J. Fuller * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 2777cb4d3eSLandon J. Fuller * THE POSSIBILITY OF SUCH DAMAGES. 2877cb4d3eSLandon J. Fuller * 2977cb4d3eSLandon J. Fuller */ 3077cb4d3eSLandon J. Fuller 3177cb4d3eSLandon J. Fuller #ifndef _BHND_NVRAM_BHND_NVRAM_SPROMVAR_H_ 3277cb4d3eSLandon J. Fuller #define _BHND_NVRAM_BHND_NVRAM_SPROMVAR_H_ 3377cb4d3eSLandon J. Fuller 3477cb4d3eSLandon J. Fuller #ifdef _KERNEL 3577cb4d3eSLandon J. Fuller #include <sys/bitstring.h> 3677cb4d3eSLandon J. Fuller #else 3777cb4d3eSLandon J. Fuller #include <bitstring.h> 3877cb4d3eSLandon J. Fuller #endif 3977cb4d3eSLandon J. Fuller 4077cb4d3eSLandon J. Fuller #include "bhnd_nvram_private.h" 4177cb4d3eSLandon J. Fuller 4277cb4d3eSLandon J. Fuller #include "bhnd_nvram_datavar.h" 4377cb4d3eSLandon J. Fuller #include "bhnd_nvram_io.h" 4477cb4d3eSLandon J. Fuller 4577cb4d3eSLandon J. Fuller /** The maximum number of array elements encoded in a single SPROM variable */ 46c283839dSLandon J. Fuller #define BHND_SPROM_ARRAY_MAXLEN 12 47c283839dSLandon J. Fuller 48c283839dSLandon J. Fuller typedef struct bhnd_sprom_opcode_state bhnd_sprom_opcode_state; 49c283839dSLandon J. Fuller typedef struct bhnd_sprom_opcode_bind bhnd_sprom_opcode_bind; 50c283839dSLandon J. Fuller typedef struct bhnd_sprom_opcode_var bhnd_sprom_opcode_var; 51c283839dSLandon J. Fuller typedef struct bhnd_sprom_opcode_idx_entry bhnd_sprom_opcode_idx_entry; 52c283839dSLandon J. Fuller 53c283839dSLandon J. Fuller int bhnd_sprom_opcode_init( 54c283839dSLandon J. Fuller bhnd_sprom_opcode_state *state, 55c283839dSLandon J. Fuller const bhnd_sprom_layout *layout); 56c283839dSLandon J. Fuller void bhnd_sprom_opcode_fini( 57c283839dSLandon J. Fuller bhnd_sprom_opcode_state *state); 58c283839dSLandon J. Fuller 59c283839dSLandon J. Fuller bhnd_sprom_opcode_idx_entry *bhnd_sprom_opcode_index_find( 60c283839dSLandon J. Fuller bhnd_sprom_opcode_state *state, 61c283839dSLandon J. Fuller const char *name); 62c283839dSLandon J. Fuller bhnd_sprom_opcode_idx_entry *bhnd_sprom_opcode_index_next( 63c283839dSLandon J. Fuller bhnd_sprom_opcode_state *state, 64c283839dSLandon J. Fuller bhnd_sprom_opcode_idx_entry *prev); 65c283839dSLandon J. Fuller 66*591e79bcSLandon J. Fuller int bhnd_sprom_opcode_init_entry( 67*591e79bcSLandon J. Fuller bhnd_sprom_opcode_state *state, 68*591e79bcSLandon J. Fuller bhnd_sprom_opcode_idx_entry *entry); 69*591e79bcSLandon J. Fuller 70*591e79bcSLandon J. Fuller int bhnd_sprom_opcode_eval_var( 71c283839dSLandon J. Fuller bhnd_sprom_opcode_state *state, 72c283839dSLandon J. Fuller bhnd_sprom_opcode_idx_entry *entry); 73c283839dSLandon J. Fuller 74c283839dSLandon J. Fuller int bhnd_sprom_opcode_seek( 75c283839dSLandon J. Fuller bhnd_sprom_opcode_state *state, 76c283839dSLandon J. Fuller bhnd_sprom_opcode_idx_entry *entry); 77*591e79bcSLandon J. Fuller int bhnd_sprom_opcode_next_var( 78*591e79bcSLandon J. Fuller bhnd_sprom_opcode_state *state); 79c283839dSLandon J. Fuller int bhnd_sprom_opcode_next_binding( 80c283839dSLandon J. Fuller bhnd_sprom_opcode_state *state); 81c283839dSLandon J. Fuller int bhnd_sprom_opcode_apply_scale( 82c283839dSLandon J. Fuller bhnd_sprom_opcode_state *state, 83c283839dSLandon J. Fuller uint32_t *value); 8477cb4d3eSLandon J. Fuller 8577cb4d3eSLandon J. Fuller /** 8677cb4d3eSLandon J. Fuller * SPROM opcode per-bind evaluation state. 8777cb4d3eSLandon J. Fuller */ 88c283839dSLandon J. Fuller struct bhnd_sprom_opcode_bind { 8977cb4d3eSLandon J. Fuller uint8_t count; 9077cb4d3eSLandon J. Fuller uint32_t skip_in; /**< input element skips */ 9177cb4d3eSLandon J. Fuller bool skip_in_negative; /**< skip_in should be subtracted */ 9277cb4d3eSLandon J. Fuller uint32_t skip_out; /**< output element skip */ 9377cb4d3eSLandon J. Fuller }; 9477cb4d3eSLandon J. Fuller 9577cb4d3eSLandon J. Fuller /** 9677cb4d3eSLandon J. Fuller * SPROM opcode per-variable evaluation state. 9777cb4d3eSLandon J. Fuller */ 98c283839dSLandon J. Fuller struct bhnd_sprom_opcode_var { 9977cb4d3eSLandon J. Fuller uint8_t nelem; /**< variable array length */ 10077cb4d3eSLandon J. Fuller uint32_t mask; /**< current bind input mask */ 10177cb4d3eSLandon J. Fuller int8_t shift; /**< current bind input shift */ 10277cb4d3eSLandon J. Fuller bhnd_nvram_type base_type; /**< current bind input type */ 10377cb4d3eSLandon J. Fuller uint32_t scale; /**< current scale to apply to scaled encodings */ 104c283839dSLandon J. Fuller bhnd_sprom_opcode_bind bind; /**< current bind state */ 10577cb4d3eSLandon J. Fuller bool have_bind; /**< if bind state is defined */ 10677cb4d3eSLandon J. Fuller size_t bind_total; /**< total count of bind operations performed */ 10777cb4d3eSLandon J. Fuller }; 10877cb4d3eSLandon J. Fuller 10977cb4d3eSLandon J. Fuller /** 11077cb4d3eSLandon J. Fuller * SPROM opcode variable definition states. 11177cb4d3eSLandon J. Fuller * 11277cb4d3eSLandon J. Fuller * Ordered to support inequality comparisons 11377cb4d3eSLandon J. Fuller * (e.g. >= SPROM_OPCODE_VAR_STATE_OPEN) 11477cb4d3eSLandon J. Fuller */ 11577cb4d3eSLandon J. Fuller typedef enum { 11677cb4d3eSLandon J. Fuller SPROM_OPCODE_VAR_STATE_NONE = 1, /**< no variable entry available */ 11777cb4d3eSLandon J. Fuller SPROM_OPCODE_VAR_STATE_OPEN = 2, /**< currently parsing a variable entry */ 11877cb4d3eSLandon J. Fuller SPROM_OPCODE_VAR_STATE_DONE = 3 /**< full variable entry has been parsed */ 119c283839dSLandon J. Fuller } bhnd_sprom_opcode_var_state; 12077cb4d3eSLandon J. Fuller 12177cb4d3eSLandon J. Fuller /** 12277cb4d3eSLandon J. Fuller * SPROM opcode evaluation state 12377cb4d3eSLandon J. Fuller */ 124c283839dSLandon J. Fuller struct bhnd_sprom_opcode_state { 125c283839dSLandon J. Fuller const bhnd_sprom_layout *layout; /**< SPROM layout */ 126c283839dSLandon J. Fuller 127c283839dSLandon J. Fuller bhnd_sprom_opcode_idx_entry *idx; /**< variable index (NULL during initialization) */ 128c283839dSLandon J. Fuller size_t num_idx; /**< variable index entry count */ 12977cb4d3eSLandon J. Fuller 13077cb4d3eSLandon J. Fuller /** Current SPROM revision range */ 13177cb4d3eSLandon J. Fuller bitstr_t bit_decl(revs, SPROM_OP_REV_MAX); 13277cb4d3eSLandon J. Fuller 13377cb4d3eSLandon J. Fuller const uint8_t *input; /**< opcode input position */ 13477cb4d3eSLandon J. Fuller 13577cb4d3eSLandon J. Fuller /* State preserved across variable definitions */ 13677cb4d3eSLandon J. Fuller uint32_t offset; /**< SPROM offset */ 13777cb4d3eSLandon J. Fuller size_t vid; /**< Variable ID */ 13877cb4d3eSLandon J. Fuller 13977cb4d3eSLandon J. Fuller /* State reset after end of each variable definition */ 140c283839dSLandon J. Fuller bhnd_sprom_opcode_var var; /**< variable record (if any) */ 141c283839dSLandon J. Fuller bhnd_sprom_opcode_var_state var_state; /**< variable record state */ 14277cb4d3eSLandon J. Fuller }; 14377cb4d3eSLandon J. Fuller 14477cb4d3eSLandon J. Fuller /** 14577cb4d3eSLandon J. Fuller * SPROM opcode variable index entry 14677cb4d3eSLandon J. Fuller */ 147c283839dSLandon J. Fuller struct bhnd_sprom_opcode_idx_entry { 14877cb4d3eSLandon J. Fuller uint16_t vid; /**< SPROM variable ID */ 14977cb4d3eSLandon J. Fuller uint16_t offset; /**< SPROM input offset */ 15077cb4d3eSLandon J. Fuller uint16_t opcodes; /**< SPROM opcode offset */ 15177cb4d3eSLandon J. Fuller }; 15277cb4d3eSLandon J. Fuller 15377cb4d3eSLandon J. Fuller /** 15477cb4d3eSLandon J. Fuller * SPROM value storage. 15577cb4d3eSLandon J. Fuller * 15677cb4d3eSLandon J. Fuller * Sufficient for representing the native encoding of any defined SPROM 15777cb4d3eSLandon J. Fuller * variable. 15877cb4d3eSLandon J. Fuller */ 15977cb4d3eSLandon J. Fuller union bhnd_nvram_sprom_storage { 160c283839dSLandon J. Fuller uint8_t u8[BHND_SPROM_ARRAY_MAXLEN]; 161c283839dSLandon J. Fuller uint16_t u16[BHND_SPROM_ARRAY_MAXLEN]; 162c283839dSLandon J. Fuller uint32_t u32[BHND_SPROM_ARRAY_MAXLEN]; 163c283839dSLandon J. Fuller int8_t i8[BHND_SPROM_ARRAY_MAXLEN]; 164c283839dSLandon J. Fuller int16_t i16[BHND_SPROM_ARRAY_MAXLEN]; 165c283839dSLandon J. Fuller int32_t i32[BHND_SPROM_ARRAY_MAXLEN]; 166c283839dSLandon J. Fuller char ch[BHND_SPROM_ARRAY_MAXLEN]; 16777cb4d3eSLandon J. Fuller }; 16877cb4d3eSLandon J. Fuller 16977cb4d3eSLandon J. Fuller /** 17077cb4d3eSLandon J. Fuller * SPROM data class instance state. 17177cb4d3eSLandon J. Fuller */ 17277cb4d3eSLandon J. Fuller struct bhnd_nvram_sprom { 17377cb4d3eSLandon J. Fuller struct bhnd_nvram_data nv; /**< common instance state */ 17477cb4d3eSLandon J. Fuller struct bhnd_nvram_io *data; /**< backing SPROM image */ 175c283839dSLandon J. Fuller const bhnd_sprom_layout *layout; /**< layout definition */ 176c283839dSLandon J. Fuller bhnd_sprom_opcode_state state; /**< opcode eval state */ 17777cb4d3eSLandon J. Fuller }; 17877cb4d3eSLandon J. Fuller 17977cb4d3eSLandon J. Fuller #endif /* _BHND_NVRAM_BHND_NVRAM_SPROMVAR_H_ */ 180