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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 30 - (show annotations)
Mon Oct 8 16:20:40 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 7701 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1325 2006/08/15 15:38:37 debug Exp $
20060723	More Transputer instructions (pfix, nfix, opr, mint, ldl, ldlp,
		eqc, rev, ajw, stl, stlf, sthf, sub, ldnl, ldnlp, ldpi, move,
		wcnt, add, bcnt).
		Adding more SPARC instructions (andcc, addcc, bl, rdpr).
		Progress on the igsfb framebuffer used by NetBSD/netwinder.
		Enabling 8-bit fills in dev_fb.
		NetBSD/netwinder 3.0.1 can now run from a disk image :-)
20060724	Cleanup/performance fix for 64-bit virtual translation table
		updates (by removing the "timestamp" stuff). A full NetBSD/pmax
		3.0.1 install for R4400 has dropped from 667 seconds to 584 :)
		Fixing the igsfb "almost vga" color (it is 24-bit, not 18-bit).
		Adding some MIPS instruction combinations (3*lw, and 3*addu).
		The 8048 keyboard now turns off interrupt enable between the
		KBR_ACK and the KBR_RSTDONE, to work better with Linux 2.6.
		Not causing PPC DEC interrupts if PPC_NO_DEC is set for a
		specific CPU; NetBSD/bebox gets slightly further than before.
		Adding some more SPARC instructions: branches, udiv.
20060725	Refreshing dev_pckbc.c a little.
		Cleanups for the SH emulation mode, and adding the first
		"compact" (16-bit) instructions: various simple movs, nop,
		shll, stc, or, ldc.
20060726	Adding dummy "pcn" (AMD PCnet NIC) PCI glue.
20060727	Various cleanups; removing stuff from cpu.h, such as
		running_translated (not really meaningful anymore), and
		page flags (breaking into the debugger clears all translations
		anyway).
		Minor MIPS instruction combination updates.
20060807	Expanding the 3*sw and 3*lw MIPS instruction combinations to
		work with 2* and 4* too, resulting in a minor performance gain.
		Implementing a usleep hack for the RM52xx/MIPS32/MIPS64 "wait"
		instruction (when emulating 1 cpu).
20060808	Experimenting with some more MIPS instruction combinations.
		Implementing support for showing a (hardcoded 12x22) text
		cursor in igsfb.
20060809	Simplifying the NetBSD/evbmips (Malta) install instructions
		somewhat (by using a NetBSD/pmax ramdisk install kernel).
20060812	Experimenting more with the MIPS 'wait' instruction.
		PCI configuration register writes can now be handled, which
		allow PCI IDE controllers to work with NetBSD/Malta 3.0.1 and
		NetBSD/cobalt 3.0.1. (Previously only NetBSD 2.1 worked.)
20060813	Updating dev_gt.c based on numbers from Alec Voropay, to enable
		Linux 2.6 to use PCI on Malta.
		Continuing on Algor interrupt stuff.
20060814	Adding support for routing ISA interrupts to two different
		interrupts, making it possible to run NetBSD/algor :-)
20060814-15	Testing for the release.

==============  RELEASE 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