dev_ahc.cc Source File

Back to the index.

dev_ahc.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004-2009 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  * COMMENT: Adaptec AHC SCSI controller
29  *
30  * NetBSD should say something like this, on SGI-IP32:
31  * ahc0 at pci0 dev 1 function 0
32  * ahc0: interrupting at crime irq 0
33  * ahc0: aic7880 Wide Channel A, SCSI Id=7, 16/255 SCBs
34  * ahc0: Host Adapter Bios disabled. Using default SCSI device parameters
35  *
36  * TODO: This more or less just a dummy device, so far.
37  */
38 
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 
43 #include "cpu.h"
44 #include "device.h"
45 #include "machine.h"
46 #include "memory.h"
47 #include "misc.h"
48 
49 #include "thirdparty/aic7xxx_reg.h"
50 
51 
52 /* #define AHC_DEBUG
53  #define debug fatal */
54 
55 
56 #define DEV_AHC_LENGTH 0x100
57 
58 struct ahc_data {
59  unsigned char reg[DEV_AHC_LENGTH];
60 };
61 
62 
64 {
65  struct ahc_data *d = (struct ahc_data *) extra;
66  uint64_t idata, odata = 0;
67  int ok = 0;
68  const char *name = NULL;
69 
70  idata = memory_readmax64(cpu, data, len);
71 
72  /* YUCK! SGI uses reversed order inside 32-bit words: */
74  relative_addr = (relative_addr & ~0x3)
75  | (3 - (relative_addr & 3));
76 
77  relative_addr %= DEV_AHC_LENGTH;
78 
79  if (len != 1)
80  fatal("[ ahc: ERROR! Unimplemented len %i ]\n", len);
81 
82  if (writeflag == MEM_READ)
83  odata = d->reg[relative_addr];
84 
85  switch (relative_addr) {
86 
87  case SCSIID:
88  if (writeflag == MEM_READ) {
89  ok = 1; name = "SCSIID";
90  odata = 0;
91  } else {
92  fatal("[ ahc: write to SCSIOFFSET, data = 0x"
93  "%02x: TODO ]\n", (int)idata);
94  }
95  break;
96 
97  case KERNEL_QINPOS:
98  if (writeflag == MEM_WRITE) {
99 
100  /* TODO */
101 
102  d->reg[INTSTAT] |= SEQINT;
103  }
104  break;
105 
106  case SEECTL:
107  ok = 1; name = "SEECTL";
108  if (writeflag == MEM_WRITE)
109  d->reg[relative_addr] = idata;
110  odata |= SEERDY;
111  break;
112 
113  case SCSICONF:
114  ok = 1; name = "SCSICONF";
115  if (writeflag == MEM_READ) {
116  odata = 0;
117  } else {
118  fatal("[ ahc: write to SCSICONF, data = 0x%02x:"
119  " TODO ]\n", (int)idata);
120  }
121  break;
122 
123  case SEQRAM:
124  case SEQADDR0:
125  case SEQADDR1:
126  /* TODO: This is just a dummy. */
127  break;
128 
129  case HCNTRL:
130  ok = 1; name = "HCNTRL";
131  if (writeflag == MEM_WRITE)
132  d->reg[relative_addr] = idata;
133  break;
134 
135  case INTSTAT:
136  ok = 1; name = "INTSTAT";
137  if (writeflag == MEM_WRITE)
138  fatal("[ ahc: write to INTSTAT? data = 0x%02x ]\n",
139  (int)idata);
140  break;
141 
142  case CLRINT:
143  if (writeflag == MEM_READ) {
144  ok = 1; name = "ERROR";
145  /* TODO */
146  } else {
147  ok = 1; name = "CLRINT";
148  if (idata & ~0xf)
149  fatal("[ ahc: write to CLRINT: 0x%02x "
150  "(TODO) ]\n", (int)idata);
151  /* Clear the lowest 4 bits of intstat: */
152  d->reg[INTSTAT] &= ~(idata & 0xf);
153  }
154  break;
155 
156  default:
157  if (writeflag == MEM_WRITE)
158  fatal("[ ahc: UNIMPLEMENTED write to address 0x%x, "
159  "data=0x%02x ]\n", (int)relative_addr, (int)idata);
160  else
161  fatal("[ ahc: UNIMPLEMENTED read from address 0x%x ]\n",
162  (int)relative_addr);
163  }
164 
165 #ifdef AHC_DEBUG
166  if (ok) {
167  if (name == NULL) {
168  if (writeflag == MEM_WRITE)
169  debug("[ ahc: write to address 0x%x: 0x"
170  "%02x ]\n", (int)relative_addr, (int)idata);
171  else
172  debug("[ ahc: read from address 0x%x: 0x"
173  "%02x ]\n", (int)relative_addr, (int)odata);
174  } else {
175  if (writeflag == MEM_WRITE)
176  debug("[ ahc: write to %s: 0x%02x ]\n",
177  name, (int)idata);
178  else
179  debug("[ ahc: read from %s: 0x%02x ]\n",
180  name, (int)odata);
181  }
182  }
183 #endif
184 
185  if (writeflag == MEM_READ)
186  memory_writemax64(cpu, data, len, odata);
187 
188  return 1;
189 }
190 
191 
193 {
194  struct ahc_data *d;
195 
196  CHECK_ALLOCATION(d = (struct ahc_data *) malloc(sizeof(struct ahc_data)));
197  memset(d, 0, sizeof(struct ahc_data));
198 
200  devinit->addr, DEV_AHC_LENGTH, dev_ahc_access, d,
201  DM_DEFAULT, NULL);
202 
203  return 1;
204 }
205 
DEVICE_ACCESS(ahc)
Definition: dev_ahc.cc:63
uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
Definition: memory.cc:55
void fatal(const char *fmt,...)
Definition: main.cc:152
#define DM_DEFAULT
Definition: memory.h:130
#define INTSTAT
Definition: aic7xxx_reg.h:1532
char * name
Definition: device.h:43
#define KERNEL_QINPOS
Definition: aic7xxx_reg.h:1374
#define MEM_READ
Definition: memory.h:116
struct memory * memory
Definition: machine.h:126
#define SEQRAM
Definition: aic7xxx_reg.h:1445
DEVINIT(ahc)
Definition: dev_ahc.cc:192
#define SEQADDR0
Definition: aic7xxx_reg.h:1447
#define SCSICONF
Definition: aic7xxx_reg.h:1417
#define SEERDY
Definition: aic7xxx_reg.h:1289
#define CHECK_ALLOCATION(ptr)
Definition: misc.h:239
#define DEV_AHC_LENGTH
Definition: dev_ahc.cc:56
#define SCSIID
Definition: aic7xxx_reg.h:1129
u_short data
Definition: siireg.h:79
#define HCNTRL
Definition: aic7xxx_reg.h:1517
#define MEM_WRITE
Definition: memory.h:117
Definition: device.h:40
#define debug
Definition: dev_adb.cc:57
Definition: cpu.h:326
struct machine * machine
Definition: device.h:41
void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data)
Definition: memory.cc:89
#define SEECTL
Definition: aic7xxx_reg.h:1285
void memory_device_register(struct memory *mem, const char *, uint64_t baseaddr, uint64_t len, int(*f)(struct cpu *, struct memory *, uint64_t, unsigned char *, size_t, int, void *), void *extra, int flags, unsigned char *dyntrans_data)
Definition: memory.cc:339
#define SEQINT
Definition: aic7xxx_reg.h:1553
#define CLRINT
Definition: aic7xxx_reg.h:1565
uint8_t byte_order
Definition: cpu.h:347
uint64_t addr
Definition: device.h:46
unsigned char reg[DEV_AHC_LENGTH]
Definition: dev_ahc.cc:59
#define SEQADDR1
Definition: aic7xxx_reg.h:1449
#define EMUL_BIG_ENDIAN
Definition: misc.h:165

Generated on Sun Sep 30 2018 16:05:18 for GXemul by doxygen 1.8.13