From nobody Sun May 19 15:05:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1dmarc=pass fromdomain=outlook.com); dmarc=pass(p=none dis=none) header.from=outlook.com ARC-Seal: i=2; a=rsa-sha256; t=1601653155; cv=pass; d=zohomail.com; s=zohoarc; b=TmoEJh5kME0wQeDCYtif5TSmRAhpqRxqcx/awrHMwaW+v6QBDBlJReIhJc5bbhMGCMDNRhcYVwqMGY3GLJP8nF3Pnfz9Uyai3YBo4Z8DfuYCY/vDIdh212cJdSesoKQHEu5J5DgMb5G0b/kxYVE8PGd1ASMD+o052kb9TQ4IU1w= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1601653155; h=Content-Type:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=EvCPr822aZ1mtr1O9MIjExpuKyOjaSg5y98QbFXLKmA=; b=aZQWm/6a43tpY6so8IOj+nZmDphfGb8pf8aZXP82G1UMt5XyySEAYA84mAsMZw7uwjePEEwfaUgagdZoiHU/+yiYDk6lYVs0F7eKdDAm5wYef94eiZEcjpPNT1/SRYik7YR013dXeBGi5CFm4z9oDzlWmTsL34yB4UZ7nmczM2c= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1dmarc=pass fromdomain=outlook.com); dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 160165315549437.94509602391406; Fri, 2 Oct 2020 08:39:15 -0700 (PDT) Received: from localhost ([::1]:35366 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kON9O-00084K-0E for importer@patchew.org; Fri, 02 Oct 2020 11:39:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39910) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kOMgH-0000Br-CF for qemu-devel@nongnu.org; Fri, 02 Oct 2020 11:09:09 -0400 Received: from mail-bn8nam12olkn2093.outbound.protection.outlook.com ([40.92.21.93]:39513 helo=NAM12-BN8-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kOMgD-000889-Od for qemu-devel@nongnu.org; Fri, 02 Oct 2020 11:09:08 -0400 Received: from BN8NAM12FT011.eop-nam12.prod.protection.outlook.com (2a01:111:e400:fc66::49) by BN8NAM12HT111.eop-nam12.prod.protection.outlook.com (2a01:111:e400:fc66::165) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3433.14; Fri, 2 Oct 2020 14:54:03 +0000 Received: from DM6PR16MB2473.namprd16.prod.outlook.com (2a01:111:e400:fc66::52) by BN8NAM12FT011.mail.protection.outlook.com (2a01:111:e400:fc66::402) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3455.13 via Frontend Transport; Fri, 2 Oct 2020 14:54:02 +0000 Received: from DM6PR16MB2473.namprd16.prod.outlook.com ([fe80::ec2c:246a:b4d4:48b1]) by DM6PR16MB2473.namprd16.prod.outlook.com ([fe80::ec2c:246a:b4d4:48b1%3]) with mapi id 15.20.3433.039; Fri, 2 Oct 2020 14:54:02 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=DUuxu5k59tGTyCKJYRZLXogB8Jl+IZQVjnVRVt9Gxcqpv4kK1vHNUH5LXsKflnJHyoyz5bZqYxL0fmr8FK8/G5ASn41Ry4wGuDwsFUb46aLZcBJO33mZCMyqi4c892wGwkKseBpr9x/CYNBbdIy2sx3s6oSpioce7BEPUPTvYZDPgQP666V0Mk65HG1KZDEOWcFsVIMph8cof3VHfdArF2FanuSA1t/jqK1yL45xVQQ4Eryj+Ov/i8U2/BUcNaTLkoE174f7NwPd9r63tFyxJk2baCQZdjTq53Nse1TXh2tRi2e2xiCh7VURsLw0dPScjGlgZzUJFPs+91S8cxEvbQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=EvCPr822aZ1mtr1O9MIjExpuKyOjaSg5y98QbFXLKmA=; b=YSJiVqqlksPfNRAw02yGavD/HhouPUc+lOPxjm4SsU5VD12UbKNP+g6dSgOJpypKxR5xSY7J++8oWHaTW6m9w6AvPJwtnZDSKe1uhyFIA7be9V6BLGmrLejaWLr8A1Sh+bcz49FJKtoF26t8ov11xLLBqMuObX3rkSSTbYwffkhI256NgzHtPLt9WLyRCA+dH7sQ22DqJaLzybb9lnHg/9eFQqmkpJhuvTqFiW6qRaGLY6RctPRKxx609+SsDu6lu+m/6fju0KLvu7fx1t+02FnGnLWh6GchuntEyhBsMObHU9BTxtAhCWiGlBiEfahdE36skEX/ZPRyGiDiYZnJMw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=outlook.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=EvCPr822aZ1mtr1O9MIjExpuKyOjaSg5y98QbFXLKmA=; b=KNPQo7vHYe6Rc8ZEnSYDKF9WV/6Dm8n1rR1GS7cd7GgZxYlMjYCGYtSiLxwBxWi7V/WeBJuzttI3uxwue2G15E2Uq4YeJkv3XaKnQoB4GkIS1gZha1x/z4bYJAoBNEP25X4aYtlyA4vo1cHQCC8uYC82831B/PxISBLYldQ9dvuvOiLd5J1u//MDB+yrz7dSd1p6+iSmw7GlHQsSnpAxwHT1Wro2uf5UhlllAQalpjcleu05/zQ0NuOpC0aVQwA/bjBg3Pp5w656kJK/p2i3MuL9tCv5FC04+9PVA0y/jmrLByvrMrptvjJq4HSB07FXm+/h67UZsvXYwqpU/+KgUg== From: Hee-cheol Yang To: "qemu-devel@nongnu.org" Subject: [PATCH] hw/avr: Add limited support for avr gpio registers Thread-Topic: [PATCH] hw/avr: Add limited support for avr gpio registers Thread-Index: AQHWmMuG5NB1zodJTkmTnks0h4NKe6mEZb8V Date: Fri, 2 Oct 2020 14:54:02 +0000 Message-ID: References: In-Reply-To: Accept-Language: ko-KR, en-US Content-Language: ko-KR X-MS-Has-Attach: X-MS-TNEF-Correlator: x-incomingtopheadermarker: OriginalChecksum:EA23784BA90AFDB73384F86D56DE3CB024F4E1980A01B9ED9638CBB3F3F5F2A8; UpperCasedChecksum:21828AA91864BDA45CB7C0C1520513CC0F6630EC4B2F314E1A408D099383F7BB; SizeAsReceived:9027; Count:45 x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [jv/kqV2vgRqW1jSOr6enUh0gSJpmZJzh] x-ms-publictraffictype: Email x-incomingheadercount: 45 x-eopattributedmessage: 0 x-ms-office365-filtering-correlation-id: ff983c97-ce91-4a8b-9bce-08d866e300c8 x-ms-traffictypediagnostic: BN8NAM12HT111: x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: JCbn9udSRhLKzGHZbVKpy+tvmGHF4m3k9wnzDUIE6aKYr4RKEbNDcW1Be9n0iowo9xasIKYfuEyZKAiO/NyiCbVprUaPzqbmY984r4ab986UrJcip60o9JAJMSDsVg4U+YBs6F5b+4WLpFbN3Hgbmup17CxBQMiBfVvC8HODt9ybQfpnEUJ/HhqkMWnPO4R1qOpp1NyY5gxf5JxeBgVIyftu2k+NF/4th90d4/VkfuHynZi9X66c+HXB7Ea/HVSq x-ms-exchange-antispam-messagedata: ZC8blrrFe/jqmGWeCEqcJxUEi2rTGrJHQFeoa/0Xv4bYa9Ws+sfNFVrRqTlsuE5A1Yj92ZpmH9v8ISYvXyq8PiAjsWxF3URnfPeCmhLRGhihjEd8AUkzi55sN8OIacdekJMf74p1LZLmTLkLrR+0Bg== x-ms-exchange-transport-forked: True Content-Type: multipart/alternative; boundary="_000_DM6PR16MB2473E9E995E8EB3743368C48E6310DM6PR16MB2473namp_" MIME-Version: 1.0 X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-AuthSource: BN8NAM12FT011.eop-nam12.prod.protection.outlook.com X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-CrossTenant-Network-Message-Id: ff983c97-ce91-4a8b-9bce-08d866e300c8 X-MS-Exchange-CrossTenant-originalarrivaltime: 02 Oct 2020 14:54:02.8682 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Internet X-MS-Exchange-CrossTenant-id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-rms-persistedconsumerorg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN8NAM12HT111 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=40.92.21.93; envelope-from=heecheol.yang@outlook.com; helo=NAM12-BN8-obe.outbound.protection.outlook.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/02 11:09:04 X-ACL-Warn: Detected OS = Windows NT kernel [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "S.E.Harris@kent.ac.uk" , "mrolnik@gmail.com" Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @outlook.com) --_000_DM6PR16MB2473E9E995E8EB3743368C48E6310DM6PR16MB2473namp_ Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add some of these features for avr gpio: - GPIO I/O : PORTx registers - Data Direction : DDRx registers Following things are not supported yet: - PINx registers - MCUR registers - Even though read/write for DDRx registers are implemented, actual direction controls are not supported yet. Signed-off-by: Heecheol Yang --- hw/avr/Kconfig | 1 + hw/avr/atmega.c | 7 ++- hw/avr/atmega.h | 2 + hw/gpio/Kconfig | 3 + hw/gpio/avr_gpio.c | 117 +++++++++++++++++++++++++++++++++++++ hw/gpio/meson.build | 2 + include/hw/gpio/avr_gpio.h | 48 +++++++++++++++ 7 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 hw/gpio/avr_gpio.c create mode 100644 include/hw/gpio/avr_gpio.h diff --git a/hw/avr/Kconfig b/hw/avr/Kconfig index d31298c3cc..16a57ced11 100644 --- a/hw/avr/Kconfig +++ b/hw/avr/Kconfig @@ -3,6 +3,7 @@ config AVR_ATMEGA_MCU select AVR_TIMER16 select AVR_USART select AVR_POWER + select AVR_GPIO config ARDUINO select AVR_ATMEGA_MCU diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c index 44c6afebbb..ad942028fd 100644 --- a/hw/avr/atmega.c +++ b/hw/avr/atmega.c @@ -283,8 +283,11 @@ static void atmega_realize(DeviceState *dev, Error **e= rrp) continue; } devname =3D g_strdup_printf("atmega-gpio-%c", 'a' + (char)i); - create_unimplemented_device(devname, - OFFSET_DATA + mc->dev[idx].addr, 3); + object_initialize_child(OBJECT(dev), devname, &s->gpio[i], + TYPE_AVR_GPIO); + sysbus_realize(SYS_BUS_DEVICE(&s->gpio[i]), &error_abort); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, + OFFSET_DATA + mc->dev[idx].addr); g_free(devname); } diff --git a/hw/avr/atmega.h b/hw/avr/atmega.h index a99ee15c7e..e2289d5744 100644 --- a/hw/avr/atmega.h +++ b/hw/avr/atmega.h @@ -13,6 +13,7 @@ #include "hw/char/avr_usart.h" #include "hw/timer/avr_timer16.h" +#include "hw/gpio/avr_gpio.h" #include "hw/misc/avr_power.h" #include "target/avr/cpu.h" #include "qom/object.h" @@ -44,6 +45,7 @@ struct AtmegaMcuState { DeviceState *io; AVRMaskState pwr[POWER_MAX]; AVRUsartState usart[USART_MAX]; + AVRGPIOState gpio[GPIO_MAX]; AVRTimer16State timer[TIMER_MAX]; uint64_t xtal_freq_hz; }; diff --git a/hw/gpio/Kconfig b/hw/gpio/Kconfig index b6fdaa2586..1752d0ce56 100644 --- a/hw/gpio/Kconfig +++ b/hw/gpio/Kconfig @@ -10,3 +10,6 @@ config GPIO_KEY config SIFIVE_GPIO bool + +config AVR_GPIO + bool diff --git a/hw/gpio/avr_gpio.c b/hw/gpio/avr_gpio.c new file mode 100644 index 0000000000..7114216847 --- /dev/null +++ b/hw/gpio/avr_gpio.c @@ -0,0 +1,117 @@ +/* + * AVR processors GPIO registers emulation. + * + * Copyright (C) 2020 Heecheol Yang + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + */ +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "qemu/timer.h" +#include "qapi/error.h" +#include "hw/sysbus.h" +#include "hw/irq.h" +#include "hw/gpio/avr_gpio.h" +#include "hw/qdev-properties.h" +#include "chardev/char-fe.h" + +static void avr_gpio_reset(DeviceState *dev) +{ + AVRGPIOState *gpio =3D AVR_GPIO(dev); + gpio->ddr_val =3D 0u; + gpio->port_val =3D 0u; +} +static uint64_t avr_gpio_read(void *opaque, hwaddr offset, unsigned int si= ze) +{ + AVRGPIOState *s =3D (AVRGPIOState *)opaque; + switch (offset) { + case GPIO_PIN: + /* Not implemented yet */ + break; + case GPIO_DDR: + return s->ddr_val; + break; + case GPIO_PORT: + return s->port_val; + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %lx\n", + __func__, offset); + break; + } + return 0; +} + +static void avr_gpio_write(void *opaque, hwaddr offset, uint64_t value, + unsigned int size) +{ + AVRGPIOState *s =3D (AVRGPIOState *)opaque; + switch (offset) { + case GPIO_PIN: + /* Not implemented yet */ + break; + case GPIO_DDR: + s->ddr_val =3D value & 0xF; + break; + case GPIO_PORT: + s->port_val =3D value & 0xF; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %lx\n", + __func__, offset); + break; + } +} + +static const MemoryRegionOps avr_gpio_ops =3D { + .read =3D avr_gpio_read, + .write =3D avr_gpio_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, +}; + +static void avr_gpio_init(Object *obj) +{ + AVRGPIOState *s =3D AVR_GPIO(obj); + memory_region_init_io(&s->mmio, obj, &avr_gpio_ops, s, TYPE_AVR_GPIO, = 3); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); + s->enabled =3D true; +} +static void avr_gpio_realize(DeviceState *dev, Error **errp) +{ + avr_gpio_reset(dev); +} + + +static void avr_gpio_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->reset =3D avr_gpio_reset; + dc->realize =3D avr_gpio_realize; +} + +static const TypeInfo avr_gpio_info =3D { + .name =3D TYPE_AVR_GPIO, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(AVRGPIOState), + .instance_init =3D avr_gpio_init, + .class_init =3D avr_gpio_class_init, +}; + +static void avr_gpio_register_types(void) +{ + type_register_static(&avr_gpio_info); +} + +type_init(avr_gpio_register_types) diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build index 86cae9a0f3..258bd5dcfc 100644 --- a/hw/gpio/meson.build +++ b/hw/gpio/meson.build @@ -11,3 +11,5 @@ softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_= gpio.c')) softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_gpio.c')) softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_gpio.c')) softmmu_ss.add(when: 'CONFIG_SIFIVE_GPIO', if_true: files('sifive_gpio.c')) + +softmmu_ss.add(when: 'CONFIG_AVR_GPIO', if_true: files('avr_gpio.c')) diff --git a/include/hw/gpio/avr_gpio.h b/include/hw/gpio/avr_gpio.h new file mode 100644 index 0000000000..45d42753c8 --- /dev/null +++ b/include/hw/gpio/avr_gpio.h @@ -0,0 +1,48 @@ +/* + * AVR processors GPIO registers definition. + * + * Copyright (C) 2020 Heecheol Yang + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + */ + +#ifndef AVR_GPIO_H +#define AVR_GPIO_H + +#include "hw/sysbus.h" +#include "qom/object.h" +#include "chardev/char-fe.h" + +/* Offsets of registers. */ +#define GPIO_PIN 0x00 +#define GPIO_DDR 0x01 +#define GPIO_PORT 0x02 + +#define TYPE_AVR_GPIO "avr-gpio" +OBJECT_DECLARE_SIMPLE_TYPE(AVRGPIOState, AVR_GPIO) + +struct AVRGPIOState { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion mmio; + + uint8_t ddr_val; + uint8_t port_val; + bool enabled; + +}; + +#endif /* AVR_GPIO_H */ -- 2.17.1 --_000_DM6PR16MB2473E9E995E8EB3743368C48E6310DM6PR16MB2473namp_ Content-Type: text/html; charset="ks_c_5601-1987" Content-Transfer-Encoding: quoted-printable
Add some of these features for avr gpio:

  - GPIO I/O : PORTx registers
  - Data Direction : DDRx registers

Following things are not supported yet:
  - PINx registers
  - MCUR registers
  - Even though read/write for DDRx registers are
    implemented, actual direction controls are not
    supported yet.

Signed-off-by: Heecheol Yang <heecheol.yang@outlook.com>
---
 hw/avr/Kconfig         &= nbsp;   |   1 +
 hw/avr/atmega.c         =    |   7 ++-
 hw/avr/atmega.h         =    |   2 +
 hw/gpio/Kconfig         =    |   3 +
 hw/gpio/avr_gpio.c         | = 117 +++++++++++++++++++++++++++++++++++++
 hw/gpio/meson.build        | =   2 +
 include/hw/gpio/avr_gpio.h |  48 +++++++++++++++
 7 files changed, 178 insertions(+), 2 deletions(-)
 create mode 100644 hw/gpio/avr_gpio.c
 create mode 100644 include/hw/gpio/avr_gpio.h

diff --git a/hw/avr/Kconfig b/hw/avr/Kconfig
index d31298c3cc..16a57ced11 100644
--- a/hw/avr/Kconfig
+++ b/hw/avr/Kconfig
@@ -3,6 +3,7 @@ config AVR_ATMEGA_MCU
     select AVR_TIMER16
     select AVR_USART
     select AVR_POWER
+    select AVR_GPIO
 
 config ARDUINO
     select AVR_ATMEGA_MCU
diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c
index 44c6afebbb..ad942028fd 100644
--- a/hw/avr/atmega.c
+++ b/hw/avr/atmega.c
@@ -283,8 +283,11 @@ static void atmega_realize(DeviceState *dev, Error **e= rrp)
             co= ntinue;
         }
         devname =3D g_strdup_print= f("atmega-gpio-%c", 'a' + (char)i);
