qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

aspeed_gpio.c (48200B)


      1 /*
      2  *  ASPEED GPIO Controller
      3  *
      4  *  Copyright (C) 2017-2019 IBM Corp.
      5  *
      6  * SPDX-License-Identifier: GPL-2.0-or-later
      7  */
      8 
      9 #include "qemu/osdep.h"
     10 #include "qemu/host-utils.h"
     11 #include "qemu/log.h"
     12 #include "hw/gpio/aspeed_gpio.h"
     13 #include "hw/misc/aspeed_scu.h"
     14 #include "qapi/error.h"
     15 #include "qapi/visitor.h"
     16 #include "hw/irq.h"
     17 #include "migration/vmstate.h"
     18 #include "trace.h"
     19 #include "hw/registerfields.h"
     20 
     21 #define GPIOS_PER_GROUP 8
     22 
     23 /* GPIO Source Types */
     24 #define ASPEED_CMD_SRC_MASK         0x01010101
     25 #define ASPEED_SOURCE_ARM           0
     26 #define ASPEED_SOURCE_LPC           1
     27 #define ASPEED_SOURCE_COPROCESSOR   2
     28 #define ASPEED_SOURCE_RESERVED      3
     29 
     30 /* GPIO Interrupt Triggers */
     31 /*
     32  *  For each set of gpios there are three sensitivity registers that control
     33  *  the interrupt trigger mode.
     34  *
     35  *  | 2 | 1 | 0 | trigger mode
     36  *  -----------------------------
     37  *  | 0 | 0 | 0 | falling-edge
     38  *  | 0 | 0 | 1 | rising-edge
     39  *  | 0 | 1 | 0 | level-low
     40  *  | 0 | 1 | 1 | level-high
     41  *  | 1 | X | X | dual-edge
     42  */
     43 #define ASPEED_FALLING_EDGE 0
     44 #define ASPEED_RISING_EDGE  1
     45 #define ASPEED_LEVEL_LOW    2
     46 #define ASPEED_LEVEL_HIGH   3
     47 #define ASPEED_DUAL_EDGE    4
     48 
     49 /* GPIO Register Address Offsets */
     50 #define GPIO_ABCD_DATA_VALUE       (0x000 >> 2)
     51 #define GPIO_ABCD_DIRECTION        (0x004 >> 2)
     52 #define GPIO_ABCD_INT_ENABLE       (0x008 >> 2)
     53 #define GPIO_ABCD_INT_SENS_0       (0x00C >> 2)
     54 #define GPIO_ABCD_INT_SENS_1       (0x010 >> 2)
     55 #define GPIO_ABCD_INT_SENS_2       (0x014 >> 2)
     56 #define GPIO_ABCD_INT_STATUS       (0x018 >> 2)
     57 #define GPIO_ABCD_RESET_TOLERANT   (0x01C >> 2)
     58 #define GPIO_EFGH_DATA_VALUE       (0x020 >> 2)
     59 #define GPIO_EFGH_DIRECTION        (0x024 >> 2)
     60 #define GPIO_EFGH_INT_ENABLE       (0x028 >> 2)
     61 #define GPIO_EFGH_INT_SENS_0       (0x02C >> 2)
     62 #define GPIO_EFGH_INT_SENS_1       (0x030 >> 2)
     63 #define GPIO_EFGH_INT_SENS_2       (0x034 >> 2)
     64 #define GPIO_EFGH_INT_STATUS       (0x038 >> 2)
     65 #define GPIO_EFGH_RESET_TOLERANT   (0x03C >> 2)
     66 #define GPIO_ABCD_DEBOUNCE_1       (0x040 >> 2)
     67 #define GPIO_ABCD_DEBOUNCE_2       (0x044 >> 2)
     68 #define GPIO_EFGH_DEBOUNCE_1       (0x048 >> 2)
     69 #define GPIO_EFGH_DEBOUNCE_2       (0x04C >> 2)
     70 #define GPIO_DEBOUNCE_TIME_1       (0x050 >> 2)
     71 #define GPIO_DEBOUNCE_TIME_2       (0x054 >> 2)
     72 #define GPIO_DEBOUNCE_TIME_3       (0x058 >> 2)
     73 #define GPIO_ABCD_COMMAND_SRC_0    (0x060 >> 2)
     74 #define GPIO_ABCD_COMMAND_SRC_1    (0x064 >> 2)
     75 #define GPIO_EFGH_COMMAND_SRC_0    (0x068 >> 2)
     76 #define GPIO_EFGH_COMMAND_SRC_1    (0x06C >> 2)
     77 #define GPIO_IJKL_DATA_VALUE       (0x070 >> 2)
     78 #define GPIO_IJKL_DIRECTION        (0x074 >> 2)
     79 #define GPIO_MNOP_DATA_VALUE       (0x078 >> 2)
     80 #define GPIO_MNOP_DIRECTION        (0x07C >> 2)
     81 #define GPIO_QRST_DATA_VALUE       (0x080 >> 2)
     82 #define GPIO_QRST_DIRECTION        (0x084 >> 2)
     83 #define GPIO_UVWX_DATA_VALUE       (0x088 >> 2)
     84 #define GPIO_UVWX_DIRECTION        (0x08C >> 2)
     85 #define GPIO_IJKL_COMMAND_SRC_0    (0x090 >> 2)
     86 #define GPIO_IJKL_COMMAND_SRC_1    (0x094 >> 2)
     87 #define GPIO_IJKL_INT_ENABLE       (0x098 >> 2)
     88 #define GPIO_IJKL_INT_SENS_0       (0x09C >> 2)
     89 #define GPIO_IJKL_INT_SENS_1       (0x0A0 >> 2)
     90 #define GPIO_IJKL_INT_SENS_2       (0x0A4 >> 2)
     91 #define GPIO_IJKL_INT_STATUS       (0x0A8 >> 2)
     92 #define GPIO_IJKL_RESET_TOLERANT   (0x0AC >> 2)
     93 #define GPIO_IJKL_DEBOUNCE_1       (0x0B0 >> 2)
     94 #define GPIO_IJKL_DEBOUNCE_2       (0x0B4 >> 2)
     95 #define GPIO_IJKL_INPUT_MASK       (0x0B8 >> 2)
     96 #define GPIO_ABCD_DATA_READ        (0x0C0 >> 2)
     97 #define GPIO_EFGH_DATA_READ        (0x0C4 >> 2)
     98 #define GPIO_IJKL_DATA_READ        (0x0C8 >> 2)
     99 #define GPIO_MNOP_DATA_READ        (0x0CC >> 2)
    100 #define GPIO_QRST_DATA_READ        (0x0D0 >> 2)
    101 #define GPIO_UVWX_DATA_READ        (0x0D4 >> 2)
    102 #define GPIO_YZAAAB_DATA_READ      (0x0D8 >> 2)
    103 #define GPIO_AC_DATA_READ          (0x0DC >> 2)
    104 #define GPIO_MNOP_COMMAND_SRC_0    (0x0E0 >> 2)
    105 #define GPIO_MNOP_COMMAND_SRC_1    (0x0E4 >> 2)
    106 #define GPIO_MNOP_INT_ENABLE       (0x0E8 >> 2)
    107 #define GPIO_MNOP_INT_SENS_0       (0x0EC >> 2)
    108 #define GPIO_MNOP_INT_SENS_1       (0x0F0 >> 2)
    109 #define GPIO_MNOP_INT_SENS_2       (0x0F4 >> 2)
    110 #define GPIO_MNOP_INT_STATUS       (0x0F8 >> 2)
    111 #define GPIO_MNOP_RESET_TOLERANT   (0x0FC >> 2)
    112 #define GPIO_MNOP_DEBOUNCE_1       (0x100 >> 2)
    113 #define GPIO_MNOP_DEBOUNCE_2       (0x104 >> 2)
    114 #define GPIO_MNOP_INPUT_MASK       (0x108 >> 2)
    115 #define GPIO_QRST_COMMAND_SRC_0    (0x110 >> 2)
    116 #define GPIO_QRST_COMMAND_SRC_1    (0x114 >> 2)
    117 #define GPIO_QRST_INT_ENABLE       (0x118 >> 2)
    118 #define GPIO_QRST_INT_SENS_0       (0x11C >> 2)
    119 #define GPIO_QRST_INT_SENS_1       (0x120 >> 2)
    120 #define GPIO_QRST_INT_SENS_2       (0x124 >> 2)
    121 #define GPIO_QRST_INT_STATUS       (0x128 >> 2)
    122 #define GPIO_QRST_RESET_TOLERANT   (0x12C >> 2)
    123 #define GPIO_QRST_DEBOUNCE_1       (0x130 >> 2)
    124 #define GPIO_QRST_DEBOUNCE_2       (0x134 >> 2)
    125 #define GPIO_QRST_INPUT_MASK       (0x138 >> 2)
    126 #define GPIO_UVWX_COMMAND_SRC_0    (0x140 >> 2)
    127 #define GPIO_UVWX_COMMAND_SRC_1    (0x144 >> 2)
    128 #define GPIO_UVWX_INT_ENABLE       (0x148 >> 2)
    129 #define GPIO_UVWX_INT_SENS_0       (0x14C >> 2)
    130 #define GPIO_UVWX_INT_SENS_1       (0x150 >> 2)
    131 #define GPIO_UVWX_INT_SENS_2       (0x154 >> 2)
    132 #define GPIO_UVWX_INT_STATUS       (0x158 >> 2)
    133 #define GPIO_UVWX_RESET_TOLERANT   (0x15C >> 2)
    134 #define GPIO_UVWX_DEBOUNCE_1       (0x160 >> 2)
    135 #define GPIO_UVWX_DEBOUNCE_2       (0x164 >> 2)
    136 #define GPIO_UVWX_INPUT_MASK       (0x168 >> 2)
    137 #define GPIO_YZAAAB_COMMAND_SRC_0  (0x170 >> 2)
    138 #define GPIO_YZAAAB_COMMAND_SRC_1  (0x174 >> 2)
    139 #define GPIO_YZAAAB_INT_ENABLE     (0x178 >> 2)
    140 #define GPIO_YZAAAB_INT_SENS_0     (0x17C >> 2)
    141 #define GPIO_YZAAAB_INT_SENS_1     (0x180 >> 2)
    142 #define GPIO_YZAAAB_INT_SENS_2     (0x184 >> 2)
    143 #define GPIO_YZAAAB_INT_STATUS     (0x188 >> 2)
    144 #define GPIO_YZAAAB_RESET_TOLERANT (0x18C >> 2)
    145 #define GPIO_YZAAAB_DEBOUNCE_1     (0x190 >> 2)
    146 #define GPIO_YZAAAB_DEBOUNCE_2     (0x194 >> 2)
    147 #define GPIO_YZAAAB_INPUT_MASK     (0x198 >> 2)
    148 #define GPIO_AC_COMMAND_SRC_0      (0x1A0 >> 2)
    149 #define GPIO_AC_COMMAND_SRC_1      (0x1A4 >> 2)
    150 #define GPIO_AC_INT_ENABLE         (0x1A8 >> 2)
    151 #define GPIO_AC_INT_SENS_0         (0x1AC >> 2)
    152 #define GPIO_AC_INT_SENS_1         (0x1B0 >> 2)
    153 #define GPIO_AC_INT_SENS_2         (0x1B4 >> 2)
    154 #define GPIO_AC_INT_STATUS         (0x1B8 >> 2)
    155 #define GPIO_AC_RESET_TOLERANT     (0x1BC >> 2)
    156 #define GPIO_AC_DEBOUNCE_1         (0x1C0 >> 2)
    157 #define GPIO_AC_DEBOUNCE_2         (0x1C4 >> 2)
    158 #define GPIO_AC_INPUT_MASK         (0x1C8 >> 2)
    159 #define GPIO_ABCD_INPUT_MASK       (0x1D0 >> 2)
    160 #define GPIO_EFGH_INPUT_MASK       (0x1D4 >> 2)
    161 #define GPIO_YZAAAB_DATA_VALUE     (0x1E0 >> 2)
    162 #define GPIO_YZAAAB_DIRECTION      (0x1E4 >> 2)
    163 #define GPIO_AC_DATA_VALUE         (0x1E8 >> 2)
    164 #define GPIO_AC_DIRECTION          (0x1EC >> 2)
    165 #define GPIO_3_3V_MEM_SIZE         0x1F0
    166 #define GPIO_3_3V_REG_ARRAY_SIZE   (GPIO_3_3V_MEM_SIZE >> 2)
    167 
    168 /* AST2600 only - 1.8V gpios */
    169 /*
    170  * The AST2600 two copies of the GPIO controller: the same 3.3V gpios as the
    171  * AST2400 (memory offsets 0x0-0x198) and a second controller with 1.8V gpios
    172  * (memory offsets 0x800-0x9D4).
    173  */
    174 #define GPIO_1_8V_ABCD_DATA_VALUE     (0x000 >> 2)
    175 #define GPIO_1_8V_ABCD_DIRECTION      (0x004 >> 2)
    176 #define GPIO_1_8V_ABCD_INT_ENABLE     (0x008 >> 2)
    177 #define GPIO_1_8V_ABCD_INT_SENS_0     (0x00C >> 2)
    178 #define GPIO_1_8V_ABCD_INT_SENS_1     (0x010 >> 2)
    179 #define GPIO_1_8V_ABCD_INT_SENS_2     (0x014 >> 2)
    180 #define GPIO_1_8V_ABCD_INT_STATUS     (0x018 >> 2)
    181 #define GPIO_1_8V_ABCD_RESET_TOLERANT (0x01C >> 2)
    182 #define GPIO_1_8V_E_DATA_VALUE        (0x020 >> 2)
    183 #define GPIO_1_8V_E_DIRECTION         (0x024 >> 2)
    184 #define GPIO_1_8V_E_INT_ENABLE        (0x028 >> 2)
    185 #define GPIO_1_8V_E_INT_SENS_0        (0x02C >> 2)
    186 #define GPIO_1_8V_E_INT_SENS_1        (0x030 >> 2)
    187 #define GPIO_1_8V_E_INT_SENS_2        (0x034 >> 2)
    188 #define GPIO_1_8V_E_INT_STATUS        (0x038 >> 2)
    189 #define GPIO_1_8V_E_RESET_TOLERANT    (0x03C >> 2)
    190 #define GPIO_1_8V_ABCD_DEBOUNCE_1     (0x040 >> 2)
    191 #define GPIO_1_8V_ABCD_DEBOUNCE_2     (0x044 >> 2)
    192 #define GPIO_1_8V_E_DEBOUNCE_1        (0x048 >> 2)
    193 #define GPIO_1_8V_E_DEBOUNCE_2        (0x04C >> 2)
    194 #define GPIO_1_8V_DEBOUNCE_TIME_1     (0x050 >> 2)
    195 #define GPIO_1_8V_DEBOUNCE_TIME_2     (0x054 >> 2)
    196 #define GPIO_1_8V_DEBOUNCE_TIME_3     (0x058 >> 2)
    197 #define GPIO_1_8V_ABCD_COMMAND_SRC_0  (0x060 >> 2)
    198 #define GPIO_1_8V_ABCD_COMMAND_SRC_1  (0x064 >> 2)
    199 #define GPIO_1_8V_E_COMMAND_SRC_0     (0x068 >> 2)
    200 #define GPIO_1_8V_E_COMMAND_SRC_1     (0x06C >> 2)
    201 #define GPIO_1_8V_ABCD_DATA_READ      (0x0C0 >> 2)
    202 #define GPIO_1_8V_E_DATA_READ         (0x0C4 >> 2)
    203 #define GPIO_1_8V_ABCD_INPUT_MASK     (0x1D0 >> 2)
    204 #define GPIO_1_8V_E_INPUT_MASK        (0x1D4 >> 2)
    205 #define GPIO_1_8V_MEM_SIZE            0x1D8
    206 #define GPIO_1_8V_REG_ARRAY_SIZE      (GPIO_1_8V_MEM_SIZE >> 2)
    207 
    208 /*
    209  * GPIO index mode support
    210  * It only supports write operation
    211  */
    212 REG32(GPIO_INDEX_REG, 0x2AC)
    213     FIELD(GPIO_INDEX_REG, NUMBER, 0, 8)
    214     FIELD(GPIO_INDEX_REG, COMMAND, 12, 1)
    215     FIELD(GPIO_INDEX_REG, TYPE, 16, 4)
    216     FIELD(GPIO_INDEX_REG, DATA_VALUE, 20, 1)
    217     FIELD(GPIO_INDEX_REG, DIRECTION, 20, 1)
    218     FIELD(GPIO_INDEX_REG, INT_ENABLE, 20, 1)
    219     FIELD(GPIO_INDEX_REG, INT_SENS_0, 21, 1)
    220     FIELD(GPIO_INDEX_REG, INT_SENS_1, 22, 1)
    221     FIELD(GPIO_INDEX_REG, INT_SENS_2, 23, 1)
    222     FIELD(GPIO_INDEX_REG, INT_STATUS, 24, 1)
    223     FIELD(GPIO_INDEX_REG, DEBOUNCE_1, 20, 1)
    224     FIELD(GPIO_INDEX_REG, DEBOUNCE_2, 21, 1)
    225     FIELD(GPIO_INDEX_REG, RESET_TOLERANT, 20, 1)
    226     FIELD(GPIO_INDEX_REG, COMMAND_SRC_0, 20, 1)
    227     FIELD(GPIO_INDEX_REG, COMMAND_SRC_1, 21, 1)
    228     FIELD(GPIO_INDEX_REG, INPUT_MASK, 20, 1)
    229 
    230 static int aspeed_evaluate_irq(GPIOSets *regs, int gpio_prev_high, int gpio)
    231 {
    232     uint32_t falling_edge = 0, rising_edge = 0;
    233     uint32_t int_trigger = extract32(regs->int_sens_0, gpio, 1)
    234                            | extract32(regs->int_sens_1, gpio, 1) << 1
    235                            | extract32(regs->int_sens_2, gpio, 1) << 2;
    236     uint32_t gpio_curr_high = extract32(regs->data_value, gpio, 1);
    237     uint32_t gpio_int_enabled = extract32(regs->int_enable, gpio, 1);
    238 
    239     if (!gpio_int_enabled) {
    240         return 0;
    241     }
    242 
    243     /* Detect edges */
    244     if (gpio_curr_high && !gpio_prev_high) {
    245         rising_edge = 1;
    246     } else if (!gpio_curr_high && gpio_prev_high) {
    247         falling_edge = 1;
    248     }
    249 
    250     if (((int_trigger == ASPEED_FALLING_EDGE)  && falling_edge)  ||
    251         ((int_trigger == ASPEED_RISING_EDGE)  && rising_edge)    ||
    252         ((int_trigger == ASPEED_LEVEL_LOW)  && !gpio_curr_high)  ||
    253         ((int_trigger == ASPEED_LEVEL_HIGH)  && gpio_curr_high)  ||
    254         ((int_trigger >= ASPEED_DUAL_EDGE)  && (rising_edge || falling_edge)))
    255     {
    256         regs->int_status = deposit32(regs->int_status, gpio, 1, 1);
    257         return 1;
    258     }
    259     return 0;
    260 }
    261 
    262 #define nested_struct_index(ta, pa, m, tb, pb) \
    263         (pb - ((tb *)(((char *)pa) + offsetof(ta, m))))
    264 
    265 static ptrdiff_t aspeed_gpio_set_idx(AspeedGPIOState *s, GPIOSets *regs)
    266 {
    267     return nested_struct_index(AspeedGPIOState, s, sets, GPIOSets, regs);
    268 }
    269 
    270 static void aspeed_gpio_update(AspeedGPIOState *s, GPIOSets *regs,
    271                                uint32_t value, uint32_t mode_mask)
    272 {
    273     uint32_t input_mask = regs->input_mask;
    274     uint32_t direction = regs->direction;
    275     uint32_t old = regs->data_value;
    276     uint32_t new = value;
    277     uint32_t diff;
    278     int gpio;
    279 
    280     diff = (old ^ new);
    281     diff &= mode_mask;
    282     if (diff) {
    283         for (gpio = 0; gpio < ASPEED_GPIOS_PER_SET; gpio++) {
    284             uint32_t mask = 1 << gpio;
    285 
    286             /* If the gpio needs to be updated... */
    287             if (!(diff & mask)) {
    288                 continue;
    289             }
    290 
    291             /* ...and we're output or not input-masked... */
    292             if (!(direction & mask) && (input_mask & mask)) {
    293                 continue;
    294             }
    295 
    296             /* ...then update the state. */
    297             if (mask & new) {
    298                 regs->data_value |= mask;
    299             } else {
    300                 regs->data_value &= ~mask;
    301             }
    302 
    303             /* If the gpio is set to output... */
    304             if (direction & mask) {
    305                 /* ...trigger the line-state IRQ */
    306                 ptrdiff_t set = aspeed_gpio_set_idx(s, regs);
    307                 qemu_set_irq(s->gpios[set][gpio], !!(new & mask));
    308             } else {
    309                 /* ...otherwise if we meet the line's current IRQ policy... */
    310                 if (aspeed_evaluate_irq(regs, old & mask, gpio)) {
    311                     /* ...trigger the VIC IRQ */
    312                     s->pending++;
    313                 }
    314             }
    315         }
    316     }
    317     qemu_set_irq(s->irq, !!(s->pending));
    318 }
    319 
    320 static bool aspeed_gpio_get_pin_level(AspeedGPIOState *s, uint32_t set_idx,
    321                                       uint32_t pin)
    322 {
    323     uint32_t reg_val;
    324     uint32_t pin_mask = 1 << pin;
    325 
    326     reg_val = s->sets[set_idx].data_value;
    327 
    328     return !!(reg_val & pin_mask);
    329 }
    330 
    331 static void aspeed_gpio_set_pin_level(AspeedGPIOState *s, uint32_t set_idx,
    332                                       uint32_t pin, bool level)
    333 {
    334     uint32_t value = s->sets[set_idx].data_value;
    335     uint32_t pin_mask = 1 << pin;
    336 
    337     if (level) {
    338         value |= pin_mask;
    339     } else {
    340         value &= ~pin_mask;
    341     }
    342 
    343     aspeed_gpio_update(s, &s->sets[set_idx], value, ~s->sets[set_idx].direction);
    344 }
    345 
    346 /*
    347  *  | src_1 | src_2 |  source     |
    348  *  |-----------------------------|
    349  *  |   0   |   0   |  ARM        |
    350  *  |   0   |   1   |  LPC        |
    351  *  |   1   |   0   |  Coprocessor|
    352  *  |   1   |   1   |  Reserved   |
    353  *
    354  *  Once the source of a set is programmed, corresponding bits in the
    355  *  data_value, direction, interrupt [enable, sens[0-2]], reset_tol and
    356  *  debounce registers can only be written by the source.
    357  *
    358  *  Source is ARM by default
    359  *  only bits 24, 16, 8, and 0 can be set
    360  *
    361  *  we don't currently have a model for the LPC or Coprocessor
    362  */
    363 static uint32_t update_value_control_source(GPIOSets *regs, uint32_t old_value,
    364                                             uint32_t value)
    365 {
    366     int i;
    367     int cmd_source;
    368 
    369     /* assume the source is always ARM for now */
    370     int source = ASPEED_SOURCE_ARM;
    371 
    372     uint32_t new_value = 0;
    373 
    374     /* for each group in set */
    375     for (i = 0; i < ASPEED_GPIOS_PER_SET; i += GPIOS_PER_GROUP) {
    376         cmd_source = extract32(regs->cmd_source_0, i, 1)
    377                 | (extract32(regs->cmd_source_1, i, 1) << 1);
    378 
    379         if (source == cmd_source) {
    380             new_value |= (0xff << i) & value;
    381         } else {
    382             new_value |= (0xff << i) & old_value;
    383         }
    384     }
    385     return new_value;
    386 }
    387 
    388 static const AspeedGPIOReg aspeed_3_3v_gpios[GPIO_3_3V_REG_ARRAY_SIZE] = {
    389     /* Set ABCD */
    390     [GPIO_ABCD_DATA_VALUE] =     { 0, gpio_reg_data_value },
    391     [GPIO_ABCD_DIRECTION] =      { 0, gpio_reg_direction },
    392     [GPIO_ABCD_INT_ENABLE] =     { 0, gpio_reg_int_enable },
    393     [GPIO_ABCD_INT_SENS_0] =     { 0, gpio_reg_int_sens_0 },
    394     [GPIO_ABCD_INT_SENS_1] =     { 0, gpio_reg_int_sens_1 },
    395     [GPIO_ABCD_INT_SENS_2] =     { 0, gpio_reg_int_sens_2 },
    396     [GPIO_ABCD_INT_STATUS] =     { 0, gpio_reg_int_status },
    397     [GPIO_ABCD_RESET_TOLERANT] = { 0, gpio_reg_reset_tolerant },
    398     [GPIO_ABCD_DEBOUNCE_1] =     { 0, gpio_reg_debounce_1 },
    399     [GPIO_ABCD_DEBOUNCE_2] =     { 0, gpio_reg_debounce_2 },
    400     [GPIO_ABCD_COMMAND_SRC_0] =  { 0, gpio_reg_cmd_source_0 },
    401     [GPIO_ABCD_COMMAND_SRC_1] =  { 0, gpio_reg_cmd_source_1 },
    402     [GPIO_ABCD_DATA_READ] =      { 0, gpio_reg_data_read },
    403     [GPIO_ABCD_INPUT_MASK] =     { 0, gpio_reg_input_mask },
    404     /* Set EFGH */
    405     [GPIO_EFGH_DATA_VALUE] =     { 1, gpio_reg_data_value },
    406     [GPIO_EFGH_DIRECTION] =      { 1, gpio_reg_direction },
    407     [GPIO_EFGH_INT_ENABLE] =     { 1, gpio_reg_int_enable },
    408     [GPIO_EFGH_INT_SENS_0] =     { 1, gpio_reg_int_sens_0 },
    409     [GPIO_EFGH_INT_SENS_1] =     { 1, gpio_reg_int_sens_1 },
    410     [GPIO_EFGH_INT_SENS_2] =     { 1, gpio_reg_int_sens_2 },
    411     [GPIO_EFGH_INT_STATUS] =     { 1, gpio_reg_int_status },
    412     [GPIO_EFGH_RESET_TOLERANT] = { 1, gpio_reg_reset_tolerant },
    413     [GPIO_EFGH_DEBOUNCE_1] =     { 1, gpio_reg_debounce_1 },
    414     [GPIO_EFGH_DEBOUNCE_2] =     { 1, gpio_reg_debounce_2 },
    415     [GPIO_EFGH_COMMAND_SRC_0] =  { 1, gpio_reg_cmd_source_0 },
    416     [GPIO_EFGH_COMMAND_SRC_1] =  { 1, gpio_reg_cmd_source_1 },
    417     [GPIO_EFGH_DATA_READ] =      { 1, gpio_reg_data_read },
    418     [GPIO_EFGH_INPUT_MASK] =     { 1, gpio_reg_input_mask },
    419     /* Set IJKL */
    420     [GPIO_IJKL_DATA_VALUE] =     { 2, gpio_reg_data_value },
    421     [GPIO_IJKL_DIRECTION] =      { 2, gpio_reg_direction },
    422     [GPIO_IJKL_INT_ENABLE] =     { 2, gpio_reg_int_enable },
    423     [GPIO_IJKL_INT_SENS_0] =     { 2, gpio_reg_int_sens_0 },
    424     [GPIO_IJKL_INT_SENS_1] =     { 2, gpio_reg_int_sens_1 },
    425     [GPIO_IJKL_INT_SENS_2] =     { 2, gpio_reg_int_sens_2 },
    426     [GPIO_IJKL_INT_STATUS] =     { 2, gpio_reg_int_status },
    427     [GPIO_IJKL_RESET_TOLERANT] = { 2, gpio_reg_reset_tolerant },
    428     [GPIO_IJKL_DEBOUNCE_1] =     { 2, gpio_reg_debounce_1 },
    429     [GPIO_IJKL_DEBOUNCE_2] =     { 2, gpio_reg_debounce_2 },
    430     [GPIO_IJKL_COMMAND_SRC_0] =  { 2, gpio_reg_cmd_source_0 },
    431     [GPIO_IJKL_COMMAND_SRC_1] =  { 2, gpio_reg_cmd_source_1 },
    432     [GPIO_IJKL_DATA_READ] =      { 2, gpio_reg_data_read },
    433     [GPIO_IJKL_INPUT_MASK] =     { 2, gpio_reg_input_mask },
    434     /* Set MNOP */
    435     [GPIO_MNOP_DATA_VALUE] =     { 3, gpio_reg_data_value },
    436     [GPIO_MNOP_DIRECTION] =      { 3, gpio_reg_direction },
    437     [GPIO_MNOP_INT_ENABLE] =     { 3, gpio_reg_int_enable },
    438     [GPIO_MNOP_INT_SENS_0] =     { 3, gpio_reg_int_sens_0 },
    439     [GPIO_MNOP_INT_SENS_1] =     { 3, gpio_reg_int_sens_1 },
    440     [GPIO_MNOP_INT_SENS_2] =     { 3, gpio_reg_int_sens_2 },
    441     [GPIO_MNOP_INT_STATUS] =     { 3, gpio_reg_int_status },
    442     [GPIO_MNOP_RESET_TOLERANT] = { 3, gpio_reg_reset_tolerant },
    443     [GPIO_MNOP_DEBOUNCE_1] =     { 3, gpio_reg_debounce_1 },
    444     [GPIO_MNOP_DEBOUNCE_2] =     { 3, gpio_reg_debounce_2 },
    445     [GPIO_MNOP_COMMAND_SRC_0] =  { 3, gpio_reg_cmd_source_0 },
    446     [GPIO_MNOP_COMMAND_SRC_1] =  { 3, gpio_reg_cmd_source_1 },
    447     [GPIO_MNOP_DATA_READ] =      { 3, gpio_reg_data_read },
    448     [GPIO_MNOP_INPUT_MASK] =     { 3, gpio_reg_input_mask },
    449     /* Set QRST */
    450     [GPIO_QRST_DATA_VALUE] =     { 4, gpio_reg_data_value },
    451     [GPIO_QRST_DIRECTION] =      { 4, gpio_reg_direction },
    452     [GPIO_QRST_INT_ENABLE] =     { 4, gpio_reg_int_enable },
    453     [GPIO_QRST_INT_SENS_0] =     { 4, gpio_reg_int_sens_0 },
    454     [GPIO_QRST_INT_SENS_1] =     { 4, gpio_reg_int_sens_1 },
    455     [GPIO_QRST_INT_SENS_2] =     { 4, gpio_reg_int_sens_2 },
    456     [GPIO_QRST_INT_STATUS] =     { 4, gpio_reg_int_status },
    457     [GPIO_QRST_RESET_TOLERANT] = { 4, gpio_reg_reset_tolerant },
    458     [GPIO_QRST_DEBOUNCE_1] =     { 4, gpio_reg_debounce_1 },
    459     [GPIO_QRST_DEBOUNCE_2] =     { 4, gpio_reg_debounce_2 },
    460     [GPIO_QRST_COMMAND_SRC_0] =  { 4, gpio_reg_cmd_source_0 },
    461     [GPIO_QRST_COMMAND_SRC_1] =  { 4, gpio_reg_cmd_source_1 },
    462     [GPIO_QRST_DATA_READ] =      { 4, gpio_reg_data_read },
    463     [GPIO_QRST_INPUT_MASK] =     { 4, gpio_reg_input_mask },
    464     /* Set UVWX */
    465     [GPIO_UVWX_DATA_VALUE] =     { 5, gpio_reg_data_value },
    466     [GPIO_UVWX_DIRECTION] =      { 5, gpio_reg_direction },
    467     [GPIO_UVWX_INT_ENABLE] =     { 5, gpio_reg_int_enable },
    468     [GPIO_UVWX_INT_SENS_0] =     { 5, gpio_reg_int_sens_0 },
    469     [GPIO_UVWX_INT_SENS_1] =     { 5, gpio_reg_int_sens_1 },
    470     [GPIO_UVWX_INT_SENS_2] =     { 5, gpio_reg_int_sens_2 },
    471     [GPIO_UVWX_INT_STATUS] =     { 5, gpio_reg_int_status },
    472     [GPIO_UVWX_RESET_TOLERANT] = { 5, gpio_reg_reset_tolerant },
    473     [GPIO_UVWX_DEBOUNCE_1] =     { 5, gpio_reg_debounce_1 },
    474     [GPIO_UVWX_DEBOUNCE_2] =     { 5, gpio_reg_debounce_2 },
    475     [GPIO_UVWX_COMMAND_SRC_0] =  { 5, gpio_reg_cmd_source_0 },
    476     [GPIO_UVWX_COMMAND_SRC_1] =  { 5, gpio_reg_cmd_source_1 },
    477     [GPIO_UVWX_DATA_READ] =      { 5, gpio_reg_data_read },
    478     [GPIO_UVWX_INPUT_MASK] =     { 5, gpio_reg_input_mask },
    479     /* Set YZAAAB */
    480     [GPIO_YZAAAB_DATA_VALUE] =     { 6, gpio_reg_data_value },
    481     [GPIO_YZAAAB_DIRECTION] =      { 6, gpio_reg_direction },
    482     [GPIO_YZAAAB_INT_ENABLE] =     { 6, gpio_reg_int_enable },
    483     [GPIO_YZAAAB_INT_SENS_0] =     { 6, gpio_reg_int_sens_0 },
    484     [GPIO_YZAAAB_INT_SENS_1] =     { 6, gpio_reg_int_sens_1 },
    485     [GPIO_YZAAAB_INT_SENS_2] =     { 6, gpio_reg_int_sens_2 },
    486     [GPIO_YZAAAB_INT_STATUS] =     { 6, gpio_reg_int_status },
    487     [GPIO_YZAAAB_RESET_TOLERANT] = { 6, gpio_reg_reset_tolerant },
    488     [GPIO_YZAAAB_DEBOUNCE_1] =     { 6, gpio_reg_debounce_1 },
    489     [GPIO_YZAAAB_DEBOUNCE_2] =     { 6, gpio_reg_debounce_2 },
    490     [GPIO_YZAAAB_COMMAND_SRC_0] =  { 6, gpio_reg_cmd_source_0 },
    491     [GPIO_YZAAAB_COMMAND_SRC_1] =  { 6, gpio_reg_cmd_source_1 },
    492     [GPIO_YZAAAB_DATA_READ] =      { 6, gpio_reg_data_read },
    493     [GPIO_YZAAAB_INPUT_MASK] =     { 6, gpio_reg_input_mask },
    494     /* Set AC  (ast2500 only) */
    495     [GPIO_AC_DATA_VALUE] =         { 7, gpio_reg_data_value },
    496     [GPIO_AC_DIRECTION] =          { 7, gpio_reg_direction },
    497     [GPIO_AC_INT_ENABLE] =         { 7, gpio_reg_int_enable },
    498     [GPIO_AC_INT_SENS_0] =         { 7, gpio_reg_int_sens_0 },
    499     [GPIO_AC_INT_SENS_1] =         { 7, gpio_reg_int_sens_1 },
    500     [GPIO_AC_INT_SENS_2] =         { 7, gpio_reg_int_sens_2 },
    501     [GPIO_AC_INT_STATUS] =         { 7, gpio_reg_int_status },
    502     [GPIO_AC_RESET_TOLERANT] =     { 7, gpio_reg_reset_tolerant },
    503     [GPIO_AC_DEBOUNCE_1] =         { 7, gpio_reg_debounce_1 },
    504     [GPIO_AC_DEBOUNCE_2] =         { 7, gpio_reg_debounce_2 },
    505     [GPIO_AC_COMMAND_SRC_0] =      { 7, gpio_reg_cmd_source_0 },
    506     [GPIO_AC_COMMAND_SRC_1] =      { 7, gpio_reg_cmd_source_1 },
    507     [GPIO_AC_DATA_READ] =          { 7, gpio_reg_data_read },
    508     [GPIO_AC_INPUT_MASK] =         { 7, gpio_reg_input_mask },
    509 };
    510 
    511 static const AspeedGPIOReg aspeed_1_8v_gpios[GPIO_1_8V_REG_ARRAY_SIZE] = {
    512     /* 1.8V Set ABCD */
    513     [GPIO_1_8V_ABCD_DATA_VALUE] =     {0, gpio_reg_data_value},
    514     [GPIO_1_8V_ABCD_DIRECTION] =      {0, gpio_reg_direction},
    515     [GPIO_1_8V_ABCD_INT_ENABLE] =     {0, gpio_reg_int_enable},
    516     [GPIO_1_8V_ABCD_INT_SENS_0] =     {0, gpio_reg_int_sens_0},
    517     [GPIO_1_8V_ABCD_INT_SENS_1] =     {0, gpio_reg_int_sens_1},
    518     [GPIO_1_8V_ABCD_INT_SENS_2] =     {0, gpio_reg_int_sens_2},
    519     [GPIO_1_8V_ABCD_INT_STATUS] =     {0, gpio_reg_int_status},
    520     [GPIO_1_8V_ABCD_RESET_TOLERANT] = {0, gpio_reg_reset_tolerant},
    521     [GPIO_1_8V_ABCD_DEBOUNCE_1] =     {0, gpio_reg_debounce_1},
    522     [GPIO_1_8V_ABCD_DEBOUNCE_2] =     {0, gpio_reg_debounce_2},
    523     [GPIO_1_8V_ABCD_COMMAND_SRC_0] =  {0, gpio_reg_cmd_source_0},
    524     [GPIO_1_8V_ABCD_COMMAND_SRC_1] =  {0, gpio_reg_cmd_source_1},
    525     [GPIO_1_8V_ABCD_DATA_READ] =      {0, gpio_reg_data_read},
    526     [GPIO_1_8V_ABCD_INPUT_MASK] =     {0, gpio_reg_input_mask},
    527     /* 1.8V Set E */
    528     [GPIO_1_8V_E_DATA_VALUE] =     {1, gpio_reg_data_value},
    529     [GPIO_1_8V_E_DIRECTION] =      {1, gpio_reg_direction},
    530     [GPIO_1_8V_E_INT_ENABLE] =     {1, gpio_reg_int_enable},
    531     [GPIO_1_8V_E_INT_SENS_0] =     {1, gpio_reg_int_sens_0},
    532     [GPIO_1_8V_E_INT_SENS_1] =     {1, gpio_reg_int_sens_1},
    533     [GPIO_1_8V_E_INT_SENS_2] =     {1, gpio_reg_int_sens_2},
    534     [GPIO_1_8V_E_INT_STATUS] =     {1, gpio_reg_int_status},
    535     [GPIO_1_8V_E_RESET_TOLERANT] = {1, gpio_reg_reset_tolerant},
    536     [GPIO_1_8V_E_DEBOUNCE_1] =     {1, gpio_reg_debounce_1},
    537     [GPIO_1_8V_E_DEBOUNCE_2] =     {1, gpio_reg_debounce_2},
    538     [GPIO_1_8V_E_COMMAND_SRC_0] =  {1, gpio_reg_cmd_source_0},
    539     [GPIO_1_8V_E_COMMAND_SRC_1] =  {1, gpio_reg_cmd_source_1},
    540     [GPIO_1_8V_E_DATA_READ] =      {1, gpio_reg_data_read},
    541     [GPIO_1_8V_E_INPUT_MASK] =     {1, gpio_reg_input_mask},
    542 };
    543 
    544 static uint64_t aspeed_gpio_read(void *opaque, hwaddr offset, uint32_t size)
    545 {
    546     AspeedGPIOState *s = ASPEED_GPIO(opaque);
    547     AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
    548     uint64_t idx = -1;
    549     const AspeedGPIOReg *reg;
    550     GPIOSets *set;
    551     uint32_t value = 0;
    552     uint64_t debounce_value;
    553 
    554     idx = offset >> 2;
    555     if (idx >= GPIO_DEBOUNCE_TIME_1 && idx <= GPIO_DEBOUNCE_TIME_3) {
    556         idx -= GPIO_DEBOUNCE_TIME_1;
    557         debounce_value = (uint64_t) s->debounce_regs[idx];
    558         trace_aspeed_gpio_read(offset, debounce_value);
    559         return debounce_value;
    560     }
    561 
    562     reg = &agc->reg_table[idx];
    563     if (reg->set_idx >= agc->nr_gpio_sets) {
    564         qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%"
    565                       PRIx64"\n", __func__, offset);
    566         return 0;
    567     }
    568 
    569     set = &s->sets[reg->set_idx];
    570     switch (reg->type) {
    571     case gpio_reg_data_value:
    572         value = set->data_value;
    573         break;
    574     case gpio_reg_direction:
    575         value = set->direction;
    576         break;
    577     case gpio_reg_int_enable:
    578         value = set->int_enable;
    579         break;
    580     case gpio_reg_int_sens_0:
    581         value = set->int_sens_0;
    582         break;
    583     case gpio_reg_int_sens_1:
    584         value = set->int_sens_1;
    585         break;
    586     case gpio_reg_int_sens_2:
    587         value = set->int_sens_2;
    588         break;
    589     case gpio_reg_int_status:
    590         value = set->int_status;
    591         break;
    592     case gpio_reg_reset_tolerant:
    593         value = set->reset_tol;
    594         break;
    595     case gpio_reg_debounce_1:
    596         value = set->debounce_1;
    597         break;
    598     case gpio_reg_debounce_2:
    599         value = set->debounce_2;
    600         break;
    601     case gpio_reg_cmd_source_0:
    602         value = set->cmd_source_0;
    603         break;
    604     case gpio_reg_cmd_source_1:
    605         value = set->cmd_source_1;
    606         break;
    607     case gpio_reg_data_read:
    608         value = set->data_read;
    609         break;
    610     case gpio_reg_input_mask:
    611         value = set->input_mask;
    612         break;
    613     default:
    614         qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%"
    615                       PRIx64"\n", __func__, offset);
    616         return 0;
    617     }
    618 
    619     trace_aspeed_gpio_read(offset, value);
    620     return value;
    621 }
    622 
    623 static void aspeed_gpio_write_index_mode(void *opaque, hwaddr offset,
    624                                                 uint64_t data, uint32_t size)
    625 {
    626 
    627     AspeedGPIOState *s = ASPEED_GPIO(opaque);
    628     AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
    629     const GPIOSetProperties *props;
    630     GPIOSets *set;
    631     uint32_t reg_idx_number = FIELD_EX32(data, GPIO_INDEX_REG, NUMBER);
    632     uint32_t reg_idx_type = FIELD_EX32(data, GPIO_INDEX_REG, TYPE);
    633     uint32_t reg_idx_command = FIELD_EX32(data, GPIO_INDEX_REG, COMMAND);
    634     uint32_t set_idx = reg_idx_number / ASPEED_GPIOS_PER_SET;
    635     uint32_t pin_idx = reg_idx_number % ASPEED_GPIOS_PER_SET;
    636     uint32_t group_idx = pin_idx / GPIOS_PER_GROUP;
    637     uint32_t reg_value = 0;
    638     uint32_t cleared;
    639 
    640     set = &s->sets[set_idx];
    641     props = &agc->props[set_idx];
    642 
    643     if (reg_idx_command)
    644         qemu_log_mask(LOG_GUEST_ERROR, "%s: offset 0x%" PRIx64 "data 0x%"
    645             PRIx64 "index mode wrong command 0x%x\n",
    646             __func__, offset, data, reg_idx_command);
    647 
    648     switch (reg_idx_type) {
    649     case gpio_reg_idx_data:
    650         reg_value = set->data_read;
    651         reg_value = deposit32(reg_value, pin_idx, 1,
    652                               FIELD_EX32(data, GPIO_INDEX_REG, DATA_VALUE));
    653         reg_value &= props->output;
    654         reg_value = update_value_control_source(set, set->data_value,
    655                                                 reg_value);
    656         set->data_read = reg_value;
    657         aspeed_gpio_update(s, set, reg_value, set->direction);
    658         return;
    659     case gpio_reg_idx_direction:
    660         reg_value = set->direction;
    661         reg_value = deposit32(reg_value, pin_idx, 1,
    662                               FIELD_EX32(data, GPIO_INDEX_REG, DIRECTION));
    663         /*
    664          *   where data is the value attempted to be written to the pin:
    665          *    pin type      | input mask | output mask | expected value
    666          *    ------------------------------------------------------------
    667          *   bidirectional  |   1       |   1        |  data
    668          *   input only     |   1       |   0        |   0
    669          *   output only    |   0       |   1        |   1
    670          *   no pin         |   0       |   0        |   0
    671          *
    672          *  which is captured by:
    673          *  data = ( data | ~input) & output;
    674          */
    675         reg_value = (reg_value | ~props->input) & props->output;
    676         set->direction = update_value_control_source(set, set->direction,
    677                                                      reg_value);
    678         break;
    679     case gpio_reg_idx_interrupt:
    680         reg_value = set->int_enable;
    681         reg_value = deposit32(reg_value, pin_idx, 1,
    682                               FIELD_EX32(data, GPIO_INDEX_REG, INT_ENABLE));
    683         set->int_enable = update_value_control_source(set, set->int_enable,
    684                                                       reg_value);
    685         reg_value = set->int_sens_0;
    686         reg_value = deposit32(reg_value, pin_idx, 1,
    687                               FIELD_EX32(data, GPIO_INDEX_REG, INT_SENS_0));
    688         set->int_sens_0 = update_value_control_source(set, set->int_sens_0,
    689                                                       reg_value);
    690         reg_value = set->int_sens_1;
    691         reg_value = deposit32(reg_value, pin_idx, 1,
    692                               FIELD_EX32(data, GPIO_INDEX_REG, INT_SENS_1));
    693         set->int_sens_1 = update_value_control_source(set, set->int_sens_1,
    694                                                       reg_value);
    695         reg_value = set->int_sens_2;
    696         reg_value = deposit32(reg_value, pin_idx, 1,
    697                               FIELD_EX32(data, GPIO_INDEX_REG, INT_SENS_2));
    698         set->int_sens_2 = update_value_control_source(set, set->int_sens_2,
    699                                                       reg_value);
    700         /* set interrupt status */
    701         reg_value = set->int_status;
    702         reg_value = deposit32(reg_value, pin_idx, 1,
    703                               FIELD_EX32(data, GPIO_INDEX_REG, INT_STATUS));
    704         cleared = ctpop32(reg_value & set->int_status);
    705         if (s->pending && cleared) {
    706             assert(s->pending >= cleared);
    707             s->pending -= cleared;
    708         }
    709         set->int_status &= ~reg_value;
    710         break;
    711     case gpio_reg_idx_debounce:
    712         reg_value = set->debounce_1;
    713         reg_value = deposit32(reg_value, pin_idx, 1,
    714                               FIELD_EX32(data, GPIO_INDEX_REG, DEBOUNCE_1));
    715         set->debounce_1 = update_value_control_source(set, set->debounce_1,
    716                                                       reg_value);
    717         reg_value = set->debounce_2;
    718         reg_value = deposit32(reg_value, pin_idx, 1,
    719                               FIELD_EX32(data, GPIO_INDEX_REG, DEBOUNCE_2));
    720         set->debounce_2 = update_value_control_source(set, set->debounce_2,
    721                                                       reg_value);
    722         return;
    723     case gpio_reg_idx_tolerance:
    724         reg_value = set->reset_tol;
    725         reg_value = deposit32(reg_value, pin_idx, 1,
    726                               FIELD_EX32(data, GPIO_INDEX_REG, RESET_TOLERANT));
    727         set->reset_tol = update_value_control_source(set, set->reset_tol,
    728                                                      reg_value);
    729         return;
    730     case gpio_reg_idx_cmd_src:
    731         reg_value = set->cmd_source_0;
    732         reg_value = deposit32(reg_value, GPIOS_PER_GROUP * group_idx, 1,
    733                               FIELD_EX32(data, GPIO_INDEX_REG, COMMAND_SRC_0));
    734         set->cmd_source_0 = reg_value & ASPEED_CMD_SRC_MASK;
    735         reg_value = set->cmd_source_1;
    736         reg_value = deposit32(reg_value, GPIOS_PER_GROUP * group_idx, 1,
    737                               FIELD_EX32(data, GPIO_INDEX_REG, COMMAND_SRC_1));
    738         set->cmd_source_1 = reg_value & ASPEED_CMD_SRC_MASK;
    739         return;
    740     case gpio_reg_idx_input_mask:
    741         reg_value = set->input_mask;
    742         reg_value = deposit32(reg_value, pin_idx, 1,
    743                               FIELD_EX32(data, GPIO_INDEX_REG, INPUT_MASK));
    744         /*
    745          * feeds into interrupt generation
    746          * 0: read from data value reg will be updated
    747          * 1: read from data value reg will not be updated
    748          */
    749         set->input_mask = reg_value & props->input;
    750         break;
    751     default:
    752         qemu_log_mask(LOG_GUEST_ERROR, "%s: offset 0x%" PRIx64 "data 0x%"
    753             PRIx64 "index mode wrong type 0x%x\n",
    754             __func__, offset, data, reg_idx_type);
    755         return;
    756     }
    757     aspeed_gpio_update(s, set, set->data_value, UINT32_MAX);
    758     return;
    759 }
    760 
    761 static void aspeed_gpio_write(void *opaque, hwaddr offset, uint64_t data,
    762                               uint32_t size)
    763 {
    764     AspeedGPIOState *s = ASPEED_GPIO(opaque);
    765     AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
    766     const GPIOSetProperties *props;
    767     uint64_t idx = -1;
    768     const AspeedGPIOReg *reg;
    769     GPIOSets *set;
    770     uint32_t cleared;
    771 
    772     trace_aspeed_gpio_write(offset, data);
    773 
    774     idx = offset >> 2;
    775 
    776     /* check gpio index mode */
    777     if (idx == R_GPIO_INDEX_REG) {
    778         aspeed_gpio_write_index_mode(opaque, offset, data, size);
    779         return;
    780     }
    781 
    782     if (idx >= GPIO_DEBOUNCE_TIME_1 && idx <= GPIO_DEBOUNCE_TIME_3) {
    783         idx -= GPIO_DEBOUNCE_TIME_1;
    784         s->debounce_regs[idx] = (uint32_t) data;
    785         return;
    786     }
    787 
    788     reg = &agc->reg_table[idx];
    789     if (reg->set_idx >= agc->nr_gpio_sets) {
    790         qemu_log_mask(LOG_GUEST_ERROR, "%s: no setter for offset 0x%"
    791                       PRIx64"\n", __func__, offset);
    792         return;
    793     }
    794 
    795     set = &s->sets[reg->set_idx];
    796     props = &agc->props[reg->set_idx];
    797 
    798     switch (reg->type) {
    799     case gpio_reg_data_value:
    800         data &= props->output;
    801         data = update_value_control_source(set, set->data_value, data);
    802         set->data_read = data;
    803         aspeed_gpio_update(s, set, data, set->direction);
    804         return;
    805     case gpio_reg_direction:
    806         /*
    807          *   where data is the value attempted to be written to the pin:
    808          *    pin type      | input mask | output mask | expected value
    809          *    ------------------------------------------------------------
    810          *   bidirectional  |   1       |   1        |  data
    811          *   input only     |   1       |   0        |   0
    812          *   output only    |   0       |   1        |   1
    813          *   no pin         |   0       |   0        |   0
    814          *
    815          *  which is captured by:
    816          *  data = ( data | ~input) & output;
    817          */
    818         data = (data | ~props->input) & props->output;
    819         set->direction = update_value_control_source(set, set->direction, data);
    820         break;
    821     case gpio_reg_int_enable:
    822         set->int_enable = update_value_control_source(set, set->int_enable,
    823                                                       data);
    824         break;
    825     case gpio_reg_int_sens_0:
    826         set->int_sens_0 = update_value_control_source(set, set->int_sens_0,
    827                                                       data);
    828         break;
    829     case gpio_reg_int_sens_1:
    830         set->int_sens_1 = update_value_control_source(set, set->int_sens_1,
    831                                                       data);
    832         break;
    833     case gpio_reg_int_sens_2:
    834         set->int_sens_2 = update_value_control_source(set, set->int_sens_2,
    835                                                       data);
    836         break;
    837     case gpio_reg_int_status:
    838         cleared = ctpop32(data & set->int_status);
    839         if (s->pending && cleared) {
    840             assert(s->pending >= cleared);
    841             s->pending -= cleared;
    842         }
    843         set->int_status &= ~data;
    844         break;
    845     case gpio_reg_reset_tolerant:
    846         set->reset_tol = update_value_control_source(set, set->reset_tol,
    847                                                      data);
    848         return;
    849     case gpio_reg_debounce_1:
    850         set->debounce_1 = update_value_control_source(set, set->debounce_1,
    851                                                       data);
    852         return;
    853     case gpio_reg_debounce_2:
    854         set->debounce_2 = update_value_control_source(set, set->debounce_2,
    855                                                       data);
    856         return;
    857     case gpio_reg_cmd_source_0:
    858         set->cmd_source_0 = data & ASPEED_CMD_SRC_MASK;
    859         return;
    860     case gpio_reg_cmd_source_1:
    861         set->cmd_source_1 = data & ASPEED_CMD_SRC_MASK;
    862         return;
    863     case gpio_reg_data_read:
    864         /* Read only register */
    865         return;
    866     case gpio_reg_input_mask:
    867         /*
    868          * feeds into interrupt generation
    869          * 0: read from data value reg will be updated
    870          * 1: read from data value reg will not be updated
    871          */
    872          set->input_mask = data & props->input;
    873         break;
    874     default:
    875         qemu_log_mask(LOG_GUEST_ERROR, "%s: no setter for offset 0x%"
    876                       PRIx64"\n", __func__, offset);
    877         return;
    878     }
    879     aspeed_gpio_update(s, set, set->data_value, UINT32_MAX);
    880     return;
    881 }
    882 
    883 static int get_set_idx(AspeedGPIOState *s, const char *group, int *group_idx)
    884 {
    885     AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
    886     int set_idx, g_idx;
    887 
    888     for (set_idx = 0; set_idx < agc->nr_gpio_sets; set_idx++) {
    889         const GPIOSetProperties *set_props = &agc->props[set_idx];
    890         for (g_idx = 0; g_idx < ASPEED_GROUPS_PER_SET; g_idx++) {
    891             if (!strncmp(group, set_props->group_label[g_idx], strlen(group))) {
    892                 *group_idx = g_idx;
    893                 return set_idx;
    894             }
    895         }
    896     }
    897     return -1;
    898 }
    899 
    900 static void aspeed_gpio_get_pin(Object *obj, Visitor *v, const char *name,
    901                                 void *opaque, Error **errp)
    902 {
    903     int pin = 0xfff;
    904     bool level = true;
    905     char group[4];
    906     AspeedGPIOState *s = ASPEED_GPIO(obj);
    907     int set_idx, group_idx = 0;
    908 
    909     if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) {
    910         /* 1.8V gpio */
    911         if (sscanf(name, "gpio%3[18A-E]%1d", group, &pin) != 2) {
    912             error_setg(errp, "%s: error reading %s", __func__, name);
    913             return;
    914         }
    915     }
    916     set_idx = get_set_idx(s, group, &group_idx);
    917     if (set_idx == -1) {
    918         error_setg(errp, "%s: invalid group %s", __func__, group);
    919         return;
    920     }
    921     pin =  pin + group_idx * GPIOS_PER_GROUP;
    922     level = aspeed_gpio_get_pin_level(s, set_idx, pin);
    923     visit_type_bool(v, name, &level, errp);
    924 }
    925 
    926 static void aspeed_gpio_set_pin(Object *obj, Visitor *v, const char *name,
    927                                void *opaque, Error **errp)
    928 {
    929     bool level;
    930     int pin = 0xfff;
    931     char group[4];
    932     AspeedGPIOState *s = ASPEED_GPIO(obj);
    933     int set_idx, group_idx = 0;
    934 
    935     if (!visit_type_bool(v, name, &level, errp)) {
    936         return;
    937     }
    938     if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) {
    939         /* 1.8V gpio */
    940         if (sscanf(name, "gpio%3[18A-E]%1d", group, &pin) != 2) {
    941             error_setg(errp, "%s: error reading %s", __func__, name);
    942             return;
    943         }
    944     }
    945     set_idx = get_set_idx(s, group, &group_idx);
    946     if (set_idx == -1) {
    947         error_setg(errp, "%s: invalid group %s", __func__, group);
    948         return;
    949     }
    950     pin =  pin + group_idx * GPIOS_PER_GROUP;
    951     aspeed_gpio_set_pin_level(s, set_idx, pin, level);
    952 }
    953 
    954 /****************** Setup functions ******************/
    955 static const GPIOSetProperties ast2400_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
    956     [0] = {0xffffffff,  0xffffffff,  {"A", "B", "C", "D"} },
    957     [1] = {0xffffffff,  0xffffffff,  {"E", "F", "G", "H"} },
    958     [2] = {0xffffffff,  0xffffffff,  {"I", "J", "K", "L"} },
    959     [3] = {0xffffffff,  0xffffffff,  {"M", "N", "O", "P"} },
    960     [4] = {0xffffffff,  0xffffffff,  {"Q", "R", "S", "T"} },
    961     [5] = {0xffffffff,  0x0000ffff,  {"U", "V", "W", "X"} },
    962     [6] = {0x0000000f,  0x0fffff0f,  {"Y", "Z", "AA", "AB"} },
    963 };
    964 
    965 static const GPIOSetProperties ast2500_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
    966     [0] = {0xffffffff,  0xffffffff,  {"A", "B", "C", "D"} },
    967     [1] = {0xffffffff,  0xffffffff,  {"E", "F", "G", "H"} },
    968     [2] = {0xffffffff,  0xffffffff,  {"I", "J", "K", "L"} },
    969     [3] = {0xffffffff,  0xffffffff,  {"M", "N", "O", "P"} },
    970     [4] = {0xffffffff,  0xffffffff,  {"Q", "R", "S", "T"} },
    971     [5] = {0xffffffff,  0x0000ffff,  {"U", "V", "W", "X"} },
    972     [6] = {0x0fffffff,  0x0fffffff,  {"Y", "Z", "AA", "AB"} },
    973     [7] = {0x000000ff,  0x000000ff,  {"AC"} },
    974 };
    975 
    976 static GPIOSetProperties ast2600_3_3v_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
    977     [0] = {0xffffffff,  0xffffffff,  {"A", "B", "C", "D"} },
    978     [1] = {0xffffffff,  0xffffffff,  {"E", "F", "G", "H"} },
    979     [2] = {0xffffffff,  0xffffffff,  {"I", "J", "K", "L"} },
    980     [3] = {0xffffffff,  0xffffffff,  {"M", "N", "O", "P"} },
    981     [4] = {0xffffffff,  0x00ffffff,  {"Q", "R", "S", "T"} },
    982     [5] = {0xffffffff,  0xffffff00,  {"U", "V", "W", "X"} },
    983     [6] = {0x0000ffff,  0x0000ffff,  {"Y", "Z"} },
    984 };
    985 
    986 static GPIOSetProperties ast2600_1_8v_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
    987     [0] = {0xffffffff,  0xffffffff,  {"18A", "18B", "18C", "18D"} },
    988     [1] = {0x0000000f,  0x0000000f,  {"18E"} },
    989 };
    990 
    991 static GPIOSetProperties ast1030_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
    992     [0] = {0xffffffff,  0xffffffff,  {"A", "B", "C", "D"} },
    993     [1] = {0xffffffff,  0xffffffff,  {"E", "F", "G", "H"} },
    994     [2] = {0xffffffff,  0xffffffff,  {"I", "J", "K", "L"} },
    995     [3] = {0xffffff3f,  0xffffff3f,  {"M", "N", "O", "P"} },
    996     [4] = {0xff060c1f,  0x00060c1f,  {"Q", "R", "S", "T"} },
    997     [5] = {0x000000ff,  0x00000000,  {"U"} },
    998 };
    999 
   1000 static const MemoryRegionOps aspeed_gpio_ops = {
   1001     .read       = aspeed_gpio_read,
   1002     .write      = aspeed_gpio_write,
   1003     .endianness = DEVICE_LITTLE_ENDIAN,
   1004     .valid.min_access_size = 4,
   1005     .valid.max_access_size = 4,
   1006 };
   1007 
   1008 static void aspeed_gpio_reset(DeviceState *dev)
   1009 {
   1010     AspeedGPIOState *s = ASPEED_GPIO(dev);
   1011 
   1012     /* TODO: respect the reset tolerance registers */
   1013     memset(s->sets, 0, sizeof(s->sets));
   1014 }
   1015 
   1016 static void aspeed_gpio_realize(DeviceState *dev, Error **errp)
   1017 {
   1018     AspeedGPIOState *s = ASPEED_GPIO(dev);
   1019     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
   1020     AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
   1021 
   1022     /* Interrupt parent line */
   1023     sysbus_init_irq(sbd, &s->irq);
   1024 
   1025     /* Individual GPIOs */
   1026     for (int i = 0; i < ASPEED_GPIO_MAX_NR_SETS; i++) {
   1027         const GPIOSetProperties *props = &agc->props[i];
   1028         uint32_t skip = ~(props->input | props->output);
   1029         for (int j = 0; j < ASPEED_GPIOS_PER_SET; j++) {
   1030             if (skip >> j & 1) {
   1031                 continue;
   1032             }
   1033             sysbus_init_irq(sbd, &s->gpios[i][j]);
   1034         }
   1035     }
   1036 
   1037     memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_gpio_ops, s,
   1038             TYPE_ASPEED_GPIO, 0x800);
   1039 
   1040     sysbus_init_mmio(sbd, &s->iomem);
   1041 }
   1042 
   1043 static void aspeed_gpio_init(Object *obj)
   1044 {
   1045     AspeedGPIOState *s = ASPEED_GPIO(obj);
   1046     AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
   1047 
   1048     for (int i = 0; i < ASPEED_GPIO_MAX_NR_SETS; i++) {
   1049         const GPIOSetProperties *props = &agc->props[i];
   1050         uint32_t skip = ~(props->input | props->output);
   1051         for (int j = 0; j < ASPEED_GPIOS_PER_SET; j++) {
   1052             if (skip >> j & 1) {
   1053                 continue;
   1054             }
   1055             int group_idx = j / GPIOS_PER_GROUP;
   1056             int pin_idx = j % GPIOS_PER_GROUP;
   1057             const char *group = &props->group_label[group_idx][0];
   1058             char *name = g_strdup_printf("gpio%s%d", group, pin_idx);
   1059             object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
   1060                                 aspeed_gpio_set_pin, NULL, NULL);
   1061             g_free(name);
   1062         }
   1063     }
   1064 }
   1065 
   1066 static const VMStateDescription vmstate_gpio_regs = {
   1067     .name = TYPE_ASPEED_GPIO"/regs",
   1068     .version_id = 1,
   1069     .minimum_version_id = 1,
   1070     .fields = (VMStateField[]) {
   1071         VMSTATE_UINT32(data_value,   GPIOSets),
   1072         VMSTATE_UINT32(data_read,    GPIOSets),
   1073         VMSTATE_UINT32(direction,    GPIOSets),
   1074         VMSTATE_UINT32(int_enable,   GPIOSets),
   1075         VMSTATE_UINT32(int_sens_0,   GPIOSets),
   1076         VMSTATE_UINT32(int_sens_1,   GPIOSets),
   1077         VMSTATE_UINT32(int_sens_2,   GPIOSets),
   1078         VMSTATE_UINT32(int_status,   GPIOSets),
   1079         VMSTATE_UINT32(reset_tol,    GPIOSets),
   1080         VMSTATE_UINT32(cmd_source_0, GPIOSets),
   1081         VMSTATE_UINT32(cmd_source_1, GPIOSets),
   1082         VMSTATE_UINT32(debounce_1,   GPIOSets),
   1083         VMSTATE_UINT32(debounce_2,   GPIOSets),
   1084         VMSTATE_UINT32(input_mask,   GPIOSets),
   1085         VMSTATE_END_OF_LIST(),
   1086     }
   1087 };
   1088 
   1089 static const VMStateDescription vmstate_aspeed_gpio = {
   1090     .name = TYPE_ASPEED_GPIO,
   1091     .version_id = 1,
   1092     .minimum_version_id = 1,
   1093     .fields = (VMStateField[]) {
   1094         VMSTATE_STRUCT_ARRAY(sets, AspeedGPIOState, ASPEED_GPIO_MAX_NR_SETS,
   1095                              1, vmstate_gpio_regs, GPIOSets),
   1096         VMSTATE_UINT32_ARRAY(debounce_regs, AspeedGPIOState,
   1097                              ASPEED_GPIO_NR_DEBOUNCE_REGS),
   1098         VMSTATE_END_OF_LIST(),
   1099    }
   1100 };
   1101 
   1102 static void aspeed_gpio_class_init(ObjectClass *klass, void *data)
   1103 {
   1104     DeviceClass *dc = DEVICE_CLASS(klass);
   1105 
   1106     dc->realize = aspeed_gpio_realize;
   1107     dc->reset = aspeed_gpio_reset;
   1108     dc->desc = "Aspeed GPIO Controller";
   1109     dc->vmsd = &vmstate_aspeed_gpio;
   1110 }
   1111 
   1112 static void aspeed_gpio_ast2400_class_init(ObjectClass *klass, void *data)
   1113 {
   1114     AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
   1115 
   1116     agc->props = ast2400_set_props;
   1117     agc->nr_gpio_pins = 216;
   1118     agc->nr_gpio_sets = 7;
   1119     agc->reg_table = aspeed_3_3v_gpios;
   1120 }
   1121 
   1122 static void aspeed_gpio_2500_class_init(ObjectClass *klass, void *data)
   1123 {
   1124     AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
   1125 
   1126     agc->props = ast2500_set_props;
   1127     agc->nr_gpio_pins = 228;
   1128     agc->nr_gpio_sets = 8;
   1129     agc->reg_table = aspeed_3_3v_gpios;
   1130 }
   1131 
   1132 static void aspeed_gpio_ast2600_3_3v_class_init(ObjectClass *klass, void *data)
   1133 {
   1134     AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
   1135 
   1136     agc->props = ast2600_3_3v_set_props;
   1137     agc->nr_gpio_pins = 208;
   1138     agc->nr_gpio_sets = 7;
   1139     agc->reg_table = aspeed_3_3v_gpios;
   1140 }
   1141 
   1142 static void aspeed_gpio_ast2600_1_8v_class_init(ObjectClass *klass, void *data)
   1143 {
   1144     AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
   1145 
   1146     agc->props = ast2600_1_8v_set_props;
   1147     agc->nr_gpio_pins = 36;
   1148     agc->nr_gpio_sets = 2;
   1149     agc->reg_table = aspeed_1_8v_gpios;
   1150 }
   1151 
   1152 static void aspeed_gpio_1030_class_init(ObjectClass *klass, void *data)
   1153 {
   1154     AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
   1155 
   1156     agc->props = ast1030_set_props;
   1157     agc->nr_gpio_pins = 151;
   1158     agc->nr_gpio_sets = 6;
   1159     agc->reg_table = aspeed_3_3v_gpios;
   1160 }
   1161 
   1162 static const TypeInfo aspeed_gpio_info = {
   1163     .name           = TYPE_ASPEED_GPIO,
   1164     .parent         = TYPE_SYS_BUS_DEVICE,
   1165     .instance_size  = sizeof(AspeedGPIOState),
   1166     .class_size     = sizeof(AspeedGPIOClass),
   1167     .class_init     = aspeed_gpio_class_init,
   1168     .abstract       = true,
   1169 };
   1170 
   1171 static const TypeInfo aspeed_gpio_ast2400_info = {
   1172     .name           = TYPE_ASPEED_GPIO "-ast2400",
   1173     .parent         = TYPE_ASPEED_GPIO,
   1174     .class_init     = aspeed_gpio_ast2400_class_init,
   1175     .instance_init  = aspeed_gpio_init,
   1176 };
   1177 
   1178 static const TypeInfo aspeed_gpio_ast2500_info = {
   1179     .name           = TYPE_ASPEED_GPIO "-ast2500",
   1180     .parent         = TYPE_ASPEED_GPIO,
   1181     .class_init     = aspeed_gpio_2500_class_init,
   1182     .instance_init  = aspeed_gpio_init,
   1183 };
   1184 
   1185 static const TypeInfo aspeed_gpio_ast2600_3_3v_info = {
   1186     .name           = TYPE_ASPEED_GPIO "-ast2600",
   1187     .parent         = TYPE_ASPEED_GPIO,
   1188     .class_init     = aspeed_gpio_ast2600_3_3v_class_init,
   1189     .instance_init  = aspeed_gpio_init,
   1190 };
   1191 
   1192 static const TypeInfo aspeed_gpio_ast2600_1_8v_info = {
   1193     .name           = TYPE_ASPEED_GPIO "-ast2600-1_8v",
   1194     .parent         = TYPE_ASPEED_GPIO,
   1195     .class_init     = aspeed_gpio_ast2600_1_8v_class_init,
   1196     .instance_init  = aspeed_gpio_init,
   1197 };
   1198 
   1199 static const TypeInfo aspeed_gpio_ast1030_info = {
   1200     .name           = TYPE_ASPEED_GPIO "-ast1030",
   1201     .parent         = TYPE_ASPEED_GPIO,
   1202     .class_init     = aspeed_gpio_1030_class_init,
   1203     .instance_init  = aspeed_gpio_init,
   1204 };
   1205 
   1206 static void aspeed_gpio_register_types(void)
   1207 {
   1208     type_register_static(&aspeed_gpio_info);
   1209     type_register_static(&aspeed_gpio_ast2400_info);
   1210     type_register_static(&aspeed_gpio_ast2500_info);
   1211     type_register_static(&aspeed_gpio_ast2600_3_3v_info);
   1212     type_register_static(&aspeed_gpio_ast2600_1_8v_info);
   1213     type_register_static(&aspeed_gpio_ast1030_info);
   1214 }
   1215 
   1216 type_init(aspeed_gpio_register_types);