/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 44 - (show 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 /*
2 * Copyright (C) 2006-2007 Anders Gavare. All rights reserved.
3 *
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 * $Id: dev_sh4.c,v 1.51 2007/08/29 20:36:49 debug Exp $
29 *
30 * COMMENT: SH4-specific memory mapped registers (0xf0000000 - 0xffffffff)
31 *
32 * 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 */
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 #include "bus_pci.h"
46 #include "console.h"
47 #include "cpu.h"
48 #include "device.h"
49 #include "devices.h"
50 #include "interrupt.h"
51 #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 #include "sh4_dmacreg.h"
59 #include "sh4_exception.h"
60 #include "sh4_intcreg.h"
61 #include "sh4_mmu.h"
62 #include "sh4_pcicreg.h"
63 #include "sh4_rtcreg.h"
64 #include "sh4_scifreg.h"
65 #include "sh4_scireg.h"
66 #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 /* 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 #define SCIF_TX_FIFO_SIZE 16
82 #define SCIF_DELAYED_TX_VALUE 2 /* 2 to be safe, 1 = fast but buggy */
83
84 /* 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 /* #define debug fatal */
94 #endif
95
96 struct sh4_data {
97 /* SCIF (Serial controller): */
98 uint16_t scif_smr;
99 uint8_t scif_brr;
100 uint16_t scif_scr;
101 uint16_t scif_ssr;
102 uint16_t scif_fcr;
103 uint16_t scif_lsr;
104 int scif_delayed_tx;
105 int scif_console_handle;
106 uint8_t scif_tx_fifo[SCIF_TX_FIFO_SIZE + 1];
107 size_t scif_tx_fifo_cursize;
108 struct interrupt scif_tx_irq;
109 struct interrupt scif_rx_irq;
110 int scif_tx_irq_asserted;
111 int scif_rx_irq_asserted;
112
113 /* Bus State Controller: */
114 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
123 /* 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 /* 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 /* 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 /* SD-RAM: */
142 uint16_t sdmr2;
143 uint16_t sdmr3;
144
145 /* Timer Management Unit: */
146 struct timer *sh4_timer;
147 struct interrupt timer_irq[4];
148 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
156 /* RTC: */
157 uint32_t rtc_reg[14]; /* Excluding rcr1 and 2 */
158 uint8_t rtc_rcr1;
159 };
160
161
162 #define SH4_PSEUDO_TIMER_HZ 110.0
163
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 *
172 * Also, RAM Refresh is also faked here.
173 */
174 static void sh4_timer_tick(struct timer *t, void *extra)
175 {
176 struct sh4_data *d = extra;
177 int i;
178
179 /* 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 /* Timer interrupts: */
188 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 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 static void scif_reassert_interrupts(struct sh4_data *d)
237 {
238 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 INTERRUPT_DEASSERT(d->scif_rx_irq);
248
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 INTERRUPT_DEASSERT(d->scif_tx_irq);
257 }
258
259
260 DEVICE_TICK(sh4)
261 {
262 struct sh4_data *d = extra;
263 unsigned int i;
264
265 /*
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 if (console_charavail(d->scif_console_handle))
272 d->scif_ssr |= SCSSR2_DR;
273 else
274 d->scif_ssr &= ~SCSSR2_DR;
275
276 if (d->scif_delayed_tx) {
277 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 d->scif_ssr |= SCSSR2_TDFE | SCSSR2_TEND;
288 }
289 }
290
291 scif_reassert_interrupts(d);
292
293 /* Timer interrupts: */
294 for (i=0; i<N_SH4_TIMERS; i++)
295 if (d->timer_interrupts_pending[i] > 0) {
296 INTERRUPT_ASSERT(d->timer_irq[i]);
297 d->tcr[i] |= TCR_UNF;
298 }
299 }
300
301
302 /*
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 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 /* 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 } 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 uint32_t old_lo = cpu->cd.sh.itlb_lo[e];
490 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 /* 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 } 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 cpu->cd.sh.itlb_lo[i +
573 SH_N_ITLB_ENTRIES] &= ~SH4_PTEL_V;
574 if (idata & SH4_UTLB_AA_V)
575 cpu->cd.sh.itlb_lo[
576 i+SH_N_ITLB_ENTRIES] |=
577 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 cpu->invalidate_translation_caches(cpu, 0,
621 INVALIDATE_ALL);
622 } 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 uint32_t old_lo = cpu->cd.sh.utlb_lo[e];
650 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 /* 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 } 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 DEVICE_ACCESS(sh4_pcic)
681 {
682 struct sh4_data *d = extra;
683 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 DEVICE_ACCESS(sh4)
839 {
840 struct sh4_data *d = extra;
841 uint64_t idata = 0, odata = 0;
842 int timer_nr = 0, dma_channel = 0;
843
844 if (writeflag == MEM_WRITE)
845 idata = memory_readmax64(cpu, data, len);
846
847 relative_addr += SH4_REG_BASE;
848
849 /* 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 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 unsigned int old_asid = cpu->cd.sh.pteh
880 & SH4_PTEH_ASID_MASK;
881 cpu->cd.sh.pteh = idata;
882
883 if ((idata & SH4_PTEH_ASID_MASK) != old_asid) {
884 /*
885 * TODO: Don't invalidate everything,
886 * only those pages that belonged to the
887 * old asid.
888 */
889 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 int i;
930 for (i = 0; i < SH_N_ITLB_ENTRIES; i++)
931 cpu->cd.sh.itlb_lo[i] &=
932 ~SH4_PTEL_V;
933
934 for (i = 0; i < SH_N_UTLB_ENTRIES; i++)
935 cpu->cd.sh.utlb_lo[i] &=
936 ~SH4_PTEL_V;
937
938 cpu->invalidate_translation_caches(cpu,
939 0, INVALIDATE_ALL);
940
941 /* The TI bit should always read as 0. */
942 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 INTERRUPT_DEASSERT(d->timer_irq[timer_nr]);
1105
1106 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 /* 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 /* BSC: Bus State Controller */
1199
1200 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 break;
1209
1210 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 /*
1244 * Refresh Time Control/Status Register. Called RTCSR in
1245 * NetBSD, but RTSCR in the SH7750 manual?
1246 */
1247 if (writeflag == MEM_WRITE) {
1248 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 } else
1255 odata = d->bsc_rtcsr;
1256 break;
1257
1258 case SH4_RTCOR:
1259 /* Refresh Time Constant Register (8 bits): */
1260 if (writeflag == MEM_WRITE)
1261 d->bsc_rtcor = idata & 0x00ff;
1262 else
1263 odata = d->bsc_rtcor & 0x00ff;
1264 break;
1265
1266 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 }
1293 break;
1294
1295 case SH4_PCTRB:
1296 if (writeflag == MEM_WRITE)
1297 d->pctrb = idata;
1298 else
1299 odata = d->pctrb;
1300 break;
1301
1302 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 /****************************/
1314 /* SCI: Serial Interface */
1315
1316 case SHREG_SCSPTR:
1317 odata = sh_sci_access(d, cpu,
1318 writeflag == MEM_WRITE? 1 : 0, idata);
1319
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 break;
1333
1334
1335 /*********************************/
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 else {
1352 cpu->cd.sh.intc_ipra = idata;
1353 sh_update_interrupt_priorities(cpu);
1354 }
1355 break;
1356
1357 case SH4_IPRB:
1358 if (writeflag == MEM_READ)
1359 odata = cpu->cd.sh.intc_iprb;
1360 else {
1361 cpu->cd.sh.intc_iprb = idata;
1362 sh_update_interrupt_priorities(cpu);
1363 }
1364 break;
1365
1366 case SH4_IPRC:
1367 if (writeflag == MEM_READ)
1368 odata = cpu->cd.sh.intc_iprc;
1369 else {
1370 cpu->cd.sh.intc_iprc = idata;
1371 sh_update_interrupt_priorities(cpu);
1372 }
1373 break;
1374
1375 case SH4_IPRD:
1376 if (writeflag == MEM_READ)
1377 odata = cpu->cd.sh.intc_iprd;
1378 else {
1379 cpu->cd.sh.intc_iprd = idata;
1380 sh_update_interrupt_priorities(cpu);
1381 }
1382 break;
1383
1384 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
1393 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 /*************************************************/
1450 /* SCIF: Serial Controller Interface with FIFO */
1451
1452 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 scif_reassert_interrupts(d);
1472 } else {
1473 odata = d->scif_scr;
1474 }
1475 break;
1476
1477 case SH4_SCIF_BASE + SCIF_FTDR:
1478 if (writeflag == MEM_WRITE) {
1479 /* Add to TX fifo: */
1480 if (d->scif_tx_fifo_cursize >=
1481 sizeof(d->scif_tx_fifo)) {
1482 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 d->scif_delayed_tx = SCIF_DELAYED_TX_VALUE;
1488 }
1489 break;
1490
1491 case SH4_SCIF_BASE + SCIF_SSR:
1492 if (writeflag == MEM_READ) {
1493 odata = d->scif_ssr;
1494 } else {
1495 d->scif_ssr = idata;
1496 scif_reassert_interrupts(d);
1497 }
1498 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 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 }
1512 break;
1513
1514 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 case SH4_SCIF_BASE + SCIF_LSR:
1523 /* TODO: Implement all bits. */
1524 odata = 0;
1525 break;
1526
1527 case SH4_SCIF_BASE + SCIF_FDR:
1528 /* Nr of bytes in the TX and RX fifos, respectively: */
1529 odata = (console_charavail(d->scif_console_handle)? 1 : 0)
1530 + (d->scif_tx_fifo_cursize << 8);
1531 break;
1532
1533
1534 /*************************************************/
1535
1536 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 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 #ifdef SH4_DEGUG
1580 /* exit(1); */
1581 #endif
1582 }
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 char tmp[200], n[200];
1594 int i;
1595 struct machine *machine = devinit->machine;
1596 struct sh4_data *d;
1597
1598 CHECK_ALLOCATION(d = malloc(sizeof(struct sh4_data)));
1599 memset(d, 0, sizeof(struct sh4_data));
1600
1601
1602 /*
1603 * Main SH4 device, and misc memory stuff:
1604 */
1605
1606 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
1616 /*
1617 * 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 * 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
1642 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
1647 /* 0xf2000000 SH4_ITLB_AA */
1648 memory_device_register(machine->memory, "sh4_itlb_aa", SH4_ITLB_AA,
1649 0x01000000, dev_sh4_itlb_aa_access, d, DM_DEFAULT, NULL);
1650
1651 /* 0xf3000000 SH4_ITLB_DA1 */
1652 memory_device_register(machine->memory, "sh4_itlb_da1", SH4_ITLB_DA1,
1653 0x01000000, dev_sh4_itlb_da1_access, d, DM_DEFAULT, NULL);
1654
1655 /* 0xf6000000 SH4_UTLB_AA */
1656 memory_device_register(machine->memory, "sh4_utlb_aa", SH4_UTLB_AA,
1657 0x01000000, dev_sh4_utlb_aa_access, d, DM_DEFAULT, NULL);
1658
1659 /* 0xf7000000 SH4_UTLB_DA1 */
1660 memory_device_register(machine->memory, "sh4_utlb_da1", SH4_UTLB_DA1,
1661 0x01000000, dev_sh4_utlb_da1_access, d, DM_DEFAULT, NULL);
1662
1663
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 d->sh4_timer = timer_add(SH4_PSEUDO_TIMER_HZ, sh4_timer_tick, d);
1719 machine_add_tickfunction(devinit->machine, dev_sh4_tick, d,
1720 SH4_TICK_SHIFT);
1721
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 snprintf(tmp, sizeof(tmp), "machine[0].cpu[0].irq[0x%x]",
1728 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 snprintf(tmp, sizeof(tmp), "machine[0].cpu[0].irq[0x%x]",
1734 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 snprintf(tmp, sizeof(tmp), "machine[0].cpu[0].irq[0x%x]",
1740 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
1747 /*
1748 * Bus State Controller initial values, according to the
1749 * SH7760 manual:
1750 */
1751
1752 d->bsc_bcr2 = 0x3ffc;
1753 d->bsc_wcr1 = 0x77777777;
1754 d->bsc_wcr2 = 0xfffeefff;
1755
1756
1757 return 1;
1758 }
1759

  ViewVC Help
Powered by ViewVC 1.1.26