mirror of
https://github.com/saymrwulf/pulp-runtime.git
synced 2026-05-16 21:00:16 +00:00
Add first driver draft for new gpio peripheral
This commit is contained in:
parent
d69fbeff36
commit
d8dc704518
6 changed files with 485 additions and 3 deletions
41
drivers/gpio/gpio.c
Normal file
41
drivers/gpio/gpio.c
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#include "gpio.h"
|
||||
#include "common/bitfield.h"
|
||||
#include "gpio_hal.h"
|
||||
#include "pulp.h"
|
||||
|
||||
|
||||
void gpio_configure(uint32_t number, uint32_t direction){
|
||||
// Now configure the GPIO peripheral
|
||||
uint32_t addr = ARCHI_GPIO_ADDR + GPIO_MODE_REG_OFFSET_BASE + number/16*4;
|
||||
uint32_t reg = archi_read32(addr);
|
||||
bitfield_field32_t field;
|
||||
field.mask = 0x3;
|
||||
field.index = number%16*2;
|
||||
reg = bitfield_field32_write(reg, field, (direction == GPIO_DIRECTION_INPUT)? GPIO_MODE_REG_VALUE_INPUT_ONLY: GPIO_MODE_REG_VALUE_OUTPUT_ACTIVE);
|
||||
archi_write32(addr, reg);
|
||||
// Enable/Disable input sampling
|
||||
addr = ARCHI_GPIO_ADDR + GPIO_EN_INPUT_REG_OFFSET_BASE + number/32*4;
|
||||
reg = archi_read32(addr);
|
||||
reg = bitfield_bit32_write(reg, number%32, direction == SIRACUSA_GPIO_DIRECTION_INPUT);
|
||||
archi_write32(addr, reg);
|
||||
hal_compiler_barrier();
|
||||
}
|
||||
|
||||
|
||||
void gpio_set(uint32_t number, uint32_t value){
|
||||
uint32_t addr;
|
||||
if (value == 1) {
|
||||
addr = ARCHI_GPIO_ADDR + GPIO_SET_REG_OFFSET_BASE + number/32*4;
|
||||
} else {
|
||||
addr = SIRACUSA_GPIO_BASE_ADDR + GPIO_CLEAR_REG_OFFSET_BASE + number/32*4;
|
||||
}
|
||||
archi_write32(addr, 1<<(number%32));
|
||||
hal_compiler_barrier();
|
||||
}
|
||||
|
||||
uint32_t gpio_get(uint32_t number){
|
||||
uint32_t addr = SIRACUSA_GPIO_BASE_ADDR + GPIO_GPIO_IN_0_REG_OFFSET + number/32*4;
|
||||
uint32_t reg = archi_read32(addr);
|
||||
return bitfield_bit32_read(reg, number%32);
|
||||
hal_compiler_barrier();
|
||||
}
|
||||
64
drivers/gpio/include/gpio.h
Normal file
64
drivers/gpio/include/gpio.h
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (C) 2022 ETH Zurich, University of Bologna
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Title: gpio.h<include>
|
||||
* Author: Manuel Eggimann <meggimann@iis.ee.ethz.ch>
|
||||
* Date: 09.03.2022
|
||||
*
|
||||
* Description: Driver for the PULP GPIO peripheral
|
||||
*/
|
||||
#ifndef GPIO_H
|
||||
#define GPIO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define GPIO_DIRECTION_OUTPUT 1
|
||||
#define GPIO_DIRECTION_INPUT 0
|
||||
|
||||
|
||||
/**
|
||||
* Configure the provided GPIO as either an input or output.
|
||||
*
|
||||
* It is the user's responsibility to ensure that the GPIO to be configures is
|
||||
* actually exposed to its corresponding IO pad. I.e. if your SoC contains an IO
|
||||
* multiplexer you have to make sure you configure it apropriately to expose the
|
||||
* GPIO on the pad.
|
||||
*
|
||||
* @param number The GPIO number to confgiure. You can either use directly an integer number or on of the PAD_GPIOXX macros.
|
||||
* @param direction Either GPIO_DIRECTION_INPUT (0) or GPIO_DIRECTION_OUTPUT
|
||||
*/
|
||||
void gpio_configure(uint32_t number, uint32_t direction);
|
||||
|
||||
/**
|
||||
* Get the current value of the GPIO.
|
||||
*
|
||||
* The GPIO must have been configured as an input using configure_gpio().
|
||||
*
|
||||
* @param number The GPIO number to confgiure. You can either use directly an integer number or on of the PAD_GPIOXX macros.
|
||||
* @returns 0 if the gpio is currently at logic level LOW or 1 if it is at logic level HIGH.
|
||||
*/
|
||||
uint32_t gpio_get(uint32_t number);
|
||||
|
||||
/**
|
||||
* Drive the GPIO to the provided value.
|
||||
*
|
||||
* The corresponding GPIO must have been configured as an output using configure_gpio().
|
||||
*
|
||||
* @param number The GPIO number to confgiure. You can either use directly an integer number or on of the PAD_GPIOXX macros.
|
||||
* @param value Either 0 or 1.
|
||||
*/
|
||||
void gpio_set(uint32_t number, uint32_t value);
|
||||
|
||||
#endif /* GPIO_H */
|
||||
86
drivers/gpio/include/gpio_hal.h
Normal file
86
drivers/gpio/include/gpio_hal.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
// Generic Hardware Abstraction Layer for the GPIO peripheral
|
||||
|
||||
#ifndef _GPIO_REG_DEFS_
|
||||
#define _GPIO_REG_DEFS_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Info register that contains information about this peripheral.
|
||||
#define GPIO_INFO_REG_OFFSET 0x0
|
||||
#define GPIO_INFO_REG_GPIO_CNT_MASK 0x3ff
|
||||
#define GPIO_INFO_REG_GPIO_CNT_OFFSET 0
|
||||
#define GPIO_INFO_REG_GPIO_CNT_FIELD \
|
||||
((bitfield_field32_t) { .mask = GPIO_INFO_GPIO_CNT_MASK, .index = GPIO_INFO_GPIO_CNT_OFFSET })
|
||||
#define GPIO_INFO_REG_VERSION_MASK 0x3ff
|
||||
#define GPIO_INFO_REG_VERSION_OFFSET 10
|
||||
#define GPIO_INFO_REG_VERSION_FIELD \
|
||||
((bitfield_field32_t) { .mask = GPIO_INFO_VERSION_MASK, .index = GPIO_INFO_VERSION_OFFSET })
|
||||
|
||||
// Global configuration register for the peripheral
|
||||
#define GPIO_CFG_REG_OFFSET 0x4
|
||||
#define GPIO_CFG_INTRPT_MODE_BIT 0
|
||||
|
||||
// Set the IO Mode of the GPIO. (common parameters)
|
||||
#define GPIO_MODE_REG_OFFSET_BASE 0x8
|
||||
#define GPIO_MODE_REG_VALUE_INPUT_ONLY 0x0
|
||||
#define GPIO_MODE_REG_VALUE_OUTPUT_ACTIVE 0x1
|
||||
#define GPIO_MODE_REG_VALUE_OPEN_DRAIN0 0x2
|
||||
#define GPIO_MODE_REG_VALUE_OPEN_DRAIN1 0x3
|
||||
|
||||
// Enable sampling on the corresponding GPIO (common parameters)
|
||||
#define GPIO_EN_INPUT_REG_OFFSET_BASE 0x80
|
||||
|
||||
// Read the current input values of all GPIOs.
|
||||
#define GPIO_INPUT_REG_OFFSET_BASE 0x100
|
||||
|
||||
// Set the output value of the corresponding GPIOs.
|
||||
#define GPIO_OUTPUT_REG_OFFSET_BASE 0x180
|
||||
|
||||
// For each asserted bit in this register, set the corresponding bit in the
|
||||
// padout register.
|
||||
#define GPIO_SET_REG_OFFSET_BASE 0x200
|
||||
|
||||
// For each asserted bit in this register, clear the corresponding bit in the
|
||||
// padout register.
|
||||
#define GPIO_CLEAR_REG_OFFSET_BASE 0X280
|
||||
|
||||
// For each asserted bit in this register, toggle the corresponding bit in
|
||||
// the padout register.
|
||||
#define GPIO_TOGGLE_REG_OFFSET_BASE 0X300
|
||||
|
||||
// Enable Interrupts on rising edges for the corresponding GPIO
|
||||
#define GPIO_INTRPT_RISE_EN_REG_OFFSET_BASE 0x380
|
||||
|
||||
// Enable Interrupts on falling edges for the corresponding GPIO
|
||||
#define GPIO_INTRPT_FALL_EN_REG_OFFSET_BASE 0x400
|
||||
|
||||
// Enable logic high level-sensitive Interrupts on the corresponding GPIO
|
||||
#define GPIO_INTRPT_HIGH_EN_REG_OFFSET_BASE 0x480
|
||||
|
||||
// Enable logic low level-sensitive Interrupts on the corresponding GPIO
|
||||
#define GPIO_INTRPT_LOW_EN_REG_OFFSET_BASE 0x500
|
||||
|
||||
// Asserted if there is any pending interrupts on corresponding GPIOs.
|
||||
#define GPIO_INTRPT_STATUS_REG_OFFSET_BASE 0x580
|
||||
|
||||
// Asserted if there is a pending rise interrupts on corresponding GPIOs.
|
||||
#define GPIO_INTRPT_RISE_STATUS_REG_OFFSET_BASE 0x600
|
||||
|
||||
// Asserted if there is any pending fall interrupts on corresponding GPIOs.
|
||||
#define GPIO_INTRPT_FALL_STATUS_REG_OFFSET_BASE 0x680
|
||||
|
||||
// Asserted if there is any pending high-level interrupts on corresponding
|
||||
// GPIOs.
|
||||
#define GPIO_INTRPT_LVL_HIGH_STATUS_REG_OFFSET_BASE 0x700
|
||||
|
||||
// Asserted if there is any pending low-level interrupts on corresponding
|
||||
// GPIOs.
|
||||
#define GPIO_INTRPT_LVL_LOW_STATUS_REG_OFFSET_BASE 0x780
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
#endif // _GPIO_REG_DEFS_
|
||||
// End generated register defines for gpio
|
||||
|
|
@ -26,9 +26,8 @@
|
|||
|
||||
#define ARCHI_SOC_PERIPHERALS_ADDR 0x1A100000
|
||||
|
||||
#define ARCHI_FC_TIMER_SIZE 0x00000800
|
||||
#define ARCHI_FC_TIMER_SIZE 0x00000800
|
||||
|
||||
#define ARCHI_FLL_OFFSET 0x00000000
|
||||
#define ARCHI_GPIO_OFFSET 0x00001000
|
||||
#define ARCHI_UDMA_OFFSET 0x00002000
|
||||
#define ARCHI_APB_SOC_CTRL_OFFSET 0x00004000
|
||||
|
|
@ -37,7 +36,9 @@
|
|||
#define ARCHI_FC_TIMER_OFFSET 0x0000B000
|
||||
#define ARCHI_FC_HWPE_OFFSET 0x0000C000
|
||||
#define ARCHI_STDOUT_OFFSET 0x0000F000
|
||||
|
||||
// Chip control port
|
||||
#define ARCHI_FLL_OFFSET 0x00020000
|
||||
#define ARCHI_PAD_CFG_OFFSET 0x00021000
|
||||
|
||||
|
||||
#define ARCHI_GPIO_ADDR ( ARCHI_SOC_PERIPHERALS_ADDR + ARCHI_GPIO_OFFSET )
|
||||
|
|
|
|||
|
|
@ -243,4 +243,9 @@
|
|||
#define ARCHI_FC_EVT_QUEUE_ERROR 29
|
||||
|
||||
|
||||
/*
|
||||
* GPIO Count
|
||||
*/
|
||||
#define GPIOCount 32
|
||||
|
||||
#endif
|
||||
|
|
|
|||
285
include/common/bitfield.h
Normal file
285
include/common/bitfield.h
Normal file
|
|
@ -0,0 +1,285 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#ifndef OPENTITAN_SW_DEVICE_LIB_BASE_BITFIELD_H_
|
||||
#define OPENTITAN_SW_DEVICE_LIB_BASE_BITFIELD_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Bitfield Manipulation Functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* All the bitfield functions are pure (they do not modify their arguments), so
|
||||
* the result must be used. We enable warnings to ensure this happens.
|
||||
*/
|
||||
#define BITFIELD_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
|
||||
|
||||
/**
|
||||
* A field of a 32-bit bitfield.
|
||||
*
|
||||
* The following field definition: `{ .mask = 0b11, .index = 12 }`
|
||||
*
|
||||
* Denotes the X-marked bits in the following 32-bit bitfield:
|
||||
*
|
||||
* field: 0b--------'--------'--XX----'--------
|
||||
* index: 31 0
|
||||
*
|
||||
* Restrictions: The index plus the width of the mask must not be greater than
|
||||
* 31.
|
||||
*/
|
||||
typedef struct bitfield_field32 {
|
||||
/** The field mask. Usually all ones. */
|
||||
uint32_t mask;
|
||||
/** The field position in the bitfield, counting from the zero-bit. */
|
||||
uint32_t index;
|
||||
} bitfield_field32_t;
|
||||
|
||||
/**
|
||||
* Reads a value from `field` in `bitfield`.
|
||||
*
|
||||
* This function uses the `field` parameter to read the value from `bitfield`.
|
||||
* The resulting value will be shifted right and zero-extended so the field's
|
||||
* zero-bit is the return value's zero-bit.
|
||||
*
|
||||
* @param bitfield Bitfield to get the field from.
|
||||
* @param field Field to read out from.
|
||||
* @return Zero-extended `field` from `bitfield`.
|
||||
*/
|
||||
BITFIELD_WARN_UNUSED_RESULT
|
||||
inline uint32_t bitfield_field32_read(uint32_t bitfield,
|
||||
bitfield_field32_t field) {
|
||||
return (bitfield >> field.index) & field.mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes `value` to `field` in `bitfield`.
|
||||
*
|
||||
* This function uses the `field` parameter to set specific bits in `bitfield`.
|
||||
* The relevant portion of `bitfield` is zeroed before the bits are set to
|
||||
* `value`.
|
||||
*
|
||||
* @param bitfield Bitfield to set the field in.
|
||||
* @param field Field within bitfield to be set.
|
||||
* @param value Value for the new field.
|
||||
* @return `bitfield` with `field` set to `value`.
|
||||
*/
|
||||
BITFIELD_WARN_UNUSED_RESULT
|
||||
inline uint32_t bitfield_field32_write(uint32_t bitfield,
|
||||
bitfield_field32_t field,
|
||||
uint32_t value) {
|
||||
bitfield &= ~(field.mask << field.index);
|
||||
bitfield |= (value & field.mask) << field.index;
|
||||
return bitfield;
|
||||
}
|
||||
|
||||
/**
|
||||
* A single bit in a 32-bit bitfield.
|
||||
*
|
||||
* This denotes the position of a single bit, counting from the zero-bit.
|
||||
*
|
||||
* For instance, `(bitfield_bit_index_t)4` denotes the X-marked bit in the
|
||||
* following 32-bit bitfield:
|
||||
*
|
||||
* field: 0b--------'--------'--------'---X----
|
||||
* index: 31 0
|
||||
*
|
||||
* Restrictions: The value must not be greater than 31.
|
||||
*/
|
||||
typedef uint32_t bitfield_bit32_index_t;
|
||||
|
||||
/**
|
||||
* Turns a `bitfield_bit32_index_t` into a `bitfield_field32_t` (which is more
|
||||
* general).
|
||||
*
|
||||
* @param bit_index The corresponding single bit to turn into a field.
|
||||
* @return A 1-bit field that corresponds to `bit_index`.
|
||||
*/
|
||||
BITFIELD_WARN_UNUSED_RESULT
|
||||
inline bitfield_field32_t bitfield_bit32_to_field32(
|
||||
bitfield_bit32_index_t bit_index) {
|
||||
return (bitfield_field32_t){
|
||||
.mask = 0x1, .index = bit_index,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the `bit_index`th bit in `bitfield`.
|
||||
*
|
||||
* @param bitfield Bitfield to get the bit from.
|
||||
* @param bit_index Bit to read.
|
||||
* @return `true` if the bit was one, `false` otherwise.
|
||||
*/
|
||||
BITFIELD_WARN_UNUSED_RESULT
|
||||
inline bool bitfield_bit32_read(uint32_t bitfield,
|
||||
bitfield_bit32_index_t bit_index) {
|
||||
return bitfield_field32_read(bitfield,
|
||||
bitfield_bit32_to_field32(bit_index)) == 0x1u;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes `value` to the `bit_index`th bit in `bitfield`.
|
||||
*
|
||||
* @param bitfield Bitfield to update the bit in.
|
||||
* @param bit_index Bit to update.
|
||||
* @param value Bit value to write to `bitfield`.
|
||||
* @return `bitfield` with the `bit_index`th bit set to `value`.
|
||||
*/
|
||||
BITFIELD_WARN_UNUSED_RESULT
|
||||
inline uint32_t bitfield_bit32_write(uint32_t bitfield,
|
||||
bitfield_bit32_index_t bit_index,
|
||||
bool value) {
|
||||
return bitfield_field32_write(bitfield, bitfield_bit32_to_field32(bit_index),
|
||||
value ? 0x1u : 0x0u);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find First Set Bit
|
||||
*
|
||||
* Returns one plus the index of the least-significant 1-bit of a 32-bit word.
|
||||
*
|
||||
* For instance, `bitfield_find_first_set32(field)` of the below 32-bit value
|
||||
* returns `5`.
|
||||
*
|
||||
* field: 0b00000000'00000000'11111111'00010000
|
||||
* index: 31 0
|
||||
*
|
||||
* This is the canonical definition for the GCC/Clang builtin `__builtin_ffs`,
|
||||
* and hence takes and returns a signed integer.
|
||||
*
|
||||
* @param bitfield Bitfield to find the first set bit in.
|
||||
* @return One plus the index of the least-significant 1-bit of `bitfield`.
|
||||
*/
|
||||
BITFIELD_WARN_UNUSED_RESULT
|
||||
inline int32_t bitfield_find_first_set32(int32_t bitfield) {
|
||||
return __builtin_ffs(bitfield);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count Leading Zeroes
|
||||
*
|
||||
* Returns the number of leading 0-bits in `bitfield`, starting at the most
|
||||
* significant bit position. If `bitfield` is 0, the result is 32, to match the
|
||||
* RISC-V B Extension.
|
||||
*
|
||||
* For instance, `bitfield_count_leading_zeroes32(field)` of the below 32-bit
|
||||
* value returns `16`.
|
||||
*
|
||||
* field: 0b00000000'00000000'11111111'00010000
|
||||
* index: 31 0
|
||||
*
|
||||
* This is the canonical definition for the GCC/Clang builtin `__builtin_clz`,
|
||||
* and hence returns a signed integer.
|
||||
*
|
||||
* @param bitfield Bitfield to count leading 0-bits from.
|
||||
* @return The number of leading 0-bits in `bitfield`.
|
||||
*/
|
||||
BITFIELD_WARN_UNUSED_RESULT
|
||||
inline int32_t bitfield_count_leading_zeroes32(uint32_t bitfield) {
|
||||
return (bitfield != 0) ? __builtin_clz(bitfield) : 32;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count Trailing Zeroes
|
||||
*
|
||||
* Returns the number of trailing 0-bits in `bitfield`, starting at the least
|
||||
* significant bit position. If `bitfield` is 0, the result is 32, to match the
|
||||
* RISC-V B Extension.
|
||||
*
|
||||
* For instance, `bitfield_count_trailing_zeroes32(field)` of the below 32-bit
|
||||
* value returns `4`.
|
||||
*
|
||||
* field: 0b00000000'00000000'11111111'00010000
|
||||
* index: 31 0
|
||||
*
|
||||
* This is the canonical definition for the GCC/Clang builtin `__builtin_ctz`,
|
||||
* and hence returns a signed integer.
|
||||
*
|
||||
* @param bitfield Bitfield to count trailing 0-bits from.
|
||||
* @return The number of trailing 0-bits in `bitfield`.
|
||||
*/
|
||||
BITFIELD_WARN_UNUSED_RESULT
|
||||
inline int32_t bitfield_count_trailing_zeroes32(uint32_t bitfield) {
|
||||
return (bitfield != 0) ? __builtin_ctz(bitfield) : 32;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count Set Bits
|
||||
*
|
||||
* Returns the number of 1-bits in `bitfield`.
|
||||
*
|
||||
* For instance, `bitfield_popcount32(field)` of the below 32-bit value returns
|
||||
* `9`.
|
||||
*
|
||||
* field: 0b00000000'00000000'11111111'00010000
|
||||
* index: 31 0
|
||||
*
|
||||
* This is the canonical definition for the GCC/Clang builtin
|
||||
* `__builtin_popcount`, and hence returns a signed integer.
|
||||
*
|
||||
* @param bitfield Bitfield to count 1-bits from.
|
||||
* @return The number of 1-bits in `bitfield`.
|
||||
*/
|
||||
BITFIELD_WARN_UNUSED_RESULT
|
||||
inline int32_t bitfield_popcount32(uint32_t bitfield) {
|
||||
return __builtin_popcount(bitfield);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parity
|
||||
*
|
||||
* Returns the number of 1-bits in `bitfield`, modulo 2.
|
||||
*
|
||||
* For instance, `bitfield_parity32(field)` of the below 32-bit value returns
|
||||
* `1`.
|
||||
*
|
||||
* field: 0b00000000'00000000'11111111'00010000
|
||||
* index: 31 0
|
||||
*
|
||||
* This is the canonical definition for the GCC/Clang builtin
|
||||
* `__builtin_parity`, and hence returns a signed integer.
|
||||
*
|
||||
* @param bitfield Bitfield to count 1-bits from.
|
||||
* @return The number of 1-bits in `bitfield`, modulo 2.
|
||||
*/
|
||||
BITFIELD_WARN_UNUSED_RESULT
|
||||
inline int32_t bitfield_parity32(uint32_t bitfield) {
|
||||
return __builtin_parity(bitfield);
|
||||
}
|
||||
|
||||
/**
|
||||
* Byte Swap
|
||||
*
|
||||
* Returns `field` with the order of the bytes reversed. Bytes here always means
|
||||
* exactly 8 bits.
|
||||
*
|
||||
* For instance, `byteswap(field)` of the below 32-bit value returns `1`.
|
||||
*
|
||||
* field: 0bAAAAAAAA'BBBBBBBB'CCCCCCCC'DDDDDDDD
|
||||
* index: 31 0
|
||||
* returns: 0bDDDDDDDD'CCCCCCCC'BBBBBBBB'AAAAAAAA
|
||||
*
|
||||
* This is the canonical definition for the GCC/Clang builtin
|
||||
* `__builtin_bswap32`.
|
||||
*
|
||||
* @param bitfield Bitfield to reverse bytes of.
|
||||
* @return `bitfield` with the order of bytes reversed.
|
||||
*/
|
||||
BITFIELD_WARN_UNUSED_RESULT
|
||||
inline uint32_t bitfield_byteswap32(uint32_t bitfield) {
|
||||
return __builtin_bswap32(bitfield);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // OPENTITAN_SW_DEVICE_LIB_BASE_BITFIELD_H_
|
||||
Loading…
Reference in a new issue