cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

nvmem.rst (6195B)


      1.. SPDX-License-Identifier: GPL-2.0
      2
      3===============
      4NVMEM Subsystem
      5===============
      6
      7 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
      8
      9This document explains the NVMEM Framework along with the APIs provided,
     10and how to use it.
     11
     121. Introduction
     13===============
     14*NVMEM* is the abbreviation for Non Volatile Memory layer. It is used to
     15retrieve configuration of SOC or Device specific data from non volatile
     16memories like eeprom, efuses and so on.
     17
     18Before this framework existed, NVMEM drivers like eeprom were stored in
     19drivers/misc, where they all had to duplicate pretty much the same code to
     20register a sysfs file, allow in-kernel users to access the content of the
     21devices they were driving, etc.
     22
     23This was also a problem as far as other in-kernel users were involved, since
     24the solutions used were pretty much different from one driver to another, there
     25was a rather big abstraction leak.
     26
     27This framework aims at solve these problems. It also introduces DT
     28representation for consumer devices to go get the data they require (MAC
     29Addresses, SoC/Revision ID, part numbers, and so on) from the NVMEMs.
     30
     31NVMEM Providers
     32+++++++++++++++
     33
     34NVMEM provider refers to an entity that implements methods to initialize, read
     35and write the non-volatile memory.
     36
     372. Registering/Unregistering the NVMEM provider
     38===============================================
     39
     40A NVMEM provider can register with NVMEM core by supplying relevant
     41nvmem configuration to nvmem_register(), on success core would return a valid
     42nvmem_device pointer.
     43
     44nvmem_unregister(nvmem) is used to unregister a previously registered provider.
     45
     46For example, a simple nvram case::
     47
     48  static int brcm_nvram_probe(struct platform_device *pdev)
     49  {
     50	struct nvmem_config config = {
     51		.name = "brcm-nvram",
     52		.reg_read = brcm_nvram_read,
     53	};
     54	...
     55	config.dev = &pdev->dev;
     56	config.priv = priv;
     57	config.size = resource_size(res);
     58
     59	devm_nvmem_register(&config);
     60  }
     61
     62Users of board files can define and register nvmem cells using the
     63nvmem_cell_table struct::
     64
     65  static struct nvmem_cell_info foo_nvmem_cells[] = {
     66	{
     67		.name		= "macaddr",
     68		.offset		= 0x7f00,
     69		.bytes		= ETH_ALEN,
     70	}
     71  };
     72
     73  static struct nvmem_cell_table foo_nvmem_cell_table = {
     74	.nvmem_name		= "i2c-eeprom",
     75	.cells			= foo_nvmem_cells,
     76	.ncells			= ARRAY_SIZE(foo_nvmem_cells),
     77  };
     78
     79  nvmem_add_cell_table(&foo_nvmem_cell_table);
     80
     81Additionally it is possible to create nvmem cell lookup entries and register
     82them with the nvmem framework from machine code as shown in the example below::
     83
     84  static struct nvmem_cell_lookup foo_nvmem_lookup = {
     85	.nvmem_name		= "i2c-eeprom",
     86	.cell_name		= "macaddr",
     87	.dev_id			= "foo_mac.0",
     88	.con_id			= "mac-address",
     89  };
     90
     91  nvmem_add_cell_lookups(&foo_nvmem_lookup, 1);
     92
     93NVMEM Consumers
     94+++++++++++++++
     95
     96NVMEM consumers are the entities which make use of the NVMEM provider to
     97read from and to NVMEM.
     98
     993. NVMEM cell based consumer APIs
    100=================================
    101
    102NVMEM cells are the data entries/fields in the NVMEM.
    103The NVMEM framework provides 3 APIs to read/write NVMEM cells::
    104
    105  struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *name);
    106  struct nvmem_cell *devm_nvmem_cell_get(struct device *dev, const char *name);
    107
    108  void nvmem_cell_put(struct nvmem_cell *cell);
    109  void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
    110
    111  void *nvmem_cell_read(struct nvmem_cell *cell, ssize_t *len);
    112  int nvmem_cell_write(struct nvmem_cell *cell, void *buf, ssize_t len);
    113
    114`*nvmem_cell_get()` apis will get a reference to nvmem cell for a given id,
    115and nvmem_cell_read/write() can then read or write to the cell.
    116Once the usage of the cell is finished the consumer should call
    117`*nvmem_cell_put()` to free all the allocation memory for the cell.
    118
    1194. Direct NVMEM device based consumer APIs
    120==========================================
    121
    122In some instances it is necessary to directly read/write the NVMEM.
    123To facilitate such consumers NVMEM framework provides below apis::
    124
    125  struct nvmem_device *nvmem_device_get(struct device *dev, const char *name);
    126  struct nvmem_device *devm_nvmem_device_get(struct device *dev,
    127					   const char *name);
    128  struct nvmem_device *nvmem_device_find(void *data,
    129			int (*match)(struct device *dev, const void *data));
    130  void nvmem_device_put(struct nvmem_device *nvmem);
    131  int nvmem_device_read(struct nvmem_device *nvmem, unsigned int offset,
    132		      size_t bytes, void *buf);
    133  int nvmem_device_write(struct nvmem_device *nvmem, unsigned int offset,
    134		       size_t bytes, void *buf);
    135  int nvmem_device_cell_read(struct nvmem_device *nvmem,
    136			   struct nvmem_cell_info *info, void *buf);
    137  int nvmem_device_cell_write(struct nvmem_device *nvmem,
    138			    struct nvmem_cell_info *info, void *buf);
    139
    140Before the consumers can read/write NVMEM directly, it should get hold
    141of nvmem_controller from one of the `*nvmem_device_get()` api.
    142
    143The difference between these apis and cell based apis is that these apis always
    144take nvmem_device as parameter.
    145
    1465. Releasing a reference to the NVMEM
    147=====================================
    148
    149When a consumer no longer needs the NVMEM, it has to release the reference
    150to the NVMEM it has obtained using the APIs mentioned in the above section.
    151The NVMEM framework provides 2 APIs to release a reference to the NVMEM::
    152
    153  void nvmem_cell_put(struct nvmem_cell *cell);
    154  void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
    155  void nvmem_device_put(struct nvmem_device *nvmem);
    156  void devm_nvmem_device_put(struct device *dev, struct nvmem_device *nvmem);
    157
    158Both these APIs are used to release a reference to the NVMEM and
    159devm_nvmem_cell_put and devm_nvmem_device_put destroys the devres associated
    160with this NVMEM.
    161
    162Userspace
    163+++++++++
    164
    1656. Userspace binary interface
    166==============================
    167
    168Userspace can read/write the raw NVMEM file located at::
    169
    170	/sys/bus/nvmem/devices/*/nvmem
    171
    172ex::
    173
    174  hexdump /sys/bus/nvmem/devices/qfprom0/nvmem
    175
    176  0000000 0000 0000 0000 0000 0000 0000 0000 0000
    177  *
    178  00000a0 db10 2240 0000 e000 0c00 0c00 0000 0c00
    179  0000000 0000 0000 0000 0000 0000 0000 0000 0000
    180  ...
    181  *
    182  0001000
    183
    1847. DeviceTree Binding
    185=====================
    186
    187See Documentation/devicetree/bindings/nvmem/nvmem.txt