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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC revision 44 by dpavlin, Mon Oct 8 16:22:56 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2006  Anders Gavare.  All rights reserved.   *  Copyright (C) 2006-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_sh4.c,v 1.21 2006/11/02 05:43:44 debug Exp $   *  $Id: dev_sh4.c,v 1.51 2007/08/29 20:36:49 debug Exp $
29   *     *  
30   *  SH4 processor specific memory mapped registers (0xf0000000 - 0xffffffff).   *  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>  #include <stdio.h>
42  #include <stdlib.h>  #include <stdlib.h>
43  #include <string.h>  #include <string.h>
44    
45    #include "bus_pci.h"
46  #include "console.h"  #include "console.h"
47  #include "cpu.h"  #include "cpu.h"
48  #include "device.h"  #include "device.h"
49  #include "devices.h"  #include "devices.h"
50    #include "interrupt.h"
51  #include "machine.h"  #include "machine.h"
52  #include "memory.h"  #include "memory.h"
53  #include "misc.h"  #include "misc.h"
# Line 45  Line 55 
55    
56  #include "sh4_bscreg.h"  #include "sh4_bscreg.h"
57  #include "sh4_cache.h"  #include "sh4_cache.h"
58    #include "sh4_dmacreg.h"
59  #include "sh4_exception.h"  #include "sh4_exception.h"
60  #include "sh4_intcreg.h"  #include "sh4_intcreg.h"
61  #include "sh4_mmu.h"  #include "sh4_mmu.h"
62    #include "sh4_pcicreg.h"
63    #include "sh4_rtcreg.h"
64  #include "sh4_scifreg.h"  #include "sh4_scifreg.h"
65    #include "sh4_scireg.h"
66  #include "sh4_tmureg.h"  #include "sh4_tmureg.h"
67    
68    
# Line 56  Line 70 
70  #define SH4_TICK_SHIFT          14  #define SH4_TICK_SHIFT          14
71  #define N_SH4_TIMERS            3  #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  */  /*  #define debug fatal  */
94    #endif
95    
96  struct sh4_data {  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;          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:  */          /*  Bus State Controller:  */
114          uint32_t        unknown_2c;          uint32_t        bsc_bcr1;
115          uint32_t        unknown_30;          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:  */          /*  Timer Management Unit:  */
146          struct timer    *sh4_timer;          struct timer    *sh4_timer;
147            struct interrupt timer_irq[4];
148          uint32_t        tocr;          uint32_t        tocr;
149          uint32_t        tstr;          uint32_t        tstr;
150          uint32_t        tcnt[N_SH4_TIMERS];          uint32_t        tcnt[N_SH4_TIMERS];
# Line 74  struct sh4_data { Line 152  struct sh4_data {
152          uint32_t        tcr[N_SH4_TIMERS];          uint32_t        tcr[N_SH4_TIMERS];
153          int             timer_interrupts_pending[N_SH4_TIMERS];          int             timer_interrupts_pending[N_SH4_TIMERS];
154          double          timer_hz[N_SH4_TIMERS];          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     100.0  #define SH4_PSEUDO_TIMER_HZ     110.0
163    
164    
165  /*  /*
# Line 86  struct sh4_data { Line 168  struct sh4_data {
168   *  This function is called SH4_PSEUDO_TIMER_HZ times per real-world second.   *  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   *  Its job is to update the SH4 timer counters, and if necessary, increase
170   *  the number of pending interrupts.   *  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)  static void sh4_timer_tick(struct timer *t, void *extra)
175  {  {
176          struct sh4_data *d = (struct sh4_data *) extra;          struct sh4_data *d = extra;
177          int i;          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++) {          for (i=0; i<N_SH4_TIMERS; i++) {
189                  int32_t old = d->tcnt[i];                  int32_t old = d->tcnt[i];
190    
# Line 128  static void sh4_timer_tick(struct timer Line 221  static void sh4_timer_tick(struct timer
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)  DEVICE_TICK(sh4)
261  {  {
262          struct sh4_data *d = (struct sh4_data *) extra;          struct sh4_data *d = extra;
263          int i;          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++)          for (i=0; i<N_SH4_TIMERS; i++)
295                  if (d->timer_interrupts_pending[i] > 0) {                  if (d->timer_interrupts_pending[i] > 0) {
296                          cpu_interrupt(cpu, SH_INTEVT_TMU0_TUNI0 + 0x20 * i);                          INTERRUPT_ASSERT(d->timer_irq[i]);
297                          d->tcr[i] |= TCR_UNF;                          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)  DEVICE_ACCESS(sh4_itlb_aa)
433  {  {
434          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
# Line 161  DEVICE_ACCESS(sh4_itlb_aa) Line 449  DEVICE_ACCESS(sh4_itlb_aa)
449                  if (idata & SH4_ITLB_AA_V)                  if (idata & SH4_ITLB_AA_V)
450                          cpu->cd.sh.itlb_lo[e] |= SH4_PTEL_V;                          cpu->cd.sh.itlb_lo[e] |= SH4_PTEL_V;
451    
452                  if (safe_to_invalidate)                  /*  Invalidate if this ITLB entry previously belonged to the
453                          cpu->invalidate_translation_caches(cpu,                      currently running process, or if it was shared:  */
454                              old_hi & ~0xfff, INVALIDATE_VADDR);                  if (cpu->cd.sh.ptel & SH4_PTEL_SH ||
455                  else                      (old_hi & SH4_ITLB_AA_ASID_MASK) ==
456                          cpu->invalidate_translation_caches(cpu,                      (cpu->cd.sh.pteh & SH4_PTEH_ASID_MASK)) {
457                              0, INVALIDATE_ALL);                          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 {          } else {
465                  odata = cpu->cd.sh.itlb_hi[e] &                  odata = cpu->cd.sh.itlb_hi[e] &
466                      (SH4_ITLB_AA_VPN_MASK | SH4_ITLB_AA_ASID_MASK);                      (SH4_ITLB_AA_VPN_MASK | SH4_ITLB_AA_ASID_MASK);
# Line 192  DEVICE_ACCESS(sh4_itlb_da1) Line 486  DEVICE_ACCESS(sh4_itlb_da1)
486          }          }
487    
488          if (writeflag == MEM_WRITE) {          if (writeflag == MEM_WRITE) {
489                    uint32_t old_lo = cpu->cd.sh.itlb_lo[e];
490                  int safe_to_invalidate = 0;                  int safe_to_invalidate = 0;
491                  if ((cpu->cd.sh.itlb_lo[e] & SH4_PTEL_SZ_MASK)==SH4_PTEL_SZ_4K)                  if ((cpu->cd.sh.itlb_lo[e] & SH4_PTEL_SZ_MASK)==SH4_PTEL_SZ_4K)
492                          safe_to_invalidate = 1;                          safe_to_invalidate = 1;
# Line 200  DEVICE_ACCESS(sh4_itlb_da1) Line 495  DEVICE_ACCESS(sh4_itlb_da1)
495                  cpu->cd.sh.itlb_lo[e] &= ~mask;                  cpu->cd.sh.itlb_lo[e] &= ~mask;
496                  cpu->cd.sh.itlb_lo[e] |= (idata & mask);                  cpu->cd.sh.itlb_lo[e] |= (idata & mask);
497    
498                  if (safe_to_invalidate)                  /*  Invalidate if this ITLB entry belongs to the
499                          cpu->invalidate_translation_caches(cpu,                      currently running process, or if it was shared:  */
500                              cpu->cd.sh.itlb_hi[e] & ~0xfff, INVALIDATE_VADDR);                  if (old_lo & SH4_PTEL_SH ||
501                  else                      (cpu->cd.sh.itlb_hi[e] & SH4_ITLB_AA_ASID_MASK) ==
502                          cpu->invalidate_translation_caches(cpu,                      (cpu->cd.sh.pteh & SH4_PTEH_ASID_MASK)) {
503                              0, INVALIDATE_ALL);                          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 {          } else {
512                  odata = cpu->cd.sh.itlb_lo[e] & mask;                  odata = cpu->cd.sh.itlb_lo[e] & mask;
513                  memory_writemax64(cpu, data, len, odata);                  memory_writemax64(cpu, data, len, odata);
# Line 267  DEVICE_ACCESS(sh4_utlb_aa) Line 569  DEVICE_ACCESS(sh4_utlb_aa)
569                                          continue;                                          continue;
570    
571                                  if (i < 0) {                                  if (i < 0) {
572                                          cpu->cd.sh.itlb_lo[i] &= ~SH4_PTEL_V;                                          cpu->cd.sh.itlb_lo[i +
573                                                SH_N_ITLB_ENTRIES] &= ~SH4_PTEL_V;
574                                          if (idata & SH4_UTLB_AA_V)                                          if (idata & SH4_UTLB_AA_V)
575                                                  cpu->cd.sh.itlb_lo[i] |=                                                  cpu->cd.sh.itlb_lo[
576                                                        i+SH_N_ITLB_ENTRIES] |=
577                                                      SH4_PTEL_V;                                                      SH4_PTEL_V;
578                                  } else {                                  } else {
579                                          cpu->cd.sh.utlb_lo[i] &=                                          cpu->cd.sh.utlb_lo[i] &=
# Line 313  DEVICE_ACCESS(sh4_utlb_aa) Line 617  DEVICE_ACCESS(sh4_utlb_aa)
617                          cpu->invalidate_translation_caches(cpu,                          cpu->invalidate_translation_caches(cpu,
618                              vaddr_to_invalidate, INVALIDATE_VADDR);                              vaddr_to_invalidate, INVALIDATE_VADDR);
619                  else                  else
620                          cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);                          cpu->invalidate_translation_caches(cpu, 0,
621                                INVALIDATE_ALL);
622          } else {          } else {
623                  odata = cpu->cd.sh.utlb_hi[e] &                  odata = cpu->cd.sh.utlb_hi[e] &
624                      (SH4_UTLB_AA_VPN_MASK | SH4_UTLB_AA_ASID_MASK);                      (SH4_UTLB_AA_VPN_MASK | SH4_UTLB_AA_ASID_MASK);
# Line 341  DEVICE_ACCESS(sh4_utlb_da1) Line 646  DEVICE_ACCESS(sh4_utlb_da1)
646          }          }
647    
648          if (writeflag == MEM_WRITE) {          if (writeflag == MEM_WRITE) {
649                    uint32_t old_lo = cpu->cd.sh.utlb_lo[e];
650                  int safe_to_invalidate = 0;                  int safe_to_invalidate = 0;
651                  if ((cpu->cd.sh.utlb_lo[e] & SH4_PTEL_SZ_MASK)==SH4_PTEL_SZ_4K)                  if ((cpu->cd.sh.utlb_lo[e] & SH4_PTEL_SZ_MASK)==SH4_PTEL_SZ_4K)
652                          safe_to_invalidate = 1;                          safe_to_invalidate = 1;
# Line 349  DEVICE_ACCESS(sh4_utlb_da1) Line 655  DEVICE_ACCESS(sh4_utlb_da1)
655                  cpu->cd.sh.utlb_lo[e] &= ~mask;                  cpu->cd.sh.utlb_lo[e] &= ~mask;
656                  cpu->cd.sh.utlb_lo[e] |= (idata & mask);                  cpu->cd.sh.utlb_lo[e] |= (idata & mask);
657    
658                  if (safe_to_invalidate)                  /*  Invalidate if this UTLB entry belongs to the
659                          cpu->invalidate_translation_caches(cpu,                      currently running process, or if it was shared:  */
660                              cpu->cd.sh.utlb_hi[e] & ~0xfff, INVALIDATE_VADDR);                  if (old_lo & SH4_PTEL_SH ||
661                  else                      (cpu->cd.sh.utlb_hi[e] & SH4_ITLB_AA_ASID_MASK) ==
662                          cpu->invalidate_translation_caches(cpu,                      (cpu->cd.sh.pteh & SH4_PTEH_ASID_MASK)) {
663                              0, INVALIDATE_ALL);                          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 {          } else {
672                  odata = cpu->cd.sh.utlb_lo[e] & mask;                  odata = cpu->cd.sh.utlb_lo[e] & mask;
673                  memory_writemax64(cpu, data, len, odata);                  memory_writemax64(cpu, data, len, odata);
# Line 364  DEVICE_ACCESS(sh4_utlb_da1) Line 677  DEVICE_ACCESS(sh4_utlb_da1)
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)  DEVICE_ACCESS(sh4)
839  {  {
840          struct sh4_data *d = (struct sh4_data *) extra;          struct sh4_data *d = extra;
841          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
842          int timer_nr = 0;          int timer_nr = 0, dma_channel = 0;
843    
844          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
845                  idata = memory_readmax64(cpu, data, len);                  idata = memory_readmax64(cpu, data, len);
846    
847          relative_addr += SH4_REG_BASE;          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) {          switch (relative_addr) {
864    
865          /*************************************************/          /*************************************************/
# Line 391  DEVICE_ACCESS(sh4) Line 876  DEVICE_ACCESS(sh4)
876                  if (writeflag == MEM_READ)                  if (writeflag == MEM_READ)
877                          odata = cpu->cd.sh.pteh;                          odata = cpu->cd.sh.pteh;
878                  else {                  else {
879                          int old_asid = cpu->cd.sh.pteh & SH4_PTEH_ASID_MASK;                          unsigned int old_asid = cpu->cd.sh.pteh
880                                & SH4_PTEH_ASID_MASK;
881                          cpu->cd.sh.pteh = idata;                          cpu->cd.sh.pteh = idata;
882    
883                          if ((idata & SH4_PTEH_ASID_MASK) != old_asid) {                          if ((idata & SH4_PTEH_ASID_MASK) != old_asid) {
884                                  /*  TODO: Don't invalidate everything?  */                                  /*
885                                     *  TODO: Don't invalidate everything,
886                                     *  only those pages that belonged to the
887                                     *  old asid.
888                                     */
889                                  cpu->invalidate_translation_caches(                                  cpu->invalidate_translation_caches(
890                                      cpu, 0, INVALIDATE_ALL);                                      cpu, 0, INVALIDATE_ALL);
891                          }                          }
# Line 436  DEVICE_ACCESS(sh4) Line 926  DEVICE_ACCESS(sh4)
926                  } else {                  } else {
927                          if (idata & SH4_MMUCR_TI) {                          if (idata & SH4_MMUCR_TI) {
928                                  /*  TLB invalidate.  */                                  /*  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    
                                 /*  TODO: Only invalidate something specific?  
                                     And not everything?  */  
938                                  cpu->invalidate_translation_caches(cpu,                                  cpu->invalidate_translation_caches(cpu,
939                                      0, INVALIDATE_ALL);                                      0, INVALIDATE_ALL);
940    
941                                  /*  Should always read back as 0.  */                                  /*  The TI bit should always read as 0.  */
942                                  idata &= ~SH4_MMUCR_TI;                                  idata &= ~SH4_MMUCR_TI;
943                          }                          }
944    
# Line 605  DEVICE_ACCESS(sh4) Line 1101  DEVICE_ACCESS(sh4)
1101                                  exit(1);                                  exit(1);
1102                          }                          }
1103    
1104                            INTERRUPT_DEASSERT(d->timer_irq[timer_nr]);
1105    
1106                          if (d->tcr[timer_nr] & TCR_UNF && !(idata & TCR_UNF)) {                          if (d->tcr[timer_nr] & TCR_UNF && !(idata & TCR_UNF)) {
                                 cpu_interrupt_ack(cpu, SH_INTEVT_TMU0_TUNI0  
                                     + 0x20 * timer_nr);  
1107                                  if (d->timer_interrupts_pending[timer_nr] > 0)                                  if (d->timer_interrupts_pending[timer_nr] > 0)
1108                                          d->timer_interrupts_pending[timer_nr]--;                                          d->timer_interrupts_pending[timer_nr]--;
1109                          }                          }
# Line 618  DEVICE_ACCESS(sh4) Line 1114  DEVICE_ACCESS(sh4)
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                    */          /*  BSC: Bus State Controller                    */
1199    
1200          case SH4_RFCR:          case SH4_BCR1:
1201                  /*  TODO  */                  if (writeflag == MEM_WRITE)
1202                  fatal("[ SH4_RFCR: TODO ]\n");                          d->bsc_bcr1 = idata & 0x033efffd;
1203                  odata = 0x11;                  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;                  break;
1227    
1228  #if 0          case SH4_WCR2:
1229          case SH4_UNKNOWN_2C:                  if (writeflag == MEM_WRITE)
1230                  /*  Not really part of the BSC? The 2C and 30 registers                          d->bsc_wcr2 = idata & 0xfffeefff;
1231                      have to do with I/O pins... TODO  */                  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                   *  TODO:  Perhaps this isn't actually part of the Bus State                   *  Refresh Time Control/Status Register. Called RTCSR in
1245                   *         controller?  Marcus Comstedt's video.s tutorial on                   *  NetBSD, but RTSCR in the SH7750 manual?
                  *         how to output video on the Dreamcast indicates that  
                  *         this is a way to sense which video cable is  
                  *         connected.  
1246                   */                   */
1247                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
1248                          d->unknown_2c = idata;                          idata &= 0x00ff;
1249                          d->unknown_30 = idata;                          if (idata & RTCSR_CMF) {
1250                                    idata = (idata & ~RTCSR_CMF)
1251                                        | (d->bsc_rtcsr & RTCSR_CMF);
1252                            }
1253                            d->bsc_rtcsr = idata & 0x00ff;
1254                  } else                  } else
1255                          odata = d->unknown_2c;                          odata = d->bsc_rtcsr;
1256                  break;                  break;
 #endif  
1257    
1258  #if 1          case SH4_RTCOR:
1259          case SH4_UNKNOWN_30:                  /*  Refresh Time Constant Register (8 bits):  */
1260                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
1261                          d->unknown_30 = idata;                          d->bsc_rtcor = idata & 0x00ff;
1262                  else {                  else
1263                          odata = d->unknown_30;                          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                          /*  SUPER-UGLY HACK!  TODO  */          case SH4_PDTRA:
1286                          d->unknown_30 ++;                  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;                  break;
1311  #endif  
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          /*********************************/          /*********************************/
# Line 675  DEVICE_ACCESS(sh4) Line 1348  DEVICE_ACCESS(sh4)
1348          case SH4_IPRA:          case SH4_IPRA:
1349                  if (writeflag == MEM_READ)                  if (writeflag == MEM_READ)
1350                          odata = cpu->cd.sh.intc_ipra;                          odata = cpu->cd.sh.intc_ipra;
1351                  else                  else {
1352                          cpu->cd.sh.intc_ipra = idata;                          cpu->cd.sh.intc_ipra = idata;
1353                            sh_update_interrupt_priorities(cpu);
1354                    }
1355                  break;                  break;
1356    
1357          case SH4_IPRB:          case SH4_IPRB:
1358                  if (writeflag == MEM_READ)                  if (writeflag == MEM_READ)
1359                          odata = cpu->cd.sh.intc_iprb;                          odata = cpu->cd.sh.intc_iprb;
1360                  else                  else {
1361                          cpu->cd.sh.intc_iprb = idata;                          cpu->cd.sh.intc_iprb = idata;
1362                            sh_update_interrupt_priorities(cpu);
1363                    }
1364                  break;                  break;
1365    
1366          case SH4_IPRC:          case SH4_IPRC:
1367                  if (writeflag == MEM_READ)                  if (writeflag == MEM_READ)
1368                          odata = cpu->cd.sh.intc_iprc;                          odata = cpu->cd.sh.intc_iprc;
1369                  else                  else {
1370                          cpu->cd.sh.intc_iprc = idata;                          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;                  break;
1447    
1448    
1449          /*************************************************/          /*************************************************/
1450          /*  SCIF: Serial Controller Interface with FIFO  */          /*  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:          case SH4_SCIF_BASE + SCIF_FTDR:
1478                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE) {
1479                          console_putchar(d->scif_console_handle, idata);                          /*  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;                  break;
1490    
1491          case SH4_SCIF_BASE + SCIF_SSR:          case SH4_SCIF_BASE + SCIF_SSR:
1492                  /*  TODO: Implement more of this.  */                  if (writeflag == MEM_READ) {
1493                  odata = SCSSR2_TDFE | SCSSR2_TEND;                          odata = d->scif_ssr;
1494                  if (console_charavail(d->scif_console_handle))                  } else {
1495                          odata |= SCSSR2_DR;                          d->scif_ssr = idata;
1496                            scif_reassert_interrupts(d);
1497                    }
1498                  break;                  break;
1499    
1500          case SH4_SCIF_BASE + SCIF_FRDR:          case SH4_SCIF_BASE + SCIF_FRDR:
# Line 715  DEVICE_ACCESS(sh4) Line 1503  DEVICE_ACCESS(sh4)
1503                          if (x == 13)                          if (x == 13)
1504                                  x = 10;                                  x = 10;
1505                          odata = x < 0? 0 : x;                          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;                  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:          case SH4_SCIF_BASE + SCIF_FDR:
1528                  odata = console_charavail(d->scif_console_handle);                  /*  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;                  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) {          default:if (writeflag == MEM_READ) {
# Line 731  DEVICE_ACCESS(sh4) Line 1576  DEVICE_ACCESS(sh4)
1576                          fatal("[ sh4: write to addr 0x%x: 0x%x ]\n",                          fatal("[ sh4: write to addr 0x%x: 0x%x ]\n",
1577                              (int)relative_addr, (int)idata);                              (int)relative_addr, (int)idata);
1578                  }                  }
1579    #ifdef SH4_DEGUG
1580                    /*  exit(1);  */
1581    #endif
1582          }          }
1583    
1584          if (writeflag == MEM_READ)          if (writeflag == MEM_READ)
# Line 742  DEVICE_ACCESS(sh4) Line 1590  DEVICE_ACCESS(sh4)
1590    
1591  DEVINIT(sh4)  DEVINIT(sh4)
1592  {  {
1593            char tmp[200], n[200];
1594            int i;
1595          struct machine *machine = devinit->machine;          struct machine *machine = devinit->machine;
1596          struct sh4_data *d = malloc(sizeof(struct sh4_data));          struct sh4_data *d;
1597          if (d == NULL) {  
1598                  fprintf(stderr, "out of memory\n");          CHECK_ALLOCATION(d = malloc(sizeof(struct sh4_data)));
                 exit(1);  
         }  
1599          memset(d, 0, sizeof(struct sh4_data));          memset(d, 0, sizeof(struct sh4_data));
1600    
1601          d->scif_console_handle = console_start_slave(devinit->machine,  
1602              "SH4 SCIF", 1);          /*
1603             *  Main SH4 device, and misc memory stuff:
1604             */
1605    
1606          memory_device_register(machine->memory, devinit->name,          memory_device_register(machine->memory, devinit->name,
1607              SH4_REG_BASE, 0x01000000, dev_sh4_access, d, DM_DEFAULT, NULL);              SH4_REG_BASE, 0x01000000, dev_sh4_access, d, DM_DEFAULT, NULL);
# Line 762  DEVINIT(sh4) Line 1612  DEVINIT(sh4)
1612          /*  0xe0000000: Store queues:  */          /*  0xe0000000: Store queues:  */
1613          dev_ram_init(machine, 0xe0000000, 32 * 2, DEV_RAM_RAM, 0x0);          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           *  0xf0000000  SH4_CCIA        I-Cache address array
1635           *  0xf1000000  SH4_CCID        I-Cache data array           *  0xf1000000  SH4_CCID        I-Cache data array
1636           *  0xf4000000  SH4_CCDA        D-Cache address array           *  0xf4000000  SH4_CCDA        D-Cache address array
# Line 770  DEVINIT(sh4) Line 1638  DEVINIT(sh4)
1638           *           *
1639           *  TODO: Implement more correct cache behaviour?           *  TODO: Implement more correct cache behaviour?
1640           */           */
1641          dev_ram_init(machine, SH4_CCIA, SH4_ICACHE_SIZE, DEV_RAM_RAM, 0x0);  
1642          dev_ram_init(machine, SH4_CCID, SH4_ICACHE_SIZE, DEV_RAM_RAM, 0x0);          dev_ram_init(machine, SH4_CCIA, SH4_ICACHE_SIZE * 2, DEV_RAM_RAM, 0x0);
1643          dev_ram_init(machine, SH4_CCDA, SH4_DCACHE_SIZE, DEV_RAM_RAM, 0x0);          dev_ram_init(machine, SH4_CCID, SH4_ICACHE_SIZE,     DEV_RAM_RAM, 0x0);
1644          dev_ram_init(machine, SH4_CCDD, SH4_DCACHE_SIZE, DEV_RAM_RAM, 0x0);          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  */          /*  0xf2000000  SH4_ITLB_AA  */
1648          memory_device_register(machine->memory, devinit->name, SH4_ITLB_AA,          memory_device_register(machine->memory, "sh4_itlb_aa", SH4_ITLB_AA,
1649              0x01000000, dev_sh4_itlb_aa_access, d, DM_DEFAULT, NULL);              0x01000000, dev_sh4_itlb_aa_access, d, DM_DEFAULT, NULL);
1650    
1651          /*  0xf3000000  SH4_ITLB_DA1  */          /*  0xf3000000  SH4_ITLB_DA1  */
1652          memory_device_register(machine->memory, devinit->name, SH4_ITLB_DA1,          memory_device_register(machine->memory, "sh4_itlb_da1", SH4_ITLB_DA1,
1653              0x01000000, dev_sh4_itlb_da1_access, d, DM_DEFAULT, NULL);              0x01000000, dev_sh4_itlb_da1_access, d, DM_DEFAULT, NULL);
1654    
1655          /*  0xf6000000  SH4_UTLB_AA  */          /*  0xf6000000  SH4_UTLB_AA  */
1656          memory_device_register(machine->memory, devinit->name, SH4_UTLB_AA,          memory_device_register(machine->memory, "sh4_utlb_aa", SH4_UTLB_AA,
1657              0x01000000, dev_sh4_utlb_aa_access, d, DM_DEFAULT, NULL);              0x01000000, dev_sh4_utlb_aa_access, d, DM_DEFAULT, NULL);
1658    
1659          /*  0xf7000000  SH4_UTLB_DA1  */          /*  0xf7000000  SH4_UTLB_DA1  */
1660          memory_device_register(machine->memory, devinit->name, SH4_UTLB_DA1,          memory_device_register(machine->memory, "sh4_utlb_da1", SH4_UTLB_DA1,
1661              0x01000000, dev_sh4_utlb_da1_access, d, DM_DEFAULT, NULL);              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);          d->sh4_timer = timer_add(SH4_PSEUDO_TIMER_HZ, sh4_timer_tick, d);
1719          machine_add_tickfunction(devinit->machine, dev_sh4_tick, d,          machine_add_tickfunction(devinit->machine, dev_sh4_tick, d,
1720              SH4_TICK_SHIFT, 0.0);              SH4_TICK_SHIFT);
1721    
1722          /*  Initial Timer values, according to the SH7750 manual:  */          /*  Initial Timer values, according to the SH7750 manual:  */
1723          d->tcor[0] = 0xffffffff; d->tcnt[0] = 0xffffffff;          d->tcor[0] = 0xffffffff; d->tcnt[0] = 0xffffffff;
1724          d->tcor[1] = 0xffffffff; d->tcnt[1] = 0xffffffff;          d->tcor[1] = 0xffffffff; d->tcnt[1] = 0xffffffff;
1725          d->tcor[2] = 0xffffffff; d->tcnt[2] = 0xffffffff;          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;          return 1;
1758  }  }
1759    

Legend:
Removed from v.32  
changed lines
  Added in v.44

  ViewVC Help
Powered by ViewVC 1.1.26