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

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

revision 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC revision 34 by dpavlin, Mon Oct 8 16:21:17 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005-2006  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-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 24  Line 24 
24   *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF   *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *  $Id: dev_gc.c,v 1.6 2006/01/01 13:17:16 debug Exp $   *  $Id: dev_gc.c,v 1.12 2007/02/16 17:17:51 debug Exp $
28   *     *  
29   *  Grand Central Interrupt controller (used by MacPPC).   *  Grand Central Interrupt controller (used by MacPPC).
30   */   */
# Line 35  Line 35 
35    
36  #include "cpu.h"  #include "cpu.h"
37  #include "device.h"  #include "device.h"
 #include "devices.h"  
38  #include "machine.h"  #include "machine.h"
39  #include "memory.h"  #include "memory.h"
40  #include "misc.h"  #include "misc.h"
41    
42    
43  /*  #define DEV_GC_LENGTH           0x100
44   *  dev_gc_access():  
45   */  struct gc_data {
46            struct interrupt cpu_irq;
47    
48            uint32_t        status_hi;
49            uint32_t        status_lo;
50            uint32_t        enable_hi;
51            uint32_t        enable_lo;
52    };
53    
54    
55    void gc_hi_interrupt_assert(struct interrupt *interrupt)
56    {
57            struct gc_data *d = interrupt->extra;
58            d->status_hi |= interrupt->line;
59            if (d->status_lo & d->enable_lo || d->status_hi & d->enable_hi)
60                    INTERRUPT_ASSERT(d->cpu_irq);
61    }
62    void gc_hi_interrupt_deassert(struct interrupt *interrupt)
63    {
64            struct gc_data *d = interrupt->extra;
65            d->status_hi &= ~interrupt->line;
66            if (!(d->status_lo & d->enable_lo || d->status_hi & d->enable_hi))
67                    INTERRUPT_DEASSERT(d->cpu_irq);
68    }
69    void gc_lo_interrupt_assert(struct interrupt *interrupt)
70    {
71            struct gc_data *d = interrupt->extra;
72            d->status_lo |= interrupt->line;
73            if (d->status_lo & d->enable_lo || d->status_hi & d->enable_hi)
74                    INTERRUPT_ASSERT(d->cpu_irq);
75    }
76    void gc_lo_interrupt_deassert(struct interrupt *interrupt)
77    {
78            struct gc_data *d = interrupt->extra;
79            d->status_lo &= ~interrupt->line;
80            if (!(d->status_lo & d->enable_lo || d->status_hi & d->enable_hi))
81                    INTERRUPT_DEASSERT(d->cpu_irq);
82    }
83    
84    
85  DEVICE_ACCESS(gc)  DEVICE_ACCESS(gc)
86  {  {
87          struct gc_data *d = extra;          struct gc_data *d = extra;
# Line 67  DEVICE_ACCESS(gc) Line 105  DEVICE_ACCESS(gc)
105    
106          case 0x10:          case 0x10:
107                  if (writeflag == MEM_READ)                  if (writeflag == MEM_READ)
108                          odata = d->status_hi                          odata = d->status_hi & d->enable_hi;
 & d->enable_hi  
 ;  
109                  break;                  break;
110    
111          case 0x14:          case 0x14:
112                  if (writeflag == MEM_READ)                  if (writeflag == MEM_READ)
113                          odata = d->enable_hi;                          odata = d->enable_hi;
114                  else {                  else {
115                          uint32_t old_enable_hi = d->enable_hi;                          int old_assert = (d->status_lo & d->enable_lo
116                                || d->status_hi & d->enable_hi);
117                            int new_assert;
118                          d->enable_hi = idata;                          d->enable_hi = idata;
119                          if (d->enable_hi != old_enable_hi)  
120                                  cpu_interrupt(cpu, d->reassert_irq);                          new_assert = (d->status_lo & d->enable_lo ||
121                                d->status_hi & d->enable_hi);
122    
123                            if (old_assert && !new_assert)
124                                    INTERRUPT_DEASSERT(d->cpu_irq);
125                            else if (!old_assert && new_assert)
126                                    INTERRUPT_ASSERT(d->cpu_irq);
127                  }                  }
128                  break;                  break;
129    
130          case 0x18:          case 0x18:
131                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
132                          uint32_t old_status_hi = d->status_hi;                          int old_assert = (d->status_lo & d->enable_lo
133                                || d->status_hi & d->enable_hi);
134                            int new_assert;
135                          d->status_hi &= ~idata;                          d->status_hi &= ~idata;
136                          if (d->status_hi != old_status_hi)  
137                                  cpu_interrupt(cpu, d->reassert_irq);                          new_assert = (d->status_lo & d->enable_lo ||
138                                d->status_hi & d->enable_hi);
139    
140                            if (old_assert && !new_assert)
141                                    INTERRUPT_DEASSERT(d->cpu_irq);
142                            else if (!old_assert && new_assert)
143                                    INTERRUPT_ASSERT(d->cpu_irq);
144                  }                  }
145                  break;                  break;
146    
147          case 0x20:          case 0x20:
148                  if (writeflag == MEM_READ)                  if (writeflag == MEM_READ)
149                          odata = d->status_lo                          odata = d->status_lo & d->enable_lo;
 & d->enable_lo  
 ;  
