• R/O
  • HTTP
  • SSH
  • HTTPS

提交

标签
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

修订版2308ac2b7c0a49a0cf66ac4877871461e2cd00fc (tree)
时间2019-08-29 22:56:39
作者Yoshinori Sato <ysato@user...>
CommiterYoshinori Sato

Log Message

SH initial submit

更改概述

差异

--- a/arch_init.c
+++ b/arch_init.c
@@ -77,8 +77,8 @@ int graphic_depth = 32;
7777 #define QEMU_ARCH QEMU_ARCH_RX
7878 #elif defined(TARGET_S390X)
7979 #define QEMU_ARCH QEMU_ARCH_S390X
80-#elif defined(TARGET_SH4)
81-#define QEMU_ARCH QEMU_ARCH_SH4
80+#elif defined(TARGET_SH)
81+#define QEMU_ARCH QEMU_ARCH_SH
8282 #elif defined(TARGET_SPARC)
8383 #define QEMU_ARCH QEMU_ARCH_SPARC
8484 #elif defined(TARGET_TRICORE)
--- a/configure
+++ b/configure
@@ -7427,7 +7427,7 @@ target_name=$(echo $target | cut -d '-' -f 1)
74277427 target_bigendian="no"
74287428
74297429 case "$target_name" in
7430- armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppc64|ppc64abi32|s390x|sh2|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
7430+ armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppc64|ppc64abi32|s390x|sh|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
74317431 target_bigendian=yes
74327432 ;;
74337433 esac
@@ -7600,9 +7600,13 @@ case "$target_name" in
76007600 target_compiler=$cross_cc_riscv64
76017601 ;;
76027602 rx)
7603- TARGET_ARCH=rx
7603+ TARGET_ARCH=rx
7604+ ;;
7605+ sh)
7606+ TARGET_ARCH=sh
76047607 bflt="yes"
7605- target_compiler=$cross_cc_rx
7608+ gdb_xml_files="sh-core.xml sh2a-nofpu.xml sh2a-fpu.xml sh3.xml sh4-dfp.xml sh4-vfp.xml"
7609+ target_compiler=$cross_cc_sh
76067610 ;;
76077611 sh4|sh4eb)
76087612 TARGET_ARCH=sh4
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -56,7 +56,7 @@ source ppc/Kconfig
5656 source riscv/Kconfig
5757 source rx/Kconfig
5858 source s390x/Kconfig
59-source sh4/Kconfig
59+source sh/Kconfig
6060 source sparc/Kconfig
6161 source sparc64/Kconfig
6262 source tricore/Kconfig
--- a/hw/char/Makefile.objs
+++ b/hw/char/Makefile.objs
@@ -16,7 +16,7 @@ common-obj-$(CONFIG_CADENCE) += cadence_uart.o
1616 obj-$(CONFIG_EXYNOS4) += exynos4210_uart.o
1717 obj-$(CONFIG_COLDFIRE) += mcf_uart.o
1818 obj-$(CONFIG_OMAP) += omap_uart.o
19-obj-$(CONFIG_SH4) += sh_serial.o
19+obj-$(CONFIG_SH) += sh_serial.o
2020 obj-$(CONFIG_PSERIES) += spapr_vty.o
2121 obj-$(CONFIG_DIGIC) += digic-uart.o
2222 obj-$(CONFIG_STM32F2XX_USART) += stm32f2xx_usart.o
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -33,7 +33,9 @@ obj-$(CONFIG_IOAPIC) += ioapic.o
3333 obj-$(CONFIG_OMAP) += omap_intc.o
3434 obj-$(CONFIG_OPENPIC_KVM) += openpic_kvm.o
3535 obj-$(CONFIG_RASPI) += bcm2835_ic.o bcm2836_control.o
36-obj-$(CONFIG_SH4) += sh_intc.o sh7619_intc.o
36+obj-$(CONFIG_SH7750) += sh_intc.o
37+obj-$(CONFIG_SH7751) += sh_intc.o
38+obj-$(CONFIG_SH7619) += sh7619_intc.o
3739 obj-$(CONFIG_XICS) += xics.o
3840 obj-$(CONFIG_XICS_SPAPR) += xics_spapr.o
3941 obj-$(CONFIG_XICS_KVM) += xics_kvm.o
--- a/hw/intc/sh7619_intc.c
+++ b/hw/intc/sh7619_intc.c
@@ -1,7 +1,7 @@
11 /*
22 * SH7619 Interrupt controller
33 *
4- * Copyright (c) 2018 Yoshinori Sato
4+ * Copyright (c) 2019 Yoshinori Sato
55 *
66 * This code is licensed under the GPL.
77 */
@@ -15,11 +15,31 @@
1515 #include "hw/intc/sh7619intc.h"
1616 #include "qemu/error-report.h"
1717
18+static int priority(SH7619INTCState *intc, int req)
19+{
20+ static const int map[] = {
21+ 3, 2, 1, 0, -1, -1, -1, -1,
22+ -1, -1, -1, -1, -1, -1, -1, -1,
23+ 7, 6, 5, 4, 11, 10, 9, 8,
24+ 15, 15, 15, 15, 14, 14, 14, 14,
25+ 13, 13, 13, 13, 19, 18, -1, -1,
26+ 23, 22, 21, 20, 27, -1, -1, -1,
27+ -1, -1, -1, -1, -1, -1, -1, -1,
28+ -1, -1, -1, -1, -1, -1, -1, -1,
29+ };
30+ int offset;
31+ int pos;
32+ offset = map[req - 64] / 4;
33+ pos = map[req - 64] % 4;
34+ return (intc->ipr[offset] >> pos) & 0x000f;
35+}
36+
1837 static void sh7619intc_set_irq(void *opaque, int n_IRQ, int level)
1938 {
2039 SH7619INTCState *intc = opaque;
2140 struct IRQSource *src;
2241 int issue = 0;
42+ int p;
2343
2444 n_IRQ += 64;
2545 if (n_IRQ < 64 || n_IRQ >= 128) {
@@ -67,42 +87,21 @@ static void sh7619intc_set_irq(void *opaque, int n_IRQ, int level)
6787 intc->irqsr |= (1 << (n_IRQ - 64));
6888 src->req = 1;
6989 if(intc->req_irq < 0) {
70- qemu_set_irq(intc->irq, 1);
90+ p = priority(intc, n_IRQ);
91+ qemu_set_irq(intc->irq, (p << 8) |n_IRQ);
7192 intc->req_irq = n_IRQ;
7293 }
7394 }
7495 }
7596
76-static int priority(SH7619INTCState *intc, int req)
97+static void intc_ack(void *opaque, int no, int request)
7798 {
78- static const int map[] = {
79- 3, 2, 1, 0, -1, -1, -1, -1,
80- -1, -1, -1, -1, -1, -1, -1, -1,
81- 7, 6, 5, 4, 11, 10, 9, 8,
82- 15, 15, 15, 15, 14, 14, 14, 14,
83- 13, 13, 13, 13, 19, 18, -1, -1,
84- 23, 22, 21, 20, 27, -1, -1, -1,
85- -1, -1, -1, -1, -1, -1, -1, -1,
86- -1, -1, -1, -1, -1, -1, -1, -1,
87- };
88- int offset;
89- int pos;
90- offset = map[req - 64] / 4;
91- pos = map[req - 64] % 4;
92- return (intc->ipr[offset] >> pos) & 0x000f;
93-}
94-
95-int sh2_intc_get_pending_vector(void *state, int imask, int *level)
96-{
97- SH7619INTCState *intc = SH7619INTC(state);
99+ SH7619INTCState *intc = SH7619INTC(opaque);
98100 int pri = priority(intc, intc->req_irq);
99- int ret = -1;
100101 int i;
101102 int pend;
102103
103- if (pri > imask) {
104- *level = pri;
105- ret = intc->req_irq;
104+ if (request == intc->req_irq) {
106105 intc->src[intc->req_irq - 64].req = 0;
107106 intc->req_irq = -1;
108107 }
@@ -115,10 +114,9 @@ int sh2_intc_get_pending_vector(void *state, int imask, int *level)
115114 }
116115 }
117116 if (pend >= 0) {
118- qemu_set_irq(intc->irq, 1);
117+ qemu_set_irq(intc->irq, (pri << 8) | pend);
119118 intc->req_irq = pend;
120119 }
121- return ret;
122120 }
123121
124122 static void intc_write1(void *opaque, hwaddr addr, uint64_t val, unsigned size)
@@ -315,6 +313,7 @@ static void sh7619intc_init(Object *obj)
315313 sysbus_init_mmio(d, &intc->memory[1]);
316314
317315 qdev_init_gpio_in(DEVICE(d), sh7619intc_set_irq, 64);
316+ qdev_init_gpio_in_named(DEVICE(d), intc_ack, "ack", 1);
318317 sysbus_init_irq(d, &intc->irq);
319318 }
320319
--- /dev/null
+++ b/hw/sh/Kconfig
@@ -0,0 +1,12 @@
1+config MS7619SE
2+ bool
3+ select SH7619
4+ select PFLASH_CFI01
5+
6+config SH7619
7+ bool
8+ select SH
9+ select RENESAS_CMT
10+
11+config SH
12+ bool
--- /dev/null
+++ b/hw/sh/Makefile.objs
@@ -0,0 +1,6 @@
1+obj-$(CONFIG_SH7750) += sh7750.o sh7750_regnames.o
2+obj-$(CONFIG_SH7751) += sh7750.o sh7750_regnames.o sh_pci.o
3+obj-$(CONFIG_SH7619) += sh7619.o
4+obj-$(CONFIG_R2D) += r2d.o
5+obj-$(CONFIG_SHIX) += shix.o
6+obj-$(CONFIG_MS7619SE) += ms7619se.o
--- /dev/null
+++ b/hw/sh/ms7619se.c
@@ -0,0 +1,166 @@
1+/*
2+ * SolutionEngine MS7619SE emulation
3+ *
4+ * Copyright (c) 2018 Yoshinori Sato
5+ *
6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7+ * of this software and associated documentation files (the "Software"), to deal
8+ * in the Software without restriction, including without limitation the rights
9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+ * THE SOFTWARE.
23+ */
24+
25+#include "qemu/osdep.h"
26+#include "qemu/error-report.h"
27+#include "qemu/units.h"
28+#include "qapi/error.h"
29+#include "qemu-common.h"
30+#include "cpu.h"
31+#include "hw/hw.h"
32+#include "hw/sysbus.h"
33+#include "hw/loader.h"
34+#include "hw/sh/sh7619.h"
35+#include "sysemu/sysemu.h"
36+#include "sysemu/qtest.h"
37+#include "sysemu/device_tree.h"
38+#include "hw/boards.h"
39+#include "hw/block/flash.h"
40+#include "exec/address-spaces.h"
41+#include "exec/cpu-all.h"
42+
43+#define FLASH_BASE 0x00000000
44+#define FLASH_SIZE 0x02000000
45+
46+#define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */
47+#define SDRAM_SIZE 0x04000000
48+
49+#define BOOT_PARAMS_OFFSET 0x0001000
50+/* CONFIG_BOOT_LINK_OFFSET of Linux kernel */
51+#define LINUX_LOAD_OFFSET 0x0800000
52+#define INITRD_LOAD_OFFSET 0x1800000
53+
54+static struct QEMU_PACKED
55+{
56+ int mount_root_rdonly;
57+ int ramdisk_flags;
58+ int orig_root_dev;
59+ int loader_type;
60+ int initrd_start;
61+ int initrd_size;
62+
63+ char pad[232];
64+
65+ char kernel_cmdline[256];
66+} boot_params;
67+
68+static void ms7619se_init(MachineState *machine)
69+{
70+ SH7619State *s = g_new(SH7619State, 1);
71+ MemoryRegion *sysmem = get_system_memory();
72+ MemoryRegion *sdram = g_new(MemoryRegion, 1);
73+ DriveInfo *dinfo;
74+ const char *kernel_filename = machine->kernel_filename;
75+ const char *kernel_cmdline = machine->kernel_cmdline;
76+ const char *initrd_filename = machine->initrd_filename;
77+
78+ /* Allocate memory space */
79+ memory_region_init_ram(sdram, NULL, "ms7619se.sdram", 64 * MiB,
80+ &error_fatal);
81+ memory_region_add_subregion(sysmem, 0x0c000000, sdram);
82+ dinfo = drive_get(IF_PFLASH, 0, 0);
83+ pflash_cfi01_register(0x0, "ms7619se.flash", 16 * MiB,
84+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
85+ 64 * KiB, 2, 0x0000, 0x0102, 0x0e1c, 0x0f1e,
86+ 0);
87+ object_initialize_child(OBJECT(machine), "sh7619", s,
88+ sizeof(SH7619State), TYPE_SH7619,
89+ &error_fatal, NULL);
90+ object_property_set_link(OBJECT(s), OBJECT(sysmem),
91+ "memory", &error_abort);
92+
93+ memset(&boot_params, 0, sizeof(boot_params));
94+
95+ if (kernel_filename) {
96+ int kernel_size;
97+
98+ kernel_size = load_image_targphys(kernel_filename,
99+ SDRAM_BASE + LINUX_LOAD_OFFSET,
100+ INITRD_LOAD_OFFSET - LINUX_LOAD_OFFSET);
101+ if (kernel_size < 0) {
102+ error_report("could not load kernel '%s'\n", kernel_filename);
103+ exit(1);
104+ }
105+ SUPERH_CPU(first_cpu)->env.pc = 0x80000000 +
106+ SDRAM_BASE + LINUX_LOAD_OFFSET;
107+ s->frqcr = 0x1103;
108+ if (initrd_filename) {
109+ int initrd_size;
110+
111+ initrd_size = load_image_targphys(initrd_filename,
112+ SDRAM_BASE + INITRD_LOAD_OFFSET,
113+ SDRAM_SIZE - INITRD_LOAD_OFFSET);
114+
115+ if (initrd_size < 0) {
116+ error_report("qemu: could not load initrd '%s'\n",
117+ initrd_filename);
118+ exit(1);
119+ }
120+ /* initialization which should be done by firmware */
121+ boot_params.loader_type = tswap32(1);
122+ boot_params.initrd_start = tswap32(INITRD_LOAD_OFFSET);
123+ boot_params.initrd_size = tswap32(initrd_size);
124+ }
125+
126+ if (kernel_cmdline) {
127+ /* I see no evidence that this .kernel_cmdline buffer requires
128+ NUL-termination, so using strncpy should be ok. */
129+ strncpy(boot_params.kernel_cmdline, kernel_cmdline,
130+ sizeof(boot_params.kernel_cmdline));
131+ }
132+
133+ rom_add_blob_fixed("boot_params", &boot_params, sizeof(boot_params),
134+ SDRAM_BASE + BOOT_PARAMS_OFFSET);
135+ }
136+ if (bios_name) {
137+ load_image_targphys(bios_name, 0, 16 * MiB);
138+ }
139+ if (bios_name == NULL && kernel_filename == NULL && !qtest_enabled()) {
140+ error_report("No bios or kernel specified");
141+ exit(1);
142+ }
143+ object_property_set_bool(OBJECT(s), true, "realized", &error_abort);
144+}
145+
146+static void ms7619se_class_init(ObjectClass *oc, void *data)
147+{
148+ MachineClass *mc = MACHINE_CLASS(oc);
149+
150+ mc->desc = "SolutionEngine 7619";
151+ mc->init = ms7619se_init;
152+ mc->default_cpu_type = TYPE_SH2_CPU;
153+}
154+
155+static const TypeInfo ms7619se_type = {
156+ .name = MACHINE_TYPE_NAME("ms7619se"),
157+ .parent = TYPE_MACHINE,
158+ .class_init = ms7619se_class_init,
159+};
160+
161+static void ms7619se_machine_init(void)
162+{
163+ type_register_static(&ms7619se_type);
164+}
165+
166+type_init(ms7619se_machine_init)
--- /dev/null
+++ b/hw/sh/r2d.c
@@ -0,0 +1,371 @@
1+/*
2+ * Renesas SH7751R R2D-PLUS emulation
3+ *
4+ * Copyright (c) 2007 Magnus Damm
5+ * Copyright (c) 2008 Paul Mundt
6+ *
7+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8+ * of this software and associated documentation files (the "Software"), to deal
9+ * in the Software without restriction, including without limitation the rights
10+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+ * copies of the Software, and to permit persons to whom the Software is
12+ * furnished to do so, subject to the following conditions:
13+ *
14+ * The above copyright notice and this permission notice shall be included in
15+ * all copies or substantial portions of the Software.
16+ *
17+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+ * THE SOFTWARE.
24+ */
25+
26+#include "qemu/osdep.h"
27+#include "qemu/units.h"
28+#include "qapi/error.h"
29+#include "cpu.h"
30+#include "hw/sysbus.h"
31+#include "hw/hw.h"
32+#include "hw/sh4/sh.h"
33+#include "sysemu/sysemu.h"
34+#include "hw/boards.h"
35+#include "hw/pci/pci.h"
36+#include "net/net.h"
37+#include "sh7750_regs.h"
38+#include "hw/ide.h"
39+#include "hw/loader.h"
40+#include "hw/usb.h"
41+#include "hw/block/flash.h"
42+#include "exec/address-spaces.h"
43+
44+#define FLASH_BASE 0x00000000
45+#define FLASH_SIZE (16 * MiB)
46+
47+#define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */
48+#define SDRAM_SIZE 0x04000000
49+
50+#define SM501_VRAM_SIZE 0x800000
51+
52+#define BOOT_PARAMS_OFFSET 0x0010000
53+/* CONFIG_BOOT_LINK_OFFSET of Linux kernel */
54+#define LINUX_LOAD_OFFSET 0x0800000
55+#define INITRD_LOAD_OFFSET 0x1800000
56+
57+#define PA_IRLMSK 0x00
58+#define PA_POWOFF 0x30
59+#define PA_VERREG 0x32
60+#define PA_OUTPORT 0x36
61+
62+typedef struct {
63+ uint16_t bcr;
64+ uint16_t irlmsk;
65+ uint16_t irlmon;
66+ uint16_t cfctl;
67+ uint16_t cfpow;
68+ uint16_t dispctl;
69+ uint16_t sdmpow;
70+ uint16_t rtcce;
71+ uint16_t pcicd;
72+ uint16_t voyagerrts;
73+ uint16_t cfrst;
74+ uint16_t admrts;
75+ uint16_t extrst;
76+ uint16_t cfcdintclr;
77+ uint16_t keyctlclr;
78+ uint16_t pad0;
79+ uint16_t pad1;
80+ uint16_t verreg;
81+ uint16_t inport;
82+ uint16_t outport;
83+ uint16_t bverreg;
84+
85+/* output pin */
86+ qemu_irq irl;
87+ MemoryRegion iomem;
88+} r2d_fpga_t;
89+
90+enum r2d_fpga_irq {
91+ PCI_INTD, CF_IDE, CF_CD, PCI_INTC, SM501, KEY, RTC_A, RTC_T,
92+ SDCARD, PCI_INTA, PCI_INTB, EXT, TP,
93+ NR_IRQS
94+};
95+
96+static const struct { short irl; uint16_t msk; } irqtab[NR_IRQS] = {
97+ [CF_IDE] = { 1, 1<<9 },
98+ [CF_CD] = { 2, 1<<8 },
99+ [PCI_INTA] = { 9, 1<<14 },
100+ [PCI_INTB] = { 10, 1<<13 },
101+ [PCI_INTC] = { 3, 1<<12 },
102+ [PCI_INTD] = { 0, 1<<11 },
103+ [SM501] = { 4, 1<<10 },
104+ [KEY] = { 5, 1<<6 },
105+ [RTC_A] = { 6, 1<<5 },
106+ [RTC_T] = { 7, 1<<4 },
107+ [SDCARD] = { 8, 1<<7 },
108+ [EXT] = { 11, 1<<0 },
109+ [TP] = { 12, 1<<15 },
110+};
111+
112+static void update_irl(r2d_fpga_t *fpga)
113+{
114+ int i, irl = 15;
115+ for (i = 0; i < NR_IRQS; i++)
116+ if (fpga->irlmon & fpga->irlmsk & irqtab[i].msk)
117+ if (irqtab[i].irl < irl)
118+ irl = irqtab[i].irl;
119+ qemu_set_irq(fpga->irl, irl ^ 15);
120+}
121+
122+static void r2d_fpga_irq_set(void *opaque, int n, int level)
123+{
124+ r2d_fpga_t *fpga = opaque;
125+ if (level)
126+ fpga->irlmon |= irqtab[n].msk;
127+ else
128+ fpga->irlmon &= ~irqtab[n].msk;
129+ update_irl(fpga);
130+}
131+
132+static uint64_t r2d_fpga_read(void *opaque, hwaddr addr, unsigned int size)
133+{
134+ r2d_fpga_t *s = opaque;
135+
136+ switch (addr) {
137+ case PA_IRLMSK:
138+ return s->irlmsk;
139+ case PA_OUTPORT:
140+ return s->outport;
141+ case PA_POWOFF:
142+ return 0x00;
143+ case PA_VERREG:
144+ return 0x10;
145+ }
146+
147+ return 0;
148+}
149+
150+static void
151+r2d_fpga_write(void *opaque, hwaddr addr, uint64_t value, unsigned int size)
152+{
153+ r2d_fpga_t *s = opaque;
154+
155+ switch (addr) {
156+ case PA_IRLMSK:
157+ s->irlmsk = value;
158+ update_irl(s);
159+ break;
160+ case PA_OUTPORT:
161+ s->outport = value;
162+ break;
163+ case PA_POWOFF:
164+ if (value & 1) {
165+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
166+ }
167+ break;
168+ case PA_VERREG:
169+ /* Discard writes */
170+ break;
171+ }
172+}
173+
174+static const MemoryRegionOps r2d_fpga_ops = {
175+ .read = r2d_fpga_read,
176+ .write = r2d_fpga_write,
177+ .impl.min_access_size = 2,
178+ .impl.max_access_size = 2,
179+ .endianness = DEVICE_NATIVE_ENDIAN,
180+};
181+
182+static qemu_irq *r2d_fpga_init(MemoryRegion *sysmem,
183+ hwaddr base, qemu_irq irl)
184+{
185+ r2d_fpga_t *s;
186+
187+ s = g_malloc0(sizeof(r2d_fpga_t));
188+
189+ s->irl = irl;
190+
191+ memory_region_init_io(&s->iomem, NULL, &r2d_fpga_ops, s, "r2d-fpga", 0x40);
192+ memory_region_add_subregion(sysmem, base, &s->iomem);
193+ return qemu_allocate_irqs(r2d_fpga_irq_set, s, NR_IRQS);
194+}
195+
196+typedef struct ResetData {
197+ SuperHCPU *cpu;
198+ uint32_t vector;
199+} ResetData;
200+
201+static void main_cpu_reset(void *opaque)
202+{
203+ ResetData *s = (ResetData *)opaque;
204+ CPUSH4State *env = &s->cpu->env;
205+
206+ cpu_reset(CPU(s->cpu));
207+ env->pc = s->vector;
208+}
209+
210+static struct QEMU_PACKED
211+{
212+ int mount_root_rdonly;
213+ int ramdisk_flags;
214+ int orig_root_dev;
215+ int loader_type;
216+ int initrd_start;
217+ int initrd_size;
218+
219+ char pad[232];
220+
221+ char kernel_cmdline[256] QEMU_NONSTRING;
222+} boot_params;
223+
224+static void r2d_init(MachineState *machine)
225+{
226+ const char *kernel_filename = machine->kernel_filename;
227+ const char *kernel_cmdline = machine->kernel_cmdline;
228+ const char *initrd_filename = machine->initrd_filename;
229+ SuperHCPU *cpu;
230+ CPUSH4State *env;
231+ ResetData *reset_info;
232+ struct SH7750State *s;
233+ MemoryRegion *sdram = g_new(MemoryRegion, 1);
234+ qemu_irq *irq;
235+ DriveInfo *dinfo;
236+ int i;
237+ DeviceState *dev;
238+ SysBusDevice *busdev;
239+ MemoryRegion *address_space_mem = get_system_memory();
240+ PCIBus *pci_bus;
241+
242+ cpu = SUPERH_CPU(cpu_create(machine->cpu_type));
243+ env = &cpu->env;
244+
245+ reset_info = g_malloc0(sizeof(ResetData));
246+ reset_info->cpu = cpu;
247+ reset_info->vector = env->pc;
248+ qemu_register_reset(main_cpu_reset, reset_info);
249+
250+ /* Allocate memory space */
251+ memory_region_init_ram(sdram, NULL, "r2d.sdram", SDRAM_SIZE, &error_fatal);
252+ memory_region_add_subregion(address_space_mem, SDRAM_BASE, sdram);
253+ /* Register peripherals */
254+ s = sh7750_init(cpu, address_space_mem);
255+ irq = r2d_fpga_init(address_space_mem, 0x04000000, sh7750_irl(s));
256+
257+ dev = qdev_create(NULL, "sh_pci");
258+ busdev = SYS_BUS_DEVICE(dev);
259+ qdev_init_nofail(dev);
260+ pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci"));
261+ sysbus_mmio_map(busdev, 0, P4ADDR(0x1e200000));
262+ sysbus_mmio_map(busdev, 1, A7ADDR(0x1e200000));
263+ sysbus_connect_irq(busdev, 0, irq[PCI_INTA]);
264+ sysbus_connect_irq(busdev, 1, irq[PCI_INTB]);
265+ sysbus_connect_irq(busdev, 2, irq[PCI_INTC]);
266+ sysbus_connect_irq(busdev, 3, irq[PCI_INTD]);
267+
268+ dev = qdev_create(NULL, "sysbus-sm501");
269+ busdev = SYS_BUS_DEVICE(dev);
270+ qdev_prop_set_uint32(dev, "vram-size", SM501_VRAM_SIZE);
271+ qdev_prop_set_uint32(dev, "base", 0x10000000);
272+ qdev_prop_set_ptr(dev, "chr-state", serial_hd(2));
273+ qdev_init_nofail(dev);
274+ sysbus_mmio_map(busdev, 0, 0x10000000);
275+ sysbus_mmio_map(busdev, 1, 0x13e00000);
276+ sysbus_connect_irq(busdev, 0, irq[SM501]);
277+
278+ /* onboard CF (True IDE mode, Master only). */
279+ dinfo = drive_get(IF_IDE, 0, 0);
280+ dev = qdev_create(NULL, "mmio-ide");
281+ busdev = SYS_BUS_DEVICE(dev);
282+ sysbus_connect_irq(busdev, 0, irq[CF_IDE]);
283+ qdev_prop_set_uint32(dev, "shift", 1);
284+ qdev_init_nofail(dev);
285+ sysbus_mmio_map(busdev, 0, 0x14001000);
286+ sysbus_mmio_map(busdev, 1, 0x1400080c);
287+ mmio_ide_init_drives(dev, dinfo, NULL);
288+
289+ /*
290+ * Onboard flash memory
291+ * According to the old board user document in Japanese (under
292+ * NDA) what is referred to as FROM (Area0) is connected via a
293+ * 32-bit bus and CS0 to CN8. The docs mention a Cypress
294+ * S29PL127J60TFI130 chipsset. Per the 'S29PL-J 002-00615
295+ * Rev. *E' datasheet, it is a 128Mbit NOR parallel flash
296+ * addressable in words of 16bit.
297+ */
298+ dinfo = drive_get(IF_PFLASH, 0, 0);
299+ pflash_cfi02_register(0x0, "r2d.flash", FLASH_SIZE,
300+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
301+ 64 * KiB, 1, 2, 0x0001, 0x227e, 0x2220, 0x2200,
302+ 0x555, 0x2aa, 0);
303+
304+ /* NIC: rtl8139 on-board, and 2 slots. */
305+ for (i = 0; i < nb_nics; i++)
306+ pci_nic_init_nofail(&nd_table[i], pci_bus,
307+ "rtl8139", i==0 ? "2" : NULL);
308+
309+ /* USB keyboard */
310+ usb_create_simple(usb_bus_find(-1), "usb-kbd");
311+
312+ /* Todo: register on board registers */
313+ memset(&boot_params, 0, sizeof(boot_params));
314+
315+ if (kernel_filename) {
316+ int kernel_size;
317+
318+ kernel_size = load_image_targphys(kernel_filename,
319+ SDRAM_BASE + LINUX_LOAD_OFFSET,
320+ INITRD_LOAD_OFFSET - LINUX_LOAD_OFFSET);
321+ if (kernel_size < 0) {
322+ fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
323+ exit(1);
324+ }
325+
326+ /* initialization which should be done by firmware */
327+ address_space_stl(&address_space_memory, SH7750_BCR1, 1 << 3,
328+ MEMTXATTRS_UNSPECIFIED, NULL); /* cs3 SDRAM */
329+ address_space_stw(&address_space_memory, SH7750_BCR2, 3 << (3 * 2),
330+ MEMTXATTRS_UNSPECIFIED, NULL); /* cs3 32bit */
331+ reset_info->vector = (SDRAM_BASE + LINUX_LOAD_OFFSET) | 0xa0000000; /* Start from P2 area */
332+ }
333+
334+ if (initrd_filename) {
335+ int initrd_size;
336+
337+ initrd_size = load_image_targphys(initrd_filename,
338+ SDRAM_BASE + INITRD_LOAD_OFFSET,
339+ SDRAM_SIZE - INITRD_LOAD_OFFSET);
340+
341+ if (initrd_size < 0) {
342+ fprintf(stderr, "qemu: could not load initrd '%s'\n", initrd_filename);
343+ exit(1);
344+ }
345+
346+ /* initialization which should be done by firmware */
347+ boot_params.loader_type = tswap32(1);
348+ boot_params.initrd_start = tswap32(INITRD_LOAD_OFFSET);
349+ boot_params.initrd_size = tswap32(initrd_size);
350+ }
351+
352+ if (kernel_cmdline) {
353+ /* I see no evidence that this .kernel_cmdline buffer requires
354+ NUL-termination, so using strncpy should be ok. */
355+ strncpy(boot_params.kernel_cmdline, kernel_cmdline,
356+ sizeof(boot_params.kernel_cmdline));
357+ }
358+
359+ rom_add_blob_fixed("boot_params", &boot_params, sizeof(boot_params),
360+ SDRAM_BASE + BOOT_PARAMS_OFFSET);
361+}
362+
363+static void r2d_machine_init(MachineClass *mc)
364+{
365+ mc->desc = "r2d-plus board";
366+ mc->init = r2d_init;
367+ mc->block_default_type = IF_IDE;
368+ mc->default_cpu_type = TYPE_SH7751R_CPU;
369+}
370+
371+DEFINE_MACHINE("r2d", r2d_machine_init)
--- /dev/null
+++ b/hw/sh/sh7619.c
@@ -0,0 +1,203 @@
1+/*
2+ * SH7619 device
3+ *
4+ * Copyright (c) 2018 Yoshinori Sato
5+ *
6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7+ * of this software and associated documentation files (the "Software"), to deal
8+ * in the Software without restriction, including without limitation the rights
9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+ * THE SOFTWARE.
23+ */
24+#include "qemu/osdep.h"
25+#include "qapi/error.h"
26+#include "hw/hw.h"
27+#include "hw/sh/sh7619.h"
28+#include "sysemu/sysemu.h"
29+#include "hw/loader.h"
30+#include "hw/intc/sh7619intc.h"
31+#include "hw/timer/renesas_cmt.h"
32+#include "cpu.h"
33+#include "exec/exec-all.h"
34+
35+#define SCIF0_ERI (88 - 64)
36+#define SCIF0_RXI (89 - 64)
37+#define SCIF0_BRI (90 - 64)
38+#define SCIF0_TXI (91 - 64)
39+#define SCIF1_ERI (92 - 64)
40+#define SCIF1_RXI (93 - 64)
41+#define SCIF1_BRI (94 - 64)
42+#define SCIF1_TXI (95 - 64)
43+#define SCIF2_ERI (96 - 64)
44+#define SCIF2_RXI (97 - 64)
45+#define SCIF2_BRI (98 - 64)
46+#define SCIF2_TXI (99 - 64)
47+
48+static void sh7619_set_irq(void *opaque, int no, int request)
49+{
50+ SuperHCPU *cpu = SUPERH_CPU(opaque);
51+ CPUState *cs = CPU(cpu);
52+ int irq = request & 0xff;
53+
54+ if (irq) {
55+ cpu->env.req_irq = irq;
56+ cpu->env.req_ipl = (request >> 8) & 0x0f;
57+ cpu_interrupt(cs, CPU_INTERRUPT_HARD);
58+ } else {
59+ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
60+ }
61+}
62+
63+static SH7619INTCState *register_intc(SH7619State *s)
64+{
65+ SysBusDevice *intc;
66+ int i;
67+
68+ intc = SYS_BUS_DEVICE(qdev_create(NULL, TYPE_SH7619INTC));
69+ sysbus_mmio_map(intc, 0, 0xf8080000);
70+ sysbus_mmio_map(intc, 1, 0xf8140000);
71+ for (i = 0; i < 64; i++)
72+ s->irq[i] = qdev_get_gpio_in(DEVICE(intc), i);
73+
74+ qdev_init_nofail(DEVICE(intc));
75+ sysbus_connect_irq(SYS_BUS_DEVICE(intc), 0,
76+ qdev_get_gpio_in(DEVICE(s), 0));
77+
78+ return SH7619INTC(intc);
79+}
80+
81+static RCMTState *register_cmt(SH7619State *s)
82+{
83+ SysBusDevice *cmt;
84+ int i;
85+
86+ cmt = SYS_BUS_DEVICE(qdev_create(NULL, TYPE_RENESAS_CMT));
87+ sysbus_mmio_map(cmt, 0, 0xf84a0070);
88+ qdev_prop_set_uint64(DEVICE(cmt), "input-freq", 31250000);
89+
90+ qdev_init_nofail(DEVICE(cmt));
91+ for (i = 0; i < 2; i++)
92+ sysbus_connect_irq(cmt, i, s->irq[(86 + i) - 64]);
93+
94+ return RCMT(cmt);
95+}
96+
97+static void cache_write(void *opaque, hwaddr addr,
98+ uint64_t mem_value, unsigned size)
99+{
100+}
101+
102+static uint64_t cache_read(void *opaque, hwaddr addr,
103+ unsigned size)
104+{
105+ return 0;
106+}
107+
108+
109+static const MemoryRegionOps cache_ops = {
110+ .read = cache_read,
111+ .write = cache_write,
112+ .endianness = DEVICE_BIG_ENDIAN,
113+};
114+
115+static void cpg_write(void *opaque, hwaddr addr,
116+ uint64_t mem_value, unsigned size)
117+{
118+ SH7619State *s = opaque;
119+ s->frqcr = mem_value;
120+}
121+
122+static uint64_t cpg_read(void *opaque, hwaddr addr,
123+ unsigned size)
124+{
125+ SH7619State *s = opaque;
126+ return s->frqcr;
127+}
128+
129+
130+static const MemoryRegionOps cpg_ops = {
131+ .read = cpg_read,
132+ .write = cpg_write,
133+ .endianness = DEVICE_BIG_ENDIAN,
134+ .impl = {
135+ .min_access_size = 2,
136+ .max_access_size = 2,
137+ },
138+};
139+
140+#define SCIF(no) \
141+ sh_serial_init(s->sysmem, 0xf8400000 + no * 0x00010000, \
142+ SH_SERIAL_FEAT_SCIF, \
143+ 31250000, serial_hd(no), \
144+ s->irq[SCIF ## no ## _ERI], \
145+ s->irq[SCIF ## no ## _RXI], \
146+ s->irq[SCIF ## no ## _TXI], \
147+ NULL, \
148+ s->irq[SCIF ## no ## _BRI])
149+
150+static void sh7619_reallize(DeviceState *dev, Error **errp)
151+{
152+ SH7619State *s = SH7619State(dev);
153+
154+ memory_region_init_io(&s->cache, NULL, &cache_ops,
155+ NULL, "cache", 0x02000000);
156+ memory_region_add_subregion(s->sysmem, 0xf0000000, &s->cache);
157+ memory_region_init_io(&s->cpg, NULL, &cpg_ops,
158+ s, "cpg", 0x00000002);
159+ memory_region_add_subregion(s->sysmem, 0xf815ff80, &s->cpg);
160+ memory_region_init_ram(&s->uram, NULL, "uram", 0x4000, NULL);
161+ memory_region_add_subregion(s->sysmem, 0xe55fc000, &s->uram);
162+
163+ /* Initialize CPU */
164+ object_initialize_child(OBJECT(s), "cpu", &s->cpu, sizeof(SuperHCPU),
165+ TYPE_SH2_CPU, errp, NULL);
166+ s->cpu.env.features = SH_FEATURE_SH2;
167+ object_property_set_bool(OBJECT(&s->cpu), true, "realized", errp);
168+ qdev_init_gpio_in(DEVICE(s), sh7619_set_irq, 1);
169+ s->intc = register_intc(s);
170+ s->cpu.env.ack = qdev_get_gpio_in_named(DEVICE(s->intc), "ack", 0);
171+ register_cmt(s);
172+ SCIF(0);
173+ SCIF(1);
174+ SCIF(2);
175+}
176+
177+static Property sh7619_properties[] = {
178+ DEFINE_PROP_LINK("memory", SH7619State, sysmem, TYPE_MEMORY_REGION,
179+ MemoryRegion *),
180+ DEFINE_PROP_END_OF_LIST(),
181+};
182+
183+static void sh7619_class_init(ObjectClass *klass, void *data)
184+{
185+ DeviceClass *dc = DEVICE_CLASS(klass);
186+
187+ dc->realize = sh7619_reallize;
188+ dc->props = sh7619_properties;
189+}
190+
191+static const TypeInfo sh7619_info = {
192+ .name = TYPE_SH7619,
193+ .parent = TYPE_SYS_BUS_DEVICE,
194+ .instance_size = sizeof(SH7619State),
195+ .class_init = sh7619_class_init,
196+};
197+
198+static void sh7619_register_types(void)
199+{
200+ type_register_static(&sh7619_info);
201+}
202+
203+type_init(sh7619_register_types)
--- /dev/null
+++ b/hw/sh/sh7750.c
@@ -0,0 +1,760 @@
1+/*
2+ * SH7750 device
3+ *
4+ * Copyright (c) 2007 Magnus Damm
5+ * Copyright (c) 2005 Samuel Tardieu
6+ *
7+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8+ * of this software and associated documentation files (the "Software"), to deal
9+ * in the Software without restriction, including without limitation the rights
10+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+ * copies of the Software, and to permit persons to whom the Software is
12+ * furnished to do so, subject to the following conditions:
13+ *
14+ * The above copyright notice and this permission notice shall be included in
15+ * all copies or substantial portions of the Software.
16+ *
17+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+ * THE SOFTWARE.
24+ */
25+#include "qemu/osdep.h"
26+#include "hw/hw.h"
27+#include "hw/sh4/sh.h"
28+#include "sysemu/sysemu.h"
29+#include "sh7750_regs.h"
30+#include "sh7750_regnames.h"
31+#include "hw/sh4/sh_intc.h"
32+#include "cpu.h"
33+#include "exec/exec-all.h"
34+
35+#define NB_DEVICES 4
36+
37+typedef struct SH7750State {
38+ MemoryRegion iomem;
39+ MemoryRegion iomem_1f0;
40+ MemoryRegion iomem_ff0;
41+ MemoryRegion iomem_1f8;
42+ MemoryRegion iomem_ff8;
43+ MemoryRegion iomem_1fc;
44+ MemoryRegion iomem_ffc;
45+ MemoryRegion mmct_iomem;
46+ /* CPU */
47+ SuperHCPU *cpu;
48+ /* Peripheral frequency in Hz */
49+ uint32_t periph_freq;
50+ /* SDRAM controller */
51+ uint32_t bcr1;
52+ uint16_t bcr2;
53+ uint16_t bcr3;
54+ uint32_t bcr4;
55+ uint16_t rfcr;
56+ /* PCMCIA controller */
57+ uint16_t pcr;
58+ /* IO ports */
59+ uint16_t gpioic;
60+ uint32_t pctra;
61+ uint32_t pctrb;
62+ uint16_t portdira; /* Cached */
63+ uint16_t portpullupa; /* Cached */
64+ uint16_t portdirb; /* Cached */
65+ uint16_t portpullupb; /* Cached */
66+ uint16_t pdtra;
67+ uint16_t pdtrb;
68+ uint16_t periph_pdtra; /* Imposed by the peripherals */
69+ uint16_t periph_portdira; /* Direction seen from the peripherals */
70+ uint16_t periph_pdtrb; /* Imposed by the peripherals */
71+ uint16_t periph_portdirb; /* Direction seen from the peripherals */
72+ sh7750_io_device *devices[NB_DEVICES]; /* External peripherals */
73+
74+ /* Cache */
75+ uint32_t ccr;
76+
77+ struct intc_desc intc;
78+} SH7750State;
79+
80+static inline int has_bcr3_and_bcr4(SH7750State * s)
81+{
82+ return s->cpu->env.features & FEATURE_R;
83+}
84+/**********************************************************************
85+ I/O ports
86+**********************************************************************/
87+
88+int sh7750_register_io_device(SH7750State * s, sh7750_io_device * device)
89+{
90+ int i;
91+
92+ for (i = 0; i < NB_DEVICES; i++) {
93+ if (s->devices[i] == NULL) {
94+ s->devices[i] = device;
95+ return 0;
96+ }
97+ }
98+ return -1;
99+}
100+
101+static uint16_t portdir(uint32_t v)
102+{
103+#define EVENPORTMASK(n) ((v & (1<<((n)<<1))) >> (n))
104+ return
105+ EVENPORTMASK(15) | EVENPORTMASK(14) | EVENPORTMASK(13) |
106+ EVENPORTMASK(12) | EVENPORTMASK(11) | EVENPORTMASK(10) |
107+ EVENPORTMASK(9) | EVENPORTMASK(8) | EVENPORTMASK(7) |
108+ EVENPORTMASK(6) | EVENPORTMASK(5) | EVENPORTMASK(4) |
109+ EVENPORTMASK(3) | EVENPORTMASK(2) | EVENPORTMASK(1) |
110+ EVENPORTMASK(0);
111+}
112+
113+static uint16_t portpullup(uint32_t v)
114+{
115+#define ODDPORTMASK(n) ((v & (1<<(((n)<<1)+1))) >> (n))
116+ return
117+ ODDPORTMASK(15) | ODDPORTMASK(14) | ODDPORTMASK(13) |
118+ ODDPORTMASK(12) | ODDPORTMASK(11) | ODDPORTMASK(10) |
119+ ODDPORTMASK(9) | ODDPORTMASK(8) | ODDPORTMASK(7) | ODDPORTMASK(6) |
120+ ODDPORTMASK(5) | ODDPORTMASK(4) | ODDPORTMASK(3) | ODDPORTMASK(2) |
121+ ODDPORTMASK(1) | ODDPORTMASK(0);
122+}
123+
124+static uint16_t porta_lines(SH7750State * s)
125+{
126+ return (s->portdira & s->pdtra) | /* CPU */
127+ (s->periph_portdira & s->periph_pdtra) | /* Peripherals */
128+ (~(s->portdira | s->periph_portdira) & s->portpullupa); /* Pullups */
129+}
130+
131+static uint16_t portb_lines(SH7750State * s)
132+{
133+ return (s->portdirb & s->pdtrb) | /* CPU */
134+ (s->periph_portdirb & s->periph_pdtrb) | /* Peripherals */
135+ (~(s->portdirb | s->periph_portdirb) & s->portpullupb); /* Pullups */
136+}
137+
138+static void gen_port_interrupts(SH7750State * s)
139+{
140+ /* XXXXX interrupts not generated */
141+}
142+
143+static void porta_changed(SH7750State * s, uint16_t prev)
144+{
145+ uint16_t currenta, changes;
146+ int i, r = 0;
147+
148+#if 0
149+ fprintf(stderr, "porta changed from 0x%04x to 0x%04x\n",
150+ prev, porta_lines(s));
151+ fprintf(stderr, "pdtra=0x%04x, pctra=0x%08x\n", s->pdtra, s->pctra);
152+#endif
153+ currenta = porta_lines(s);
154+ if (currenta == prev)
155+ return;
156+ changes = currenta ^ prev;
157+
158+ for (i = 0; i < NB_DEVICES; i++) {
159+ if (s->devices[i] && (s->devices[i]->portamask_trigger & changes)) {
160+ r |= s->devices[i]->port_change_cb(currenta, portb_lines(s),
161+ &s->periph_pdtra,
162+ &s->periph_portdira,
163+ &s->periph_pdtrb,
164+ &s->periph_portdirb);
165+ }
166+ }
167+
168+ if (r)
169+ gen_port_interrupts(s);
170+}
171+
172+static void portb_changed(SH7750State * s, uint16_t prev)
173+{
174+ uint16_t currentb, changes;
175+ int i, r = 0;
176+
177+ currentb = portb_lines(s);
178+ if (currentb == prev)
179+ return;
180+ changes = currentb ^ prev;
181+
182+ for (i = 0; i < NB_DEVICES; i++) {
183+ if (s->devices[i] && (s->devices[i]->portbmask_trigger & changes)) {
184+ r |= s->devices[i]->port_change_cb(portb_lines(s), currentb,
185+ &s->periph_pdtra,
186+ &s->periph_portdira,
187+ &s->periph_pdtrb,
188+ &s->periph_portdirb);
189+ }
190+ }
191+
192+ if (r)
193+ gen_port_interrupts(s);
194+}
195+
196+/**********************************************************************
197+ Memory
198+**********************************************************************/
199+
200+static void error_access(const char *kind, hwaddr addr)
201+{
202+ fprintf(stderr, "%s to %s (0x" TARGET_FMT_plx ") not supported\n",
203+ kind, regname(addr), addr);
204+}
205+
206+static void ignore_access(const char *kind, hwaddr addr)
207+{
208+ fprintf(stderr, "%s to %s (0x" TARGET_FMT_plx ") ignored\n",
209+ kind, regname(addr), addr);
210+}
211+
212+static uint32_t sh7750_mem_readb(void *opaque, hwaddr addr)
213+{
214+ switch (addr) {
215+ default:
216+ error_access("byte read", addr);
217+ abort();
218+ }
219+}
220+
221+static uint32_t sh7750_mem_readw(void *opaque, hwaddr addr)
222+{
223+ SH7750State *s = opaque;
224+
225+ switch (addr) {
226+ case SH7750_BCR2_A7:
227+ return s->bcr2;
228+ case SH7750_BCR3_A7:
229+ if(!has_bcr3_and_bcr4(s))
230+ error_access("word read", addr);
231+ return s->bcr3;
232+ case SH7750_FRQCR_A7:
233+ return 0;
234+ case SH7750_PCR_A7:
235+ return s->pcr;
236+ case SH7750_RFCR_A7:
237+ fprintf(stderr,
238+ "Read access to refresh count register, incrementing\n");
239+ return s->rfcr++;
240+ case SH7750_PDTRA_A7:
241+ return porta_lines(s);
242+ case SH7750_PDTRB_A7:
243+ return portb_lines(s);
244+ case SH7750_RTCOR_A7:
245+ case SH7750_RTCNT_A7:
246+ case SH7750_RTCSR_A7:
247+ ignore_access("word read", addr);
248+ return 0;
249+ default:
250+ error_access("word read", addr);
251+ abort();
252+ }
253+}
254+
255+static uint32_t sh7750_mem_readl(void *opaque, hwaddr addr)
256+{
257+ SH7750State *s = opaque;
258+ SuperHCPUClass *scc;
259+
260+ switch (addr) {
261+ case SH7750_BCR1_A7:
262+ return s->bcr1;
263+ case SH7750_BCR4_A7:
264+ if(!has_bcr3_and_bcr4(s))
265+ error_access("long read", addr);
266+ return s->bcr4;
267+ case SH7750_WCR1_A7:
268+ case SH7750_WCR2_A7:
269+ case SH7750_WCR3_A7:
270+ case SH7750_MCR_A7:
271+ ignore_access("long read", addr);
272+ return 0;
273+ case SH7750_MMUCR_A7:
274+ return s->cpu->env.mmucr;
275+ case SH7750_PTEH_A7:
276+ return s->cpu->env.pteh;
277+ case SH7750_PTEL_A7:
278+ return s->cpu->env.ptel;
279+ case SH7750_TTB_A7:
280+ return s->cpu->env.ttb;
281+ case SH7750_TEA_A7:
282+ return s->cpu->env.tea;
283+ case SH7750_TRA_A7:
284+ return s->cpu->env.tra;
285+ case SH7750_EXPEVT_A7:
286+ return s->cpu->env.expevt;
287+ case SH7750_INTEVT_A7:
288+ return s->cpu->env.intevt;
289+ case SH7750_CCR_A7:
290+ return s->ccr;
291+ case 0x1f000030: /* Processor version */
292+ scc = SUPERH_CPU_GET_CLASS(s->cpu);
293+ return scc->pvr;
294+ case 0x1f000040: /* Cache version */
295+ scc = SUPERH_CPU_GET_CLASS(s->cpu);
296+ return scc->cvr;
297+ case 0x1f000044: /* Processor revision */
298+ scc = SUPERH_CPU_GET_CLASS(s->cpu);
299+ return scc->prr;
300+ default:
301+ error_access("long read", addr);
302+ abort();
303+ }
304+}
305+
306+#define is_in_sdrmx(a, x) (a >= SH7750_SDMR ## x ## _A7 \
307+ && a <= (SH7750_SDMR ## x ## _A7 + SH7750_SDMR ## x ## _REGNB))
308+static void sh7750_mem_writeb(void *opaque, hwaddr addr,
309+ uint32_t mem_value)
310+{
311+
312+ if (is_in_sdrmx(addr, 2) || is_in_sdrmx(addr, 3)) {
313+ ignore_access("byte write", addr);
314+ return;
315+ }
316+
317+ error_access("byte write", addr);
318+ abort();
319+}
320+
321+static void sh7750_mem_writew(void *opaque, hwaddr addr,
322+ uint32_t mem_value)
323+{
324+ SH7750State *s = opaque;
325+ uint16_t temp;
326+
327+ switch (addr) {
328+ /* SDRAM controller */
329+ case SH7750_BCR2_A7:
330+ s->bcr2 = mem_value;
331+ return;
332+ case SH7750_BCR3_A7:
333+ if(!has_bcr3_and_bcr4(s))
334+ error_access("word write", addr);
335+ s->bcr3 = mem_value;
336+ return;
337+ case SH7750_PCR_A7:
338+ s->pcr = mem_value;
339+ return;
340+ case SH7750_RTCNT_A7:
341+ case SH7750_RTCOR_A7:
342+ case SH7750_RTCSR_A7:
343+ ignore_access("word write", addr);
344+ return;
345+ /* IO ports */
346+ case SH7750_PDTRA_A7:
347+ temp = porta_lines(s);
348+ s->pdtra = mem_value;
349+ porta_changed(s, temp);
350+ return;
351+ case SH7750_PDTRB_A7:
352+ temp = portb_lines(s);
353+ s->pdtrb = mem_value;
354+ portb_changed(s, temp);
355+ return;
356+ case SH7750_RFCR_A7:
357+ fprintf(stderr, "Write access to refresh count register\n");
358+ s->rfcr = mem_value;
359+ return;
360+ case SH7750_GPIOIC_A7:
361+ s->gpioic = mem_value;
362+ if (mem_value != 0) {
363+ fprintf(stderr, "I/O interrupts not implemented\n");
364+ abort();
365+ }
366+ return;
367+ default:
368+ error_access("word write", addr);
369+ abort();
370+ }
371+}
372+
373+static void sh7750_mem_writel(void *opaque, hwaddr addr,
374+ uint32_t mem_value)
375+{
376+ SH7750State *s = opaque;
377+ uint16_t temp;
378+
379+ switch (addr) {
380+ /* SDRAM controller */
381+ case SH7750_BCR1_A7:
382+ s->bcr1 = mem_value;
383+ return;
384+ case SH7750_BCR4_A7:
385+ if(!has_bcr3_and_bcr4(s))
386+ error_access("long write", addr);
387+ s->bcr4 = mem_value;
388+ return;
389+ case SH7750_WCR1_A7:
390+ case SH7750_WCR2_A7:
391+ case SH7750_WCR3_A7:
392+ case SH7750_MCR_A7:
393+ ignore_access("long write", addr);
394+ return;
395+ /* IO ports */
396+ case SH7750_PCTRA_A7:
397+ temp = porta_lines(s);
398+ s->pctra = mem_value;
399+ s->portdira = portdir(mem_value);
400+ s->portpullupa = portpullup(mem_value);
401+ porta_changed(s, temp);
402+ return;
403+ case SH7750_PCTRB_A7:
404+ temp = portb_lines(s);
405+ s->pctrb = mem_value;
406+ s->portdirb = portdir(mem_value);
407+ s->portpullupb = portpullup(mem_value);
408+ portb_changed(s, temp);
409+ return;
410+ case SH7750_MMUCR_A7:
411+ if (mem_value & MMUCR_TI) {
412+ cpu_sh4_invalidate_tlb(&s->cpu->env);
413+ }
414+ s->cpu->env.mmucr = mem_value & ~MMUCR_TI;
415+ return;
416+ case SH7750_PTEH_A7:
417+ /* If asid changes, clear all registered tlb entries. */
418+ if ((s->cpu->env.pteh & 0xff) != (mem_value & 0xff)) {
419+ tlb_flush(CPU(s->cpu));
420+ }
421+ s->cpu->env.pteh = mem_value;
422+ return;
423+ case SH7750_PTEL_A7:
424+ s->cpu->env.ptel = mem_value;
425+ return;
426+ case SH7750_PTEA_A7:
427+ s->cpu->env.ptea = mem_value & 0x0000000f;
428+ return;
429+ case SH7750_TTB_A7:
430+ s->cpu->env.ttb = mem_value;
431+ return;
432+ case SH7750_TEA_A7:
433+ s->cpu->env.tea = mem_value;
434+ return;
435+ case SH7750_TRA_A7:
436+ s->cpu->env.tra = mem_value & 0x000007ff;
437+ return;
438+ case SH7750_EXPEVT_A7:
439+ s->cpu->env.expevt = mem_value & 0x000007ff;
440+ return;
441+ case SH7750_INTEVT_A7:
442+ s->cpu->env.intevt = mem_value & 0x000007ff;
443+ return;
444+ case SH7750_CCR_A7:
445+ s->ccr = mem_value;
446+ return;
447+ default:
448+ error_access("long write", addr);
449+ abort();
450+ }
451+}
452+
453+static uint64_t sh7750_mem_readfn(void *opaque, hwaddr addr, unsigned size)
454+{
455+ switch (size) {
456+ case 1:
457+ return sh7750_mem_readb(opaque, addr);
458+ case 2:
459+ return sh7750_mem_readw(opaque, addr);
460+ case 4:
461+ return sh7750_mem_readl(opaque, addr);
462+ default:
463+ g_assert_not_reached();
464+ }
465+}
466+
467+static void sh7750_mem_writefn(void *opaque, hwaddr addr,
468+ uint64_t value, unsigned size)
469+{
470+ switch (size) {
471+ case 1:
472+ sh7750_mem_writeb(opaque, addr, value);
473+ break;
474+ case 2:
475+ sh7750_mem_writew(opaque, addr, value);
476+ break;
477+ case 4:
478+ sh7750_mem_writel(opaque, addr, value);
479+ break;
480+ default:
481+ g_assert_not_reached();
482+ }
483+}
484+
485+static const MemoryRegionOps sh7750_mem_ops = {
486+ .read = sh7750_mem_readfn,
487+ .write = sh7750_mem_writefn,
488+ .valid.min_access_size = 1,
489+ .valid.max_access_size = 4,
490+ .endianness = DEVICE_NATIVE_ENDIAN,
491+};
492+
493+/* sh775x interrupt controller tables for sh_intc.c
494+ * stolen from linux/arch/sh/kernel/cpu/sh4/setup-sh7750.c
495+ */
496+
497+enum {
498+ UNUSED = 0,
499+
500+ /* interrupt sources */
501+ IRL_0, IRL_1, IRL_2, IRL_3, IRL_4, IRL_5, IRL_6, IRL_7,
502+ IRL_8, IRL_9, IRL_A, IRL_B, IRL_C, IRL_D, IRL_E,
503+ IRL0, IRL1, IRL2, IRL3,
504+ HUDI, GPIOI,
505+ DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3,
506+ DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7,
507+ DMAC_DMAE,
508+ PCIC0_PCISERR, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
509+ PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3,
510+ TMU3, TMU4, TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
511+ RTC_ATI, RTC_PRI, RTC_CUI,
512+ SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI,
513+ SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI,
514+ WDT,
515+ REF_RCMI, REF_ROVI,
516+
517+ /* interrupt groups */
518+ DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF,
519+ /* irl bundle */
520+ IRL,
521+
522+ NR_SOURCES,
523+};
524+
525+static struct intc_vect vectors[] = {
526+ INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620),
527+ INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
528+ INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
529+ INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
530+ INTC_VECT(RTC_CUI, 0x4c0),
531+ INTC_VECT(SCI1_ERI, 0x4e0), INTC_VECT(SCI1_RXI, 0x500),
532+ INTC_VECT(SCI1_TXI, 0x520), INTC_VECT(SCI1_TEI, 0x540),
533+ INTC_VECT(SCIF_ERI, 0x700), INTC_VECT(SCIF_RXI, 0x720),
534+ INTC_VECT(SCIF_BRI, 0x740), INTC_VECT(SCIF_TXI, 0x760),
535+ INTC_VECT(WDT, 0x560),
536+ INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0),
537+};
538+
539+static struct intc_group groups[] = {
540+ INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
541+ INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
542+ INTC_GROUP(SCI1, SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI),
543+ INTC_GROUP(SCIF, SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI),
544+ INTC_GROUP(REF, REF_RCMI, REF_ROVI),
545+};
546+
547+static struct intc_prio_reg prio_registers[] = {
548+ { 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
549+ { 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } },
550+ { 0xffd0000c, 0, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } },
551+ { 0xffd00010, 0, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } },
552+ { 0xfe080000, 0, 32, 4, /* INTPRI00 */ { 0, 0, 0, 0,
553+ TMU4, TMU3,
554+ PCIC1, PCIC0_PCISERR } },
555+};
556+
557+/* SH7750R and SH7751R both have 8-channel DMA controllers */
558+
559+/* SH7750R, SH7751 and SH7751R all have two extra timer channels */
560+
561+static struct intc_mask_reg mask_registers[] = {
562+ { 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */
563+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
564+ 0, 0, 0, 0, 0, 0, TMU4, TMU3,
565+ PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
566+ PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2,
567+ PCIC1_PCIDMA3, PCIC0_PCISERR } },
568+};
569+
570+/* SH7750S, SH7750R, SH7751 and SH7751R all have IRLM priority registers */
571+
572+/* SH7751 and SH7751R both have PCI */
573+
574+/**********************************************************************
575+ Memory mapped cache and TLB
576+**********************************************************************/
577+
578+#define MM_REGION_MASK 0x07000000
579+#define MM_ICACHE_ADDR (0)
580+#define MM_ICACHE_DATA (1)
581+#define MM_ITLB_ADDR (2)
582+#define MM_ITLB_DATA (3)
583+#define MM_OCACHE_ADDR (4)
584+#define MM_OCACHE_DATA (5)
585+#define MM_UTLB_ADDR (6)
586+#define MM_UTLB_DATA (7)
587+#define MM_REGION_TYPE(addr) ((addr & MM_REGION_MASK) >> 24)
588+
589+static uint64_t invalid_read(void *opaque, hwaddr addr)
590+{
591+ abort();
592+
593+ return 0;
594+}
595+
596+static uint64_t sh7750_mmct_read(void *opaque, hwaddr addr,
597+ unsigned size)
598+{
599+ SH7750State *s = opaque;
600+ uint32_t ret = 0;
601+
602+ if (size != 4) {
603+ return invalid_read(opaque, addr);
604+ }
605+
606+ switch (MM_REGION_TYPE(addr)) {
607+ case MM_ICACHE_ADDR:
608+ case MM_ICACHE_DATA:
609+ /* do nothing */
610+ break;
611+ case MM_ITLB_ADDR:
612+ ret = cpu_sh4_read_mmaped_itlb_addr(&s->cpu->env, addr);
613+ break;
614+ case MM_ITLB_DATA:
615+ ret = cpu_sh4_read_mmaped_itlb_data(&s->cpu->env, addr);
616+ break;
617+ case MM_OCACHE_ADDR:
618+ case MM_OCACHE_DATA:
619+ /* do nothing */
620+ break;
621+ case MM_UTLB_ADDR:
622+ ret = cpu_sh4_read_mmaped_utlb_addr(&s->cpu->env, addr);
623+ break;
624+ case MM_UTLB_DATA:
625+ ret = cpu_sh4_read_mmaped_utlb_data(&s->cpu->env, addr);
626+ break;
627+ default:
628+ abort();
629+ }
630+
631+ return ret;
632+}
633+
634+static void invalid_write(void *opaque, hwaddr addr,
635+ uint64_t mem_value)
636+{
637+ abort();
638+}
639+
640+static void sh7750_mmct_write(void *opaque, hwaddr addr,
641+ uint64_t mem_value, unsigned size)
642+{
643+ SH7750State *s = opaque;
644+
645+ if (size != 4) {
646+ invalid_write(opaque, addr, mem_value);
647+ }
648+
649+ switch (MM_REGION_TYPE(addr)) {
650+ case MM_ICACHE_ADDR:
651+ case MM_ICACHE_DATA:
652+ /* do nothing */
653+ break;
654+ case MM_ITLB_ADDR:
655+ cpu_sh4_write_mmaped_itlb_addr(&s->cpu->env, addr, mem_value);
656+ break;
657+ case MM_ITLB_DATA:
658+ cpu_sh4_write_mmaped_itlb_data(&s->cpu->env, addr, mem_value);
659+ abort();
660+ break;
661+ case MM_OCACHE_ADDR:
662+ case MM_OCACHE_DATA:
663+ /* do nothing */
664+ break;
665+ case MM_UTLB_ADDR:
666+ cpu_sh4_write_mmaped_utlb_addr(&s->cpu->env, addr, mem_value);
667+ break;
668+ case MM_UTLB_DATA:
669+ cpu_sh4_write_mmaped_utlb_data(&s->cpu->env, addr, mem_value);
670+ break;
671+ default:
672+ abort();
673+ break;
674+ }
675+}
676+
677+static const MemoryRegionOps sh7750_mmct_ops = {
678+ .read = sh7750_mmct_read,
679+ .write = sh7750_mmct_write,
680+ .endianness = DEVICE_NATIVE_ENDIAN,
681+};
682+
683+SH7750State *sh7750_init(SuperHCPU *cpu, MemoryRegion *sysmem)
684+{
685+ SH7750State *s;
686+
687+ s = g_malloc0(sizeof(SH7750State));
688+ s->cpu = cpu;
689+ s->periph_freq = 60000000; /* 60MHz */
690+ memory_region_init_io(&s->iomem, NULL, &sh7750_mem_ops, s,
691+ "memory", 0x1fc01000);
692+
693+ memory_region_init_alias(&s->iomem_1f0, NULL, "memory-1f0",
694+ &s->iomem, 0x1f000000, 0x1000);
695+ memory_region_add_subregion(sysmem, 0x1f000000, &s->iomem_1f0);
696+
697+ memory_region_init_alias(&s->iomem_ff0, NULL, "memory-ff0",
698+ &s->iomem, 0x1f000000, 0x1000);
699+ memory_region_add_subregion(sysmem, 0xff000000, &s->iomem_ff0);
700+
701+ memory_region_init_alias(&s->iomem_1f8, NULL, "memory-1f8",
702+ &s->iomem, 0x1f800000, 0x1000);
703+ memory_region_add_subregion(sysmem, 0x1f800000, &s->iomem_1f8);
704+
705+ memory_region_init_alias(&s->iomem_ff8, NULL, "memory-ff8",
706+ &s->iomem, 0x1f800000, 0x1000);
707+ memory_region_add_subregion(sysmem, 0xff800000, &s->iomem_ff8);
708+
709+ memory_region_init_alias(&s->iomem_1fc, NULL, "memory-1fc",
710+ &s->iomem, 0x1fc00000, 0x1000);
711+ memory_region_add_subregion(sysmem, 0x1fc00000, &s->iomem_1fc);
712+
713+ memory_region_init_alias(&s->iomem_ffc, NULL, "memory-ffc",
714+ &s->iomem, 0x1fc00000, 0x1000);
715+ memory_region_add_subregion(sysmem, 0xffc00000, &s->iomem_ffc);
716+
717+ memory_region_init_io(&s->mmct_iomem, NULL, &sh7750_mmct_ops, s,
718+ "cache-and-tlb", 0x08000000);
719+ memory_region_add_subregion(sysmem, 0xf0000000, &s->mmct_iomem);
720+
721+ sh_intc_init(sysmem, &s->intc, NR_SOURCES,
722+ _INTC_ARRAY(mask_registers),
723+ _INTC_ARRAY(prio_registers));
724+
725+ sh_intc_register_sources(&s->intc,
726+ _INTC_ARRAY(vectors),
727+ _INTC_ARRAY(groups));
728+
729+ sh_serial_init(sysmem, 0x1fe00000,
730+ 0, s->periph_freq, serial_hd(0),
731+ s->intc.irqs[SCI1_ERI],
732+ s->intc.irqs[SCI1_RXI],
733+ s->intc.irqs[SCI1_TXI],
734+ s->intc.irqs[SCI1_TEI],
735+ NULL);
736+ sh_serial_init(sysmem, 0x1fe80000,
737+ SH_SERIAL_FEAT_SCIF,
738+ s->periph_freq, serial_hd(1),
739+ s->intc.irqs[SCIF_ERI],
740+ s->intc.irqs[SCIF_RXI],
741+ s->intc.irqs[SCIF_TXI],
742+ NULL,
743+ s->intc.irqs[SCIF_BRI]);
744+
745+ tmu012_init(sysmem, 0x1fd80000,
746+ TMU012_FEAT_TOCR | TMU012_FEAT_3CHAN | TMU012_FEAT_EXTCLK,
747+ s->periph_freq,
748+ s->intc.irqs[TMU0],
749+ s->intc.irqs[TMU1],
750+ s->intc.irqs[TMU2_TUNI],
751+ s->intc.irqs[TMU2_TICPI]);
752+
753+ return s;
754+}
755+
756+qemu_irq sh7750_irl(SH7750State *s)
757+{
758+ sh_intc_toggle_source(sh_intc_source(&s->intc, IRL), 1, 0); /* enable */
759+ return qemu_allocate_irq(sh_intc_set_irl, sh_intc_source(&s->intc, IRL), 0);
760+}
--- /dev/null
+++ b/hw/sh/sh7750_regnames.c
@@ -0,0 +1,98 @@
1+#include "qemu/osdep.h"
2+#include "hw/hw.h"
3+#include "hw/sh4/sh.h"
4+#include "sh7750_regs.h"
5+#include "sh7750_regnames.h"
6+
7+#define REGNAME(r) {r, #r},
8+
9+typedef struct {
10+ uint32_t regaddr;
11+ const char *regname;
12+} regname_t;
13+
14+static regname_t regnames[] = {
15+ REGNAME(SH7750_PTEH_A7)
16+ REGNAME(SH7750_PTEL_A7)
17+ REGNAME(SH7750_PTEA_A7)
18+ REGNAME(SH7750_TTB_A7)
19+ REGNAME(SH7750_TEA_A7)
20+ REGNAME(SH7750_MMUCR_A7)
21+ REGNAME(SH7750_CCR_A7)
22+ REGNAME(SH7750_QACR0_A7)
23+ REGNAME(SH7750_QACR1_A7)
24+ REGNAME(SH7750_TRA_A7)
25+ REGNAME(SH7750_EXPEVT_A7)
26+ REGNAME(SH7750_INTEVT_A7)
27+ REGNAME(SH7750_STBCR_A7)
28+ REGNAME(SH7750_STBCR2_A7)
29+ REGNAME(SH7750_FRQCR_A7)
30+ REGNAME(SH7750_WTCNT_A7)
31+ REGNAME(SH7750_WTCSR_A7)
32+ REGNAME(SH7750_R64CNT_A7)
33+ REGNAME(SH7750_RSECCNT_A7)
34+ REGNAME(SH7750_RMINCNT_A7)
35+ REGNAME(SH7750_RHRCNT_A7)
36+ REGNAME(SH7750_RWKCNT_A7)
37+ REGNAME(SH7750_RDAYCNT_A7)
38+ REGNAME(SH7750_RMONCNT_A7)
39+ REGNAME(SH7750_RYRCNT_A7)
40+ REGNAME(SH7750_RSECAR_A7)
41+ REGNAME(SH7750_RMINAR_A7)
42+ REGNAME(SH7750_RHRAR_A7)
43+ REGNAME(SH7750_RWKAR_A7)
44+ REGNAME(SH7750_RDAYAR_A7)
45+ REGNAME(SH7750_RMONAR_A7)
46+ REGNAME(SH7750_RCR1_A7)
47+ REGNAME(SH7750_RCR2_A7)
48+ REGNAME(SH7750_BCR1_A7)
49+ REGNAME(SH7750_BCR2_A7)
50+ REGNAME(SH7750_WCR1_A7)
51+ REGNAME(SH7750_WCR2_A7)
52+ REGNAME(SH7750_WCR3_A7)
53+ REGNAME(SH7750_MCR_A7)
54+ REGNAME(SH7750_PCR_A7)
55+ REGNAME(SH7750_RTCSR_A7)
56+ REGNAME(SH7750_RTCNT_A7)
57+ REGNAME(SH7750_RTCOR_A7)
58+ REGNAME(SH7750_RFCR_A7)
59+ REGNAME(SH7750_SAR0_A7)
60+ REGNAME(SH7750_SAR1_A7)
61+ REGNAME(SH7750_SAR2_A7)
62+ REGNAME(SH7750_SAR3_A7)
63+ REGNAME(SH7750_DAR0_A7)
64+ REGNAME(SH7750_DAR1_A7)
65+ REGNAME(SH7750_DAR2_A7)
66+ REGNAME(SH7750_DAR3_A7)
67+ REGNAME(SH7750_DMATCR0_A7)
68+ REGNAME(SH7750_DMATCR1_A7)
69+ REGNAME(SH7750_DMATCR2_A7)
70+ REGNAME(SH7750_DMATCR3_A7)
71+ REGNAME(SH7750_CHCR0_A7)
72+ REGNAME(SH7750_CHCR1_A7)
73+ REGNAME(SH7750_CHCR2_A7)
74+ REGNAME(SH7750_CHCR3_A7)
75+ REGNAME(SH7750_DMAOR_A7)
76+ REGNAME(SH7750_PCTRA_A7)
77+ REGNAME(SH7750_PDTRA_A7)
78+ REGNAME(SH7750_PCTRB_A7)
79+ REGNAME(SH7750_PDTRB_A7)
80+ REGNAME(SH7750_GPIOIC_A7)
81+ REGNAME(SH7750_ICR_A7)
82+ REGNAME(SH7750_BCR3_A7)
83+ REGNAME(SH7750_BCR4_A7)
84+ REGNAME(SH7750_SDMR2_A7)
85+ REGNAME(SH7750_SDMR3_A7) {(uint32_t) - 1, NULL}
86+};
87+
88+const char *regname(uint32_t addr)
89+{
90+ unsigned int i;
91+
92+ for (i = 0; regnames[i].regaddr != (uint32_t) - 1; i++) {
93+ if (regnames[i].regaddr == addr)
94+ return regnames[i].regname;
95+ }
96+
97+ return "<unknown reg>";
98+}
--- /dev/null
+++ b/hw/sh/sh7750_regnames.h
@@ -0,0 +1,6 @@
1+#ifndef SH7750_REGNAMES_H
2+#define SH7750_REGNAMES_H
3+
4+const char *regname(uint32_t addr);
5+
6+#endif /* SH7750_REGNAMES_H */
--- /dev/null
+++ b/hw/sh/sh7750_regs.h
@@ -0,0 +1,1277 @@
1+/*
2+ * SH-7750 memory-mapped registers
3+ * This file based on information provided in the following document:
4+ * "Hitachi SuperH (tm) RISC engine. SH7750 Series (SH7750, SH7750S)
5+ * Hardware Manual"
6+ * Document Number ADE-602-124C, Rev. 4.0, 4/21/00, Hitachi Ltd.
7+ *
8+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
9+ * Author: Alexandra Kossovsky <sasha@oktet.ru>
10+ * Victor V. Vengerov <vvv@oktet.ru>
11+ *
12+ * The license and distribution terms for this file may be
13+ * found in the file LICENSE in this distribution or at
14+ * http://www.rtems.com/license/LICENSE.
15+ *
16+ * @(#) sh7750_regs.h,v 1.2.4.1 2003/09/04 18:46:00 joel Exp
17+ */
18+
19+#ifndef SH7750_REGS_H
20+#define SH7750_REGS_H
21+
22+/*
23+ * All register has 2 addresses: in 0xff000000 - 0xffffffff (P4 address) and
24+ * in 0x1f000000 - 0x1fffffff (area 7 address)
25+ */
26+#define SH7750_P4_BASE 0xff000000 /* Accessible only in
27+ privileged mode */
28+#define SH7750_A7_BASE 0x1f000000 /* Accessible only using TLB */
29+
30+#define SH7750_P4_REG32(ofs) (SH7750_P4_BASE + (ofs))
31+#define SH7750_A7_REG32(ofs) (SH7750_A7_BASE + (ofs))
32+
33+/*
34+ * MMU Registers
35+ */
36+
37+/* Page Table Entry High register - PTEH */
38+#define SH7750_PTEH_REGOFS 0x000000 /* offset */
39+#define SH7750_PTEH SH7750_P4_REG32(SH7750_PTEH_REGOFS)
40+#define SH7750_PTEH_A7 SH7750_A7_REG32(SH7750_PTEH_REGOFS)
41+#define SH7750_PTEH_VPN 0xfffffd00 /* Virtual page number */
42+#define SH7750_PTEH_VPN_S 10
43+#define SH7750_PTEH_ASID 0x000000ff /* Address space identifier */
44+#define SH7750_PTEH_ASID_S 0
45+
46+/* Page Table Entry Low register - PTEL */
47+#define SH7750_PTEL_REGOFS 0x000004 /* offset */
48+#define SH7750_PTEL SH7750_P4_REG32(SH7750_PTEL_REGOFS)
49+#define SH7750_PTEL_A7 SH7750_A7_REG32(SH7750_PTEL_REGOFS)
50+#define SH7750_PTEL_PPN 0x1ffffc00 /* Physical page number */
51+#define SH7750_PTEL_PPN_S 10
52+#define SH7750_PTEL_V 0x00000100 /* Validity (0-entry is invalid) */
53+#define SH7750_PTEL_SZ1 0x00000080 /* Page size bit 1 */
54+#define SH7750_PTEL_SZ0 0x00000010 /* Page size bit 0 */
55+#define SH7750_PTEL_SZ_1KB 0x00000000 /* 1-kbyte page */
56+#define SH7750_PTEL_SZ_4KB 0x00000010 /* 4-kbyte page */
57+#define SH7750_PTEL_SZ_64KB 0x00000080 /* 64-kbyte page */
58+#define SH7750_PTEL_SZ_1MB 0x00000090 /* 1-Mbyte page */
59+#define SH7750_PTEL_PR 0x00000060 /* Protection Key Data */
60+#define SH7750_PTEL_PR_ROPO 0x00000000 /* read-only in priv mode */
61+#define SH7750_PTEL_PR_RWPO 0x00000020 /* read-write in priv mode */
62+#define SH7750_PTEL_PR_ROPU 0x00000040 /* read-only in priv or user mode */
63+#define SH7750_PTEL_PR_RWPU 0x00000060 /* read-write in priv or user mode */
64+#define SH7750_PTEL_C 0x00000008 /* Cacheability
65+ (0 - page not cacheable) */
66+#define SH7750_PTEL_D 0x00000004 /* Dirty bit (1 - write has been
67+ performed to a page) */
68+#define SH7750_PTEL_SH 0x00000002 /* Share Status bit (1 - page are
69+ shared by processes) */
70+#define SH7750_PTEL_WT 0x00000001 /* Write-through bit, specifies the
71+ cache write mode:
72+ 0 - Copy-back mode
73+ 1 - Write-through mode */
74+
75+/* Page Table Entry Assistance register - PTEA */
76+#define SH7750_PTEA_REGOFS 0x000034 /* offset */
77+#define SH7750_PTEA SH7750_P4_REG32(SH7750_PTEA_REGOFS)
78+#define SH7750_PTEA_A7 SH7750_A7_REG32(SH7750_PTEA_REGOFS)
79+#define SH7750_PTEA_TC 0x00000008 /* Timing Control bit
80+ 0 - use area 5 wait states
81+ 1 - use area 6 wait states */
82+#define SH7750_PTEA_SA 0x00000007 /* Space Attribute bits: */
83+#define SH7750_PTEA_SA_UNDEF 0x00000000 /* 0 - undefined */
84+#define SH7750_PTEA_SA_IOVAR 0x00000001 /* 1 - variable-size I/O space */
85+#define SH7750_PTEA_SA_IO8 0x00000002 /* 2 - 8-bit I/O space */
86+#define SH7750_PTEA_SA_IO16 0x00000003 /* 3 - 16-bit I/O space */
87+#define SH7750_PTEA_SA_CMEM8 0x00000004 /* 4 - 8-bit common memory space */
88+#define SH7750_PTEA_SA_CMEM16 0x00000005 /* 5 - 16-bit common memory space */
89+#define SH7750_PTEA_SA_AMEM8 0x00000006 /* 6 - 8-bit attr memory space */
90+#define SH7750_PTEA_SA_AMEM16 0x00000007 /* 7 - 16-bit attr memory space */
91+
92+
93+/* Translation table base register */
94+#define SH7750_TTB_REGOFS 0x000008 /* offset */
95+#define SH7750_TTB SH7750_P4_REG32(SH7750_TTB_REGOFS)
96+#define SH7750_TTB_A7 SH7750_A7_REG32(SH7750_TTB_REGOFS)
97+
98+/* TLB exeption address register - TEA */
99+#define SH7750_TEA_REGOFS 0x00000c /* offset */
100+#define SH7750_TEA SH7750_P4_REG32(SH7750_TEA_REGOFS)
101+#define SH7750_TEA_A7 SH7750_A7_REG32(SH7750_TEA_REGOFS)
102+
103+/* MMU control register - MMUCR */
104+#define SH7750_MMUCR_REGOFS 0x000010 /* offset */
105+#define SH7750_MMUCR SH7750_P4_REG32(SH7750_MMUCR_REGOFS)
106+#define SH7750_MMUCR_A7 SH7750_A7_REG32(SH7750_MMUCR_REGOFS)
107+#define SH7750_MMUCR_AT 0x00000001 /* Address translation bit */
108+#define SH7750_MMUCR_TI 0x00000004 /* TLB invalidate */
109+#define SH7750_MMUCR_SV 0x00000100 /* Single Virtual Mode bit */
110+#define SH7750_MMUCR_SQMD 0x00000200 /* Store Queue Mode bit */
111+#define SH7750_MMUCR_URC 0x0000FC00 /* UTLB Replace Counter */
112+#define SH7750_MMUCR_URC_S 10
113+#define SH7750_MMUCR_URB 0x00FC0000 /* UTLB Replace Boundary */
114+#define SH7750_MMUCR_URB_S 18
115+#define SH7750_MMUCR_LRUI 0xFC000000 /* Least Recently Used ITLB */
116+#define SH7750_MMUCR_LRUI_S 26
117+
118+
119+
120+
121+/*
122+ * Cache registers
123+ * IC -- instructions cache
124+ * OC -- operand cache
125+ */
126+
127+/* Cache Control Register - CCR */
128+#define SH7750_CCR_REGOFS 0x00001c /* offset */
129+#define SH7750_CCR SH7750_P4_REG32(SH7750_CCR_REGOFS)
130+#define SH7750_CCR_A7 SH7750_A7_REG32(SH7750_CCR_REGOFS)
131+
132+#define SH7750_CCR_IIX 0x00008000 /* IC index enable bit */
133+#define SH7750_CCR_ICI 0x00000800 /* IC invalidation bit:
134+ set it to clear IC */
135+#define SH7750_CCR_ICE 0x00000100 /* IC enable bit */
136+#define SH7750_CCR_OIX 0x00000080 /* OC index enable bit */
137+#define SH7750_CCR_ORA 0x00000020 /* OC RAM enable bit
138+ if you set OCE = 0,
139+ you should set ORA = 0 */
140+#define SH7750_CCR_OCI 0x00000008 /* OC invalidation bit */
141+#define SH7750_CCR_CB 0x00000004 /* Copy-back bit for P1 area */
142+#define SH7750_CCR_WT 0x00000002 /* Write-through bit for P0,U0,P3 area */
143+#define SH7750_CCR_OCE 0x00000001 /* OC enable bit */
144+
145+/* Queue address control register 0 - QACR0 */
146+#define SH7750_QACR0_REGOFS 0x000038 /* offset */
147+#define SH7750_QACR0 SH7750_P4_REG32(SH7750_QACR0_REGOFS)
148+#define SH7750_QACR0_A7 SH7750_A7_REG32(SH7750_QACR0_REGOFS)
149+
150+/* Queue address control register 1 - QACR1 */
151+#define SH7750_QACR1_REGOFS 0x00003c /* offset */
152+#define SH7750_QACR1 SH7750_P4_REG32(SH7750_QACR1_REGOFS)
153+#define SH7750_QACR1_A7 SH7750_A7_REG32(SH7750_QACR1_REGOFS)
154+
155+
156+/*
157+ * Exeption-related registers
158+ */
159+
160+/* Immediate data for TRAPA instruction - TRA */
161+#define SH7750_TRA_REGOFS 0x000020 /* offset */
162+#define SH7750_TRA SH7750_P4_REG32(SH7750_TRA_REGOFS)
163+#define SH7750_TRA_A7 SH7750_A7_REG32(SH7750_TRA_REGOFS)
164+
165+#define SH7750_TRA_IMM 0x000003fd /* Immediate data operand */
166+#define SH7750_TRA_IMM_S 2
167+
168+/* Exeption event register - EXPEVT */
169+#define SH7750_EXPEVT_REGOFS 0x000024
170+#define SH7750_EXPEVT SH7750_P4_REG32(SH7750_EXPEVT_REGOFS)
171+#define SH7750_EXPEVT_A7 SH7750_A7_REG32(SH7750_EXPEVT_REGOFS)
172+
173+#define SH7750_EXPEVT_EX 0x00000fff /* Exeption code */
174+#define SH7750_EXPEVT_EX_S 0
175+
176+/* Interrupt event register */
177+#define SH7750_INTEVT_REGOFS 0x000028
178+#define SH7750_INTEVT SH7750_P4_REG32(SH7750_INTEVT_REGOFS)
179+#define SH7750_INTEVT_A7 SH7750_A7_REG32(SH7750_INTEVT_REGOFS)
180+#define SH7750_INTEVT_EX 0x00000fff /* Exeption code */
181+#define SH7750_INTEVT_EX_S 0
182+
183+/*
184+ * Exception/interrupt codes
185+ */
186+#define SH7750_EVT_TO_NUM(evt) ((evt) >> 5)
187+
188+/* Reset exception category */
189+#define SH7750_EVT_POWER_ON_RST 0x000 /* Power-on reset */
190+#define SH7750_EVT_MANUAL_RST 0x020 /* Manual reset */
191+#define SH7750_EVT_TLB_MULT_HIT 0x140 /* TLB multiple-hit exception */
192+
193+/* General exception category */
194+#define SH7750_EVT_USER_BREAK 0x1E0 /* User break */
195+#define SH7750_EVT_IADDR_ERR 0x0E0 /* Instruction address error */
196+#define SH7750_EVT_TLB_READ_MISS 0x040 /* ITLB miss exception /
197+ DTLB miss exception (read) */
198+#define SH7750_EVT_TLB_READ_PROTV 0x0A0 /* ITLB protection violation /
199+ DTLB protection violation (read) */
200+#define SH7750_EVT_ILLEGAL_INSTR 0x180 /* General Illegal Instruction
201+ exception */
202+#define SH7750_EVT_SLOT_ILLEGAL_INSTR 0x1A0 /* Slot Illegal Instruction
203+ exception */
204+#define SH7750_EVT_FPU_DISABLE 0x800 /* General FPU disable exception */
205+#define SH7750_EVT_SLOT_FPU_DISABLE 0x820 /* Slot FPU disable exception */
206+#define SH7750_EVT_DATA_READ_ERR 0x0E0 /* Data address error (read) */
207+#define SH7750_EVT_DATA_WRITE_ERR 0x100 /* Data address error (write) */
208+#define SH7750_EVT_DTLB_WRITE_MISS 0x060 /* DTLB miss exception (write) */
209+#define SH7750_EVT_DTLB_WRITE_PROTV 0x0C0 /* DTLB protection violation
210+ exception (write) */
211+#define SH7750_EVT_FPU_EXCEPTION 0x120 /* FPU exception */
212+#define SH7750_EVT_INITIAL_PGWRITE 0x080 /* Initial Page Write exception */
213+#define SH7750_EVT_TRAPA 0x160 /* Unconditional trap (TRAPA) */
214+
215+/* Interrupt exception category */
216+#define SH7750_EVT_NMI 0x1C0 /* Non-maskable interrupt */
217+#define SH7750_EVT_IRQ0 0x200 /* External Interrupt 0 */
218+#define SH7750_EVT_IRQ1 0x220 /* External Interrupt 1 */
219+#define SH7750_EVT_IRQ2 0x240 /* External Interrupt 2 */
220+#define SH7750_EVT_IRQ3 0x260 /* External Interrupt 3 */
221+#define SH7750_EVT_IRQ4 0x280 /* External Interrupt 4 */
222+#define SH7750_EVT_IRQ5 0x2A0 /* External Interrupt 5 */
223+#define SH7750_EVT_IRQ6 0x2C0 /* External Interrupt 6 */
224+#define SH7750_EVT_IRQ7 0x2E0 /* External Interrupt 7 */
225+#define SH7750_EVT_IRQ8 0x300 /* External Interrupt 8 */
226+#define SH7750_EVT_IRQ9 0x320 /* External Interrupt 9 */
227+#define SH7750_EVT_IRQA 0x340 /* External Interrupt A */
228+#define SH7750_EVT_IRQB 0x360 /* External Interrupt B */
229+#define SH7750_EVT_IRQC 0x380 /* External Interrupt C */
230+#define SH7750_EVT_IRQD 0x3A0 /* External Interrupt D */
231+#define SH7750_EVT_IRQE 0x3C0 /* External Interrupt E */
232+
233+/* Peripheral Module Interrupts - Timer Unit (TMU) */
234+#define SH7750_EVT_TUNI0 0x400 /* TMU Underflow Interrupt 0 */
235+#define SH7750_EVT_TUNI1 0x420 /* TMU Underflow Interrupt 1 */
236+#define SH7750_EVT_TUNI2 0x440 /* TMU Underflow Interrupt 2 */
237+#define SH7750_EVT_TICPI2 0x460 /* TMU Input Capture Interrupt 2 */
238+
239+/* Peripheral Module Interrupts - Real-Time Clock (RTC) */
240+#define SH7750_EVT_RTC_ATI 0x480 /* Alarm Interrupt Request */
241+#define SH7750_EVT_RTC_PRI 0x4A0 /* Periodic Interrupt Request */
242+#define SH7750_EVT_RTC_CUI 0x4C0 /* Carry Interrupt Request */
243+
244+/* Peripheral Module Interrupts - Serial Communication Interface (SCI) */
245+#define SH7750_EVT_SCI_ERI 0x4E0 /* Receive Error */
246+#define SH7750_EVT_SCI_RXI 0x500 /* Receive Data Register Full */
247+#define SH7750_EVT_SCI_TXI 0x520 /* Transmit Data Register Empty */
248+#define SH7750_EVT_SCI_TEI 0x540 /* Transmit End */
249+
250+/* Peripheral Module Interrupts - Watchdog Timer (WDT) */
251+#define SH7750_EVT_WDT_ITI 0x560 /* Interval Timer Interrupt
252+ (used when WDT operates in
253+ interval timer mode) */
254+
255+/* Peripheral Module Interrupts - Memory Refresh Unit (REF) */
256+#define SH7750_EVT_REF_RCMI 0x580 /* Compare-match Interrupt */
257+#define SH7750_EVT_REF_ROVI 0x5A0 /* Refresh Counter Overflow
258+ interrupt */
259+
260+/* Peripheral Module Interrupts - Hitachi User Debug Interface (H-UDI) */
261+#define SH7750_EVT_HUDI 0x600 /* UDI interrupt */
262+
263+/* Peripheral Module Interrupts - General-Purpose I/O (GPIO) */
264+#define SH7750_EVT_GPIO 0x620 /* GPIO Interrupt */
265+
266+/* Peripheral Module Interrupts - DMA Controller (DMAC) */
267+#define SH7750_EVT_DMAC_DMTE0 0x640 /* DMAC 0 Transfer End Interrupt */
268+#define SH7750_EVT_DMAC_DMTE1 0x660 /* DMAC 1 Transfer End Interrupt */
269+#define SH7750_EVT_DMAC_DMTE2 0x680 /* DMAC 2 Transfer End Interrupt */
270+#define SH7750_EVT_DMAC_DMTE3 0x6A0 /* DMAC 3 Transfer End Interrupt */
271+#define SH7750_EVT_DMAC_DMAE 0x6C0 /* DMAC Address Error Interrupt */
272+
273+/* Peripheral Module Interrupts - Serial Communication Interface with FIFO */
274+/* (SCIF) */
275+#define SH7750_EVT_SCIF_ERI 0x700 /* Receive Error */
276+#define SH7750_EVT_SCIF_RXI 0x720 /* Receive FIFO Data Full or
277+ Receive Data ready interrupt */
278+#define SH7750_EVT_SCIF_BRI 0x740 /* Break or overrun error */
279+#define SH7750_EVT_SCIF_TXI 0x760 /* Transmit FIFO Data Empty */
280+
281+/*
282+ * Power Management
283+ */
284+#define SH7750_STBCR_REGOFS 0xC00004 /* offset */
285+#define SH7750_STBCR SH7750_P4_REG32(SH7750_STBCR_REGOFS)
286+#define SH7750_STBCR_A7 SH7750_A7_REG32(SH7750_STBCR_REGOFS)
287+
288+#define SH7750_STBCR_STBY 0x80 /* Specifies a transition to standby mode:
289+ 0 - Transition to SLEEP mode on SLEEP
290+ 1 - Transition to STANDBY mode on SLEEP */
291+#define SH7750_STBCR_PHZ 0x40 /* State of peripheral module pins in
292+ standby mode:
293+ 0 - normal state
294+ 1 - high-impendance state */
295+
296+#define SH7750_STBCR_PPU 0x20 /* Peripheral module pins pull-up controls */
297+#define SH7750_STBCR_MSTP4 0x10 /* Stopping the clock supply to DMAC */
298+#define SH7750_STBCR_DMAC_STP SH7750_STBCR_MSTP4
299+#define SH7750_STBCR_MSTP3 0x08 /* Stopping the clock supply to SCIF */
300+#define SH7750_STBCR_SCIF_STP SH7750_STBCR_MSTP3
301+#define SH7750_STBCR_MSTP2 0x04 /* Stopping the clock supply to TMU */
302+#define SH7750_STBCR_TMU_STP SH7750_STBCR_MSTP2
303+#define SH7750_STBCR_MSTP1 0x02 /* Stopping the clock supply to RTC */
304+#define SH7750_STBCR_RTC_STP SH7750_STBCR_MSTP1
305+#define SH7750_STBCR_MSPT0 0x01 /* Stopping the clock supply to SCI */
306+#define SH7750_STBCR_SCI_STP SH7750_STBCR_MSTP0
307+
308+#define SH7750_STBCR_STBY 0x80
309+
310+
311+#define SH7750_STBCR2_REGOFS 0xC00010 /* offset */
312+#define SH7750_STBCR2 SH7750_P4_REG32(SH7750_STBCR2_REGOFS)
313+#define SH7750_STBCR2_A7 SH7750_A7_REG32(SH7750_STBCR2_REGOFS)
314+
315+#define SH7750_STBCR2_DSLP 0x80 /* Specifies transition to deep sleep mode:
316+ 0 - transition to sleep or standby mode
317+ as it is specified in STBY bit
318+ 1 - transition to deep sleep mode on
319+ execution of SLEEP instruction */
320+#define SH7750_STBCR2_MSTP6 0x02 /* Stopping the clock supply to Store Queue
321+ in the cache controller */
322+#define SH7750_STBCR2_SQ_STP SH7750_STBCR2_MSTP6
323+#define SH7750_STBCR2_MSTP5 0x01 /* Stopping the clock supply to the User
324+ Break Controller (UBC) */
325+#define SH7750_STBCR2_UBC_STP SH7750_STBCR2_MSTP5
326+
327+/*
328+ * Clock Pulse Generator (CPG)
329+ */
330+#define SH7750_FRQCR_REGOFS 0xC00000 /* offset */
331+#define SH7750_FRQCR SH7750_P4_REG32(SH7750_FRQCR_REGOFS)
332+#define SH7750_FRQCR_A7 SH7750_A7_REG32(SH7750_FRQCR_REGOFS)
333+
334+#define SH7750_FRQCR_CKOEN 0x0800 /* Clock Output Enable
335+ 0 - CKIO pin goes to HiZ/pullup
336+ 1 - Clock is output from CKIO */
337+#define SH7750_FRQCR_PLL1EN 0x0400 /* PLL circuit 1 enable */
338+#define SH7750_FRQCR_PLL2EN 0x0200 /* PLL circuit 2 enable */
339+
340+#define SH7750_FRQCR_IFC 0x01C0 /* CPU clock frequency division ratio: */
341+#define SH7750_FRQCR_IFCDIV1 0x0000 /* 0 - * 1 */
342+#define SH7750_FRQCR_IFCDIV2 0x0040 /* 1 - * 1/2 */
343+#define SH7750_FRQCR_IFCDIV3 0x0080 /* 2 - * 1/3 */
344+#define SH7750_FRQCR_IFCDIV4 0x00C0 /* 3 - * 1/4 */
345+#define SH7750_FRQCR_IFCDIV6 0x0100 /* 4 - * 1/6 */
346+#define SH7750_FRQCR_IFCDIV8 0x0140 /* 5 - * 1/8 */
347+
348+#define SH7750_FRQCR_BFC 0x0038 /* Bus clock frequency division ratio: */
349+#define SH7750_FRQCR_BFCDIV1 0x0000 /* 0 - * 1 */
350+#define SH7750_FRQCR_BFCDIV2 0x0008 /* 1 - * 1/2 */
351+#define SH7750_FRQCR_BFCDIV3 0x0010 /* 2 - * 1/3 */
352+#define SH7750_FRQCR_BFCDIV4 0x0018 /* 3 - * 1/4 */
353+#define SH7750_FRQCR_BFCDIV6 0x0020 /* 4 - * 1/6 */
354+#define SH7750_FRQCR_BFCDIV8 0x0028 /* 5 - * 1/8 */
355+
356+#define SH7750_FRQCR_PFC 0x0007 /* Peripheral module clock frequency
357+ division ratio: */
358+#define SH7750_FRQCR_PFCDIV2 0x0000 /* 0 - * 1/2 */
359+#define SH7750_FRQCR_PFCDIV3 0x0001 /* 1 - * 1/3 */
360+#define SH7750_FRQCR_PFCDIV4 0x0002 /* 2 - * 1/4 */
361+#define SH7750_FRQCR_PFCDIV6 0x0003 /* 3 - * 1/6 */
362+#define SH7750_FRQCR_PFCDIV8 0x0004 /* 4 - * 1/8 */
363+
364+/*
365+ * Watchdog Timer (WDT)
366+ */
367+
368+/* Watchdog Timer Counter register - WTCNT */
369+#define SH7750_WTCNT_REGOFS 0xC00008 /* offset */
370+#define SH7750_WTCNT SH7750_P4_REG32(SH7750_WTCNT_REGOFS)
371+#define SH7750_WTCNT_A7 SH7750_A7_REG32(SH7750_WTCNT_REGOFS)
372+#define SH7750_WTCNT_KEY 0x5A00 /* When WTCNT byte register written,
373+ you have to set the upper byte to
374+ 0x5A */
375+
376+/* Watchdog Timer Control/Status register - WTCSR */
377+#define SH7750_WTCSR_REGOFS 0xC0000C /* offset */
378+#define SH7750_WTCSR SH7750_P4_REG32(SH7750_WTCSR_REGOFS)
379+#define SH7750_WTCSR_A7 SH7750_A7_REG32(SH7750_WTCSR_REGOFS)
380+#define SH7750_WTCSR_KEY 0xA500 /* When WTCSR byte register written,
381+ you have to set the upper byte to
382+ 0xA5 */
383+#define SH7750_WTCSR_TME 0x80 /* Timer enable (1-upcount start) */
384+#define SH7750_WTCSR_MODE 0x40 /* Timer Mode Select: */
385+#define SH7750_WTCSR_MODE_WT 0x40 /* Watchdog Timer Mode */
386+#define SH7750_WTCSR_MODE_IT 0x00 /* Interval Timer Mode */
387+#define SH7750_WTCSR_RSTS 0x20 /* Reset Select: */
388+#define SH7750_WTCSR_RST_MAN 0x20 /* Manual Reset */
389+#define SH7750_WTCSR_RST_PWR 0x00 /* Power-on Reset */
390+#define SH7750_WTCSR_WOVF 0x10 /* Watchdog Timer Overflow Flag */
391+#define SH7750_WTCSR_IOVF 0x08 /* Interval Timer Overflow Flag */
392+#define SH7750_WTCSR_CKS 0x07 /* Clock Select: */
393+#define SH7750_WTCSR_CKS_DIV32 0x00 /* 1/32 of frequency divider 2 input */
394+#define SH7750_WTCSR_CKS_DIV64 0x01 /* 1/64 */
395+#define SH7750_WTCSR_CKS_DIV128 0x02 /* 1/128 */
396+#define SH7750_WTCSR_CKS_DIV256 0x03 /* 1/256 */
397+#define SH7750_WTCSR_CKS_DIV512 0x04 /* 1/512 */
398+#define SH7750_WTCSR_CKS_DIV1024 0x05 /* 1/1024 */
399+#define SH7750_WTCSR_CKS_DIV2048 0x06 /* 1/2048 */
400+#define SH7750_WTCSR_CKS_DIV4096 0x07 /* 1/4096 */
401+
402+/*
403+ * Real-Time Clock (RTC)
404+ */
405+/* 64-Hz Counter Register (byte, read-only) - R64CNT */
406+#define SH7750_R64CNT_REGOFS 0xC80000 /* offset */
407+#define SH7750_R64CNT SH7750_P4_REG32(SH7750_R64CNT_REGOFS)
408+#define SH7750_R64CNT_A7 SH7750_A7_REG32(SH7750_R64CNT_REGOFS)
409+
410+/* Second Counter Register (byte, BCD-coded) - RSECCNT */
411+#define SH7750_RSECCNT_REGOFS 0xC80004 /* offset */
412+#define SH7750_RSECCNT SH7750_P4_REG32(SH7750_RSECCNT_REGOFS)
413+#define SH7750_RSECCNT_A7 SH7750_A7_REG32(SH7750_RSECCNT_REGOFS)
414+
415+/* Minute Counter Register (byte, BCD-coded) - RMINCNT */
416+#define SH7750_RMINCNT_REGOFS 0xC80008 /* offset */
417+#define SH7750_RMINCNT SH7750_P4_REG32(SH7750_RMINCNT_REGOFS)
418+#define SH7750_RMINCNT_A7 SH7750_A7_REG32(SH7750_RMINCNT_REGOFS)
419+
420+/* Hour Counter Register (byte, BCD-coded) - RHRCNT */
421+#define SH7750_RHRCNT_REGOFS 0xC8000C /* offset */
422+#define SH7750_RHRCNT SH7750_P4_REG32(SH7750_RHRCNT_REGOFS)
423+#define SH7750_RHRCNT_A7 SH7750_A7_REG32(SH7750_RHRCNT_REGOFS)
424+
425+/* Day-of-Week Counter Register (byte) - RWKCNT */
426+#define SH7750_RWKCNT_REGOFS 0xC80010 /* offset */
427+#define SH7750_RWKCNT SH7750_P4_REG32(SH7750_RWKCNT_REGOFS)
428+#define SH7750_RWKCNT_A7 SH7750_A7_REG32(SH7750_RWKCNT_REGOFS)
429+
430+#define SH7750_RWKCNT_SUN 0 /* Sunday */
431+#define SH7750_RWKCNT_MON 1 /* Monday */
432+#define SH7750_RWKCNT_TUE 2 /* Tuesday */
433+#define SH7750_RWKCNT_WED 3 /* Wednesday */
434+#define SH7750_RWKCNT_THU 4 /* Thursday */
435+#define SH7750_RWKCNT_FRI 5 /* Friday */
436+#define SH7750_RWKCNT_SAT 6 /* Saturday */
437+
438+/* Day Counter Register (byte, BCD-coded) - RDAYCNT */
439+#define SH7750_RDAYCNT_REGOFS 0xC80014 /* offset */
440+#define SH7750_RDAYCNT SH7750_P4_REG32(SH7750_RDAYCNT_REGOFS)
441+#define SH7750_RDAYCNT_A7 SH7750_A7_REG32(SH7750_RDAYCNT_REGOFS)
442+
443+/* Month Counter Register (byte, BCD-coded) - RMONCNT */
444+#define SH7750_RMONCNT_REGOFS 0xC80018 /* offset */
445+#define SH7750_RMONCNT SH7750_P4_REG32(SH7750_RMONCNT_REGOFS)
446+#define SH7750_RMONCNT_A7 SH7750_A7_REG32(SH7750_RMONCNT_REGOFS)
447+
448+/* Year Counter Register (half, BCD-coded) - RYRCNT */
449+#define SH7750_RYRCNT_REGOFS 0xC8001C /* offset */
450+#define SH7750_RYRCNT SH7750_P4_REG32(SH7750_RYRCNT_REGOFS)
451+#define SH7750_RYRCNT_A7 SH7750_A7_REG32(SH7750_RYRCNT_REGOFS)
452+
453+/* Second Alarm Register (byte, BCD-coded) - RSECAR */
454+#define SH7750_RSECAR_REGOFS 0xC80020 /* offset */
455+#define SH7750_RSECAR SH7750_P4_REG32(SH7750_RSECAR_REGOFS)
456+#define SH7750_RSECAR_A7 SH7750_A7_REG32(SH7750_RSECAR_REGOFS)
457+#define SH7750_RSECAR_ENB 0x80 /* Second Alarm Enable */
458+
459+/* Minute Alarm Register (byte, BCD-coded) - RMINAR */
460+#define SH7750_RMINAR_REGOFS 0xC80024 /* offset */
461+#define SH7750_RMINAR SH7750_P4_REG32(SH7750_RMINAR_REGOFS)
462+#define SH7750_RMINAR_A7 SH7750_A7_REG32(SH7750_RMINAR_REGOFS)
463+#define SH7750_RMINAR_ENB 0x80 /* Minute Alarm Enable */
464+
465+/* Hour Alarm Register (byte, BCD-coded) - RHRAR */
466+#define SH7750_RHRAR_REGOFS 0xC80028 /* offset */
467+#define SH7750_RHRAR SH7750_P4_REG32(SH7750_RHRAR_REGOFS)
468+#define SH7750_RHRAR_A7 SH7750_A7_REG32(SH7750_RHRAR_REGOFS)
469+#define SH7750_RHRAR_ENB 0x80 /* Hour Alarm Enable */
470+
471+/* Day-of-Week Alarm Register (byte) - RWKAR */
472+#define SH7750_RWKAR_REGOFS 0xC8002C /* offset */
473+#define SH7750_RWKAR SH7750_P4_REG32(SH7750_RWKAR_REGOFS)
474+#define SH7750_RWKAR_A7 SH7750_A7_REG32(SH7750_RWKAR_REGOFS)
475+#define SH7750_RWKAR_ENB 0x80 /* Day-of-week Alarm Enable */
476+
477+#define SH7750_RWKAR_SUN 0 /* Sunday */
478+#define SH7750_RWKAR_MON 1 /* Monday */
479+#define SH7750_RWKAR_TUE 2 /* Tuesday */
480+#define SH7750_RWKAR_WED 3 /* Wednesday */
481+#define SH7750_RWKAR_THU 4 /* Thursday */
482+#define SH7750_RWKAR_FRI 5 /* Friday */
483+#define SH7750_RWKAR_SAT 6 /* Saturday */
484+
485+/* Day Alarm Register (byte, BCD-coded) - RDAYAR */
486+#define SH7750_RDAYAR_REGOFS 0xC80030 /* offset */
487+#define SH7750_RDAYAR SH7750_P4_REG32(SH7750_RDAYAR_REGOFS)
488+#define SH7750_RDAYAR_A7 SH7750_A7_REG32(SH7750_RDAYAR_REGOFS)
489+#define SH7750_RDAYAR_ENB 0x80 /* Day Alarm Enable */
490+
491+/* Month Counter Register (byte, BCD-coded) - RMONAR */
492+#define SH7750_RMONAR_REGOFS 0xC80034 /* offset */
493+#define SH7750_RMONAR SH7750_P4_REG32(SH7750_RMONAR_REGOFS)
494+#define SH7750_RMONAR_A7 SH7750_A7_REG32(SH7750_RMONAR_REGOFS)
495+#define SH7750_RMONAR_ENB 0x80 /* Month Alarm Enable */
496+
497+/* RTC Control Register 1 (byte) - RCR1 */
498+#define SH7750_RCR1_REGOFS 0xC80038 /* offset */
499+#define SH7750_RCR1 SH7750_P4_REG32(SH7750_RCR1_REGOFS)
500+#define SH7750_RCR1_A7 SH7750_A7_REG32(SH7750_RCR1_REGOFS)
501+#define SH7750_RCR1_CF 0x80 /* Carry Flag */
502+#define SH7750_RCR1_CIE 0x10 /* Carry Interrupt Enable */
503+#define SH7750_RCR1_AIE 0x08 /* Alarm Interrupt Enable */
504+#define SH7750_RCR1_AF 0x01 /* Alarm Flag */
505+
506+/* RTC Control Register 2 (byte) - RCR2 */
507+#define SH7750_RCR2_REGOFS 0xC8003C /* offset */
508+#define SH7750_RCR2 SH7750_P4_REG32(SH7750_RCR2_REGOFS)
509+#define SH7750_RCR2_A7 SH7750_A7_REG32(SH7750_RCR2_REGOFS)
510+#define SH7750_RCR2_PEF 0x80 /* Periodic Interrupt Flag */
511+#define SH7750_RCR2_PES 0x70 /* Periodic Interrupt Enable: */
512+#define SH7750_RCR2_PES_DIS 0x00 /* Periodic Interrupt Disabled */
513+#define SH7750_RCR2_PES_DIV256 0x10 /* Generated at 1/256 sec interval */
514+#define SH7750_RCR2_PES_DIV64 0x20 /* Generated at 1/64 sec interval */
515+#define SH7750_RCR2_PES_DIV16 0x30 /* Generated at 1/16 sec interval */
516+#define SH7750_RCR2_PES_DIV4 0x40 /* Generated at 1/4 sec interval */
517+#define SH7750_RCR2_PES_DIV2 0x50 /* Generated at 1/2 sec interval */
518+#define SH7750_RCR2_PES_x1 0x60 /* Generated at 1 sec interval */
519+#define SH7750_RCR2_PES_x2 0x70 /* Generated at 2 sec interval */
520+#define SH7750_RCR2_RTCEN 0x08 /* RTC Crystal Oscillator is Operated */
521+#define SH7750_RCR2_ADJ 0x04 /* 30-Second Adjastment */
522+#define SH7750_RCR2_RESET 0x02 /* Frequency divider circuits are reset */
523+#define SH7750_RCR2_START 0x01 /* 0 - sec, min, hr, day-of-week, month,
524+ year counters are stopped
525+ 1 - sec, min, hr, day-of-week, month,
526+ year counters operate normally */
527+/*
528+ * Bus State Controller - BSC
529+ */
530+/* Bus Control Register 1 - BCR1 */
531+#define SH7750_BCR1_REGOFS 0x800000 /* offset */
532+#define SH7750_BCR1 SH7750_P4_REG32(SH7750_BCR1_REGOFS)
533+#define SH7750_BCR1_A7 SH7750_A7_REG32(SH7750_BCR1_REGOFS)
534+#define SH7750_BCR1_ENDIAN 0x80000000 /* Endianness (1 - little endian) */
535+#define SH7750_BCR1_MASTER 0x40000000 /* Master/Slave mode (1-master) */
536+#define SH7750_BCR1_A0MPX 0x20000000 /* Area 0 Memory Type (0-SRAM,1-MPX) */
537+#define SH7750_BCR1_IPUP 0x02000000 /* Input Pin Pull-up Control:
538+ 0 - pull-up resistor is on for
539+ control input pins
540+ 1 - pull-up resistor is off */
541+#define SH7750_BCR1_OPUP 0x01000000 /* Output Pin Pull-up Control:
542+ 0 - pull-up resistor is on for
543+ control output pins
544+ 1 - pull-up resistor is off */
545+#define SH7750_BCR1_A1MBC 0x00200000 /* Area 1 SRAM Byte Control Mode:
546+ 0 - Area 1 SRAM is set to
547+ normal mode
548+ 1 - Area 1 SRAM is set to byte
549+ control mode */
550+#define SH7750_BCR1_A4MBC 0x00100000 /* Area 4 SRAM Byte Control Mode:
551+ 0 - Area 4 SRAM is set to
552+ normal mode
553+ 1 - Area 4 SRAM is set to byte
554+ control mode */
555+#define SH7750_BCR1_BREQEN 0x00080000 /* BREQ Enable:
556+ 0 - External requests are not
557+ accepted
558+ 1 - External requests are
559+ accepted */
560+#define SH7750_BCR1_PSHR 0x00040000 /* Partial Sharing Bit:
561+ 0 - Master Mode
562+ 1 - Partial-sharing Mode */
563+#define SH7750_BCR1_MEMMPX 0x00020000 /* Area 1 to 6 MPX Interface:
564+ 0 - SRAM/burst ROM interface
565+ 1 - MPX interface */
566+#define SH7750_BCR1_HIZMEM 0x00008000 /* High Impendance Control. Specifies
567+ the state of A[25:0], BS\, CSn\,
568+ RD/WR\, CE2A\, CE2B\ in standby
569+ mode and when bus is released:
570+ 0 - signals go to High-Z mode
571+ 1 - signals driven */
572+#define SH7750_BCR1_HIZCNT 0x00004000 /* High Impendance Control. Specifies
573+ the state of the RAS\, RAS2\, WEn\,
574+ CASn\, DQMn, RD\, CASS\, FRAME\,
575+ RD2\ signals in standby mode and
576+ when bus is released:
577+ 0 - signals go to High-Z mode
578+ 1 - signals driven */
579+#define SH7750_BCR1_A0BST 0x00003800 /* Area 0 Burst ROM Control */
580+#define SH7750_BCR1_A0BST_SRAM 0x0000 /* Area 0 accessed as SRAM i/f */
581+#define SH7750_BCR1_A0BST_ROM4 0x0800 /* Area 0 accessed as burst ROM
582+ interface, 4 cosequtive access */
583+#define SH7750_BCR1_A0BST_ROM8 0x1000 /* Area 0 accessed as burst ROM
584+ interface, 8 cosequtive access */
585+#define SH7750_BCR1_A0BST_ROM16 0x1800 /* Area 0 accessed as burst ROM
586+ interface, 16 cosequtive access */
587+#define SH7750_BCR1_A0BST_ROM32 0x2000 /* Area 0 accessed as burst ROM
588+ interface, 32 cosequtive access */
589+
590+#define SH7750_BCR1_A5BST 0x00000700 /* Area 5 Burst ROM Control */
591+#define SH7750_BCR1_A5BST_SRAM 0x0000 /* Area 5 accessed as SRAM i/f */
592+#define SH7750_BCR1_A5BST_ROM4 0x0100 /* Area 5 accessed as burst ROM
593+ interface, 4 cosequtive access */
594+#define SH7750_BCR1_A5BST_ROM8 0x0200 /* Area 5 accessed as burst ROM
595+ interface, 8 cosequtive access */
596+#define SH7750_BCR1_A5BST_ROM16 0x0300 /* Area 5 accessed as burst ROM
597+ interface, 16 cosequtive access */
598+#define SH7750_BCR1_A5BST_ROM32 0x0400 /* Area 5 accessed as burst ROM
599+ interface, 32 cosequtive access */
600+
601+#define SH7750_BCR1_A6BST 0x000000E0 /* Area 6 Burst ROM Control */
602+#define SH7750_BCR1_A6BST_SRAM 0x0000 /* Area 6 accessed as SRAM i/f */
603+#define SH7750_BCR1_A6BST_ROM4 0x0020 /* Area 6 accessed as burst ROM
604+ interface, 4 cosequtive access */
605+#define SH7750_BCR1_A6BST_ROM8 0x0040 /* Area 6 accessed as burst ROM
606+ interface, 8 cosequtive access */
607+#define SH7750_BCR1_A6BST_ROM16 0x0060 /* Area 6 accessed as burst ROM
608+ interface, 16 cosequtive access */
609+#define SH7750_BCR1_A6BST_ROM32 0x0080 /* Area 6 accessed as burst ROM
610+ interface, 32 cosequtive access */
611+
612+#define SH7750_BCR1_DRAMTP 0x001C /* Area 2 and 3 Memory Type */
613+#define SH7750_BCR1_DRAMTP_2SRAM_3SRAM 0x0000 /* Area 2 and 3 are SRAM or MPX
614+ interface. */
615+#define SH7750_BCR1_DRAMTP_2SRAM_3SDRAM 0x0008 /* Area 2 - SRAM/MPX, Area 3 -
616+ synchronous DRAM */
617+#define SH7750_BCR1_DRAMTP_2SDRAM_3SDRAM 0x000C /* Area 2 and 3 are synchronous
618+ DRAM interface */
619+#define SH7750_BCR1_DRAMTP_2SRAM_3DRAM 0x0010 /* Area 2 - SRAM/MPX, Area 3 -
620+ DRAM interface */
621+#define SH7750_BCR1_DRAMTP_2DRAM_3DRAM 0x0014 /* Area 2 and 3 are DRAM
622+ interface */
623+
624+#define SH7750_BCR1_A56PCM 0x00000001 /* Area 5 and 6 Bus Type:
625+ 0 - SRAM interface
626+ 1 - PCMCIA interface */
627+
628+/* Bus Control Register 2 (half) - BCR2 */
629+#define SH7750_BCR2_REGOFS 0x800004 /* offset */
630+#define SH7750_BCR2 SH7750_P4_REG32(SH7750_BCR2_REGOFS)
631+#define SH7750_BCR2_A7 SH7750_A7_REG32(SH7750_BCR2_REGOFS)
632+
633+#define SH7750_BCR2_A0SZ 0xC000 /* Area 0 Bus Width */
634+#define SH7750_BCR2_A0SZ_S 14
635+#define SH7750_BCR2_A6SZ 0x3000 /* Area 6 Bus Width */
636+#define SH7750_BCR2_A6SZ_S 12
637+#define SH7750_BCR2_A5SZ 0x0C00 /* Area 5 Bus Width */
638+#define SH7750_BCR2_A5SZ_S 10
639+#define SH7750_BCR2_A4SZ 0x0300 /* Area 4 Bus Width */
640+#define SH7750_BCR2_A4SZ_S 8
641+#define SH7750_BCR2_A3SZ 0x00C0 /* Area 3 Bus Width */
642+#define SH7750_BCR2_A3SZ_S 6
643+#define SH7750_BCR2_A2SZ 0x0030 /* Area 2 Bus Width */
644+#define SH7750_BCR2_A2SZ_S 4
645+#define SH7750_BCR2_A1SZ 0x000C /* Area 1 Bus Width */
646+#define SH7750_BCR2_A1SZ_S 2
647+#define SH7750_BCR2_SZ_64 0 /* 64 bits */
648+#define SH7750_BCR2_SZ_8 1 /* 8 bits */
649+#define SH7750_BCR2_SZ_16 2 /* 16 bits */
650+#define SH7750_BCR2_SZ_32 3 /* 32 bits */
651+#define SH7750_BCR2_PORTEN 0x0001 /* Port Function Enable :
652+ 0 - D51-D32 are not used as a port
653+ 1 - D51-D32 are used as a port */
654+
655+/* Wait Control Register 1 - WCR1 */
656+#define SH7750_WCR1_REGOFS 0x800008 /* offset */
657+#define SH7750_WCR1 SH7750_P4_REG32(SH7750_WCR1_REGOFS)
658+#define SH7750_WCR1_A7 SH7750_A7_REG32(SH7750_WCR1_REGOFS)
659+#define SH7750_WCR1_DMAIW 0x70000000 /* DACK Device Inter-Cycle Idle
660+ specification */
661+#define SH7750_WCR1_DMAIW_S 28
662+#define SH7750_WCR1_A6IW 0x07000000 /* Area 6 Inter-Cycle Idle spec. */
663+#define SH7750_WCR1_A6IW_S 24
664+#define SH7750_WCR1_A5IW 0x00700000 /* Area 5 Inter-Cycle Idle spec. */
665+#define SH7750_WCR1_A5IW_S 20
666+#define SH7750_WCR1_A4IW 0x00070000 /* Area 4 Inter-Cycle Idle spec. */
667+#define SH7750_WCR1_A4IW_S 16
668+#define SH7750_WCR1_A3IW 0x00007000 /* Area 3 Inter-Cycle Idle spec. */
669+#define SH7750_WCR1_A3IW_S 12
670+#define SH7750_WCR1_A2IW 0x00000700 /* Area 2 Inter-Cycle Idle spec. */
671+#define SH7750_WCR1_A2IW_S 8
672+#define SH7750_WCR1_A1IW 0x00000070 /* Area 1 Inter-Cycle Idle spec. */
673+#define SH7750_WCR1_A1IW_S 4
674+#define SH7750_WCR1_A0IW 0x00000007 /* Area 0 Inter-Cycle Idle spec. */
675+#define SH7750_WCR1_A0IW_S 0
676+
677+/* Wait Control Register 2 - WCR2 */
678+#define SH7750_WCR2_REGOFS 0x80000C /* offset */
679+#define SH7750_WCR2 SH7750_P4_REG32(SH7750_WCR2_REGOFS)
680+#define SH7750_WCR2_A7 SH7750_A7_REG32(SH7750_WCR2_REGOFS)
681+
682+#define SH7750_WCR2_A6W 0xE0000000 /* Area 6 Wait Control */
683+#define SH7750_WCR2_A6W_S 29
684+#define SH7750_WCR2_A6B 0x1C000000 /* Area 6 Burst Pitch */
685+#define SH7750_WCR2_A6B_S 26
686+#define SH7750_WCR2_A5W 0x03800000 /* Area 5 Wait Control */
687+#define SH7750_WCR2_A5W_S 23
688+#define SH7750_WCR2_A5B 0x00700000 /* Area 5 Burst Pitch */
689+#define SH7750_WCR2_A5B_S 20
690+#define SH7750_WCR2_A4W 0x000E0000 /* Area 4 Wait Control */
691+#define SH7750_WCR2_A4W_S 17
692+#define SH7750_WCR2_A3W 0x0000E000 /* Area 3 Wait Control */
693+#define SH7750_WCR2_A3W_S 13
694+#define SH7750_WCR2_A2W 0x00000E00 /* Area 2 Wait Control */
695+#define SH7750_WCR2_A2W_S 9
696+#define SH7750_WCR2_A1W 0x000001C0 /* Area 1 Wait Control */
697+#define SH7750_WCR2_A1W_S 6
698+#define SH7750_WCR2_A0W 0x00000038 /* Area 0 Wait Control */
699+#define SH7750_WCR2_A0W_S 3
700+#define SH7750_WCR2_A0B 0x00000007 /* Area 0 Burst Pitch */
701+#define SH7750_WCR2_A0B_S 0
702+
703+#define SH7750_WCR2_WS0 0 /* 0 wait states inserted */
704+#define SH7750_WCR2_WS1 1 /* 1 wait states inserted */
705+#define SH7750_WCR2_WS2 2 /* 2 wait states inserted */
706+#define SH7750_WCR2_WS3 3 /* 3 wait states inserted */
707+#define SH7750_WCR2_WS6 4 /* 6 wait states inserted */
708+#define SH7750_WCR2_WS9 5 /* 9 wait states inserted */
709+#define SH7750_WCR2_WS12 6 /* 12 wait states inserted */
710+#define SH7750_WCR2_WS15 7 /* 15 wait states inserted */
711+
712+#define SH7750_WCR2_BPWS0 0 /* 0 wait states inserted from 2nd access */
713+#define SH7750_WCR2_BPWS1 1 /* 1 wait states inserted from 2nd access */
714+#define SH7750_WCR2_BPWS2 2 /* 2 wait states inserted from 2nd access */
715+#define SH7750_WCR2_BPWS3 3 /* 3 wait states inserted from 2nd access */
716+#define SH7750_WCR2_BPWS4 4 /* 4 wait states inserted from 2nd access */
717+#define SH7750_WCR2_BPWS5 5 /* 5 wait states inserted from 2nd access */
718+#define SH7750_WCR2_BPWS6 6 /* 6 wait states inserted from 2nd access */
719+#define SH7750_WCR2_BPWS7 7 /* 7 wait states inserted from 2nd access */
720+
721+/* DRAM CAS\ Assertion Delay (area 3,2) */
722+#define SH7750_WCR2_DRAM_CAS_ASW1 0 /* 1 cycle */
723+#define SH7750_WCR2_DRAM_CAS_ASW2 1 /* 2 cycles */
724+#define SH7750_WCR2_DRAM_CAS_ASW3 2 /* 3 cycles */
725+#define SH7750_WCR2_DRAM_CAS_ASW4 3 /* 4 cycles */
726+#define SH7750_WCR2_DRAM_CAS_ASW7 4 /* 7 cycles */
727+#define SH7750_WCR2_DRAM_CAS_ASW10 5 /* 10 cycles */
728+#define SH7750_WCR2_DRAM_CAS_ASW13 6 /* 13 cycles */
729+#define SH7750_WCR2_DRAM_CAS_ASW16 7 /* 16 cycles */
730+
731+/* SDRAM CAS\ Latency Cycles */
732+#define SH7750_WCR2_SDRAM_CAS_LAT1 1 /* 1 cycle */
733+#define SH7750_WCR2_SDRAM_CAS_LAT2 2 /* 2 cycles */
734+#define SH7750_WCR2_SDRAM_CAS_LAT3 3 /* 3 cycles */
735+#define SH7750_WCR2_SDRAM_CAS_LAT4 4 /* 4 cycles */
736+#define SH7750_WCR2_SDRAM_CAS_LAT5 5 /* 5 cycles */
737+
738+/* Wait Control Register 3 - WCR3 */
739+#define SH7750_WCR3_REGOFS 0x800010 /* offset */
740+#define SH7750_WCR3 SH7750_P4_REG32(SH7750_WCR3_REGOFS)
741+#define SH7750_WCR3_A7 SH7750_A7_REG32(SH7750_WCR3_REGOFS)
742+
743+#define SH7750_WCR3_A6S 0x04000000 /* Area 6 Write Strobe Setup time */
744+#define SH7750_WCR3_A6H 0x03000000 /* Area 6 Data Hold Time */
745+#define SH7750_WCR3_A6H_S 24
746+#define SH7750_WCR3_A5S 0x00400000 /* Area 5 Write Strobe Setup time */
747+#define SH7750_WCR3_A5H 0x00300000 /* Area 5 Data Hold Time */
748+#define SH7750_WCR3_A5H_S 20
749+#define SH7750_WCR3_A4S 0x00040000 /* Area 4 Write Strobe Setup time */
750+#define SH7750_WCR3_A4H 0x00030000 /* Area 4 Data Hold Time */
751+#define SH7750_WCR3_A4H_S 16
752+#define SH7750_WCR3_A3S 0x00004000 /* Area 3 Write Strobe Setup time */
753+#define SH7750_WCR3_A3H 0x00003000 /* Area 3 Data Hold Time */
754+#define SH7750_WCR3_A3H_S 12
755+#define SH7750_WCR3_A2S 0x00000400 /* Area 2 Write Strobe Setup time */
756+#define SH7750_WCR3_A2H 0x00000300 /* Area 2 Data Hold Time */
757+#define SH7750_WCR3_A2H_S 8
758+#define SH7750_WCR3_A1S 0x00000040 /* Area 1 Write Strobe Setup time */
759+#define SH7750_WCR3_A1H 0x00000030 /* Area 1 Data Hold Time */
760+#define SH7750_WCR3_A1H_S 4
761+#define SH7750_WCR3_A0S 0x00000004 /* Area 0 Write Strobe Setup time */
762+#define SH7750_WCR3_A0H 0x00000003 /* Area 0 Data Hold Time */
763+#define SH7750_WCR3_A0H_S 0
764+
765+#define SH7750_WCR3_DHWS_0 0 /* 0 wait states data hold time */
766+#define SH7750_WCR3_DHWS_1 1 /* 1 wait states data hold time */
767+#define SH7750_WCR3_DHWS_2 2 /* 2 wait states data hold time */
768+#define SH7750_WCR3_DHWS_3 3 /* 3 wait states data hold time */
769+
770+#define SH7750_MCR_REGOFS 0x800014 /* offset */
771+#define SH7750_MCR SH7750_P4_REG32(SH7750_MCR_REGOFS)
772+#define SH7750_MCR_A7 SH7750_A7_REG32(SH7750_MCR_REGOFS)
773+
774+#define SH7750_MCR_RASD 0x80000000 /* RAS Down mode */
775+#define SH7750_MCR_MRSET 0x40000000 /* SDRAM Mode Register Set */
776+#define SH7750_MCR_PALL 0x00000000 /* SDRAM Precharge All cmd. Mode */
777+#define SH7750_MCR_TRC 0x38000000 /* RAS Precharge Time at End of
778+ Refresh: */
779+#define SH7750_MCR_TRC_0 0x00000000 /* 0 */
780+#define SH7750_MCR_TRC_3 0x08000000 /* 3 */
781+#define SH7750_MCR_TRC_6 0x10000000 /* 6 */
782+#define SH7750_MCR_TRC_9 0x18000000 /* 9 */
783+#define SH7750_MCR_TRC_12 0x20000000 /* 12 */
784+#define SH7750_MCR_TRC_15 0x28000000 /* 15 */
785+#define SH7750_MCR_TRC_18 0x30000000 /* 18 */
786+#define SH7750_MCR_TRC_21 0x38000000 /* 21 */
787+
788+#define SH7750_MCR_TCAS 0x00800000 /* CAS Negation Period */
789+#define SH7750_MCR_TCAS_1 0x00000000 /* 1 */
790+#define SH7750_MCR_TCAS_2 0x00800000 /* 2 */
791+
792+#define SH7750_MCR_TPC 0x00380000 /* DRAM: RAS Precharge Period
793+ SDRAM: minimum number of cycles
794+ until the next bank active cmd
795+ is output after precharging */
796+#define SH7750_MCR_TPC_S 19
797+#define SH7750_MCR_TPC_SDRAM_1 0x00000000 /* 1 cycle */
798+#define SH7750_MCR_TPC_SDRAM_2 0x00080000 /* 2 cycles */
799+#define SH7750_MCR_TPC_SDRAM_3 0x00100000 /* 3 cycles */
800+#define SH7750_MCR_TPC_SDRAM_4 0x00180000 /* 4 cycles */
801+#define SH7750_MCR_TPC_SDRAM_5 0x00200000 /* 5 cycles */
802+#define SH7750_MCR_TPC_SDRAM_6 0x00280000 /* 6 cycles */
803+#define SH7750_MCR_TPC_SDRAM_7 0x00300000 /* 7 cycles */
804+#define SH7750_MCR_TPC_SDRAM_8 0x00380000 /* 8 cycles */
805+
806+#define SH7750_MCR_RCD 0x00030000 /* DRAM: RAS-CAS Assertion Delay time
807+ SDRAM: bank active-read/write cmd
808+ delay time */
809+#define SH7750_MCR_RCD_DRAM_2 0x00000000 /* DRAM delay 2 clocks */
810+#define SH7750_MCR_RCD_DRAM_3 0x00010000 /* DRAM delay 3 clocks */
811+#define SH7750_MCR_RCD_DRAM_4 0x00020000 /* DRAM delay 4 clocks */
812+#define SH7750_MCR_RCD_DRAM_5 0x00030000 /* DRAM delay 5 clocks */
813+#define SH7750_MCR_RCD_SDRAM_2 0x00010000 /* DRAM delay 2 clocks */
814+#define SH7750_MCR_RCD_SDRAM_3 0x00020000 /* DRAM delay 3 clocks */
815+#define SH7750_MCR_RCD_SDRAM_4 0x00030000 /* DRAM delay 4 clocks */
816+
817+#define SH7750_MCR_TRWL 0x0000E000 /* SDRAM Write Precharge Delay */
818+#define SH7750_MCR_TRWL_1 0x00000000 /* 1 */
819+#define SH7750_MCR_TRWL_2 0x00002000 /* 2 */
820+#define SH7750_MCR_TRWL_3 0x00004000 /* 3 */
821+#define SH7750_MCR_TRWL_4 0x00006000 /* 4 */
822+#define SH7750_MCR_TRWL_5 0x00008000 /* 5 */
823+
824+#define SH7750_MCR_TRAS 0x00001C00 /* DRAM: CAS-Before-RAS Refresh RAS
825+ asserting period
826+ SDRAM: Command interval after
827+ synchronous DRAM refresh */
828+#define SH7750_MCR_TRAS_DRAM_2 0x00000000 /* 2 */
829+#define SH7750_MCR_TRAS_DRAM_3 0x00000400 /* 3 */
830+#define SH7750_MCR_TRAS_DRAM_4 0x00000800 /* 4 */
831+#define SH7750_MCR_TRAS_DRAM_5 0x00000C00 /* 5 */
832+#define SH7750_MCR_TRAS_DRAM_6 0x00001000 /* 6 */
833+#define SH7750_MCR_TRAS_DRAM_7 0x00001400 /* 7 */
834+#define SH7750_MCR_TRAS_DRAM_8 0x00001800 /* 8 */
835+#define SH7750_MCR_TRAS_DRAM_9 0x00001C00 /* 9 */
836+
837+#define SH7750_MCR_TRAS_SDRAM_TRC_4 0x00000000 /* 4 + TRC */
838+#define SH7750_MCR_TRAS_SDRAM_TRC_5 0x00000400 /* 5 + TRC */
839+#define SH7750_MCR_TRAS_SDRAM_TRC_6 0x00000800 /* 6 + TRC */
840+#define SH7750_MCR_TRAS_SDRAM_TRC_7 0x00000C00 /* 7 + TRC */
841+#define SH7750_MCR_TRAS_SDRAM_TRC_8 0x00001000 /* 8 + TRC */
842+#define SH7750_MCR_TRAS_SDRAM_TRC_9 0x00001400 /* 9 + TRC */
843+#define SH7750_MCR_TRAS_SDRAM_TRC_10 0x00001800 /* 10 + TRC */
844+#define SH7750_MCR_TRAS_SDRAM_TRC_11 0x00001C00 /* 11 + TRC */
845+
846+#define SH7750_MCR_BE 0x00000200 /* Burst Enable */
847+#define SH7750_MCR_SZ 0x00000180 /* Memory Data Size */
848+#define SH7750_MCR_SZ_64 0x00000000 /* 64 bits */
849+#define SH7750_MCR_SZ_16 0x00000100 /* 16 bits */
850+#define SH7750_MCR_SZ_32 0x00000180 /* 32 bits */
851+
852+#define SH7750_MCR_AMX 0x00000078 /* Address Multiplexing */
853+#define SH7750_MCR_AMX_S 3
854+#define SH7750_MCR_AMX_DRAM_8BIT_COL 0x00000000 /* 8-bit column addr */
855+#define SH7750_MCR_AMX_DRAM_9BIT_COL 0x00000008 /* 9-bit column addr */
856+#define SH7750_MCR_AMX_DRAM_10BIT_COL 0x00000010 /* 10-bit column addr */
857+#define SH7750_MCR_AMX_DRAM_11BIT_COL 0x00000018 /* 11-bit column addr */
858+#define SH7750_MCR_AMX_DRAM_12BIT_COL 0x00000020 /* 12-bit column addr */
859+/* See SH7750 Hardware Manual for SDRAM address multiplexor selection */
860+
861+#define SH7750_MCR_RFSH 0x00000004 /* Refresh Control */
862+#define SH7750_MCR_RMODE 0x00000002 /* Refresh Mode: */
863+#define SH7750_MCR_RMODE_NORMAL 0x00000000 /* Normal Refresh Mode */
864+#define SH7750_MCR_RMODE_SELF 0x00000002 /* Self-Refresh Mode */
865+#define SH7750_MCR_RMODE_EDO 0x00000001 /* EDO Mode */
866+
867+/* SDRAM Mode Set address */
868+#define SH7750_SDRAM_MODE_A2_BASE 0xFF900000
869+#define SH7750_SDRAM_MODE_A3_BASE 0xFF940000
870+#define SH7750_SDRAM_MODE_A2_32BIT(x) (SH7750_SDRAM_MODE_A2_BASE + ((x) << 2))
871+#define SH7750_SDRAM_MODE_A3_32BIT(x) (SH7750_SDRAM_MODE_A3_BASE + ((x) << 2))
872+#define SH7750_SDRAM_MODE_A2_64BIT(x) (SH7750_SDRAM_MODE_A2_BASE + ((x) << 3))
873+#define SH7750_SDRAM_MODE_A3_64BIT(x) (SH7750_SDRAM_MODE_A3_BASE + ((x) << 3))
874+
875+
876+/* PCMCIA Control Register (half) - PCR */
877+#define SH7750_PCR_REGOFS 0x800018 /* offset */
878+#define SH7750_PCR SH7750_P4_REG32(SH7750_PCR_REGOFS)
879+#define SH7750_PCR_A7 SH7750_A7_REG32(SH7750_PCR_REGOFS)
880+
881+#define SH7750_PCR_A5PCW 0xC000 /* Area 5 PCMCIA Wait - Number of wait
882+ states to be added to the number of
883+ waits specified by WCR2 in a low-speed
884+ PCMCIA wait cycle */
885+#define SH7750_PCR_A5PCW_0 0x0000 /* 0 waits inserted */
886+#define SH7750_PCR_A5PCW_15 0x4000 /* 15 waits inserted */
887+#define SH7750_PCR_A5PCW_30 0x8000 /* 30 waits inserted */
888+#define SH7750_PCR_A5PCW_50 0xC000 /* 50 waits inserted */
889+
890+#define SH7750_PCR_A6PCW 0x3000 /* Area 6 PCMCIA Wait - Number of wait
891+ states to be added to the number of
892+ waits specified by WCR2 in a low-speed
893+ PCMCIA wait cycle */
894+#define SH7750_PCR_A6PCW_0 0x0000 /* 0 waits inserted */
895+#define SH7750_PCR_A6PCW_15 0x1000 /* 15 waits inserted */
896+#define SH7750_PCR_A6PCW_30 0x2000 /* 30 waits inserted */
897+#define SH7750_PCR_A6PCW_50 0x3000 /* 50 waits inserted */
898+
899+#define SH7750_PCR_A5TED 0x0E00 /* Area 5 Address-OE\/WE\ Assertion Delay,
900+ delay time from address output to
901+ OE\/WE\ assertion on the connected
902+ PCMCIA interface */
903+#define SH7750_PCR_A5TED_S 9
904+#define SH7750_PCR_A6TED 0x01C0 /* Area 6 Address-OE\/WE\ Assertion Delay */
905+#define SH7750_PCR_A6TED_S 6
906+
907+#define SH7750_PCR_TED_0WS 0 /* 0 Waits inserted */
908+#define SH7750_PCR_TED_1WS 1 /* 1 Waits inserted */
909+#define SH7750_PCR_TED_2WS 2 /* 2 Waits inserted */
910+#define SH7750_PCR_TED_3WS 3 /* 3 Waits inserted */
911+#define SH7750_PCR_TED_6WS 4 /* 6 Waits inserted */
912+#define SH7750_PCR_TED_9WS 5 /* 9 Waits inserted */
913+#define SH7750_PCR_TED_12WS 6 /* 12 Waits inserted */
914+#define SH7750_PCR_TED_15WS 7 /* 15 Waits inserted */
915+
916+#define SH7750_PCR_A5TEH 0x0038 /* Area 5 OE\/WE\ Negation Address delay,
917+ address hold delay time from OE\/WE\
918+ negation in a write on the connected
919+ PCMCIA interface */
920+#define SH7750_PCR_A5TEH_S 3
921+
922+#define SH7750_PCR_A6TEH 0x0007 /* Area 6 OE\/WE\ Negation Address delay */
923+#define SH7750_PCR_A6TEH_S 0
924+
925+#define SH7750_PCR_TEH_0WS 0 /* 0 Waits inserted */
926+#define SH7750_PCR_TEH_1WS 1 /* 1 Waits inserted */
927+#define SH7750_PCR_TEH_2WS 2 /* 2 Waits inserted */
928+#define SH7750_PCR_TEH_3WS 3 /* 3 Waits inserted */
929+#define SH7750_PCR_TEH_6WS 4 /* 6 Waits inserted */
930+#define SH7750_PCR_TEH_9WS 5 /* 9 Waits inserted */
931+#define SH7750_PCR_TEH_12WS 6 /* 12 Waits inserted */
932+#define SH7750_PCR_TEH_15WS 7 /* 15 Waits inserted */
933+
934+/* Refresh Timer Control/Status Register (half) - RTSCR */
935+#define SH7750_RTCSR_REGOFS 0x80001C /* offset */
936+#define SH7750_RTCSR SH7750_P4_REG32(SH7750_RTCSR_REGOFS)
937+#define SH7750_RTCSR_A7 SH7750_A7_REG32(SH7750_RTCSR_REGOFS)
938+
939+#define SH7750_RTCSR_KEY 0xA500 /* RTCSR write key */
940+#define SH7750_RTCSR_CMF 0x0080 /* Compare-Match Flag (indicates a
941+ match between the refresh timer
942+ counter and refresh time constant) */
943+#define SH7750_RTCSR_CMIE 0x0040 /* Compare-Match Interrupt Enable */
944+#define SH7750_RTCSR_CKS 0x0038 /* Refresh Counter Clock Selects */
945+#define SH7750_RTCSR_CKS_DIS 0x0000 /* Clock Input Disabled */
946+#define SH7750_RTCSR_CKS_CKIO_DIV4 0x0008 /* Bus Clock / 4 */
947+#define SH7750_RTCSR_CKS_CKIO_DIV16 0x0010 /* Bus Clock / 16 */
948+#define SH7750_RTCSR_CKS_CKIO_DIV64 0x0018 /* Bus Clock / 64 */
949+#define SH7750_RTCSR_CKS_CKIO_DIV256 0x0020 /* Bus Clock / 256 */
950+#define SH7750_RTCSR_CKS_CKIO_DIV1024 0x0028 /* Bus Clock / 1024 */
951+#define SH7750_RTCSR_CKS_CKIO_DIV2048 0x0030 /* Bus Clock / 2048 */
952+#define SH7750_RTCSR_CKS_CKIO_DIV4096 0x0038 /* Bus Clock / 4096 */
953+
954+#define SH7750_RTCSR_OVF 0x0004 /* Refresh Count Overflow Flag */
955+#define SH7750_RTCSR_OVIE 0x0002 /* Refresh Count Overflow Interrupt
956+ Enable */
957+#define SH7750_RTCSR_LMTS 0x0001 /* Refresh Count Overflow Limit Select */
958+#define SH7750_RTCSR_LMTS_1024 0x0000 /* Count Limit is 1024 */
959+#define SH7750_RTCSR_LMTS_512 0x0001 /* Count Limit is 512 */
960+
961+/* Refresh Timer Counter (half) - RTCNT */
962+#define SH7750_RTCNT_REGOFS 0x800020 /* offset */
963+#define SH7750_RTCNT SH7750_P4_REG32(SH7750_RTCNT_REGOFS)
964+#define SH7750_RTCNT_A7 SH7750_A7_REG32(SH7750_RTCNT_REGOFS)
965+
966+#define SH7750_RTCNT_KEY 0xA500 /* RTCNT write key */
967+
968+/* Refresh Time Constant Register (half) - RTCOR */
969+#define SH7750_RTCOR_REGOFS 0x800024 /* offset */
970+#define SH7750_RTCOR SH7750_P4_REG32(SH7750_RTCOR_REGOFS)
971+#define SH7750_RTCOR_A7 SH7750_A7_REG32(SH7750_RTCOR_REGOFS)
972+
973+#define SH7750_RTCOR_KEY 0xA500 /* RTCOR write key */
974+
975+/* Refresh Count Register (half) - RFCR */
976+#define SH7750_RFCR_REGOFS 0x800028 /* offset */
977+#define SH7750_RFCR SH7750_P4_REG32(SH7750_RFCR_REGOFS)
978+#define SH7750_RFCR_A7 SH7750_A7_REG32(SH7750_RFCR_REGOFS)
979+
980+#define SH7750_RFCR_KEY 0xA400 /* RFCR write key */
981+
982+/* Synchronous DRAM mode registers - SDMR */
983+#define SH7750_SDMR2_REGOFS 0x900000 /* base offset */
984+#define SH7750_SDMR2_REGNB 0x0FFC /* nb of register */
985+#define SH7750_SDMR2 SH7750_P4_REG32(SH7750_SDMR2_REGOFS)
986+#define SH7750_SDMR2_A7 SH7750_A7_REG32(SH7750_SDMR2_REGOFS)
987+
988+#define SH7750_SDMR3_REGOFS 0x940000 /* offset */
989+#define SH7750_SDMR3_REGNB 0x0FFC /* nb of register */
990+#define SH7750_SDMR3 SH7750_P4_REG32(SH7750_SDMR3_REGOFS)
991+#define SH7750_SDMR3_A7 SH7750_A7_REG32(SH7750_SDMR3_REGOFS)
992+
993+/*
994+ * Direct Memory Access Controller (DMAC)
995+ */
996+
997+/* DMA Source Address Register - SAR0, SAR1, SAR2, SAR3 */
998+#define SH7750_SAR_REGOFS(n) (0xA00000 + ((n)*16)) /* offset */
999+#define SH7750_SAR(n) SH7750_P4_REG32(SH7750_SAR_REGOFS(n))
1000+#define SH7750_SAR_A7(n) SH7750_A7_REG32(SH7750_SAR_REGOFS(n))
1001+#define SH7750_SAR0 SH7750_SAR(0)
1002+#define SH7750_SAR1 SH7750_SAR(1)
1003+#define SH7750_SAR2 SH7750_SAR(2)
1004+#define SH7750_SAR3 SH7750_SAR(3)
1005+#define SH7750_SAR0_A7 SH7750_SAR_A7(0)
1006+#define SH7750_SAR1_A7 SH7750_SAR_A7(1)
1007+#define SH7750_SAR2_A7 SH7750_SAR_A7(2)
1008+#define SH7750_SAR3_A7 SH7750_SAR_A7(3)
1009+
1010+/* DMA Destination Address Register - DAR0, DAR1, DAR2, DAR3 */
1011+#define SH7750_DAR_REGOFS(n) (0xA00004 + ((n)*16)) /* offset */
1012+#define SH7750_DAR(n) SH7750_P4_REG32(SH7750_DAR_REGOFS(n))
1013+#define SH7750_DAR_A7(n) SH7750_A7_REG32(SH7750_DAR_REGOFS(n))
1014+#define SH7750_DAR0 SH7750_DAR(0)
1015+#define SH7750_DAR1 SH7750_DAR(1)
1016+#define SH7750_DAR2 SH7750_DAR(2)
1017+#define SH7750_DAR3 SH7750_DAR(3)
1018+#define SH7750_DAR0_A7 SH7750_DAR_A7(0)
1019+#define SH7750_DAR1_A7 SH7750_DAR_A7(1)
1020+#define SH7750_DAR2_A7 SH7750_DAR_A7(2)
1021+#define SH7750_DAR3_A7 SH7750_DAR_A7(3)
1022+
1023+/* DMA Transfer Count Register - DMATCR0, DMATCR1, DMATCR2, DMATCR3 */
1024+#define SH7750_DMATCR_REGOFS(n) (0xA00008 + ((n)*16)) /* offset */
1025+#define SH7750_DMATCR(n) SH7750_P4_REG32(SH7750_DMATCR_REGOFS(n))
1026+#define SH7750_DMATCR_A7(n) SH7750_A7_REG32(SH7750_DMATCR_REGOFS(n))
1027+#define SH7750_DMATCR0_P4 SH7750_DMATCR(0)
1028+#define SH7750_DMATCR1_P4 SH7750_DMATCR(1)
1029+#define SH7750_DMATCR2_P4 SH7750_DMATCR(2)
1030+#define SH7750_DMATCR3_P4 SH7750_DMATCR(3)
1031+#define SH7750_DMATCR0_A7 SH7750_DMATCR_A7(0)
1032+#define SH7750_DMATCR1_A7 SH7750_DMATCR_A7(1)
1033+#define SH7750_DMATCR2_A7 SH7750_DMATCR_A7(2)
1034+#define SH7750_DMATCR3_A7 SH7750_DMATCR_A7(3)
1035+
1036+/* DMA Channel Control Register - CHCR0, CHCR1, CHCR2, CHCR3 */
1037+#define SH7750_CHCR_REGOFS(n) (0xA0000C + ((n)*16)) /* offset */
1038+#define SH7750_CHCR(n) SH7750_P4_REG32(SH7750_CHCR_REGOFS(n))
1039+#define SH7750_CHCR_A7(n) SH7750_A7_REG32(SH7750_CHCR_REGOFS(n))
1040+#define SH7750_CHCR0 SH7750_CHCR(0)
1041+#define SH7750_CHCR1 SH7750_CHCR(1)
1042+#define SH7750_CHCR2 SH7750_CHCR(2)
1043+#define SH7750_CHCR3 SH7750_CHCR(3)
1044+#define SH7750_CHCR0_A7 SH7750_CHCR_A7(0)
1045+#define SH7750_CHCR1_A7 SH7750_CHCR_A7(1)
1046+#define SH7750_CHCR2_A7 SH7750_CHCR_A7(2)
1047+#define SH7750_CHCR3_A7 SH7750_CHCR_A7(3)
1048+
1049+#define SH7750_CHCR_SSA 0xE0000000 /* Source Address Space Attribute */
1050+#define SH7750_CHCR_SSA_PCMCIA 0x00000000 /* Reserved in PCMCIA access */
1051+#define SH7750_CHCR_SSA_DYNBSZ 0x20000000 /* Dynamic Bus Sizing I/O space */
1052+#define SH7750_CHCR_SSA_IO8 0x40000000 /* 8-bit I/O space */
1053+#define SH7750_CHCR_SSA_IO16 0x60000000 /* 16-bit I/O space */
1054+#define SH7750_CHCR_SSA_CMEM8 0x80000000 /* 8-bit common memory space */
1055+#define SH7750_CHCR_SSA_CMEM16 0xA0000000 /* 16-bit common memory space */
1056+#define SH7750_CHCR_SSA_AMEM8 0xC0000000 /* 8-bit attribute memory space */
1057+#define SH7750_CHCR_SSA_AMEM16 0xE0000000 /* 16-bit attribute memory space */
1058+
1059+#define SH7750_CHCR_STC 0x10000000 /* Source Address Wait Control Select,
1060+ specifies CS5 or CS6 space wait
1061+ control for PCMCIA access */
1062+
1063+#define SH7750_CHCR_DSA 0x0E000000 /* Source Address Space Attribute */
1064+#define SH7750_CHCR_DSA_PCMCIA 0x00000000 /* Reserved in PCMCIA access */
1065+#define SH7750_CHCR_DSA_DYNBSZ 0x02000000 /* Dynamic Bus Sizing I/O space */
1066+#define SH7750_CHCR_DSA_IO8 0x04000000 /* 8-bit I/O space */
1067+#define SH7750_CHCR_DSA_IO16 0x06000000 /* 16-bit I/O space */
1068+#define SH7750_CHCR_DSA_CMEM8 0x08000000 /* 8-bit common memory space */
1069+#define SH7750_CHCR_DSA_CMEM16 0x0A000000 /* 16-bit common memory space */
1070+#define SH7750_CHCR_DSA_AMEM8 0x0C000000 /* 8-bit attribute memory space */
1071+#define SH7750_CHCR_DSA_AMEM16 0x0E000000 /* 16-bit attribute memory space */
1072+
1073+#define SH7750_CHCR_DTC 0x01000000 /* Destination Address Wait Control
1074+ Select, specifies CS5 or CS6
1075+ space wait control for PCMCIA
1076+ access */
1077+
1078+#define SH7750_CHCR_DS 0x00080000 /* DREQ\ Select : */
1079+#define SH7750_CHCR_DS_LOWLVL 0x00000000 /* Low Level Detection */
1080+#define SH7750_CHCR_DS_FALL 0x00080000 /* Falling Edge Detection */
1081+
1082+#define SH7750_CHCR_RL 0x00040000 /* Request Check Level: */
1083+#define SH7750_CHCR_RL_ACTH 0x00000000 /* DRAK is an active high out */
1084+#define SH7750_CHCR_RL_ACTL 0x00040000 /* DRAK is an active low out */
1085+
1086+#define SH7750_CHCR_AM 0x00020000 /* Acknowledge Mode: */
1087+#define SH7750_CHCR_AM_RD 0x00000000 /* DACK is output in read cycle */
1088+#define SH7750_CHCR_AM_WR 0x00020000 /* DACK is output in write cycle */
1089+
1090+#define SH7750_CHCR_AL 0x00010000 /* Acknowledge Level: */
1091+#define SH7750_CHCR_AL_ACTH 0x00000000 /* DACK is an active high out */
1092+#define SH7750_CHCR_AL_ACTL 0x00010000 /* DACK is an active low out */
1093+
1094+#define SH7750_CHCR_DM 0x0000C000 /* Destination Address Mode: */
1095+#define SH7750_CHCR_DM_FIX 0x00000000 /* Destination Addr Fixed */
1096+#define SH7750_CHCR_DM_INC 0x00004000 /* Destination Addr Incremented */
1097+#define SH7750_CHCR_DM_DEC 0x00008000 /* Destination Addr Decremented */
1098+
1099+#define SH7750_CHCR_SM 0x00003000 /* Source Address Mode: */
1100+#define SH7750_CHCR_SM_FIX 0x00000000 /* Source Addr Fixed */
1101+#define SH7750_CHCR_SM_INC 0x00001000 /* Source Addr Incremented */
1102+#define SH7750_CHCR_SM_DEC 0x00002000 /* Source Addr Decremented */
1103+
1104+#define SH7750_CHCR_RS 0x00000F00 /* Request Source Select: */
1105+#define SH7750_CHCR_RS_ER_DA_EA_TO_EA 0x000 /* External Request, Dual Address
1106+ Mode (External Addr Space->
1107+ External Addr Space) */
1108+#define SH7750_CHCR_RS_ER_SA_EA_TO_ED 0x200 /* External Request, Single
1109+ Address Mode (External Addr
1110+ Space -> External Device) */
1111+#define SH7750_CHCR_RS_ER_SA_ED_TO_EA 0x300 /* External Request, Single
1112+ Address Mode, (External
1113+ Device -> External Addr
1114+ Space) */
1115+#define SH7750_CHCR_RS_AR_EA_TO_EA 0x400 /* Auto-Request (External Addr
1116+ Space -> External Addr Space) */
1117+
1118+#define SH7750_CHCR_RS_AR_EA_TO_OCP 0x500 /* Auto-Request (External Addr
1119+ Space -> On-chip Peripheral
1120+ Module) */
1121+#define SH7750_CHCR_RS_AR_OCP_TO_EA 0x600 /* Auto-Request (On-chip
1122+ Peripheral Module ->
1123+ External Addr Space */
1124+#define SH7750_CHCR_RS_SCITX_EA_TO_SC 0x800 /* SCI Transmit-Data-Empty intr
1125+ transfer request (external
1126+ address space -> SCTDR1) */
1127+#define SH7750_CHCR_RS_SCIRX_SC_TO_EA 0x900 /* SCI Receive-Data-Full intr
1128+ transfer request (SCRDR1 ->
1129+ External Addr Space) */
1130+#define SH7750_CHCR_RS_SCIFTX_EA_TO_SC 0xA00 /* SCIF Transmit-Data-Empty intr
1131+ transfer request (external
1132+ address space -> SCFTDR1) */
1133+#define SH7750_CHCR_RS_SCIFRX_SC_TO_EA 0xB00 /* SCIF Receive-Data-Full intr
1134+ transfer request (SCFRDR2 ->
1135+ External Addr Space) */
1136+#define SH7750_CHCR_RS_TMU2_EA_TO_EA 0xC00 /* TMU Channel 2 (input capture
1137+ interrupt), (external address
1138+ space -> external address
1139+ space) */
1140+#define SH7750_CHCR_RS_TMU2_EA_TO_OCP 0xD00 /* TMU Channel 2 (input capture
1141+ interrupt), (external address
1142+ space -> on-chip peripheral
1143+ module) */
1144+#define SH7750_CHCR_RS_TMU2_OCP_TO_EA 0xE00 /* TMU Channel 2 (input capture
1145+ interrupt), (on-chip
1146+ peripheral module -> external
1147+ address space) */
1148+
1149+#define SH7750_CHCR_TM 0x00000080 /* Transmit mode: */
1150+#define SH7750_CHCR_TM_CSTEAL 0x00000000 /* Cycle Steal Mode */
1151+#define SH7750_CHCR_TM_BURST 0x00000080 /* Burst Mode */
1152+
1153+#define SH7750_CHCR_TS 0x00000070 /* Transmit Size: */
1154+#define SH7750_CHCR_TS_QUAD 0x00000000 /* Quadword Size (64 bits) */
1155+#define SH7750_CHCR_TS_BYTE 0x00000010 /* Byte Size (8 bit) */
1156+#define SH7750_CHCR_TS_WORD 0x00000020 /* Word Size (16 bit) */
1157+#define SH7750_CHCR_TS_LONG 0x00000030 /* Longword Size (32 bit) */
1158+#define SH7750_CHCR_TS_BLOCK 0x00000040 /* 32-byte block transfer */
1159+
1160+#define SH7750_CHCR_IE 0x00000004 /* Interrupt Enable */
1161+#define SH7750_CHCR_TE 0x00000002 /* Transfer End */
1162+#define SH7750_CHCR_DE 0x00000001 /* DMAC Enable */
1163+
1164+/* DMA Operation Register - DMAOR */
1165+#define SH7750_DMAOR_REGOFS 0xA00040 /* offset */
1166+#define SH7750_DMAOR SH7750_P4_REG32(SH7750_DMAOR_REGOFS)
1167+#define SH7750_DMAOR_A7 SH7750_A7_REG32(SH7750_DMAOR_REGOFS)
1168+
1169+#define SH7750_DMAOR_DDT 0x00008000 /* On-Demand Data Transfer Mode */
1170+
1171+#define SH7750_DMAOR_PR 0x00000300 /* Priority Mode: */
1172+#define SH7750_DMAOR_PR_0123 0x00000000 /* CH0 > CH1 > CH2 > CH3 */
1173+#define SH7750_DMAOR_PR_0231 0x00000100 /* CH0 > CH2 > CH3 > CH1 */
1174+#define SH7750_DMAOR_PR_2013 0x00000200 /* CH2 > CH0 > CH1 > CH3 */
1175+#define SH7750_DMAOR_PR_RR 0x00000300 /* Round-robin mode */
1176+
1177+#define SH7750_DMAOR_COD 0x00000010 /* Check Overrun for DREQ\ */
1178+#define SH7750_DMAOR_AE 0x00000004 /* Address Error flag */
1179+#define SH7750_DMAOR_NMIF 0x00000002 /* NMI Flag */
1180+#define SH7750_DMAOR_DME 0x00000001 /* DMAC Master Enable */
1181+
1182+/*
1183+ * I/O Ports
1184+ */
1185+/* Port Control Register A - PCTRA */
1186+#define SH7750_PCTRA_REGOFS 0x80002C /* offset */
1187+#define SH7750_PCTRA SH7750_P4_REG32(SH7750_PCTRA_REGOFS)
1188+#define SH7750_PCTRA_A7 SH7750_A7_REG32(SH7750_PCTRA_REGOFS)
1189+
1190+#define SH7750_PCTRA_PBPUP(n) 0 /* Bit n is pulled up */
1191+#define SH7750_PCTRA_PBNPUP(n) (1 << ((n)*2+1)) /* Bit n is not pulled up */
1192+#define SH7750_PCTRA_PBINP(n) 0 /* Bit n is an input */
1193+#define SH7750_PCTRA_PBOUT(n) (1 << ((n)*2)) /* Bit n is an output */
1194+
1195+/* Port Data Register A - PDTRA(half) */
1196+#define SH7750_PDTRA_REGOFS 0x800030 /* offset */
1197+#define SH7750_PDTRA SH7750_P4_REG32(SH7750_PDTRA_REGOFS)
1198+#define SH7750_PDTRA_A7 SH7750_A7_REG32(SH7750_PDTRA_REGOFS)
1199+
1200+#define SH7750_PDTRA_BIT(n) (1 << (n))
1201+
1202+/* Port Control Register B - PCTRB */
1203+#define SH7750_PCTRB_REGOFS 0x800040 /* offset */
1204+#define SH7750_PCTRB SH7750_P4_REG32(SH7750_PCTRB_REGOFS)
1205+#define SH7750_PCTRB_A7 SH7750_A7_REG32(SH7750_PCTRB_REGOFS)
1206+
1207+#define SH7750_PCTRB_PBPUP(n) 0 /* Bit n is pulled up */
1208+#define SH7750_PCTRB_PBNPUP(n) (1 << ((n-16)*2+1)) /* Bit n is not pulled up */
1209+#define SH7750_PCTRB_PBINP(n) 0 /* Bit n is an input */
1210+#define SH7750_PCTRB_PBOUT(n) (1 << ((n-16)*2)) /* Bit n is an output */
1211+
1212+/* Port Data Register B - PDTRB(half) */
1213+#define SH7750_PDTRB_REGOFS 0x800044 /* offset */
1214+#define SH7750_PDTRB SH7750_P4_REG32(SH7750_PDTRB_REGOFS)
1215+#define SH7750_PDTRB_A7 SH7750_A7_REG32(SH7750_PDTRB_REGOFS)
1216+
1217+#define SH7750_PDTRB_BIT(n) (1 << ((n)-16))
1218+
1219+/* GPIO Interrupt Control Register - GPIOIC(half) */
1220+#define SH7750_GPIOIC_REGOFS 0x800048 /* offset */
1221+#define SH7750_GPIOIC SH7750_P4_REG32(SH7750_GPIOIC_REGOFS)
1222+#define SH7750_GPIOIC_A7 SH7750_A7_REG32(SH7750_GPIOIC_REGOFS)
1223+
1224+#define SH7750_GPIOIC_PTIREN(n) (1 << (n)) /* Port n is used as a GPIO int */
1225+
1226+/*
1227+ * Interrupt Controller - INTC
1228+ */
1229+/* Interrupt Control Register - ICR (half) */
1230+#define SH7750_ICR_REGOFS 0xD00000 /* offset */
1231+#define SH7750_ICR SH7750_P4_REG32(SH7750_ICR_REGOFS)
1232+#define SH7750_ICR_A7 SH7750_A7_REG32(SH7750_ICR_REGOFS)
1233+
1234+#define SH7750_ICR_NMIL 0x8000 /* NMI Input Level */
1235+#define SH7750_ICR_MAI 0x4000 /* NMI Interrupt Mask */
1236+
1237+#define SH7750_ICR_NMIB 0x0200 /* NMI Block Mode: */
1238+#define SH7750_ICR_NMIB_BLK 0x0000 /* NMI requests held pending while
1239+ SR.BL bit is set to 1 */
1240+#define SH7750_ICR_NMIB_NBLK 0x0200 /* NMI requests detected when SR.BL bit
1241+ set to 1 */
1242+
1243+#define SH7750_ICR_NMIE 0x0100 /* NMI Edge Select: */
1244+#define SH7750_ICR_NMIE_FALL 0x0000 /* Interrupt request detected on falling
1245+ edge of NMI input */
1246+#define SH7750_ICR_NMIE_RISE 0x0100 /* Interrupt request detected on rising
1247+ edge of NMI input */
1248+
1249+#define SH7750_ICR_IRLM 0x0080 /* IRL Pin Mode: */
1250+#define SH7750_ICR_IRLM_ENC 0x0000 /* IRL\ pins used as a level-encoded
1251+ interrupt requests */
1252+#define SH7750_ICR_IRLM_RAW 0x0080 /* IRL\ pins used as a four independent
1253+ interrupt requests */
1254+
1255+/*
1256+ * User Break Controller registers
1257+ */
1258+#define SH7750_BARA 0x200000 /* Break address regiser A */
1259+#define SH7750_BAMRA 0x200004 /* Break address mask regiser A */
1260+#define SH7750_BBRA 0x200008 /* Break bus cycle regiser A */
1261+#define SH7750_BARB 0x20000c /* Break address regiser B */
1262+#define SH7750_BAMRB 0x200010 /* Break address mask regiser B */
1263+#define SH7750_BBRB 0x200014 /* Break bus cycle regiser B */
1264+#define SH7750_BASRB 0x000018 /* Break ASID regiser B */
1265+#define SH7750_BDRB 0x200018 /* Break data regiser B */
1266+#define SH7750_BDMRB 0x20001c /* Break data mask regiser B */
1267+#define SH7750_BRCR 0x200020 /* Break control register */
1268+
1269+#define SH7750_BRCR_UDBE 0x0001 /* User break debug enable bit */
1270+
1271+/*
1272+ * Missing in RTEMS, added for QEMU
1273+ */
1274+#define SH7750_BCR3_A7 0x1f800050
1275+#define SH7750_BCR4_A7 0x1e0a00f0
1276+
1277+#endif
--- /dev/null
+++ b/hw/sh/sh_pci.c
@@ -0,0 +1,208 @@
1+/*
2+ * SuperH on-chip PCIC emulation.
3+ *
4+ * Copyright (c) 2008 Takashi YOSHII
5+ *
6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7+ * of this software and associated documentation files (the "Software"), to deal
8+ * in the Software without restriction, including without limitation the rights
9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+ * THE SOFTWARE.
23+ */
24+
25+#include "qemu/osdep.h"
26+#include "hw/sysbus.h"
27+#include "hw/sh4/sh.h"
28+#include "hw/pci/pci.h"
29+#include "hw/pci/pci_host.h"
30+#include "qemu/bswap.h"
31+#include "qemu/module.h"
32+#include "exec/address-spaces.h"
33+
34+#define TYPE_SH_PCI_HOST_BRIDGE "sh_pci"
35+
36+#define SH_PCI_HOST_BRIDGE(obj) \
37+ OBJECT_CHECK(SHPCIState, (obj), TYPE_SH_PCI_HOST_BRIDGE)
38+
39+typedef struct SHPCIState {
40+ PCIHostState parent_obj;
41+
42+ PCIDevice *dev;
43+ qemu_irq irq[4];
44+ MemoryRegion memconfig_p4;
45+ MemoryRegion memconfig_a7;
46+ MemoryRegion isa;
47+ uint32_t par;
48+ uint32_t mbr;
49+ uint32_t iobr;
50+} SHPCIState;
51+
52+static void sh_pci_reg_write (void *p, hwaddr addr, uint64_t val,
53+ unsigned size)
54+{
55+ SHPCIState *pcic = p;
56+ PCIHostState *phb = PCI_HOST_BRIDGE(pcic);
57+
58+ switch(addr) {
59+ case 0 ... 0xfc:
60+ stl_le_p(pcic->dev->config + addr, val);
61+ break;
62+ case 0x1c0:
63+ pcic->par = val;
64+ break;
65+ case 0x1c4:
66+ pcic->mbr = val & 0xff000001;
67+ break;
68+ case 0x1c8:
69+ if ((val & 0xfffc0000) != (pcic->iobr & 0xfffc0000)) {
70+ memory_region_del_subregion(get_system_memory(), &pcic->isa);
71+ pcic->iobr = val & 0xfffc0001;
72+ memory_region_add_subregion(get_system_memory(),
73+ pcic->iobr & 0xfffc0000, &pcic->isa);
74+ }
75+ break;
76+ case 0x220:
77+ pci_data_write(phb->bus, pcic->par, val, 4);
78+ break;
79+ }
80+}
81+
82+static uint64_t sh_pci_reg_read (void *p, hwaddr addr,
83+ unsigned size)
84+{
85+ SHPCIState *pcic = p;
86+ PCIHostState *phb = PCI_HOST_BRIDGE(pcic);
87+
88+ switch(addr) {
89+ case 0 ... 0xfc:
90+ return ldl_le_p(pcic->dev->config + addr);
91+ case 0x1c0:
92+ return pcic->par;
93+ case 0x1c4:
94+ return pcic->mbr;
95+ case 0x1c8:
96+ return pcic->iobr;
97+ case 0x220:
98+ return pci_data_read(phb->bus, pcic->par, 4);
99+ }
100+ return 0;
101+}
102+
103+static const MemoryRegionOps sh_pci_reg_ops = {
104+ .read = sh_pci_reg_read,
105+ .write = sh_pci_reg_write,
106+ .endianness = DEVICE_NATIVE_ENDIAN,
107+ .valid = {
108+ .min_access_size = 4,
109+ .max_access_size = 4,
110+ },
111+};
112+
113+static int sh_pci_map_irq(PCIDevice *d, int irq_num)
114+{
115+ return (d->devfn >> 3);
116+}
117+
118+static void sh_pci_set_irq(void *opaque, int irq_num, int level)
119+{
120+ qemu_irq *pic = opaque;
121+
122+ qemu_set_irq(pic[irq_num], level);
123+}
124+
125+static void sh_pci_device_realize(DeviceState *dev, Error **errp)
126+{
127+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
128+ SHPCIState *s = SH_PCI_HOST_BRIDGE(dev);
129+ PCIHostState *phb = PCI_HOST_BRIDGE(s);
130+ int i;
131+
132+ for (i = 0; i < 4; i++) {
133+ sysbus_init_irq(sbd, &s->irq[i]);
134+ }
135+ phb->bus = pci_register_root_bus(DEVICE(dev), "pci",
136+ sh_pci_set_irq, sh_pci_map_irq,
137+ s->irq,
138+ get_system_memory(),
139+ get_system_io(),
140+ PCI_DEVFN(0, 0), 4, TYPE_PCI_BUS);
141+ memory_region_init_io(&s->memconfig_p4, OBJECT(s), &sh_pci_reg_ops, s,
142+ "sh_pci", 0x224);
143+ memory_region_init_alias(&s->memconfig_a7, OBJECT(s), "sh_pci.2",
144+ &s->memconfig_p4, 0, 0x224);
145+ memory_region_init_alias(&s->isa, OBJECT(s), "sh_pci.isa",
146+ get_system_io(), 0, 0x40000);
147+ sysbus_init_mmio(sbd, &s->memconfig_p4);
148+ sysbus_init_mmio(sbd, &s->memconfig_a7);
149+ s->iobr = 0xfe240000;
150+ memory_region_add_subregion(get_system_memory(), s->iobr, &s->isa);
151+
152+ s->dev = pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "sh_pci_host");
153+}
154+
155+static void sh_pci_host_realize(PCIDevice *d, Error **errp)
156+{
157+ pci_set_word(d->config + PCI_COMMAND, PCI_COMMAND_WAIT);
158+ pci_set_word(d->config + PCI_STATUS, PCI_STATUS_CAP_LIST |
159+ PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM);
160+}
161+
162+static void sh_pci_host_class_init(ObjectClass *klass, void *data)
163+{
164+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
165+ DeviceClass *dc = DEVICE_CLASS(klass);
166+
167+ k->realize = sh_pci_host_realize;
168+ k->vendor_id = PCI_VENDOR_ID_HITACHI;
169+ k->device_id = PCI_DEVICE_ID_HITACHI_SH7751R;
170+ /*
171+ * PCI-facing part of the host bridge, not usable without the
172+ * host-facing part, which can't be device_add'ed, yet.
173+ */
174+ dc->user_creatable = false;
175+}
176+
177+static const TypeInfo sh_pci_host_info = {
178+ .name = "sh_pci_host",
179+ .parent = TYPE_PCI_DEVICE,
180+ .instance_size = sizeof(PCIDevice),
181+ .class_init = sh_pci_host_class_init,
182+ .interfaces = (InterfaceInfo[]) {
183+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
184+ { },
185+ },
186+};
187+
188+static void sh_pci_device_class_init(ObjectClass *klass, void *data)
189+{
190+ DeviceClass *dc = DEVICE_CLASS(klass);
191+
192+ dc->realize = sh_pci_device_realize;
193+}
194+
195+static const TypeInfo sh_pci_device_info = {
196+ .name = TYPE_SH_PCI_HOST_BRIDGE,
197+ .parent = TYPE_PCI_HOST_BRIDGE,
198+ .instance_size = sizeof(SHPCIState),
199+ .class_init = sh_pci_device_class_init,
200+};
201+
202+static void sh_pci_register_types(void)
203+{
204+ type_register_static(&sh_pci_device_info);
205+ type_register_static(&sh_pci_host_info);
206+}
207+
208+type_init(sh_pci_register_types)
--- /dev/null
+++ b/hw/sh/shix.c
@@ -0,0 +1,90 @@
1+/*
2+ * SHIX 2.0 board description
3+ *
4+ * Copyright (c) 2005 Samuel Tardieu
5+ *
6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7+ * of this software and associated documentation files (the "Software"), to deal
8+ * in the Software without restriction, including without limitation the rights
9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+ * THE SOFTWARE.
23+ */
24+/*
25+ Shix 2.0 board by Alexis Polti, described at
26+ https://web.archive.org/web/20070917001736/perso.enst.fr/~polti/realisations/shix20
27+
28+ More information in target/sh4/README.sh4
29+*/
30+#include "qemu/osdep.h"
31+#include "qapi/error.h"
32+#include "cpu.h"
33+#include "hw/hw.h"
34+#include "hw/sh4/sh.h"
35+#include "sysemu/sysemu.h"
36+#include "sysemu/qtest.h"
37+#include "hw/boards.h"
38+#include "hw/loader.h"
39+#include "exec/address-spaces.h"
40+#include "qemu/error-report.h"
41+
42+#define BIOS_FILENAME "shix_bios.bin"
43+#define BIOS_ADDRESS 0xA0000000
44+
45+static void shix_init(MachineState *machine)
46+{
47+ int ret;
48+ SuperHCPU *cpu;
49+ struct SH7750State *s;
50+ MemoryRegion *sysmem = get_system_memory();
51+ MemoryRegion *rom = g_new(MemoryRegion, 1);
52+ MemoryRegion *sdram = g_new(MemoryRegion, 2);
53+
54+ cpu = SUPERH_CPU(cpu_create(machine->cpu_type));
55+
56+ /* Allocate memory space */
57+ memory_region_init_ram(rom, NULL, "shix.rom", 0x4000, &error_fatal);
58+ memory_region_set_readonly(rom, true);
59+ memory_region_add_subregion(sysmem, 0x00000000, rom);
60+ memory_region_init_ram(&sdram[0], NULL, "shix.sdram1", 0x01000000,
61+ &error_fatal);
62+ memory_region_add_subregion(sysmem, 0x08000000, &sdram[0]);
63+ memory_region_init_ram(&sdram[1], NULL, "shix.sdram2", 0x01000000,
64+ &error_fatal);
65+ memory_region_add_subregion(sysmem, 0x0c000000, &sdram[1]);
66+
67+ /* Load BIOS in 0 (and access it through P2, 0xA0000000) */
68+ if (bios_name == NULL)
69+ bios_name = BIOS_FILENAME;
70+ ret = load_image_targphys(bios_name, 0, 0x4000);
71+ if (ret < 0 && !qtest_enabled()) {
72+ error_report("Could not load SHIX bios '%s'", bios_name);
73+ exit(1);
74+ }
75+
76+ /* Register peripherals */
77+ s = sh7750_init(cpu, sysmem);
78+ /* XXXXX Check success */
79+ tc58128_init(s, "shix_linux_nand.bin", NULL);
80+}
81+
82+static void shix_machine_init(MachineClass *mc)
83+{
84+ mc->desc = "shix card";
85+ mc->init = shix_init;
86+ mc->is_default = 1;
87+ mc->default_cpu_type = TYPE_SH7750R_CPU;
88+}
89+
90+DEFINE_MACHINE("shix", shix_machine_init)
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -15,7 +15,7 @@ enum {
1515 QEMU_ARCH_MIPS = (1 << 7),
1616 QEMU_ARCH_PPC = (1 << 8),
1717 QEMU_ARCH_S390X = (1 << 9),
18- QEMU_ARCH_SH4 = (1 << 10),
18+ QEMU_ARCH_SH = (1 << 10),
1919 QEMU_ARCH_SPARC = (1 << 11),
2020 QEMU_ARCH_XTENSA = (1 << 12),
2121 QEMU_ARCH_OPENRISC = (1 << 13),
--- /dev/null
+++ b/target/sh/Makefile.objs
@@ -0,0 +1,10 @@
1+obj-y += translate.o op_helper.o helper.o cpu.o gdbstub.o
2+
3+DECODETREE = $(SRC_PATH)/scripts/decodetree.py
4+
5+target/sh/decode.inc.c: \
6+ $(SRC_PATH)/target/sh/insns.decode $(DECODETREE)
7+ $(call quiet-command, \
8+ $(PYTHON) $(DECODETREE) -w 16 -o $@ $<, "GEN", $(TARGET_DIR)$@)
9+
10+target/sh/translate.o: target/sh/decode.inc.c
--- /dev/null
+++ b/target/sh/cpu-param.h
@@ -0,0 +1,21 @@
1+/*
2+ * SH4 cpu parameters for qemu.
3+ *
4+ * Copyright (c) 2005 Samuel Tardieu
5+ * SPDX-License-Identifier: LGPL-2.0+
6+ */
7+
8+#ifndef SH4_CPU_PARAM_H
9+#define SH4_CPU_PARAM_H 1
10+
11+#define TARGET_LONG_BITS 32
12+#define TARGET_PAGE_BITS 12 /* 4k */
13+#define TARGET_PHYS_ADDR_SPACE_BITS 32
14+#ifdef CONFIG_USER_ONLY
15+# define TARGET_VIRT_ADDR_SPACE_BITS 31
16+#else
17+# define TARGET_VIRT_ADDR_SPACE_BITS 32
18+#endif
19+#define NB_MMU_MODES 2
20+
21+#endif
--- /dev/null
+++ b/target/sh/cpu-qom.h
@@ -0,0 +1,62 @@
1+/*
2+ * QEMU SuperH CPU
3+ *
4+ * Copyright (c) 2012 SUSE LINUX Products GmbH
5+ *
6+ * This library is free software; you can redistribute it and/or
7+ * modify it under the terms of the GNU Lesser General Public
8+ * License as published by the Free Software Foundation; either
9+ * version 2.1 of the License, or (at your option) any later version.
10+ *
11+ * This library is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+ * Lesser General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU Lesser General Public
17+ * License along with this library; if not, see
18+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
19+ */
20+#ifndef QEMU_SUPERH_CPU_QOM_H
21+#define QEMU_SUPERH_CPU_QOM_H
22+
23+#include "qom/cpu.h"
24+
25+#define TYPE_SUPERH_CPU "superh-cpu"
26+
27+#define TYPE_SH2_CPU SUPERH_CPU_TYPE_NAME("sh2")
28+#define TYPE_SH4_CPU SUPERH_CPU_TYPE_NAME("sh4")
29+
30+#define SUPERH_CPU_CLASS(klass) \
31+ OBJECT_CLASS_CHECK(SuperHCPUClass, (klass), TYPE_SUPERH_CPU)
32+#define SUPERH_CPU(obj) \
33+ OBJECT_CHECK(SuperHCPU, (obj), TYPE_SUPERH_CPU)
34+#define SUPERH_CPU_GET_CLASS(obj) \
35+ OBJECT_GET_CLASS(SuperHCPUClass, (obj), TYPE_SUPERH_CPU)
36+
37+/**
38+ * SuperHCPUClass:
39+ * @parent_realize: The parent class' realize handler.
40+ * @parent_reset: The parent class' reset handler.
41+ * @pvr: Processor Version Register
42+ * @prr: Processor Revision Register
43+ * @cvr: Cache Version Register
44+ *
45+ * A SuperH CPU model.
46+ */
47+typedef struct SuperHCPUClass {
48+ /*< private >*/
49+ CPUClass parent_class;
50+ /*< public >*/
51+
52+ DeviceRealize parent_realize;
53+ void (*parent_reset)(CPUState *cpu);
54+
55+ uint32_t pvr;
56+ uint32_t prr;
57+ uint32_t cvr;
58+} SuperHCPUClass;
59+
60+#define CPUArchState struct CPUSHState
61+
62+#endif
--- /dev/null
+++ b/target/sh/cpu.c
@@ -0,0 +1,211 @@
1+/*
2+ * QEMU SuperH CPU
3+ *
4+ * Copyright (c) 2005 Samuel Tardieu
5+ * Copyright (c) 2012 SUSE LINUX Products GmbH
6+ * Copyright (c) 2019 Yoshinori Sato
7+ *
8+ * This library is free software; you can redistribute it and/or
9+ * modify it under the terms of the GNU Lesser General Public
10+ * License as published by the Free Software Foundation; either
11+ * version 2.1 of the License, or (at your option) any later version.
12+ *
13+ * This library is distributed in the hope that it will be useful,
14+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+ * Lesser General Public License for more details.
17+ *
18+ * You should have received a copy of the GNU Lesser General Public
19+ * License along with this library; if not, see
20+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
21+ */
22+
23+#include "qemu/osdep.h"
24+#include "qapi/error.h"
25+#include "qemu/qemu-print.h"
26+#include "cpu.h"
27+#include "migration/vmstate.h"
28+#include "exec/exec-all.h"
29+#include "hw/loader.h"
30+
31+static void superh_cpu_set_pc(CPUState *cs, vaddr value)
32+{
33+ SuperHCPU *cpu = SUPERH_CPU(cs);
34+
35+ cpu->env.pc = value;
36+}
37+
38+static void superh_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
39+{
40+ SuperHCPU *cpu = SUPERH_CPU(cs);
41+
42+ cpu->env.pc = tb->pc;
43+ cpu->env.flags = tb->flags & TB_FLAG_ENVFLAGS_MASK;
44+}
45+
46+static bool superh_cpu_has_work(CPUState *cs)
47+{
48+ return cs->interrupt_request & CPU_INTERRUPT_HARD;
49+}
50+
51+/* CPUClass::reset() */
52+static void superh_cpu_reset(CPUState *s)
53+{
54+ SuperHCPU *cpu = SUPERH_CPU(s);
55+ SuperHCPUClass *scc = SUPERH_CPU_GET_CLASS(cpu);
56+ CPUSHState *env = &cpu->env;
57+
58+ scc->parent_reset(s);
59+
60+ memset(env, 0, offsetof(CPUSHState, end_reset_fields));
61+
62+ if ((env->features & FEATURE_ISA) > 2) {
63+ env->pc = 0xA0000000;
64+ env->sr = FIELD_DP32(0, SR, MD, 1);
65+ env->sr = FIELD_DP32(env->sr, SR, BL, 1);
66+ env->sr = FIELD_DP32(env->sr, SR, RB, 1);
67+ env->sr = FIELD_DP32(env->sr, SR, FD, 0);
68+ env->sr = FIELD_DP32(env->sr, SR, I, 0x0f);
69+ if ((env->features & FEATURE_ISA) == 4) {
70+#if 0
71+ env->fpscr = FPSCR_DN | FPSCR_RM_ZERO; /* CPU reset value according to SH4 manual */
72+ set_float_rounding_mode(float_round_to_zero, &env->fp_status);
73+ set_flush_to_zero(1, &env->fp_status);
74+ set_default_nan_mode(1, &env->fp_status);
75+#endif
76+ }
77+ } else {
78+ uint32_t *resetvec;
79+ env->sr = FIELD_DP32(env->sr, SR, I, 0x0f);
80+ resetvec = rom_ptr(0x00000000, 4);
81+ if (resetvec) {
82+ env->pc = ldl_p(resetvec);
83+ resetvec = rom_ptr(0x00000004, 4);
84+ env->regs[15] = ldl_p(resetvec);
85+ }
86+ }
87+
88+}
89+
90+static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
91+{
92+ info->mach = bfd_mach_sh;
93+ info->print_insn = print_insn_sh;
94+}
95+
96+static void superh_cpu_list_entry(gpointer data, gpointer user_data)
97+{
98+ const char *typename = object_class_get_name(OBJECT_CLASS(data));
99+
100+ qemu_printf("%s\n", typename);
101+}
102+
103+void sh_cpu_list(void)
104+{
105+ GSList *list;
106+
107+ list = object_class_get_list_sorted(TYPE_SUPERH_CPU, false);
108+ g_slist_foreach(list, superh_cpu_list_entry, NULL);
109+ g_slist_free(list);
110+}
111+
112+static ObjectClass *superh_cpu_class_by_name(const char *cpu_model)
113+{
114+ ObjectClass *oc;
115+
116+ oc = object_class_by_name(cpu_model);
117+
118+ if (object_class_dynamic_cast(oc, TYPE_SUPERH_CPU) == NULL ||
119+ object_class_is_abstract(oc)) {
120+ oc = NULL;
121+ }
122+
123+ return oc;
124+}
125+
126+static void superh_cpu_realizefn(DeviceState *dev, Error **errp)
127+{
128+ CPUState *cs = CPU(dev);
129+ SuperHCPUClass *scc = SUPERH_CPU_GET_CLASS(dev);
130+ Error *local_err = NULL;
131+
132+ cpu_exec_realizefn(cs, &local_err);
133+ if (local_err != NULL) {
134+ error_propagate(errp, local_err);
135+ return;
136+ }
137+
138+ cpu_reset(cs);
139+ qemu_init_vcpu(cs);
140+
141+ scc->parent_realize(dev, errp);
142+}
143+
144+static void superh_cpu_initfn(Object *obj)
145+{
146+ SuperHCPU *cpu = SUPERH_CPU(obj);
147+
148+ cpu_set_cpustate_pointers(cpu);
149+}
150+
151+static const VMStateDescription vmstate_sh_cpu = {
152+ .name = "cpu",
153+ .unmigratable = 1,
154+};
155+
156+static void superh_cpu_class_init(ObjectClass *oc, void *data)
157+{
158+ DeviceClass *dc = DEVICE_CLASS(oc);
159+ CPUClass *cc = CPU_CLASS(oc);
160+ SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc);
161+
162+ device_class_set_parent_realize(dc, superh_cpu_realizefn,
163+ &scc->parent_realize);
164+
165+ scc->parent_reset = cc->reset;
166+ cc->reset = superh_cpu_reset;
167+
168+ cc->class_by_name = superh_cpu_class_by_name;
169+ cc->has_work = superh_cpu_has_work;
170+ cc->do_interrupt = superh_cpu_do_interrupt;
171+ cc->cpu_exec_interrupt = superh_cpu_exec_interrupt;
172+ cc->dump_state = superh_cpu_dump_state;
173+ cc->set_pc = superh_cpu_set_pc;
174+ cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
175+ cc->gdb_read_register = superh_cpu_gdb_read_register;
176+ cc->gdb_write_register = superh_cpu_gdb_write_register;
177+ cc->tlb_fill = superh_cpu_tlb_fill;
178+#ifndef CONFIG_USER_ONLY
179+ cc->do_unaligned_access = superh_cpu_do_unaligned_access;
180+ cc->get_phys_page_debug = superh_cpu_get_phys_page_debug;
181+#endif
182+ cc->disas_set_info = superh_cpu_disas_set_info;
183+ cc->tcg_initialize = sh_translate_init;
184+
185+ cc->gdb_num_core_regs = 23;
186+ cc->gdb_core_xml_file = "sh-core.xml";
187+ dc->vmsd = &vmstate_sh_cpu;
188+}
189+
190+static const TypeInfo superh_cpu_type_info = {
191+ .name = TYPE_SUPERH_CPU,
192+ .parent = TYPE_CPU,
193+ .instance_size = sizeof(SuperHCPU),
194+ .instance_init = superh_cpu_initfn,
195+ .abstract = true,
196+ .class_size = sizeof(SuperHCPUClass),
197+ .class_init = superh_cpu_class_init,
198+};
199+
200+static const TypeInfo sh2_cpu_type_info = {
201+ .name = TYPE_SH2_CPU,
202+ .parent = TYPE_SUPERH_CPU,
203+};
204+
205+static void sh_cpu_register_types(void)
206+{
207+ type_register_static(&superh_cpu_type_info);
208+ type_register_static(&sh2_cpu_type_info);
209+}
210+
211+type_init(sh_cpu_register_types)
--- /dev/null
+++ b/target/sh/cpu.h
@@ -0,0 +1,338 @@
1+/*
2+ * Renesas SH emulation
3+ *
4+ * Copyright (c) 2005 Samuel Tardieu
5+ * Copyright (c) 2019 Yoshinori Sato
6+ *
7+ * This library is free software; you can redistribute it and/or
8+ * modify it under the terms of the GNU Lesser General Public
9+ * License as published by the Free Software Foundation; either
10+ * version 2.1 of the License, or (at your option) any later version.
11+ *
12+ * This library is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+ * Lesser General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU Lesser General Public
18+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+#ifndef SH_CPU_H
22+#define SH_CPU_H
23+
24+#include "cpu-qom.h"
25+#include "exec/cpu-defs.h"
26+#include "hw/registerfields.h"
27+
28+#define ALIGNED_ONLY
29+
30+/* SR */
31+REG32(SR, 0)
32+FIELD(SR, MD, 30, 1)
33+FIELD(SR, RB, 29, 1)
34+FIELD(SR, BL, 28, 1)
35+FIELD(SR, FD, 15, 1)
36+FIELD(SR, M, 9, 1)
37+FIELD(SR, Q, 8, 1)
38+FIELD(SR, I, 4, 4)
39+FIELD(SR, S, 1, 1)
40+FIELD(SR, T, 0, 1)
41+
42+#define DELAY_SLOT_MASK 0x7
43+#define DELAY_SLOT (1 << 0)
44+#define DELAY_SLOT_CONDITIONAL (1 << 1)
45+#define DELAY_SLOT_RTE (1 << 2)
46+
47+#define TB_FLAG_ENVFLAGS_MASK DELAY_SLOT_MASK
48+#define FEATURE_ISA (15)
49+#define FEATURE_A (1 << 4)
50+#define FEATURE_R (1 << 5)
51+
52+#define SH_FEATURE_SH2 (2)
53+#define SH_FEATURE_SH2A (2 | FEATURE_A)
54+#define SH_FEATURE_SH3 (3)
55+#define SH_FEATURE_SH4 (4)
56+#define SH_FEATURE_SH4A (4 | FEATURE_A)
57+
58+typedef struct tlb_t {
59+ uint32_t vpn; /* virtual page number */
60+ uint32_t ppn; /* physical page number */
61+ uint32_t size; /* mapped page size in bytes */
62+ uint8_t asid; /* address space identifier */
63+ uint8_t v:1; /* validity */
64+ uint8_t sz:2; /* page size */
65+ uint8_t sh:1; /* share status */
66+ uint8_t c:1; /* cacheability */
67+ uint8_t pr:2; /* protection key */
68+ uint8_t d:1; /* dirty */
69+ uint8_t wt:1; /* write through */
70+ uint8_t sa:3; /* space attribute (PCMCIA) */
71+ uint8_t tc:1; /* timing control */
72+} tlb_t;
73+
74+#define UTLB_SIZE 64
75+#define ITLB_SIZE 4
76+
77+#define TARGET_INSN_START_EXTRA_WORDS 1
78+
79+typedef struct CPUSHState {
80+ uint32_t regs[32];
81+ uint32_t sr;
82+ uint32_t sr_m; /* M bit of status register */
83+ uint32_t sr_q; /* Q bit of status register */
84+ uint32_t sr_t; /* T bit of status register */
85+
86+ uint32_t ssr; /* saved status register */
87+ uint32_t spc; /* saved program counter */
88+ uint32_t gbr; /* global base register */
89+ uint32_t vbr; /* vector base register */
90+ uint32_t sgr; /* saved global register 15 */
91+ uint32_t dbr; /* debug base register */
92+ uint32_t pc; /* program counter */
93+ uint32_t delayed_pc; /* target of delayed branch */
94+ uint32_t delayed_cond; /* condition of delayed branch */
95+ uint64_t mac; /* multiply and accumulate high */
96+ uint32_t pr; /* procedure register */
97+
98+ /* Those belong to the specific unit (SH7750) but are handled here */
99+ uint32_t mmucr; /* MMU control register */
100+ uint32_t pteh; /* page table entry high register */
101+ uint32_t ptel; /* page table entry low register */
102+ uint32_t ptea; /* page table entry assistance register */
103+ uint32_t ttb; /* tranlation table base register */
104+ uint32_t tea; /* TLB exception address register */
105+ uint32_t tra; /* TRAPA exception register */
106+ uint32_t expevt; /* exception event register */
107+ uint32_t intevt; /* interrupt event register */
108+
109+ tlb_t itlb[ITLB_SIZE]; /* instruction translation table */
110+ tlb_t utlb[UTLB_SIZE]; /* unified translation table */
111+ /* Fields up to this point are cleared by a CPU reset */
112+ struct {} end_reset_fields;
113+
114+ /* The features that we should emulate. See sh_features above. */
115+ uint32_t features;
116+ uint32_t flags; /* general execution flags */
117+ int req_irq;
118+ int req_ipl;
119+ qemu_irq ack;
120+
121+ int in_sleep; /* SR_BL ignored during sleep */
122+} CPUSHState;
123+
124+
125+
126+/**
127+ * SuperHCPU:
128+ * @env: #CPUSHState
129+ *
130+ * A SuperH CPU.
131+ */
132+struct SuperHCPU {
133+ /*< private >*/
134+ CPUState parent_obj;
135+ /*< public >*/
136+
137+ CPUNegativeOffsetState neg;
138+ CPUSHState env;
139+};
140+
141+
142+void superh_cpu_do_interrupt(CPUState *cpu);
143+bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
144+void superh_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
145+hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
146+int superh_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
147+int superh_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
148+void superh_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
149+ MMUAccessType access_type,
150+ int mmu_idx, uintptr_t retaddr);
151+
152+void sh_translate_init(void);
153+int cpu_sh4_signal_handler(int host_signum, void *pinfo,
154+ void *puc);
155+bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
156+ MMUAccessType access_type, int mmu_idx,
157+ bool probe, uintptr_t retaddr);
158+
159+void sh_cpu_list(void);
160+#if !defined(CONFIG_USER_ONLY)
161+void cpu_sh4_invalidate_tlb(CPUSHState *s);
162+uint32_t cpu_sh4_read_mmaped_itlb_addr(CPUSHState *s,
163+ hwaddr addr);
164+void cpu_sh4_write_mmaped_itlb_addr(CPUSHState *s, hwaddr addr,
165+ uint32_t mem_value);
166+uint32_t cpu_sh4_read_mmaped_itlb_data(CPUSHState *s,
167+ hwaddr addr);
168+void cpu_sh4_write_mmaped_itlb_data(CPUSHState *s, hwaddr addr,
169+ uint32_t mem_value);
170+uint32_t cpu_sh4_read_mmaped_utlb_addr(CPUSHState *s,
171+ hwaddr addr);
172+void cpu_sh4_write_mmaped_utlb_addr(CPUSHState *s, hwaddr addr,
173+ uint32_t mem_value);
174+uint32_t cpu_sh4_read_mmaped_utlb_data(CPUSHState *s,
175+ hwaddr addr);
176+void cpu_sh4_write_mmaped_utlb_data(CPUSHState *s, hwaddr addr,
177+ uint32_t mem_value);
178+#endif
179+
180+int cpu_sh4_is_cached(CPUSHState * env, target_ulong addr);
181+
182+void cpu_load_tlb(CPUSHState * env);
183+
184+#define SUPERH_CPU_TYPE_SUFFIX "-" TYPE_SUPERH_CPU
185+#define SUPERH_CPU_TYPE_NAME(model) model SUPERH_CPU_TYPE_SUFFIX
186+#define CPU_RESOLVING_TYPE TYPE_SUPERH_CPU
187+
188+#define cpu_signal_handler cpu_sh_signal_handler
189+#define cpu_list sh_cpu_list
190+
191+/* MMU modes definitions */
192+#define MMU_MODE0_SUFFIX _kernel
193+#define MMU_MODE1_SUFFIX _user
194+#define MMU_USER_IDX 1
195+static inline int cpu_mmu_index (CPUSHState *env, bool ifetch)
196+{
197+ /* The instruction in a RTE delay slot is fetched in privileged
198+ mode, but executed in user mode. */
199+ if (ifetch && (env->flags & DELAY_SLOT_RTE)) {
200+ return 0;
201+ } else {
202+ if ((env->features & FEATURE_ISA) > 2) {
203+ return (FIELD_EX32(env->sr, SR, MD )) == 0 ? 1 : 0;
204+ } else {
205+ return 0;
206+ }
207+ }
208+}
209+
210+typedef struct SuperHCPU SuperHCPU;
211+typedef SuperHCPU ArchCPU;
212+
213+#include "exec/cpu-all.h"
214+
215+/* Memory access type */
216+enum {
217+ /* Privilege */
218+ ACCESS_PRIV = 0x01,
219+ /* Direction */
220+ ACCESS_WRITE = 0x02,
221+ /* Type of instruction */
222+ ACCESS_CODE = 0x10,
223+ ACCESS_INT = 0x20
224+};
225+
226+/* MMU control register */
227+#define MMUCR 0x1F000010
228+#define MMUCR_AT (1<<0)
229+#define MMUCR_TI (1<<2)
230+#define MMUCR_SV (1<<8)
231+#define MMUCR_URC_BITS (6)
232+#define MMUCR_URC_OFFSET (10)
233+#define MMUCR_URC_SIZE (1 << MMUCR_URC_BITS)
234+#define MMUCR_URC_MASK (((MMUCR_URC_SIZE) - 1) << MMUCR_URC_OFFSET)
235+static inline int cpu_mmucr_urc (uint32_t mmucr)
236+{
237+ return ((mmucr & MMUCR_URC_MASK) >> MMUCR_URC_OFFSET);
238+}
239+
240+/* PTEH : Page Translation Entry High register */
241+#define PTEH_ASID_BITS (8)
242+#define PTEH_ASID_SIZE (1 << PTEH_ASID_BITS)
243+#define PTEH_ASID_MASK (PTEH_ASID_SIZE - 1)
244+#define cpu_pteh_asid(pteh) ((pteh) & PTEH_ASID_MASK)
245+#define PTEH_VPN_BITS (22)
246+#define PTEH_VPN_OFFSET (10)
247+#define PTEH_VPN_SIZE (1 << PTEH_VPN_BITS)
248+#define PTEH_VPN_MASK (((PTEH_VPN_SIZE) - 1) << PTEH_VPN_OFFSET)
249+static inline int cpu_pteh_vpn (uint32_t pteh)
250+{
251+ return ((pteh & PTEH_VPN_MASK) >> PTEH_VPN_OFFSET);
252+}
253+
254+/* PTEL : Page Translation Entry Low register */
255+#define PTEL_V (1 << 8)
256+#define cpu_ptel_v(ptel) (((ptel) & PTEL_V) >> 8)
257+#define PTEL_C (1 << 3)
258+#define cpu_ptel_c(ptel) (((ptel) & PTEL_C) >> 3)
259+#define PTEL_D (1 << 2)
260+#define cpu_ptel_d(ptel) (((ptel) & PTEL_D) >> 2)
261+#define PTEL_SH (1 << 1)
262+#define cpu_ptel_sh(ptel)(((ptel) & PTEL_SH) >> 1)
263+#define PTEL_WT (1 << 0)
264+#define cpu_ptel_wt(ptel) ((ptel) & PTEL_WT)
265+
266+#define PTEL_SZ_HIGH_OFFSET (7)
267+#define PTEL_SZ_HIGH (1 << PTEL_SZ_HIGH_OFFSET)
268+#define PTEL_SZ_LOW_OFFSET (4)
269+#define PTEL_SZ_LOW (1 << PTEL_SZ_LOW_OFFSET)
270+static inline int cpu_ptel_sz (uint32_t ptel)
271+{
272+ int sz;
273+ sz = (ptel & PTEL_SZ_HIGH) >> PTEL_SZ_HIGH_OFFSET;
274+ sz <<= 1;
275+ sz |= (ptel & PTEL_SZ_LOW) >> PTEL_SZ_LOW_OFFSET;
276+ return sz;
277+}
278+
279+#define PTEL_PPN_BITS (19)
280+#define PTEL_PPN_OFFSET (10)
281+#define PTEL_PPN_SIZE (1 << PTEL_PPN_BITS)
282+#define PTEL_PPN_MASK (((PTEL_PPN_SIZE) - 1) << PTEL_PPN_OFFSET)
283+static inline int cpu_ptel_ppn (uint32_t ptel)
284+{
285+ return ((ptel & PTEL_PPN_MASK) >> PTEL_PPN_OFFSET);
286+}
287+
288+#define PTEL_PR_BITS (2)
289+#define PTEL_PR_OFFSET (5)
290+#define PTEL_PR_SIZE (1 << PTEL_PR_BITS)
291+#define PTEL_PR_MASK (((PTEL_PR_SIZE) - 1) << PTEL_PR_OFFSET)
292+static inline int cpu_ptel_pr (uint32_t ptel)
293+{
294+ return ((ptel & PTEL_PR_MASK) >> PTEL_PR_OFFSET);
295+}
296+
297+/* PTEA : Page Translation Entry Assistance register */
298+#define PTEA_SA_BITS (3)
299+#define PTEA_SA_SIZE (1 << PTEA_SA_BITS)
300+#define PTEA_SA_MASK (PTEA_SA_SIZE - 1)
301+#define cpu_ptea_sa(ptea) ((ptea) & PTEA_SA_MASK)
302+#define PTEA_TC (1 << 3)
303+#define cpu_ptea_tc(ptea) (((ptea) & PTEA_TC) >> 3)
304+
305+static inline target_ulong cpu_read_sr(CPUSHState *env)
306+{
307+ uint32_t sr = env->sr;
308+ sr = FIELD_DP32(sr, SR, M, env->sr_m);
309+ sr = FIELD_DP32(sr, SR, Q, env->sr_q);
310+ sr = FIELD_DP32(sr, SR, T, env->sr_t);
311+ return sr;
312+}
313+
314+static inline void cpu_write_sr(CPUSHState *env, target_ulong sr)
315+{
316+ env->sr = FIELD_DP32(env->sr, SR, MD, FIELD_EX32(sr, SR, MD));
317+ env->sr = FIELD_DP32(env->sr, SR, BL, FIELD_EX32(sr, SR, BL));
318+ env->sr = FIELD_DP32(env->sr, SR, RB, FIELD_EX32(sr, SR, RB));
319+ env->sr = FIELD_DP32(env->sr, SR, FD, FIELD_EX32(sr, SR, FD));
320+ env->sr = FIELD_DP32(env->sr, SR, I, FIELD_EX32(sr, SR, I));
321+ env->sr = FIELD_DP32(env->sr, SR, S, FIELD_EX32(sr, SR, S));
322+ env->sr_m = FIELD_EX32(sr, SR, M);
323+ env->sr_q = FIELD_EX32(sr, SR, Q);
324+ env->sr_t = FIELD_EX32(sr, SR, T);
325+}
326+
327+static inline void cpu_get_tb_cpu_state(CPUSHState *env, target_ulong *pc,
328+ target_ulong *cs_base, uint32_t *flags)
329+{
330+ *pc = env->pc;
331+ *flags = env->flags; /* TB_FLAG_ENVFLAGS_MASK: bits 0-2, 4-12 */
332+ *flags = FIELD_DP32(*flags, SR, MD, FIELD_EX32(env->sr, SR, MD));
333+ *flags = FIELD_DP32(*flags, SR, RB, FIELD_EX32(env->sr, SR, RB));
334+ *flags = FIELD_DP32(*flags, SR, FD, FIELD_EX32(env->sr, SR, FD));
335+
336+}
337+
338+#endif /* CPU_H */
--- /dev/null
+++ b/target/sh/gdbstub.c
@@ -0,0 +1,154 @@
1+/*
2+ * SuperH gdb server stub
3+ *
4+ * Copyright (c) 2003-2005 Fabrice Bellard
5+ * Copyright (c) 2013 SUSE LINUX Products GmbH
6+ *
7+ * This library is free software; you can redistribute it and/or
8+ * modify it under the terms of the GNU Lesser General Public
9+ * License as published by the Free Software Foundation; either
10+ * version 2.1 of the License, or (at your option) any later version.
11+ *
12+ * This library is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+ * Lesser General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU Lesser General Public
18+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19+ */
20+#include "qemu/osdep.h"
21+#include "cpu.h"
22+#include "exec/gdbstub.h"
23+
24+/* Hint: Use "set architecture sh4" in GDB to see fpu registers */
25+/* FIXME: We should use XML for this. */
26+
27+static inline int regbank(CPUSHState *env)
28+{
29+ if ((env->features & FEATURE_ISA) >= 3) {
30+ return FIELD_EX32(env->sr, SR, MD) && FIELD_EX32(env->sr, SR, RB) ?
31+ 16 : 0;
32+ } else {
33+ return 0;
34+ }
35+}
36+
37+int superh_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
38+{
39+ SuperHCPU *cpu = SUPERH_CPU(cs);
40+ CPUSHState *env = &cpu->env;
41+
42+ switch (n) {
43+ case 0 ... 7:
44+ return gdb_get_regl(mem_buf, env->regs[n + regbank(env)]);
45+ case 8 ... 15:
46+ return gdb_get_regl(mem_buf, env->regs[n]);
47+ case 16:
48+ return gdb_get_regl(mem_buf, env->pc);
49+ case 17:
50+ return gdb_get_regl(mem_buf, env->pr);
51+ case 18:
52+ return gdb_get_regl(mem_buf, env->gbr);
53+ case 19:
54+ return gdb_get_regl(mem_buf, env->vbr);
55+ case 20:
56+ return gdb_get_regl(mem_buf, env->mac >> 32);
57+ case 21:
58+ return gdb_get_regl(mem_buf, env->mac & 0xffffffff);
59+ case 22:
60+ return gdb_get_regl(mem_buf, cpu_read_sr(env));
61+#if 0
62+ case 23:
63+ return gdb_get_regl(mem_buf, env->fpul);
64+ case 24:
65+ return gdb_get_regl(mem_buf, env->fpscr);
66+ case 25 ... 40:
67+ if (env->fpscr & FPSCR_FR) {
68+ stfl_p(mem_buf, env->fregs[n - 9]);
69+ } else {
70+ stfl_p(mem_buf, env->fregs[n - 25]);
71+ }
72+ return 4;
73+#endif
74+ case 41:
75+ return gdb_get_regl(mem_buf, env->ssr);
76+ case 42:
77+ return gdb_get_regl(mem_buf, env->spc);
78+ case 43 ... 50:
79+ return gdb_get_regl(mem_buf, env->regs[n - 43]);
80+ case 51 ... 58:
81+ return gdb_get_regl(mem_buf, env->regs[n - (51 - 16)]);
82+ }
83+
84+ return 0;
85+}
86+
87+int superh_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
88+{
89+ SuperHCPU *cpu = SUPERH_CPU(cs);
90+ CPUSHState *env = &cpu->env;
91+
92+ switch (n) {
93+ case 0 ... 7:
94+ env->regs[n + regbank(env)] = ldl_p(mem_buf);
95+ break;
96+ case 8 ... 15:
97+ env->regs[n] = ldl_p(mem_buf);
98+ break;
99+ case 16:
100+ env->pc = ldl_p(mem_buf);
101+ break;
102+ case 17:
103+ env->pr = ldl_p(mem_buf);
104+ break;
105+ case 18:
106+ env->gbr = ldl_p(mem_buf);
107+ break;
108+ case 19:
109+ env->vbr = ldl_p(mem_buf);
110+ break;
111+ case 20:
112+ env->mac &= 0xffffffff;
113+ env->mac |= (uint64_t)ldl_p(mem_buf) << 32;
114+ break;
115+ case 21:
116+ env->mac &= 0xffffffff00000000;
117+ env->mac |= ldl_p(mem_buf);
118+ break;
119+ case 22:
120+ cpu_write_sr(env, ldl_p(mem_buf));
121+ break;
122+#if 0
123+ case 23:
124+ env->fpul = ldl_p(mem_buf);
125+ break;
126+ case 24:
127+ env->fpscr = ldl_p(mem_buf);
128+ break;
129+ case 25 ... 40:
130+ if (env->fpscr & FPSCR_FR) {
131+ env->fregs[n - 9] = ldfl_p(mem_buf);
132+ } else {
133+ env->fregs[n - 25] = ldfl_p(mem_buf);
134+ }
135+ break;
136+#endif
137+ case 41:
138+ env->ssr = ldl_p(mem_buf);
139+ break;
140+ case 42:
141+ env->spc = ldl_p(mem_buf);
142+ break;
143+ case 43 ... 50:
144+ env->regs[n - 43] = ldl_p(mem_buf);
145+ break;
146+ case 51 ... 58:
147+ env->regs[n - (51 - 16)] = ldl_p(mem_buf);
148+ break;
149+ default:
150+ return 0;
151+ }
152+
153+ return 4;
154+}
--- /dev/null
+++ b/target/sh/helper.c
@@ -0,0 +1,1006 @@
1+/*
2+ * SH emulation
3+ *
4+ * Copyright (c) 2005 Samuel Tardieu
5+ * Copyright (c) 2019 Yoshinori Sato
6+ *
7+ * This library is free software; you can redistribute it and/or
8+ * modify it under the terms of the GNU Lesser General Public
9+ * License as published by the Free Software Foundation; either
10+ * version 2.1 of the License, or (at your option) any later version.
11+ *
12+ * This library is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+ * Lesser General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU Lesser General Public
18+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19+ */
20+#include "qemu/osdep.h"
21+
22+#include "cpu.h"
23+#include "exec/exec-all.h"
24+#include "exec/log.h"
25+#include "exec/cpu_ldst.h"
26+#include "sysemu/sysemu.h"
27+
28+#define MMU_OK 0
29+#define MMU_ITLB_MISS (-1)
30+#define MMU_ITLB_MULTIPLE (-2)
31+#define MMU_ITLB_VIOLATION (-3)
32+#define MMU_DTLB_MISS_READ (-4)
33+#define MMU_DTLB_MISS_WRITE (-5)
34+#define MMU_DTLB_INITIAL_WRITE (-6)
35+#define MMU_DTLB_VIOLATION_READ (-7)
36+#define MMU_DTLB_VIOLATION_WRITE (-8)
37+#define MMU_DTLB_MULTIPLE (-9)
38+#define MMU_DTLB_MISS (-10)
39+#define MMU_IADDR_ERROR (-11)
40+#define MMU_DADDR_ERROR_READ (-12)
41+#define MMU_DADDR_ERROR_WRITE (-13)
42+
43+#if defined(CONFIG_USER_ONLY)
44+
45+void superh_cpu_do_interrupt(CPUState *cs)
46+{
47+ cs->exception_index = -1;
48+}
49+
50+int cpu_sh4_is_cached(CPUSHState *env, target_ulong addr)
51+{
52+ /* For user mode, only U0 area is cacheable. */
53+ return !(addr & 0x80000000);
54+}
55+
56+#else /* !CONFIG_USER_ONLY */
57+
58+static void superh_cpu_do_interrupt_evt(CPUState *cs)
59+{
60+ SuperHCPU *cpu = SUPERH_CPU(cs);
61+ CPUSHState *env = &cpu->env;
62+ int do_irq = cs->interrupt_request & CPU_INTERRUPT_HARD;
63+ int do_exp, irq_vector = cs->exception_index;
64+
65+ /* prioritize exceptions over interrupts */
66+
67+ do_exp = cs->exception_index != -1;
68+ do_irq = do_irq && (cs->exception_index == -1);
69+
70+ if (FIELD_EX32(env->sr, SR, BL)) {
71+ if (do_exp && cs->exception_index != 0x1e0) {
72+ /* In theory a masked exception generates a reset exception,
73+ which in turn jumps to the reset vector. However this only
74+ works when using a bootloader. When using a kernel and an
75+ initrd, they need to be reloaded and the program counter
76+ should be loaded with the kernel entry point.
77+ qemu_system_reset_request takes care of that. */
78+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
79+ return;
80+ }
81+ if (do_irq && !env->in_sleep) {
82+ return; /* masked */
83+ }
84+ }
85+ env->in_sleep = 0;
86+
87+ if (do_irq) {
88+ if (env->req_ipl >= FIELD_EX32(env->sr, SR, I)) {
89+ irq_vector = env->req_irq;
90+ qemu_set_irq(env->ack, irq_vector);
91+ } else {
92+ return;
93+ }
94+ }
95+
96+ if (qemu_loglevel_mask(CPU_LOG_INT)) {
97+ const char *expname;
98+ switch (cs->exception_index) {
99+ case 0x0e0:
100+ expname = "addr_error";
101+ break;
102+ case 0x040:
103+ expname = "tlb_miss";
104+ break;
105+ case 0x0a0:
106+ expname = "tlb_violation";
107+ break;
108+ case 0x180:
109+ expname = "illegal_instruction";
110+ break;
111+ case 0x1a0:
112+ expname = "slot_illegal_instruction";
113+ break;
114+ case 0x800:
115+ expname = "fpu_disable";
116+ break;
117+ case 0x820:
118+ expname = "slot_fpu";
119+ break;
120+ case 0x100:
121+ expname = "data_write";
122+ break;
123+ case 0x060:
124+ expname = "dtlb_miss_write";
125+ break;
126+ case 0x0c0:
127+ expname = "dtlb_violation_write";
128+ break;
129+ case 0x120:
130+ expname = "fpu_exception";
131+ break;
132+ case 0x080:
133+ expname = "initial_page_write";
134+ break;
135+ case 0x160:
136+ expname = "trapa";
137+ break;
138+ default:
139+ expname = do_irq ? "interrupt" : "???";
140+ break;
141+ }
142+ qemu_log("exception 0x%03x [%s] raised\n",
143+ irq_vector, expname);
144+ log_cpu_state(cs, 0);
145+ }
146+
147+ env->ssr = cpu_read_sr(env);
148+ env->spc = env->pc;
149+ env->sgr = env->regs[15];
150+ env->sr = FIELD_DP32(env->sr, SR, BL, 1);
151+ env->sr = FIELD_DP32(env->sr, SR, MD, 1);
152+ env->sr = FIELD_DP32(env->sr, SR, RB, 1);
153+
154+ if (env->flags & DELAY_SLOT_MASK) {
155+ /* Branch instruction should be executed again before delay slot. */
156+ env->spc -= 2;
157+ /* Clear flags for exception/interrupt routine. */
158+ env->flags &= ~DELAY_SLOT_MASK;
159+ }
160+
161+ if (do_exp) {
162+ env->expevt = cs->exception_index;
163+ switch (cs->exception_index) {
164+ case 0x000:
165+ case 0x020:
166+ case 0x140:
167+ env->sr = FIELD_DP32(env->sr, SR, FD, 0);
168+ env->sr = FIELD_DP32(env->sr, SR, I, 0x0f);
169+ env->pc = 0xa0000000;
170+ break;
171+ case 0x040:
172+ case 0x060:
173+ env->pc = env->vbr + 0x400;
174+ break;
175+ case 0x160:
176+ env->spc += 2; /* special case for TRAPA */
177+ /* fall through */
178+ default:
179+ env->pc = env->vbr + 0x100;
180+ break;
181+ }
182+ return;
183+ }
184+
185+ if (do_irq) {
186+ env->intevt = irq_vector;
187+ env->pc = env->vbr + 0x600;
188+ return;
189+ }
190+}
191+
192+static void superh_cpu_do_interrupt_vec(CPUState *cs)
193+{
194+ SuperHCPU *cpu = SUPERH_CPU(cs);
195+ CPUSHState *env = &cpu->env;
196+ int do_irq = cs->interrupt_request & CPU_INTERRUPT_HARD;
197+ int do_exp, irq_vector = cs->exception_index;
198+ uint32_t sr;
199+
200+ /* prioritize exceptions over interrupts */
201+
202+ do_exp = cs->exception_index != -1;
203+ do_irq = do_irq && (cs->exception_index == -1);
204+
205+ env->in_sleep = 0;
206+
207+ if (do_irq) {
208+ if (env->req_ipl >= FIELD_EX32(env->sr, SR, I)) {
209+ irq_vector = env->req_irq;
210+ qemu_set_irq(env->ack, irq_vector);
211+ } else {
212+ return;
213+ }
214+ }
215+
216+ if (qemu_loglevel_mask(CPU_LOG_INT)) {
217+ const char *expname;
218+ switch (cs->exception_index) {
219+ case 0x0e0:
220+ expname = "addr_error";
221+ break;
222+ case 0x180:
223+ expname = "illegal_instruction";
224+ break;
225+ case 0x1a0:
226+ expname = "slot_illegal_instruction";
227+ break;
228+ case 0x160:
229+ expname = "trapa";
230+ irq_vector = env->tra >> 2;
231+ break;
232+ default:
233+ expname = do_irq ? "interrupt" : "???";
234+ break;
235+ }
236+ qemu_log("exception 0x%03x [%s] raised\n",
237+ irq_vector, expname);
238+ log_cpu_state(cs, 0);
239+ }
240+
241+ if (env->flags & DELAY_SLOT_MASK) {
242+ /* Branch instruction should be executed again before delay slot. */
243+ env->pc -= 2;
244+ /* Clear flags for exception/interrupt routine. */
245+ env->flags &= ~DELAY_SLOT_MASK;
246+ }
247+
248+ sr = cpu_read_sr(env);
249+ cpu_stl_kernel(env, env->regs[15], sr);
250+ env->regs[15] -= 4;
251+ cpu_stl_kernel(env, env->regs[15], env->pc);
252+ env->regs[15] -= 4;
253+ if (do_irq) {
254+ env->sr = FIELD_DP32(env->sr, SR, I, env->req_ipl);
255+ }
256+ if (do_exp) {
257+ switch (cs->exception_index) {
258+ case 0x0e0:
259+ irq_vector = 9;
260+ break;
261+ case 0x180:
262+ irq_vector = 4;
263+ break;
264+ case 0x1a0:
265+ irq_vector = 6;
266+ break;
267+ }
268+ }
269+ env->pc = cpu_ldl_kernel(env, env->vbr + irq_vector * 4);
270+}
271+
272+void superh_cpu_do_interrupt(CPUState *cs)
273+{
274+ SuperHCPU *cpu = SUPERH_CPU(cs);
275+ CPUSHState *env = &cpu->env;
276+
277+ if ((env->features & FEATURE_ISA) < 3) {
278+ superh_cpu_do_interrupt_vec(cs);
279+ } else {
280+ superh_cpu_do_interrupt_evt(cs);
281+ }
282+}
283+
284+static void update_itlb_use(CPUSHState * env, int itlbnb)
285+{
286+ uint8_t or_mask = 0, and_mask = (uint8_t) - 1;
287+
288+ switch (itlbnb) {
289+ case 0:
290+ and_mask = 0x1f;
291+ break;
292+ case 1:
293+ and_mask = 0xe7;
294+ or_mask = 0x80;
295+ break;
296+ case 2:
297+ and_mask = 0xfb;
298+ or_mask = 0x50;
299+ break;
300+ case 3:
301+ or_mask = 0x2c;
302+ break;
303+ }
304+
305+ env->mmucr &= (and_mask << 24) | 0x00ffffff;
306+ env->mmucr |= (or_mask << 24);
307+}
308+
309+static int itlb_replacement(CPUSHState * env)
310+{
311+ if ((env->mmucr & 0xe0000000) == 0xe0000000) {
312+ return 0;
313+ }
314+ if ((env->mmucr & 0x98000000) == 0x18000000) {
315+ return 1;
316+ }
317+ if ((env->mmucr & 0x54000000) == 0x04000000) {
318+ return 2;
319+ }
320+ if ((env->mmucr & 0x2c000000) == 0x00000000) {
321+ return 3;
322+ }
323+ cpu_abort(env_cpu(env), "Unhandled itlb_replacement");
324+}
325+
326+/* Find the corresponding entry in the right TLB
327+ Return entry, MMU_DTLB_MISS or MMU_DTLB_MULTIPLE
328+*/
329+static int find_tlb_entry(CPUSHState * env, target_ulong address,
330+ tlb_t * entries, uint8_t nbtlb, int use_asid)
331+{
332+ int match = MMU_DTLB_MISS;
333+ uint32_t start, end;
334+ uint8_t asid;
335+ int i;
336+
337+ asid = env->pteh & 0xff;
338+
339+ for (i = 0; i < nbtlb; i++) {
340+ if (!entries[i].v)
341+ continue; /* Invalid entry */
342+ if (!entries[i].sh && use_asid && entries[i].asid != asid)
343+ continue; /* Bad ASID */
344+ start = (entries[i].vpn << 10) & ~(entries[i].size - 1);
345+ end = start + entries[i].size - 1;
346+ if (address >= start && address <= end) { /* Match */
347+ if (match != MMU_DTLB_MISS)
348+ return MMU_DTLB_MULTIPLE; /* Multiple match */
349+ match = i;
350+ }
351+ }
352+ return match;
353+}
354+
355+static void increment_urc(CPUSHState * env)
356+{
357+ uint8_t urb, urc;
358+
359+ /* Increment URC */
360+ urb = ((env->mmucr) >> 18) & 0x3f;
361+ urc = ((env->mmucr) >> 10) & 0x3f;
362+ urc++;
363+ if ((urb > 0 && urc > urb) || urc > (UTLB_SIZE - 1))
364+ urc = 0;
365+ env->mmucr = (env->mmucr & 0xffff03ff) | (urc << 10);
366+}
367+
368+/* Copy and utlb entry into itlb
369+ Return entry
370+*/
371+static int copy_utlb_entry_itlb(CPUSHState *env, int utlb)
372+{
373+ int itlb;
374+
375+ tlb_t * ientry;
376+ itlb = itlb_replacement(env);
377+ ientry = &env->itlb[itlb];
378+ if (ientry->v) {
379+ tlb_flush_page(env_cpu(env), ientry->vpn << 10);
380+ }
381+ *ientry = env->utlb[utlb];
382+ update_itlb_use(env, itlb);
383+ return itlb;
384+}
385+
386+/* Find itlb entry
387+ Return entry, MMU_ITLB_MISS, MMU_ITLB_MULTIPLE or MMU_DTLB_MULTIPLE
388+*/
389+static int find_itlb_entry(CPUSHState * env, target_ulong address,
390+ int use_asid)
391+{
392+ int e;
393+
394+ e = find_tlb_entry(env, address, env->itlb, ITLB_SIZE, use_asid);
395+ if (e == MMU_DTLB_MULTIPLE) {
396+ e = MMU_ITLB_MULTIPLE;
397+ } else if (e == MMU_DTLB_MISS) {
398+ e = MMU_ITLB_MISS;
399+ } else if (e >= 0) {
400+ update_itlb_use(env, e);
401+ }
402+ return e;
403+}
404+
405+/* Find utlb entry
406+ Return entry, MMU_DTLB_MISS, MMU_DTLB_MULTIPLE */
407+static int find_utlb_entry(CPUSHState * env, target_ulong address, int use_asid)
408+{
409+ /* per utlb access */
410+ increment_urc(env);
411+
412+ /* Return entry */
413+ return find_tlb_entry(env, address, env->utlb, UTLB_SIZE, use_asid);
414+}
415+
416+/* Match address against MMU
417+ Return MMU_OK, MMU_DTLB_MISS_READ, MMU_DTLB_MISS_WRITE,
418+ MMU_DTLB_INITIAL_WRITE, MMU_DTLB_VIOLATION_READ,
419+ MMU_DTLB_VIOLATION_WRITE, MMU_ITLB_MISS,
420+ MMU_ITLB_MULTIPLE, MMU_ITLB_VIOLATION,
421+ MMU_IADDR_ERROR, MMU_DADDR_ERROR_READ, MMU_DADDR_ERROR_WRITE.
422+*/
423+static int get_mmu_address(CPUSHState * env, target_ulong * physical,
424+ int *prot, target_ulong address,
425+ int rw, int access_type)
426+{
427+ int use_asid, n;
428+ tlb_t *matching = NULL;
429+
430+ use_asid = !(env->mmucr & MMUCR_SV) || !FIELD_EX32(env->sr, SR, MD);
431+
432+ if (rw == 2) {
433+ n = find_itlb_entry(env, address, use_asid);
434+ if (n >= 0) {
435+ matching = &env->itlb[n];
436+ if (!FIELD_EX32(env->sr, SR, MD) && !(matching->pr & 2)) {
437+ n = MMU_ITLB_VIOLATION;
438+ } else {
439+ *prot = PAGE_EXEC;
440+ }
441+ } else {
442+ n = find_utlb_entry(env, address, use_asid);
443+ if (n >= 0) {
444+ n = copy_utlb_entry_itlb(env, n);
445+ matching = &env->itlb[n];
446+ if (!FIELD_EX32(env->sr, SR, MD) && !(matching->pr & 2)) {
447+ n = MMU_ITLB_VIOLATION;
448+ } else {
449+ *prot = PAGE_READ | PAGE_EXEC;
450+ if ((matching->pr & 1) && matching->d) {
451+ *prot |= PAGE_WRITE;
452+ }
453+ }
454+ } else if (n == MMU_DTLB_MULTIPLE) {
455+ n = MMU_ITLB_MULTIPLE;
456+ } else if (n == MMU_DTLB_MISS) {
457+ n = MMU_ITLB_MISS;
458+ }
459+ }
460+ } else {
461+ n = find_utlb_entry(env, address, use_asid);
462+ if (n >= 0) {
463+ matching = &env->utlb[n];
464+ if (!FIELD_EX32(env->sr, SR, MD) && !(matching->pr & 2)) {
465+ n = (rw == 1) ? MMU_DTLB_VIOLATION_WRITE :
466+ MMU_DTLB_VIOLATION_READ;
467+ } else if ((rw == 1) && !(matching->pr & 1)) {
468+ n = MMU_DTLB_VIOLATION_WRITE;
469+ } else if ((rw == 1) && !matching->d) {
470+ n = MMU_DTLB_INITIAL_WRITE;
471+ } else {
472+ *prot = PAGE_READ;
473+ if ((matching->pr & 1) && matching->d) {
474+ *prot |= PAGE_WRITE;
475+ }
476+ }
477+ } else if (n == MMU_DTLB_MISS) {
478+ n = (rw == 1) ? MMU_DTLB_MISS_WRITE :
479+ MMU_DTLB_MISS_READ;
480+ }
481+ }
482+ if (n >= 0) {
483+ n = MMU_OK;
484+ *physical = ((matching->ppn << 10) & ~(matching->size - 1)) |
485+ (address & (matching->size - 1));
486+ }
487+ return n;
488+}
489+
490+static int get_physical_address_sh4(CPUSHState * env, target_ulong * physical,
491+ int *prot, target_ulong address,
492+ int rw, int access_type)
493+{
494+ /* P1, P2 and P4 areas do not use translation */
495+ if ((address >= 0x80000000 && address < 0xc0000000) ||
496+ address >= 0xe0000000) {
497+ if (!FIELD_EX32(env->sr, SR, MD)
498+ && (address < 0xe0000000 || address >= 0xe4000000)) {
499+ /* Unauthorized access in user mode (only store queues are available) */
500+ qemu_log_mask(LOG_GUEST_ERROR, "Unauthorized access\n");
501+ if (rw == 0)
502+ return MMU_DADDR_ERROR_READ;
503+ else if (rw == 1)
504+ return MMU_DADDR_ERROR_WRITE;
505+ else
506+ return MMU_IADDR_ERROR;
507+ }
508+ if (address >= 0x80000000 && address < 0xc0000000) {
509+ /* Mask upper 3 bits for P1 and P2 areas */
510+ *physical = address & 0x1fffffff;
511+ } else {
512+ *physical = address;
513+ }
514+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
515+ return MMU_OK;
516+ }
517+
518+ /* If MMU is disabled, return the corresponding physical page */
519+ if (!(env->mmucr & MMUCR_AT)) {
520+ *physical = address & 0x1FFFFFFF;
521+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
522+ return MMU_OK;
523+ }
524+
525+ /* We need to resort to the MMU */
526+ return get_mmu_address(env, physical, prot, address, rw, access_type);
527+}
528+
529+static int get_physical_address_sh2(CPUSHState * env, target_ulong * physical,
530+ int *prot, target_ulong address)
531+{
532+ /* P1, P2 and P4 areas do not use translation */
533+ if ((address >= 0x80000000 && address < 0xc0000000) ||
534+ address >= 0xe0000000) {
535+ if (address >= 0x80000000 && address < 0xc0000000) {
536+ /* Mask upper 3 bits for P1 and P2 areas */
537+ *physical = address & 0x1fffffff;
538+ } else {
539+ *physical = address;
540+ }
541+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
542+ return MMU_OK;
543+ }
544+
545+ if (address < 0x80000000) {
546+ /* P0 */
547+ *physical = address & 0x7FFFFFFF;
548+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
549+ } else {
550+ /* P3 */
551+ *physical = address & 0x1FFFFFFF;
552+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
553+ }
554+ return MMU_OK;
555+}
556+
557+hwaddr superh_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
558+{
559+ SuperHCPU *cpu = SUPERH_CPU(cs);
560+ CPUSHState *env = &cpu->env;
561+ target_ulong physical;
562+ int prot;
563+
564+ switch(env->features & FEATURE_ISA) {
565+ case 2:
566+ get_physical_address_sh2(env, &physical, &prot, addr);
567+ break;
568+ case 4:
569+ get_physical_address_sh4(env, &physical, &prot, addr, 0, 0);
570+ break;
571+ }
572+ return physical;
573+}
574+
575+void cpu_load_tlb(CPUSHState * env)
576+{
577+ CPUState *cs = env_cpu(env);
578+ int n = cpu_mmucr_urc(env->mmucr);
579+ tlb_t * entry = &env->utlb[n];
580+
581+ if (entry->v) {
582+ /* Overwriting valid entry in utlb. */
583+ target_ulong address = entry->vpn << 10;
584+ tlb_flush_page(cs, address);
585+ }
586+
587+ /* Take values into cpu status from registers. */
588+ entry->asid = (uint8_t)cpu_pteh_asid(env->pteh);
589+ entry->vpn = cpu_pteh_vpn(env->pteh);
590+ entry->v = (uint8_t)cpu_ptel_v(env->ptel);
591+ entry->ppn = cpu_ptel_ppn(env->ptel);
592+ entry->sz = (uint8_t)cpu_ptel_sz(env->ptel);
593+ switch (entry->sz) {
594+ case 0: /* 00 */
595+ entry->size = 1024; /* 1K */
596+ break;
597+ case 1: /* 01 */
598+ entry->size = 1024 * 4; /* 4K */
599+ break;
600+ case 2: /* 10 */
601+ entry->size = 1024 * 64; /* 64K */
602+ break;
603+ case 3: /* 11 */
604+ entry->size = 1024 * 1024; /* 1M */
605+ break;
606+ default:
607+ cpu_abort(cs, "Unhandled load_tlb");
608+ break;
609+ }
610+ entry->sh = (uint8_t)cpu_ptel_sh(env->ptel);
611+ entry->c = (uint8_t)cpu_ptel_c(env->ptel);
612+ entry->pr = (uint8_t)cpu_ptel_pr(env->ptel);
613+ entry->d = (uint8_t)cpu_ptel_d(env->ptel);
614+ entry->wt = (uint8_t)cpu_ptel_wt(env->ptel);
615+ entry->sa = (uint8_t)cpu_ptea_sa(env->ptea);
616+ entry->tc = (uint8_t)cpu_ptea_tc(env->ptea);
617+}
618+
619+ void cpu_sh4_invalidate_tlb(CPUSHState *s)
620+{
621+ int i;
622+
623+ /* UTLB */
624+ for (i = 0; i < UTLB_SIZE; i++) {
625+ tlb_t * entry = &s->utlb[i];
626+ entry->v = 0;
627+ }
628+ /* ITLB */
629+ for (i = 0; i < ITLB_SIZE; i++) {
630+ tlb_t * entry = &s->itlb[i];
631+ entry->v = 0;
632+ }
633+
634+ tlb_flush(env_cpu(s));
635+}
636+
637+uint32_t cpu_sh4_read_mmaped_itlb_addr(CPUSHState *s,
638+ hwaddr addr)
639+{
640+ int index = (addr & 0x00000300) >> 8;
641+ tlb_t * entry = &s->itlb[index];
642+
643+ return (entry->vpn << 10) |
644+ (entry->v << 8) |
645+ (entry->asid);
646+}
647+
648+void cpu_sh4_write_mmaped_itlb_addr(CPUSHState *s, hwaddr addr,
649+ uint32_t mem_value)
650+{
651+ uint32_t vpn = (mem_value & 0xfffffc00) >> 10;
652+ uint8_t v = (uint8_t)((mem_value & 0x00000100) >> 8);
653+ uint8_t asid = (uint8_t)(mem_value & 0x000000ff);
654+
655+ int index = (addr & 0x00000300) >> 8;
656+ tlb_t * entry = &s->itlb[index];
657+ if (entry->v) {
658+ /* Overwriting valid entry in itlb. */
659+ target_ulong address = entry->vpn << 10;
660+ tlb_flush_page(env_cpu(s), address);
661+ }
662+ entry->asid = asid;
663+ entry->vpn = vpn;
664+ entry->v = v;
665+}
666+
667+uint32_t cpu_sh4_read_mmaped_itlb_data(CPUSHState *s,
668+ hwaddr addr)
669+{
670+ int array = (addr & 0x00800000) >> 23;
671+ int index = (addr & 0x00000300) >> 8;
672+ tlb_t * entry = &s->itlb[index];
673+
674+ if (array == 0) {
675+ /* ITLB Data Array 1 */
676+ return (entry->ppn << 10) |
677+ (entry->v << 8) |
678+ (entry->pr << 5) |
679+ ((entry->sz & 1) << 6) |
680+ ((entry->sz & 2) << 4) |
681+ (entry->c << 3) |
682+ (entry->sh << 1);
683+ } else {
684+ /* ITLB Data Array 2 */
685+ return (entry->tc << 1) |
686+ (entry->sa);
687+ }
688+}
689+
690+void cpu_sh4_write_mmaped_itlb_data(CPUSHState *s, hwaddr addr,
691+ uint32_t mem_value)
692+{
693+ int array = (addr & 0x00800000) >> 23;
694+ int index = (addr & 0x00000300) >> 8;
695+ tlb_t * entry = &s->itlb[index];
696+
697+ if (array == 0) {
698+ /* ITLB Data Array 1 */
699+ if (entry->v) {
700+ /* Overwriting valid entry in utlb. */
701+ target_ulong address = entry->vpn << 10;
702+ tlb_flush_page(env_cpu(s), address);
703+ }
704+ entry->ppn = (mem_value & 0x1ffffc00) >> 10;
705+ entry->v = (mem_value & 0x00000100) >> 8;
706+ entry->sz = (mem_value & 0x00000080) >> 6 |
707+ (mem_value & 0x00000010) >> 4;
708+ entry->pr = (mem_value & 0x00000040) >> 5;
709+ entry->c = (mem_value & 0x00000008) >> 3;
710+ entry->sh = (mem_value & 0x00000002) >> 1;
711+ } else {
712+ /* ITLB Data Array 2 */
713+ entry->tc = (mem_value & 0x00000008) >> 3;
714+ entry->sa = (mem_value & 0x00000007);
715+ }
716+}
717+
718+uint32_t cpu_sh4_read_mmaped_utlb_addr(CPUSHState *s,
719+ hwaddr addr)
720+{
721+ int index = (addr & 0x00003f00) >> 8;
722+ tlb_t * entry = &s->utlb[index];
723+
724+ increment_urc(s); /* per utlb access */
725+
726+ return (entry->vpn << 10) |
727+ (entry->v << 8) |
728+ (entry->asid);
729+}
730+
731+void cpu_sh4_write_mmaped_utlb_addr(CPUSHState *s, hwaddr addr,
732+ uint32_t mem_value)
733+{
734+ int associate = addr & 0x0000080;
735+ uint32_t vpn = (mem_value & 0xfffffc00) >> 10;
736+ uint8_t d = (uint8_t)((mem_value & 0x00000200) >> 9);
737+ uint8_t v = (uint8_t)((mem_value & 0x00000100) >> 8);
738+ uint8_t asid = (uint8_t)(mem_value & 0x000000ff);
739+ int use_asid = !(s->mmucr & MMUCR_SV) || !FIELD_EX32(s->sr, SR, MD);
740+
741+ if (associate) {
742+ int i;
743+ tlb_t * utlb_match_entry = NULL;
744+ int needs_tlb_flush = 0;
745+
746+ /* search UTLB */
747+ for (i = 0; i < UTLB_SIZE; i++) {
748+ tlb_t * entry = &s->utlb[i];
749+ if (!entry->v)
750+ continue;
751+
752+ if (entry->vpn == vpn
753+ && (!use_asid || entry->asid == asid || entry->sh)) {
754+ if (utlb_match_entry) {
755+ CPUState *cs = env_cpu(s);
756+
757+ /* Multiple TLB Exception */
758+ cs->exception_index = 0x140;
759+ s->tea = addr;
760+ break;
761+ }
762+ if (entry->v && !v)
763+ needs_tlb_flush = 1;
764+ entry->v = v;
765+ entry->d = d;
766+ utlb_match_entry = entry;
767+ }
768+ increment_urc(s); /* per utlb access */
769+ }
770+
771+ /* search ITLB */
772+ for (i = 0; i < ITLB_SIZE; i++) {
773+ tlb_t * entry = &s->itlb[i];
774+ if (entry->vpn == vpn
775+ && (!use_asid || entry->asid == asid || entry->sh)) {
776+ if (entry->v && !v)
777+ needs_tlb_flush = 1;
778+ if (utlb_match_entry)
779+ *entry = *utlb_match_entry;
780+ else
781+ entry->v = v;
782+ break;
783+ }
784+ }
785+
786+ if (needs_tlb_flush) {
787+ tlb_flush_page(env_cpu(s), vpn << 10);
788+ }
789+ } else {
790+ int index = (addr & 0x00003f00) >> 8;
791+ tlb_t * entry = &s->utlb[index];
792+ if (entry->v) {
793+ CPUState *cs = env_cpu(s);
794+
795+ /* Overwriting valid entry in utlb. */
796+ target_ulong address = entry->vpn << 10;
797+ tlb_flush_page(cs, address);
798+ }
799+ entry->asid = asid;
800+ entry->vpn = vpn;
801+ entry->d = d;
802+ entry->v = v;
803+ increment_urc(s);
804+ }
805+}
806+
807+uint32_t cpu_sh4_read_mmaped_utlb_data(CPUSHState *s,
808+ hwaddr addr)
809+{
810+ int array = (addr & 0x00800000) >> 23;
811+ int index = (addr & 0x00003f00) >> 8;
812+ tlb_t * entry = &s->utlb[index];
813+
814+ increment_urc(s); /* per utlb access */
815+
816+ if (array == 0) {
817+ /* ITLB Data Array 1 */
818+ return (entry->ppn << 10) |
819+ (entry->v << 8) |
820+ (entry->pr << 5) |
821+ ((entry->sz & 1) << 6) |
822+ ((entry->sz & 2) << 4) |
823+ (entry->c << 3) |
824+ (entry->d << 2) |
825+ (entry->sh << 1) |
826+ (entry->wt);
827+ } else {
828+ /* ITLB Data Array 2 */
829+ return (entry->tc << 1) |
830+ (entry->sa);
831+ }
832+}
833+
834+void cpu_sh4_write_mmaped_utlb_data(CPUSHState *s, hwaddr addr,
835+ uint32_t mem_value)
836+{
837+ int array = (addr & 0x00800000) >> 23;
838+ int index = (addr & 0x00003f00) >> 8;
839+ tlb_t * entry = &s->utlb[index];
840+
841+ increment_urc(s); /* per utlb access */
842+
843+ if (array == 0) {
844+ /* UTLB Data Array 1 */
845+ if (entry->v) {
846+ /* Overwriting valid entry in utlb. */
847+ target_ulong address = entry->vpn << 10;
848+ tlb_flush_page(env_cpu(s), address);
849+ }
850+ entry->ppn = (mem_value & 0x1ffffc00) >> 10;
851+ entry->v = (mem_value & 0x00000100) >> 8;
852+ entry->sz = (mem_value & 0x00000080) >> 6 |
853+ (mem_value & 0x00000010) >> 4;
854+ entry->pr = (mem_value & 0x00000060) >> 5;
855+ entry->c = (mem_value & 0x00000008) >> 3;
856+ entry->d = (mem_value & 0x00000004) >> 2;
857+ entry->sh = (mem_value & 0x00000002) >> 1;
858+ entry->wt = (mem_value & 0x00000001);
859+ } else {
860+ /* UTLB Data Array 2 */
861+ entry->tc = (mem_value & 0x00000008) >> 3;
862+ entry->sa = (mem_value & 0x00000007);
863+ }
864+}
865+
866+int cpu_sh4_is_cached(CPUSHState * env, target_ulong addr)
867+{
868+ int n;
869+ int use_asid = !(env->mmucr & MMUCR_SV) || !FIELD_EX32(env->sr, SR, MD);
870+
871+ /* check area */
872+ if (FIELD_EX32(env->sr, SR, MD)) {
873+ /* For privileged mode, P2 and P4 area is not cacheable. */
874+ if ((0xA0000000 <= addr && addr < 0xC0000000) || 0xE0000000 <= addr)
875+ return 0;
876+ } else {
877+ /* For user mode, only U0 area is cacheable. */
878+ if (0x80000000 <= addr)
879+ return 0;
880+ }
881+
882+ /*
883+ * TODO : Evaluate CCR and check if the cache is on or off.
884+ * Now CCR is not in CPUSHState, but in SH7750State.
885+ * When you move the ccr into CPUSHState, the code will be
886+ * as follows.
887+ */
888+#if 0
889+ /* check if operand cache is enabled or not. */
890+ if (!(env->ccr & 1))
891+ return 0;
892+#endif
893+
894+ /* if MMU is off, no check for TLB. */
895+ if (env->mmucr & MMUCR_AT)
896+ return 1;
897+
898+ /* check TLB */
899+ n = find_tlb_entry(env, addr, env->itlb, ITLB_SIZE, use_asid);
900+ if (n >= 0)
901+ return env->itlb[n].c;
902+
903+ n = find_tlb_entry(env, addr, env->utlb, UTLB_SIZE, use_asid);
904+ if (n >= 0)
905+ return env->utlb[n].c;
906+
907+ return 0;
908+}
909+
910+#endif
911+
912+bool superh_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
913+{
914+ if (interrupt_request & CPU_INTERRUPT_HARD) {
915+ SuperHCPU *cpu = SUPERH_CPU(cs);
916+ CPUSHState *env = &cpu->env;
917+
918+ /* Delay slots are indivisible, ignore interrupts */
919+ if (env->flags & DELAY_SLOT_MASK) {
920+ return false;
921+ } else {
922+ superh_cpu_do_interrupt(cs);
923+ return true;
924+ }
925+ }
926+ return false;
927+}
928+
929+bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
930+ MMUAccessType access_type, int mmu_idx,
931+ bool probe, uintptr_t retaddr)
932+{
933+ SuperHCPU *cpu = SUPERH_CPU(cs);
934+ CPUSHState *env = &cpu->env;
935+ int ret;
936+
937+#ifdef CONFIG_USER_ONLY
938+ ret = (access_type == MMU_DATA_STORE ? MMU_DTLB_VIOLATION_WRITE :
939+ access_type == MMU_INST_FETCH ? MMU_ITLB_VIOLATION :
940+ MMU_DTLB_VIOLATION_READ);
941+#else
942+ target_ulong physical;
943+ int prot, sh_access_type;
944+
945+ sh_access_type = ACCESS_INT;
946+ switch(env->features & FEATURE_ISA) {
947+ case 2:
948+ ret = get_physical_address_sh2(env, &physical, &prot, address);
949+ break;
950+ case 4:
951+ ret = get_physical_address_sh4(env, &physical, &prot, address,
952+ access_type, sh_access_type);
953+ break;
954+ }
955+ if (ret == MMU_OK) {
956+ address &= TARGET_PAGE_MASK;
957+ physical &= TARGET_PAGE_MASK;
958+ tlb_set_page(cs, address, physical, prot, mmu_idx, TARGET_PAGE_SIZE);
959+ return true;
960+ }
961+ if (probe) {
962+ return false;
963+ }
964+
965+ if (ret != MMU_DTLB_MULTIPLE && ret != MMU_ITLB_MULTIPLE) {
966+ env->pteh = (env->pteh & PTEH_ASID_MASK) | (address & PTEH_VPN_MASK);
967+ }
968+#endif
969+
970+ env->tea = address;
971+ switch (ret) {
972+ case MMU_ITLB_MISS:
973+ case MMU_DTLB_MISS_READ:
974+ cs->exception_index = 0x040;
975+ break;
976+ case MMU_DTLB_MULTIPLE:
977+ case MMU_ITLB_MULTIPLE:
978+ cs->exception_index = 0x140;
979+ break;
980+ case MMU_ITLB_VIOLATION:
981+ cs->exception_index = 0x0a0;
982+ break;
983+ case MMU_DTLB_MISS_WRITE:
984+ cs->exception_index = 0x060;
985+ break;
986+ case MMU_DTLB_INITIAL_WRITE:
987+ cs->exception_index = 0x080;
988+ break;
989+ case MMU_DTLB_VIOLATION_READ:
990+ cs->exception_index = 0x0a0;
991+ break;
992+ case MMU_DTLB_VIOLATION_WRITE:
993+ cs->exception_index = 0x0c0;
994+ break;
995+ case MMU_IADDR_ERROR:
996+ case MMU_DADDR_ERROR_READ:
997+ cs->exception_index = 0x0e0;
998+ break;
999+ case MMU_DADDR_ERROR_WRITE:
1000+ cs->exception_index = 0x100;
1001+ break;
1002+ default:
1003+ cpu_abort(cs, "Unhandled MMU fault");
1004+ }
1005+ cpu_loop_exit_restore(cs, retaddr);
1006+}
--- /dev/null
+++ b/target/sh/helper.h
@@ -0,0 +1,13 @@
1+DEF_HELPER_1(ldtlb, void, env)
2+DEF_HELPER_1(raise_illegal_instruction, noreturn, env)
3+DEF_HELPER_1(raise_slot_illegal_instruction, noreturn, env)
4+DEF_HELPER_1(raise_fpu_disable, noreturn, env)
5+DEF_HELPER_1(raise_slot_fpu_disable, noreturn, env)
6+DEF_HELPER_1(debug, noreturn, env)
7+DEF_HELPER_1(sleep, noreturn, env)
8+DEF_HELPER_2(trapa, noreturn, env, i32)
9+DEF_HELPER_1(exclusive, noreturn, env)
10+
11+DEF_HELPER_3(macl, void, env, i32, i32)
12+DEF_HELPER_3(macw, void, env, i32, i32)
13+
--- /dev/null
+++ b/target/sh/insns.decode
@@ -0,0 +1,236 @@
1+&rn_imm rn imm
2+&rn_dsp rn dsp sz
3+&rn_mem rn rm sz
4+&rn_rm_dsp rn rm dsp sz
5+&rn_rm rn rm
6+&rn rn
7+&rm rm
8+&imm imm
9+&rn_rm_cd rn rm cd
10+
11+@rn_imm .... rn:4 imm:s8 &rn_imm
12+@rn_pc .... rn:4 dsp:8 &rn_dsp
13+@rnm .... rn:4 rm:4 .. sz:2 &rn_mem
14+@rnd .... .. sz:2 rn:4 dsp:4 &rn_rm_dsp
15+@rmd .... .. sz:2 rm:4 dsp:4 &rn_rm_dsp
16+@rnrm .... rn:4 rm:4 .... &rn_rm
17+@cmp .... rn:4 rm:4 cd:4
18+@cmp_pl .... rn:4 .... .... &rn_rm_cd rm=0 cd=5
19+@cmp_pz .... rn:4 .... .... &rn_rm_cd rm=0 cd=1
20+@cmp_s .... rn:4 rm:4 .... &rn_rm_cd cd=12
21+@rn .... rn:4 .... .... &rn
22+@rm .... rm:4 .... .... &rm
23+@imm .... .... imm:8 &imm
24+# MOV #imm,Rn
25+MOV_ir 1110 .... .... .... @rn_imm
26+# MOV.W @(disp,PC),Rn
27+MOV_pc_r 1001 .... .... .... @rn_pc sz=1
28+# MOV.L @(disp,PC),Rn
29+MOV_pc_r 1101 .... .... .... @rn_pc sz=2
30+# MOV Rm,Rn
31+# MOV.<BWL> @Rm,Rn
32+{
33+ MOV_rr 0110 .... .... 0011 @rnrm
34+ MOV_mr 0110 .... .... 00 .. @rnm
35+}
36+# MOV.<BWL> Rm,@Rn
37+MOV_rm 0010 .... .... 00 .. @rnm
38+# MOV.<BWL> Rm,@-Rn
39+# DIV0S Rm,Rn
40+{
41+ DIV0S 0010 .... .... 0111 @rnrm
42+ MOV_rmd 0010 .... .... 01 .. @rnm
43+}
44+# MOV.<BWL> @Rm+,Rn
45+# NOT Rm,Rn
46+{
47+ NOT 0110 .... .... 0111 @rnrm
48+ MOV_mir 0110 .... .... 01 .. @rnm
49+}
50+# MOV.<BW> R0,@(disp,Rn)
51+MOV_rm_rn_dsp 1000 00 .. .... .... @rnd rm=0
52+# MOV.L Rm,@(disp,Rn)
53+MOV_rm_rn_dsp 0001 rn:4 rm:4 dsp:4 &rn_rm_dsp sz=2
54+# MOV.<BW> @(disp,Rm),R0
55+MOV_rm_dsp_rn 1000 01 .. .... .... @rmd rn=0
56+# MOV.L @(disp,Rm),Rn
57+MOV_rm_dsp_rn 0101 rn:4 rm:4 dsp:4 &rn_rm_dsp sz=2
58+# MOV.<BWL> Rm,@(R0,Rn)
59+# MUL.L Rm,Rn
60+{
61+ MUL 0000 .... .... 0111 @rnrm
62+ MOV_rm_r0_rn 0000 .... .... 01 .. @rnm
63+}
64+# MOV.<BWL> @(R0,Rm),Rn
65+# MAC.L @Rm+,@Rn+
66+{
67+ MACL 0000 .... .... 1111 @rnrm
68+ MOV_r0_rm_rn 0000 .... .... 11 .. @rnm
69+}
70+# MOV.<BWL> R0,@(disp,GBR)
71+# TRAPA #imm
72+{
73+ TRAPA 11000011 imm:8
74+ MOV_r0_dsp_gbr 1100 00 sz:2 dsp:8
75+}
76+# MOV.B @(disp,GBR),R0
77+# MOVA @(disp,PC),R0
78+{
79+ MOVA 1100 0111 dsp:8
80+ MOV_dsp_gbr_r0 1100 01 sz:2 dsp:8
81+}
82+# MOVT Rn
83+MOVT 0000 .... 0010 1001 @rn
84+# SWAP.<BW> Rm,Rn
85+# NEG Rm,Rn
86+# NEGC Rm,Rn
87+{
88+ NEG 0110 .... .... 1011 @rnrm
89+ NEGC 0110 .... .... 1010 @rnrm
90+ SWAP 0110 .... .... 10 .. @rnm
91+}
92+# XTRCT Rm,Rn
93+XTRACT 0010 .... .... 1101 @rnrm
94+# ADD Rm,Rn
95+# ADDC Rm,Rn
96+# ADDV Rm,Rn
97+# DIV1 Rm,Rn
98+# DMULS.L Rm,Rn
99+# DMULU.L Rm,Rn
100+# CMP/EQ Rm,Rn
101+# CMP/HS Rm,Rn
102+# CMP/GE Rm,Rn
103+# CMP/HI Rm,Rn
104+# CMP/GT Rm,Rn
105+# SUB Rm,Rn
106+# SUBC Rm,Rn
107+# SUBV Rm,Rn
108+{
109+ ADD_rr 0011 .... .... 1100 @rnrm
110+ ADDC 0011 .... .... 1110 @rnrm
111+ ADDV 0011 .... .... 1111 @rnrm
112+ DIV1 0011 .... .... 0100 @rnrm
113+ DMULS 0011 .... .... 1101 @rnrm
114+ DMULU 0011 .... .... 0101 @rnrm
115+ SUB 0011 .... .... 1000 @rnrm
116+ SUBC 0011 .... .... 1010 @rnrm
117+ SUBV 0011 .... .... 1011 @rnrm
118+ CMP_cd 0011 .... .... .... @cmp
119+}
120+# ADD #imm,Rn
121+ADD_ir 0111 .... .... .... @rn_imm
122+# CMP/EQ #imm,R0
123+CMP_eq 1000 1000 imm:s8
124+# CMP/PL Rn
125+CMP_cd 0100 .... 0001 0101 @cmp_pl
126+# CMP/PZ Rn
127+CMP_cd 0100 .... 0001 0001 @cmp_pz
128+# CMP/STR Rm,Rn
129+CMP_cd 0010 .... .... 1100 @cmp_s
130+# DIV0U
131+DIV0U 0000 0000 0001 1001
132+# DT Rn
133+DT 0100 .... 0001 0000 @rn
134+# EXTS.<BW> Rm,Rn
135+EXTS 0110 rn:4 rm:4 111 sz:1
136+# EXTU.<BW> Rm,Rn
137+EXTU 0110 rn:4 rm:4 110 sz:1
138+# MAC.W @Rm+,@Rn+
139+MACW 0100 .... .... 1111 @rnrm
140+# MULS.W Rm,Rn
141+MULS 0010 .... .... 1111 @rnrm
142+# MULU.W Rm,Rn
143+MULU 0010 .... .... 1110 @rnrm
144+# AND Rm,Rn
145+AND_rr 0010 .... .... 1001 @rnrm
146+# AND #imm,R0
147+AND_ir 1100 1001 .... .... @imm
148+# AND.B #imm,@(R0,GBR)
149+AND_im 1100 1101 .... .... @imm
150+# OR Rm,Rn
151+OR_rr 0010 .... .... 1011 @rnrm
152+# OR #imm,R0
153+OR_ir 1100 1011 .... .... @imm
154+# OR.B #imm,@(R0,GBR)
155+OR_im 1100 1111 .... .... @imm
156+# TAS.B @Rn
157+TAS 0100 .... 0001 1011 @rn
158+# TST Rm,Rn
159+TST_rr 0010 .... .... 1000 @rnrm
160+# TST #imm,R0
161+TST_ir 1100 1000 .... .... @imm
162+# TST.B #imm,@(R0,GBR)
163+TST_im 1100 1100 .... .... @imm
164+# XOR Rm,Rn
165+XOR_rr 0010 .... .... 1010 @rnrm
166+# XOR #imm,R0
167+XOR_ir 1100 1010 .... .... @imm
168+# XOR.B #imm,@(R0,GBR)
169+XOR_im 1100 1110 .... .... @imm
170+# ROTL Rn
171+ROTL 0100 .... 0000 0100 @rn
172+# ROTR Rn
173+ROTR 0100 .... 0000 0101 @rn
174+# ROTCL Rn
175+ROTCL 0100 .... 0010 0100 @rn
176+# ROTCR Rn
177+ROTCR 0100 .... 0010 0101 @rn
178+# SHAL Rn
179+SHAL 0100 .... 0010 0000 @rn
180+# SHAR Rn
181+SHAR 0100 .... 0010 0001 @rn
182+# SHLL Rn
183+SHLL 0100 .... 0000 0000 @rn
184+# SHLR Rn
185+SHLR 0100 .... 0000 0001 @rn
186+# SHLL<2,8,16> Rn
187+SHLL2 0100 rn:4 00 n:2 1000
188+# SHLR<2,8,16> Rn
189+SHLR2 0100 rn:4 00 n:2 1001
190+# BF label
191+# BF/S label
192+# BT label
193+# BT/S label
194+BRANCH_T 1000 1 d:1 nt:1 1 dsp:s8
195+# BRA label
196+BRA 1010 dsp:s12
197+# BRAF Rm
198+BRAF 0000 .... 0010 0011 @rm
199+# BSR label
200+BSR 1011 dsp:s12
201+# BSRF Rm
202+BSRF 0000 .... 0000 0011 @rm
203+# JMP @Rm
204+JMP 0100 .... 0010 1011 @rm
205+# JSR @Rm
206+JSR 0100 .... 0000 1011 @rm
207+# RTS
208+RTS 0000 0000 0000 1011
209+# CLRMAC
210+CLRMAC 0000 0000 0010 1000
211+# CLRT
212+CLRT 0000 0000 0000 1000
213+# LDC Rm,<SR,GBR,VBR>
214+LDC_r 0100 rm:4 dst:4 1110
215+# LDC.L @Rm+,<SR,GBR,VBR>
216+LDC_m 0100 rm:4 dst:4 0111
217+# LDS Rm,<MACH,MACL,PR>
218+LDS_r 0100 rm:4 dst:4 1010
219+# LDS.L @Rm+,MACH
220+LDS_m 0100 rm:4 dst:4 0110
221+# NOP
222+NOP 0000 0000 0000 1001
223+# RTE
224+RTE 0000 0000 0010 1011
225+# SETT
226+SETT 0000 0000 0001 1000
227+# SLEEP
228+SLEEP 0000 0000 0001 1011
229+# STC <SR,GBR,VBR>,Rn
230+STC_r 0000 rn:4 src:4 0010
231+# STC.L <SR,GBR,VBR>,@-Rn
232+STC_m 0100 rn:4 src:4 0011
233+# STS <MACH,MACL,PR>,Rn
234+STS_r 0000 rn:4 src:4 1010
235+# STS.L <MACH,MACL,PR>,@-Rn
236+STS_m 0100 rn:4 src:4 0010
--- /dev/null
+++ b/target/sh/op_helper.c
@@ -0,0 +1,133 @@
1+/*
2+ * SH4 emulation
3+ *
4+ * Copyright (c) 2005 Samuel Tardieu
5+ *
6+ * This library is free software; you can redistribute it and/or
7+ * modify it under the terms of the GNU Lesser General Public
8+ * License as published by the Free Software Foundation; either
9+ * version 2.1 of the License, or (at your option) any later version.
10+ *
11+ * This library is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+ * Lesser General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU Lesser General Public
17+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18+ */
19+#include "qemu/osdep.h"
20+#include "cpu.h"
21+#include "exec/helper-proto.h"
22+#include "exec/exec-all.h"
23+#include "exec/cpu_ldst.h"
24+#include "fpu/softfloat.h"
25+
26+#ifndef CONFIG_USER_ONLY
27+
28+void superh_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
29+ MMUAccessType access_type,
30+ int mmu_idx, uintptr_t retaddr)
31+{
32+ switch (access_type) {
33+ case MMU_INST_FETCH:
34+ case MMU_DATA_LOAD:
35+ cs->exception_index = 0x0e0;
36+ break;
37+ case MMU_DATA_STORE:
38+ cs->exception_index = 0x100;
39+ break;
40+ }
41+ cpu_loop_exit_restore(cs, retaddr);
42+}
43+
44+#endif
45+
46+void helper_ldtlb(CPUSHState *env)
47+{
48+#ifdef CONFIG_USER_ONLY
49+ cpu_abort(env_cpu(env), "Unhandled ldtlb");
50+#else
51+ cpu_load_tlb(env);
52+#endif
53+}
54+
55+static inline void QEMU_NORETURN raise_exception(CPUSHState *env, int index,
56+ uintptr_t retaddr)
57+{
58+ CPUState *cs = env_cpu(env);
59+
60+ cs->exception_index = index;
61+ cpu_loop_exit_restore(cs, retaddr);
62+}
63+
64+void helper_raise_illegal_instruction(CPUSHState *env)
65+{
66+ raise_exception(env, 0x180, 0);
67+}
68+
69+void helper_raise_slot_illegal_instruction(CPUSHState *env)
70+{
71+ raise_exception(env, 0x1a0, 0);
72+}
73+
74+void helper_raise_fpu_disable(CPUSHState *env)
75+{
76+ raise_exception(env, 0x800, 0);
77+}
78+
79+void helper_raise_slot_fpu_disable(CPUSHState *env)
80+{
81+ raise_exception(env, 0x820, 0);
82+}
83+
84+void helper_debug(CPUSHState *env)
85+{
86+ raise_exception(env, EXCP_DEBUG, 0);
87+}
88+
89+void helper_sleep(CPUSHState *env)
90+{
91+ CPUState *cs = env_cpu(env);
92+
93+ cs->halted = 1;
94+ env->in_sleep = 1;
95+ raise_exception(env, EXCP_HLT, 0);
96+}
97+
98+void helper_trapa(CPUSHState *env, uint32_t tra)
99+{
100+ env->tra = tra << 2;
101+ raise_exception(env, 0x160, 0);
102+}
103+
104+void helper_exclusive(CPUSHState *env)
105+{
106+ /* We do not want cpu_restore_state to run. */
107+ cpu_loop_exit_atomic(env_cpu(env), 0);
108+}
109+
110+void helper_macl(CPUSHState *env, uint32_t arg0, uint32_t arg1)
111+{
112+ env->mac += (int64_t) (int32_t) arg0 *(int64_t) (int32_t) arg1;
113+ if (FIELD_EX32(env->sr, SR, S)) {
114+ if ((int64_t)env->mac < 0) {
115+ env->mac |= 0xffff000000000000;
116+ } else {
117+ env->mac &= 0x00007fffffffffff;
118+ }
119+ }
120+}
121+
122+void helper_macw(CPUSHState *env, uint32_t arg0, uint32_t arg1)
123+{
124+ env->mac += (int64_t) (int16_t) arg0 *(int64_t) (int16_t) arg1;
125+ if (FIELD_EX32(env->sr, SR, S)) {
126+ if (env->mac < -0x80000000) {
127+ env->mac = 0x180000000;
128+ } else if (env->mac > 0x000000007fffffff) {
129+ env->mac = 0x17fffffff;
130+ }
131+ }
132+}
133+
--- /dev/null
+++ b/target/sh/translate.c
@@ -0,0 +1,1489 @@
1+/*
2+ * SH translation
3+ *
4+ * Copyright (c) 2005 Samuel Tardieu
5+ * Copyright (c) 2019 Yoshinori Sato
6+ *
7+ * This library is free software; you can redistribute it and/or
8+ * modify it under the terms of the GNU Lesser General Public
9+ * License as published by the Free Software Foundation; either
10+ * version 2.1 of the License, or (at your option) any later version.
11+ *
12+ * This library is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+ * Lesser General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU Lesser General Public
18+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+#include "qemu/osdep.h"
22+#include "cpu.h"
23+#include "disas/disas.h"
24+#include "exec/exec-all.h"
25+#include "tcg-op.h"
26+#include "exec/cpu_ldst.h"
27+#include "exec/helper-proto.h"
28+#include "exec/helper-gen.h"
29+#include "exec/translator.h"
30+#include "trace-tcg.h"
31+#include "exec/log.h"
32+#include "qemu/qemu-print.h"
33+
34+
35+typedef struct DisasContext {
36+ DisasContextBase base;
37+
38+ uint32_t tbflags; /* should stay unmodified during the TB translation */
39+ uint32_t envflags; /* should stay in sync with env->flags using TCG ops */
40+ int memidx;
41+ uint32_t delayed_pc;
42+ uint32_t features;
43+ int sr_rb;
44+} DisasContext;
45+
46+#if defined(CONFIG_USER_ONLY)
47+#define IS_USER(ctx) 1
48+#else
49+#define IS_USER(ctx) (FIELD_EX32(ctx->tbflags, SR, MD) == 0)
50+#endif
51+
52+/* Target-specific values for ctx->base.is_jmp. */
53+/* We want to exit back to the cpu loop for some reason.
54+ Usually this is to recognize interrupts immediately. */
55+#define DISAS_STOP DISAS_TARGET_0
56+
57+/* global register indexes */
58+static TCGv cpu_regs[32];
59+static TCGv cpu_sr, cpu_sr_m, cpu_sr_q, cpu_sr_t;
60+static TCGv cpu_pc, cpu_ssr, cpu_spc, cpu_gbr;
61+static TCGv cpu_vbr, cpu_sgr, cpu_dbr;
62+static TCGv cpu_pr;
63+static TCGv_i64 cpu_mac;
64+
65+/* internal register indexes */
66+static TCGv cpu_flags, cpu_delayed_pc, cpu_delayed_cond;
67+
68+#include "exec/gen-icount.h"
69+
70+void sh_translate_init(void)
71+{
72+ int i;
73+ static const char * const gregnames[24] = {
74+ "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
75+ "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
76+ "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
77+ "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
78+ "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
79+ };
80+ /* cpu_regs[0] - cpu_regs[15] -> bank0 */
81+ /* cpu_regs[16] - cpu_regs[31] -> bank1 */
82+ for (i = 0; i < ARRAY_SIZE(gregnames); i++) {
83+ cpu_regs[i] = tcg_global_mem_new_i32(cpu_env,
84+ offsetof(CPUSHState, regs[i]),
85+ gregnames[i]);
86+ }
87+ memcpy(cpu_regs + 24, cpu_regs + 8, 8 * sizeof(TCGv));
88+
89+ cpu_pc = tcg_global_mem_new_i32(cpu_env,
90+ offsetof(CPUSHState, pc), "PC");
91+ cpu_sr = tcg_global_mem_new_i32(cpu_env,
92+ offsetof(CPUSHState, sr), "SR");
93+ cpu_sr_m = tcg_global_mem_new_i32(cpu_env,
94+ offsetof(CPUSHState, sr_m), "SR_M");
95+ cpu_sr_q = tcg_global_mem_new_i32(cpu_env,
96+ offsetof(CPUSHState, sr_q), "SR_Q");
97+ cpu_sr_t = tcg_global_mem_new_i32(cpu_env,
98+ offsetof(CPUSHState, sr_t), "SR_T");
99+ cpu_ssr = tcg_global_mem_new_i32(cpu_env,
100+ offsetof(CPUSHState, ssr), "SSR");
101+ cpu_spc = tcg_global_mem_new_i32(cpu_env,
102+ offsetof(CPUSHState, spc), "SPC");
103+ cpu_gbr = tcg_global_mem_new_i32(cpu_env,
104+ offsetof(CPUSHState, gbr), "GBR");
105+ cpu_vbr = tcg_global_mem_new_i32(cpu_env,
106+ offsetof(CPUSHState, vbr), "VBR");
107+ cpu_sgr = tcg_global_mem_new_i32(cpu_env,
108+ offsetof(CPUSHState, sgr), "SGR");
109+ cpu_dbr = tcg_global_mem_new_i32(cpu_env,
110+ offsetof(CPUSHState, dbr), "DBR");
111+ cpu_mac = tcg_global_mem_new_i64(cpu_env,
112+ offsetof(CPUSHState, mac), "MAC");
113+ cpu_pr = tcg_global_mem_new_i32(cpu_env,
114+ offsetof(CPUSHState, pr), "PR");
115+ cpu_flags = tcg_global_mem_new_i32(cpu_env,
116+ offsetof(CPUSHState, flags), "_flags_");
117+ cpu_delayed_pc = tcg_global_mem_new_i32(cpu_env,
118+ offsetof(CPUSHState, delayed_pc),
119+ "_delayed_pc_");
120+ cpu_delayed_cond = tcg_global_mem_new_i32(cpu_env,
121+ offsetof(CPUSHState,
122+ delayed_cond),
123+ "_delayed_cond_");
124+}
125+
126+void superh_cpu_dump_state(CPUState *cs, FILE *f, int flags)
127+{
128+ SuperHCPU *cpu = SUPERH_CPU(cs);
129+ CPUSHState *env = &cpu->env;
130+ int i;
131+ int regs;
132+
133+ qemu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x\n",
134+ env->pc, cpu_read_sr(env), env->pr);
135+ qemu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
136+ env->spc, env->ssr, env->gbr, env->vbr);
137+ qemu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x\n",
138+ env->sgr, env->dbr, env->delayed_pc);
139+ regs = ((env->features & FEATURE_ISA) > 2) ? 24 : 16;
140+ for (i = 0; i < regs; i += 4) {
141+ qemu_printf("r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
142+ i, env->regs[i], i + 1, env->regs[i + 1],
143+ i + 2, env->regs[i + 2], i + 3, env->regs[i + 3]);
144+ }
145+ if (env->flags & DELAY_SLOT) {
146+ qemu_printf("in delay slot (delayed_pc=0x%08x)\n",
147+ env->delayed_pc);
148+ } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
149+ qemu_printf("in conditional delay slot (delayed_pc=0x%08x)\n",
150+ env->delayed_pc);
151+ } else if (env->flags & DELAY_SLOT_RTE) {
152+ qemu_fprintf(f, "in rte delay slot (delayed_pc=0x%08x)\n",
153+ env->delayed_pc);
154+ }
155+}
156+
157+static inline void gen_save_cpu_state(DisasContext *ctx, bool save_pc)
158+{
159+ if (save_pc) {
160+ tcg_gen_movi_i32(cpu_pc, ctx->base.pc_next);
161+ }
162+ if (ctx->delayed_pc != (uint32_t) -1) {
163+ tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
164+ }
165+ tcg_gen_movi_i32(cpu_flags, ctx->envflags);
166+}
167+
168+static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
169+{
170+ /* Use a direct jump if in same page and singlestep not enabled */
171+ if (unlikely(ctx->base.singlestep_enabled)) {
172+ return false;
173+ }
174+ return true;
175+}
176+
177+static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
178+{
179+ tcg_gen_movi_i32(cpu_pc, dest);
180+ if (ctx->base.singlestep_enabled) {
181+ gen_helper_debug(cpu_env);
182+ } else {
183+ tcg_gen_lookup_and_goto_ptr();
184+ }
185+ ctx->base.is_jmp = DISAS_NORETURN;
186+}
187+
188+static void gen_jump(DisasContext * ctx)
189+{
190+ if (ctx->delayed_pc == -1) {
191+ /* Target is not statically known, it comes necessarily from a
192+ delayed jump as immediate jump are conditinal jumps */
193+ tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
194+ tcg_gen_discard_i32(cpu_delayed_pc);
195+ if (ctx->base.singlestep_enabled) {
196+ gen_helper_debug(cpu_env);
197+ } else {
198+ tcg_gen_lookup_and_goto_ptr();
199+ }
200+ ctx->base.is_jmp = DISAS_NORETURN;
201+ } else {
202+ gen_goto_tb(ctx, 0, ctx->delayed_pc);
203+ }
204+}
205+
206+/* Immediate conditional jump (bt or bf) */
207+static void gen_conditional_jump(DisasContext *ctx, target_ulong dest,
208+ bool jump_if_false)
209+{
210+ TCGLabel *l1 = gen_new_label();
211+ TCGCond cond_not_taken = jump_if_false ? TCG_COND_NE : TCG_COND_EQ;
212+
213+ gen_save_cpu_state(ctx, false);
214+ tcg_gen_brcondi_i32(cond_not_taken, cpu_sr_t, 0, l1);
215+ gen_goto_tb(ctx, 0, dest);
216+ gen_set_label(l1);
217+ gen_goto_tb(ctx, 1, ctx->base.pc_next);
218+ ctx->base.is_jmp = DISAS_NORETURN;
219+}
220+
221+/* Delayed conditional jump (bt or bf) */
222+static void gen_delayed_conditional_jump(DisasContext * ctx)
223+{
224+ TCGLabel *l1 = gen_new_label();
225+ TCGv ds = tcg_temp_new();
226+
227+ tcg_gen_mov_i32(ds, cpu_delayed_cond);
228+ tcg_gen_discard_i32(cpu_delayed_cond);
229+
230+ tcg_gen_brcondi_i32(TCG_COND_NE, ds, 0, l1);
231+ gen_goto_tb(ctx, 1, ctx->base.pc_next);
232+ gen_set_label(l1);
233+ gen_jump(ctx);
234+}
235+
236+static void gen_write_sr(TCGv val)
237+{
238+ tcg_gen_mov_i32(cpu_sr, val);
239+ tcg_gen_extract_i32(cpu_sr_t, val, R_SR_T_SHIFT, 1);
240+ tcg_gen_extract_i32(cpu_sr_q, val, R_SR_Q_SHIFT, 1);
241+ tcg_gen_extract_i32(cpu_sr_m, val, R_SR_M_SHIFT, 1);
242+}
243+
244+static void gen_read_sr(TCGv ret)
245+{
246+ tcg_gen_mov_i32(ret, cpu_sr);
247+ tcg_gen_deposit_i32(ret, ret, cpu_sr_t, R_SR_T_SHIFT, 1);
248+ tcg_gen_deposit_i32(ret, ret, cpu_sr_q, R_SR_Q_SHIFT, 1);
249+ tcg_gen_deposit_i32(ret, ret, cpu_sr_m, R_SR_M_SHIFT, 1);
250+}
251+
252+/* Include the auto-generated decoder. */
253+#include "decode.inc.c"
254+
255+#define REG(ctx, rn) \
256+ (FIELD_EX32(ctx->base.tb->flags, SR, RB)) ? (rn + 16) : rn
257+
258+#define CHECK_NOT_DELAY_SLOT(ctx) \
259+ if (ctx->envflags & DELAY_SLOT_MASK) { \
260+ gen_save_cpu_state(ctx, true); \
261+ gen_helper_raise_slot_illegal_instruction(cpu_env); \
262+ }
263+
264+#define CHECK_PRIVILEGED(ctx) \
265+ if (IS_USER(ctx)) { \
266+ gen_save_cpu_state(ctx, true); \
267+ if (ctx->envflags & DELAY_SLOT_MASK) { \
268+ gen_helper_raise_slot_illegal_instruction(cpu_env); \
269+ } else { \
270+ gen_helper_raise_illegal_instruction(cpu_env); \
271+ } \
272+ }
273+
274+#define ISA(ctx) (ctx->features & FEATURE_ISA)
275+#define IS_SH2(ctx) (ISA(ctx) == 2)
276+#define R_SP 15
277+
278+static bool trans_MOV_ir(DisasContext *ctx, arg_MOV_ir *a)
279+{
280+ tcg_gen_movi_i32(cpu_regs[REG(ctx, a->rn)], a->imm);
281+ return true;
282+}
283+
284+static bool trans_MOV_pc_r(DisasContext *ctx, arg_MOV_pc_r *a)
285+{
286+ uint32_t pc_mask = ~((1 << a->sz) - 1);
287+ TCGv addr = tcg_const_i32((a->dsp << a->sz) +
288+ ((ctx->base.pc_next + 2) & pc_mask));
289+ tcg_gen_qemu_ld_i32(cpu_regs[REG(ctx, a->rn)], addr,
290+ ctx->memidx, MO_SIGN | MO_TE | a->sz);
291+ tcg_temp_free(addr);
292+ return true;
293+}
294+
295+static bool trans_MOV_rr(DisasContext *ctx, arg_MOV_rr *a)
296+{
297+ tcg_gen_mov_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rm)]);
298+ return true;
299+}
300+
301+static bool trans_MOV_mr(DisasContext *ctx, arg_MOV_mr *a)
302+{
303+ tcg_gen_qemu_ld_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rm)],
304+ ctx->memidx, MO_SIGN | MO_TE | a->sz);
305+ return true;
306+}
307+
308+static bool trans_MOV_rm(DisasContext *ctx, arg_MOV_rm *a)
309+{
310+ tcg_gen_qemu_st_i32(cpu_regs[REG(ctx, a->rm)], cpu_regs[REG(ctx, a->rn)],
311+ ctx->memidx, MO_TE | a->sz);
312+ return true;
313+}
314+
315+static bool trans_MOV_rmd(DisasContext *ctx, arg_MOV_rmd *a)
316+{
317+ TCGv addr = tcg_temp_new();
318+ tcg_gen_subi_i32(addr, cpu_regs[REG(ctx, a->rn)], 1 << a->sz);
319+ tcg_gen_qemu_st_i32(cpu_regs[REG(ctx, a->rm)], addr,
320+ ctx->memidx, MO_TE | a->sz);
321+ tcg_gen_mov_i32(cpu_regs[REG(ctx, a->rn)], addr);
322+ tcg_temp_free(addr);
323+ return true;
324+}
325+
326+static bool trans_MOV_mir(DisasContext *ctx, arg_MOV_mir *a)
327+{
328+ tcg_gen_qemu_ld_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rm)],
329+ ctx->memidx, MO_SIGN | MO_TE | a->sz);
330+ if (a->rm != a->rn) {
331+ tcg_gen_addi_i32(cpu_regs[REG(ctx, a->rm)],
332+ cpu_regs[REG(ctx, a->rm)], 1 << a->sz);
333+ }
334+ return true;
335+}
336+
337+static bool trans_MOV_rm_rn_dsp(DisasContext *ctx, arg_MOV_rm_rn_dsp *a)
338+{
339+ TCGv addr;
340+ addr = tcg_temp_new();
341+ tcg_gen_addi_i32(addr, cpu_regs[REG(ctx, a->rn)], a->dsp << a->sz);
342+ tcg_gen_qemu_st_i32(cpu_regs[REG(ctx, a->rm)], addr,
343+ ctx->memidx, MO_TE | a->sz);
344+ tcg_temp_free(addr);
345+ return true;
346+}
347+
348+static bool trans_MOV_rm_dsp_rn(DisasContext *ctx, arg_MOV_rm_dsp_rn *a)
349+{
350+ TCGv addr;
351+ addr = tcg_temp_new();
352+ tcg_gen_addi_i32(addr, cpu_regs[REG(ctx, a->rm)], a->dsp << a->sz);
353+ tcg_gen_qemu_ld_i32(cpu_regs[REG(ctx, a->rn)], addr,
354+ ctx->memidx, MO_SIGN | MO_TE | a->sz);
355+ tcg_temp_free(addr);
356+ return true;
357+}
358+
359+static bool trans_MOV_rm_r0_rn(DisasContext *ctx, arg_MOV_rm_r0_rn *a)
360+{
361+ TCGv addr;
362+ addr = tcg_temp_new();
363+ tcg_gen_add_i32(addr, cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, 0)]);
364+ tcg_gen_qemu_st_i32(cpu_regs[REG(ctx, a->rm)], addr,
365+ ctx->memidx, MO_TE | a->sz);
366+ tcg_temp_free(addr);
367+ return true;
368+}
369+
370+static bool trans_MOV_r0_rm_rn(DisasContext *ctx, arg_MOV_r0_rm_rn *a)
371+{
372+ TCGv addr;
373+ addr = tcg_temp_new();
374+ tcg_gen_add_i32(addr, cpu_regs[REG(ctx, a->rm)], cpu_regs[REG(ctx, 0)]);
375+ tcg_gen_qemu_ld_i32(cpu_regs[REG(ctx, a->rn)], addr,
376+ ctx->memidx, MO_SIGN | MO_TE | a->sz);
377+ tcg_temp_free(addr);
378+ return true;
379+}
380+
381+static bool trans_MOV_r0_dsp_gbr(DisasContext *ctx, arg_MOV_r0_dsp_gbr *a)
382+{
383+ TCGv addr;
384+ addr = tcg_temp_new();
385+ tcg_gen_addi_i32(addr, cpu_gbr, a->dsp << a->sz);
386+ tcg_gen_qemu_st_i32(cpu_regs[REG(ctx, 0)], addr,
387+ ctx->memidx, MO_TE | a->sz);
388+ tcg_temp_free(addr);
389+ return true;
390+}
391+
392+static bool trans_MOV_dsp_gbr_r0(DisasContext *ctx, arg_MOV_r0_dsp_gbr *a)
393+{
394+ TCGv addr;
395+ addr = tcg_temp_new();
396+ tcg_gen_addi_i32(addr, cpu_gbr, a->dsp << a->sz);
397+ tcg_gen_qemu_ld_i32(cpu_regs[REG(ctx, 0)], addr,
398+ ctx->memidx, MO_SIGN | MO_TE | a->sz);
399+ tcg_temp_free(addr);
400+ return true;
401+}
402+
403+static bool trans_MOVA(DisasContext *ctx, arg_MOVA *a)
404+{
405+ uint32_t pc;
406+ if (ctx->envflags & DELAY_SLOT_MASK) {
407+ pc = ctx->delayed_pc + 2;
408+ } else {
409+ pc= ctx->base.pc_next + 2;
410+ }
411+ tcg_gen_movi_i32(cpu_regs[REG(ctx, 0)],
412+ ((pc & 0xfffffffc)+ a->dsp * 4));
413+ return true;
414+}
415+
416+static bool trans_MOVT(DisasContext *ctx, arg_MOVT *a)
417+{
418+ tcg_gen_mov_i32(cpu_regs[REG(ctx, a->rn)], cpu_sr_t);
419+ return true;
420+}
421+
422+static bool trans_SWAP(DisasContext *ctx, arg_SWAP *a)
423+{
424+ TCGv temp = tcg_temp_new();
425+ switch (a->sz) {
426+ case 0: /* Byte */
427+ tcg_gen_ext16u_i32(temp, cpu_regs[REG(ctx, a->rm)]);
428+ tcg_gen_bswap16_i32(temp, temp);
429+ tcg_gen_deposit_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rm)],
430+ temp, 0, 16);
431+ break;
432+ case 1: /* Word */
433+ tcg_gen_rotli_i32(cpu_regs[REG(ctx, a->rn)],
434+ cpu_regs[REG(ctx, a->rm)], 16);
435+ break;
436+ default:
437+ g_assert_not_reached();
438+ }
439+ tcg_temp_free(temp);
440+ return true;
441+}
442+
443+static bool trans_XTRACT(DisasContext *ctx, arg_XTRACT *a)
444+{
445+ tcg_gen_shri_i32(cpu_regs[REG(ctx, a->rn)],
446+ cpu_regs[REG(ctx, a->rn)], 16);
447+ tcg_gen_deposit_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)],
448+ cpu_regs[REG(ctx, a->rm)], 16, 16);
449+ return true;
450+}
451+
452+static bool trans_ADD_rr(DisasContext *ctx, arg_ADD_rr *a)
453+{
454+ tcg_gen_add_i32(cpu_regs[REG(ctx, a->rn)],
455+ cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rm)]);
456+ return true;
457+}
458+
459+static bool trans_ADD_ir(DisasContext *ctx, arg_ADD_ir *a)
460+{
461+ tcg_gen_addi_i32(cpu_regs[REG(ctx, a->rn)],
462+ cpu_regs[REG(ctx, a->rn)], a->imm);
463+ return true;
464+}
465+
466+static bool trans_ADDC(DisasContext *ctx, arg_ADDC *a)
467+{
468+ TCGv z = tcg_const_i32(0);
469+ tcg_gen_add2_i32(cpu_regs[REG(ctx, a->rn)], cpu_sr_t,
470+ cpu_regs[REG(ctx, a->rn)], z,
471+ cpu_sr_t, z);
472+ tcg_gen_add2_i32(cpu_regs[REG(ctx, a->rn)], cpu_sr_t,
473+ cpu_regs[REG(ctx, a->rn)], cpu_sr_t,
474+ cpu_regs[REG(ctx, a->rm)], z);
475+ tcg_temp_free(z);
476+ return true;
477+}
478+
479+static bool trans_ADDV(DisasContext *ctx, arg_ADDV *a)
480+{
481+ tcg_gen_add_i32(cpu_sr_t, cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rm)]);
482+ tcg_gen_xor_i32(cpu_sr_t, cpu_sr_t, cpu_regs[REG(ctx, a->rn)]);
483+ tcg_gen_shri_i32(cpu_sr_t, cpu_sr_t, 31);
484+ tcg_gen_add_i32(cpu_regs[REG(ctx, a->rn)],
485+ cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rm)]);
486+ return true;
487+}
488+
489+static bool trans_SUB(DisasContext *ctx, arg_SUB *a)
490+{
491+ tcg_gen_sub_i32(cpu_regs[REG(ctx, a->rn)],
492+ cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rm)]);
493+ return true;
494+}
495+
496+static bool trans_SUBC(DisasContext *ctx, arg_SUBC *a)
497+{
498+ TCGv t0, t1;
499+ t0 = tcg_const_i32(0);
500+ t1 = tcg_temp_new();
501+ tcg_gen_add2_i32(t1, cpu_sr_t, cpu_sr_t, t0, cpu_regs[REG(ctx, a->rm)], t0);
502+ tcg_gen_sub2_i32(cpu_regs[REG(ctx, a->rn)], cpu_sr_t,
503+ cpu_regs[REG(ctx, a->rn)], t0, t1, cpu_sr_t);
504+ tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
505+ tcg_temp_free(t0);
506+ tcg_temp_free(t1);
507+ return true;
508+}
509+
510+static bool trans_SUBV(DisasContext *ctx, arg_SUBV *a)
511+{
512+ tcg_gen_sub_i32(cpu_sr_t, cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rm)]);
513+ tcg_gen_xor_i32(cpu_sr_t, cpu_sr_t, cpu_regs[REG(ctx, a->rn)]);
514+ tcg_gen_shri_i32(cpu_sr_t, cpu_sr_t, 31);
515+ tcg_gen_sub_i32(cpu_regs[REG(ctx, a->rn)],
516+ cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rm)]);
517+ return true;
518+}
519+
520+static bool trans_CMP_cd(DisasContext *ctx, arg_CMP_cd *a)
521+{
522+ TCGCond cond;
523+ bool cmpz = false;
524+ switch(a->cd) {
525+ case 0: /* EQ */
526+ cond = TCG_COND_EQ;
527+ break;
528+ case 3: /* GE */
529+ cond = TCG_COND_GE;
530+ break;
531+ case 7: /* GT */
532+ cond = TCG_COND_GT;
533+ break;
534+ case 6: /* HI */
535+ cond = TCG_COND_GTU;
536+ break;
537+ case 2: /* HS */
538+ cond = TCG_COND_GEU;
539+ break;
540+ case 5: /* PL */
541+ cond = TCG_COND_GT;
542+ cmpz = true;
543+ break;
544+ case 1: /* PZ */
545+ cond = TCG_COND_GE;
546+ cmpz = true;
547+ break;
548+ case 12: { /* STR */
549+ TCGv cmp1 = tcg_temp_new();
550+ TCGv cmp2 = tcg_temp_new();
551+ tcg_gen_xor_i32(cmp2, cpu_regs[REG(ctx, a->rm)], cpu_regs[REG(ctx, a->rn)]);
552+ tcg_gen_subi_i32(cmp1, cmp2, 0x01010101);
553+ tcg_gen_andc_i32(cmp1, cmp1, cmp2);
554+ tcg_gen_andi_i32(cmp1, cmp1, 0x80808080);
555+ tcg_gen_setcondi_i32(TCG_COND_NE, cpu_sr_t, cmp1, 0);
556+ tcg_temp_free(cmp2);
557+ tcg_temp_free(cmp1);
558+ return true;
559+ }
560+ default:
561+ g_assert_not_reached();
562+ }
563+ if (cmpz) {
564+ tcg_gen_setcondi_i32(cond, cpu_sr_t, cpu_regs[REG(ctx, a->rn)], 0);
565+ } else {
566+ tcg_gen_setcond_i32(cond, cpu_sr_t,
567+ cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rm)]);
568+ }
569+ return true;
570+}
571+
572+static bool trans_CMP_eq(DisasContext *ctx, arg_CMP_eq *a)
573+{
574+ tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t,
575+ cpu_regs[REG(ctx, 0)], a->imm);
576+ return true;
577+}
578+
579+static bool trans_DIV0S(DisasContext *ctx, arg_DIV0S *a)
580+{
581+ tcg_gen_shri_i32(cpu_sr_q, cpu_regs[REG(ctx, a->rn)], 31);
582+ tcg_gen_shri_i32(cpu_sr_m, cpu_regs[REG(ctx, a->rm)], 31);
583+ tcg_gen_xor_i32(cpu_sr_t, cpu_sr_q, cpu_sr_m);
584+ return true;
585+}
586+
587+static bool trans_DIV0U(DisasContext *ctx, arg_DIV0U *a)
588+{
589+ TCGv z = tcg_const_i32(0);
590+ tcg_gen_mov_i32(cpu_sr_t, z);
591+ tcg_gen_mov_i32(cpu_sr_m, z);
592+ tcg_gen_mov_i32(cpu_sr_q, z);
593+ return true;
594+}
595+
596+static bool trans_DIV1(DisasContext *ctx, arg_DIV1 *a)
597+{
598+ TCGv t0 = tcg_temp_new();
599+ TCGv t1 = tcg_temp_new();
600+ TCGv t2 = tcg_temp_new();
601+ TCGv zero = tcg_const_i32(0);
602+
603+ /* shift left arg1, saving the bit being pushed out and inserting
604+ T on the right */
605+ tcg_gen_shri_i32(t0, cpu_regs[REG(ctx, a->rn)], 31);
606+ tcg_gen_shli_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], 1);
607+ tcg_gen_or_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], cpu_sr_t);
608+
609+ /* Add or subtract arg0 from arg1 depending if Q == M. To avoid
610+ using 64-bit temps, we compute arg0's high part from q ^ m, so
611+ that it is 0x00000000 when adding the value or 0xffffffff when
612+ subtracting it. */
613+ tcg_gen_xor_i32(t1, cpu_sr_q, cpu_sr_m);
614+ tcg_gen_subi_i32(t1, t1, 1);
615+ tcg_gen_neg_i32(t2, cpu_regs[REG(ctx, a->rm)]);
616+ tcg_gen_movcond_i32(TCG_COND_EQ, t2, t1, zero, cpu_regs[REG(ctx, a->rm)], t2);
617+ tcg_gen_add2_i32(cpu_regs[REG(ctx, a->rn)], t1,
618+ cpu_regs[REG(ctx, a->rn)], zero, t2, t1);
619+
620+ /* compute T and Q depending on carry */
621+ tcg_gen_andi_i32(t1, t1, 1);
622+ tcg_gen_xor_i32(t1, t1, t0);
623+ tcg_gen_xori_i32(cpu_sr_t, t1, 1);
624+ tcg_gen_xor_i32(cpu_sr_q, cpu_sr_m, t1);
625+
626+ tcg_temp_free(zero);
627+ tcg_temp_free(t2);
628+ tcg_temp_free(t1);
629+ tcg_temp_free(t0);
630+ return true;
631+}
632+
633+static bool trans_DT(DisasContext *ctx, arg_DT *a)
634+{
635+ tcg_gen_subi_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], 1);
636+ tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, cpu_regs[REG(ctx, a->rn)], 0);
637+ return true;
638+}
639+
640+static bool trans_EXTS(DisasContext *ctx, arg_EXTS *a)
641+{
642+ switch(a->sz) {
643+ case 0:
644+ tcg_gen_ext8s_i32(cpu_regs[REG(ctx, a->rn)],
645+ cpu_regs[REG(ctx, a->rm)]);
646+ break;
647+ case 1:
648+ tcg_gen_ext16s_i32(cpu_regs[REG(ctx, a->rn)],
649+ cpu_regs[REG(ctx, a->rm)]);
650+ break;
651+ }
652+ return true;
653+}
654+
655+static bool trans_EXTU(DisasContext *ctx, arg_EXTS *a)
656+{
657+ switch(a->sz) {
658+ case 0:
659+ tcg_gen_ext8u_i32(cpu_regs[REG(ctx, a->rn)],
660+ cpu_regs[REG(ctx, a->rm)]);
661+ break;
662+ case 1:
663+ tcg_gen_ext16u_i32(cpu_regs[REG(ctx, a->rn)],
664+ cpu_regs[REG(ctx, a->rm)]);
665+ break;
666+ }
667+ return true;
668+}
669+
670+static bool trans_MULS(DisasContext *ctx, arg_MULS *a)
671+{
672+ TCGv arg1 = tcg_temp_new();
673+ TCGv arg2 = tcg_temp_new();
674+ TCGv_i64 low64 = tcg_temp_new_i64();
675+ tcg_gen_ext16s_i32(arg1, cpu_regs[REG(ctx, a->rm)]);
676+ tcg_gen_ext16s_i32(arg2, cpu_regs[REG(ctx, a->rn)]);
677+ tcg_gen_mul_i32(arg1, arg1, arg2);
678+ tcg_gen_extu_i32_i64(low64, arg2);
679+ tcg_gen_deposit_i64(cpu_mac, cpu_mac, low64, 0, 32);
680+ tcg_temp_free(arg1);
681+ tcg_temp_free(arg2);
682+ tcg_temp_free_i64(low64);
683+ return true;
684+}
685+
686+static bool trans_MULU(DisasContext *ctx, arg_MULU *a)
687+{
688+ TCGv arg1 = tcg_temp_new();
689+ TCGv arg2 = tcg_temp_new();
690+ TCGv_i64 low64 = tcg_temp_new_i64();
691+ tcg_gen_ext16u_i32(arg1, cpu_regs[REG(ctx, a->rm)]);
692+ tcg_gen_ext16u_i32(arg2, cpu_regs[REG(ctx, a->rn)]);
693+ tcg_gen_mul_i32(arg1, arg1, arg2);
694+ tcg_gen_extu_i32_i64(low64, arg2);
695+ tcg_gen_deposit_i64(cpu_mac, cpu_mac, low64, 0, 32);
696+ tcg_temp_free(arg1);
697+ tcg_temp_free(arg2);
698+ tcg_temp_free_i64(low64);
699+ return true;
700+}
701+
702+static bool trans_DMULS(DisasContext *ctx, arg_DMULS *a)
703+{
704+ TCGv_i64 arg1 = tcg_temp_new_i64();
705+ TCGv_i64 arg2 = tcg_temp_new_i64();
706+ tcg_gen_ext_i32_i64(arg1, cpu_regs[REG(ctx, a->rm)]);
707+ tcg_gen_ext_i32_i64(arg2, cpu_regs[REG(ctx, a->rn)]);
708+ tcg_gen_mul_i64(cpu_mac, arg1, arg2);
709+ tcg_temp_free_i64(arg1);
710+ tcg_temp_free_i64(arg2);
711+ return true;
712+}
713+
714+static bool trans_DMULU(DisasContext *ctx, arg_DMULU *a)
715+{
716+ TCGv_i64 arg1 = tcg_temp_new_i64();
717+ TCGv_i64 arg2 = tcg_temp_new_i64();
718+ tcg_gen_extu_i32_i64(arg1, cpu_regs[REG(ctx, a->rm)]);
719+ tcg_gen_extu_i32_i64(arg2, cpu_regs[REG(ctx, a->rn)]);
720+ tcg_gen_mul_i64(cpu_mac, arg1, arg2);
721+ tcg_temp_free_i64(arg1);
722+ tcg_temp_free_i64(arg2);
723+ return true;
724+}
725+
726+static bool trans_MUL(DisasContext *ctx, arg_MUL *a)
727+{
728+ TCGv low = tcg_temp_new();
729+ TCGv_i64 low64 = tcg_temp_new_i64();
730+ tcg_gen_mul_i32(low, cpu_regs[REG(ctx, a->rm)], cpu_regs[REG(ctx, a->rn)]);
731+ tcg_gen_extu_i32_i64(low64, low);
732+ tcg_gen_deposit_i64(cpu_mac, cpu_mac, low64, 0, 32);
733+ tcg_temp_free(low);
734+ tcg_temp_free_i64(low64);
735+ return true;
736+}
737+
738+static bool trans_MACL(DisasContext *ctx, arg_MACL *a)
739+{
740+ TCGv arg0, arg1;
741+ arg0 = tcg_temp_new();
742+ tcg_gen_qemu_ld_i32(arg0, cpu_regs[REG(ctx, a->rm)],
743+ ctx->memidx, MO_TE | MO_32);
744+ arg1 = tcg_temp_new();
745+ tcg_gen_qemu_ld_i32(arg1, cpu_regs[REG(ctx, a->rn)],
746+ ctx->memidx, MO_TE | MO_32);
747+ gen_helper_macl(cpu_env, arg0, arg1);
748+ tcg_gen_addi_i32(cpu_regs[REG(ctx, a->rm)], cpu_regs[REG(ctx, a->rm)], 4);
749+ tcg_gen_addi_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], 4);
750+ tcg_temp_free(arg1);
751+ tcg_temp_free(arg0);
752+ return true;
753+}
754+
755+static bool trans_MACW(DisasContext *ctx, arg_MACW *a)
756+{
757+ TCGv arg0, arg1;
758+ arg0 = tcg_temp_new();
759+ tcg_gen_qemu_ld_i32(arg0, cpu_regs[REG(ctx, a->rm)],
760+ ctx->memidx, MO_TE | MO_16);
761+ arg1 = tcg_temp_new();
762+ tcg_gen_qemu_ld_i32(arg1, cpu_regs[REG(ctx, a->rn)],
763+ ctx->memidx, MO_TE | MO_16);
764+ gen_helper_macw(cpu_env, arg0, arg1);
765+ tcg_gen_addi_i32(cpu_regs[REG(ctx, a->rm)], cpu_regs[REG(ctx, a->rm)], 2);
766+ tcg_gen_addi_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], 2);
767+ tcg_temp_free(arg1);
768+ tcg_temp_free(arg0);
769+ return true;
770+}
771+
772+static bool trans_NEG(DisasContext *ctx, arg_NEG *a)
773+{
774+ tcg_gen_neg_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rm)]);
775+ return true;
776+}
777+
778+static bool trans_NEGC(DisasContext *ctx, arg_NEG *a)
779+{
780+ TCGv z = tcg_const_i32(0);
781+ tcg_gen_add2_i32(cpu_regs[REG(ctx, a->rn)], cpu_sr_t,
782+ cpu_regs[REG(ctx, a->rm)], z, cpu_sr_t, z);
783+ tcg_gen_sub2_i32(cpu_regs[REG(ctx, a->rn)], cpu_sr_t,
784+ z, z, cpu_regs[REG(ctx, a->rn)], cpu_sr_t);
785+ tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
786+ tcg_temp_free(z);
787+ return true;
788+}
789+
790+static bool trans_AND_rr(DisasContext *ctx, arg_AND_rr *a)
791+{
792+ tcg_gen_and_i32(cpu_regs[REG(ctx, a->rn)],
793+ cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rm)]);
794+ return true;
795+}
796+
797+static bool trans_AND_ir(DisasContext *ctx, arg_AND_ir *a)
798+{
799+ tcg_gen_andi_i32(cpu_regs[REG(ctx, 0)],
800+ cpu_regs[REG(ctx, 0)], a->imm);
801+ return true;
802+}
803+
804+static bool trans_AND_im(DisasContext *ctx, arg_AND_im *a)
805+{
806+ TCGv val = tcg_temp_new();
807+ TCGv addr = tcg_temp_new();
808+ tcg_gen_add_i32(addr, cpu_regs[REG(ctx, 0)], cpu_gbr);
809+ tcg_gen_qemu_ld_i32(val, addr,
810+ ctx->memidx, MO_TE | MO_8);
811+ tcg_gen_andi_i32(val, val, a->imm);
812+ tcg_gen_qemu_st_i32(val, addr,
813+ ctx->memidx, MO_TE | MO_8);
814+ tcg_temp_free(val);
815+ tcg_temp_free(addr);
816+ return true;
817+}
818+
819+static bool trans_OR_rr(DisasContext *ctx, arg_OR_rr *a)
820+{
821+ tcg_gen_or_i32(cpu_regs[REG(ctx, a->rn)],
822+ cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rm)]);
823+ return true;
824+}
825+
826+static bool trans_OR_ir(DisasContext *ctx, arg_OR_ir *a)
827+{
828+ tcg_gen_ori_i32(cpu_regs[REG(ctx, 0)],
829+ cpu_regs[REG(ctx, 0)], a->imm);
830+ return true;
831+}
832+
833+static bool trans_OR_im(DisasContext *ctx, arg_OR_im *a)
834+{
835+ TCGv val = tcg_temp_new();
836+ TCGv addr = tcg_temp_new();
837+ tcg_gen_add_i32(addr, cpu_regs[REG(ctx, 0)], cpu_gbr);
838+ tcg_gen_qemu_ld_i32(val, addr,
839+ ctx->memidx, MO_TE | MO_8);
840+ tcg_gen_ori_i32(val, val, a->imm);
841+ tcg_gen_qemu_st_i32(val, addr,
842+ ctx->memidx, MO_TE | MO_8);
843+ tcg_temp_free(val);
844+ tcg_temp_free(addr);
845+ return true;
846+}
847+
848+static bool trans_TST_rr(DisasContext *ctx, arg_TST_rr *a)
849+{
850+ TCGv temp = tcg_temp_new();
851+ tcg_gen_and_i32(temp,
852+ cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rm)]);
853+ tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, temp, 0);
854+ tcg_temp_free(temp);
855+ return true;
856+}
857+
858+static bool trans_TST_ir(DisasContext *ctx, arg_TST_ir *a)
859+{
860+ TCGv temp = tcg_temp_new();
861+ tcg_gen_andi_i32(temp,
862+ cpu_regs[REG(ctx, 0)], a->imm);
863+ tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, temp, 0);
864+ tcg_temp_free(temp);
865+ return true;
866+}
867+
868+static bool trans_TST_im(DisasContext *ctx, arg_TST_im *a)
869+{
870+ TCGv val = tcg_temp_new();
871+ TCGv addr = tcg_temp_new();
872+ tcg_gen_add_i32(addr, cpu_regs[REG(ctx, 0)], cpu_gbr);
873+ tcg_gen_qemu_ld_i32(val, addr,
874+ ctx->memidx, MO_TE | MO_8);
875+ tcg_gen_andi_i32(val, val, a->imm);
876+ tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
877+ tcg_temp_free(val);
878+ tcg_temp_free(addr);
879+ return true;
880+}
881+
882+static bool trans_XOR_rr(DisasContext *ctx, arg_XOR_rr *a)
883+{
884+ tcg_gen_xor_i32(cpu_regs[REG(ctx, a->rn)],
885+ cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rm)]);
886+ return true;
887+}
888+
889+static bool trans_XOR_ir(DisasContext *ctx, arg_XOR_ir *a)
890+{
891+ tcg_gen_xori_i32(cpu_regs[REG(ctx, 0)],
892+ cpu_regs[REG(ctx, 0)], a->imm);
893+ return true;
894+}
895+
896+static bool trans_XOR_im(DisasContext *ctx, arg_XOR_im *a)
897+{
898+ TCGv val = tcg_temp_new();
899+ TCGv addr = tcg_temp_new();
900+ tcg_gen_add_i32(addr, cpu_regs[REG(ctx, 0)], cpu_gbr);
901+ tcg_gen_qemu_ld_i32(val, addr,
902+ ctx->memidx, MO_TE | MO_8);
903+ tcg_gen_xori_i32(val, val, a->imm);
904+ tcg_gen_qemu_st_i32(val, addr,
905+ ctx->memidx, MO_TE | MO_8);
906+ tcg_temp_free(val);
907+ tcg_temp_free(addr);
908+ return true;
909+}
910+
911+static bool trans_NOT(DisasContext *ctx, arg_NOT *a)
912+{
913+ tcg_gen_not_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rm)]);
914+ return true;
915+}
916+
917+static bool trans_TAS(DisasContext *ctx, arg_TAS *a)
918+{
919+ TCGv val = tcg_temp_new();
920+ tcg_gen_qemu_ld_i32(val, cpu_regs[REG(ctx, a->rn)],
921+ ctx->memidx, MO_TE | MO_8);
922+ tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
923+ tcg_gen_ori_i32(val, val, 0x80);
924+ tcg_gen_qemu_st_i32(val, cpu_regs[REG(ctx, a->rn)],
925+ ctx->memidx, MO_TE | MO_8);
926+ return true;
927+}
928+
929+static bool trans_ROTL(DisasContext *ctx, arg_ROTL *a)
930+{
931+ tcg_gen_rotli_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], 1);
932+ tcg_gen_andi_i32(cpu_sr_t, cpu_regs[REG(ctx, a->rn)], 1);
933+ return true;
934+}
935+
936+static bool trans_ROTR(DisasContext *ctx, arg_ROTR *a)
937+{
938+ tcg_gen_andi_i32(cpu_sr_t, cpu_regs[REG(ctx, a->rn)], 1);
939+ tcg_gen_rotli_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], 1);
940+ return true;
941+}
942+
943+static bool trans_ROTCL(DisasContext *ctx, arg_ROTCL *a)
944+{
945+ TCGv temp = tcg_temp_new();
946+ tcg_gen_shri_i32(temp, cpu_regs[REG(ctx, a->rn)], 31);
947+ tcg_gen_shli_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], 1);
948+ tcg_gen_or_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], cpu_sr_t);
949+ tcg_gen_mov_i32(cpu_sr_t, temp);
950+ tcg_temp_free(temp);
951+ return true;
952+}
953+
954+static bool trans_ROTCR(DisasContext *ctx, arg_ROTCR *a)
955+{
956+ TCGv temp = tcg_temp_new();
957+ tcg_gen_andi_i32(temp, cpu_regs[REG(ctx, a->rn)], 1);
958+ tcg_gen_shri_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], 1);
959+ tcg_gen_deposit_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)],
960+ temp, 31, 1);
961+ tcg_gen_mov_i32(cpu_sr_t, temp);
962+ tcg_temp_free(temp);
963+ return true;
964+}
965+
966+static bool trans_SHAL(DisasContext *ctx, arg_SHAL *a)
967+{
968+ tcg_gen_shri_i32(cpu_sr_t, cpu_regs[REG(ctx, a->rn)], 31);
969+ tcg_gen_shli_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], 1);
970+ return true;
971+}
972+
973+static bool trans_SHLL(DisasContext *ctx, arg_SHLL *a)
974+{
975+ tcg_gen_shri_i32(cpu_sr_t, cpu_regs[REG(ctx, a->rn)], 31);
976+ tcg_gen_shli_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], 1);
977+ return true;
978+}
979+
980+static bool trans_SHAR(DisasContext *ctx, arg_SHAR *a)
981+{
982+ tcg_gen_andi_i32(cpu_sr_t, cpu_regs[REG(ctx, a->rn)], 1);
983+ tcg_gen_sari_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], 1);
984+ return true;
985+}
986+
987+static bool trans_SHLR(DisasContext *ctx, arg_SHLR *a)
988+{
989+ tcg_gen_shri_i32(cpu_sr_t, cpu_regs[REG(ctx, a->rn)], 31);
990+ tcg_gen_shri_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], 1);
991+ return true;
992+}
993+
994+static bool trans_SHLL2(DisasContext *ctx, arg_SHLL2 *a)
995+{
996+ static const int cnt[] = {2, 8, 16};
997+ tcg_gen_shli_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], cnt[a->n]);
998+ return true;
999+}
1000+
1001+static bool trans_SHLR2(DisasContext *ctx, arg_SHLR2 *a)
1002+{
1003+ static const int cnt[] = {2, 8, 16};
1004+ tcg_gen_shri_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], cnt[a->n]);
1005+ return true;
1006+}
1007+
1008+static bool trans_BRANCH_T(DisasContext *ctx, arg_BRANCH_T *a)
1009+{
1010+ uint32_t dst = ctx->base.pc_next + 2 + a->dsp * 2;
1011+ CHECK_NOT_DELAY_SLOT(ctx);
1012+ if (!a->d) {
1013+ gen_conditional_jump(ctx, dst, a->nt);
1014+ } else {
1015+ if (a->nt) {
1016+ tcg_gen_xori_i32(cpu_delayed_cond, cpu_sr_t, 1);
1017+ } else {
1018+ tcg_gen_mov_i32(cpu_delayed_cond, cpu_sr_t);
1019+ }
1020+ ctx->delayed_pc = dst;
1021+ ctx->envflags |= DELAY_SLOT_CONDITIONAL;
1022+ }
1023+ return true;
1024+}
1025+
1026+static bool trans_BRA(DisasContext *ctx, arg_BRA *a)
1027+{
1028+ uint32_t dst = ctx->base.pc_next + 2 + a->dsp * 2;
1029+ CHECK_NOT_DELAY_SLOT(ctx);
1030+ ctx->delayed_pc = dst;
1031+ ctx->envflags |= DELAY_SLOT;
1032+ return true;
1033+}
1034+
1035+static bool trans_BRAF(DisasContext *ctx, arg_BRAF *a)
1036+{
1037+ CHECK_NOT_DELAY_SLOT(ctx);
1038+ tcg_gen_addi_i32(cpu_delayed_pc,
1039+ cpu_regs[REG(ctx, a->rm)], ctx->base.pc_next + 2);
1040+ ctx->envflags |= DELAY_SLOT;
1041+ ctx->delayed_pc = (uint32_t) - 1;
1042+ return true;
1043+}
1044+
1045+static bool trans_BSR(DisasContext *ctx, arg_BSR *a)
1046+{
1047+ uint32_t dst = ctx->base.pc_next + 2 + a->dsp * 2;
1048+ CHECK_NOT_DELAY_SLOT(ctx);
1049+ tcg_gen_movi_i32(cpu_pr, ctx->base.pc_next + 2);
1050+ ctx->delayed_pc = dst;
1051+ ctx->envflags |= DELAY_SLOT;
1052+ return true;
1053+}
1054+
1055+static bool trans_BSRF(DisasContext *ctx, arg_BSRF *a)
1056+{
1057+ CHECK_NOT_DELAY_SLOT(ctx);
1058+ tcg_gen_movi_i32(cpu_pr, ctx->base.pc_next + 2);
1059+ tcg_gen_addi_i32(cpu_delayed_pc,
1060+ cpu_regs[REG(ctx, a->rm)], ctx->base.pc_next + 2);
1061+ ctx->envflags |= DELAY_SLOT;
1062+ ctx->delayed_pc = (uint32_t) - 1;
1063+ return true;
1064+}
1065+
1066+static bool trans_JMP(DisasContext *ctx, arg_JMP *a)
1067+{
1068+ CHECK_NOT_DELAY_SLOT(ctx);
1069+ tcg_gen_movi_i32(cpu_pr, ctx->base.pc_next + 2);
1070+ tcg_gen_mov_i32(cpu_delayed_pc, cpu_regs[REG(ctx, a->rm)]);
1071+ ctx->envflags |= DELAY_SLOT;
1072+ ctx->delayed_pc = (uint32_t) - 1;
1073+ return true;
1074+}
1075+
1076+static bool trans_JSR(DisasContext *ctx, arg_JSR *a)
1077+{
1078+ CHECK_NOT_DELAY_SLOT(ctx);
1079+ tcg_gen_movi_i32(cpu_pr, ctx->base.pc_next + 2);
1080+ tcg_gen_mov_i32(cpu_delayed_pc, cpu_regs[REG(ctx, a->rm)]);
1081+ ctx->envflags |= DELAY_SLOT;
1082+ ctx->delayed_pc = (uint32_t) - 1;
1083+ return true;
1084+}
1085+
1086+static bool trans_RTS(DisasContext *ctx, arg_RTS *a)
1087+{
1088+ CHECK_NOT_DELAY_SLOT(ctx);
1089+ tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);
1090+ ctx->envflags |= DELAY_SLOT;
1091+ ctx->delayed_pc = (uint32_t) - 1;
1092+ return true;
1093+}
1094+
1095+static bool trans_CLRMAC(DisasContext *ctx, arg_CLRMAC *a)
1096+{
1097+ tcg_gen_movi_i64(cpu_mac, 0);
1098+ return true;
1099+}
1100+
1101+static bool trans_CLRT(DisasContext *ctx, arg_CLRT *a)
1102+{
1103+ tcg_gen_movi_i32(cpu_sr_t, 0);
1104+ return true;
1105+}
1106+
1107+static bool trans_SETT(DisasContext *ctx, arg_SETT *a)
1108+{
1109+ tcg_gen_movi_i32(cpu_sr_t, 1);
1110+ return true;
1111+}
1112+
1113+static bool trans_LDC_r(DisasContext *ctx, arg_LDC_r *a)
1114+{
1115+ CHECK_PRIVILEGED(ctx);
1116+ switch(a->dst) {
1117+ case 0: /* SR */
1118+ gen_write_sr(cpu_regs[REG(ctx, a->rm)]);
1119+ ctx->base.is_jmp = DISAS_STOP;
1120+ break;
1121+ case 1: /* GBR */
1122+ tcg_gen_mov_i32(cpu_gbr, cpu_regs[REG(ctx, a->rm)]);
1123+ break;
1124+ case 2: /* VBR */
1125+ tcg_gen_mov_i32(cpu_vbr, cpu_regs[REG(ctx, a->rm)]);
1126+ break;
1127+ default:
1128+ g_assert_not_reached();
1129+ }
1130+ return true;
1131+}
1132+
1133+static bool trans_LDC_m(DisasContext *ctx, arg_LDC_m *a)
1134+{
1135+ CHECK_PRIVILEGED(ctx);
1136+ switch(a->dst) {
1137+ case 0: { /* SR */
1138+ TCGv val = tcg_temp_new();
1139+ tcg_gen_qemu_ld_i32(val, cpu_regs[REG(ctx, a->rm)],
1140+ ctx->memidx, MO_TE | MO_32);
1141+ gen_write_sr(val);
1142+ tcg_temp_free(val);
1143+ ctx->base.is_jmp = DISAS_STOP;
1144+ break;
1145+ }
1146+ case 1: /* GBR */
1147+ tcg_gen_qemu_ld_i32(cpu_gbr, cpu_regs[REG(ctx, a->rm)],
1148+ ctx->memidx, MO_TE | MO_32);
1149+ break;
1150+ case 2: /* VBR */
1151+ tcg_gen_qemu_ld_i32(cpu_vbr, cpu_regs[REG(ctx, a->rm)],
1152+ ctx->memidx, MO_TE | MO_32);
1153+ break;
1154+ default:
1155+ g_assert_not_reached();
1156+ }
1157+ tcg_gen_addi_i32(cpu_regs[REG(ctx, a->rm)], cpu_regs[REG(ctx, a->rm)], 4);
1158+ return true;
1159+}
1160+
1161+static bool trans_LDS_r(DisasContext *ctx, arg_LDS_r *a)
1162+{
1163+ TCGv temp = tcg_temp_new();
1164+ switch(a->dst) {
1165+ case 0: /* MACH */
1166+ tcg_gen_extrl_i64_i32(temp, cpu_mac);
1167+ tcg_gen_concat_i32_i64(cpu_mac, cpu_regs[REG(ctx, a->rm)], temp);
1168+ break;
1169+ case 1: /* MACL */
1170+ tcg_gen_extrh_i64_i32(temp, cpu_mac);
1171+ tcg_gen_concat_i32_i64(cpu_mac, temp, cpu_regs[REG(ctx, a->rm)]);
1172+ break;
1173+ case 2: /* PR */
1174+ tcg_gen_mov_i32(cpu_pr, cpu_regs[REG(ctx, a->rm)]);
1175+ break;
1176+ default:
1177+ g_assert_not_reached();
1178+ }
1179+ tcg_temp_free(temp);
1180+ return true;
1181+}
1182+
1183+static bool trans_LDS_m(DisasContext *ctx, arg_LDS_m *a)
1184+{
1185+ TCGv hi = tcg_temp_new();
1186+ TCGv lo = tcg_temp_new();
1187+ switch(a->dst) {
1188+ case 0: /* MACH */
1189+ tcg_gen_extrl_i64_i32(lo, cpu_mac);
1190+ tcg_gen_qemu_ld_i32(hi, cpu_regs[REG(ctx, a->rm)],
1191+ ctx->memidx, MO_TE | MO_32);
1192+ tcg_gen_concat_i32_i64(cpu_mac, hi, lo);
1193+ break;
1194+ case 1: /* MACL */
1195+ tcg_gen_extrh_i64_i32(hi, cpu_mac);
1196+ tcg_gen_qemu_ld_i32(lo, cpu_regs[REG(ctx, a->rm)],
1197+ ctx->memidx, MO_TE | MO_32);
1198+ tcg_gen_concat_i32_i64(cpu_mac, hi, lo);
1199+ break;
1200+ case 2: /* PR */
1201+ tcg_gen_qemu_ld_i32(cpu_pr, cpu_regs[REG(ctx, a->rm)],
1202+ ctx->memidx, MO_TE | MO_32);
1203+ break;
1204+ default:
1205+ g_assert_not_reached();
1206+ }
1207+ tcg_gen_addi_i32(cpu_regs[REG(ctx, a->rm)], cpu_regs[REG(ctx, a->rm)], 4);
1208+ tcg_temp_free(hi);
1209+ tcg_temp_free(lo);
1210+ return true;
1211+}
1212+
1213+static bool trans_STC_r(DisasContext *ctx, arg_STC_r *a)
1214+{
1215+ CHECK_PRIVILEGED(ctx);
1216+ switch(a->src) {
1217+ case 0: /* SR */
1218+ gen_read_sr(cpu_regs[REG(ctx, a->rn)]);
1219+ break;
1220+ case 1: /* GBR */
1221+ tcg_gen_mov_i32(cpu_regs[REG(ctx, a->rn)], cpu_gbr);
1222+ break;
1223+ case 2: /* VBR */
1224+ tcg_gen_mov_i32(cpu_regs[REG(ctx, a->rn)], cpu_vbr);
1225+ break;
1226+ default:
1227+ g_assert_not_reached();
1228+ }
1229+ return true;
1230+}
1231+
1232+static bool trans_STC_m(DisasContext *ctx, arg_STC_m *a)
1233+{
1234+ CHECK_PRIVILEGED(ctx);
1235+ tcg_gen_subi_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], 4);
1236+ switch(a->src) {
1237+ case 0: { /* SR */
1238+ TCGv sr = tcg_temp_new();
1239+ gen_read_sr(sr);
1240+ tcg_gen_qemu_st_i32(sr, cpu_regs[REG(ctx, a->rn)],
1241+ ctx->memidx, MO_TE | MO_32);
1242+ tcg_temp_free(sr);
1243+ break;
1244+ }
1245+ case 1: /* GBR */
1246+ tcg_gen_qemu_st_i32(cpu_gbr, cpu_regs[REG(ctx, a->rn)],
1247+ ctx->memidx, MO_TE | MO_32);
1248+ break;
1249+ case 2: /* VBR */
1250+ tcg_gen_qemu_st_i32(cpu_vbr, cpu_regs[REG(ctx, a->rn)],
1251+ ctx->memidx, MO_TE | MO_32);
1252+ break;
1253+ default:
1254+ g_assert_not_reached();
1255+ }
1256+ return true;
1257+}
1258+
1259+static bool trans_STS_r(DisasContext *ctx, arg_STS_r *a)
1260+{
1261+ switch(a->src) {
1262+ case 0: /* MACH */
1263+ tcg_gen_extrh_i64_i32(cpu_regs[a->rn], cpu_mac);
1264+ break;
1265+ case 1: /* MACL */
1266+ tcg_gen_extrl_i64_i32(cpu_regs[a->rn], cpu_mac);
1267+ break;
1268+ case 2: /* PR */
1269+ tcg_gen_mov_i32(cpu_regs[REG(ctx, a->rn)], cpu_pr);
1270+ break;
1271+ default:
1272+ g_assert_not_reached();
1273+ }
1274+ return true;
1275+}
1276+
1277+static bool trans_STS_m(DisasContext *ctx, arg_STS_m *a)
1278+{
1279+ TCGv val = tcg_temp_new();
1280+ tcg_gen_subi_i32(cpu_regs[REG(ctx, a->rn)], cpu_regs[REG(ctx, a->rn)], 4);
1281+ switch(a->src) {
1282+ case 0: /* MACH */
1283+ tcg_gen_extrh_i64_i32(val, cpu_mac);
1284+ tcg_gen_qemu_st_i32(val, cpu_regs[REG(ctx, a->rn)],
1285+ ctx->memidx, MO_TE | MO_32);
1286+ break;
1287+ case 1: /* MACL */
1288+ tcg_gen_extrl_i64_i32(val, cpu_mac);
1289+ tcg_gen_qemu_st_i32(val, cpu_regs[REG(ctx, a->rn)],
1290+ ctx->memidx, MO_TE | MO_32);
1291+ break;
1292+ case 2: /* PR */
1293+ tcg_gen_qemu_st_i32(cpu_pr, cpu_regs[REG(ctx, a->rn)],
1294+ ctx->memidx, MO_TE | MO_32);
1295+ break;
1296+ default:
1297+ g_assert_not_reached();
1298+ }
1299+ tcg_temp_free(val);
1300+ return true;
1301+}
1302+
1303+static bool trans_NOP(DisasContext *ctx, arg_NOP *a)
1304+{
1305+ return true;
1306+}
1307+
1308+static bool trans_TRAPA(DisasContext *ctx, arg_TRAPA *a)
1309+{
1310+ TCGv imm = tcg_const_i32(a->imm);;
1311+ CHECK_NOT_DELAY_SLOT(ctx);
1312+ gen_save_cpu_state(ctx, true);
1313+ gen_helper_trapa(cpu_env, imm);
1314+ tcg_temp_free(imm);
1315+ ctx->base.is_jmp = DISAS_NORETURN;
1316+ return true;
1317+}
1318+
1319+static bool trans_RTE(DisasContext *ctx, arg_RTE *a)
1320+{
1321+ CHECK_PRIVILEGED(ctx);
1322+ CHECK_NOT_DELAY_SLOT(ctx);
1323+ if (IS_SH2(ctx)) {
1324+ /* SH2 */
1325+ TCGv sr = tcg_temp_new();
1326+ tcg_gen_qemu_ld_i32(cpu_delayed_pc, cpu_regs[REG(ctx, R_SP)],
1327+ ctx->memidx, MO_TE | MO_32);
1328+ tcg_gen_addi_i32(cpu_regs[REG(ctx, R_SP)], cpu_regs[REG(ctx, R_SP)], 4);
1329+ tcg_gen_qemu_ld_i32(sr, cpu_regs[REG(ctx, R_SP)],
1330+ ctx->memidx, MO_TE | MO_32);
1331+ tcg_gen_addi_i32(cpu_regs[REG(ctx, R_SP)], cpu_regs[REG(ctx, R_SP)], 4);
1332+ gen_write_sr(sr);
1333+ tcg_temp_free(sr);
1334+ } else {
1335+ /* SH3 / SH4 */
1336+ gen_write_sr(cpu_ssr);
1337+ tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);
1338+ }
1339+ ctx->envflags |= DELAY_SLOT_RTE;
1340+ ctx->delayed_pc = (uint32_t) - 1;
1341+ ctx->base.is_jmp = DISAS_STOP;
1342+
1343+ return true;
1344+}
1345+
1346+static bool trans_SLEEP(DisasContext *ctx, arg_SLEEP *a)
1347+{
1348+ CHECK_PRIVILEGED(ctx);
1349+ tcg_gen_movi_i32(cpu_pc, ctx->base.pc_next);
1350+ gen_helper_sleep(cpu_env);
1351+ return true;
1352+}
1353+
1354+static void sh_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
1355+{
1356+ DisasContext *ctx = container_of(dcbase, DisasContext, base);
1357+ CPUSHState *env = cs->env_ptr;
1358+ uint32_t tbflags;
1359+
1360+ tbflags = ctx->base.tb->flags;
1361+ ctx->envflags = tbflags & TB_FLAG_ENVFLAGS_MASK;
1362+ ctx->features = env->features;
1363+ if (!IS_SH2(ctx)) {
1364+ ctx->memidx = FIELD_EX32(tbflags, SR, MD) == 0 ? 1 : 0;
1365+ ctx->sr_rb = FIELD_EX32(tbflags, SR, RB);
1366+ } else {
1367+ ctx->memidx = 0;
1368+ ctx->sr_rb = 0;
1369+ }
1370+ /* We don't know if the delayed pc came from a dynamic or static branch,
1371+ so assume it is a dynamic branch. */
1372+ ctx->delayed_pc = -1; /* use delayed pc from env pointer */
1373+}
1374+
1375+static void sh_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
1376+{
1377+}
1378+
1379+static void sh_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
1380+{
1381+ DisasContext *ctx = container_of(dcbase, DisasContext, base);
1382+
1383+ tcg_gen_insn_start(ctx->base.pc_next, ctx->envflags);
1384+}
1385+
1386+static bool sh_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
1387+ const CPUBreakpoint *bp)
1388+{
1389+ DisasContext *ctx = container_of(dcbase, DisasContext, base);
1390+
1391+ /* We have hit a breakpoint - make sure PC is up-to-date */
1392+ gen_save_cpu_state(ctx, true);
1393+ gen_helper_debug(cpu_env);
1394+ ctx->base.is_jmp = DISAS_NORETURN;
1395+ /* The address covered by the breakpoint must be included in
1396+ [tb->pc, tb->pc + tb->size) in order to for it to be
1397+ properly cleared -- thus we increment the PC here so that
1398+ the logic setting tb->size below does the right thing. */
1399+ ctx->base.pc_next += 2;
1400+ return true;
1401+}
1402+
1403+static void sh_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
1404+{
1405+ CPUSHState *env = cs->env_ptr;
1406+ DisasContext *ctx = container_of(dcbase, DisasContext, base);
1407+ uint32_t old_flags = ctx->envflags;
1408+ uint32_t insn;
1409+
1410+ insn = cpu_lduw_code(env, ctx->base.pc_next);
1411+ ctx->base.pc_next += 2;
1412+ if (!decode(ctx, insn)) {
1413+ gen_save_cpu_state(ctx, true);
1414+ if (old_flags & DELAY_SLOT_MASK) {
1415+ gen_helper_raise_slot_illegal_instruction(cpu_env);
1416+ } else {
1417+ gen_helper_raise_illegal_instruction(cpu_env);
1418+ }
1419+ }
1420+ if (old_flags & DELAY_SLOT_MASK) {
1421+ /* go out of the delay slot */
1422+ ctx->envflags &= ~DELAY_SLOT_MASK;
1423+
1424+ tcg_gen_movi_i32(cpu_flags, ctx->envflags);
1425+ if (old_flags & DELAY_SLOT_CONDITIONAL) {
1426+ gen_delayed_conditional_jump(ctx);
1427+ } else {
1428+ gen_jump(ctx);
1429+ }
1430+ }
1431+}
1432+
1433+static void sh_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
1434+{
1435+ DisasContext *ctx = container_of(dcbase, DisasContext, base);
1436+
1437+ switch (ctx->base.is_jmp) {
1438+ case DISAS_STOP:
1439+ gen_save_cpu_state(ctx, true);
1440+ if (ctx->base.singlestep_enabled) {
1441+ gen_helper_debug(cpu_env);
1442+ } else {
1443+ tcg_gen_exit_tb(NULL, 0);
1444+ }
1445+ break;
1446+ case DISAS_NEXT:
1447+ case DISAS_TOO_MANY:
1448+ gen_save_cpu_state(ctx, false);
1449+ gen_goto_tb(ctx, 0, ctx->base.pc_next);
1450+ break;
1451+ case DISAS_NORETURN:
1452+ break;
1453+ default:
1454+ g_assert_not_reached();
1455+ }
1456+}
1457+
1458+static void sh_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
1459+{
1460+ qemu_log("IN:\n"); /* , lookup_symbol(dcbase->pc_first)); */
1461+ log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
1462+}
1463+
1464+static const TranslatorOps sh_tr_ops = {
1465+ .init_disas_context = sh_tr_init_disas_context,
1466+ .tb_start = sh_tr_tb_start,
1467+ .insn_start = sh_tr_insn_start,
1468+ .breakpoint_check = sh_tr_breakpoint_check,
1469+ .translate_insn = sh_tr_translate_insn,
1470+ .tb_stop = sh_tr_tb_stop,
1471+ .disas_log = sh_tr_disas_log,
1472+};
1473+
1474+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
1475+{
1476+ DisasContext ctx;
1477+
1478+ translator_loop(&sh_tr_ops, &ctx.base, cs, tb, max_insns);
1479+}
1480+
1481+void restore_state_to_opc(CPUSHState *env, TranslationBlock *tb,
1482+ target_ulong *data)
1483+{
1484+ env->pc = data[0];
1485+ env->flags = data[1];
1486+ /* Theoretically delayed_pc should also be restored. In practice the
1487+ branch instruction is re-executed after exception, so the delayed
1488+ branch target will be recomputed. */
1489+}