LCOV - code coverage report
Current view: top level - zephyr/sys - device_mmio.h Hit Total Coverage
Test: new.info Lines: 23 25 92.0 %
Date: 2024-12-22 00:14:23

          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 1.14