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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations)
Mon Oct 8 16:20:48 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 7701 byte(s)
0.4.2
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.43 2006/08/13 08:34:06 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
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40
41 #include "bus_pci.h"
42 #include "cpu.h"
43 #include "devices.h"
44 #include "machine.h"
45 #include "memory.h"
46 #include "misc.h"
47
48 #include "gtreg.h"
49
50
51 #define TICK_SHIFT 14
52
53 /* #define debug fatal */
54
55 #define PCI_PRODUCT_GALILEO_GT64011 0x4146 /* GT-64011 */
56 #define PCI_PRODUCT_GALILEO_GT64120 0x4620 /* GT-64120 */
57 #define PCI_PRODUCT_GALILEO_GT64260 0x6430 /* GT-64260 */
58
59
60 struct gt_data {
61 int timer0_irqnr;
62 int pci_irqbase;
63 int type;
64
65 /* Address decode registers: */
66 uint32_t decode[GT_N_DECODE_REGS];
67
68 struct pci_data *pci_data;
69 };
70
71
72 DEVICE_TICK(gt)
73 {
74 struct gt_data *gt_data = extra;
75
76 /* TODO: Implement real timer interrupts. */
77
78 cpu_interrupt(cpu, gt_data->timer0_irqnr);
79 }
80
81
82 DEVICE_ACCESS(gt)
83 {
84 uint64_t idata = 0, odata = 0;
85 int bus, dev, func, reg;
86 size_t i;
87 struct gt_data *d = extra;
88
89 if (writeflag == MEM_WRITE)
90 idata = memory_readmax64(cpu, data, len);
91
92 switch (relative_addr) {
93
94 case GT_PCI0IOLD_OFS:
95 case GT_PCI0IOHD_OFS:
96 case GT_PCI0M0LD_OFS:
97 case GT_PCI0M0HD_OFS:
98 case GT_PCI0M1LD_OFS:
99 case GT_PCI0M1HD_OFS:
100 case GT_PCI0IOREMAP_OFS:
101 case GT_PCI0M0REMAP_OFS:
102 case GT_PCI0M1REMAP_OFS:
103 if (writeflag == MEM_READ) {
104 odata = d->decode[relative_addr / 8];
105 debug("[ gt: read from offset 0x%x: 0x%x ]\n",
106 (int)relative_addr, (int)odata);
107 } else {
108 d->decode[relative_addr / 8] = idata;
109 fatal("[ gt: write to offset 0x%x: 0x%x (TODO) ]\n",
110 (int)relative_addr, (int)idata);
111 }
112 break;
113
114 case GT_PCI0_CMD_OFS:
115 if (writeflag == MEM_WRITE) {
116 debug("[ gt: write to GT_PCI0_CMD: 0x%08x (TODO) ]\n",
117 (int)idata);
118 } else {
119 debug("[ gt: read from GT_PCI0_CMD (0x%08x) (TODO) ]\n",
120 (int)odata);
121 }
122 break;
123
124 case GT_INTR_CAUSE:
125 if (writeflag == MEM_WRITE) {
126 debug("[ gt: write to GT_INTR_CAUSE: 0x%08x ]\n",
127 (int)idata);
128 return 1;
129 } else {
130 odata = GTIC_T0EXP;
131 cpu_interrupt_ack(cpu, d->timer0_irqnr);
132
133 debug("[ gt: read from GT_INTR_CAUSE (0x%08x) ]\n",
134 (int)odata);
135 }
136 break;
137
138 case GT_PCI0_INTR_ACK:
139 odata = cpu->machine->isa_pic_data.last_int;
140 cpu_interrupt_ack(cpu, d->pci_irqbase + odata);
141 break;
142
143 case GT_PCI0_CFG_ADDR:
144 if (cpu->byte_order != EMUL_LITTLE_ENDIAN) {
145 fatal("[ gt: TODO: big endian PCI access ]\n");
146 exit(1);
147 }
148 bus_pci_decompose_1(idata, &bus, &dev, &func, &reg);
149 bus_pci_setaddr(cpu, d->pci_data, bus, dev, func, reg);
150 break;
151
152 case GT_PCI0_CFG_DATA:
153 if (cpu->byte_order != EMUL_LITTLE_ENDIAN) {
154 fatal("[ gt: TODO: big endian PCI access ]\n");
155 exit(1);
156 }
157 bus_pci_data_access(cpu, d->pci_data, writeflag == MEM_READ?
158 &odata : &idata, len, writeflag);
159 break;
160
161 default:
162 if (writeflag == MEM_READ) {
163 debug("[ gt: read from addr 0x%x ]\n",
164 (int)relative_addr);
165 } else {
166 debug("[ gt: write to addr 0x%x:", (int)relative_addr);
167 for (i=0; i<len; i++)
168 debug(" %02x", data[i]);
169 debug(" ]\n");
170 }
171 }
172
173 if (writeflag == MEM_READ)
174 memory_writemax64(cpu, data, len, odata);
175
176 return 1;
177 }
178
179
180 /*
181 * dev_gt_init():
182 *
183 * Initialize a Gallileo PCI controller device. First, the controller itself
184 * is added to the bus, then a pointer to the bus is returned.
185 */
186 struct pci_data *dev_gt_init(struct machine *machine, struct memory *mem,
187 uint64_t baseaddr, int irq_nr, int pciirq, int type)
188 {
189 struct gt_data *d;
190 uint64_t pci_portbase = 0, pci_membase = 0;
191 uint64_t isa_portbase = 0, isa_membase = 0;
192 int isa_irqbase = 0, pci_irqbase = 0;
193 uint64_t pci_io_offset = 0, pci_mem_offset = 0;
194 char *gt_name = "NO";
195
196 d = malloc(sizeof(struct gt_data));
197 if (d == NULL) {
198 fprintf(stderr, "out of memory\n");
199 exit(1);
200 }
201 memset(d, 0, sizeof(struct gt_data));
202 d->timer0_irqnr = irq_nr;
203
204 switch (type) {
205 case 11:
206 /* Cobalt: */
207 d->type = PCI_PRODUCT_GALILEO_GT64011;
208 gt_name = "gt64011";
209 pci_io_offset = 0;
210 pci_mem_offset = 0;
211 pci_portbase = 0x10000000ULL;
212 pci_membase = 0x10100000ULL;
213 pci_irqbase = 8;
214 isa_portbase = 0x10000000ULL;
215 isa_membase = 0x10100000ULL;
216 isa_irqbase = 8;
217 break;
218 case 120:
219 /* EVBMIPS (Malta): */
220 d->type = PCI_PRODUCT_GALILEO_GT64120;
221 gt_name = "gt64120";
222 pci_io_offset = 0;
223 pci_mem_offset = 0;
224 pci_portbase = 0x18000000ULL;
225 pci_membase = 0x10000000ULL;
226 pci_irqbase = 8;
227 isa_portbase = 0x18000000ULL;
228 isa_membase = 0x10000000ULL;
229 isa_irqbase = 8;
230 break;
231 case 260:
232 /* MVMEPPC (mvme5500): */
233 d->type = PCI_PRODUCT_GALILEO_GT64260;
234 gt_name = "gt64260";
235 pci_io_offset = 0;
236 pci_mem_offset = 0;
237 pci_portbase = 0x18000000ULL;
238 pci_membase = 0x10000000ULL;
239 pci_irqbase = 8;
240 isa_portbase = 0x18000000ULL;
241 isa_membase = 0x10000000ULL;
242 isa_irqbase = 8;
243 break;
244 default:fatal("dev_gt_init(): unimplemented GT type (%i).\n", type);
245 exit(1);
246 }
247
248
249 d->pci_irqbase = pci_irqbase;
250
251 /*
252 * TODO: FIX THESE! Hardcoded numbers = bad.
253 */
254 d->decode[GT_PCI0IOLD_OFS / 8] = pci_portbase >> 21;
255 d->decode[GT_PCI0IOHD_OFS / 8] = 0x40;
256 d->decode[GT_PCI0M0LD_OFS / 8] = 0x80;
257 d->decode[GT_PCI0M0HD_OFS / 8] = 0x3f;
258 d->decode[GT_PCI0M1LD_OFS / 8] = 0xc1;
259 d->decode[GT_PCI0M1HD_OFS / 8] = 0x5e;
260 d->decode[GT_PCI0IOREMAP_OFS / 8] = d->decode[GT_PCI0IOLD_OFS / 8];
261 d->decode[GT_PCI0M0REMAP_OFS / 8] = d->decode[GT_PCI0M0LD_OFS / 8];
262 d->decode[GT_PCI0M1REMAP_OFS / 8] = d->decode[GT_PCI0M1LD_OFS / 8];
263
264 d->pci_data = bus_pci_init(machine,
265 pciirq, pci_io_offset, pci_mem_offset,
266 pci_portbase, pci_membase, pci_irqbase,
267 isa_portbase, isa_membase, isa_irqbase);
268
269 /*
270 * According to NetBSD/cobalt:
271 * pchb0 at pci0 dev 0 function 0: Galileo GT-64011
272 * System Controller, rev 1
273 */
274 bus_pci_add(machine, d->pci_data, mem, 0, 0, 0, gt_name);
275
276 memory_device_register(mem, "gt", baseaddr, DEV_GT_LENGTH,
277 dev_gt_access, d, DM_DEFAULT, NULL);
278 machine_add_tickfunction(machine, dev_gt_tick, d, TICK_SHIFT, 0.0);
279
280 return d->pci_data;
281 }
282

  ViewVC Help
Powered by ViewVC 1.1.26