/[gxemul]/upstream/0.3.2/src/devices/pci_ahc.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.2/src/devices/pci_ahc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5 - (show annotations)
Mon Oct 8 16:18:06 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 7118 byte(s)
0.3.2
1 /*
2 * Copyright (C) 2004-2005 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: pci_ahc.c,v 1.19 2005/04/05 20:33:08 debug Exp $
29 *
30 * Adaptec AHC SCSI controller.
31 *
32 * NetBSD should say something like this, on SGI-IP32:
33 * ahc0 at pci0 dev 1 function 0
34 * ahc0: interrupting at crime irq 0
35 * ahc0: aic7880 Wide Channel A, SCSI Id=7, 16/255 SCBs
36 * ahc0: Host Adapter Bios disabled. Using default SCSI device parameters
37 *
38 * TODO: This more or less just a dummy device, so far.
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 "memory.h"
49 #include "misc.h"
50
51 #include "aic7xxx_reg.h"
52
53
54 /* #define AHC_DEBUG
55 #define debug fatal */
56
57
58 #define PCI_VENDOR_ADP 0x9004 /* Adaptec */
59 #define PCI_VENDOR_ADP2 0x9005 /* Adaptec (2nd PCI Vendor ID) */
60 #define PCI_PRODUCT_ADP_2940U 0x8178 /* AHA-2940 Ultra */
61 #define PCI_PRODUCT_ADP_2940UP 0x8778 /* AHA-2940 Ultra Pro */
62
63 #define DEV_AHC_LENGTH 0x100
64
65 struct ahc_data {
66 unsigned char reg[DEV_AHC_LENGTH];
67 };
68
69
70 /*
71 * pci_ahc_rr():
72 */
73 uint32_t pci_ahc_rr(int reg)
74 {
75 /* Numbers taken from a Adaptec 2940U: */
76 /* http://mail-index.netbsd.org/netbsd-bugs/2000/04/29/0000.html */
77
78 switch (reg) {
79 case 0x00:
80 return PCI_VENDOR_ADP +
81 ((uint32_t)PCI_PRODUCT_ADP_2940U << 16);
82 case 0x04:
83 return 0x02900007;
84 case 0x08:
85 /* Revision ? */
86 return PCI_CLASS_CODE(PCI_CLASS_MASS_STORAGE,
87 PCI_SUBCLASS_MASS_STORAGE_SCSI, 0) + 0x1;
88 case 0x0c:
89 return 0x00004008;
90 case 0x10:
91 return 1; /* 1 = type i/o. 0x0000e801; address? */
92 case 0x14:
93 return 0; /* 0xf1002000; */
94 case 0x18:
95 return 0x00000000;
96 case 0x1c:
97 return 0x00000000;
98 case 0x20:
99 return 0x00000000;
100 case 0x24:
101 return 0x00000000;
102 case 0x28:
103 return 0x00000000;
104 case 0x2c:
105 return 0; /* 0x78819004; subsystem vendor id ??? */
106 case 0x30:
107 return 0xef000000;
108 case 0x34:
109 return 0x000000dc;
110 case 0x38:
111 return 0x00000000;
112 case 0x3c:
113 return 0x08080109; /* interrupt pin A? */
114 default:
115 return 0;
116 }
117 }
118
119
120 /*
121 * dev_ahc_access():
122 */
123 int dev_ahc_access(struct cpu *cpu, struct memory *mem,
124 uint64_t relative_addr, unsigned char *data, size_t len,
125 int writeflag, void *extra)
126 {
127 struct ahc_data *d = extra;
128 uint64_t idata, odata = 0;
129 int ok = 0;
130 char *name = NULL;
131
132 idata = memory_readmax64(cpu, data, len);
133
134 /* YUCK! SGI uses reversed order inside 32-bit words: */
135 if (cpu->byte_order == EMUL_BIG_ENDIAN)
136 relative_addr = (relative_addr & ~0x3)
137 | (3 - (relative_addr & 3));
138
139 relative_addr %= DEV_AHC_LENGTH;
140
141 if (len != 1)
142 fatal("[ ahc: ERROR! Unimplemented len %i ]\n", len);
143
144 if (writeflag == MEM_READ)
145 odata = d->reg[relative_addr];
146
147 switch (relative_addr) {
148
149 case SCSIID:
150 if (writeflag == MEM_READ) {
151 ok = 1; name = "SCSIID";
152 odata = 0;
153 } else {
154 fatal("[ ahc: write to SCSIOFFSET, data = 0x"
155 "%02x: TODO ]\n", (int)idata);
156 }
157 break;
158
159 case KERNEL_QINPOS:
160 if (writeflag == MEM_WRITE) {
161
162 /* TODO */
163
164 d->reg[INTSTAT] |= SEQINT;
165 }
166 break;
167
168 case SEECTL:
169 ok = 1; name = "SEECTL";
170 if (writeflag == MEM_WRITE)
171 d->reg[relative_addr] = idata;
172 odata |= SEERDY;
173 break;
174
175 case SCSICONF:
176 ok = 1; name = "SCSICONF";
177 if (writeflag == MEM_READ) {
178 odata = 0;
179 } else {
180 fatal("[ ahc: write to SCSICONF, data = 0x%02x:"
181 " TODO ]\n", (int)idata);
182 }
183 break;
184
185 case SEQRAM:
186 case SEQADDR0:
187 case SEQADDR1:
188 /* TODO: This is just a dummy. */
189 break;
190
191 case HCNTRL:
192 ok = 1; name = "HCNTRL";
193 if (writeflag == MEM_WRITE)
194 d->reg[relative_addr] = idata;
195 break;
196
197 case INTSTAT:
198 ok = 1; name = "INTSTAT";
199 if (writeflag == MEM_WRITE)
200 fatal("[ ahc: write to INTSTAT? data = 0x%02x ]\n",
201 (int)idata);
202 break;
203
204 case CLRINT:
205 if (writeflag == MEM_READ) {
206 ok = 1; name = "ERROR";
207 /* TODO */
208 } else {
209 ok = 1; name = "CLRINT";
210 if (idata & ~0xf)
211 fatal("[ ahc: write to CLRINT: 0x%02x "
212 "(TODO) ]\n", (int)idata);
213 /* Clear the lowest 4 bits of intstat: */
214 d->reg[INTSTAT] &= ~(idata & 0xf);
215 }
216 break;
217
218 default:
219 if (writeflag == MEM_WRITE)
220 fatal("[ ahc: UNIMPLEMENTED write to address 0x%x, "
221 "data=0x%02x ]\n", (int)relative_addr, (int)idata);
222 else
223 fatal("[ ahc: UNIMPLEMENTED read from address 0x%x ]\n",
224 (int)relative_addr);
225 }
226
227 #if 0
228 cpu_interrupt(cpu, 0x200);
229 #endif
230
231 #ifdef AHC_DEBUG
232 if (ok) {
233 if (name == NULL) {
234 if (writeflag == MEM_WRITE)
235 debug("[ ahc: write to address 0x%x: 0x"
236 "%02x ]\n", (int)relative_addr, (int)idata);
237 else
238 debug("[ ahc: read from address 0x%x: 0x"
239 "%02x ]\n", (int)relative_addr, (int)odata);
240 } else {
241 if (writeflag == MEM_WRITE)
242 debug("[ ahc: write to %s: 0x%02x ]\n",
243 name, (int)idata);
244 else
245 debug("[ ahc: read from %s: 0x%02x ]\n",
246 name, (int)odata);
247 }
248 }
249 #endif
250
251 if (writeflag == MEM_READ)
252 memory_writemax64(cpu, data, len, odata);
253
254 return 1;
255 }
256
257
258 /*
259 * pci_ahc_init():
260 */
261 void pci_ahc_init(struct machine *machine, struct memory *mem)
262 {
263 struct ahc_data *d;
264
265 d = malloc(sizeof(struct ahc_data));
266 if (d == NULL) {
267 fprintf(stderr, "out of memory\n");
268 exit(1);
269 }
270 memset(d, 0, sizeof(struct ahc_data));
271
272 /* TODO: this address is based on what NetBSD/sgimips uses
273 on SGI IP32 (O2). Fix this. */
274
275 memory_device_register(mem, "ahc", 0x18000000, DEV_AHC_LENGTH,
276 dev_ahc_access, d, MEM_DEFAULT, NULL);
277
278 /* OpenBSD/sgi snapshots sometime between 2005-03-11 and
279 2005-04-04 changed to using 0x1a000000: */
280 dev_ram_init(mem, 0x1a000000, 0x2000000, DEV_RAM_MIRROR,
281 0x18000000);
282 }
283

  ViewVC Help
Powered by ViewVC 1.1.26