qemu

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

rx62n.c (10603B)


      1 /*
      2  * RX62N Microcontroller
      3  *
      4  * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware
      5  * (Rev.1.40 R01UH0033EJ0140)
      6  *
      7  * Copyright (c) 2019 Yoshinori Sato
      8  * Copyright (c) 2020 Philippe Mathieu-Daudé
      9  *
     10  * This program is free software; you can redistribute it and/or modify it
     11  * under the terms and conditions of the GNU General Public License,
     12  * version 2 or later, as published by the Free Software Foundation.
     13  *
     14  * This program is distributed in the hope it will be useful, but WITHOUT
     15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     16  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
     17  * more details.
     18  *
     19  * You should have received a copy of the GNU General Public License along with
     20  * this program.  If not, see <http://www.gnu.org/licenses/>.
     21  */
     22 
     23 #include "qemu/osdep.h"
     24 #include "qapi/error.h"
     25 #include "qemu/error-report.h"
     26 #include "hw/rx/rx62n.h"
     27 #include "hw/loader.h"
     28 #include "hw/sysbus.h"
     29 #include "hw/qdev-properties.h"
     30 #include "sysemu/sysemu.h"
     31 #include "qom/object.h"
     32 
     33 /*
     34  * RX62N Internal Memory
     35  */
     36 #define RX62N_IRAM_BASE     0x00000000
     37 #define RX62N_DFLASH_BASE   0x00100000
     38 #define RX62N_CFLASH_BASE   0xfff80000
     39 
     40 /*
     41  * RX62N Peripheral Address
     42  * See users manual section 5
     43  */
     44 #define RX62N_ICU_BASE  0x00087000
     45 #define RX62N_TMR_BASE  0x00088200
     46 #define RX62N_CMT_BASE  0x00088000
     47 #define RX62N_SCI_BASE  0x00088240
     48 
     49 /*
     50  * RX62N Peripheral IRQ
     51  * See users manual section 11
     52  */
     53 #define RX62N_TMR_IRQ   174
     54 #define RX62N_CMT_IRQ   28
     55 #define RX62N_SCI_IRQ   214
     56 
     57 #define RX62N_XTAL_MIN_HZ  (8 * 1000 * 1000)
     58 #define RX62N_XTAL_MAX_HZ (14 * 1000 * 1000)
     59 #define RX62N_PCLK_MAX_HZ (50 * 1000 * 1000)
     60 
     61 struct RX62NClass {
     62     /*< private >*/
     63     DeviceClass parent_class;
     64     /*< public >*/
     65     const char *name;
     66     uint64_t ram_size;
     67     uint64_t rom_flash_size;
     68     uint64_t data_flash_size;
     69 };
     70 typedef struct RX62NClass RX62NClass;
     71 
     72 DECLARE_CLASS_CHECKERS(RX62NClass, RX62N_MCU,
     73                        TYPE_RX62N_MCU)
     74 
     75 /*
     76  * IRQ -> IPR mapping table
     77  * 0x00 - 0x91: IPR no (IPR00 to IPR91)
     78  * 0xff: IPR not assigned
     79  * See "11.3.1 Interrupt Vector Table" in hardware manual.
     80  */
     81 static const uint8_t ipr_table[NR_IRQS] = {
     82     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     83     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 15 */
     84     0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0x02,
     85     0xff, 0xff, 0xff, 0x03, 0x04, 0x05, 0x06, 0x07, /* 31 */
     86     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
     87     0x10, 0x11, 0x12, 0x13, 0x14, 0x14, 0x14, 0x14, /* 47 */
     88     0x15, 0x15, 0x15, 0x15, 0xff, 0xff, 0xff, 0xff,
     89     0x18, 0x18, 0x18, 0x18, 0x18, 0x1d, 0x1e, 0x1f, /* 63 */
     90     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
     91     0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 79 */
     92     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     93     0xff, 0xff, 0x3a, 0x3b, 0x3c, 0xff, 0xff, 0xff, /* 95 */
     94     0x40, 0xff, 0x44, 0x45, 0xff, 0xff, 0x48, 0xff,
     95     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 111 */
     96     0xff, 0xff, 0x51, 0x51, 0x51, 0x51, 0x52, 0x52,
     97     0x52, 0x53, 0x53, 0x54, 0x54, 0x55, 0x55, 0x56, /* 127 */
     98     0x56, 0x57, 0x57, 0x57, 0x57, 0x58, 0x59, 0x59,
     99     0x59, 0x59, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5c, /* 143 */
    100     0x5c, 0x5c, 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f,
    101     0x5f, 0x60, 0x60, 0x61, 0x61, 0x62, 0x62, 0x62, /* 159 */
    102     0x62, 0x63, 0x64, 0x64, 0x64, 0x64, 0x65, 0x66,
    103     0x66, 0x66, 0x67, 0x67, 0x67, 0x67, 0x68, 0x68, /* 175 */
    104     0x68, 0x69, 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6b,
    105     0x6b, 0x6b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 191 */
    106     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0x71,
    107     0x72, 0x73, 0x74, 0x75, 0xff, 0xff, 0xff, 0xff, /* 207 */
    108     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80,
    109     0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, /* 223 */
    110     0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0xff, 0xff,
    111     0xff, 0xff, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, /* 239 */
    112     0x86, 0x86, 0xff, 0xff, 0xff, 0xff, 0x88, 0x89,
    113     0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, /* 255 */
    114 };
    115 
    116 /*
    117  * Level triggerd IRQ list
    118  * Not listed IRQ is Edge trigger.
    119  * See "11.3.1 Interrupt Vector Table" in hardware manual.
    120  */
    121 static const uint8_t levelirq[] = {
    122      16,  21,  32,  44,  47,  48,  51,  64,  65,  66,
    123      67,  68,  69,  70,  71,  72,  73,  74,  75,  76,
    124      77,  78,  79,  90,  91, 170, 171, 172, 173, 214,
    125     217, 218, 221, 222, 225, 226, 229, 234, 237, 238,
    126     241, 246, 249, 250, 253,
    127 };
    128 
    129 static void register_icu(RX62NState *s)
    130 {
    131     int i;
    132     SysBusDevice *icu;
    133 
    134     object_initialize_child(OBJECT(s), "icu", &s->icu, TYPE_RX_ICU);
    135     icu = SYS_BUS_DEVICE(&s->icu);
    136     qdev_prop_set_uint32(DEVICE(icu), "len-ipr-map", NR_IRQS);
    137     for (i = 0; i < NR_IRQS; i++) {
    138         char propname[32];
    139         snprintf(propname, sizeof(propname), "ipr-map[%d]", i);
    140         qdev_prop_set_uint32(DEVICE(icu), propname, ipr_table[i]);
    141     }
    142     qdev_prop_set_uint32(DEVICE(icu), "len-trigger-level",
    143                          ARRAY_SIZE(levelirq));
    144     for (i = 0; i < ARRAY_SIZE(levelirq); i++) {
    145         char propname[32];
    146         snprintf(propname, sizeof(propname), "trigger-level[%d]", i);
    147         qdev_prop_set_uint32(DEVICE(icu), propname, levelirq[i]);
    148     }
    149 
    150     for (i = 0; i < NR_IRQS; i++) {
    151         s->irq[i] = qdev_get_gpio_in(DEVICE(icu), i);
    152     }
    153     sysbus_realize(icu, &error_abort);
    154     sysbus_connect_irq(icu, 0, qdev_get_gpio_in(DEVICE(&s->cpu), RX_CPU_IRQ));
    155     sysbus_connect_irq(icu, 1, qdev_get_gpio_in(DEVICE(&s->cpu), RX_CPU_FIR));
    156     sysbus_connect_irq(icu, 2, s->irq[SWI]);
    157     sysbus_mmio_map(SYS_BUS_DEVICE(icu), 0, RX62N_ICU_BASE);
    158 }
    159 
    160 static void register_tmr(RX62NState *s, int unit)
    161 {
    162     SysBusDevice *tmr;
    163     int i, irqbase;
    164 
    165     object_initialize_child(OBJECT(s), "tmr[*]",
    166                             &s->tmr[unit], TYPE_RENESAS_TMR);
    167     tmr = SYS_BUS_DEVICE(&s->tmr[unit]);
    168     qdev_prop_set_uint64(DEVICE(tmr), "input-freq", s->pclk_freq_hz);
    169     sysbus_realize(tmr, &error_abort);
    170 
    171     irqbase = RX62N_TMR_IRQ + TMR_NR_IRQ * unit;
    172     for (i = 0; i < TMR_NR_IRQ; i++) {
    173         sysbus_connect_irq(tmr, i, s->irq[irqbase + i]);
    174     }
    175     sysbus_mmio_map(tmr, 0, RX62N_TMR_BASE + unit * 0x10);
    176 }
    177 
    178 static void register_cmt(RX62NState *s, int unit)
    179 {
    180     SysBusDevice *cmt;
    181     int i, irqbase;
    182 
    183     object_initialize_child(OBJECT(s), "cmt[*]",
    184                             &s->cmt[unit], TYPE_RENESAS_CMT);
    185     cmt = SYS_BUS_DEVICE(&s->cmt[unit]);
    186     qdev_prop_set_uint64(DEVICE(cmt), "input-freq", s->pclk_freq_hz);
    187     sysbus_realize(cmt, &error_abort);
    188 
    189     irqbase = RX62N_CMT_IRQ + CMT_NR_IRQ * unit;
    190     for (i = 0; i < CMT_NR_IRQ; i++) {
    191         sysbus_connect_irq(cmt, i, s->irq[irqbase + i]);
    192     }
    193     sysbus_mmio_map(cmt, 0, RX62N_CMT_BASE + unit * 0x10);
    194 }
    195 
    196 static void register_sci(RX62NState *s, int unit)
    197 {
    198     SysBusDevice *sci;
    199     int i, irqbase;
    200 
    201     object_initialize_child(OBJECT(s), "sci[*]",
    202                             &s->sci[unit], TYPE_RENESAS_SCI);
    203     sci = SYS_BUS_DEVICE(&s->sci[unit]);
    204     qdev_prop_set_chr(DEVICE(sci), "chardev", serial_hd(unit));
    205     qdev_prop_set_uint64(DEVICE(sci), "input-freq", s->pclk_freq_hz);
    206     sysbus_realize(sci, &error_abort);
    207 
    208     irqbase = RX62N_SCI_IRQ + SCI_NR_IRQ * unit;
    209     for (i = 0; i < SCI_NR_IRQ; i++) {
    210         sysbus_connect_irq(sci, i, s->irq[irqbase + i]);
    211     }
    212     sysbus_mmio_map(sci, 0, RX62N_SCI_BASE + unit * 0x08);
    213 }
    214 
    215 static void rx62n_realize(DeviceState *dev, Error **errp)
    216 {
    217     RX62NState *s = RX62N_MCU(dev);
    218     RX62NClass *rxc = RX62N_MCU_GET_CLASS(dev);
    219 
    220     if (s->xtal_freq_hz == 0) {
    221         error_setg(errp, "\"xtal-frequency-hz\" property must be provided.");
    222         return;
    223     }
    224     /* XTAL range: 8-14 MHz */
    225     if (s->xtal_freq_hz < RX62N_XTAL_MIN_HZ
    226             || s->xtal_freq_hz > RX62N_XTAL_MAX_HZ) {
    227         error_setg(errp, "\"xtal-frequency-hz\" property in incorrect range.");
    228         return;
    229     }
    230     /* Use a 4x fixed multiplier */
    231     s->pclk_freq_hz = 4 * s->xtal_freq_hz;
    232     /* PCLK range: 8-50 MHz */
    233     assert(s->pclk_freq_hz <= RX62N_PCLK_MAX_HZ);
    234 
    235     memory_region_init_ram(&s->iram, OBJECT(dev), "iram",
    236                            rxc->ram_size, &error_abort);
    237     memory_region_add_subregion(s->sysmem, RX62N_IRAM_BASE, &s->iram);
    238     memory_region_init_rom(&s->d_flash, OBJECT(dev), "flash-data",
    239                            rxc->data_flash_size, &error_abort);
    240     memory_region_add_subregion(s->sysmem, RX62N_DFLASH_BASE, &s->d_flash);
    241     memory_region_init_rom(&s->c_flash, OBJECT(dev), "flash-code",
    242                            rxc->rom_flash_size, &error_abort);
    243     memory_region_add_subregion(s->sysmem, RX62N_CFLASH_BASE, &s->c_flash);
    244 
    245     /* Initialize CPU */
    246     object_initialize_child(OBJECT(s), "cpu", &s->cpu, TYPE_RX62N_CPU);
    247     qdev_realize(DEVICE(&s->cpu), NULL, &error_abort);
    248 
    249     register_icu(s);
    250     s->cpu.env.ack = qdev_get_gpio_in_named(DEVICE(&s->icu), "ack", 0);
    251     register_tmr(s, 0);
    252     register_tmr(s, 1);
    253     register_cmt(s, 0);
    254     register_cmt(s, 1);
    255     register_sci(s, 0);
    256 }
    257 
    258 static Property rx62n_properties[] = {
    259     DEFINE_PROP_LINK("main-bus", RX62NState, sysmem, TYPE_MEMORY_REGION,
    260                      MemoryRegion *),
    261     DEFINE_PROP_BOOL("load-kernel", RX62NState, kernel, false),
    262     DEFINE_PROP_UINT32("xtal-frequency-hz", RX62NState, xtal_freq_hz, 0),
    263     DEFINE_PROP_END_OF_LIST(),
    264 };
    265 
    266 static void rx62n_class_init(ObjectClass *klass, void *data)
    267 {
    268     DeviceClass *dc = DEVICE_CLASS(klass);
    269 
    270     dc->realize = rx62n_realize;
    271     device_class_set_props(dc, rx62n_properties);
    272 }
    273 
    274 static void r5f562n7_class_init(ObjectClass *oc, void *data)
    275 {
    276     RX62NClass *rxc = RX62N_MCU_CLASS(oc);
    277 
    278     rxc->ram_size = 64 * KiB;
    279     rxc->rom_flash_size = 384 * KiB;
    280     rxc->data_flash_size = 32 * KiB;
    281 };
    282 
    283 static void r5f562n8_class_init(ObjectClass *oc, void *data)
    284 {
    285     RX62NClass *rxc = RX62N_MCU_CLASS(oc);
    286 
    287     rxc->ram_size = 96 * KiB;
    288     rxc->rom_flash_size = 512 * KiB;
    289     rxc->data_flash_size = 32 * KiB;
    290 };
    291 
    292 static const TypeInfo rx62n_types[] = {
    293     {
    294         .name           = TYPE_R5F562N7_MCU,
    295         .parent         = TYPE_RX62N_MCU,
    296         .class_init     = r5f562n7_class_init,
    297     }, {
    298         .name           = TYPE_R5F562N8_MCU,
    299         .parent         = TYPE_RX62N_MCU,
    300         .class_init     = r5f562n8_class_init,
    301     }, {
    302         .name           = TYPE_RX62N_MCU,
    303         .parent         = TYPE_DEVICE,
    304         .instance_size  = sizeof(RX62NState),
    305         .class_size     = sizeof(RX62NClass),
    306         .class_init     = rx62n_class_init,
    307         .abstract       = true,
    308      }
    309 };
    310 
    311 DEFINE_TYPES(rx62n_types)