/[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 44 - (hide annotations)
Mon Oct 8 16:22:56 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 42562 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1632 2007/09/11 21:46:35 debug Exp $
20070616	Implementing the MIPS32/64 revision 2 "ror" instruction.
20070617	Adding a struct for each physpage which keeps track of which
		ranges within that page (base offset, length) that are
		continuously translatable. When running with native code
		generation enabled (-b), a range is added after each read-
		ahead loop.
		Experimenting with using the physical program counter sample
		data (implemented 20070608) together with the "translatable
		range" information, to figure out which physical address ranges
		would be worth translating to native code (if the number of
		samples falling within a range is above a certain threshold).
20070618	Adding automagic building of .index comment files for
		src/file/, src/promemul/, src src/useremul/ as well.
		Adding a "has been translated" bit to the ranges, so that only
		not-yet-translated ranges will be sampled.
20070619	Moving src/cpu.c and src/memory_rw.c into src/cpus/,
		src/device.c into src/devices/, and src/machine.c into
		src/machines/.
		Creating a skeleton cc/ld native backend module; beginning on
		the function which will detect cc command line, etc.
20070620	Continuing on the native code generation infrastructure.
20070621	Moving src/x11.c and src/console.c into a new src/console/
		subdir (for everything that is console or framebuffer related).
		Moving src/symbol*.c into a new src/symbol/, which should
		contain anything that is symbol handling related.
20070624	Making the program counter sampling threshold a "settings
		variable" (sampling_threshold), i.e. it can now be changed
		during runtime.
		Switching the RELEASE notes format from plain text to HTML.
		If the TMPDIR environment variable is set, it is used instead
		of "/tmp" for temporary files.
		Continuing on the cc/ld backend: simple .c code is generated,
		the compiler and linker are called, etc.
		Adding detection of host architecture to the configure script
		(again), and adding icache invalidation support (only
		implemented for Alpha hosts so far).
20070625	Simplifying the program counter sampling mechanism.
20070626	Removing the cc/ld native code generation stuff, program
		counter sampling, etc; it would not have worked well in the
		general case.
20070627	Removing everything related to native code generation.
20070629	Removing the (practically unusable) support for multiple
		emulations. (The single emulation allowed now still supports
		multiple simultaneous machines, as before.)
		Beginning on PCCTWO and M88K interrupts.
20070723	Adding a dummy skeleton for emulation of M32R processors.
20070901	Fixing a warning found by "gcc version 4.3.0 20070817
		(experimental)" on amd64.
20070905	Removing some more traces of the old "multiple emulations"
		code.
		Also looking in /usr/local/include and /usr/local/lib for
		X11 libs, when running configure.
20070909	Minor updates to the guest OS install instructions, in
		preparation for the NetBSD 4.0 release.
20070918	More testing of NetBSD 4.0 RC1.

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 44 * $Id: dev_sh4.c,v 1.51 2007/08/29 20:36:49 debug Exp $
29 dpavlin 32 *
30 dpavlin 42 * COMMENT: SH4-specific memory mapped registers (0xf0000000 - 0xffffffff)
31 dpavlin 34 *
32 dpavlin 38 * TODO: Among other things:
33     *
34     * x) Interrupt masks (msk register stuff).
35     * x) BSC (Bus state controller).
36     * x) DMA
37     * x) UBC
38     * x) ...
39 dpavlin 32 */
40    
41     #include <stdio.h>
42     #include <stdlib.h>
43     #include <string.h>
44    
45 dpavlin 40 #include "bus_pci.h"
46 dpavlin 32 #include "console.h"
47     #include "cpu.h"
48     #include "device.h"
49     #include "devices.h"
50 dpavlin 34 #include "interrupt.h"
51 dpavlin 32 #include "machine.h"
52     #include "memory.h"
53     #include "misc.h"
54     #include "timer.h"
55    
56     #include "sh4_bscreg.h"
57     #include "sh4_cache.h"
58 dpavlin 34 #include "sh4_dmacreg.h"
59 dpavlin 32 #include "sh4_exception.h"
60     #include "sh4_intcreg.h"
61     #include "sh4_mmu.h"
62 dpavlin 40 #include "sh4_pcicreg.h"
63 dpavlin 34 #include "sh4_rtcreg.h"
64 dpavlin 32 #include "sh4_scifreg.h"
65 dpavlin 38 #include "sh4_scireg.h"
66 dpavlin 32 #include "sh4_tmureg.h"
67    
68    
69     #define SH4_REG_BASE 0xff000000
70     #define SH4_TICK_SHIFT 14
71     #define N_SH4_TIMERS 3
72    
73 dpavlin 40 /* PCI stuff: */
74     #define N_PCIC_REGS (0x224 / sizeof(uint32_t))
75     #define N_PCIC_IRQS 16
76     #define PCIC_REG(addr) ((addr - SH4_PCIC) / sizeof(uint32_t))
77     #define PCI_VENDOR_HITACHI 0x1054
78     #define PCI_PRODUCT_HITACHI_SH7751 0x3505
79     #define PCI_PRODUCT_HITACHI_SH7751R 0x350e
80    
81 dpavlin 38 #define SCIF_TX_FIFO_SIZE 16
82 dpavlin 40 #define SCIF_DELAYED_TX_VALUE 2 /* 2 to be safe, 1 = fast but buggy */
83 dpavlin 38
84 dpavlin 34 /* General-purpose I/O stuff: */
85     #define SH4_PCTRA 0xff80002c
86     #define SH4_PDTRA 0xff800030
87     #define SH4_PCTRB 0xff800040
88     #define SH4_PDTRB 0xff800044
89     #define SH4_GPIOIC 0xff800048
90    
91     #ifdef UNSTABLE_DEVEL
92     #define SH4_DEGUG
93 dpavlin 32 /* #define debug fatal */
94 dpavlin 34 #endif
95 dpavlin 32
96     struct sh4_data {
97 dpavlin 34 /* SCIF (Serial controller): */
98     uint16_t scif_smr;
99     uint8_t scif_brr;
100     uint16_t scif_scr;
101 dpavlin 36 uint16_t scif_ssr;
102 dpavlin 34 uint16_t scif_fcr;
103 dpavlin 38 uint16_t scif_lsr;
104 dpavlin 36 int scif_delayed_tx;
105 dpavlin 32 int scif_console_handle;
106 dpavlin 38 uint8_t scif_tx_fifo[SCIF_TX_FIFO_SIZE + 1];
107 dpavlin 40 size_t scif_tx_fifo_cursize;
108 dpavlin 36 struct interrupt scif_tx_irq;
109     struct interrupt scif_rx_irq;
110 dpavlin 38 int scif_tx_irq_asserted;
111     int scif_rx_irq_asserted;
112 dpavlin 32
113     /* Bus State Controller: */
114 dpavlin 34 uint32_t bsc_bcr1;
115     uint16_t bsc_bcr2;
116     uint32_t bsc_wcr1;
117     uint32_t bsc_wcr2;
118     uint32_t bsc_mcr;
119     uint16_t bsc_rtcsr;
120     uint16_t bsc_rtcor;
121     uint16_t bsc_rfcr;
122 dpavlin 32
123 dpavlin 34 /* GPIO: */
124     uint32_t pctra; /* Port Control Register A */
125     uint32_t pdtra; /* Port Data Register A */
126     uint32_t pctrb; /* Port Control Register B */
127     uint32_t pdtrb; /* Port Data Register B */
128    
129 dpavlin 40 /* PCIC (PCI controller): */
130     struct pci_data *pci_data;
131     struct interrupt cpu_pcic_interrupt[N_PCIC_IRQS];
132     uint32_t pcic_reg[N_PCIC_REGS];
133    
134 dpavlin 38 /* SCI (serial interface): */
135     int sci_bits_outputed;
136     int sci_bits_read;
137     uint8_t sci_scsptr;
138     uint8_t sci_curbyte;
139     uint8_t sci_cur_addr;
140    
141 dpavlin 34 /* SD-RAM: */
142     uint16_t sdmr2;
143     uint16_t sdmr3;
144    
145 dpavlin 32 /* Timer Management Unit: */
146     struct timer *sh4_timer;
147 dpavlin 34 struct interrupt timer_irq[4];
148 dpavlin 32 uint32_t tocr;
149     uint32_t tstr;
150     uint32_t tcnt[N_SH4_TIMERS];
151     uint32_t tcor[N_SH4_TIMERS];
152     uint32_t tcr[N_SH4_TIMERS];
153     int timer_interrupts_pending[N_SH4_TIMERS];
154     double timer_hz[N_SH4_TIMERS];
155 dpavlin 34
156     /* RTC: */
157     uint32_t rtc_reg[14]; /* Excluding rcr1 and 2 */
158     uint8_t rtc_rcr1;
159 dpavlin 32 };
160    
161    
162 dpavlin 38 #define SH4_PSEUDO_TIMER_HZ 110.0
163 dpavlin 32
164    
165     /*
166     * sh4_timer_tick():
167     *
168     * This function is called SH4_PSEUDO_TIMER_HZ times per real-world second.
169     * Its job is to update the SH4 timer counters, and if necessary, increase
170     * the number of pending interrupts.
171 dpavlin 34 *
172     * Also, RAM Refresh is also faked here.
173 dpavlin 32 */
174     static void sh4_timer_tick(struct timer *t, void *extra)
175     {
176 dpavlin 42 struct sh4_data *d = extra;
177 dpavlin 32 int i;
178    
179 dpavlin 34 /* Fake RAM refresh: */
180     d->bsc_rfcr ++;
181     if (d->bsc_rtcsr & (RTCSR_CMIE | RTCSR_OVIE)) {
182     fatal("sh4: RTCSR_CMIE | RTCSR_OVIE: TODO\n");
183     /* TODO: Implement refresh interrupts etc. */
184     exit(1);
185     }
186    
187 dpavlin 36 /* Timer interrupts: */
188 dpavlin 32 for (i=0; i<N_SH4_TIMERS; i++) {
189     int32_t old = d->tcnt[i];
190    
191     /* printf("tcnt[%i] = %08x tcor[%i] = %08x\n",
192     i, d->tcnt[i], i, d->tcor[i]); */
193    
194     /* Only update timers that are currently started: */
195     if (!(d->tstr & (TSTR_STR0 << i)))
196     continue;
197    
198     /* Update the current count: */
199     d->tcnt[i] -= d->timer_hz[i] / SH4_PSEUDO_TIMER_HZ;
200    
201     /* Has the timer underflowed? */
202     if ((int32_t)d->tcnt[i] < 0 && old >= 0) {
203     d->tcr[i] |= TCR_UNF;
204    
205     if (d->tcr[i] & TCR_UNIE)
206     d->timer_interrupts_pending[i] ++;
207    
208     /*
209     * Set tcnt[i] to tcor[i]. Note: Since this function
210     * is only called now and then, adding tcor[i] to
211     * tcnt[i] produces more correct values for long
212     * running timers.
213     */
214     d->tcnt[i] += d->tcor[i];
215    
216     /* At least make sure that tcnt is non-negative... */
217     if ((int32_t)d->tcnt[i] < 0)
218     d->tcnt[i] = 0;
219     }
220     }
221     }
222    
223    
224 dpavlin 40 static void sh4_pcic_interrupt_assert(struct interrupt *interrupt)
225     {
226     struct sh4_data *d = interrupt->extra;
227     INTERRUPT_ASSERT(d->cpu_pcic_interrupt[interrupt->line]);
228     }
229     static void sh4_pcic_interrupt_deassert(struct interrupt *interrupt)
230     {
231     struct sh4_data *d = interrupt->extra;
232     INTERRUPT_DEASSERT(d->cpu_pcic_interrupt[interrupt->line]);
233     }
234    
235    
236 dpavlin 36 static void scif_reassert_interrupts(struct sh4_data *d)
237     {
238 dpavlin 38 int old_tx_asserted = d->scif_tx_irq_asserted;
239     int old_rx_asserted = d->scif_rx_irq_asserted;
240    
241     d->scif_rx_irq_asserted =
242     d->scif_scr & SCSCR2_RIE && d->scif_ssr & SCSSR2_DR;
243    
244     if (d->scif_rx_irq_asserted && !old_rx_asserted)
245     INTERRUPT_ASSERT(d->scif_rx_irq);
246     else if (!d->scif_rx_irq_asserted && old_rx_asserted)
247 dpavlin 36 INTERRUPT_DEASSERT(d->scif_rx_irq);
248 dpavlin 38
249     d->scif_tx_irq_asserted =
250     d->scif_scr & SCSCR2_TIE &&
251     d->scif_ssr & (SCSSR2_TDFE | SCSSR2_TEND);
252    
253     if (d->scif_tx_irq_asserted && !old_tx_asserted)
254     INTERRUPT_ASSERT(d->scif_tx_irq);
255     else if (!d->scif_tx_irq_asserted && old_tx_asserted)
256 dpavlin 36 INTERRUPT_DEASSERT(d->scif_tx_irq);
257     }
258    
259    
260 dpavlin 32 DEVICE_TICK(sh4)
261     {
262 dpavlin 42 struct sh4_data *d = extra;
263 dpavlin 40 unsigned int i;
264 dpavlin 32
265 dpavlin 38 /*
266     * Serial controller interrupts:
267     *
268     * RX: Cause interrupt if any char is available.
269     * TX: Send entire TX FIFO contents, and interrupt.
270     */
271 dpavlin 36 if (console_charavail(d->scif_console_handle))
272     d->scif_ssr |= SCSSR2_DR;
273     else
274 dpavlin 38 d->scif_ssr &= ~SCSSR2_DR;
275    
276 dpavlin 36 if (d->scif_delayed_tx) {
277 dpavlin 38 if (--d->scif_delayed_tx == 0) {
278     /* Send TX FIFO contents: */
279     for (i=0; i<d->scif_tx_fifo_cursize; i++)
280     console_putchar(d->scif_console_handle,
281     d->scif_tx_fifo[i]);
282    
283     /* Clear FIFO: */
284     d->scif_tx_fifo_cursize = 0;
285    
286     /* Done sending; cause a transmit end interrupt: */
287 dpavlin 36 d->scif_ssr |= SCSSR2_TDFE | SCSSR2_TEND;
288 dpavlin 38 }
289 dpavlin 36 }
290    
291     scif_reassert_interrupts(d);
292    
293     /* Timer interrupts: */
294 dpavlin 32 for (i=0; i<N_SH4_TIMERS; i++)
295     if (d->timer_interrupts_pending[i] > 0) {
296 dpavlin 34 INTERRUPT_ASSERT(d->timer_irq[i]);
297 dpavlin 32 d->tcr[i] |= TCR_UNF;
298     }
299     }
300    
301    
302 dpavlin 38 /*
303     * sh_sci_cmd():
304     *
305     * Handle a SCI command byte.
306     *
307     * Bit: Meaning:
308     * 7 Ignored (usually 1?)
309     * 6 0=Write, 1=Read
310     * 5 AD: Address transfer
311     * 4 DT: Data transfer
312     * 3..0 Data or address bits
313     */
314     static void sh_sci_cmd(struct sh4_data *d, struct cpu *cpu)
315     {
316     uint8_t cmd = d->sci_curbyte;
317     int writeflag = cmd & 0x40? 0 : 1;
318     int address_transfer;
319    
320     /* fatal("[ CMD BYTE %02x ]\n", cmd); */
321    
322     if (!(cmd & 0x80)) {
323     fatal("SCI cmd bit 7 not set? TODO\n");
324     exit(1);
325     }
326    
327     if ((cmd & 0x30) == 0x20)
328     address_transfer = 1;
329     else if ((cmd & 0x30) == 0x10)
330     address_transfer = 0;
331     else {
332     fatal("SCI: Neither data nor address transfer? TODO\n");
333     exit(1);
334     }
335    
336     if (address_transfer)
337     d->sci_cur_addr = cmd & 0x0f;
338    
339     if (!writeflag) {
340     /* Read data from the current address: */
341     uint8_t data_byte;
342    
343     cpu->memory_rw(cpu, cpu->mem, SCI_DEVICE_BASE + d->sci_cur_addr,
344     &data_byte, 1, MEM_READ, PHYSICAL);
345    
346     debug("[ SCI: read addr=%x data=%x ]\n",
347     d->sci_cur_addr, data_byte);
348    
349     d->sci_curbyte = data_byte;
350    
351     /* Set bit 7 right away: */
352     d->sci_scsptr &= ~SCSPTR_SPB1DT;
353     if (data_byte & 0x80)
354     d->sci_scsptr |= SCSPTR_SPB1DT;
355     }
356    
357     if (writeflag && !address_transfer) {
358     /* Write the 4 data bits to the current address: */
359     uint8_t data_byte = cmd & 0x0f;
360    
361     debug("[ SCI: write addr=%x data=%x ]\n",
362     d->sci_cur_addr, data_byte);
363    
364     cpu->memory_rw(cpu, cpu->mem, SCI_DEVICE_BASE + d->sci_cur_addr,
365     &data_byte, 1, MEM_WRITE, PHYSICAL);
366     }
367     }
368    
369    
370     /*
371     * sh_sci_access():
372     *
373     * Reads or writes a bit via the SH4's serial interface. If writeflag is
374     * non-zero, input is used. If writeflag is zero, a bit is outputed as
375     * the return value from this function.
376     */
377     static uint8_t sh_sci_access(struct sh4_data *d, struct cpu *cpu,
378     int writeflag, uint8_t input)
379     {
380     if (writeflag) {
381     /* WRITE: */
382     int clockpulse;
383     uint8_t old = d->sci_scsptr;
384     d->sci_scsptr = input;
385    
386     /*
387     * Clock pulse (SCSPTR_SPB0DT going from 0 to 1,
388     * when SCSPTR_SPB0IO was already set):
389     */
390     clockpulse = old & SCSPTR_SPB0IO &&
391     d->sci_scsptr & SCSPTR_SPB0DT &&
392     !(old & SCSPTR_SPB0DT);
393    
394     if (!clockpulse)
395     return 0;
396    
397     /* Are we in output or input mode? */
398     if (d->sci_scsptr & SCSPTR_SPB1IO) {
399     /* Output: */
400     int bit = d->sci_scsptr & SCSPTR_SPB1DT? 1 : 0;
401     d->sci_curbyte <<= 1;
402     d->sci_curbyte |= bit;
403     d->sci_bits_outputed ++;
404     if (d->sci_bits_outputed == 8) {
405     /* 4 control bits and 4 address/data bits have
406     been written. */
407     sh_sci_cmd(d, cpu);
408     d->sci_bits_outputed = 0;
409     }
410     } else {
411     /* Input: */
412     int bit;
413     d->sci_bits_read ++;
414     d->sci_bits_read &= 7;
415    
416     bit = d->sci_curbyte & (0x80 >> d->sci_bits_read);
417    
418     d->sci_scsptr &= ~SCSPTR_SPB1DT;
419     if (bit)
420     d->sci_scsptr |= SCSPTR_SPB1DT;
421     }
422    
423     /* Return (value doesn't matter). */
424     return 0;
425     } else {
426     /* READ: */
427     return d->sci_scsptr;
428     }
429     }
430    
431    
432 dpavlin 32 DEVICE_ACCESS(sh4_itlb_aa)
433     {
434     uint64_t idata = 0, odata = 0;
435     int e = (relative_addr & SH4_ITLB_E_MASK) >> SH4_ITLB_E_SHIFT;
436    
437     if (writeflag == MEM_WRITE) {
438     int safe_to_invalidate = 0;
439     uint32_t old_hi = cpu->cd.sh.itlb_hi[e];
440     if ((cpu->cd.sh.itlb_lo[e] & SH4_PTEL_SZ_MASK)==SH4_PTEL_SZ_4K)
441     safe_to_invalidate = 1;
442    
443     idata = memory_readmax64(cpu, data, len);
444     cpu->cd.sh.itlb_hi[e] &=
445     ~(SH4_PTEH_VPN_MASK | SH4_PTEH_ASID_MASK);
446     cpu->cd.sh.itlb_hi[e] |= (idata &
447     (SH4_ITLB_AA_VPN_MASK | SH4_ITLB_AA_ASID_MASK));
448     cpu->cd.sh.itlb_lo[e] &= ~SH4_PTEL_V;
449     if (idata & SH4_ITLB_AA_V)
450     cpu->cd.sh.itlb_lo[e] |= SH4_PTEL_V;
451    
452 dpavlin 34 /* Invalidate if this ITLB entry previously belonged to the
453     currently running process, or if it was shared: */
454     if (cpu->cd.sh.ptel & SH4_PTEL_SH ||
455     (old_hi & SH4_ITLB_AA_ASID_MASK) ==
456     (cpu->cd.sh.pteh & SH4_PTEH_ASID_MASK)) {
457     if (safe_to_invalidate)
458     cpu->invalidate_translation_caches(cpu,
459     old_hi & ~0xfff, INVALIDATE_VADDR);
460     else
461     cpu->invalidate_translation_caches(cpu,
462     0, INVALIDATE_ALL);
463     }
464 dpavlin 32 } else {
465     odata = cpu->cd.sh.itlb_hi[e] &
466     (SH4_ITLB_AA_VPN_MASK | SH4_ITLB_AA_ASID_MASK);
467     if (cpu->cd.sh.itlb_lo[e] & SH4_PTEL_V)
468     odata |= SH4_ITLB_AA_V;
469     memory_writemax64(cpu, data, len, odata);
470     }
471    
472     return 1;
473     }
474    
475    
476     DEVICE_ACCESS(sh4_itlb_da1)
477     {
478     uint32_t mask = SH4_PTEL_SH | SH4_PTEL_C | SH4_PTEL_SZ_MASK |
479     SH4_PTEL_PR_MASK | SH4_PTEL_V | 0x1ffffc00;
480     uint64_t idata = 0, odata = 0;
481     int e = (relative_addr & SH4_ITLB_E_MASK) >> SH4_ITLB_E_SHIFT;
482    
483     if (relative_addr & 0x800000) {
484     fatal("sh4_itlb_da1: TODO: da2 area\n");
485     exit(1);
486     }
487    
488     if (writeflag == MEM_WRITE) {
489 dpavlin 34 uint32_t old_lo = cpu->cd.sh.itlb_lo[e];
490 dpavlin 32 int safe_to_invalidate = 0;
491     if ((cpu->cd.sh.itlb_lo[e] & SH4_PTEL_SZ_MASK)==SH4_PTEL_SZ_4K)
492     safe_to_invalidate = 1;
493    
494     idata = memory_readmax64(cpu, data, len);
495     cpu->cd.sh.itlb_lo[e] &= ~mask;
496     cpu->cd.sh.itlb_lo[e] |= (idata & mask);
497    
498 dpavlin 34 /* Invalidate if this ITLB entry belongs to the
499     currently running process, or if it was shared: */
500     if (old_lo & SH4_PTEL_SH ||
501     (cpu->cd.sh.itlb_hi[e] & SH4_ITLB_AA_ASID_MASK) ==
502     (cpu->cd.sh.pteh & SH4_PTEH_ASID_MASK)) {
503     if (safe_to_invalidate)
504     cpu->invalidate_translation_caches(cpu,
505     cpu->cd.sh.itlb_hi[e] & ~0xfff,
506     INVALIDATE_VADDR);
507     else
508     cpu->invalidate_translation_caches(cpu,
509     0, INVALIDATE_ALL);
510     }
511 dpavlin 32 } else {
512     odata = cpu->cd.sh.itlb_lo[e] & mask;
513     memory_writemax64(cpu, data, len, odata);
514     }
515    
516     return 1;
517     }
518    
519    
520     DEVICE_ACCESS(sh4_utlb_aa)
521     {
522     uint64_t idata = 0, odata = 0;
523     int i, e = (relative_addr & SH4_UTLB_E_MASK) >> SH4_UTLB_E_SHIFT;
524     int a = relative_addr & SH4_UTLB_A;
525    
526     if (writeflag == MEM_WRITE) {
527     int n_hits = 0;
528     int safe_to_invalidate = 0;
529     uint32_t vaddr_to_invalidate = 0;
530    
531     idata = memory_readmax64(cpu, data, len);
532     if (a) {
533     for (i=-SH_N_ITLB_ENTRIES; i<SH_N_UTLB_ENTRIES; i++) {
534     uint32_t lo, hi;
535     uint32_t mask = 0xfffff000;
536     int sh;
537    
538     if (i < 0) {
539     lo = cpu->cd.sh.itlb_lo[
540     i + SH_N_ITLB_ENTRIES];
541     hi = cpu->cd.sh.itlb_hi[
542     i + SH_N_ITLB_ENTRIES];
543     } else {
544     lo = cpu->cd.sh.utlb_lo[i];
545     hi = cpu->cd.sh.utlb_hi[i];
546     }
547    
548     sh = lo & SH4_PTEL_SH;
549     if (!(lo & SH4_PTEL_V))
550     continue;
551    
552     switch (lo & SH4_PTEL_SZ_MASK) {
553     case SH4_PTEL_SZ_1K: mask = 0xfffffc00; break;
554     case SH4_PTEL_SZ_64K: mask = 0xffff0000; break;
555     case SH4_PTEL_SZ_1M: mask = 0xfff00000; break;
556     }
557    
558     if ((hi & mask) != (idata & mask))
559     continue;
560    
561     if ((lo & SH4_PTEL_SZ_MASK) ==
562     SH4_PTEL_SZ_4K) {
563     safe_to_invalidate = 1;
564     vaddr_to_invalidate = hi & mask;
565     }
566    
567     if (!sh && (hi & SH4_PTEH_ASID_MASK) !=
568     (cpu->cd.sh.pteh & SH4_PTEH_ASID_MASK))
569     continue;
570    
571     if (i < 0) {
572 dpavlin 38 cpu->cd.sh.itlb_lo[i +
573     SH_N_ITLB_ENTRIES] &= ~SH4_PTEL_V;
574 dpavlin 32 if (idata & SH4_UTLB_AA_V)
575 dpavlin 38 cpu->cd.sh.itlb_lo[
576     i+SH_N_ITLB_ENTRIES] |=
577 dpavlin 32 SH4_PTEL_V;
578     } else {
579     cpu->cd.sh.utlb_lo[i] &=
580     ~(SH4_PTEL_D | SH4_PTEL_V);
581     if (idata & SH4_UTLB_AA_D)
582     cpu->cd.sh.utlb_lo[i] |=
583     SH4_PTEL_D;
584     if (idata & SH4_UTLB_AA_V)
585     cpu->cd.sh.utlb_lo[i] |=
586     SH4_PTEL_V;
587     }
588    
589     if (i >= 0)
590     n_hits ++;
591     }
592    
593     if (n_hits > 1)
594     sh_exception(cpu,
595     EXPEVT_RESET_TLB_MULTI_HIT, 0, 0);
596     } else {
597     if ((cpu->cd.sh.utlb_lo[e] & SH4_PTEL_SZ_MASK) ==
598     SH4_PTEL_SZ_4K) {
599     safe_to_invalidate = 1;
600     vaddr_to_invalidate =
601     cpu->cd.sh.utlb_hi[e] & ~0xfff;
602     }
603    
604     cpu->cd.sh.utlb_hi[e] &=
605     ~(SH4_PTEH_VPN_MASK | SH4_PTEH_ASID_MASK);
606     cpu->cd.sh.utlb_hi[e] |= (idata &
607     (SH4_UTLB_AA_VPN_MASK | SH4_UTLB_AA_ASID_MASK));
608    
609     cpu->cd.sh.utlb_lo[e] &= ~(SH4_PTEL_D | SH4_PTEL_V);
610     if (idata & SH4_UTLB_AA_D)
611     cpu->cd.sh.utlb_lo[e] |= SH4_PTEL_D;
612     if (idata & SH4_UTLB_AA_V)
613     cpu->cd.sh.utlb_lo[e] |= SH4_PTEL_V;
614     }
615    
616     if (safe_to_invalidate)
617     cpu->invalidate_translation_caches(cpu,
618     vaddr_to_invalidate, INVALIDATE_VADDR);
619     else
620 dpavlin 34 cpu->invalidate_translation_caches(cpu, 0,
621     INVALIDATE_ALL);
622 dpavlin 32 } else {
623     odata = cpu->cd.sh.utlb_hi[e] &
624     (SH4_UTLB_AA_VPN_MASK | SH4_UTLB_AA_ASID_MASK);
625     if (cpu->cd.sh.utlb_lo[e] & SH4_PTEL_D)
626     odata |= SH4_UTLB_AA_D;
627     if (cpu->cd.sh.utlb_lo[e] & SH4_PTEL_V)
628     odata |= SH4_UTLB_AA_V;
629     memory_writemax64(cpu, data, len, odata);
630     }
631    
632     return 1;
633     }
634    
635    
636     DEVICE_ACCESS(sh4_utlb_da1)
637     {
638     uint32_t mask = SH4_PTEL_WT | SH4_PTEL_SH | SH4_PTEL_D | SH4_PTEL_C
639     | SH4_PTEL_SZ_MASK | SH4_PTEL_PR_MASK | SH4_PTEL_V | 0x1ffffc00;
640     uint64_t idata = 0, odata = 0;
641     int e = (relative_addr & SH4_UTLB_E_MASK) >> SH4_UTLB_E_SHIFT;
642    
643     if (relative_addr & 0x800000) {
644     fatal("sh4_utlb_da1: TODO: da2 area\n");
645     exit(1);
646     }
647    
648     if (writeflag == MEM_WRITE) {
649 dpavlin 34 uint32_t old_lo = cpu->cd.sh.utlb_lo[e];
650 dpavlin 32 int safe_to_invalidate = 0;
651     if ((cpu->cd.sh.utlb_lo[e] & SH4_PTEL_SZ_MASK)==SH4_PTEL_SZ_4K)
652     safe_to_invalidate = 1;
653    
654     idata = memory_readmax64(cpu, data, len);
655     cpu->cd.sh.utlb_lo[e] &= ~mask;
656     cpu->cd.sh.utlb_lo[e] |= (idata & mask);
657    
658 dpavlin 34 /* Invalidate if this UTLB entry belongs to the
659     currently running process, or if it was shared: */
660     if (old_lo & SH4_PTEL_SH ||
661     (cpu->cd.sh.utlb_hi[e] & SH4_ITLB_AA_ASID_MASK) ==
662     (cpu->cd.sh.pteh & SH4_PTEH_ASID_MASK)) {
663     if (safe_to_invalidate)
664     cpu->invalidate_translation_caches(cpu,
665     cpu->cd.sh.utlb_hi[e] & ~0xfff,
666     INVALIDATE_VADDR);
667     else
668     cpu->invalidate_translation_caches(cpu,
669     0, INVALIDATE_ALL);
670     }
671 dpavlin 32 } else {
672     odata = cpu->cd.sh.utlb_lo[e] & mask;
673     memory_writemax64(cpu, data, len, odata);
674     }
675    
676     return 1;
677     }
678    
679    
680 dpavlin 40 DEVICE_ACCESS(sh4_pcic)
681     {
682 dpavlin 42 struct sh4_data *d = extra;
683 dpavlin 40 uint64_t idata = 0, odata = 0;
684    
685     if (writeflag == MEM_WRITE)
686     idata = memory_readmax64(cpu, data, len);
687    
688     relative_addr += SH4_PCIC;
689    
690     /* Register read/write: */
691     if (writeflag == MEM_WRITE)
692     d->pcic_reg[PCIC_REG(relative_addr)] = idata;
693     else
694     odata = d->pcic_reg[PCIC_REG(relative_addr)];
695    
696     /* Special cases: */
697    
698     switch (relative_addr) {
699    
700     case SH4_PCICONF0:
701     if (writeflag == MEM_WRITE) {
702     fatal("[ sh4_pcic: TODO: Write to SH4_PCICONF0? ]\n");
703     exit(1);
704     } else {
705     if (strcmp(cpu->cd.sh.cpu_type.name, "SH7751") == 0) {
706     odata = PCI_ID_CODE(PCI_VENDOR_HITACHI,
707     PCI_PRODUCT_HITACHI_SH7751);
708     } else if (strcmp(cpu->cd.sh.cpu_type.name,
709     "SH7751R") == 0) {
710     odata = PCI_ID_CODE(PCI_VENDOR_HITACHI,
711     PCI_PRODUCT_HITACHI_SH7751R);
712     } else {
713     fatal("sh4_pcic: TODO: PCICONF0 read for"
714     " unimplemented CPU type?\n");
715     exit(1);
716     }
717     }
718     break;
719    
720     case SH4_PCICONF1:
721     case SH4_PCICONF2:
722     case SH4_PCICR:
723     case SH4_PCIBCR1:
724     case SH4_PCIBCR2:
725     case SH4_PCIBCR3:
726     case SH4_PCIWCR1:
727     case SH4_PCIWCR2:
728     case SH4_PCIWCR3:
729     case SH4_PCIMCR:
730     break;
731    
732     case SH4_PCICONF5:
733     /* Hardcoded to what OpenBSD/landisk uses: */
734     if (writeflag == MEM_WRITE && idata != 0xac000000) {
735     fatal("sh4_pcic: SH4_PCICONF5 unknown value"
736     " 0x%"PRIx32"\n", (uint32_t) idata);
737     exit(1);
738     }
739     break;
740    
741     case SH4_PCICONF6:
742     /* Hardcoded to what OpenBSD/landisk uses: */
743     if (writeflag == MEM_WRITE && idata != 0x8c000000) {
744     fatal("sh4_pcic: SH4_PCICONF6 unknown value"
745     " 0x%"PRIx32"\n", (uint32_t) idata);
746     exit(1);
747     }
748     break;
749    
750     case SH4_PCILSR0:
751     /* Hardcoded to what OpenBSD/landisk uses: */
752     if (writeflag == MEM_WRITE && idata != ((64 - 1) << 20)) {
753     fatal("sh4_pcic: SH4_PCILSR0 unknown value"
754     " 0x%"PRIx32"\n", (uint32_t) idata);
755     exit(1);
756     }
757     break;
758    
759     case SH4_PCILAR0:
760     /* Hardcoded to what OpenBSD/landisk uses: */
761     if (writeflag == MEM_WRITE && idata != 0xac000000) {
762     fatal("sh4_pcic: SH4_PCILAR0 unknown value"
763     " 0x%"PRIx32"\n", (uint32_t) idata);
764     exit(1);
765     }
766     break;
767    
768     case SH4_PCILSR1:
769     /* Hardcoded to what OpenBSD/landisk uses: */
770     if (writeflag == MEM_WRITE && idata != ((64 - 1) << 20)) {
771     fatal("sh4_pcic: SH4_PCILSR1 unknown value"
772     " 0x%"PRIx32"\n", (uint32_t) idata);
773     exit(1);
774     }
775     break;
776    
777     case SH4_PCILAR1:
778     /* Hardcoded to what OpenBSD/landisk uses: */
779     if (writeflag == MEM_WRITE && idata != 0xac000000) {
780     fatal("sh4_pcic: SH4_PCILAR1 unknown value"
781     " 0x%"PRIx32"\n", (uint32_t) idata);
782     exit(1);
783     }
784     break;
785    
786     case SH4_PCIMBR:
787     if (writeflag == MEM_WRITE && idata != SH4_PCIC_MEM) {
788     fatal("sh4_pcic: PCIMBR set to 0x%"PRIx32", not"
789     " 0x%"PRIx32"? TODO\n", (uint32_t) idata,
790     (uint32_t) SH4_PCIC_MEM);
791     exit(1);
792     }
793     break;
794    
795     case SH4_PCIIOBR:
796     if (writeflag == MEM_WRITE && idata != SH4_PCIC_IO) {
797     fatal("sh4_pcic: PCIIOBR set to 0x%"PRIx32", not"
798     " 0x%"PRIx32"? TODO\n", (uint32_t) idata,
799     (uint32_t) SH4_PCIC_IO);
800     exit(1);
801     }
802     break;
803    
804     case SH4_PCIPAR:
805     /* PCI bus access Address Register: */
806     {
807     int bus = (idata >> 16) & 0xff;
808     int dev = (idata >> 11) & 0x1f;
809     int func = (idata >> 8) & 7;
810     int reg = idata & 0xff;
811     bus_pci_setaddr(cpu, d->pci_data, bus, dev, func, reg);
812     }
813     break;
814    
815     case SH4_PCIPDR:
816     /* PCI bus access Data Register: */
817     bus_pci_data_access(cpu, d->pci_data, writeflag == MEM_READ?
818     &odata : &idata, len, writeflag);
819     break;
820    
821     default:if (writeflag == MEM_READ) {
822     fatal("[ sh4_pcic: read from addr 0x%x: TODO ]\n",
823     (int)relative_addr);
824     } else {
825     fatal("[ sh4_pcic: write to addr 0x%x: 0x%x: TODO ]\n",
826     (int)relative_addr, (int)idata);
827     }
828     exit(1);
829     }
830    
831     if (writeflag == MEM_READ)
832     memory_writemax64(cpu, data, len, odata);
833    
834     return 1;
835     }
836    
837    
838 dpavlin 32 DEVICE_ACCESS(sh4)
839     {
840 dpavlin 42 struct sh4_data *d = extra;
841 dpavlin 32 uint64_t idata = 0, odata = 0;
842 dpavlin 34 int timer_nr = 0, dma_channel = 0;
843 dpavlin 32
844     if (writeflag == MEM_WRITE)
845     idata = memory_readmax64(cpu, data, len);
846    
847     relative_addr += SH4_REG_BASE;
848    
849 dpavlin 34 /* SD-RAM access uses address only: */
850     if (relative_addr >= 0xff900000 && relative_addr <= 0xff97ffff) {
851     /* Possibly not 100% correct... TODO */
852     int v = (relative_addr >> 2) & 0xffff;
853     if (relative_addr & 0x00040000)
854     d->sdmr3 = v;
855     else
856     d->sdmr2 = v;
857     debug("[ sh4: sdmr%i set to 0x%04"PRIx16" ]\n",
858     relative_addr & 0x00040000? 3 : 2, v);
859     return 1;
860     }
861    
862    
863 dpavlin 32 switch (relative_addr) {
864    
865     /*************************************************/
866    
867     case SH4_PVR_ADDR:
868     odata = cpu->cd.sh.cpu_type.pvr;
869     break;
870    
871     case SH4_PRR_ADDR:
872     odata = cpu->cd.sh.cpu_type.prr;
873     break;
874    
875     case SH4_PTEH:
876     if (writeflag == MEM_READ)
877     odata = cpu->cd.sh.pteh;
878     else {
879 dpavlin 40 unsigned int old_asid = cpu->cd.sh.pteh
880     & SH4_PTEH_ASID_MASK;
881 dpavlin 32 cpu->cd.sh.pteh = idata;
882    
883     if ((idata & SH4_PTEH_ASID_MASK) != old_asid) {
884 dpavlin 34 /*
885     * TODO: Don't invalidate everything,
886     * only those pages that belonged to the
887     * old asid.
888     */
889 dpavlin 32 cpu->invalidate_translation_caches(
890     cpu, 0, INVALIDATE_ALL);
891     }
892     }
893     break;
894    
895     case SH4_PTEL:
896     if (writeflag == MEM_READ)
897     odata = cpu->cd.sh.ptel;
898     else
899     cpu->cd.sh.ptel = idata;
900     break;
901    
902     case SH4_TTB:
903     if (writeflag == MEM_READ)
904     odata = cpu->cd.sh.ttb;
905     else
906     cpu->cd.sh.ttb = idata;
907     break;
908    
909     case SH4_TEA:
910     if (writeflag == MEM_READ)
911     odata = cpu->cd.sh.tea;
912     else
913     cpu->cd.sh.tea = idata;
914     break;
915    
916     case SH4_PTEA:
917     if (writeflag == MEM_READ)
918     odata = cpu->cd.sh.ptea;
919     else
920     cpu->cd.sh.ptea = idata;
921     break;
922    
923     case SH4_MMUCR:
924     if (writeflag == MEM_READ) {
925     odata = cpu->cd.sh.mmucr;
926     } else {
927     if (idata & SH4_MMUCR_TI) {
928     /* TLB invalidate. */
929 dpavlin 34 int i;
930     for (i = 0; i < SH_N_ITLB_ENTRIES; i++)
931     cpu->cd.sh.itlb_lo[i] &=
932     ~SH4_PTEL_V;
933 dpavlin 32
934 dpavlin 34 for (i = 0; i < SH_N_UTLB_ENTRIES; i++)
935     cpu->cd.sh.utlb_lo[i] &=
936     ~SH4_PTEL_V;
937    
938 dpavlin 32 cpu->invalidate_translation_caches(cpu,
939     0, INVALIDATE_ALL);
940    
941 dpavlin 40 /* The TI bit should always read as 0. */
942 dpavlin 32 idata &= ~SH4_MMUCR_TI;
943     }
944    
945     cpu->cd.sh.mmucr = idata;
946     }
947     break;
948    
949     case SH4_CCR:
950     if (writeflag == MEM_READ) {
951     odata = cpu->cd.sh.ccr;
952     } else {
953     cpu->cd.sh.ccr = idata;
954     }
955     break;
956    
957     case SH4_QACR0:
958     if (writeflag == MEM_READ) {
959     odata = cpu->cd.sh.qacr0;
960     } else {
961     cpu->cd.sh.qacr0 = idata;
962     }
963     break;
964    
965     case SH4_QACR1:
966     if (writeflag == MEM_READ) {
967     odata = cpu->cd.sh.qacr1;
968     } else {
969     cpu->cd.sh.qacr1 = idata;
970     }
971     break;
972    
973     case SH4_TRA:
974     if (writeflag == MEM_READ)
975     odata = cpu->cd.sh.tra;
976     else
977     cpu->cd.sh.tra = idata;
978     break;
979    
980     case SH4_EXPEVT:
981     if (writeflag == MEM_READ)
982     odata = cpu->cd.sh.expevt;
983     else
984     cpu->cd.sh.expevt = idata;
985     break;
986    
987     case SH4_INTEVT:
988     if (writeflag == MEM_READ)
989     odata = cpu->cd.sh.intevt;
990     else
991     cpu->cd.sh.intevt = idata;
992     break;
993    
994    
995     /********************************/
996     /* UBC: User Break Controller */
997    
998     case 0xff200008: /* SH4_BBRA */
999     /* TODO */
1000     break;
1001    
1002    
1003     /********************************/
1004     /* TMU: Timer Management Unit */
1005    
1006     case SH4_TOCR:
1007     /* Timer Output Control Register */
1008     if (writeflag == MEM_WRITE) {
1009     d->tocr = idata;
1010     if (idata & TOCR_TCOE)
1011     fatal("[ sh4 timer: TCOE not yet "
1012     "implemented ]\n");
1013     } else {
1014     odata = d->tocr;
1015     }
1016     break;
1017    
1018     case SH4_TSTR:
1019     /* Timer Start Register */
1020     if (writeflag == MEM_READ) {
1021     odata = d->tstr;
1022     } else {
1023     if (idata & 1 && !(d->tstr & 1))
1024     debug("[ sh4 timer: starting timer 0 ]\n");
1025     if (idata & 2 && !(d->tstr & 2))
1026     debug("[ sh4 timer: starting timer 1 ]\n");
1027     if (idata & 4 && !(d->tstr & 4))
1028     debug("[ sh4 timer: starting timer 2 ]\n");
1029     if (!(idata & 1) && d->tstr & 1)
1030     debug("[ sh4 timer: stopping timer 0 ]\n");
1031     if (!(idata & 2) && d->tstr & 2)
1032     debug("[ sh4 timer: stopping timer 1 ]\n");
1033     if (!(idata & 4) && d->tstr & 4)
1034     debug("[ sh4 timer: stopping timer 2 ]\n");
1035     d->tstr = idata;
1036     }
1037     break;
1038    
1039     case SH4_TCOR2:
1040     timer_nr ++;
1041     case SH4_TCOR1:
1042     timer_nr ++;
1043     case SH4_TCOR0:
1044     /* Timer Constant Register */
1045     if (writeflag == MEM_READ)
1046     odata = d->tcor[timer_nr];
1047     else
1048     d->tcor[timer_nr] = idata;
1049     break;
1050    
1051     case SH4_TCNT2:
1052     timer_nr ++;
1053     case SH4_TCNT1:
1054     timer_nr ++;
1055     case SH4_TCNT0:
1056     /* Timer Counter Register */
1057     if (writeflag == MEM_READ)
1058     odata = d->tcnt[timer_nr];
1059     else
1060     d->tcnt[timer_nr] = idata;
1061     break;
1062    
1063     case SH4_TCR2:
1064     timer_nr ++;
1065     case SH4_TCR1:
1066     timer_nr ++;
1067     case SH4_TCR0:
1068     /* Timer Control Register */
1069     if (writeflag == MEM_READ) {
1070     odata = d->tcr[timer_nr];
1071     } else {
1072     if (cpu->cd.sh.pclock == 0) {
1073     fatal("INTERNAL ERROR: pclock must be set"
1074     " for this machine. Aborting.\n");
1075     exit(1);
1076     }
1077    
1078     switch (idata & 3) {
1079     case TCR_TPSC_P4:
1080     d->timer_hz[timer_nr] = cpu->cd.sh.pclock/4.0;
1081     break;
1082     case TCR_TPSC_P16:
1083     d->timer_hz[timer_nr] = cpu->cd.sh.pclock/16.0;
1084     break;
1085     case TCR_TPSC_P64:
1086     d->timer_hz[timer_nr] = cpu->cd.sh.pclock/64.0;
1087     break;
1088     case TCR_TPSC_P256:
1089     d->timer_hz[timer_nr] = cpu->cd.sh.pclock/256.0;
1090     break;
1091     }
1092    
1093     debug("[ sh4 timer %i clock set to %f Hz ]\n",
1094     timer_nr, d->timer_hz[timer_nr]);
1095    
1096     if (idata & (TCR_ICPF | TCR_ICPE1 | TCR_ICPE0 |
1097     TCR_CKEG1 | TCR_CKEG0 | TCR_TPSC2)) {
1098     fatal("Unimplemented SH4 timer control"
1099     " bits: 0x%08"PRIx32". Aborting.\n",
1100     (int) idata);
1101     exit(1);
1102     }
1103    
1104 dpavlin 38 INTERRUPT_DEASSERT(d->timer_irq[timer_nr]);
1105    
1106 dpavlin 32 if (d->tcr[timer_nr] & TCR_UNF && !(idata & TCR_UNF)) {
1107     if (d->timer_interrupts_pending[timer_nr] > 0)
1108     d->timer_interrupts_pending[timer_nr]--;
1109     }
1110    
1111     d->tcr[timer_nr] = idata;
1112     }
1113     break;
1114    
1115    
1116     /*************************************************/
1117 dpavlin 34 /* DMAC: DMA Controller */
1118    
1119     case SH4_SAR3:
1120     dma_channel ++;
1121     case SH4_SAR2:
1122     dma_channel ++;
1123     case SH4_SAR1:
1124     dma_channel ++;
1125     case SH4_SAR0:
1126     dma_channel ++;
1127     if (writeflag == MEM_READ)
1128     odata = cpu->cd.sh.dmac_sar[dma_channel];
1129     else
1130     cpu->cd.sh.dmac_sar[dma_channel] = idata;
1131     break;
1132    
1133     case SH4_DAR3:
1134     dma_channel ++;
1135     case SH4_DAR2:
1136     dma_channel ++;
1137     case SH4_DAR1:
1138     dma_channel ++;
1139     case SH4_DAR0:
1140     dma_channel ++;
1141     if (writeflag == MEM_READ)
1142     odata = cpu->cd.sh.dmac_dar[dma_channel];
1143     else
1144     cpu->cd.sh.dmac_dar[dma_channel] = idata;
1145     break;
1146    
1147     case SH4_DMATCR3:
1148     dma_channel ++;
1149     case SH4_DMATCR2:
1150     dma_channel ++;
1151     case SH4_DMATCR1:
1152     dma_channel ++;
1153     case SH4_DMATCR0:
1154     dma_channel ++;
1155     if (writeflag == MEM_READ)
1156     odata = cpu->cd.sh.dmac_tcr[dma_channel] & 0x00ffffff;
1157     else {
1158     if (idata & ~0x00ffffff) {
1159     fatal("[ SH4 DMA: Attempt to set top 8 "
1160     "bits of the count register? 0x%08"
1161     PRIx32" ]\n", (uint32_t) idata);
1162     exit(1);
1163     }
1164    
1165     /* Special case: writing 0 to the count register
1166     means 16777216: */
1167     if (idata == 0)
1168     idata = 0x01000000;
1169     cpu->cd.sh.dmac_tcr[dma_channel] = idata;
1170     }
1171     break;
1172    
1173     case SH4_CHCR3:
1174     dma_channel ++;
1175     case SH4_CHCR2:
1176     dma_channel ++;
1177     case SH4_CHCR1:
1178     dma_channel ++;
1179     case SH4_CHCR0:
1180     dma_channel ++;
1181     if (writeflag == MEM_READ)
1182     odata = cpu->cd.sh.dmac_chcr[dma_channel];
1183     else {
1184     /* IP.BIN sets this to 0x12c0, and I want to know if
1185     some other guest OS uses other values. */
1186     if (idata != 0x12c0) {
1187     fatal("[ SH4 DMA: Attempt to set chcr "
1188     "to 0x%08"PRIx32" ]\n", (uint32_t) idata);
1189     exit(1);
1190     }
1191    
1192     cpu->cd.sh.dmac_chcr[dma_channel] = idata;
1193     }
1194     break;
1195    
1196    
1197     /*************************************************/
1198 dpavlin 32 /* BSC: Bus State Controller */
1199    
1200 dpavlin 34 case SH4_BCR1:
1201     if (writeflag == MEM_WRITE)
1202     d->bsc_bcr1 = idata & 0x033efffd;
1203     else {
1204     odata = d->bsc_bcr1;
1205     if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1206     odata |= BCR1_LITTLE_ENDIAN;
1207     }
1208 dpavlin 32 break;
1209    
1210 dpavlin 34 case SH4_BCR2:
1211     if (len != sizeof(uint16_t)) {
1212     fatal("Non-16-bit SH4_BCR2 access?\n");
1213     exit(1);
1214     }
1215     if (writeflag == MEM_WRITE)
1216     d->bsc_bcr2 = idata & 0x3ffd;
1217     else
1218     odata = d->bsc_bcr2;
1219     break;
1220    
1221     case SH4_WCR1:
1222     if (writeflag == MEM_WRITE)
1223     d->bsc_wcr1 = idata & 0x77777777;
1224     else
1225     odata = d->bsc_wcr1;
1226     break;
1227    
1228     case SH4_WCR2:
1229     if (writeflag == MEM_WRITE)
1230     d->bsc_wcr2 = idata & 0xfffeefff;
1231     else
1232     odata = d->bsc_wcr2;
1233     break;
1234    
1235     case SH4_MCR:
1236     if (writeflag == MEM_WRITE)
1237     d->bsc_mcr = idata & 0xf8bbffff;
1238     else
1239     odata = d->bsc_mcr;
1240     break;
1241    
1242     case SH4_RTCSR:
1243 dpavlin 32 /*
1244 dpavlin 34 * Refresh Time Control/Status Register. Called RTCSR in
1245     * NetBSD, but RTSCR in the SH7750 manual?
1246 dpavlin 32 */
1247     if (writeflag == MEM_WRITE) {
1248 dpavlin 34 idata &= 0x00ff;
1249     if (idata & RTCSR_CMF) {
1250     idata = (idata & ~RTCSR_CMF)
1251     | (d->bsc_rtcsr & RTCSR_CMF);
1252     }
1253     d->bsc_rtcsr = idata & 0x00ff;
1254 dpavlin 32 } else
1255 dpavlin 34 odata = d->bsc_rtcsr;
1256 dpavlin 32 break;
1257    
1258 dpavlin 34 case SH4_RTCOR:
1259     /* Refresh Time Constant Register (8 bits): */
1260 dpavlin 32 if (writeflag == MEM_WRITE)
1261 dpavlin 34 d->bsc_rtcor = idata & 0x00ff;
1262     else
1263     odata = d->bsc_rtcor & 0x00ff;
1264     break;
1265 dpavlin 32
1266 dpavlin 34 case SH4_RFCR:
1267     /* Refresh Count Register (10 bits): */
1268     if (writeflag == MEM_WRITE)
1269     d->bsc_rfcr = idata & 0x03ff;
1270     else
1271     odata = d->bsc_rfcr & 0x03ff;
1272     break;
1273    
1274    
1275     /*******************************************/
1276     /* GPIO: General-purpose I/O controller */
1277    
1278     case SH4_PCTRA:
1279     if (writeflag == MEM_WRITE)
1280     d->pctra = idata;
1281     else
1282     odata = d->pctra;
1283     break;
1284    
1285     case SH4_PDTRA:
1286     if (writeflag == MEM_WRITE) {
1287     debug("[ sh4: pdtra: write: TODO ]\n");
1288     d->pdtra = idata;
1289     } else {
1290     debug("[ sh4: pdtra: read: TODO ]\n");
1291     odata = d->pdtra;
1292 dpavlin 32 }
1293     break;
1294    
1295 dpavlin 34 case SH4_PCTRB:
1296     if (writeflag == MEM_WRITE)
1297     d->pctrb = idata;
1298     else
1299     odata = d->pctrb;
1300     break;
1301 dpavlin 32
1302 dpavlin 34 case SH4_PDTRB:
1303     if (writeflag == MEM_WRITE) {
1304     debug("[ sh4: pdtrb: write: TODO ]\n");
1305     d->pdtrb = idata;
1306     } else {
1307     debug("[ sh4: pdtrb: read: TODO ]\n");
1308     odata = d->pdtrb;
1309     }
1310     break;
1311    
1312    
1313 dpavlin 38 /****************************/
1314     /* SCI: Serial Interface */
1315    
1316     case SHREG_SCSPTR:
1317     odata = sh_sci_access(d, cpu,
1318     writeflag == MEM_WRITE? 1 : 0, idata);
1319 dpavlin 40
1320     /*
1321     * TODO
1322     *
1323     * Find out the REAL way to make OpenBSD/landisk 4.1 run
1324     * in a stable manner! This is a SUPER-UGLY HACK which
1325     * just side-steps the real bug.
1326     *
1327     * NOTE: Snapshots of OpenBSD/landisk _after_ 4.1 seem
1328     * to work WITHOUT this hack, but NOT with it!
1329     */
1330     cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
1331    
1332 dpavlin 38 break;
1333    
1334    
1335 dpavlin 32 /*********************************/
1336     /* INTC: Interrupt Controller */
1337    
1338     case SH4_ICR:
1339     if (writeflag == MEM_WRITE) {
1340     if (idata & 0x80) {
1341     fatal("SH4 INTC: IRLM not yet "
1342     "supported. TODO\n");
1343     exit(1);
1344     }
1345     }
1346     break;
1347    
1348     case SH4_IPRA:
1349     if (writeflag == MEM_READ)
1350     odata = cpu->cd.sh.intc_ipra;
1351 dpavlin 38 else {
1352 dpavlin 32 cpu->cd.sh.intc_ipra = idata;
1353 dpavlin 38 sh_update_interrupt_priorities(cpu);
1354     }
1355 dpavlin 32 break;
1356    
1357     case SH4_IPRB:
1358     if (writeflag == MEM_READ)
1359     odata = cpu->cd.sh.intc_iprb;
1360 dpavlin 38 else {
1361 dpavlin 32 cpu->cd.sh.intc_iprb = idata;
1362 dpavlin 38 sh_update_interrupt_priorities(cpu);
1363     }
1364 dpavlin 32 break;
1365    
1366     case SH4_IPRC:
1367     if (writeflag == MEM_READ)
1368     odata = cpu->cd.sh.intc_iprc;
1369 dpavlin 38 else {
1370 dpavlin 32 cpu->cd.sh.intc_iprc = idata;
1371 dpavlin 38 sh_update_interrupt_priorities(cpu);
1372     }
1373 dpavlin 32 break;
1374    
1375 dpavlin 34 case SH4_IPRD:
1376     if (writeflag == MEM_READ)
1377     odata = cpu->cd.sh.intc_iprd;
1378 dpavlin 38 else {
1379 dpavlin 34 cpu->cd.sh.intc_iprd = idata;
1380 dpavlin 38 sh_update_interrupt_priorities(cpu);
1381     }
1382 dpavlin 34 break;
1383 dpavlin 32
1384 dpavlin 38 case SH4_INTPRI00:
1385     if (writeflag == MEM_READ)
1386     odata = cpu->cd.sh.intc_intpri00;
1387     else {
1388     cpu->cd.sh.intc_intpri00 = idata;
1389     sh_update_interrupt_priorities(cpu);
1390     }
1391     break;
1392 dpavlin 34
1393 dpavlin 38 case SH4_INTPRI00 + 4:
1394     if (writeflag == MEM_READ)
1395     odata = cpu->cd.sh.intc_intpri04;
1396     else {
1397     cpu->cd.sh.intc_intpri04 = idata;
1398     sh_update_interrupt_priorities(cpu);
1399     }
1400     break;
1401    
1402     case SH4_INTPRI00 + 8:
1403     if (writeflag == MEM_READ)
1404     odata = cpu->cd.sh.intc_intpri08;
1405     else {
1406     cpu->cd.sh.intc_intpri08 = idata;
1407     sh_update_interrupt_priorities(cpu);
1408     }
1409     break;
1410    
1411     case SH4_INTPRI00 + 0xc:
1412     if (writeflag == MEM_READ)
1413     odata = cpu->cd.sh.intc_intpri0c;
1414     else {
1415     cpu->cd.sh.intc_intpri0c = idata;
1416     sh_update_interrupt_priorities(cpu);
1417     }
1418     break;
1419    
1420     case SH4_INTMSK00:
1421     /* Note: Writes can only set bits, not clear them. */
1422     if (writeflag == MEM_READ)
1423     odata = cpu->cd.sh.intc_intmsk00;
1424     else
1425     cpu->cd.sh.intc_intmsk00 |= idata;
1426     break;
1427    
1428     case SH4_INTMSK00 + 4:
1429     /* Note: Writes can only set bits, not clear them. */
1430     if (writeflag == MEM_READ)
1431     odata = cpu->cd.sh.intc_intmsk04;
1432     else
1433     cpu->cd.sh.intc_intmsk04 |= idata;
1434     break;
1435    
1436     case SH4_INTMSKCLR00:
1437     /* Note: Writes can only clear bits, not set them. */
1438     if (writeflag == MEM_WRITE)
1439     cpu->cd.sh.intc_intmsk00 &= ~idata;
1440     break;
1441    
1442     case SH4_INTMSKCLR00 + 4:
1443     /* Note: Writes can only clear bits, not set them. */
1444     if (writeflag == MEM_WRITE)
1445     cpu->cd.sh.intc_intmsk04 &= ~idata;
1446     break;
1447    
1448    
1449 dpavlin 32 /*************************************************/
1450     /* SCIF: Serial Controller Interface with FIFO */
1451    
1452 dpavlin 34 case SH4_SCIF_BASE + SCIF_SMR:
1453     if (writeflag == MEM_WRITE) {
1454     d->scif_smr = idata;
1455     } else {
1456     odata = d->scif_smr;
1457     }
1458     break;
1459    
1460     case SH4_SCIF_BASE + SCIF_BRR:
1461     if (writeflag == MEM_WRITE) {
1462     d->scif_brr = idata;
1463     } else {
1464     odata = d->scif_brr;
1465     }
1466     break;
1467    
1468     case SH4_SCIF_BASE + SCIF_SCR:
1469     if (writeflag == MEM_WRITE) {
1470     d->scif_scr = idata;
1471 dpavlin 36 scif_reassert_interrupts(d);
1472 dpavlin 34 } else {
1473     odata = d->scif_scr;
1474     }
1475     break;
1476    
1477 dpavlin 32 case SH4_SCIF_BASE + SCIF_FTDR:
1478 dpavlin 36 if (writeflag == MEM_WRITE) {
1479 dpavlin 38 /* Add to TX fifo: */
1480 dpavlin 40 if (d->scif_tx_fifo_cursize >=
1481     sizeof(d->scif_tx_fifo)) {
1482 dpavlin 38 fatal("[ SCIF TX fifo overrun! ]\n");
1483     d->scif_tx_fifo_cursize = 0;
1484     }
1485    
1486     d->scif_tx_fifo[d->scif_tx_fifo_cursize++] = idata;
1487 dpavlin 40 d->scif_delayed_tx = SCIF_DELAYED_TX_VALUE;
1488 dpavlin 36 }
1489 dpavlin 32 break;
1490    
1491     case SH4_SCIF_BASE + SCIF_SSR:
1492 dpavlin 36 if (writeflag == MEM_READ) {
1493     odata = d->scif_ssr;
1494     } else {
1495 dpavlin 38 d->scif_ssr = idata;
1496 dpavlin 36 scif_reassert_interrupts(d);
1497     }
1498 dpavlin 32 break;
1499    
1500     case SH4_SCIF_BASE + SCIF_FRDR:
1501     {
1502     int x = console_readchar(d->scif_console_handle);
1503     if (x == 13)
1504     x = 10;
1505     odata = x < 0? 0 : x;
1506 dpavlin 38 if (console_charavail(d->scif_console_handle))
1507     d->scif_ssr |= SCSSR2_DR;
1508     else
1509     d->scif_ssr &= ~SCSSR2_DR;
1510     scif_reassert_interrupts(d);
1511 dpavlin 32 }
1512     break;
1513    
1514 dpavlin 34 case SH4_SCIF_BASE + SCIF_FCR:
1515     if (writeflag == MEM_WRITE) {
1516     d->scif_fcr = idata;
1517     } else {
1518     odata = d->scif_fcr;
1519     }
1520     break;
1521    
1522 dpavlin 38 case SH4_SCIF_BASE + SCIF_LSR:
1523     /* TODO: Implement all bits. */
1524     odata = 0;
1525     break;
1526    
1527 dpavlin 32 case SH4_SCIF_BASE + SCIF_FDR:
1528 dpavlin 40 /* Nr of bytes in the TX and RX fifos, respectively: */
1529 dpavlin 38 odata = (console_charavail(d->scif_console_handle)? 1 : 0)
1530     + (d->scif_tx_fifo_cursize << 8);
1531 dpavlin 32 break;
1532    
1533 dpavlin 34
1534 dpavlin 32 /*************************************************/
1535    
1536 dpavlin 34 case SH4_RSECCNT:
1537     case SH4_RMINCNT:
1538     case SH4_RHRCNT:
1539     case SH4_RWKCNT:
1540     case SH4_RDAYCNT:
1541     case SH4_RMONCNT:
1542     case SH4_RYRCNT:
1543     case SH4_RSECAR:
1544     case SH4_RMINAR:
1545     case SH4_RHRAR:
1546     case SH4_RWKAR:
1547     case SH4_RDAYAR:
1548     case SH4_RMONAR:
1549     if (writeflag == MEM_WRITE) {
1550     d->rtc_reg[(relative_addr - 0xffc80000) / 4] = idata;
1551     } else {
1552     /* TODO: Update rtc_reg based on host's date/time. */
1553     odata = d->rtc_reg[(relative_addr - 0xffc80000) / 4];
1554     }
1555     break;
1556    
1557     case SH4_RCR1:
1558     if (writeflag == MEM_READ)
1559     odata = d->rtc_rcr1;
1560     else {
1561     d->rtc_rcr1 = idata;
1562     if (idata & 0x18) {
1563     fatal("SH4: TODO: RTC interrupt enable\n");
1564     exit(1);
1565     }
1566     }
1567     break;
1568    
1569    
1570     /*************************************************/
1571    
1572 dpavlin 32 default:if (writeflag == MEM_READ) {
1573     fatal("[ sh4: read from addr 0x%x ]\n",
1574     (int)relative_addr);
1575     } else {
1576     fatal("[ sh4: write to addr 0x%x: 0x%x ]\n",
1577     (int)relative_addr, (int)idata);
1578     }
1579 dpavlin 34 #ifdef SH4_DEGUG
1580 dpavlin 40 /* exit(1); */
1581 dpavlin 34 #endif
1582 dpavlin 32 }
1583    
1584     if (writeflag == MEM_READ)
1585     memory_writemax64(cpu, data, len, odata);
1586    
1587     return 1;
1588     }
1589    
1590    
1591     DEVINIT(sh4)
1592     {
1593 dpavlin 40 char tmp[200], n[200];
1594     int i;
1595 dpavlin 32 struct machine *machine = devinit->machine;
1596 dpavlin 42 struct sh4_data *d;
1597 dpavlin 40
1598 dpavlin 42 CHECK_ALLOCATION(d = malloc(sizeof(struct sh4_data)));
1599 dpavlin 32 memset(d, 0, sizeof(struct sh4_data));
1600    
1601    
1602 dpavlin 40 /*
1603     * Main SH4 device, and misc memory stuff:
1604     */
1605 dpavlin 36
1606 dpavlin 32 memory_device_register(machine->memory, devinit->name,
1607     SH4_REG_BASE, 0x01000000, dev_sh4_access, d, DM_DEFAULT, NULL);
1608    
1609     /* On-chip RAM/cache: */
1610     dev_ram_init(machine, 0x1e000000, 0x8000, DEV_RAM_RAM, 0x0);
1611    
1612     /* 0xe0000000: Store queues: */
1613     dev_ram_init(machine, 0xe0000000, 32 * 2, DEV_RAM_RAM, 0x0);
1614    
1615 dpavlin 40
1616 dpavlin 32 /*
1617 dpavlin 40 * SCIF (Serial console):
1618     */
1619    
1620     d->scif_console_handle = console_start_slave(devinit->machine,
1621     "SH4 SCIF", 1);
1622    
1623     snprintf(tmp, sizeof(tmp), "%s.irq[0x%x]",
1624     devinit->interrupt_path, SH4_INTEVT_SCIF_RXI);
1625     INTERRUPT_CONNECT(tmp, d->scif_rx_irq);
1626     snprintf(tmp, sizeof(tmp), "%s.irq[0x%x]",
1627     devinit->interrupt_path, SH4_INTEVT_SCIF_TXI);
1628     INTERRUPT_CONNECT(tmp, d->scif_tx_irq);
1629    
1630    
1631     /*
1632     * Caches (fake):
1633     *
1634 dpavlin 32 * 0xf0000000 SH4_CCIA I-Cache address array
1635     * 0xf1000000 SH4_CCID I-Cache data array
1636     * 0xf4000000 SH4_CCDA D-Cache address array
1637     * 0xf5000000 SH4_CCDD D-Cache data array
1638     *
1639     * TODO: Implement more correct cache behaviour?
1640     */
1641 dpavlin 40
1642 dpavlin 36 dev_ram_init(machine, SH4_CCIA, SH4_ICACHE_SIZE * 2, DEV_RAM_RAM, 0x0);
1643     dev_ram_init(machine, SH4_CCID, SH4_ICACHE_SIZE, DEV_RAM_RAM, 0x0);
1644     dev_ram_init(machine, SH4_CCDA, SH4_DCACHE_SIZE * 2, DEV_RAM_RAM, 0x0);
1645     dev_ram_init(machine, SH4_CCDD, SH4_DCACHE_SIZE, DEV_RAM_RAM, 0x0);
1646 dpavlin 32
1647     /* 0xf2000000 SH4_ITLB_AA */
1648 dpavlin 40 memory_device_register(machine->memory, "sh4_itlb_aa", SH4_ITLB_AA,
1649 dpavlin 32 0x01000000, dev_sh4_itlb_aa_access, d, DM_DEFAULT, NULL);
1650    
1651     /* 0xf3000000 SH4_ITLB_DA1 */
1652 dpavlin 40 memory_device_register(machine->memory, "sh4_itlb_da1", SH4_ITLB_DA1,
1653 dpavlin 32 0x01000000, dev_sh4_itlb_da1_access, d, DM_DEFAULT, NULL);
1654    
1655     /* 0xf6000000 SH4_UTLB_AA */
1656 dpavlin 40 memory_device_register(machine->memory, "sh4_utlb_aa", SH4_UTLB_AA,
1657 dpavlin 32 0x01000000, dev_sh4_utlb_aa_access, d, DM_DEFAULT, NULL);
1658    
1659     /* 0xf7000000 SH4_UTLB_DA1 */
1660 dpavlin 40 memory_device_register(machine->memory, "sh4_utlb_da1", SH4_UTLB_DA1,
1661 dpavlin 32 0x01000000, dev_sh4_utlb_da1_access, d, DM_DEFAULT, NULL);
1662    
1663 dpavlin 40
1664     /*
1665     * PCIC (PCI controller) at 0xfe200000:
1666     */
1667    
1668     memory_device_register(machine->memory, "sh4_pcic", SH4_PCIC,
1669     N_PCIC_REGS * sizeof(uint32_t), dev_sh4_pcic_access, d,
1670     DM_DEFAULT, NULL);
1671    
1672     /* Initial PCI control register contents: */
1673     d->bsc_bcr2 = BCR2_PORTEN;
1674     d->pcic_reg[PCIC_REG(SH4_PCICONF2)] = PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
1675     PCI_SUBCLASS_BRIDGE_HOST, 0);
1676    
1677     /* Register 16 PCIC interrupts: */
1678     for (i=0; i<N_PCIC_IRQS; i++) {
1679     struct interrupt template;
1680     snprintf(n, sizeof(n), "%s.pcic.%i",
1681     devinit->interrupt_path, i);
1682     memset(&template, 0, sizeof(template));
1683     template.line = i;
1684     template.name = n;
1685     template.extra = d;
1686     template.interrupt_assert = sh4_pcic_interrupt_assert;
1687     template.interrupt_deassert = sh4_pcic_interrupt_deassert;
1688     interrupt_handler_register(&template);
1689    
1690     snprintf(tmp, sizeof(tmp), "%s.irq[0x%x]",
1691     devinit->interrupt_path, SH4_INTEVT_IRQ0 + 0x20 * i);
1692     INTERRUPT_CONNECT(tmp, d->cpu_pcic_interrupt[i]);
1693     }
1694    
1695     /* Register the PCI bus: */
1696     snprintf(tmp, sizeof(tmp), "%s.pcic", devinit->interrupt_path);
1697     d->pci_data = bus_pci_init(
1698     devinit->machine,
1699     tmp, /* pciirq */
1700     0, /* pci device io offset */
1701     0, /* pci device mem offset */
1702     SH4_PCIC_IO, /* PCI portbase */
1703     SH4_PCIC_MEM, /* PCI membase */
1704     tmp, /* PCI irqbase */
1705     0x00000000, /* ISA portbase */
1706     0x00000000, /* ISA membase */
1707     "TODOisaIrqBase"); /* ISA irqbase */
1708    
1709     /* Return PCI bus pointer, to allow per-machine devices
1710     to be added later: */
1711     devinit->return_ptr = d->pci_data;
1712    
1713    
1714     /*
1715     * Timer:
1716     */
1717    
1718 dpavlin 32 d->sh4_timer = timer_add(SH4_PSEUDO_TIMER_HZ, sh4_timer_tick, d);
1719     machine_add_tickfunction(devinit->machine, dev_sh4_tick, d,
1720 dpavlin 42 SH4_TICK_SHIFT);
1721 dpavlin 32
1722     /* Initial Timer values, according to the SH7750 manual: */
1723     d->tcor[0] = 0xffffffff; d->tcnt[0] = 0xffffffff;
1724     d->tcor[1] = 0xffffffff; d->tcnt[1] = 0xffffffff;
1725     d->tcor[2] = 0xffffffff; d->tcnt[2] = 0xffffffff;
1726    
1727 dpavlin 44 snprintf(tmp, sizeof(tmp), "machine[0].cpu[0].irq[0x%x]",
1728 dpavlin 34 SH_INTEVT_TMU0_TUNI0);
1729     if (!interrupt_handler_lookup(tmp, &d->timer_irq[0])) {
1730     fatal("Could not find interrupt '%s'.\n", tmp);
1731     exit(1);
1732     }
1733 dpavlin 44 snprintf(tmp, sizeof(tmp), "machine[0].cpu[0].irq[0x%x]",
1734 dpavlin 34 SH_INTEVT_TMU1_TUNI1);
1735     if (!interrupt_handler_lookup(tmp, &d->timer_irq[1])) {
1736     fatal("Could not find interrupt '%s'.\n", tmp);
1737     exit(1);
1738     }
1739 dpavlin 44 snprintf(tmp, sizeof(tmp), "machine[0].cpu[0].irq[0x%x]",
1740 dpavlin 34 SH_INTEVT_TMU2_TUNI2);
1741     if (!interrupt_handler_lookup(tmp, &d->timer_irq[2])) {
1742     fatal("Could not find interrupt '%s'.\n", tmp);
1743     exit(1);
1744     }
1745    
1746 dpavlin 40
1747 dpavlin 38 /*
1748     * Bus State Controller initial values, according to the
1749     * SH7760 manual:
1750     */
1751 dpavlin 40
1752 dpavlin 34 d->bsc_bcr2 = 0x3ffc;
1753     d->bsc_wcr1 = 0x77777777;
1754     d->bsc_wcr2 = 0xfffeefff;
1755    
1756 dpavlin 40
1757 dpavlin 32 return 1;
1758     }
1759    

  ViewVC Help
Powered by ViewVC 1.1.26