/[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

Annotation of /trunk/src/devices/dev_gt.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 30 - (hide 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 dpavlin 4 /*
2 dpavlin 22 * Copyright (C) 2003-2006 Anders Gavare. All rights reserved.
3 dpavlin 4 *
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 dpavlin 30 * $Id: dev_gt.c,v 1.43 2006/08/13 08:34:06 debug Exp $
29 dpavlin 4 *
30 dpavlin 10 * Galileo Technology GT-64xxx PCI controller.
31 dpavlin 4 *
32 dpavlin 10 * GT-64011 Used in Cobalt machines.
33     * GT-64120 Used in evbmips machines (Malta).
34 dpavlin 22 * GT-64260 Used in mvmeppc machines.
35 dpavlin 4 */
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 dpavlin 28 #include "gtreg.h"
49 dpavlin 4
50 dpavlin 28
51 dpavlin 12 #define TICK_SHIFT 14
52 dpavlin 4
53 dpavlin 12 /* #define debug fatal */
54    
55 dpavlin 20 #define PCI_PRODUCT_GALILEO_GT64011 0x4146 /* GT-64011 */
56     #define PCI_PRODUCT_GALILEO_GT64120 0x4620 /* GT-64120 */
57 dpavlin 22 #define PCI_PRODUCT_GALILEO_GT64260 0x6430 /* GT-64260 */
58 dpavlin 4
59 dpavlin 28
60 dpavlin 4 struct gt_data {
61 dpavlin 28 int timer0_irqnr;
62     int pci_irqbase;
63     int type;
64 dpavlin 4
65 dpavlin 30 /* Address decode registers: */
66     uint32_t decode[GT_N_DECODE_REGS];
67 dpavlin 28
68     struct pci_data *pci_data;
69 dpavlin 4 };
70    
71    
72 dpavlin 28 DEVICE_TICK(gt)
73 dpavlin 4 {
74     struct gt_data *gt_data = extra;
75    
76 dpavlin 28 /* TODO: Implement real timer interrupts. */
77    
78     cpu_interrupt(cpu, gt_data->timer0_irqnr);
79 dpavlin 4 }
80    
81    
82 dpavlin 22 DEVICE_ACCESS(gt)
83 dpavlin 4 {
84     uint64_t idata = 0, odata = 0;
85 dpavlin 22 int bus, dev, func, reg;
86     size_t i;
87 dpavlin 4 struct gt_data *d = extra;
88    
89 dpavlin 18 if (writeflag == MEM_WRITE)
90     idata = memory_readmax64(cpu, data, len);
91 dpavlin 4
92     switch (relative_addr) {
93 dpavlin 12
94 dpavlin 28 case GT_PCI0IOLD_OFS:
95 dpavlin 30 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 dpavlin 28 if (writeflag == MEM_READ) {
104 dpavlin 30 odata = d->decode[relative_addr / 8];
105     debug("[ gt: read from offset 0x%x: 0x%x ]\n",
106     (int)relative_addr, (int)odata);
107 dpavlin 28 } else {
108 dpavlin 30 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 dpavlin 12 }
112     break;
113    
114 dpavlin 30 case GT_PCI0_CMD_OFS:
115     if (writeflag == MEM_WRITE) {
116     debug("[ gt: write to GT_PCI0_CMD: 0x%08x (TODO) ]\n",
117 dpavlin 28 (int)idata);
118     } else {
119 dpavlin 30 debug("[ gt: read from GT_PCI0_CMD (0x%08x) (TODO) ]\n",
120     (int)odata);
121 dpavlin 28 }
122     break;
123    
124     case GT_INTR_CAUSE:
125 dpavlin 4 if (writeflag == MEM_WRITE) {
126 dpavlin 28 debug("[ gt: write to GT_INTR_CAUSE: 0x%08x ]\n",
127     (int)idata);
128 dpavlin 4 return 1;
129     } else {
130 dpavlin 28 odata = GTIC_T0EXP;
131     cpu_interrupt_ack(cpu, d->timer0_irqnr);
132 dpavlin 4
133 dpavlin 28 debug("[ gt: read from GT_INTR_CAUSE (0x%08x) ]\n",
134     (int)odata);
135 dpavlin 4 }
136     break;
137 dpavlin 12
138 dpavlin 28 case GT_PCI0_INTR_ACK:
139 dpavlin 20 odata = cpu->machine->isa_pic_data.last_int;
140 dpavlin 28 cpu_interrupt_ack(cpu, d->pci_irqbase + odata);
141 dpavlin 12 break;
142    
143 dpavlin 28 case GT_PCI0_CFG_ADDR:
144 dpavlin 22 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 dpavlin 28 case GT_PCI0_CFG_DATA:
153 dpavlin 22 if (cpu->byte_order != EMUL_LITTLE_ENDIAN) {
154     fatal("[ gt: TODO: big endian PCI access ]\n");
155     exit(1);
156 dpavlin 4 }
157 dpavlin 22 bus_pci_data_access(cpu, d->pci_data, writeflag == MEM_READ?
158     &odata : &idata, len, writeflag);
159 dpavlin 4 break;
160 dpavlin 22
161 dpavlin 4 default:
162 dpavlin 20 if (writeflag == MEM_READ) {
163 dpavlin 12 debug("[ gt: read from addr 0x%x ]\n",
164 dpavlin 4 (int)relative_addr);
165     } else {
166 dpavlin 12 debug("[ gt: write to addr 0x%x:", (int)relative_addr);
167 dpavlin 4 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 dpavlin 30 * 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 dpavlin 4 */
186     struct pci_data *dev_gt_init(struct machine *machine, struct memory *mem,
187 dpavlin 10 uint64_t baseaddr, int irq_nr, int pciirq, int type)
188 dpavlin 4 {
189     struct gt_data *d;
190 dpavlin 20 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 dpavlin 22 char *gt_name = "NO";
195 dpavlin 4
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 dpavlin 28 d->timer0_irqnr = irq_nr;
203 dpavlin 4
204 dpavlin 10 switch (type) {
205     case 11:
206 dpavlin 20 /* Cobalt: */
207 dpavlin 10 d->type = PCI_PRODUCT_GALILEO_GT64011;
208 dpavlin 22 gt_name = "gt64011";
209 dpavlin 20 pci_io_offset = 0;
210     pci_mem_offset = 0;
211     pci_portbase = 0x10000000ULL;
212     pci_membase = 0x10100000ULL;
213 dpavlin 28 pci_irqbase = 8;
214 dpavlin 20 isa_portbase = 0x10000000ULL;
215     isa_membase = 0x10100000ULL;
216     isa_irqbase = 8;
217 dpavlin 10 break;
218     case 120:
219 dpavlin 20 /* EVBMIPS (Malta): */
220 dpavlin 10 d->type = PCI_PRODUCT_GALILEO_GT64120;
221 dpavlin 22 gt_name = "gt64120";
222 dpavlin 20 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 dpavlin 10 break;
231 dpavlin 22 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 dpavlin 10 exit(1);
246     }
247    
248 dpavlin 30
249 dpavlin 28 d->pci_irqbase = pci_irqbase;
250    
251 dpavlin 30 /*
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 dpavlin 22 d->pci_data = bus_pci_init(machine,
265 dpavlin 20 pciirq, pci_io_offset, pci_mem_offset,
266     pci_portbase, pci_membase, pci_irqbase,
267     isa_portbase, isa_membase, isa_irqbase);
268    
269 dpavlin 4 /*
270     * According to NetBSD/cobalt:
271     * pchb0 at pci0 dev 0 function 0: Galileo GT-64011
272     * System Controller, rev 1
273     */
274 dpavlin 22 bus_pci_add(machine, d->pci_data, mem, 0, 0, 0, gt_name);
275 dpavlin 4
276     memory_device_register(mem, "gt", baseaddr, DEV_GT_LENGTH,
277 dpavlin 20 dev_gt_access, d, DM_DEFAULT, NULL);
278 dpavlin 24 machine_add_tickfunction(machine, dev_gt_tick, d, TICK_SHIFT, 0.0);
279 dpavlin 4
280     return d->pci_data;
281     }
282    

  ViewVC Help
Powered by ViewVC 1.1.26