-        create_unimplemented_device(dev= name,
-            &n= bsp;            = ;           OFFSET_DATA += mc->dev[idx].addr, 3);
+        object_initialize_child(OBJECT(= dev), devname, &s->gpio[i],
+            &n= bsp;            = ;       TYPE_AVR_GPIO);
+        sysbus_realize(SYS_BUS_DEVICE(&= amp;s->gpio[i]), &error_abort);
+        sysbus_mmio_map(SYS_BUS_DEVICE(= &s->gpio[i]), 0,
+            OFFSET_= DATA + mc->dev[idx].addr);
         g_free(devname);
     }
 
diff --git a/hw/avr/atmega.h b/hw/avr/atmega.h
index a99ee15c7e..e2289d5744 100644
--- a/hw/avr/atmega.h
+++ b/hw/avr/atmega.h
@@ -13,6 +13,7 @@
 
 #include "hw/char/avr_usart.h"
 #include "hw/timer/avr_timer16.h"
+#include "hw/gpio/avr_gpio.h"
 #include "hw/misc/avr_power.h"
 #include "target/avr/cpu.h"
 #include "qom/object.h"
@@ -44,6 +45,7 @@ struct AtmegaMcuState {
     DeviceState *io;
     AVRMaskState pwr[POWER_MAX];
     AVRUsartState usart[USART_MAX];
+    AVRGPIOState gpio[GPIO_MAX];
     AVRTimer16State timer[TIMER_MAX];
     uint64_t xtal_freq_hz;
 };
