/[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 34 by dpavlin, Mon Oct 8 16:21:17 2007 UTC revision 42 by dpavlin, Mon Oct 8 16:22:32 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_sh4.c,v 1.29 2007/01/29 18:06:37 debug Exp $   *  $Id: dev_sh4.c,v 1.50 2007/06/15 19:57:34 debug Exp $
29   *     *  
30   *  SH4 processor specific memory mapped registers (0xf0000000 - 0xffffffff).   *  COMMENT: SH4-specific memory mapped registers (0xf0000000 - 0xffffffff)
31   *   *
32   *  TODO: Lots and lots of stuff.   *  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"
# Line 52  Line 59 
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"  #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 61  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:  */  /*  General-purpose I/O stuff:  */
85  #define SH4_PCTRA               0xff80002c  #define SH4_PCTRA               0xff80002c
86  #define SH4_PDTRA               0xff800030  #define SH4_PDTRA               0xff800030
# Line 78  struct sh4_data { Line 98  struct sh4_data {
98          uint16_t        scif_smr;          uint16_t        scif_smr;
99          uint8_t         scif_brr;          uint8_t         scif_brr;
100          uint16_t        scif_scr;          uint16_t        scif_scr;
101            uint16_t        scif_ssr;
102          uint16_t        scif_fcr;          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        bsc_bcr1;          uint32_t        bsc_bcr1;
# Line 97  struct sh4_data { Line 126  struct sh4_data {
126          uint32_t        pctrb;          /*  Port Control Register B  */          uint32_t        pctrb;          /*  Port Control Register B  */
127          uint32_t        pdtrb;          /*  Port Data Register B  */          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:  */          /*  SD-RAM:  */
142          uint16_t        sdmr2;          uint16_t        sdmr2;
143          uint16_t        sdmr3;          uint16_t        sdmr3;
# Line 118  struct sh4_data { Line 159  struct sh4_data {
159  };  };
160    
161    
162  #define SH4_PSEUDO_TIMER_HZ     100.0  #define SH4_PSEUDO_TIMER_HZ     110.0
163    
164    
165  /*  /*
# Line 132  struct sh4_data { Line 173  struct sh4_data {
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:  */          /*  Fake RAM refresh:  */
# Line 143  static void sh4_timer_tick(struct timer Line 184  static void sh4_timer_tick(struct timer
184                  exit(1);                  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 179  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                          INTERRUPT_ASSERT(d->timer_irq[i]);                          INTERRUPT_ASSERT(d->timer_irq[i]);
# Line 192  DEVICE_TICK(sh4) Line 299  DEVICE_TICK(sh4)
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 332  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 438  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, dma_channel = 0;          int timer_nr = 0, dma_channel = 0;
843    
# Line 479  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) {
# Line 540  DEVICE_ACCESS(sh4) Line 938  DEVICE_ACCESS(sh4)
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 703  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)) {
                                 INTERRUPT_DEASSERT(d->timer_irq[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 911  DEVICE_ACCESS(sh4) Line 1310  DEVICE_ACCESS(sh4)
1310                  break;                  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  */          /*  INTC:  Interrupt Controller  */
1337    
# Line 927  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;                  break;
1374    
1375          case SH4_IPRD:          case SH4_IPRD:
1376                  if (writeflag == MEM_READ)                  if (writeflag == MEM_READ)
1377                          odata = cpu->cd.sh.intc_iprd;                          odata = cpu->cd.sh.intc_iprd;
1378                  else                  else {
1379                          cpu->cd.sh.intc_iprd = idata;                          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    
# Line 975  DEVICE_ACCESS(sh4) Line 1468  DEVICE_ACCESS(sh4)
1468          case SH4_SCIF_BASE + SCIF_SCR:          case SH4_SCIF_BASE + SCIF_SCR:
1469                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
1470                          d->scif_scr = idata;                          d->scif_scr = idata;
1471                            scif_reassert_interrupts(d);
1472                  } else {                  } else {
1473                          odata = d->scif_scr;                          odata = d->scif_scr;
1474                  }                  }
1475                  break;                  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 998  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;                  break;
1513    
# Line 1009  DEVICE_ACCESS(sh4) Line 1519  DEVICE_ACCESS(sh4)
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    
# Line 1060  DEVICE_ACCESS(sh4) Line 1577  DEVICE_ACCESS(sh4)
1577                              (int)relative_addr, (int)idata);                              (int)relative_addr, (int)idata);
1578                  }                  }
1579  #ifdef SH4_DEGUG  #ifdef SH4_DEGUG
1580  //              exit(1);                  /*  exit(1);  */
1581  #endif  #endif
1582          }          }
1583    
# Line 1073  DEVICE_ACCESS(sh4) Line 1590  DEVICE_ACCESS(sh4)
1590    
1591  DEVINIT(sh4)  DEVINIT(sh4)
1592  {  {
1593          char tmp[200];          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 1094  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 1102  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;
# Line 1151  DEVINIT(sh4) Line 1743  DEVINIT(sh4)
1743                  exit(1);                  exit(1);
1744          }          }
1745    
1746          /*  Bus State Controller initial values:  */  
1747            /*
1748             *  Bus State Controller initial values, according to the
1749             *  SH7760 manual:
1750             */
1751    
1752          d->bsc_bcr2 = 0x3ffc;          d->bsc_bcr2 = 0x3ffc;
1753          d->bsc_wcr1 = 0x77777777;          d->bsc_wcr1 = 0x77777777;
1754          d->bsc_wcr2 = 0xfffeefff;          d->bsc_wcr2 = 0xfffeefff;
1755    
1756    
1757          return 1;          return 1;
1758  }  }
1759    

Legend:
Removed from v.34  
changed lines
  Added in v.42

  ViewVC Help
Powered by ViewVC 1.1.26