LCOV - code coverage report
Current view: top level - zephyr/sys - device_mmio.h Coverage Total Hit
Test: new.info Lines: 92.0 % 25 23
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            0 : /*
       2              :  * Copyright (c) 2020 Intel Corporation.
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : #ifndef ZEPHYR_INCLUDE_SYS_DEVICE_MMIO_H
       7              : #define ZEPHYR_INCLUDE_SYS_DEVICE_MMIO_H
       8              : 
       9              : #include <zephyr/toolchain.h>
      10              : #include <zephyr/linker/sections.h>
      11              : 
      12              : /**
      13              :  * @defgroup device-mmio Device memory-mapped IO management
      14              :  * @ingroup device_model
      15              :  *
      16              :  * Definitions and helper macros for managing driver memory-mapped
      17              :  * input/output (MMIO) regions appropriately in either RAM or ROM.
      18              :  *
      19              :  * In most cases drivers will just want to include device.h, but
      20              :  * including this separately may be needed for arch-level driver code
      21              :  * which uses the DEVICE_MMIO_TOPLEVEL variants and including the
      22              :  * main device.h would introduce header dependency loops due to that
      23              :  * header's reliance on kernel.h.
      24              :  *
      25              :  * @{
      26              :  */
      27              : 
      28              : /* Storing MMIO addresses in RAM is a system-wide decision based on
      29              :  * configuration. This is just used to simplify some other definitions.
      30              :  *
      31              :  * If we have an MMU enabled, all physical MMIO regions must be mapped into
      32              :  * the kernel's virtual address space at runtime, this is a hard requirement.
      33              :  *
      34              :  * If we have PCIE enabled, this does mean that non-PCIE drivers may waste
      35              :  * a bit of RAM, but systems with PCI express are not RAM constrained.
      36              :  */
      37              : #if defined(CONFIG_MMU) || defined(CONFIG_PCIE) || defined(CONFIG_EXTERNAL_ADDRESS_TRANSLATION)
      38            0 : #define DEVICE_MMIO_IS_IN_RAM
      39              : #endif
      40              : 
      41              : #if defined(CONFIG_EXTERNAL_ADDRESS_TRANSLATION)
      42              : #include <zephyr/drivers/mm/system_mm.h>
      43              : #endif
      44              : 
      45              : #ifndef _ASMLANGUAGE
      46              : #include <stdint.h>
      47              : #include <stddef.h>
      48              : #include <zephyr/kernel/mm.h>
      49              : #include <zephyr/sys/sys_io.h>
      50              : 
      51              : #ifdef DEVICE_MMIO_IS_IN_RAM
      52              : /* Store the physical address and size from DTS, we'll memory
      53              :  * map into the virtual address space at runtime. This is not applicable
      54              :  * to PCIe devices, which must query the bus for BAR information.
      55              :  */
      56              : struct z_device_mmio_rom {
      57              :         /** MMIO physical address */
      58              :         uintptr_t phys_addr;
      59              : 
      60              :         /** MMIO region size */
      61              :         size_t size;
      62              : };
      63              : 
      64              : #define Z_DEVICE_MMIO_ROM_INITIALIZER(node_id) \
      65              :         { \
      66              :                 .phys_addr = DT_REG_ADDR(node_id), \
      67              :                 .size = DT_REG_SIZE(node_id) \
      68              :         }
      69              : 
      70              : #define Z_DEVICE_MMIO_NAMED_ROM_INITIALIZER(name, node_id) \
      71              :         { \
      72              :                 .phys_addr = DT_REG_ADDR_BY_NAME(node_id, name), \
      73              :                 .size = DT_REG_SIZE_BY_NAME(node_id, name) \
      74              :         }
      75              : 
      76              : /**
      77              :  * Set linear address for device MMIO access
      78              :  *
      79              :  * This function sets the `virt_addr` parameter to the correct linear
      80              :  * address for the MMIO region.
      81              :  *
      82              :  * If the MMU is enabled, mappings may be created in the page tables.
      83              :  *
      84              :  * Normally, only a caching mode needs to be set for the 'flags' parameter.
      85              :  * The mapped linear address will have read-write access to supervisor mode.
      86              :  *
      87              :  * @see k_map()
      88              :  *
      89              :  * @param[out] virt_addr Output linear address storage location, most
      90              :  *                       users will want some DEVICE_MMIO_RAM_PTR() value
      91              :  * @param[in] phys_addr Physical address base of the MMIO region
      92              :  * @param[in] size Size of the MMIO region
      93              :  * @param[in] flags Caching mode and access flags, see K_MEM_CACHE_* and
      94              :  *                  K_MEM_PERM_* macros
      95              :  */
      96              : __boot_func
      97            1 : static inline void device_map(mm_reg_t *virt_addr, uintptr_t phys_addr,
      98              :                               size_t size, uint32_t flags)
      99              : {
     100              : #ifdef CONFIG_MMU
     101              :         /* Pass along flags and add that we want supervisor mode
     102              :          * read-write access.
     103              :          */
     104              :         k_mem_map_phys_bare((uint8_t **)virt_addr, phys_addr, size,
     105              :                             flags | K_MEM_PERM_RW);
     106              : #else
     107              :         ARG_UNUSED(size);
     108              :         ARG_UNUSED(flags);
     109              : #ifdef CONFIG_EXTERNAL_ADDRESS_TRANSLATION
     110              :         sys_mm_drv_page_phys_get((void *) phys_addr, virt_addr);
     111              : #else
     112              :         *virt_addr = phys_addr;
     113              : #endif /* CONFIG_EXTERNAL_ADDRESS_TRANSLATION */
     114              : #endif /* CONFIG_MMU */
     115              : }
     116              : #else
     117              : /* No MMU or PCIe. Just store the address from DTS and treat as a linear
     118              :  * address
     119              :  */
     120              : struct z_device_mmio_rom {
     121              :         /** MMIO linear address */
     122              :         mm_reg_t addr;
     123              : };
     124              : 
     125              : #define Z_DEVICE_MMIO_ROM_INITIALIZER(node_id) \
     126              :         { \
     127              :                 .addr = (mm_reg_t)DT_REG_ADDR_U64(node_id) \
     128              :         }
     129              : 
     130              : #define Z_DEVICE_MMIO_NAMED_ROM_INITIALIZER(name, node_id) \
     131              :         { \
     132              :                 .addr = (mm_reg_t)DT_REG_ADDR_BY_NAME_U64(node_id, name) \
     133              :         }
     134              : 
     135              : #endif /* DEVICE_MMIO_IS_IN_RAM */
     136              : #endif /* !_ASMLANGUAGE */
     137              : /** @} */
     138              : 
     139              : /**
     140              :  * @defgroup device-mmio-single Single MMIO region macros
     141              :  * @ingroup device-mmio
     142              :  *
     143              :  * For drivers which need to manage just one MMIO region, the most common
     144              :  * case.
     145              :  *
     146              :  * @{
     147              :  */
     148              : 
     149              : /**
     150              :  * @def DEVICE_MMIO_RAM
     151              :  *
     152              :  * Declare storage for MMIO information within a device's dev_data struct.
     153              :  *
     154              :  * This gets accessed by the DEVICE_MMIO_MAP() and DEVICE_MMIO_GET() macros.
     155              :  *
     156              :  * Depending on configuration, no memory may be reserved at all.
     157              :  * This must be the first member of the data struct.
     158              :  *
     159              :  * There must be a corresponding DEVICE_MMIO_ROM in config_info if the
     160              :  * physical address is known at build time, but may be omitted if not (such
     161              :  * as with PCIe)
     162              :  *
     163              :  * Example for a driver named "foo":
     164              :  *
     165              :  * @code{.c}
     166              :  *
     167              :  * struct foo_driver_data {
     168              :  *      DEVICE_MMIO_RAM;
     169              :  *      int wibble;
     170              :  *      ...
     171              :  * }
     172              :  *
     173              :  * @endcode
     174              :  *
     175              :  * No build-time initialization of this memory is necessary; it
     176              :  * will be set up in the init function by DEVICE_MMIO_MAP().
     177              :  *
     178              :  * A pointer to this memory may be obtained with DEVICE_MMIO_RAM_PTR().
     179              :  */
     180              : #ifdef DEVICE_MMIO_IS_IN_RAM
     181            1 : #define DEVICE_MMIO_RAM                 mm_reg_t _mmio
     182              : #else
     183              : #define DEVICE_MMIO_RAM
     184              : #endif
     185              : 
     186              : #ifdef DEVICE_MMIO_IS_IN_RAM
     187              : /**
     188              :  * Return a pointer to the RAM-based storage area for a device's MMIO
     189              :  * address.
     190              :  *
     191              :  * This is useful for the target MMIO address location when using
     192              :  * device_map() directly.
     193              :  *
     194              :  * @param device device node_id object
     195              :  * @retval mm_reg_t  pointer to storage location
     196              :  */
     197            1 : #define DEVICE_MMIO_RAM_PTR(device)     (mm_reg_t *)((device)->data)
     198              : #endif /* DEVICE_MMIO_IS_IN_RAM */
     199              : 
     200              : /**
     201              :  * @brief Declare storage for MMIO data within a device's config struct
     202              :  *
     203              :  * This gets accessed by DEVICE_MMIO_MAP() and DEVICE_MMIO_GET() macros.
     204              :  *
     205              :  * What gets stored here varies considerably by configuration.
     206              :  * This must be the first member of the config struct. There must be
     207              :  * a corresponding DEVICE_MMIO_RAM in data.
     208              :  *
     209              :  * This storage is not used if the device is PCIe and may be omitted.
     210              :  *
     211              :  * This should be initialized at build time with information from DTS
     212              :  * using DEVICE_MMIO_ROM_INIT().
     213              :  *
     214              :  * A pointer to this memory may be obtained with DEVICE_MMIO_ROM_PTR().
     215              :  *
     216              :  * Example for a driver named "foo":
     217              :  *
     218              :  * @code{.c}
     219              :  *
     220              :  * struct foo_config {
     221              :  *      DEVICE_MMIO_ROM;
     222              :  *      int baz;
     223              :  *      ...
     224              :  * }
     225              :  *
     226              :  * @endcode
     227              :  *
     228              :  * @see DEVICE_MMIO_ROM_INIT()
     229              :  */
     230            1 : #define DEVICE_MMIO_ROM         struct z_device_mmio_rom _mmio
     231              : 
     232              : /**
     233              :  * Return a pointer to the ROM-based storage area for a device's MMIO
     234              :  * information. This macro will not work properly if the ROM storage
     235              :  * was omitted from the config struct declaration, and should not
     236              :  * be used in this case.
     237              :  *
     238              :  * @param dev device instance object
     239              :  * @retval struct device_mmio_rom * pointer to storage location
     240              :  */
     241            1 : #define DEVICE_MMIO_ROM_PTR(dev) \
     242              :         ((struct z_device_mmio_rom *)((dev)->config))
     243              : 
     244              : /**
     245              :  * @brief Initialize a DEVICE_MMIO_ROM member
     246              :  *
     247              :  * Initialize MMIO-related information within a specific instance of
     248              :  * a device config struct, using information from DTS.
     249              :  *
     250              :  * Example for a driver belonging to the "foo" subsystem:
     251              :  *
     252              :  * @code{.c}
     253              :  *
     254              :  * struct foo_config my_config = {
     255              :  *      DEVICE_MMIO_ROM_INIT(DT_DRV_INST(...)),
     256              :  *      .baz = 2;
     257              :  *      ...
     258              :  * }
     259              :  *
     260              :  * @endcode
     261              :  *
     262              :  * @see DEVICE_MMIO_ROM()
     263              :  *
     264              :  * @param node_id DTS node_id
     265              :  */
     266            1 : #define DEVICE_MMIO_ROM_INIT(node_id) \
     267              :         ._mmio = Z_DEVICE_MMIO_ROM_INITIALIZER(node_id)
     268              : 
     269              : /**
     270              :  * @def DEVICE_MMIO_MAP(device, flags)
     271              :  *
     272              :  * @brief Map MMIO memory into the address space
     273              :  *
     274              :  * This is not intended for PCIe devices; these must be probed at runtime
     275              :  * and you will want to make a device_map() call directly, using
     276              :  * DEVICE_MMIO_RAM_PTR() as the target virtual address location.
     277              :  *
     278              :  * The flags argument is currently used for caching mode, which should be
     279              :  * one of the DEVICE_CACHE_* macros. Unused bits are reserved for future
     280              :  * expansion.
     281              :  *
     282              :  * @param dev Device object instance
     283              :  * @param flags cache mode flags
     284              :  */
     285              : #ifdef DEVICE_MMIO_IS_IN_RAM
     286            1 : #define DEVICE_MMIO_MAP(dev, flags) \
     287              :         device_map(DEVICE_MMIO_RAM_PTR(dev), \
     288              :                    DEVICE_MMIO_ROM_PTR(dev)->phys_addr, \
     289              :                    DEVICE_MMIO_ROM_PTR(dev)->size, \
     290              :                    (flags))
     291              : #else
     292              : #define DEVICE_MMIO_MAP(dev, flags) do { } while (false)
     293              : #endif
     294              : 
     295              : /**
     296              :  * @def DEVICE_MMIO_GET(dev)
     297              :  *
     298              :  * @brief Obtain the MMIO address for a device
     299              :  *
     300              :  * For most microcontrollers MMIO addresses can be fixed values known at
     301              :  * build time, and we can store this in device->config, residing in ROM.
     302              :  *
     303              :  * However, some devices can only know their MMIO addresses at runtime,
     304              :  * because they need to be memory-mapped into the address space, enumerated
     305              :  * from PCI, or both.
     306              :  *
     307              :  * This macro returns the linear address of the driver's MMIO region.
     308              :  * This is for drivers which have exactly one MMIO region.
     309              :  * A call must have been made to device_map() in the driver init function.
     310              :  *
     311              :  * @param dev Device object
     312              :  * @return mm_reg_t  linear address of the MMIO region
     313              :  */
     314              : #ifdef DEVICE_MMIO_IS_IN_RAM
     315            1 : #define DEVICE_MMIO_GET(dev)    (*DEVICE_MMIO_RAM_PTR(dev))
     316              : #else
     317              : #define DEVICE_MMIO_GET(dev)    (DEVICE_MMIO_ROM_PTR(dev)->addr)
     318              : #endif
     319              : /** @} */
     320              : 
     321              : /**
     322              :  * @defgroup device-mmio-named Named MMIO region macros
     323              :  * @ingroup device-mmio
     324              :  *
     325              :  * For drivers which need to manage multiple MMIO regions, which will
     326              :  * be referenced by name.
     327              :  *
     328              :  * @{
     329              :  */
     330              : 
     331              : /**
     332              :  * @def DEVICE_MMIO_NAMED_RAM(name)
     333              :  *
     334              :  * @brief Declare storage for MMIO data within a device's dev_data struct
     335              :  *
     336              :  * This gets accessed by the DEVICE_MMIO_NAMED_MAP() and
     337              :  * DEVICE_MMIO_NAMED_GET() macros.
     338              :  *
     339              :  * Depending on configuration, no memory may be reserved at all.
     340              :  * Multiple named regions may be declared.
     341              :  *
     342              :  * There must be a corresponding DEVICE_MMIO_ROM in config if the
     343              :  * physical address is known at build time, but may be omitted if not (such
     344              :  * as with PCIe.
     345              :  *
     346              :  * Example for a driver named "foo":
     347              :  *
     348              :  * @code{.c}
     349              :  *
     350              :  * struct foo_driver_data {
     351              :  *      int blarg;
     352              :  *      DEVICE_MMIO_NAMED_RAM(corge);
     353              :  *      DEVICE_MMIO_NAMED_RAM(grault);
     354              :  *      int wibble;
     355              :  *      ...
     356              :  * }
     357              :  *
     358              :  * @endcode
     359              :  *
     360              :  * No build-time initialization of this memory is necessary; it
     361              :  * will be set up in the init function by DEVICE_MMIO_NAMED_MAP().
     362              :  *
     363              :  * @param name Member name to use to store within dev_data.
     364              :  */
     365              : #ifdef DEVICE_MMIO_IS_IN_RAM
     366            1 : #define DEVICE_MMIO_NAMED_RAM(name)     mm_reg_t name
     367              : #else
     368              : #define DEVICE_MMIO_NAMED_RAM(name)
     369              : #endif /* DEVICE_MMIO_IS_IN_RAM */
     370              : 
     371              : #ifdef DEVICE_MMIO_IS_IN_RAM
     372              : /**
     373              :  * @brief Return a pointer to the RAM storage for a device's named MMIO address
     374              :  *
     375              :  * This macro requires that the macro DEV_DATA is locally defined and returns
     376              :  * a properly typed pointer to the particular dev_data struct for this driver.
     377              :  *
     378              :  * @param dev device instance object
     379              :  * @param name Member name within dev_data
     380              :  * @retval mm_reg_t  pointer to storage location
     381              :  */
     382            1 : #define DEVICE_MMIO_NAMED_RAM_PTR(dev, name) \
     383              :                 (&(DEV_DATA(dev)->name))
     384              : #endif /* DEVICE_MMIO_IS_IN_RAM */
     385              : 
     386              : /**
     387              :  * @brief Declare storage for MMIO data within a device's config struct.
     388              :  *
     389              :  * This gets accessed by DEVICE_MMIO_NAMED_MAP() and
     390              :  * DEVICE_MMIO_NAMED_GET() macros.
     391              :  *
     392              :  * What gets stored here varies considerably by configuration. Multiple named
     393              :  * regions may be declared. There must be corresponding entries in the dev_data
     394              :  * struct.
     395              :  *
     396              :  * This storage is not used if the device is PCIe and may be omitted.
     397              :  *
     398              :  * If used, this must be initialized at build time with information from DTS
     399              :  * using DEVICE_MMIO_NAMED_ROM_INIT()
     400              :  *
     401              :  * A pointer to this memory may be obtained with DEVICE_MMIO_NAMED_ROM_PTR().
     402              :  *
     403              :  * Example for a driver named "foo":
     404              :  *
     405              :  * @code{.c}
     406              :  *
     407              :  * struct foo_config {
     408              :  *      int bar;
     409              :  *      DEVICE_MMIO_NAMED_ROM(corge);
     410              :  *      DEVICE_MMIO_NAMED_ROM(grault);
     411              :  *      int baz;
     412              :  *      ...
     413              :  * }
     414              :  *
     415              :  * @endcode
     416              :  *
     417              :  * @see DEVICE_MMIO_NAMED_ROM_INIT()
     418              :  *
     419              :  * @param name Member name to store within config
     420              :  */
     421            1 : #define DEVICE_MMIO_NAMED_ROM(name) struct z_device_mmio_rom name
     422              : 
     423              : /**
     424              :  * Return a pointer to the ROM-based storage area for a device's MMIO
     425              :  * information.
     426              :  *
     427              :  * This macro requires that the macro DEV_CFG is locally defined and returns
     428              :  * a properly typed pointer to the particular config struct for this
     429              :  * driver.
     430              :  *
     431              :  * @param dev device instance object
     432              :  * @param name Member name within config
     433              :  * @retval struct device_mmio_rom * pointer to storage location
     434              :  */
     435            1 : #define DEVICE_MMIO_NAMED_ROM_PTR(dev, name) (&(DEV_CFG(dev)->name))
     436              : 
     437              : /**
     438              :  * @brief Initialize a named DEVICE_MMIO_NAMED_ROM member
     439              :  *
     440              :  * Initialize MMIO-related information within a specific instance of
     441              :  * a device config struct, using information from DTS.
     442              :  *
     443              :  * Example for an instance of a driver belonging to the "foo" subsystem
     444              :  * that will have two regions named 'corge' and 'grault':
     445              :  *
     446              :  * @code{.c}
     447              :  *
     448              :  * struct foo_config my_config = {
     449              :  *      bar = 7;
     450              :  *      DEVICE_MMIO_NAMED_ROM_INIT(corge, DT_DRV_INST(...));
     451              :  *      DEVICE_MMIO_NAMED_ROM_INIT(grault, DT_DRV_INST(...));
     452              :  *      baz = 2;
     453              :  *      ...
     454              :  * }
     455              :  *
     456              :  * @endcode
     457              :  *
     458              :  * @see DEVICE_MMIO_NAMED_ROM()
     459              :  *
     460              :  * @param name Member name within config for the MMIO region
     461              :  * @param node_id DTS node identifier
     462              :  */
     463            1 : #define DEVICE_MMIO_NAMED_ROM_INIT(name, node_id) \
     464              :         .name = Z_DEVICE_MMIO_ROM_INITIALIZER(node_id)
     465              : 
     466              : /**
     467              :  * @brief Initialize a named DEVICE_MMIO_NAMED_ROM member using a named DT
     468              :  *        reg property.
     469              :  *
     470              :  * Same as @ref DEVICE_MMIO_NAMED_ROM_INIT but the size and address are taken
     471              :  * from a named DT reg property.
     472              :  *
     473              :  * Example for an instance of a driver belonging to the "foo" subsystem
     474              :  * that will have two DT-defined regions named 'chip' and 'dale':
     475              :  *
     476              :  * @code{.dts}
     477              :  *
     478              :  *    foo@E5000000 {
     479              :  *         reg = <0xE5000000 0x1000>, <0xE6000000 0x1000>;
     480              :  *         reg-names = "chip", "dale";
     481              :  *         ...
     482              :  *    };
     483              :  *
     484              :  * @endcode
     485              :  *
     486              :  * @code{.c}
     487              :  *
     488              :  * struct foo_config my_config = {
     489              :  *      bar = 7;
     490              :  *      DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME(chip, DT_DRV_INST(...));
     491              :  *      DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME(dale, DT_DRV_INST(...));
     492              :  *      baz = 2;
     493              :  *      ...
     494              :  * }
     495              :  *
     496              :  * @endcode
     497              :  *
     498              :  * @see DEVICE_MMIO_NAMED_ROM_INIT()
     499              :  *
     500              :  * @param name Member name within config for the MMIO region and name of the
     501              :  *             reg property in the DT
     502              :  * @param node_id DTS node identifier
     503              :  */
     504            1 : #define DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME(name, node_id) \
     505              :         .name = Z_DEVICE_MMIO_NAMED_ROM_INITIALIZER(name, node_id)
     506              : 
     507              : /**
     508              :  * @brief Set up memory for a named MMIO region
     509              :  *
     510              :  * This performs the necessary PCI probing and/or MMU virtual memory mapping
     511              :  * such that DEVICE_MMIO_GET(name) returns a suitable linear memory address
     512              :  * for the MMIO region.
     513              :  *
     514              :  * If such operations are not required by the target hardware, this expands
     515              :  * to nothing.
     516              :  *
     517              :  * This should be called from the driver's init function, once for each
     518              :  * MMIO region that needs to be mapped.
     519              :  *
     520              :  * This macro requires that the macros DEV_DATA and DEV_CFG are locally
     521              :  * defined and return properly typed pointers to the particular dev_data
     522              :  * and config structs for this driver.
     523              :  *
     524              :  * The flags argument is currently used for caching mode, which should be
     525              :  * one of the DEVICE_CACHE_* macros. Unused bits are reserved for future
     526              :  * expansion.
     527              :  *
     528              :  * @param dev Device object
     529              :  * @param name Member name for MMIO information, as declared with
     530              :  *             DEVICE_MMIO_NAMED_RAM/DEVICE_MMIO_NAMED_ROM
     531              :  * @param flags One of the DEVICE_CACHE_* caching modes
     532              :  */
     533              : #ifdef DEVICE_MMIO_IS_IN_RAM
     534            1 : #define DEVICE_MMIO_NAMED_MAP(dev, name, flags) \
     535              :         device_map(DEVICE_MMIO_NAMED_RAM_PTR((dev), name), \
     536              :                    (DEVICE_MMIO_NAMED_ROM_PTR((dev), name)->phys_addr), \
     537              :                    (DEVICE_MMIO_NAMED_ROM_PTR((dev), name)->size), \
     538              :                    (flags))
     539              : #else
     540              : #define DEVICE_MMIO_NAMED_MAP(dev, name, flags) do { } while (false)
     541              : #endif
     542              : 
     543              : /**
     544              :  * @def DEVICE_MMIO_NAMED_GET(dev, name)
     545              :  *
     546              :  * @brief Obtain a named MMIO address for a device
     547              :  *
     548              :  * This macro returns the MMIO base address for a named region from the
     549              :  * appropriate place within the device object's linked  data structures.
     550              :  *
     551              :  * This is for drivers which have multiple MMIO regions.
     552              :  *
     553              :  * This macro requires that the macros DEV_DATA and DEV_CFG are locally
     554              :  * defined and return properly typed pointers to the particular dev_data
     555              :  * and config structs for this driver.
     556              :  *
     557              :  * @see DEVICE_MMIO_GET
     558              :  *
     559              :  * @param dev Device object
     560              :  * @param name Member name for MMIO information, as declared with
     561              :  *             DEVICE_MMIO_NAMED_RAM/DEVICE_MMIO_NAMED_ROM
     562              :  * @return mm_reg_t  linear address of the MMIO region
     563              :  */
     564              : #ifdef DEVICE_MMIO_IS_IN_RAM
     565            1 : #define DEVICE_MMIO_NAMED_GET(dev, name) \
     566              :                 (*DEVICE_MMIO_NAMED_RAM_PTR((dev), name))
     567              : #else
     568              : #define DEVICE_MMIO_NAMED_GET(dev, name) \
     569              :                 ((DEVICE_MMIO_NAMED_ROM_PTR((dev), name))->addr)
     570              : #endif /* DEVICE_MMIO_IS_IN_RAM */
     571              : 
     572              : /** @} */
     573              : 
     574              : /**
     575              :  * @defgroup device-mmio-toplevel Top-level MMIO region macros
     576              :  * @ingroup device-mmio
     577              :  *
     578              :  * For drivers which do not use Zephyr's driver model and do not
     579              :  * associate struct device with a driver instance. Top-level storage
     580              :  * is used instead, with either global or static scope.
     581              :  *
     582              :  * This is often useful for interrupt controller and timer drivers.
     583              :  *
     584              :  * Currently PCIe devices are not well-supported with this set of macros.
     585              :  * Either use Zephyr's driver model for these kinds of devices, or
     586              :  * manage memory manually with calls to device_map().
     587              :  *
     588              :  * @{
     589              :  */
     590              : 
     591              :  #define Z_TOPLEVEL_ROM_NAME(name) _CONCAT(z_mmio_rom__, name)
     592              :  #define Z_TOPLEVEL_RAM_NAME(name) _CONCAT(z_mmio_ram__, name)
     593              : 
     594              : /**
     595              :  * @def DEVICE_MMIO_TOPLEVEL(name, node_id)
     596              :  *
     597              :  * @brief Declare top-level storage for MMIO information, global scope
     598              :  *
     599              :  * This is intended for drivers which do not use Zephyr's driver model
     600              :  * of config/dev_data linked to a struct device.
     601              :  *
     602              :  * Instead, this is a top-level declaration for the driver's C file.
     603              :  * The scope of this declaration is global and may be referenced by
     604              :  * other C files, using DEVICE_MMIO_TOPLEVEL_DECLARE.
     605              :  *
     606              :  * @param name Base symbol name
     607              :  * @param node_id Device-tree node identifier for this region
     608              :  */
     609              : #ifdef DEVICE_MMIO_IS_IN_RAM
     610            1 : #define DEVICE_MMIO_TOPLEVEL(name, node_id) \
     611              :         __pinned_bss \
     612              :         mm_reg_t Z_TOPLEVEL_RAM_NAME(name); \
     613              :         __pinned_rodata \
     614              :         const struct z_device_mmio_rom Z_TOPLEVEL_ROM_NAME(name) = \
     615              :                 Z_DEVICE_MMIO_ROM_INITIALIZER(node_id)
     616              : #else
     617              : #define DEVICE_MMIO_TOPLEVEL(name, node_id) \
     618              :         __pinned_rodata \
     619              :         const struct z_device_mmio_rom Z_TOPLEVEL_ROM_NAME(name) = \
     620              :                 Z_DEVICE_MMIO_ROM_INITIALIZER(node_id)
     621              : #endif /* DEVICE_MMIO_IS_IN_RAM */
     622              : 
     623              : /**
     624              :  * @def DEVICE_MMIO_TOPLEVEL_DECLARE(name)
     625              :  *
     626              :  * Provide an extern reference to a top-level MMIO region
     627              :  *
     628              :  * If a top-level MMIO region defined with DEVICE_MMIO_DEFINE needs to be
     629              :  * referenced from other C files, this macro provides the necessary extern
     630              :  * definitions.
     631              :  *
     632              :  * @see DEVICE_MMIO_TOPLEVEL
     633              :  *
     634              :  * @param name Name of the top-level MMIO region
     635              :  */
     636              : 
     637              : #ifdef DEVICE_MMIO_IS_IN_RAM
     638            1 : #define DEVICE_MMIO_TOPLEVEL_DECLARE(name) \
     639              :         extern mm_reg_t Z_TOPLEVEL_RAM_NAME(name); \
     640              :         extern const struct z_device_mmio_rom Z_TOPLEVEL_ROM_NAME(name)
     641              : #else
     642              : #define DEVICE_MMIO_TOPLEVEL_DECLARE(name) \
     643              :         extern const struct z_device_mmio_rom Z_TOPLEVEL_ROM_NAME(name)
     644              : #endif /* DEVICE_MMIO_IS_IN_RAM */
     645              : 
     646              : /**
     647              :  * @def  DEVICE_MMIO_TOPLEVEL_STATIC(name, node_id)
     648              :  *
     649              :  * @brief Declare top-level storage for MMIO information, static scope
     650              :  *
     651              :  * This is intended for drivers which do not use Zephyr's driver model
     652              :  * of config/dev_data linked to a struct device.
     653              :  *
     654              :  * Instead, this is a top-level declaration for the driver's C file.
     655              :  * The scope of this declaration is static.
     656              :  *
     657              :  * @param name Name of the top-level MMIO region
     658              :  * @param node_id Device-tree node identifier for this region
     659              :  */
     660              : #ifdef DEVICE_MMIO_IS_IN_RAM
     661            1 : #define DEVICE_MMIO_TOPLEVEL_STATIC(name, node_id) \
     662              :         __pinned_bss \
     663              :         static mm_reg_t Z_TOPLEVEL_RAM_NAME(name); \
     664              :         __pinned_rodata \
     665              :         static const struct z_device_mmio_rom Z_TOPLEVEL_ROM_NAME(name) = \
     666              :                 Z_DEVICE_MMIO_ROM_INITIALIZER(node_id)
     667              : #else
     668              : #define DEVICE_MMIO_TOPLEVEL_STATIC(name, node_id) \
     669              :         __pinned_rodata \
     670              :         static const struct z_device_mmio_rom Z_TOPLEVEL_ROM_NAME(name) = \
     671              :                 Z_DEVICE_MMIO_ROM_INITIALIZER(node_id)
     672              : #endif /* DEVICE_MMIO_IS_IN_RAM */
     673              : 
     674              : #ifdef DEVICE_MMIO_IS_IN_RAM
     675              : /**
     676              :  * @brief Return a pointer to the RAM storage for a device's toplevel MMIO
     677              :  * address.
     678              :  *
     679              :  * @param name Name of toplevel MMIO region
     680              :  * @retval mm_reg_t  pointer to storage location
     681              :  */
     682            1 : #define DEVICE_MMIO_TOPLEVEL_RAM_PTR(name) &Z_TOPLEVEL_RAM_NAME(name)
     683              : #endif /* DEVICE_MMIO_IS_IN_RAM */
     684              : 
     685              : /**
     686              :  * Return a pointer to the ROM-based storage area for a toplevel MMIO region.
     687              :  *
     688              :  * @param name MMIO region name
     689              :  * @retval struct device_mmio_rom * pointer to storage location
     690              :  */
     691            1 : #define DEVICE_MMIO_TOPLEVEL_ROM_PTR(name) &Z_TOPLEVEL_ROM_NAME(name)
     692              : 
     693              : /**
     694              :  * @def DEVICE_MMIO_TOPLEVEL_MAP(name, flags)
     695              :  *
     696              :  * @brief Set up memory for a driver'sMMIO region
     697              :  *
     698              :  * This performs the necessary MMU virtual memory mapping
     699              :  * such that DEVICE_MMIO_GET() returns a suitable linear memory address
     700              :  * for the MMIO region.
     701              :  *
     702              :  * If such operations are not required by the target hardware, this expands
     703              :  * to nothing.
     704              :  *
     705              :  * This should be called once from the driver's init function.
     706              :  *
     707              :  * The flags argument is currently used for caching mode, which should be
     708              :  * one of the DEVICE_CACHE_* macros. Unused bits are reserved for future
     709              :  * expansion.
     710              :  *
     711              :  * @param name Name of the top-level MMIO region
     712              :  * @param flags One of the DEVICE_CACHE_* caching modes
     713              :  */
     714              : #ifdef DEVICE_MMIO_IS_IN_RAM
     715            1 : #define DEVICE_MMIO_TOPLEVEL_MAP(name, flags) \
     716              :         device_map(&Z_TOPLEVEL_RAM_NAME(name), \
     717              :                    Z_TOPLEVEL_ROM_NAME(name).phys_addr, \
     718              :                    Z_TOPLEVEL_ROM_NAME(name).size, (flags))
     719              : #else
     720              : #define DEVICE_MMIO_TOPLEVEL_MAP(name, flags) do { } while (false)
     721              : #endif
     722              : 
     723              : /**
     724              :  * @def DEVICE_MMIO_TOPLEVEL_GET(name)
     725              :  *
     726              :  * @brief Obtain the MMIO address for a device declared top-level
     727              :  *
     728              :  * @see DEVICE_MMIO_GET
     729              :  *
     730              :  * @param name Name of the top-level MMIO region
     731              :  * @return mm_reg_t  linear address of the MMIO region
     732              :  */
     733              : #ifdef DEVICE_MMIO_IS_IN_RAM
     734            1 : #define DEVICE_MMIO_TOPLEVEL_GET(name)  \
     735              :                 ((mm_reg_t)Z_TOPLEVEL_RAM_NAME(name))
     736              : #else
     737              : #define DEVICE_MMIO_TOPLEVEL_GET(name)  \
     738              :                 ((mm_reg_t)Z_TOPLEVEL_ROM_NAME(name).addr)
     739              : #endif
     740              : /** @} */
     741              : 
     742              : #endif /* ZEPHYR_INCLUDE_SYS_DEVICE_MMIO_H */
        

Generated by: LCOV version 2.0-1