qemu/hw/gpio/xlnx-zynqmp-gpio.c
<<
>>
Prefs
   1/*
   2 * QEMU model of the GPIO gpio Registers
   3 *
   4 * Copyright (c) 2017 Xilinx Inc.
   5 *
   6 * Partly autogenerated by xregqemu.py 2017-02-11.
   7 *
   8 * Permission is hereby granted, free of charge, to any person obtaining a copy
   9 * of this software and associated documentation files (the "Software"), to deal
  10 * in the Software without restriction, including without limitation the rights
  11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12 * copies of the Software, and to permit persons to whom the Software is
  13 * furnished to do so, subject to the following conditions:
  14 *
  15 * The above copyright notice and this permission notice shall be included in
  16 * all copies or substantial portions of the Software.
  17 *
  18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24 * THE SOFTWARE.
  25 */
  26
  27#include "qemu/osdep.h"
  28#include "hw/sysbus.h"
  29#include "hw/register-dep.h"
  30#include "qemu/bitops.h"
  31#include "qemu/log.h"
  32
  33#include "hw/fdt_generic_util.h"
  34
  35#ifndef XLNX_ZYNQMP_GPIO_ERR_DEBUG
  36#define XLNX_ZYNQMP_GPIO_ERR_DEBUG 0
  37#endif
  38
  39#define TYPE_XLNX_ZYNQMP_GPIO "xlnx.zynqmp-gpio"
  40
  41#define XLNX_ZYNQMP_GPIO(obj) \
  42     OBJECT_CHECK(XlnxZynqmpGPIO, (obj), TYPE_XLNX_ZYNQMP_GPIO)
  43
  44#define DPRINT(...) \
  45    if (XLNX_ZYNQMP_GPIO_ERR_DEBUG) {  \
  46        qemu_log("%s:", __func__);     \
  47        qemu_log(__VA_ARGS__);         \
  48    }
  49
  50DEP_REG32(MASK_DATA_0_LSW, 0x0)
  51    DEP_FIELD(MASK_DATA_0_LSW, MASK_0_LSW, 16, 16)
  52    DEP_FIELD(MASK_DATA_0_LSW, DATA_0_LSW, 16, 0)
  53DEP_REG32(MASK_DATA_0_MSW, 0x4)
  54    DEP_FIELD(MASK_DATA_0_MSW, MASK_0_MSW, 10, 16)
  55    DEP_FIELD(MASK_DATA_0_MSW, DATA_0_MSW, 10, 0)
  56DEP_REG32(MASK_DATA_1_LSW, 0x8)
  57    DEP_FIELD(MASK_DATA_1_LSW, MASK_1_LSW, 16, 16)
  58    DEP_FIELD(MASK_DATA_1_LSW, DATA_1_LSW, 16, 0)
  59DEP_REG32(MASK_DATA_1_MSW, 0xc)
  60    DEP_FIELD(MASK_DATA_1_MSW, MASK_1_MSW, 10, 16)
  61    DEP_FIELD(MASK_DATA_1_MSW, DATA_1_MSW, 10, 0)
  62DEP_REG32(MASK_DATA_2_LSW, 0x10)
  63    DEP_FIELD(MASK_DATA_2_LSW, MASK_2_LSW, 16, 16)
  64    DEP_FIELD(MASK_DATA_2_LSW, DATA_2_LSW, 16, 0)
  65DEP_REG32(MASK_DATA_2_MSW, 0x14)
  66    DEP_FIELD(MASK_DATA_2_MSW, MASK_2_MSW, 10, 16)
  67    DEP_FIELD(MASK_DATA_2_MSW, DATA_2_MSW, 10, 0)
  68DEP_REG32(MASK_DATA_3_LSW, 0x18)
  69    DEP_FIELD(MASK_DATA_3_LSW, MASK_3_LSW, 16, 16)
  70    DEP_FIELD(MASK_DATA_3_LSW, DATA_3_LSW, 16, 0)
  71DEP_REG32(MASK_DATA_3_MSW, 0x1c)
  72    DEP_FIELD(MASK_DATA_3_MSW, MASK_3_MSW, 16, 16)
  73    DEP_FIELD(MASK_DATA_3_MSW, DATA_3_MSW, 16, 0)
  74DEP_REG32(MASK_DATA_4_LSW, 0x20)
  75    DEP_FIELD(MASK_DATA_4_LSW, MASK_4_LSW, 16, 16)
  76    DEP_FIELD(MASK_DATA_4_LSW, DATA_4_LSW, 16, 0)
  77DEP_REG32(MASK_DATA_4_MSW, 0x24)
  78    DEP_FIELD(MASK_DATA_4_MSW, MASK_4_MSW, 16, 16)
  79    DEP_FIELD(MASK_DATA_4_MSW, DATA_4_MSW, 16, 0)
  80DEP_REG32(MASK_DATA_5_LSW, 0x28)
  81    DEP_FIELD(MASK_DATA_5_LSW, MASK_5_LSW, 16, 16)
  82    DEP_FIELD(MASK_DATA_5_LSW, DATA_5_LSW, 16, 0)
  83DEP_REG32(MASK_DATA_5_MSW, 0x2c)
  84    DEP_FIELD(MASK_DATA_5_MSW, MASK_5_MSW, 16, 16)
  85    DEP_FIELD(MASK_DATA_5_MSW, DATA_5_MSW, 16, 0)
  86DEP_REG32(DATA_0, 0x40)
  87    DEP_FIELD(DATA_0, DATA_0, 26, 0)
  88DEP_REG32(DATA_1, 0x44)
  89    DEP_FIELD(DATA_1, DATA_1, 26, 0)
  90DEP_REG32(DATA_2, 0x48)
  91    DEP_FIELD(DATA_2, DATA_2, 26, 0)
  92DEP_REG32(DATA_3, 0x4c)
  93DEP_REG32(DATA_4, 0x50)
  94DEP_REG32(DATA_5, 0x54)
  95DEP_REG32(DATA_0_RO, 0x60)
  96    DEP_FIELD(DATA_0_RO, DATA_0_RO, 26, 0)
  97DEP_REG32(DATA_1_RO, 0x64)
  98    DEP_FIELD(DATA_1_RO, DATA_1_RO, 26, 0)
  99DEP_REG32(DATA_2_RO, 0x68)
 100    DEP_FIELD(DATA_2_RO, DATA_2_RO, 26, 0)
 101DEP_REG32(DATA_3_RO, 0x6c)
 102DEP_REG32(DATA_4_RO, 0x70)
 103DEP_REG32(DATA_5_RO, 0x74)
 104DEP_REG32(DIRM_0, 0x204)
 105    DEP_FIELD(DIRM_0, DIRECTION_0, 26, 0)
 106DEP_REG32(OEN_0, 0x208)
 107    DEP_FIELD(OEN_0, OP_ENABLE_0, 26, 0)
 108DEP_REG32(INT_MASK_0, 0x20c)
 109    DEP_FIELD(INT_MASK_0, INT_MASK_0, 26, 0)
 110DEP_REG32(INT_EN_0, 0x210)
 111    DEP_FIELD(INT_EN_0, INT_ENABLE_0, 26, 0)
 112DEP_REG32(INT_DIS_0, 0x214)
 113    DEP_FIELD(INT_DIS_0, INT_DISABLE_0, 26, 0)
 114DEP_REG32(INT_STAT_0, 0x218)
 115    DEP_FIELD(INT_STAT_0, INT_STATUS_0, 26, 0)
 116DEP_REG32(INT_TYPE_0, 0x21c)
 117    DEP_FIELD(INT_TYPE_0, INT_TYPE_0, 26, 0)
 118DEP_REG32(INT_POLARITY_0, 0x220)
 119    DEP_FIELD(INT_POLARITY_0, INT_POL_0, 26, 0)
 120DEP_REG32(INT_ANY_0, 0x224)
 121    DEP_FIELD(INT_ANY_0, INT_ON_ANY_0, 26, 0)
 122DEP_REG32(DIRM_1, 0x244)
 123    DEP_FIELD(DIRM_1, DIRECTION_1, 26, 0)
 124DEP_REG32(OEN_1, 0x248)
 125    DEP_FIELD(OEN_1, OP_ENABLE_1, 26, 0)
 126DEP_REG32(INT_MASK_1, 0x24c)
 127    DEP_FIELD(INT_MASK_1, INT_MASK_1, 26, 0)
 128DEP_REG32(INT_EN_1, 0x250)
 129    DEP_FIELD(INT_EN_1, INT_ENABLE_1, 26, 0)
 130DEP_REG32(INT_DIS_1, 0x254)
 131    DEP_FIELD(INT_DIS_1, INT_DISABLE_1, 26, 0)
 132DEP_REG32(INT_STAT_1, 0x258)
 133    DEP_FIELD(INT_STAT_1, INT_STATUS_1, 26, 0)
 134DEP_REG32(INT_TYPE_1, 0x25c)
 135    DEP_FIELD(INT_TYPE_1, INT_TYPE_1, 26, 0)
 136DEP_REG32(INT_POLARITY_1, 0x260)
 137    DEP_FIELD(INT_POLARITY_1, INT_POL_1, 26, 0)
 138DEP_REG32(INT_ANY_1, 0x264)
 139    DEP_FIELD(INT_ANY_1, INT_ON_ANY_1, 26, 0)
 140DEP_REG32(DIRM_2, 0x284)
 141    DEP_FIELD(DIRM_2, DIRECTION_2, 26, 0)
 142DEP_REG32(OEN_2, 0x288)
 143    DEP_FIELD(OEN_2, OP_ENABLE_2, 26, 0)
 144DEP_REG32(INT_MASK_2, 0x28c)
 145    DEP_FIELD(INT_MASK_2, INT_MASK_2, 26, 0)
 146DEP_REG32(INT_EN_2, 0x290)
 147    DEP_FIELD(INT_EN_2, INT_ENABLE_2, 26, 0)
 148DEP_REG32(INT_DIS_2, 0x294)
 149    DEP_FIELD(INT_DIS_2, INT_DISABLE_2, 26, 0)
 150DEP_REG32(INT_STAT_2, 0x298)
 151    DEP_FIELD(INT_STAT_2, INT_STATUS_2, 26, 0)
 152DEP_REG32(INT_TYPE_2, 0x29c)
 153    DEP_FIELD(INT_TYPE_2, INT_TYPE_2, 26, 0)
 154DEP_REG32(INT_POLARITY_2, 0x2a0)
 155    DEP_FIELD(INT_POLARITY_2, INT_POL_2, 26, 0)
 156DEP_REG32(INT_ANY_2, 0x2a4)
 157    DEP_FIELD(INT_ANY_2, INT_ON_ANY_2, 26, 0)
 158DEP_REG32(DIRM_3, 0x2c4)
 159DEP_REG32(OEN_3, 0x2c8)
 160DEP_REG32(INT_MASK_3, 0x2cc)
 161DEP_REG32(INT_EN_3, 0x2d0)
 162DEP_REG32(INT_DIS_3, 0x2d4)
 163DEP_REG32(INT_STAT_3, 0x2d8)
 164DEP_REG32(INT_TYPE_3, 0x2dc)
 165DEP_REG32(INT_POLARITY_3, 0x2e0)
 166DEP_REG32(INT_ANY_3, 0x2e4)
 167DEP_REG32(DIRM_4, 0x304)
 168DEP_REG32(OEN_4, 0x308)
 169DEP_REG32(INT_MASK_4, 0x30c)
 170DEP_REG32(INT_EN_4, 0x310)
 171DEP_REG32(INT_DIS_4, 0x314)
 172DEP_REG32(INT_STAT_4, 0x318)
 173DEP_REG32(INT_TYPE_4, 0x31c)
 174DEP_REG32(INT_POLARITY_4, 0x320)
 175DEP_REG32(INT_ANY_4, 0x324)
 176DEP_REG32(DIRM_5, 0x344)
 177DEP_REG32(OEN_5, 0x348)
 178DEP_REG32(INT_MASK_5, 0x34c)
 179DEP_REG32(INT_EN_5, 0x350)
 180DEP_REG32(INT_DIS_5, 0x354)
 181DEP_REG32(INT_STAT_5, 0x358)
 182DEP_REG32(INT_TYPE_5, 0x35c)
 183DEP_REG32(INT_POLARITY_5, 0x360)
 184DEP_REG32(INT_ANY_5, 0x364)
 185
 186#define R_MAX (R_INT_ANY_5 + 1)
 187
 188#define ZYNQMP_GPIO_BANK0 0
 189#define ZYNQMP_GPIO_BANK1 26
 190#define ZYNQMP_GPIO_BANK2 52
 191#define ZYNQMP_GPIO_BANK3 78
 192#define ZYNQMP_GPIO_BANK4 110
 193#define ZYNQMP_GPIO_BANK5 142
 194
 195#define ZYNQMP_NUM_GPIOS              174
 196#define ZYNQMP_NUM_OEN_SIGNALS        ZYNQMP_NUM_GPIOS
 197#define ZYNQMP_NUM_EMIO_PINS_PER_BANK  32
 198#define ZYNQMP_NUM_MIO_PINS_PER_BANK   26
 199#define ZYNQMP_GPIO_NUM_BANKS           6
 200#define ZYNQMP_GPIO_NUM_MIO_BANKS       3
 201#define ZYNQMP_GPIO_NUM_EMIO_BANKS      3
 202#define ZYNQMP_GPIO_EMIO_START_OFFSET  ZYNQMP_GPIO_BANK3
 203#define ZYNQMP_GPIO_MIO_START_OFFSET   ZYQNMP_GPIO_BANK0
 204
 205#define R_GPIO_DATA_X(bank)      ((A_DATA_0 + (bank * 0x4)) / 4)
 206
 207#define R_GPIO_DIRM_X(bank)      ((A_DIRM_0 + (bank * 0x40)) / 4)
 208#define R_GPIO_OEN_X(bank)       ((A_OEN_0 + (bank * 0x40)) / 4)
 209#define R_GPIO_INT_MASK_X(bank)  ((A_INT_MASK_0 + (bank * 0x40)) / 4)
 210#define R_GPIO_INT_STAT_X(bank)  ((A_INT_STAT_0 + (bank * 0x40)) / 4)
 211#define R_GPIO_INT_POL_X(bank)   ((A_INT_POLARITY_0 + (bank * 0x40)) / 4)
 212
 213typedef struct XlnxZynqmpGPIO {
 214    SysBusDevice parent_obj;
 215    MemoryRegion iomem;
 216
 217    qemu_irq irq;
 218    qemu_irq *gpio_out;
 219    qemu_irq *gpio_oen;
 220
 221    uint32_t regs[R_MAX];
 222    DepRegisterInfo regs_info[R_MAX];
 223} XlnxZynqmpGPIO;
 224
 225/* Returns Bank number based on addr passed
 226 */
 227static int gpio_get_bank(hwaddr addr)
 228{
 229    switch (addr & 0xFFF) {
 230    case 0x0 ... 0x2c:
 231        return addr / 8;
 232    case 0x40 ... 0x54:
 233        addr -= 0x40;
 234        return addr / 4;
 235    case 0x60 ... 0x74:
 236        addr -= 0x60;
 237        return addr / 4;
 238    case 0x204 ... 0x364:
 239        return (addr >> 6) & 0x7;
 240    default:
 241        DPRINT("Register offset doesn't belong to any bank");
 242    };
 243    return 0;
 244}
 245
 246static int gpio_get_bank_by_pin(int pin, int *offset)
 247{
 248    switch (pin) {
 249    case ZYNQMP_GPIO_BANK0 ... (ZYNQMP_GPIO_BANK1 - 1):
 250        *offset = pin - ZYNQMP_GPIO_BANK0;
 251        return 0;
 252    case ZYNQMP_GPIO_BANK1 ... (ZYNQMP_GPIO_BANK2 - 1):
 253        *offset = pin - ZYNQMP_GPIO_BANK1;
 254        return 1;
 255    case ZYNQMP_GPIO_BANK2 ... (ZYNQMP_GPIO_BANK3 - 1):
 256        *offset = pin - ZYNQMP_GPIO_BANK2;
 257        return 2;
 258    case ZYNQMP_GPIO_BANK3 ... (ZYNQMP_GPIO_BANK4 - 1):
 259        *offset = pin - ZYNQMP_GPIO_BANK3;
 260        return 3;
 261    case ZYNQMP_GPIO_BANK4 ... (ZYNQMP_GPIO_BANK5 - 1):
 262        *offset = pin - ZYNQMP_GPIO_BANK4;
 263        return 4;
 264    case ZYNQMP_GPIO_BANK5 ... (ZYNQMP_NUM_GPIOS - 1):
 265        *offset = pin - ZYNQMP_GPIO_BANK5;
 266        return 5;
 267    default:
 268        DPRINT("Pin number exceeded max gpios\n");
 269    };
 270    return 0;
 271}
 272
 273static void gpio_update_irq(XlnxZynqmpGPIO *s)
 274{
 275    bool line;
 276    int i;
 277
 278    /* if mask high, interrupt disabled
 279     * if mask low, interrupt enabled
 280     */
 281    for (i = 0; i < ZYNQMP_GPIO_NUM_BANKS; i++) {
 282        line = !!(~s->regs[R_GPIO_INT_MASK_X(i)] &
 283                   s->regs[R_GPIO_INT_STAT_X(i)]);
 284        qemu_set_irq(s->irq, line);
 285    }
 286}
 287
 288static void gpio_update_isr(XlnxZynqmpGPIO *s, int bank, int pin_offset,
 289                            uint32_t level, uint32_t level_old)
 290{
 291    uint32_t pol = s->regs[R_GPIO_INT_POL_X(bank)] & (1 << pin_offset);
 292
 293    if ((level == 0 && level_old == 1 && !pol) || /* Falling Edge */
 294       (level == 1 && level_old == 0 && pol)) {   /* Raising Edge */
 295        s->regs[R_GPIO_INT_STAT_X(bank)] =
 296           deposit32(s->regs[R_GPIO_INT_STAT_X(bank)], pin_offset, 1, level);
 297    }
 298}
 299
 300static void gpio_update_pins(XlnxZynqmpGPIO *s, int bank, int offset, int width,
 301                             uint32_t mask, uint32_t val, uint32_t val_old)
 302{
 303    int pin = 0;
 304    uint32_t i;
 305    /* Get the banks first pin number in s->gpio_out
 306     */
 307    switch (bank) {
 308    case 0:
 309        pin = ZYNQMP_GPIO_BANK0 + offset;
 310        break;
 311    case 1:
 312        pin = ZYNQMP_GPIO_BANK1 + offset;
 313        break;
 314    case 2:
 315        pin = ZYNQMP_GPIO_BANK2 + offset;
 316        break;
 317    case 3:
 318        pin = ZYNQMP_GPIO_BANK3 + offset;
 319        break;
 320    case 4:
 321        pin = ZYNQMP_GPIO_BANK4 + offset;
 322        break;
 323    case 5:
 324        pin = ZYNQMP_GPIO_BANK5 + offset;
 325        break;
 326    };
 327
 328    for (i = pin; i < pin + width; i++) {
 329        /* 'i' is pin-offset of the s->gpio_out
 330         * i - pin should provice bank-pin-offset */
 331        gpio_update_isr(s, bank, i - pin, extract32(val, i - pin, 1),
 332                        extract32(val_old, i - pin, 1));
 333        if (mask & (1 << (i - pin))) {
 334            DPRINT("gpio out[%d] set to %d\n", i, extract32(val, i - pin, 1));
 335            qemu_set_irq(s->gpio_out[i], extract32(val, i - pin, 1));
 336        }
 337    }
 338}
 339
 340static void zynqmp_gpio_in_handler(void *opaque, int n, int level)
 341{
 342    XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(opaque);
 343    int offset = 0;
 344    int bank = gpio_get_bank_by_pin(n, &offset);
 345    uint32_t mask;
 346    uint32_t data_old = s->regs[R_GPIO_DATA_X(bank)];
 347
 348    /* Accept the data only if gpio is set as input */
 349    mask = ~(s->regs[R_GPIO_DIRM_X(bank)]);
 350
 351    if (mask & (1 << offset)) {
 352        DPRINT("gpio in[%d] set to %d\n", n, level);
 353        s->regs[R_GPIO_DATA_X(bank)] =
 354            deposit32(s->regs[R_GPIO_DATA_X(bank)], offset, 1, level);
 355
 356        gpio_update_isr(s, bank, offset, level,
 357                        extract32(data_old, offset, 1));
 358    }
 359    gpio_update_irq(s);
 360}
 361
 362static uint64_t gpio_data_reg_prew(DepRegisterInfo *reg, uint64_t val)
 363{
 364    XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(reg->opaque);
 365    uint32_t data = (uint32_t) val;
 366    int bank = gpio_get_bank(reg->access->decode.addr);
 367    int width;
 368    uint32_t data_old = s->regs[R_GPIO_DATA_X(bank)];
 369    uint32_t mask;
 370
 371    /* BANK 0,1,2 have 26 pins each
 372     * BANK 3,4,5 have 32 pins each
 373     */
 374    width = bank < 3 ? 26 : 32;
 375
 376    mask = (s->regs[R_GPIO_OEN_X(bank)] &
 377            s->regs[R_GPIO_DIRM_X(bank)]);
 378
 379    gpio_update_pins(s, bank, 0, width, mask, data, data_old);
 380    return val;
 381}
 382
 383static uint64_t gpio_mask_data_lsw_prew(DepRegisterInfo *reg, uint64_t val)
 384{
 385    XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(reg->opaque);
 386    uint32_t data = (uint32_t) val;
 387    uint16_t maskw = data >> 16;
 388    uint32_t data_old = 0;
 389    int bank = gpio_get_bank(reg->access->decode.addr);
 390    uint32_t data_reg = R_GPIO_DATA_X(bank);
 391    uint32_t mask;
 392
 393    /* Clear the mask value from data*/
 394    data &= (1 << 16) - 1;
 395    data_old = s->regs[data_reg] & 0x0000FFFF;
 396    /* Pins corresponding to unmasked bits of maskw are allowed to update
 397     * i.e high bit in ~maskw */
 398    s->regs[data_reg] = deposit32(s->regs[data_reg], 0, 16,
 399                                  (data_old & maskw) | (~maskw & data));
 400
 401    mask = (s->regs[R_GPIO_OEN_X(bank)] &
 402            s->regs[R_GPIO_DIRM_X(bank)]);
 403    gpio_update_pins(s, bank, 0, 16, (mask & 0x0000FFFF),
 404                     (s->regs[data_reg] & 0x0000FFFF),
 405                      data_old);
 406    return val;
 407}
 408
 409static uint64_t gpio_mask_data_msw_prew(DepRegisterInfo *reg, uint64_t val)
 410{
 411    XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(reg->opaque);
 412    uint32_t data = (uint32_t) val;
 413    uint16_t maskw = data >> 16;
 414    uint32_t data_old = 0;
 415    int width;
 416    int bank = gpio_get_bank(reg->access->decode.addr);
 417    uint32_t data_reg = R_GPIO_DATA_X(bank);
 418    uint32_t mask;
 419
 420    /* BANK 0,1,2 have 10 pins and
 421     * BANK 3,4,5 have 16 pins in
 422     * the upper-half of the bank
 423     */
 424    width = bank < 3 ? 10 : 16;
 425
 426    data &= (1 << width) - 1;
 427    data_old = s->regs[data_reg] >> 16;
 428
 429    s->regs[data_reg] = deposit32(s->regs[data_reg], 16, width,
 430                                  (data_old & maskw) | (~maskw & data));
 431
 432    mask = (s->regs[R_GPIO_OEN_X(bank)] &
 433            s->regs[R_GPIO_DIRM_X(bank)]);
 434    gpio_update_pins(s, bank, 16, width, (mask >> 16),
 435                     (s->regs[data_reg] >> 16), data_old);
 436    return val;
 437}
 438
 439static uint64_t gpio_reg_wo(DepRegisterInfo *reg, uint64_t val)
 440{
 441    return 0;
 442}
 443
 444static uint64_t gpio_data_ro_postr(DepRegisterInfo *reg, uint64_t val)
 445{
 446    XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(reg->opaque);
 447    int bank = gpio_get_bank(reg->access->decode.addr);
 448
 449    return s->regs[R_GPIO_DATA_X(bank)];
 450}
 451
 452static void gpio_int_en_postw(DepRegisterInfo *reg, uint64_t val)
 453{
 454    XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(reg->opaque);
 455    uint32_t data = (uint32_t) val;
 456    int bank = gpio_get_bank(reg->access->decode.addr);
 457
 458    s->regs[R_GPIO_INT_MASK_X(bank)] &= ~data;
 459}
 460
 461static void gpio_int_dis_postw(DepRegisterInfo *reg, uint64_t val)
 462{
 463    XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(reg->opaque);
 464    uint32_t data = (uint32_t) val;
 465    int bank = gpio_get_bank(reg->access->decode.addr);
 466
 467    s->regs[R_GPIO_INT_MASK_X(bank)] |= data;
 468}
 469
 470static uint64_t gpio_oen_prew(DepRegisterInfo *reg, uint64_t val)
 471{
 472    XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(reg->opaque);
 473    uint32_t data = (uint32_t) val;
 474    uint32_t data_old = *(uint32_t *)reg->data;
 475    int bank = gpio_get_bank(reg->access->decode.addr);
 476    int oen_pin;
 477    int width;
 478    int i;
 479
 480    if (bank < ZYNQMP_GPIO_NUM_MIO_BANKS) {
 481        /* Calculate the oen signal offset for pins mapped to mio */
 482        oen_pin = bank * ZYNQMP_NUM_MIO_PINS_PER_BANK;
 483        width = ZYNQMP_NUM_MIO_PINS_PER_BANK;
 484    } else if (bank < ZYNQMP_GPIO_NUM_BANKS) {
 485        /* Calculate the oen signal offset for emios.
 486         * EMIO's would start from bank 3 */
 487        oen_pin = ZYNQMP_GPIO_EMIO_START_OFFSET +
 488                  (bank - ZYNQMP_GPIO_NUM_MIO_BANKS) *
 489                   ZYNQMP_NUM_EMIO_PINS_PER_BANK;
 490        width = ZYNQMP_NUM_EMIO_PINS_PER_BANK;
 491    } else {
 492        DPRINT("bank %d not available\n", bank);
 493        return val;
 494    }
 495
 496    for (i = 0; i < width; i++) {
 497        /* Change in the oen value should update the signal */
 498        if ((data_old ^ data) & (1 << i)) {
 499            qemu_set_irq(s->gpio_oen[oen_pin + i], extract32(data, i, 1));
 500        }
 501    }
 502
 503    return val;
 504}
 505
 506static DepRegisterAccessInfo gpio_regs_info[] = {
 507    {   .name = "MASK_DATA_0_LSW",
 508        .decode.addr = A_MASK_DATA_0_LSW,
 509        .pre_write = gpio_mask_data_lsw_prew,
 510        .post_read = gpio_reg_wo,
 511    },{ .name = "MASK_DATA_0_MSW",
 512        .decode.addr = A_MASK_DATA_0_MSW,
 513        .rsvd = 0xfc00fc00,
 514        .pre_write = gpio_mask_data_msw_prew,
 515        .post_read = gpio_reg_wo,
 516    },{   .name = "MASK_DATA_1_LSW",
 517        .decode.addr = A_MASK_DATA_1_LSW,
 518        .pre_write = gpio_mask_data_lsw_prew,
 519        .post_read = gpio_reg_wo,
 520    },{ .name = "MASK_DATA_1_MSW",
 521        .decode.addr = A_MASK_DATA_1_MSW,
 522        .rsvd = 0xfc00fc00,
 523        .pre_write = gpio_mask_data_msw_prew,
 524        .post_read = gpio_reg_wo,
 525    },{   .name = "MASK_DATA_2_LSW",
 526        .decode.addr = A_MASK_DATA_2_LSW,
 527        .pre_write = gpio_mask_data_lsw_prew,
 528        .post_read = gpio_reg_wo,
 529    },{ .name = "MASK_DATA_2_MSW",
 530        .decode.addr = A_MASK_DATA_2_MSW,
 531        .rsvd = 0xfc00fc00,
 532        .pre_write = gpio_mask_data_msw_prew,
 533        .post_read = gpio_reg_wo,
 534    },{   .name = "MASK_DATA_3_LSW",
 535        .decode.addr = A_MASK_DATA_3_LSW,
 536        .pre_write = gpio_mask_data_lsw_prew,
 537        .post_read = gpio_reg_wo,
 538    },{ .name = "MASK_DATA_3_MSW",
 539        .decode.addr = A_MASK_DATA_3_MSW,
 540        .pre_write = gpio_mask_data_msw_prew,
 541        .post_read = gpio_reg_wo,
 542    },{   .name = "MASK_DATA_4_LSW",
 543        .decode.addr = A_MASK_DATA_4_LSW,
 544        .pre_write = gpio_mask_data_lsw_prew,
 545        .post_read = gpio_reg_wo,
 546    },{ .name = "MASK_DATA_4_MSW",
 547        .decode.addr = A_MASK_DATA_4_MSW,
 548        .pre_write = gpio_mask_data_msw_prew,
 549        .post_read = gpio_reg_wo,
 550    },{   .name = "MASK_DATA_5_LSW",
 551        .decode.addr = A_MASK_DATA_5_LSW,
 552        .pre_write = gpio_mask_data_lsw_prew,
 553        .post_read = gpio_reg_wo,
 554    },{ .name = "MASK_DATA_5_MSW",
 555        .decode.addr = A_MASK_DATA_5_MSW,
 556        .pre_write = gpio_mask_data_msw_prew,
 557        .post_read = gpio_reg_wo,
 558    },{ .name = "DATA_0",  .decode.addr = A_DATA_0,
 559        .pre_write = gpio_data_reg_prew,
 560        .rsvd = 0xfc000000,
 561    },{ .name = "DATA_1",  .decode.addr = A_DATA_1,
 562        .pre_write = gpio_data_reg_prew,
 563        .rsvd = 0xfc000000,
 564    },{ .name = "DATA_2",  .decode.addr = A_DATA_2,
 565        .pre_write = gpio_data_reg_prew,
 566        .rsvd = 0xfc000000,
 567    },{ .name = "DATA_3",  .decode.addr = A_DATA_3,
 568        .pre_write = gpio_data_reg_prew,
 569    },{ .name = "DATA_4",  .decode.addr = A_DATA_4,
 570        .pre_write = gpio_data_reg_prew,
 571    },{ .name = "DATA_5",  .decode.addr = A_DATA_5,
 572        .pre_write = gpio_data_reg_prew,
 573    },{ .name = "DATA_0_RO",
 574        .decode.addr = A_DATA_0_RO,
 575        .rsvd = 0xfc000000,
 576        .ro = 0xffffffff,
 577        .post_read = gpio_data_ro_postr,
 578    },{ .name = "DATA_1_RO",
 579        .decode.addr = A_DATA_1_RO,
 580        .rsvd = 0xfc000000,
 581        .ro = 0xffffffff,
 582        .post_read = gpio_data_ro_postr,
 583    },{ .name = "DATA_2_RO",
 584        .decode.addr = A_DATA_2_RO,
 585        .rsvd = 0xfc000000,
 586        .ro = 0xffffffff,
 587        .post_read = gpio_data_ro_postr,
 588    },{ .name = "DATA_3_RO",
 589        .decode.addr = A_DATA_3_RO,
 590        .ro = 0xffffffff,
 591        .post_read = gpio_data_ro_postr,
 592    },{ .name = "DATA_4_RO",
 593        .decode.addr = A_DATA_4_RO,
 594        .ro = 0xffffffff,
 595        .post_read = gpio_data_ro_postr,
 596    },{ .name = "DATA_5_RO",
 597        .decode.addr = A_DATA_5_RO,
 598        .ro = 0xffffffff,
 599        .post_read = gpio_data_ro_postr,
 600    },{ .name = "DIRM_0",  .decode.addr = A_DIRM_0,
 601        .rsvd = 0xfc000000,
 602    },{ .name = "OEN_0",  .decode.addr = A_OEN_0,
 603        .rsvd = 0xfc000000,
 604        .pre_write = gpio_oen_prew,
 605    },{ .name = "INT_MASK_0",
 606        .decode.addr = A_INT_MASK_0,
 607        .reset = 0x3ffffff,
 608        .rsvd = 0xfc000000,
 609        .ro = 0x3ffffff,
 610    },{ .name = "INT_EN_0",  .decode.addr = A_INT_EN_0,
 611        .post_write = gpio_int_en_postw,
 612        .rsvd = 0xfc000000,
 613    },{ .name = "INT_DIS_0",
 614        .decode.addr = A_INT_DIS_0,
 615        .rsvd = 0xfc000000,
 616        .post_write = gpio_int_dis_postw,
 617    },{ .name = "INT_STAT_0",
 618        .decode.addr = A_INT_STAT_0,
 619        .w1c = 0x3ffffff,
 620        .rsvd = 0xfc000000,
 621    },{ .name = "INT_TYPE_0",
 622        .decode.addr = A_INT_TYPE_0,
 623        .rsvd = 0xfc000000,
 624        .reset = 0x3ffffff,
 625    },{ .name = "INT_POLARITY_0",
 626        .decode.addr = A_INT_POLARITY_0,
 627        .rsvd = 0xfc000000,
 628    },{ .name = "INT_ANY_0",
 629        .decode.addr = A_INT_ANY_0,
 630        .rsvd = 0xfc000000,
 631    },{ .name = "DIRM_1",  .decode.addr = A_DIRM_1,
 632        .rsvd = 0xfc000000,
 633    },{ .name = "OEN_1",  .decode.addr = A_OEN_1,
 634        .rsvd = 0xfc000000,
 635        .pre_write = gpio_oen_prew,
 636    },{ .name = "INT_MASK_1",
 637        .decode.addr = A_INT_MASK_1,
 638        .reset = 0x3ffffff,
 639        .rsvd = 0xfc000000,
 640        .ro = 0x3ffffff,
 641    },{ .name = "INT_EN_1",  .decode.addr = A_INT_EN_1,
 642        .rsvd = 0xfc000000,
 643        .post_write = gpio_int_en_postw,
 644    },{ .name = "INT_DIS_1",
 645        .rsvd = 0xfc000000,
 646        .decode.addr = A_INT_DIS_1,
 647        .post_write = gpio_int_dis_postw,
 648    },{ .name = "INT_STAT_1",
 649        .decode.addr = A_INT_STAT_1,
 650        .rsvd = 0xfc000000,
 651        .w1c = 0x3ffffff,
 652    },{ .name = "INT_TYPE_1",
 653        .decode.addr = A_INT_TYPE_1,
 654        .rsvd = 0xfc000000,
 655        .reset = 0x3ffffff,
 656    },{ .name = "INT_POLARITY_1",
 657        .decode.addr = A_INT_POLARITY_1,
 658        .rsvd = 0xfc000000,
 659    },{ .name = "INT_ANY_1",
 660        .decode.addr = A_INT_ANY_1,
 661        .rsvd = 0xfc000000,
 662    },{ .name = "DIRM_2",  .decode.addr = A_DIRM_2,
 663        .rsvd = 0xfc000000,
 664    },{ .name = "OEN_2",  .decode.addr = A_OEN_2,
 665        .rsvd = 0xfc000000,
 666        .pre_write = gpio_oen_prew,
 667    },{ .name = "INT_MASK_2",
 668        .decode.addr = A_INT_MASK_2,
 669        .ro = 0x3ffffff,
 670        .rsvd = 0xfc000000,
 671        .reset = 0x3ffffff,
 672    },{ .name = "INT_EN_2",  .decode.addr = A_INT_EN_2,
 673        .post_write = gpio_int_en_postw,
 674        .rsvd = 0xfc000000,
 675    },{ .name = "INT_DIS_2",
 676        .decode.addr = A_INT_DIS_2,
 677        .rsvd = 0xfc000000,
 678        .post_write = gpio_int_dis_postw,
 679    },{ .name = "INT_STAT_2",
 680        .decode.addr = A_INT_STAT_2,
 681        .rsvd = 0xfc000000,
 682        .w1c = 0x3ffffff,
 683    },{ .name = "INT_TYPE_2",
 684        .decode.addr = A_INT_TYPE_2,
 685        .rsvd = 0xfc000000,
 686        .reset = 0x3ffffff,
 687    },{ .name = "INT_POLARITY_2",
 688        .decode.addr = A_INT_POLARITY_2,
 689        .rsvd = 0xfc000000,
 690    },{ .name = "INT_ANY_2",
 691        .decode.addr = A_INT_ANY_2,
 692        .rsvd = 0xfc000000,
 693    },{ .name = "DIRM_3",  .decode.addr = A_DIRM_3,
 694    },{ .name = "OEN_3",  .decode.addr = A_OEN_3,
 695        .pre_write = gpio_oen_prew,
 696    },{ .name = "INT_MASK_3",
 697        .decode.addr = A_INT_MASK_3,
 698        .ro = 0xffffffff,
 699        .reset = 0xffffffff,
 700    },{ .name = "INT_EN_3",  .decode.addr = A_INT_EN_3,
 701        .post_write = gpio_int_en_postw,
 702    },{ .name = "INT_DIS_3",
 703        .decode.addr = A_INT_DIS_3,
 704        .post_write = gpio_int_dis_postw,
 705    },{ .name = "INT_STAT_3",
 706        .decode.addr = A_INT_STAT_3,
 707        .w1c = 0xffffffff,
 708    },{ .name = "INT_TYPE_3",
 709        .decode.addr = A_INT_TYPE_3,
 710        .reset = 0xffffffff,
 711    },{ .name = "INT_POLARITY_3",
 712        .decode.addr = A_INT_POLARITY_3,
 713    },{ .name = "INT_ANY_3",
 714        .decode.addr = A_INT_ANY_3,
 715    },{ .name = "DIRM_4",  .decode.addr = A_DIRM_4,
 716    },{ .name = "OEN_4",  .decode.addr = A_OEN_4,
 717        .pre_write = gpio_oen_prew,
 718    },{ .name = "INT_MASK_4",
 719        .decode.addr = A_INT_MASK_4,
 720        .ro = 0xffffffff,
 721        .reset = 0xffffffff,
 722    },{ .name = "INT_EN_4",  .decode.addr = A_INT_EN_4,
 723        .post_write = gpio_int_en_postw,
 724    },{ .name = "INT_DIS_4",
 725        .decode.addr = A_INT_DIS_4,
 726        .post_write = gpio_int_dis_postw,
 727    },{ .name = "INT_STAT_4",
 728        .decode.addr = A_INT_STAT_4,
 729        .w1c = 0xffffffff,
 730    },{ .name = "INT_TYPE_4",
 731        .decode.addr = A_INT_TYPE_4,
 732        .reset = 0xffffffff,
 733    },{ .name = "INT_POLARITY_4",
 734        .decode.addr = A_INT_POLARITY_4,
 735    },{ .name = "INT_ANY_4",
 736        .decode.addr = A_INT_ANY_4,
 737    },{ .name = "DIRM_5",  .decode.addr = A_DIRM_5,
 738    },{ .name = "OEN_5",  .decode.addr = A_OEN_5,
 739        .pre_write = gpio_oen_prew,
 740    },{ .name = "INT_MASK_5",
 741        .decode.addr = A_INT_MASK_5,
 742        .ro = 0xffffffff,
 743        .reset = 0xffffffff,
 744    },{ .name = "INT_EN_5",  .decode.addr = A_INT_EN_5,
 745        .post_write = gpio_int_en_postw,
 746    },{ .name = "INT_DIS_5",
 747        .decode.addr = A_INT_DIS_5,
 748        .post_write = gpio_int_dis_postw,
 749    },{ .name = "INT_STAT_5",
 750        .decode.addr = A_INT_STAT_5,
 751        .w1c = 0xffffffff,
 752    },{ .name = "INT_TYPE_5",
 753        .decode.addr = A_INT_TYPE_5,
 754        .reset = 0xffffffff,
 755    },{ .name = "INT_POLARITY_5",
 756        .decode.addr = A_INT_POLARITY_5,
 757    },{ .name = "INT_ANY_5",
 758        .decode.addr = A_INT_ANY_5,
 759    },
 760};
 761
 762static void gpio_reset(DeviceState *dev)
 763{
 764    XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(dev);
 765    unsigned int i;
 766
 767    for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
 768        dep_register_reset(&s->regs_info[i]);
 769    }
 770
 771}
 772
 773static uint64_t gpio_read(void *opaque, hwaddr addr, unsigned size)
 774{
 775    XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(opaque);
 776    DepRegisterInfo *r = &s->regs_info[addr / 4];
 777
 778    if (!r->data) {
 779        qemu_log("%s: Decode error: read from %" HWADDR_PRIx "\n",
 780                 object_get_canonical_path(OBJECT(s)),
 781                 addr);
 782        return 0;
 783    }
 784    return dep_register_read(r);
 785}
 786
 787static void gpio_write(void *opaque, hwaddr addr, uint64_t value,
 788                      unsigned size)
 789{
 790    XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(opaque);
 791    DepRegisterInfo *r = &s->regs_info[addr / 4];
 792
 793    if (!r->data) {
 794        qemu_log("%s: Decode error: write to %" HWADDR_PRIx "=%" PRIx64 "\n",
 795                 object_get_canonical_path(OBJECT(s)),
 796                 addr, value);
 797        return;
 798    }
 799    dep_register_write(r, value, ~0);
 800    gpio_update_irq(s);
 801}
 802
 803static const MemoryRegionOps gpio_ops = {
 804    .read = gpio_read,
 805    .write = gpio_write,
 806    .endianness = DEVICE_LITTLE_ENDIAN,
 807    .valid = {
 808        .min_access_size = 4,
 809        .max_access_size = 4,
 810    },
 811};
 812
 813static void gpio_realize(DeviceState *dev, Error **errp)
 814{
 815    XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(dev);
 816    const char *prefix = object_get_canonical_path(OBJECT(dev));
 817    const char *gpios_name;
 818    unsigned int i;
 819
 820    for (i = 0; i < ARRAY_SIZE(gpio_regs_info); ++i) {
 821        DepRegisterInfo *r = &s->regs_info[gpio_regs_info[i].decode.addr / 4];
 822
 823        *r = (DepRegisterInfo) {
 824            .data = (uint8_t *)&s->regs[
 825                    gpio_regs_info[i].decode.addr / 4],
 826            .data_size = sizeof(uint32_t),
 827            .access = &gpio_regs_info[i],
 828            .debug = XLNX_ZYNQMP_GPIO_ERR_DEBUG,
 829            .prefix = prefix,
 830            .opaque = s,
 831        };
 832    }
 833    s->gpio_out = g_new0(qemu_irq, ZYNQMP_NUM_GPIOS);
 834    s->gpio_oen = g_new0(qemu_irq, ZYNQMP_NUM_OEN_SIGNALS);
 835
 836    gpios_name = g_strdup("zynqmp_gpio_out");
 837    qdev_init_gpio_out_named(dev, s->gpio_out, gpios_name, ZYNQMP_NUM_GPIOS);
 838    g_free((gpointer) gpios_name);
 839
 840    gpios_name = g_strdup("zynqmp_gpio_oen");
 841    qdev_init_gpio_out_named(dev, s->gpio_oen, gpios_name,
 842                             ZYNQMP_NUM_OEN_SIGNALS);
 843    g_free((gpointer) gpios_name);
 844
 845    gpios_name = g_strdup("zynqmp_gpio_in");
 846    qdev_init_gpio_in_named(dev, zynqmp_gpio_in_handler, gpios_name,
 847                            ZYNQMP_NUM_GPIOS);
 848    g_free((gpointer)gpios_name);
 849
 850}
 851
 852static void gpio_init(Object *obj)
 853{
 854    XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(obj);
 855    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 856
 857    memory_region_init_io(&s->iomem, obj, &gpio_ops, s,
 858                          TYPE_XLNX_ZYNQMP_GPIO, R_MAX * 4);
 859    sysbus_init_mmio(sbd, &s->iomem);
 860    sysbus_init_irq(sbd, &s->irq);
 861}
 862
 863static const VMStateDescription vmstate_gpio = {
 864    .name = TYPE_XLNX_ZYNQMP_GPIO,
 865    .version_id = 1,
 866    .minimum_version_id = 1,
 867    .minimum_version_id_old = 1,
 868    .fields = (VMStateField[]) {
 869        VMSTATE_UINT32_ARRAY(regs, XlnxZynqmpGPIO, R_MAX),
 870        VMSTATE_END_OF_LIST(),
 871    }
 872};
 873
 874static const FDTGenericGPIOSet xlnx_gpio_controller_gpios[] = {
 875    {
 876        .names = &fdt_generic_gpio_name_set_gpio,
 877        .gpios = (FDTGenericGPIOConnection []) {
 878            { .name = "zynqmp_gpio_out", .fdt_index = 0,
 879               .range = ZYNQMP_NUM_GPIOS},
 880            { .name = "zynqmp_gpio_oen", .fdt_index = ZYNQMP_NUM_GPIOS,
 881              .range = ZYNQMP_NUM_OEN_SIGNALS},
 882            { },
 883        },
 884    },
 885    { },
 886};
 887
 888static const FDTGenericGPIOSet xlnx_gpio_client_gpios[] = {
 889    {
 890        .names = &fdt_generic_gpio_name_set_gpio,
 891        .gpios = (FDTGenericGPIOConnection []) {
 892           { .name = "zynqmp_gpio_in", .fdt_index = 0,
 893             .range = ZYNQMP_NUM_GPIOS },
 894           { },
 895        },
 896    },
 897    { },
 898};
 899
 900static void gpio_class_init(ObjectClass *klass, void *data)
 901{
 902    DeviceClass *dc = DEVICE_CLASS(klass);
 903    FDTGenericGPIOClass *fggc = FDT_GENERIC_GPIO_CLASS(klass);
 904
 905    dc->reset = gpio_reset;
 906    dc->realize = gpio_realize;
 907    dc->vmsd = &vmstate_gpio;
 908    fggc->controller_gpios = xlnx_gpio_controller_gpios;
 909    fggc->client_gpios = xlnx_gpio_client_gpios;
 910}
 911
 912static const TypeInfo gpio_info = {
 913    .name          = TYPE_XLNX_ZYNQMP_GPIO,
 914    .parent        = TYPE_SYS_BUS_DEVICE,
 915    .instance_size = sizeof(XlnxZynqmpGPIO),
 916    .class_init    = gpio_class_init,
 917    .instance_init = gpio_init,
 918    .interfaces    = (InterfaceInfo[]) {
 919        { TYPE_FDT_GENERIC_GPIO },
 920        { }
 921    },
 922};
 923
 924static void gpio_register_types(void)
 925{
 926    type_register_static(&gpio_info);
 927}
 928
 929type_init(gpio_register_types)
 930