dev_gc.cc Source File

Back to the index.

dev_gc.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2009 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *
28  * COMMENT: Grand Central Interrupt controller (used by MacPPC)
29  */
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 
35 #include "cpu.h"
36 #include "device.h"
37 #include "machine.h"
38 #include "memory.h"
39 #include "misc.h"
40 
41 
42 #define DEV_GC_LENGTH 0x100
43 
44 struct gc_data {
46 
47  uint32_t status_hi;
48  uint32_t status_lo;
49  uint32_t enable_hi;
50  uint32_t enable_lo;
51 };
52 
53 
55 {
56  struct gc_data *d = (struct gc_data *) interrupt->extra;
57  d->status_hi |= interrupt->line;
58  if (d->status_lo & d->enable_lo || d->status_hi & d->enable_hi)
60 }
62 {
63  struct gc_data *d = (struct gc_data *) interrupt->extra;
64  d->status_hi &= ~interrupt->line;
65  if (!(d->status_lo & d->enable_lo || d->status_hi & d->enable_hi))
67 }
69 {
70  struct gc_data *d = (struct gc_data *) interrupt->extra;
71  d->status_lo |= interrupt->line;
72  if (d->status_lo & d->enable_lo || d->status_hi & d->enable_hi)
74 }
76 {
77  struct gc_data *d = (struct gc_data *) interrupt->extra;
78  d->status_lo &= ~interrupt->line;
79  if (!(d->status_lo & d->enable_lo || d->status_hi & d->enable_hi))
81 }
82 
83 
85 {
86  struct gc_data *d = (struct gc_data *) extra;
87  uint64_t idata = 0, odata = 0;
88 
89  if (writeflag == MEM_WRITE)
90  idata = memory_readmax64(cpu, data, len);
91 
92  switch (relative_addr) {
93 
94 #if 0
95 #define INT_STATE_REG_H (interrupt_reg + 0x00)
96 #define INT_ENABLE_REG_H (interrupt_reg + 0x04)
97 #define INT_CLEAR_REG_H (interrupt_reg + 0x08)
98 #define INT_LEVEL_REG_H (interrupt_reg + 0x0c)
99 #define INT_STATE_REG_L (interrupt_reg + 0x10)
100 #define INT_ENABLE_REG_L (interrupt_reg + 0x14)
101 #define INT_CLEAR_REG_L (interrupt_reg + 0x18)
102 #define INT_LEVEL_REG_L (interrupt_reg + 0x1c)
103 #endif
104 
105  case 0x10:
106  if (writeflag == MEM_READ)
107  odata = d->status_hi & d->enable_hi;
108  break;
109 
110  case 0x14:
111  if (writeflag == MEM_READ)
112  odata = d->enable_hi;
113  else {
114  int old_assert = (d->status_lo & d->enable_lo
115  || d->status_hi & d->enable_hi);
116  int new_assert;
117  d->enable_hi = idata;
118 
119  new_assert = (d->status_lo & d->enable_lo ||
120  d->status_hi & d->enable_hi);
121 
122  if (old_assert && !new_assert)
124  else if (!old_assert && new_assert)
126  }
127  break;
128 
129  case 0x18:
130  if (writeflag == MEM_WRITE) {
131  int old_assert = (d->status_lo & d->enable_lo
132  || d->status_hi & d->enable_hi);
133  int new_assert;
134  d->status_hi &= ~idata;
135 
136  new_assert = (d->status_lo & d->enable_lo ||
137  d->status_hi & d->enable_hi);
138 
139  if (old_assert && !new_assert)
141  else if (!old_assert && new_assert)
143  }
144  break;
145 
146  case 0x20:
147  if (writeflag == MEM_READ)
148  odata = d->status_lo & d->enable_lo;
149  break;
150 
151  case 0x24:
152  if (writeflag == MEM_READ)
153  odata = d->enable_lo;
154  else {
155  int old_assert = (d->status_lo & d->enable_lo
156  || d->status_hi & d->enable_hi);
157  int new_assert;
158  d->enable_lo = idata;
159 
160  new_assert = (d->status_lo & d->enable_lo ||
161  d->status_hi & d->enable_hi);
162 
163  if (old_assert && !new_assert)
165  else if (!old_assert && new_assert)
167  }
168  break;
169 
170  case 0x28:
171  if (writeflag == MEM_WRITE) {
172  int old_assert = (d->status_lo & d->enable_lo
173  || d->status_hi & d->enable_hi);
174  int new_assert;
175  d->status_lo &= ~idata;
176 
177  new_assert = (d->status_lo & d->enable_lo ||
178  d->status_hi & d->enable_hi);
179 
180  if (old_assert && !new_assert)
182  else if (!old_assert && new_assert)
184  }
185  break;
186 
187  case 0x1c:
188  case 0x2c:
189  /* Avoid a debug message. */
190  break;
191 
192  default:if (writeflag == MEM_WRITE) {
193  fatal("[ gc: unimplemented write to "
194  "offset 0x%x: data=0x%x ]\n", (int)
195  relative_addr, (int)idata);
196  } else {
197  fatal("[ gc: unimplemented read from "
198  "offset 0x%x ]\n", (int)relative_addr);
199  }
200  }
201 
202  if (writeflag == MEM_READ)
203  memory_writemax64(cpu, data, len, odata);
204 
205  return 1;
206 }
207 
208 
210 {
211  struct gc_data *d;
212  int i;
213 
214  CHECK_ALLOCATION(d = (struct gc_data *) malloc(sizeof(struct gc_data)));
215  memset(d, 0, sizeof(struct gc_data));
216 
217  /* Connect to the CPU interrupt pin: */
219 
220  /*
221  * Register the 64 Grand Central interrupts (32 lo, 32 hi):
222  */
223  for (i=0; i<32; i++) {
224  struct interrupt templ;
225  char n[300];
226  snprintf(n, sizeof(n), "%s.gc.lo.%i",
227  devinit->interrupt_path, i);
228  memset(&templ, 0, sizeof(templ));
229  templ.line = 1 << i;
230  templ.name = n;
231  templ.extra = d;
235 
236  snprintf(n, sizeof(n), "%s.gc.hi.%i",
237  devinit->interrupt_path, i);
238  memset(&templ, 0, sizeof(templ));
239  templ.line = 1 << i;
240  templ.name = n;
241  templ.extra = d;
245  }
246 
248  devinit->addr, DEV_GC_LENGTH, dev_gc_access, d, DM_DEFAULT, NULL);
249 
250  return 1;
251 }
252 
uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
Definition: memory.cc:55
void fatal(const char *fmt,...)
Definition: main.cc:152
void(* interrupt_assert)(struct interrupt *)
Definition: interrupt.h:38
#define DM_DEFAULT
Definition: memory.h:130
struct interrupt cpu_irq
Definition: dev_gc.cc:45
uint32_t status_hi
Definition: dev_gc.cc:47
void interrupt_handler_register(struct interrupt *templ)
Definition: interrupt.cc:81
#define MEM_READ
Definition: memory.h:116
void(* interrupt_deassert)(struct interrupt *)
Definition: interrupt.h:39
struct memory * memory
Definition: machine.h:126
void gc_hi_interrupt_deassert(struct interrupt *interrupt)
Definition: dev_gc.cc:61
void gc_lo_interrupt_assert(struct interrupt *interrupt)
Definition: dev_gc.cc:68
DEVICE_ACCESS(gc)
Definition: dev_gc.cc:84
uint32_t enable_hi
Definition: dev_gc.cc:49
#define CHECK_ALLOCATION(ptr)
Definition: misc.h:239
u_short data
Definition: siireg.h:79
#define INTERRUPT_ASSERT(istruct)
Definition: interrupt.h:74
#define MEM_WRITE
Definition: memory.h:117
uint32_t enable_lo
Definition: dev_gc.cc:50
void gc_hi_interrupt_assert(struct interrupt *interrupt)
Definition: dev_gc.cc:54
Definition: device.h:40
DEVINIT(gc)
Definition: dev_gc.cc:209
uint32_t line
Definition: interrupt.h:51
#define INTERRUPT_CONNECT(name, istruct)
Definition: interrupt.h:77
Definition: cpu.h:326
struct machine * machine
Definition: device.h:41
char * name
Definition: interrupt.h:66
void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data)
Definition: memory.cc:89
void memory_device_register(struct memory *mem, const char *, uint64_t baseaddr, uint64_t len, int(*f)(struct cpu *, struct memory *, uint64_t, unsigned char *, size_t, int, void *), void *extra, int flags, unsigned char *dyntrans_data)
Definition: memory.cc:339
uint32_t status_lo
Definition: dev_gc.cc:48
#define DEV_GC_LENGTH
Definition: dev_gc.cc:42
void gc_lo_interrupt_deassert(struct interrupt *interrupt)
Definition: dev_gc.cc:75
addr & if(addr >=0x24 &&page !=NULL)
uint64_t addr
Definition: device.h:46
void * extra
Definition: interrupt.h:59
char * interrupt_path
Definition: device.h:50
#define INTERRUPT_DEASSERT(istruct)
Definition: interrupt.h:75

Generated on Fri Dec 7 2018 19:52:23 for GXemul by doxygen 1.8.13