Lines Matching +full:data +full:- +full:shift

1 /*-
2 * Copyright (c) 2015-2016 Landon Fuller <landonf@FreeBSD.org>
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
58 * BHND SPROM NVRAM data class
60 * The SPROM data format is a fixed-layout, non-self-descriptive binary format,
86 struct bhnd_nvram_io *data,
88 uint32_t mask, int8_t shift,
93 struct bhnd_nvram_io *data,
95 uint32_t mask, int8_t shift,
105 (((struct bhnd_sprom_opcode_idx_entry *)(_cookie))->vid)
117 * @param io An I/O context mapping the SPROM data to be identified.
122 * @retval non-zero If checking @p io otherwise fails, a regular unix
132 if (layout->flags & SPROM_LAYOUT_MAGIC_NONE) in bhnd_nvram_sprom_check_magic()
136 error = bhnd_nvram_io_read(io, layout->magic_offset, magic, in bhnd_nvram_sprom_check_magic()
144 if (*magic != layout->magic_value) in bhnd_nvram_sprom_check_magic()
151 * Attempt to identify the format of the SPROM data mapped by @p io.
153 * The SPROM data format does not provide any identifying information at a
156 * revisions, validate a signature at a revision-specific offset).
158 * @param io An I/O context mapping the SPROM data to be identified.
162 * @retval non-zero If identifying @p io otherwise fails, a regular unix
194 if ((layout->flags & SPROM_LAYOUT_MAGIC_NONE)) in bhnd_nvram_sprom_ident()
198 * Read image data and update CRC (errors are reported in bhnd_nvram_sprom_ident()
205 if (nbytes > layout->size) in bhnd_nvram_sprom_ident()
206 BHND_NV_PANIC("SPROM layout defined out-of-order"); in bhnd_nvram_sprom_ident()
208 nread = layout->size - nbytes; in bhnd_nvram_sprom_ident()
223 nread -= nr; in bhnd_nvram_sprom_ident()
227 /* Read 8-bit SPROM revision, maintaining 16-bit size alignment in bhnd_nvram_sprom_ident()
229 error = bhnd_nvram_io_read(io, layout->srev_offset, &srevcrc, in bhnd_nvram_sprom_ident()
239 if (layout->rev == 1 && srev == 0x10) in bhnd_nvram_sprom_ident()
243 if (srev != layout->rev) in bhnd_nvram_sprom_ident()
254 magic, layout->magic_value); in bhnd_nvram_sprom_ident()
265 * data corruption -- log the CRC error */ in bhnd_nvram_sprom_ident()
396 * @retval non-zero If serialization otherwise fails, a regular unix error
411 var = bhnd_nvram_get_vardefn(entry->vid); in bhnd_nvram_sprom_write_var()
414 var_base_type = bhnd_nvram_base_type(var->type); in bhnd_nvram_sprom_write_var()
420 nelem = state->var.nelem; in bhnd_nvram_sprom_write_var()
421 BHND_NV_ASSERT(nelem <= var->nelem, ("SPROM nelem=%zu exceeds maximum " in bhnd_nvram_sprom_write_var()
422 "NVRAM nelem=%hhu", nelem, var->nelem)); in bhnd_nvram_sprom_write_var()
424 /* Promote the data to a common 32-bit representation */ in bhnd_nvram_sprom_write_var()
430 /* Calculate total size of the 32-bit promoted representation */ in bhnd_nvram_sprom_write_var()
432 /* Variable-width types are unsupported */ in bhnd_nvram_sprom_write_var()
434 var->name, var->type); in bhnd_nvram_sprom_write_var()
441 "incorrect\n", var->name); in bhnd_nvram_sprom_write_var()
445 /* Initialize our common 32-bit value representation */ in bhnd_nvram_sprom_write_var()
449 if (!(var->flags & BHND_NVRAM_VF_IGNALL1)) { in bhnd_nvram_sprom_write_var()
451 var->name); in bhnd_nvram_sprom_write_var()
464 error = bhnd_nvram_val_convert_init(&bcm_val, var->fmt, value, in bhnd_nvram_sprom_write_var()
470 bhnd_nvram_val_fmt_name(var->fmt)); in bhnd_nvram_sprom_write_var()
477 * Promote to a common 32-bit representation. in bhnd_nvram_sprom_write_var()
479 * We must use the raw type to interpret the input data as its in bhnd_nvram_sprom_write_var()
480 * underlying integer representation -- otherwise, coercion in bhnd_nvram_sprom_write_var()
484 * For example, direct CHAR -> UINT32 coercion would attempt to in bhnd_nvram_sprom_write_var()
486 * promoting the raw UTF8 byte value to a 32-bit value. in bhnd_nvram_sprom_write_var()
513 "required %s[%zu]", var->name, type_name, in bhnd_nvram_sprom_write_var()
536 state->var_state >= SPROM_OPCODE_VAR_STATE_OPEN, in bhnd_nvram_sprom_write_var()
538 BHND_NV_ASSERT(state->var.have_bind, ("invalid bind state")); in bhnd_nvram_sprom_write_var()
540 binding_var = &state->var; in bhnd_nvram_sprom_write_var()
541 binding = &state->var.bind; in bhnd_nvram_sprom_write_var()
547 skip_out_bytes = binding->skip_in; in bhnd_nvram_sprom_write_var()
553 offset = state->offset; in bhnd_nvram_sprom_write_var()
554 for (size_t i = 0; i < binding->count; i++) { in bhnd_nvram_sprom_write_var()
557 "beyond nelem %zu\n", binding->skip_out, in bhnd_nvram_sprom_write_var()
565 binding_var->base_type, in bhnd_nvram_sprom_write_var()
567 binding_var->mask, in bhnd_nvram_sprom_write_var()
568 binding_var->shift, in bhnd_nvram_sprom_write_var()
577 if (binding->skip_in_negative) { in bhnd_nvram_sprom_write_var()
578 offset -= skip_out_bytes; in bhnd_nvram_sprom_write_var()
585 if (binding->skip_out == 0) in bhnd_nvram_sprom_write_var()
589 if (SIZE_MAX - binding->skip_out < ipos) { in bhnd_nvram_sprom_write_var()
591 "%zu\n", binding->skip_out, ipos); in bhnd_nvram_sprom_write_var()
595 ipos += binding->skip_out; in bhnd_nvram_sprom_write_var()
646 *olen = layout->size; in bhnd_nvram_sprom_serialize()
668 "%hhu\n", name, layout->rev); in bhnd_nvram_sprom_serialize()
674 /* Zero-initialize output */ in bhnd_nvram_sprom_serialize()
685 * Serialize all SPROM variable data. in bhnd_nvram_sprom_serialize()
692 var = bhnd_nvram_get_vardefn(entry->vid); in bhnd_nvram_sprom_serialize()
696 prop = bhnd_nvram_plist_get_prop(props, var->name); in bhnd_nvram_sprom_serialize()
708 "%s: %d\n", var->name, in bhnd_nvram_sprom_serialize()
709 bhnd_nvram_type_name(var->type), error); in bhnd_nvram_sprom_serialize()
723 if (!(layout->flags & SPROM_LAYOUT_MAGIC_NONE)) { in bhnd_nvram_sprom_serialize()
726 magic = htole16(layout->magic_value); in bhnd_nvram_sprom_serialize()
727 error = bhnd_nvram_io_write(io, layout->magic_offset, &magic, in bhnd_nvram_sprom_serialize()
735 /* Calculate the CRC over all SPROM data, not including the CRC byte. */ in bhnd_nvram_sprom_serialize()
736 crc = ~bhnd_nvram_crc8(outp, layout->crc_offset, in bhnd_nvram_sprom_serialize()
740 error = bhnd_nvram_io_write(io, layout->crc_offset, &crc, sizeof(crc)); in bhnd_nvram_sprom_serialize()
768 /* Identify the SPROM input data */ in bhnd_nvram_sprom_new()
769 if ((error = bhnd_nvram_sprom_ident(io, &sp->layout))) in bhnd_nvram_sprom_new()
773 sp->data = bhnd_nvram_iobuf_copy_range(io, 0, sp->layout->size); in bhnd_nvram_sprom_new()
774 if (sp->data == NULL) in bhnd_nvram_sprom_new()
778 if ((error = bhnd_sprom_opcode_init(&sp->state, sp->layout))) in bhnd_nvram_sprom_new()
784 if (sp->data != NULL) in bhnd_nvram_sprom_new()
785 bhnd_nvram_io_free(sp->data); in bhnd_nvram_sprom_new()
795 bhnd_sprom_opcode_fini(&sp->state); in bhnd_nvram_sprom_free()
796 bhnd_nvram_io_free(sp->data); in bhnd_nvram_sprom_free()
803 return (sprom->layout->num_vars); in bhnd_nvram_sprom_count()
829 while ((entry = bhnd_sprom_opcode_index_next(&sp->state, entry))) { in bhnd_nvram_sprom_next()
837 if (var->flags & BHND_NVRAM_VF_IGNALL1) { in bhnd_nvram_sprom_next()
842 &len, var->type); in bhnd_nvram_sprom_next()
851 return (var->name); in bhnd_nvram_sprom_next()
866 entry = bhnd_sprom_opcode_index_find(&sp->state, name); in bhnd_nvram_sprom_find()
871 * Write @p value of @p type to the SPROM @p data at @p offset, applying
872 * @p mask and @p shift, and OR with the existing data.
875 * @param data The SPROM data to be modified.
877 * @param offset The data offset to be written.
879 * @param shift The shift to be applied to @p value; if positive, a left
880 * shift will be applied, if negative, a right shift (this is the reverse of the
883 * current contents of @p data at @p offset.
887 struct bhnd_nvram_io *data, bhnd_nvram_type type, size_t offset, in bhnd_nvram_sprom_write_offset() argument
888 uint32_t mask, int8_t shift, uint32_t value) in bhnd_nvram_sprom_write_offset() argument
894 /* Narrow the 32-bit representation */ \ in bhnd_nvram_sprom_write_offset()
897 /* Shift and mask the new value */ \ in bhnd_nvram_sprom_write_offset()
898 if (shift > 0) \ in bhnd_nvram_sprom_write_offset()
899 scratch._repr[1] <<= shift; \ in bhnd_nvram_sprom_write_offset()
900 else if (shift < 0) \ in bhnd_nvram_sprom_write_offset()
901 scratch._repr[1] >>= -shift; \ in bhnd_nvram_sprom_write_offset()
908 error = bhnd_nvram_io_read(data, offset, \ in bhnd_nvram_sprom_write_offset()
912 "%#zx: %d\n", var->name, offset, error); \ in bhnd_nvram_sprom_write_offset()
918 if (shift >= 0) \ in bhnd_nvram_sprom_write_offset()
919 scratch._repr[0] &= ~_swap(mask << shift); \ in bhnd_nvram_sprom_write_offset()
920 else if (shift < 0) \ in bhnd_nvram_sprom_write_offset()
921 scratch._repr[0] &= ~_swap(mask >> (-shift)); \ in bhnd_nvram_sprom_write_offset()
925 error = bhnd_nvram_io_write(data, offset, \ in bhnd_nvram_sprom_write_offset()
929 "%#zx: %d\n", var->name, offset, error); \ in bhnd_nvram_sprom_write_offset()
934 /* Apply mask/shift and widen to a common 32bit representation */ in bhnd_nvram_sprom_write_offset()
958 BHND_NV_LOG("unhandled %s offset type: %d\n", var->name, type); in bhnd_nvram_sprom_write_offset()
967 * Read the value of @p type from the SPROM @p data at @p offset, apply @p mask
968 * and @p shift, and OR with the existing @p value.
971 * @param data The SPROM data to be decoded.
973 * @param offset The data offset to be read.
975 * @param shift The shift to be applied after masking; if positive, a right
976 * shift will be applied, if negative, a left shift.
982 struct bhnd_nvram_io *data, bhnd_nvram_type type, size_t offset, in bhnd_nvram_sprom_read_offset() argument
983 uint32_t mask, int8_t shift, uint32_t *value) in bhnd_nvram_sprom_read_offset() argument
990 error = bhnd_nvram_io_read(data, offset, \ in bhnd_nvram_sprom_read_offset()
994 "%#zx: %d\n", var->name, offset, error); \ in bhnd_nvram_sprom_read_offset()
1001 /* Mask and shift the value */ \ in bhnd_nvram_sprom_read_offset()
1003 if (shift > 0) { \ in bhnd_nvram_sprom_read_offset()
1004 scratch. _repr[0] >>= shift; \ in bhnd_nvram_sprom_read_offset()
1005 } else if (shift < 0) { \ in bhnd_nvram_sprom_read_offset()
1006 scratch. _repr[0] <<= -shift; \ in bhnd_nvram_sprom_read_offset()
1009 /* Widen to 32-bit representation and OR with current \ in bhnd_nvram_sprom_read_offset()
1014 /* Apply mask/shift and widen to a common 32bit representation */ in bhnd_nvram_sprom_read_offset()
1038 BHND_NV_LOG("unhandled %s offset type: %d\n", var->name, type); in bhnd_nvram_sprom_read_offset()
1054 * parsed variable data.
1078 var = bhnd_nvram_get_vardefn(entry->vid); in bhnd_nvram_sprom_read_var()
1093 nelem = state->var.nelem; in bhnd_nvram_sprom_read_var()
1094 if (nelem > var->nelem) { in bhnd_nvram_sprom_read_var()
1097 var->name, var->nelem); in bhnd_nvram_sprom_read_var()
1102 var_btype = bhnd_nvram_base_type(var->type); in bhnd_nvram_sprom_read_var()
1107 * variable-width data types */ in bhnd_nvram_sprom_read_var()
1108 BHND_NV_LOG("invalid SPROM data type: %d", var->type); in bhnd_nvram_sprom_read_var()
1117 "incorrect\n", var->name); in bhnd_nvram_sprom_read_var()
1121 /* Zero-initialize our decode buffer; any output elements skipped in bhnd_nvram_sprom_read_var()
1126 * Decode the SPROM data, iteratively decoding up to nelem values. in bhnd_nvram_sprom_read_var()
1135 if (var->flags & BHND_NVRAM_VF_IGNALL1) in bhnd_nvram_sprom_read_var()
1149 state->var_state >= SPROM_OPCODE_VAR_STATE_OPEN, in bhnd_nvram_sprom_read_var()
1151 BHND_NV_ASSERT(state->var.have_bind, ("invalid bind state")); in bhnd_nvram_sprom_read_var()
1153 binding_var = &state->var; in bhnd_nvram_sprom_read_var()
1154 binding = &state->var.bind; in bhnd_nvram_sprom_read_var()
1159 binding->skip_out, ipos, nelem); in bhnd_nvram_sprom_read_var()
1164 skip_in_bytes = binding->skip_in; in bhnd_nvram_sprom_read_var()
1170 offset = state->offset; in bhnd_nvram_sprom_read_var()
1171 for (size_t i = 0; i < binding->count; i++) { in bhnd_nvram_sprom_read_var()
1175 binding_var->base_type, in bhnd_nvram_sprom_read_var()
1177 binding_var->mask, in bhnd_nvram_sprom_read_var()
1178 binding_var->shift, in bhnd_nvram_sprom_read_var()
1185 if (var->flags & BHND_NVRAM_VF_IGNALL1 && in bhnd_nvram_sprom_read_var()
1190 all1 = binding_var->mask; in bhnd_nvram_sprom_read_var()
1191 if (binding_var->shift > 0) in bhnd_nvram_sprom_read_var()
1192 all1 >>= binding_var->shift; in bhnd_nvram_sprom_read_var()
1193 else if (binding_var->shift < 0) in bhnd_nvram_sprom_read_var()
1194 all1 <<= -binding_var->shift; in bhnd_nvram_sprom_read_var()
1203 if (binding->skip_in_negative) { in bhnd_nvram_sprom_read_var()
1204 offset -= skip_in_bytes; in bhnd_nvram_sprom_read_var()
1211 if (binding->skip_out == 0) in bhnd_nvram_sprom_read_var()
1215 * overflow-checked coercion from the widened in bhnd_nvram_sprom_read_var()
1238 if (SIZE_MAX - binding->skip_out < ipos) { in bhnd_nvram_sprom_read_var()
1240 "%zu\n", binding->skip_out, ipos); in bhnd_nvram_sprom_read_var()
1244 ipos += binding->skip_out; in bhnd_nvram_sprom_read_var()
1257 if ((var->flags & BHND_NVRAM_VF_IGNALL1) && all_bits_set) in bhnd_nvram_sprom_read_var()
1261 return (bhnd_nvram_val_init(val, var->fmt, inp, ilen, var->type, in bhnd_nvram_sprom_read_var()
1267 * using @p storage for actual data storage.
1293 return (bhnd_nvram_sprom_read_var(&sp->state, entry, sp->data, storage, in bhnd_nvram_sprom_getvar_common()
1309 return (-1); in bhnd_nvram_sprom_getvar_order()
1378 return (var->name); in bhnd_nvram_sprom_getvar_name()
1398 if ((entry = bhnd_sprom_opcode_index_find(&sp->state, name)) == NULL) in bhnd_nvram_sprom_filter_setvar()
1401 var = bhnd_nvram_get_vardefn(entry->vid); in bhnd_nvram_sprom_filter_setvar()
1405 error = bhnd_nvram_val_convert_new(&spval, var->fmt, value, in bhnd_nvram_sprom_filter_setvar()
1411 error = bhnd_nvram_sprom_write_var(&sp->state, entry, spval, NULL); in bhnd_nvram_sprom_filter_setvar()
1437 if ((entry = bhnd_sprom_opcode_index_find(&sp->state, name)) == NULL) in bhnd_nvram_sprom_filter_unsetvar()
1440 var = bhnd_nvram_get_vardefn(entry->vid); in bhnd_nvram_sprom_filter_unsetvar()
1445 * Since SPROM's layout is fixed, this requires IGNALL -- if in bhnd_nvram_sprom_filter_unsetvar()
1447 if (!(var->flags & BHND_NVRAM_VF_IGNALL1)) in bhnd_nvram_sprom_filter_unsetvar()