uint8_t read8(struct memory* m, uint16_t addr) { if (!valid_ptr(m, addr)) { fprintf(stderr, "mmu: warning: read8\'ing bad address: %04X\n", addr); return 0; } if (addr >= 0xFF00 && addr < 0xFF80) return io_read8(m, addr & 0xFF); if (addr == 0xFFFF) return read_interrupt_enable((struct regs*)m->devices[DEVICE_CPU], addr); return m->read8(m, addr); }
/* * The offset of GPIODATA register is 0. * The values read from GPIODATA are determined for each bit, by the mask bit * derived from the address used to access the data register, PADDR[9:2]. * Bits that are 1 in the address mask cause the corresponding bits in GPIODATA * to be read, and bits that are 0 in the address mask cause the corresponding * bits in GPIODATA to be read as 0, regardless of their value. */ static enum gpio_level pl061_get_value(unsigned int gpio_pin) { vaddr_t base_addr; unsigned int offset; assert(gpio_pin < PLAT_PL061_MAX_GPIOS); base_addr = pl061_reg_base[gpio_pin / GPIOS_PER_PL061]; offset = gpio_pin % GPIOS_PER_PL061; if (io_read8(base_addr + BIT(offset + 2))) return GPIO_LEVEL_HIGH; return GPIO_LEVEL_LOW; }
enum pl061_mode_control pl061_get_mode_control(unsigned int gpio_pin) { vaddr_t base_addr; uint8_t data; unsigned int offset; assert(gpio_pin < PLAT_PL061_MAX_GPIOS); base_addr = pl061_reg_base[gpio_pin / GPIOS_PER_PL061]; offset = gpio_pin % GPIOS_PER_PL061; data = io_read8(base_addr + GPIOAFSEL); if (data & BIT(offset)) return PL061_MC_HW; return PL061_MC_SW; }
static enum gpio_dir pl061_get_direction(unsigned int gpio_pin) { vaddr_t base_addr; uint8_t data; unsigned int offset; assert(gpio_pin < PLAT_PL061_MAX_GPIOS); base_addr = pl061_reg_base[gpio_pin / GPIOS_PER_PL061]; offset = gpio_pin % GPIOS_PER_PL061; data = io_read8(base_addr + GPIODIR); if (data & BIT(offset)) return GPIO_DIR_OUT; return GPIO_DIR_IN; }
static enum gpio_interrupt pl061_get_interrupt(unsigned int gpio_pin) { vaddr_t base_addr; uint8_t data; unsigned int offset; assert(gpio_pin < PLAT_PL061_MAX_GPIOS); base_addr = pl061_reg_base[gpio_pin / GPIOS_PER_PL061]; offset = gpio_pin % GPIOS_PER_PL061; data = io_read8(base_addr + GPIOIE); if (data & BIT(offset)) return GPIO_INTERRUPT_ENABLE; return GPIO_INTERRUPT_DISABLE; }