diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-04-25 08:19:06 +0200 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-04-25 08:19:06 +0200 |
| commit | f6a38d6c14b314d7b85855f311527ede869db96f (patch) | |
| tree | 8c6dfa8f2638d14b44ffb7b091e2d69efce34711 /Private/NewBoot/BootKit | |
| parent | 8153dc983802115951836f2b164af371ee6e3d73 (diff) | |
MHR-16: see below.
- Use QR-code to redirect to support page inside bootloader.
- Start working on NewLoader, since the PEF linker is done.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'Private/NewBoot/BootKit')
| -rw-r--r-- | Private/NewBoot/BootKit/Vendor/Qr.hxx | 36 | ||||
| -rw-r--r-- | Private/NewBoot/BootKit/Vendor/QrVendor/base.h | 25 | ||||
| -rw-r--r-- | Private/NewBoot/BootKit/Vendor/QrVendor/bit.h | 245 |
3 files changed, 283 insertions, 23 deletions
diff --git a/Private/NewBoot/BootKit/Vendor/Qr.hxx b/Private/NewBoot/BootKit/Vendor/Qr.hxx index 7fec429e..ca5eb566 100644 --- a/Private/NewBoot/BootKit/Vendor/Qr.hxx +++ b/Private/NewBoot/BootKit/Vendor/Qr.hxx @@ -5,6 +5,9 @@ #include <stddef.h> #include <stdint.h> +#include <BootKit/Vendor/QrVendor/base.h> +#include <BootKit/Vendor/QrVendor/bit.h> + #include <BootKit/Vendor/QrPrelude.hxx> #include <BootKit/Vendor/Support.hxx> #include <Builtins/Toolbox/Toolbox.hxx> @@ -276,7 +279,7 @@ public: void apply_mask(int mask, uint8_t *patterns); private: - static_assert(V <= 40, "invalid version"); + static_assert(V >= 1 && V <= 40, "invalid version"); static constexpr int SIDE = 17 + V * 4; static constexpr int N_BITS = SIDE * SIDE; static constexpr int N_ALIGN = V == 1 ? 0 : V / 7 + 2; @@ -286,42 +289,29 @@ public: static constexpr int N_VER_BITS = V > 6 ? 36 : 0; static constexpr int N_DAT_BITS = N_BITS - (192 + N_ALIGN_BITS + N_TIMING_BITS + 31 + N_VER_BITS); - static constexpr int N_BYTES = N_BITS; // Actual number of bytes_in_bits + static constexpr int N_BYTES = utl::bytes_in_bits(N_BITS); // Actual number of bytes_in_bits // required to store whole Qr code - static constexpr int N_DAT_BYTES = - N_DAT_BITS; // Actual number of bytes_in_bits required to store + static constexpr int N_DAT_BYTES = utl::bytes_in_bits(N_DAT_BITS); // Actual number of bytes_in_bits required to store // [data + ecc] static constexpr int N_DAT_CAPACITY = N_DAT_BITS >> 3; // Capacity of [data + ecc] without remainder bits private: /// @brief internal function to retrieve bit from a bitset. - uint8_t get_arr_bit(uint8_t *arr, uint64_t bit) const { - return ((volatile uint8_t *)arr)[bit]; + uint8_t get_arr_bit(uint8_t *arr, unsigned bit) const { + return utl::get_arr_bit(arr, bit); } /// @brief internal function to set bit from a bitset. - bool set_arr_bit(uint8_t *arr, uint64_t bit) { - if (((volatile uint8_t *)arr)[bit] == 0) { - ((volatile uint8_t *)arr)[bit] = 1; - - return true; - } - - return false; + void set_arr_bit(uint8_t *arr, unsigned bit) { + utl::set_arr_bit(arr, bit); } /// @brief internal function to clear bit from a bitset. - bool clr_arr_bit(uint8_t *arr, uint64_t bit) { - if (((volatile uint8_t *)arr)[bit] == 1) { - ((volatile uint8_t *)arr)[bit] = 0; - - return true; - } - - return false; + void clr_arr_bit(uint8_t *arr, unsigned bit) { + utl::clr_arr_bit(arr, bit); } - uint8_t code[N_BITS] = {0}; + uint8_t code[N_BYTES] = {}; bool status = false; }; diff --git a/Private/NewBoot/BootKit/Vendor/QrVendor/base.h b/Private/NewBoot/BootKit/Vendor/QrVendor/base.h new file mode 100644 index 00000000..d8261d1e --- /dev/null +++ b/Private/NewBoot/BootKit/Vendor/QrVendor/base.h @@ -0,0 +1,25 @@ +#ifndef UTL_BASE_H +#define UTL_BASE_H + +#include <cstdint> +#include <cstddef> +#include <cassert> + +namespace utl { + +/** + * @brief Helper to get number of elements in array. + * + * @tparam T Auto-deduced element type + * @tparam N Auto-deduced number of elements + * @return Array size + */ +template<class T, size_t N> +constexpr size_t countof(T(&)[N]) +{ + return N; +} + +} + +#endif
\ No newline at end of file diff --git a/Private/NewBoot/BootKit/Vendor/QrVendor/bit.h b/Private/NewBoot/BootKit/Vendor/QrVendor/bit.h new file mode 100644 index 00000000..646151b6 --- /dev/null +++ b/Private/NewBoot/BootKit/Vendor/QrVendor/bit.h @@ -0,0 +1,245 @@ +#ifndef UTL_BIT_H +#define UTL_BIT_H + +#include <bit> + +namespace utl { + +/** + * @brief Size of object in terms of bits. + * + * @tparam T Object type + * @return Number of bits + */ +template<class T> +constexpr auto bit_size() +{ + return sizeof(T) * 8; +} + +/** + * @brief Integer with all bits set to 1. + * + * @tparam T Integer type + * @return All set integer + */ +template<class T> +constexpr T bit_full() +{ + return T(-1); +} + +/** + * @brief Wrap around mask for power of two number of bits + * within given integer type. For example: + * [ bit_wrap<uint8_t> = 8 - 1 = 0b111 ] + * [ bit_wrap<uint16_t> = 16 - 1 = 0b1111 ] + * [ bit_wrap<uint32_t> = 32 - 1 = 0b11111 ] + * + * @tparam T Integer type + * @return Wrap around mask for number of bits + */ +template<class T> +constexpr T bit_wrap() +{ + return bit_size<T>() - 1; +} + +/** + * @brief Number of bits to fit bit_wrap<T> result, in other words + * bit width of (sizeof(T) * 8 - 1). For example: + * [ bit_shft<uint8_t> = bit_width(0b111) = 3 ] + * [ bit_shft<uint16_t> = bit_width(0b1111) = 4 ] + * [ bit_shft<uint32_t> = bit_width(0b11111) = 5 ] + * + * @tparam T Integer type + * @return Number of bits to shift to divide by sizeof(T) * 8 + */ +template<class T> +constexpr auto bit_shft() +{ + return std::bit_width(bit_wrap<T>()); +} + +/** + * @brief Round up division by number of bits within given integer type, + * which sizeof(T) * 8 is power of two. + * + * @tparam T Inetegr type + * @param x Dividend + * @return Quotient + */ +template<class T> +constexpr auto bit_ceil(auto x) +{ + return (x + bit_wrap<T>()) >> bit_shft<T>(); +} + +/** + * @brief Count leading zeros. + * + * @param x Unsigned integer argument + * @return Number of leading zeros + */ +constexpr unsigned cntlz(auto x) +{ + if constexpr (std::is_same_v<decltype(x), int>) + return std::countl_zero(unsigned(x)); + else + return std::countl_zero(x); +} + +/** + * @brief Count trailing zeros. + * + * @param x Unsigned integer argument + * @return Number of trailing zeros + */ +constexpr unsigned cnttz(auto x) +{ + if constexpr (std::is_same_v<decltype(x), int>) + return std::countr_zero(unsigned(x)); + else + return std::countr_zero(x); +} + +/** + * @brief Get number of words (integers) required to store N bits. + * + * @tparam T Word integer type + * @param n Number of bits to store + * @return Number of words + */ +template<class T> +constexpr size_t words_in_bits(size_t n) +{ + return (n >> bit_shft<T>()) + !!(n & bit_wrap<T>()); +} + +/** + * @brief Get number of bytes required to store N bits. + * + * @param n Number of bits to store + * @return Number of bytes + */ +constexpr size_t bytes_in_bits(size_t n) +{ + return words_in_bits<uint8_t>(n); +} + +/** + * @brief Make integer with bit at given position. + * + * @tparam T Inetegr type + * @param n Bit position + * @return Integer with set bit + */ +template<class T = unsigned> +constexpr T bit(int n) +{ + return T(1) << n; +} + +/** + * @brief Get n-th bit of an integer. + * + * @tparam T Integer type + * @param x Integer + * @param n Bit position from LSB + * @return true if set + */ +template<class T> +constexpr bool get_bit(T x, int n) +{ + return (x >> n) & 1; +} + +/** + * @brief Set n-th bit of an integer. + * + * @tparam T Integer type + * @param x Integer + * @param n Bit position from LSB + */ +template<class T> +constexpr void set_bit(T& x, int n) +{ + x |= 1 << n; +} + +/** + * @brief Clear n-th bit of an integer. + * + * @tparam T Integer type + * @param x Integer + * @param n Bit position from LSB + */ +template<class T> +constexpr void clr_bit(T& x, int n) +{ + x &= ~(1 << n); +} + +/** + * @brief Get n-th bit in array of words (starting from LSB). + * + * @tparam T Word type + * @param p Array of words + * @param n Index of bit to get + * @return true if set + */ +template<class T> +constexpr bool get_arr_bit(const T* p, unsigned n) +{ + return get_bit(p[n >> bit_shft<T>()], n & bit_wrap<T>()); +} + +/** + * @brief Set n-th bit in array of words (starting from LSB). + * + * @tparam T Word type + * @param p Array of words + * @param n Index of bit to set + */ +template<class T> +constexpr void set_arr_bit(T* p, unsigned n) +{ + set_bit(p[n >> bit_shft<T>()], n & bit_wrap<T>()); +} + +/** + * @brief Clear n-th bit in array of words (starting from LSB). + * + * @tparam T Word type + * @param p Array of words + * @param n Index of bit to clear + */ +template<class T> +constexpr void clr_arr_bit(T* p, unsigned n) +{ + clr_bit(p[n >> bit_shft<T>()], n & bit_wrap<T>()); +} + +/** + * @brief Shift bits left in array of integer elements from least significant bit + * and considering 0-th byte as the right most. + * uint16_t example: 0b10000000'11100001 ==> 0b00000001'11000010. + * + * @tparam T Integer type + * @tparam L Length of array + * @param x Array of integers, nullptr not acceptable! + * @param len Number of elements + */ +template<class T, size_t L> +constexpr void shift_left(T (&x)[L]) +{ + for (int i = L - 1; i > 0; --i) { + x[i] <<= 1; + x[i] |= x[i - 1] >> bit_wrap<T>(); + } + x[0] <<= 1; +} + +} + +#endif |