diff --git a/hw/gpio/Kconfig b/hw/gpio/Kconfig
index b6fdaa2586..1752d0ce56 100644
--- a/hw/gpio/Kconfig
+++ b/hw/gpio/Kconfig
@@ -10,3 +10,6 @@ config GPIO_KEY
 
 config SIFIVE_GPIO
     bool
+
+config AVR_GPIO
+    bool
diff --git a/hw/gpio/avr_gpio.c b/hw/gpio/avr_gpio.c
new file mode 100644
index 0000000000..7114216847
--- /dev/null
+++ b/hw/gpio/avr_gpio.c
@@ -0,0 +1,117 @@
+/*
+ * AVR processors GPIO registers emulation.
+ *
+ * Copyright (C) 2020 Heecheol Yang <heecheol.yang@outlook.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along=
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "qapi/error.h"
+#include "hw/sysbus.h"
+#include "hw/irq.h"
+#include "hw/gpio/avr_gpio.h"
+#include "hw/qdev-properties.h"
+#include "chardev/char-fe.h"
+
+static void avr_gpio_reset(DeviceState *dev)
+{
+    AVRGPIOState *gpio =3D AVR_GPIO(dev);
+    gpio->ddr_val =3D 0u;
+    gpio->port_val =3D 0u;
+}
+static uint64_t avr_gpio_read(void *opaque, hwaddr offset, unsigned int si= ze)
+{
+    AVRGPIOState *s =3D (AVRGPIOState *)opaque;
+    switch (offset) {
+    case GPIO_PIN:
+        /* Not implemented yet */
+        break;
+    case GPIO_DDR:
+        return s->ddr_val;
+        break;
+    case GPIO_PORT:
+        return s->port_val;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, = "%s: Bad offset %lx\n",
+            &n= bsp;   __func__, offset);
+        break;
+    }
+    return 0;
+}
+
+static void avr_gpio_write(void *opaque, hwaddr offset, uint64_t value, +            &n= bsp;            = ;       unsigned int size)
+{
+    AVRGPIOState *s =3D (AVRGPIOState *)opaque;
+    switch (offset) {
+    case GPIO_PIN:
+        /* Not implemented yet */
+        break;
+    case GPIO_DDR:
+        s->ddr_val =3D value & 0= xF;
+        break;
+    case GPIO_PORT:
+        s->port_val =3D value & = 0xF;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, = "%s: Bad offset %lx\n",
+            &n= bsp;   __func__, offset);
+        break;
+    }
+}
+
+static const MemoryRegionOps avr_gpio_ops =3D {
+    .read =3D avr_gpio_read,
+    .write =3D avr_gpio_write,
+    .endianness =3D DEVICE_NATIVE_ENDIAN,
+};
+
+static void avr_gpio_init(Object *obj)
+{
+    AVRGPIOState *s =3D AVR_GPIO(obj);
+    memory_region_init_io(&s->mmio, obj, &avr_gp= io_ops, s, TYPE_AVR_GPIO, 3);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);=
+    s->enabled =3D true;
+}
+static void avr_gpio_realize(DeviceState *dev, Error **errp)
+{
+    avr_gpio_reset(dev);
+}
+
+
+static void avr_gpio_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc =3D DEVICE_CLASS(klass);
+
+    dc->reset =3D avr_gpio_reset;
+    dc->realize =3D avr_gpio_realize;
+}
+
+static const TypeInfo avr_gpio_info =3D {
+    .name        &n= bsp; =3D TYPE_AVR_GPIO,
+    .parent        =3D T= YPE_SYS_BUS_DEVICE,
+    .instance_size =3D sizeof(AVRGPIOState),
+    .instance_init =3D avr_gpio_init,
+    .class_init    =3D avr_gpio_class_init,<= br> +};
+
+static void avr_gpio_register_types(void)
+{
+    type_register_static(&avr_gpio_info);
+}
+
+type_init(avr_gpio_register_types)
diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
index 86cae9a0f3..258bd5dcfc 100644
--- a/hw/gpio/meson.build
+++ b/hw/gpio/meson.build
@@ -11,3 +11,5 @@ softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_= gpio.c'))
 softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_gpio.c')= )
 softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_gpio= .c'))
 softmmu_ss.add(when: 'CONFIG_SIFIVE_GPIO', if_true: files('sifive_gpi= o.c'))
