diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 292ba4cb05e7b..6398869b34fee 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -192,10 +192,9 @@ jobs: BLOBDIR: /tools/blobs with: run: | - # install venv + # install python venv apt-get update - apt install -y python3-dev - apt install -y python3-venv + apt-get install -y python3 python3-dev python3-venv # get NTFC sources git clone -b release-0.0.1 https://github.com/szafonimateusz-mi/nuttx-ntfc diff --git a/CMakeLists.txt b/CMakeLists.txt index 82ff10e2cd9a2..4761cb6560eca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -166,20 +166,9 @@ if(NOT EXISTS "${NUTTX_DEFCONFIG}") endif() # Process initial defconfig ################################################### -# Process initial defconfig to recursively expand #include in it +# Process initial defconfig to recursively expand #include in it include(nuttx_process_config) -get_filename_component(NUTTX_DEFCONFIG_DIR "${NUTTX_DEFCONFIG}" DIRECTORY) -process_config( - ${CMAKE_BINARY_DIR}/.defconfig.processed - ${NUTTX_DEFCONFIG} - INCLUDE_PATHS - ${NUTTX_DEFCONFIG_DIR}/../../common/configs - ${NUTTX_DEFCONFIG_DIR}/../common - ${NUTTX_DEFCONFIG_DIR} - ${NUTTX_DIR}/../apps - ${NUTTX_DIR}/../nuttx-apps) -set(NUTTX_DEFCONFIG ${CMAKE_BINARY_DIR}/.defconfig.processed) # Generate initial .config ################################################### # This is needed right before any other configure step so that we can source @@ -502,22 +491,6 @@ if(CONFIG_NDEBUG) add_compile_options(-DNDEBUG) endif() -# Cmake build provide absolute paths to compile files. If __FILE__ macros are -# used in the source code(ASSERT), the binary will contain many invalid paths. -# This saves some memory, stops exposing build systems locations in binaries, -# make failure logs more deterministic and most importantly makes builds more -# failure logs more deterministic and most importantly makes builds more -# deterministic. Debuggers usually have a path mapping feature to ensure the -# files are still found. -if(NOT MSVC) - if(CONFIG_OUTPUT_STRIP_PATHS) - add_compile_options(-fmacro-prefix-map=${NUTTX_DIR}=) - add_compile_options(-fmacro-prefix-map=${NUTTX_APPS_DIR}=) - add_compile_options(-fmacro-prefix-map=${NUTTX_BOARD_ABS_DIR}=) - add_compile_options(-fmacro-prefix-map=${NUTTX_CHIP_ABS_DIR}=) - endif() -endif() - add_definitions(-D__NuttX__) add_compile_options($<$:-D__ASSEMBLY__>) diff --git a/Documentation/ReleaseNotes/NuttX-7.29 b/Documentation/ReleaseNotes/NuttX-7.29 index e51c46dfdd6fe..5b6c01baf049c 100644 --- a/Documentation/ReleaseNotes/NuttX-7.29 +++ b/Documentation/ReleaseNotes/NuttX-7.29 @@ -25,7 +25,7 @@ still needed). From Gregory Nutt. - Rename all internal OS functions from task_* to nxtask_* to indicate that they are NuttX internal functions. From Gregory Nutt. - Rename sched_process_timer to nxsched_process_timer. Rename -sched_timer_expiration to nxsched_timer_expiration. Rename +sched_timer_expiration to nxsched_tick_expiration. Rename sched_alarm_expiration to nxsched_alarm_expiration. Those are the appropriate names for an internal sched/ function (still many named incorrectly). From Gregory Nutt. diff --git a/Documentation/components/crypto.rst b/Documentation/components/crypto.rst index 1a94ae0b05767..8d6862752d883 100644 --- a/Documentation/components/crypto.rst +++ b/Documentation/components/crypto.rst @@ -2,4 +2,136 @@ Crypto API Subsystem ==================== -In the future this page will contain details about the Crypto API in NuttX. +Overview +======== + +The NuttX Crypto API subsystem provides a unified interface for cryptographic operations, supporting various encryption, decryption, hashing, and authentication algorithms. The subsystem abstracts hardware and software crypto implementations through a common interface. + +Supported Algorithms +==================== + +Symmetric Encryption Algorithms +-------------------------------- + +**AES (Advanced Encryption Standard)** + +- AES-CBC Mode: + - CRYPTO_AES_CBC (128-bit key size) + - CRYPTO_AES_192_CBC (192-bit key size) + - CRYPTO_AES_256_CBC (256-bit key size) + +- AES-CTR Mode (Counter mode): + - CRYPTO_AES_CTR + +- AES-XTS Mode (XEX-based Tweaked CodeBook): + - CRYPTO_AES_XTS + +- AES-GCM Mode (Galois/Counter Mode): + - CRYPTO_AES_GCM_16 + +- AES-OFB Mode (Output Feedback): + - CRYPTO_AES_OFB + +- AES-CFB Mode (Cipher Feedback): + - CRYPTO_AES_CFB_8 (8-bit) + - CRYPTO_AES_CFB_128 (128-bit) + +**Other Block Cipher Modes** + +- Blowfish (BLF): + - CRYPTO_BLF_CBC + +- CAST (CAST-128): + - CRYPTO_CAST_CBC + +- Rijndael (128-bit): + - CRYPTO_RIJNDAEL128_CBC + +- Null (No encryption): + - CRYPTO_NULL + +Authentication and Hashing Algorithms +-------------------------------------- + +**HMAC (Hash-based Message Authentication Code)** + +- MD5-HMAC: + - CRYPTO_MD5_HMAC + +- SHA-1 HMAC: + - CRYPTO_SHA1_HMAC + +- SHA-2 HMAC: + - CRYPTO_SHA2_256_HMAC (256-bit) + - CRYPTO_SHA2_384_HMAC (384-bit) + - CRYPTO_SHA2_512_HMAC (512-bit) + +**Hash Functions** + +- MD5: + - CRYPTO_MD5 + +- SHA-1: + - CRYPTO_SHA1 + +- SHA-2: + - CRYPTO_SHA2_224 (224-bit) + - CRYPTO_SHA2_256 (256-bit) + - CRYPTO_SHA2_384 (384-bit) + - CRYPTO_SHA2_512 (512-bit) + +- RIPEMD-160: + - CRYPTO_RIPEMD160 (as hash function) + - CRYPTO_RIPEMD160_HMAC + +**Message Authentication Codes** + +- AES-GMAC (Galois Message Authentication Code): + - CRYPTO_AES_128_GMAC (128-bit key) + - CRYPTO_AES_192_GMAC (192-bit key) + - CRYPTO_AES_256_GMAC (256-bit key) + - CRYPTO_AES_GMAC (generic) + +- AES-CMAC (Cipher-based Message Authentication Code): + - CRYPTO_AES_CMAC + - CRYPTO_AES_128_CMAC (128-bit) + +- Poly1305: + - CRYPTO_POLY1305 + - CRYPTO_CHACHA20_POLY1305 + - CRYPTO_CHACHA20_POLY1305_MAC + +**Stream Ciphers** + +- ChaCha20: + - CRYPTO_CHACHA20_POLY1305 (with Poly1305 MAC) + +Integrity and Checksums +------------------------ + +- CRC-32: + - CRYPTO_CRC32 + +- Extended Sequence Numbers (ESN): + - CRYPTO_ESN + +Compression +----------- + +- Deflate Compression: + - CRYPTO_DEFLATE_COMP + +Usage +===== + +The Crypto API is accessed through the cryptodev interface, which provides ioctl commands for initializing cryptographic sessions and performing operations. + +Basic Usage Pattern +------------------- + +1. Open the cryptodev device (/dev/crypto) +2. Initialize a cryptographic session with desired algorithm +3. Submit crypto operations (encrypt/decrypt/hash) +4. Close the session when done + +For more details, refer to the cryptodev.h header file and specific driver documentation. diff --git a/Documentation/components/drivers/special/ioexpander.rst b/Documentation/components/drivers/special/ioexpander.rst index 5a2f5134dd998..f52f019df434b 100644 --- a/Documentation/components/drivers/special/ioexpander.rst +++ b/Documentation/components/drivers/special/ioexpander.rst @@ -2,29 +2,37 @@ IO Expander Device Drivers ========================== -- ``include/nuttx/ioexpander/ioexpander.h`` and ``include/nuttx/ioexpander/gpio.h``. - All structures and APIs needed to work with ioexpander drivers are provided in - this header file. +The IO Expander subsystem is defined in the following headers: -- ``struct ioexpander_ops_s``. Each ioexpand device driver must implement - an instance of ``struct ioexpander_ops_s``. That structure defines a - call table with the methods, and we also provide macros to help access methods. +- ``include/nuttx/ioexpander/ioexpander.h`` — defines the public IO expander + interface: macros, types, and helper access macros used by drivers and + consumers. +- ``include/nuttx/ioexpander/gpio.h`` — provides the "gpio lower half" + helper that allows registering an IO expander pin as a standard GPIO + character device (see ``gpio_lower_half`` and ``gpio_lower_half_byname``). -- we also provide method ``gpio_lower_half`` to make ioexpander compatible with normal gpio. +Each IO expander driver must implement an instance of ``struct +ioexpander_ops_s``. That structure defines the lower-half call table and +the operations a driver must provide; the public header also includes +helper macros that dispatch to the lower-half operations table. -- **Binding ioexpander Drivers**. ioexpander drivers are not normally directly - accessed by user code, we should always get lower level drivers, for example I2C, - and map extended gpio feature same asa normal gpio. See for example, - ``int nrf52_sx1509_initialize(void)`` - in ``boards/arm/nrf52/thingy52/src/nrf52_sx1509.c``. In general, the binding - sequence is: +The helper ``gpio_lower_half`` can be used to register individual expander +pins as standard GPIO devices so that upper-half GPIO consumers can access +expander pins through the common GPIO character driver. - #. Get an instance of ``struct i2c_master_s`` from the - hardware-specific I2C device driver, and - #. Provide that instance and configurations to the ioexpander initialization method - to get the ``struct ioexpander_dev_s`` ioe device instance. - #. Then use ioe device instance to do ioexpander operations, or use ``gpio_lower_half`` - to make ioexpand compatible with normal gpio. +**Binding IO expander drivers** + +IO expander drivers are usually bound by board-specific code rather than +accessed directly from application code. For I2C- or SPI-connected +expanders the typical sequence is: + +#. Obtain the bus instance (for example, a ``struct i2c_master_s *``) from + the hardware-specific bus driver. +#. Call the expander driver's initialization routine with the bus instance + and device-specific configuration; the init routine returns a + ``struct ioexpander_dev_s *`` instance. +#. Use the returned ``ioe`` instance directly, or register individual + expander pins with the upper-half GPIO driver via ``gpio_lower_half``. - **Examples**: ``drivers/ioexpander/pca9555.c``, @@ -33,3 +41,213 @@ IO Expander Device Drivers ``drivers/ioexpander/ioe_rpmsg.c``, ``boards/sim/sim/sim/src/sim_ioexpander.c``, ``boards/arm/nrf52/thingy52/src/nrf52_sx1509.c`` etc. + +Further details +=============== + +Header files +------------ + +The relevant header files are: + +- ``include/nuttx/ioexpander/ioexpander.h`` — defines macros, types and access + macros used to interact with IO expanders. +- ``include/nuttx/ioexpander/gpio.h`` — provides the "gpio lower half" helper + that allows registering an IO expander pin as a standard GPIO device. + +Overview of key macros and options +---------------------------------- + +The following is a concise reference of the important macros defined in the +header. These are the options you will typically use through ``IOEXP_SETOPTION`` +and the various access macros. The primary preprocessor definitions are +listed below (C syntax): + +.. code-block:: c + + /* Direction definitions */ + #define IOEXPANDER_DIRECTION_IN 0 /* float */ + #define IOEXPANDER_DIRECTION_IN_PULLUP 1 + #define IOEXPANDER_DIRECTION_IN_PULLDOWN 2 + #define IOEXPANDER_DIRECTION_OUT 3 /* push-pull */ + #define IOEXPANDER_DIRECTION_OUT_OPENDRAIN 4 + #define IOEXPANDER_DIRECTION_OUT_LED 5 /* LED output */ + + /* Pinset mask helpers */ + #define IOEXPANDER_PINMASK (((ioe_pinset_t)1 << CONFIG_IOEXPANDER_NPINS) - 1) + #define PINSET_ALL (~((ioe_pinset_t)0)) + + /* Common option values (used with IOEXP_SETOPTION) */ + /* Invert (active level) */ + #define IOEXPANDER_OPTION_INVERT 1 + #define IOEXPANDER_VAL_NORMAL 0 /* normal polarity */ + #define IOEXPANDER_VAL_INVERT 1 /* inverted polarity */ + + /* Interrupt configuration (level/edge and high/low/rising/falling/both) */ + #define IOEXPANDER_OPTION_INTCFG 2 + #define IOEXPANDER_VAL_DISABLE 0 /* 0000 disable interrupts */ + #define IOEXPANDER_VAL_LEVEL 1 /* xx01: level triggered */ + #define IOEXPANDER_VAL_EDGE 2 /* xx10: edge triggered */ + #define IOEXPANDER_VAL_HIGH 5 /* 0101: high level */ + #define IOEXPANDER_VAL_LOW 9 /* 1001: low level */ + #define IOEXPANDER_VAL_RISING 6 /* 0110: rising edge */ + #define IOEXPANDER_VAL_FALLING 10 /* 1010: falling edge */ + #define IOEXPANDER_VAL_BOTH 14 /* 1110: both edges */ + + /* LED configuration */ + #define IOEXPANDER_OPTION_LEDCFG 3 /* assign an LED number to a pin */ + + /* Non-generic (driver-specific) option */ + #define IOEXPANDER_OPTION_NONGENERIC 4 /* pass driver-specific struct */ + + /* Wakeup configuration (configure pin as SoC wake-up source) */ + #define IOEXPANDER_OPTION_WAKEUPCFG 5 + #define IOEXPANDER_WAKEUP_DISABLE 0 + #define IOEXPANDER_WAKEUP_ENABLE 1 + + /* Debounce and interrupt mask (recent additions) */ + #define IOEXPANDER_OPTION_SETDEBOUNCE 6 /* configure debounce */ + #define IOEXPANDER_DEBOUNCE_DISABLE 0 + #define IOEXPANDER_DEBOUNCE_ENABLE 1 + + #define IOEXPANDER_OPTION_SETMASK 7 /* control interrupt masking */ + #define IOEXPANDER_MASK_DISABLE 0 /* unmask (enable) interrupts */ + #define IOEXPANDER_MASK_ENABLE 1 /* mask (suppress) interrupts */ + +Access macros (API) +------------------- + +The header exposes a set of helper macros that dispatch to the underlying +driver operations table (``struct ioexpander_ops_s``): + +.. c:macro:: IOEXP_SETDIRECTION(dev, pin, dir) + + Set a pin direction (input, output, open-drain, LED, pull-up/down). + Returns 0 on success or a negative errno on failure. + +.. c:macro:: IOEXP_SETOPTION(dev, pin, opt, val) + + Generic option setting interface used to configure the options listed + above. Note that ``val`` is a ``void *``; drivers may accept an integer + casted to a pointer or a pointer to a driver-specific structure. + + Examples:: + + /* Invert pin polarity */ + IOEXP_SETOPTION(dev, 3, IOEXPANDER_OPTION_INVERT, + (FAR void *)IOEXPANDER_VAL_INVERT); + + /* Enable debounce on pin 2 */ + IOEXP_SETOPTION(dev, 2, IOEXPANDER_OPTION_SETDEBOUNCE, + (FAR void *)IOEXPANDER_DEBOUNCE_ENABLE); + + /* Mask interrupts for pin 5 */ + IOEXP_SETOPTION(dev, 5, IOEXPANDER_OPTION_SETMASK, + (FAR void *)IOEXPANDER_MASK_ENABLE); + +.. c:macro:: IOEXP_WRITEPIN(dev, pin, val) + + Set the pin level. Returns 0 on success or a negative errno on error. + +.. c:macro:: IOEXP_READPIN(dev, pin, valptr) + + Read the actual physical pin level. The value is returned via ``valptr``. + +.. c:macro:: IOEXP_READBUF(dev, pin, valptr) + + Read the buffered/register value cached by the expander. + + - ``IOEXP_WRITEPIN`` sets the pin level (TRUE typically means high). + Drivers handle polarity inversion if configured. + - ``IOEXP_READPIN`` reads the actual physical pin level. + - ``IOEXP_READBUF`` reads the buffered/register value cached by the + expander. + +Multi-pin operations +-------------------- + +When ``CONFIG_IOEXPANDER_MULTIPIN`` is enabled, batch operations are +available that may be more efficient than repeated single-pin calls: + +- ``IOEXP_MULTIWRITEPIN(dev, pins, vals, count)`` +- ``IOEXP_MULTIREADPIN(dev, pins, vals, count)`` +- ``IOEXP_MULTIREADBUF(dev, pins, vals, count)`` + +Interrupts and callbacks +------------------------ + +If ``CONFIG_IOEXPANDER_INT_ENABLE`` is enabled the header defines the +callback type and attach/detach helper macros. The callback signature +is:: + + typedef CODE int (*ioe_callback_t)(FAR struct ioexpander_dev_s *dev, + ioe_pinset_t pinset, FAR void *arg); + +The callback is invoked when events occur for the monitored pinset. The +attach/detach helpers are provided as macros that dispatch to the lower-half +driver when ``CONFIG_IOEXPANDER_INT_ENABLE`` is enabled: + +.. c:macro:: IOEP_ATTACH(dev, pinset, callback, arg) + + Attach and enable a pin interrupt callback. Returns a non-NULL opaque + handle on success. ``pinset`` selects which pin(s) will generate the + callback; ``callback`` is a function of type ``ioe_callback_t`` and + ``arg`` is passed through to the callback. + +.. c:macro:: IOEP_DETACH(dev, handle) + + Detach and disable a previously attached callback referenced by ``handle``. + +Note: when ``CONFIG_IOEXPANDER_NPINS`` > 64, ``ioe_pinset_t`` represents a +single interrupt pin number rather than a bitmask. + +Driver interface (lower-half) +----------------------------- + +Each IO expander driver must implement the operations table +``struct ioexpander_ops_s``. At minimum the driver should provide: + +- ``ioe_direction`` +- ``ioe_option`` +- ``ioe_writepin`` +- ``ioe_readpin`` +- ``ioe_readbuf`` + +Optional multi-pin and interrupt attach/detach methods should be provided +when the corresponding configuration options are enabled. + +Binding to the upper layer (gpio_lower_half) +-------------------------------------------- + +Applications normally do not access IO expander drivers directly. Typical +binding steps are: + +1. Obtain the bus instance (for example, ``struct i2c_master_s *``) from + the hardware-specific bus driver. +2. Call the expander driver's initialization routine with the bus instance + and device configuration to obtain a ``struct ioexpander_dev_s *``. +3. Use the returned ``ioe`` instance directly, or register individual + expander pins as standard GPIO devices via ``gpio_lower_half`` or + ``gpio_lower_half_byname``. + +Example (pseudocode):: + + /* Get the I2C bus */ + struct i2c_master_s *i2c = up_i2cinitialize(0); + + /* Initialize the expander (driver-specific init) */ + struct ioexpander_dev_s *ioe = pca9555_initialize(i2c, CONFIG_PCA9555_ADDR); + + /* Configure pin 0 as input with pull-up and enable debounce */ + IOEXP_SETDIRECTION(ioe, 0, IOEXPANDER_DIRECTION_IN_PULLUP); + IOEXP_SETOPTION(ioe, 0, IOEXPANDER_OPTION_SETDEBOUNCE, + (FAR void *)IOEXPANDER_DEBOUNCE_ENABLE); + +Examples and references +----------------------- + +See the following drivers and board examples for concrete usage: + +- ``drivers/ioexpander/pca9555.c`` — I2C IO expander implementation. +- ``drivers/ioexpander/ioe_rpmsg.c`` — RPMSG-based IO expander. +- ``boards/arm/nrf52/thingy52/src/nrf52_sx1509.c`` — binding example. diff --git a/Documentation/components/tools/index.rst b/Documentation/components/tools/index.rst index f380acfbe20ea..65ccb8e054574 100644 --- a/Documentation/components/tools/index.rst +++ b/Documentation/components/tools/index.rst @@ -13,6 +13,48 @@ cmpconfig.c This C file can be used to build a utility for comparing two NuttX configuration files. +checkkconfig.py +--------------- + +``checkkconfig.py`` is a Python script that simulates the effects of modifying a CONFIG item. +It can be used to check whether my config changes are what I expected. + +Help message:: + + $ tools/checkkconfig.py -h + usage: checkkconfig.py [-h] -f FILE (-s CONFIG VALUE | -d DIFF) + + optional arguments: + -h, --help show this help message and exit + -f FILE, --file FILE Path to the input defconfig file + -s CONFIG_XXX VALUE, --single CONFIG VALUE + Analyze single change: CONFIG_NAME y/m/n + -d DIFF, --diff DIFF Analyze changes from diff file + + example: ./tools/checkkconfig.py -f defconfig -s ELF n + + outputs: + Change report for ELF=n + Config Option Old New + ---------------------------------------------------------------------- + BINFMT_LOADABLE y n + ELF y n + ELF_STACKSIZE 8192 + LIBC_ARCH_ELF y n + LIBC_MODLIB y n + MODLIB_ALIGN_LOG2 2 + MODLIB_BUFFERINCR 32 + MODLIB_BUFFERSIZE 32 + MODLIB_MAXDEPEND 2 + MODLIB_RELOCATION_BUFFERCOUNT 256 + MODLIB_SYMBOL_CACHECOUNT 256 + +As we can see, we can clearly know that +if I turn off ELF in defconfig at this time, +it will bring about the following configuration linkage changes + +It can also parse diff files, which can be used to check the changes of multiple configs. + checkpatch.sh ------------- diff --git a/Documentation/reference/os/nuttx.rst b/Documentation/reference/os/nuttx.rst index 5678d2d9bac11..04c8b606435c9 100644 --- a/Documentation/reference/os/nuttx.rst +++ b/Documentation/reference/os/nuttx.rst @@ -22,16 +22,6 @@ OS List Management APIs periodically -- the calling interval must be ``CONFIG_USEC_PER_TICK``. -.. c:function:: void nxsched_timer_expiration(void) - - Description: if ``CONFIG_SCHED_TICKLESS`` is defined, then this - function is provided by the RTOS base code and called from - platform-specific code when the interval timer used to implemented - the tick-less OS expires. - - **Assumptions**: Base code implementation assumes that this - function is called from interrupt handling logic with interrupts disabled. - .. c:function:: void irq_dispatch(int irq, FAR void *context) This function must be called from the diff --git a/Documentation/reference/os/time_clock.rst b/Documentation/reference/os/time_clock.rst index 86d35955827c7..f178f9807513c 100644 --- a/Documentation/reference/os/time_clock.rst +++ b/Documentation/reference/os/time_clock.rst @@ -372,7 +372,7 @@ In addition to these imported interfaces, the RTOS will export the following interfaces for use by the platform-specific interval timer implementation: -- ``nxsched_timer_expiration()``: called by the platform-specific logic when the interval time expires. +- ``nxsched_process_timer()``: called by the platform-specific logic when the interval time expires. .. c:function:: void archname_timer_initialize(void) @@ -410,7 +410,7 @@ timer implementation: Cancel the alarm and return the time of cancellation of the alarm. These two steps need to be as nearly atomic as possible. - ``nxsched_timer_expiration()`` will not be called unless the alarm + ``nxsched_process_timer()`` will not be called unless the alarm is restarted with ``up_alarm_start()``. If, as a race condition, the alarm has already expired when this function is called, then time returned is the current time. @@ -427,13 +427,13 @@ timer implementation: .. c:function:: int up_alarm_start(FAR const struct timespec *ts) - Start the alarm. ``nxsched_timer_expiration()`` will be called + Start the alarm. ``nxsched_process_timer()`` will be called when the alarm occurs (unless ``up_alarm_cancel`` is called to stop it). :param ts: The time in the future at the alarm is expected to occur. When the alarm occurs the timer logic will call - ``nxsched_timer_expiration()``. + ``nxsched_process_timer()``. :return: Zero (OK) on success; a negated errno value on failure. @@ -445,11 +445,11 @@ timer implementation: Cancel the interval timer and return the time remaining on the timer. These two steps need to be as nearly atomic as possible. -``nxsched_timer_expiration()`` will not be called unless the timer +``nxsched_process_timer()`` will not be called unless the timer is restarted with ``up_timer_start()``. If, as a race condition, the timer has already expired when this function is called, then that pending interrupt must be cleared so that -``nxsched_timer_expiration()`` is not called spuriously and the +``nxsched_process_timer()`` is not called spuriously and the remaining time of zero should be returned. :param ts: Location to return the remaining time. Zero should be @@ -463,12 +463,12 @@ disabled internally to assure non-reentrancy. .. c:function:: int up_timer_start(FAR const struct timespec *ts) -Start the interval timer. ``nxsched_timer_expiration()`` will be +Start the interval timer. ``nxsched_process_timer()`` will be called at the completion of the timeout (unless ``up_timer_cancel()`` is called to stop the timing). :param ts: Provides the time interval until - ``nxsched_timer_expiration()`` is called. + ``nxsched_process_timer()`` is called. :return: Zero (OK) on success; a negated errno value on failure. @@ -564,41 +564,6 @@ or ``kill()`` to communicate with NuttX tasks. context of the timer interrupt handler and is subject to all ISR restrictions. -.. c:function:: int wd_restart(FAR struct wdog_s *wdog, clock_t delay) - - This function restarts the specified watchdog timer using the same - function and argument that were specified in the previous wd_start() - call, but with a new delay value. It can be used when the user wants - to restart the same watchdog with a different timeout value, or to - refresh (feed) an existing watchdog before it expires. - - :param wdog: Pointer to the watchdog timer to restart - :param delay: Delay count in clock ticks - - **NOTE**: The parameter must be of type ``wdparm_t``. - - :return: Zero (``OK``) is returned on success; a negated ``errno`` value - is return to indicate the nature of any failure. - -.. c:function:: int wd_restart_next(FAR struct wdog_s *wdog, clock_t delay) - - This function restarts the specified watchdog timer using a new delay - value, but schedules the next expiration based on the previous - expiration time (wdog->expired + delay). This allows the watchdog to - maintain a consistent periodic interval even if there is some delay in - handling the expiration callback. - - It can be used when the user wants to restart a watchdog for a different - purpose or continue periodic timing based on the previous timeout point. - - :param wdog: Pointer to the watchdog timer to restart - :param delay: Delay count in clock ticks - - **NOTE**: The parameter must be of type ``wdparm_t``. - - :return: Zero (``OK``) is returned on success; a negated ``errno`` value - is return to indicate the nature of any failure. - .. c:function:: int wd_cancel(FAR struct wdog_s *wdog) This function cancels a currently running @@ -745,12 +710,15 @@ that returns immediately without waiting for the timer to stop executing. **POSIX Compatibility:** This is a NON-POSIX interface. -.. c:function:: int hrtimer_start(FAR hrtimer_t *hrtimer, uint64_t ns, \ +.. c:function:: int hrtimer_start(FAR hrtimer_t *hrtimer, \ + hrtimer_entry_t func, \ + uint64_t expired, \ enum hrtimer_mode_e mode) This function starts a high-resolution timer in absolute or relative mode. :param hrtimer: Timer instance to cancel + :param func: Expiration callback function :param ns: Timer expiration in nanoseconds (absolute or relative) :param mode: HRTIMER_MODE_ABS or HRTIMER_MODE_REL @@ -758,7 +726,8 @@ that returns immediately without waiting for the timer to stop executing. **POSIX Compatibility:** This is a NON-POSIX interface. -.. c:type:: uint64_t (*hrtimer_cb)(FAR hrtimer_t *hrtimer, uint64_t expired) +.. c:type:: uint64_t (*hrtimer_entry_t)(FAR hrtimer_t *hrtimer, \ + uint64_t expired) **High-resolution Timer Callback**: when a hrtimer expires, the callback function with this type is called. diff --git a/arch/Kconfig b/arch/Kconfig index ea801c57f5cc3..597a0490de802 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -200,6 +200,7 @@ config ARCH_TRICORE select ARCH_HAVE_STACKCHECK select ARCH_HAVE_CUSTOMOPT select ARCH_HAVE_TCBINFO + select ARCH_HAVE_REGCPY ---help--- Infineon 32-bit AURIX TriCore architectures @@ -1134,6 +1135,12 @@ config ARCH_STACKDUMP ---help--- Enable to do stack dumps after assertions +config ARCH_HAVE_REGCPY + bool "common copy of cpu regs" + default n + ---help--- + Supports context data copying with different architectures + config ARCH_STACKDUMP_MAX_LENGTH int "The maximum length for dump stack on assertions" depends on ARCH_STACKDUMP diff --git a/arch/arm/src/am335x/CMakeLists.txt b/arch/arm/src/am335x/CMakeLists.txt new file mode 100644 index 0000000000000..45e786b93c4bd --- /dev/null +++ b/arch/arm/src/am335x/CMakeLists.txt @@ -0,0 +1,50 @@ +# ############################################################################## +# arch/arm/src/am335x/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you 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. +# +# ############################################################################## + +# AM335x-specific C source files + +set(SRCS + am335x_boot.c + am335x_clockconfig.c + am335x_pinmux.c + am335x_irq.c + am335x_gpio.c + am335x_lowputc.c + am335x_serial.c + am335x_wdog.c + am335x_sysclk.c + am335x_i2c.c + am335x_can.c) + +if(NOT CONFIG_SCHED_TICKLESS) + list(APPEND SRCS am335x_timerisr.c) +endif() + +if(CONFIG_AM335X_GPIO_IRQ) + list(APPEND SRCS am335x_gpioirq.c) +endif() + +if(CONFIG_AM335X_LCDC) + list(APPEND SRCS am335x_lcdc.c am335x_edid.c) +endif() + +target_sources(arch PRIVATE ${SRCS}) diff --git a/arch/arm/src/armv7-a/arm_gicv2.c b/arch/arm/src/armv7-a/arm_gicv2.c index 1020c01e776d4..03ad226ba94ac 100644 --- a/arch/arm/src/armv7-a/arm_gicv2.c +++ b/arch/arm/src/armv7-a/arm_gicv2.c @@ -668,7 +668,7 @@ void up_trigger_irq(int irq, cpu_set_t cpuset) } /**************************************************************************** - * Name: arm_gic_irq_trigger + * Name: up_set_irq_type * * Description: * Set the trigger type for the specified IRQ source and the current CPU. @@ -677,32 +677,37 @@ void up_trigger_irq(int irq, cpu_set_t cpuset) * avoided in common implementations where possible. * * Input Parameters: - * irq - The interrupt request to modify. - * edge - False: Active HIGH level sensitive, True: Rising edge sensitive + * irq - The interrupt request to modify. + * mode - Level sensitive or edge sensitive * * Returned Value: * Zero (OK) on success; a negated errno value is returned on any failure. * ****************************************************************************/ -int arm_gic_irq_trigger(int irq, bool edge) +int up_set_irq_type(int irq, int mode) { uintptr_t regaddr; uint32_t regval; uint32_t intcfg; - if (irq > GIC_IRQ_SGI15 && irq < NR_IRQS) + if (!GIC_IS_SGI(irq)) { + if (mode == IRQ_HIGH_LEVEL || mode == IRQ_LOW_LEVEL) + { + intcfg = INT_ICDICFR_1N; + } + else + { + intcfg = INT_ICDICFR_EDGE | INT_ICDICFR_1N; + } + /* Get the address of the Interrupt Configuration Register for this * irq. */ regaddr = GIC_ICDICFR(irq); - /* Get the new Interrupt configuration bit setting */ - - intcfg = (edge ? (INT_ICDICFR_EDGE | INT_ICDICFR_1N) : INT_ICDICFR_1N); - /* Write the correct interrupt trigger to the Interrupt Configuration * Register. */ diff --git a/arch/arm/src/armv7-a/arm_gicv2m.c b/arch/arm/src/armv7-a/arm_gicv2m.c index d00b7abc658b9..ecdad35d91b0c 100644 --- a/arch/arm/src/armv7-a/arm_gicv2m.c +++ b/arch/arm/src/armv7-a/arm_gicv2m.c @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -117,7 +118,7 @@ int up_alloc_irq_msi(uint8_t busno, uint32_t devfn, int *pirq, int num) irq = g_v2m.spi_start + offset; for (i = 0; i < num; i++) { - arm_gic_irq_trigger(i + irq, true); + up_set_irq_type(i + irq, IRQ_RISING_EDGE); pirq[i] = i + irq; } diff --git a/arch/arm/src/armv7-a/gic.h b/arch/arm/src/armv7-a/gic.h index e23193d6bc3cc..879ac3b483325 100644 --- a/arch/arm/src/armv7-a/gic.h +++ b/arch/arm/src/armv7-a/gic.h @@ -623,6 +623,8 @@ #define GIC_IRQ_SGI14 14 /* Software Generated Interrupt (SGI) 14 */ #define GIC_IRQ_SGI15 15 /* Software Generated Interrupt (SGI) 15 */ +#define GIC_IRQ_PPI0 16 + #define GIC_IRQ_VM 25 /* Virtual Maintenance Interrupt (VM) PPI(6) */ #define GIC_IRQ_HTM 26 /* Hypervisor Timer (HTM) PPI(5) */ #define GIC_IRQ_VTM 27 /* Virtual Timer (VTM) PPI(4) */ @@ -631,6 +633,9 @@ #define GIC_IRQ_PTM 30 /* Non-secure Physical Timer (PTM) PPI(2) */ #define GIC_IRQ_IRQ 31 /* Interrupt Request (nIRQ) PPI(3) */ +#define GIC_IS_SGI(intid) ((intid) >= GIC_IRQ_SGI0 && \ + (intid) < GIC_IRQ_PPI0) + /* Shared Peripheral Interrupts (SPI) follow */ #define GIC_IRQ_SPI 32 /* First SPI interrupt ID */ @@ -746,26 +751,6 @@ void arm_gic0_initialize(void); void arm_gic_initialize(void); -/**************************************************************************** - * Name: arm_gic_irq_trigger - * - * Description: - * Set the trigger type for the specificd IRQ source and the current CPU. - * - * Since this API is not supported on all architectures, it should be - * avoided in common implementations where possible. - * - * Input Parameters: - * irq - The interrupt request to modify. - * edge - False: Active HIGH level sensitive, True: Rising edge sensitive - * - * Returned Value: - * Zero (OK) on success; a negated errno value is returned on any failure. - * - ****************************************************************************/ - -int arm_gic_irq_trigger(int irq, bool edge); - /**************************************************************************** * Name: arm_decodeirq * diff --git a/arch/arm/src/armv7-m/Toolchain.defs b/arch/arm/src/armv7-m/Toolchain.defs index 499be35aed135..180dd97ebaa68 100644 --- a/arch/arm/src/armv7-m/Toolchain.defs +++ b/arch/arm/src/armv7-m/Toolchain.defs @@ -28,9 +28,9 @@ ifeq ($(CONFIG_ARCH_CORTEXM4),y) TOOLCHAIN_MTUNE := -cpu=cortexm4 ifeq ($(CONFIG_ARCH_FPU),y) ifeq ($(CONFIG_ARCH_DPFPU),y) - TOOLCHAIN_MFLOAT := -fpu=vfpv3 + TOOLCHAIN_MFLOAT := -fpu=vfpv4 else - TOOLCHAIN_MFLOAT := -fpu=vfpv3_d16 + TOOLCHAIN_MFLOAT := -fpu=vfpv4_d16 endif endif else @@ -47,9 +47,9 @@ else ifeq ($(CONFIG_ARCH_CORTEXM7),y) TOOLCHAIN_MTUNE := -cpu=cortexm7 ifeq ($(CONFIG_ARCH_FPU),y) ifeq ($(CONFIG_ARCH_DPFPU),y) - TOOLCHAIN_MFLOAT := -fpu=vfpv3 + TOOLCHAIN_MFLOAT := -fpu=vfpv5 else - TOOLCHAIN_MFLOAT := -fpu=vfpv3_d16 + TOOLCHAIN_MFLOAT := -fpu=vfpv5_d16 endif endif else diff --git a/arch/arm/src/armv7-m/arm_exception.S b/arch/arm/src/armv7-m/arm_exception.S index d209e4cf853e4..c2053a59e1725 100644 --- a/arch/arm/src/armv7-m/arm_exception.S +++ b/arch/arm/src/armv7-m/arm_exception.S @@ -113,7 +113,7 @@ */ .text - .section .text.exception_common + .section .text.exception_common, "ax" #ifdef __ghs__ .type exception_common, $function #else diff --git a/arch/arm/src/armv7-r/arm_gicv2.c b/arch/arm/src/armv7-r/arm_gicv2.c index 6aecd09e29958..f8ea1ab3987a1 100644 --- a/arch/arm/src/armv7-r/arm_gicv2.c +++ b/arch/arm/src/armv7-r/arm_gicv2.c @@ -610,7 +610,7 @@ void up_trigger_irq(int irq, cpu_set_t cpuset) } /**************************************************************************** - * Name: arm_gic_irq_trigger + * Name: up_set_irq_type * * Description: * Set the trigger type for the specified IRQ source and the current CPU. @@ -619,32 +619,37 @@ void up_trigger_irq(int irq, cpu_set_t cpuset) * avoided in common implementations where possible. * * Input Parameters: - * irq - The interrupt request to modify. - * edge - False: Active HIGH level sensitive, True: Rising edge sensitive + * irq - The interrupt request to modify. + * mode - Level sensitive or edge sensitive * * Returned Value: * Zero (OK) on success; a negated errno value is returned on any failure. * ****************************************************************************/ -int arm_gic_irq_trigger(int irq, bool edge) +int up_set_irq_type(int irq, int mode) { uintptr_t regaddr; uint32_t regval; uint32_t intcfg; - if (irq > GIC_IRQ_SGI15 && irq < NR_IRQS) + if (!GIC_IS_SGI(irq)) { + if (mode == IRQ_HIGH_LEVEL || mode == IRQ_LOW_LEVEL) + { + intcfg = INT_ICDICFR_1N; + } + else + { + intcfg = INT_ICDICFR_EDGE | INT_ICDICFR_1N; + } + /* Get the address of the Interrupt Configuration Register for this * irq. */ regaddr = GIC_ICDICFR(irq); - /* Get the new Interrupt configuration bit setting */ - - intcfg = (edge ? (INT_ICDICFR_EDGE | INT_ICDICFR_1N) : INT_ICDICFR_1N); - /* Write the correct interrupt trigger to the Interrupt Configuration * Register. */ diff --git a/arch/arm/src/armv7-r/gic.h b/arch/arm/src/armv7-r/gic.h index ceb1b5594e73c..87fd4308c929e 100644 --- a/arch/arm/src/armv7-r/gic.h +++ b/arch/arm/src/armv7-r/gic.h @@ -596,6 +596,8 @@ #define GIC_IRQ_SGI14 14 /* Software Generated Interrupt (SGI) 14 */ #define GIC_IRQ_SGI15 15 /* Software Generated Interrupt (SGI) 15 */ +#define GIC_IRQ_PPI0 16 + #define GIC_IRQ_VM 25 /* Virtual Maintenance Interrupt (VM) PPI(6) */ #define GIC_IRQ_HTM 26 /* Hypervisor Timer (HTM) PPI(5) */ #define GIC_IRQ_VTM 27 /* Virtual Timer (VTM) PPI(4) */ @@ -604,6 +606,9 @@ #define GIC_IRQ_PTM 30 /* Non-secure Physical Timer (PTM) PPI(2) */ #define GIC_IRQ_IRQ 31 /* Interrupt Request (nIRQ) PPI(3) */ +#define GIC_IS_SGI(intid) ((intid) >= GIC_IRQ_SGI0 && \ + (intid) < GIC_IRQ_PPI0) + /* Shared Peripheral Interrupts (SPI) follow */ #define GIC_IRQ_SPI 32 /* First SPI interrupt ID */ @@ -748,26 +753,6 @@ void arm_gic0_initialize(void); void arm_gic_initialize(void); -/**************************************************************************** - * Name: arm_gic_irq_trigger - * - * Description: - * Set the trigger type for the specificd IRQ source and the current CPU. - * - * Since this API is not supported on all architectures, it should be - * avoided in common implementations where possible. - * - * Input Parameters: - * irq - The interrupt request to modify. - * edge - False: Active HIGH level sensitive, True: Rising edge sensitive - * - * Returned Value: - * Zero (OK) on success; a negated errno value is returned on any failure. - * - ****************************************************************************/ - -int arm_gic_irq_trigger(int irq, bool edge); - /**************************************************************************** * Name: arm_decodeirq * diff --git a/arch/arm/src/armv8-r/arm_gic.h b/arch/arm/src/armv8-r/arm_gic.h index 2a5c1a1941c29..eb03f48fd4a96 100644 --- a/arch/arm/src/armv8-r/arm_gic.h +++ b/arch/arm/src/armv8-r/arm_gic.h @@ -335,8 +335,6 @@ void arm_gic_irq_set_priority(unsigned int intid, unsigned int prio, void arm_gic_set_group(unsigned int intid, unsigned int group); #endif -int arm_gic_irq_trigger(unsigned int intid, uint32_t flags); - int arm_gic_raise_sgi(unsigned int sgi_id, uint16_t target_list); #ifdef CONFIG_SMP diff --git a/arch/arm/src/armv8-r/arm_gicv3.c b/arch/arm/src/armv8-r/arm_gicv3.c index f0b723a9ce37d..cf69315b81e9f 100644 --- a/arch/arm/src/armv8-r/arm_gicv3.c +++ b/arch/arm/src/armv8-r/arm_gicv3.c @@ -207,7 +207,7 @@ void arm_gic_irq_set_priority(unsigned int intid, unsigned int prio, } /*************************************************************************** - * Name: arm_gic_irq_trigger + * Name: up_set_irq_type * * Description: * Set the trigger type for the specified IRQ source and the current CPU. @@ -216,27 +216,26 @@ void arm_gic_irq_set_priority(unsigned int intid, unsigned int prio, * avoided in common implementations where possible. * * Input Parameters: - * irq - The interrupt request to modify. - * flags - irq type, IRQ_TYPE_EDGE or IRQ_TYPE_LEVEL - * Default is IRQ_TYPE_LEVEL + * irq - The interrupt request to modify. + * mode - Level sensitive or edge sensitive * * Returned Value: * Zero (OK) on success; a negated errno value is returned on any failure. * ***************************************************************************/ -int arm_gic_irq_trigger(unsigned int intid, uint32_t flags) +int up_set_irq_type(int irq, int mode) { - uint32_t idx = intid / GIC_NUM_INTR_PER_REG; + uint32_t idx = irq / GIC_NUM_INTR_PER_REG; uint32_t shift; uint32_t val; - unsigned long base = GET_DIST_BASE(intid); + unsigned long base = GET_DIST_BASE(irq); irqstate_t irq_flags; - if (!GIC_IS_SGI(intid)) + if (!GIC_IS_SGI(irq)) { - idx = intid / GIC_NUM_CFG_PER_REG; - shift = (intid & (GIC_NUM_CFG_PER_REG - 1)) * 2; + idx = irq / GIC_NUM_CFG_PER_REG; + shift = (irq & (GIC_NUM_CFG_PER_REG - 1)) * 2; /* GICD_ICFGR requires full 32-bit RMW operations. * Each interrupt uses 2 bits; thus updates must be synchronized @@ -246,7 +245,7 @@ int arm_gic_irq_trigger(unsigned int intid, uint32_t flags) irq_flags = spin_lock_irqsave(&g_gic_lock); val = getreg32(ICFGR(base, idx)); val &= ~(GICD_ICFGR_MASK << shift); - if (flags & IRQ_TYPE_EDGE) + if (mode != IRQ_HIGH_LEVEL && mode != IRQ_LOW_LEVEL) { val |= (GICD_ICFGR_TYPE << shift); } diff --git a/arch/arm/src/cmake/armv7-m_ghs.cmake b/arch/arm/src/cmake/armv7-m_ghs.cmake index c78665b97e8d4..ad1c4b5919e8e 100644 --- a/arch/arm/src/cmake/armv7-m_ghs.cmake +++ b/arch/arm/src/cmake/armv7-m_ghs.cmake @@ -26,18 +26,18 @@ if(CONFIG_ARCH_CORTEXM4) list(APPEND PLATFORM_FLAGS -cpu=cortexm4) if(CONFIG_ARCH_FPU) if(CONFIG_ARCH_DPFPU) - list(APPEND PLATFORM_FLAGS -fpu=vfpv3) + list(APPEND PLATFORM_FLAGS -fpu=vfpv4) else() - list(APPEND PLATFORM_FLAGS -fpu=vfpv3_d16) + list(APPEND PLATFORM_FLAGS -fpu=vfpv4_d16) endif() endif() elseif(CONFIG_ARCH_CORTEXM7) list(APPEND PLATFORM_FLAGS -cpu=cortexm7) if(CONFIG_ARCH_FPU) if(CONFIG_ARCH_DPFPU) - list(APPEND PLATFORM_FLAGS -fpu=vfpv3) + list(APPEND PLATFORM_FLAGS -fpu=vfpv5) else() - list(APPEND PLATFORM_FLAGS -fpu=vfpv3_d16) + list(APPEND PLATFORM_FLAGS -fpu=vfpv5_d16) endif() endif() else() diff --git a/arch/arm/src/cmake/ghs.cmake b/arch/arm/src/cmake/ghs.cmake index c7529eb9a96a4..8ad3015c5f5f4 100644 --- a/arch/arm/src/cmake/ghs.cmake +++ b/arch/arm/src/cmake/ghs.cmake @@ -60,7 +60,7 @@ endif() # Architecture flags add_link_options(-entry=__start) -add_compile_options(--no_commons -Wall -Wshadow -Wundef -nostdlib) +add_compile_options(--no_commons --ghstd=last -Wshadow -Wundef -nostdlib) add_compile_options(--option=305) if(CONFIG_DEBUG_CUSTOMOPT) @@ -147,6 +147,12 @@ if(CONFIG_ARM_THUMB) add_compile_options(-thumb) endif() +# Optimization of unused sections + +if(CONFIG_DEBUG_OPT_UNUSED_SECTIONS) + add_compile_options(-ffunction-sections -fdata-sections) +endif() + # Debug --whole-archive if(CONFIG_DEBUG_LINK_WHOLE_ARCHIVE) @@ -219,12 +225,34 @@ function(nuttx_generate_preprocess_target) ARGN ${ARGN}) + # in greenhills, for file to pre-process, if the file name is ends with + # "*.ld", will report error, and we need to change the target file name to + # "*.ld.i" or "*.ld.tmp", this is a special corner case, and the official + # greenhills reference manual do not have explanation about why the only + # "*.ld" should handle + set(EXPECT_TARGET_FILE_NAME ${TARGET_FILE}) + string(REGEX MATCH ".*\.ld$" ends_with_ld ${TARGET_FILE}) + + if(ends_with_ld STREQUAL ${TARGET_FILE}) + set(EXPECT_TARGET_FILE_NAME "${TARGET_FILE}.i") + endif() + add_custom_command( - OUTPUT ${TARGET_FILE} - COMMAND ${PREPROCESS} -I${CMAKE_BINARY_DIR}/include -filetype.cpp - ${SOURCE_FILE} -o ${TARGET_FILE} + OUTPUT ${EXPECT_TARGET_FILE_NAME} + COMMAND + ${PREPROCESS} + $> + -I${CMAKE_BINARY_DIR}/include -filetype.cpp ${SOURCE_FILE} -o + ${EXPECT_TARGET_FILE_NAME} DEPENDS ${SOURCE_FILE} ${DEPENDS}) + if(NOT ${EXPECT_TARGET_FILE_NAME} STREQUAL ${TARGET_FILE}) + add_custom_command( + OUTPUT ${TARGET_FILE} + COMMAND ${CMAKE_COMMAND} -E copy ${EXPECT_TARGET_FILE_NAME} ${TARGET_FILE} + DEPENDS ${EXPECT_TARGET_FILE_NAME}) + endif() + endfunction() # override nuttx_find_toolchain_lib diff --git a/arch/arm/src/common/Toolchain.defs b/arch/arm/src/common/Toolchain.defs index f38ab852f0928..5b683e26c9edf 100644 --- a/arch/arm/src/common/Toolchain.defs +++ b/arch/arm/src/common/Toolchain.defs @@ -410,7 +410,14 @@ ARCHOPTIMIZATION += --no_commons else ARCHOPTIMIZATION += -fno-common endif -ARCHOPTIMIZATION += -Wall -Wshadow -Wundef + +ifeq ($(CONFIG_ARM_TOOLCHAIN_GHS),y) + ARCHOPTIMIZATION += --ghstd=last +else + ARCHOPTIMIZATION += -Wall +endif + +ARCHOPTIMIZATION += -Wshadow -Wundef ifeq ($(CONFIG_ARM_TOOLCHAIN_ARMCLANG),y) ARCHOPTIMIZATION += -nostdlib @@ -438,8 +445,8 @@ ifeq ($(CONFIG_ARM_TOOLCHAIN_ARMCLANG),) ifeq ($(CONFIG_DEBUG_OPT_UNUSED_SECTIONS),y) ifeq ($(CONFIG_ARCH_TOOLCHAIN_GHS),) LDFLAGS += --gc-sections - ARCHOPTIMIZATION += -ffunction-sections -fdata-sections endif + ARCHOPTIMIZATION += -ffunction-sections -fdata-sections endif endif diff --git a/arch/arm/src/common/iar/fork.S b/arch/arm/src/common/iar/fork.S index 4177a1f8e8dec..3f16484a36530 100644 --- a/arch/arm/src/common/iar/fork.S +++ b/arch/arm/src/common/iar/fork.S @@ -29,7 +29,7 @@ #include "arm_fork.h" MODULE up_fork - SECTION .text:CODE:NOROOT(2) + SECTION .text:CODE:NOROOT(2), "ax" /**************************************************************************** * Pre-processor Definitions diff --git a/arch/arm/src/cxd56xx/cxd56_farapistub.S b/arch/arm/src/cxd56xx/cxd56_farapistub.S index 9982a02409087..7c72ab5dcf38e 100644 --- a/arch/arm/src/cxd56xx/cxd56_farapistub.S +++ b/arch/arm/src/cxd56xx/cxd56_farapistub.S @@ -21,7 +21,7 @@ ****************************************************************************/ .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} @@ -193,7 +193,7 @@ _modulelist_power_mgr: .word 0 .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} @@ -319,7 +319,7 @@ _modulelist_flash_mgr: .word 0 .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} @@ -389,7 +389,7 @@ _modulelist_rtc_mgr: .word 0 .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} @@ -551,7 +551,7 @@ _modulelist_gnss_pwr: .word 0 .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} @@ -591,7 +591,7 @@ _modulelist_aca: .word 0 .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} @@ -631,7 +631,7 @@ _modulelist_pinconfig: .word 0 .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} @@ -707,7 +707,7 @@ _modulelist_uart: .word 0 .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} @@ -783,7 +783,7 @@ _modulelist_update_mgr: .word 0 .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} diff --git a/arch/arm/src/imx6/imx_enet.c b/arch/arm/src/imx6/imx_enet.c index dcf7ab0c75be2..655398d652c5a 100644 --- a/arch/arm/src/imx6/imx_enet.c +++ b/arch/arm/src/imx6/imx_enet.c @@ -39,6 +39,7 @@ #include +#include #include #include #include @@ -2581,7 +2582,7 @@ int imx_netinitialize(int intf) /* Configure as a (high) level interrupt */ - arm_gic_irq_trigger(IMX_IRQ_ENET0, false); + up_set_irq_type(IMX_IRQ_ENET0, IRQ_HIGH_LEVEL); #ifdef CONFIG_NET_ETHERNET /* Determine a semi-unique MAC address from MCU UID diff --git a/arch/arm/src/imx6/imx_serial.c b/arch/arm/src/imx6/imx_serial.c index c68f7c79b0da6..81070ba5c77ea 100644 --- a/arch/arm/src/imx6/imx_serial.c +++ b/arch/arm/src/imx6/imx_serial.c @@ -599,7 +599,7 @@ static int imx_attach(struct uart_dev_s *dev) { /* Configure as a (high) level interrupt */ - arm_gic_irq_trigger(priv->irq, false); + up_set_irq_type(priv->irq, IRQ_HIGH_LEVEL); /* Enable the interrupt (RX and TX interrupts are still disabled * in the UART diff --git a/arch/arm/src/imx6/imx_timerisr.c b/arch/arm/src/imx6/imx_timerisr.c index f6d4fe20c30b7..8937b04256ecc 100644 --- a/arch/arm/src/imx6/imx_timerisr.c +++ b/arch/arm/src/imx6/imx_timerisr.c @@ -246,7 +246,7 @@ void up_timer_initialize(void) /* Configure as a (rising) edge-triggered interrupt */ - arm_gic_irq_trigger(IMX_IRQ_GPT, true); + up_set_irq_type(IMX_IRQ_GPT, IRQ_RISING_EDGE); /* Attach the timer interrupt vector */ diff --git a/arch/arm/src/imxrt/imxrt_clockconfig_ver1.h b/arch/arm/src/imxrt/imxrt_clockconfig_ver1.h index 73433b1db92b7..e7b0f627e033f 100644 --- a/arch/arm/src/imxrt/imxrt_clockconfig_ver1.h +++ b/arch/arm/src/imxrt/imxrt_clockconfig_ver1.h @@ -21,7 +21,7 @@ ****************************************************************************/ #ifndef __ARCH_ARM_SRC_IMXRT_IMXRT_CLOCKCONFIG_VER1_H -#define __ARCH_ARM_SRC_IMXRT_IMXRT_CLOCKCONFIG_VER2_H +#define __ARCH_ARM_SRC_IMXRT_IMXRT_CLOCKCONFIG_VER1_H /**************************************************************************** * Included Files diff --git a/arch/arm/src/imxrt/imxrt_tickless.c b/arch/arm/src/imxrt/imxrt_tickless.c index 406bd23cb0866..bbcd10263d1d3 100644 --- a/arch/arm/src/imxrt/imxrt_tickless.c +++ b/arch/arm/src/imxrt/imxrt_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * * NOTE @@ -183,7 +183,7 @@ static void imxrt_interval_handler(void) g_tickless.pending = false; - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -477,7 +477,7 @@ int up_timer_gettime(struct timespec *ts) * Name: up_alarm_start * * Description: - * Start the alarm. nxsched_timer_expiration() will be called when the + * Start the alarm. nxsched_process_timer() will be called when the * alarm occurs (unless up_alaram_cancel is called to stop it). * * Provided by platform-specific code and called from the RTOS base code. @@ -485,7 +485,7 @@ int up_timer_gettime(struct timespec *ts) * Input Parameters: * ts - The time in the future at the alarm is expected to occur. When * the alarm occurs the timer logic will call - * nxsched_timer_expiration(). + * nxsched_process_timer(). * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -553,7 +553,7 @@ int up_alarm_start(const struct timespec *ts) * Description: * Cancel the alarm and return the time of cancellation of the alarm. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the alarm is + * nxsched_process_timer() will not be called unless the alarm is * restarted with up_alarm_start(). * * If, as a race condition, the alarm has already expired when this diff --git a/arch/arm/src/lpc43xx/lpc43_rit.c b/arch/arm/src/lpc43xx/lpc43_rit.c index 0188723a8d548..f7e788672f1b2 100644 --- a/arch/arm/src/lpc43xx/lpc43_rit.c +++ b/arch/arm/src/lpc43xx/lpc43_rit.c @@ -86,7 +86,7 @@ static int lpc43_rit_isr(int irq, void *context, void *arg) { /* handle expired alarm */ - nxsched_timer_expiration(); + nxsched_process_timer(); } leave_critical_section(flags); diff --git a/arch/arm/src/lpc43xx/lpc43_tickless_rit.c b/arch/arm/src/lpc43xx/lpc43_tickless_rit.c index 8c08db6b8b6db..5dac6789b618a 100644 --- a/arch/arm/src/lpc43xx/lpc43_tickless_rit.c +++ b/arch/arm/src/lpc43xx/lpc43_tickless_rit.c @@ -496,7 +496,7 @@ static inline void lpc43_tl_alarm(uint32_t curr) lpc43_tl_init_timer_vars(); lpc43_tl_set_default_compare(curr); - nxsched_timer_expiration(); + nxsched_process_timer(); } /* Interrupt handler */ diff --git a/arch/arm/src/lpc54xx/lpc54_tickless.c b/arch/arm/src/lpc54xx/lpc54_tickless.c index dedd2a00db9d1..2ef0d16d91131 100644 --- a/arch/arm/src/lpc54xx/lpc54_tickless.c +++ b/arch/arm/src/lpc54xx/lpc54_tickless.c @@ -539,7 +539,7 @@ static inline void lpc54_tl_alarm(uint64_t curr) lpc54_init_timer_vars(); lpc54_set_default_compare(curr); - nxsched_timer_expiration(); + nxsched_process_timer(); } /* Interrupt handler */ diff --git a/arch/arm/src/moxart/moxart_head.S b/arch/arm/src/moxart/moxart_head.S index 0b8b6cd3cf91f..a67cdeabaf06c 100644 --- a/arch/arm/src/moxart/moxart_head.S +++ b/arch/arm/src/moxart/moxart_head.S @@ -22,7 +22,7 @@ /* Place a branch to the real head at the entry point */ -.section .text.start +.section .text.start, "ax" b __start /* Exception Vectors like they are needed for the exception vector @@ -30,7 +30,7 @@ * linked to appear at 0x80001c */ -.section .text.exceptions +.section .text.exceptions, "ax" _undef_instr: b arm_vectorundefinsn _sw_interr: diff --git a/arch/arm/src/nrf52/nrf52_tickless_rtc.c b/arch/arm/src/nrf52/nrf52_tickless_rtc.c index 78aeb7f68886b..9d05a70322954 100644 --- a/arch/arm/src/nrf52/nrf52_tickless_rtc.c +++ b/arch/arm/src/nrf52/nrf52_tickless_rtc.c @@ -246,7 +246,7 @@ static int rtc_handler(int irq, void *context, void *arg) /* let scheduler now of alarm firing */ - nxsched_timer_expiration(); + nxsched_process_timer(); } leave_critical_section(flags); @@ -357,5 +357,5 @@ void up_timer_initialize(void) /* kick off alarm scheduling */ - nxsched_timer_expiration(); + nxsched_process_timer(); } diff --git a/arch/arm/src/nrf53/nrf53_tickless_rtc.c b/arch/arm/src/nrf53/nrf53_tickless_rtc.c index 0af41431673c9..8fa6e0df3386a 100644 --- a/arch/arm/src/nrf53/nrf53_tickless_rtc.c +++ b/arch/arm/src/nrf53/nrf53_tickless_rtc.c @@ -244,7 +244,7 @@ static int rtc_handler(int irq, void *context, void *arg) /* let scheduler now of alarm firing */ - nxsched_timer_expiration(); + nxsched_process_timer(); } leave_critical_section(flags); @@ -355,5 +355,5 @@ void up_timer_initialize(void) /* kick off alarm scheduling */ - nxsched_timer_expiration(); + nxsched_process_timer(); } diff --git a/arch/arm/src/nrf91/nrf91_tickless_rtc.c b/arch/arm/src/nrf91/nrf91_tickless_rtc.c index 4165c01f3615a..b3065a546206d 100644 --- a/arch/arm/src/nrf91/nrf91_tickless_rtc.c +++ b/arch/arm/src/nrf91/nrf91_tickless_rtc.c @@ -240,7 +240,7 @@ static int rtc_handler(int irq, void *context, void *arg) /* let scheduler now of alarm firing */ - nxsched_timer_expiration(); + nxsched_process_timer(); } leave_critical_section(flags); @@ -351,5 +351,5 @@ void up_timer_initialize(void) /* kick off alarm scheduling */ - nxsched_timer_expiration(); + nxsched_process_timer(); } diff --git a/arch/arm/src/sam34/sam4cm_tickless.c b/arch/arm/src/sam34/sam4cm_tickless.c index a2f2621df130d..b8262b751d20a 100644 --- a/arch/arm/src/sam34/sam4cm_tickless.c +++ b/arch/arm/src/sam34/sam4cm_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -188,7 +188,7 @@ static struct sam_tickless_s g_tickless; static void sam_oneshot_handler(void *arg) { tmrinfo("Expired...\n"); - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -323,7 +323,7 @@ int up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -365,14 +365,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/sama5/sam_tickless.c b/arch/arm/src/sama5/sam_tickless.c index da588817430f5..cf497896013a3 100644 --- a/arch/arm/src/sama5/sam_tickless.c +++ b/arch/arm/src/sama5/sam_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -200,7 +200,7 @@ static struct sam_tickless_s g_tickless; static void sam_oneshot_handler(void *arg) { tmrinfo("Expired...\n"); - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -335,7 +335,7 @@ int up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -377,14 +377,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/samd5e5/sam_tickless.c b/arch/arm/src/samd5e5/sam_tickless.c index bde7eb332e8be..7629bdab14b25 100644 --- a/arch/arm/src/samd5e5/sam_tickless.c +++ b/arch/arm/src/samd5e5/sam_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -198,7 +198,7 @@ static struct sam_tickless_s g_tickless; static void sam_oneshot_handler(void *arg) { tmrinfo("Expired...\n"); - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -333,7 +333,7 @@ int up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -375,14 +375,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/samv7/Kconfig b/arch/arm/src/samv7/Kconfig index 257096a71a334..3a3c6f6500d24 100644 --- a/arch/arm/src/samv7/Kconfig +++ b/arch/arm/src/samv7/Kconfig @@ -3258,7 +3258,6 @@ config SAMV7_EMAC0_MII config SAMV7_EMAC0_RMII bool "RMII" - depends on !ARCH_CHIP_SAM4E ---help--- Support Ethernet RMII interface (vs MII). diff --git a/arch/arm/src/samv7/sam_tickless.c b/arch/arm/src/samv7/sam_tickless.c index f867d0f94aea5..6777cf2f8ead9 100644 --- a/arch/arm/src/samv7/sam_tickless.c +++ b/arch/arm/src/samv7/sam_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -212,7 +212,7 @@ static struct sam_tickless_s g_tickless; static void sam_oneshot_handler(void *arg) { tmrinfo("Expired...\n"); - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -321,7 +321,7 @@ int up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -363,14 +363,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/stm32/stm32_tickless.c b/arch/arm/src/stm32/stm32_tickless.c index 6062912deafd5..d7eb0b7499938 100644 --- a/arch/arm/src/stm32/stm32_tickless.c +++ b/arch/arm/src/stm32/stm32_tickless.c @@ -54,7 +54,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -318,7 +318,7 @@ static void stm32_interval_handler(void) g_tickless.pending = false; - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -746,7 +746,7 @@ void up_timer_getmask(clock_t *mask) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -883,14 +883,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/stm32f7/stm32_tickless.c b/arch/arm/src/stm32f7/stm32_tickless.c index fcb9d1b5e3d08..3e426826d27ea 100644 --- a/arch/arm/src/stm32f7/stm32_tickless.c +++ b/arch/arm/src/stm32f7/stm32_tickless.c @@ -54,7 +54,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -322,7 +322,7 @@ static void stm32_interval_handler(void) g_tickless.pending = false; - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -787,7 +787,7 @@ void up_timer_getmask(clock_t *mask) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -926,14 +926,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/stm32h7/stm32_tickless.c b/arch/arm/src/stm32h7/stm32_tickless.c index feb5d85c754e7..7e3b712f9ffd9 100644 --- a/arch/arm/src/stm32h7/stm32_tickless.c +++ b/arch/arm/src/stm32h7/stm32_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -309,7 +309,7 @@ static void stm32_interval_handler(void) g_tickless.pending = false; - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -761,7 +761,7 @@ void up_timer_getmask(clock_t *mask) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -900,14 +900,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/stm32l4/stm32l4_tickless.c b/arch/arm/src/stm32l4/stm32l4_tickless.c index de6172ea04d39..6ca4f157bb310 100644 --- a/arch/arm/src/stm32l4/stm32l4_tickless.c +++ b/arch/arm/src/stm32l4/stm32l4_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -144,7 +144,7 @@ static struct stm32l4_tickless_s g_tickless; static void stm32l4_oneshot_handler(void *arg) { tmrinfo("Expired...\n"); - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -273,7 +273,7 @@ int up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -312,14 +312,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/stm32wb/stm32wb_tickless.c b/arch/arm/src/stm32wb/stm32wb_tickless.c index fc24296d3acc3..88c7a1bca596b 100644 --- a/arch/arm/src/stm32wb/stm32wb_tickless.c +++ b/arch/arm/src/stm32wb/stm32wb_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -272,7 +272,7 @@ static void stm32wb_interval_handler(void) g_tickless.pending = false; - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -612,7 +612,7 @@ void up_timer_getmask(clock_t *mask) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -749,14 +749,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/tlsr82/chip/b87/boot/cstartup_flash.S b/arch/arm/src/tlsr82/chip/b87/boot/cstartup_flash.S index 735ccc413ab51..c2627de59dcaf 100644 --- a/arch/arm/src/tlsr82/chip/b87/boot/cstartup_flash.S +++ b/arch/arm/src/tlsr82/chip/b87/boot/cstartup_flash.S @@ -404,7 +404,7 @@ __irq: tjl tc32_exception ASMEND: - .section .bss + .section .bss, "aw" .global g_intstackalloc .global g_intstacktop .align 4 diff --git a/arch/arm/src/xmc4/xmc4_tickless.c b/arch/arm/src/xmc4/xmc4_tickless.c index ce7e35b0a8d5d..85c7a95111891 100644 --- a/arch/arm/src/xmc4/xmc4_tickless.c +++ b/arch/arm/src/xmc4/xmc4_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * * NOTE @@ -150,7 +150,7 @@ static void xmc4_interval_handler(void *arg) putreg32(CCU4_CC4_TCCLR_TRBC_MASK, XMC4_CCU41_CC40TCCLR); g_tickless.pending = false; - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -385,7 +385,7 @@ int up_timer_gettime(struct timespec *ts) * Name: up_alarm_start * * Description: - * Start the alarm. nxsched_timer_expiration() will be called when the + * Start the alarm. nxsched_process_timer() will be called when the * alarm occurs (unless up_alaram_cancel is called to stop it). * * Provided by platform-specific code and called from the RTOS base code. @@ -393,7 +393,7 @@ int up_timer_gettime(struct timespec *ts) * Input Parameters: * ts - The time in the future at the alarm is expected to occur. When * the alarm occurs the timer logic will call - * nxsched_timer_expiration(). + * nxsched_process_timer(). * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -466,7 +466,7 @@ int up_timer_start(const struct timespec *ts) * Description: * Cancel the alarm and return the time of cancellation of the alarm. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the alarm is + * nxsched_process_timer() will not be called unless the alarm is * restarted with up_alarm_start(). * * If, as a race condition, the alarm has already expired when this diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 51f28f74d972b..6ed533f771a31 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -34,6 +34,7 @@ config ARCH_CHIP_A64 select ARCH_HAVE_IRQTRIGGER select ARCH_NEED_ADDRENV_MAPPING select ARM64_HAVE_PSCI + select ARCH_HAVE_IRQPRIO ---help--- Allwinner A64 SoC @@ -44,6 +45,7 @@ config ARCH_CHIP_RK3399 select ARCH_HAVE_RESET select ARCH_NEED_ADDRENV_MAPPING select ARM64_HAVE_PSCI + select ARCH_HAVE_IRQPRIO ---help--- Rockchip RK3399 SoC @@ -57,6 +59,7 @@ config ARCH_CHIP_QEMU select ARCH_HAVE_RESET select ARCH_HAVE_TEXT_HEAP select ARM64_HAVE_PSCI + select ARCH_HAVE_IRQPRIO ---help--- QEMU virt platform (ARMv8a) @@ -72,6 +75,7 @@ config ARCH_CHIP_GOLDFISH select ARCH_HAVE_RESET select ARCH_NEED_ADDRENV_MAPPING select ARM64_HAVE_PSCI + select ARCH_HAVE_IRQPRIO ---help--- Android GoldFish platform for NuttX (ARMv8a), based on ARM virt board @@ -80,6 +84,7 @@ config ARCH_CHIP_FVP_ARMV8R bool "ARM FVP virt platform (ARMv8r)" select ARCH_CORTEX_R82 select ARCH_HAVE_IRQTRIGGER + select ARCH_HAVE_IRQPRIO ---help--- ARM FVP virt platform (ARMv8r) @@ -88,6 +93,7 @@ config ARCH_CHIP_IMX8 select ARCH_HAVE_ADDRENV select ARCH_HAVE_IRQTRIGGER select ARCH_NEED_ADDRENV_MAPPING + select ARCH_HAVE_IRQPRIO ---help--- NXP i.MX8 (ARMv8a) applications processors @@ -98,6 +104,7 @@ config ARCH_CHIP_IMX9 select ARCH_HAVE_I2CRESET select ARCH_HAVE_IRQTRIGGER select ARCH_NEED_ADDRENV_MAPPING + select ARCH_HAVE_IRQPRIO ---help--- NXP i.MX9 (ARMv8.2a) applications processors @@ -109,6 +116,7 @@ config ARCH_CHIP_ZYNQ_MPSOC select ARCH_HAVE_IRQTRIGGER select ARCH_NEED_ADDRENV_MAPPING select ARM64_HAVE_PSCI + select ARCH_HAVE_IRQPRIO ---help--- XilinX ZYNQ MPSOC @@ -123,6 +131,7 @@ config ARCH_CHIP_BCM2711 select ARCH_USE_MMU # Required for up_testset select ARMV8A_HAVE_GICv2 select ARCH_HAVE_SDIO + select ARCH_HAVE_IRQPRIO ---help--- Broadcom BCM2711 quad-core ARM Cortex A72 diff --git a/arch/arm64/src/a64/a64_serial.c b/arch/arm64/src/a64/a64_serial.c index b795faf629659..737623869aa67 100644 --- a/arch/arm64/src/a64/a64_serial.c +++ b/arch/arm64/src/a64/a64_serial.c @@ -648,7 +648,8 @@ static int a64_uart_attach(struct uart_dev_s *dev) /* Set Interrupt Priority in Generic Interrupt Controller v2 */ - arm64_gic_irq_set_priority(port->irq_num, 0, IRQ_TYPE_LEVEL); + up_prioritize_irq(port->irq_num, 0); + up_set_irq_type(port->irq_num, IRQ_HIGH_LEVEL); /* Enable UART Interrupt */ diff --git a/arch/arm64/src/a64/a64_twi.c b/arch/arm64/src/a64/a64_twi.c index 79d913a72f12b..a016c0151e767 100644 --- a/arch/arm64/src/a64/a64_twi.c +++ b/arch/arm64/src/a64/a64_twi.c @@ -1845,7 +1845,8 @@ static void twi_hw_initialize(struct a64_twi_priv_s *priv) /* Set Interrupt Priority in Generic Interrupt Controller v2 */ - arm64_gic_irq_set_priority(priv->config->irq, IRQ_TYPE_LEVEL, 0); + up_prioritize_irq(priv->config->irq, 0); + up_set_irq_type(priv->config->irq, IRQ_HIGH_LEVEL); /* Enable TWI Interrupt */ diff --git a/arch/arm64/src/bcm2711/bcm2711_gpio.c b/arch/arm64/src/bcm2711/bcm2711_gpio.c index f155e58a66ad1..e47ae8580eaba 100644 --- a/arch/arm64/src/bcm2711/bcm2711_gpio.c +++ b/arch/arm64/src/bcm2711/bcm2711_gpio.c @@ -272,7 +272,8 @@ static int bcm2711_gpio_irqs_init(void) for (int i = 0; i < NUM_GPIO_IRQS; i++) { up_enable_irq(g_gpio_irqs[i]); - arm64_gic_irq_set_priority(g_gpio_irqs[i], 0, IRQ_TYPE_LEVEL); + up_prioritize_irq(g_gpio_irqs[i], 0); + up_set_irq_type(g_gpio_irqs[i], IRQ_HIGH_LEVEL); } /* Mark as initialized. */ diff --git a/arch/arm64/src/bcm2711/bcm2711_i2c.c b/arch/arm64/src/bcm2711/bcm2711_i2c.c index 706c0002299f6..c5aa8ea1db261 100644 --- a/arch/arm64/src/bcm2711/bcm2711_i2c.c +++ b/arch/arm64/src/bcm2711/bcm2711_i2c.c @@ -1106,7 +1106,8 @@ struct i2c_master_s *bcm2711_i2cbus_initialize(int port) /* Enable interrupt handler */ - arm64_gic_irq_set_priority(BCM_IRQ_VC_I2C, 0, IRQ_TYPE_EDGE); + up_prioritize_irq(BCM_IRQ_VC_I2C, 0); + up_set_irq_type(BCM_IRQ_VC_I2C, IRQ_RISING_EDGE); up_enable_irq(BCM_IRQ_VC_I2C); g_i2c_irqinit = true; /* Mark IRQ handler as initialized */ i2cinfo("I2C IRQ enabled\n"); diff --git a/arch/arm64/src/bcm2711/bcm2711_sdio.c b/arch/arm64/src/bcm2711/bcm2711_sdio.c index a0d395b4e6c71..8e54c2e6e4f8e 100644 --- a/arch/arm64/src/bcm2711/bcm2711_sdio.c +++ b/arch/arm64/src/bcm2711/bcm2711_sdio.c @@ -1068,7 +1068,8 @@ static int bcm2711_attach(FAR struct sdio_dev_s *dev) /* Enable the interrupt handler */ - arm64_gic_irq_set_priority(BCM_IRQ_VC_EMMC, 0, IRQ_TYPE_LEVEL); + up_prioritize_irq(BCM_IRQ_VC_EMMC, 0); + up_set_irq_type(BCM_IRQ_VC_EMMC, IRQ_HIGH_LEVEL); up_enable_irq(BCM_IRQ_VC_EMMC); g_emmc_irqinit = true; mcinfo("EMMC IRQ enabled."); diff --git a/arch/arm64/src/bcm2711/bcm2711_serial.c b/arch/arm64/src/bcm2711/bcm2711_serial.c index dc4d0c0415239..15ebc54dc459b 100644 --- a/arch/arm64/src/bcm2711/bcm2711_serial.c +++ b/arch/arm64/src/bcm2711/bcm2711_serial.c @@ -568,7 +568,8 @@ static int bcm2711_miniuart_attach(struct uart_dev_s *dev) /* Set interrupt priority in GICv2 */ - arm64_gic_irq_set_priority(BCM_IRQ_VC_AUX, 0, IRQ_TYPE_LEVEL); + up_prioritize_irq(BCM_IRQ_VC_AUX, 0); + up_set_irq_type(BCM_IRQ_VC_AUX, IRQ_HIGH_LEVEL); /* Enable UART interrupt */ diff --git a/arch/arm64/src/bcm2711/bcm2711_spi.c b/arch/arm64/src/bcm2711/bcm2711_spi.c index 585c63215b67f..28f27cf8d2baa 100644 --- a/arch/arm64/src/bcm2711/bcm2711_spi.c +++ b/arch/arm64/src/bcm2711/bcm2711_spi.c @@ -1020,7 +1020,8 @@ struct spi_dev_s *bcm2711_spibus_initialize(int port) return NULL; } - arm64_gic_irq_set_priority(BCM_IRQ_VC_SPI, 0, IRQ_TYPE_LEVEL); + up_prioritize_irq(BCM_IRQ_VC_SPI, 0); + up_set_irq_type(BCM_IRQ_VC_SPI, IRQ_HIGH_LEVEL); up_enable_irq(BCM_IRQ_VC_SPI); g_interrupts = true; diff --git a/arch/arm64/src/common/arm64_backtrace.c b/arch/arm64/src/common/arm64_backtrace.c index ee908fee736a1..828a16aecd521 100644 --- a/arch/arm64/src/common/arm64_backtrace.c +++ b/arch/arm64/src/common/arm64_backtrace.c @@ -162,8 +162,8 @@ int up_backtrace(struct tcb_s *tcb, { ret = backtrace(tcb->stack_base_ptr, tcb->stack_base_ptr + tcb->adj_stack_size, - running_regs()[REG_X29], - running_regs()[REG_ELR], + (void *)(tcb->xcp.regs)[REG_X29], + (void *)(tcb->xcp.regs)[REG_ELR], buffer, size, &skip); } diff --git a/arch/arm64/src/common/arm64_gic.h b/arch/arm64/src/common/arm64_gic.h index 43eec799a5aab..ffb5f10bba18c 100644 --- a/arch/arm64/src/common/arm64_gic.h +++ b/arch/arm64/src/common/arm64_gic.h @@ -248,10 +248,6 @@ #define GICD_ICFGR_MASK BIT_MASK(2) #define GICD_ICFGR_TYPE BIT(1) -/* BIT(0) reserved for IRQ_ZERO_LATENCY */ -#define IRQ_TYPE_LEVEL BIT(1) -#define IRQ_TYPE_EDGE BIT(2) - #define GIC_SPI_INT_BASE 32 #define GIC_SPI_MAX_INTID 1019 #define GIC_IS_SPI(intid) (((intid) >= GIC_SPI_INT_BASE) && \ @@ -261,10 +257,6 @@ #define GIC_DIST_IROUTER 0x6000 #define IROUTER(base, n) (base + GIC_DIST_IROUTER + (n) * 8) -/* BIT(0) reserved for IRQ_ZERO_LATENCY */ -#define IRQ_TYPE_LEVEL BIT(1) -#define IRQ_TYPE_EDGE BIT(2) - #define IRQ_DEFAULT_PRIORITY 0xa0 #define GIC_IRQ_SGI0 0 @@ -300,9 +292,6 @@ bool arm64_gic_irq_is_enabled(unsigned int intid); int arm64_gic_initialize(void); -void arm64_gic_irq_set_priority(unsigned int intid, unsigned int prio, - uint32_t flags); -int arm64_gic_irq_trigger(unsigned int intid, uint32_t flags); /**************************************************************************** * Name: arm64_decodeirq @@ -323,7 +312,6 @@ uint64_t * arm64_decodeirq(uint64_t *regs); void arm64_gic_raise_sgi(unsigned int sgi_id, uint16_t target_list); -int arm64_gicv_irq_trigger(int irq, bool edge); #ifdef CONFIG_ARM64_GICV2M int arm64_gic_v2m_initialize(void); #endif diff --git a/arch/arm64/src/common/arm64_gicv2.c b/arch/arm64/src/common/arm64_gicv2.c index ab7b789d3c0c3..ef9fb5e3433ea 100644 --- a/arch/arm64/src/common/arm64_gicv2.c +++ b/arch/arm64/src/common/arm64_gicv2.c @@ -1318,7 +1318,7 @@ void up_trigger_irq(int irq, cpu_set_t cpuset) } /**************************************************************************** - * Name: arm64_gicv_irq_trigger + * Name: up_set_irq_type * * Description: * Set the trigger type for the specified IRQ source and the current CPU. @@ -1327,32 +1327,37 @@ void up_trigger_irq(int irq, cpu_set_t cpuset) * avoided in common implementations where possible. * * Input Parameters: - * irq - The interrupt request to modify. - * edge - False: Active HIGH level sensitive, True: Rising edge sensitive + * irq - The interrupt request to modify. + * mode - Level sensitive or edge sensitive * * Returned Value: * Zero (OK) on success; a negated errno value is returned on any failure. * ****************************************************************************/ -int arm64_gicv_irq_trigger(int irq, bool edge) +int up_set_irq_type(int irq, int mode) { uintptr_t regaddr; uint32_t regval; uint32_t intcfg; - if (irq > GIC_IRQ_SGI15 && irq < NR_IRQS) + if (!GIC_IS_SGI(irq)) { + if (mode == IRQ_HIGH_LEVEL || mode == IRQ_LOW_LEVEL) + { + intcfg = INT_ICDICFR_1N; + } + else + { + intcfg = INT_ICDICFR_EDGE | INT_ICDICFR_1N; + } + /* Get the address of the Interrupt Configuration Register for this * irq. */ regaddr = GIC_ICDICFR(irq); - /* Get the new Interrupt configuration bit setting */ - - intcfg = (edge ? (INT_ICDICFR_EDGE | INT_ICDICFR_1N) : INT_ICDICFR_1N); - /* Write the correct interrupt trigger to the Interrupt Configuration * Register. */ @@ -1368,56 +1373,6 @@ int arm64_gicv_irq_trigger(int irq, bool edge) return -EINVAL; } -/**************************************************************************** - * Name: arm64_gic_irq_set_priority - * - * Description: - * Set the interrupt priority and type. - * - * If CONFIG_SMP is not selected, the cpuset is ignored and SGI is sent - * only to the current CPU. - * - * Input Parameters - * intid - The SGI interrupt ID (0-15) - * prio - The interrupt priority - * flags - Bit IRQ_TYPE_EDGE is 1 if interrupt should be edge-triggered - * - * Returned Value: - * None - * - ****************************************************************************/ - -void arm64_gic_irq_set_priority(unsigned int intid, unsigned int prio, - uint32_t flags) -{ - int ret; - - /* Disable the interrupt */ - - up_disable_irq(intid); - - /* Set the interrupt priority */ - - ret = up_prioritize_irq(intid, prio); - DEBUGASSERT(ret == OK); - - /* Configure interrupt type */ - - if (!GIC_IS_SGI(intid)) - { - if (flags & IRQ_TYPE_EDGE) - { - ret = arm64_gicv_irq_trigger(intid, true); - DEBUGASSERT(ret == OK); - } - else - { - ret = arm64_gicv_irq_trigger(intid, false); - DEBUGASSERT(ret == OK); - } - } -} - /**************************************************************************** * Name: arm64_gic_initialize * diff --git a/arch/arm64/src/common/arm64_gicv2m.c b/arch/arm64/src/common/arm64_gicv2m.c index bb97882edb08e..f987a82460584 100644 --- a/arch/arm64/src/common/arm64_gicv2m.c +++ b/arch/arm64/src/common/arm64_gicv2m.c @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -132,7 +133,7 @@ int up_alloc_irq_msi(uint8_t busno, uint32_t devfn, int *pirq, int num) irq = g_v2m.spi_start + offset; for (i = 0; i < num; i++) { - arm64_gicv_irq_trigger(i + irq, true); + up_set_irq_type(i + irq, IRQ_RISING_EDGE); pirq[i] = irq + i; } diff --git a/arch/arm64/src/common/arm64_gicv3.c b/arch/arm64/src/common/arm64_gicv3.c index ad3bd40b74bdb..e776dd6e92ab4 100644 --- a/arch/arm64/src/common/arm64_gicv3.c +++ b/arch/arm64/src/common/arm64_gicv3.c @@ -156,53 +156,8 @@ static inline void arm64_gic_write_irouter(uint64_t val, unsigned int intid) putreg64(val, addr); } -void arm64_gic_irq_set_priority(unsigned int intid, unsigned int prio, - uint32_t flags) -{ - uint32_t mask = BIT(intid & (GIC_NUM_INTR_PER_REG - 1)); - uint32_t idx = intid / GIC_NUM_INTR_PER_REG; - uint32_t shift; - uint32_t val; - unsigned long base = GET_DIST_BASE(intid); - irqstate_t irq_flags; - - /* Disable the interrupt */ - - putreg32(mask, ICENABLER(base, idx)); - gic_wait_rwp(intid); - - /* PRIORITYR registers provide byte access */ - - putreg8(prio & GIC_PRI_MASK, IPRIORITYR(base, intid)); - - /* Interrupt type config */ - - if (!GIC_IS_SGI(intid)) - { - idx = intid / GIC_NUM_CFG_PER_REG; - shift = (intid & (GIC_NUM_CFG_PER_REG - 1)) * 2; - - /* GICD_ICFGR requires full 32-bit RMW operations. - * Each interrupt uses 2 bits; thus updates must be synchronized - * to avoid losing configuration in concurrent environments. - */ - - irq_flags = spin_lock_irqsave(&g_gic_lock); - - val = getreg32(ICFGR(base, idx)); - val &= ~(GICD_ICFGR_MASK << shift); - if (flags & IRQ_TYPE_EDGE) - { - val |= (GICD_ICFGR_TYPE << shift); - } - - putreg32(val, ICFGR(base, idx)); - spin_unlock_irqrestore(&g_gic_lock, irq_flags); - } -} - /*************************************************************************** - * Name: arm64_gic_irq_trigger + * Name: up_set_irq_type * * Description: * Set the trigger type for the specified IRQ source and the current CPU. @@ -211,27 +166,26 @@ void arm64_gic_irq_set_priority(unsigned int intid, unsigned int prio, * avoided in common implementations where possible. * * Input Parameters: - * irq - The interrupt request to modify. - * flags - irq type, IRQ_TYPE_EDGE or IRQ_TYPE_LEVEL - * Default is IRQ_TYPE_LEVEL + * irq - The interrupt request to modify. + * mode - Level sensitive or edge sensitive * * Returned Value: * Zero (OK) on success; a negated errno value is returned on any failure. * ***************************************************************************/ -int arm64_gic_irq_trigger(unsigned int intid, uint32_t flags) +int up_set_irq_type(int irq, int mode) { - uint32_t idx = intid / GIC_NUM_INTR_PER_REG; + uint32_t idx = irq / GIC_NUM_INTR_PER_REG; uint32_t shift; uint32_t val; - unsigned long base = GET_DIST_BASE(intid); + unsigned long base = GET_DIST_BASE(irq); irqstate_t irq_flags; - if (!GIC_IS_SGI(intid)) + if (!GIC_IS_SGI(irq)) { - idx = intid / GIC_NUM_CFG_PER_REG; - shift = (intid & (GIC_NUM_CFG_PER_REG - 1)) * 2; + idx = irq / GIC_NUM_CFG_PER_REG; + shift = (irq & (GIC_NUM_CFG_PER_REG - 1)) * 2; /* GICD_ICFGR requires full 32-bit RMW operations. * Each interrupt uses 2 bits; thus updates must be synchronized @@ -242,7 +196,7 @@ int arm64_gic_irq_trigger(unsigned int intid, uint32_t flags) val = getreg32(ICFGR(base, idx)); val &= ~(GICD_ICFGR_MASK << shift); - if (flags & IRQ_TYPE_EDGE) + if (mode != IRQ_HIGH_LEVEL && mode != IRQ_LOW_LEVEL) { val |= (GICD_ICFGR_TYPE << shift); } diff --git a/arch/arm64/src/common/arm64_initialstate.c b/arch/arm64/src/common/arm64_initialstate.c index ff2d9c5cffc48..a70d5cf5bd0e5 100644 --- a/arch/arm64/src/common/arm64_initialstate.c +++ b/arch/arm64/src/common/arm64_initialstate.c @@ -91,6 +91,10 @@ void arm64_new_task(struct tcb_s * tcb) xcp->regs[REG_SCTLR_EL1] |= SCTLR_TCF1_BIT; #endif +#ifndef CONFIG_ARM64_DECODEFIQ + xcp->regs[REG_SPSR] |= DAIF_FIQ_BIT; +#endif + #ifdef CONFIG_SUPPRESS_INTERRUPTS xcp->regs[REG_SPSR] |= (DAIF_IRQ_BIT | DAIF_FIQ_BIT); #endif /* CONFIG_SUPPRESS_INTERRUPTS */ diff --git a/arch/arm64/src/common/arm64_mpu.c b/arch/arm64/src/common/arm64_mpu.c index 098c9a2b15da2..41f3c081a6446 100644 --- a/arch/arm64/src/common/arm64_mpu.c +++ b/arch/arm64/src/common/arm64_mpu.c @@ -73,7 +73,7 @@ * regions. */ -static unsigned int g_mpu_region; +static unsigned int g_mpu_region[CONFIG_SMP_NCPUS]; /**************************************************************************** * Private Functions @@ -153,12 +153,12 @@ static void mpu_init(void) unsigned int mpu_allocregion(void) { unsigned int num_regions = get_num_regions(); - unsigned int i = ffs(~g_mpu_region) - 1; + unsigned int i = ffs(~g_mpu_region[this_cpu()]) - 1; /* There are not enough regions to apply */ DEBUGASSERT(i < num_regions); - g_mpu_region |= 1 << i; + g_mpu_region[this_cpu()] |= 1 << i; return i; } @@ -191,7 +191,7 @@ void mpu_freeregion(unsigned int region) write_sysreg(0, prbar_el1); write_sysreg(0, prlar_el1); - g_mpu_region &= ~(1 << region); + g_mpu_region[this_cpu()] &= ~(1 << region); UP_MB(); } @@ -275,7 +275,7 @@ void mpu_modify_region(unsigned int region, /* Check that the region is valid */ - DEBUGASSERT(g_mpu_region & (1 << region)); + DEBUGASSERT(g_mpu_region[this_cpu()] & (1 << region)); rbar |= table->attr.rbar & (MPU_RBAR_XN_MSK | MPU_RBAR_AP_MSK | MPU_RBAR_SH_MSK); diff --git a/arch/arm64/src/common/arm64_syscall.c b/arch/arm64/src/common/arm64_syscall.c index 166dc8963d051..6e837df1c23e3 100644 --- a/arch/arm64/src/common/arm64_syscall.c +++ b/arch/arm64/src/common/arm64_syscall.c @@ -164,6 +164,10 @@ uint64_t *arm64_syscall(uint64_t *regs) uint64_t spsr; #endif + /* Set irq flag */ + + write_sysreg((uintptr_t)tcb | 1, tpidr_el1); + /* Nested interrupts are not supported */ DEBUGASSERT(regs); @@ -314,6 +318,10 @@ uint64_t *arm64_syscall(uint64_t *regs) default: { svcerr("ERROR: Bad SYS call: 0x%" PRIx64 "\n", cmd); + + /* Clear irq flag */ + + write_sysreg((uintptr_t)tcb & ~1ul, tpidr_el1); return 0; } break; @@ -326,5 +334,9 @@ uint64_t *arm64_syscall(uint64_t *regs) */ (*running_task)->xcp.regs = NULL; + + /* Clear irq flag */ + + write_sysreg((uintptr_t)tcb & ~1ul, tpidr_el1); return regs; } diff --git a/arch/arm64/src/imx9/ddr/imx9_ddr_training.c b/arch/arm64/src/imx9/ddr/imx9_ddr_training.c index ddd66646b8576..bc86f6fcf7384 100644 --- a/arch/arm64/src/imx9/ddr/imx9_ddr_training.c +++ b/arch/arm64/src/imx9/ddr/imx9_ddr_training.c @@ -58,7 +58,7 @@ /* DDR training binaries via incbin */ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 64 \n" " .globl g_dmem1d_begin \n" "g_dmem1d_begin: \n" diff --git a/arch/arm64/src/rk3399/rk3399_serial.c b/arch/arm64/src/rk3399/rk3399_serial.c index cb7c3968675cc..1ab9c3ed86a7b 100644 --- a/arch/arm64/src/rk3399/rk3399_serial.c +++ b/arch/arm64/src/rk3399/rk3399_serial.c @@ -641,7 +641,8 @@ static int a64_uart_attach(struct uart_dev_s *dev) /* Set Interrupt Priority in Generic Interrupt Controller v2 */ - arm64_gic_irq_set_priority(port->irq_num, 0, IRQ_TYPE_LEVEL); + up_prioritize_irq(port->irq_num, 0); + up_set_irq_type(port->irq_num, IRQ_RISING_EDGE); /* Enable UART Interrupt */ diff --git a/arch/arm64/src/zynq-mpsoc/zynq_serial.c b/arch/arm64/src/zynq-mpsoc/zynq_serial.c index 9285b952fe0c9..8b63a91c3f279 100644 --- a/arch/arm64/src/zynq-mpsoc/zynq_serial.c +++ b/arch/arm64/src/zynq-mpsoc/zynq_serial.c @@ -775,7 +775,8 @@ static int zynq_uart_attach(struct uart_dev_s *dev) /* Set Interrupt Priority in Generic Interrupt Controller v2 */ - arm64_gic_irq_set_priority(port->irq_num, 0, IRQ_TYPE_LEVEL); + up_prioritize_irq(port->irq_num, 0); + up_set_irq_type(port->irq_num, IRQ_HIGH_LEVEL); /* Enable UART Interrupt */ diff --git a/arch/avr/src/avrdx/avrdx_timerisr_tickless_alarm.c b/arch/avr/src/avrdx/avrdx_timerisr_tickless_alarm.c index 323bcd8e53cc2..0257da058b2f6 100644 --- a/arch/avr/src/avrdx/avrdx_timerisr_tickless_alarm.c +++ b/arch/avr/src/avrdx/avrdx_timerisr_tickless_alarm.c @@ -269,7 +269,7 @@ static void avrdx_check_alarm_expired(uint8_t context) * context. Remove non-interrupt flags from the context before * using it. * - * Deactivate alarm first. Call to nxsched_timer_expiration() + * Deactivate alarm first. Call to nxsched_process_timer() * in turns calls up_timer_gettick(), that one calls * up_timer_gettime() which calls this method through * avrdx_increment_uptime(), causing a recursion loop. @@ -283,7 +283,7 @@ static void avrdx_check_alarm_expired(uint8_t context) */ avrdx_deactivate_alarm(); - nxsched_timer_expiration(); + nxsched_process_timer(); } else { diff --git a/arch/risc-v/src/common/espressif/esp_tickless.c b/arch/risc-v/src/common/espressif/esp_tickless.c index 9d7b57224ebeb..f66688a19b395 100644 --- a/arch/risc-v/src/common/espressif/esp_tickless.c +++ b/arch/risc-v/src/common/espressif/esp_tickless.c @@ -97,7 +97,7 @@ static int esp_tickless_isr(int irq, void *context, void *arg) systimer_ll_clear_alarm_int(systimer_hal.dev, SYSTIMER_ALARM_OS_TICK_CORE0); - nxsched_timer_expiration(); + nxsched_process_timer(); return OK; } @@ -235,7 +235,7 @@ int IRAM_ATTR up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -325,14 +325,14 @@ int IRAM_ATTR up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/risc-v/src/esp32c3-legacy/esp32c3_tickless.c b/arch/risc-v/src/esp32c3-legacy/esp32c3_tickless.c index 4176ccee90941..d16ea6308fee1 100644 --- a/arch/risc-v/src/esp32c3-legacy/esp32c3_tickless.c +++ b/arch/risc-v/src/esp32c3-legacy/esp32c3_tickless.c @@ -281,7 +281,7 @@ static void IRAM_ATTR up_timer_expire(int irq, void *regs, void *arg) { g_timer_started = false; setbits(SYS_TIMER_TARGET0_INT_CLR, SYS_TIMER_SYSTIMER_INT_CLR_REG); - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -343,7 +343,7 @@ int IRAM_ATTR up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -420,14 +420,14 @@ int IRAM_ATTR up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/risc-v/src/litex/litex_tickless.c b/arch/risc-v/src/litex/litex_tickless.c index cb9efbaa21240..48b6c6228f780 100644 --- a/arch/risc-v/src/litex/litex_tickless.c +++ b/arch/risc-v/src/litex/litex_tickless.c @@ -79,7 +79,7 @@ static int up_timer_expire(int irq, void *regs, void *arg) { g_timer_started = false; putreg32(1 << LITEX_TIMER0_TIMEOUT_EV_OFFSET, LITEX_TIMER0_EV_PENDING); - nxsched_timer_expiration(); + nxsched_process_timer(); return OK; } @@ -211,7 +211,7 @@ int up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -272,14 +272,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/sim/Kconfig b/arch/sim/Kconfig index 944a12c6c7e4c..c545404454a86 100644 --- a/arch/sim/Kconfig +++ b/arch/sim/Kconfig @@ -284,16 +284,38 @@ config SIM_NETDEV_NUMBER Note that only one network device will be brought up by netinit automatically, others will be kept in DOWN state by default. +if SIM_NETDEV && DRIVERS_IEEE80211 && NETDEV_WIRELESS_HANDLER + config SIM_WIFIDEV_NUMBER int "Number of Simulated WiFi Device" default 0 range 0 SIM_NETDEV_NUMBER - depends on SIM_NETDEV && DRIVERS_IEEE80211 && NETDEV_WIRELESS_HANDLER ---help--- The number of simulated wifi network devices. Note that only one network device will be brought up by netinit automatically, others will be kept in DOWN state by default. + +choice + prompt "Select SimWiFi Platform" + depends on SIM_WIFIDEV_NUMBER != 0 + default SIM_WIFIDEV_HOST + +config SIM_WIFIDEV_HOST + bool "Use the host Wi-Fi interfaces" + ---help--- + Use the host Wi-Fi interfaces, which are either simulated by + hwsim or the real wireless network cards. + +config SIM_WIFIDEV_PSEUDO + bool "Use the Simulated Wi-Fi devices" + depends on DRIVERS_WIFI_SIM + ---help--- + Use the the Simulated Wi-Fi devices, which are supported by the bss file. +endchoice + +endif + endif config SIM_NETDEV_VPNKIT_PATH diff --git a/arch/sim/include/setjmp.h b/arch/sim/include/setjmp.h index 042eeed980fdf..3c252575fe8b0 100644 --- a/arch/sim/include/setjmp.h +++ b/arch/sim/include/setjmp.h @@ -40,7 +40,7 @@ #if defined(CONFIG_HOST_X86_64) && !defined(CONFIG_SIM_M32) /* Storage order: %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15, %rip */ -# define XCPTCONTEXT_REGS 9 +# define XCPTCONTEXT_REGS 11 # define XCPTCONTEXT_SIZE (8 * XCPTCONTEXT_REGS) # ifdef __ASSEMBLY__ @@ -54,6 +54,8 @@ # define JB_R15 (6*8) # define JB_RIP (7*8) # define JB_FLAG (8*8) +# define JB_ERRNO (9*8) +# define JB_ALIGN0 (10*8) # else @@ -66,6 +68,8 @@ # define JB_R15 (6) # define JB_RIP (7) # define JB_FLAG (8) +# define JB_ERRNO (9) +# define JB_ALIGN0 (10) # endif /* __ASSEMBLY__ */ @@ -78,7 +82,7 @@ #elif defined(CONFIG_HOST_X86) || defined(CONFIG_SIM_M32) /* Storage order: %ebx, %esi, %edi, %ebp, sp, and return PC */ -# define XCPTCONTEXT_REGS (8) +# define XCPTCONTEXT_REGS (9) # define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) # ifdef __ASSEMBLY__ @@ -91,6 +95,7 @@ # define JB_EIP (5*4) # define JB_FLAG (6*4) # define JB_FLAG1 (7*4) +# define JB_ERRNO (8*4) # else @@ -102,6 +107,7 @@ # define JB_EIP (5) # define JB_FLAG (6) # define JB_FLAG1 (7) +# define JB_ERRNO (8) # endif /* __ASSEMBLY__ */ @@ -113,7 +119,7 @@ #elif defined(CONFIG_HOST_ARM) -# define XCPTCONTEXT_REGS 18 +# define XCPTCONTEXT_REGS 19 # define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) # define JB_FP 7 @@ -121,10 +127,11 @@ # define JB_PC 9 # define JB_FLAG 16 # define JB_FLAG1 17 +# define JB_ERRNO 18 #elif defined(CONFIG_HOST_ARM64) -# define XCPTCONTEXT_REGS 33 +# define XCPTCONTEXT_REGS 34 # define XCPTCONTEXT_SIZE (8 * XCPTCONTEXT_REGS) # ifdef __ASSEMBLY__ @@ -148,6 +155,7 @@ # define JB_FP (12) # define JB_SP (13) # define JB_FLAG (32) +# define JB_ERRNO (33) # endif /* __ASSEMBLY__ */ diff --git a/arch/sim/src/Makefile b/arch/sim/src/Makefile index 542a0567470fd..9c4b42e8e762e 100644 --- a/arch/sim/src/Makefile +++ b/arch/sim/src/Makefile @@ -118,7 +118,7 @@ ifeq ($(CONFIG_FS_LARGEFILE),y) endif HOSTSRCS = sim_hostirq.c sim_hostmemory.c sim_hostmisc.c sim_hosttime.c sim_hostuart.c -HOSTSRCS += sim_hostfs.c +HOSTSRCS += sim_hostfs.c sim_errno.c hostfs.h: $(TOPDIR)/include/nuttx/fs/hostfs.h @echo "CP: $<" @@ -209,8 +209,9 @@ ifeq ($(CONFIG_FS_FAT),y) STDLIBS += -lz endif -ifneq ($(CONFIG_SIM_WIFIDEV_NUMBER),0) +ifeq ($(CONFIG_SIM_WIFIDEV_HOST),y) CFLAGS += -DTOPDIR=\"$(TOPDIR)\" + CSRCS += sim_wifihost.c endif ifeq ($(CONFIG_SIM_NETDEV_TAP),y) diff --git a/arch/sim/src/cmake/Toolchain.cmake b/arch/sim/src/cmake/Toolchain.cmake index fa1be1575b1f6..b5d87923a8c6d 100644 --- a/arch/sim/src/cmake/Toolchain.cmake +++ b/arch/sim/src/cmake/Toolchain.cmake @@ -220,6 +220,10 @@ if(CONFIG_LIBCXX) add_compile_options($<$:-D_LIBCPP_DISABLE_AVAILABILITY>) endif() +if(CONFIG_LIBCXX_TEST) + add_link_options(-Wl,-latomic) +endif() + if(APPLE) add_link_options(-Wl,-dead_strip) else() diff --git a/arch/sim/src/sim/CMakeLists.txt b/arch/sim/src/sim/CMakeLists.txt index 3b3da83e189b8..875040d5ef0aa 100644 --- a/arch/sim/src/sim/CMakeLists.txt +++ b/arch/sim/src/sim/CMakeLists.txt @@ -213,6 +213,11 @@ if(CONFIG_SIM_X11FB) endif() endif() +if(NOT ${CONFIG_SIM_WIFIDEV_NUMBER} EQUAL 0) + add_compile_options(-DTOPDIR=$(TOPDIR)) + list(APPEND SRCS sim_wifihost.c) +endif() + if(CONFIG_SIM_NETDEV_TAP) list(APPEND SRCS sim_netdriver.c) @@ -284,6 +289,8 @@ endif() list(APPEND HOSTSRCS sim_hostfs.c) list(APPEND HOST_DEFINITIONS CONFIG_NAME_MAX=${CONFIG_NAME_MAX}) +list(APPEND HOSTSRCS sim_errno.c) + configure_file(${NUTTX_DIR}/include/nuttx/fs/hostfs.h ${CMAKE_CURRENT_BINARY_DIR}/hostfs.h COPYONLY) configure_file(${CMAKE_BINARY_DIR}/include/nuttx/config.h diff --git a/arch/sim/src/sim/posix/sim_alsa.c b/arch/sim/src/sim/posix/sim_alsa.c index 064dc2480fb9d..5c8e566148d17 100644 --- a/arch/sim/src/sim/posix/sim_alsa.c +++ b/arch/sim/src/sim/posix/sim_alsa.c @@ -29,8 +29,7 @@ #include #include #include -#include - +#include #include #include @@ -53,10 +52,9 @@ struct sim_audio_s { struct audio_lowerhalf_s dev; struct dq_queue_s pendq; + struct work_s work; mutex_t pendlock; - struct wdog_s wdog; /* Watchdog for event loop */ - bool playback; bool offload; bool paused; @@ -1134,13 +1132,14 @@ static int sim_mixer_open(struct sim_audio_s *priv) return 0; } -static void sim_alsa_interrupt(wdparm_t arg) +static void sim_audio_work(FAR void *arg) { struct sim_audio_s *priv = (struct sim_audio_s *)arg; sim_audio_process(priv); - wd_start_next(&priv->wdog, SIM_AUDIO_PERIOD, sim_alsa_interrupt, arg); + work_queue_next_wq(g_work_queue, &priv->work, sim_audio_work, priv, + SIM_AUDIO_PERIOD); } /**************************************************************************** @@ -1169,7 +1168,9 @@ struct audio_lowerhalf_s *sim_audio_initialize(bool playback, bool offload) return NULL; } - wd_start(&priv->wdog, 0, sim_alsa_interrupt, (wdparm_t)priv); + memset(&priv->work, 0, sizeof(struct work_s)); + work_queue_wq(g_work_queue, &priv->work, sim_audio_work, priv, + SIM_AUDIO_PERIOD); /* Setting default config */ @@ -1181,6 +1182,5 @@ struct audio_lowerhalf_s *sim_audio_initialize(bool playback, bool offload) priv->channels = 2; priv->bps = 16; priv->frame_size = 4; - return &priv->dev; } diff --git a/arch/sim/src/sim/posix/sim_errno.c b/arch/sim/src/sim/posix/sim_errno.c new file mode 100644 index 0000000000000..77066082a1721 --- /dev/null +++ b/arch/sim/src/sim/posix/sim_errno.c @@ -0,0 +1,46 @@ +/**************************************************************************** + * arch/sim/src/sim/posix/sim_errno.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int host_errno_convert(int errcode) +{ + return errcode; +} + +int host_errno_get(void) +{ + return errno; +} + +void host_errno_set(int errcode) +{ + errno = errcode; +} diff --git a/arch/sim/src/sim/posix/sim_hostfs.c b/arch/sim/src/sim/posix/sim_hostfs.c index a22d7118d3272..8597b036f1ca1 100644 --- a/arch/sim/src/sim/posix/sim_hostfs.c +++ b/arch/sim/src/sim/posix/sim_hostfs.c @@ -194,7 +194,13 @@ int host_open(const char *pathname, int flags, int mode) mapflags |= O_DIRECTORY; } - return host_uninterruptible_errno(open, pathname, mapflags, mode); + int ret = open(pathname, mapflags, mode); + if (ret == -1) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -205,7 +211,13 @@ int host_close(int fd) { /* Just call the close routine */ - return host_uninterruptible_errno(close, fd); + int ret = close(fd); + if (ret == -1) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -216,7 +228,13 @@ nuttx_ssize_t host_read(int fd, void *buf, nuttx_size_t count) { /* Just call the read routine */ - return host_uninterruptible_errno(read, fd, buf, count); + nuttx_ssize_t ret = read(fd, buf, count); + if (ret == -1) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -227,7 +245,13 @@ nuttx_ssize_t host_write(int fd, const void *buf, nuttx_size_t count) { /* Just call the write routine */ - return host_uninterruptible_errno(write, fd, buf, count); + nuttx_ssize_t ret = write(fd, buf, count); + if (ret == -1) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -239,7 +263,13 @@ nuttx_off_t host_lseek(int fd, nuttx_off_t pos, nuttx_off_t offset, { /* Just call the lseek routine */ - return host_uninterruptible_errno(lseek, fd, offset, whence); + nuttx_off_t ret = lseek(fd, offset, whence); + if (ret == (nuttx_off_t)-1) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -250,7 +280,13 @@ int host_ioctl(int fd, int request, unsigned long arg) { /* Just call the ioctl routine */ - return host_uninterruptible_errno(ioctl, fd, request, arg); + int ret = ioctl(fd, request, arg); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -270,7 +306,13 @@ void host_sync(int fd) int host_dup(int fd) { - return host_uninterruptible_errno(dup, fd); + int ret = dup(fd); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -284,7 +326,11 @@ int host_fstat(int fd, struct nuttx_stat_s *buf) /* Call the host's stat routine */ - ret = host_uninterruptible_errno(fstat, fd, &hostbuf); + ret = fstat(fd, &hostbuf); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } /* Map the return values */ @@ -303,19 +349,19 @@ int host_fchstat(int fd, const struct nuttx_stat_s *buf, int flags) if (flags & NUTTX_CH_STAT_MODE) { - ret = host_uninterruptible_errno(fchmod, fd, buf->st_mode); + ret = fchmod(fd, buf->st_mode); if (ret < 0) { - return ret; + return host_errno_convert(-errno); } } if (flags & (NUTTX_CH_STAT_UID | NUTTX_CH_STAT_GID)) { - ret = host_uninterruptible_errno(fchown, fd, buf->st_uid, buf->st_gid); + ret = fchown(fd, buf->st_uid, buf->st_gid); if (ret < 0) { - return ret; + return host_errno_convert(-errno); } } @@ -343,10 +389,10 @@ int host_fchstat(int fd, const struct nuttx_stat_s *buf, int flags) times[1].tv_nsec = UTIME_OMIT; } - ret = host_uninterruptible_errno(futimens, fd, times); + ret = futimens(fd, times); if (ret < 0) { - return ret; + return host_errno_convert(-errno); } } @@ -359,7 +405,13 @@ int host_fchstat(int fd, const struct nuttx_stat_s *buf, int flags) int host_ftruncate(int fd, nuttx_off_t length) { - return host_uninterruptible_errno(ftruncate, fd, length); + int ret = ftruncate(fd, length); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -449,7 +501,13 @@ void host_rewinddir(void *dirp) int host_closedir(void *dirp) { - return host_uninterruptible_errno(closedir, dirp); + int ret = closedir(dirp); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -463,7 +521,11 @@ int host_statfs(const char *path, struct nuttx_statfs_s *buf) /* Call the host's statfs routine */ - ret = host_uninterruptible_errno(statvfs, path, &hostbuf); + ret = statvfs(path, &hostbuf); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } /* Map the struct statfs value */ @@ -485,7 +547,13 @@ int host_statfs(const char *path, struct nuttx_statfs_s *buf) int host_unlink(const char *pathname) { - return host_uninterruptible_errno(unlink, pathname); + int ret = unlink(pathname); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -496,7 +564,13 @@ int host_mkdir(const char *pathname, int mode) { /* Just call the host's mkdir routine */ - return host_uninterruptible_errno(mkdir, pathname, mode); + int ret = mkdir(pathname, mode); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -505,7 +579,13 @@ int host_mkdir(const char *pathname, int mode) int host_rmdir(const char *pathname) { - return host_uninterruptible_errno(rmdir, pathname); + int ret = rmdir(pathname); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -514,7 +594,13 @@ int host_rmdir(const char *pathname) int host_rename(const char *oldpath, const char *newpath) { - return host_uninterruptible_errno(rename, oldpath, newpath); + int ret = rename(oldpath, newpath); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -528,7 +614,11 @@ int host_stat(const char *path, struct nuttx_stat_s *buf) /* Call the host's stat routine */ - ret = host_uninterruptible_errno(stat, path, &hostbuf); + ret = stat(path, &hostbuf); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } /* Map the return values */ @@ -547,20 +637,19 @@ int host_chstat(const char *path, const struct nuttx_stat_s *buf, int flags) if (flags & NUTTX_CH_STAT_MODE) { - ret = host_uninterruptible_errno(chmod, path, buf->st_mode); + ret = chmod(path, buf->st_mode); if (ret < 0) { - return ret; + return host_errno_convert(-errno); } } if (flags & (NUTTX_CH_STAT_UID | NUTTX_CH_STAT_GID)) { - ret = host_uninterruptible_errno(chown, path, - buf->st_uid, buf->st_gid); + ret = chown(path, buf->st_uid, buf->st_gid); if (ret < 0) { - return ret; + return host_errno_convert(-errno); } } @@ -588,10 +677,10 @@ int host_chstat(const char *path, const struct nuttx_stat_s *buf, int flags) times[1].tv_nsec = UTIME_OMIT; } - ret = host_uninterruptible_errno(utimensat, AT_FDCWD, path, times, 0); + ret = utimensat(AT_FDCWD, path, times, 0); if (ret < 0) { - return ret; + return host_errno_convert(-errno); } } diff --git a/arch/sim/src/sim/posix/sim_hostirq.c b/arch/sim/src/sim/posix/sim_hostirq.c index 06c2f70d81a9c..6a678589be8ad 100644 --- a/arch/sim/src/sim/posix/sim_hostirq.c +++ b/arch/sim/src/sim/posix/sim_hostirq.c @@ -134,20 +134,6 @@ void up_irq_enable(void) up_irq_restore(0); } -/**************************************************************************** - * Name: up_irqinitialize - ****************************************************************************/ - -void up_irqinitialize(void) -{ -#ifdef CONFIG_SMP - /* Register the pause handler */ - - sim_init_ipi(SIGUSR1); - sim_init_func_call_ipi(SIGUSR2); -#endif -} - /**************************************************************************** * Name: up_enable_irq * @@ -192,3 +178,17 @@ void up_disable_irq(int irq) signal(irq, SIG_IGN); } + +/**************************************************************************** + * Name: host_irqinitialize + ****************************************************************************/ + +void host_irqinitialize(void) +{ +#ifdef CONFIG_SMP + /* Register the pause handler */ + + sim_init_ipi(SIGUSR1); + sim_init_func_call_ipi(SIGUSR2); +#endif +} diff --git a/arch/sim/src/sim/posix/sim_hostmisc.c b/arch/sim/src/sim/posix/sim_hostmisc.c index 6015af0701eed..d759f1f57ccb3 100644 --- a/arch/sim/src/sim/posix/sim_hostmisc.c +++ b/arch/sim/src/sim/posix/sim_hostmisc.c @@ -128,38 +128,32 @@ int host_system(char *buf, size_t len, const char *fmt, ...) int ret; char cmd[512]; va_list vars; - uint64_t flags; va_start(vars, fmt); - ret = host_uninterruptible_errno(vsnprintf, cmd, sizeof(cmd), fmt, vars); + ret = vsnprintf(cmd, sizeof(cmd), fmt, vars); va_end(vars); if (ret <= 0 || ret > sizeof(cmd)) { - return ret < 0 ? ret : -EINVAL; + return ret < 0 ? -errno : -EINVAL; } if (buf == NULL) { - ret = host_uninterruptible_errno(system, cmd); + ret = host_uninterruptible(system, cmd); } else { - flags = up_irq_save(); fp = host_uninterruptible(popen, cmd, "r"); if (fp == NULL) { - ret = -errno; - up_irq_restore(flags); - return ret; + return -errno; } - up_irq_restore(flags); - - ret = host_uninterruptible_errno(fread, buf, 1, len, fp); + ret = host_uninterruptible(fread, buf, 1, len, fp); host_uninterruptible(pclose, fp); } - return ret; + return ret < 0 ? -errno : ret; } /**************************************************************************** @@ -229,6 +223,6 @@ int host_waitpid(pid_t pid) { int status; - pid = host_uninterruptible_errno(waitpid, pid, &status, 0); - return pid < 0 ? pid : status; + pid = host_uninterruptible(waitpid, pid, &status, 0); + return pid < 0 ? -errno : status; } diff --git a/arch/sim/src/sim/posix/sim_hostuart.c b/arch/sim/src/sim/posix/sim_hostuart.c index 12f1965895e4a..facc21e467e0e 100644 --- a/arch/sim/src/sim/posix/sim_hostuart.c +++ b/arch/sim/src/sim/posix/sim_hostuart.c @@ -96,15 +96,15 @@ void host_uart_start(void) { /* Get the current stdin terminal mode */ - host_uninterruptible_no_return(tcgetattr, 0, &g_cooked); + tcgetattr(0, &g_cooked); /* Put stdin into raw mode */ - host_uninterruptible_no_return(setrawmode, 0); + setrawmode(0); /* Restore the original terminal mode before exit */ - host_uninterruptible_no_return(atexit, restoremode); + atexit(restoremode); } /**************************************************************************** @@ -115,12 +115,16 @@ int host_uart_open(const char *pathname) { int fd; - fd = host_uninterruptible_errno(open, pathname, O_RDWR | O_NONBLOCK); + fd = open(pathname, O_RDWR | O_NONBLOCK); if (fd >= 0) { /* keep raw mode */ - host_uninterruptible_no_return(setrawmode, fd); + setrawmode(fd); + } + else + { + fd = -errno; } return fd; @@ -132,7 +136,7 @@ int host_uart_open(const char *pathname) void host_uart_close(int fd) { - host_uninterruptible(close, fd); + close(fd); } /**************************************************************************** @@ -145,11 +149,11 @@ int host_uart_puts(int fd, const char *buf, size_t size) do { - ret = host_uninterruptible_errno(write, fd, buf, size); + ret = write(fd, buf, size); } - while (ret < 0 && ret == -EINTR); + while (ret < 0 && errno == EINTR); - return ret; + return ret < 0 ? -errno : ret; } /**************************************************************************** @@ -162,11 +166,11 @@ int host_uart_gets(int fd, char *buf, size_t size) do { - ret = host_uninterruptible_errno(read, fd, buf, size); + ret = read(fd, buf, size); } - while (ret < 0 && ret == -EINTR); + while (ret < 0 && errno == EINTR); - return ret; + return ret < 0 ? -errno : ret; } /**************************************************************************** @@ -178,8 +182,12 @@ int host_uart_getcflag(int fd, unsigned int *cflag) struct termios t; int ret; - ret = host_uninterruptible_errno(tcgetattr, fd, &t); - if (ret >= 0) + ret = tcgetattr(fd, &t); + if (ret < 0) + { + ret = -errno; + } + else { *cflag = t.c_cflag; } @@ -196,11 +204,16 @@ int host_uart_setcflag(int fd, unsigned int cflag) struct termios t; int ret; - ret = host_uninterruptible_errno(tcgetattr, fd, &t); + ret = tcgetattr(fd, &t); if (!ret) { t.c_cflag = cflag; - ret = host_uninterruptible_errno(tcsetattr, fd, TCSANOW, &t); + ret = tcsetattr(fd, TCSANOW, &t); + } + + if (ret < 0) + { + ret = -errno; } return ret; @@ -216,7 +229,7 @@ bool host_uart_checkin(int fd) pfd.fd = fd; pfd.events = POLLIN; - return host_uninterruptible(poll, &pfd, 1, 0) == 1; + return poll(&pfd, 1, 0) == 1; } /**************************************************************************** @@ -229,7 +242,7 @@ bool host_uart_checkout(int fd) pfd.fd = fd; pfd.events = POLLOUT; - return host_uninterruptible(poll, &pfd, 1, 0) == 1; + return poll(&pfd, 1, 0) == 1; } /**************************************************************************** diff --git a/arch/sim/src/sim/posix/sim_hostusrsock.c b/arch/sim/src/sim/posix/sim_hostusrsock.c index 6c5f8a897acee..4ba0fb0dafa54 100644 --- a/arch/sim/src/sim/posix/sim_hostusrsock.c +++ b/arch/sim/src/sim/posix/sim_hostusrsock.c @@ -188,7 +188,7 @@ static int optname_to_native(int optname) default: syslog(LOG_ERR, "Invalid optname: %x\n", optname); - return -1; + return -ENOPROTOOPT; } } @@ -198,6 +198,10 @@ static int host_usrsock_sockopt(int sockfd, int level, int optname, { int ret = -EINVAL; + /* For the parameters that nuttx does not support, + * return the ENOPROTOOPT. + */ + if (level == NUTTX_SOL_SOCKET) { level = SOL_SOCKET; @@ -216,13 +220,13 @@ static int host_usrsock_sockopt(int sockfd, int level, int optname, } else { - return ret; + return -ENOPROTOOPT; } optname = optname_to_native(optname); if (optname < 0) { - return ret; + return optname; } if (set) @@ -263,6 +267,10 @@ int host_usrsock_socket(int domain, int type, int protocol) { type = SOCK_DGRAM; } + else if (type == NUTTX_SOCK_RAW) + { + type = SOCK_RAW; + } else { return -EINVAL; diff --git a/arch/sim/src/sim/posix/sim_rawgadget.c b/arch/sim/src/sim/posix/sim_rawgadget.c index e9bf63f17f431..b0164e9cf6ab8 100644 --- a/arch/sim/src/sim/posix/sim_rawgadget.c +++ b/arch/sim/src/sim/posix/sim_rawgadget.c @@ -325,7 +325,7 @@ static void host_raw_init(int fd, enum usb_device_speed speed, static int host_raw_run(int fd) { - int rv = host_uninterruptible_errno(ioctl, fd, USB_RAW_IOCTL_RUN, 0); + int rv = host_uninterruptible(ioctl, fd, USB_RAW_IOCTL_RUN, 0); if (rv < 0) { ERROR("ioctl(USB_RAW_IOCTL_RUN) fail"); diff --git a/arch/sim/src/sim/sim_initialize.c b/arch/sim/src/sim/sim_initialize.c index f736c8415ff34..45584ed8ed339 100644 --- a/arch/sim/src/sim/sim_initialize.c +++ b/arch/sim/src/sim/sim_initialize.c @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -51,13 +52,19 @@ #if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) || \ defined(CONFIG_SIM_BUTTONS) -static struct wdog_s g_x11event_wdog; /* Watchdog for event loop */ +static struct work_s g_x11event_work; /* Watchdog for event loop */ #endif #ifdef CONFIG_SIM_X11FB -static struct wdog_s g_x11update_wdog; /* Watchdog for update loop */ +static struct work_s g_x11update_work; /* Watchdog for update loop */ #endif +/**************************************************************************** + * Public Data + ****************************************************************************/ + +struct kwork_wqueue_s *g_work_queue; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -88,11 +95,11 @@ static void sim_init_cmdline(void) #if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) || \ defined(CONFIG_SIM_BUTTONS) -static void sim_x11event_interrupt(wdparm_t arg) +static void sim_x11event_work(void *arg) { sim_x11events(); - wd_start_next((FAR struct wdog_s *)arg, SIM_X11EVENT_PERIOD, - sim_x11event_interrupt, arg); + work_queue_next_wq(g_work_queue, &g_x11event_work, sim_x11event_work, + NULL, SIM_X11EVENT_PERIOD); } #endif @@ -105,11 +112,11 @@ static void sim_x11event_interrupt(wdparm_t arg) ****************************************************************************/ #ifdef CONFIG_SIM_X11FB -static void sim_x11update_interrupt(wdparm_t arg) +static void sim_x11update_work(void *arg) { sim_x11loop(); - wd_start_next((FAR struct wdog_s *)arg, SIM_X11UPDATE_PERIOD, - sim_x11update_interrupt, arg); + work_queue_next_wq(g_work_queue, &g_x11update_work, sim_x11update_work, + NULL, SIM_X11UPDATE_PERIOD); } #endif @@ -317,12 +324,31 @@ void up_initialize(void) #if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) || \ defined(CONFIG_SIM_BUTTONS) - wd_start(&g_x11event_wdog, 0, sim_x11event_interrupt, - (wdparm_t)&g_x11event_wdog); + work_queue_wq(g_work_queue, &g_x11event_work, sim_x11event_work, + NULL, SIM_X11EVENT_PERIOD); #endif #ifdef CONFIG_SIM_X11FB - wd_start(&g_x11update_wdog, 0, sim_x11update_interrupt, - (wdparm_t)&g_x11update_wdog); + work_queue_wq(g_work_queue, &g_x11update_work, sim_x11update_work, + NULL, SIM_X11UPDATE_PERIOD); #endif } + +/**************************************************************************** + * Name: up_irqinitialize + * + * Description: + * initialize the high-priority work queue used for handling + * periodic or async tasks within the simulator, then invokes the + * platform-specific IRQ initialize. + * + ****************************************************************************/ + +void up_irqinitialize(void) +{ + g_work_queue = work_queue_create("sim_loop_wq", + CONFIG_SCHED_HPWORKPRIORITY, NULL, + CONFIG_SCHED_HPWORKSTACKSIZE, 1u); + + host_irqinitialize(); +} diff --git a/arch/sim/src/sim/sim_internal.h b/arch/sim/src/sim/sim_internal.h index 68247ebb7da56..1db555c4140e6 100644 --- a/arch/sim/src/sim/sim_internal.h +++ b/arch/sim/src/sim/sim_internal.h @@ -107,12 +107,6 @@ #define sim_savestate(regs) sim_copyfullstate(regs, up_current_regs()) #define sim_restorestate(regs) up_set_current_regs(regs) -/* Provide a common interface, which should have different conversions - * on different platforms. - */ - -#define host_errno_convert(errcode) (errcode) - #define sim_saveusercontext(saveregs, ret) \ do \ { \ @@ -123,6 +117,7 @@ val[0] = flags & UINT32_MAX; \ val[1] = (flags >> 32) & UINT32_MAX; \ \ + env[JB_ERRNO] = host_errno_get(); \ ret = setjmp(saveregs); \ } \ while (0) @@ -134,6 +129,8 @@ uint32_t *flags = (uint32_t *)&env[JB_FLAG]; \ \ up_irq_restore(((uint64_t)flags[1] << 32) | flags[0]); \ + \ + host_errno_set(env[JB_ERRNO]); \ longjmp(env, 1); \ } \ while (0) @@ -155,18 +152,6 @@ } \ while (0) -#define host_uninterruptible_errno(func, ...) \ - ({ \ - uint64_t flags_ = up_irq_save(); \ - typeof(func(__VA_ARGS__)) ret_ = func(__VA_ARGS__); \ - if (ret_ < 0) \ - { \ - ret_ = host_errno_convert(-errno); \ - } \ - up_irq_restore(flags_); \ - ret_; \ - }) - /* File System Definitions **************************************************/ /* These definitions characterize the compressed filesystem image */ @@ -213,6 +198,7 @@ struct i2c_master_s; extern int g_argc; extern char **g_argv; +extern struct kwork_wqueue_s *g_work_queue; /**************************************************************************** * Public Function Prototypes @@ -227,6 +213,16 @@ void sim_copyfullstate(xcpt_reg_t *dest, xcpt_reg_t *src); void *sim_doirq(int irq, void *regs); void sim_unlock(void); +/* sim_errno.c */ + +int host_errno_convert(int errcode); +int host_errno_get(void); +void host_errno_set(int errcode); + +/* sim_hostirq.c ************************************************************/ + +void host_irqinitialize(void); + /* sim_hostmisc.c ***********************************************************/ void host_abort(int status); diff --git a/arch/sim/src/sim/sim_netdriver.c b/arch/sim/src/sim/sim_netdriver.c index 4dfef8da682e1..535b4e3c86db3 100644 --- a/arch/sim/src/sim/sim_netdriver.c +++ b/arch/sim/src/sim/sim_netdriver.c @@ -70,8 +70,10 @@ #include #include #include +#include #include "sim_internal.h" +#include "sim_wifihost.h" #define SIM_NETDEV_BUFSIZE (CONFIG_SIM_NETDEV_MTU + ETH_HDRLEN + \ CONFIG_NET_GUARDSIZE) @@ -90,20 +92,24 @@ #define DEVIDX(p) ((struct sim_netdev_s *)(p) - g_sim_dev) #define DEVBUF(p) (((struct sim_netdev_s *)(p))->buf) -#if CONFIG_SIM_WIFIDEV_NUMBER != 0 -# include "sim_wifidriver.c" -#else +#define IDXDEV(i) ((struct netdev_lowerhalf_s *)(&g_sim_dev[i].dev)) + /**************************************************************************** * Private Types ****************************************************************************/ struct sim_netdev_s { +#if defined(CONFIG_SIM_WIFIDEV_HOST) + struct sim_wifihost_lowerhalf_s dev; +#elif defined(CONFIG_SIM_WIFIDEV_PSEUDO) + struct wifi_sim_lowerhalf_s dev; +#else struct netdev_lowerhalf_s dev; +#endif uint8_t buf[SIM_NETDEV_BUFSIZE]; /* Used when packet buffer is fragmented */ - struct wdog_s wdog; + struct work_s work; }; -#endif /**************************************************************************** * Private Function Prototypes @@ -211,7 +217,11 @@ static int netdriver_ifup(struct netdev_lowerhalf_s *dev) #if CONFIG_SIM_WIFIDEV_NUMBER != 0 if (DEVIDX(dev) < CONFIG_SIM_WIFIDEV_NUMBER) { - if (wifidriver_connected(dev)) +# if defined(CONFIG_SIM_WIFIDEV_HOST) + if (sim_wifihost_connected((struct sim_wifihost_lowerhalf_s *)dev)) +# elif defined(CONFIG_SIM_WIFIDEV_PSEUDO) + if (wifi_sim_connected((struct wifi_sim_lowerhalf_s *)dev)) +# endif { netdev_lower_carrier_on(dev); } @@ -258,7 +268,7 @@ static void netdriver_rxready_interrupt(void *priv) netdev_lower_rxready(dev); } -static void sim_netdev_interrupt(wdparm_t arg) +static void sim_netdev_work(void *arg) { struct sim_netdev_s *priv = (struct sim_netdev_s *)arg; struct netdev_lowerhalf_s *dev = &priv->dev; @@ -268,8 +278,8 @@ static void sim_netdev_interrupt(wdparm_t arg) netdev_lower_rxready(dev); } - wd_start_next(&priv->wdog, SIM_NETDEV_PERIOD, - sim_netdev_interrupt, arg); + work_queue_next_wq(g_work_queue, &priv->work, sim_netdev_work, arg, + SIM_NETDEV_PERIOD); } /**************************************************************************** @@ -283,7 +293,7 @@ int sim_netdriver_init(void) for (devidx = 0; devidx < CONFIG_SIM_NETDEV_NUMBER; devidx++) { - dev = &g_sim_dev[devidx].dev; + dev = IDXDEV(devidx); /* Internal initialization */ @@ -300,7 +310,17 @@ int sim_netdriver_init(void) #if CONFIG_SIM_WIFIDEV_NUMBER != 0 if (devidx < CONFIG_SIM_WIFIDEV_NUMBER) { - wifidriver_init(dev, devidx); + int ret = +# if defined(CONFIG_SIM_WIFIDEV_HOST) + sim_wifihost_init((struct sim_wifihost_lowerhalf_s *)dev, + devidx); +# elif defined(CONFIG_SIM_WIFIDEV_PSEUDO) + wifi_sim_init((struct wifi_sim_lowerhalf_s *)dev); +# endif + if (ret < 0) + { + return ret; + } } #endif @@ -310,8 +330,9 @@ int sim_netdriver_init(void) netdev_lower_register(dev, devidx < CONFIG_SIM_WIFIDEV_NUMBER ? NET_LL_IEEE80211 : NET_LL_ETHERNET); - wd_start(&g_sim_dev[devidx].wdog, 0, - sim_netdev_interrupt, (wdparm_t)&g_sim_dev[devidx]); + work_queue_wq(g_work_queue, &g_sim_dev[devidx].work, + sim_netdev_work, &g_sim_dev[devidx], + SIM_NETDEV_PERIOD); } return OK; @@ -319,13 +340,24 @@ int sim_netdriver_init(void) void sim_netdriver_setmacaddr(int devidx, unsigned char *macaddr) { - memcpy(g_sim_dev[devidx].dev.netdev.d_mac.ether.ether_addr_octet, macaddr, + memcpy(IDXDEV(devidx)->netdev.d_mac.ether.ether_addr_octet, macaddr, IFHWADDRLEN); } void sim_netdriver_setmtu(int devidx, int mtu) { - g_sim_dev[devidx].dev.netdev.d_pktsize = MIN(SIM_NETDEV_BUFSIZE, + IDXDEV(devidx)->netdev.d_pktsize = MIN(SIM_NETDEV_BUFSIZE, mtu + ETH_HDRLEN); } +void sim_netdriver_loop(void) +{ + int devidx; + for (devidx = 0; devidx < CONFIG_SIM_NETDEV_NUMBER; devidx++) + { + if (sim_netdev_avail(devidx)) + { + netdev_lower_rxready(IDXDEV(devidx)); + } + } +} diff --git a/arch/sim/src/sim/sim_rpmsg_virtio.c b/arch/sim/src/sim/sim_rpmsg_virtio.c index fbedcf8bd57c1..e2f6bcfac9b43 100644 --- a/arch/sim/src/sim/sim_rpmsg_virtio.c +++ b/arch/sim/src/sim/sim_rpmsg_virtio.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include "sim_internal.h" @@ -67,9 +67,9 @@ struct sim_rpmsg_virtio_dev_s char cpuname[RPMSG_NAME_SIZE + 1]; char shmemname[RPMSG_NAME_SIZE + 1]; - /* Wdog for transmit */ + /* Work for transmit */ - struct wdog_s wdog; + struct work_s work; }; /**************************************************************************** @@ -164,7 +164,7 @@ sim_rpmsg_virtio_register_callback(struct rpmsg_virtio_lite_s *dev, return 0; } -static void sim_rpmsg_virtio_work(wdparm_t arg) +static void sim_rpmsg_virtio_work(void *arg) { struct sim_rpmsg_virtio_dev_s *dev = (struct sim_rpmsg_virtio_dev_s *)arg; @@ -189,8 +189,8 @@ static void sim_rpmsg_virtio_work(wdparm_t arg) } } - wd_start(&dev->wdog, SIM_RPMSG_VIRTIO_WORK_DELAY, - sim_rpmsg_virtio_work, (wdparm_t)dev); + work_queue_next_wq(g_work_queue, &dev->work, sim_rpmsg_virtio_work, dev, + SIM_RPMSG_VIRTIO_WORK_DELAY); } static int sim_rpmsg_virtio_notify(struct rpmsg_virtio_lite_s *dev, @@ -252,5 +252,6 @@ int sim_rpmsg_virtio_init(const char *shmemname, const char *cpuname, return ret; } - return wd_start(&priv->wdog, 0, sim_rpmsg_virtio_work, (wdparm_t)priv); + return work_queue_wq(g_work_queue, &priv->work, sim_rpmsg_virtio_work, + priv, 0); } diff --git a/arch/sim/src/sim/sim_rptun.c b/arch/sim/src/sim/sim_rptun.c index 5295cab5f5e5f..f8641146eab6d 100644 --- a/arch/sim/src/sim/sim_rptun.c +++ b/arch/sim/src/sim/sim_rptun.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include "sim_internal.h" @@ -74,9 +74,9 @@ struct sim_rptun_dev_s char shmemname[RPMSG_NAME_SIZE + 1]; pid_t pid; - /* Wdog for transmit */ + /* Work for transmit */ - struct wdog_s wdog; + struct work_s work; }; /**************************************************************************** @@ -327,7 +327,7 @@ static void sim_rptun_check_reset(struct sim_rptun_dev_s *priv) } } -static void sim_rptun_work(wdparm_t arg) +static void sim_rptun_work(void *arg) { struct sim_rptun_dev_s *dev = (struct sim_rptun_dev_s *)arg; @@ -358,7 +358,8 @@ static void sim_rptun_work(wdparm_t arg) } } - wd_start(&dev->wdog, SIM_RPTUN_WORK_DELAY, sim_rptun_work, (wdparm_t)dev); + work_queue_next_wq(g_work_queue, &dev->work, sim_rptun_work, dev, + SIM_RPTUN_WORK_DELAY); } /**************************************************************************** @@ -405,5 +406,5 @@ int sim_rptun_init(const char *shmemname, const char *cpuname, int master) return ret; } - return wd_start(&dev->wdog, 0, sim_rptun_work, (wdparm_t)dev); + return work_queue_wq(g_work_queue, &dev->work, sim_rptun_work, dev, 0); } diff --git a/arch/sim/src/sim/sim_usbdev.c b/arch/sim/src/sim/sim_usbdev.c index f3a48196323ac..19a4a5a0def77 100644 --- a/arch/sim/src/sim/sim_usbdev.c +++ b/arch/sim/src/sim/sim_usbdev.c @@ -38,7 +38,7 @@ #include #include -#include +#include #include #include #include @@ -159,7 +159,7 @@ struct sim_usbdev_s uint16_t epavail; /* Bitset of available endpoints */ struct sim_ep_s eps[SIM_USB_EPNUM]; spinlock_t lock; /* Spinlock */ - struct wdog_s wdog; /* Watchdog for event loop */ + struct work_s work; /* Work for event loop */ }; struct sim_req_s @@ -1045,7 +1045,7 @@ static void sim_usbdev_devinit(struct sim_usbdev_s *dev) dev->epavail = SIM_EPSET_NOEP0; } -static void sim_usbdev_interrupt(wdparm_t arg) +static void sim_usbdev_work(void *arg) { struct sim_usbdev_s *priv = (struct sim_usbdev_s *)arg; struct sim_ep_s *privep; @@ -1080,7 +1080,8 @@ static void sim_usbdev_interrupt(wdparm_t arg) } } - wd_start_next(&priv->wdog, SIM_USB_PERIOD, sim_usbdev_interrupt, arg); + work_queue_next_wq(g_work_queue, &priv->work, sim_usbdev_work, priv, + SIM_USB_PERIOD); } /**************************************************************************** @@ -1138,7 +1139,8 @@ int usbdev_register(struct usbdevclass_driver_s *driver) #endif } - wd_start(&priv->wdog, 0, sim_usbdev_interrupt, (wdparm_t)priv); + work_queue_wq(g_work_queue, &priv->work, sim_usbdev_work, priv, + SIM_USB_PERIOD); return ret; } diff --git a/arch/sim/src/sim/sim_usbhost.c b/arch/sim/src/sim/sim_usbhost.c index 4f3df26b19829..000d08b97553d 100644 --- a/arch/sim/src/sim/sim_usbhost.c +++ b/arch/sim/src/sim/sim_usbhost.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "sim_usbhost.h" #include "sim_internal.h" @@ -111,7 +112,7 @@ struct sim_usbhost_s sem_t pscsem; /* Semaphore to wait for port status change events */ struct usbhost_devaddr_s devgen; /* Address generation data */ - struct wdog_s wdog; + struct work_s work; }; /**************************************************************************** @@ -709,10 +710,10 @@ static void sim_usbhost_rqcomplete(struct sim_usbhost_s *drvr) } /**************************************************************************** - * Name: sim_usbhost_interrupt + * Name: sim_usbhost_work ****************************************************************************/ -static void sim_usbhost_interrupt(wdparm_t arg) +static void sim_usbhost_work(void *arg) { struct sim_usbhost_s *priv = (struct sim_usbhost_s *)arg; struct usbhost_hubport_s *hport; @@ -778,7 +779,8 @@ static void sim_usbhost_interrupt(wdparm_t arg) } } - wd_start_next(&priv->wdog, SIM_USBHOST_PERIOD, sim_usbhost_interrupt, arg); + work_queue_next_wq(g_work_queue, &priv->work, sim_usbhost_work, priv, + SIM_USBHOST_PERIOD); } /**************************************************************************** @@ -851,7 +853,8 @@ int sim_usbhost_initialize(void) return -ENODEV; } - wd_start(&priv->wdog, 0, sim_usbhost_interrupt, (wdparm_t)priv); + work_queue_wq(g_work_queue, &priv->work, sim_usbhost_work, priv, + SIM_USBHOST_PERIOD); return OK; } diff --git a/arch/sim/src/sim/sim_usrsock.c b/arch/sim/src/sim/sim_usrsock.c index 8605890fc8a18..17ce01baa4e98 100644 --- a/arch/sim/src/sim/sim_usrsock.c +++ b/arch/sim/src/sim/sim_usrsock.c @@ -32,7 +32,9 @@ #include #include +#include +#include "sim_internal.h" #include "sim_hostusrsock.h" /**************************************************************************** @@ -395,8 +397,8 @@ static const usrsock_handler_t g_usrsock_handler[] = static void sim_usrsock_work(void *arg) { - work_queue(HPWORK, &g_usrsock.work, (void *)sim_usrsock_work, - NULL, SIM_USRSOCK_PERIOD); + work_queue_next_wq(g_work_queue, &g_usrsock.work, sim_usrsock_work, + NULL, SIM_USRSOCK_PERIOD); } /**************************************************************************** @@ -410,8 +412,8 @@ int usrsock_event_callback(int16_t usockid, uint16_t events) void usrsock_register(void) { - work_queue(HPWORK, &g_usrsock.work, (void *)sim_usrsock_work, - NULL, SIM_USRSOCK_PERIOD); + work_queue_wq(g_work_queue, &g_usrsock.work, sim_usrsock_work, + NULL, SIM_USRSOCK_PERIOD); } /**************************************************************************** diff --git a/arch/sim/src/sim/sim_wifidriver.c b/arch/sim/src/sim/sim_wifihost.c similarity index 91% rename from arch/sim/src/sim/sim_wifidriver.c rename to arch/sim/src/sim/sim_wifihost.c index 16036860e332e..5d45177167e50 100644 --- a/arch/sim/src/sim/sim_wifidriver.c +++ b/arch/sim/src/sim/sim_wifihost.c @@ -1,7 +1,6 @@ /**************************************************************************** - * arch/sim/src/sim/sim_wifidriver.c - * - * SPDX-License-Identifier: Apache-2.0 + * arch/sim/src/sim/sim_wifihost.c + * Manage the host wireless * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -35,6 +34,7 @@ #include #include "sim_internal.h" +#include "sim_wifihost.h" /**************************************************************************** * Pre-processor Definitions @@ -105,6 +105,9 @@ ret__; \ }) +#define NETDEV2WIFI(dev) \ + ((struct sim_wifi_s *)((struct sim_wifihost_lowerhalf_s *)dev)->wifi) + /**************************************************************************** * Private Types ****************************************************************************/ @@ -155,10 +158,9 @@ struct sim_bss_info_s int16_t snr; /* average SNR of during frame reception */ }; -struct sim_netdev_s +struct sim_wifi_s { - struct netdev_lowerhalf_s dev; - uint8_t buf[SIM_NETDEV_BUFSIZE]; /* Used when packet buffer is fragmented */ + struct netdev_lowerhalf_s *dev; char ssid[SSID_MAX_LEN]; char bssid[ETH_ALEN]; uint16_t channel; @@ -257,7 +259,7 @@ static const struct wireless_ops_s g_iw_ops = * Private Functions ****************************************************************************/ -static int get_cmd_result_num(struct sim_netdev_s *wifidev, char *cmd) +static int get_cmd_result_num(struct sim_wifi_s *wifidev, char *cmd) { int num = 0; char rbuf[BUF_LEN]; @@ -277,21 +279,21 @@ static int get_cmd_result_num(struct sim_netdev_s *wifidev, char *cmd) /* For sta, add an available network. */ -static int wpa_add_network(struct sim_netdev_s *wifidev) +static int wpa_add_network(struct sim_wifi_s *wifidev) { return get_cmd_result_num(wifidev, "add_network"); } /* For sta, get the number of available networks. */ -static int wpa_get_network_num(struct sim_netdev_s *wifidev) +static int wpa_get_network_num(struct sim_wifi_s *wifidev) { return get_cmd_result_num(wifidev, "list_network | grep \"\\[\" | wc -l"); } /* For sta, get the available network_id. */ -static int wpa_get_last_network_id(struct sim_netdev_s *wifidev, +static int wpa_get_last_network_id(struct sim_wifi_s *wifidev, int network_num) { int num; @@ -823,7 +825,7 @@ static int get_bss_info(struct sim_bss_info_s *bss_info, char *buf, int len) return OK; } -static int get_scan_results(struct sim_netdev_s *wifidev, +static int get_scan_results(struct sim_wifi_s *wifidev, struct sim_scan_result_s *scan_reqs) { int ret; @@ -898,7 +900,7 @@ static int get_scan_results(struct sim_netdev_s *wifidev, return ret; } -static bool get_wpa_state(struct sim_netdev_s *wifidev) +static bool get_wpa_state(struct sim_wifi_s *wifidev) { int ret; char rbuf[BUF_LEN]; @@ -914,7 +916,7 @@ static bool get_wpa_state(struct sim_netdev_s *wifidev) return false; } -static bool get_wpa_bssid(struct sim_netdev_s *wifidev, +static bool get_wpa_bssid(struct sim_wifi_s *wifidev, unsigned char *bssid) { int ret; @@ -931,7 +933,7 @@ static bool get_wpa_bssid(struct sim_netdev_s *wifidev, return false; } -static bool get_wpa_rssi(struct sim_netdev_s *wifidev, int32_t *rssi) +static bool get_wpa_rssi(struct sim_wifi_s *wifidev, int32_t *rssi) { int ret; char rbuf[BUF_LEN]; @@ -948,14 +950,14 @@ static bool get_wpa_rssi(struct sim_netdev_s *wifidev, int32_t *rssi) return false; } -static void get_wpa_ssid(struct sim_netdev_s *wifidev, +static void get_wpa_ssid(struct sim_wifi_s *wifidev, struct iw_point *essid) { essid->length = strlen(wifidev->ssid); strlcpy(essid->pointer, wifidev->ssid, essid->length + 1); } -static int get_wpa_freq(struct sim_netdev_s *wifidev) +static int get_wpa_freq(struct sim_wifi_s *wifidev) { return get_cmd_result_num(wifidev, "status | grep freq | awk -F'=' '{print $2}'"); @@ -1075,7 +1077,7 @@ static int wifi_send_event(struct net_driver_s *dev, unsigned int cmd, return OK; } -static int wifidriver_start_scan(struct sim_netdev_s *wifidev, +static int wifidriver_start_scan(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int ret; @@ -1110,7 +1112,7 @@ static int wifidriver_start_scan(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_scan_result(struct sim_netdev_s *wifidev, +static int wifidriver_scan_result(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { struct sim_scan_result_s scan_req; @@ -1139,7 +1141,7 @@ static int wifidriver_scan_result(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_set_auth(struct sim_netdev_s *wifidev, +static int wifidriver_set_auth(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int ret = 0; @@ -1210,7 +1212,7 @@ static int wifidriver_set_auth(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_get_auth(struct sim_netdev_s *wifidev, +static int wifidriver_get_auth(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int ret = 0; @@ -1233,7 +1235,7 @@ static int wifidriver_get_auth(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_set_psk(struct sim_netdev_s *wifidev, +static int wifidriver_set_psk(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { struct iw_encode_ext *ext; @@ -1287,7 +1289,7 @@ static int wifidriver_set_psk(struct sim_netdev_s *wifidev, return ret ; } -static int wifidriver_get_psk(struct sim_netdev_s *wifidev, +static int wifidriver_get_psk(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { struct iw_encode_ext *ext; @@ -1323,7 +1325,7 @@ static int wifidriver_get_psk(struct sim_netdev_s *wifidev, return ret ; } -static int wifidriver_set_essid(struct sim_netdev_s *wifidev, +static int wifidriver_set_essid(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { char ssid_buf[SSID_MAX_LEN]; @@ -1379,7 +1381,7 @@ static int wifidriver_set_essid(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_get_essid(struct sim_netdev_s *wifidev, +static int wifidriver_get_essid(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int ret = 0; @@ -1414,7 +1416,7 @@ static int wifidriver_get_essid(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_set_bssid(struct sim_netdev_s *wifidev, +static int wifidriver_set_bssid(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int ret = 0; @@ -1453,7 +1455,7 @@ static int wifidriver_set_bssid(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_get_bssid(struct sim_netdev_s *wifidev, +static int wifidriver_get_bssid(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { struct sockaddr *sockaddr = &pwrq->u.ap_addr; @@ -1485,7 +1487,7 @@ static int wifidriver_get_bssid(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_start_connect(struct sim_netdev_s *wifidev) +static int wifidriver_start_connect(struct sim_wifi_s *wifidev) { int timeout = 10; @@ -1519,7 +1521,7 @@ static int wifidriver_start_connect(struct sim_netdev_s *wifidev) memset(&wrqu, 0, sizeof(wrqu)); memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN); - wifi_send_event(&wifidev->dev.netdev, SIOCGIWAP, &wrqu); + wifi_send_event(&wifidev->dev->netdev, SIOCGIWAP, &wrqu); return OK; } @@ -1544,7 +1546,7 @@ static int wifidriver_start_connect(struct sim_netdev_s *wifidev) return OK; } -static int wifidriver_start_disconnect(struct sim_netdev_s *wifidev) +static int wifidriver_start_disconnect(struct sim_wifi_s *wifidev) { int ret; @@ -1564,14 +1566,14 @@ static int wifidriver_start_disconnect(struct sim_netdev_s *wifidev) return ret; } -static int wifidriver_get_mode(struct sim_netdev_s *wifidev, +static int wifidriver_get_mode(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { pwrq->u.mode = wifidev->mode; return OK; } -static int wifidriver_set_mode(struct sim_netdev_s *wifidev, +static int wifidriver_set_mode(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int ret; @@ -1638,7 +1640,7 @@ static int wifidriver_set_mode(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_set_country(struct sim_netdev_s *wifidev, +static int wifidriver_set_country(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { char country[4] = @@ -1658,7 +1660,7 @@ static int wifidriver_set_country(struct sim_netdev_s *wifidev, return set_cmd(wifidev, "set country %s", country); } -static int wifidriver_get_country(struct sim_netdev_s *wifidev, +static int wifidriver_get_country(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { char country[128]; @@ -1696,7 +1698,7 @@ static int wifidriver_get_country(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_get_sensitivity(struct sim_netdev_s *wifidev, +static int wifidriver_get_sensitivity(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int32_t rssi; @@ -1722,7 +1724,7 @@ static int wifidriver_get_sensitivity(struct sim_netdev_s *wifidev, return ret; } -int wifidriver_set_freq(struct sim_netdev_s *wifidev, struct iwreq *pwrq) +int wifidriver_set_freq(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int channel; int ret = 0; @@ -1747,7 +1749,7 @@ int wifidriver_set_freq(struct sim_netdev_s *wifidev, struct iwreq *pwrq) return ret; } -static int wifidriver_get_freq(struct sim_netdev_s *wifidev, +static int wifidriver_get_freq(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { switch (wifidev->mode) @@ -1775,7 +1777,7 @@ static int wifidriver_get_freq(struct sim_netdev_s *wifidev, return OK; } -static int wifidriver_get_range(struct sim_netdev_s *wifidev, +static int wifidriver_get_range(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int k; @@ -1798,7 +1800,7 @@ static int wifidriver_connect(struct netdev_lowerhalf_s *dev) { int ret; - ret = wifidriver_start_connect((struct sim_netdev_s *)dev); + ret = wifidriver_start_connect(NETDEV2WIFI(dev)); if (ret >= 0) { netdev_lower_carrier_on(dev); @@ -1812,7 +1814,7 @@ static int wifidriver_disconnect(struct netdev_lowerhalf_s *dev) int ret; union iwreq_data wrqu; - ret = wifidriver_start_disconnect((struct sim_netdev_s *)dev); + ret = wifidriver_start_disconnect(NETDEV2WIFI(dev)); if (ret >= 0) { netdev_lower_carrier_off(dev); @@ -1827,7 +1829,7 @@ static int wifidriver_disconnect(struct netdev_lowerhalf_s *dev) static int wifidriver_essid(struct netdev_lowerhalf_s *dev, struct iwreq *iwr, bool set) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = NETDEV2WIFI(dev); if (set) { @@ -1843,7 +1845,7 @@ static int wifidriver_bssid(struct netdev_lowerhalf_s *dev, struct iwreq *iwr, bool set) { int ret; - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = NETDEV2WIFI(dev); if (set) { @@ -1866,18 +1868,18 @@ static int wifidriver_passwd(struct netdev_lowerhalf_s *dev, { if (set) { - return wifidriver_set_psk((struct sim_netdev_s *)dev, iwr); + return wifidriver_set_psk(NETDEV2WIFI(dev), iwr); } else { - return wifidriver_get_psk((struct sim_netdev_s *)dev, iwr); + return wifidriver_get_psk(NETDEV2WIFI(dev), iwr); } } static int wifidriver_mode(struct netdev_lowerhalf_s *dev, struct iwreq *iwr, bool set) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = NETDEV2WIFI(dev); if (set) { @@ -1892,7 +1894,7 @@ static int wifidriver_mode(struct netdev_lowerhalf_s *dev, static int wifidriver_auth(struct netdev_lowerhalf_s *dev, struct iwreq *iwr, bool set) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = NETDEV2WIFI(dev); if (set) { @@ -1907,7 +1909,7 @@ static int wifidriver_auth(struct netdev_lowerhalf_s *dev, static int wifidriver_freq(struct netdev_lowerhalf_s *dev, struct iwreq *iwr, bool set) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = NETDEV2WIFI(dev); if (set) { @@ -1934,7 +1936,7 @@ static int wifidriver_txpower(struct netdev_lowerhalf_s *dev, static int wifidriver_country(struct netdev_lowerhalf_s *dev, struct iwreq *iwr, bool set) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = NETDEV2WIFI(dev); if (set) { @@ -1949,7 +1951,7 @@ static int wifidriver_country(struct netdev_lowerhalf_s *dev, static int wifidriver_sensitivity(struct netdev_lowerhalf_s *dev, struct iwreq *iwr, bool set) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = NETDEV2WIFI(dev); if (set) { @@ -1964,7 +1966,7 @@ static int wifidriver_sensitivity(struct netdev_lowerhalf_s *dev, static int wifidriver_scan(struct netdev_lowerhalf_s *dev, struct iwreq *iwr, bool set) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = NETDEV2WIFI(dev); if (set) { @@ -1979,12 +1981,20 @@ static int wifidriver_scan(struct netdev_lowerhalf_s *dev, static int wifidriver_range(struct netdev_lowerhalf_s *dev, struct iwreq *iwr) { - return wifidriver_get_range((struct sim_netdev_s *)dev, iwr); + return wifidriver_get_range(NETDEV2WIFI(dev), iwr); } -static bool wifidriver_connected(struct netdev_lowerhalf_s *dev) +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sim_wifihost_connected + ****************************************************************************/ + +bool sim_wifihost_connected(struct sim_wifihost_lowerhalf_s *dev) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = (struct sim_wifi_s *)dev->wifi; if (wifidev->mode == IW_MODE_MASTER) { @@ -1998,21 +2008,36 @@ static bool wifidriver_connected(struct netdev_lowerhalf_s *dev) return false; } -static void wifidriver_init(struct netdev_lowerhalf_s *dev, int devidx) +/**************************************************************************** + * Name: sim_wifihost_init + ****************************************************************************/ + +int sim_wifihost_init(struct sim_wifihost_lowerhalf_s *dev, int devidx) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *priv; - wifidev->mode = IW_MODE_AUTO; - wifidev->devidx = devidx; + priv = kmm_zalloc(sizeof(*priv)); + if (priv == NULL) + { + nerr("wifi driver priv alloc failed\n"); + return -ENOMEM; + } + + dev->wifi = priv; + priv->dev = &dev->lower; + priv->mode = IW_MODE_AUTO; + priv->devidx = devidx; + + /* Bind the wireless ops interfaces. */ + + dev->lower.iw_ops = &g_iw_ops; /* The default host wlan interface name is corresponding to the nuttx * wlan interface name. If not, should modify the host wlan interface * name. */ - snprintf(wifidev->host_ifname, IFNAMSIZ, "wlan%d", devidx); + snprintf(priv->host_ifname, IFNAMSIZ, "wlan%d", devidx); - /* Bind the wireless ops interfaces. */ - - dev->iw_ops = &g_iw_ops; + return OK; } diff --git a/arch/sim/src/sim/sim_wifihost.h b/arch/sim/src/sim/sim_wifihost.h new file mode 100644 index 0000000000000..8c2c0d90b4f6a --- /dev/null +++ b/arch/sim/src/sim/sim_wifihost.h @@ -0,0 +1,73 @@ +/**************************************************************************** + * arch/sim/src/sim/sim_wifihost.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +#ifndef __ARCH_SIM_SRC_SIM_WIFIHOST_H +#define __ARCH_SIM_SRC_SIM_WIFIHOST_H + +#if CONFIG_SIM_WIFIDEV_NUMBER != 0 + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Type Definitions + ****************************************************************************/ + +struct sim_wifihost_lowerhalf_s +{ + /* This holds the information visible to the NuttX network */ + + struct netdev_lowerhalf_s lower; /* The netdev lowerhalf */ + + void *wifi; +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int sim_wifihost_init(struct sim_wifihost_lowerhalf_s *dev, int devidx); +bool sim_wifihost_connected(struct sim_wifihost_lowerhalf_s *dev); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_DRIVERS_WIFI_SIM */ +#endif /* __ARCH_SIM_SRC_SIM_WIFIHOST_H */ diff --git a/arch/sim/src/sim/win/sim_errno.c b/arch/sim/src/sim/win/sim_errno.c new file mode 100644 index 0000000000000..b416b5d14e113 --- /dev/null +++ b/arch/sim/src/sim/win/sim_errno.c @@ -0,0 +1,46 @@ +/**************************************************************************** + * arch/sim/src/sim/win/sim_errno.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int host_errno_convert(int errcode) +{ + return errcode; +} + +int host_errno_get(void) +{ + return errno; +} + +void host_errno_set(int errcode) +{ + errno = errcode; +} diff --git a/arch/sim/src/sim/win/sim_hostirq.c b/arch/sim/src/sim/win/sim_hostirq.c index 2945f33eed501..3db2b92a1fd27 100644 --- a/arch/sim/src/sim/win/sim_hostirq.c +++ b/arch/sim/src/sim/win/sim_hostirq.c @@ -80,14 +80,6 @@ void up_irq_restore(uint64_t flags) { } -/**************************************************************************** - * Name: up_irqinitialize - ****************************************************************************/ - -void up_irqinitialize(void) -{ -} - /**************************************************************************** * Name: up_enable_irq * @@ -111,3 +103,11 @@ void up_enable_irq(int irq) void up_disable_irq(int irq) { } + +/**************************************************************************** + * Name: host_irqinitialize + ****************************************************************************/ + +void host_irqinitialize(void) +{ +} diff --git a/arch/sparc/src/bm3803/bm3803_tickless.c b/arch/sparc/src/bm3803/bm3803_tickless.c index 121d506772e96..b7e100bfc12f8 100644 --- a/arch/sparc/src/bm3803/bm3803_tickless.c +++ b/arch/sparc/src/bm3803/bm3803_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -144,7 +144,7 @@ static struct bm3803_tickless_s g_tickless; static void bm3803_oneshot_handler(void *arg) { tmrinfo("Expired...\n"); - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -273,7 +273,7 @@ int up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -312,14 +312,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/tricore/include/inttypes.h b/arch/tricore/include/inttypes.h index d5b5ba723ab38..5e762312f1fd1 100644 --- a/arch/tricore/include/inttypes.h +++ b/arch/tricore/include/inttypes.h @@ -69,14 +69,14 @@ #define PRIx32 "lx" #define PRIx64 "llx" -#define PRIxPTR "x" +#define PRIxPTR "lx" #define PRIX8 "X" #define PRIX16 "X" #define PRIX32 "lX" #define PRIX64 "llX" -#define PRIXPTR "X" +#define PRIXPTR "lX" #define SCNd8 "hhd" #define SCNd16 "hd" diff --git a/arch/tricore/include/irq.h b/arch/tricore/include/irq.h index cedddc410bea0..9f357334229d0 100644 --- a/arch/tricore/include/irq.h +++ b/arch/tricore/include/irq.h @@ -34,6 +34,7 @@ #include #ifndef __ASSEMBLY__ # include +# include #endif /* Include NuttX-specific IRQ definitions */ @@ -73,17 +74,9 @@ extern "C" * Public Data ****************************************************************************/ -/* g_current_regs[] holds a references to the current interrupt level - * register storage structure. If is non-NULL only during interrupt - * processing. Access to g_current_regs[] must be through the macro - * g_current_regs for portability. - */ - -/* For the case of architectures with multiple CPUs, then there must be one - * such value for each processor that can receive an interrupt. - */ +/* g_interrupt_context store irq status */ -EXTERN volatile uintptr_t *g_current_regs[CONFIG_SMP_NCPUS]; +EXTERN volatile bool g_interrupt_context[CONFIG_SMP_NCPUS]; /**************************************************************************** * Public Function Prototypes @@ -155,21 +148,21 @@ void up_irq_restore(irqstate_t flags) * Inline Functions ****************************************************************************/ -static inline_function uintptr_t *up_current_regs(void) -{ -#ifdef CONFIG_SMP - return (uintptr_t *)g_current_regs[up_cpu_index()]; -#else - return (uintptr_t *)g_current_regs[0]; -#endif -} +/**************************************************************************** + * Name: up_set_interrupt_context + * + * Description: + * Set the interrupt handler context. + * + ****************************************************************************/ -static inline_function void up_set_current_regs(uintptr_t *regs) +noinstrument_function +static inline_function void up_set_interrupt_context(bool flag) { #ifdef CONFIG_SMP - g_current_regs[up_cpu_index()] = regs; + g_interrupt_context[up_this_cpu()] = flag; #else - g_current_regs[0] = regs; + g_interrupt_context[0] = flag; #endif } @@ -187,15 +180,14 @@ static inline_function bool up_interrupt_context(void) { #ifdef CONFIG_SMP irqstate_t flags = up_irq_save(); -#endif - - bool ret = up_current_regs() != NULL; + bool ret = g_interrupt_context[up_this_cpu()]; -#ifdef CONFIG_SMP up_irq_restore(flags); -#endif return ret; +#else + return g_interrupt_context[0]; +#endif } /**************************************************************************** @@ -204,21 +196,42 @@ static inline_function bool up_interrupt_context(void) static inline_function uintptr_t up_getusrsp(void *regs) { - uintptr_t *csa = regs; + uintptr_t *csaregs = regs; - while (((uintptr_t)csa & PCXI_UL) == 0) + if (csaregs[REG_LPCXI] & PCXI_UL) { - csa = tricore_csa2addr((uintptr_t)csa); - csa = (uintptr_t *)csa[0]; + csaregs = tricore_csa2addr(csaregs[REG_LPCXI]); + } + else + { + csaregs += TC_CONTEXT_REGS; } - csa = tricore_csa2addr((uintptr_t)csa); - - return csa[REG_SP]; + return csaregs[REG_SP]; } #endif /* __ASSEMBLY__ */ +/**************************************************************************** + * Name: up_switch_context + ****************************************************************************/ + +#define up_switch_context(tcb, rtcb) \ + do { \ + if (!up_interrupt_context()) \ + { \ + sys_call0(SYS_switch_context); \ + } \ + UNUSED(rtcb); \ + } while (0) + +/**************************************************************************** + * Name: up_getusrpc + ****************************************************************************/ + +#define up_getusrpc(regs) \ + (((uint32_t *)((regs) ? (regs) : running_regs()))[REG_UPC]) + #undef EXTERN #ifdef __cplusplus } diff --git a/arch/tricore/include/tc3xx/irq.h b/arch/tricore/include/tc3xx/irq.h index d7b7b399540c4..a9b76965b6875 100644 --- a/arch/tricore/include/tc3xx/irq.h +++ b/arch/tricore/include/tc3xx/irq.h @@ -83,9 +83,10 @@ #define REG_LPC REG_LA11 #define TC_CONTEXT_REGS (16) +#define TC_CONTEXT_SIZE (sizeof(void *) * TC_CONTEXT_REGS) -#define XCPTCONTEXT_REGS (TC_CONTEXT_REGS) -#define XCPTCONTEXT_SIZE (sizeof(void *) * TC_CONTEXT_REGS) +#define XCPTCONTEXT_REGS (TC_CONTEXT_REGS * 2) +#define XCPTCONTEXT_SIZE (sizeof(void *) * XCPTCONTEXT_REGS) #define NR_IRQS (255) diff --git a/arch/tricore/src/common/CMakeLists.txt b/arch/tricore/src/common/CMakeLists.txt index 1183ed621e939..c0f55332edb3a 100644 --- a/arch/tricore/src/common/CMakeLists.txt +++ b/arch/tricore/src/common/CMakeLists.txt @@ -40,7 +40,6 @@ set(SRCS tricore_sigdeliver.c tricore_stackframe.c tricore_svcall.c - tricore_switchcontext.c tricore_tcbinfo.c tricore_trapcall.c tricore_systimer.c diff --git a/arch/tricore/src/common/Make.defs b/arch/tricore/src/common/Make.defs index c3e9c77dd30c2..8dbfbffd42755 100644 --- a/arch/tricore/src/common/Make.defs +++ b/arch/tricore/src/common/Make.defs @@ -41,7 +41,6 @@ CMN_CSRCS += tricore_schedulesigaction.c CMN_CSRCS += tricore_sigdeliver.c CMN_CSRCS += tricore_stackframe.c CMN_CSRCS += tricore_svcall.c -CMN_CSRCS += tricore_switchcontext.c CMN_CSRCS += tricore_tcbinfo.c CMN_CSRCS += tricore_trapcall.c CMN_CSRCS += tricore_systimer.c diff --git a/arch/tricore/src/common/tricore_csa.c b/arch/tricore/src/common/tricore_csa.c index 74dd8931ac8bf..d68ea4ae215f6 100644 --- a/arch/tricore/src/common/tricore_csa.c +++ b/arch/tricore/src/common/tricore_csa.c @@ -64,8 +64,8 @@ uintptr_t *tricore_alloc_csa(uintptr_t pc, uintptr_t sp, __isync(); - memset(pucsa, 0, XCPTCONTEXT_SIZE); - memset(plcsa, 0, XCPTCONTEXT_SIZE); + memset(pucsa, 0, TC_CONTEXT_SIZE); + memset(plcsa, 0, TC_CONTEXT_SIZE); pucsa[REG_SP] = sp; pucsa[REG_PSW] = psw; @@ -82,7 +82,7 @@ uintptr_t *tricore_alloc_csa(uintptr_t pc, uintptr_t sp, plcsa[REG_LPCXI] |= PCXI_PIE; } - return (uintptr_t *)tricore_addr2csa(plcsa); + return plcsa; } /**************************************************************************** diff --git a/arch/tricore/src/common/tricore_doirq.c b/arch/tricore/src/common/tricore_doirq.c index f5d686c3532d4..02da6543d69e5 100644 --- a/arch/tricore/src/common/tricore_doirq.c +++ b/arch/tricore/src/common/tricore_doirq.c @@ -46,8 +46,8 @@ IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255) { - struct tcb_s *running_task = g_running_tasks[this_cpu()]; - struct tcb_s *tcb; + struct tcb_s **running_task = &g_running_tasks[this_cpu()]; + struct tcb_s *tcb = this_task(); #ifdef CONFIG_SUPPRESS_INTERRUPTS PANIC(); @@ -56,40 +56,31 @@ IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255) uintptr_t *regs; icr.U = __mfcr(CPU_ICR); - regs = (uintptr_t *)__mfcr(CPU_PCXI); + regs = tricore_csa2addr(__mfcr(CPU_PCXI)); - if (running_task != NULL) + if (*running_task != NULL) { - running_task->xcp.regs = regs; + (*running_task)->xcp.regs = regs; } board_autoled_on(LED_INIRQ); /* Nested interrupts are not supported */ - DEBUGASSERT(up_current_regs() == NULL); + DEBUGASSERT(!up_interrupt_context()); - /* Current regs non-zero indicates that we are processing an interrupt; - * current_regs is also used to manage interrupt level context switches. - */ + /* Set irq flag */ - up_set_current_regs(regs); + up_set_interrupt_context(true); /* Deliver the IRQ */ irq_dispatch(icr.B.CCPN, regs); - /* Check for a context switch. If a context switch occurred, then - * g_current_regs will have a different value than it did on entry. If an - * interrupt level context switch has occurred, then restore the floating - * point state and the establish the correct address environment before - * returning from the interrupt. - */ + /* Check for a context switch. */ - if (regs != up_current_regs()) + if (*running_task != tcb) { - tcb = this_task(); - #ifdef CONFIG_ARCH_ADDRENV /* Make sure that the address environment for the previously * running task is closed down gracefully (data caches dump, @@ -102,31 +93,28 @@ IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255) /* Update scheduler parameters */ - nxsched_switch_context(running_task, tcb); + nxsched_switch_context(*running_task, tcb); /* Record the new "running" task when context switch occurred. * g_running_tasks[] is only used by assertion logic for reporting * crashes. */ - running_task = tcb; - g_running_tasks[this_cpu()] = running_task; + *running_task = tcb; - __mtcr(CPU_PCXI, (uintptr_t)up_current_regs()); + __mtcr(CPU_PCXI, tricore_addr2csa(tcb->xcp.regs)); __isync(); } - /* Set current_regs to NULL to indicate that we are no longer in an - * interrupt handler. - */ + /* Set irq flag */ - up_set_current_regs(NULL); + up_set_interrupt_context(false); /* running_task->xcp.regs is about to become invalid * and will be marked as NULL to avoid misusage. */ - running_task->xcp.regs = NULL; + (*running_task)->xcp.regs = NULL; board_autoled_off(LED_INIRQ); #endif } diff --git a/arch/tricore/src/common/tricore_exit.c b/arch/tricore/src/common/tricore_exit.c index ffa58ddc38154..71201c3b3ecda 100644 --- a/arch/tricore/src/common/tricore_exit.c +++ b/arch/tricore/src/common/tricore_exit.c @@ -56,25 +56,17 @@ void up_exit(int status) { - struct tcb_s *tcb = this_task(); - /* Destroy the task at the head of the ready to run list. */ nxtask_exit(); - /* Now, perform the context switch to the new ready-to-run task at the - * head of the list. - */ - - tcb = this_task(); - /* Scheduler parameters will update inside syscall */ g_running_tasks[this_cpu()] = NULL; /* Then switch contexts */ - tricore_fullcontextrestore(tcb->xcp.regs); + tricore_fullcontextrestore(); /* tricore_fullcontextrestore() should not return but could if the software * interrupts are disabled. diff --git a/arch/tricore/src/common/tricore_initialize.c b/arch/tricore/src/common/tricore_initialize.c index 9fa6ac844686d..21173d355fd81 100644 --- a/arch/tricore/src/common/tricore_initialize.c +++ b/arch/tricore/src/common/tricore_initialize.c @@ -34,7 +34,9 @@ * Public Data ****************************************************************************/ -volatile uintptr_t *g_current_regs[CONFIG_SMP_NCPUS]; +/* g_interrupt_context store irq status */ + +volatile bool g_interrupt_context[CONFIG_SMP_NCPUS]; /**************************************************************************** * Public Functions @@ -59,6 +61,8 @@ volatile uintptr_t *g_current_regs[CONFIG_SMP_NCPUS]; void up_initialize(void) { + tricore_trapinit(); + /* Initialize the serial device driver */ #ifdef USE_SERIALDRIVER diff --git a/arch/tricore/src/common/tricore_internal.h b/arch/tricore/src/common/tricore_internal.h index b6df70c1ace0f..57d4557146f70 100644 --- a/arch/tricore/src/common/tricore_internal.h +++ b/arch/tricore/src/common/tricore_internal.h @@ -129,22 +129,7 @@ #define modreg32(v,m,a) putreg32((getreg32(a) & ~(m)) | ((v) & (m)), (a)) #define modreg64(v,m,a) putreg64((getreg64(a) & ~(m)) | ((v) & (m)), (a)) -/* Context switching */ - -#ifndef tricore_fullcontextrestore -# define tricore_fullcontextrestore(restoreregs) \ - sys_call1(SYS_restore_context, (uintptr_t)restoreregs); -#else -extern void tricore_fullcontextrestore(uintptr_t *restoreregs); -#endif - -#ifndef tricore_switchcontext -# define tricore_switchcontext(saveregs, restoreregs) \ - sys_call2(SYS_switch_context, (uintptr_t)saveregs, (uintptr_t)restoreregs); -#else -extern void tricore_switchcontext(uintptr_t **saveregs, - uintptr_t *restoreregs); -#endif +#define tricore_fullcontextrestore() sys_call0(SYS_restore_context) /**************************************************************************** * Public Types @@ -204,11 +189,6 @@ extern uintptr_t __A0_MEM[]; /* End+1 of .data */ * Inline Functions ****************************************************************************/ -/* Macros to handle saving and restoring interrupt state. */ - -#define tricore_savestate(regs) (regs = up_current_regs()) -#define tricore_restorestate(regs) (up_set_current_regs(regs)) - /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -221,6 +201,7 @@ void tricore_sigdeliver(void); void tricore_svcall(volatile void *trap); void tricore_trapcall(volatile void *trap); +void tricore_trapinit(void); /* Context Save Areas *******************************************************/ diff --git a/arch/tricore/src/common/tricore_registerdump.c b/arch/tricore/src/common/tricore_registerdump.c index bc29358ca1b80..4a225e60b2ba0 100644 --- a/arch/tricore/src/common/tricore_registerdump.c +++ b/arch/tricore/src/common/tricore_registerdump.c @@ -39,10 +39,108 @@ * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: tricore_dump_upcsa + ****************************************************************************/ + +void tricore_dump_upcsa(volatile uint32_t *regs) +{ + _alert("UPCXI:%-13.8" PRIX32 "PSW:%-15.8" PRIX32 + "SP:%-16.8" PRIX32 "A11:%-15.8" PRIX32 "\n", + regs[REG_UPCXI], regs[REG_PSW], regs[REG_A10], regs[REG_UA11]); + _alert("D8:%-16.8" PRIX32 "D9:%-16.8" PRIX32 + "D10:%-15.8" PRIX32 "D11:%-15.8" PRIX32 "\n", + regs[REG_D8], regs[REG_D9], regs[REG_D10], regs[REG_D11]); + _alert("A12:%-15.8" PRIX32 "A13:%-15.8" PRIX32 + "A14:%-15.8" PRIX32 "A15:%-15.8" PRIX32 "\n", + regs[REG_A12], regs[REG_A13], regs[REG_A14], regs[REG_A15]); + _alert("D12:%-15.8" PRIX32 "D13:%-15.8" PRIX32 + "D14:%-15.8" PRIX32 "D15:%-15.8" PRIX32 "\n\n", + regs[REG_D12], regs[REG_D13], regs[REG_D14], regs[REG_D15]); +} + +/**************************************************************************** + * Name: tricore_dump_lowcsa + ****************************************************************************/ + +void tricore_dump_lowcsa(volatile uint32_t *regs) +{ + _alert("LPCXI:%-13.8" PRIX32 "PC:%-16.8" PRIX32 + "A2:%-16.8" PRIX32 "A3:%-16.8" PRIX32 "\n", + regs[REG_LPCXI] | PCXI_UL, regs[REG_LA11], + regs[REG_A2], regs[REG_A3]); + _alert("D0:%-16.8" PRIX32 "D1:%-16.8" PRIX32 + "D2:%-16.8" PRIX32 "D3:%-16.8" PRIX32 "\n", + regs[REG_D0], regs[REG_D1], regs[REG_D2], regs[REG_D3]); + _alert("A4:%-16.8" PRIX32 "A5:%-16.8" PRIX32 + "A6:%-16.8" PRIX32 "A7:%-16.8" PRIX32 "\n", + regs[REG_A4], regs[REG_A5], regs[REG_A6], regs[REG_A7]); + _alert("D4:%-16.8" PRIX32 "D5:%-16.8" PRIX32 + "D6:%-16.8" PRIX32 "D7:%-16.8" PRIX32 "\n\n", + regs[REG_D4], regs[REG_D5], regs[REG_D6], regs[REG_D7]); +} + +/**************************************************************************** + * Name: tricore_dump_trapctrl + ****************************************************************************/ + +void tricore_dump_trapctrl(void) +{ + _alert("PSTR:%-14.8" PRIX32 "DSTR:%-14.8" PRIX32 + "DATR:%-14.8" PRIX32 "DEADD:%-13.8" PRIX32 "\n\n", + (uint32_t)__mfcr(CPU_PSTR), (uint32_t)__mfcr(CPU_DSTR), + (uint32_t)__mfcr(CPU_DATR), (uint32_t)__mfcr(CPU_DEADD)); +} + +/**************************************************************************** + * Name: tricore_dump_csachain + ****************************************************************************/ + +void tricore_dump_csachain(uintptr_t pcxi) +{ + while (pcxi & FCX_FREE) + { + if (pcxi & PCXI_UL) + { + tricore_dump_upcsa((uint32_t *)tricore_csa2addr(pcxi)); + } + else + { + tricore_dump_lowcsa((uint32_t *)tricore_csa2addr(pcxi)); + } + + pcxi = tricore_csa2addr(pcxi)[0]; + } +} + /**************************************************************************** * Name: up_dump_register ****************************************************************************/ void up_dump_register(void *dumpregs) { + volatile uint32_t *regs = dumpregs; + + tricore_dump_lowcsa(regs); + + tricore_dump_upcsa(regs + TC_CONTEXT_REGS); + + tricore_dump_trapctrl(); +} + +/**************************************************************************** + * Name: up_regs_memcpy + ****************************************************************************/ + +void up_regs_memcpy(FAR void *dest, FAR void *src, size_t count) +{ + int csa_size = TC_CONTEXT_REGS * sizeof(uintptr_t); + int csa_num = count / csa_size; + + while (csa_num--) + { + memcpy(dest, src, csa_size); + dest = (char *)dest + csa_size; + src = tricore_csa2addr(((uintptr_t *)src)[REG_LPCXI]); + } } diff --git a/arch/tricore/src/common/tricore_saveusercontext.c b/arch/tricore/src/common/tricore_saveusercontext.c index c2b6152305b2c..25a46f8201753 100644 --- a/arch/tricore/src/common/tricore_saveusercontext.c +++ b/arch/tricore/src/common/tricore_saveusercontext.c @@ -32,6 +32,10 @@ * Pre-processor Definitions ****************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -46,7 +50,30 @@ int up_saveusercontext(void *saveregs) { - uintptr_t *regs = tricore_csa2addr(__mfcr(CPU_PCXI)); - memcpy(saveregs, regs, XCPTCONTEXT_SIZE); + uintptr_t *regs; + uintptr_t pcxi; + int csa_size = TC_CONTEXT_REGS * sizeof(uintptr_t); + + pcxi = __mfcr(CPU_PCXI); + regs = tricore_csa2addr(pcxi); + memcpy((char *)saveregs + csa_size, regs, csa_size); + + /* to unify the trap processing, extra save lowcsa */ + + __asm("svlcx"); + + regs = tricore_csa2addr(__mfcr(CPU_PCXI)); + memcpy(saveregs, regs, csa_size); + + /* lowcsa[REG_LPCXI] saves the upcsa's pcxi, but if lowcsa and upcsa is + * stored at continuous addresses, pcxi has no meaning. Use PCXI_UL + * without marking whether it is lowcsa or upcsa, but to mark whether + * lowcsa and upcsa is stored at continuous addresses. + */ + + ((uintptr_t *)saveregs)[REG_LPCXI] = pcxi & (~PCXI_UL); + + __asm("rslcx"); + return 0; } diff --git a/arch/tricore/src/common/tricore_schedulesigaction.c b/arch/tricore/src/common/tricore_schedulesigaction.c index ffac299f1ac3b..3f4662077cb24 100644 --- a/arch/tricore/src/common/tricore_schedulesigaction.c +++ b/arch/tricore/src/common/tricore_schedulesigaction.c @@ -90,7 +90,7 @@ void up_schedule_sigaction(struct tcb_s *tcb) * a task is signalling itself for some reason. */ - if (up_current_regs() == NULL) + if (!up_interrupt_context()) { /* In this case just deliver the signal now. */ @@ -117,16 +117,16 @@ void up_schedule_sigaction(struct tcb_s *tcb) * been delivered. */ - tricore_savestate(tcb->xcp.saved_regs); + tcb->xcp.saved_regs = tcb->xcp.regs; /* Create a new CSA for signal delivery. The new context * will borrow the process stack of the current tcb. */ - up_set_current_regs(tricore_alloc_csa((uintptr_t) - tricore_sigdeliver, - STACK_ALIGN_DOWN(up_getusrsp(tcb->xcp.regs)), - PSW_IO_SUPERVISOR | PSW_CDE, true)); + tcb->xcp.regs = + tricore_alloc_csa((uintptr_t)tricore_sigdeliver, + STACK_ALIGN_DOWN(up_getusrsp(tcb->xcp.regs)), + PSW_IO_SUPERVISOR | PSW_CDE, true); } } @@ -151,8 +151,9 @@ void up_schedule_sigaction(struct tcb_s *tcb) * will borrow the process stack of the current tcb. */ - tcb->xcp.regs = tricore_alloc_csa((uintptr_t)tricore_sigdeliver, - STACK_ALIGN_DOWN(up_getusrsp(tcb->xcp.regs)), - PSW_IO_SUPERVISOR | PSW_CDE, true); + tcb->xcp.regs = + tricore_alloc_csa((uintptr_t)tricore_sigdeliver, + STACK_ALIGN_DOWN(up_getusrsp(tcb->xcp.regs)), + PSW_IO_SUPERVISOR | PSW_CDE, true); } } diff --git a/arch/tricore/src/common/tricore_sigdeliver.c b/arch/tricore/src/common/tricore_sigdeliver.c index 5149dec75ba45..bddb489298533 100644 --- a/arch/tricore/src/common/tricore_sigdeliver.c +++ b/arch/tricore/src/common/tricore_sigdeliver.c @@ -116,5 +116,6 @@ void tricore_sigdeliver(void) board_autoled_off(LED_SIGNAL); - tricore_fullcontextrestore(regs); + rtcb->xcp.regs = regs; + tricore_fullcontextrestore(); } diff --git a/arch/tricore/src/common/tricore_svcall.c b/arch/tricore/src/common/tricore_svcall.c index 575a43eebf503..fb1f35c686b0e 100644 --- a/arch/tricore/src/common/tricore_svcall.c +++ b/arch/tricore/src/common/tricore_svcall.c @@ -56,87 +56,53 @@ void tricore_svcall(volatile void *trap) { - struct tcb_s *running_task; - struct tcb_s *tcb; - int cpu = this_cpu(); - + struct tcb_s **running_task = &g_running_tasks[this_cpu()]; + struct tcb_s *tcb = this_task(); uintptr_t *regs; uint32_t cmd; regs = (uintptr_t *)__mfcr(CPU_PCXI); - running_task = g_running_tasks[cpu]; - tcb = this_task(); - /* DSYNC instruction should be executed immediately prior to the MTCR */ __dsync(); regs = tricore_csa2addr((uintptr_t)regs); - up_set_current_regs(regs); + /* Set irq flag */ + + up_set_interrupt_context(true); cmd = regs[REG_D8]; + if (cmd != SYS_restore_context) + { + (*running_task)->xcp.regs = tricore_csa2addr(regs[REG_UPCXI]); + } + else + { + tricore_reclaim_csa(regs[REG_UPCXI]); + } + /* Handle the SVCall according to the command in R0 */ switch (cmd) { - /* R0=SYS_restore_context: This a restore context command: - * - * void tricore_fullcontextrestore(uint32_t *restoreregs) - * noreturn_function; - * - * At this point, the following values are saved in context: - * - * R0 = SYS_restore_context - * R1 = restoreregs - * - * In this case, we simply need to set g_current_regs to restore - * register area referenced in the saved R1. context == g_current_regs - * is the normal exception return. By setting g_current_regs = - * context[R1], we force the return to the saved context referenced - * in R1. - */ + case SYS_switch_context: + nxsched_switch_context(*running_task, tcb); case SYS_restore_context: - { - tricore_reclaim_csa(regs[REG_UPCXI]); - up_set_current_regs((uintptr_t *)regs[REG_D9]); - } - break; - - case SYS_switch_context: - { - *(uintptr_t **)regs[REG_D9] = (uintptr_t *)regs[REG_UPCXI]; - up_set_current_regs((uintptr_t *)regs[REG_D10]); - } + *running_task = tcb; + regs[REG_UPCXI] = tricore_addr2csa(tcb->xcp.regs); + __isync(); break; default: - { - svcerr("ERROR: Bad SYS call: %d\n", (int)regs[REG_D0]); - } + svcerr("ERROR: Bad SYS call: %d\n", (int)regs[REG_D0]); break; } - if (regs != up_current_regs()) - { - /* Update scheduler parameters */ - - nxsched_switch_context(running_task, tcb); - - /* Record the new "running" task when context switch occurred. - * g_running_tasks[] is only used by assertion logic for reporting - * crashes. - */ - - g_running_tasks[cpu] = this_task(); - - regs[REG_UPCXI] = (uintptr_t)up_current_regs(); - - __isync(); - } + /* Set irq flag */ - up_set_current_regs(NULL); + up_set_interrupt_context(false); } diff --git a/arch/tricore/src/common/tricore_switchcontext.c b/arch/tricore/src/common/tricore_switchcontext.c index 7d08421a8ffe5..532fe248a3a34 100644 --- a/arch/tricore/src/common/tricore_switchcontext.c +++ b/arch/tricore/src/common/tricore_switchcontext.c @@ -59,35 +59,10 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb) { - /* Are we in an interrupt handler? */ - - if (up_current_regs()) - { - /* Yes, then we have to do things differently. - * Just copy the g_current_regs into the OLD rtcb. - */ - - tricore_savestate(rtcb->xcp.regs); - - /* Then switch contexts. Any necessary address environment - * changes will be made when the interrupt returns. - */ - - tricore_restorestate(tcb->xcp.regs); - } - - /* No, then we will need to perform the user context switch */ - - else + if (!up_interrupt_context()) { /* Then switch contexts */ tricore_switchcontext(&rtcb->xcp.regs, tcb->xcp.regs); - - /* tricore_switchcontext forces a context switch to the task at the - * head of the ready-to-run list. It does not 'return' in the - * normal sense. When it does return, it is because the blocked - * task is again ready to run and has execution priority. - */ } } diff --git a/arch/tricore/src/common/tricore_trapcall.c b/arch/tricore/src/common/tricore_trapcall.c index a83bcb21a4a4a..b924ad77d4832 100644 --- a/arch/tricore/src/common/tricore_trapcall.c +++ b/arch/tricore/src/common/tricore_trapcall.c @@ -34,20 +34,262 @@ #include #include +#include #include #include "tricore_internal.h" #include "IfxCpu_Trap.h" +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static IfxCpu_Trap g_trapinfo; + /**************************************************************************** * Private Functions ****************************************************************************/ +static void tricore_trapinfo(volatile void *trap) +{ + IfxCpu_Trap *ctrap = (IfxCpu_Trap *)trap; + + g_trapinfo.tCpu = ctrap->tCpu; + g_trapinfo.tClass = ctrap->tClass; + g_trapinfo.tId = ctrap->tId; + g_trapinfo.tAddr = ctrap->tAddr; +} + /**************************************************************************** * Public Functions ****************************************************************************/ +int tricore_mmutrap(uint32_t tid, void *context, void *arg) +{ + _alert("PANIC!!! MMU Trap:\n"); + _alert("\tClass %d TID: %" PRId32 " regs: %p\n", + IfxCpu_Trap_Class_memoryManagement, + tid, context); + + _alert("MMU Trap Reason:\n"); + if (tid == IfxCpu_Trap_MemoryManagement_Id_virtualAddressFill) + { + _alert("\tVirtual Address Fill\n"); + } + + if (tid == IfxCpu_Trap_MemoryManagement_Id_virtualAddressProtection) + { + _alert("\tVirtual Address Protection\n"); + } + + up_irq_save(); + PANIC_WITH_REGS("panic", context); + return OK; +} + +int tricore_internalprotrape(uint32_t tid, void *context, void *arg) +{ + _alert("PANIC!!! Internal Protection Trap:\n"); + _alert("\tClass %d TID: %" PRId32 " regs: %p\n", + IfxCpu_Trap_Class_internalProtection, tid, context); + + _alert("Internal Protection Reason:\n"); + if (tid == IfxCpu_Trap_InternalProtection_Id_privilegeViolation) + { + _alert("\tPrivileged Instruction\n"); + } + + if (tid == IfxCpu_Trap_InternalProtection_Id_memoryProtectionRead) + { + _alert("\tMemory Protection Read\n"); + } + + if (tid == IfxCpu_Trap_InternalProtection_Id_memoryProtectionWrite) + { + _alert("\tMemory Proteciton Write\n"); + } + + if (tid == IfxCpu_Trap_InternalProtection_Id_memoryProtectionExecute) + { + _alert("\tMemory Protection Execution\n"); + } + + if (tid == + IfxCpu_Trap_InternalProtection_Id_memoryProtectionPeripheralAccess) + { + _alert("\tMemory Protection Peripheral Access\n"); + } + + if (tid == IfxCpu_Trap_InternalProtection_Id_memoryProtectionNullAddress) + { + _alert("\tMemory Protection Null Address\n"); + } + + if (tid == IfxCpu_Trap_InternalProtection_Id_globalRegisterWriteProtection) + { + _alert("\tGlobal Register Write Protection\n"); + } + + up_irq_save(); + PANIC_WITH_REGS("panic", context); + return OK; +} + +int tricore_insterrorstrap(uint32_t tid, void *context, void *arg) +{ + _alert("PANIC!!! Instruction Errors Trap:\n"); + _alert("\tClass %d TID: %" PRId32 " regs: %p\n", + IfxCpu_Trap_Class_instructionErrors, tid, context); + + _alert("Instruction Errors Trap Reason:\n"); + if (tid == IfxCpu_Trap_InstructionErrors_Id_illegalOpcode) + { + _alert("\tIllegal Opcode\n"); + } + + if (tid == IfxCpu_Trap_InstructionErrors_Id_unimplementedOpcode) + { + _alert("\tUnimplemented Opcode\n"); + } + + if (tid == IfxCpu_Trap_InstructionErrors_Id_invalidOperand) + { + _alert("\tInvalid Operand Specification\n"); + } + + if (tid == IfxCpu_Trap_InstructionErrors_Id_dataAddressAlignment) + { + _alert("\tData Address Alignment\n"); + } + + if (tid == IfxCpu_Trap_InstructionErrors_Id_invalidMemoryAddress) + { + _alert("\tInvalid Local Memory Address\n"); + } + + up_irq_save(); + PANIC_WITH_REGS("panic", context); + return OK; +} + +int tricore_contexmnttrap(uint32_t tid, void *context, void *arg) +{ + _alert("PANIC!!! Context Management Trap:\n"); + _alert("\tClass %d TID: %" PRId32 " regs: %p\n", + IfxCpu_Trap_Class_contextManagement, tid, context); + + _alert("Context Management Reason:\n"); + if (tid == IfxCpu_Trap_ContextManagement_Id_freeContextListDepletion) + { + _alert("\tFree Context List Depletion\n"); + } + + if (tid == IfxCpu_Trap_ContextManagement_Id_callDepthOverflow) + { + _alert("\tCall Depth Overflow\n"); + } + + if (tid == IfxCpu_Trap_ContextManagement_Id_callDepthUnderflow) + { + _alert("\tCall Depth Underflow\n"); + } + + if (tid == IfxCpu_Trap_ContextManagement_Id_freeContextListUnderflow) + { + _alert("\tFree Context List Underflow\n"); + } + + if (tid == IfxCpu_Trap_ContextManagement_Id_callStackUnderflow) + { + _alert("\tCall Stack Underflow\n"); + } + + if (tid == IfxCpu_Trap_ContextManagement_Id_contextType) + { + _alert("\tContext Type\n"); + } + + if (tid == IfxCpu_Trap_ContextManagement_Id_nestingError) + { + _alert("\tNesting Error:RFE with non-zero call depth\n"); + } + + up_irq_save(); + PANIC_WITH_REGS("panic", context); + return OK; +} + +int tricore_bustrap(uint32_t tid, void *context, void *arg) +{ + _alert("PANIC!!! System Bus Trap:\n"); + _alert("\tClass %d TID: %" PRId32 " regs: %p\n", IfxCpu_Trap_Class_bus, + tid, context); + + _alert("System Bus Reason:\n"); + if (tid == IfxCpu_Trap_Bus_Id_programFetchSynchronousError) + { + _alert("\tProgram Fetch Synchronous Error\n"); + } + + if (tid == IfxCpu_Trap_Bus_Id_dataAccessSynchronousError) + { + _alert("\tData Access Synchronous Error\n"); + } + + if (tid == IfxCpu_Trap_Bus_Id_dataAccessAsynchronousError) + { + _alert("\tData Access Asysnchronous Error\n"); + } + + if (tid == IfxCpu_Trap_Bus_Id_CoprocessorTrapAsynchronousError) + { + _alert("\tCoprocessor Trap Asynchronous Error\n"); + } + + if (tid == IfxCpu_Trap_Bus_Id_programMemoryIntegrityError) + { + _alert("\tProgram Memory Integrity Error\n"); + } + + if (tid == IfxCpu_Trap_Bus_Id_dataMemoryIntegrityError) + { + _alert("\tData Memory Integrity Error\n"); + } + + if (tid == IfxCpu_Trap_Bus_Id_temporalAsynchronousError) + { + _alert("\tTemporal Asynchronous Error\n"); + } + + up_irq_save(); + PANIC_WITH_REGS("panic", context); + return OK; +} + +int tricore_assertiontrap(uint32_t tid, void *context, void *arg) +{ + _alert("PANIC!!! Assertion Trap:\n"); + _alert("\tClass %d TID: %" PRId32 " regs: %p\n", + IfxCpu_Trap_Class_assertion, + tid, context); + + _alert("System Bus Reason:\n"); + if (tid == IfxCpu_Trap_Assertion_Id_arithmeticOverflow) + { + _alert("\tArithmetic Overflow\n"); + } + + if (tid == IfxCpu_Trap_Assertion_Id_stickyArithmeticOverflow) + { + _alert("\tSticky Arithmetic Overflow\n"); + } + + up_irq_save(); + PANIC_WITH_REGS("panic", context); + return OK; +} + /**************************************************************************** * Name: tricore_trapcall * @@ -59,11 +301,79 @@ void tricore_trapcall(volatile void *trap) { uintptr_t *regs; + uintptr_t pcxi; + + IfxCpu_Trap *ctrap = (IfxCpu_Trap *)trap; + IfxCpu_Trap_Class tclass = (IfxCpu_Trap_Class)ctrap->tClass; + unsigned int tid = ctrap->tId; + + tricore_trapinfo(trap); regs = tricore_csa2addr(__mfcr(CPU_PCXI)); + pcxi = regs[REG_UPCXI]; + regs = tricore_csa2addr(pcxi); + + if (!up_interrupt_context()) + { + /* Update the current task's regs */ + + g_running_tasks[this_cpu()]->xcp.regs = regs; + } + + up_set_interrupt_context(true); + + if (tclass == IfxCpu_Trap_Class_memoryManagement) + { + tricore_mmutrap(tid, regs, NULL); + return; + } + + if (tclass == IfxCpu_Trap_Class_internalProtection) + { + tricore_internalprotrape(tid, regs, NULL); + return; + } + + if (tclass == IfxCpu_Trap_Class_instructionErrors) + { + tricore_insterrorstrap(tid, regs, NULL); + return; + } + + if (tclass == IfxCpu_Trap_Class_contextManagement) + { + tricore_contexmnttrap(tid, regs, NULL); + return; + } - up_set_current_regs(regs); + if (tclass == IfxCpu_Trap_Class_bus) + { + tricore_bustrap(tid, regs, NULL); + return; + } + + if (tclass == IfxCpu_Trap_Class_assertion) + { + tricore_assertiontrap(tid, regs, NULL); + return; + } up_irq_save(); - PANIC_WITH_REGS("Trap", up_current_regs()); + PANIC_WITH_REGS("Trap", regs); +} + +/**************************************************************************** + * Function: tricore_trapinit + * + * Description: + * Trap init for tricore arch. + * + ****************************************************************************/ + +void tricore_trapinit(void) +{ +#ifdef CONFIG_COREDUMP + coredump_add_memory_region(&g_trapinfo, sizeof(g_trapinfo), + PF_REGISTER); +#endif } diff --git a/arch/x86_64/include/irq.h b/arch/x86_64/include/irq.h index 8a1db30b81c05..89f6eaa1867b6 100644 --- a/arch/x86_64/include/irq.h +++ b/arch/x86_64/include/irq.h @@ -76,7 +76,7 @@ struct intel64_cpu_s struct tcb_s *this_task; -#ifdef CONFIG_LIB_SYSCALL +#ifdef CONFIG_ARCH_HAVE_SYSCALL /* Current user RSP for syscall */ uint64_t *ustack; diff --git a/arch/x86_64/src/cmake/platform.cmake b/arch/x86_64/src/cmake/platform.cmake index 30b1047094b65..705f0613edd10 100644 --- a/arch/x86_64/src/cmake/platform.cmake +++ b/arch/x86_64/src/cmake/platform.cmake @@ -84,3 +84,34 @@ endif() nuttx_add_extra_library(${EXTRA_LIB}) set(PREPROCESS ${CMAKE_C_COMPILER} ${CMAKE_C_FLAG_ARGS} -E -P -x c) + +if(CONFIG_ARCH_MULTIBOOT1) + message(STATUS "Generating: nuttx.mb1 in ELF32/multiboot1") + if(CONFIG_ALLSYMS) + set(FINAL_NUTTX_ELF "${CMAKE_BINARY_DIR}/final_nuttx") + else() + set(FINAL_NUTTX_ELF "${CMAKE_BINARY_DIR}/nuttx") + endif() + set(NUTTX_ELF "${CMAKE_BINARY_DIR}/nuttx") + set(NUTTX_BIN "${NUTTX_ELF}.bin") + set(NUTTX_REALMODE_BIN "${NUTTX_ELF}_realmode.bin") + set(NUTTX_MB1 "${NUTTX_ELF}.mb1") + add_custom_command( + OUTPUT ${NUTTX_BIN} ${NUTTX_REALMODE_BIN} + COMMAND ${CMAKE_OBJCOPY} -R .realmode -R .note.* -O binary + ${FINAL_NUTTX_ELF} ${NUTTX_BIN} + COMMAND ${CMAKE_OBJCOPY} -j .realmode -O binary ${FINAL_NUTTX_ELF} + ${NUTTX_REALMODE_BIN} + DEPENDS ${FINAL_NUTTX_ELF} + COMMENT "Generating binary and realmode segments from nuttx ELF") + add_custom_command( + OUTPUT ${NUTTX_MB1} + COMMAND + ${CMAKE_C_COMPILER} -m32 -no-pie -nostdlib -DNUTTX_BIN='"${NUTTX_BIN}"' + -DNUTTX_REALMODE_BIN='"${NUTTX_REALMODE_BIN}"' + ${CMAKE_SOURCE_DIR}/arch/x86_64/src/common/multiboot1.S -T + ${CMAKE_SOURCE_DIR}/arch/x86_64/src/common/multiboot1.ld -o ${NUTTX_MB1} + DEPENDS ${NUTTX_BIN} ${NUTTX_REALMODE_BIN} + COMMENT "Building nuttx.mb1 multiboot1 image") + add_custom_target(multiboot1 ALL DEPENDS ${NUTTX_MB1}) +endif() diff --git a/arch/x86_64/src/common/CMakeLists.txt b/arch/x86_64/src/common/CMakeLists.txt index c797d00619ee4..045b1aeece8f7 100644 --- a/arch/x86_64/src/common/CMakeLists.txt +++ b/arch/x86_64/src/common/CMakeLists.txt @@ -38,7 +38,7 @@ if(CONFIG_ARCH_HAVE_FORK) list(APPEND SRCS x86_64_fork.c fork.S) endif() -if(CONFIG_LIB_SYSCALL) +if(CONFIG_ARCH_HAVE_SYSCALL) list(APPEND SRCS x86_64_syscall.c) endif() diff --git a/arch/x86_64/src/common/Make.defs b/arch/x86_64/src/common/Make.defs index f63e2cbce822f..47e1dc16a19b4 100644 --- a/arch/x86_64/src/common/Make.defs +++ b/arch/x86_64/src/common/Make.defs @@ -34,7 +34,7 @@ CMN_CSRCS += x86_64_fork.c CMN_ASRCS += fork.S endif -ifeq ($(CONFIG_LIB_SYSCALL),y) +ifeq ($(CONFIG_ARCH_HAVE_SYSCALL),y) CMN_CSRCS += x86_64_syscall.c endif diff --git a/arch/x86_64/src/common/fork.S b/arch/x86_64/src/common/fork.S index f526a5fa9569d..1621b560474a1 100644 --- a/arch/x86_64/src/common/fork.S +++ b/arch/x86_64/src/common/fork.S @@ -118,10 +118,14 @@ up_fork: pushq %r12 movq %rsp, %rdi + subq $8, %rsp + /* call function */ callq x86_64_fork + addq $8, %rsp + /* Do not modify return value %rax */ /* Restore non-volatile registers */ diff --git a/arch/x86_64/src/common/x86_64_syscall.c b/arch/x86_64/src/common/x86_64_syscall.c index 960b992bb0210..833c191bf5bcb 100644 --- a/arch/x86_64/src/common/x86_64_syscall.c +++ b/arch/x86_64/src/common/x86_64_syscall.c @@ -109,7 +109,10 @@ uint64_t *x86_64_syscall(uint64_t *regs) uint64_t arg4 = regs[REG_R10]; uint64_t arg5 = regs[REG_R8]; uint64_t arg6 = regs[REG_R9]; - uintptr_t ret = 0; + + UNUSED(arg4); + UNUSED(arg5); + UNUSED(arg6); /* The syscall command is in RAX on entry */ @@ -293,11 +296,13 @@ uint64_t *x86_64_syscall(uint64_t *regs) default: { +#ifdef CONFIG_LIB_SYSCALL int nbr = cmd - CONFIG_SYS_RESERVED; - struct tcb_s *rtcb = nxsched_self(); syscall_stub_t stub = (syscall_stub_t)g_stublookup[nbr]; #ifdef CONFIG_ARCH_KERNEL_STACK + struct tcb_s *rtcb = nxsched_self(); + /* Store reference to user RSP for signals */ rtcb->xcp.saved_ursp = regs[REG_RSP]; @@ -312,20 +317,18 @@ uint64_t *x86_64_syscall(uint64_t *regs) up_irq_restore(X86_64_RFLAGS_IF); } - /* Call syscall function */ - - ret = stub(nbr, arg1, arg2, arg3, arg4, arg5, arg6); + /* Call syscall function and store return value in RAX register */ + regs[REG_RAX] = stub(nbr, arg1, arg2, arg3, arg4, arg5, arg6); +#else + svcerr("ERROR: Bad SYS call: %" PRId32 "\n", cmd); +#endif break; } } dump_syscall("Exit", regs); - /* Store return value in RAX register */ - - regs[REG_RAX] = ret; - /* Return pointer to regs */ return regs; diff --git a/arch/x86_64/src/intel64/Kconfig b/arch/x86_64/src/intel64/Kconfig index 9787d9896701e..1d13fce8a7a1d 100644 --- a/arch/x86_64/src/intel64/Kconfig +++ b/arch/x86_64/src/intel64/Kconfig @@ -23,10 +23,10 @@ config ARCH_INTEL64_HAVE_TSC config ARCH_INTEL64_HAS_TSC_ADJUST bool "MSR_IA32_TSC_ADJUST support" - depends on ARCH_INTEL64_HAVE_TSC + depends on ARCH_INTEL64_HAVE_TSC && SCHED_TICKLESS default y ---help--- - MSR_IA32_TSC_ADJUST is used to adjust the offset of the Time Stamp Counter (TSC). + MSR_IA32_TSC_ADJUST is used to adjust the offset of the Time Stamp Counter (TSC). config ARCH_INTEL64_CACHE_LINESIZE diff --git a/arch/x86_64/src/intel64/intel64_cpu.c b/arch/x86_64/src/intel64/intel64_cpu.c index f93289ae789e4..2f91da3f15beb 100644 --- a/arch/x86_64/src/intel64/intel64_cpu.c +++ b/arch/x86_64/src/intel64/intel64_cpu.c @@ -244,7 +244,7 @@ void x86_64_cpu_init(void) g_cpu_priv[i].loapic_id = lapic->apic_id; g_cpu_priv[i].id = i; g_cpu_priv[i].ready = false; -#ifdef CONFIG_LIB_SYSCALL +#ifdef CONFIG_ARCH_HAVE_SYSCALL g_cpu_priv[i].ustack = NULL; g_cpu_priv[i].uvbase = (uint64_t *)CONFIG_ARCH_TEXT_VBASE; #endif @@ -383,7 +383,7 @@ void x86_64_cpu_priv_set(uint8_t cpu) write_gsbase((uintptr_t)&g_cpu_priv[cpu]); -#ifdef CONFIG_LIB_SYSCALL +#ifdef CONFIG_ARCH_HAVE_SYSCALL /* Configure SYSCALL instruction entry point */ write_msr(MSR_LSTAR, (uintptr_t)x86_64_syscall_entry); diff --git a/arch/x86_64/src/intel64/intel64_head.S b/arch/x86_64/src/intel64/intel64_head.S index 154c849344f42..060d3d184f385 100644 --- a/arch/x86_64/src/intel64/intel64_head.S +++ b/arch/x86_64/src/intel64/intel64_head.S @@ -80,7 +80,7 @@ .global __enable_sse_avx .global __enable_pcid .global __revoke_low_memory -#ifdef CONFIG_LIB_SYSCALL +#ifdef CONFIG_ARCH_HAVE_SYSCALL .global x86_64_syscall_entry .global x86_64_syscall #endif @@ -348,7 +348,7 @@ start64_init: movl $MSR_EFER, %ecx rdmsr -#ifdef CONFIG_LIB_SYSCALL +#ifdef CONFIG_ARCH_HAVE_SYSCALL or $(EFER_LME | EFER_SCE), %eax #else or $EFER_LME, %eax @@ -536,7 +536,7 @@ __enable_pcid: .size __enable_pcid, . - __enable_pcid -#ifdef CONFIG_LIB_SYSCALL +#ifdef CONFIG_ARCH_HAVE_SYSCALL /**************************************************************************** * Name: x86_64_syscall_entry * @@ -696,6 +696,10 @@ no_kstack_switch: syscall_no_ring3: # endif + /* Restore the value of RFLAGS from R11 */ + pushq %r11 + popfq + /* Return to address pointed in RCX - must be on stack */ pushq %rcx ret diff --git a/arch/x86_64/src/intel64/intel64_saveusercontext.S b/arch/x86_64/src/intel64/intel64_saveusercontext.S index 7e40f91035d3b..78151d090304f 100644 --- a/arch/x86_64/src/intel64/intel64_saveusercontext.S +++ b/arch/x86_64/src/intel64/intel64_saveusercontext.S @@ -105,7 +105,7 @@ up_saveusercontext: movq %rbp, (8*REG_RBP)(%rdi) -#ifdef CONFIG_LIB_SYSCALL +#ifdef CONFIG_ARCH_HAVE_SYSCALL /* Save CS and SS if we support syscalls */ xor %rax, %rax mov %cs, %ax diff --git a/arch/x86_64/src/intel64/intel64_tsc_timerisr.c b/arch/x86_64/src/intel64/intel64_tsc_timerisr.c index b2dc70e435407..23d9eadda4ce1 100644 --- a/arch/x86_64/src/intel64/intel64_tsc_timerisr.c +++ b/arch/x86_64/src/intel64/intel64_tsc_timerisr.c @@ -55,7 +55,7 @@ * Private Data ****************************************************************************/ -unsigned long g_x86_64_timer_freq; +extern unsigned long g_x86_64_timer_freq; /**************************************************************************** * Private Functions diff --git a/arch/xtensa/src/esp32/esp32_tickless.c b/arch/xtensa/src/esp32/esp32_tickless.c index c57661cf6fa8f..d621f7d71c310 100644 --- a/arch/xtensa/src/esp32/esp32_tickless.c +++ b/arch/xtensa/src/esp32/esp32_tickless.c @@ -270,7 +270,7 @@ static int up_timer_expire(int irq, void *regs, void *arg) if (do_sched) { up_timer_cancel(NULL); - nxsched_timer_expiration(); + nxsched_process_timer(); } } else @@ -340,7 +340,7 @@ int IRAM_ATTR up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -415,14 +415,14 @@ int IRAM_ATTR up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/xtensa/src/esp32s3/esp32s3_tickless.c b/arch/xtensa/src/esp32s3/esp32s3_tickless.c index fc5e56c7453dc..e8357b5eb95db 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_tickless.c +++ b/arch/xtensa/src/esp32s3/esp32s3_tickless.c @@ -255,7 +255,7 @@ static int IRAM_ATTR tickless_isr(int irq, void *context, void *arg) return OK; } - nxsched_timer_expiration(); + nxsched_process_timer(); return OK; } @@ -319,7 +319,7 @@ int IRAM_ATTR up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -397,14 +397,14 @@ int IRAM_ATTR up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/boards/arm/am335x/beaglebone-black/CMakeLists.txt b/boards/arm/am335x/beaglebone-black/CMakeLists.txt new file mode 100644 index 0000000000000..152e98405a698 --- /dev/null +++ b/boards/arm/am335x/beaglebone-black/CMakeLists.txt @@ -0,0 +1,23 @@ +# ############################################################################## +# boards/arm/am335x/beaglebone-black/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you 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. +# +# ############################################################################## + +add_subdirectory(src) diff --git a/boards/arm/am335x/beaglebone-black/src/CMakeLists.txt b/boards/arm/am335x/beaglebone-black/src/CMakeLists.txt new file mode 100644 index 0000000000000..90057ac2ca6fd --- /dev/null +++ b/boards/arm/am335x/beaglebone-black/src/CMakeLists.txt @@ -0,0 +1,39 @@ +# ############################################################################## +# boards/arm/am335x/beaglebone-black/src/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you 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. +# +# ############################################################################## + +set(SRCS am335x_boot.c am335x_bringup.c am335x_leds.c) + +if(CONFIG_BOARDCTL) + list(APPEND SRCS am335x_appinit.c) +endif() + +if(CONFIG_ARCH_BUTTONS) + list(APPEND SRCS am335x_buttons.c) +endif() + +if(CONFIG_AM335X_LCDC) + list(APPEND SRCS am335x_lcd.c) +endif() + +target_sources(board PRIVATE ${SRCS}) + +set_property(GLOBAL PROPERTY LD_SCRIPT "${NUTTX_BOARD_DIR}/scripts/sdram.ld") diff --git a/boards/arm/gd32f4/gd32f450zk-aiotbox/src/gd32f4xx_romfs.c b/boards/arm/gd32f4/gd32f450zk-aiotbox/src/gd32f4xx_romfs.c index 6f81c0ed4a6fc..8e17344333c15 100644 --- a/boards/arm/gd32f4/gd32f450zk-aiotbox/src/gd32f4xx_romfs.c +++ b/boards/arm/gd32f4/gd32f450zk-aiotbox/src/gd32f4xx_romfs.c @@ -69,7 +69,7 @@ ****************************************************************************/ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 16 \n" " .globl romfs_data_begin \n" "romfs_data_begin: \n" diff --git a/boards/arm/gd32f4/gd32f450zk-eval/src/gd32f4xx_romfs.c b/boards/arm/gd32f4/gd32f450zk-eval/src/gd32f4xx_romfs.c index a77bd149721fc..73fa182b78f44 100644 --- a/boards/arm/gd32f4/gd32f450zk-eval/src/gd32f4xx_romfs.c +++ b/boards/arm/gd32f4/gd32f450zk-eval/src/gd32f4xx_romfs.c @@ -69,7 +69,7 @@ ****************************************************************************/ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 16 \n" " .globl romfs_data_begin \n" "romfs_data_begin: \n" diff --git a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.c b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.c index 91e0b0df63618..667ef8b345d70 100644 --- a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.c +++ b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.c @@ -69,7 +69,7 @@ ****************************************************************************/ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 16 \n" " .globl romfs_data_begin \n" "romfs_data_begin: \n" diff --git a/boards/arm/gd32f4/gd32f470zk-aiotbox/src/gd32f4xx_romfs.c b/boards/arm/gd32f4/gd32f470zk-aiotbox/src/gd32f4xx_romfs.c index 3dcd603c46ddc..a5a162fb61003 100644 --- a/boards/arm/gd32f4/gd32f470zk-aiotbox/src/gd32f4xx_romfs.c +++ b/boards/arm/gd32f4/gd32f470zk-aiotbox/src/gd32f4xx_romfs.c @@ -69,7 +69,7 @@ ****************************************************************************/ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 16 \n" " .globl romfs_data_begin \n" "romfs_data_begin: \n" diff --git a/boards/arm/gd32f4/gd32f470zk-eval/src/gd32f4xx_romfs.c b/boards/arm/gd32f4/gd32f470zk-eval/src/gd32f4xx_romfs.c index e201cbeda3db9..1794fc6ab6342 100644 --- a/boards/arm/gd32f4/gd32f470zk-eval/src/gd32f4xx_romfs.c +++ b/boards/arm/gd32f4/gd32f470zk-eval/src/gd32f4xx_romfs.c @@ -69,7 +69,7 @@ ****************************************************************************/ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 16 \n" " .globl romfs_data_begin \n" "romfs_data_begin: \n" diff --git a/boards/arm/kinetis/freedom-k28f/src/k28_usbhshost.c b/boards/arm/kinetis/freedom-k28f/src/k28_usbhshost.c index f10e3218a433c..6e109c885152b 100644 --- a/boards/arm/kinetis/freedom-k28f/src/k28_usbhshost.c +++ b/boards/arm/kinetis/freedom-k28f/src/k28_usbhshost.c @@ -377,7 +377,7 @@ static void usb_msc_disconnect(void *arg) else { - ferr("ERROR: Unmount failed: %d\n", errcode); + ferr("ERROR: Unmount failed: %d\n", ret); } } } diff --git a/boards/arm/lpc17xx_40xx/pnev5180b/src/lpc17_40_romfs.c b/boards/arm/lpc17xx_40xx/pnev5180b/src/lpc17_40_romfs.c index 2d22cb139c58b..7570b09d80397 100644 --- a/boards/arm/lpc17xx_40xx/pnev5180b/src/lpc17_40_romfs.c +++ b/boards/arm/lpc17xx_40xx/pnev5180b/src/lpc17_40_romfs.c @@ -69,7 +69,7 @@ ****************************************************************************/ __asm__ ( - ".section .rodata\n" + ".section .rodata, \"a\"\n" ".balign 16\n" ".globl romfs_data_begin\n" "romfs_data_begin:\n" diff --git a/boards/arm/lpc54xx/lpcxpresso-lpc54628/configs/netnsh/defconfig b/boards/arm/lpc54xx/lpcxpresso-lpc54628/configs/netnsh/defconfig index e137fea389bd3..cbba6d078db66 100644 --- a/boards/arm/lpc54xx/lpcxpresso-lpc54628/configs/netnsh/defconfig +++ b/boards/arm/lpc54xx/lpcxpresso-lpc54628/configs/netnsh/defconfig @@ -43,6 +43,7 @@ CONFIG_NET_ICMPv6=y CONFIG_NET_ICMPv6_NEIGHBOR=y CONFIG_NET_ICMPv6_SOCKET=y CONFIG_NET_IPv6=y +CONFIG_NET_SOCKOPTS=y CONFIG_NET_STATISTICS=y CONFIG_NET_TCP=y CONFIG_NET_TCP_WRITE_BUFFERS=y diff --git a/boards/arm/stm32/nucleo-f429zi/src/stm32_romfs_initialize.c b/boards/arm/stm32/nucleo-f429zi/src/stm32_romfs_initialize.c index feceef0b1167f..61ea69b5dab50 100644 --- a/boards/arm/stm32/nucleo-f429zi/src/stm32_romfs_initialize.c +++ b/boards/arm/stm32/nucleo-f429zi/src/stm32_romfs_initialize.c @@ -71,7 +71,7 @@ ****************************************************************************/ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 16 \n" " .globl romfs_data_begin \n" "romfs_data_begin: \n" diff --git a/boards/arm/stm32/nucleo-f446re/src/stm32_romfs_initialize.c b/boards/arm/stm32/nucleo-f446re/src/stm32_romfs_initialize.c index 4bb1c495fc0d8..e984d4d194802 100644 --- a/boards/arm/stm32/nucleo-f446re/src/stm32_romfs_initialize.c +++ b/boards/arm/stm32/nucleo-f446re/src/stm32_romfs_initialize.c @@ -71,7 +71,7 @@ ****************************************************************************/ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 16 \n" " .globl romfs_data_begin \n" "romfs_data_begin: \n" diff --git a/boards/arm/stm32/omnibusf4/src/stm32_romfs_initialize.c b/boards/arm/stm32/omnibusf4/src/stm32_romfs_initialize.c index c5418c4f1e8d5..3f5e6e9e3df80 100644 --- a/boards/arm/stm32/omnibusf4/src/stm32_romfs_initialize.c +++ b/boards/arm/stm32/omnibusf4/src/stm32_romfs_initialize.c @@ -83,7 +83,7 @@ ****************************************************************************/ __asm__ ( - ".section .rodata\n" + ".section .rodata, \"a\"\n" ".balign 16\n" ".globl romfs_data_begin\n" "romfs_data_begin:\n" diff --git a/boards/arm/stm32/stm32f103-minimum/src/stm32_gpio.c b/boards/arm/stm32/stm32f103-minimum/src/stm32_gpio.c index 8e91c3c77a793..34685edc3f1d9 100644 --- a/boards/arm/stm32/stm32f103-minimum/src/stm32_gpio.c +++ b/boards/arm/stm32/stm32f103-minimum/src/stm32_gpio.c @@ -62,18 +62,25 @@ struct stm32gpint_dev_s * Private Function Prototypes ****************************************************************************/ +#if BOARD_NGPIOIN > 0 static int gpin_read(struct gpio_dev_s *dev, bool *value); +#endif /* BOARD_NGPIOIN > 0 */ +#if BOARD_NGPIOOUT > 0 static int gpout_read(struct gpio_dev_s *dev, bool *value); static int gpout_write(struct gpio_dev_s *dev, bool value); +#endif /* BOARD_NGPIOOUT > 0 */ +#if BOARD_NGPIOINT > 0 static int gpint_read(struct gpio_dev_s *dev, bool *value); static int gpint_attach(struct gpio_dev_s *dev, pin_interrupt_t callback); static int gpint_enable(struct gpio_dev_s *dev, bool enable); +#endif /* BOARD_NGPIOINT > 0 */ /**************************************************************************** * Private Data ****************************************************************************/ +#if BOARD_NGPIOIN > 0 static const struct gpio_operations_s gpin_ops = { .go_read = gpin_read, @@ -81,7 +88,9 @@ static const struct gpio_operations_s gpin_ops = .go_attach = NULL, .go_enable = NULL, }; +#endif /* BOARD_NGPIOIN > 0 */ +#if BOARD_NGPIOOUT > 0 static const struct gpio_operations_s gpout_ops = { .go_read = gpout_read, @@ -89,7 +98,9 @@ static const struct gpio_operations_s gpout_ops = .go_attach = NULL, .go_enable = NULL, }; +#endif /* BOARD_NGPIOOUT > 0 */ +#if BOARD_NGPIOINT > 0 static const struct gpio_operations_s gpint_ops = { .go_read = gpint_read, @@ -97,6 +108,7 @@ static const struct gpio_operations_s gpint_ops = .go_attach = gpint_attach, .go_enable = gpint_enable, }; +#endif /* BOARD_NGPIOINT > 0 */ #if BOARD_NGPIOIN > 0 /* This array maps the GPIO pins used as INPUT */ @@ -109,7 +121,7 @@ static const uint32_t g_gpioinputs[BOARD_NGPIOIN] = static struct stm32gpio_dev_s g_gpin[BOARD_NGPIOIN]; #endif -#if BOARD_NGPIOOUT +#if BOARD_NGPIOOUT > 0 /* This array maps the GPIO pins used as OUTPUT */ static const uint32_t g_gpiooutputs[BOARD_NGPIOOUT] = @@ -135,6 +147,7 @@ static struct stm32gpint_dev_s g_gpint[BOARD_NGPIOINT]; * Private Functions ****************************************************************************/ + #if BOARD_NGPIOINT > 0 static int stm32gpio_interrupt(int irq, void *context, void *arg) { struct stm32gpint_dev_s *stm32gpint = @@ -147,7 +160,9 @@ static int stm32gpio_interrupt(int irq, void *context, void *arg) stm32gpint->stm32gpio.id); return OK; } +#endif /* BOARD_NGPIOINT > 0 */ +#if BOARD_NGPIOIN > 0 static int gpin_read(struct gpio_dev_s *dev, bool *value) { struct stm32gpio_dev_s *stm32gpio = @@ -160,7 +175,9 @@ static int gpin_read(struct gpio_dev_s *dev, bool *value) *value = stm32_gpioread(g_gpioinputs[stm32gpio->id]); return OK; } +#endif /* BOARD_NGPIOIN > 0*/ +#if BOARD_NGPIOOUT > 0 static int gpout_read(struct gpio_dev_s *dev, bool *value) { struct stm32gpio_dev_s *stm32gpio = @@ -186,7 +203,9 @@ static int gpout_write(struct gpio_dev_s *dev, bool value) stm32_gpiowrite(g_gpiooutputs[stm32gpio->id], value); return OK; } +#endif /* BOARD_NGPIOOUT > 0 */ +#if BOARD_NGPIOINT > 0 static int gpint_read(struct gpio_dev_s *dev, bool *value) { struct stm32gpint_dev_s *stm32gpint = @@ -245,6 +264,7 @@ static int gpint_enable(struct gpio_dev_s *dev, bool enable) return OK; } +#endif /* BOARD_NGPIOINT > 0 */ /**************************************************************************** * Public Functions diff --git a/boards/arm/stm32/stm32f4discovery/configs/testlibcxx/defconfig b/boards/arm/stm32/stm32f4discovery/configs/testlibcxx/defconfig index fd17d3158312a..c31179247f3c4 100644 --- a/boards/arm/stm32/stm32f4discovery/configs/testlibcxx/defconfig +++ b/boards/arm/stm32/stm32f4discovery/configs/testlibcxx/defconfig @@ -23,6 +23,7 @@ CONFIG_HAVE_CXX=y CONFIG_INIT_ENTRYPOINT="nsh_main" CONFIG_INTELHEX_BINARY=y CONFIG_LIBCXX=y +CONFIG_LIBCXXABI=y CONFIG_LIBC_FLOATINGPOINT=y CONFIG_LIBC_LOCALE=y CONFIG_LIBC_LOCALTIME=y @@ -36,6 +37,7 @@ CONFIG_RAM_SIZE=114688 CONFIG_RAM_START=0x20000000 CONFIG_RAW_BINARY=y CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_THREAD_LOCAL=y CONFIG_SCHED_WAITPID=y CONFIG_START_DAY=2 CONFIG_START_MONTH=11 @@ -49,3 +51,6 @@ CONFIG_TLS_TASK_NELEM=8 CONFIG_USART2_RXBUFSIZE=128 CONFIG_USART2_SERIAL_CONSOLE=y CONFIG_USART2_TXBUFSIZE=128 +CONFIG_CXX_EXCEPTION=y +CONFIG_CXX_RTTI=y +CONFIG_TESTING_CXXTEST=y diff --git a/boards/arm/stm32/stm32f4discovery/src/stm32_romfs_initialize.c b/boards/arm/stm32/stm32f4discovery/src/stm32_romfs_initialize.c index 1c453643f5dfd..e52b94b231808 100644 --- a/boards/arm/stm32/stm32f4discovery/src/stm32_romfs_initialize.c +++ b/boards/arm/stm32/stm32f4discovery/src/stm32_romfs_initialize.c @@ -84,7 +84,7 @@ ****************************************************************************/ __asm__ ( - ".section .rodata\n" + ".section .rodata, \"a\"\n" ".balign 16\n" ".globl romfs_data_begin\n" "romfs_data_begin:\n" diff --git a/boards/arm/stm32f7/common/src/stm32_romfs_initialize.c b/boards/arm/stm32f7/common/src/stm32_romfs_initialize.c index 171e35352e723..4351cbf11666c 100644 --- a/boards/arm/stm32f7/common/src/stm32_romfs_initialize.c +++ b/boards/arm/stm32f7/common/src/stm32_romfs_initialize.c @@ -83,7 +83,7 @@ ****************************************************************************/ __asm__ ( - ".section .rodata\n" + ".section .rodata, \"a\"\n" ".balign 16\n" ".globl romfs_data_begin\n" "romfs_data_begin:\n" diff --git a/boards/arm/stm32h7/nucleo-h743zi/src/stm32_romfs_initialize.c b/boards/arm/stm32h7/nucleo-h743zi/src/stm32_romfs_initialize.c index 241430732717e..4476ebe23156b 100644 --- a/boards/arm/stm32h7/nucleo-h743zi/src/stm32_romfs_initialize.c +++ b/boards/arm/stm32h7/nucleo-h743zi/src/stm32_romfs_initialize.c @@ -69,7 +69,7 @@ ****************************************************************************/ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 16 \n" " .globl romfs_data_begin \n" "romfs_data_begin: \n" diff --git a/boards/arm64/a64/pinephone/configs/lcd/defconfig b/boards/arm64/a64/pinephone/configs/lcd/defconfig index f96772ab24eb9..b2fb74644c300 100644 --- a/boards/arm64/a64/pinephone/configs/lcd/defconfig +++ b/boards/arm64/a64/pinephone/configs/lcd/defconfig @@ -13,6 +13,7 @@ CONFIG_ARCH_BOARD_PINEPHONE=y CONFIG_ARCH_CHIP="a64" CONFIG_ARCH_CHIP_A64=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BOARDCTL_RESET=y CONFIG_BOARD_LOOPSPERMSEC=116524 CONFIG_BUILTIN=y diff --git a/boards/arm64/a64/pinephone/configs/lvgl/defconfig b/boards/arm64/a64/pinephone/configs/lvgl/defconfig index 81b1f6dc1bfcb..afe848365b612 100644 --- a/boards/arm64/a64/pinephone/configs/lvgl/defconfig +++ b/boards/arm64/a64/pinephone/configs/lvgl/defconfig @@ -14,6 +14,7 @@ CONFIG_ARCH_BOARD_PINEPHONE=y CONFIG_ARCH_CHIP="a64" CONFIG_ARCH_CHIP_A64=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BOARDCTL_RESET=y CONFIG_BOARD_LOOPSPERMSEC=116524 CONFIG_BUILTIN=y diff --git a/boards/arm64/a64/pinephone/configs/nsh/defconfig b/boards/arm64/a64/pinephone/configs/nsh/defconfig index 4b41f295da254..22260c9573d04 100644 --- a/boards/arm64/a64/pinephone/configs/nsh/defconfig +++ b/boards/arm64/a64/pinephone/configs/nsh/defconfig @@ -13,6 +13,7 @@ CONFIG_ARCH_BOARD_PINEPHONE=y CONFIG_ARCH_CHIP="a64" CONFIG_ARCH_CHIP_A64=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BOARDCTL_RESET=y CONFIG_BOARD_LOOPSPERMSEC=116524 CONFIG_BUILTIN=y diff --git a/boards/arm64/a64/pinephone/configs/sensor/defconfig b/boards/arm64/a64/pinephone/configs/sensor/defconfig index 3c261f5f0f642..861b3b4d310ac 100644 --- a/boards/arm64/a64/pinephone/configs/sensor/defconfig +++ b/boards/arm64/a64/pinephone/configs/sensor/defconfig @@ -15,6 +15,7 @@ CONFIG_ARCH_BOARD_PINEPHONE=y CONFIG_ARCH_CHIP="a64" CONFIG_ARCH_CHIP_A64=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BOARDCTL_RESET=y CONFIG_BOARD_LOOPSPERMSEC=116524 CONFIG_BUILTIN=y diff --git a/boards/arm64/a64/pinephone/src/pinephone_touch.c b/boards/arm64/a64/pinephone/src/pinephone_touch.c index 138140e2a84ff..3b581f1360389 100644 --- a/boards/arm64/a64/pinephone/src/pinephone_touch.c +++ b/boards/arm64/a64/pinephone/src/pinephone_touch.c @@ -117,7 +117,8 @@ static int pinephone_gt9xx_irq_attach(const struct gt9xx_board_s *state, /* Set Interrupt Priority in Generic Interrupt Controller v2 */ - arm64_gic_irq_set_priority(A64_IRQ_PH_EINT, 0, IRQ_TYPE_EDGE); + up_prioritize_irq(A64_IRQ_PH_EINT, 0); + up_set_irq_type(A64_IRQ_PH_EINT, IRQ_RISING_EDGE); /* Enable Interrupts for Port PH */ diff --git a/boards/arm64/bcm2711/raspberrypi-4b/configs/cgol/defconfig b/boards/arm64/bcm2711/raspberrypi-4b/configs/cgol/defconfig index 90a30df936bac..ba110299cde40 100644 --- a/boards/arm64/bcm2711/raspberrypi-4b/configs/cgol/defconfig +++ b/boards/arm64/bcm2711/raspberrypi-4b/configs/cgol/defconfig @@ -14,6 +14,7 @@ CONFIG_ARCH_CHIP="bcm2711" CONFIG_ARCH_CHIP_BCM2711=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BCM2711_FRAMEBUFFER=y CONFIG_BOARD_LOOPSPERMSEC=132954 CONFIG_BUILTIN=y diff --git a/boards/arm64/bcm2711/raspberrypi-4b/configs/fb/defconfig b/boards/arm64/bcm2711/raspberrypi-4b/configs/fb/defconfig index a8268ea2cd786..0459e7f031cb1 100644 --- a/boards/arm64/bcm2711/raspberrypi-4b/configs/fb/defconfig +++ b/boards/arm64/bcm2711/raspberrypi-4b/configs/fb/defconfig @@ -14,6 +14,7 @@ CONFIG_ARCH_CHIP="bcm2711" CONFIG_ARCH_CHIP_BCM2711=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BCM2711_FRAMEBUFFER=y CONFIG_BOARD_LOOPSPERMSEC=132954 CONFIG_BUILTIN=y diff --git a/boards/arm64/bcm2711/raspberrypi-4b/configs/lvgl/defconfig b/boards/arm64/bcm2711/raspberrypi-4b/configs/lvgl/defconfig index d959a08a0c4d4..539f85ad073c0 100644 --- a/boards/arm64/bcm2711/raspberrypi-4b/configs/lvgl/defconfig +++ b/boards/arm64/bcm2711/raspberrypi-4b/configs/lvgl/defconfig @@ -14,6 +14,7 @@ CONFIG_ARCH_CHIP="bcm2711" CONFIG_ARCH_CHIP_BCM2711=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BCM2711_FRAMEBUFFER=y CONFIG_BOARD_LATE_INITIALIZE=y CONFIG_BOARD_LOOPSPERMSEC=132954 diff --git a/boards/arm64/bcm2711/raspberrypi-4b/configs/nsh/defconfig b/boards/arm64/bcm2711/raspberrypi-4b/configs/nsh/defconfig index d0ddcd64efca1..5d0766b5262dc 100644 --- a/boards/arm64/bcm2711/raspberrypi-4b/configs/nsh/defconfig +++ b/boards/arm64/bcm2711/raspberrypi-4b/configs/nsh/defconfig @@ -13,6 +13,7 @@ CONFIG_ARCH_CHIP="bcm2711" CONFIG_ARCH_CHIP_BCM2711=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BOARD_LOOPSPERMSEC=132954 CONFIG_BUILTIN=y CONFIG_DEBUG_ASSERTIONS=y diff --git a/boards/arm64/bcm2711/raspberrypi-4b/configs/sd/defconfig b/boards/arm64/bcm2711/raspberrypi-4b/configs/sd/defconfig index a521ef1b36d92..af3389573a0c0 100644 --- a/boards/arm64/bcm2711/raspberrypi-4b/configs/sd/defconfig +++ b/boards/arm64/bcm2711/raspberrypi-4b/configs/sd/defconfig @@ -14,6 +14,7 @@ CONFIG_ARCH_CHIP="bcm2711" CONFIG_ARCH_CHIP_BCM2711=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BCM2711_EMMC2=y CONFIG_BCM2711_EMMC=y CONFIG_BOARD_LOOPSPERMSEC=132954 diff --git a/boards/arm64/rk3399/nanopi_m4/configs/nsh/defconfig b/boards/arm64/rk3399/nanopi_m4/configs/nsh/defconfig index 5bbde6996df2f..0ad77abe8fd37 100644 --- a/boards/arm64/rk3399/nanopi_m4/configs/nsh/defconfig +++ b/boards/arm64/rk3399/nanopi_m4/configs/nsh/defconfig @@ -14,6 +14,7 @@ CONFIG_ARCH_CHIP="rk3399" CONFIG_ARCH_CHIP_RK3399=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BOARD_LOOPSPERMSEC=116524 CONFIG_BUILTIN=y CONFIG_DEBUG_ASSERTIONS=y diff --git a/boards/arm64/rk3399/pinephonepro/configs/nsh/defconfig b/boards/arm64/rk3399/pinephonepro/configs/nsh/defconfig index 7ceae852668df..4cdda4dd59947 100644 --- a/boards/arm64/rk3399/pinephonepro/configs/nsh/defconfig +++ b/boards/arm64/rk3399/pinephonepro/configs/nsh/defconfig @@ -14,6 +14,7 @@ CONFIG_ARCH_CHIP="rk3399" CONFIG_ARCH_CHIP_RK3399=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BOARD_LOOPSPERMSEC=116524 CONFIG_BUILTIN=y CONFIG_DEBUG_ASSERTIONS=y diff --git a/boards/arm64/zynq-mpsoc/zcu111/configs/jtag/defconfig b/boards/arm64/zynq-mpsoc/zcu111/configs/jtag/defconfig index 2d00862bcb16d..97737c569f6e9 100644 --- a/boards/arm64/zynq-mpsoc/zcu111/configs/jtag/defconfig +++ b/boards/arm64/zynq-mpsoc/zcu111/configs/jtag/defconfig @@ -15,6 +15,7 @@ CONFIG_ARCH_CHIP="zynq-mpsoc" CONFIG_ARCH_CHIP_ZYNQ_MPSOC=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_ARM64_DCACHE_DISABLE=y CONFIG_ARM64_GIC_VERSION=2 CONFIG_ARM64_ICACHE_DISABLE=y diff --git a/boards/arm64/zynq-mpsoc/zcu111/configs/netjtag/defconfig b/boards/arm64/zynq-mpsoc/zcu111/configs/netjtag/defconfig index 8775f4cdce8a1..f64751f4409f5 100644 --- a/boards/arm64/zynq-mpsoc/zcu111/configs/netjtag/defconfig +++ b/boards/arm64/zynq-mpsoc/zcu111/configs/netjtag/defconfig @@ -15,6 +15,7 @@ CONFIG_ARCH_CHIP="zynq-mpsoc" CONFIG_ARCH_CHIP_ZYNQ_MPSOC=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_ARM64_DCACHE_DISABLE=y CONFIG_ARM64_GIC_VERSION=2 CONFIG_ARM64_ICACHE_DISABLE=y diff --git a/boards/arm64/zynq-mpsoc/zcu111/configs/netnsh/defconfig b/boards/arm64/zynq-mpsoc/zcu111/configs/netnsh/defconfig index ed7f23b3a6752..91c5b72030569 100644 --- a/boards/arm64/zynq-mpsoc/zcu111/configs/netnsh/defconfig +++ b/boards/arm64/zynq-mpsoc/zcu111/configs/netnsh/defconfig @@ -13,6 +13,7 @@ CONFIG_ARCH_CHIP="zynq-mpsoc" CONFIG_ARCH_CHIP_ZYNQ_MPSOC=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_ARM64_DCACHE_DISABLE=y CONFIG_ARM64_GIC_VERSION=2 CONFIG_ARM64_ICACHE_DISABLE=y diff --git a/boards/arm64/zynq-mpsoc/zcu111/configs/nsh/defconfig b/boards/arm64/zynq-mpsoc/zcu111/configs/nsh/defconfig index 74b9e4a22c66f..1d7c7bbdf5773 100644 --- a/boards/arm64/zynq-mpsoc/zcu111/configs/nsh/defconfig +++ b/boards/arm64/zynq-mpsoc/zcu111/configs/nsh/defconfig @@ -13,6 +13,7 @@ CONFIG_ARCH_CHIP="zynq-mpsoc" CONFIG_ARCH_CHIP_ZYNQ_MPSOC=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_ARM64_DCACHE_DISABLE=y CONFIG_ARM64_GIC_VERSION=2 CONFIG_ARM64_ICACHE_DISABLE=y diff --git a/boards/risc-v/esp32c3/common/scripts/esp32c3_legacy_sections.ld b/boards/risc-v/esp32c3/common/scripts/esp32c3_legacy_sections.ld index 30085c090d3f7..a78f41df69b81 100644 --- a/boards/risc-v/esp32c3/common/scripts/esp32c3_legacy_sections.ld +++ b/boards/risc-v/esp32c3/common/scripts/esp32c3_legacy_sections.ld @@ -72,9 +72,25 @@ SECTIONS *(.noinit.*) } >dram0_0_seg + .tbss (NOLOAD) : + { + . = ALIGN(4); + _stbss = ABSOLUTE(.); + *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon) + _etbss = ABSOLUTE(.); + . = ALIGN(4); + } >dram0_0_seg + .dram0.data : { + . = ALIGN(4); + _stdata = ABSOLUTE(.); + *(.tdata .tdata.* .gnu.linkonce.td.*) + _etdata = ABSOLUTE(.); + . = ALIGN(4); + _sdata = ABSOLUTE(.); + *(.data) *(.data.*) *(.gnu.linkonce.d.*) diff --git a/boards/risc-v/esp32c3/common/scripts/esp32c3_sections.ld b/boards/risc-v/esp32c3/common/scripts/esp32c3_sections.ld index a17778cd55afc..34e62006d6789 100644 --- a/boards/risc-v/esp32c3/common/scripts/esp32c3_sections.ld +++ b/boards/risc-v/esp32c3/common/scripts/esp32c3_sections.ld @@ -248,10 +248,26 @@ SECTIONS . = ALIGN(4) ; } >dram0_0_seg + .tbss (NOLOAD) : + { + . = ALIGN(4); + _stbss = ABSOLUTE(.); + *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon) + _etbss = ABSOLUTE(.); + . = ALIGN(4); + } >dram0_0_seg + .dram0.data : { . = ALIGN (16); _data_start = ABSOLUTE(.); + + . = ALIGN(4); + _stdata = ABSOLUTE(.); + *(.tdata .tdata.* .gnu.linkonce.td.*) + _etdata = ABSOLUTE(.); + . = ALIGN(4); + _sdata = ABSOLUTE(.); *(.data) *(.data.*) @@ -511,6 +527,7 @@ SECTIONS __init_array_start = ABSOLUTE(.); KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) __init_array_end = ABSOLUTE(.); + _einit = ABSOLUTE(.); /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ @@ -526,8 +543,6 @@ SECTIONS KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) _esp_system_init_fn_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); - } >default_rodata_seg AT > ROM .flash.rodata_noload (NOLOAD) : diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/configs/testlibcxx/defconfig b/boards/risc-v/esp32c3/esp32c3-devkit/configs/testlibcxx/defconfig new file mode 100644 index 0000000000000..7c73421feaed8 --- /dev/null +++ b/boards/risc-v/esp32c3/esp32c3-devkit/configs/testlibcxx/defconfig @@ -0,0 +1,60 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="esp32c3-devkit" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_ESP32C3_DEVKIT=y +CONFIG_ARCH_CHIP="esp32c3" +CONFIG_ARCH_CHIP_ESP32C3=y +CONFIG_ARCH_INTERRUPTSTACK=1536 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_LOOPSPERMSEC=15000 +CONFIG_BUILTIN=y +CONFIG_FS_PROCFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=0 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_BACKTRACE=y +CONFIG_SCHED_WAITPID=y +CONFIG_SCHED_THREAD_LOCAL=y +CONFIG_START_DAY=29 +CONFIG_START_MONTH=11 +CONFIG_START_YEAR=2019 +CONFIG_SYSTEM_DUMPSTACK=y +CONFIG_SYSTEM_NSH=y +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_BUILTIN=y +CONFIG_CXX_LOCALIZATION=y +CONFIG_CXX_WCHAR=y +CONFIG_EXAMPLES_HELLOXX=y +CONFIG_HAVE_CXX=y +CONFIG_LIBCXX=y +CONFIG_LIBCXXABI=y +CONFIG_CXX_EXCEPTION=y +CONFIG_CXX_RTTI=y +CONFIG_TESTING_CXXTEST=y +CONFIG_LIBC_LOCALE=y +CONFIG_TLS_NELEM=16 +CONFIG_TLS_TASK_NELEM=8 +CONFIG_DEFAULT_TASK_STACKSIZE=4096 diff --git a/boards/risc-v/esp32c3/esp32c3-xiao/configs/ble/defconfig b/boards/risc-v/esp32c3/esp32c3-xiao/configs/ble/defconfig index b85ccf328a750..0f69698320f04 100644 --- a/boards/risc-v/esp32c3/esp32c3-xiao/configs/ble/defconfig +++ b/boards/risc-v/esp32c3/esp32c3-xiao/configs/ble/defconfig @@ -28,8 +28,6 @@ CONFIG_DRIVERS_WIRELESS=y CONFIG_ESPRESSIF_BLE=y CONFIG_ESPRESSIF_USBSERIAL=y CONFIG_FS_PROCFS=y -CONFIG_HAVE_CXX=y -CONFIG_HAVE_CXXINITIALIZE=y CONFIG_IDLETHREAD_STACKSIZE=2048 CONFIG_INIT_ENTRYPOINT="nsh_main" CONFIG_INTELHEX_BINARY=y diff --git a/boards/risc-v/esp32c6/common/scripts/esp32c6_sections.ld b/boards/risc-v/esp32c6/common/scripts/esp32c6_sections.ld index cb0c9459457aa..edb0de6f6896f 100644 --- a/boards/risc-v/esp32c6/common/scripts/esp32c6_sections.ld +++ b/boards/risc-v/esp32c6/common/scripts/esp32c6_sections.ld @@ -273,11 +273,28 @@ SECTIONS *(.noinit.*) } >dram0_0_seg + .tbss (NOLOAD) : + { + . = ALIGN(4); + _stbss = ABSOLUTE(.); + *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon) + _etbss = ABSOLUTE(.); + . = ALIGN(4); + } >dram0_0_seg + .dram0.data : { . = ALIGN (16); _data_start = ABSOLUTE(.); + + . = ALIGN(4); + _stdata = ABSOLUTE(.); + *(.tdata .tdata.* .gnu.linkonce.td.*) + _etdata = ABSOLUTE(.); + . = ALIGN(4); + _sdata = ABSOLUTE(.); + *(.data) *(.data.*) *(.gnu.linkonce.d.*) @@ -523,6 +540,7 @@ SECTIONS __init_array_start = ABSOLUTE(.); KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) __init_array_end = ABSOLUTE(.); + _einit = ABSOLUTE(.); /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ @@ -538,8 +556,6 @@ SECTIONS KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) _esp_system_init_fn_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); - } >default_rodata_seg AT > ROM .flash.rodata_noload (NOLOAD) : diff --git a/boards/risc-v/esp32h2/common/scripts/esp32h2_sections.ld b/boards/risc-v/esp32h2/common/scripts/esp32h2_sections.ld index f7c3526db0cad..8d0246fb8165c 100644 --- a/boards/risc-v/esp32h2/common/scripts/esp32h2_sections.ld +++ b/boards/risc-v/esp32h2/common/scripts/esp32h2_sections.ld @@ -264,11 +264,28 @@ SECTIONS *(.noinit.*) } >dram0_0_seg + .tbss (NOLOAD) : + { + . = ALIGN(4); + _stbss = ABSOLUTE(.); + *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon) + _etbss = ABSOLUTE(.); + . = ALIGN(4); + } >dram0_0_seg + .dram0.data : { . = ALIGN (16); _data_start = ABSOLUTE(.); + + . = ALIGN(4); + _stdata = ABSOLUTE(.); + *(.tdata .tdata.* .gnu.linkonce.td.*) + _etdata = ABSOLUTE(.); + . = ALIGN(4); + _sdata = ABSOLUTE(.); + *(.data) *(.data.*) *(.gnu.linkonce.d.*) @@ -513,6 +530,7 @@ SECTIONS _sinit = ABSOLUTE(.); . = ALIGN(4); + _sdata = ABSOLUTE(.); __init_priority_array_start = ABSOLUTE(.); KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)) __init_priority_array_end = ABSOLUTE(.); @@ -521,6 +539,7 @@ SECTIONS __init_array_start = ABSOLUTE(.); KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) __init_array_end = ABSOLUTE(.); + _einit = ABSOLUTE(.); /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ @@ -536,8 +555,6 @@ SECTIONS KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) _esp_system_init_fn_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); - } >default_rodata_seg AT > ROM .flash.rodata_noload (NOLOAD) : diff --git a/boards/risc-v/qemu-rv/rv-virt/configs/citest/defconfig b/boards/risc-v/qemu-rv/rv-virt/configs/citest/defconfig index c711d7defe273..f94782f57f09b 100644 --- a/boards/risc-v/qemu-rv/rv-virt/configs/citest/defconfig +++ b/boards/risc-v/qemu-rv/rv-virt/configs/citest/defconfig @@ -125,6 +125,7 @@ CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_POPEN=y CONFIG_SYSTEM_SETLOGMASK=y CONFIG_TESTING_CMOCKA=y +CONFIG_TESTING_CMOCKA_PROG=y CONFIG_TESTING_CXXTEST=y CONFIG_TESTING_FMEMOPEN_TEST=y CONFIG_TESTING_FOPENCOOKIE_TEST=y diff --git a/boards/sim/sim/sim/configs/citest/defconfig b/boards/sim/sim/sim/configs/citest/defconfig index 6f371fb9a4698..f6a89d075308d 100644 --- a/boards/sim/sim/sim/configs/citest/defconfig +++ b/boards/sim/sim/sim/configs/citest/defconfig @@ -133,6 +133,7 @@ CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_POPEN=y CONFIG_SYSTEM_SETLOGMASK=y CONFIG_TESTING_CMOCKA=y +CONFIG_TESTING_CMOCKA_PROG=y CONFIG_TESTING_CXXTEST=y CONFIG_TESTING_DRIVER_TEST=y CONFIG_TESTING_DRIVER_TEST_SIMPLE=y diff --git a/boards/sim/sim/sim/configs/posix_test/defconfig b/boards/sim/sim/sim/configs/posix_test/defconfig index c9a79c1866424..4e936955c260d 100644 --- a/boards/sim/sim/sim/configs/posix_test/defconfig +++ b/boards/sim/sim/sim/configs/posix_test/defconfig @@ -59,6 +59,8 @@ CONFIG_LIBC_NUMBERED_ARGS=y CONFIG_LIBC_PASSWD_FILE=y CONFIG_MQ_MAXMSGSIZE=64 CONFIG_NDEBUG=y +CONFIG_NET=y +CONFIG_NET_SOCKOPTS=y CONFIG_NSH_ARCHINIT=y CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_FILE_APPS=y @@ -81,7 +83,6 @@ CONFIG_SCHED_LPNTHREADS=1 CONFIG_SCHED_LPWORK=y CONFIG_SCHED_SPORADIC=y CONFIG_SCHED_USER_IDENTITY=y -CONFIG_SCHED_WAITPID=y CONFIG_SIG_DEFAULT=y CONFIG_SIG_EVTHREAD=y CONFIG_SIM_HOSTFS=y @@ -91,6 +92,7 @@ CONFIG_START_MONTH=6 CONFIG_START_YEAR=2008 CONFIG_SYSTEM_DUMPSTACK=y CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_SYSTEM=y CONFIG_TESTING_LTP=y CONFIG_TLS_NCLEANUP=4 CONFIG_TLS_NELEM=16 diff --git a/cmake/menuconfig.cmake b/cmake/menuconfig.cmake index 694c29845a62e..22093f57da1a7 100644 --- a/cmake/menuconfig.cmake +++ b/cmake/menuconfig.cmake @@ -95,6 +95,13 @@ add_custom_target( ${CMAKE_BINARY_DIR}/defconfig.tmp COMMAND ${CMAKE_COMMAND} -P ${NUTTX_DIR}/cmake/savedefconfig.cmake ${CMAKE_BINARY_DIR}/.config ${CMAKE_BINARY_DIR}/defconfig.tmp - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_BINARY_DIR}/defconfig - ${NUTTX_DEFCONFIG} + COMMAND + ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/process_config.py + postprocess ${CMAKE_BINARY_DIR}/config_tree.json + ${CMAKE_BINARY_DIR}/defconfig.orig ${CMAKE_BINARY_DIR}/defconfig + ${CMAKE_BINARY_DIR}/defconfig.post + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_BINARY_DIR}/defconfig.post ${NUTTX_DEFCONFIG} + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_BINARY_DIR}/defconfig.post ${NUTTX_ORIG_DEFCONFIG} WORKING_DIRECTORY ${NUTTX_DIR}) diff --git a/cmake/nuttx_add_application.cmake b/cmake/nuttx_add_application.cmake index 1c8259e3a76b8..efee621dda720 100644 --- a/cmake/nuttx_add_application.cmake +++ b/cmake/nuttx_add_application.cmake @@ -233,9 +233,8 @@ function(nuttx_add_application) endif() if(INCLUDE_DIRECTORIES) - foreach(inc ${INCLUDE_DIRECTORIES}) - target_include_directories(${TARGET} PRIVATE ${inc}) - endforeach() + target_include_directories(${TARGET} BEFORE + PRIVATE ${INCLUDE_DIRECTORIES}) endif() endif() diff --git a/cmake/nuttx_add_library.cmake b/cmake/nuttx_add_library.cmake index 1b9b409f6b5f1..2b4c1172bf1d0 100644 --- a/cmake/nuttx_add_library.cmake +++ b/cmake/nuttx_add_library.cmake @@ -62,6 +62,12 @@ function(nuttx_add_library_internal target) # Set install config for all library install(TARGETS ${target}) + # Set target information for debug and dump + set_property( + TARGET nuttx_target_interface + APPEND + PROPERTY ALL_TARGETS ${target}) + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/targets "${target}\n") endfunction() # Auxiliary libraries diff --git a/cmake/nuttx_extensions.cmake b/cmake/nuttx_extensions.cmake index 9eeb1164a5afa..89594dcdcfa42 100644 --- a/cmake/nuttx_extensions.cmake +++ b/cmake/nuttx_extensions.cmake @@ -28,6 +28,10 @@ include(nuttx_parse_function_args) # compiler options and include path needed by all apps libraries. add_custom_target(nuttx_apps_interface) +# "nuttx_target_interface" is a source-less target that hold target information +# for target debug and dump +add_custom_target(nuttx_target_interface) + # Macro: nuttx_library # # Creates a library target with the given name and mode. If MODE is "KERNEL", it @@ -153,7 +157,7 @@ endfunction() # Usage: nuttx_include_directories("include/path1" "include/path2") function(nuttx_include_directories) if(TARGET ${NX_CURRENT_LIBRARY}) - target_include_directories(${NX_CURRENT_LIBRARY} PRIVATE ${ARGN}) + target_include_directories(${NX_CURRENT_LIBRARY} PUBLIC ${ARGN}) endif() endfunction() @@ -298,3 +302,14 @@ function(nuttx_link_libraries) endforeach() endif() endfunction() + +# dump targets information +add_custom_target( + dump_targets + COMMAND ${CMAKE_COMMAND} -E remove target_dump + COMMAND ${CMAKE_COMMAND} -E echo + "'$'" + COMMAND + ${CMAKE_COMMAND} -E echo + "'$'" >> target_dump + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/cmake/nuttx_kconfig.cmake b/cmake/nuttx_kconfig.cmake index f9364ea9a2c62..cc55acc9f86bb 100644 --- a/cmake/nuttx_kconfig.cmake +++ b/cmake/nuttx_kconfig.cmake @@ -216,6 +216,18 @@ function(nuttx_olddefconfig) "nuttx_olddefconfig: Failed to initialize Kconfig configuration: ${KCONFIG_OUTPUT}" ) endif() + + # save the orig compressed formatted defconfig at the very beginning + execute_process(COMMAND savedefconfig --out ${CMAKE_BINARY_DIR}/defconfig.tmp + WORKING_DIRECTORY ${NUTTX_DIR}) + + execute_process( + COMMAND + ${CMAKE_COMMAND} -P ${NUTTX_DIR}/cmake/savedefconfig.cmake + ${CMAKE_BINARY_DIR}/.config.compressed ${CMAKE_BINARY_DIR}/defconfig.tmp + ${CMAKE_BINARY_DIR}/defconfig.orig + WORKING_DIRECTORY ${NUTTX_DIR}) + endfunction() function(nuttx_setconfig) diff --git a/cmake/nuttx_process_config.cmake b/cmake/nuttx_process_config.cmake index 8fab3b72eddd0..f66238b0f7e6a 100644 --- a/cmake/nuttx_process_config.cmake +++ b/cmake/nuttx_process_config.cmake @@ -20,7 +20,10 @@ # # ############################################################################## -function(process_config OUTPUT INPUT) +# save preprocess defconfig as orig by default +set(NUTTX_ORIG_DEFCONFIG ${NUTTX_DEFCONFIG}) + +function(process_config OUTPUT INPUT TREE_FILE) set(options) set(oneValueArgs) set(multiValueArgs INCLUDE_PATHS) @@ -32,10 +35,14 @@ function(process_config OUTPUT INPUT) list(APPEND include_args "${path}") endforeach() - message(STATUS "Processing includes: ${INPUT} -> ${OUTPUT}") + if(TREE_FILE) + set(TREE_OPTION --tree) + endif() + message(STATUS "Processing includes: ${INPUT} → ${OUTPUT}") execute_process( - COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/process_config.py - ${OUTPUT} ${INPUT} ${include_args} + COMMAND + ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/process_config.py + preprocess ${OUTPUT} ${INPUT} ${include_args} ${TREE_OPTION} ${TREE_FILE} RESULT_VARIABLE result OUTPUT_VARIABLE out ERROR_VARIABLE err) @@ -44,3 +51,28 @@ function(process_config OUTPUT INPUT) message(FATAL_ERROR "Failed to process includes:\n${err}") endif() endfunction() + +# fetch defconfig content +file(READ "${NUTTX_DEFCONFIG}" FILE_CONTENTS) +string(FIND "${FILE_CONTENTS}" "#include" INCLUDE_FOUND) + +if(NOT EXISTS ${CMAKE_BINARY_DIR}/.defconfig.processed) + set(TREE_FILE ${CMAKE_BINARY_DIR}/config_tree.json) +else() + set(TREE_FILE ${CMAKE_BINARY_DIR}/config_tree_dirty.json) +endif() +# Should we preprocess defconfig? +if(INCLUDE_FOUND GREATER -1) + get_filename_component(NUTTX_DEFCONFIG_DIR "${NUTTX_DEFCONFIG}" DIRECTORY) + process_config( + ${CMAKE_BINARY_DIR}/.defconfig.processed + ${NUTTX_DEFCONFIG} + ${TREE_FILE} + INCLUDE_PATHS + ${NUTTX_DEFCONFIG_DIR}/../../common/configs + ${NUTTX_DEFCONFIG_DIR}/../common + ${NUTTX_DEFCONFIG_DIR} + ${NUTTX_DIR}/../apps + ${NUTTX_DIR}/../nuttx-apps) + set(NUTTX_DEFCONFIG ${CMAKE_BINARY_DIR}/.defconfig.processed) +endif() diff --git a/cmake/nuttx_toolchain.cmake b/cmake/nuttx_toolchain.cmake index 0b728f2c47f44..beecf63424a20 100644 --- a/cmake/nuttx_toolchain.cmake +++ b/cmake/nuttx_toolchain.cmake @@ -30,6 +30,22 @@ if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") endif() endif() +# Cmake build provide absolute paths to compile files. If __FILE__ macros are +# used in the source code(ASSERT), the binary will contain many invalid paths. +# This saves some memory, stops exposing build systems locations in binaries, +# make failure logs more deterministic and most importantly makes builds more +# failure logs more deterministic and most importantly makes builds more +# deterministic. Debuggers usually have a path mapping feature to ensure the +# files are still found. +if((NOT MSVC) AND (NOT CONFIG_ARCH_TOOLCHAIN_GHS)) + if(CONFIG_OUTPUT_STRIP_PATHS) + add_compile_options(-fmacro-prefix-map=${NUTTX_DIR}=) + add_compile_options(-fmacro-prefix-map=${NUTTX_APPS_DIR}=) + add_compile_options(-fmacro-prefix-map=${NUTTX_BOARD_ABS_DIR}=) + add_compile_options(-fmacro-prefix-map=${NUTTX_CHIP_ABS_DIR}=) + endif() +endif() + # Support CMake to define additional configuration options if(EXTRA_FLAGS) diff --git a/cmake/savedefconfig.cmake b/cmake/savedefconfig.cmake index c6f06e3ff4cef..de94ff10e0fd1 100644 --- a/cmake/savedefconfig.cmake +++ b/cmake/savedefconfig.cmake @@ -45,8 +45,11 @@ endforeach() get_filename_component(BINARY_DIR "${TARGET_FILE}" DIRECTORY) -set(OUTPUT_FILE ${BINARY_DIR}/defconfig) - +if(CMAKE_ARGV5) + set(OUTPUT_FILE ${CMAKE_ARGV5}) +else() + set(OUTPUT_FILE ${BINARY_DIR}/defconfig) +endif() # cmake-format: off file(WRITE ${OUTPUT_FILE} "") file(APPEND ${OUTPUT_FILE} "\#\n") diff --git a/crypto/cryptodev.c b/crypto/cryptodev.c index ce242b871809c..bd9cfe9367319 100644 --- a/crypto/cryptodev.c +++ b/crypto/cryptodev.c @@ -228,6 +228,8 @@ static int cryptof_ioctl(FAR struct file *filep, case CRYPTO_BLF_CBC: case CRYPTO_CAST_CBC: case CRYPTO_AES_CBC: + case CRYPTO_AES_192_CBC: + case CRYPTO_AES_256_CBC: case CRYPTO_AES_CMAC: case CRYPTO_AES_CTR: case CRYPTO_AES_XTS: @@ -980,6 +982,7 @@ static int cryptof_open(FAR struct file *filep) kmm_free(cria.cri_key); } + free(fcrd); return ret; } diff --git a/drivers/can/can_sender.c b/drivers/can/can_sender.c index 666fbd07b416e..eee0cabd6fee4 100644 --- a/drivers/can/can_sender.c +++ b/drivers/can/can_sender.c @@ -25,6 +25,7 @@ ****************************************************************************/ #include +#include #include /**************************************************************************** diff --git a/drivers/drivers_initialize.c b/drivers/drivers_initialize.c index 1a012f928e71a..7393f37d93d5e 100644 --- a/drivers/drivers_initialize.c +++ b/drivers/drivers_initialize.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -267,6 +268,12 @@ void drivers_initialize(void) usrsock_rpmsg_server_initialize(); #endif +#ifdef CONFIG_NET_RPMSG_DRV_SERVER + /* Initialize the net rpmsg default server */ + + net_rpmsg_drv_server_init(); +#endif + #ifdef CONFIG_SMART_DEV_LOOP smart_loop_register_driver(); #endif diff --git a/drivers/misc/optee.c b/drivers/misc/optee.c index 5d49136aab61b..71497f461180c 100644 --- a/drivers/misc/optee.c +++ b/drivers/misc/optee.c @@ -36,6 +36,7 @@ #include #ifdef CONFIG_ARCH_ADDRENV +# include # include # include # include diff --git a/drivers/mmcsd/mmcsd_sdio.c b/drivers/mmcsd/mmcsd_sdio.c index a9cdf7fbf7e14..1149e821ac142 100644 --- a/drivers/mmcsd/mmcsd_sdio.c +++ b/drivers/mmcsd/mmcsd_sdio.c @@ -951,7 +951,7 @@ static void mmcsd_decode_csd(FAR struct mmcsd_state_s *priv, uint32_t csd[4]) finfo(" FILE_FORMAT: %d ECC: %d (MMC) CRC: %d\n", decoded.fileformat, decoded.mmcecc, decoded.crc); - finfo("Capacity: %luKb, Block size: %db, nblocks: %d wrprotect: %d\n", + finfo("Capacity: %luKB, Block size: %dB, nblocks: %d wrprotect: %d\n", (unsigned long)MMCSD_CAPACITY(priv->part[0].nblocks, priv->blockshift), priv->blocksize, priv->part[0].nblocks, priv->wrprotect); diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 3686d8bcc5261..08b6472f7b7d7 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -189,20 +189,12 @@ config MTD_CONFIG_NAME_LEN config MTD_CONFIG_FAIL_SAFE bool "Enable Fail Safe MTD Config" default n - depends on MTD_BYTE_WRITE ---help--- Enable the new storage layout to support the resilient to power loss. This replaces the drivers/mtd/mtd_config, which is resilient to power loss. -config MTD_WRITE_ALIGN_SIZE - int "align size [1,2,4,8,16] for per write operation" - default 1 - depends on MTD_CONFIG_FAIL_SAFE - ---help--- - align size will be one of 1,2,4,8,16 - -config MTD_BLOCKSIZE_MULTIPLE +config MTD_CONFIG_BLOCKSIZE_MULTIPLE int "Set NVS blocksize multiple" default 1 depends on MTD_CONFIG_FAIL_SAFE @@ -1503,4 +1495,17 @@ config MTD_CFI ---help--- Support CFI(common flash interface) NOR FLASH. +config MTD_CFI_PAGE_SIZE + int "Page Size of MTD CFI NOR FLASH (bytes)" + default 16 + range 1 524288 + depends on MTD_CFI + ---help--- + Configure the write page size (in bytes) used by the CFI NOR Flash + driver. The value must be at least 1 and should not exceed the maximum + write buffer size supported by the CFI device. + In the driver, this capability is typically exposed as the device's + "write page size" parameter for each write, so this configuration + value should be chosen such that it is equal to write page size for + the target flash. endif # MTD diff --git a/drivers/mtd/cfi.c b/drivers/mtd/cfi.c index c51f5ed881431..ce6e1c3ab6bc3 100644 --- a/drivers/mtd/cfi.c +++ b/drivers/mtd/cfi.c @@ -969,8 +969,9 @@ int cfi_check(FAR struct cfi_dev_s *cfi) cfi->cfi_offset = g_cfi_query_address[i]; cfi->dev_num = cfi->bankwidth / cfi->dev_width; - cfi->page_size = (1 << info->max_write_bytes_num) * - cfi->dev_num; + cfi->page_size = MIN(CONFIG_MTD_CFI_PAGE_SIZE, + (1 << info->max_write_bytes_num) * + cfi->dev_num); /* fix amd feature */ diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c index ace0eeb2c539b..253ce90564264 100644 --- a/drivers/mtd/ftl.c +++ b/drivers/mtd/ftl.c @@ -392,13 +392,14 @@ static ssize_t ftl_mtd_erase(FAR struct ftl_struct_s *dev, off_t startblock) if (dev->lptable == NULL) { ret = MTD_ERASE(dev->mtd, startblock, 1); - if (ret < 0) + if (ret < 0 && ret != -ENOSYS) { ferr("ERROR: Erase block %" PRIdOFF " failed: %zd\n", startblock, ret); + return ret; } - return ret; + return OK; } while (1) @@ -409,9 +410,9 @@ static ssize_t ftl_mtd_erase(FAR struct ftl_struct_s *dev, off_t startblock) } ret = MTD_ERASE(dev->mtd, dev->lptable[startblock], 1); - if (ret == 1) + if (ret >= 0 || ret == -ENOSYS) { - return ret; + return OK; } MTD_MARKBAD(dev->mtd, dev->lptable[startblock]); @@ -561,6 +562,18 @@ static ssize_t ftl_flush(FAR void *priv, FAR const uint8_t *buffer, int nbytes; int ret; + if (dev->mtd->erase == NULL && dev->lptable == NULL) + { + ret = MTD_BWRITE(dev->mtd, startblock, nblocks, buffer); + if (ret != nblocks) + { + ferr("ERROR: Direct write block %" PRIdOFF " failed: %d\n", + startblock, ret); + } + + return ret; + } + if (dev->oflags & O_DIRECT) { /* Direct write mode */ diff --git a/drivers/mtd/mtd_config_fs.c b/drivers/mtd/mtd_config_fs.c index 0b89520648961..37215d5e1982d 100644 --- a/drivers/mtd/mtd_config_fs.c +++ b/drivers/mtd/mtd_config_fs.c @@ -51,35 +51,13 @@ * low 2 bytes represent the offset in a block */ -#define ADDR_BLOCK_MASK 0xFFFF0000 -#define ADDR_BLOCK_SHIFT 16 -#define ADDR_OFFS_MASK 0x0000FFFF +#define NVS_ADDR_BLOCK_MASK 0xFFFF0000 +#define NVS_ADDR_BLOCK_SHIFT 16 +#define NVS_ADDR_OFFS_MASK 0x0000FFFF -/* We don't want to store all the read content in stack or heap, - * so we make a buffer to do compare or move. - */ - -#define NVS_BUFFER_SIZE MAX(NVS_ALIGN_UP(32), NVS_ALIGN_SIZE) - -/* If data is written after last ate, and power loss happens, - * we need to find a clean offset by skipping dirty data. - * This macro defines how many bytes to skip when dirty data - * is spotted(may take several skips). - * Normally 1 byte is okay, such process only happens when - * nvs is started, and it is acceptable to take some time during - * starting. - */ - -#define NVS_CORRUPT_DATA_SKIP_STEP NVS_ALIGN_SIZE - -/* Gc done or close ate has the id of 0xffffffff. - * We can tell if the ate is special by looking at its id. - */ - -#define NVS_SPECIAL_ATE_ID 0xffffffff - -#define NVS_ALIGN_SIZE CONFIG_MTD_WRITE_ALIGN_SIZE -#define NVS_ALIGN_UP(x) (((x) + NVS_ALIGN_SIZE - 1) & ~(NVS_ALIGN_SIZE - 1)) +#define NVS_ATE(name, size) \ + char name##_buf[size]; \ + FAR struct nvs_ate *name = (FAR struct nvs_ate *)name##_buf /**************************************************************************** * Private Types @@ -90,6 +68,7 @@ struct nvs_fs { FAR struct mtd_dev_s *mtd; /* MTD device */ + uint32_t progsize; /* Size of one read/write block */ uint32_t blocksize; /* Size of one nvs block */ uint32_t nblocks; /* Number of nvs blocks */ uint8_t erasestate; /* Erased value */ @@ -113,15 +92,7 @@ begin_packed_struct struct nvs_ate uint16_t key_len; /* Key string len */ uint8_t part; /* Part of a multipart data - future extension */ uint8_t crc8; /* Crc8 check of the ate entry */ -#if CONFIG_MTD_WRITE_ALIGN_SIZE <= 4 - /* stay compatible with situation which align byte be 1 */ - - uint8_t expired[NVS_ALIGN_SIZE]; - uint8_t reserved[4 - NVS_ALIGN_SIZE]; -#else - uint8_t padding[NVS_ALIGN_UP(12) - 12]; - uint8_t expired[NVS_ALIGN_SIZE]; -#endif + uint8_t expired[0]; } end_packed_struct; /**************************************************************************** @@ -189,6 +160,66 @@ static uint32_t nvs_fnv_hash(FAR const uint8_t *input, uint32_t len) return hval; } +/**************************************************************************** + * Name: nvs_align_up + ****************************************************************************/ + +static inline size_t nvs_align_up(FAR struct nvs_fs *fs, size_t len) +{ + return (len + (fs->progsize - 1)) & ~(fs->progsize - 1); +} + +/**************************************************************************** + * Name: nvs_ate_size + ****************************************************************************/ + +static inline size_t nvs_ate_size(FAR struct nvs_fs *fs) +{ + /* Stay compatible with situation which align byte be 1 */ + + if (fs->progsize == 1) + { + return sizeof(struct nvs_ate) + 4; + } + + return nvs_align_up(fs, sizeof(struct nvs_ate)) + fs->progsize; +} + +/**************************************************************************** + * Name: nvs_buffer_size + ****************************************************************************/ + +static inline size_t nvs_buffer_size(FAR struct nvs_fs *fs) +{ + return nvs_align_up(fs, 32); +} + +/**************************************************************************** + * Name: nvs_ate_expired + ****************************************************************************/ + +static inline bool nvs_ate_expired(FAR struct nvs_fs *fs, + FAR struct nvs_ate *entry) +{ + return entry->expired[nvs_align_up(fs, sizeof(*entry)) - sizeof(*entry)] != + fs->erasestate; +} + +/**************************************************************************** + * Name: nvs_special_ate_id + * + * Description: + * Gc done or close ate has the id of 0xffffffff. + * We can tell if the ate is special by looking at its id. + * + ****************************************************************************/ + +static inline uint32_t nvs_special_ate_id(FAR struct nvs_fs *fs) +{ + return (fs->erasestate << 24) | (fs->erasestate << 16) | + (fs->erasestate << 8) | fs->erasestate; +} + /**************************************************************************** * Name: nvs_flash_wrt * @@ -201,18 +232,58 @@ static int nvs_flash_wrt(FAR struct nvs_fs *fs, uint32_t addr, FAR const void *data, size_t len) { off_t offset; - int ret; + int rc; - offset = fs->blocksize * (addr >> ADDR_BLOCK_SHIFT); - offset += addr & ADDR_OFFS_MASK; + offset = fs->blocksize * (addr >> NVS_ADDR_BLOCK_SHIFT); + offset += addr & NVS_ADDR_OFFS_MASK; - ret = MTD_WRITE(fs->mtd, offset, len, data); - if (ret < 0) +#ifdef CONFIG_MTD_BYTE_WRITE + rc = MTD_WRITE(fs->mtd, offset, len, data); +#else + rc = MTD_BWRITE(fs->mtd, offset / fs->progsize, len / fs->progsize, data); +#endif + + return rc < 0 ? rc : 0; +} + +/**************************************************************************** + * Name: nvs_flash_brd + ****************************************************************************/ + +static int nvs_flash_brd(FAR struct nvs_fs *fs, off_t offset, + FAR void *data, size_t len) +{ + int rc; + +#ifdef CONFIG_MTD_BYTE_WRITE + rc = MTD_READ(fs->mtd, offset, len, data); +#else + rc = MTD_BREAD(fs->mtd, offset / fs->progsize, len / fs->progsize, data); +#endif + if (rc == -EBADMSG) { - return ret; + /* ECC fail first time + * try again to avoid transient electronic interference + */ + +#ifdef CONFIG_MTD_BYTE_WRITE + rc = MTD_READ(fs->mtd, offset, len, data); +#else + rc = MTD_BREAD(fs->mtd, offset / fs->progsize, len / fs->progsize, + data); +#endif + if (rc == -EBADMSG) + { + /* ECC fail second time + * fill ~erasestate to trigger recovery process + */ + + memset(data, ~fs->erasestate, len); + rc = 0; + } } - return OK; + return rc < 0 ? rc : 0; } /**************************************************************************** @@ -226,32 +297,67 @@ static int nvs_flash_wrt(FAR struct nvs_fs *fs, uint32_t addr, static int nvs_flash_rd(FAR struct nvs_fs *fs, uint32_t addr, FAR void *data, size_t len) { +#ifdef CONFIG_MTD_BYTE_WRITE off_t offset; - int ret; - offset = fs->blocksize * (addr >> ADDR_BLOCK_SHIFT); - offset += addr & ADDR_OFFS_MASK; + offset = fs->blocksize * (addr >> NVS_ADDR_BLOCK_SHIFT); + offset += addr & NVS_ADDR_OFFS_MASK; - ret = MTD_READ(fs->mtd, offset, len, data); - if (ret == -EBADMSG) + return nvs_flash_brd(fs, offset, data, len); +#else + uint8_t buf[fs->progsize]; + size_t bytes_to_rd; + off_t begin_padding; + off_t offset; + int rc; + + offset = fs->blocksize * (addr >> NVS_ADDR_BLOCK_SHIFT) + + (addr & NVS_ADDR_OFFS_MASK); + begin_padding = offset % fs->progsize; + + if (begin_padding > 0) { - /* ECC fail first time - * try again to avoid transient electronic interference - */ + offset -= begin_padding; + bytes_to_rd = MIN(fs->progsize - begin_padding, len); + rc = nvs_flash_brd(fs, offset, buf, fs->progsize); + if (rc < 0) + { + return rc; + } - ret = MTD_READ(fs->mtd, offset, len, data); - if (ret == -EBADMSG) + memcpy(data, buf + begin_padding, bytes_to_rd); + offset += fs->progsize; + data += bytes_to_rd; + len -= bytes_to_rd; + } + + if (len >= fs->progsize) + { + bytes_to_rd = len / fs->progsize * fs->progsize; + rc = nvs_flash_brd(fs, offset, data, bytes_to_rd); + if (rc < 0) { - /* ECC fail second time - * fill ~erasestate to trigger recovery process - */ + return rc; + } - memset(data, ~fs->erasestate, len); - ret = 0; + offset += bytes_to_rd; + data += bytes_to_rd; + len -= bytes_to_rd; + } + + if (len > 0) + { + rc = nvs_flash_brd(fs, offset, buf, fs->progsize); + if (rc < 0) + { + return rc; } + + memcpy(data, buf, len); } - return ret < 0 ? ret : 0; + return 0; +#endif } /**************************************************************************** @@ -265,10 +371,11 @@ static int nvs_flash_rd(FAR struct nvs_fs *fs, uint32_t addr, static int nvs_flash_ate_wrt(FAR struct nvs_fs *fs, FAR const struct nvs_ate *entry) { + size_t ate_size = nvs_ate_size(fs); int rc; - rc = nvs_flash_wrt(fs, fs->ate_wra, entry, sizeof(struct nvs_ate)); - fs->ate_wra -= sizeof(struct nvs_ate); + rc = nvs_flash_wrt(fs, fs->ate_wra, entry, ate_size); + fs->ate_wra -= ate_size; return rc; } @@ -297,7 +404,7 @@ static int nvs_flash_data_wrt(FAR struct nvs_fs *fs, static int nvs_flash_ate_rd(FAR struct nvs_fs *fs, uint32_t addr, FAR struct nvs_ate *entry) { - return nvs_flash_rd(fs, addr, entry, sizeof(struct nvs_ate)); + return nvs_flash_rd(fs, addr, entry, nvs_ate_size(fs)); } /**************************************************************************** @@ -314,13 +421,13 @@ static int nvs_flash_block_cmp(FAR struct nvs_fs *fs, uint32_t addr, FAR const void *data, size_t len) { FAR const uint8_t *data8 = (FAR const uint8_t *)data; - int rc; + uint8_t buf[nvs_buffer_size(fs)]; size_t bytes_to_cmp; - uint8_t buf[NVS_BUFFER_SIZE]; + int rc; while (len > 0) { - bytes_to_cmp = MIN(NVS_BUFFER_SIZE, len); + bytes_to_cmp = MIN(sizeof(buf), len); rc = nvs_flash_rd(fs, addr, buf, bytes_to_cmp); if (rc) { @@ -354,14 +461,14 @@ static int nvs_flash_block_cmp(FAR struct nvs_fs *fs, uint32_t addr, static int nvs_flash_direct_cmp(FAR struct nvs_fs *fs, uint32_t addr1, uint32_t addr2, size_t len) { - int rc; + uint8_t buf1[nvs_buffer_size(fs)]; + uint8_t buf2[sizeof(buf1)]; size_t bytes_to_cmp; - uint8_t buf1[NVS_BUFFER_SIZE]; - uint8_t buf2[NVS_BUFFER_SIZE]; + int rc; while (len > 0) { - bytes_to_cmp = MIN(NVS_BUFFER_SIZE, len); + bytes_to_cmp = MIN(sizeof(buf1), len); rc = nvs_flash_rd(fs, addr1, buf1, bytes_to_cmp); if (rc) { @@ -401,14 +508,14 @@ static int nvs_flash_direct_cmp(FAR struct nvs_fs *fs, uint32_t addr1, static int nvs_flash_cmp_const(FAR struct nvs_fs *fs, uint32_t addr, uint8_t value, size_t len) { - int rc; + uint8_t cmp[nvs_buffer_size(fs)]; size_t bytes_to_cmp; - uint8_t cmp[NVS_BUFFER_SIZE]; + int rc; - memset(cmp, value, NVS_BUFFER_SIZE); + memset(cmp, value, sizeof(cmp)); while (len > 0) { - bytes_to_cmp = MIN(NVS_BUFFER_SIZE, len); + bytes_to_cmp = MIN(sizeof(cmp), len); rc = nvs_flash_block_cmp(fs, addr, cmp, bytes_to_cmp); if (rc) { @@ -434,13 +541,13 @@ static int nvs_flash_cmp_const(FAR struct nvs_fs *fs, uint32_t addr, static int nvs_flash_block_move(FAR struct nvs_fs *fs, uint32_t addr, size_t len) { - int rc; + uint8_t buf[nvs_buffer_size(fs)]; size_t bytes_to_copy; - uint8_t buf[NVS_BUFFER_SIZE]; + int rc; while (len) { - bytes_to_copy = MIN(NVS_BUFFER_SIZE, len); + bytes_to_copy = MIN(sizeof(buf), len); rc = nvs_flash_rd(fs, addr, buf, bytes_to_copy); if (rc) { @@ -475,8 +582,9 @@ static int nvs_flash_erase_block(FAR struct nvs_fs *fs, uint32_t addr) finfo("Erasing addr %" PRIx32 "\n", addr); rc = MTD_ERASE(fs->mtd, - CONFIG_MTD_BLOCKSIZE_MULTIPLE * (addr >> ADDR_BLOCK_SHIFT), - CONFIG_MTD_BLOCKSIZE_MULTIPLE); + CONFIG_MTD_CONFIG_BLOCKSIZE_MULTIPLE * + (addr >> NVS_ADDR_BLOCK_SHIFT), + CONFIG_MTD_CONFIG_BLOCKSIZE_MULTIPLE); if (rc < 0) { ferr("Erasing failed %d\n", rc); @@ -508,22 +616,17 @@ static void nvs_ate_crc8_update(FAR struct nvs_ate *entry) * * Description: * Crc check on allocation entry. - * Returns 0 if OK, 1 on crc fail. + * Returns true if OK, false on crc fail. * ****************************************************************************/ -static int nvs_ate_crc8_check(FAR const struct nvs_ate *entry) +static bool nvs_ate_crc8_check(FAR const struct nvs_ate *entry) { uint8_t ate_crc; ate_crc = crc8part((FAR const uint8_t *)entry, offsetof(struct nvs_ate, crc8), 0xff); - if (ate_crc == entry->crc8) - { - return 0; - } - - return 1; + return ate_crc == entry->crc8; } /**************************************************************************** @@ -536,12 +639,12 @@ static int nvs_ate_crc8_check(FAR const struct nvs_ate *entry) ****************************************************************************/ static int nvs_ate_cmp_const(FAR const struct nvs_ate *entry, - uint8_t value) + uint8_t value, size_t len) { FAR const uint8_t *data8 = (FAR const uint8_t *)entry; - int i; + size_t i; - for (i = 0; i < sizeof(struct nvs_ate); i++) + for (i = 0; i < len; i++) { if (data8[i] != value) { @@ -556,20 +659,15 @@ static int nvs_ate_cmp_const(FAR const struct nvs_ate *entry, * Name: nvs_ate_valid * * Description: - * Return 1 if crc8 and offset valid, 0 otherwise + * Return true if crc8 and offset valid, false otherwise * ****************************************************************************/ -static int nvs_ate_valid(FAR struct nvs_fs *fs, +static bool nvs_ate_valid(FAR struct nvs_fs *fs, FAR const struct nvs_ate *entry) { - if (nvs_ate_crc8_check(entry) || - entry->offset >= (fs->blocksize - sizeof(struct nvs_ate))) - { - return 0; - } - - return 1; + return nvs_ate_crc8_check(entry) && + entry->offset < (fs->blocksize - nvs_ate_size(fs)); } /**************************************************************************** @@ -581,25 +679,25 @@ static int nvs_ate_valid(FAR struct nvs_fs *fs, * - Calid ate. * - Len = 0 and id = 0xFFFFFFFF. * - Offset points to location at ate multiple from block size. - * Return 1 if valid, 0 otherwise. + * Return true if valid, false otherwise. * ****************************************************************************/ -static int nvs_close_ate_valid(FAR struct nvs_fs *fs, +static bool nvs_close_ate_valid(FAR struct nvs_fs *fs, FAR const struct nvs_ate *entry) { if (!nvs_ate_valid(fs, entry) || entry->len != 0 || - entry->id != NVS_SPECIAL_ATE_ID) + entry->id != nvs_special_ate_id(fs)) { - return 0; + return false; } - if ((fs->blocksize - entry->offset) % sizeof(struct nvs_ate)) + if ((fs->blocksize - entry->offset) % nvs_ate_size(fs)) { - return 0; + return false; } - return 1; + return true; } /**************************************************************************** @@ -616,14 +714,12 @@ static int nvs_close_ate_valid(FAR struct nvs_fs *fs, int nvs_flash_write_multi_blk(FAR struct nvs_fs *fs, const uint8_t *addr, size_t size) { - size_t blk_cnt; int left; int rc; - blk_cnt = size / NVS_ALIGN_SIZE; - left = size % NVS_ALIGN_SIZE; + left = size % fs->progsize; - if (blk_cnt) + if (size > left) { rc = nvs_flash_data_wrt(fs, addr, size - left); if (rc) @@ -648,19 +744,20 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id, FAR const uint8_t *key, size_t key_size, FAR const void *data, size_t len) { - int rc; - struct nvs_ate entry; - uint16_t left; + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(entry, ate_size); + uint8_t buf[fs->progsize]; uint16_t copy_len = 0; - uint8_t buf[NVS_ALIGN_SIZE]; + uint16_t left; + int rc; - memset(&entry, fs->erasestate, sizeof(entry)); - entry.id = id; - entry.offset = fs->data_wra & ADDR_OFFS_MASK; - entry.len = len; - entry.key_len = key_size; + memset(entry, fs->erasestate, ate_size); + entry->id = id; + entry->offset = fs->data_wra & NVS_ADDR_OFFS_MASK; + entry->len = len; + entry->key_len = key_size; - nvs_ate_crc8_update(&entry); + nvs_ate_crc8_update(entry); /* Let's save key and data into one, key comes first, then data */ @@ -675,14 +772,14 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id, /* Write align block which include part key + part data */ left = rc; - memset(buf, fs->erasestate, NVS_ALIGN_SIZE); + memset(buf, fs->erasestate, sizeof(buf)); - copy_len = (left + len) <= NVS_ALIGN_SIZE ? - len : (NVS_ALIGN_SIZE - left); + copy_len = (left + len) <= sizeof(buf) ? + len : (sizeof(buf) - left); memcpy(buf, key + key_size - left, left); memcpy(buf + left, data, copy_len); - rc = nvs_flash_data_wrt(fs, buf, NVS_ALIGN_SIZE); + rc = nvs_flash_data_wrt(fs, buf, sizeof(buf)); if (rc) { ferr("Write value failed, rc=%d\n", rc); @@ -701,10 +798,10 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id, /* Add padding at the end of data */ left = rc; - memset(buf, fs->erasestate, NVS_ALIGN_SIZE); + memset(buf, fs->erasestate, sizeof(buf)); memcpy(buf, data + len - left, left); - rc = nvs_flash_data_wrt(fs, buf, NVS_ALIGN_SIZE); + rc = nvs_flash_data_wrt(fs, buf, sizeof(buf)); if (rc) { ferr("Write value failed, rc=%d\n", rc); @@ -714,7 +811,7 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id, /* Last, let's save entry to flash */ - rc = nvs_flash_ate_wrt(fs, &entry); + rc = nvs_flash_ate_wrt(fs, entry); if (rc) { ferr("Write ate failed, rc=%d\n", rc); @@ -740,41 +837,42 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id, static int nvs_recover_last_ate(FAR struct nvs_fs *fs, FAR uint32_t *addr) { + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(end_ate, ate_size); uint32_t data_end_addr; uint32_t ate_end_addr; - struct nvs_ate end_ate; int rc; finfo("Recovering last ate from block %" PRIu32 "\n", - (*addr >> ADDR_BLOCK_SHIFT)); + (*addr >> NVS_ADDR_BLOCK_SHIFT)); - *addr -= sizeof(struct nvs_ate); + *addr -= ate_size; ate_end_addr = *addr; - data_end_addr = *addr & ADDR_BLOCK_MASK; + data_end_addr = *addr & NVS_ADDR_BLOCK_MASK; while (ate_end_addr > data_end_addr) { - rc = nvs_flash_ate_rd(fs, ate_end_addr, &end_ate); + rc = nvs_flash_ate_rd(fs, ate_end_addr, end_ate); if (rc) { return rc; } - if (nvs_ate_valid(fs, &end_ate)) + if (nvs_ate_valid(fs, end_ate)) { /* Found a valid ate, update data_end_addr and *addr */ - data_end_addr &= ADDR_BLOCK_MASK; - data_end_addr += end_ate.offset + - NVS_ALIGN_UP(end_ate.key_len + end_ate.len); + data_end_addr &= NVS_ADDR_BLOCK_MASK; + data_end_addr += end_ate->offset + + nvs_align_up(fs, end_ate->key_len + end_ate->len); *addr = ate_end_addr; } - if (ate_end_addr < sizeof(struct nvs_ate)) + if (ate_end_addr < ate_size) { break; } - ate_end_addr -= sizeof(struct nvs_ate); + ate_end_addr -= ate_size; } return 0; @@ -792,8 +890,9 @@ static int nvs_recover_last_ate(FAR struct nvs_fs *fs, static int nvs_prev_ate(FAR struct nvs_fs *fs, FAR uint32_t *addr, FAR struct nvs_ate *ate) { + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(close_ate, ate_size); int rc; - struct nvs_ate close_ate; rc = nvs_flash_ate_rd(fs, *addr, ate); if (rc) @@ -801,31 +900,30 @@ static int nvs_prev_ate(FAR struct nvs_fs *fs, FAR uint32_t *addr, return rc; } - *addr += sizeof(struct nvs_ate); - if (((*addr) & ADDR_OFFS_MASK) != - (fs->blocksize - sizeof(struct nvs_ate))) + *addr += ate_size; + if (((*addr) & NVS_ADDR_OFFS_MASK) != (fs->blocksize - ate_size)) { return 0; } /* Last ate in block, do jump to previous block */ - if (((*addr) >> ADDR_BLOCK_SHIFT) == 0) + if (((*addr) >> NVS_ADDR_BLOCK_SHIFT) == 0) { - *addr += ((fs->nblocks - 1) << ADDR_BLOCK_SHIFT); + *addr += ((fs->nblocks - 1) << NVS_ADDR_BLOCK_SHIFT); } else { - *addr -= (1 << ADDR_BLOCK_SHIFT); + *addr -= (1 << NVS_ADDR_BLOCK_SHIFT); } - rc = nvs_flash_ate_rd(fs, *addr, &close_ate); + rc = nvs_flash_ate_rd(fs, *addr, close_ate); if (rc) { return rc; } - rc = nvs_ate_cmp_const(&close_ate, fs->erasestate); + rc = nvs_ate_cmp_const(close_ate, fs->erasestate, ate_size); /* At the end of filesystem */ @@ -837,10 +935,10 @@ static int nvs_prev_ate(FAR struct nvs_fs *fs, FAR uint32_t *addr, /* Update the address if the close ate is valid. */ - if (nvs_close_ate_valid(fs, &close_ate)) + if (nvs_close_ate_valid(fs, close_ate)) { - *addr &= ADDR_BLOCK_MASK; - *addr += close_ate.offset; + *addr &= NVS_ADDR_BLOCK_MASK; + *addr += close_ate->offset; return 0; } @@ -861,10 +959,10 @@ static int nvs_prev_ate(FAR struct nvs_fs *fs, FAR uint32_t *addr, static void nvs_block_advance(FAR struct nvs_fs *fs, FAR uint32_t *addr) { - *addr += (1 << ADDR_BLOCK_SHIFT); - if ((*addr >> ADDR_BLOCK_SHIFT) == fs->nblocks) + *addr += (1 << NVS_ADDR_BLOCK_SHIFT); + if ((*addr >> NVS_ADDR_BLOCK_SHIFT) == fs->nblocks) { - *addr -= (fs->nblocks << ADDR_BLOCK_SHIFT); + *addr -= (fs->nblocks << NVS_ADDR_BLOCK_SHIFT); } } @@ -879,22 +977,22 @@ static void nvs_block_advance(FAR struct nvs_fs *fs, FAR uint32_t *addr) static int nvs_block_close(FAR struct nvs_fs *fs) { + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(close_ate, ate_size); int rc; - struct nvs_ate close_ate; - memset(&close_ate, fs->erasestate, sizeof(close_ate)); - close_ate.id = NVS_SPECIAL_ATE_ID; - close_ate.len = 0; - close_ate.key_len = 0; - close_ate.offset = - (fs->ate_wra + sizeof(struct nvs_ate)) & ADDR_OFFS_MASK; + memset(close_ate, fs->erasestate, ate_size); + close_ate->id = nvs_special_ate_id(fs); + close_ate->len = 0; + close_ate->key_len = 0; + close_ate->offset = (fs->ate_wra + ate_size) & NVS_ADDR_OFFS_MASK; - fs->ate_wra &= ADDR_BLOCK_MASK; - fs->ate_wra += fs->blocksize - sizeof(struct nvs_ate); + fs->ate_wra &= NVS_ADDR_BLOCK_MASK; + fs->ate_wra += fs->blocksize - ate_size; - nvs_ate_crc8_update(&close_ate); + nvs_ate_crc8_update(close_ate); - rc = nvs_flash_ate_wrt(fs, &close_ate); + rc = nvs_flash_ate_wrt(fs, close_ate); if (rc < 0) { ferr("Write ate failed, rc=%d\n", rc); @@ -902,7 +1000,7 @@ static int nvs_block_close(FAR struct nvs_fs *fs) nvs_block_advance(fs, &fs->ate_wra); - fs->data_wra = fs->ate_wra & ADDR_BLOCK_MASK; + fs->data_wra = fs->ate_wra & NVS_ADDR_BLOCK_MASK; finfo("block close, data_wra=0x%" PRIx32 "\n", fs->data_wra); return 0; @@ -914,17 +1012,19 @@ static int nvs_block_close(FAR struct nvs_fs *fs) static int nvs_add_gc_done_ate(FAR struct nvs_fs *fs) { - struct nvs_ate gc_done_ate; - - finfo("Adding gc done ate at %" PRIx32 "\n", fs->ate_wra & ADDR_OFFS_MASK); - memset(&gc_done_ate, fs->erasestate, sizeof(gc_done_ate)); - gc_done_ate.id = NVS_SPECIAL_ATE_ID; - gc_done_ate.len = 0; - gc_done_ate.key_len = 0; - gc_done_ate.offset = fs->data_wra & ADDR_OFFS_MASK; - nvs_ate_crc8_update(&gc_done_ate); - - return nvs_flash_ate_wrt(fs, &gc_done_ate); + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(gc_done_ate, ate_size); + + finfo("Adding gc done ate at %" PRIx32 "\n", + fs->ate_wra & NVS_ADDR_OFFS_MASK); + memset(gc_done_ate, fs->erasestate, ate_size); + gc_done_ate->id = nvs_special_ate_id(fs); + gc_done_ate->len = 0; + gc_done_ate->key_len = 0; + gc_done_ate->offset = fs->data_wra & NVS_ADDR_OFFS_MASK; + nvs_ate_crc8_update(gc_done_ate); + + return nvs_flash_ate_wrt(fs, gc_done_ate); } /**************************************************************************** @@ -933,10 +1033,10 @@ static int nvs_add_gc_done_ate(FAR struct nvs_fs *fs) static int nvs_expire_ate(FAR struct nvs_fs *fs, uint32_t addr) { - uint8_t expired[NVS_ALIGN_SIZE]; + uint8_t expired[fs->progsize]; memset(expired, ~fs->erasestate, sizeof(expired)); - return nvs_flash_wrt(fs, addr + offsetof(struct nvs_ate, expired), + return nvs_flash_wrt(fs, addr + nvs_align_up(fs, sizeof(struct nvs_ate)), expired, sizeof(expired)); } @@ -952,27 +1052,28 @@ static int nvs_expire_ate(FAR struct nvs_fs *fs, uint32_t addr) static int nvs_gc(FAR struct nvs_fs *fs) { - int rc; - struct nvs_ate close_ate; - struct nvs_ate gc_ate; - uint32_t sec_addr; - uint32_t gc_addr; + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(close_ate, ate_size); + NVS_ATE(gc_ate, ate_size); uint32_t gc_prev_addr; uint32_t data_addr; uint32_t stop_addr; + uint32_t sec_addr; + uint32_t gc_addr; + int rc; finfo("gc: before gc, ate_wra %" PRIx32 "\n", fs->ate_wra); - sec_addr = (fs->ate_wra & ADDR_BLOCK_MASK); + sec_addr = (fs->ate_wra & NVS_ADDR_BLOCK_MASK); nvs_block_advance(fs, &sec_addr); - gc_addr = sec_addr + fs->blocksize - sizeof(struct nvs_ate); + gc_addr = sec_addr + fs->blocksize - ate_size; finfo("gc: set, sec_addr %" PRIx32 ", gc_addr %" PRIx32 "\n", sec_addr, gc_addr); /* If the block is not closed don't do gc */ - rc = nvs_flash_ate_rd(fs, gc_addr, &close_ate); + rc = nvs_flash_ate_rd(fs, gc_addr, close_ate); if (rc < 0) { /* Flash error */ @@ -980,18 +1081,18 @@ static int nvs_gc(FAR struct nvs_fs *fs) return rc; } - rc = nvs_ate_cmp_const(&close_ate, fs->erasestate); + rc = nvs_ate_cmp_const(close_ate, fs->erasestate, ate_size); if (!rc) { goto gc_done; } - stop_addr = gc_addr - sizeof(struct nvs_ate); + stop_addr = gc_addr - ate_size; - if (nvs_close_ate_valid(fs, &close_ate)) + if (nvs_close_ate_valid(fs, close_ate)) { - gc_addr &= ADDR_BLOCK_MASK; - gc_addr += close_ate.offset; + gc_addr &= NVS_ADDR_BLOCK_MASK; + gc_addr += close_ate->offset; } else { @@ -1005,45 +1106,45 @@ static int nvs_gc(FAR struct nvs_fs *fs) do { gc_prev_addr = gc_addr; - rc = nvs_prev_ate(fs, &gc_addr, &gc_ate); + rc = nvs_prev_ate(fs, &gc_addr, gc_ate); if (rc) { return rc; } - if (gc_ate.expired[0] != fs->erasestate) + if (nvs_ate_expired(fs, gc_ate)) { /* Deleted or old ate, ignore it */ continue; } - if (!nvs_ate_valid(fs, &gc_ate)) + if (!nvs_ate_valid(fs, gc_ate)) { continue; } - if (gc_ate.id != NVS_SPECIAL_ATE_ID) + if (gc_ate->id != nvs_special_ate_id(fs)) { /* Copy needed */ finfo("Moving %" PRIu32 ", key_len %" PRIu16 ", len %" PRIu16 "\n", - gc_ate.id, gc_ate.key_len, gc_ate.len); + gc_ate->id, gc_ate->key_len, gc_ate->len); - data_addr = gc_prev_addr & ADDR_BLOCK_MASK; - data_addr += gc_ate.offset; - - gc_ate.offset = fs->data_wra & ADDR_OFFS_MASK; - nvs_ate_crc8_update(&gc_ate); + data_addr = gc_prev_addr & NVS_ADDR_BLOCK_MASK; + data_addr += gc_ate->offset; + gc_ate->offset = fs->data_wra & NVS_ADDR_OFFS_MASK; + nvs_ate_crc8_update(gc_ate); rc = nvs_flash_block_move(fs, data_addr, - NVS_ALIGN_UP(gc_ate.key_len + gc_ate.len)); + nvs_align_up(fs, gc_ate->key_len + + gc_ate->len)); if (rc) { return rc; } - rc = nvs_flash_ate_wrt(fs, &gc_ate); + rc = nvs_flash_ate_wrt(fs, gc_ate); if (rc) { return rc; @@ -1076,23 +1177,21 @@ static int nvs_gc(FAR struct nvs_fs *fs) static int nvs_startup(FAR struct nvs_fs *fs) { - int rc; - struct nvs_ate last_ate; - size_t empty_len; - uint32_t wlk_addr; + struct mtd_geometry_s geo; uint32_t second_addr; uint32_t last_addr; - struct nvs_ate second_ate; - struct mtd_geometry_s geo; + uint32_t wlk_addr; + size_t empty_len; /* Initialize addr to 0 for the case fs->nblocks == 0. This * should never happen but both * Coverity and GCC believe the contrary. */ + uint16_t closed_blocks = 0; uint32_t addr = 0; uint16_t i; - uint16_t closed_blocks = 0; + int rc; fs->ate_wra = 0; fs->data_wra = 0; @@ -1112,6 +1211,14 @@ static int nvs_startup(FAR struct nvs_fs *fs) return rc; } + fs->blocksize = CONFIG_MTD_CONFIG_BLOCKSIZE_MULTIPLE * geo.erasesize; + fs->nblocks = geo.neraseblocks / CONFIG_MTD_CONFIG_BLOCKSIZE_MULTIPLE; + fs->progsize = geo.blocksize; + + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(second_ate, ate_size); + NVS_ATE(last_ate, ate_size); + rc = MTD_IOCTL(fs->mtd, MTDIOC_ERASESTATE, (unsigned long)((uintptr_t)&fs->erasestate)); if (rc < 0) @@ -1120,9 +1227,6 @@ static int nvs_startup(FAR struct nvs_fs *fs) return rc; } - fs->blocksize = CONFIG_MTD_BLOCKSIZE_MULTIPLE * geo.erasesize; - fs->nblocks = geo.neraseblocks / CONFIG_MTD_BLOCKSIZE_MULTIPLE; - /* Check the number of blocks, it should be at least 2. */ if (fs->nblocks < 2) @@ -1137,10 +1241,9 @@ static int nvs_startup(FAR struct nvs_fs *fs) for (i = 0; i < fs->nblocks; i++) { - addr = (i << ADDR_BLOCK_SHIFT) + - (uint16_t)(fs->blocksize - sizeof(struct nvs_ate)); - rc = nvs_flash_cmp_const(fs, addr, fs->erasestate, - sizeof(struct nvs_ate)); + addr = (i << NVS_ADDR_BLOCK_SHIFT) + + (uint16_t)(fs->blocksize - ate_size); + rc = nvs_flash_cmp_const(fs, addr, fs->erasestate, ate_size); fwarn("rc=%d\n", rc); if (rc) { @@ -1148,8 +1251,7 @@ static int nvs_startup(FAR struct nvs_fs *fs) closed_blocks++; nvs_block_advance(fs, &addr); - rc = nvs_flash_cmp_const(fs, addr, fs->erasestate, - sizeof(struct nvs_ate)); + rc = nvs_flash_cmp_const(fs, addr, fs->erasestate, ate_size); if (!rc) { /* Open block */ @@ -1177,8 +1279,8 @@ static int nvs_startup(FAR struct nvs_fs *fs) * the last block contains no ate's. So we check this first */ - rc = nvs_flash_cmp_const(fs, addr - sizeof(struct nvs_ate), - fs->erasestate, sizeof(struct nvs_ate)); + rc = nvs_flash_cmp_const(fs, addr - ate_size, + fs->erasestate, ate_size); if (!rc) { /* Empty ate */ @@ -1203,19 +1305,19 @@ static int nvs_startup(FAR struct nvs_fs *fs) */ fs->ate_wra = addr; - fs->data_wra = addr & ADDR_BLOCK_MASK; + fs->data_wra = addr & NVS_ADDR_BLOCK_MASK; finfo("recovered ate ate_wra=0x%" PRIx32 ", data_wra=0x%" PRIx32 "\n", fs->ate_wra, fs->data_wra); while (fs->ate_wra >= fs->data_wra) { - rc = nvs_flash_ate_rd(fs, fs->ate_wra, &last_ate); + rc = nvs_flash_ate_rd(fs, fs->ate_wra, last_ate); if (rc) { return rc; } - rc = nvs_ate_cmp_const(&last_ate, fs->erasestate); + rc = nvs_ate_cmp_const(last_ate, fs->erasestate, ate_size); if (!rc) { /* Found 0xff empty location */ @@ -1223,17 +1325,18 @@ static int nvs_startup(FAR struct nvs_fs *fs) break; } - if (nvs_ate_valid(fs, &last_ate)) + if (nvs_ate_valid(fs, last_ate)) { /* Complete write of ate was performed */ - fs->data_wra = addr & ADDR_BLOCK_MASK; - fs->data_wra += last_ate.offset + - NVS_ALIGN_UP(last_ate.key_len + last_ate.len); + fs->data_wra = addr & NVS_ADDR_BLOCK_MASK; + fs->data_wra += last_ate->offset + + nvs_align_up(fs, last_ate->key_len + + last_ate->len); finfo("recovered data_wra=0x%" PRIx32 "\n", fs->data_wra); } - fs->ate_wra -= sizeof(struct nvs_ate); + fs->ate_wra -= ate_size; } /* If the block after the write block is not empty, gc was interrupted @@ -1243,7 +1346,7 @@ static int nvs_startup(FAR struct nvs_fs *fs) * data might not fit into the block. */ - addr = fs->ate_wra & ADDR_BLOCK_MASK; + addr = fs->ate_wra & NVS_ADDR_BLOCK_MASK; nvs_block_advance(fs, &addr); rc = nvs_flash_cmp_const(fs, addr, fs->erasestate, fs->blocksize); if (rc < 0) @@ -1258,27 +1361,27 @@ static int nvs_startup(FAR struct nvs_fs *fs) */ bool gc_done_marker = false; - struct nvs_ate gc_done_ate; + NVS_ATE(gc_done_ate, ate_size); - addr = fs->ate_wra + sizeof(struct nvs_ate); - while ((addr & ADDR_OFFS_MASK) < - (fs->blocksize - sizeof(struct nvs_ate))) + addr = fs->ate_wra + ate_size; + while ((addr & NVS_ADDR_OFFS_MASK) < + (fs->blocksize - ate_size)) { - rc = nvs_flash_ate_rd(fs, addr, &gc_done_ate); + rc = nvs_flash_ate_rd(fs, addr, gc_done_ate); if (rc) { return rc; } - if (nvs_ate_valid(fs, &gc_done_ate) && - (gc_done_ate.id == NVS_SPECIAL_ATE_ID) && - (gc_done_ate.len == 0)) + if (nvs_ate_valid(fs, gc_done_ate) && + (gc_done_ate->id == nvs_special_ate_id(fs)) && + (gc_done_ate->len == 0)) { gc_done_marker = true; break; } - addr += sizeof(struct nvs_ate); + addr += ate_size; } if (gc_done_marker) @@ -1286,7 +1389,7 @@ static int nvs_startup(FAR struct nvs_fs *fs) /* Erase the next block */ fwarn("GC Done marker found\n"); - addr = fs->ate_wra & ADDR_BLOCK_MASK; + addr = fs->ate_wra & NVS_ADDR_BLOCK_MASK; nvs_block_advance(fs, &addr); rc = nvs_flash_erase_block(fs, addr); goto end; @@ -1299,9 +1402,9 @@ static int nvs_startup(FAR struct nvs_fs *fs) return rc; } - fs->ate_wra &= ADDR_BLOCK_MASK; - fs->ate_wra += (fs->blocksize - 2 * sizeof(struct nvs_ate)); - fs->data_wra = (fs->ate_wra & ADDR_BLOCK_MASK); + fs->ate_wra &= NVS_ADDR_BLOCK_MASK; + fs->ate_wra += (fs->blocksize - 2 * ate_size); + fs->data_wra = (fs->ate_wra & NVS_ADDR_BLOCK_MASK); finfo("GC when data_wra=0x%" PRIx32 "\n", fs->data_wra); rc = nvs_gc(fs); goto end; @@ -1324,7 +1427,7 @@ static int nvs_startup(FAR struct nvs_fs *fs) break; } - fs->data_wra += NVS_CORRUPT_DATA_SKIP_STEP; + fs->data_wra += fs->progsize; finfo("update for powerloss data write, data_wra=0x%" PRIx32 "\n", fs->data_wra); } @@ -1334,8 +1437,8 @@ static int nvs_startup(FAR struct nvs_fs *fs) * valid data (this also avoids closing a block without any data). */ - if (((fs->ate_wra + 2 * sizeof(struct nvs_ate)) == fs->blocksize) && - (fs->data_wra != (fs->ate_wra & ADDR_BLOCK_MASK))) + if (((fs->ate_wra + 2 * ate_size) == fs->blocksize) && + (fs->data_wra != (fs->ate_wra & NVS_ADDR_BLOCK_MASK))) { rc = nvs_flash_erase_block(fs, fs->ate_wra); if (rc) @@ -1343,7 +1446,7 @@ static int nvs_startup(FAR struct nvs_fs *fs) return rc; } - fs->data_wra = fs->ate_wra & ADDR_BLOCK_MASK; + fs->data_wra = fs->ate_wra & NVS_ADDR_BLOCK_MASK; finfo("erase due to no data, data_wra=0x%" PRIx32 "\n", fs->data_wra); } @@ -1358,7 +1461,7 @@ static int nvs_startup(FAR struct nvs_fs *fs) while (1) { last_addr = wlk_addr; - rc = nvs_prev_ate(fs, &wlk_addr, &last_ate); + rc = nvs_prev_ate(fs, &wlk_addr, last_ate); if (rc) { return rc; @@ -1371,35 +1474,39 @@ static int nvs_startup(FAR struct nvs_fs *fs) break; } - if (nvs_ate_valid(fs, &last_ate) - && (last_ate.id != NVS_SPECIAL_ATE_ID)) + if (nvs_ate_valid(fs, last_ate) + && (last_ate->id != nvs_special_ate_id(fs))) { finfo("ate found at 0x%" PRIx32 ", id %" PRIu32 ", " "key_len %" PRIu16 ", offset %" PRIu16 "\n", - last_addr, last_ate.id, last_ate.key_len, last_ate.offset); + last_addr, last_ate->id, last_ate->key_len, + last_ate->offset); while (1) { second_addr = wlk_addr; - rc = nvs_prev_ate(fs, &wlk_addr, &second_ate); + rc = nvs_prev_ate(fs, &wlk_addr, second_ate); if (rc) { return rc; } - if (nvs_ate_valid(fs, &second_ate) - && second_ate.id == last_ate.id - && second_ate.expired[0] == fs->erasestate) + if (nvs_ate_valid(fs, second_ate) + && second_ate->id == last_ate->id + && !nvs_ate_expired(fs, second_ate)) { finfo("same id at 0x%" PRIx32 ", key_len %" PRIu16 ", " "offset %" PRIu16 "\n", - second_addr, second_ate.key_len, second_ate.offset); - if ((second_ate.key_len == last_ate.key_len) && + second_addr, second_ate->key_len, + second_ate->offset); + if ((second_ate->key_len == last_ate->key_len) && !nvs_flash_direct_cmp(fs, - (last_addr & ADDR_BLOCK_MASK) + - last_ate.offset, - (second_addr & ADDR_BLOCK_MASK) + - second_ate.offset, - last_ate.key_len)) + (last_addr & + NVS_ADDR_BLOCK_MASK) + + last_ate->offset, + (second_addr & + NVS_ADDR_BLOCK_MASK) + + second_ate->offset, + last_ate->key_len)) { finfo("old ate found at 0x%" PRIx32 "\n", second_addr); rc = nvs_expire_ate(fs, second_addr); @@ -1431,8 +1538,8 @@ static int nvs_startup(FAR struct nvs_fs *fs) * space when doing gc. */ - if ((!rc) && ((fs->ate_wra & ADDR_OFFS_MASK) == - (fs->blocksize - 2 * sizeof(struct nvs_ate)))) + if ((!rc) && ((fs->ate_wra & NVS_ADDR_OFFS_MASK) == + (fs->blocksize - 2 * ate_size))) { rc = nvs_add_gc_done_ate(fs); } @@ -1440,9 +1547,11 @@ static int nvs_startup(FAR struct nvs_fs *fs) finfo("%" PRIu32 " Eraseblocks of %" PRIu32 " bytes\n", fs->nblocks, fs->blocksize); finfo("alloc wra: %" PRIu32 ", 0x%" PRIx32 "\n", - (fs->ate_wra >> ADDR_BLOCK_SHIFT), (fs->ate_wra & ADDR_OFFS_MASK)); + fs->ate_wra >> NVS_ADDR_BLOCK_SHIFT, + fs->ate_wra & NVS_ADDR_OFFS_MASK); finfo("data wra: %" PRIu32 ", 0x%" PRIx32 "\n", - (fs->data_wra >> ADDR_BLOCK_SHIFT), (fs->data_wra & ADDR_OFFS_MASK)); + fs->data_wra >> NVS_ADDR_BLOCK_SHIFT, + fs->data_wra & NVS_ADDR_OFFS_MASK); return rc; } @@ -1474,12 +1583,13 @@ static ssize_t nvs_read_entry(FAR struct nvs_fs *fs, FAR const uint8_t *key, size_t key_size, FAR void *data, size_t len, FAR uint32_t *ate_addr) { - int rc; + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(wlk_ate, ate_size); uint32_t wlk_addr; uint32_t rd_addr; uint32_t hist_addr; - struct nvs_ate wlk_ate; uint32_t hash_id; + int rc; hash_id = nvs_fnv_hash(key, key_size) % 0xfffffffd + 1; wlk_addr = fs->ate_wra; @@ -1489,22 +1599,23 @@ static ssize_t nvs_read_entry(FAR struct nvs_fs *fs, FAR const uint8_t *key, { rd_addr = wlk_addr; hist_addr = wlk_addr; - rc = nvs_prev_ate(fs, &wlk_addr, &wlk_ate); + rc = nvs_prev_ate(fs, &wlk_addr, wlk_ate); if (rc) { ferr("Walk to previous ate failed, rc=%d\n", rc); return rc; } - if ((wlk_ate.id == hash_id) && (nvs_ate_valid(fs, &wlk_ate))) + if (wlk_ate->id == hash_id && nvs_ate_valid(fs, wlk_ate)) { - if ((wlk_ate.key_len == key_size) + if ((wlk_ate->key_len == key_size) && (!nvs_flash_block_cmp(fs, - (rd_addr & ADDR_BLOCK_MASK) + wlk_ate.offset, key, key_size))) + (rd_addr & NVS_ADDR_BLOCK_MASK) + + wlk_ate->offset, key, key_size))) { /* It is old or deleted, return -ENOENT */ - if (wlk_ate.expired[0] != fs->erasestate) + if (nvs_ate_expired(fs, wlk_ate)) { return -ENOENT; } @@ -1525,10 +1636,10 @@ static ssize_t nvs_read_entry(FAR struct nvs_fs *fs, FAR const uint8_t *key, if (data && len) { - rd_addr &= ADDR_BLOCK_MASK; - rd_addr += wlk_ate.offset + wlk_ate.key_len; + rd_addr &= NVS_ADDR_BLOCK_MASK; + rd_addr += wlk_ate->offset + wlk_ate->key_len; rc = nvs_flash_rd(fs, rd_addr, data, - MIN(len, wlk_ate.len)); + MIN(len, wlk_ate->len)); if (rc) { ferr("Data read failed, rc=%d\n", rc); @@ -1541,7 +1652,7 @@ static ssize_t nvs_read_entry(FAR struct nvs_fs *fs, FAR const uint8_t *key, *ate_addr = hist_addr; } - return wlk_ate.len; + return wlk_ate->len; } /**************************************************************************** @@ -1567,7 +1678,8 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, int gc_count; size_t data_size; size_t key_size; - struct nvs_ate wlk_ate; + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(wlk_ate, ate_size); uint32_t wlk_addr; uint32_t rd_addr; uint32_t hist_addr; @@ -1593,7 +1705,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, /* Data now contains input data and input key, input key first. */ - data_size = NVS_ALIGN_UP(key_size + pdata->len); + data_size = nvs_align_up(fs, key_size + pdata->len); /* The maximum data size is block size - 3 ate * where: 1 ate for data, 1 ate for block close, 1 ate for gc done. @@ -1602,7 +1714,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, finfo("key_size=%zu, len=%zu, data_size = %zu\n", key_size, pdata->len, data_size); - if ((data_size > (fs->blocksize - 3 * sizeof(struct nvs_ate))) || + if ((data_size > (fs->blocksize - 3 * ate_size)) || ((pdata->len > 0) && (pdata->configdata == NULL))) { return -EINVAL; @@ -1620,18 +1732,18 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, { rd_addr = wlk_addr; hist_addr = wlk_addr; - rc = nvs_prev_ate(fs, &wlk_addr, &wlk_ate); + rc = nvs_prev_ate(fs, &wlk_addr, wlk_ate); if (rc) { return rc; } - if ((wlk_ate.id == hash_id) && (nvs_ate_valid(fs, &wlk_ate))) + if (wlk_ate->id == hash_id && nvs_ate_valid(fs, wlk_ate)) { - if ((wlk_ate.key_len == key_size) + if ((wlk_ate->key_len == key_size) && !nvs_flash_block_cmp(fs, - (rd_addr & ADDR_BLOCK_MASK) + - wlk_ate.offset, key, key_size)) + (rd_addr & NVS_ADDR_BLOCK_MASK) + + wlk_ate->offset, key, key_size)) { prev_found = true; break; @@ -1654,13 +1766,13 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, /* Previous entry found. */ - rd_addr &= ADDR_BLOCK_MASK; + rd_addr &= NVS_ADDR_BLOCK_MASK; if (pdata->len == 0) { /* If prev ate is expired, it is deleted. */ - if (wlk_ate.expired[0] != fs->erasestate) + if (nvs_ate_expired(fs, wlk_ate)) { /* Skip delete entry as it is already the * last one. @@ -1683,15 +1795,14 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, return 0; } } - else if (pdata->len == wlk_ate.len && - wlk_ate.expired[0] == fs->erasestate) + else if (pdata->len == wlk_ate->len && !nvs_ate_expired(fs, wlk_ate)) { /* Do not try to compare if lengths are not equal * or prev one is deleted. * Compare the data and if equal return 0. */ - rd_addr += wlk_ate.offset + wlk_ate.key_len; + rd_addr += wlk_ate->offset + wlk_ate->key_len; rc = nvs_flash_block_cmp(fs, rd_addr, pdata->configdata, pdata->len); if (rc <= 0) @@ -1712,9 +1823,9 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, /* Leave space for gc_done ate */ - required_space = data_size + sizeof(struct nvs_ate); + required_space = data_size + ate_size; gc_count = 0; - block_to_write_befor_gc = fs->ate_wra >> ADDR_BLOCK_SHIFT; + block_to_write_befor_gc = fs->ate_wra >> NVS_ADDR_BLOCK_SHIFT; while (1) { if (gc_count == fs->nblocks) @@ -1731,7 +1842,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, /* Nvs is changed after gc, we will look for the old ate. */ - if (prev_found && wlk_ate.expired[0] == fs->erasestate) + if (prev_found && !nvs_ate_expired(fs, wlk_ate)) { finfo("prev entry exists, search for it\n"); @@ -1739,7 +1850,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, if (gc_count >= fs->nblocks - 1 - (block_to_write_befor_gc + fs->nblocks - - (hist_addr >> ADDR_BLOCK_SHIFT)) + (hist_addr >> NVS_ADDR_BLOCK_SHIFT)) % fs->nblocks) { rc = nvs_read_entry(fs, key, key_size, NULL, 0, @@ -1774,7 +1885,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, * already expired) */ - if (prev_found && wlk_ate.expired[0] == fs->erasestate) + if (prev_found && !nvs_ate_expired(fs, wlk_ate)) { rc = nvs_expire_ate(fs, hist_addr); finfo("expir prev entry, %" PRIx32 ", rc %d\n", @@ -1854,7 +1965,7 @@ static ssize_t nvs_read(FAR struct nvs_fs *fs, FAR struct config_data_s *pdata) { size_t key_size; - ssize_t ret; + ssize_t rc; #ifdef CONFIG_MTD_CONFIG_NAMED FAR const uint8_t *key; @@ -1876,15 +1987,15 @@ static ssize_t nvs_read(FAR struct nvs_fs *fs, key_size = sizeof(pdata->id) + sizeof(pdata->instance); #endif - ret = nvs_read_entry(fs, key, key_size, pdata->configdata, pdata->len, + rc = nvs_read_entry(fs, key, key_size, pdata->configdata, pdata->len, NULL); - if (ret > 0) + if (rc > 0) { - pdata->len = ret; + pdata->len = rc; return 0; } - return ret; + return rc; } /**************************************************************************** @@ -1906,9 +2017,10 @@ static ssize_t nvs_read(FAR struct nvs_fs *fs, static int nvs_next(FAR struct nvs_fs *fs, FAR struct config_data_s *pdata, bool first) { - int rc; - struct nvs_ate step_ate; + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(step_ate, ate_size); uint32_t rd_addr; + int rc; if (pdata == NULL || pdata->len == 0 || pdata->configdata == NULL) { @@ -1936,15 +2048,15 @@ static int nvs_next(FAR struct nvs_fs *fs, do { rd_addr = fs->step_addr; - rc = nvs_prev_ate(fs, &(fs->step_addr), &step_ate); + rc = nvs_prev_ate(fs, &(fs->step_addr), step_ate); if (rc) { return rc; } - if (nvs_ate_valid(fs, &step_ate) - && step_ate.id != NVS_SPECIAL_ATE_ID - && step_ate.expired[0] == fs->erasestate) + if (nvs_ate_valid(fs, step_ate) + && step_ate->id != nvs_special_ate_id(fs) + && !nvs_ate_expired(fs, step_ate)) { break; } @@ -1957,8 +2069,8 @@ static int nvs_next(FAR struct nvs_fs *fs, while (true); #ifdef CONFIG_MTD_CONFIG_NAMED - rc = nvs_flash_rd(fs, (rd_addr & ADDR_BLOCK_MASK) + step_ate.offset, - key, MIN(step_ate.key_len, CONFIG_MTD_CONFIG_NAME_LEN)); + rc = nvs_flash_rd(fs, (rd_addr & NVS_ADDR_BLOCK_MASK) + step_ate->offset, + key, MIN(step_ate->key_len, CONFIG_MTD_CONFIG_NAME_LEN)); if (rc) { ferr("Key read failed, rc=%d\n", rc); @@ -1967,8 +2079,8 @@ static int nvs_next(FAR struct nvs_fs *fs, key[CONFIG_MTD_CONFIG_NAME_LEN - 1] = 0; #else - rc = nvs_flash_rd(fs, (rd_addr & ADDR_BLOCK_MASK) + step_ate.offset, - key, MIN(sizeof(key), step_ate.key_len)); + rc = nvs_flash_rd(fs, (rd_addr & NVS_ADDR_BLOCK_MASK) + step_ate->offset, + key, MIN(sizeof(key), step_ate->key_len)); if (rc) { ferr("Key read failed, rc=%d\n", rc); @@ -1979,16 +2091,16 @@ static int nvs_next(FAR struct nvs_fs *fs, memcpy(&pdata->instance, key + sizeof(pdata->id), sizeof(pdata->instance)); #endif - rc = nvs_flash_rd(fs, (rd_addr & ADDR_BLOCK_MASK) + step_ate.offset + - step_ate.key_len, pdata->configdata, - MIN(pdata->len, step_ate.len)); + rc = nvs_flash_rd(fs, (rd_addr & NVS_ADDR_BLOCK_MASK) + step_ate->offset + + step_ate->key_len, pdata->configdata, + MIN(pdata->len, step_ate->len)); if (rc) { ferr("Value read failed, rc=%d\n", rc); return rc; } - pdata->len = MIN(pdata->len, step_ate.len); + pdata->len = MIN(pdata->len, step_ate->len); return OK; } @@ -2067,12 +2179,12 @@ static int mtdconfig_ioctl(FAR struct file *filep, int cmd, FAR struct inode *inode = filep->f_inode; FAR struct nvs_fs *fs = inode->i_private; FAR struct config_data_s *pdata = (FAR struct config_data_s *)arg; - int ret = -ENOTTY; + int rc = -ENOTTY; - ret = nxmutex_lock(&fs->nvs_lock); - if (ret < 0) + rc = nxmutex_lock(&fs->nvs_lock); + if (rc < 0) { - return ret; + return rc; } switch (cmd) @@ -2081,15 +2193,15 @@ static int mtdconfig_ioctl(FAR struct file *filep, int cmd, /* Read a nvs item. */ - ret = nvs_read(fs, pdata); + rc = nvs_read(fs, pdata); break; case CFGDIOC_SETCONFIG: /* Write a nvs item. */ - ret = nvs_write(fs, pdata); - if (ret >= 0) + rc = nvs_write(fs, pdata); + if (rc >= 0) { mtdconfig_notify(fs, POLLPRI); } @@ -2100,8 +2212,8 @@ static int mtdconfig_ioctl(FAR struct file *filep, int cmd, /* Delete a nvs item. */ - ret = nvs_delete(fs, pdata); - if (ret >= 0) + rc = nvs_delete(fs, pdata); + if (rc >= 0) { mtdconfig_notify(fs, POLLPRI); } @@ -2112,31 +2224,31 @@ static int mtdconfig_ioctl(FAR struct file *filep, int cmd, /* Get the first item. */ - ret = nvs_next(fs, pdata, true); + rc = nvs_next(fs, pdata, true); break; case CFGDIOC_NEXTCONFIG: /* Get the next item. */ - ret = nvs_next(fs, pdata, false); + rc = nvs_next(fs, pdata, false); break; case MTDIOC_BULKERASE: /* Call the MTD's ioctl for this. */ - ret = MTD_IOCTL(fs->mtd, cmd, arg); - if (ret >= 0) + rc = MTD_IOCTL(fs->mtd, cmd, arg); + if (rc >= 0) { - ret = nvs_startup(fs); + rc = nvs_startup(fs); } break; } nxmutex_unlock(&fs->nvs_lock); - return ret; + return rc; } /**************************************************************************** @@ -2185,8 +2297,8 @@ static int mtdconfig_poll(FAR struct file *filep, FAR struct pollfd *fds, int mtdconfig_register_by_path(FAR struct mtd_dev_s *mtd, FAR const char *path) { - int ret; FAR struct nvs_fs *fs; + int rc; fs = kmm_malloc(sizeof(struct nvs_fs)); if (fs == NULL) @@ -2197,35 +2309,35 @@ int mtdconfig_register_by_path(FAR struct mtd_dev_s *mtd, /* Initialize the mtdnvs device structure */ fs->mtd = mtd; - ret = nxmutex_init(&fs->nvs_lock); - if (ret < 0) + rc = nxmutex_init(&fs->nvs_lock); + if (rc < 0) { - ferr("ERROR: nxmutex_init failed: %d\n", ret); + ferr("ERROR: nxmutex_init failed: %d\n", rc); goto errout; } - ret = nvs_startup(fs); - if (ret < 0) + rc = nvs_startup(fs); + if (rc < 0) { - ferr("ERROR: nvs_init failed: %d\n", ret); + ferr("ERROR: nvs_init failed: %d\n", rc); goto mutex_err; } - ret = register_driver(path, &g_mtdnvs_fops, 0666, fs); - if (ret < 0) + rc = register_driver(path, &g_mtdnvs_fops, 0666, fs); + if (rc < 0) { - ferr("ERROR: register mtd config failed: %d\n", ret); + ferr("ERROR: register mtd config failed: %d\n", rc); goto mutex_err; } - return ret; + return rc; mutex_err: nxmutex_destroy(&fs->nvs_lock); errout: kmm_free(fs); - return ret; + return rc; } /**************************************************************************** @@ -2251,16 +2363,16 @@ int mtdconfig_register(FAR struct mtd_dev_s *mtd) int mtdconfig_unregister_by_path(FAR const char *path) { - int ret; - struct file file; FAR struct inode *inode; FAR struct nvs_fs *fs; + struct file file; + int rc; - ret = file_open(&file, path, O_CLOEXEC); - if (ret < 0) + rc = file_open(&file, path, O_CLOEXEC); + if (rc < 0) { - ferr("ERROR: open file %s err: %d\n", path, ret); - return ret; + ferr("ERROR: open file %s err: %d\n", path, rc); + return rc; } inode = file.f_inode; diff --git a/drivers/mtd/mtd_partition.c b/drivers/mtd/mtd_partition.c index 20401040bc27a..b9a87c2029c03 100644 --- a/drivers/mtd/mtd_partition.c +++ b/drivers/mtd/mtd_partition.c @@ -901,7 +901,7 @@ FAR struct mtd_dev_s *mtd_partition(FAR struct mtd_dev_s *mtd, * nullified by kmm_zalloc). */ - part->child.erase = part_erase; + part->child.erase = mtd->erase ? part_erase : NULL; part->child.bread = part_bread; part->child.bwrite = part_bwrite; part->child.read = mtd->read ? part_read : NULL; diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 992a22b27e342..7a792b5370264 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -66,6 +66,12 @@ config NET_RPMSG_STACKSIZE ---help--- The stack size allocated for the net RPMSG task. +config NET_RPMSG_DRV_SERVER + bool "Net rpmsg default server" + default n + ---help--- + Enable the net rpmsg default server. + endif # NET_RPMSG_DRV config NETDEV_TELNET diff --git a/drivers/net/igc.c b/drivers/net/igc.c index 96fef7e275b06..7d3a720401c45 100644 --- a/drivers/net/igc.c +++ b/drivers/net/igc.c @@ -652,7 +652,7 @@ static FAR netpkt_t *igc_receive(FAR struct netdev_lowerhalf_s *dev) if (rx->errors) { nerr("RX error reported (%"PRIu8")\n", rx->errors); - NETDEV_RXERRORS(&priv->dev); + NETDEV_RXERRORS(&priv->dev.netdev); netpkt_free(dev, pkt, NETPKT_RX); return NULL; } @@ -691,7 +691,7 @@ static void igc_txdone(FAR struct netdev_lowerhalf_s *dev) if (!(priv->tx[priv->tx_done].status & IGC_TDESC_STATUS_DD)) { nerr("tx failed: 0x%" PRIx32 "\n", priv->tx[priv->tx_done].status); - NETDEV_TXERRORS(priv->dev); + NETDEV_TXERRORS(&priv->dev.netdev); } /* Free net packet */ diff --git a/drivers/net/rpmsgdrv.c b/drivers/net/rpmsgdrv.c index 6a3bc1676bc1f..fcffdc272a5ad 100644 --- a/drivers/net/rpmsgdrv.c +++ b/drivers/net/rpmsgdrv.c @@ -34,30 +34,27 @@ #include #include #include +#include #include #include #include -#include +#include #include #include +#include #include /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ -/* Work queue support is required. */ - -#if !defined(CONFIG_SCHED_WORKQUEUE) -# error Work queue support is required in this configuration (CONFIG_SCHED_WORKQUEUE) -#endif - -#ifdef CONFIG_NET_DUMPPACKET -# define net_rpmsg_drv_dumppacket lib_dumpbuffer -#else -# define net_rpmsg_drv_dumppacket(m, b, l) -#endif +#define NET_RPMSG_DRV_BUFSIZE (CONFIG_NET_ETH_PKTSIZE + CONFIG_NET_GUARDSIZE) +#define NET_RPMSG_DRV_MAX_PKT_SIZE \ + ((CONFIG_NET_LL_GUARDSIZE - ETH_HDRLEN) + NET_RPMSG_DRV_BUFSIZE) +#define NET_RPMSG_DRV_MAX_NIOB \ + ((NET_RPMSG_DRV_MAX_PKT_SIZE + CONFIG_IOB_BUFSIZE - 1) / \ + CONFIG_IOB_BUFSIZE) /**************************************************************************** * Private Types @@ -75,32 +72,39 @@ struct net_rpmsg_drv_cookie_s struct net_rpmsg_drv_s { - FAR const char *cpuname; - FAR const char *devname; + char cpuname[RPMSG_NAME_SIZE]; + netpkt_queue_t rxqueue; /* RX packet queue */ + spinlock_t lock; /* Spinlock for protecting rxqueue */ + FAR void *priv; /* Private data for upper layer */ + net_rpmsg_drv_cb_t cb; /* IFUP/DOWN Callback function */ + sem_t wait; /* Wait sem, used for preventing any + * operation until the connection + * between two cpu established. + */ struct rpmsg_endpoint ept; - struct work_s pollwork; /* For deferring poll work to the work queue */ /* This holds the information visible to the NuttX network */ - struct net_driver_s dev; /* Interface understood by the network */ + struct netdev_lowerhalf_s dev; /* Interface understood by the network */ }; /**************************************************************************** * Private Function Prototypes ****************************************************************************/ -/* Common TX logic */ - -static int net_rpmsg_drv_transmit(FAR struct net_driver_s *dev, - bool nocopy); -static int net_rpmsg_drv_txpoll(FAR struct net_driver_s *dev); -static void net_rpmsg_drv_reply(FAR struct net_driver_s *dev); - /* RPMSG related functions */ +/* Request handler functions */ + static int net_rpmsg_drv_default_handler(FAR struct rpmsg_endpoint *ept, FAR void *data, size_t len, uint32_t src, FAR void *priv); +static int net_rpmsg_drv_ifup_handler(FAR struct rpmsg_endpoint *ept, + FAR void *data, size_t len, + uint32_t src, FAR void *priv); +static int net_rpmsg_drv_ifdown_handler(FAR struct rpmsg_endpoint *ept, + FAR void *data, size_t len, + uint32_t src, FAR void *priv); static int net_rpmsg_drv_sockioctl_handler(FAR struct rpmsg_endpoint *ept, FAR void *data, size_t len, uint32_t src, FAR void *priv); @@ -108,35 +112,46 @@ static int net_rpmsg_drv_transfer_handler(FAR struct rpmsg_endpoint *ept, FAR void *data, size_t len, uint32_t src, FAR void *priv); +/* Response handler functions */ + +static int net_rpmsg_drv_default_response(FAR struct rpmsg_endpoint *ept, + FAR void *data, size_t len, + uint32_t src, FAR void *priv); + +/* RPMSG device related functions */ + static void net_rpmsg_drv_device_created(FAR struct rpmsg_device *rdev, - FAR void *priv_); + FAR void *priv); static void net_rpmsg_drv_device_destroy(FAR struct rpmsg_device *rdev, - FAR void *priv_); + FAR void *priv); static int net_rpmsg_drv_ept_cb(FAR struct rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, FAR void *priv); -static int net_rpmsg_drv_send_recv(struct net_driver_s *dev, - void *header_, uint32_t command, int len); +static int net_rpmsg_drv_send_recv(struct netdev_lowerhalf_s *dev, + void *header_, uint32_t command, + int len); /* NuttX callback functions */ -static int net_rpmsg_drv_ifup(FAR struct net_driver_s *dev); -static int net_rpmsg_drv_ifdown(FAR struct net_driver_s *dev); +static int net_rpmsg_drv_ifup(FAR struct netdev_lowerhalf_s *dev); +static int net_rpmsg_drv_ifdown(FAR struct netdev_lowerhalf_s *dev); -static void net_rpmsg_drv_txavail_work(FAR void *arg); -static int net_rpmsg_drv_txavail(FAR struct net_driver_s *dev); +static int net_rpmsg_drv_transmit(FAR struct netdev_lowerhalf_s *dev, + FAR netpkt_t *pkt); +static FAR netpkt_t * +net_rpmsg_drv_receive(FAR struct netdev_lowerhalf_s *dev); -#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) -static int net_rpmsg_drv_addmac(FAR struct net_driver_s *dev, - FAR const uint8_t *mac); +#ifdef CONFIG_NET_MCASTGROUP +static int net_rpmsg_drv_addmac(FAR struct netdev_lowerhalf_s *dev, + FAR const uint8_t *mac); #ifdef CONFIG_NET_IGMP -static int net_rpmsg_drv_rmmac(FAR struct net_driver_s *dev, - FAR const uint8_t *mac); +static int net_rpmsg_drv_rmmac(FAR struct netdev_lowerhalf_s *dev, + FAR const uint8_t *mac); #endif #endif #ifdef CONFIG_NETDEV_IOCTL -static int net_rpmsg_drv_ioctl(FAR struct net_driver_s *dev, int cmd, - unsigned long arg); +static int net_rpmsg_drv_ioctl(FAR struct netdev_lowerhalf_s *dev, int cmd, + unsigned long arg); #endif /**************************************************************************** @@ -145,8 +160,8 @@ static int net_rpmsg_drv_ioctl(FAR struct net_driver_s *dev, int cmd, static const rpmsg_ept_cb g_net_rpmsg_drv_handler[] = { - [NET_RPMSG_IFUP] = net_rpmsg_drv_default_handler, - [NET_RPMSG_IFDOWN] = net_rpmsg_drv_default_handler, + [NET_RPMSG_IFUP] = net_rpmsg_drv_ifup_handler, + [NET_RPMSG_IFDOWN] = net_rpmsg_drv_ifdown_handler, [NET_RPMSG_ADDMCAST] = net_rpmsg_drv_default_handler, [NET_RPMSG_RMMCAST] = net_rpmsg_drv_default_handler, [NET_RPMSG_DEVIOCTL] = net_rpmsg_drv_default_handler, @@ -154,23 +169,45 @@ static const rpmsg_ept_cb g_net_rpmsg_drv_handler[] = [NET_RPMSG_TRANSFER] = net_rpmsg_drv_transfer_handler, }; +static const rpmsg_ept_cb g_net_rpmsg_drv_response[] = +{ + [NET_RPMSG_IFUP] = net_rpmsg_drv_default_response, + [NET_RPMSG_IFDOWN] = net_rpmsg_drv_default_response, + [NET_RPMSG_ADDMCAST] = net_rpmsg_drv_default_response, + [NET_RPMSG_RMMCAST] = net_rpmsg_drv_default_response, + [NET_RPMSG_DEVIOCTL] = net_rpmsg_drv_default_response, + [NET_RPMSG_SOCKIOCTL] = net_rpmsg_drv_default_response, + [NET_RPMSG_TRANSFER] = net_rpmsg_drv_default_response, +}; + +static const struct netdev_ops_s g_net_rpmsg_drv_ops = +{ + .ifup = net_rpmsg_drv_ifup, + .ifdown = net_rpmsg_drv_ifdown, + .transmit = net_rpmsg_drv_transmit, + .receive = net_rpmsg_drv_receive, +#ifdef CONFIG_NET_MCASTGROUP + .addmac = net_rpmsg_drv_addmac, + .rmmac = net_rpmsg_drv_rmmac, +#endif +#ifdef CONFIG_NETDEV_IOCTL + .ioctl = net_rpmsg_drv_ioctl, +#endif +}; + /**************************************************************************** * Private Functions ****************************************************************************/ -static void net_rpmsg_drv_wait(FAR sem_t *sem) -{ - net_sem_wait_uninterruptible(sem); -} - /**************************************************************************** * Name: net_rpmsg_drv_transmit * * Description: - * Start hardware transmission. Called from watchdog based polling. + * Start hardware transmission. * * Parameters: * dev - Reference to the NuttX driver state structure + * pkt - The packet to be sent * * Returned Value: * OK on success; a negated errno on failure @@ -180,148 +217,123 @@ static void net_rpmsg_drv_wait(FAR sem_t *sem) * ****************************************************************************/ -static int net_rpmsg_drv_transmit(FAR struct net_driver_s *dev, bool nocopy) +static int net_rpmsg_drv_transmit(FAR struct netdev_lowerhalf_s *dev, + FAR netpkt_t *pkt) { - FAR struct net_rpmsg_drv_s *priv = dev->d_private; - FAR struct net_rpmsg_transfer_s *msg; + FAR struct net_rpmsg_drv_s *drv = + container_of(dev, struct net_rpmsg_drv_s, dev); + FAR struct net_rpmsg_transfer_s *transfer; + unsigned int datalen = netpkt_getdatalen(dev, pkt); + uint32_t len; int ret; - /* Verify that the hardware is ready to send another packet. If we get - * here, then we are committed to sending a packet; Higher level logic - * must have assured that there is no transmission in progress. - */ - - /* Increment statistics */ - - net_rpmsg_drv_dumppacket("transmit", dev->d_buf, dev->d_len); - NETDEV_TXPACKETS(dev); - - /* Send the packet: address=dev->d_buf, length=dev->d_len */ - - msg = (FAR struct net_rpmsg_transfer_s *)dev->d_buf - 1; - - msg->header.command = NET_RPMSG_TRANSFER; - msg->header.result = 0; - msg->header.cookie = 0; - msg->length = dev->d_len; - - if (nocopy) + transfer = rpmsg_get_tx_payload_buffer(&drv->ept, &len, true); + if (transfer == NULL) { - ret = rpmsg_send_nocopy(&priv->ept, msg, sizeof(*msg) + msg->length); + nwarn("WARNING: Failed to get buffer for xmit\n"); + return -ENOMEM; } - else + + if (len < sizeof(*transfer) + datalen) { - ret = rpmsg_send(&priv->ept, msg, sizeof(*msg) + msg->length); + nerr("ERROR: Buffer is too small for xmit\n"); + rpmsg_release_tx_buffer(&drv->ept, transfer); + return -ENOMEM; } + transfer->header.command = NET_RPMSG_TRANSFER; + transfer->header.result = 0; + transfer->header.cookie = 0; + transfer->length = datalen; + netpkt_copyout(dev, (FAR uint8_t *)(transfer + 1), pkt, datalen, 0); + + len = sizeof(*transfer) + datalen; + ret = rpmsg_send_nocopy(&drv->ept, transfer, len); if (ret < 0) { - if (nocopy) - { - rpmsg_release_tx_buffer(&priv->ept, msg); - } - - NETDEV_TXERRORS(dev); + nerr("ERROR: Failed to send packet\n"); + rpmsg_release_tx_buffer(&drv->ept, transfer); return ret; } - else - { - NETDEV_TXDONE(dev); - return OK; - } -} -/**************************************************************************** - * Name: net_rpmsg_drv_txpoll - * - * Description: - * The transmitter is available, check if the network has any outgoing - * packets ready to send. This is a callback from devif_poll(). - * devif_poll() may be called: - * - * 1. When the preceding TX packet send is complete, - * 2. When the preceding TX packet send fail - * 3. During normal TX polling - * - * Parameters: - * dev - Reference to the NuttX driver state structure - * - * Returned Value: - * OK on success; a negated errno on failure - * - * Assumptions: - * The network is locked. - * - ****************************************************************************/ + netpkt_free(dev, pkt, NETPKT_TX); + netdev_lower_txdone(dev); + return OK; +} -static int net_rpmsg_drv_txpoll(FAR struct net_driver_s *dev) +static FAR netpkt_t * +net_rpmsg_drv_receive(FAR struct netdev_lowerhalf_s *dev) { - FAR struct net_rpmsg_drv_s *priv = dev->d_private; - uint32_t size; + FAR struct net_rpmsg_drv_s *drv = + container_of(dev, struct net_rpmsg_drv_s, dev); + FAR netpkt_t *pkt; + irqstate_t flags; - /* Send the packet */ + flags = spin_lock_irqsave(&drv->lock); + pkt = netpkt_remove_queue(&drv->rxqueue); + spin_unlock_irqrestore(&drv->lock, flags); - net_rpmsg_drv_transmit(dev, true); + return pkt; +} + +/* RPMSG related functions */ - /* Check if there is room in the device to hold another packet. If - * not, return a non-zero value to terminate the poll. - */ +static void rpmsg_send_response(FAR struct rpmsg_endpoint *ept, + FAR struct net_rpmsg_header_s *header, + size_t len, int result) +{ + header->command |= NET_RPMSG_RESPONSE; + header->result = result; + rpmsg_send(ept, header, len); +} + +static int net_rpmsg_drv_default_handler(FAR struct rpmsg_endpoint *ept, + FAR void *data, size_t len, + uint32_t src, FAR void *priv) +{ + FAR struct net_rpmsg_header_s *header = data; - dev->d_buf = rpmsg_get_tx_payload_buffer(&priv->ept, &size, false); - if (dev->d_buf) + if (header->cookie) { - dev->d_buf += sizeof(struct net_rpmsg_transfer_s); - dev->d_pktsize = size - sizeof(struct net_rpmsg_transfer_s); + rpmsg_send_response(ept, header, sizeof(*header), -EOPNOTSUPP); } - return dev->d_buf == NULL; + return 0; } -/**************************************************************************** - * Name: net_rpmsg_drv_reply - * - * Description: - * After a packet has been received and dispatched to the network, it - * may return with an outgoing packet. This function checks for - * that case and performs the transmission if necessary. - * - * Parameters: - * dev - Reference to the NuttX driver state structure - * - * Returned Value: - * None - * - * Assumptions: - * The network is locked. - * - ****************************************************************************/ - -static void net_rpmsg_drv_reply(FAR struct net_driver_s *dev) +static int net_rpmsg_drv_ifup_handler(FAR struct rpmsg_endpoint *ept, + FAR void *data, size_t len, + uint32_t src, FAR void *priv) { - /* If the packet dispatch resulted in data that should be sent out on the - * network, the field d_len will set to a value > 0. - */ + FAR struct net_rpmsg_drv_s *drv = priv; + FAR struct net_rpmsg_header_s *header = data; - if (dev->d_len > 0) + netdev_lower_carrier_on(&drv->dev); + if (drv->cb != NULL) { - /* And send the packet */ - - net_rpmsg_drv_transmit(dev, false); + drv->cb(&drv->dev, NET_RPMSG_EVENT_CARRIER_ON); } -} -/* RPMSG related functions */ + rpmsg_send_response(ept, header, sizeof(*header), 0); -static int net_rpmsg_drv_default_handler(FAR struct rpmsg_endpoint *ept, - FAR void *data, size_t len, - uint32_t src, FAR void *priv) + return 0; +} + +static int net_rpmsg_drv_ifdown_handler(FAR struct rpmsg_endpoint *ept, + FAR void *data, size_t len, + uint32_t src, FAR void *priv) { + FAR struct net_rpmsg_drv_s *drv = priv; FAR struct net_rpmsg_header_s *header = data; - FAR struct net_rpmsg_drv_cookie_s *cookie = - (struct net_rpmsg_drv_cookie_s *)(uintptr_t)header->cookie; - memcpy(cookie->header, header, len); - nxsem_post(&cookie->sem); + netdev_lower_carrier_off(&drv->dev); + if (drv->cb != NULL) + { + drv->cb(&drv->dev, NET_RPMSG_EVENT_CARRIER_OFF); + } + + rpmsg_send_response(ept, header, sizeof(*header), 0); + return 0; } @@ -361,7 +373,8 @@ static int net_rpmsg_drv_sockioctl_task(int argc, FAR char *argv[]) if (msg->header.cookie) { - rpmsg_send(ept, msg, sizeof(*msg) + msg->length); + rpmsg_send_response(ept, &msg->header, sizeof(*msg) + msg->length, + msg->header.result); } rpmsg_release_rx_buffer(ept, msg); @@ -394,58 +407,6 @@ static int net_rpmsg_drv_sockioctl_handler(FAR struct rpmsg_endpoint *ept, return 0; } -#ifdef CONFIG_NET_IPv4 -static bool net_rpmsg_drv_is_ipv4(FAR struct net_driver_s *dev) -{ - FAR struct ipv4_hdr_s *ip = - (FAR struct ipv4_hdr_s *)(dev->d_buf + dev->d_llhdrlen); - FAR struct eth_hdr_s *eth = (FAR struct eth_hdr_s *)dev->d_buf; - - if (dev->d_lltype == NET_LL_ETHERNET || dev->d_lltype == NET_LL_IEEE80211) - { - return eth->type == HTONS(ETHTYPE_IP); - } - else - { - return (ip->vhl & IP_VERSION_MASK) == IPv4_VERSION; - } -} -#endif - -#ifdef CONFIG_NET_IPv6 -static bool net_rpmsg_drv_is_ipv6(FAR struct net_driver_s *dev) -{ - FAR struct ipv6_hdr_s *ip = - (FAR struct ipv6_hdr_s *)(dev->d_buf + dev->d_llhdrlen); - FAR struct eth_hdr_s *eth = (FAR struct eth_hdr_s *)dev->d_buf; - - if (dev->d_lltype == NET_LL_ETHERNET || dev->d_lltype == NET_LL_IEEE80211) - { - return eth->type == HTONS(ETHTYPE_IP6); - } - else - { - return (ip->vtc & IP_VERSION_MASK) == IPv6_VERSION; - } -} -#endif - -#ifdef CONFIG_NET_ARP -static bool net_rpmsg_drv_is_arp(FAR struct net_driver_s *dev) -{ - FAR struct eth_hdr_s *eth = (FAR struct eth_hdr_s *)dev->d_buf; - - if (dev->d_lltype == NET_LL_ETHERNET || dev->d_lltype == NET_LL_IEEE80211) - { - return eth->type == HTONS(ETHTYPE_ARP); - } - else - { - return false; - } -} -#endif - /**************************************************************************** * Name: net_rpmsg_drv_transfer_handler * @@ -467,128 +428,145 @@ static int net_rpmsg_drv_transfer_handler(FAR struct rpmsg_endpoint *ept, FAR void *data, size_t len, uint32_t src, FAR void *priv) { - FAR struct net_driver_s *dev = ept->priv; - FAR struct net_rpmsg_transfer_s *msg = data; - FAR void *oldbuf; - - /* Lock the network and serialize driver operations if necessary. - * NOTE: Serialization is only required in the case where the driver work - * is performed on an LP worker thread and where more than one LP worker - * thread has been configured. - */ - - net_lock(); - - /* Check for errors and update statistics */ - - net_rpmsg_drv_dumppacket("receive", msg->data, msg->length); - - NETDEV_RXPACKETS(dev); - - /* Copy the data from the hardware to dev->d_buf. Set - * amount of data in dev->d_len - */ - - oldbuf = dev->d_buf; - - dev->d_buf = msg->data; - dev->d_len = msg->length; - -#ifdef CONFIG_NET_PKT - /* When packet sockets are enabled, feed the frame into the tap */ + FAR struct net_rpmsg_transfer_s *transfer = data; + FAR struct net_rpmsg_drv_s *drv = priv; + FAR struct netdev_lowerhalf_s *dev = &drv->dev; + FAR netpkt_t *pkt; + irqstate_t flags; + int ret; - pkt_input(dev); -#endif + if (transfer->length > len - sizeof(*transfer)) + { + nerr("ERROR: net_rpmsg got invalid transfer length!"); + goto drop; + } - /* We only accept IP packets of the configured type and ARP packets */ + /* TODO: No-Copy, hold rx buffer */ -#ifdef CONFIG_NET_IPv4 - if (net_rpmsg_drv_is_ipv4(dev)) + pkt = netpkt_alloc(dev, NETPKT_RX); + if (pkt == NULL) { - ninfo("IPv4 frame\n"); - NETDEV_RXIPV4(dev); + nerr("ERROR: Failed to allocate buffer!\n"); + goto drop; + } - /* Receive an IPv4 packet from the network device */ + if (netpkt_copyin(dev, pkt, (FAR uint8_t *)(transfer + 1), + transfer->length, 0) < 0) + { + nerr("ERROR: Failed to copy in data!\n"); + goto free; + } - ipv4_input(dev); + flags = spin_lock_irqsave(&drv->lock); + ret = netpkt_tryadd_queue(pkt, &drv->rxqueue); + spin_unlock_irqrestore(&drv->lock, flags); + if (ret < 0) + { + nerr("ERROR: Failed to add pkt to queue!\n"); + goto free; + } - /* Check for a reply to the IPv4 packet */ + netdev_lower_rxready(dev); + return 0; - net_rpmsg_drv_reply(dev); - } - else -#endif -#ifdef CONFIG_NET_IPv6 - if (net_rpmsg_drv_is_ipv6(dev)) - { - ninfo("IPv6 frame\n"); - NETDEV_RXIPV6(dev); +free: + netpkt_free(dev, pkt, NETPKT_RX); - /* Dispatch IPv6 packet to the network layer */ +drop: + NETDEV_RXDROPPED(&dev->netdev); + return 0; +} - ipv6_input(dev); +/**************************************************************************** + * Name: net_rpmsg_drv_default_response + * + * Description: + * This function is used to handle the response from the RPMSG device. + * It is used to copy the response to the cookie and post the semaphore. + * + ****************************************************************************/ - /* Check for a reply to the IPv6 packet */ +static int net_rpmsg_drv_default_response(FAR struct rpmsg_endpoint *ept, + FAR void *data, size_t len, + uint32_t src, FAR void *priv) +{ + FAR struct net_rpmsg_header_s *header = data; + FAR struct net_rpmsg_drv_cookie_s *cookie = + (struct net_rpmsg_drv_cookie_s *)(uintptr_t)header->cookie; - net_rpmsg_drv_reply(dev); - } - else -#endif -#ifdef CONFIG_NET_ARP - if (net_rpmsg_drv_is_arp(dev)) - { - ninfo("ARP frame\n"); - NETDEV_RXARP(dev); + memcpy(cookie->header, header, len); + nxsem_post(&cookie->sem); + return 0; +} - /* Dispatch ARP packet to the network layer */ +/**************************************************************************** + * Name: net_rpmsg_drv_ept_release + ****************************************************************************/ - arp_input(dev); +static void net_rpmsg_drv_ept_release(FAR struct rpmsg_endpoint *ept) +{ + FAR struct net_rpmsg_drv_s *drv = ept->priv; - /* Check for a reply to the ARP packet */ + netdev_lower_carrier_off(&drv->dev); + rpmsg_wait(&drv->ept, &drv->wait); +} - net_rpmsg_drv_reply(dev); - } - else -#endif - { - NETDEV_RXDROPPED(dev); - } +/**************************************************************************** + * Name: net_rpmsg_drv_ns_bound + * + * Description: + * Rpmsg device end point service bound callback function , called when + * remote end point address is received. + * + * Parameters: + * ept - The rpmsg-device end point + * + * Returned Values: + * None + * + ****************************************************************************/ - dev->d_buf = oldbuf; - net_unlock(); +static void net_rpmsg_drv_ns_bound(FAR struct rpmsg_endpoint *ept) +{ + FAR struct net_rpmsg_drv_s *drv = ept->priv; - return 0; + rpmsg_post(&drv->ept, &drv->wait); } +/**************************************************************************** + * Name: net_rpmsg_drv_device_created + ****************************************************************************/ + static void net_rpmsg_drv_device_created(FAR struct rpmsg_device *rdev, - FAR void *priv_) + FAR void *priv) { - FAR struct net_driver_s *dev = priv_; - FAR struct net_rpmsg_drv_s *priv = dev->d_private; + FAR struct net_rpmsg_drv_s *drv = priv; char eptname[RPMSG_NAME_SIZE]; - if (!strcmp(priv->cpuname, rpmsg_get_cpuname(rdev))) + if (!strcmp(drv->cpuname, rpmsg_get_cpuname(rdev))) { - priv->ept.priv = dev; + drv->ept.priv = drv; snprintf(eptname, sizeof(eptname), - NET_RPMSG_EPT_NAME, priv->devname); + NET_RPMSG_EPT_PREFIX "%s", drv->dev.netdev.d_ifname); - rpmsg_create_ept(&priv->ept, rdev, eptname, + rpmsg_create_ept(&drv->ept, rdev, eptname, RPMSG_ADDR_ANY, RPMSG_ADDR_ANY, net_rpmsg_drv_ept_cb, NULL); } } +/**************************************************************************** + * Name: net_rpmsg_drv_device_destroy + ****************************************************************************/ + static void net_rpmsg_drv_device_destroy(FAR struct rpmsg_device *rdev, - FAR void *priv_) + FAR void *priv) { - FAR struct net_driver_s *dev = priv_; - FAR struct net_rpmsg_drv_s *priv = dev->d_private; + FAR struct net_rpmsg_drv_s *drv = priv; - if (!strcmp(priv->cpuname, rpmsg_get_cpuname(rdev))) + if (!strcmp(drv->cpuname, rpmsg_get_cpuname(rdev))) { - rpmsg_destroy_ept(&priv->ept); - dev->d_buf = NULL; + rpmsg_destroy_ept(&drv->ept); } } @@ -596,26 +574,41 @@ static int net_rpmsg_drv_ept_cb(FAR struct rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, FAR void *priv) { FAR struct net_rpmsg_header_s *header = data; - uint32_t command = header->command; + uint32_t cmd = NET_RPMSG_GET_COMMAND(header->command); - if (command < sizeof(g_net_rpmsg_drv_handler) / - sizeof(g_net_rpmsg_drv_handler[0])) + if (cmd < nitems(g_net_rpmsg_drv_handler)) { - return g_net_rpmsg_drv_handler[command](ept, data, len, src, priv); + if (NET_RPMSG_IS_RESPONSE(header->command)) + { + return g_net_rpmsg_drv_response[cmd](ept, data, len, src, priv); + } + else + { + return g_net_rpmsg_drv_handler[cmd](ept, data, len, src, priv); + } } return -EINVAL; } -static int net_rpmsg_drv_send_recv(FAR struct net_driver_s *dev, +static int net_rpmsg_drv_send_recv(FAR struct netdev_lowerhalf_s *dev, FAR void *header_, uint32_t command, int len) { - FAR struct net_rpmsg_drv_s *priv = dev->d_private; + FAR struct net_rpmsg_drv_s *drv = + container_of(dev, struct net_rpmsg_drv_s, dev); FAR struct net_rpmsg_header_s *header = header_; FAR struct net_rpmsg_drv_cookie_s cookie; + int sval = 0; int ret; + nxsem_get_value(&drv->wait, &sval); + if (sval <= 0) + { + rpmsg_wait(&drv->ept, &drv->wait); + rpmsg_post(&drv->ept, &drv->wait); + } + nxsem_init(&cookie.sem, 0, 0); cookie.header = header; @@ -623,13 +616,14 @@ static int net_rpmsg_drv_send_recv(FAR struct net_driver_s *dev, header->result = -ENXIO; header->cookie = (uintptr_t)&cookie; - ret = rpmsg_send(&priv->ept, header, len); + ret = rpmsg_send(&drv->ept, header, len); if (ret < 0) { goto out; } - net_rpmsg_drv_wait(&cookie.sem); + net_sem_timedwait2(&cookie.sem, false, UINT_MAX, &dev->netdev.d_lock, + NULL); ret = cookie.header->result; out: @@ -655,8 +649,10 @@ static int net_rpmsg_drv_send_recv(FAR struct net_driver_s *dev, * ****************************************************************************/ -static int net_rpmsg_drv_ifup(FAR struct net_driver_s *dev) +static int net_rpmsg_drv_ifup(FAR struct netdev_lowerhalf_s *dev) { + FAR struct net_rpmsg_drv_s *drv = + container_of(dev, struct net_rpmsg_drv_s, dev); struct net_rpmsg_ifup_s msg = { }; @@ -665,33 +661,34 @@ static int net_rpmsg_drv_ifup(FAR struct net_driver_s *dev) #ifdef CONFIG_NET_IPv4 ninfo("Bringing up: %u.%u.%u.%u\n", - ip4_addr1(dev->d_ipaddr), ip4_addr2(dev->d_ipaddr), - ip4_addr3(dev->d_ipaddr), ip4_addr4(dev->d_ipaddr)); + ip4_addr1(dev->netdev.d_ipaddr), ip4_addr2(dev->netdev.d_ipaddr), + ip4_addr3(dev->netdev.d_ipaddr), ip4_addr4(dev->netdev.d_ipaddr)); #endif #ifdef CONFIG_NET_IPv6 ninfo("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", - dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2], - dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5], - dev->d_ipv6addr[6], dev->d_ipv6addr[7]); + dev->netdev.d_ipv6addr[0], dev->netdev.d_ipv6addr[1], + dev->netdev.d_ipv6addr[2], dev->netdev.d_ipv6addr[3], + dev->netdev.d_ipv6addr[4], dev->netdev.d_ipv6addr[5], + dev->netdev.d_ipv6addr[6], dev->netdev.d_ipv6addr[7]); #endif - net_lock(); + netdev_lock(&dev->netdev); /* Prepare the message */ - msg.lnkaddr.length = netdev_lladdrsize(dev); - memcpy(msg.lnkaddr.addr, &dev->d_mac, msg.lnkaddr.length); + msg.lnkaddr.length = netdev_lladdrsize(&dev->netdev); + memcpy(msg.lnkaddr.addr, &dev->netdev.d_mac, msg.lnkaddr.length); #ifdef CONFIG_NET_IPv4 - net_ipv4addr_copy(msg.ipaddr, dev->d_ipaddr); - net_ipv4addr_copy(msg.draddr, dev->d_draddr); - net_ipv4addr_copy(msg.netmask, dev->d_netmask); + net_ipv4addr_copy(msg.ipaddr, dev->netdev.d_ipaddr); + net_ipv4addr_copy(msg.draddr, dev->netdev.d_draddr); + net_ipv4addr_copy(msg.netmask, dev->netdev.d_netmask); #endif #ifdef CONFIG_NET_IPv6 - net_ipv6addr_copy(msg.ipv6addr, dev->d_ipv6addr); - net_ipv6addr_copy(msg.ipv6draddr, dev->d_ipv6draddr); - net_ipv6addr_copy(msg.ipv6netmask, dev->d_ipv6netmask); + net_ipv6addr_copy(msg.ipv6addr, dev->netdev.d_ipv6addr); + net_ipv6addr_copy(msg.ipv6draddr, dev->netdev.d_ipv6draddr); + net_ipv6addr_copy(msg.ipv6netmask, dev->netdev.d_ipv6netmask); #endif /* Send the message */ @@ -699,27 +696,27 @@ static int net_rpmsg_drv_ifup(FAR struct net_driver_s *dev) ret = net_rpmsg_drv_send_recv(dev, &msg, NET_RPMSG_IFUP, sizeof(msg)); if (ret < 0) { - net_unlock(); + netdev_unlock(&dev->netdev); return ret; } /* Update net_driver_t field */ - memcpy(&dev->d_mac, msg.lnkaddr.addr, msg.lnkaddr.length); + memcpy(&dev->netdev.d_mac, msg.lnkaddr.addr, msg.lnkaddr.length); #ifdef CONFIG_NET_IPv4 - net_ipv4addr_copy(dev->d_ipaddr, msg.ipaddr); - net_ipv4addr_copy(dev->d_draddr, msg.draddr); - net_ipv4addr_copy(dev->d_netmask, msg.netmask); + net_ipv4addr_copy(dev->netdev.d_ipaddr, msg.ipaddr); + net_ipv4addr_copy(dev->netdev.d_draddr, msg.draddr); + net_ipv4addr_copy(dev->netdev.d_netmask, msg.netmask); #endif #ifdef CONFIG_NET_IPv6 - net_ipv6addr_copy(dev->d_ipv6addr, msg.ipv6addr); - net_ipv6addr_copy(dev->d_ipv6draddr, msg.ipv6draddr); - net_ipv6addr_copy(dev->d_ipv6netmask, msg.ipv6netmask); + net_ipv6addr_copy(dev->netdev.d_ipv6addr, msg.ipv6addr); + net_ipv6addr_copy(dev->netdev.d_ipv6draddr, msg.ipv6draddr); + net_ipv6addr_copy(dev->netdev.d_ipv6netmask, msg.ipv6netmask); #endif - net_unlock(); + netdev_unlock(&dev->netdev); #ifdef CONFIG_NETDB_DNSCLIENT # ifdef CONFIG_NET_IPv4 @@ -755,6 +752,11 @@ static int net_rpmsg_drv_ifup(FAR struct net_driver_s *dev) # endif #endif + if (drv->cb != NULL) + { + drv->cb(dev, NET_RPMSG_EVENT_IF_UP); + } + return OK; } @@ -775,120 +777,28 @@ static int net_rpmsg_drv_ifup(FAR struct net_driver_s *dev) * ****************************************************************************/ -static int net_rpmsg_drv_ifdown(FAR struct net_driver_s *dev) -{ - FAR struct net_rpmsg_drv_s *priv = dev->d_private; - FAR struct net_rpmsg_ifdown_s msg; - - work_cancel(LPWORK, &priv->pollwork); - - /* Put the EMAC in its reset, non-operational state. This should be - * a known configuration that will guarantee the net_rpmsg_drv_ifup() - * always successfully brings the interface back up. - */ - - return net_rpmsg_drv_send_recv(dev, &msg, NET_RPMSG_IFDOWN, sizeof(msg)); -} - -/**************************************************************************** - * Name: net_rpmsg_drv_txavail_work - * - * Description: - * Perform an out-of-cycle poll on the worker thread. - * - * Parameters: - * arg - Reference to the NuttX driver state structure (cast to void*) - * - * Returned Value: - * None - * - * Assumptions: - * Runs on a work queue thread. - * - ****************************************************************************/ - -static void net_rpmsg_drv_txavail_work(FAR void *arg) +static int net_rpmsg_drv_ifdown(FAR struct netdev_lowerhalf_s *dev) { - FAR struct net_driver_s *dev = arg; - FAR struct net_rpmsg_drv_s *priv = dev->d_private; - uint32_t size; - - /* Lock the network and serialize driver operations if necessary. - * NOTE: Serialization is only required in the case where the driver work - * is performed on an LP worker thread and where more than one LP worker - * thread has been configured. - */ - - net_lock(); + FAR struct net_rpmsg_drv_s *drv = + container_of(dev, struct net_rpmsg_drv_s, dev); + struct net_rpmsg_ifdown_s msg = + { + }; - /* Ignore the notification if the interface is not yet up */ + int ret; - if (IFF_IS_UP(dev->d_flags)) + ret = net_rpmsg_drv_send_recv(dev, &msg, NET_RPMSG_IFDOWN, sizeof(msg)); + if (ret < 0) { - /* Try to get the payload buffer if not yet */ - - if (dev->d_buf == NULL) - { - dev->d_buf = rpmsg_get_tx_payload_buffer(&priv->ept, &size, false); - if (dev->d_buf) - { - dev->d_buf += sizeof(struct net_rpmsg_transfer_s); - dev->d_pktsize = size - sizeof(struct net_rpmsg_transfer_s); - } - } - - /* Check if there is room in the hardware to hold another outgoing - * packet. - */ - - if (dev->d_buf) - { - /* If so, then poll the network for new XMIT data */ - - devif_poll(dev, net_rpmsg_drv_txpoll); - } + return ret; } - net_unlock(); -} - -/**************************************************************************** - * Name: net_rpmsg_drv_txavail - * - * Description: - * Driver callback invoked when new TX data is available. This is a - * stimulus perform an out-of-cycle poll and, thereby, reduce the TX - * latency. - * - * Parameters: - * dev - Reference to the NuttX driver state structure - * - * Returned Value: - * None - * - * Assumptions: - * The network is locked. - * - ****************************************************************************/ - -static int net_rpmsg_drv_txavail(FAR struct net_driver_s *dev) -{ - FAR struct net_rpmsg_drv_s *priv = dev->d_private; - - /* Is our single work structure available? It may not be if there are - * pending interrupt actions and we will have to ignore the Tx - * availability action. - */ - - if (work_available(&priv->pollwork)) + if (drv->cb != NULL) { - /* Schedule to serialize the poll on the worker thread. */ - - work_queue(LPWORK, &priv->pollwork, net_rpmsg_drv_txavail_work, - dev, 0); + drv->cb(dev, NET_RPMSG_EVENT_IF_DOWN); } - return OK; + return ret; } /**************************************************************************** @@ -907,19 +817,18 @@ static int net_rpmsg_drv_txavail(FAR struct net_driver_s *dev) * ****************************************************************************/ -#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) -static int net_rpmsg_drv_addmac(FAR struct net_driver_s *dev, +#ifdef CONFIG_NET_MCASTGROUP +static int net_rpmsg_drv_addmac(FAR struct netdev_lowerhalf_s *dev, FAR const uint8_t *mac) { struct net_rpmsg_mcast_s msg; /* Add the MAC address to the hardware multicast routing table */ - msg.lnkaddr.length = netdev_lladdrsize(dev); + msg.lnkaddr.length = netdev_lladdrsize(&dev->netdev); memcpy(msg.lnkaddr.addr, mac, msg.lnkaddr.length); return net_rpmsg_drv_send_recv(dev, &msg, NET_RPMSG_ADDMCAST, sizeof(msg)); } -#endif /**************************************************************************** * Name: net_rpmsg_drv_rmmac @@ -937,15 +846,14 @@ static int net_rpmsg_drv_addmac(FAR struct net_driver_s *dev, * ****************************************************************************/ -#ifdef CONFIG_NET_IGMP -static int net_rpmsg_drv_rmmac(FAR struct net_driver_s *dev, +static int net_rpmsg_drv_rmmac(FAR struct netdev_lowerhalf_s *dev, FAR const uint8_t *mac) { struct net_rpmsg_mcast_s msg; /* Remove the MAC address from the hardware multicast routing table */ - msg.lnkaddr.length = netdev_lladdrsize(dev); + msg.lnkaddr.length = netdev_lladdrsize(&dev->netdev); memcpy(msg.lnkaddr.addr, mac, msg.lnkaddr.length); return net_rpmsg_drv_send_recv(dev, &msg, NET_RPMSG_RMMCAST, sizeof(msg)); } @@ -971,7 +879,7 @@ static int net_rpmsg_drv_rmmac(FAR struct net_driver_s *dev, ****************************************************************************/ #ifdef CONFIG_NETDEV_IOCTL -static int net_rpmsg_drv_ioctl(FAR struct net_driver_s *dev, int cmd, +static int net_rpmsg_drv_ioctl(FAR struct netdev_lowerhalf_s *dev, int cmd, unsigned long arg) { ssize_t len; @@ -1005,6 +913,93 @@ static int net_rpmsg_drv_ioctl(FAR struct net_driver_s *dev, int cmd, } #endif +/**************************************************************************** + * Name: net_rpmsg_drv_alloc + ****************************************************************************/ + +static FAR struct net_rpmsg_drv_s * +net_rpmsg_drv_alloc(FAR const char *devname, enum net_lltype_e lltype) +{ + FAR struct net_rpmsg_drv_s *drv = kmm_zalloc(sizeof(*drv)); + FAR struct netdev_lowerhalf_s *netdev; + + if (!drv) + { + return NULL; + } + + netdev = &drv->dev; + netdev->quota[NETPKT_RX] = CONFIG_IOB_NBUFFERS / + NET_RPMSG_DRV_MAX_NIOB / 4; + netdev->quota[NETPKT_TX] = 1; + netdev->ops = &g_net_rpmsg_drv_ops; + + drv->ept.priv = drv; + drv->ept.release_cb = net_rpmsg_drv_ept_release; + drv->ept.ns_bound_cb = net_rpmsg_drv_ns_bound; + + nxsem_init(&drv->wait, 0, 0); + spin_lock_init(&drv->lock); + + /* Init a random MAC address, the caller can override it. */ + + arc4random_buf(&netdev->netdev.d_mac.ether.ether_addr_octet, + sizeof(netdev->netdev.d_mac.ether.ether_addr_octet)); + + strlcpy(netdev->netdev.d_ifname, devname, IFNAMSIZ); + + netdev_lower_register(netdev, lltype); + + return drv; +} + +#ifdef CONFIG_NET_RPMSG_DRV_SERVER +/**************************************************************************** + * Name: net_rpmsg_drv_ns_match + ****************************************************************************/ + +static bool net_rpmsg_drv_ns_match(FAR struct rpmsg_device *rdev, + FAR void *priv, FAR const char *name, + uint32_t dest) +{ + return !strncmp(name, NET_RPMSG_EPT_PREFIX, strlen(NET_RPMSG_EPT_PREFIX)); +} + +/**************************************************************************** + * Name: net_rpmsg_drv_ns_bind + ****************************************************************************/ + +static void net_rpmsg_drv_ns_bind(FAR struct rpmsg_device *rdev, + FAR void *priv_, FAR const char *name, + uint32_t dest) +{ + FAR struct net_rpmsg_drv_s *drv; + FAR struct net_driver_s *dev; + const char *devname = name + strlen(NET_RPMSG_EPT_PREFIX); + + dev = netdev_findbyname(devname); + if (dev) + { + drv = container_of(dev, struct net_rpmsg_drv_s, dev.netdev); + drv->ept.priv = drv; + drv->ept.release_cb = net_rpmsg_drv_ept_release; + drv->ept.ns_bound_cb = net_rpmsg_drv_ns_bound; + } + else + { + drv = net_rpmsg_drv_alloc(devname, NET_LL_ETHERNET); + if (!drv) + { + return; + } + } + + rpmsg_create_ept(&drv->ept, rdev, name, RPMSG_ADDR_ANY, dest, + net_rpmsg_drv_ept_cb, rpmsg_destroy_ept); + rpmsg_post(&drv->ept, &drv->wait); +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -1013,82 +1008,97 @@ static int net_rpmsg_drv_ioctl(FAR struct net_driver_s *dev, int cmd, * Name: net_rpmsg_drv_init * * Description: - * Initialize the net rpmsg driver + * Allocate a new network device instance for the RPMSG network and + * register it with the network device manager. This is the client side of + * the RPMSG driver. The RPMSG driver is the server side of the driver. * * Parameters: - * name - Specify the netdev name - * lltype - Identify the link type + * cpuname - Remote CPU name + * devname - Local and remote network device name + * lltype - Link layer type * * Returned Value: - * OK on success; Negated errno on failure. - * - * Assumptions: - * Called early in initialization before multi-tasking is initiated. + * A pointer to the allocated network device instance. NULL is returned on + * failure. * ****************************************************************************/ -int net_rpmsg_drv_init(FAR const char *cpuname, - FAR const char *devname, - enum net_lltype_e lltype) +FAR struct netdev_lowerhalf_s * +net_rpmsg_drv_init(FAR const char *cpuname, FAR const char *devname, + enum net_lltype_e lltype) { - FAR struct net_rpmsg_drv_s *priv; - FAR struct net_driver_s *dev; + FAR struct net_rpmsg_drv_s *drv; + FAR struct netdev_lowerhalf_s *dev; int ret; /* Allocate the interface structure */ - priv = kmm_zalloc(sizeof(*priv)); - if (priv == NULL) + if (!devname || !cpuname || + !(drv = net_rpmsg_drv_alloc(devname, lltype))) { - return -ENOMEM; + return NULL; } - dev = &priv->dev; + strlcpy(drv->cpuname, cpuname, RPMSG_NAME_SIZE); - priv->cpuname = cpuname; - priv->devname = devname; - - /* Initialize the driver structure */ - - strlcpy(dev->d_ifname, devname, sizeof(dev->d_ifname)); - dev->d_ifup = net_rpmsg_drv_ifup; /* I/F up (new IP address) callback */ - dev->d_ifdown = net_rpmsg_drv_ifdown; /* I/F down callback */ - dev->d_txavail = net_rpmsg_drv_txavail; /* New TX data callback */ -#ifdef CONFIG_NET_IGMP - dev->d_addmac = net_rpmsg_drv_addmac; /* Add multicast MAC address */ - dev->d_rmmac = net_rpmsg_drv_rmmac; /* Remove multicast MAC address */ -#endif -#ifdef CONFIG_NETDEV_IOCTL - dev->d_ioctl = net_rpmsg_drv_ioctl; /* Handle network IOCTL commands */ -#endif - dev->d_private = priv; /* Used to recover private state from dev */ + dev = &drv->dev; /* Register the device with the openamp */ - ret = rpmsg_register_callback(dev, - net_rpmsg_drv_device_created, - net_rpmsg_drv_device_destroy, - NULL, - NULL); + ret = rpmsg_register_callback(drv, + net_rpmsg_drv_device_created, + net_rpmsg_drv_device_destroy, + NULL, + NULL); if (ret < 0) { - kmm_free(priv); - return ret; + netdev_lower_unregister(dev); + nxsem_destroy(&drv->wait); + kmm_free(drv); + return NULL; } - /* Register the device with the OS so that socket IOCTLs can be performed */ + return dev; +} + +/**************************************************************************** + * Name: net_rpmsg_drv_priv + ****************************************************************************/ - ret = netdev_register(dev, lltype); - if (ret < 0) - { - rpmsg_unregister_callback(dev, - net_rpmsg_drv_device_created, - net_rpmsg_drv_device_destroy, - NULL, - NULL); - kmm_free(priv); - } +FAR void *net_rpmsg_drv_priv(FAR struct netdev_lowerhalf_s *dev) +{ + FAR struct net_rpmsg_drv_s *drv = + container_of(dev, struct net_rpmsg_drv_s, dev); - return ret; + return drv->priv; +} + +/**************************************************************************** + * Name: net_rpmsg_drv_set_callback + ****************************************************************************/ + +void net_rpmsg_drv_set_callback(FAR struct netdev_lowerhalf_s *dev, + net_rpmsg_drv_cb_t cb, FAR void *priv) +{ + FAR struct net_rpmsg_drv_s *drv = + container_of(dev, struct net_rpmsg_drv_s, dev); + + drv->cb = cb; + drv->priv = priv; } + +#ifdef CONFIG_NET_RPMSG_DRV_SERVER +/**************************************************************************** + * Name: net_rpmsg_drv_server_init + ****************************************************************************/ + +int net_rpmsg_drv_server_init(void) +{ + return rpmsg_register_callback(NULL, + NULL, + NULL, + net_rpmsg_drv_ns_match, + net_rpmsg_drv_ns_bind); +} +#endif diff --git a/drivers/net/wifi_sim.c b/drivers/net/wifi_sim.c index 4f5168fa738a8..70ef054593bd9 100644 --- a/drivers/net/wifi_sim.c +++ b/drivers/net/wifi_sim.c @@ -146,6 +146,7 @@ enum WLAN_STA_STATE_E WLAN_STA_STATE_INIT, WLAN_STA_STATE_CONNECTING, WLAN_STA_STATE_CONNECTED, + WLAN_STA_STATE_DISCONNECTED, }; enum WLAN_STA_CONNERR_E @@ -915,6 +916,8 @@ static int wifidriver_start_disconnect(FAR struct wifi_sim_s *wifidev) { if (wifidev->state == WLAN_STA_STATE_CONNECTED) { + wifidev->state = WLAN_STA_STATE_DISCONNECTED; + /* free the connected_ap */ free(wifidev->connected_ap); @@ -1974,6 +1977,8 @@ int wifi_sim_init(FAR struct wifi_sim_lowerhalf_s *netdev) priv->lower = &netdev->lower; netdev->wifi = priv; + priv->mode = IW_MODE_AUTO; + return OK; } @@ -1993,3 +1998,23 @@ void wifi_sim_remove(FAR struct wifi_sim_lowerhalf_s *netdev) kmm_free(netdev->wifi); } +/**************************************************************************** + * Name: wifi_sim_connected + ****************************************************************************/ + +bool wifi_sim_connected(FAR struct wifi_sim_lowerhalf_s *dev) +{ + FAR struct wifi_sim_s *wifidev = (FAR struct wifi_sim_s *)dev->wifi; + + if (wifidev->mode == IW_MODE_MASTER) + { + return true; + } + else if (wifidev->mode == IW_MODE_INFRA) + { + return wifidev->state == WLAN_STA_STATE_CONNECTED; + } + + return false; +} + diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 42860eb325cfe..694ce7f372daa 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -687,7 +687,8 @@ static void pci_setup_device(FAR struct pci_device_s *dev, int max_bar, FAR struct pci_resource_s *mem_pref) { int bar; - uint32_t orig; + uint32_t orig0; + uint32_t orig1; uint32_t mask; uint64_t orig64; uint64_t size64; @@ -711,10 +712,9 @@ static void pci_setup_device(FAR struct pci_device_s *dev, int max_bar, FAR struct pci_resource_s *res; unsigned int flags; - pci_read_config_dword(dev, base_address_0, &orig); - pci_write_config_dword(dev, base_address_0, 0xfffffffe); + pci_read_config_dword(dev, base_address_0, &orig0); + pci_write_config_dword(dev, base_address_0, 0xffffffff); pci_read_config_dword(dev, base_address_0, &mask); - pci_write_config_dword(dev, base_address_0, orig); if (mask == 0 || mask == 0xffffffff) { @@ -770,21 +770,22 @@ static void pci_setup_device(FAR struct pci_device_s *dev, int max_bar, res = mem; } - orig64 = orig; + orig64 = orig0; maxbase = mask; if (mask & PCI_BASE_ADDRESS_MEM_TYPE_64) { uint32_t masktmp; - pci_read_config_dword(dev, base_address_1, &orig); + pci_read_config_dword(dev, base_address_1, &orig1); pci_write_config_dword(dev, base_address_1, 0xffffffff); pci_read_config_dword(dev, base_address_1, &masktmp); - pci_write_config_dword(dev, base_address_1, orig); + pci_write_config_dword(dev, base_address_1, orig1); mask64 |= (uint64_t)masktmp << 32; - orig64 |= (uint64_t)orig << 32; + orig64 |= (uint64_t)orig1 << 32; maxbase |= (uint64_t)masktmp << 32; } + pci_write_config_dword(dev, base_address_0, orig0); size64 = pci_size(orig64, maxbase, mask64); if (size64 == 0) { @@ -840,12 +841,12 @@ static void pci_setup_device(FAR struct pci_device_s *dev, int max_bar, } } - pci_read_config_dword(dev, rom_addr, &orig); + pci_read_config_dword(dev, rom_addr, &orig0); pci_write_config_dword(dev, rom_addr, ~PCI_ROM_ADDRESS_ENABLE); pci_read_config_dword(dev, rom_addr, &mask); - pci_write_config_dword(dev, rom_addr, orig); - start = PCI_ROM_ADDR(orig); + pci_write_config_dword(dev, rom_addr, orig0); + start = PCI_ROM_ADDR(orig0); size64 = PCI_ROM_SIZE(mask); if (start != 0 && size64 != 0) { diff --git a/drivers/rpmsg/rpmsg.c b/drivers/rpmsg/rpmsg.c index cb6a0960ad12b..311e22211a165 100644 --- a/drivers/rpmsg/rpmsg.c +++ b/drivers/rpmsg/rpmsg.c @@ -32,8 +32,10 @@ #include #include #include +#include #include "rpmsg_ping.h" +#include "rpmsg_router.h" #include "rpmsg_test.h" /**************************************************************************** @@ -220,17 +222,7 @@ int rpmsg_get_signals(FAR struct rpmsg_device *rdev) { FAR struct rpmsg_s *rpmsg = rpmsg_get_by_rdev(rdev); - if (rpmsg == NULL) - { - return -EINVAL; - } - - if (rpmsg->ops->get_signals != NULL) - { - return rpmsg->ops->get_signals(rpmsg); - } - - return 0; + return atomic_read(&rpmsg->signals); } int rpmsg_register_callback(FAR void *priv, @@ -528,6 +520,7 @@ int rpmsg_register(FAR const char *path, FAR struct rpmsg_s *rpmsg, metal_list_init(&rpmsg->bind); nxrmutex_init(&rpmsg->lock); rpmsg->ops = ops; + atomic_store(&rpmsg->signals, RPMSG_SIGNAL_RUNNING); /* Add priv to list */ @@ -592,3 +585,40 @@ void rpmsg_dump_all(void) { rpmsg_ioctl(NULL, RPMSGIOC_DUMP, 0); } + +void rpmsg_modify_signals(FAR struct rpmsg_s *rpmsg, + int setflags, int clrflags) +{ + FAR struct rpmsg_device *rdev = rpmsg->rdev; + FAR struct rpmsg_endpoint *ept; + FAR struct metal_list *node; + bool needlock; + + atomic_fetch_and(&rpmsg->signals, ~clrflags); + atomic_fetch_or(&rpmsg->signals, setflags); + + /* Send signal to Router Hub */ + + needlock = !up_interrupt_context() && !sched_idletask(); + if (needlock) + { + metal_mutex_acquire(&rdev->lock); + } + + metal_list_for_each(&rdev->endpoints, node) + { + ept = metal_container_of(node, struct rpmsg_endpoint, node); + if (!strncmp(ept->name, RPMSG_ROUTER_NAME, + RPMSG_ROUTER_NAME_LEN)) + { + rpmsg_ept_incref(ept); + ept->cb(ept, NULL, 0, RPMSG_ADDR_ANY, NULL); + rpmsg_ept_decref(ept); + } + } + + if (needlock) + { + metal_mutex_release(&rdev->lock); + } +} diff --git a/drivers/rpmsg/rpmsg_port.c b/drivers/rpmsg/rpmsg_port.c index 161398e689c56..391786af1c9c9 100644 --- a/drivers/rpmsg/rpmsg_port.c +++ b/drivers/rpmsg/rpmsg_port.c @@ -51,7 +51,6 @@ static FAR const char * rpmsg_port_get_local_cpuname(FAR struct rpmsg_s *rpmsg); static FAR const char *rpmsg_port_get_cpuname(FAR struct rpmsg_s *rpmsg); static void rpmsg_port_dump(FAR struct rpmsg_s *rpmsg); -static int rpmsg_port_get_signals(FAR struct rpmsg_s *rpmsg); /**************************************************************************** * Private Data @@ -66,7 +65,6 @@ static const struct rpmsg_ops_s g_rpmsg_port_ops = rpmsg_port_dump, rpmsg_port_get_local_cpuname, rpmsg_port_get_cpuname, - rpmsg_port_get_signals, }; /**************************************************************************** @@ -566,17 +564,6 @@ static FAR const char *rpmsg_port_get_cpuname(FAR struct rpmsg_s *rpmsg) return port->cpuname; } -/**************************************************************************** - * Name: rpmsg_port_get_signals - ****************************************************************************/ - -static int rpmsg_port_get_signals(FAR struct rpmsg_s *rpmsg) -{ - FAR struct rpmsg_port_s *port = (FAR struct rpmsg_port_s *)rpmsg; - - return atomic_read(&port->signals); -} - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -769,7 +756,6 @@ int rpmsg_port_register(FAR struct rpmsg_port_s *port, return ret; } - atomic_fetch_or(&port->signals, RPMSG_SIGNAL_RUNNING); rpmsg_register_endpoint(&port->rdev, &port->rdev.ns_ept, "NS", RPMSG_NS_EPT_ADDR, RPMSG_NS_EPT_ADDR, rpmsg_port_ns_callback, NULL, port); diff --git a/drivers/rpmsg/rpmsg_port.h b/drivers/rpmsg/rpmsg_port.h index 220a5eddeaac5..647a7afb21ee2 100644 --- a/drivers/rpmsg/rpmsg_port.h +++ b/drivers/rpmsg/rpmsg_port.h @@ -29,8 +29,6 @@ #include -#include - #include #include #include @@ -131,10 +129,6 @@ struct rpmsg_port_s char cpuname[RPMSG_NAME_SIZE]; - /* Remote cpu status */ - - atomic_t signals; - /* Ops need implemented by drivers under port layer */ const FAR struct rpmsg_port_ops_s *ops; diff --git a/drivers/rpmsg/rpmsg_port_spi.c b/drivers/rpmsg/rpmsg_port_spi.c index 7112f25d69b17..3c6ebf581a0b5 100644 --- a/drivers/rpmsg/rpmsg_port_spi.c +++ b/drivers/rpmsg/rpmsg_port_spi.c @@ -321,11 +321,11 @@ static void rpmsg_port_spi_complete_handler(FAR void *arg) if (rpspi->rxhdr->cmd == RPMSG_PORT_SPI_CMD_SUSPEND) { - atomic_fetch_and(&rpspi->port.signals, ~RPMSG_SIGNAL_RUNNING); + rpmsg_modify_signals(&rpspi->port.rpmsg, 0, RPMSG_SIGNAL_RUNNING); } else if (rpspi->rxhdr->cmd == RPMSG_PORT_SPI_CMD_RESUME) { - atomic_fetch_or(&rpspi->port.signals, RPMSG_SIGNAL_RUNNING); + rpmsg_modify_signals(&rpspi->port.rpmsg, RPMSG_SIGNAL_RUNNING, 0); } else if (rpspi->rxhdr->cmd != RPMSG_PORT_SPI_CMD_AVAIL) { diff --git a/drivers/rpmsg/rpmsg_port_spi_slave.c b/drivers/rpmsg/rpmsg_port_spi_slave.c index 5591962941d63..c5fe29635c981 100644 --- a/drivers/rpmsg/rpmsg_port_spi_slave.c +++ b/drivers/rpmsg/rpmsg_port_spi_slave.c @@ -382,11 +382,11 @@ static void rpmsg_port_spi_slave_notify(FAR struct spi_slave_dev_s *dev, if (rpspi->rxhdr->cmd == RPMSG_PORT_SPI_CMD_SUSPEND) { - atomic_fetch_and(&rpspi->port.signals, ~RPMSG_SIGNAL_RUNNING); + rpmsg_modify_signals(&rpspi->port.rpmsg, 0, RPMSG_SIGNAL_RUNNING); } else if (rpspi->rxhdr->cmd == RPMSG_PORT_SPI_CMD_RESUME) { - atomic_fetch_or(&rpspi->port.signals, RPMSG_SIGNAL_RUNNING); + rpmsg_modify_signals(&rpspi->port.rpmsg, RPMSG_SIGNAL_RUNNING, 0); } else if (rpspi->rxhdr->cmd != RPMSG_PORT_SPI_CMD_AVAIL) { diff --git a/drivers/rpmsg/rpmsg_port_uart.c b/drivers/rpmsg/rpmsg_port_uart.c index 217090692c0ee..fa77627830eac 100644 --- a/drivers/rpmsg/rpmsg_port_uart.c +++ b/drivers/rpmsg/rpmsg_port_uart.c @@ -379,14 +379,16 @@ static int rpmsg_port_uart_rx_thread(int argc, FAR char *argv[]) else if (buf[i] == RPMSG_PORT_UART_SUSPEND) { rpmsgdbg("Received suspend command\n"); - atomic_fetch_and(&rpuart->port.signals, ~RPMSG_SIGNAL_RUNNING); + rpmsg_modify_signals(&rpuart->port.rpmsg, + 0, RPMSG_SIGNAL_RUNNING); nxsem_wait(&rpuart->wake); continue; } else if (buf[i] == RPMSG_PORT_UART_RESUME) { rpmsgdbg("Received resume command\n"); - atomic_fetch_or(&rpuart->port.signals, RPMSG_SIGNAL_RUNNING); + rpmsg_modify_signals(&rpuart->port.rpmsg, + RPMSG_SIGNAL_RUNNING, 0); nxsem_post(&rpuart->wake); continue; } diff --git a/drivers/rpmsg/rpmsg_router.h b/drivers/rpmsg/rpmsg_router.h index 8f7547f9ce5b7..cb799cd253b60 100644 --- a/drivers/rpmsg/rpmsg_router.h +++ b/drivers/rpmsg/rpmsg_router.h @@ -29,8 +29,6 @@ #include -#ifdef CONFIG_RPMSG_ROUTER - /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -43,6 +41,10 @@ #define RPMSG_ROUTER_CREATE 1 #define RPMSG_ROUTER_DESTROY 2 +#define RPMSG_ROUTER_SUSPEND 3 +#define RPMSG_ROUTER_RESUME 4 + +#ifdef CONFIG_RPMSG_ROUTER /**************************************************************************** * Public Types diff --git a/drivers/rpmsg/rpmsg_router_edge.c b/drivers/rpmsg/rpmsg_router_edge.c index 294d008959b76..3bdfbc8c40695 100644 --- a/drivers/rpmsg/rpmsg_router_edge.c +++ b/drivers/rpmsg/rpmsg_router_edge.c @@ -683,15 +683,34 @@ static int rpmsg_router_cb(FAR struct rpmsg_endpoint *ept, if (msg->cmd == RPMSG_ROUTER_DESTROY) { edge = ept->priv; + if (edge == NULL) + { + return -EINVAL; + } + + rpmsg_router_edge_destroy(edge); + ept->priv = NULL; + return 0; + } + else if (msg->cmd == RPMSG_ROUTER_SUSPEND || + msg->cmd == RPMSG_ROUTER_RESUME) + { + edge = ept->priv; + if (edge == NULL) + { + return -EINVAL; + } - if (edge) + if (msg->cmd == RPMSG_ROUTER_SUSPEND) { - rpmsg_router_edge_destroy(edge); - ept->priv = NULL; - return 0; + rpmsg_modify_signals(&edge->rpmsg, 0, RPMSG_SIGNAL_RUNNING); + } + else + { + rpmsg_modify_signals(&edge->rpmsg, RPMSG_SIGNAL_RUNNING, 0); } - return -EINVAL; + return 0; } /* Create the router edge device */ diff --git a/drivers/rpmsg/rpmsg_router_hub.c b/drivers/rpmsg/rpmsg_router_hub.c index 5aad21480c58d..6f872d90abf11 100644 --- a/drivers/rpmsg/rpmsg_router_hub.c +++ b/drivers/rpmsg/rpmsg_router_hub.c @@ -35,6 +35,7 @@ #include #include +#include #include #include "rpmsg_router.h" @@ -59,6 +60,7 @@ struct rpmsg_router_hub_s { struct rpmsg_endpoint ept[2]; + struct work_s work; char cpuname[2][RPMSG_ROUTER_CPUNAME_LEN]; mutex_t lock; }; @@ -359,6 +361,31 @@ static void rpmsg_router_bound(FAR struct rpmsg_endpoint *ept) } } +/**************************************************************************** + * Name: rpmsg_router_notify_edge + ****************************************************************************/ + +static void rpmsg_router_notify_edge(FAR void *arg) +{ + FAR struct rpmsg_endpoint *ept = arg; + FAR struct rpmsg_router_hub_s *hub = ept->priv; + struct rpmsg_router_s msg; + int i; + + msg.cmd = rpmsg_is_running(ept->rdev) ? + RPMSG_ROUTER_RESUME : RPMSG_ROUTER_SUSPEND; + for (i = 0; i < 2; i++) + { + if (strcmp(rpmsg_get_cpuname(ept->rdev), hub->cpuname[i])) + { + rpmsg_send(&hub->ept[i], &msg, sizeof(msg)); + } + } + + rpmsg_ept_decref(&hub->ept[0]); + rpmsg_ept_decref(&hub->ept[1]); +} + /**************************************************************************** * Name: rpmsg_router_cb ****************************************************************************/ @@ -366,6 +393,17 @@ static void rpmsg_router_bound(FAR struct rpmsg_endpoint *ept) static int rpmsg_router_cb(FAR struct rpmsg_endpoint *ept, FAR void *data, size_t len, uint32_t src, FAR void *priv) { + FAR struct rpmsg_router_hub_s *hub = ept->priv; + + /* Send pm signal to the other edge core */ + + if (data == NULL) + { + rpmsg_ept_incref(&hub->ept[0]); + rpmsg_ept_incref(&hub->ept[1]); + work_queue(HPWORK, &hub->work, rpmsg_router_notify_edge, ept, 0); + } + return 0; } diff --git a/drivers/sensors/Kconfig b/drivers/sensors/Kconfig index c75577743b1c2..587c75ee6353c 100644 --- a/drivers/sensors/Kconfig +++ b/drivers/sensors/Kconfig @@ -74,7 +74,6 @@ config SENSORS_WTGAHRS2 config SENSORS_FAKESENSOR bool "Fake Sensor Support" - depends on SENSORS_GNSS default n ---help--- Simulate physical sensor by reading data from csv file. diff --git a/drivers/sensors/fakesensor_uorb.c b/drivers/sensors/fakesensor_uorb.c index 6077cf9e32c80..9f3bcc976deaa 100644 --- a/drivers/sensors/fakesensor_uorb.c +++ b/drivers/sensors/fakesensor_uorb.c @@ -39,10 +39,13 @@ #include #include #include -#include #include #include +#ifdef CONFIG_SENSORS_GNSS +#include +#endif + /**************************************************************************** * Private Types ****************************************************************************/ @@ -52,7 +55,9 @@ struct fakesensor_s union { struct sensor_lowerhalf_s lower; +#ifdef CONFIG_SENSORS_GNSS struct gnss_lowerhalf_s gnss; +#endif }; int type; @@ -77,14 +82,17 @@ static int fakesensor_set_interval(FAR struct sensor_lowerhalf_s *lower, static int fakesensor_batch(FAR struct sensor_lowerhalf_s *lower, FAR struct file *filep, FAR uint32_t *latency_us); +static void fakesensor_push_event(FAR struct fakesensor_s *sensor, + uint64_t event_timestamp); +static int fakesensor_thread(int argc, char** argv); + +#ifdef CONFIG_SENSORS_GNSS static int fakegnss_activate(FAR struct gnss_lowerhalf_s *lower, FAR struct file *filep, bool sw); static int fakegnss_set_interval(FAR struct gnss_lowerhalf_s *lower, FAR struct file *filep, FAR uint32_t *period_us); -static void fakesensor_push_event(FAR struct fakesensor_s *sensor, - uint64_t event_timestamp); -static int fakesensor_thread(int argc, char** argv); +#endif /**************************************************************************** * Private Data @@ -97,11 +105,13 @@ static struct sensor_ops_s g_fakesensor_ops = .batch = fakesensor_batch, }; +#ifdef CONFIG_SENSORS_GNSS static struct gnss_ops_s g_fakegnss_ops = { .activate = fakegnss_activate, .set_interval = fakegnss_set_interval, }; +#endif /**************************************************************************** * Private Functions @@ -211,6 +221,7 @@ static inline void fakesensor_read_baro(FAR struct fakesensor_s *sensor, sizeof(struct sensor_baro)); } +#ifdef CONFIG_SENSORS_GNSS static inline void fakesensor_read_gnss(FAR struct fakesensor_s *sensor) { char raw[150]; @@ -227,6 +238,7 @@ static inline void fakesensor_read_gnss(FAR struct fakesensor_s *sensor) } } } +#endif static int fakesensor_activate(FAR struct sensor_lowerhalf_s *lower, FAR struct file *filep, bool enable) @@ -249,11 +261,13 @@ static int fakesensor_activate(FAR struct sensor_lowerhalf_s *lower, return OK; } +#ifdef CONFIG_SENSORS_GNSS static int fakegnss_activate(FAR struct gnss_lowerhalf_s *lower, FAR struct file *filep, bool enable) { return fakesensor_activate((FAR void *)lower, filep, enable); } +#endif static int fakesensor_set_interval(FAR struct sensor_lowerhalf_s *lower, FAR struct file *filep, @@ -265,12 +279,14 @@ static int fakesensor_set_interval(FAR struct sensor_lowerhalf_s *lower, return OK; } +#ifdef CONFIG_SENSORS_GNSS static int fakegnss_set_interval(FAR struct gnss_lowerhalf_s *lower, FAR struct file *filep, FAR uint32_t *period_us) { return fakesensor_set_interval((FAR void *)lower, filep, period_us); } +#endif static int fakesensor_batch(FAR struct sensor_lowerhalf_s *lower, FAR struct file *filep, @@ -313,10 +329,12 @@ void fakesensor_push_event(FAR struct fakesensor_s *sensor, fakesensor_read_baro(sensor, event_timestamp); break; +#ifdef CONFIG_SENSORS_GNSS case SENSOR_TYPE_GNSS: case SENSOR_TYPE_GNSS_SATELLITE: fakesensor_read_gnss(sensor); break; +#endif default: snerr("fakesensor: unsupported type sensor type\n"); @@ -420,6 +438,7 @@ int fakesensor_init(int type, FAR const char *file_name, FAR struct fakesensor_s *sensor; FAR char *argv[2]; char arg1[32]; +#ifdef CONFIG_SENSORS_GNSS uint32_t nbuffer[] = { [SENSOR_GNSS_IDX_GNSS] = batch_number, [SENSOR_GNSS_IDX_GNSS_SATELLITE] = batch_number, @@ -427,6 +446,7 @@ int fakesensor_init(int type, FAR const char *file_name, [SENSOR_GNSS_IDX_GNSS_CLOCK] = batch_number, [SENSOR_GNSS_IDX_GNSS_GEOFENCE] = batch_number, }; +#endif int ret; @@ -460,12 +480,14 @@ int fakesensor_init(int type, FAR const char *file_name, /* Register sensor */ +#ifdef CONFIG_SENSORS_GNSS if (type == SENSOR_TYPE_GNSS || type == SENSOR_TYPE_GNSS_SATELLITE) { sensor->gnss.ops = &g_fakegnss_ops; gnss_register(&sensor->gnss, devno, nbuffer, nitems(nbuffer)); } else +#endif { sensor->lower.type = type; sensor->lower.ops = &g_fakesensor_ops; diff --git a/drivers/sensors/sensor.c b/drivers/sensors/sensor.c index 1e8aa6e127ec7..5bfdaba006356 100644 --- a/drivers/sensors/sensor.c +++ b/drivers/sensors/sensor.c @@ -218,6 +218,7 @@ static const struct sensor_meta_s g_sensor_meta[] = {sizeof(struct sensor_pm25), "pm25"}, {sizeof(struct sensor_pm10), "pm10"}, {sizeof(struct sensor_uv), "uv"}, + {sizeof(struct sensor_eng), "eng"}, }; static const struct file_operations g_sensor_fops = diff --git a/drivers/timers/arch_alarm.c b/drivers/timers/arch_alarm.c index 4f04e0d44b66b..98a49a8e2d417 100644 --- a/drivers/timers/arch_alarm.c +++ b/drivers/timers/arch_alarm.c @@ -26,6 +26,8 @@ #include +#include + #include #include #include @@ -34,6 +36,10 @@ * Pre-processor Definitions ****************************************************************************/ +#ifndef CONFIG_BOARD_LOOPSPERMSEC +# define CONFIG_BOARD_LOOPSPERMSEC 0 +#endif + #define CONFIG_BOARD_LOOPSPER100USEC ((CONFIG_BOARD_LOOPSPERMSEC+5)/10) #define CONFIG_BOARD_LOOPSPER10USEC ((CONFIG_BOARD_LOOPSPERMSEC+50)/100) #define CONFIG_BOARD_LOOPSPERUSEC ((CONFIG_BOARD_LOOPSPERMSEC+500)/1000) @@ -56,6 +62,8 @@ static void udelay_coarse(useconds_t microseconds) { volatile int i; + DEBUGASSERT(CONFIG_BOARD_LOOPSPERMSEC != 0); + /* We'll do this a little at a time because we expect that the * CONFIG_BOARD_LOOPSPERUSEC is very inaccurate during to truncation in * the divisions of its calculation. We'll use the largest values that @@ -119,7 +127,7 @@ static void oneshot_callback(FAR struct oneshot_lowerhalf_s *lower, FAR void *arg) { #ifdef CONFIG_SCHED_TICKLESS - nxsched_timer_expiration(); + nxsched_process_timer(); #else clock_t now; @@ -301,7 +309,7 @@ int weak_function up_timer_gettime(struct timespec *ts) * Description: * Cancel the alarm and return the time of cancellation of the alarm. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the alarm is + * nxsched_process_timer() will not be called unless the alarm is * restarted with up_alarm_start(). * * If, as a race condition, the alarm has already expired when this @@ -360,14 +368,14 @@ int weak_function up_alarm_tick_cancel(FAR clock_t *ticks) * Name: up_alarm_start * * Description: - * Start the alarm. nxsched_timer_expiration() will be called when the + * Start the alarm. nxsched_process_timer() will be called when the * alarm occurs (unless up_alaram_cancel is called to stop it). * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: * ts - The time in the future at the alarm is expected to occur. When the - * alarm occurs the timer logic will call nxsched_timer_expiration(). + * alarm occurs the timer logic will call nxsched_process_timer(). * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on diff --git a/drivers/timers/arch_timer.c b/drivers/timers/arch_timer.c index a6caacb59b3e4..da4bf6a486dac 100644 --- a/drivers/timers/arch_timer.c +++ b/drivers/timers/arch_timer.c @@ -26,6 +26,8 @@ #include +#include + #include #include #include @@ -34,8 +36,8 @@ * Pre-processor Definitions ****************************************************************************/ -#if defined(CONFIG_SCHED_TICKLESS) && defined(CONFIG_SCHED_TICKLESS_ALARM) -# error CONFIG_SCHED_TICKLESS_ALARM must be unset to use the arch timer +#ifndef CONFIG_BOARD_LOOPSPERMSEC +# define CONFIG_BOARD_LOOPSPERMSEC 0 #endif #define CONFIG_BOARD_LOOPSPER100USEC ((CONFIG_BOARD_LOOPSPERMSEC+5)/10) @@ -122,6 +124,8 @@ static void udelay_coarse(useconds_t microseconds) { volatile int i; + DEBUGASSERT(CONFIG_BOARD_LOOPSPERMSEC != 0); + /* We'll do this a little at a time because we expect that the * CONFIG_BOARD_LOOPSPERUSEC is very inaccurate during to truncation in * the divisions of its calculation. We'll use the largest values that @@ -174,7 +178,7 @@ static bool timer_callback(FAR uint32_t *next_interval, FAR void *arg) g_timer.timebase += *next_interval; temp_interval = g_oneshot_maxticks; g_timer.next_interval = &temp_interval; - nxsched_timer_expiration(); + nxsched_process_timer(); g_timer.next_interval = NULL; TIMER_TICK_GETSTATUS(g_timer.lower, &status); @@ -295,7 +299,7 @@ int weak_function up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -344,14 +348,14 @@ int weak_function up_timer_tick_cancel(FAR clock_t *ticks) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be called at + * Start the interval timer. nxsched_process_timer() will be called at * the completion of the timeout (unless up_timer_cancel is called to stop * the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/drivers/virtio/virtio-net.c b/drivers/virtio/virtio-net.c index 1c3909937b832..b289fc7dc877d 100644 --- a/drivers/virtio/virtio-net.c +++ b/drivers/virtio/virtio-net.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -624,20 +625,8 @@ static void virtio_net_set_macaddr(FAR struct virtio_net_priv_s *priv) * conflicts with something else on the network. */ - srand(time(NULL) + -#ifdef CONFIG_NETDEV_IFINDEX - dev->d_ifindex -#else - (uintptr_t)dev % 256 -#endif - ); - mac[0] = 0x42; - mac[1] = rand() % 256; - mac[2] = rand() % 256; - mac[3] = rand() % 256; - mac[4] = rand() % 256; - mac[5] = rand() % 256; + arc4random_buf(mac + 1, 5); } } diff --git a/fs/driver/fs_blockproxy.c b/fs/driver/fs_blockproxy.c index 5e2858a1155ea..1227e269dc5f1 100644 --- a/fs/driver/fs_blockproxy.c +++ b/fs/driver/fs_blockproxy.c @@ -69,19 +69,17 @@ static mutex_t g_devno_lock = NXMUTEX_INITIALIZER; * attempt to open() the file. * * Input Parameters: - * None + * devbuf - Buffer to store the generated device name + * len - Length of the buffer * * Returned Value: - * The allocated path to the device. This must be released by the caller - * to prevent memory links. NULL will be returned only the case where - * we fail to allocate memory. + * Zero (OK) on success; a negated errno value on failure. * ****************************************************************************/ -static FAR char *unique_chardev(void) +static int unique_chardev(FAR char *devbuf, size_t len) { struct stat statbuf; - char devbuf[16]; uint32_t devno; int ret; @@ -95,7 +93,7 @@ static FAR char *unique_chardev(void) if (ret < 0) { ferr("ERROR: nxmutex_lock failed: %d\n", ret); - return NULL; + return ret; } /* Get the next device number and release the semaphore */ @@ -106,8 +104,7 @@ static FAR char *unique_chardev(void) /* Construct the full device number */ devno &= 0xffffff; - snprintf(devbuf, sizeof(devbuf), "/dev/tmpc%06lx", - (unsigned long)devno); + snprintf(devbuf, len, "/dev/tmpc%06lx", (unsigned long)devno); /* Make sure that file name is not in use */ @@ -115,7 +112,7 @@ static FAR char *unique_chardev(void) if (ret < 0) { DEBUGASSERT(ret == -ENOENT); - return fs_heap_strdup(devbuf); + return OK; } /* It is in use, try again */ @@ -147,19 +144,19 @@ static FAR char *unique_chardev(void) int block_proxy(FAR struct file *filep, FAR const char *blkdev, int oflags) { + char chardev[16]; struct file temp; - FAR char *chardev; int ret; DEBUGASSERT(blkdev); /* Create a unique temporary file name for the character device */ - chardev = unique_chardev(); - if (chardev == NULL) + ret = unique_chardev(chardev, sizeof(chardev)); + if (ret != OK) { ferr("ERROR: Failed to create temporary device name\n"); - return -ENOMEM; + return ret; } /* Wrap the block driver with an instance of the BCH driver */ @@ -169,8 +166,7 @@ int block_proxy(FAR struct file *filep, FAR const char *blkdev, int oflags) { ferr("ERROR: bchdev_register(%s, %s) failed: %d\n", blkdev, chardev, ret); - - goto errout_with_chardev; + return ret; } /* Open the newly created character driver */ @@ -180,7 +176,8 @@ int block_proxy(FAR struct file *filep, FAR const char *blkdev, int oflags) if (ret < 0) { ferr("ERROR: Failed to open %s: %d\n", chardev, ret); - goto errout_with_bchdev; + nx_unlink(chardev); + return ret; } ret = file_dup2(&temp, filep); @@ -188,7 +185,8 @@ int block_proxy(FAR struct file *filep, FAR const char *blkdev, int oflags) if (ret < 0) { ferr("ERROR: Failed to dup2%s: %d\n", chardev, ret); - goto errout_with_bchdev; + nx_unlink(chardev); + return ret; } /* Unlink the character device name. The driver instance will persist, @@ -200,19 +198,8 @@ int block_proxy(FAR struct file *filep, FAR const char *blkdev, int oflags) if (ret < 0) { ferr("ERROR: Failed to unlink %s: %d\n", chardev, ret); - goto errout_with_chardev; } - /* Free the allocated character driver name. */ - - fs_heap_free(chardev); - return OK; - -errout_with_bchdev: - nx_unlink(chardev); - -errout_with_chardev: - fs_heap_free(chardev); return ret; } diff --git a/fs/driver/fs_mtdproxy.c b/fs/driver/fs_mtdproxy.c index 44f9bc84e5137..93865d225b17c 100644 --- a/fs/driver/fs_mtdproxy.c +++ b/fs/driver/fs_mtdproxy.c @@ -40,7 +40,6 @@ #include #include "driver/driver.h" -#include "fs_heap.h" /**************************************************************************** * Private Data @@ -62,19 +61,17 @@ static mutex_t g_devno_lock = NXMUTEX_INITIALIZER; * attempt to open() the file. * * Input Parameters: - * None + * devbuf - Buffer to store the generated device name + * len - Length of the buffer * * Returned Value: - * The allocated path to the device. This must be released by the caller - * to prevent memory links. NULL will be returned only the case where - * we fail to allocate memory. + * Zero (OK) on success; a negated errno value on failure. * ****************************************************************************/ -static FAR char *unique_blkdev(void) +static int unique_blkdev(FAR char *devbuf, size_t len) { struct stat statbuf; - char devbuf[16]; uint32_t devno; int ret; @@ -88,7 +85,7 @@ static FAR char *unique_blkdev(void) if (ret < 0) { ferr("ERROR: nxmutex_lock failed: %d\n", ret); - return NULL; + return ret; } /* Get the next device number and release the semaphore */ @@ -99,8 +96,7 @@ static FAR char *unique_blkdev(void) /* Construct the full device number */ devno &= 0xffffff; - snprintf(devbuf, sizeof(devbuf), "/dev/tmpb%06lx", - (unsigned long)devno); + snprintf(devbuf, len, "/dev/tmpb%06lx", (unsigned long)devno); /* Make sure that file name is not in use */ @@ -108,7 +104,7 @@ static FAR char *unique_blkdev(void) if (ret < 0) { DEBUGASSERT(ret == -ENOENT); - return fs_heap_strdup(devbuf); + return OK; } /* It is in use, try again */ @@ -143,17 +139,17 @@ static FAR char *unique_blkdev(void) int mtd_proxy(FAR const char *mtddev, int mountflags, FAR struct inode **ppinode) { + char blkdev[16]; FAR struct inode *mtd; - FAR char *blkdev; int ret; /* Create a unique temporary file name for the block device */ - blkdev = unique_blkdev(); - if (blkdev == NULL) + ret = unique_blkdev(blkdev, sizeof(blkdev)); + if (ret != OK) { ferr("ERROR: Failed to create temporary device name\n"); - return -ENOMEM; + return ret; } /* Wrap the mtd driver with an instance of the ftl driver */ @@ -162,7 +158,7 @@ int mtd_proxy(FAR const char *mtddev, int mountflags, if (ret < 0) { ferr("ERROR: Failed to find %s mtd driver\n", mtddev); - goto out_with_blkdev; + return ret; } ret = ftl_initialize_by_path(blkdev, mtd->u.i_mtd, mountflags); @@ -171,7 +167,7 @@ int mtd_proxy(FAR const char *mtddev, int mountflags, { ferr("ERROR: ftl_initialize_by_path(%s, %s) failed: %d\n", mtddev, blkdev, ret); - goto out_with_blkdev; + return ret; } /* Open the newly created block driver */ @@ -180,7 +176,8 @@ int mtd_proxy(FAR const char *mtddev, int mountflags, if (ret < 0) { ferr("ERROR: Failed to open %s: %d\n", blkdev, ret); - goto out_with_fltdev; + nx_unlink(blkdev); + return ret; } /* Unlink and free the block device name. The driver instance will @@ -188,9 +185,11 @@ int mtd_proxy(FAR const char *mtddev, int mountflags, * we have a problem here!) */ -out_with_fltdev: - nx_unlink(blkdev); -out_with_blkdev: - fs_heap_free(blkdev); + ret = nx_unlink(blkdev); + if (ret < 0) + { + ferr("ERROR: Failed to unlink %s: %d\n", blkdev, ret); + } + return ret; } diff --git a/include/crypto/cryptodev.h b/include/crypto/cryptodev.h index a9c231dfd4fb7..d180e6a12a427 100644 --- a/include/crypto/cryptodev.h +++ b/include/crypto/cryptodev.h @@ -103,38 +103,40 @@ #define CRYPTO_MD5_HMAC 4 #define CRYPTO_SHA1_HMAC 5 #define CRYPTO_RIPEMD160_HMAC 6 -#define CRYPTO_RIJNDAEL128_CBC 7 /* 128 bit blocksize */ -#define CRYPTO_AES_CBC 7 /* 128 bit blocksize -- the same as above */ -#define CRYPTO_DEFLATE_COMP 8 /* Deflate compression algorithm */ -#define CRYPTO_NULL 9 -#define CRYPTO_SHA2_256_HMAC 11 -#define CRYPTO_SHA2_384_HMAC 12 -#define CRYPTO_SHA2_512_HMAC 13 -#define CRYPTO_AES_CTR 14 -#define CRYPTO_AES_XTS 15 -#define CRYPTO_AES_GCM_16 16 -#define CRYPTO_AES_128_GMAC 17 -#define CRYPTO_AES_192_GMAC 18 -#define CRYPTO_AES_256_GMAC 19 -#define CRYPTO_AES_GMAC 20 -#define CRYPTO_AES_OFB 21 -#define CRYPTO_AES_CFB_8 22 -#define CRYPTO_AES_CFB_128 23 -#define CRYPTO_CHACHA20_POLY1305 24 -#define CRYPTO_CHACHA20_POLY1305_MAC 25 -#define CRYPTO_MD5 26 -#define CRYPTO_POLY1305 27 -#define CRYPTO_RIPEMD160 28 -#define CRYPTO_SHA1 29 -#define CRYPTO_SHA2_224 30 -#define CRYPTO_SHA2_256 31 -#define CRYPTO_SHA2_384 32 -#define CRYPTO_SHA2_512 33 -#define CRYPTO_CRC32 34 -#define CRYPTO_AES_CMAC 35 -#define CRYPTO_AES_128_CMAC 36 -#define CRYPTO_ESN 37 /* Support for Extended Sequence Numbers */ -#define CRYPTO_ALGORITHM_MAX 37 /* Keep updated */ +#define CRYPTO_RIJNDAEL128_CBC 7 /* 128 bit blocksize */ +#define CRYPTO_AES_CBC 7 /* 128 bit blocksize -- the same as above */ +#define CRYPTO_AES_192_CBC 8 /* 192 bit keysize */ +#define CRYPTO_AES_256_CBC 9 /* 256 bit keysize */ +#define CRYPTO_DEFLATE_COMP 10 /* Deflate compression algorithm */ +#define CRYPTO_NULL 11 +#define CRYPTO_SHA2_256_HMAC 12 +#define CRYPTO_SHA2_384_HMAC 13 +#define CRYPTO_SHA2_512_HMAC 14 +#define CRYPTO_AES_CTR 15 +#define CRYPTO_AES_XTS 16 +#define CRYPTO_AES_GCM_16 17 +#define CRYPTO_AES_128_GMAC 18 +#define CRYPTO_AES_192_GMAC 19 +#define CRYPTO_AES_256_GMAC 20 +#define CRYPTO_AES_GMAC 21 +#define CRYPTO_AES_OFB 22 +#define CRYPTO_AES_CFB_8 23 +#define CRYPTO_AES_CFB_128 24 +#define CRYPTO_CHACHA20_POLY1305 25 +#define CRYPTO_CHACHA20_POLY1305_MAC 26 +#define CRYPTO_MD5 27 +#define CRYPTO_POLY1305 28 +#define CRYPTO_RIPEMD160 29 +#define CRYPTO_SHA1 30 +#define CRYPTO_SHA2_224 31 +#define CRYPTO_SHA2_256 32 +#define CRYPTO_SHA2_384 33 +#define CRYPTO_SHA2_512 34 +#define CRYPTO_CRC32 35 +#define CRYPTO_AES_CMAC 36 +#define CRYPTO_AES_128_CMAC 37 +#define CRYPTO_ESN 38 /* Support for Extended Sequence Numbers */ +#define CRYPTO_ALGORITHM_MAX 38 /* Keep updated */ /* Algorithm flags */ diff --git a/include/fcntl.h b/include/fcntl.h index 5be8390ecec86..49fa89a9eb65c 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -67,7 +67,7 @@ /* Unsupported, but required open flags */ -#define O_RSYNC 0 /* Synchronize input on read */ +#define O_RSYNC O_SYNC /* Synchronize input on read */ #define O_ACCMODE O_RDWR /* Mask for access mode */ #define O_NOCTTY 0 /* Required by POSIX */ #define O_BINARY 0 /* Open the file in binary (untranslated) mode. */ @@ -160,13 +160,6 @@ #define F_SEAL_WRITE 0x0008 /* Prevent writes */ #define F_SEAL_FUTURE_WRITE 0x0010 /* Prevent future writes while mapped */ -/* int creat(const char *path, mode_t mode); - * - * is equivalent to open with O_WRONLY|O_CREAT|O_TRUNC. - */ - -#define creat(path, mode) open(path, O_WRONLY|O_CREAT|O_TRUNC, mode) - #if defined(CONFIG_FS_LARGEFILE) # define F_GETLK64 F_GETLK # define F_SETLK64 F_SETLK @@ -215,6 +208,7 @@ extern "C" /* POSIX-like File System Interfaces */ +int creat(FAR const char *pathname, mode_t mode); int open(FAR const char *path, int oflag, ...); int openat(int dirfd, FAR const char *path, int oflag, ...); int fcntl(int fd, int cmd, ...); diff --git a/include/limits.h b/include/limits.h index 4d9a65d07c8e4..4cf2644161443 100644 --- a/include/limits.h +++ b/include/limits.h @@ -314,6 +314,12 @@ #define SEM_NSEMS_MAX _POSIX_SEM_NSEMS_MAX #define SEM_VALUE_MAX _POSIX_SEM_VALUE_MAX +/* Required for POSIX pthread management */ + +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 +#define _POSIX_THREAD_KEYS_MAX CONFIG_TLS_NELEM +#define _POSIX_THREAD_THREADS_MAX 64 + /* Required for readv() and writev() */ /* There really is no upper limit on the number of vectors */ diff --git a/include/netinet/if_ether.h b/include/netinet/if_ether.h index 01da882ab35c6..db35a1c43a9e4 100644 --- a/include/netinet/if_ether.h +++ b/include/netinet/if_ether.h @@ -50,6 +50,7 @@ #define ETH_P_IP ETHERTYPE_IP #define ETH_P_IPV6 ETHERTYPE_IPV6 #define ETH_P_ARP ETHERTYPE_ARP +#define ETH_P_TSN 0x22F0 /* TSN (IEEE 1722) packet */ /**************************************************************************** * Public Type Definitions diff --git a/include/netinet/in.h b/include/netinet/in.h index 33d35a7a1d8ce..9647922d66277 100644 --- a/include/netinet/in.h +++ b/include/netinet/in.h @@ -287,7 +287,7 @@ struct ip_mreq struct ip_mreqn { struct in_addr imr_multiaddr; /* IPv4 multicast address of group */ - struct in_addr imr_interface; /* Local IPv4 address of interface */ + struct in_addr imr_address; /* Local IPv4 address of interface */ unsigned int imr_ifindex; /* Local interface index */ }; diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 788b4219909fb..132c7e5f43df0 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -92,6 +92,12 @@ * Pre-processor definitions ****************************************************************************/ +#define IRQ_RISING_EDGE 0x00 +#define IRQ_FALLING_EDGE 0x01 +#define IRQ_BOTH_EDGE 0x02 +#define IRQ_HIGH_LEVEL 0x03 +#define IRQ_LOW_LEVEL 0x04 + #define DEBUGPOINT_NONE 0x00 #define DEBUGPOINT_WATCHPOINT_RO 0x01 #define DEBUGPOINT_WATCHPOINT_WO 0x02 @@ -1821,6 +1827,18 @@ void up_affinity_irq(int irq, cpu_set_t cpuset); void up_trigger_irq(int irq, cpu_set_t cpuset); #endif +/**************************************************************************** + * Name: up_set_irq_type + * + * Description: + * Config an IRQ trigger type. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_NOINTC +int up_set_irq_type(int irq, int mode); +#endif + /**************************************************************************** * Name: up_prioritize_irq * @@ -1925,7 +1943,7 @@ void up_timer_initialize(void); * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -1973,7 +1991,7 @@ void up_timer_getmask(FAR clock_t *mask); * Description: * Cancel the alarm and return the time of cancellation of the alarm. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the alarm is + * nxsched_process_timer() will not be called unless the alarm is * restarted with up_alarm_start(). * * If, as a race condition, the alarm has already expired when this @@ -2010,7 +2028,7 @@ int up_alarm_tick_cancel(FAR clock_t *ticks); * Name: up_alarm_start * * Description: - * Start the alarm. nxsched_timer_expiration() will be called when the + * Start the alarm. nxsched_process_timer() will be called when the * alarm occurs (unless up_alaram_cancel is called to stop it). * * Provided by platform-specific code and called from the RTOS base code. @@ -2018,7 +2036,7 @@ int up_alarm_tick_cancel(FAR clock_t *ticks); * Input Parameters: * ts - The time in the future at the alarm is expected to occur. When * the alarm occurs the timer logic will call - * nxsched_timer_expiration(). + * nxsched_process_timer(). * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -2042,7 +2060,7 @@ int up_alarm_tick_start(clock_t ticks); * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -2081,14 +2099,14 @@ int up_timer_tick_cancel(FAR clock_t *ticks); * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be called at + * Start the interval timer. nxsched_process_timer() will be called at * the completion of the timeout (unless up_timer_cancel is called to stop * the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: @@ -2461,33 +2479,7 @@ void up_ndelay(unsigned long nanoseconds); * ****************************************************************************/ -#ifndef CONFIG_SCHED_TICKLESS void nxsched_process_timer(void); -#endif - -/**************************************************************************** - * Name: nxsched_timer_expiration - * - * Description: - * If CONFIG_SCHED_TICKLESS is defined, then this function is provided by - * the RTOS base code and called from platform-specific code when the - * interval timer used to implement the tick-less OS expires. - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * Base code implementation assumes that this function is called from - * interrupt handling logic with interrupts disabled. - * - ****************************************************************************/ - -#if defined(CONFIG_SCHED_TICKLESS) -void nxsched_timer_expiration(void); -#endif /**************************************************************************** * Name: nxsched_get_next_expired @@ -2939,6 +2931,16 @@ bool up_fpucmp(FAR const void *saveregs1, FAR const void *saveregs2); #define up_fpucmp(r1, r2) (true) #endif +/**************************************************************************** + * Name: up_regs_memcpy + ****************************************************************************/ + +#ifdef CONFIG_ARCH_HAVE_REGCPY +void up_regs_memcpy(FAR void *dest, FAR void *src, size_t count); +#else +#define up_regs_memcpy(dest, src, count) memcpy(dest, src, count) +#endif + #ifdef CONFIG_ARCH_HAVE_DEBUG /**************************************************************************** diff --git a/include/nuttx/hrtimer.h b/include/nuttx/hrtimer.h index e6c617b6b2937..350776889d88e 100644 --- a/include/nuttx/hrtimer.h +++ b/include/nuttx/hrtimer.h @@ -54,10 +54,6 @@ enum hrtimer_mode_e /* Forward declarations */ struct hrtimer_s; -struct hrtimer_node_s; - -typedef struct hrtimer_s hrtimer_t; -typedef struct hrtimer_node_s hrtimer_node_t; /* Callback type for high-resolution timer expiration * @@ -65,15 +61,15 @@ typedef struct hrtimer_node_s hrtimer_node_t; * timer context and must not block. */ -typedef CODE uint64_t (*hrtimer_entry_t)(FAR const hrtimer_t *hrtimer, +typedef CODE uint64_t (*hrtimer_entry_t)(FAR const struct hrtimer_s *hrtimer, uint64_t expired); /* Red-black tree node used to order hrtimers by expiration time */ -struct hrtimer_node_s +typedef struct hrtimer_node_s { RB_ENTRY(hrtimer_node_s) entry; /* RB-tree linkage */ -}; +} hrtimer_node_t; /* High-resolution timer object * @@ -82,12 +78,12 @@ struct hrtimer_node_s * directly by users except through the provided APIs. */ -struct hrtimer_s +typedef struct hrtimer_s { hrtimer_node_t node; /* RB-tree node for sorted insertion */ hrtimer_entry_t func; /* Expiration callback function */ uint64_t expired; /* Absolute expiration time (ns) */ -}; +} hrtimer_t; /**************************************************************************** * Public Function Prototypes @@ -118,12 +114,7 @@ extern "C" * None ****************************************************************************/ -static inline_function -void hrtimer_init(FAR hrtimer_t *hrtimer, hrtimer_cb func) -{ - memset(hrtimer, 0, sizeof(hrtimer_t)); - hrtimer->func = func; -} +#define hrtimer_init(hrtimer) memset(hrtimer, 0, sizeof(hrtimer_t)) /**************************************************************************** * Name: hrtimer_cancel @@ -184,6 +175,7 @@ int hrtimer_cancel_sync(FAR hrtimer_t *hrtimer); * * Input Parameters: * hrtimer - Timer instance to start + * func - Expiration callback function * expired - Expiration time in nanoseconds * mode - HRTIMER_MODE_ABS or HRTIMER_MODE_REL * @@ -191,7 +183,7 @@ int hrtimer_cancel_sync(FAR hrtimer_t *hrtimer); * OK on success; a negated errno value on failure. ****************************************************************************/ -int hrtimer_start(FAR hrtimer_t *hrtimer, +int hrtimer_start(FAR hrtimer_t *hrtimer, hrtimer_entry_t func, uint64_t expired, enum hrtimer_mode_e mode); diff --git a/include/nuttx/ioexpander/ioexpander.h b/include/nuttx/ioexpander/ioexpander.h index b2df1e4b31f46..218bd3c34a678 100644 --- a/include/nuttx/ioexpander/ioexpander.h +++ b/include/nuttx/ioexpander/ioexpander.h @@ -83,7 +83,11 @@ #define IOEXPANDER_WAKEUP_DISABLE 0 /* Do not cfg the pin as wake up source */ #define IOEXPANDER_WAKEUP_ENABLE 1 /* Cfg the pin as wake up source */ #define IOEXPANDER_OPTION_SETDEBOUNCE 6 /* Configure debounce duration */ +# define IOEXPANDER_DEBOUNCE_DISABLE 0 /* Disable debounce */ +# define IOEXPANDER_DEBOUNCE_ENABLE 1 /* Enable debounce */ #define IOEXPANDER_OPTION_SETMASK 7 /* Mask the interrupter */ +# define IOEXPANDER_MASK_DISABLE 0 /* Unmask the interrupter */ +# define IOEXPANDER_MASK_ENABLE 1 /* Mask the interrupter */ /* Access macros ************************************************************/ diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index a77546dc2d706..2fcdf612aeb7d 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -1504,6 +1504,41 @@ void netdev_lock(FAR struct net_driver_s *dev); void netdev_unlock(FAR struct net_driver_s *dev); +/**************************************************************************** + * Name: netdev_findbyname + * + * Description: + * Find a previously registered network device using its assigned + * network interface name + * + * Input Parameters: + * ifname The interface name of the device of interest + * + * Returned Value: + * Pointer to driver on success; null on failure + * + ****************************************************************************/ + +FAR struct net_driver_s *netdev_findbyname(FAR const char *ifname); + +/**************************************************************************** + * Name: netdev_findbyindex + * + * Description: + * Find a previously registered network device by assigned interface index. + * + * Input Parameters: + * ifindex - The interface index. This is a one-based index and must be + * greater than zero. + * + * Returned Value: + * Pointer to driver on success; NULL on failure. This function will return + * NULL only if there is no device corresponding to the provided index. + * + ****************************************************************************/ + +FAR struct net_driver_s *netdev_findbyindex(int ifindex); + #undef EXTERN #ifdef __cplusplus } diff --git a/include/nuttx/net/rpmsg.h b/include/nuttx/net/rpmsg.h index ff9137bb403eb..8f18b9ffe153d 100644 --- a/include/nuttx/net/rpmsg.h +++ b/include/nuttx/net/rpmsg.h @@ -33,7 +33,7 @@ * Pre-processor Definitions ****************************************************************************/ -#define NET_RPMSG_EPT_NAME "rpmsg-%s" +#define NET_RPMSG_EPT_PREFIX "rpmsg-net-" #define NET_RPMSG_IFUP 0 /* IP-->LINK */ #define NET_RPMSG_IFDOWN 1 /* IP-->LINK */ @@ -43,6 +43,10 @@ #define NET_RPMSG_SOCKIOCTL 5 /* IP<--LINK */ #define NET_RPMSG_TRANSFER 6 /* IP<->LINK */ +#define NET_RPMSG_RESPONSE (1 << 31) +#define NET_RPMSG_IS_RESPONSE(cmd) (!!((cmd) & NET_RPMSG_RESPONSE)) +#define NET_RPMSG_GET_COMMAND(cmd) ((cmd) & ~NET_RPMSG_RESPONSE) + /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/include/nuttx/net/rpmsgdrv.h b/include/nuttx/net/rpmsgdrv.h index 061c0191b2526..ff36c04e21fbc 100644 --- a/include/nuttx/net/rpmsgdrv.h +++ b/include/nuttx/net/rpmsgdrv.h @@ -28,18 +28,106 @@ ****************************************************************************/ #include -#include +#include /**************************************************************************** - * Public Function Prototypes + * Pre-processor Definitions ****************************************************************************/ #ifdef CONFIG_NET_RPMSG_DRV -int net_rpmsg_drv_init(FAR const char *cpuname, - FAR const char *devname, - enum net_lltype_e lltype); + +#define NET_RPMSG_EVENT_IF_UP 1 +#define NET_RPMSG_EVENT_IF_DOWN 2 +#define NET_RPMSG_EVENT_CARRIER_ON 3 +#define NET_RPMSG_EVENT_CARRIER_OFF 4 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef CODE void (*net_rpmsg_drv_cb_t)(FAR struct netdev_lowerhalf_s *dev, + int event); + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ #else -#define net_rpmsg_drv_init(cpuname, devname, lltye) +#define EXTERN extern #endif +/**************************************************************************** + * Name: net_rpmsg_drv_init + * + * Description: + * Allocate a new network device instance for the RPMSG network and + * register it with the network device manager. This is the client side of + * the RPMSG driver. The RPMSG driver is the server side of the driver. + * + * Input Parameters: + * cpuname - Remote CPU name + * devname - Local and remote network device name + * lltype - Link layer type + * priv - Reference to the caller's private data + * + * Returned Value: + * A pointer to the allocated network device instance. NULL is returned on + * failure. + * + ****************************************************************************/ + +FAR struct netdev_lowerhalf_s * +net_rpmsg_drv_init(FAR const char *cpuname, FAR const char *devname, + enum net_lltype_e lltype); + +/**************************************************************************** + * Name: net_rpmsg_drv_priv + * + * Description: + * Get the private data associated with the network device instance. + * + * Input Parameters: + * dev - Reference to the network device instance. + * + ****************************************************************************/ + +FAR void *net_rpmsg_drv_priv(FAR struct netdev_lowerhalf_s *dev); + +/**************************************************************************** + * Name: net_rpmsg_drv_set_callback + * + * Description: + * Set the callback function for the network device instance. + * + * Input Parameters: + * dev - Reference to the network device instance. + * cb - Callback function to be set. + * + ****************************************************************************/ + +void net_rpmsg_drv_set_callback(FAR struct netdev_lowerhalf_s *dev, + net_rpmsg_drv_cb_t cb, FAR void *priv); + +/**************************************************************************** + * Name: net_rpmsg_drv_server_init + * + * Description: + * Initialize the RPMSG network (for server side). + * + ****************************************************************************/ + +#ifdef CONFIG_NET_RPMSG_DRV_SERVER +int net_rpmsg_drv_server_init(void); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif #endif /* __INCLUDE_NUTTX_NET_RPMSGDRV_H */ diff --git a/include/nuttx/net/wifi_sim.h b/include/nuttx/net/wifi_sim.h index 1b3d473a6e6fe..8fb707bbe2838 100644 --- a/include/nuttx/net/wifi_sim.h +++ b/include/nuttx/net/wifi_sim.h @@ -64,6 +64,7 @@ struct wifi_sim_lowerhalf_s int wifi_sim_init(FAR struct wifi_sim_lowerhalf_s *netdev); void wifi_sim_remove(FAR struct wifi_sim_lowerhalf_s *netdev); +bool wifi_sim_connected(FAR struct wifi_sim_lowerhalf_s *dev); #undef EXTERN #ifdef __cplusplus diff --git a/include/nuttx/notifier.h b/include/nuttx/notifier.h index 7fdbdbdb79fad..9afe8457f39c2 100644 --- a/include/nuttx/notifier.h +++ b/include/nuttx/notifier.h @@ -41,7 +41,7 @@ * Pre-processor Definitions ****************************************************************************/ -#define ATOMIC_NOTIFIER_INIT(name) {NULL} +#define ATOMIC_NOTIFIER_INIT(name) {NULL, RSPINLOCK_INITIALIZER} #define ATOMIC_NOTIFIER_HEAD(name) \ struct atomic_notifier_head name = ATOMIC_NOTIFIER_INIT(name) @@ -81,6 +81,7 @@ struct notifier_block struct atomic_notifier_head { FAR struct notifier_block *head; + rspinlock_t lock; }; struct blocking_notifier_head @@ -179,9 +180,9 @@ extern "C" { \ FAR struct atomic_notifier_head *nh = (nhead); \ irqstate_t flags; \ - flags = enter_critical_section(); \ + flags = rspin_lock_irqsave_nopreempt(&nh->lock); \ notifier_chain_register(nh->head, (nb), false); \ - leave_critical_section(flags); \ + rspin_unlock_irqrestore_nopreempt(&nh->lock, flags); \ } \ while(0) @@ -190,9 +191,9 @@ extern "C" { \ FAR struct atomic_notifier_head *nh = (nhead); \ irqstate_t flags; \ - flags = enter_critical_section(); \ + flags = rspin_lock_irqsave_nopreempt(&nh->lock); \ notifier_chain_register(nh->head, (nb), true); \ - leave_critical_section(flags); \ + rspin_unlock_irqrestore_nopreempt(&nh->lock, flags); \ } \ while(0) @@ -201,9 +202,9 @@ extern "C" { \ FAR struct atomic_notifier_head *nh = (nhead); \ irqstate_t flags; \ - flags = enter_critical_section(); \ + flags = rspin_lock_irqsave_nopreempt(&nh->lock); \ notifier_chain_unregister(nh->head, (nb)); \ - leave_critical_section(flags); \ + rspin_unlock_irqrestore_nopreempt(&nh->lock, flags); \ } \ while(0) @@ -212,9 +213,9 @@ extern "C" { \ FAR struct atomic_notifier_head *nh = (nhead); \ irqstate_t flags; \ - flags = enter_critical_section(); \ + flags = rspin_lock_irqsave_nopreempt(&nh->lock); \ notifier_call_chain(nh->head, (val), (v), -1, NULL); \ - leave_critical_section(flags); \ + rspin_unlock_irqrestore_nopreempt(&nh->lock, flags); \ } \ while(0) diff --git a/include/nuttx/rpmsg/rpmsg.h b/include/nuttx/rpmsg/rpmsg.h index b31b56e299879..06f0be0193a9c 100644 --- a/include/nuttx/rpmsg/rpmsg.h +++ b/include/nuttx/rpmsg/rpmsg.h @@ -31,6 +31,7 @@ #ifdef CONFIG_RPMSG +#include #include #include #include @@ -63,6 +64,7 @@ struct rpmsg_s #ifdef CONFIG_RPMSG_TEST struct rpmsg_endpoint test; #endif + atomic_int signals; struct rpmsg_device rdev[0]; }; @@ -82,7 +84,6 @@ struct rpmsg_ops_s CODE void (*dump)(FAR struct rpmsg_s *rpmsg); CODE FAR const char *(*get_local_cpuname)(FAR struct rpmsg_s *rpmsg); CODE FAR const char *(*get_cpuname)(FAR struct rpmsg_s *rpmsg); - CODE int (*get_signals)(FAR struct rpmsg_s *rpmsg); }; CODE typedef void (*rpmsg_dev_cb_t)(FAR struct rpmsg_device *rdev, @@ -112,6 +113,8 @@ int rpmsg_post(FAR struct rpmsg_endpoint *ept, FAR sem_t *sem); FAR const char *rpmsg_get_local_cpuname(FAR struct rpmsg_device *rdev); FAR const char *rpmsg_get_cpuname(FAR struct rpmsg_device *rdev); int rpmsg_get_signals(FAR struct rpmsg_device *rdev); +void rpmsg_modify_signals(FAR struct rpmsg_s *rpmsg, + int setflags, int clrflags); static inline_function bool rpmsg_is_running(FAR struct rpmsg_device *rdev) { diff --git a/include/nuttx/tls.h b/include/nuttx/tls.h index 4646ba5cef18f..4159035d00006 100644 --- a/include/nuttx/tls.h +++ b/include/nuttx/tls.h @@ -199,7 +199,7 @@ struct tls_cleanup_s struct tls_info_s { - FAR struct task_info_s * tl_task; + FAR struct task_info_s *tl_task; #if defined(CONFIG_TLS_NELEM) && CONFIG_TLS_NELEM > 0 uintptr_t tl_elem[CONFIG_TLS_NELEM]; /* TLS elements */ @@ -224,6 +224,7 @@ struct tls_info_s uint16_t tl_size; /* Actual size with alignments */ int tl_errno; /* Per-thread error number */ pid_t tl_tid; /* Thread ID */ + FAR char **tl_argv; /* Arguments first string */ }; /**************************************************************************** diff --git a/include/nuttx/uorb.h b/include/nuttx/uorb.h index 4b74ddfbedb68..067e997d5dba5 100644 --- a/include/nuttx/uorb.h +++ b/include/nuttx/uorb.h @@ -475,7 +475,6 @@ /* GNSS Geofence */ #define SENSOR_TYPE_GNSS_GEOFENCE 52 - /* Velocity Sensor * A sensor of this type measures the velocity as it is moving. * The default unit velocity is meter by seconds m/s (SI). @@ -511,11 +510,20 @@ #define SENSOR_TYPE_ULTRAVIOLET 57 +/* ENG (Electroneurography) + * A sensor of this type measures the electrical activity of peripheral + * nerves. This neural electrical signal, generated by nerve impulses + * traveling through axons and captured by electrodes, provides valuable + * information about nervous system and muscle-nerve communication. + */ + +#define SENSOR_TYPE_ENG 58 + /* The total number of sensor * please increase it if you added a new sensor type! */ -#define SENSOR_TYPE_COUNT 58 +#define SENSOR_TYPE_COUNT 59 /* The additional sensor open flags */ @@ -902,6 +910,13 @@ struct sensor_cap /* Type: Capacitance */ int32_t rawdata[4]; /* in SI units pF */ }; +struct sensor_eng /* Type: ENG */ +{ + uint64_t timestamp; /* Unit is microseconds */ + float voltage[4]; /* Voltage unit in mV */ + uint32_t stat; /* Status. bit3:0 - value 3:0 is valid or not */ +}; + struct sensor_gnss /* Type: GNSS */ { uint64_t timestamp; /* Time since system start, Units is microseconds */ diff --git a/include/pthread.h b/include/pthread.h index 4d3d90dc698e8..50ea4fbb80a00 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -604,7 +604,7 @@ pid_t pthread_gettid_np(pthread_t thread); /* Compare two thread IDs. */ -#define pthread_equal(t1,t2) ((t1) == (t2)) +int pthread_equal(pthread_t t1, pthread_t t2); /* Thread scheduling parameters */ @@ -774,11 +774,6 @@ int pthread_rwlock_clockwrlock(FAR pthread_rwlock_t *lock, int pthread_rwlock_trywrlock(FAR pthread_rwlock_t *lock); int pthread_rwlock_unlock(FAR pthread_rwlock_t *lock); -/* Pthread signal management APIs */ - -int pthread_kill(pthread_t thread, int sig); -int pthread_sigmask(int how, FAR const sigset_t *set, FAR sigset_t *oset); - #ifdef CONFIG_PTHREAD_SPINLOCKS /* Pthread spinlocks */ @@ -820,50 +815,11 @@ int pthread_atfork(CODE void (*prepare)(void), * available in any inclusion ordering. */ -#ifndef __PTHREAD_KEY_T_DEFINED -typedef int pthread_key_t; -# define __PTHREAD_KEY_T_DEFINED 1 -#endif - #ifndef __PTHREAD_ADDR_T_DEFINED typedef FAR void *pthread_addr_t; # define __PTHREAD_ADDR_T_DEFINED 1 #endif -#ifndef __PTHREAD_ATTR_T_DEFINED -struct pthread_attr_s; -typedef struct pthread_attr_s pthread_attr_t; -# define __PTHREAD_ATTR_T_DEFINED 1 -#endif - -#ifndef __PTHREAD_T_DEFINED -typedef pid_t pthread_t; -# define __PTHREAD_T_DEFINED 1 -#endif - -#ifndef __PTHREAD_CONDATTR_T_DEFINED -typedef struct pthread_condattr_s pthread_condattr_t; -# define __PTHREAD_CONDATTR_T_DEFINED 1 -#endif - -#ifndef __PTHREAD_COND_T_DEFINED -struct pthread_cond_s; -typedef struct pthread_cond_s pthread_cond_t; -# define __PTHREAD_COND_T_DEFINED 1 -#endif - -#ifndef __PTHREAD_MUTEXATTR_T_DEFINED -struct pthread_mutexattr_s; -typedef struct pthread_mutexattr_s pthread_mutexattr_t; -# define __PTHREAD_MUTEXATTR_T_DEFINED 1 -#endif - -#ifndef __PTHREAD_MUTEX_T_DEFINED -struct pthread_mutex_s; -typedef struct pthread_mutex_s pthread_mutex_t; -# define __PTHREAD_MUTEX_T_DEFINED 1 -#endif - #ifndef __PTHREAD_BARRIERATTR_T_DEFINED struct pthread_barrierattr_s; typedef struct pthread_barrierattr_s pthread_barrierattr_t; @@ -896,10 +852,4 @@ typedef struct pthread_spinlock_s pthread_spinlock_t; # endif #endif /* CONFIG_PTHREAD_SPINLOCKS */ -#ifndef __PTHREAD_ONCE_T_DEFINED -struct pthread_once_s; -typedef struct pthread_once_s pthread_once_t; -# define __PTHREAD_ONCE_T_DEFINED 1 -#endif - #endif /* __INCLUDE_PTHREAD_H */ diff --git a/include/signal.h b/include/signal.h index b63d77aa99946..f3d9ccd165eff 100644 --- a/include/signal.h +++ b/include/signal.h @@ -486,6 +486,11 @@ int sigwaitinfo(FAR const sigset_t *set, FAR struct siginfo *value); int sigaltstack(FAR const stack_t *ss, FAR stack_t *oss); int siginterrupt(int signo, int flag); +/* Pthread signal management APIs */ + +int pthread_kill(pthread_t thread, int sig); +int pthread_sigmask(int how, FAR const sigset_t *set, FAR sigset_t *oset); + #undef EXTERN #ifdef __cplusplus } diff --git a/include/stddef.h b/include/stddef.h index 85d5da51bd42c..afe88c6d7f1e2 100644 --- a/include/stddef.h +++ b/include/stddef.h @@ -37,6 +37,8 @@ * Type Definitions ****************************************************************************/ +#ifndef __ASSEMBLY__ + /* The header shall define the following types: * * ptrdiff_t @@ -84,4 +86,6 @@ typedef struct #endif } max_align_t; +#endif /* __ASSEMBLY__ */ + #endif /* __INCLUDE_STDDEF_H */ diff --git a/include/stdint.h b/include/stdint.h index e14610ea146c2..0feaf403da69f 100644 --- a/include/stdint.h +++ b/include/stdint.h @@ -156,6 +156,8 @@ * Public Types ****************************************************************************/ +#ifndef __ASSEMBLY__ + /* Exact-width integer types. NOTE that these types are defined in * architecture-specific logic with leading underscore character. This file * typedef's these to the final name without the underscore character. This @@ -254,5 +256,7 @@ typedef _uint_farptr_t uint_farptr_t; typedef _intmax_t intmax_t; typedef _uintmax_t uintmax_t; +#endif /* __ASSEMBLY__ */ + #endif /* CONFIG_ARCH_STDINT_H */ #endif /* __INCLUDE_STDINT_H */ diff --git a/include/stdio.h b/include/stdio.h index 65b11586964c1..1aa4e6691b5c8 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -87,7 +87,7 @@ /* The maximum number of unique temporary file names that can be generated */ -#define TMP_MAX 56800235584ull +#define TMP_MAX 308915776 #if defined(CONFIG_FS_LARGEFILE) # define tmpfile64 tmpfile @@ -163,7 +163,7 @@ int fscanf(FAR FILE *stream, FAR const IPTR char *fmt, ...) scanf_like(2, 3); int fseek(FAR FILE *stream, long int offset, int whence); int fseeko(FAR FILE *stream, off_t offset, int whence); -int fsetpos(FAR FILE *stream, FAR fpos_t *pos); +int fsetpos(FAR FILE *stream, FAR const fpos_t *pos); long ftell(FAR FILE *stream); off_t ftello(FAR FILE *stream); size_t fwrite(FAR const void *ptr, size_t size, size_t n_items, diff --git a/include/sys/ioctl.h b/include/sys/ioctl.h index 61eaf31f2d1d1..6483935ac451c 100644 --- a/include/sys/ioctl.h +++ b/include/sys/ioctl.h @@ -68,6 +68,13 @@ * Pre-processor Definitions ****************************************************************************/ +/* The compatibility IOCTL definitions */ + +#define _IO(type,nr) _IOC((type),(nr)) + +#define FS_IOC_GETFLAGS FIOC_GETFLAGS +#define FS_IOC_SETFLAGS FIOC_SETFLAGS + #undef EXTERN #if defined(__cplusplus) #define EXTERN extern "C" diff --git a/include/sys/resource.h b/include/sys/resource.h index 6bb4cf00f78b7..55b8164efebdf 100644 --- a/include/sys/resource.h +++ b/include/sys/resource.h @@ -67,6 +67,8 @@ #define RLIMIT_RTPRIO 14 /* Limit on RT tasks priority */ #define RLIMIT_RTTIME 15 /* Limit on timeout for RT tasks (us) */ +#define RLIM_NLIMITS 16 /* Limits of all supported kinds */ + #if defined(CONFIG_FS_LARGEFILE) # define RLIM_INFINITY UINT64_MAX /* No limit */ # define RLIM_SAVED_MAX UINT64_MAX /* Unrepresentable saved hard limit */ diff --git a/include/sys/types.h b/include/sys/types.h index e059ef20ab6af..51b190ae322dd 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -317,12 +317,61 @@ typedef CODE int (*main_t)(int argc, FAR char *argv[]); /* POSIX-like OS return values: */ +#ifdef OK +# undef OK +#endif + enum { ERROR = -1, OK = 0 }; +#ifndef __PTHREAD_ATTR_T_DEFINED +struct pthread_attr_s; +typedef struct pthread_attr_s pthread_attr_t; +# define __PTHREAD_ATTR_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_COND_T_DEFINED +struct pthread_cond_s; +typedef struct pthread_cond_s pthread_cond_t; +# define __PTHREAD_COND_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_CONDATTR_T_DEFINED +typedef struct pthread_condattr_s pthread_condattr_t; +# define __PTHREAD_CONDATTR_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_KEY_T_DEFINED +typedef int pthread_key_t; +# define __PTHREAD_KEY_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_MUTEX_T_DEFINED +struct pthread_mutex_s; +typedef struct pthread_mutex_s pthread_mutex_t; +# define __PTHREAD_MUTEX_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_MUTEXATTR_T_DEFINED +struct pthread_mutexattr_s; +typedef struct pthread_mutexattr_s pthread_mutexattr_t; +# define __PTHREAD_MUTEXATTR_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_T_DEFINED +typedef pid_t pthread_t; +# define __PTHREAD_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_ONCE_T_DEFINED +struct pthread_once_s; +typedef struct pthread_once_s pthread_once_t; +# define __PTHREAD_ONCE_T_DEFINED 1 +#endif + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/include/sys/wait.h b/include/sys/wait.h index 658a236d553b6..4f653a8fbe426 100644 --- a/include/sys/wait.h +++ b/include/sys/wait.h @@ -46,11 +46,12 @@ #define WEXITSTATUS(s) (((s) >> 8) & 0xff) /* Return exit status */ #define WIFEXITED(s) (((s) & 0xff) == 0) /* True: Child exited normally */ -#define WIFCONTINUED(s) (false) /* True: Child has been continued */ -#define WIFSIGNALED(s) (false) /* True: Child exited due to uncaught signal */ -#define WIFSTOPPED(s) (false) /* True: Child is currently stopped */ -#define WSTOPSIG(s) (false) /* Return signal number that caused process to stop */ -#define WTERMSIG(s) (false) /* Return signal number that caused process to terminate */ +#define WIFCONTINUED(s) (false) /* True: Child has been continued */ +#define WIFSIGNALED(s) (false) /* True: Child exited due to uncaught signal */ +#define WIFSTOPPED(s) (false) /* True: Child is currently stopped */ +#define WSTOPSIG(s) (false) /* Return signal number that caused process to stop */ +#define WTERMSIG(s) (((s) >> 8) & 0x7f) /* Return signal number that caused process to terminate */ +#define WCOREDUMP(s) (((s) >> 8) & 0x80) /* True: Child has produced a core dump */ /* The following symbolic constants are possible values for the options * argument to waitpid() (1) and/or waitid() (2), diff --git a/include/ulimit.h b/include/ulimit.h new file mode 100644 index 0000000000000..2260cd69b7ab6 --- /dev/null +++ b/include/ulimit.h @@ -0,0 +1,52 @@ +/**************************************************************************** + * include/ulimit.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +#ifndef __INCLUDE_ULIMIT_H +#define __INCLUDE_ULIMIT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get limit on the size of a file, in units of 512 bytes */ + +#define UL_GETFSIZE 1 + +/* Set limit on the size of a file */ + +#define UL_SETFSIZE 2 + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +long int ulimit(int cmd, long newlimit); + +#endif /* __INCLUDE_ULIMIT_H */ diff --git a/include/unistd.h b/include/unistd.h index a4626136f1ef7..4948ae82834f1 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -97,7 +97,7 @@ #define _POSIX_SYNC_IO 1 #undef _POSIX_ASYNC_IO -#undef _POSIX_PRIO_IO +#define _POSIX_PRIO_IO 1 #define _XOPEN_UNIX 1 #define _XOPEN_VERSION 700L diff --git a/libs/libc/gdbstub/lib_gdbstub.c b/libs/libc/gdbstub/lib_gdbstub.c index 362735fe5dbf0..4467ee00b090a 100644 --- a/libs/libc/gdbstub/lib_gdbstub.c +++ b/libs/libc/gdbstub/lib_gdbstub.c @@ -116,6 +116,10 @@ static const struct memory_region_s g_memory_region[] = }; #endif +#if defined(CONFIG_SMP) && defined(CONFIG_ARCH_HAVE_DEBUG) +static struct smp_call_data_s g_call_data; +#endif + /**************************************************************************** * Private Functions Prototypes ****************************************************************************/ @@ -1889,8 +1893,9 @@ int gdb_debugpoint_add(int type, FAR void *addr, size_t size, point.size = size; point.callback = callback; point.arg = arg; - return nxsched_smp_call((1 << CONFIG_SMP_NCPUS) - 1, - gdb_smp_debugpoint_add, &point); + + nxsched_smp_call_init(&g_call_data, gdb_smp_debugpoint_add, &point); + return nxsched_smp_call_async((1 << CONFIG_SMP_NCPUS) - 1, &g_call_data); #else return up_debugpoint_add(type, addr, size, callback, arg); #endif @@ -1908,8 +1913,8 @@ int gdb_debugpoint_remove(int type, FAR void *addr, size_t size) point.addr = addr; point.size = size; - return nxsched_smp_call((1 << CONFIG_SMP_NCPUS) - 1, - gdb_smp_debugpoint_remove, &point); + nxsched_smp_call_init(&g_call_data, gdb_smp_debugpoint_remove, &point); + return nxsched_smp_call_async((1 << CONFIG_SMP_NCPUS) - 1, &g_call_data); #else return up_debugpoint_remove(type, addr, size); #endif diff --git a/libs/libc/machine/arm/armv7-m/arch_memchr.S b/libs/libc/machine/arm/armv7-m/arch_memchr.S index f8922711b3a22..ce01481fcee5d 100644 --- a/libs/libc/machine/arm/armv7-m/arch_memchr.S +++ b/libs/libc/machine/arm/armv7-m/arch_memchr.S @@ -136,7 +136,7 @@ */ .text - .section .text.memchr + .section .text.memchr, "ax" .thumb_func .align 4 .p2align 4,,15 diff --git a/libs/libc/machine/arm/armv7-m/arch_memcpy.S b/libs/libc/machine/arm/armv7-m/arch_memcpy.S index c05eda88b8c1a..1b298ddbeaff2 100644 --- a/libs/libc/machine/arm/armv7-m/arch_memcpy.S +++ b/libs/libc/machine/arm/armv7-m/arch_memcpy.S @@ -94,7 +94,7 @@ .syntax unified .text - .section .text.memcpy + .section .text.memcpy, "ax" .align 2 .global ARCH_LIBCFUN(memcpy) .thumb diff --git a/libs/libc/machine/arm/armv7-m/arch_strcmp.S b/libs/libc/machine/arm/armv7-m/arch_strcmp.S index 1fb87bc1269b5..6e57b8d77f3b3 100644 --- a/libs/libc/machine/arm/armv7-m/arch_strcmp.S +++ b/libs/libc/machine/arm/armv7-m/arch_strcmp.S @@ -72,7 +72,7 @@ .macro def_fn f p2align=0 .text - .section .text.strcmp + .section .text.strcmp, "ax" .p2align \p2align .global \f .type \f, %function diff --git a/libs/libc/machine/arm/armv7-m/arch_strcpy.S b/libs/libc/machine/arm/armv7-m/arch_strcpy.S index b81c5ed3a3505..9d450d6b08159 100644 --- a/libs/libc/machine/arm/armv7-m/arch_strcpy.S +++ b/libs/libc/machine/arm/armv7-m/arch_strcpy.S @@ -60,7 +60,7 @@ .syntax unified .text - .section .text.strcpy + .section .text.strcpy, "ax" .align 2 .global ARCH_LIBCFUN(strcpy) .thumb diff --git a/libs/libc/machine/arm/armv7-m/arch_strlen.S b/libs/libc/machine/arm/armv7-m/arch_strlen.S index d5c6ea5adaa7c..f13bd749ca0c0 100644 --- a/libs/libc/machine/arm/armv7-m/arch_strlen.S +++ b/libs/libc/machine/arm/armv7-m/arch_strlen.S @@ -70,7 +70,7 @@ .macro def_fn f p2align=0 .text - .section .text.strlen + .section .text.strlen, "ax" .p2align \p2align .global \f .type \f, %function diff --git a/libs/libc/misc/CMakeLists.txt b/libs/libc/misc/CMakeLists.txt index fc032f5de3baf..5ca89843e398d 100644 --- a/libs/libc/misc/CMakeLists.txt +++ b/libs/libc/misc/CMakeLists.txt @@ -28,6 +28,7 @@ list( SRCS lib_bitmap.c lib_circbuf.c + lib_creat.c lib_mknod.c lib_umask.c lib_utsname.c diff --git a/libs/libc/misc/Make.defs b/libs/libc/misc/Make.defs index a901639e9a7db..091fc7306c51c 100644 --- a/libs/libc/misc/Make.defs +++ b/libs/libc/misc/Make.defs @@ -22,11 +22,11 @@ # Add the internal C files to the build -CSRCS += lib_bitmap.c lib_circbuf.c lib_mknod.c lib_umask.c lib_utsname.c -CSRCS += lib_getrandom.c lib_xorshift128.c lib_tea_encrypt.c lib_tea_decrypt.c -CSRCS += lib_cxx_initialize.c lib_impure.c lib_memfd.c lib_mutex.c -CSRCS += lib_fchmodat.c lib_fstatat.c lib_getfullpath.c lib_openat.c -CSRCS += lib_mkdirat.c lib_utimensat.c lib_mallopt.c +CSRCS += lib_bitmap.c lib_circbuf.c lib_creat.c lib_mknod.c lib_umask.c +CSRCS += lib_utsname.c lib_getrandom.c lib_xorshift128.c lib_tea_encrypt.c +CSRCS += lib_tea_decrypt.c lib_cxx_initialize.c lib_impure.c lib_memfd.c +CSRCS += lib_mutex.c lib_fchmodat.c lib_fstatat.c lib_getfullpath.c +CSRCS += lib_openat.c lib_mkdirat.c lib_utimensat.c lib_mallopt.c CSRCS += lib_idr.c lib_getnprocs.c ifeq ($(CONFIG_LIBC_TEMPBUFFER),y) diff --git a/libs/libc/misc/lib_creat.c b/libs/libc/misc/lib_creat.c new file mode 100644 index 0000000000000..56683adbde3e7 --- /dev/null +++ b/libs/libc/misc/lib_creat.c @@ -0,0 +1,52 @@ +/**************************************************************************** + * libs/libc/misc/lib_creat.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: creat + * + * Description: + * The creat() function is just a simple wrapper of open() function + * + * Input Parameters: + * path - The path for the file to create on + * mode - the access mode + * + * Returned Value: + * Return a file descriptor of the file that created success, + * return -1 if error occurd on creat new file, and errno is setup + * + ****************************************************************************/ + +int creat(FAR const char *path, mode_t mode) +{ + return open(path, O_WRONLY | O_CREAT | O_TRUNC, mode); +} diff --git a/libs/libc/misc/lib_ftok.c b/libs/libc/misc/lib_ftok.c index ed35966a29802..56cb7b4e80d7e 100644 --- a/libs/libc/misc/lib_ftok.c +++ b/libs/libc/misc/lib_ftok.c @@ -72,7 +72,7 @@ key_t ftok(FAR const char *pathname, int proj_id) snprintf(fullpath, PATH_MAX, "%s/", CONFIG_LIBC_FTOK_VFS_PATH); - strlcat(fullpath, pathname, sizeof(fullpath)); + strlcat(fullpath, pathname, PATH_MAX); if (stat(fullpath, &st) < 0 && get_errno() == ENOENT) { /* Directory not exist, let's create one for caller */ diff --git a/libs/libc/netdb/lib_dnsaddserver.c b/libs/libc/netdb/lib_dnsaddserver.c index b32d17ad4d4d7..4827ac0aa031c 100644 --- a/libs/libc/netdb/lib_dnsaddserver.c +++ b/libs/libc/netdb/lib_dnsaddserver.c @@ -227,7 +227,9 @@ int dns_add_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen) ret = OK; } - goto errout; + dns_unlock(); + fclose(stream); + return ret; } #if CONFIG_NETDB_DNSSERVER_NAMESERVERS > 1 diff --git a/libs/libc/pthread/CMakeLists.txt b/libs/libc/pthread/CMakeLists.txt index 415b2cecb6de7..72ddf8fa5bd06 100644 --- a/libs/libc/pthread/CMakeLists.txt +++ b/libs/libc/pthread/CMakeLists.txt @@ -70,6 +70,7 @@ if(NOT CONFIG_DISABLE_PTHREAD) pthread_conddestroy.c pthread_condtimedwait.c pthread_create.c + pthread_equal.c pthread_exit.c pthread_kill.c pthread_setname_np.c diff --git a/libs/libc/pthread/Make.defs b/libs/libc/pthread/Make.defs index 1e9476a82247e..fff7b1356df96 100644 --- a/libs/libc/pthread/Make.defs +++ b/libs/libc/pthread/Make.defs @@ -46,7 +46,7 @@ CSRCS += pthread_condattr_init.c pthread_condattr_destroy.c CSRCS += pthread_condattr_getpshared.c pthread_condattr_setpshared.c CSRCS += pthread_condattr_setclock.c pthread_condattr_getclock.c CSRCS += pthread_condinit.c pthread_conddestroy.c pthread_condtimedwait.c -CSRCS += pthread_create.c pthread_exit.c pthread_kill.c +CSRCS += pthread_create.c pthread_equal.c pthread_exit.c pthread_kill.c CSRCS += pthread_setname_np.c pthread_getname_np.c CSRCS += pthread_get_stackaddr_np.c pthread_get_stacksize_np.c CSRCS += pthread_mutexattr_init.c pthread_mutexattr_destroy.c diff --git a/libs/libc/pthread/pthread_equal.c b/libs/libc/pthread/pthread_equal.c new file mode 100644 index 0000000000000..f6851511f4e87 --- /dev/null +++ b/libs/libc/pthread/pthread_equal.c @@ -0,0 +1,55 @@ +/**************************************************************************** + * libs/libc/pthread/pthread_equal.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pthread_equal + * + * Description: + * Detect whether the two pthreads is equal or not + * + * Input Parameters: + * t1 - the first pthread to compare + * t2 - the another pthread to compare + * + * Returned Value: + * 1 (TRUE) if the two pthreads are equal, 0 (FALSE) otherwise. + * + * Assumptions: + * + ****************************************************************************/ + +int pthread_equal(pthread_t t1, pthread_t t2) +{ + return t1 == t2; +} diff --git a/libs/libc/stdio/lib_freopen.c b/libs/libc/stdio/lib_freopen.c index 2297bfbdc06fd..8489b9b6fb26b 100644 --- a/libs/libc/stdio/lib_freopen.c +++ b/libs/libc/stdio/lib_freopen.c @@ -31,6 +31,10 @@ #include #include +#ifdef CONFIG_FDSAN +# include +#endif + #include "libc.h" /**************************************************************************** @@ -97,12 +101,6 @@ FAR FILE *freopen(FAR const char *path, FAR const char *mode, return NULL; } - fd = open(path, oflags, 0666); - if (fd < 0) - { - return NULL; - } - /* Make sure that we have exclusive access to the stream */ flockfile(stream); @@ -117,11 +115,31 @@ FAR FILE *freopen(FAR const char *path, FAR const char *mode, funlockfile(stream); - /* Duplicate the new fd to the stream. */ + /* close the old fd */ - ret = dup2(fd, fileno(stream)); - close(fd); - if (ret < 0) +#ifdef CONFIG_FDSAN + android_fdsan_close_with_tag(fileno(stream), + android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_FILE, + (uintptr_t)stream)); +#else + close(fileno(stream)); +#endif + + /* Open the new file and reused the fd */ + + fd = open(path, oflags, 0666); +#ifdef CONFIG_FDSAN + android_fdsan_exchange_owner_tag(fd, 0, + android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_FILE, + (uintptr_t)stream)); +#endif + flockfile(stream); + stream->fs_cookie = (FAR void *)(intptr_t)fd; + funlockfile(stream); + + /* To clear the stale fd */ + + if (fd < 0) { return NULL; } diff --git a/libs/libc/stdio/lib_fsetpos.c b/libs/libc/stdio/lib_fsetpos.c index a0ac40ffc09a8..c42b8e07fc18b 100644 --- a/libs/libc/stdio/lib_fsetpos.c +++ b/libs/libc/stdio/lib_fsetpos.c @@ -53,7 +53,7 @@ * ****************************************************************************/ -int fsetpos(FAR FILE *stream, FAR fpos_t *pos) +int fsetpos(FAR FILE *stream, FAR const fpos_t *pos) { #ifdef CONFIG_DEBUG_FEATURES if (!stream || !pos) diff --git a/libs/libc/unistd/CMakeLists.txt b/libs/libc/unistd/CMakeLists.txt index 792c1ac4a7459..0cef734cc7a9d 100644 --- a/libs/libc/unistd/CMakeLists.txt +++ b/libs/libc/unistd/CMakeLists.txt @@ -69,7 +69,8 @@ set(SRCS lib_getpass.c lib_chdir.c lib_fchdir.c - lib_confstr.c) + lib_confstr.c + lib_ulimit.c) if(NOT CONFIG_SCHED_USER_IDENTITY) list( diff --git a/libs/libc/unistd/Make.defs b/libs/libc/unistd/Make.defs index 1ce751bd868d8..e5d8d248f6014 100644 --- a/libs/libc/unistd/Make.defs +++ b/libs/libc/unistd/Make.defs @@ -33,7 +33,7 @@ CSRCS += lib_futimes.c lib_lutimes.c lib_gethostname.c lib_sethostname.c CSRCS += lib_fchownat.c lib_linkat.c lib_readlinkat.c lib_symlinkat.c CSRCS += lib_unlinkat.c lib_usleep.c lib_getpgrp.c lib_getpgid.c CSRCS += lib_lockf.c lib_flock.c lib_getpass.c -CSRCS += lib_chdir.c lib_fchdir.c lib_confstr.c +CSRCS += lib_chdir.c lib_fchdir.c lib_confstr.c lib_ulimit.c ifneq ($(CONFIG_SCHED_USER_IDENTITY),y) CSRCS += lib_setuid.c lib_setgid.c lib_getuid.c lib_getgid.c diff --git a/libs/libc/unistd/lib_pathconf.c b/libs/libc/unistd/lib_pathconf.c index 69d750a62f5a4..d5630f8953ad5 100644 --- a/libs/libc/unistd/lib_pathconf.c +++ b/libs/libc/unistd/lib_pathconf.c @@ -136,6 +136,9 @@ long fpathconf(int fildes, int name) case _PC_MAX_INPUT: return _POSIX_MAX_INPUT; + case _PC_PRIO_IO: + return _POSIX_PRIO_IO; + default: /* Assume valid but not implemented for the time being */ diff --git a/libs/libc/unistd/lib_sysconf.c b/libs/libc/unistd/lib_sysconf.c index 8683350a9a1b2..dc6bfb8cba186 100644 --- a/libs/libc/unistd/lib_sysconf.c +++ b/libs/libc/unistd/lib_sysconf.c @@ -57,133 +57,133 @@ * symbolic constants defined in that are the corresponding * values used for name. * - * Variable Value of Name + * Variable Value of Name * - * {AIO_LISTIO_MAX} _SC_AIO_LISTIO_MAX - * {AIO_MAX} _SC_AIO_MAX - * {AIO_PRIO_DELTA_MAX} _SC_AIO_PRIO_DELTA_MAX - * {ARG_MAX} _SC_ARG_MAX - * {ATEXIT_MAX} _SC_ATEXIT_MAX - * {BC_BASE_MAX} _SC_BC_BASE_MAX - * {BC_DIM_MAX} _SC_BC_DIM_MAX - * {BC_SCALE_MAX} _SC_BC_SCALE_MAX - * {BC_STRING_MAX} _SC_BC_STRING_MAX - * {CHILD_MAX} _SC_CHILD_MAX - * Clock ticks/second _SC_CLK_TCK - * {COLL_WEIGHTS_MAX} _SC_COLL_WEIGHTS_MAX - * {DELAYTIMER_MAX} _SC_DELAYTIMER_MAX - * {EXPR_NEST_MAX} _SC_EXPR_NEST_MAX - * {HOST_NAME_MAX} _SC_HOST_NAME_MAX - * {IOV_MAX} _SC_IOV_MAX - * {LINE_MAX} _SC_LINE_MAX - * {LOGIN_NAME_MAX} _SC_LOGIN_NAME_MAX - * {NGROUPS_MAX} _SC_NGROUPS_MAX - * Maximum size of getgrgid_r() and _SC_GETGR_R_SIZE_MAX + * {AIO_LISTIO_MAX} _SC_AIO_LISTIO_MAX + * {AIO_MAX} _SC_AIO_MAX + * {AIO_PRIO_DELTA_MAX} _SC_AIO_PRIO_DELTA_MAX + * {ARG_MAX} _SC_ARG_MAX + * {ATEXIT_MAX} _SC_ATEXIT_MAX + * {BC_BASE_MAX} _SC_BC_BASE_MAX + * {BC_DIM_MAX} _SC_BC_DIM_MAX + * {BC_SCALE_MAX} _SC_BC_SCALE_MAX + * {BC_STRING_MAX} _SC_BC_STRING_MAX + * {CHILD_MAX} _SC_CHILD_MAX + * Clock ticks/second _SC_CLK_TCK + * {COLL_WEIGHTS_MAX} _SC_COLL_WEIGHTS_MAX + * {DELAYTIMER_MAX} _SC_DELAYTIMER_MAX + * {EXPR_NEST_MAX} _SC_EXPR_NEST_MAX + * {HOST_NAME_MAX} _SC_HOST_NAME_MAX + * {IOV_MAX} _SC_IOV_MAX + * {LINE_MAX} _SC_LINE_MAX + * {LOGIN_NAME_MAX} _SC_LOGIN_NAME_MAX + * {NGROUPS_MAX} _SC_NGROUPS_MAX + * Maximum size of getgrgid_r() and _SC_GETGR_R_SIZE_MAX * getgrnam_r() data buffers - * Maximum size of getpwuid_r() and _SC_GETPW_R_SIZE_MAX + * Maximum size of getpwuid_r() and _SC_GETPW_R_SIZE_MAX * getpwnam_r() data buffers - * {MQ_OPEN_MAX} _SC_MQ_OPEN_MAX - * {MQ_PRIO_MAX} _SC_MQ_PRIO_MAX - * {OPEN_MAX} _SC_OPEN_MAX - * _POSIX_ADVISORY_INFO _SC_ADVISORY_INFO - * _POSIX_BARRIERS _SC_BARRIERS - * _POSIX_ASYNCHRONOUS_IO _SC_ASYNCHRONOUS_IO - * _POSIX_CLOCK_SELECTION _SC_CLOCK_SELECTION - * _POSIX_CPUTIME _SC_CPUTIME - * _POSIX_FSYNC _SC_FSYNC - * _POSIX_IPV6 _SC_IPV6 - * _POSIX_JOB_CONTROL _SC_JOB_CONTROL - * _POSIX_MAPPED_FILES _SC_MAPPED_FILES - * _POSIX_MEMLOCK _SC_MEMLOCK - * _POSIX_MEMLOCK_RANGE _SC_MEMLOCK_RANGE - * _POSIX_MEMORY_PROTECTION _SC_MEMORY_PROTECTION - * _POSIX_MESSAGE_PASSING _SC_MESSAGE_PASSING - * _POSIX_MONOTONIC_CLOCK _SC_MONOTONIC_CLOCK - * _POSIX_PRIORITIZED_IO _SC_PRIORITIZED_IO - * _POSIX_PRIORITY_SCHEDULING _SC_PRIORITY_SCHEDULING - * _POSIX_RAW_SOCKETS _SC_RAW_SOCKETS - * _POSIX_READER_WRITER_LOCKS _SC_READER_WRITER_LOCKS - * _POSIX_REALTIME_SIGNALS _SC_REALTIME_SIGNALS - * _POSIX_REGEXP _SC_REGEXP - * _POSIX_SAVED_IDS _SC_SAVED_IDS - * _POSIX_SEMAPHORES _SC_SEMAPHORES - * _POSIX_SHARED_MEMORY_OBJECTS _SC_SHARED_MEMORY_OBJECTS - * _POSIX_SHELL _SC_SHELL - * _POSIX_SPAWN _SC_SPAWN - * _POSIX_SPIN_LOCKS _SC_SPIN_LOCKS - * _POSIX_SPORADIC_SERVER _SC_SPORADIC_SERVER - * _POSIX_SS_REPL_MAX _SC_SS_REPL_MAX - * _POSIX_SYNCHRONIZED_IO _SC_SYNCHRONIZED_IO - * _POSIX_THREAD_ATTR_STACKADDR _SC_THREAD_ATTR_STACKADDR - * _POSIX_THREAD_ATTR_STACKSIZE _SC_THREAD_ATTR_STACKSIZE - * _POSIX_THREAD_CPUTIME _SC_THREAD_CPUTIME - * _POSIX_THREAD_PRIO_INHERIT _SC_THREAD_PRIO_INHERIT - * _POSIX_THREAD_PRIO_PROTECT _SC_THREAD_PRIO_PROTECT - * _POSIX_THREAD_PRIORITY_SCHEDULING _SC_THREAD_PRIORITY_SCHEDULING - * _POSIX_THREAD_PROCESS_SHARED _SC_THREAD_PROCESS_SHARED - * _POSIX_THREAD_SAFE_FUNCTIONS _SC_THREAD_SAFE_FUNCTIONS - * _POSIX_THREAD_SPORADIC_SERVER _SC_THREAD_SPORADIC_SERVER - * _POSIX_THREADS _SC_THREADS - * _POSIX_TIMEOUTS _SC_TIMEOUTS - * _POSIX_TIMERS _SC_TIMERS - * _POSIX_TRACE _SC_TRACE - * _POSIX_TRACE_EVENT_FILTER _SC_TRACE_EVENT_FILTER - * _POSIX_TRACE_EVENT_NAME_MAX _SC_TRACE_EVENT_NAME_MAX - * _POSIX_TRACE_INHERIT _SC_TRACE_INHERIT - * _POSIX_TRACE_LOG _SC_TRACE_LOG - * _POSIX_TRACE_NAME_MAX _SC_TRACE_NAME_MAX - * _POSIX_TRACE_SYS_MAX _SC_TRACE_SYS_MAX - * _POSIX_TRACE_USER_EVENT_MAX _SC_TRACE_USER_EVENT_MAX - * _POSIX_TYPED_MEMORY_OBJECTS _SC_TYPED_MEMORY_OBJECTS - * _POSIX_VERSION _SC_VERSION - * _POSIX_V6_ILP32_OFF32 _SC_V6_ILP32_OFF32 - * _POSIX_V6_ILP32_OFFBIG _SC_V6_ILP32_OFFBIG - * _POSIX_V6_LP64_OFF64 _SC_V6_LP64_OFF64 - * _POSIX_V6_LPBIG_OFFBIG _SC_V6_LPBIG_OFFBIG - * _POSIX2_C_BIND _SC_2_C_BIND - * _POSIX2_C_DEV _SC_2_C_DEV - * _POSIX2_CHAR_TERM _SC_2_CHAR_TERM - * _POSIX2_FORT_DEV _SC_2_FORT_DEV - * _POSIX2_FORT_RUN _SC_2_FORT_RUN - * _POSIX2_LOCALEDEF _SC_2_LOCALEDEF - * _POSIX2_PBS _SC_2_PBS - * _POSIX2_PBS_ACCOUNTING _SC_2_PBS_ACCOUNTING - * _POSIX2_PBS_CHECKPOINT _SC_2_PBS_CHECKPOINT - * _POSIX2_PBS_LOCATE _SC_2_PBS_LOCATE - * _POSIX2_PBS_MESSAGE _SC_2_PBS_MESSAGE - * _POSIX2_PBS_TRACK _SC_2_PBS_TRACK - * _POSIX2_SW_DEV _SC_2_SW_DEV - * _POSIX2_UPE _SC_2_UPE - * _POSIX2_VERSION _SC_2_VERSION - * {PAGE_SIZE} _SC_PAGE_SIZE - * {PAGESIZE} _SC_PAGESIZE - * {PTHREAD_DESTRUCTOR_ITERATIONS} _SC_THREAD_DESTRUCTOR_ITERATIONS - * {PTHREAD_KEYS_MAX} _SC_THREAD_KEYS_MAX - * {PTHREAD_STACK_MIN} _SC_THREAD_STACK_MIN - * {PTHREAD_THREADS_MAX} _SC_THREAD_THREADS_MAX - * {RE_DUP_MAX} _SC_RE_DUP_MAX - * {RTSIG_MAX} _SC_RTSIG_MAX - * {SEM_NSEMS_MAX} _SC_SEM_NSEMS_MAX - * {SEM_VALUE_MAX} _SC_SEM_VALUE_MAX - * {SIGQUEUE_MAX} _SC_SIGQUEUE_MAX - * {STREAM_MAX} _SC_STREAM_MAX - * {SYMLOOP_MAX} _SC_SYMLOOP_MAX - * {TIMER_MAX} _SC_TIMER_MAX - * {TTY_NAME_MAX} _SC_TTY_NAME_MAX - * {TZNAME_MAX} _SC_TZNAME_MAX - * _XBS5_ILP32_OFF32 (LEGACY) _SC_XBS5_ILP32_OFF32 (LEGACY) - * _XBS5_ILP32_OFFBIG (LEGACY) _SC_XBS5_ILP32_OFFBIG (LEGACY) - * _XBS5_LP64_OFF64 (LEGACY) _SC_XBS5_LP64_OFF64 (LEGACY) - * _XBS5_LPBIG_OFFBIG (LEGACY) _SC_XBS5_LPBIG_OFFBIG (LEGACY) - * _XOPEN_CRYPT _SC_XOPEN_CRYPT - * _XOPEN_ENH_I18N _SC_XOPEN_ENH_I18N - * _XOPEN_LEGACY _SC_XOPEN_LEGACY - * _XOPEN_REALTIME _SC_XOPEN_REALTIME - * _XOPEN_REALTIME_THREADS _SC_XOPEN_REALTIME_THREADS - * _XOPEN_SHM _SC_XOPEN_SHM - * _XOPEN_STREAMS _SC_XOPEN_STREAMS - * _XOPEN_UNIX _SC_XOPEN_UNIX - * _XOPEN_VERSION _SC_XOPEN_VERSION + * {MQ_OPEN_MAX} _SC_MQ_OPEN_MAX + * {MQ_PRIO_MAX} _SC_MQ_PRIO_MAX + * {OPEN_MAX} _SC_OPEN_MAX + * _POSIX_ADVISORY_INFO _SC_ADVISORY_INFO + * _POSIX_BARRIERS _SC_BARRIERS + * _POSIX_ASYNCHRONOUS_IO _SC_ASYNCHRONOUS_IO + * _POSIX_CLOCK_SELECTION _SC_CLOCK_SELECTION + * _POSIX_CPUTIME _SC_CPUTIME + * _POSIX_FSYNC _SC_FSYNC + * _POSIX_IPV6 _SC_IPV6 + * _POSIX_JOB_CONTROL _SC_JOB_CONTROL + * _POSIX_MAPPED_FILES _SC_MAPPED_FILES + * _POSIX_MEMLOCK _SC_MEMLOCK + * _POSIX_MEMLOCK_RANGE _SC_MEMLOCK_RANGE + * _POSIX_MEMORY_PROTECTION _SC_MEMORY_PROTECTION + * _POSIX_MESSAGE_PASSING _SC_MESSAGE_PASSING + * _POSIX_MONOTONIC_CLOCK _SC_MONOTONIC_CLOCK + * _POSIX_PRIORITIZED_IO _SC_PRIORITIZED_IO + * _POSIX_PRIORITY_SCHEDULING _SC_PRIORITY_SCHEDULING + * _POSIX_RAW_SOCKETS _SC_RAW_SOCKETS + * _POSIX_READER_WRITER_LOCKS _SC_READER_WRITER_LOCKS + * _POSIX_REALTIME_SIGNALS _SC_REALTIME_SIGNALS + * _POSIX_REGEXP _SC_REGEXP + * _POSIX_SAVED_IDS _SC_SAVED_IDS + * _POSIX_SEMAPHORES _SC_SEMAPHORES + * _POSIX_SHARED_MEMORY_OBJECTS _SC_SHARED_MEMORY_OBJECTS + * _POSIX_SHELL _SC_SHELL + * _POSIX_SPAWN _SC_SPAWN + * _POSIX_SPIN_LOCKS _SC_SPIN_LOCKS + * _POSIX_SPORADIC_SERVER _SC_SPORADIC_SERVER + * _POSIX_SS_REPL_MAX _SC_SS_REPL_MAX + * _POSIX_SYNCHRONIZED_IO _SC_SYNCHRONIZED_IO + * _POSIX_THREAD_ATTR_STACKADDR _SC_THREAD_ATTR_STACKADDR + * _POSIX_THREAD_ATTR_STACKSIZE _SC_THREAD_ATTR_STACKSIZE + * _POSIX_THREAD_CPUTIME _SC_THREAD_CPUTIME + * _POSIX_THREAD_PRIO_INHERIT _SC_THREAD_PRIO_INHERIT + * _POSIX_THREAD_PRIO_PROTECT _SC_THREAD_PRIO_PROTECT + * _POSIX_THREAD_PRIORITY_SCHEDULING _SC_THREAD_PRIORITY_SCHEDULING + * _POSIX_THREAD_PROCESS_SHARED _SC_THREAD_PROCESS_SHARED + * _POSIX_THREAD_SAFE_FUNCTIONS _SC_THREAD_SAFE_FUNCTIONS + * _POSIX_THREAD_SPORADIC_SERVER _SC_THREAD_SPORADIC_SERVER + * _POSIX_THREADS _SC_THREADS + * _POSIX_TIMEOUTS _SC_TIMEOUTS + * _POSIX_TIMERS _SC_TIMERS + * _POSIX_TRACE _SC_TRACE + * _POSIX_TRACE_EVENT_FILTER _SC_TRACE_EVENT_FILTER + * _POSIX_TRACE_EVENT_NAME_MAX _SC_TRACE_EVENT_NAME_MAX + * _POSIX_TRACE_INHERIT _SC_TRACE_INHERIT + * _POSIX_TRACE_LOG _SC_TRACE_LOG + * _POSIX_TRACE_NAME_MAX _SC_TRACE_NAME_MAX + * _POSIX_TRACE_SYS_MAX _SC_TRACE_SYS_MAX + * _POSIX_TRACE_USER_EVENT_MAX _SC_TRACE_USER_EVENT_MAX + * _POSIX_TYPED_MEMORY_OBJECTS _SC_TYPED_MEMORY_OBJECTS + * _POSIX_VERSION _SC_VERSION + * _POSIX_V6_ILP32_OFF32 _SC_V6_ILP32_OFF32 + * _POSIX_V6_ILP32_OFFBIG _SC_V6_ILP32_OFFBIG + * _POSIX_V6_LP64_OFF64 _SC_V6_LP64_OFF64 + * _POSIX_V6_LPBIG_OFFBIG _SC_V6_LPBIG_OFFBIG + * _POSIX2_C_BIND _SC_2_C_BIND + * _POSIX2_C_DEV _SC_2_C_DEV + * _POSIX2_CHAR_TERM _SC_2_CHAR_TERM + * _POSIX2_FORT_DEV _SC_2_FORT_DEV + * _POSIX2_FORT_RUN _SC_2_FORT_RUN + * _POSIX2_LOCALEDEF _SC_2_LOCALEDEF + * _POSIX2_PBS _SC_2_PBS + * _POSIX2_PBS_ACCOUNTING _SC_2_PBS_ACCOUNTING + * _POSIX2_PBS_CHECKPOINT _SC_2_PBS_CHECKPOINT + * _POSIX2_PBS_LOCATE _SC_2_PBS_LOCATE + * _POSIX2_PBS_MESSAGE _SC_2_PBS_MESSAGE + * _POSIX2_PBS_TRACK _SC_2_PBS_TRACK + * _POSIX2_SW_DEV _SC_2_SW_DEV + * _POSIX2_UPE _SC_2_UPE + * _POSIX2_VERSION _SC_2_VERSION + * {PAGE_SIZE} _SC_PAGE_SIZE + * {PAGESIZE} _SC_PAGESIZE + * _POSIX_THREAD_DESTRUCTOR_ITERATIONS _SC_THREAD_DESTRUCTOR_ITERATIONS + * _POSIX_THREAD_KEYS_MAX _SC_THREAD_KEYS_MAX + * {PTHREAD_STACK_MIN} _SC_THREAD_STACK_MIN + * _POSIX_THREAD_THREADS_MAX _SC_THREAD_THREADS_MAX + * {RE_DUP_MAX} _SC_RE_DUP_MAX + * {RTSIG_MAX} _SC_RTSIG_MAX + * {SEM_NSEMS_MAX} _SC_SEM_NSEMS_MAX + * {SEM_VALUE_MAX} _SC_SEM_VALUE_MAX + * {SIGQUEUE_MAX} _SC_SIGQUEUE_MAX + * {STREAM_MAX} _SC_STREAM_MAX + * {SYMLOOP_MAX} _SC_SYMLOOP_MAX + * {TIMER_MAX} _SC_TIMER_MAX + * {TTY_NAME_MAX} _SC_TTY_NAME_MAX + * {TZNAME_MAX} _SC_TZNAME_MAX + * _XBS5_ILP32_OFF32 (LEGACY) _SC_XBS5_ILP32_OFF32 (LEGACY) + * _XBS5_ILP32_OFFBIG (LEGACY) _SC_XBS5_ILP32_OFFBIG (LEGACY) + * _XBS5_LP64_OFF64 (LEGACY) _SC_XBS5_LP64_OFF64 (LEGACY) + * _XBS5_LPBIG_OFFBIG (LEGACY) _SC_XBS5_LPBIG_OFFBIG (LEGACY) + * _XOPEN_CRYPT _SC_XOPEN_CRYPT + * _XOPEN_ENH_I18N _SC_XOPEN_ENH_I18N + * _XOPEN_LEGACY _SC_XOPEN_LEGACY + * _XOPEN_REALTIME _SC_XOPEN_REALTIME + * _XOPEN_REALTIME_THREADS _SC_XOPEN_REALTIME_THREADS + * _XOPEN_SHM _SC_XOPEN_SHM + * _XOPEN_STREAMS _SC_XOPEN_STREAMS + * _XOPEN_UNIX _SC_XOPEN_UNIX + * _XOPEN_VERSION _SC_XOPEN_VERSION * * Returned Value: * If name is an invalid value, sysconf() will return -1 and set errno to diff --git a/libs/libc/unistd/lib_ulimit.c b/libs/libc/unistd/lib_ulimit.c new file mode 100644 index 0000000000000..ddf56b4a4e986 --- /dev/null +++ b/libs/libc/unistd/lib_ulimit.c @@ -0,0 +1,76 @@ +/**************************************************************************** + * libs/libc/unistd/lib_ulimit.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ulimit + * + * Description: + * The ulimit will make calls to getrlimit() and setrlimit() to perform + * get and set resource limits respectively. + * + * Returned value: + * On success, return a non-negative value. + * On failure, return -1 and set the errno value. + * + ****************************************************************************/ + +long ulimit(int cmd, long newlimit) +{ + long ret = ERROR; + + switch (cmd) + { + case UL_GETFSIZE: + { + struct rlimit rlp; + getrlimit(RLIMIT_FSIZE, &rlp); + ret = rlp.rlim_cur / 512UL; + } + break; + case UL_SETFSIZE: + { + struct rlimit rlp; + rlp.rlim_max = RLIM_INFINITY; + rlp.rlim_cur = newlimit * 512UL; + ret = setrlimit(RLIMIT_FSIZE, &rlp); + } + break; + default: + set_errno(EINVAL); + break; + } + + return ret; +} diff --git a/libs/libc/wqueue/CMakeLists.txt b/libs/libc/wqueue/CMakeLists.txt index 520547b6f4f87..e89e6757ec811 100644 --- a/libs/libc/wqueue/CMakeLists.txt +++ b/libs/libc/wqueue/CMakeLists.txt @@ -20,6 +20,6 @@ # # ############################################################################## -if(CONFIG_LIB_USRWORK) +if(CONFIG_LIBC_USRWORK) target_sources(c PRIVATE work_usrthread.c work_queue.c work_cancel.c) endif() diff --git a/libs/libm/libm/lib_atanf.c b/libs/libm/libm/lib_atanf.c index 08547152c4658..65376153f7915 100644 --- a/libs/libm/libm/lib_atanf.c +++ b/libs/libm/libm/lib_atanf.c @@ -31,12 +31,15 @@ #include #include #include +#include /**************************************************************************** * Public Functions ****************************************************************************/ +#define ABS(a) ((a) > 0 ? (a) : -(a)) + float atanf(float x) { - return asinf(x / sqrtf(x * x + 1.0F)); + return asinf(x / MAX(ABS(x), sqrtf(x * x + 1.0F))); } diff --git a/libs/libxx/Kconfig b/libs/libxx/Kconfig index 62618e15bb603..80b9ca0f94e8f 100644 --- a/libs/libxx/Kconfig +++ b/libs/libxx/Kconfig @@ -29,7 +29,6 @@ choice config LIBCXXTOOLCHAIN bool "Toolchain C++ support" select HAVE_CXXINITIALIZE - select LIBC_LOCALE ---help--- Use Standard C++ library from toolchain. @@ -75,6 +74,7 @@ choice config LIBCXXABI bool "LLVM low level C++ Library" + select SCHED_THREAD_LOCAL ---help--- LLVM "libc++abi" C++ Standard Library https://libcxxabi.llvm.org/ @@ -100,15 +100,16 @@ config LIBCXXABI_VERSION string "Select libcxxabi version" depends on LIBCXXABI default LIBCXX_VERSION if LIBCXX - default "17.0.6" if !LIBCXX + default "19.1.7" if !LIBCXX config CXX_STANDARD string "Language standard" - default "gnu++20" if LIBCXX + default "c++14" if TRICORE_TOOLCHAIN_TASKING + default "gnu++23" if LIBCXX default "gnu++17" if !LIBCXX ---help--- Possible values: - gnu++98/c++98, gnu++11/c++11, gnu++14/c++14, gnu++17/c++17 and gnu++20/c++20 + gnu++98/c++98, gnu++11/c++11, gnu++14/c++14, gnu++17/c++17, gnu++20/c++20 and gnu++23/c++23 config CXX_EXCEPTION bool "Enable Exception Support" @@ -119,10 +120,22 @@ config CXX_RTTI config CXX_WCHAR bool "Enable Wide Character Support" +choice + prompt "C++ Locale and Stream select" + default CXX_NO_LOCALIZATION + +config CXX_NO_LOCALIZATION + bool "No Locale and Stream Support" + +config CXX_MINI_LOCALIZATION + bool "Enable mini Locale and Stream Support" + config CXX_LOCALIZATION bool "Enable Locale and Stream Support" depends on LIBC_LOCALE +endchoice + if UCLIBCXX config UCLIBCXX_BUFSIZE @@ -134,6 +147,11 @@ endif config LIBCXX_VERSION string "Select libcxx version" depends on LIBCXX - default "17.0.6" + default "19.1.7" + +config LIBCXX_TEST + bool "LLVM Libcxx Library Test" + depends on LIBCXX && CXX_EXCEPTION + default n endif diff --git a/libs/libxx/__assertion_handler b/libs/libxx/__assertion_handler new file mode 100644 index 0000000000000..41969decc8447 --- /dev/null +++ b/libs/libxx/__assertion_handler @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ASSERTION_HANDLER +#define _LIBCPP___ASSERTION_HANDLER + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#define _LIBCPP_ASSERTION_HANDLER(message) ((void)(message), __builtin_trap()) + +#endif // _LIBCPP___ASSERTION_HANDLER diff --git a/libs/libxx/__config_site b/libs/libxx/__config_site index e7d5116ceb0ce..3be0c26adf10a 100644 --- a/libs/libxx/__config_site +++ b/libs/libxx/__config_site @@ -18,46 +18,55 @@ /* #undef _LIBCPP_HAS_NO_THREADS */ /* #undef _LIBCPP_HAS_NO_MONOTONIC_CLOCK */ /* #undef _LIBCPP_HAS_MUSL_LIBC */ -/* #undef _LIBCPP_HAS_THREAD_API_PTHREAD */ +#define _LIBCPP_HAS_THREAD_API_PTHREAD 1 /* #undef _LIBCPP_HAS_THREAD_API_EXTERNAL */ /* #undef _LIBCPP_HAS_THREAD_API_WIN32 */ -/* #undef _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS */ +#define _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS 1 #define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS /* #undef _LIBCPP_NO_VCRUNTIME */ /* #undef _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION */ /* #undef _LIBCPP_HAS_NO_FILESYSTEM */ /* #undef _LIBCPP_HAS_NO_RANDOM_DEVICE */ -#ifndef CONFIG_CXX_LOCALIZATION -# define _LIBCPP_HAS_NO_LOCALIZATION +#if defined(CONFIG_CXX_NO_LOCALIZATION) +#define _LIBCPP_HAS_NO_LOCALIZATION +#elif defined(CONFIG_CXX_MINI_LOCALIZATION) +#define _LIBCPP_HAS_MINI_LOCALIZATION #endif #ifndef CONFIG_CXX_WCHAR -# define _LIBCPP_HAS_NO_WIDE_CHARACTERS +#define _LIBCPP_HAS_NO_WIDE_CHARACTERS #endif #define _LIBCPP_ENABLE_ASSERTIONS_DEFAULT 0 // PSTL backends +#define _LIBCPP_PSTL_BACKEND_SERIAL #define _LIBCPP_PSTL_CPU_BACKEND_SERIAL /* #undef _LIBCPP_PSTL_CPU_BACKEND_THREAD */ /* #undef _LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH */ +// Force each translation unit to emit the necessary basic_string +// specializations (avoids missing wide-character dtor symbols). +#define _LIBCPP_DISABLE_EXTERN_TEMPLATE 1 + +// Type traits tuning. +#define _LIBCPP_DISABLE_DECAY_BUILTIN 1 + // Hardening. #define _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT 0 #define _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT 0 +#define _LIBCPP_HARDENING_MODE_DEFAULT _LIBCPP_HARDENING_MODE_FAST +#define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEFAULT #define _LIBCPP_DISABLE_DEPRECATION_WARNINGS 1 #define _LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT 1 // __USE_MINGW_ANSI_STDIO gets redefined on MinGW #ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wmacro-redefined" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmacro-redefined" #endif - - - #ifdef __clang__ -# pragma clang diagnostic pop +#pragma clang diagnostic pop #endif #define _SYS_REENT_H_ diff --git a/libs/libxx/libcxx/0001-Fix-build-error-about-__GLIBC__.patch b/libs/libxx/libcxx/0001-Fix-build-error-about-__GLIBC__.patch index 95d6ee09dff05..1fda8077e4579 100644 --- a/libs/libxx/libcxx/0001-Fix-build-error-about-__GLIBC__.patch +++ b/libs/libxx/libcxx/0001-Fix-build-error-about-__GLIBC__.patch @@ -1,17 +1,13 @@ -diff --git libcxx/src/locale.cpp libcxx/src/locale.cpp --- libcxx/src/locale.cpp +++ libcxx/src/locale.cpp -@@ -41,6 +41,10 @@ +@@ -40,6 +40,10 @@ + #include "include/atomic_support.h" #include "include/sso_allocator.h" - +#if defined(__NuttX__) && defined(__GLIBC__) -+# undef __GLIBC__ ++# undef __GLIBC__ +#endif + + // On Linux, wint_t and wchar_t have different signed-ness, and this causes // lots of noise in the build log, but no bugs that I know of. - _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wsign-conversion") --- -2.34.1 - diff --git a/libs/libxx/libcxx/0001-libcxx-fix-ld-errors.patch b/libs/libxx/libcxx/0001-libcxx-fix-ld-errors.patch index 8bfbe4528c264..5b4d09082b08d 100644 --- a/libs/libxx/libcxx/0001-libcxx-fix-ld-errors.patch +++ b/libs/libxx/libcxx/0001-libcxx-fix-ld-errors.patch @@ -1,28 +1,27 @@ -diff --git libcxx/include/ostream libcxx/include/ostream ---- libcxx/include/ostream -+++ libcxx/include/ostream -@@ -320,7 +320,10 @@ template - basic_ostream<_CharT, _Traits>::sentry::~sentry() - { - if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) -- && !uncaught_exception()) +--- libcxx/include/__ostream/basic_ostream.h ++++ libcxx/include/__ostream/basic_ostream.h +@@ -152,7 +152,11 @@ + + template + basic_ostream<_CharT, _Traits>::sentry::~sentry() { +- if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) && !uncaught_exception()) { ++ if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) +#ifndef _LIBCPP_HAS_NO_EXCEPTIONS -+ && !uncaught_exception() ++ && !uncaught_exception() +#endif -+ ) - { ++ ) { #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - try -diff --git libcxx/src/exception.cpp libcxx/src/exception.cpp + try { + #endif // _LIBCPP_HAS_NO_EXCEPTIONS --- libcxx/src/exception.cpp +++ libcxx/src/exception.cpp @@ -19,6 +19,9 @@ #if defined(_LIBCPP_ABI_MICROSOFT) - #include "support/runtime/exception_msvc.ipp" - #include "support/runtime/exception_pointer_msvc.ipp" + # include "support/runtime/exception_msvc.ipp" + # include "support/runtime/exception_pointer_msvc.ipp" +#elif defined(_LIBCPPABI_VERSION) && defined(_LIBCPP_HAS_NO_EXCEPTIONS) -+#include "include/atomic_support.h" -+#include "support/runtime/exception_pointer_unimplemented.ipp" ++# include "include/atomic_support.h" ++# include "support/runtime/exception_pointer_unimplemented.ipp" #elif defined(_LIBCPPABI_VERSION) - #include "support/runtime/exception_libcxxabi.ipp" - #include "support/runtime/exception_pointer_cxxabi.ipp" + # include "support/runtime/exception_libcxxabi.ipp" + # include "support/runtime/exception_pointer_cxxabi.ipp" diff --git a/libs/libxx/libcxx/0001-libcxx-remove-mach-time-h.patch b/libs/libxx/libcxx/0001-libcxx-remove-mach-time-h.patch index 7019bc6d563be..30e4d101361b7 100644 --- a/libs/libxx/libcxx/0001-libcxx-remove-mach-time-h.patch +++ b/libs/libxx/libcxx/0001-libcxx-remove-mach-time-h.patch @@ -1,11 +1,11 @@ --- libcxx/src/chrono.cpp +++ libcxx/src/chrono.cpp -@@ -48,10 +48,6 @@ +@@ -50,10 +50,6 @@ # include #endif - + -#if __has_include() --# include +-# include -#endif - #if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB) diff --git a/libs/libxx/libcxx/0001_fix_stdatomic_h_miss_typedef.patch b/libs/libxx/libcxx/0001_fix_stdatomic_h_miss_typedef.patch index 56ae62c402361..9b3d56f113489 100644 --- a/libs/libxx/libcxx/0001_fix_stdatomic_h_miss_typedef.patch +++ b/libs/libxx/libcxx/0001_fix_stdatomic_h_miss_typedef.patch @@ -1,11 +1,11 @@ ---- libcxx/include/stdatomic.h.old 2023-12-06 21:01:46.168049453 +0800 -+++ libcxx/include/stdatomic.h 2023-12-06 21:01:55.056057032 +0800 +--- libcxx/include/stdatomic.h ++++ libcxx/include/stdatomic.h @@ -220,7 +220,7 @@ using std::atomic_signal_fence _LIBCPP_USING_IF_EXISTS; using std::atomic_thread_fence _LIBCPP_USING_IF_EXISTS; - + -#elif defined(_LIBCPP_COMPILER_CLANG_BASED) +#else - + // Before C++23, we include the next on the path to avoid hijacking // the header. We do this because Clang has historically shipped a diff --git a/libs/libxx/libcxx/0002-libcxx-decay-and-tzdb-fixes.patch b/libs/libxx/libcxx/0002-libcxx-decay-and-tzdb-fixes.patch new file mode 100644 index 0000000000000..90f5a293fc36d --- /dev/null +++ b/libs/libxx/libcxx/0002-libcxx-decay-and-tzdb-fixes.patch @@ -0,0 +1,49 @@ +--- libcxx/include/__type_traits/decay.h ++++ libcxx/include/__type_traits/decay.h +@@ -25,7 +25,7 @@ + + _LIBCPP_BEGIN_NAMESPACE_STD + +-#if __has_builtin(__decay) ++#if __has_builtin(__decay) && !defined(_LIBCPP_DISABLE_DECAY_BUILTIN) + template + using __decay_t _LIBCPP_NODEBUG = __decay(_Tp); + +--- libcxx/src/experimental/tzdb.cpp ++++ libcxx/src/experimental/tzdb.cpp +@@ -50,6 +50,8 @@ + _LIBCPP_WEAK string_view __libcpp_tzdb_directory() { + #if defined(__linux__) + return "/usr/share/zoneinfo/"; ++#elif defined(CONFIG_LIBC_TZDIR) ++ return CONFIG_LIBC_TZDIR "/"; + #else +-# error "unknown path to the IANA Time Zone Database" ++ return string_view{}; + #endif + +--- libcxx/src/include/overridable_function.h ++++ libcxx/src/include/overridable_function.h +@@ -96,7 +96,7 @@ + } + _LIBCPP_END_NAMESPACE_STD + +-#elif defined(_LIBCPP_OBJECT_FORMAT_ELF) ++#elif defined(_LIBCPP_OBJECT_FORMAT_ELF) && !defined(CONFIG_ESPRESSIF_CHIP_SERIES) + + # define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1 + # define _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE __attribute__((__section__("__lcxx_override"))) +@@ -121,6 +121,13 @@ + + #else + ++# ifdef CONFIG_ESPRESSIF_CHIP_SERIES ++// esptool requires every loadable segment to be 4-byte aligned, but the ++// __lcxx_override section can end up with compressed instructions that don't ++// satisfy that constraint on Espressif parts. Skip the detection machinery on ++// those targets and fall back to the generic implementation. ++# endif ++ + # define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 0 + # define _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE /* nothing */ + diff --git a/libs/libxx/libcxx/CMakeLists.txt b/libs/libxx/libcxx/CMakeLists.txt index 664600337647f..cc43f9ffb65de 100644 --- a/libs/libxx/libcxx/CMakeLists.txt +++ b/libs/libxx/libcxx/CMakeLists.txt @@ -45,16 +45,16 @@ if(CONFIG_LIBCXX) PATCH_COMMAND patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < ${CMAKE_CURRENT_LIST_DIR}/0001_fix_stdatomic_h_miss_typedef.patch && - patch -p3 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/mbstate_t.patch && patch -p1 -d - ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-remove-mach-time-h.patch && patch - -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-ld-errors.patch && patch -p1 - -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-remove-mach-time-h.patch && + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-ld-errors.patch && + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < ${CMAKE_CURRENT_LIST_DIR}/0001-Fix-build-error-about-__GLIBC__.patch && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-libc-Fix-failures-with-GCC-14-92663.patch + ${CMAKE_CURRENT_LIST_DIR}/0002-libcxx-decay-and-tzdb-fixes.patch && + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/mbstate_t.patch DOWNLOAD_NO_PROGRESS true TIMEOUT 30) @@ -66,16 +66,24 @@ if(CONFIG_LIBCXX) endif() + configure_file(${CMAKE_CURRENT_LIST_DIR}/../__assertion_handler + ${CMAKE_CURRENT_LIST_DIR}/libcxx/include/__assertion_handler + COPYONLY) + nuttx_create_symlink(${CMAKE_CURRENT_LIST_DIR}/libcxx/include ${CMAKE_BINARY_DIR}/include/libcxx) - configure_file(${CMAKE_CURRENT_LIST_DIR}/../__config_site - ${CMAKE_BINARY_DIR}/include/libcxx/__config_site COPYONLY) + nuttx_create_symlink(${CMAKE_CURRENT_LIST_DIR}/../__config_site + ${CMAKE_BINARY_DIR}/include/libcxx_config/__config_site) set_property( TARGET nuttx APPEND - PROPERTY NUTTX_CXX_INCLUDE_DIRECTORIES ${CMAKE_BINARY_DIR}/include/libcxx) + PROPERTY NUTTX_CXX_INCLUDE_DIRECTORIES + ${CMAKE_BINARY_DIR}/include/libcxx + ${CMAKE_BINARY_DIR}/include/libcxx_config + ${CMAKE_CURRENT_LIST_DIR}/libcxx/test/support + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src) add_compile_definitions(_LIBCPP_BUILDING_LIBRARY) if(CONFIG_LIBSUPCXX_TOOLCHAIN) @@ -91,28 +99,54 @@ if(CONFIG_LIBCXX) endif() file(GLOB SRCS ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/*.cpp) - file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/experimental/*.cpp) - list(APPEND SRCS ${SRCSTMP}) - file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/filesystem/*.cpp) - list(APPEND SRCS ${SRCSTMP}) - file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/ryu/*.cpp) - list(APPEND SRCS ${SRCSTMP}) - - if(NOT CONFIG_CXX_LOCALIZATION) + list(APPEND SRCS ${CMAKE_CURRENT_LIST_DIR}/nuttx_string_instantiations.cpp) + + string(REGEX MATCH "[0-9]+$" CPP_STD_VER "${CONFIG_CXX_STANDARD}") + if(${CPP_STD_VER} GREATER_EQUAL 20) + file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/experimental/*.cpp) + list(APPEND SRCS ${SRCSTMP}) + file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/filesystem/*.cpp) + list(APPEND SRCS ${SRCSTMP}) + file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/ryu/*.cpp) + list(APPEND SRCS ${SRCSTMP}) + endif() + + if(${CPP_STD_VER} LESS_EQUAL 14) file( GLOB SRCSTMP + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/any.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/variant.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/optional.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/memory_resource.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/pstl/*.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/legacy_debug_handler.cpp) + list(REMOVE_ITEM SRCS ${SRCSTMP}) + endif() + + if(CONFIG_CXX_NO_LOCALIZATION) + file( + GLOB + SRCSTMP + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/fstream.cpp ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/ios.cpp ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/ios.instantiations.cpp ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/iostream.cpp ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/locale.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/ostream.cpp ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/regex.cpp - ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/strstream.cpp) + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/strstream.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/experimental/chrono_exception.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/experimental/time_zone.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/experimental/tzdb.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/experimental/tzdb_list.cpp) list(REMOVE_ITEM SRCS ${SRCSTMP}) endif() - set(FLAGS -Wno-attributes -Wno-deprecated-declarations -Wno-shadow - -Wno-sign-compare -Wno-cpp) + if(NOT CONFIG_TRICORE_TOOLCHAIN_TASKING) + set(FLAGS -Wno-attributes -Wno-deprecated-declarations -Wno-shadow + -Wno-sign-compare -Wno-cpp) + endif() if(GCCVER GREATER_EQUAL 12) list(APPEND FLAGS -Wno-maybe-uninitialized -Wno-alloc-size-larger-than) @@ -123,4 +157,190 @@ if(CONFIG_LIBCXX) target_compile_options(libcxx PRIVATE ${FLAGS}) target_include_directories(libcxx BEFORE PRIVATE ${CMAKE_CURRENT_LIST_DIR}/libcxx/src) + + if(CONFIG_LIBCXX_TEST) + list( + APPEND + FLAGS + -Wno-array-bounds + -Wno-permissive + -Wno-unused-variable + -Wno-unused-but-set-variable + -Wno-psabi + -Wno-unused-local-typedefs + -Wno-unused-result + -Wno-unused-function + -Wno-undef + -Wno-return-type + -Wno-self-move + -Wno-class-memaccess + -Wno-tautological-compare + -Wno-narrowing + -Wno-use-after-free + -Wno-invalid-memory-model + -Wno-mismatched-new-delete) + add_compile_options(-UNDEBUG) + add_compile_definitions( + DISABLE_NEW_COUNT + _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE + _LIBCPP_ENABLE_DEBUG_MODE + _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS + _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR + _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS + _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS + _LIBCPP_DISABLE_DEPRECATION_WARNINGS) + + set(i 0) + set(TEST_DIR "${CMAKE_CURRENT_LIST_DIR}/libcxx/test") + file(GLOB_RECURSE TESTS "${TEST_DIR}/*.pass.cpp") + file( + GLOB + UNSUPPORTED_TESTS + # error: ‘_wremove’ was not declared in this scope + ${TEST_DIR}/libcxx/input.output/file.streams/fstreams/ifstream.members/open_wchar_pointer.pass.cpp + ${TEST_DIR}/libcxx/input.output/file.streams/fstreams/ofstream.members/open_wchar_pointer.pass.cpp + ${TEST_DIR}/libcxx/input.output/file.streams/fstreams/ofstream.cons/wchar_pointer.pass.cpp + ${TEST_DIR}/libcxx/input.output/file.streams/fstreams/fstream.members/open_wchar_pointer.pass.cpp + ${TEST_DIR}/libcxx/input.output/file.streams/fstreams/fstream.cons/wchar_pointer.pass.cpp + # error: ‘x’ in ‘struct Foo’ does not name a type + ${TEST_DIR}/libcxx/selftest/compile.pass.cpp/compile-error.compile.pass.cpp + ${TEST_DIR}/libcxx/selftest/pass.cpp/compile-error.pass.cpp + ${TEST_DIR}/libcxx/selftest/link.pass.cpp/compile-error.link.pass.cpp + # error: ‘__sanitizer_verify_contiguous_container’ was not declared in + # this scope + ${TEST_DIR}/libcxx/containers/sequences/vector/asan.pass.cpp + # error: attributes are not allowed on a function-definition + ${TEST_DIR}/libcxx/thread/thread.mutex/thread_safety_requires_capability.pass.cpp + # fatal error: Block.h: No such file or directory + ${TEST_DIR}/libcxx/utilities/function.objects/func.blocks.pass.cpp + # link error + ${TEST_DIR}/libcxx/selftest/compile.pass.cpp/link-error.compile.pass.cpp + ${TEST_DIR}/libcxx/selftest/link.pass.cpp/link-error.link.pass.cpp + ${TEST_DIR}/libcxx/selftest/pass.cpp/link-error.pass.cpp + # std::views::join + ${TEST_DIR}/std/ranges/range.adaptors/range.join.view/adaptor.pass.cpp + ${TEST_DIR}/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp + ${TEST_DIR}/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp + ${TEST_DIR}/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp + # no build __partition_chunks + ${TEST_DIR}/libcxx/algorithms/pstl.libdispatch.chunk_partitions.pass.cpp + # REQUIRES: c++98 || c++03 || c++11 || c++14 + ${TEST_DIR}/std/containers/associative/multimap/multimap.value_compare/types.pass.cpp + ${TEST_DIR}/std/containers/associative/map/map.value_compare/types.pass.cpp + # std::result_of + ${TEST_DIR}/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp + ${TEST_DIR}/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp + ${TEST_DIR}/std/utilities/function.objects/func.invoke/invoke.pass.cpp + ${TEST_DIR}/std/utilities/function.objects/func.invoke/invoke_constexpr.pass.cpp + # WINT_MIN undef + ${TEST_DIR}/std/language.support/cstdint/cstdint.syn/cstdint.pass.cpp + ${TEST_DIR}/std/input.output/file.streams/c.files/cinttypes.pass.cpp + # static assertion failed + ${TEST_DIR}/std/language.support/support.runtime/cstdlib.pass.cpp + # error: static assertion failed: Types differ unexpectedly + ${TEST_DIR}/std/strings/c.strings/cstring.pass.cpp + ${TEST_DIR}/std/strings/c.strings/cwchar.pass.cpp + # error: ‘is_literal_type_v’ is not a member of ‘std’ + ${TEST_DIR}/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.pass.cpp + ${TEST_DIR}/libcxx/containers/sequences/vector/asan.pass.cpp + # error: static assertion failed + ${TEST_DIR}/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp + # unsport c++20 + ${TEST_DIR}/std/utilities/memory/default.allocator/allocator_types.void.compile.pass.cpp + ${TEST_DIR}/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp + ${TEST_DIR}/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/auto_ptr_Y.pass.cpp + ${TEST_DIR}/std/utilities/utility/pairs/pairs.pair/assign_pair_cxx03.pass.cpp + ${TEST_DIR}/std/utilities/function.objects/func.require/binary_function.pass.cpp + ${TEST_DIR}/std/utilities/function.objects/func.require/unary_function.pass.cpp + ${TEST_DIR}/std/utilities/function.objects/refwrap/weak_result.pass.cpp + ${TEST_DIR}/std/utilities/function.objects/refwrap/binder_typedefs.compile.pass.cpp + ${TEST_DIR}/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array11.pass.cpp + ${TEST_DIR}/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete11.pass.cpp + # arm build error + ${TEST_DIR}/std/numerics/cfenv/cfenv.syn/cfenv.pass.cpp + ${TEST_DIR}/std/utilities/format/format.formatter/format.formatter.spec/formatter.floating_point.pass.cpp + ${TEST_DIR}/std/localization/locales/locale.convenience/conversions/conversions.buffer/seekoff.pass.cpp + ) + + file( + GLOB_RECURSE + SKIP_TESTS + ${TEST_DIR}/libcxx/containers/views/mdspan/*.pass.cpp + ${TEST_DIR}/libcxx/input.output/iostream.format/print.fun/*.pass.cpp + ${TEST_DIR}/libcxx/ranges/range.factories/range.repeat.view/*.pass.cpp + ${TEST_DIR}/libcxx/utilities/expected/*.pass.cpp + # skip deprecated test + ${TEST_DIR}/libcxx/depr/*.pass.cpp + ${TEST_DIR}/std/depr/*.pass.cpp + ${TEST_DIR}/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/*.pass.cpp + # arm atomic undef + ${TEST_DIR}/std/atomics/atomics.types.operations/atomics.types.operations.req/*.pass.cpp + ${TEST_DIR}/std/atomics/atomics.types.operations/atomics.types.operations.wait/*.pass.cpp + ) + list(REMOVE_ITEM TESTS ${UNSUPPORTED_TESTS} ${SKIP_TESTS}) + foreach(TEST ${TESTS}) + if(EXISTS ${TEST}) + set(GREP_PATTERNS + "UNSUPPORTED: c++03, c++11, c++14, c++17, c++20" + "TEST_LIBCPP_ASSERT_FAILURE" + "static_assert(test" + "UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME" + "UNSUPPORTED: gcc" + "include " + "std::ranges::join_view" + "std::binary_function" + "std::unary_function" + "std::binary_negate" + "std::not1" + "std::not2" + "std::unary_negate" + "std::raw_storage_iterator" + "void operator delete" + "filesystem_test_helper.h" + "asan_testing.h") + + set(SKIP_TEST FALSE) + + foreach(PATTERN IN LISTS GREP_PATTERNS) + execute_process(COMMAND grep -q "${PATTERN}" ${TEST} + RESULT_VARIABLE grep_result) + + if(grep_result EQUAL 0) + set(SKIP_TEST TRUE) + break() + endif() + endforeach() + + if(SKIP_TEST) + continue() + endif() + + execute_process(COMMAND grep -q "int main" ${TEST} + RESULT_VARIABLE grep_result) + if(NOT grep_result EQUAL 0) + continue() + endif() + + get_filename_component(TEST_NAME ${TEST} NAME_WE) + foreach(CHARACTER "+" "-" "=" "[]") + string(REPLACE "${CHARACTER}" "_" TEST_NAME "${TEST_NAME}") + endforeach() + + nuttx_add_application( + NAME + ${TEST_NAME}_${i} + SRCS + ${TEST} + STACKSIZE + 102400 + COMPILE_FLAGS + ${FLAGS}) + set_source_files_properties( + ${TEST_DIR}/libcxx/containers/sequences/vector/exception_safety_exceptions_disabled.pass.cpp + PROPERTIES COMPILE_FLAGS -fno-exceptions) + math(EXPR i "${i}+1") + endif() + endforeach() + endif() + endif() diff --git a/libs/libxx/libcxx/Make.defs b/libs/libxx/libcxx/Make.defs index e5cc01af997b0..19fa8dae78f43 100644 --- a/libs/libxx/libcxx/Make.defs +++ b/libs/libxx/libcxx/Make.defs @@ -32,11 +32,12 @@ libcxx/libcxx: libcxx-$(LIBCXX_VERSION).src.tar.xz --exclude libcxx-$(LIBCXX_VERSION).src/test/std/pstl $(Q) mv libcxx-$(LIBCXX_VERSION).src $@ $(Q) patch -p0 < libcxx/0001_fix_stdatomic_h_miss_typedef.patch -d libcxx - $(Q) patch -p2 < libcxx/mbstate_t.patch -d libcxx $(Q) patch -p0 < libcxx/0001-libcxx-remove-mach-time-h.patch -d libcxx $(Q) patch -p0 < libcxx/0001-libcxx-fix-ld-errors.patch -d libcxx $(Q) patch -p0 < libcxx/0001-Fix-build-error-about-__GLIBC__.patch -d libcxx - $(Q) patch -p0 < libcxx/0001-libc-Fix-failures-with-GCC-14-92663.patch -d libcxx + $(Q) patch -p0 < libcxx/0002-libcxx-decay-and-tzdb-fixes.patch -d libcxx + $(Q) patch -p0 < libcxx/mbstate_t.patch -d libcxx + $(Q) cp $(CURDIR)/__assertion_handler libcxx/libcxx/include/__assertion_handler endif @@ -72,16 +73,36 @@ ifeq ($(shell expr "$(GCCVER)" \>= 12), 1) endif CPPSRCS += $(wildcard libcxx/libcxx/src/*.cpp) -CPPSRCS += $(wildcard libcxx/libcxx/src/experimental/*.cpp) -CPPSRCS += $(wildcard libcxx/libcxx/src/filesystem/*.cpp) -CPPSRCS += $(wildcard libcxx/libcxx/src/ryu/*.cpp) +CPPSRCS += libcxx/nuttx_string_instantiations.cpp +CPP_STD_VER := $(shell echo $(CONFIG_CXX_STANDARD) | sed -E 's/.*\+\+([0-9]+)$$/\1/') +ifeq ($(shell [ $(CPP_STD_VER) -ge 20 ] && echo true),true) + CPPSRCS += $(wildcard libcxx/libcxx/src/experimental/*.cpp) + CPPSRCS += $(wildcard libcxx/libcxx/src/filesystem/*.cpp) + CPPSRCS += $(wildcard libcxx/libcxx/src/ryu/*.cpp) +endif + +ifeq ($(shell [ $(CPP_STD_VER) -le 14 ] && echo true),true) + EXCLUDE_CPP := libcxx/libcxx/src/any.cpp + EXCLUDE_CPP += libcxx/libcxx/src/variant.cpp + EXCLUDE_CPP += libcxx/libcxx/src/optional.cpp + EXCLUDE_CPP += libcxx/libcxx/src/memory_resource.cpp + EXCLUDE_CPP += libcxx/libcxx/src/legacy_debug_handler.cpp + EXCLUDE_CPP += $(wildcard libcxx/libcxx/src/pstl/*.cpp) + CPPSRCS := $(filter-out $(EXCLUDE_FILES), $(CPPSRCS)) +endif -ifeq ($(CONFIG_CXX_LOCALIZATION),) +ifeq ($(CONFIG_CXX_NO_LOCALIZATION),y) LOCALE_CPPSRCS := libcxx/libcxx/src/ios.cpp LOCALE_CPPSRCS += libcxx/libcxx/src/ios.instantiations.cpp LOCALE_CPPSRCS += libcxx/libcxx/src/iostream.cpp LOCALE_CPPSRCS += libcxx/libcxx/src/locale.cpp LOCALE_CPPSRCS += libcxx/libcxx/src/regex.cpp LOCALE_CPPSRCS += libcxx/libcxx/src/strstream.cpp + LOCALE_CPPSRCS += libcxx/libcxx/src/fstream.cpp + LOCALE_CPPSRCS += libcxx/libcxx/src/ostream.cpp + LOCALE_CPPSRCS += libcxx/libcxx/src/experimental/chrono_exception.cpp + LOCALE_CPPSRCS += libcxx/libcxx/src/experimental/time_zone.cpp + LOCALE_CPPSRCS += libcxx/libcxx/src/experimental/tzdb.cpp + LOCALE_CPPSRCS += libcxx/libcxx/src/experimental/tzdb_list.cpp CPPSRCS := $(filter-out $(LOCALE_CPPSRCS), $(CPPSRCS)) endif diff --git a/libs/libxx/libcxx/mbstate_t.patch b/libs/libxx/libcxx/mbstate_t.patch index 1aee59bde04de..1ad88535bf20e 100644 --- a/libs/libxx/libcxx/mbstate_t.patch +++ b/libs/libxx/libcxx/mbstate_t.patch @@ -1,17 +1,11 @@ ---- libs/libxx/libcxx/include/__mbstate_t.h 2023-11-28 09:52:28.000000000 +0100 -+++ libs/libxx/libcxx/include/__mbstate_t.h 2023-12-05 16:14:46.523689408 +0100 -@@ -39,12 +39,12 @@ - # define __NEED_mbstate_t - # include - # undef __NEED_mbstate_t -+#elif !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) && __has_include_next() -+# include_next // fall back to the C standard provider of mbstate_t - #elif __has_include() - # include // works on most Unixes - #elif __has_include() - # include // works on Darwin --#elif !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) && __has_include_next() --# include_next // fall back to the C standard provider of mbstate_t +--- libcxx/include/__mbstate_t.h ++++ libcxx/include/__mbstate_t.h +@@ -45,6 +45,8 @@ + # include // works on Darwin + #elif !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) && __has_include_next() + # include_next // fall back to the C standard provider of mbstate_t ++#elif defined(__NuttX__) && __has_include_next() ++# include_next // NuttX always exposes mbstate_t through #elif __has_include_next() - # include_next // is also required to make mbstate_t visible + # include_next // is also required to make mbstate_t visible #else diff --git a/libs/libxx/libcxx/nuttx_string_instantiations.cpp b/libs/libxx/libcxx/nuttx_string_instantiations.cpp new file mode 100644 index 0000000000000..0430cd49d283b --- /dev/null +++ b/libs/libxx/libcxx/nuttx_string_instantiations.cpp @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// Force emission of the std::__1::basic_string destructors for the +// character sets that NuttX enables. The upstream libc++ headers declare +// the relevant template instantiations as "extern", so without providing +// explicit definitions the linker cannot resolve references coming from +// locale-heavy translation units such as locale.cpp. + +#include + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Emit the full char specialization so all key functions (including dtors) +// are visible from libxx.a instead of remaining TU-local. +template class _LIBCPP_EXPORTED_FROM_ABI basic_string; + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +// Emit the wchar_t specialization to satisfy localization-widechar users. +template class _LIBCPP_EXPORTED_FROM_ABI basic_string; +#endif + +_LIBCPP_END_NAMESPACE_STD diff --git a/libs/libxx/libcxxabi/CMakeLists.txt b/libs/libxx/libcxxabi/CMakeLists.txt index ab747e6ee31bd..7a2ccf24e123c 100644 --- a/libs/libxx/libcxxabi/CMakeLists.txt +++ b/libs/libxx/libcxxabi/CMakeLists.txt @@ -41,7 +41,11 @@ if(CONFIG_LIBCXXABI) "" TEST_COMMAND "" - PATCH_COMMAND "" + PATCH_COMMAND + patch -p0 -d ${CMAKE_CURRENT_LIST_DIR} < + ${CMAKE_CURRENT_LIST_DIR}/0001-libcxxabi-Fix-build-warnings-generated-by-CMake-comp.patch && + patch -p0 -d ${CMAKE_CURRENT_LIST_DIR} < + ${CMAKE_CURRENT_LIST_DIR}/0002-libcxxabi-fix-compilation-errors.patch DOWNLOAD_NO_PROGRESS true TIMEOUT 30) @@ -77,22 +81,21 @@ if(CONFIG_LIBCXXABI) cxa_vector.cpp cxa_virtual.cpp) add_compile_definitions(_LIBCPP_BUILDING_LIBRARY) - if(CONFIG_LIBSUPCXX_TOOLCHAIN) - add_compile_definitions(__GLIBCXX__) - endif() + add_compile_definitions(LIBCXXABI_BAREMETAL) - if(CONFIG_LIBSUPCXX) - add_compile_definitions(__GLIBCXX__) - endif() # C++ STL files list(APPEND SRCS stdlib_exception.cpp stdlib_new_delete.cpp - stdlib_stdexcept.cpp stdlib_typeinfo.cpp) - + stdlib_stdexcept.cpp) # Internal files - list(APPEND SRCS abort_message.cpp fallback_malloc.cpp private_typeinfo.cpp) + list(APPEND SRCS abort_message.cpp fallback_malloc.cpp) if(CONFIG_CXX_EXCEPTION) - list(APPEND SRCS cxa_exception.cpp cxa_personality.cpp) + list(APPEND SRCS cxa_exception.cpp cxa_exception_storage.cpp + cxa_personality.cpp) + endif() + + if(CONFIG_CXX_RTTI) + list(APPEND SRCS private_typeinfo.cpp stdlib_typeinfo.cpp) endif() if(CONFIG_LIBCXXABI) @@ -104,9 +107,6 @@ if(CONFIG_LIBCXXABI) list(APPEND TARGET_SRCS ${src}) endforeach() - # RTTI is required for building the libcxxabi library - target_compile_options(libcxxabi PRIVATE -frtti) - if(CONFIG_SIM_UBSAN OR CONFIG_MM_UBSAN) target_compile_options(libcxxabi PRIVATE -fno-sanitize=vptr) endif() @@ -114,7 +114,7 @@ if(CONFIG_LIBCXXABI) # Fix compilation error on ARM32:libcxxabi/src/cxa_personality.cpp:594:22: # error: '_URC_FATAL_PHASE1_ERROR' was not declared in this scope 594 | # results.reason = _URC_FATAL_PHASE1_ERROR; - if(CONFIG_ARCH_ARM) + if(CONFIG_ARCH_ARM AND NOT CONFIG_ARCH_TOOLCHAIN_CLANG) target_compile_definitions(libcxxabi PRIVATE _URC_FATAL_PHASE2_ERROR=_URC_FAILURE) target_compile_definitions(libcxxabi diff --git a/libs/libxx/libcxxabi/Make.defs b/libs/libxx/libcxxabi/Make.defs index 362a7a575fce5..f50918a8836f7 100644 --- a/libs/libxx/libcxxabi/Make.defs +++ b/libs/libxx/libcxxabi/Make.defs @@ -43,7 +43,7 @@ context:: $(TOPDIR)/include/libcxxabi distclean:: $(Q) $(DIRUNLINK) $(TOPDIR)/include/libcxxabi ifeq ($(wildcard libcxxabi/libcxxabi/.git),) - $(Q) $(DELFILE) libcxxabi-$(LIBCXX_VERSION).src.tar.xz + $(Q) $(DELFILE) libcxxabi-$(LIBCXXABI_VERSION).src.tar.xz $(call DELDIR, libcxxabi/libcxxabi) endif @@ -61,28 +61,32 @@ endif endif # C++ABI files -CPPSRCS += cxa_aux_runtime.cpp cxa_default_handlers.cpp cxa_demangle.cpp cxa_exception_storage.cpp +CPPSRCS += cxa_aux_runtime.cpp cxa_default_handlers.cpp cxa_demangle.cpp CPPSRCS += cxa_guard.cpp cxa_handlers.cpp cxa_thread_atexit.cpp cxa_vector.cpp cxa_virtual.cpp # C++ STL files -CPPSRCS += stdlib_exception.cpp stdlib_new_delete.cpp stdlib_stdexcept.cpp stdlib_typeinfo.cpp +CPPSRCS += stdlib_exception.cpp stdlib_new_delete.cpp stdlib_stdexcept.cpp # Internal files -CPPSRCS += abort_message.cpp fallback_malloc.cpp private_typeinfo.cpp +CPPSRCS += abort_message.cpp fallback_malloc.cpp ifeq ($(CONFIG_CXX_EXCEPTION),y) -CPPSRCS += cxa_exception.cpp cxa_personality.cpp +CPPSRCS += cxa_exception.cpp cxa_personality.cpp cxa_exception_storage.cpp +endif + +ifeq ($(CONFIG_CXX_RTTI),y) +CPPSRCS += private_typeinfo.cpp stdlib_typeinfo.cpp endif # Fix compilation error on ARM32: # libcxxabi/src/cxa_personality.cpp:594:22: error: '_URC_FATAL_PHASE1_ERROR' was not declared in this scope # 594 | results.reason = _URC_FATAL_PHASE1_ERROR; ifeq ($(CONFIG_ARCH_ARM),y) -CXXFLAGS += -D_URC_FATAL_PHASE2_ERROR=_URC_FAILURE -D_URC_FATAL_PHASE1_ERROR=_URC_FAILURE + ifeq ($(CONFIG_ARCH_TOOLCHAIN_CLANG),) + CXXFLAGS += -D_URC_FATAL_PHASE2_ERROR=_URC_FAILURE -D_URC_FATAL_PHASE1_ERROR=_URC_FAILURE + endif endif CXXFLAGS += -DLIBCXXABI_NON_DEMANGLING_TERMINATE - -# RTTI is required for building the libcxxabi library -CXXFLAGS += -frtti +CXXFLAGS += -DLIBCXXABI_BAREMETAL DEPPATH += --dep-path libcxxabi/libcxxabi/src VPATH += libcxxabi/libcxxabi/src diff --git a/libs/libxx/libcxxabi/__config_site b/libs/libxx/libcxxabi/__config_site new file mode 100644 index 0000000000000..a1b448d265167 --- /dev/null +++ b/libs/libxx/libcxxabi/__config_site @@ -0,0 +1,14 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCXXABI___CONFIG_SITE +#define _LIBCXXABI___CONFIG_SITE + +#include + +#endif // _LIBCXXABI___CONFIG_SITE diff --git a/net/devif/ipv4_input.c b/net/devif/ipv4_input.c index 5ea71232e6b4a..7fbf8d003becd 100644 --- a/net/devif/ipv4_input.c +++ b/net/devif/ipv4_input.c @@ -94,6 +94,7 @@ #include #include #include +#include #include "arp/arp.h" #include "inet/inet.h" @@ -118,6 +119,53 @@ * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: ipv4_check_opt + * + * Description: + * Check the IP options length. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_FEATURES +static int ipv4_check_opt(FAR struct ipv4_hdr_s *ipv4) +{ + FAR uint8_t *opt = (FAR uint8_t *)(ipv4 + 1); + int optlen; + + optlen = ((ipv4->vhl & IPv4_HLMASK) << 2) - IPv4_HDRLEN; + while (optlen > 0) + { + if (opt[0] == IPOPT_END_TYPE) + { + break; + } + else if (opt[0] == IPOPT_NOOP_TYPE) + { + opt++; + optlen--; + } + else if (optlen > 1) + { + int len = opt[1]; + if (len > optlen) + { + return -EINVAL; + } + + opt += len; + optlen -= len; + } + else + { + return -EINVAL; + } + } + + return OK; +} +#endif + /**************************************************************************** * Name: ipv4_in * @@ -189,7 +237,7 @@ static int ipv4_in(FAR struct net_driver_s *dev) dev->d_len -= NET_LL_HDRLEN(dev); - if (IPv4_HDRLEN > dev->d_len) + if (((ipv4->vhl & IPv4_HLMASK) << 2) > dev->d_len) { nwarn("WARNING: Packet shorter than IPv4 header\n"); goto drop; @@ -242,6 +290,17 @@ static int ipv4_in(FAR struct net_driver_s *dev) goto drop; } +#ifdef CONFIG_DEBUG_FEATURES + if (ipv4_check_opt(ipv4) != OK) + { +#ifdef CONFIG_NET_STATISTICS + g_netstats.ipv4.drop++; +#endif + nwarn("WARNING: IP options error\n"); + goto drop; + } +#endif + #ifdef CONFIG_NET_NAT44 /* Try NAT inbound, rule matching will be performed in NAT module. */ diff --git a/net/icmpv6/icmpv6_autoconfig.c b/net/icmpv6/icmpv6_autoconfig.c index 1121807f01cd9..70a7dd09fece7 100644 --- a/net/icmpv6/icmpv6_autoconfig.c +++ b/net/icmpv6/icmpv6_autoconfig.c @@ -189,6 +189,13 @@ static int icmpv6_send_message(FAR struct net_driver_s *dev, bool advertise) struct icmpv6_router_s state; int ret; + /* Check whether the link-local address has been overwritten. */ + + if (netdev_ipv6_lladdr(dev) == NULL) + { + return -EADDRNOTAVAIL; + } + /* Initialize the state structure with the network locked. */ nxsem_init(&state.snd_sem, 0, 0); /* Doesn't really fail */ diff --git a/net/inet/ipv4_setsockopt.c b/net/inet/ipv4_setsockopt.c index cd0a6bd97f6e1..ddc60352915ec 100644 --- a/net/inet/ipv4_setsockopt.c +++ b/net/inet/ipv4_setsockopt.c @@ -267,7 +267,7 @@ int ipv4_setsockopt(FAR struct socket *psock, int option, { if (net_ipv4addr_cmp(mreq.imr_multiaddr.s_addr, INADDR_ANY)) { - conn->mreq.imr_interface.s_addr = 0; + conn->mreq.imr_address.s_addr = 0; conn->mreq.imr_ifindex = 0; ret = OK; break; @@ -299,7 +299,7 @@ int ipv4_setsockopt(FAR struct socket *psock, int option, } #endif - conn->mreq.imr_interface.s_addr = mreq.imr_multiaddr.s_addr; + conn->mreq.imr_address.s_addr = mreq.imr_multiaddr.s_addr; conn->mreq.imr_ifindex = mreq.imr_ifindex; ret = OK; break; diff --git a/net/ipfrag/ipv4_frag.c b/net/ipfrag/ipv4_frag.c index d62d09ee913c5..2c15267f45a16 100644 --- a/net/ipfrag/ipv4_frag.c +++ b/net/ipfrag/ipv4_frag.c @@ -309,7 +309,7 @@ int32_t ipv4_fragin(FAR struct net_driver_s *dev) */ ipv4_fragin_reassemble(node); - netdev_iob_replace(dev, node->outgoframe); + netdev_iob_replace_l2(dev, node->outgoframe); /* Free the memory of node */ diff --git a/net/ipfrag/ipv6_frag.c b/net/ipfrag/ipv6_frag.c index ffae571ef4864..0a86c26ce2c2b 100644 --- a/net/ipfrag/ipv6_frag.c +++ b/net/ipfrag/ipv6_frag.c @@ -515,7 +515,7 @@ int32_t ipv6_fragin(FAR struct net_driver_s *dev) */ ipv6_fragin_reassemble(node); - netdev_iob_replace(dev, node->outgoframe); + netdev_iob_replace_l2(dev, node->outgoframe); /* Free the memory of node */ diff --git a/net/neighbor/neighbor_ethernet_out.c b/net/neighbor/neighbor_ethernet_out.c index 1e753a76785da..143369c9da60a 100644 --- a/net/neighbor/neighbor_ethernet_out.c +++ b/net/neighbor/neighbor_ethernet_out.c @@ -155,7 +155,7 @@ void neighbor_ethernet_out(FAR struct net_driver_s *dev) if (neighbor_lookup(ipaddr, &laddr) < 0) { -#ifdef CONFIG_NET_ICMPv6 +#ifdef NET_ICMPv6_HAVE_STACK /* No ARP packet if this device do not support ARP */ if (IFF_IS_NOARP(dev->d_flags)) @@ -163,7 +163,7 @@ void neighbor_ethernet_out(FAR struct net_driver_s *dev) return; } - ninfo("IPv6 Neighbor solicitation for IPv6\n"); + ninfo("IPv6 Neighbor solicitation for IPv6\n"); /* The destination address was not in our Neighbor Table, so we * overwrite the IPv6 packet with an ICMPv6 Neighbor Solicitation diff --git a/net/netdev/netdev.h b/net/netdev/netdev.h index 1e3003de02d35..5f50d6dad4cd7 100644 --- a/net/netdev/netdev.h +++ b/net/netdev/netdev.h @@ -106,23 +106,6 @@ typedef int (*netdev_callback_t)(FAR struct net_driver_s *dev, bool netdev_verify(FAR struct net_driver_s *dev); -/**************************************************************************** - * Name: netdev_findbyname - * - * Description: - * Find a previously registered network device using its assigned - * network interface name - * - * Input Parameters: - * ifname The interface name of the device of interest - * - * Returned Value: - * Pointer to driver on success; null on failure - * - ****************************************************************************/ - -FAR struct net_driver_s *netdev_findbyname(FAR const char *ifname); - /**************************************************************************** * Name: netdev_foreach * @@ -241,24 +224,6 @@ FAR struct net_driver_s *netdev_findby_ripv6addr( const net_ipv6addr_t ripaddr); #endif -/**************************************************************************** - * Name: netdev_findbyindex - * - * Description: - * Find a previously registered network device by assigned interface index. - * - * Input Parameters: - * ifindex - The interface index. This is a one-based index and must be - * greater than zero. - * - * Returned Value: - * Pointer to driver on success; NULL on failure. This function will return - * NULL only if there is no device corresponding to the provided index. - * - ****************************************************************************/ - -FAR struct net_driver_s *netdev_findbyindex(int ifindex); - /**************************************************************************** * Name: netdev_nextindex * diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index 39217a0e9b48b..3b7ccb27731b0 100644 --- a/net/netdev/netdev_ioctl.c +++ b/net/netdev/netdev_ioctl.c @@ -394,11 +394,11 @@ static int netdev_bluetooth_ioctl(FAR struct socket *psock, int cmd, { FAR struct net_driver_s *dev; FAR char *ifname; - int ret = -EINVAL; + int ret = -ENOTTY; - if (arg != 0ul) + if (_BLUETOOTHIOCVALID(cmd)) { - if (_BLUETOOTHIOCVALID(cmd)) + if (arg != 0ul) { /* Get the name of the Bluetooth device to receive the IOCTL * command @@ -411,9 +411,9 @@ static int netdev_bluetooth_ioctl(FAR struct socket *psock, int cmd, } else { - /* Not a Bluetooth IOCTL command */ + /* Argument is invalid */ - return -ENOTTY; + return -EINVAL; } /* Find the device with this name */ @@ -459,9 +459,9 @@ static int netdev_iee802154_ioctl(FAR struct socket *psock, int cmd, FAR char *ifname; int ret = -ENOTTY; - if (arg != 0ul) + if (_MAC802154IOCVALID(cmd)) { - if (_MAC802154IOCVALID(cmd)) + if (arg != 0ul) { /* Get the IEEE802.15.4 MAC device to receive the radio IOCTL * command @@ -474,9 +474,9 @@ static int netdev_iee802154_ioctl(FAR struct socket *psock, int cmd, } else { - /* Not an EEE802.15.4 MAC IOCTL command */ + /* Argument is invalid */ - return -ENOTTY; + return -EINVAL; } /* Find the device with this name */ @@ -520,9 +520,9 @@ static int netdev_pktradio_ioctl(FAR struct socket *psock, int cmd, FAR char *ifname; int ret = -ENOTTY; - if (arg != 0ul) + if (_PKRADIOIOCVALID(cmd)) { - if (_PKRADIOIOCVALID(cmd)) + if (arg != 0ul) { /* Get the packet radio device to receive the radio IOCTL * command @@ -535,10 +535,9 @@ static int netdev_pktradio_ioctl(FAR struct socket *psock, int cmd, } else { - /* Not a packet radio IOCTL command */ + /* Argument is invalid */ - nwarn("WARNING: Not a packet radio IOCTL command: %d\n", cmd); - return -ENOTTY; + return -EINVAL; } /* Find the device with this name */ diff --git a/net/route/net_add_ramroute.c b/net/route/net_add_ramroute.c index e0c95943d51ae..140a21f2bbfeb 100644 --- a/net/route/net_add_ramroute.c +++ b/net/route/net_add_ramroute.c @@ -82,13 +82,13 @@ int net_addroute_ipv4(in_addr_t target, in_addr_t netmask, in_addr_t router) /* Get exclusive address to the networking data structures */ - net_lock(); + net_lockroute_ipv4(); /* Then add the new entry to the table */ ramroute_ipv4_addlast((FAR struct net_route_ipv4_entry_s *)route, &g_ipv4_routes); - net_unlock(); + net_unlockroute_ipv4(); netlink_route_notify(route, RTM_NEWROUTE, AF_INET); return OK; @@ -119,13 +119,11 @@ int net_addroute_ipv6(net_ipv6addr_t target, net_ipv6addr_t netmask, /* Get exclusive address to the networking data structures */ - net_lock(); - - /* Then add the new entry to the table */ + net_lockroute_ipv6(); ramroute_ipv6_addlast((FAR struct net_route_ipv6_entry_s *)route, &g_ipv6_routes); - net_unlock(); + net_unlockroute_ipv6(); netlink_route_notify(route, RTM_NEWROUTE, AF_INET6); return OK; diff --git a/net/route/net_alloc_ramroute.c b/net/route/net_alloc_ramroute.c index e5ec79ece31d9..2f4c62617fa00 100644 --- a/net/route/net_alloc_ramroute.c +++ b/net/route/net_alloc_ramroute.c @@ -33,6 +33,7 @@ #include #include +#include "utils/utils.h" #include "route/ramroute.h" #include "route/route.h" @@ -58,80 +59,22 @@ FAR struct net_route_ipv6_queue_s g_ipv6_routes; * Private Data ****************************************************************************/ -/* These are lists of free routing table entries */ +/* The array containing all routing table entries. */ #ifdef CONFIG_ROUTE_IPv4_RAMROUTE -static struct net_route_ipv4_queue_s g_free_ipv4routes; +NET_BUFPOOL_DECLARE(g_ipv4routes, sizeof(struct net_route_ipv4_entry_s), + CONFIG_ROUTE_MAX_IPv4_RAMROUTES, 0, 0); #endif #ifdef CONFIG_ROUTE_IPv6_RAMROUTE -static struct net_route_ipv6_queue_s g_free_ipv6routes; -#endif - -/* These are arrays of pre-allocated network routes */ - -#ifdef CONFIG_ROUTE_IPv4_RAMROUTE -static struct net_route_ipv4_entry_s - g_prealloc_ipv4routes[CONFIG_ROUTE_MAX_IPv4_RAMROUTES]; -#endif - -#ifdef CONFIG_ROUTE_IPv6_RAMROUTE -static struct net_route_ipv6_entry_s - g_prealloc_ipv6routes[CONFIG_ROUTE_MAX_IPv6_RAMROUTES]; +NET_BUFPOOL_DECLARE(g_ipv6routes, sizeof(struct net_route_ipv6_entry_s), + CONFIG_ROUTE_MAX_IPv6_RAMROUTES, 0, 0); #endif /**************************************************************************** * Public Functions ****************************************************************************/ -/**************************************************************************** - * Name: net_init_ramroute - * - * Description: - * Initialize the in-memory, RAM routing table - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions: - * Called early in initialization so that no special protection is needed. - * - ****************************************************************************/ - -void net_init_ramroute(void) -{ - int i; - - /* Initialize the routing table and the free list */ - -#ifdef CONFIG_ROUTE_IPv4_RAMROUTE - ramroute_init(&g_ipv4_routes); - ramroute_init(&g_free_ipv4routes); - - /* Add all of the pre-allocated routing table entries to a free list */ - - for (i = 0; i < CONFIG_ROUTE_MAX_IPv4_RAMROUTES; i++) - { - ramroute_ipv4_addlast(&g_prealloc_ipv4routes[i], &g_free_ipv4routes); - } -#endif - -#ifdef CONFIG_ROUTE_IPv6_RAMROUTE - ramroute_init(&g_ipv6_routes); - ramroute_init(&g_free_ipv6routes); - - /* Add all of the pre-allocated routing table entries to a free list */ - - for (i = 0; i < CONFIG_ROUTE_MAX_IPv6_RAMROUTES; i++) - { - ramroute_ipv6_addlast(&g_prealloc_ipv6routes[i], &g_free_ipv6routes); - } -#endif -} - /**************************************************************************** * Name: net_allocroute_ipv4 and net_allocroute_ipv6 * @@ -152,15 +95,11 @@ FAR struct net_route_ipv4_s *net_allocroute_ipv4(void) { FAR struct net_route_ipv4_entry_s *route; - /* Get exclusive address to the networking data structures */ - - net_lock(); - - /* Then add the remove the first entry from the table */ - - route = ramroute_ipv4_remfirst(&g_free_ipv4routes); + /* Get exclusive address to the networking data structures and + * then remove the first entry from the g_ipv4routes pool + */ - net_unlock(); + route = NET_BUFPOOL_TRYALLOC(g_ipv4routes); if (!route) { return NULL; @@ -175,15 +114,11 @@ FAR struct net_route_ipv6_s *net_allocroute_ipv6(void) { FAR struct net_route_ipv6_entry_s *route; - /* Get exclusive address to the networking data structures */ + /* Get exclusive address to the networking data structures and + * then remove the first entry from the g_ipv6routes pool + */ - net_lock(); - - /* Then add the remove the first entry from the table */ - - route = ramroute_ipv6_remfirst(&g_free_ipv6routes); - - net_unlock(); + route = NET_BUFPOOL_TRYALLOC(g_ipv6routes); if (!route) { return NULL; @@ -212,15 +147,9 @@ void net_freeroute_ipv4(FAR struct net_route_ipv4_s *route) { DEBUGASSERT(route); - /* Get exclusive address to the networking data structures */ - - net_lock(); + /* Add the new entry to the g_ipv4routes pool */ - /* Then add the new entry to the table */ - - ramroute_ipv4_addlast((FAR struct net_route_ipv4_entry_s *)route, - &g_free_ipv4routes); - net_unlock(); + NET_BUFPOOL_FREE(g_ipv4routes, (FAR struct net_route_ipv4_entry_s *)route); } #endif @@ -229,15 +158,49 @@ void net_freeroute_ipv6(FAR struct net_route_ipv6_s *route) { DEBUGASSERT(route); - /* Get exclusive address to the networking data structures */ + /* Add the new entry to the g_ipv6routes pool */ + + NET_BUFPOOL_FREE(g_ipv6routes, (FAR struct net_route_ipv6_entry_s *)route); +} +#endif + +/**************************************************************************** + * Name: net_lockroute_ipv4 and net_unlockroute_ipv4 + * + * Description: + * Lock and unlock the g_ipv4routes pool + * + ****************************************************************************/ + +#ifdef CONFIG_ROUTE_IPv4_RAMROUTE +void net_lockroute_ipv4(void) +{ + NET_BUFPOOL_LOCK(g_ipv4routes); +} + +void net_unlockroute_ipv4(void) +{ + NET_BUFPOOL_UNLOCK(g_ipv4routes); +} +#endif - net_lock(); +/**************************************************************************** + * Name: net_lockroute_ipv6 and net_unlockroute_ipv6 + * + * Description: + * Lock and unlock the g_ipv6routes pool + * + ****************************************************************************/ - /* Then add the new entry to the table */ +#ifdef CONFIG_ROUTE_IPv6_RAMROUTE +void net_lockroute_ipv6(void) +{ + NET_BUFPOOL_LOCK(g_ipv6routes); +} - ramroute_ipv6_addlast((FAR struct net_route_ipv6_entry_s *)route, - &g_free_ipv6routes); - net_unlock(); +void net_unlockroute_ipv6(void) +{ + NET_BUFPOOL_UNLOCK(g_ipv6routes); } #endif diff --git a/net/route/net_foreach_ramroute.c b/net/route/net_foreach_ramroute.c index 97b2fcfe0930c..90f5959f0a63e 100644 --- a/net/route/net_foreach_ramroute.c +++ b/net/route/net_foreach_ramroute.c @@ -68,7 +68,7 @@ int net_foreachroute_ipv4(route_handler_ipv4_t handler, FAR void *arg) /* Prevent concurrent access to the routing table */ - net_lock(); + net_lockroute_ipv4(); /* Visit each entry in the routing table */ @@ -82,9 +82,9 @@ int net_foreachroute_ipv4(route_handler_ipv4_t handler, FAR void *arg) ret = handler(&route->entry, arg); } - /* Unlock the network */ + /* Unlock the g_ipv4_routes */ - net_unlock(); + net_unlockroute_ipv4(); return ret; } #endif @@ -98,7 +98,7 @@ int net_foreachroute_ipv6(route_handler_ipv6_t handler, FAR void *arg) /* Prevent concurrent access to the routing table */ - net_lock(); + net_lockroute_ipv6(); /* Visit each entry in the routing table */ @@ -112,9 +112,9 @@ int net_foreachroute_ipv6(route_handler_ipv6_t handler, FAR void *arg) ret = handler(&route->entry, arg); } - /* Unlock the network */ + /* Unlock the g_ipv6_routes */ - net_unlock(); + net_unlockroute_ipv6(); return ret; } #endif diff --git a/net/route/net_initroute.c b/net/route/net_initroute.c index aedaa758bacee..ac4a1fa50d943 100644 --- a/net/route/net_initroute.c +++ b/net/route/net_initroute.c @@ -52,10 +52,6 @@ void net_init_route(void) { -#if defined(CONFIG_ROUTE_IPv4_RAMROUTE) || defined(CONFIG_ROUTE_IPv6_RAMROUTE) - net_init_ramroute(); -#endif - #if defined(CONFIG_ROUTE_IPv4_CACHEROUTE) || defined(CONFIG_ROUTE_IPv6_CACHEROUTE) net_init_cacheroute(); #endif diff --git a/net/route/ramroute.h b/net/route/ramroute.h index 74aff0c0c67be..b3c9cf0f6af48 100644 --- a/net/route/ramroute.h +++ b/net/route/ramroute.h @@ -119,25 +119,6 @@ extern struct net_route_ipv6_queue_s g_ipv6_routes; * Public Function Prototypes ****************************************************************************/ -/**************************************************************************** - * Name: net_init_ramroute - * - * Description: - * Initialize the in-memory, RAM routing table - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions: - * Called early in initialization so that no special protection is needed. - * - ****************************************************************************/ - -void net_init_ramroute(void); - /**************************************************************************** * Name: net_allocroute_ipv4 and net_allocroute_ipv6 * @@ -183,6 +164,32 @@ void net_freeroute_ipv4(FAR struct net_route_ipv4_s *route); void net_freeroute_ipv6(FAR struct net_route_ipv6_s *route); #endif +/**************************************************************************** + * Name: net_lockroute_ipv4 and net_unlockroute_ipv4 + * + * Description: + * Lock and unlock the g_ipv4routes pool + * + ****************************************************************************/ + +#ifdef CONFIG_ROUTE_IPv4_RAMROUTE +void net_lockroute_ipv4(void); +void net_unlockroute_ipv4(void); +#endif + +/**************************************************************************** + * Name: net_lockroute_ipv6 and net_unlockroute_ipv6 + * + * Description: + * Lock and unlock the g_ipv6routes pool + * + ****************************************************************************/ + +#ifdef CONFIG_ROUTE_IPv6_RAMROUTE +void net_lockroute_ipv6(void); +void net_unlockroute_ipv6(void); +#endif + /**************************************************************************** * Name: (various low-level list operations) * diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c index 74c8d53651d1b..54cbd2e73d851 100644 --- a/net/tcp/tcp_input.c +++ b/net/tcp/tcp_input.c @@ -1600,33 +1600,7 @@ static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain, } #else /* CONFIG_NET_TCPURGDATA */ - /* Check the URG flag. If this is set, We must gracefully ignore - * and discard the urgent data. - */ - - if ((tcp->flags & TCP_URG) != 0) - { - uint16_t urglen = (tcp->urgp[0] << 8) | tcp->urgp[1]; - if (urglen > dev->d_len) - { - /* There is more urgent data in the next segment to come. */ - - urglen = dev->d_len; - } - - /* The d_len field contains the length of the incoming data; - * The d_appdata field points to the any "normal" data that - * may follow the urgent data. - * - * NOTE: If the urgent data continues in the next packet, then - * d_len will be zero and d_appdata will point past the end of - * the payload (which is OK). - */ - - net_incr32(conn->rcvseq, urglen); - dev->d_len -= urglen; - dev->d_appdata += urglen; - } + /* Urgent data needs to be treated as normal data */ #endif /* CONFIG_NET_TCPURGDATA */ #ifdef CONFIG_NET_TCP_KEEPALIVE diff --git a/net/tcp/tcp_timer.c b/net/tcp/tcp_timer.c index 368a3379b2076..33c70aff0f5be 100644 --- a/net/tcp/tcp_timer.c +++ b/net/tcp/tcp_timer.c @@ -695,7 +695,15 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn) devif_conn_event(conn->dev, TCP_ABORT, conn->sconn.list); - tcp_stop_monitor(conn, TCP_ABORT); + + /* We also send a reset packet to the remote host. */ + + tcp_send(dev, conn, TCP_RST | TCP_ACK, hdrlen); + + /* Stop the timer work */ + + conn->keeptimer = 0; + conn->timer = 0; } else { diff --git a/sched/Kconfig b/sched/Kconfig index 5339e2b75077a..7c3d8092533df 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -1671,6 +1671,15 @@ config SIG_SIGPOLL_ACTION Backward compatible behavior would require that the application use sigaction() to ignore SIGPOLL. +config SIG_SIGURG_ACTION + bool "SIGURG" + default n + ---help--- + Enable the default action for SIGURG (ignore the signal) + Make sure that your applications are expecting this POSIX behavior. + Backward compatible behavior would require that the application use + sigaction() to ignore SIGURG. + endif # SIG_DEFAULT endmenu # Signal Configuration @@ -2008,6 +2017,5 @@ config HRTIMER bool "High resolution timer support" depends on SYSTEM_TIME64 default n - depends on SYSTEM_TIME64 ---help--- Enable to support high resolution timer diff --git a/sched/hrtimer/hrtimer.h b/sched/hrtimer/hrtimer.h index 99858415d2948..92e932ac947c3 100644 --- a/sched/hrtimer/hrtimer.h +++ b/sched/hrtimer/hrtimer.h @@ -198,10 +198,7 @@ RB_PROTOTYPE(hrtimer_tree_s, hrtimer_node_s, entry, hrtimer_compare); static inline_function bool hrtimer_is_armed(FAR hrtimer_t *hrtimer) { - /* RB-tree root has NULL parent, so root must be checked explicitly */ - - return RB_PARENT(&hrtimer->node, entry) != NULL || - RB_ROOT(&g_hrtimer_tree) == &hrtimer->node; + return hrtimer->func != NULL; } /**************************************************************************** @@ -217,7 +214,7 @@ static inline_function void hrtimer_remove(FAR hrtimer_t *hrtimer) /* Explicitly clear parent to mark the timer as unarmed */ - RB_PARENT(&hrtimer->node, entry) = NULL; + hrtimer->func = NULL; } /**************************************************************************** diff --git a/sched/hrtimer/hrtimer_process.c b/sched/hrtimer/hrtimer_process.c index f94f699aa9edd..c7a40fd25111b 100644 --- a/sched/hrtimer/hrtimer_process.c +++ b/sched/hrtimer/hrtimer_process.c @@ -139,6 +139,7 @@ void hrtimer_process(uint64_t now) DEBUGASSERT(hrtimer->expired > period); + hrtimer->func = func; hrtimer_insert(hrtimer); } diff --git a/sched/hrtimer/hrtimer_start.c b/sched/hrtimer/hrtimer_start.c index caba6fc50f8dc..0f24e0952c9da 100644 --- a/sched/hrtimer/hrtimer_start.c +++ b/sched/hrtimer/hrtimer_start.c @@ -44,6 +44,7 @@ * * Input Parameters: * hrtimer - Pointer to the hrtimer structure. + * func - Expiration callback function. * expired - Expiration time in nanoseconds. Interpretation * depends on mode. * mode - Timer mode (HRTIMER_MODE_ABS or HRTIMER_MODE_REL). @@ -59,7 +60,7 @@ * nanoseconds from the current time. ****************************************************************************/ -int hrtimer_start(FAR hrtimer_t *hrtimer, +int hrtimer_start(FAR hrtimer_t *hrtimer, hrtimer_entry_t func, uint64_t expired, enum hrtimer_mode_e mode) { @@ -77,6 +78,8 @@ int hrtimer_start(FAR hrtimer_t *hrtimer, hrtimer_remove(hrtimer); } + hrtimer->func = func; + /* Compute absolute expiration time */ if (mode == HRTIMER_MODE_ABS) diff --git a/sched/misc/assert.c b/sched/misc/assert.c index 0c89d62a7dfe6..a5cd333d697e1 100644 --- a/sched/misc/assert.c +++ b/sched/misc/assert.c @@ -611,7 +611,8 @@ static void dump_deadlock(void) static noreturn_function int pause_cpu_handler(FAR void *arg) { - memcpy(g_last_regs[this_cpu()], running_regs(), sizeof(g_last_regs[0])); + up_regs_memcpy(g_last_regs[this_cpu()], running_regs(), + sizeof(g_last_regs[0])); g_cpu_paused[this_cpu()] = true; up_flush_dcache_all(); while (1); @@ -877,7 +878,8 @@ void _assert(FAR const char *filename, int linenum, } else { - memcpy(g_last_regs[this_cpu()], regs, sizeof(g_last_regs[0])); + up_regs_memcpy(g_last_regs[this_cpu()], regs, sizeof(g_last_regs[0])); + regs = g_last_regs[this_cpu()]; } notifier_data.rtcb = rtcb; diff --git a/sched/sched/sched_get_tls.c b/sched/sched/sched_get_tls.c index db178095d7246..4fb5ce7142864 100644 --- a/sched/sched/sched_get_tls.c +++ b/sched/sched/sched_get_tls.c @@ -75,6 +75,5 @@ FAR char **nxsched_get_stackargs(FAR struct tcb_s *tcb) { /* The args data follows the TLS data */ - return (FAR char**)((FAR char *)tcb->stack_alloc_ptr + - nxsched_get_tls(tcb)->tl_size); + return nxsched_get_tls(tcb)->tl_argv; } diff --git a/sched/sched/sched_processtimer.c b/sched/sched/sched_processtimer.c index 6dbf2d155095f..46d2bce0b2f3b 100644 --- a/sched/sched/sched_processtimer.c +++ b/sched/sched/sched_processtimer.c @@ -49,6 +49,7 @@ * Private Functions ****************************************************************************/ +#ifndef CONFIG_SCHED_TICKLESS /**************************************************************************** * Name: nxsched_cpu_scheduler * @@ -144,18 +145,6 @@ static inline void nxsched_process_scheduler(void) # define nxsched_process_scheduler() #endif -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * System Timer Hooks - * - * These are standard interfaces that are exported by the OS - * for use by the architecture specific logic - * - ****************************************************************************/ - /**************************************************************************** * Name: nxsched_process_timer * @@ -165,6 +154,8 @@ static inline void nxsched_process_scheduler(void) * architecture specific code, but must call the following OS * function periodically -- the calling interval must be * USEC_PER_TICK + * These are standard interfaces that are exported by the OS + * for use by the architecture specific logic * * Input Parameters: * None @@ -204,3 +195,4 @@ void nxsched_process_timer(void) board_timerhook(); #endif } +#endif diff --git a/sched/sched/sched_timerexpiration.c b/sched/sched/sched_timerexpiration.c index 1c1785e6d4b8c..cf9f0ff050252 100644 --- a/sched/sched/sched_timerexpiration.c +++ b/sched/sched/sched_timerexpiration.c @@ -92,7 +92,7 @@ static clock_t nxsched_timer_start(clock_t ticks, clock_t interval); static clock_t g_timer_tick; /* This is the duration of the currently active timer or, when - * nxsched_timer_expiration() is called, the duration of interval timer + * nxsched_process_timer() is called, the duration of interval timer * that just expired. The value zero means that no timer was active. */ @@ -373,7 +373,7 @@ static clock_t nxsched_timer_start(clock_t ticks, clock_t interval) ****************************************************************************/ /**************************************************************************** - * Name: nxsched_timer_expiration + * Name: nxsched_process_timer * * Description: * if CONFIG_SCHED_TICKLESS is defined, then this function is provided by @@ -388,7 +388,7 @@ static clock_t nxsched_timer_start(clock_t ticks, clock_t interval) * ****************************************************************************/ -void nxsched_timer_expiration(void) +void nxsched_process_timer(void) { irqstate_t flags; clock_t ticks; diff --git a/sched/signal/sig_default.c b/sched/signal/sig_default.c index 957ce3b2dca22..1d02736232440 100644 --- a/sched/signal/sig_default.c +++ b/sched/signal/sig_default.c @@ -149,6 +149,9 @@ static const struct nxsig_defaction_s g_defactions[] = #ifdef CONFIG_SIG_SIGPOLL_ACTION { SIGPOLL, 0, nxsig_abnormal_termination }, #endif +#ifdef CONFIG_SIG_SIGURG_ACTION + { SIGURG, 0, nxsig_null_action }, +#endif }; #define NACTIONS (sizeof(g_defactions) / sizeof(struct nxsig_defaction_s)) diff --git a/sched/task/task_argvstr.c b/sched/task/task_argvstr.c index a835835ef2647..d4854b7829868 100644 --- a/sched/task/task_argvstr.c +++ b/sched/task/task_argvstr.c @@ -89,11 +89,14 @@ size_t nxtask_argvstr(FAR struct tcb_s *tcb, FAR char *args, size_t size) else #endif { - FAR char **argv = nxsched_get_stackargs(tcb) + 1; + FAR char **argv = nxsched_get_stackargs(tcb); - while (*argv != NULL && n < size) + if (argv++) { - n += snprintf(args + n, size - n, " %s", *argv++); + while (*argv != NULL && n < size) + { + n += snprintf(args + n, size - n, " %s", *argv++); + } } } diff --git a/sched/task/task_setup.c b/sched/task/task_setup.c index c226bdbc27db1..6748392401d13 100644 --- a/sched/task/task_setup.c +++ b/sched/task/task_setup.c @@ -630,6 +630,9 @@ int nxtask_setup_stackargs(FAR struct tcb_s *tcb, stackargv[argc + 1] = NULL; + /* Initialize argv last to avoid accessing the partial initialized fields */ + + nxsched_get_tls(tcb)->tl_argv = stackargv; return OK; } diff --git a/sched/tls/tls_dupinfo.c b/sched/tls/tls_dupinfo.c index de7a4022c090b..0987e9d61703e 100644 --- a/sched/tls/tls_dupinfo.c +++ b/sched/tls/tls_dupinfo.c @@ -70,5 +70,12 @@ int tls_dup_info(FAR struct tcb_s *dst, FAR struct tcb_s *src) /* Attach per-task info in group to TLS */ info->tl_task = dst->group->tg_info; + + /* Initialize the starting address of argv to NULL to prevent + * it from being misused. + */ + + info->tl_argv = NULL; + return OK; } diff --git a/sched/tls/tls_initinfo.c b/sched/tls/tls_initinfo.c index bf7227fd1a519..c38704a19cf93 100644 --- a/sched/tls/tls_initinfo.c +++ b/sched/tls/tls_initinfo.c @@ -78,5 +78,11 @@ int tls_init_info(FAR struct tcb_s *tcb) info->tl_tid = tcb->pid; + /* Initialize the starting address of argv to NULL to prevent + * it from being misused. + */ + + info->tl_argv = NULL; + return OK; } diff --git a/tools/checkkconfig.py b/tools/checkkconfig.py new file mode 100755 index 0000000000000..74c5c0415c42c --- /dev/null +++ b/tools/checkkconfig.py @@ -0,0 +1,307 @@ +#!/usr/bin/env python3 +# tools/checkkconfig.py +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you 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. +# + +# +# [checkkconfig.py] is a tool that simulates the effects of modifying a CONFIG item, +# Can be used to check whether my config changes are what I expected. +# +# usage: checkkconfig.py [-h] -f FILE (-s CONFIG VALUE | -d DIFF) +# +# optional arguments: +# -h, --help show this help message and exit +# -f FILE, --file FILE Path to the input defconfig file +# -s CONFIG_XXX VALUE, --single CONFIG VALUE +# Analyze single change: CONFIG_NAME y/m/n +# -d DIFF, --diff DIFF Analyze changes from diff file +# +# example: ./tools/checkkconfig.py -f defconfig -s ELF n +# +# outputs: +# Change report for ELF=n +# Config Option Old New +# ---------------------------------------------------------------------- +# BINFMT_LOADABLE y n +# ELF y n +# ELF_STACKSIZE 8192 +# LIBC_ARCH_ELF y n +# LIBC_MODLIB y n +# MODLIB_ALIGN_LOG2 2 +# MODLIB_BUFFERINCR 32 +# MODLIB_BUFFERSIZE 32 +# MODLIB_MAXDEPEND 2 +# MODLIB_RELOCATION_BUFFERCOUNT 256 +# MODLIB_SYMBOL_CACHECOUNT 256 +# +# As we can see, we can clearly know that +# if I turn off ELF in defconfig at this time, +# it will bring about the following configuration linkage changes +# +# It can also parse diff files, which can be used to check the changes of multiple configs. +# diff file example: +# diff --git a/boards/demo/configs/nsh/defconfig b/boards/demo/configs/nsh/defconfig +# index cf7d07c..5de20d4 100644 +# --- a/boards/demo/configs/nsh/defconfig +# +++ b/boards/demo/configs/nsh/defconfig +# @@ -51,7 +51,6 @@ CONFIG_ARMV7A_STRING_FUNCTION=y +# CONFIG_ARM_PSCI=y +# CONFIG_ARM_SEMIHOSTING_HOSTFS=y +# CONFIG_ARM_THUMB=y +# -CONFIG_AUDIO=y +# CONFIG_BCH=y +# CONFIG_BINFMT_ELF_EXECUTABLE=y +# CONFIG_BLUETOOTH=y +# @@ -104,7 +103,6 @@ CONFIG_DRIVERS_VIRTIO_SERIAL=y +# CONFIG_DRIVERS_VIRTIO_SOUND=y +# CONFIG_DRIVERS_WIFI_SIM=y +# CONFIG_DRIVERS_WIRELESS=y +# -CONFIG_ELF=y +# CONFIG_ETC_ROMFS=y +# CONFIG_EVENT_FD=y +# CONFIG_EXAMPLES_FB=y +# +# example: ./tools/checkkconfig.py -f defconfig -d changes.diff +# +# outputs: +# Change report for diff: changes.diff +# Config Option Old New +# ---------------------------------------------------------------------- +# AUDIO y n +# AUDIO_BUFFER_NUMBYTES 8192 +# AUDIO_EXCLUDE_EQUALIZER y n +# AUDIO_EXCLUDE_REWIND y n +# AUDIO_FORMAT_AMR y n +# AUDIO_FORMAT_MP3 y n +# AUDIO_FORMAT_OPUS y n +# AUDIO_FORMAT_PCM y n +# AUDIO_FORMAT_SBC y n +# AUDIO_NUM_BUFFERS 2 +# BINFMT_LOADABLE y n +# ELF y n +# ELF_STACKSIZE 8192 +# LIBC_ARCH_ELF y n +# LIBC_MODLIB y n +# MODLIB_ALIGN_LOG2 2 +# MODLIB_BUFFERINCR 32 +# MODLIB_BUFFERSIZE 32 +# MODLIB_MAXDEPEND 2 +# MODLIB_RELOCATION_BUFFERCOUNT 256 +# MODLIB_SYMBOL_CACHECOUNT 256 +# NXPLAYER_COMMAND_LINE y n +# NXPLAYER_DEFAULT_MEDIADIR /music +# NXPLAYER_FMT_FROM_EXT y n +# NXPLAYER_INCLUDE_DEVICE_SEARCH y n +# NXPLAYER_INCLUDE_HELP y n +# NXPLAYER_INCLUDE_MEDIADIR y n +# NXPLAYER_INCLUDE_PREFERRED_DEVICE y n +# NXPLAYER_MAINTHREAD_STACKSIZE 8192 +# NXPLAYER_PLAYTHREAD_STACKSIZE 8192 +# NXRECORDER_COMMAND_LINE y n +# NXRECORDER_FMT_FROM_EXT y n +# NXRECORDER_INCLUDE_HELP y n +# NXRECORDER_MAINTHREAD_STACKSIZE 8192 +# NXRECORDER_RECORDTHREAD_STACKSIZE 8192 +# SYSTEM_NXPLAYER y n +# SYSTEM_NXRECORDER y n +# +# +# RECAUTION: +# Because NuttX apps Kconfig of menu is generated by build system, +# and arch/board bridge Kconfig is symlink to real arch board dir. +# So it is best to check the defconfig that has been configured. +# If the environment does not generate Kconfig menu, etc. +# the tool will execute `configure.sh` and distclean at the end. +# + +import argparse +import os +import re +import subprocess +import sys +from pathlib import Path + +try: + from kconfiglib import Kconfig +except ImportError: + print( + "ERROR: checkkconfig tool depends on kconfiglib for parse Kconfig tree.\nplease install it.\npip install kconfiglib", + file=sys.stderr, + ) + sys.exit(1) + +TOPDIR = Path(__file__).resolve().parent.parent +DPATH = Path("defconfig") +NEED_RESET = False + + +# Prepare environment for Kconfig +def prepare_env(): + global NEED_RESET + # check if we are in the configured Kconfig environment + full_config_file = TOPDIR / Path(".config") + if not full_config_file.exists(): + print("apps preconfig do not generate yet \nrun configure.sh first") + result = subprocess.run( + [f"{TOPDIR}/tools/configure.sh", "-e", f"{str(DPATH.parent)}"], + capture_output=True, + text=True, + ) + if result.returncode != 0: + print( + f"ERROR: {TOPDIR}/tools/configure.sh run fail\n configure path: {str(DPATH.parent)}", + file=sys.stderr, + ) + print(f"STDERROR:{result.stderr}", file=sys.stderr) + sys.exit(1) + NEED_RESET = True + os.environ["APPSDIR"] = "../apps" + os.environ["APPSBINDIR"] = "../apps" + os.environ["EXTERNALDIR"] = "dummy" + os.environ["BINDIR"] = str(TOPDIR) + os.environ["KCONFIG_CONFIG"] = str(DPATH) + + +# Reset environment to previous +def reset_env(): + os.environ.pop("APPSDIR", None) + os.environ.pop("APPSBINDIR", None) + os.environ.pop("EXTERNALDIR", None) + os.environ.pop("BINDIR", None) + os.environ.pop("KCONFIG_CONFIG", None) + if NEED_RESET: + result = subprocess.run( + ["make", "distclean"], cwd=TOPDIR, capture_output=True, text=True + ) + print(result.stdout) + if result.returncode != 0: + print( + "ERROR: distclean error please clean up your workspace manually", + file=sys.stderr, + ) + print(f"STDERROR:{result.stderr}", file=sys.stderr) + + +# Parse a diff file and return a dict of changes +def parse_diff(diff_path): + changes = {} + diff_pattern = re.compile(r"^([+-])CONFIG_(\w+)=([ymn])$") + with open(diff_path, "r") as f: + for line in f: + line = line.strip() + + match = diff_pattern.match(line) + if not match: + continue + + op, name, value = match.groups() + full_name = f"{name}" + + if op == "-": + changes[full_name] = "n" + elif op == "+": + changes[full_name] = value.lower() + return changes + + +# Apply a set of changes to a Kconfig tree and return a list of changed symbols +def apply_changes(kconf, changes): + + # step 1: keep track of original values + orig_state = {sym.name: sym.str_value for sym in kconf.defined_syms} + + # step 2: apply the config settings + value_map = {"n": 0, "m": 1, "y": 2} + for target, value in changes.items(): + sym = kconf.syms.get(target) + if not sym: + print(f"Warning: {target} not found, skipped") + continue + if value not in value_map: + print(f"Invalid value {value} for {target}, skipped") + continue + sym.set_value(value_map[value]) + + # step 3: check for changes + changed = [] + for sym in kconf.defined_syms: + orig = orig_state.get(sym.name, "") + curr = sym.str_value + if orig != curr: + changed.append((sym.name, orig, curr)) + + return changed + + +def track_single_change(target, value): + kconf = Kconfig() + kconf.load_config() + return apply_changes(kconf, {target: value}) + + +def track_diff_changes(diff_path): + kconf = Kconfig() + kconf.load_config() + changes = parse_diff(diff_path) + return apply_changes(kconf, changes) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument( + "-f", "--file", required=True, help="Path to the input defconfig file" + ) + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument( + "-s", + "--single", + nargs=2, + metavar=("CONFIG", "VALUE"), + help="Analyze single change: CONFIG_NAME y/m/n", + ) + group.add_argument("-d", "--diff", help="Analyze changes from diff file") + + args = parser.parse_args() + + DPATH = Path(args.file) + + if not DPATH.is_absolute(): + DPATH = TOPDIR / DPATH + + if not DPATH.exists: + print("ERROR: defconfig file DO NOT exist", file=sys.stderr) + sys.exit(1) + + prepare_env() + + if args.single: + target, value = args.single + changes = track_single_change(target, value.lower()) + title = f"Change report for {target}={value}" + elif args.diff: + changes = track_diff_changes(args.diff) + title = f"Change report for diff: {args.diff}" + + reset_env() + + print(f"\n{title}") + print(f"{'Config Option':<40} {'Old':<20} {'New':<20}") + print("-" * 70) + for name, old, new in sorted(changes, key=lambda x: x[0]): + print(f"{name:<40} {old or '':<20} {new or '':<20}") diff --git a/tools/nxstyle.c b/tools/nxstyle.c index 58094557a1e03..b6b9c81ebf6a6 100644 --- a/tools/nxstyle.c +++ b/tools/nxstyle.c @@ -223,6 +223,10 @@ static const char *g_white_prefix[] = "Http", /* Ref: apps/netutils/xedge/BAS/examples/xedge/src/xedge.h */ "Disk", /* Ref: apps/netutils/xedge/BAS/examples/xedge/src/xedge.h */ "Xedge", /* Ref: apps/netutils/xedge/BAS/examples/xedge/src/xedge.h */ + "tAddr", /* Ref: arch/tricore/src */ + "tClass", /* Ref: arch/tricore/src */ + "tCpu", /* Ref: arch/tricore/src */ + "tId", /* Ref: arch/tricore/src */ NULL }; diff --git a/tools/process_config.py b/tools/process_config.py old mode 100644 new mode 100755 index dc2894f21d953..4ba405049abc5 --- a/tools/process_config.py +++ b/tools/process_config.py @@ -19,52 +19,157 @@ # under the License. # +import json +import os import re +import shutil import sys +from collections import OrderedDict from pathlib import Path -def expand_file(input_path, include_paths, processed=None): +def parse_config_line(line): """ - Recursively expand the file, returning its contents in order as a list of lines. + Parse a configuration line and return the key and value. + + Args: + line (str): A line from a configuration file + + Returns: + tuple: (key, value) if the line contains a configuration, (None, None) otherwise + + Handles two formats: + 1. "# CONFIG_XXX is not set" -> returns (CONFIG_XXX, 'n') + 2. "CONFIG_XXX=value" -> returns (CONFIG_XXX, value) + """ + line = line.strip() + if not line: + return None, None + + # Handle "# CONFIG_XXX is not set" format + if line.startswith("# ") and line.endswith(" is not set"): + config_name = line.split()[1] + return config_name, "n" + + # Handle "CONFIG_XXX=value" format + if "=" in line: + key, value = line.split("=", 1) + return key, value + + return None, None + + +def opposite(value): + if value == "n": + return "y" + else: + return "n" + + +def expand_file(input_path, include_paths, processed=None, tree_node=None): + """ + Recursively expand a configuration file with #include directives. + + Args: + input_path (str): Path to the input configuration file + include_paths (list): List of directories to search for included files + processed (set, optional): Set of already processed files to avoid circular includes + tree_node (dict, optional): Node in the configuration tree being built + + Returns: + tuple: (list of expanded lines, tree structure node) + + This function: + 1. Reads the input file line by line + 2. Processes #include directives by recursively expanding included files + 3. Parses configuration lines to build a configuration dictionary + 4. Builds a tree structure representing the file inclusion hierarchy + 5. Returns the expanded content and the tree structure """ if processed is None: processed = set() + if tree_node is None: + tree_node = { + "file": str(input_path), + "includes": [], + "configs": OrderedDict(), + "include_lines": [], + "raw_content": [], # Store original content for postprocessing + } input_path = Path(input_path).resolve() if input_path in processed: - return [] # Already processed, avoid duplicate includes + return [], tree_node processed.add(input_path) expanded_lines = [] + current_configs = OrderedDict() with input_path.open("r", encoding="utf-8") as f: lines = f.readlines() + # Save original content for postprocessing + tree_node["raw_content"] = [line.rstrip("\n") for line in lines] + for line in lines: line_strip = line.strip() - match = re.match(r'#include\s*[<"]([^">]+)[">]', line_strip) + match = re.match(r"#include\s*[<\"]([^\">]+)[\">]", line_strip) if match: include_file = match.group(1) found = False - # Check the current directory first + # Record original include line for postprocessing + tree_node["include_lines"].append(line.rstrip("\n")) + # Check current directory first direct_path = input_path.parent / include_file if direct_path.exists(): - expanded_lines.extend( - expand_file(direct_path, include_paths, processed) + include_node = { + "file": str(direct_path), + "includes": [], + "configs": OrderedDict(), + "include_lines": [], + "raw_content": [], + } + tree_node["includes"].append(include_node) + + # Recursively expand the included file + included_lines, include_node = expand_file( + direct_path, include_paths, processed, include_node ) + expanded_lines.extend(included_lines) + + # Merge configurations (later configurations override earlier ones) + for key, value in include_node["configs"].items(): + current_configs[key] = value + tree_node["configs"][key] = value + found = True else: - # Then check in the include paths - + # Check include paths for path in include_paths: candidate = Path(path) / include_file if candidate.exists(): - expanded_lines.extend( - expand_file(candidate, include_paths, processed) + include_node = { + "file": str(candidate), + "includes": [], + "configs": OrderedDict(), + "include_lines": [], + "raw_content": [], + } + tree_node["includes"].append(include_node) + + # Recursively expand the included file + included_lines, include_node = expand_file( + candidate, include_paths, processed, include_node ) + expanded_lines.extend(included_lines) + + # Merge configurations + for key, value in include_node["configs"].items(): + current_configs[key] = value + tree_node["configs"][key] = value + found = True break @@ -75,31 +180,352 @@ def expand_file(input_path, include_paths, processed=None): ) sys.exit(1) else: + # Parse configuration line + key, value = parse_config_line(line) + if key is not None: + current_configs[key] = value + tree_node["configs"][key] = value expanded_lines.append(line) - expanded_lines.append("\n") # Keep separation between files - return expanded_lines + expanded_lines.append("\n") # Maintain separation between files + return expanded_lines, tree_node + + +def preprocess(output_path, input_path, include_paths, tree_output_path=None): + """ + Process a configuration file with #include directives. + + Args: + output_path (str): Path to write the expanded configuration + input_path (str): Path to the input configuration file + include_paths (list): List of directories to search for included files + tree_output_path (str, optional): Path to write the tree structure + This function: + 1. Expands the input file by processing #include directives + 2. Writes the expanded configuration to output_path + 3. Optionally writes the tree structure to tree_output_path for postprocessing + """ + lines, tree = expand_file(input_path, include_paths) -def process_file(output_path, input_path, include_paths): - lines = expand_file(input_path, include_paths) + # Write expanded configuration with open(output_path, "w", encoding="utf-8") as out: out.writelines(lines) + # Write tree structure if requested + if tree_output_path and tree["includes"]: + with open(tree_output_path, "w", encoding="utf-8") as f: + json.dump(tree, f, indent=2, ensure_ascii=False) + + +def get_all_included_configs(tree): + """ + Extract all configuration options from included files. + + Args: + tree (dict): The configuration tree structure + + Returns: + OrderedDict: Dictionary of configuration options from all included files + + This function recursively traverses the tree to collect all configurations + from files included via #include directives. + """ + included_configs = OrderedDict() + + def collect_configs(node): + for include in node.get("includes", []): + collect_configs(include) + for key, value in node.get("configs", {}).items(): + included_configs[key] = value + + # Collect configurations from included files only (not the main file) + for include in tree.get("includes", []): + collect_configs(include) + + return included_configs + + +def get_main_configs(tree): + """ + Extract configuration options from the main file (excluding #include directives). + + Args: + tree (dict): The configuration tree structure + + Returns: + OrderedDict: Dictionary of configuration options from the main file + """ + main_configs = OrderedDict() + for line in tree["raw_content"]: + key, value = parse_config_line(line) + if key is not None: + main_configs[key] = value + return main_configs + + +def get_current_configs(config_path): + """ + Parse the current full configuration file. + + Args: + config_path (str): Path to the current configuration file + + Returns: + OrderedDict: Dictionary of configuration options from the current file + """ + configs = OrderedDict() + with open(config_path, "r", encoding="utf-8") as f: + for line in f: + key, value = parse_config_line(line) + if key is not None: + configs[key] = value + return configs + + +def postprocess_inner(tree_path, added, changed, removed, output_path): + """ + Postprocess configuration changes to generate a defconfig with #include directives. + + This function takes the specific changes (added, changed, removed) calculated + by postprocess and applies them to the original defconfig structure + represented by the tree, producing a new defconfig file. + + Args: + tree_path (str): Path to the config_tree.json generated during preprocessing of the ORIGINAL defconfig. + added (dict): {key: value} - Configurations added by the user. + changed (dict): {key: (old_value, new_value)} - Configurations changed by the user. + removed (dict): {key: old_value} - Configurations removed by the user. + output_path (str): Path where the new defconfig should be written. + """ + # 1. Load the original tree structure (this represents the structure of the ORIGINAL defconfig) + with open(tree_path, "r", encoding="utf-8") as f: + original_tree = json.load(f, object_pairs_hook=OrderedDict) + + # 2. Get the original configuration sets from the tree + original_included_configs = get_all_included_configs(original_tree) + original_main_configs = get_main_configs(original_tree) + + # 3. Dictionary to store the final configurations that will go into the main defconfig file + final_main_configs = OrderedDict() + + # --- Logic to determine final content of the main defconfig file --- + + # a. Handle configurations that were originally in included files + # We only place them in the main defconfig if they were explicitly added/changed/removed. + # If untouched, they remain in their included files implicitly. + for key in original_included_configs: + if key in added: + # User added/changed a config that was originally in an included file. + # It must now be explicitly set in the main defconfig to override the included value. + final_main_configs[key] = added[key] + elif key in changed: + # User changed a config that was originally in an included file. + final_main_configs[key] = changed[key][1] # Use the new value + elif key in removed: + # User removed a config that was originally in an included file. + # To "remove" it, we explicitly set it to opposite orig value in the main defconfig. + # This overrides the value from the included file. + final_main_configs[key] = opposite(removed[key]) + + # b. Handle configurations that were originally in the main file + # They should generally stay represented in the main file output. + for key in original_main_configs: + if key in added: + # User added/changed a config that was already in the main file. + final_main_configs[key] = added[key] + elif key in changed: + # User changed a config that was in the main file. + final_main_configs[key] = changed[key][1] # Use the new value + elif key in removed: + # User removed a config that was in the main file. + # Explicitly set to opposite orig value to override its previous state. + final_main_configs[key] = opposite(removed[key]) + else: + # Config was in the original main file and user did NOT touch it. + # According to the new logic, we should PRESERVE these in the output main defconfig + # to maintain the structure and non-default values from the original main file. + # This prevents the output from becoming sparse if the user only made minor changes. + final_main_configs[key] = original_main_configs[key] + + # c. Handle configurations that are entirely new (not present in original main or included) + # These must go into the main defconfig file. + for key, value in added.items(): + if key not in original_main_configs and key not in original_included_configs: + final_main_configs[key] = value + + # 4. Write the final output defconfig file + with open(output_path, "w", encoding="utf-8") as f: + # Write the original #include directives to preserve the structure + for include_line in original_tree.get("include_lines", []): + f.write(include_line + "\n") + + # Add a newline for separation if there were includes + if original_tree.get("include_lines"): + f.write("\n") + + # Write the final configurations for the main file in sorted order + final_write_list = [] + for key, value in final_main_configs.items(): + if value == "n": + final_write_list.append(f"# {key} is not set\n") + else: + final_write_list.append(f"{key}={value}\n") + + # Sort configurations for consistent and readable output + final_write_list.sort() + for write_line in final_write_list: + f.write(write_line) + + +def get_config_diff(old_config, new_config): + """ + Compare two config dictionaries and return the differences. + + Args: + old_config (dict): The original configuration. + new_config (dict): The modified configuration. + + Returns: + tuple: (added, changed, removed) + added (dict): Items in new_config but not in old_config. + changed (dict): Items with different values. {key: (old_value, new_value)}. + removed (dict): Items in old_config but not in new_config. + """ + added = {} + changed = {} + removed = {} + + # Find added and changed items + for key, new_value in new_config.items(): + if key not in old_config: + added[key] = new_value + elif old_config[key] != new_value: + changed[key] = (old_config[key], new_value) # (old_value, new_value) + + # Find removed items + for key in old_config: + if key not in new_config: + removed[key] = old_config[key] + + return added, changed, removed + + +def load_config_file(filepath): + """ + Load a .config or defconfig file into an OrderedDict. + """ + config = OrderedDict() + try: + with open(filepath, "r") as f: + for line in f: + key, value = parse_config_line(line) + if key is not None: + config[key] = value + except FileNotFoundError: + print( + f"Warning: Config file {filepath} not found. Treating as empty.", + file=sys.stderr, + ) + return config + + +def postprocess( + tree_path, original_defconfig_path, modified_defconfig_path, output_defconfig_path +): + """ + An improved postprocess that compares defconfig files before and after modification. + + This function addresses the issue where Kconfig's savedefconfig omits default values, + making it hard to distinguish user deletions from optimizations. + + Args: + tree_path (str): Path to the config_tree.json generated during preprocessing. + original_defconfig_path (str): Path to the defconfig file BEFORE user modification. + modified_defconfig_path (str): Path to the defconfig file AFTER user modification. + output_defconfig_path (str): Path where the updated defconfig should be written. + """ + # 1. Load the defconfig files + defconfig_original = load_config_file(original_defconfig_path) + defconfig_modified = load_config_file(modified_defconfig_path) + + # 2. Compare the defconfig files to find the actual user changes + added, changed, removed = get_config_diff(defconfig_original, defconfig_modified) + + # 3. Use the new postprocess_inner function to generate the final defconfig + # Pass the calculated differences (added, changed, removed) and the original tree. + postprocess_inner(tree_path, added, changed, removed, output_defconfig_path) + if __name__ == "__main__": if len(sys.argv) < 3: print( - "Usage: process_includes.py [include_paths...]", + "Usage: process_config.py [options]", + file=sys.stderr, + ) + print("Modes:", file=sys.stderr) + print( + " preprocess [include_paths...] [--tree ]", + file=sys.stderr, + ) + print( + " postprocess ", file=sys.stderr, ) sys.exit(1) - output_file = Path(sys.argv[1]) - input_file = sys.argv[2] - include_dirs = sys.argv[3:] + mode = sys.argv[1] - if output_file.exists(): - output_file.unlink() + if mode == "preprocess": + if len(sys.argv) < 4: + print( + "Usage: preprocess [include_paths...] [--tree ]", + file=sys.stderr, + ) + sys.exit(1) + + output_file = Path(sys.argv[2]) + input_file = sys.argv[3] + include_dirs = [] + tree_file = None + + # Parse arguments + i = 4 + while i < len(sys.argv): + if sys.argv[i] == "--tree" and i + 1 < len(sys.argv): + tree_file = sys.argv[i + 1] + i += 2 + else: + include_dirs.append(sys.argv[i]) + i += 1 - process_file(output_file, input_file, include_dirs) + if output_file.exists(): + output_file.unlink() + + preprocess(output_file, input_file, include_dirs, tree_file) + + elif mode == "postprocess": + if len(sys.argv) < 6: + print( + "Usage: postprocess ", + file=sys.stderr, + ) + sys.exit(1) + + tree_file = sys.argv[2] + original_defconfig = sys.argv[3] + modified_defconfig = sys.argv[4] + output_defconfig = sys.argv[5] + if Path(tree_file).is_file(): + post_defconfig = output_defconfig + "tmp" + postprocess( + tree_file, original_defconfig, modified_defconfig, post_defconfig + ) + shutil.copy2(post_defconfig, output_defconfig) + os.remove(post_defconfig) + else: + shutil.copy2(modified_defconfig, output_defconfig) + + else: + print(f"Unknown mode: {mode}", file=sys.stderr) + sys.exit(1)