11599121bSAlistair Francis /* 21599121bSAlistair Francis * Register Definition API 31599121bSAlistair Francis * 41599121bSAlistair Francis * Copyright (c) 2016 Xilinx Inc. 51599121bSAlistair Francis * Copyright (c) 2013 Peter Crosthwaite <peter.crosthwaite@xilinx.com> 61599121bSAlistair Francis * 71599121bSAlistair Francis * This work is licensed under the terms of the GNU GPL, version 2. See 81599121bSAlistair Francis * the COPYING file in the top-level directory. 91599121bSAlistair Francis */ 101599121bSAlistair Francis 111599121bSAlistair Francis #ifndef REGISTER_H 121599121bSAlistair Francis #define REGISTER_H 131599121bSAlistair Francis 1449e14ddbSPeter Crosthwaite #include "hw/qdev-core.h" 151599121bSAlistair Francis #include "exec/memory.h" 16afb3141cSPeter Maydell #include "hw/registerfields.h" 17db1015e9SEduardo Habkost #include "qom/object.h" 181599121bSAlistair Francis 191599121bSAlistair Francis typedef struct RegisterInfo RegisterInfo; 201599121bSAlistair Francis typedef struct RegisterAccessInfo RegisterAccessInfo; 210b73c9bbSAlistair Francis typedef struct RegisterInfoArray RegisterInfoArray; 221599121bSAlistair Francis 231599121bSAlistair Francis /** 241599121bSAlistair Francis * Access description for a register that is part of guest accessible device 251599121bSAlistair Francis * state. 261599121bSAlistair Francis * 271599121bSAlistair Francis * @name: String name of the register 281599121bSAlistair Francis * @ro: whether or not the bit is read-only 291599121bSAlistair Francis * @w1c: bits with the common write 1 to clear semantic. 301599121bSAlistair Francis * @reset: reset value. 311599121bSAlistair Francis * @cor: Bits that are clear on read 321599121bSAlistair Francis * @rsvd: Bits that are reserved and should not be changed 331599121bSAlistair Francis * 341599121bSAlistair Francis * @pre_write: Pre write callback. Passed the value that's to be written, 351599121bSAlistair Francis * immediately before the actual write. The returned value is what is written, 361599121bSAlistair Francis * giving the handler a chance to modify the written value. 371599121bSAlistair Francis * @post_write: Post write callback. Passed the written value. Most write side 384e5f0fb7SAlistair Francis * effects should be implemented here. This is called during device reset. 391599121bSAlistair Francis * 401599121bSAlistair Francis * @post_read: Post read callback. Passes the value that is about to be returned 411599121bSAlistair Francis * for a read. The return value from this function is what is ultimately read, 421599121bSAlistair Francis * allowing this function to modify the value before return to the client. 431599121bSAlistair Francis */ 441599121bSAlistair Francis 451599121bSAlistair Francis struct RegisterAccessInfo { 461599121bSAlistair Francis const char *name; 471599121bSAlistair Francis uint64_t ro; 481599121bSAlistair Francis uint64_t w1c; 491599121bSAlistair Francis uint64_t reset; 501599121bSAlistair Francis uint64_t cor; 511599121bSAlistair Francis uint64_t rsvd; 521599121bSAlistair Francis uint64_t unimp; 531599121bSAlistair Francis 541599121bSAlistair Francis uint64_t (*pre_write)(RegisterInfo *reg, uint64_t val); 551599121bSAlistair Francis void (*post_write)(RegisterInfo *reg, uint64_t val); 561599121bSAlistair Francis 571599121bSAlistair Francis uint64_t (*post_read)(RegisterInfo *reg, uint64_t val); 580b73c9bbSAlistair Francis 590b73c9bbSAlistair Francis hwaddr addr; 601599121bSAlistair Francis }; 611599121bSAlistair Francis 621599121bSAlistair Francis /** 631599121bSAlistair Francis * A register that is part of guest accessible state 641599121bSAlistair Francis * @data: pointer to the register data. Will be cast 651599121bSAlistair Francis * to the relevant uint type depending on data_size. 661599121bSAlistair Francis * @data_size: Size of the register in bytes. Must be 671599121bSAlistair Francis * 1, 2, 4 or 8 681599121bSAlistair Francis * 691599121bSAlistair Francis * @access: Access description of this register 701599121bSAlistair Francis * 711599121bSAlistair Francis * @debug: Whether or not verbose debug is enabled 721599121bSAlistair Francis * @prefix: String prefix for log and debug messages 731599121bSAlistair Francis * 741599121bSAlistair Francis * @opaque: Opaque data for the register 751599121bSAlistair Francis */ 761599121bSAlistair Francis 771599121bSAlistair Francis struct RegisterInfo { 7849e14ddbSPeter Crosthwaite /* <private> */ 7949e14ddbSPeter Crosthwaite DeviceState parent_obj; 8049e14ddbSPeter Crosthwaite 811599121bSAlistair Francis /* <public> */ 821599121bSAlistair Francis void *data; 831599121bSAlistair Francis int data_size; 841599121bSAlistair Francis 851599121bSAlistair Francis const RegisterAccessInfo *access; 861599121bSAlistair Francis 871599121bSAlistair Francis void *opaque; 881599121bSAlistair Francis }; 891599121bSAlistair Francis 90*e178113fSMarkus Armbruster #define TYPE_REGISTER "qemu-register" 918110fa1dSEduardo Habkost DECLARE_INSTANCE_CHECKER(RegisterInfo, REGISTER, 928110fa1dSEduardo Habkost TYPE_REGISTER) 9349e14ddbSPeter Crosthwaite 941599121bSAlistair Francis /** 950b73c9bbSAlistair Francis * This structure is used to group all of the individual registers which are 960b73c9bbSAlistair Francis * modeled using the RegisterInfo structure. 970b73c9bbSAlistair Francis * 985bb8590dSStefan Weil * @r is an array containing of all the relevant RegisterInfo structures. 990b73c9bbSAlistair Francis * 1000b73c9bbSAlistair Francis * @num_elements is the number of elements in the array r 1010b73c9bbSAlistair Francis * 1020b73c9bbSAlistair Francis * @mem: optional Memory region for the register 1030b73c9bbSAlistair Francis */ 1040b73c9bbSAlistair Francis 1050b73c9bbSAlistair Francis struct RegisterInfoArray { 106a7422959SPeter Crosthwaite MemoryRegion mem; 107a7422959SPeter Crosthwaite 1080b73c9bbSAlistair Francis int num_elements; 1090b73c9bbSAlistair Francis RegisterInfo **r; 1100b73c9bbSAlistair Francis 1110b73c9bbSAlistair Francis bool debug; 1120b73c9bbSAlistair Francis const char *prefix; 1130b73c9bbSAlistair Francis }; 1140b73c9bbSAlistair Francis 1150b73c9bbSAlistair Francis /** 1161599121bSAlistair Francis * write a value to a register, subject to its restrictions 1171599121bSAlistair Francis * @reg: register to write to 1181599121bSAlistair Francis * @val: value to write 1191599121bSAlistair Francis * @we: write enable mask 1201599121bSAlistair Francis * @prefix: The device prefix that should be printed before the register name 1211599121bSAlistair Francis * @debug: Should the write operation debug information be printed? 1221599121bSAlistair Francis */ 1231599121bSAlistair Francis 1241599121bSAlistair Francis void register_write(RegisterInfo *reg, uint64_t val, uint64_t we, 1251599121bSAlistair Francis const char *prefix, bool debug); 1261599121bSAlistair Francis 1271599121bSAlistair Francis /** 1281599121bSAlistair Francis * read a value from a register, subject to its restrictions 1291599121bSAlistair Francis * @reg: register to read from 1301599121bSAlistair Francis * @re: read enable mask 1311599121bSAlistair Francis * @prefix: The device prefix that should be printed before the register name 1321599121bSAlistair Francis * @debug: Should the read operation debug information be printed? 1331599121bSAlistair Francis * returns: value read 1341599121bSAlistair Francis */ 1351599121bSAlistair Francis 1361599121bSAlistair Francis uint64_t register_read(RegisterInfo *reg, uint64_t re, const char* prefix, 1371599121bSAlistair Francis bool debug); 1381599121bSAlistair Francis 1391599121bSAlistair Francis /** 1404e5f0fb7SAlistair Francis * Resets a register. This will also call the post_write hook if it exists. 1414e5f0fb7SAlistair Francis * @reg: The register to reset. 1421599121bSAlistair Francis */ 1431599121bSAlistair Francis 1441599121bSAlistair Francis void register_reset(RegisterInfo *reg); 1451599121bSAlistair Francis 1460b73c9bbSAlistair Francis /** 14749e14ddbSPeter Crosthwaite * Initialize a register. 14849e14ddbSPeter Crosthwaite * @reg: Register to initialize 14949e14ddbSPeter Crosthwaite */ 15049e14ddbSPeter Crosthwaite 15149e14ddbSPeter Crosthwaite void register_init(RegisterInfo *reg); 15249e14ddbSPeter Crosthwaite 15349e14ddbSPeter Crosthwaite /** 1540b73c9bbSAlistair Francis * Memory API MMIO write handler that will write to a Register API register. 1550b73c9bbSAlistair Francis * @opaque: RegisterInfo to write to 1560b73c9bbSAlistair Francis * @addr: Address to write 1570b73c9bbSAlistair Francis * @value: Value to write 1580b73c9bbSAlistair Francis * @size: Number of bytes to write 1590b73c9bbSAlistair Francis */ 1600b73c9bbSAlistair Francis 1610b73c9bbSAlistair Francis void register_write_memory(void *opaque, hwaddr addr, uint64_t value, 1620b73c9bbSAlistair Francis unsigned size); 1630b73c9bbSAlistair Francis 1640b73c9bbSAlistair Francis /** 1650b73c9bbSAlistair Francis * Memory API MMIO read handler that will read from a Register API register. 1660b73c9bbSAlistair Francis * @opaque: RegisterInfo to read from 1670b73c9bbSAlistair Francis * @addr: Address to read 1680b73c9bbSAlistair Francis * @size: Number of bytes to read 1690b73c9bbSAlistair Francis * returns: Value read from register 1700b73c9bbSAlistair Francis */ 1710b73c9bbSAlistair Francis 1720b73c9bbSAlistair Francis uint64_t register_read_memory(void *opaque, hwaddr addr, unsigned size); 1730b73c9bbSAlistair Francis 174a7422959SPeter Crosthwaite /** 175a7422959SPeter Crosthwaite * Init a block of registers into a container MemoryRegion. A 176a7422959SPeter Crosthwaite * number of constant register definitions are parsed to create a corresponding 177a7422959SPeter Crosthwaite * array of RegisterInfo's. 178a7422959SPeter Crosthwaite * 179a7422959SPeter Crosthwaite * @owner: device owning the registers 180a7422959SPeter Crosthwaite * @rae: Register definitions to init 181a7422959SPeter Crosthwaite * @num: number of registers to init (length of @rae) 182a7422959SPeter Crosthwaite * @ri: Register array to init, must already be allocated 183a7422959SPeter Crosthwaite * @data: Array to use for register data, must already be allocated 184a7422959SPeter Crosthwaite * @ops: Memory region ops to access registers. 185a7422959SPeter Crosthwaite * @debug enabled: turn on/off verbose debug information 186268f5497SPhilippe Mathieu-Daudé * @memory_size: Size of the memory region 187a7422959SPeter Crosthwaite * returns: A structure containing all of the registers and an initialized 188a7422959SPeter Crosthwaite * memory region (r_array->mem) the caller should add to a container. 189a7422959SPeter Crosthwaite */ 190a7422959SPeter Crosthwaite 191f08085f4SJoaquin de Andres RegisterInfoArray *register_init_block8(DeviceState *owner, 192f08085f4SJoaquin de Andres const RegisterAccessInfo *rae, 193f08085f4SJoaquin de Andres int num, RegisterInfo *ri, 194f08085f4SJoaquin de Andres uint8_t *data, 195f08085f4SJoaquin de Andres const MemoryRegionOps *ops, 196f08085f4SJoaquin de Andres bool debug_enabled, 197f08085f4SJoaquin de Andres uint64_t memory_size); 198f08085f4SJoaquin de Andres 199a7422959SPeter Crosthwaite RegisterInfoArray *register_init_block32(DeviceState *owner, 200a7422959SPeter Crosthwaite const RegisterAccessInfo *rae, 201a7422959SPeter Crosthwaite int num, RegisterInfo *ri, 202a7422959SPeter Crosthwaite uint32_t *data, 203a7422959SPeter Crosthwaite const MemoryRegionOps *ops, 204a7422959SPeter Crosthwaite bool debug_enabled, 205a7422959SPeter Crosthwaite uint64_t memory_size); 206a7422959SPeter Crosthwaite 207a7422959SPeter Crosthwaite /** 208a7422959SPeter Crosthwaite * This function should be called to cleanup the registers that were initialized 209a7422959SPeter Crosthwaite * when calling register_init_block32(). This function should only be called 210a7422959SPeter Crosthwaite * from the device's instance_finalize function. 211a7422959SPeter Crosthwaite * 212a7422959SPeter Crosthwaite * Any memory operations that the device performed that require cleanup (such 213a7422959SPeter Crosthwaite * as creating subregions) need to be called before calling this function. 214a7422959SPeter Crosthwaite * 215a7422959SPeter Crosthwaite * @r_array: A structure containing all of the registers, as returned by 216a7422959SPeter Crosthwaite * register_init_block32() 217a7422959SPeter Crosthwaite */ 218a7422959SPeter Crosthwaite 219a7422959SPeter Crosthwaite void register_finalize_block(RegisterInfoArray *r_array); 220a7422959SPeter Crosthwaite 2211599121bSAlistair Francis #endif 222