Alistair Francis | 1599121 | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Register Definition API |
| 3 | * |
| 4 | * Copyright (c) 2016 Xilinx Inc. |
| 5 | * Copyright (c) 2013 Peter Crosthwaite <peter.crosthwaite@xilinx.com> |
| 6 | * |
| 7 | * This work is licensed under the terms of the GNU GPL, version 2. See |
| 8 | * the COPYING file in the top-level directory. |
| 9 | */ |
| 10 | |
| 11 | #ifndef REGISTER_H |
| 12 | #define REGISTER_H |
| 13 | |
Peter Crosthwaite | 49e14dd | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 14 | #include "hw/qdev-core.h" |
Alistair Francis | 1599121 | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 15 | #include "exec/memory.h" |
Peter Maydell | afb3141 | 2017-01-27 15:20:21 +0000 | [diff] [blame] | 16 | #include "hw/registerfields.h" |
Alistair Francis | 1599121 | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 17 | |
| 18 | typedef struct RegisterInfo RegisterInfo; |
| 19 | typedef struct RegisterAccessInfo RegisterAccessInfo; |
Alistair Francis | 0b73c9b | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 20 | typedef struct RegisterInfoArray RegisterInfoArray; |
Alistair Francis | 1599121 | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 21 | |
| 22 | /** |
| 23 | * Access description for a register that is part of guest accessible device |
| 24 | * state. |
| 25 | * |
| 26 | * @name: String name of the register |
| 27 | * @ro: whether or not the bit is read-only |
| 28 | * @w1c: bits with the common write 1 to clear semantic. |
| 29 | * @reset: reset value. |
| 30 | * @cor: Bits that are clear on read |
| 31 | * @rsvd: Bits that are reserved and should not be changed |
| 32 | * |
| 33 | * @pre_write: Pre write callback. Passed the value that's to be written, |
| 34 | * immediately before the actual write. The returned value is what is written, |
| 35 | * giving the handler a chance to modify the written value. |
| 36 | * @post_write: Post write callback. Passed the written value. Most write side |
Alistair Francis | 4e5f0fb | 2018-03-01 11:05:43 +0000 | [diff] [blame] | 37 | * effects should be implemented here. This is called during device reset. |
Alistair Francis | 1599121 | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 38 | * |
| 39 | * @post_read: Post read callback. Passes the value that is about to be returned |
| 40 | * for a read. The return value from this function is what is ultimately read, |
| 41 | * allowing this function to modify the value before return to the client. |
| 42 | */ |
| 43 | |
| 44 | struct RegisterAccessInfo { |
| 45 | const char *name; |
| 46 | uint64_t ro; |
| 47 | uint64_t w1c; |
| 48 | uint64_t reset; |
| 49 | uint64_t cor; |
| 50 | uint64_t rsvd; |
| 51 | uint64_t unimp; |
| 52 | |
| 53 | uint64_t (*pre_write)(RegisterInfo *reg, uint64_t val); |
| 54 | void (*post_write)(RegisterInfo *reg, uint64_t val); |
| 55 | |
| 56 | uint64_t (*post_read)(RegisterInfo *reg, uint64_t val); |
Alistair Francis | 0b73c9b | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 57 | |
| 58 | hwaddr addr; |
Alistair Francis | 1599121 | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 59 | }; |
| 60 | |
| 61 | /** |
| 62 | * A register that is part of guest accessible state |
| 63 | * @data: pointer to the register data. Will be cast |
| 64 | * to the relevant uint type depending on data_size. |
| 65 | * @data_size: Size of the register in bytes. Must be |
| 66 | * 1, 2, 4 or 8 |
| 67 | * |
| 68 | * @access: Access description of this register |
| 69 | * |
| 70 | * @debug: Whether or not verbose debug is enabled |
| 71 | * @prefix: String prefix for log and debug messages |
| 72 | * |
| 73 | * @opaque: Opaque data for the register |
| 74 | */ |
| 75 | |
| 76 | struct RegisterInfo { |
Peter Crosthwaite | 49e14dd | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 77 | /* <private> */ |
| 78 | DeviceState parent_obj; |
| 79 | |
Alistair Francis | 1599121 | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 80 | /* <public> */ |
| 81 | void *data; |
| 82 | int data_size; |
| 83 | |
| 84 | const RegisterAccessInfo *access; |
| 85 | |
| 86 | void *opaque; |
| 87 | }; |
| 88 | |
Peter Crosthwaite | 49e14dd | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 89 | #define TYPE_REGISTER "qemu,register" |
| 90 | #define REGISTER(obj) OBJECT_CHECK(RegisterInfo, (obj), TYPE_REGISTER) |
| 91 | |
Alistair Francis | 1599121 | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 92 | /** |
Alistair Francis | 0b73c9b | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 93 | * This structure is used to group all of the individual registers which are |
| 94 | * modeled using the RegisterInfo structure. |
| 95 | * |
Stefan Weil | 5bb8590 | 2016-11-19 20:47:15 +0100 | [diff] [blame] | 96 | * @r is an array containing of all the relevant RegisterInfo structures. |
Alistair Francis | 0b73c9b | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 97 | * |
| 98 | * @num_elements is the number of elements in the array r |
| 99 | * |
| 100 | * @mem: optional Memory region for the register |
| 101 | */ |
| 102 | |
| 103 | struct RegisterInfoArray { |
Peter Crosthwaite | a742295 | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 104 | MemoryRegion mem; |
| 105 | |
Alistair Francis | 0b73c9b | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 106 | int num_elements; |
| 107 | RegisterInfo **r; |
| 108 | |
| 109 | bool debug; |
| 110 | const char *prefix; |
| 111 | }; |
| 112 | |
| 113 | /** |
Alistair Francis | 1599121 | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 114 | * write a value to a register, subject to its restrictions |
| 115 | * @reg: register to write to |
| 116 | * @val: value to write |
| 117 | * @we: write enable mask |
| 118 | * @prefix: The device prefix that should be printed before the register name |
| 119 | * @debug: Should the write operation debug information be printed? |
| 120 | */ |
| 121 | |
| 122 | void register_write(RegisterInfo *reg, uint64_t val, uint64_t we, |
| 123 | const char *prefix, bool debug); |
| 124 | |
| 125 | /** |
| 126 | * read a value from a register, subject to its restrictions |
| 127 | * @reg: register to read from |
| 128 | * @re: read enable mask |
| 129 | * @prefix: The device prefix that should be printed before the register name |
| 130 | * @debug: Should the read operation debug information be printed? |
| 131 | * returns: value read |
| 132 | */ |
| 133 | |
| 134 | uint64_t register_read(RegisterInfo *reg, uint64_t re, const char* prefix, |
| 135 | bool debug); |
| 136 | |
| 137 | /** |
Alistair Francis | 4e5f0fb | 2018-03-01 11:05:43 +0000 | [diff] [blame] | 138 | * Resets a register. This will also call the post_write hook if it exists. |
| 139 | * @reg: The register to reset. |
Alistair Francis | 1599121 | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 140 | */ |
| 141 | |
| 142 | void register_reset(RegisterInfo *reg); |
| 143 | |
Alistair Francis | 0b73c9b | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 144 | /** |
Peter Crosthwaite | 49e14dd | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 145 | * Initialize a register. |
| 146 | * @reg: Register to initialize |
| 147 | */ |
| 148 | |
| 149 | void register_init(RegisterInfo *reg); |
| 150 | |
| 151 | /** |
Alistair Francis | 0b73c9b | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 152 | * Memory API MMIO write handler that will write to a Register API register. |
| 153 | * @opaque: RegisterInfo to write to |
| 154 | * @addr: Address to write |
| 155 | * @value: Value to write |
| 156 | * @size: Number of bytes to write |
| 157 | */ |
| 158 | |
| 159 | void register_write_memory(void *opaque, hwaddr addr, uint64_t value, |
| 160 | unsigned size); |
| 161 | |
| 162 | /** |
| 163 | * Memory API MMIO read handler that will read from a Register API register. |
| 164 | * @opaque: RegisterInfo to read from |
| 165 | * @addr: Address to read |
| 166 | * @size: Number of bytes to read |
| 167 | * returns: Value read from register |
| 168 | */ |
| 169 | |
| 170 | uint64_t register_read_memory(void *opaque, hwaddr addr, unsigned size); |
| 171 | |
Peter Crosthwaite | a742295 | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 172 | /** |
| 173 | * Init a block of registers into a container MemoryRegion. A |
| 174 | * number of constant register definitions are parsed to create a corresponding |
| 175 | * array of RegisterInfo's. |
| 176 | * |
| 177 | * @owner: device owning the registers |
| 178 | * @rae: Register definitions to init |
| 179 | * @num: number of registers to init (length of @rae) |
| 180 | * @ri: Register array to init, must already be allocated |
| 181 | * @data: Array to use for register data, must already be allocated |
| 182 | * @ops: Memory region ops to access registers. |
| 183 | * @debug enabled: turn on/off verbose debug information |
| 184 | * returns: A structure containing all of the registers and an initialized |
| 185 | * memory region (r_array->mem) the caller should add to a container. |
| 186 | */ |
| 187 | |
| 188 | RegisterInfoArray *register_init_block32(DeviceState *owner, |
| 189 | const RegisterAccessInfo *rae, |
| 190 | int num, RegisterInfo *ri, |
| 191 | uint32_t *data, |
| 192 | const MemoryRegionOps *ops, |
| 193 | bool debug_enabled, |
| 194 | uint64_t memory_size); |
| 195 | |
| 196 | /** |
| 197 | * This function should be called to cleanup the registers that were initialized |
| 198 | * when calling register_init_block32(). This function should only be called |
| 199 | * from the device's instance_finalize function. |
| 200 | * |
| 201 | * Any memory operations that the device performed that require cleanup (such |
| 202 | * as creating subregions) need to be called before calling this function. |
| 203 | * |
| 204 | * @r_array: A structure containing all of the registers, as returned by |
| 205 | * register_init_block32() |
| 206 | */ |
| 207 | |
| 208 | void register_finalize_block(RegisterInfoArray *r_array); |
| 209 | |
Alistair Francis | 1599121 | 2016-07-04 13:06:36 +0100 | [diff] [blame] | 210 | #endif |