150                  break;                  break;
151    
152          case 0x24:          case 0x24:
153                  if (writeflag == MEM_READ)                  if (writeflag == MEM_READ)
154                          odata = d->enable_lo;                          odata = d->enable_lo;
155                  else {                  else {
156                          uint32_t old_enable_lo = d->enable_lo;                          int old_assert = (d->status_lo & d->enable_lo
157                                || d->status_hi & d->enable_hi);
158                            int new_assert;
159                          d->enable_lo = idata;                          d->enable_lo = idata;
160                          if (d->enable_lo != old_enable_lo)  
161                                  cpu_interrupt(cpu, d->reassert_irq);                          new_assert = (d->status_lo & d->enable_lo ||
162                                d->status_hi & d->enable_hi);
163    
164                            if (old_assert && !new_assert)
165                                    INTERRUPT_DEASSERT(d->cpu_irq);
166                            else if (!old_assert && new_assert)
167                                    INTERRUPT_ASSERT(d->cpu_irq);
168                  }                  }
169                  break;                  break;
170    
171          case 0x28:          case 0x28:
172                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
173                          uint32_t old_status_lo = d->status_lo;                          int old_assert = (d->status_lo & d->enable_lo
174                                || d->status_hi & d->enable_hi);
175                            int new_assert;
176                          d->status_lo &= ~idata;                          d->status_lo &= ~idata;
177                          if (d->status_lo != old_status_lo)  
178                                  cpu_interrupt(cpu, d->reassert_irq);                          new_assert = (d->status_lo & d->enable_lo ||
179                                d->status_hi & d->enable_hi);
180    
181                            if (old_assert && !new_assert)
182                                    INTERRUPT_DEASSERT(d->cpu_irq);
183                            else if (!old_assert && new_assert)
184                                    INTERRUPT_ASSERT(d->cpu_irq);
185                  }                  }
186                  break;                  break;
187    
188            case 0x2c:
189                    /*  Avoid a debug message.  */
190                    break;
191    
192          default:if (writeflag == MEM_WRITE) {          default:if (writeflag == MEM_WRITE) {
193                          fatal("[ gc: unimplemented write to "                          fatal("[ gc: unimplemented write to "
194                              "offset 0x%x: data=0x%x ]\n", (int)                              "offset 0x%x: data=0x%x ]\n", (int)
# Line 136  DEVICE_ACCESS(gc) Line 206  DEVICE_ACCESS(gc)
206  }  }
207    
208    
209  /*  DEVINIT(gc)
  *  dev_gc_init():  
  */  
 struct gc_data *dev_gc_init(struct machine *machine, struct memory *mem,  
         uint64_t addr, int reassert_irq)  
210  {  {
211          struct gc_data *d;          struct gc_data *d;
212            int i;
213    
214          d = malloc(sizeof(struct gc_data));          d = malloc(sizeof(struct gc_data));
215          if (d == NULL) {          if (d == NULL) {
# Line 150  struct gc_data *dev_gc_init(struct machi Line 217  struct gc_data *dev_gc_init(struct machi
217                  exit(1);                  exit(1);
218          }          }
219          memset(d, 0, sizeof(struct gc_data));          memset(d, 0, sizeof(struct gc_data));
         d->reassert_irq = reassert_irq;  
220    
221          memory_device_register(mem, "gc", addr, 0x100,          /*  Connect to the CPU:  */
222              dev_gc_access, d, DM_DEFAULT, NULL);          INTERRUPT_CONNECT(devinit->interrupt_path, d->cpu_irq);
223    
224          return d;          /*
225             *  Register the 64 Grand Central interrupts (32 lo, 32 hi):
226             */
227            for (i=0; i<32; i++) {
228                    struct interrupt template;
229                    char n[300];
230                    snprintf(n, sizeof(n), "%s.gc.lo.%i",
231                        devinit->interrupt_path, i);
232                    memset(&template, 0, sizeof(template));
233                    template.line = 1 << i;
234                    template.name = n;
235                    template.extra = d;
236                    template.interrupt_assert = gc_lo_interrupt_assert;
237                    template.interrupt_deassert = gc_lo_interrupt_deassert;
238                    interrupt_handler_register(&template);
239    
240                    snprintf(n, sizeof(n), "%s.gc.hi.%i",
241                        devinit->interrupt_path, i);
242                    memset(&template, 0, sizeof(template));
243                    template.line = 1 << i;
244                    template.name = n;
245                    template.extra = d;
246                    template.interrupt_assert = gc_hi_interrupt_assert;
247                    template.interrupt_deassert = gc_hi_interrupt_deassert;
248                    interrupt_handler_register(&template);
249            }
250    
251            memory_device_register(devinit->machine->memory, "gc",
252                devinit->addr, DEV_GC_LENGTH, dev_gc_access, d, DM_DEFAULT, NULL);
253    
254            return 1;
255  }  }
256    

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

  ViewVC Help
Powered by ViewVC 1.1.26