+
+softmmu_ss.add(when: 'CONFIG_AVR_GPIO', if_true: files('avr_gpio.c'))
diff --git a/include/hw/gpio/avr_gpio.h b/include/hw/gpio/avr_gpio.h
new file mode 100644
index 0000000000..45d42753c8
--- /dev/null
+++ b/include/hw/gpio/avr_gpio.h
@@ -0,0 +1,48 @@
+/*
+ * AVR processors GPIO registers definition.
+ *
+ * Copyright (C) 2020 Heecheol Yang <heecheol.yang@outlook.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along=
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef AVR_GPIO_H
+#define AVR_GPIO_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+#include "chardev/char-fe.h"
+
+/* Offsets of registers. */
+#define GPIO_PIN   0x00
+#define GPIO_DDR   0x01
+#define GPIO_PORT  0x02
+
+#define TYPE_AVR_GPIO "avr-gpio"
+OBJECT_DECLARE_SIMPLE_TYPE(AVRGPIOState, AVR_GPIO)
+
+struct AVRGPIOState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    MemoryRegion mmio;
+
+    uint8_t ddr_val;
+    uint8_t port_val;
+    bool enabled;
+
+};
+
+#endif /* AVR_GPIO_H */
--
2.17.1

--_000_DM6PR16MB2473E9E995E8EB3743368C48E6310DM6PR16MB2473namp_--