/[gxemul]/upstream/0.3.8/src/devices/dev_gt.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

Contents of /upstream/0.3.8/src/devices/dev_gt.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (show annotations)
Mon Oct 8 16:19:43 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 7149 byte(s)
0.3.8
1 /*
2 * Copyright (C) 2003-2006 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 * $Id: dev_gt.c,v 1.40 2006/01/14 11:29:36 debug Exp $
29 *
30 * Galileo Technology GT-64xxx PCI controller.
31 *
32 * GT-64011 Used in Cobalt machines.
33 * GT-64120 Used in evbmips machines (Malta).
34 * GT-64260 Used in mvmeppc machines.
35 *
36 * TODO: This more or less just a dummy device, so far. It happens to work
37 * with some NetBSD ports in some cases, and perhaps with Linux too,
38 * but it is not really working for anything else.
39 */
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 #include "bus_pci.h"
46 #include "cpu.h"
47 #include "devices.h"
48 #include "machine.h"
49 #include "memory.h"
50 #include "misc.h"
51
52
53 #define TICK_SHIFT 14
54
55 /* #define debug fatal */
56
57 #define PCI_PRODUCT_GALILEO_GT64011 0x4146 /* GT-64011 */
58 #define PCI_PRODUCT_GALILEO_GT64120 0x4620 /* GT-64120 */
59 #define PCI_PRODUCT_GALILEO_GT64260 0x6430 /* GT-64260 */
60
61 struct gt_data {
62 int irqnr;
63 int pciirq;
64 int type;
65
66 struct pci_data *pci_data;
67 };
68
69
70 /*
71 * dev_gt_tick():
72 */
73 void dev_gt_tick(struct cpu *cpu, void *extra)
74 {
75 struct gt_data *gt_data = extra;
76
77 cpu_interrupt(cpu, gt_data->irqnr);
78 }
79
80
81 /*
82 * dev_gt_access():
83 */
84 DEVICE_ACCESS(gt)
85 {
86 uint64_t idata = 0, odata = 0;
87 int bus, dev, func, reg;
88 size_t i;
89 struct gt_data *d = extra;
90
91 if (writeflag == MEM_WRITE)
92 idata = memory_readmax64(cpu, data, len);
93
94 switch (relative_addr) {
95
96 case 0x48:
97 switch (d->type) {
98 case PCI_PRODUCT_GALILEO_GT64120:
99 /*
100 * This is needed for Linux on Malta, according
101 * to Alec Voropay. (TODO: Remove this hack when
102 * things have stabilized.)
103 */
104 if (writeflag == MEM_READ) {
105 odata = 0x18000000 >> 21;
106 debug("[ gt: read from 0x48: 0x%08x ]\n",
107 (int)odata);
108 }
109 break;
110 default:
111 fatal("[ gt: access to 0x48? (type %i) ]\n", d->type);
112 }
113 break;
114
115 case 0xc18:
116 if (writeflag == MEM_WRITE) {
117 debug("[ gt: write to 0xc18: 0x%08x ]\n", (int)idata);
118 return 1;
119 } else {
120 odata = 0xffffffffULL;
121 /*
122 * ??? interrupt something...
123 *
124 * TODO: Remove this hack when things have stabilized.
125 */
126 odata = 0x00000100;
127 /* netbsd/cobalt cobalt/machdep.c:cpu_intr() */
128
129 cpu_interrupt_ack(cpu, d->irqnr);
130
131 debug("[ gt: read from 0xc18 (0x%08x) ]\n", (int)odata);
132 }
133 break;
134
135 case 0xc34: /* GT_PCI0_INTR_ACK */
136 odata = cpu->machine->isa_pic_data.last_int;
137 cpu_interrupt_ack(cpu, 8 + odata);
138 break;
139
140 case 0xcf8: /* PCI ADDR */
141 if (cpu->byte_order != EMUL_LITTLE_ENDIAN) {
142 fatal("[ gt: TODO: big endian PCI access ]\n");
143 exit(1);
144 }
145 bus_pci_decompose_1(idata, &bus, &dev, &func, &reg);
146 bus_pci_setaddr(cpu, d->pci_data, bus, dev, func, reg);
147 break;
148
149 case 0xcfc: /* PCI DATA */
150 if (cpu->byte_order != EMUL_LITTLE_ENDIAN) {
151 fatal("[ gt: TODO: big endian PCI access ]\n");
152 exit(1);
153 }
154 bus_pci_data_access(cpu, d->pci_data, writeflag == MEM_READ?
155 &odata : &idata, len, writeflag);
156 break;
157
158 default:
159 if (writeflag == MEM_READ) {
160 debug("[ gt: read from addr 0x%x ]\n",
161 (int)relative_addr);
162 } else {
163 debug("[ gt: write to addr 0x%x:", (int)relative_addr);
164 for (i=0; i<len; i++)
165 debug(" %02x", data[i]);
166 debug(" ]\n");
167 }
168 }
169
170 if (writeflag == MEM_READ)
171 memory_writemax64(cpu, data, len, odata);
172
173 return 1;
174 }
175
176
177 /*
178 * dev_gt_init():
179 *
180 * Initialize a GT device. Return a pointer to the pci_data used, so that
181 * the caller may add PCI devices. First, however, we add the GT device
182 * itself.
183 */
184 struct pci_data *dev_gt_init(struct machine *machine, struct memory *mem,
185 uint64_t baseaddr, int irq_nr, int pciirq, int type)
186 {
187 struct gt_data *d;
188 uint64_t pci_portbase = 0, pci_membase = 0;
189 uint64_t isa_portbase = 0, isa_membase = 0;
190 int isa_irqbase = 0, pci_irqbase = 0;
191 uint64_t pci_io_offset = 0, pci_mem_offset = 0;
192 char *gt_name = "NO";
193
194 d = malloc(sizeof(struct gt_data));
195 if (d == NULL) {
196 fprintf(stderr, "out of memory\n");
197 exit(1);
198 }
199 memset(d, 0, sizeof(struct gt_data));
200 d->irqnr = irq_nr;
201 d->pciirq = pciirq;
202
203 switch (type) {
204 case 11:
205 /* Cobalt: */
206 d->type = PCI_PRODUCT_GALILEO_GT64011;
207 gt_name = "gt64011";
208 pci_io_offset = 0;
209 pci_mem_offset = 0;
210 pci_portbase = 0x10000000ULL;
211 pci_membase = 0x10100000ULL;
212 pci_irqbase = 0;
213 isa_portbase = 0x10000000ULL;
214 isa_membase = 0x10100000ULL;
215 isa_irqbase = 8;
216 break;
217 case 120:
218 /* EVBMIPS (Malta): */
219 d->type = PCI_PRODUCT_GALILEO_GT64120;
220 gt_name = "gt64120";
221 pci_io_offset = 0;
222 pci_mem_offset = 0;
223 pci_portbase = 0x18000000ULL;
224 pci_membase = 0x10000000ULL;
225 pci_irqbase = 8;
226 isa_portbase = 0x18000000ULL;
227 isa_membase = 0x10000000ULL;
228 isa_irqbase = 8;
229 break;
230 case 260:
231 /* MVMEPPC (mvme5500): */
232 d->type = PCI_PRODUCT_GALILEO_GT64260;
233 gt_name = "gt64260";
234 pci_io_offset = 0;
235 pci_mem_offset = 0;
236 pci_portbase = 0x18000000ULL;
237 pci_membase = 0x10000000ULL;
238 pci_irqbase = 8;
239 isa_portbase = 0x18000000ULL;
240 isa_membase = 0x10000000ULL;
241 isa_irqbase = 8;
242 break;
243 default:fatal("dev_gt_init(): unimplemented GT type (%i).\n", type);
244 exit(1);
245 }
246
247 d->pci_data = bus_pci_init(machine,
248 pciirq, pci_io_offset, pci_mem_offset,
249 pci_portbase, pci_membase, pci_irqbase,
250 isa_portbase, isa_membase, isa_irqbase);
251
252 /*
253 * According to NetBSD/cobalt:
254 * pchb0 at pci0 dev 0 function 0: Galileo GT-64011
255 * System Controller, rev 1
256 */
257 bus_pci_add(machine, d->pci_data, mem, 0, 0, 0, gt_name);
258
259 memory_device_register(mem, "gt", baseaddr, DEV_GT_LENGTH,
260 dev_gt_access, d, DM_DEFAULT, NULL);
261 machine_add_tickfunction(machine, dev_gt_tick, d, TICK_SHIFT);
262
263 return d->pci_data;
264 }
265

  ViewVC Help
Powered by ViewVC 1.1.26