/[gxemul]/trunk/src/devices/dev_sh4.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/src/devices/dev_sh4.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 36 - (hide annotations)
Mon Oct 8 16:21:34 2007 UTC (13 years, 3 months ago) by dpavlin
File MIME type: text/plain
File size: 29218 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1497 2007/03/18 03:41:36 debug Exp $
20070224	Minor update to the initialization of the ns16550 in
		machine_walnut.c, to allow that machine type to boot with the
		new interrupt system (although it is still a dummy machine).
		Adding a wdc at 0x14000000 to machine_landisk.c, and fixing
		the SCIF serial interrupts of the SH4 cpu enough to get
		NetBSD/landisk booting from a disk image :-)  Adding a
		preliminary install instruction skeleton to guestoses.html.
20070306	Adding SH-IPL+G PROM emulation, and also passing the "end"
		symbol in r5 on bootup, for Landisk emulation. This is enough
		to get OpenBSD/landisk to install :)  Adding a preliminary
		install instruction skeleton to the documentation. SuperH
		emulation is still shaky, though :-/
20070307	Fixed a strangeness in memory_sh.c (read/write was never
		returned for any page). (Unknown whether this fixes any actual
		problems, though.)
20070308	dev_ram.c fix: invalidate code translations on writes to
		RAM, emulated as separate devices. Linux/dreamcast gets
		further in the boot process than before, but still bugs out
		in userland.
		Fixing bugs in the "stc.l gbr,@-rN" and "ldc.l @rN+,gbr" SuperH 
		instructions (they should NOT check the MD bit), allowing the
		Linux/dreamcast Live CD to reach userland correctly :-)
20070310	Changing the cpu name "Alpha" in src/useremul.c to "21364" to
		unbreak userland syscall emulation of FreeBSD/Alpha binaries.
20070314	Applying a patch from Michael Yaroslavtsev which fixes the
		previous Linux lib64 patch to the configure script.
20070315	Adding a (dummy) sun4v machine type, and SPARC T1 cpu type.
20070316	Creating a new directory, src/disk, and moving diskimage.c
		to it. Separating out bootblock loading stuff from emul.c into
		new files in src/disk.
		Adding some more SPARC registers.
20070318	Preparing/testing for a minirelease, 0.4.4.1.

==============  RELEASE 0.4.4.1  ==============


