/[gxemul]/trunk/src/devices/dev_pcc2.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_pcc2.c

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

revision 43 by dpavlin, Mon Oct 8 16:22:32 2007 UTC revision 44 by dpavlin, Mon Oct 8 16:22:56 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: dev_pcc2.c,v 1.4 2007/06/15 19:57:33 debug Exp $   *  $Id: dev_pcc2.c,v 1.6 2007/08/29 20:36:49 debug Exp $
29   *   *
30   *  COMMENT: PCC2 bus (used in MVME machine)   *  COMMENT: Peripheral Channel Controller (PCC2) bus (used in MVME machines)
31   *   *
32   *  TODO   *  See "Single Board Computers Programmer's Reference Guide (Part 2 of 2)",
33     *  "VMESBCA2/PG1" (vmesbcp2.pdf) for more details.
34     *
35     *  Note: This is somewhat MVME187-specific, at the moment.
36     *
37     *
38     *  TODO: Lots of stuff.
39   */   */
40    
41  #include <stdio.h>  #include <stdio.h>
# Line 39  Line 45 
45  #include "cpu.h"  #include "cpu.h"
46  #include "device.h"  #include "device.h"
47  #include "emul.h"  #include "emul.h"
48    #include "interrupt.h"
49  #include "machine.h"  #include "machine.h"
50  #include "memory.h"  #include "memory.h"
51  #include "misc.h"  #include "misc.h"
52    
53    
54    #include "mvme187.h"
55  #include "mvme_pcctworeg.h"  #include "mvme_pcctworeg.h"
56    
57    #define INTERRUPT_LEVEL_MASK    0x07
58    
59    
60  /*  #define     debug fatal  */  /*  #define     debug fatal  */
61    
62  struct pcc2_data {  struct pcc2_data {
63            struct interrupt        cpu_irq;
64    
65          uint8_t                 pcctwo_reg[PCC2_SIZE];          uint8_t                 pcctwo_reg[PCC2_SIZE];
66    
67            uint8_t                 cur_int_vec;
68  };  };
69    
70    
71    static void reassert_interrupts(struct pcc2_data *d)
72    {
73            /*  Block interrupts at the mask level or lower:  */
74            if ((d->pcctwo_reg[PCCTWO_IPL] & INTERRUPT_LEVEL_MASK) <=
75                (d->pcctwo_reg[PCCTWO_MASK] & INTERRUPT_LEVEL_MASK))
76                    INTERRUPT_DEASSERT(d->cpu_irq);
77            else
78                    INTERRUPT_ASSERT(d->cpu_irq);
79    }
80    
81    
82  DEVICE_ACCESS(pcc2)  DEVICE_ACCESS(pcc2)
83  {  {
84          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
85          struct pcc2_data *d = extra;          struct pcc2_data *d = extra;
86    
87            /*  0xfff42000..0xfff42fff, but only 0x40 unique registers:  */
88            relative_addr %= PCC2_SIZE;
89    
90          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
91                  idata = memory_readmax64(cpu, data, len);                  idata = memory_readmax64(cpu, data, len);
92    
# Line 75  DEVICE_ACCESS(pcc2) Line 103  DEVICE_ACCESS(pcc2)
103                  }                  }
104                  break;                  break;
105    
         case PCCTWO_GENCTL:  
106          case PCCTWO_VECBASE:          case PCCTWO_VECBASE:
107                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE) {
108                          d->pcctwo_reg[relative_addr] = idata;                          d->pcctwo_reg[PCCTWO_VECBASE] = idata & 0xf0;
109                            if (idata & ~0xf0)
110                                    fatal("[ pcc2: HUH? write to PCCTWO_VECBASE"
111                                        " with value 0x%02x. ]\n", (int) idata);
112                    }
113                    break;
114    
115            case PCCTWO_IPL:
116                    if (writeflag == MEM_WRITE) {
117                            fatal("[ pcc2: HUH? Write attempt to PCCTWO_IPL. ]\n");
118                    }
119                  break;                  break;
120    
121          case PCCTWO_MASK:          case PCCTWO_MASK:
122                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
123                          d->pcctwo_reg[relative_addr] = idata;                          d->pcctwo_reg[relative_addr] = idata;
124                          /*  TODO: Re-Assert interrupts!  */                          reassert_interrupts(d);
125                  }                  }
126                  break;                  break;
127    
128          default:debug("[ pcc2: unimplemented %s offset 0x%x",          default:
129                    debug("[ pcc2: unimplemented %s offset 0x%x",
130                      writeflag == MEM_WRITE? "write to" : "read from",                      writeflag == MEM_WRITE? "write to" : "read from",
131                      (int) relative_addr);                      (int) relative_addr);
132                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
# Line 104  DEVICE_ACCESS(pcc2) Line 142  DEVICE_ACCESS(pcc2)
142  }  }
143    
144    
145    DEVICE_ACCESS(mvme187_iack)
146    {
147            uint64_t odata = 0;
148            struct pcc2_data *d = extra;
149    
150            if (writeflag == MEM_WRITE) {
151                    fatal("[ pcc2: write to mvme187_iack? ]\n");
152            } else {
153                    odata = d->cur_int_vec;
154                    memory_writemax64(cpu, data, len, odata);
155            }
156    
157            return 1;
158    }
159    
160    
161  DEVINIT(pcc2)  DEVINIT(pcc2)
162  {  {
163          struct pcc2_data *d;          struct pcc2_data *d;
# Line 111  DEVINIT(pcc2) Line 165  DEVINIT(pcc2)
165          CHECK_ALLOCATION(d = malloc(sizeof(struct pcc2_data)));          CHECK_ALLOCATION(d = malloc(sizeof(struct pcc2_data)));
166          memset(d, 0, sizeof(struct pcc2_data));          memset(d, 0, sizeof(struct pcc2_data));
167    
168            /*  Initial values, according to the manual:  */
169          d->pcctwo_reg[PCCTWO_CHIPID] = PCC2_ID;          d->pcctwo_reg[PCCTWO_CHIPID] = PCC2_ID;
170            d->pcctwo_reg[PCCTWO_CHIPREV] = 0x00;
171            d->pcctwo_reg[PCCTWO_VECBASE] = 0x0f;
172    
173            /*  Connect to the CPU's interrupt pin:  */
174            INTERRUPT_CONNECT(devinit->interrupt_path, d->cpu_irq);
175    
176          memory_device_register(devinit->machine->memory, "pcc2",          memory_device_register(devinit->machine->memory, "pcc2",
177              devinit->addr, PCC2_SIZE, dev_pcc2_access, (void *)d,              devinit->addr, 4096, dev_pcc2_access, (void *)d,
178                DM_DEFAULT, NULL);
179    
180            memory_device_register(devinit->machine->memory, "mvme187_iack",
181                M187_IACK, 32, dev_mvme187_iack_access, (void *)d,
182              DM_DEFAULT, NULL);              DM_DEFAULT, NULL);
183    
184          return 1;          return 1;

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

  ViewVC Help
Powered by ViewVC 1.1.26