1 dpavlin 32 /*
2 dpavlin 34 * Copyright (C) 2006-2007 Anders Gavare. All rights reserved.
3 dpavlin 32 *
4     * Redistribution and use in source and binary forms, with or without
5     * modification, are permitted provided that the following conditions are met:
6     *
7     * 1. Redistributions of source code must retain the above copyright
8     * notice, this list of conditions and the following disclaimer.
9     * 2. Redistributions in binary form must reproduce the above copyright
10     * notice, this list of conditions and the following disclaimer in the
11     * documentation and/or other materials provided with the distribution.
12     * 3. The name of the author may not be used to endorse or promote products
13     * derived from this software without specific prior written permission.
14     *
15     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18     * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25     * SUCH DAMAGE.
26     *
27     *
28 dpavlin 36 * $Id: dev_sh4.c,v 1.32 2007/03/16 18:47:26 debug Exp $
29 dpavlin 32 *
30     * SH4 processor specific memory mapped registers (0xf0000000 - 0xffffffff).
31 dpavlin 34 *
32     * TODO: Lots and lots of stuff.
33 dpavlin 32 */
34    
35     #include <stdio.h>
36     #include <stdlib.h>
37     #include <string.h>
38    
39     #include "console.h"
40     #include "cpu.h"
41     #include "device.h"
42     #include "devices.h"
43 dpavlin 34 #include "interrupt.h"
44 dpavlin 32 #include "machine.h"
45     #include "memory.h"
46     #include "misc.h"
47     #include "timer.h"
48    
49     #include "sh4_bscreg.h"
50     #include "sh4_cache.h"
51 dpavlin 34 #include "sh4_dmacreg.h"
52 dpavlin 32 #include "sh4_exception.h"
53     #include "sh4_intcreg.h"
54     #include "sh4_mmu.h"
55 dpavlin 34 #include "sh4_rtcreg.h"
56 dpavlin 32 #include "sh4_scifreg.h"
57     #include "sh4_tmureg.h"
58    
59    
60     #define SH4_REG_BASE 0xff000000
61     #define SH4_TICK_SHIFT 14
62     #define N_SH4_TIMERS 3
63    
64 dpavlin 34 /* General-purpose I/O stuff: */
65     #define SH4_PCTRA 0xff80002c
66     #define SH4_PDTRA 0xff800030
67     #define SH4_PCTRB 0xff800040
68     #define SH4_PDTRB 0xff800044
69     #define SH4_GPIOIC 0xff800048
70    
71     #ifdef UNSTABLE_DEVEL
72     #define SH4_DEGUG
73 dpavlin 32 /* #define debug fatal */
74 dpavlin 34 #endif
75 dpavlin 32
76     struct sh4_data {
77 dpavlin 34 /* SCIF (Serial controller): */
78     uint16_t scif_smr;
79     uint8_t scif_brr;
80     uint16_t scif_scr;
81 dpavlin 36 uint16_t scif_ssr;
82 dpavlin 34 uint16_t scif_fcr;
83 dpavlin 36 int scif_delayed_tx;
84 dpavlin 32 int scif_console_handle;
85 dpavlin 36 struct interrupt scif_tx_irq;
86     struct interrupt scif_rx_irq;
87 dpavlin 32
88     /* Bus State Controller: */
89 dpavlin 34 uint32_t bsc_bcr1;
90     uint16_t bsc_bcr2;
91     uint32_t bsc_wcr1;
92     uint32_t bsc_wcr2;
93     uint32_t bsc_mcr;
94     uint16_t bsc_rtcsr;
95     uint16_t bsc_rtcor;
96     uint16_t bsc_rfcr;
97 dpavlin 32
98 dpavlin 34 /* GPIO: */
99     uint32_t pctra; /* Port Control Register A */
100     uint32_t pdtra; /* Port Data Register A */
101     uint32_t pctrb; /* Port Control Register B */
102     uint32_t pdtrb; /* Port Data Register B */
103    
104     /* SD-RAM: */
105     uint16_t sdmr2;
106     uint16_t sdmr3;
107    
108 dpavlin 32 /* Timer Management Unit: */
109     struct timer *sh4_timer;
110 dpavlin 34 struct interrupt timer_irq[4];
111 dpavlin 32 uint32_t tocr;
112     uint32_t tstr;
113     uint32_t tcnt[N_SH4_TIMERS];
114     uint32_t tcor[N_SH4_TIMERS];
115     uint32_t tcr[N_SH4_TIMERS];
116     int timer_interrupts_pending[N_SH4_TIMERS];
117     double timer_hz[N_SH4_TIMERS];
118 dpavlin 34
119     /* RTC: */
120     uint32_t rtc_reg[14]; /* Excluding rcr1 and 2 */
121     uint8_t rtc_rcr1;
122 dpavlin 32 };
123    
124    
125     #define SH4_PSEUDO_TIMER_HZ 100.0
126    
127    
128     /*
129     * sh4_timer_tick():
130     *
131     * This function is called SH4_PSEUDO_TIMER_HZ times per real-world second.
132     * Its job is to update the SH4 timer counters, and if necessary, increase
133     * the number of pending interrupts.
134 dpavlin 34 *
135     * Also, RAM Refresh is also faked here.
136 dpavlin 32 */
137     static void sh4_timer_tick(struct timer *t, void *extra)
138     {
139     struct sh4_data *d = (struct sh4_data *) extra;
140     int i;
141    
142 dpavlin 34 /* Fake RAM refresh: */
143     d->bsc_rfcr ++;
144     if (d->bsc_rtcsr & (RTCSR_CMIE | RTCSR_OVIE)) {
145     fatal("sh4: RTCSR_CMIE | RTCSR_OVIE: TODO\n");
146     /* TODO: Implement refresh interrupts etc. */
147     exit(1);
148     }
149    
150 dpavlin 36 /* Timer interrupts: */
151 dpavlin 32 for (i=0; i<N_SH4_TIMERS; i++) {
152     int32_t old = d->tcnt[i];
153    
154     /* printf("tcnt[%i] = %08x tcor[%i] = %08x\n",
155     i, d->tcnt[i], i, d->tcor[i]); */
156    
157     /* Only update timers that are currently started: */
158     if (!(d->tstr & (TSTR_STR0 << i)))
159     continue;
160    
161     /* Update the current count: */
162     d->tcnt[i] -= d->timer_hz[i] / SH4_PSEUDO_TIMER_HZ;
163    
164     /* Has the timer underflowed? */
165     if ((int32_t)d->tcnt[i] < 0 && old >= 0) {
166     d->tcr[i] |= TCR_UNF;
167    
168     if (d->tcr[i] & TCR_UNIE)
169     d->timer_interrupts_pending[i] ++;
170    
171     /*
172     * Set tcnt[i] to tcor[i]. Note: Since this function
173     * is only called now and then, adding tcor[i] to
174     * tcnt[i] produces more correct values for long
175     * running timers.
176     */
177     d->tcnt[i] += d->tcor[i];
178    
179     /* At least make sure that tcnt is non-negative... */
180     if ((int32_t)d->tcnt[i] < 0)
181     d->tcnt[i] = 0;
182     }
183     }
184     }
185    
186    
187 dpavlin 36 static void scif_reassert_interrupts(struct sh4_data *d)
188     {
189     if (d->scif_scr & SCSCR2_RIE) {
190     if (d->scif_ssr & SCSSR2_DR)
191     INTERRUPT_ASSERT(d->scif_rx_irq);
192     } else {
193     INTERRUPT_DEASSERT(d->scif_rx_irq);
194     }
195     if (d->scif_scr & SCSCR2_TIE) {
196     if (d->scif_ssr & (SCSSR2_TDFE | SCSSR2_TEND))
197     INTERRUPT_ASSERT(d->scif_tx_irq);
198     } else {
199     INTERRUPT_DEASSERT(d->scif_tx_irq);
200     }
201     }
202    
203    
204 dpavlin 32 DEVICE_TICK(sh4)
205     {
206     struct sh4_data *d = (struct sh4_data *) extra;
207     int i;
208    
209 dpavlin 36 /* Serial controller interrupts: */
210     /* TODO: Which bits go to which interrupt? */
211     if (console_charavail(d->scif_console_handle))
212     d->scif_ssr |= SCSSR2_DR;
213     else
214     d->scif_ssr &= SCSSR2_DR;
215     if (d->scif_delayed_tx) {
216     if (--d->scif_delayed_tx == 0)
217     d->scif_ssr |= SCSSR2_TDFE | SCSSR2_TEND;
218     }
219    
220     scif_reassert_interrupts(d);
221    
222     /* Timer interrupts: */
223 dpavlin 32 for (i=0; i<N_SH4_TIMERS; i++)
224     if (d->timer_interrupts_pending[i] > 0) {
225 dpavlin 34 INTERRUPT_ASSERT(d->timer_irq[i]);
226 dpavlin 32 d->tcr[i] |= TCR_UNF;
227     }
228     }
229    
230    
231     DEVICE_ACCESS(sh4_itlb_aa)
232     {
233     uint64_t idata = 0, odata = 0;
234     int e = (relative_addr & SH4_ITLB_E_MASK) >> SH4_ITLB_E_SHIFT;
235    
236     if (writeflag == MEM_WRITE) {
237     int safe_to_invalidate = 0;
238     uint32_t old_hi = cpu->cd.sh.itlb_hi[e];
239     if ((cpu->cd.sh.itlb_lo[e] & SH4_PTEL_SZ_MASK)==SH4_PTEL_SZ_4K)
240     safe_to_invalidate = 1;
241    
242     idata = memory_readmax64(cpu, data, len);
243     cpu->cd.sh.itlb_hi[e] &=
244     ~(SH4_PTEH_VPN_MASK | SH4_PTEH_ASID_MASK);
245     cpu->cd.sh.itlb_hi[e] |= (idata &
246     (SH4_ITLB_AA_VPN_MASK | SH4_ITLB_AA_ASID_MASK));
247     cpu->cd.sh.itlb_lo[e] &= ~SH4_PTEL_V;
248     if (idata & SH4_ITLB_AA_V)
249     cpu->cd.sh.itlb_lo[e] |= SH4_PTEL_V;
250    
251 dpavlin 34 /* Invalidate if this ITLB entry previously belonged to the
252     currently running process, or if it was shared: */
253     if (cpu->cd.sh.ptel & SH4_PTEL_SH ||
254     (old_hi & SH4_ITLB_AA_ASID_MASK) ==
255     (cpu->cd.sh.pteh & SH4_PTEH_ASID_MASK)) {
256     if (safe_to_invalidate)
257     cpu->invalidate_translation_caches(cpu,
258     old_hi & ~0xfff, INVALIDATE_VADDR);
259     else
260     cpu->invalidate_translation_caches(cpu,
261     0, INVALIDATE_ALL);
262     }
263 dpavlin 32 } else {
264     odata = cpu->cd.sh.itlb_hi[e] &
265     (SH4_ITLB_AA_VPN_MASK | SH4_ITLB_AA_ASID_MASK);
266     if (cpu->cd.sh.itlb_lo[e] & SH4_PTEL_V)
267     odata |= SH4_ITLB_AA_V;
268     memory_writemax64(cpu, data, len, odata);
269     }
270    
271     return 1;
272     }
273    
274    
275     DEVICE_ACCESS(sh4_itlb_da1)
276     {
277     uint32_t mask = SH4_PTEL_SH | SH4_PTEL_C | SH4_PTEL_SZ_MASK |
278     SH4_PTEL_PR_MASK | SH4_PTEL_V | 0x1ffffc00;
279     uint64_t idata = 0, odata = 0;
280     int e = (relative_addr & SH4_ITLB_E_MASK) >> SH4_ITLB_E_SHIFT;
281    
282     if (relative_addr & 0x800000) {
283     fatal("sh4_itlb_da1: TODO: da2 area\n");
284     exit(1);
285     }
286    
287     if (writeflag == MEM_WRITE) {
288 dpavlin 34 uint32_t old_lo = cpu->cd.sh.itlb_lo[e];
289 dpavlin 32 int safe_to_invalidate = 0;
290     if ((cpu->cd.sh.itlb_lo[e] & SH4_PTEL_SZ_MASK)==SH4_PTEL_SZ_4K)
291     safe_to_invalidate = 1;
292    
293     idata = memory_readmax64(cpu, data, len);
294     cpu->cd.sh.itlb_lo[e] &= ~mask;
295     cpu->cd.sh.itlb_lo[e] |= (idata & mask);
296    
297 dpavlin 34 /* Invalidate if this ITLB entry belongs to the
298     currently running process, or if it was shared: */
299     if (old_lo & SH4_PTEL_SH ||
300     (cpu->cd.sh.itlb_hi[e] & SH4_ITLB_AA_ASID_MASK) ==
301     (cpu->cd.sh.pteh & SH4_PTEH_ASID_MASK)) {
302     if (safe_to_invalidate)
303     cpu->invalidate_translation_caches(cpu,
304     cpu->cd.sh.itlb_hi[e] & ~0xfff,
305     INVALIDATE_VADDR);
306     else
307     cpu->invalidate_translation_caches(cpu,
308     0, INVALIDATE_ALL);
309     }
310 dpavlin 32 } else {
311     odata = cpu->cd.sh.itlb_lo[e] & mask;
312     memory_writemax64(cpu, data, len, odata);
313     }
314    
315     return 1;
316     }
317    
318    
319     DEVICE_ACCESS(sh4_utlb_aa)
320     {
321     uint64_t idata = 0, odata = 0;
322     int i, e = (relative_addr & SH4_UTLB_E_MASK) >> SH4_UTLB_E_SHIFT;
323     int a = relative_addr & SH4_UTLB_A;
324    
325     if (writeflag == MEM_WRITE) {
326     int n_hits = 0;
327     int safe_to_invalidate = 0;
328     uint32_t vaddr_to_invalidate = 0;
329    
330     idata = memory_readmax64(cpu, data, len);
331     if (a) {
332     for (i=-SH_N_ITLB_ENTRIES; i<SH_N_UTLB_ENTRIES; i++) {
333     uint32_t lo, hi;
334     uint32_t mask = 0xfffff000;
335     int sh;
336    
337     if (i < 0) {
338     lo = cpu->cd.sh.itlb_lo[
339     i + SH_N_ITLB_ENTRIES];
340     hi = cpu->cd.sh.itlb_hi[
341     i + SH_N_ITLB_ENTRIES];
342     } else {
343     lo = cpu->cd.sh.utlb_lo[i];
344     hi = cpu->cd.sh.utlb_hi[i];
345     }
346    
347     sh = lo & SH4_PTEL_SH;
348     if (!(lo & SH4_PTEL_V))
349     continue;
350    
351     switch (lo & SH4_PTEL_SZ_MASK) {
352     case SH4_PTEL_SZ_1K: mask = 0xfffffc00; break;
353     case SH4_PTEL_SZ_64K: mask = 0xffff0000; break;
354     case SH4_PTEL_SZ_1M: mask = 0xfff00000; break;
355     }
356    
357     if ((hi & mask) != (idata & mask))
358     continue;
359    
360     if ((lo & SH4_PTEL_SZ_MASK) ==
361     SH4_PTEL_SZ_4K) {
362     safe_to_invalidate = 1;
363     vaddr_to_invalidate = hi & mask;
364     }
365    
366     if (!sh && (hi & SH4_PTEH_ASID_MASK) !=
367     (cpu->cd.sh.pteh & SH4_PTEH_ASID_MASK))
368     continue;
369    
370     if (i < 0) {
371     cpu->cd.sh.itlb_lo[i] &= ~SH4_PTEL_V;
372     if (idata & SH4_UTLB_AA_V)
373     cpu->cd.sh.itlb_lo[i] |=
374     SH4_PTEL_V;
375     } else {
376     cpu->cd.sh.utlb_lo[i] &=
377     ~(SH4_PTEL_D | SH4_PTEL_V);
378     if (idata & SH4_UTLB_AA_D)
379     cpu->cd.sh.utlb_lo[i] |=
380     SH4_PTEL_D;
381     if (idata & SH4_UTLB_AA_V)
382     cpu->cd.sh.utlb_lo[i] |=
383     SH4_PTEL_V;
384     }
385    
386     if (i >= 0)
387     n_hits ++;
388     }
389    
390     if (n_hits > 1)
391     sh_exception(cpu,
392     EXPEVT_RESET_TLB_MULTI_HIT, 0, 0);
393     } else {
394     if ((cpu->cd.sh.utlb_lo[e] & SH4_PTEL_SZ_MASK) ==
395     SH4_PTEL_SZ_4K) {
396     safe_to_invalidate = 1;
397     vaddr_to_invalidate =
398     cpu->cd.sh.utlb_hi[e] & ~0xfff;
399     }
400    
401     cpu->cd.sh.utlb_hi[e] &=
402     ~(SH4_PTEH_VPN_MASK | SH4_PTEH_ASID_MASK);
403     cpu->cd.sh.utlb_hi[e] |= (idata &
404     (SH4_UTLB_AA_VPN_MASK | SH4_UTLB_AA_ASID_MASK));
405    
406     cpu->cd.sh.utlb_lo[e] &= ~(SH4_PTEL_D | SH4_PTEL_V);
407     if (idata & SH4_UTLB_AA_D)
408     cpu->cd.sh.utlb_lo[e] |= SH4_PTEL_D;
409     if (idata & SH4_UTLB_AA_V)
410     cpu->cd.sh.utlb_lo[e] |= SH4_PTEL_V;
411     }
412    
413     if (safe_to_invalidate)
414     cpu->invalidate_translation_caches(cpu,
415     vaddr_to_invalidate, INVALIDATE_VADDR);
416     else
417 dpavlin 34 cpu->invalidate_translation_caches(cpu, 0,
418     INVALIDATE_ALL);
419 dpavlin 32 } else {
420     odata = cpu->cd.sh.utlb_hi[e] &
421     (SH4_UTLB_AA_VPN_MASK | SH4_UTLB_AA_ASID_MASK);
422     if (cpu->cd.sh.utlb_lo[e] & SH4_PTEL_D)
423     odata |= SH4_UTLB_AA_D;
424     if (cpu->cd.sh.utlb_lo[e] & SH4_PTEL_V)
425     odata |= SH4_UTLB_AA_V;
426     memory_writemax64(cpu, data, len, odata);
427     }
428    
429     return 1;
430     }
431    
432    
433     DEVICE_ACCESS(sh4_utlb_da1)
434     {
435     uint32_t mask = SH4_PTEL_WT | SH4_PTEL_SH | SH4_PTEL_D | SH4_PTEL_C
436     | SH4_PTEL_SZ_MASK | SH4_PTEL_PR_MASK | SH4_PTEL_V | 0x1ffffc00;
437     uint64_t idata = 0, odata = 0;
438     int e = (relative_addr & SH4_UTLB_E_MASK) >> SH4_UTLB_E_SHIFT;
439    
440     if (relative_addr & 0x800000) {
441     fatal("sh4_utlb_da1: TODO: da2 area\n");
442     exit(1);
443     }
444    
445     if (writeflag == MEM_WRITE) {
446 dpavlin 34 uint32_t old_lo = cpu->cd.sh.utlb_lo[e];
447 dpavlin 32 int safe_to_invalidate = 0;
448     if ((cpu->cd.sh.utlb_lo[e] & SH4_PTEL_SZ_MASK)==SH4_PTEL_SZ_4K)
449     safe_to_invalidate = 1;
450    
451     idata = memory_readmax64(cpu, data, len);
452     cpu->cd.sh.utlb_lo[e] &= ~mask;
453     cpu->cd.sh.utlb_lo[e] |= (idata & mask);
454    
455 dpavlin 34 /* Invalidate if this UTLB entry belongs to the
456     currently running process, or if it was shared: */
457     if (old_lo & SH4_PTEL_SH ||
458     (cpu->cd.sh.utlb_hi[e] & SH4_ITLB_AA_ASID_MASK) ==
459     (cpu->cd.sh.pteh & SH4_PTEH_ASID_MASK)) {
460     if (safe_to_invalidate)
461     cpu->invalidate_translation_caches(cpu,
462     cpu->cd.sh.utlb_hi[e] & ~0xfff,
463     INVALIDATE_VADDR);
464     else
465     cpu->invalidate_translation_caches(cpu,
466     0, INVALIDATE_ALL);
467     }
468 dpavlin 32 } else {
469     odata = cpu->cd.sh.utlb_lo[e] & mask;
470     memory_writemax64(cpu, data, len, odata);
471     }
472    
473     return 1;
474     }
475    
476    
477     DEVICE_ACCESS(sh4)
478     {
479     struct sh4_data *d = (struct sh4_data *) extra;
480     uint64_t idata = 0, odata = 0;
481 dpavlin 34 int timer_nr = 0, dma_channel = 0;
482 dpavlin 32
483     if (writeflag == MEM_WRITE)
484     idata = memory_readmax64(cpu, data, len);
485    
486     relative_addr += SH4_REG_BASE;
487    
488 dpavlin 34 /* SD-RAM access uses address only: */
489     if (relative_addr >= 0xff900000 && relative_addr <= 0xff97ffff) {
490     /* Possibly not 100% correct... TODO */
491     int v = (relative_addr >> 2) & 0xffff;
492     if (relative_addr & 0x00040000)
493     d->sdmr3 = v;
494     else
495     d->sdmr2 = v;
496     debug("[ sh4: sdmr%i set to 0x%04"PRIx16" ]\n",
497     relative_addr & 0x00040000? 3 : 2, v);
498     return 1;
499     }
500    
501    
502 dpavlin 32 switch (relative_addr) {
503    
504     /*************************************************/
505    
506     case SH4_PVR_ADDR:
507     odata = cpu->cd.sh.cpu_type.pvr;
508     break;
509    
510     case SH4_PRR_ADDR:
511     odata = cpu->cd.sh.cpu_type.prr;
512     break;
513    
514     case SH4_PTEH:
515     if (writeflag == MEM_READ)
516     odata = cpu->cd.sh.pteh;
517     else {
518     int old_asid = cpu->cd.sh.pteh & SH4_PTEH_ASID_MASK;
519     cpu->cd.sh.pteh = idata;
520    
521     if ((idata & SH4_PTEH_ASID_MASK) != old_asid) {
522 dpavlin 34 /*
523     * TODO: Don't invalidate everything,
524     * only those pages that belonged to the
525     * old asid.
526     */
527 dpavlin 32 cpu->invalidate_translation_caches(
528     cpu, 0, INVALIDATE_ALL);
529     }
530     }
531     break;
532    
533     case SH4_PTEL:
534     if (writeflag == MEM_READ)
535     odata = cpu->cd.sh.ptel;
536     else
537     cpu->cd.sh.ptel = idata;
538     break;
539    
540     case SH4_TTB:
541     if (writeflag == MEM_READ)
542     odata = cpu->cd.sh.ttb;
543     else
544     cpu->cd.sh.ttb = idata;
545     break;
546    
547     case SH4_TEA:
548     if (writeflag == MEM_READ)
549     odata = cpu->cd.sh.tea;
550     else
551     cpu->cd.sh.tea = idata;
552     break;
553    
554     case SH4_PTEA:
555     if (writeflag == MEM_READ)
556     odata = cpu->cd.sh.ptea;
557     else
558     cpu->cd.sh.ptea = idata;
559     break;
560    
561     case SH4_MMUCR:
562     if (writeflag == MEM_READ) {
563     odata = cpu->cd.sh.mmucr;
564     } else {
565     if (idata & SH4_MMUCR_TI) {
566     /* TLB invalidate. */
567 dpavlin 34 int i;
568     for (i = 0; i < SH_N_ITLB_ENTRIES; i++)
569     cpu->cd.sh.itlb_lo[i] &=
570     ~SH4_PTEL_V;
571 dpavlin 32
572 dpavlin 34 for (i = 0; i < SH_N_UTLB_ENTRIES; i++)
573     cpu->cd.sh.utlb_lo[i] &=
574     ~SH4_PTEL_V;
575    
576 dpavlin 32 cpu->invalidate_translation_caches(cpu,
577     0, INVALIDATE_ALL);
578    
579     /* Should always read back as 0. */
580     idata &= ~SH4_MMUCR_TI;
581     }
582    
583     cpu->cd.sh.mmucr = idata;
584     }
585     break;
586    
587     case SH4_CCR:
588     if (writeflag == MEM_READ) {
589     odata = cpu->cd.sh.ccr;
590     } else {
591     cpu->cd.sh.ccr = idata;
592     }
593     break;
594    
595     case SH4_QACR0:
596     if (writeflag == MEM_READ) {
597     odata = cpu->cd.sh.qacr0;
598     } else {
599     cpu->cd.sh.qacr0 = idata;
600     }
601     break;
602    
603     case SH4_QACR1:
604     if (writeflag == MEM_READ) {
605     odata = cpu->cd.sh.qacr1;
606     } else {
607     cpu->cd.sh.qacr1 = idata;
608     }
609     break;
610    
611     case SH4_TRA:
612     if (writeflag == MEM_READ)
613     odata = cpu->cd.sh.tra;
614     else
615     cpu->cd.sh.tra = idata;
616     break;
617    
618     case SH4_EXPEVT:
619     if (writeflag == MEM_READ)
620     odata = cpu->cd.sh.expevt;
621     else
622     cpu->cd.sh.expevt = idata;
623     break;
624    
625     case SH4_INTEVT:
626     if (writeflag == MEM_READ)
627     odata = cpu->cd.sh.intevt;
628     else
629     cpu->cd.sh.intevt = idata;
630     break;
631    
632    
633     /********************************/
634     /* UBC: User Break Controller */
635    
636     case 0xff200008: /* SH4_BBRA */
637     /* TODO */
638     break;
639    
640    
641     /********************************/
642     /* TMU: Timer Management Unit */
643    
644     case SH4_TOCR:
645     /* Timer Output Control Register */
646     if (writeflag == MEM_WRITE) {
647     d->tocr = idata;
648     if (idata & TOCR_TCOE)
649     fatal("[ sh4 timer: TCOE not yet "
650     "implemented ]\n");
651     } else {
652     odata = d->tocr;
653     }
654     break;
655    
656     case SH4_TSTR:
657     /* Timer Start Register */
658     if (writeflag == MEM_READ) {
659     odata = d->tstr;
660     } else {
661     if (idata & 1 && !(d->tstr & 1))
662     debug("[ sh4 timer: starting timer 0 ]\n");
663     if (idata & 2 && !(d->tstr & 2))
664     debug("[ sh4 timer: starting timer 1 ]\n");
665     if (idata & 4 && !(d->tstr & 4))
666     debug("[ sh4 timer: starting timer 2 ]\n");
667     if (!(idata & 1) && d->tstr & 1)
668     debug("[ sh4 timer: stopping timer 0 ]\n");
669     if (!(idata & 2) && d->tstr & 2)
670     debug("[ sh4 timer: stopping timer 1 ]\n");
671     if (!(idata & 4) && d->tstr & 4)
672     debug("[ sh4 timer: stopping timer 2 ]\n");
673     d->tstr = idata;
674     }
675     break;
676    
677     case SH4_TCOR2:
678     timer_nr ++;
679     case SH4_TCOR1:
680     timer_nr ++;
681     case SH4_TCOR0:
682     /* Timer Constant Register */
683     if (writeflag == MEM_READ)
684     odata = d->tcor[timer_nr];
685     else
686     d->tcor[timer_nr] = idata;
687     break;
688    
689     case SH4_TCNT2:
690     timer_nr ++;
691     case SH4_TCNT1:
692     timer_nr ++;
693     case SH4_TCNT0:
694     /* Timer Counter Register */
695     if (writeflag == MEM_READ)
696     odata = d->tcnt[timer_nr];
697     else
698     d->tcnt[timer_nr] = idata;
699     break;
700    
701     case SH4_TCR2:
702     timer_nr ++;
703     case SH4_TCR1:
704     timer_nr ++;
705     case SH4_TCR0:
706     /* Timer Control Register */
707     if (writeflag == MEM_READ) {
708     odata = d->tcr[timer_nr];
709     } else {
710     if (cpu->cd.sh.pclock == 0) {
711     fatal("INTERNAL ERROR: pclock must be set"
712     " for this machine. Aborting.\n");
713     exit(1);
714     }
715    
716     switch (idata & 3) {
717     case TCR_TPSC_P4:
718     d->timer_hz[timer_nr] = cpu->cd.sh.pclock/4.0;
719     break;
720     case TCR_TPSC_P16:
721     d->timer_hz[timer_nr] = cpu->cd.sh.pclock/16.0;
722     break;
723     case TCR_TPSC_P64:
724     d->timer_hz[timer_nr] = cpu->cd.sh.pclock/64.0;
725     break;
726     case TCR_TPSC_P256:
727     d->timer_hz[timer_nr] = cpu->cd.sh.pclock/256.0;
728     break;
729     }
730    
731     debug("[ sh4 timer %i clock set to %f Hz ]\n",
732     timer_nr, d->timer_hz[timer_nr]);
733    
734     if (idata & (TCR_ICPF | TCR_ICPE1 | TCR_ICPE0 |
735     TCR_CKEG1 | TCR_CKEG0 | TCR_TPSC2)) {
736     fatal("Unimplemented SH4 timer control"
737     " bits: 0x%08"PRIx32". Aborting.\n",
738     (int) idata);
739     exit(1);
740     }
741    
742     if (d->tcr[timer_nr] & TCR_UNF && !(idata & TCR_UNF)) {
743 dpavlin 34 INTERRUPT_DEASSERT(d->timer_irq[timer_nr]);
744 dpavlin 32 if (d->timer_interrupts_pending[timer_nr] > 0)
745     d->timer_interrupts_pending[timer_nr]--;
746     }
747    
748     d->tcr[timer_nr] = idata;
749     }
750     break;
751    
752    
753     /*************************************************/
754 dpavlin 34 /* DMAC: DMA Controller */
755    
756     case SH4_SAR3:
757     dma_channel ++;
758     case SH4_SAR2:
759     dma_channel ++;
760     case SH4_SAR1:
761     dma_channel ++;
762     case SH4_SAR0:
763     dma_channel ++;
764     if (writeflag == MEM_READ)
765     odata = cpu->cd.sh.dmac_sar[dma_channel];
766     else
767     cpu->cd.sh.dmac_sar[dma_channel] = idata;
768     break;
769    
770     case SH4_DAR3:
771     dma_channel ++;
772     case SH4_DAR2:
773     dma_channel ++;
774     case SH4_DAR1:
775     dma_channel ++;
776     case SH4_DAR0:
777     dma_channel ++;
778     if (writeflag == MEM_READ)
779     odata = cpu->cd.sh.dmac_dar[dma_channel];
780     else
781     cpu->cd.sh.dmac_dar[dma_channel] = idata;
782     break;
783    
784     case SH4_DMATCR3:
785     dma_channel ++;
786     case SH4_DMATCR2:
787     dma_channel ++;
788     case SH4_DMATCR1:
789     dma_channel ++;
790     case SH4_DMATCR0:
791     dma_channel ++;
792     if (writeflag == MEM_READ)
793     odata = cpu->cd.sh.dmac_tcr[dma_channel] & 0x00ffffff;
794     else {
795     if (idata & ~0x00ffffff) {
796     fatal("[ SH4 DMA: Attempt to set top 8 "
797     "bits of the count register? 0x%08"
798     PRIx32" ]\n", (uint32_t) idata);
799     exit(1);
800     }
801    
802     /* Special case: writing 0 to the count register
803     means 16777216: */
804     if (idata == 0)
805     idata = 0x01000000;
806     cpu->cd.sh.dmac_tcr[dma_channel] = idata;
807     }
808     break;
809    
810     case SH4_CHCR3:
811     dma_channel ++;
812     case SH4_CHCR2:
813     dma_channel ++;
814     case SH4_CHCR1:
815     dma_channel ++;
816     case SH4_CHCR0:
817     dma_channel ++;
818     if (writeflag == MEM_READ)
819     odata = cpu->cd.sh.dmac_chcr[dma_channel];
820     else {
821     /* IP.BIN sets this to 0x12c0, and I want to know if
822     some other guest OS uses other values. */
823     if (idata != 0x12c0) {
824     fatal("[ SH4 DMA: Attempt to set chcr "
825     "to 0x%08"PRIx32" ]\n", (uint32_t) idata);
826     exit(1);
827     }
828    
829     cpu->cd.sh.dmac_chcr[dma_channel] = idata;
830     }
831     break;
832    
833    
834     /*************************************************/
835 dpavlin 32 /* BSC: Bus State Controller */
836    
837 dpavlin 34 case SH4_BCR1:
838     if (writeflag == MEM_WRITE)
839     d->bsc_bcr1 = idata & 0x033efffd;
840     else {
841     odata = d->bsc_bcr1;
842     if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
843     odata |= BCR1_LITTLE_ENDIAN;
844     }
845 dpavlin 32 break;
846    
847 dpavlin 34 case SH4_BCR2:
848     if (len != sizeof(uint16_t)) {
849     fatal("Non-16-bit SH4_BCR2 access?\n");
850     exit(1);
851     }
852     if (writeflag == MEM_WRITE)
853     d->bsc_bcr2 = idata & 0x3ffd;
854     else
855     odata = d->bsc_bcr2;
856     break;
857    
858     case SH4_WCR1:
859     if (writeflag == MEM_WRITE)
860     d->bsc_wcr1 = idata & 0x77777777;
861     else
862     odata = d->bsc_wcr1;
863     break;
864    
865     case SH4_WCR2:
866     if (writeflag == MEM_WRITE)
867     d->bsc_wcr2 = idata & 0xfffeefff;
868     else
869     odata = d->bsc_wcr2;
870     break;
871    
872     case SH4_MCR:
873     if (writeflag == MEM_WRITE)
874     d->bsc_mcr = idata & 0xf8bbffff;
875     else
876     odata = d->bsc_mcr;
877     break;
878    
879     case SH4_RTCSR:
880 dpavlin 32 /*
881 dpavlin 34 * Refresh Time Control/Status Register. Called RTCSR in
882     * NetBSD, but RTSCR in the SH7750 manual?
883 dpavlin 32 */
884     if (writeflag == MEM_WRITE) {
885 dpavlin 34 idata &= 0x00ff;
886     if (idata & RTCSR_CMF) {
887     idata = (idata & ~RTCSR_CMF)
888     | (d->bsc_rtcsr & RTCSR_CMF);
889     }
890     d->bsc_rtcsr = idata & 0x00ff;
891 dpavlin 32 } else
892 dpavlin 34 odata = d->bsc_rtcsr;
893 dpavlin 32 break;
894    
895 dpavlin 34 case SH4_RTCOR:
896     /* Refresh Time Constant Register (8 bits): */
897 dpavlin 32 if (writeflag == MEM_WRITE)
898 dpavlin 34 d->bsc_rtcor = idata & 0x00ff;
899     else
900     odata = d->bsc_rtcor & 0x00ff;
901     break;
902 dpavlin 32
903 dpavlin 34 case SH4_RFCR:
904     /* Refresh Count Register (10 bits): */
905     if (writeflag == MEM_WRITE)
906     d->bsc_rfcr = idata & 0x03ff;
907     else
908     odata = d->bsc_rfcr & 0x03ff;
909     break;
910    
911    
912     /*******************************************/
913     /* GPIO: General-purpose I/O controller */
914    
915     case SH4_PCTRA:
916     if (writeflag == MEM_WRITE)
917     d->pctra = idata;
918     else
919     odata = d->pctra;
920     break;
921    
922     case SH4_PDTRA:
923     if (writeflag == MEM_WRITE) {
924     debug("[ sh4: pdtra: write: TODO ]\n");
925     d->pdtra = idata;
926     } else {
927     debug("[ sh4: pdtra: read: TODO ]\n");
928     odata = d->pdtra;
929 dpavlin 32 }
930     break;
931    
932 dpavlin 34 case SH4_PCTRB:
933     if (writeflag == MEM_WRITE)
934     d->pctrb = idata;
935     else
936     odata = d->pctrb;
937     break;
938 dpavlin 32
939 dpavlin 34 case SH4_PDTRB:
940     if (writeflag == MEM_WRITE) {
941     debug("[ sh4: pdtrb: write: TODO ]\n");
942     d->pdtrb = idata;
943     } else {
944     debug("[ sh4: pdtrb: read: TODO ]\n");
945     odata = d->pdtrb;
946     }
947     break;
948    
949    
950 dpavlin 32 /*********************************/
951     /* INTC: Interrupt Controller */
952    
953     case SH4_ICR:
954     if (writeflag == MEM_WRITE) {
955     if (idata & 0x80) {
956     fatal("SH4 INTC: IRLM not yet "
957     "supported. TODO\n");
958     exit(1);
959     }
960     }
961     break;
962    
963     case SH4_IPRA:
964     if (writeflag == MEM_READ)
965     odata = cpu->cd.sh.intc_ipra;
966     else
967     cpu->cd.sh.intc_ipra = idata;
968     break;
969    
970     case SH4_IPRB:
971     if (writeflag == MEM_READ)
972     odata = cpu->cd.sh.intc_iprb;
973     else
974     cpu->cd.sh.intc_iprb = idata;
975     break;
976    
977     case SH4_IPRC:
978     if (writeflag == MEM_READ)
979     odata = cpu->cd.sh.intc_iprc;
980     else
981     cpu->cd.sh.intc_iprc = idata;
982     break;
983    
984 dpavlin 34 case SH4_IPRD:
985     if (writeflag == MEM_READ)
986     odata = cpu->cd.sh.intc_iprd;
987     else
988     cpu->cd.sh.intc_iprd = idata;
989     break;
990 dpavlin 32
991 dpavlin 34
992 dpavlin 32 /*************************************************/
993     /* SCIF: Serial Controller Interface with FIFO */
994    
995 dpavlin 34 case SH4_SCIF_BASE + SCIF_SMR:
996     if (writeflag == MEM_WRITE) {
997     d->scif_smr = idata;
998     } else {
999     odata = d->scif_smr;
1000     }
1001     break;
1002    
1003     case SH4_SCIF_BASE + SCIF_BRR:
1004     if (writeflag == MEM_WRITE) {
1005     d->scif_brr = idata;
1006     } else {
1007     odata = d->scif_brr;
1008     }
1009     break;
1010    
1011     case SH4_SCIF_BASE + SCIF_SCR:
1012     if (writeflag == MEM_WRITE) {
1013     d->scif_scr = idata;
1014 dpavlin 36 scif_reassert_interrupts(d);
1015 dpavlin 34 } else {
1016     odata = d->scif_scr;
1017     }
1018     break;
1019    
1020 dpavlin 32 case SH4_SCIF_BASE + SCIF_FTDR:
1021 dpavlin 36 if (writeflag == MEM_WRITE) {
1022 dpavlin 32 console_putchar(d->scif_console_handle, idata);
1023 dpavlin 36 d->scif_delayed_tx = 1;
1024     }
1025 dpavlin 32 break;
1026    
1027     case SH4_SCIF_BASE + SCIF_SSR:
1028 dpavlin 36 if (writeflag == MEM_READ) {
1029     odata = d->scif_ssr;
1030     } else {
1031     d->scif_ssr &= ~idata;
1032     scif_reassert_interrupts(d);
1033     }
1034 dpavlin 32 break;
1035    
1036     case SH4_SCIF_BASE + SCIF_FRDR:
1037     {
1038     int x = console_readchar(d->scif_console_handle);
1039     if (x == 13)
1040     x = 10;
1041     odata = x < 0? 0 : x;
1042 dpavlin 36 d->scif_ssr &= ~SCSSR2_DR;
1043 dpavlin 32 }
1044     break;
1045    
1046 dpavlin 34 case SH4_SCIF_BASE + SCIF_FCR:
1047     if (writeflag == MEM_WRITE) {
1048     d->scif_fcr = idata;
1049     } else {
1050     odata = d->scif_fcr;
1051     }
1052     break;
1053    
1054 dpavlin 32 case SH4_SCIF_BASE + SCIF_FDR:
1055     odata = console_charavail(d->scif_console_handle);
1056     break;
1057    
1058 dpavlin 34
1059 dpavlin 32 /*************************************************/
1060    
1061 dpavlin 34 case SH4_RSECCNT:
1062     case SH4_RMINCNT:
1063     case SH4_RHRCNT:
1064     case SH4_RWKCNT:
1065     case SH4_RDAYCNT:
1066     case SH4_RMONCNT:
1067     case SH4_RYRCNT:
1068     case SH4_RSECAR:
1069     case SH4_RMINAR:
1070     case SH4_RHRAR:
1071     case SH4_RWKAR:
1072     case SH4_RDAYAR:
1073     case SH4_RMONAR:
1074     if (writeflag == MEM_WRITE) {
1075     d->rtc_reg[(relative_addr - 0xffc80000) / 4] = idata;
1076     } else {
1077     /* TODO: Update rtc_reg based on host's date/time. */
1078     odata = d->rtc_reg[(relative_addr - 0xffc80000) / 4];
1079     }
1080     break;
1081    
1082     case SH4_RCR1:
1083     if (writeflag == MEM_READ)
1084     odata = d->rtc_rcr1;
1085     else {
1086     d->rtc_rcr1 = idata;
1087     if (idata & 0x18) {
1088     fatal("SH4: TODO: RTC interrupt enable\n");
1089     exit(1);
1090     }
1091     }
1092     break;
1093    
1094    
1095     /*************************************************/
1096    
1097 dpavlin 32 default:if (writeflag == MEM_READ) {
1098     fatal("[ sh4: read from addr 0x%x ]\n",
1099     (int)relative_addr);
1100     } else {
1101     fatal("[ sh4: write to addr 0x%x: 0x%x ]\n",
1102     (int)relative_addr, (int)idata);
1103     }
1104 dpavlin 34 #ifdef SH4_DEGUG
1105     // exit(1);
1106     #endif
1107 dpavlin 32 }
1108    
1109     if (writeflag == MEM_READ)
1110     memory_writemax64(cpu, data, len, odata);
1111    
1112     return 1;
1113     }
1114    
1115    
1116     DEVINIT(sh4)
1117     {
1118 dpavlin 34 char tmp[200];
1119 dpavlin 32 struct machine *machine = devinit->machine;
1120     struct sh4_data *d = malloc(sizeof(struct sh4_data));
1121     if (d == NULL) {
1122     fprintf(stderr, "out of memory\n");
1123     exit(1);
1124     }
1125     memset(d, 0, sizeof(struct sh4_data));
1126    
1127     d->scif_console_handle = console_start_slave(devinit->machine,
1128     "SH4 SCIF", 1);
1129    
1130 dpavlin 36 snprintf(tmp, sizeof(tmp), "%s.irq[0x%x]",
1131     devinit->interrupt_path, SH4_INTEVT_SCIF_RXI);
1132     INTERRUPT_CONNECT(tmp, d->scif_rx_irq);
1133     snprintf(tmp, sizeof(tmp), "%s.irq[0x%x]",
1134     devinit->interrupt_path, SH4_INTEVT_SCIF_TXI);
1135     INTERRUPT_CONNECT(tmp, d->scif_tx_irq);
1136    
1137 dpavlin 32 memory_device_register(machine->memory, devinit->name,
1138     SH4_REG_BASE, 0x01000000, dev_sh4_access, d, DM_DEFAULT, NULL);
1139    
1140     /* On-chip RAM/cache: */
1141     dev_ram_init(machine, 0x1e000000, 0x8000, DEV_RAM_RAM, 0x0);
1142    
1143     /* 0xe0000000: Store queues: */
1144     dev_ram_init(machine, 0xe0000000, 32 * 2, DEV_RAM_RAM, 0x0);
1145    
1146     /*
1147     * 0xf0000000 SH4_CCIA I-Cache address array
1148     * 0xf1000000 SH4_CCID I-Cache data array
1149     * 0xf4000000 SH4_CCDA D-Cache address array
1150     * 0xf5000000 SH4_CCDD D-Cache data array
1151     *
1152     * TODO: Implement more correct cache behaviour?
1153     */
1154 dpavlin 36 dev_ram_init(machine, SH4_CCIA, SH4_ICACHE_SIZE * 2, DEV_RAM_RAM, 0x0);
1155     dev_ram_init(machine, SH4_CCID, SH4_ICACHE_SIZE, DEV_RAM_RAM, 0x0);
1156     dev_ram_init(machine, SH4_CCDA, SH4_DCACHE_SIZE * 2, DEV_RAM_RAM, 0x0);
1157     dev_ram_init(machine, SH4_CCDD, SH4_DCACHE_SIZE, DEV_RAM_RAM, 0x0);
1158 dpavlin 32
1159     /* 0xf2000000 SH4_ITLB_AA */
1160     memory_device_register(machine->memory, devinit->name, SH4_ITLB_AA,
1161     0x01000000, dev_sh4_itlb_aa_access, d, DM_DEFAULT, NULL);
1162    
1163     /* 0xf3000000 SH4_ITLB_DA1 */
1164     memory_device_register(machine->memory, devinit->name, SH4_ITLB_DA1,
1165     0x01000000, dev_sh4_itlb_da1_access, d, DM_DEFAULT, NULL);
1166    
1167     /* 0xf6000000 SH4_UTLB_AA */
1168     memory_device_register(machine->memory, devinit->name, SH4_UTLB_AA,
1169     0x01000000, dev_sh4_utlb_aa_access, d, DM_DEFAULT, NULL);
1170    
1171     /* 0xf7000000 SH4_UTLB_DA1 */
1172     memory_device_register(machine->memory, devinit->name, SH4_UTLB_DA1,
1173     0x01000000, dev_sh4_utlb_da1_access, d, DM_DEFAULT, NULL);
1174    
1175     d->sh4_timer = timer_add(SH4_PSEUDO_TIMER_HZ, sh4_timer_tick, d);
1176     machine_add_tickfunction(devinit->machine, dev_sh4_tick, d,
1177     SH4_TICK_SHIFT, 0.0);
1178    
1179     /* Initial Timer values, according to the SH7750 manual: */
1180     d->tcor[0] = 0xffffffff; d->tcnt[0] = 0xffffffff;
1181     d->tcor[1] = 0xffffffff; d->tcnt[1] = 0xffffffff;
1182     d->tcor[2] = 0xffffffff; d->tcnt[2] = 0xffffffff;
1183    
1184 dpavlin 34 snprintf(tmp, sizeof(tmp), "emul[0].machine[0].cpu[0].irq[0x%x]",
1185     SH_INTEVT_TMU0_TUNI0);
1186     if (!interrupt_handler_lookup(tmp, &d->timer_irq[0])) {
1187     fatal("Could not find interrupt '%s'.\n", tmp);
1188     exit(1);
1189     }
1190     snprintf(tmp, sizeof(tmp), "emul[0].machine[0].cpu[0].irq[0x%x]",
1191     SH_INTEVT_TMU1_TUNI1);
1192     if (!interrupt_handler_lookup(tmp, &d->timer_irq[1])) {
1193     fatal("Could not find interrupt '%s'.\n", tmp);
1194     exit(1);
1195     }
1196     snprintf(tmp, sizeof(tmp), "emul[0].machine[0].cpu[0].irq[0x%x]",
1197     SH_INTEVT_TMU2_TUNI2);
1198     if (!interrupt_handler_lookup(tmp, &d->timer_irq[2])) {
1199     fatal("Could not find interrupt '%s'.\n", tmp);
1200     exit(1);
1201     }
1202    
1203     /* Bus State Controller initial values: */
1204     d->bsc_bcr2 = 0x3ffc;
1205     d->bsc_wcr1 = 0x77777777;
1206     d->bsc_wcr2 = 0xfffeefff;
1207    
1208 dpavlin 32 return 1;
1209     }
1210    

  ViewVC Help
Powered by ViewVC 1.1.26