dev_ahc.cc Source File

Back to the index.

dev_ahc.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004-2018 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  *
32  * ahc0 at pci0 dev 1 function 0: Adaptec aic7880 Ultra SCSI adapter
33  * ahc0: interrupting at crime interrupt 8
34  * ahc0: Using left over BIOS settings
35  * ahc0: Host Adapter has no SEEPROM. Using default SCSI target parameters
36  * ahc0: aic7880: Ultra Wide Channel A, SCSI Id=0, 16/253 SCBs
37  * scsibus0 at ahc0: 16 targets, 8 luns per target
38  *
39  * TODO: This is just a dummy device, so far.
40  */
41 
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 
46 #include "cpu.h"
47 #include "device.h"
48 #include "machine.h"
49 #include "memory.h"
50 #include "misc.h"
51 
52 #include "thirdparty/aic7xxx_reg.h"
53 
54 
55 #define AHC_DEBUG
56 #define debug fatal
57 
58 
59 #define DEV_AHC_LENGTH 0x100
60 
61 struct ahc_data {
62  unsigned char reg[DEV_AHC_LENGTH];
63 };
64 
65 
67 {
68  struct ahc_data *d = (struct ahc_data *) extra;
69  uint64_t idata, odata = 0;
70  int ok = 0;
71  const char *name = NULL;
72 
73  idata = memory_readmax64(cpu, data, len);
74 
75  /* SGI uses weird reversed order addresses: */
77  relative_addr ^= 3;
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 
data
u_short data
Definition: siireg.h:79
debug
#define debug
Definition: dev_ahc.cc:56
HCNTRL
#define HCNTRL
Definition: aic7xxx_reg.h:1517
devinit::addr
uint64_t addr
Definition: device.h:46
ahc_data::reg
unsigned char reg[DEV_AHC_LENGTH]
Definition: dev_ahc.cc:62
memory_device_register
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
SEQRAM
#define SEQRAM
Definition: aic7xxx_reg.h:1445
ahc_data
Definition: dev_ahc.cc:61
MEM_READ
#define MEM_READ
Definition: memory.h:116
cpu::byte_order
uint8_t byte_order
Definition: cpu.h:347
EMUL_BIG_ENDIAN
#define EMUL_BIG_ENDIAN
Definition: misc.h:165
DM_DEFAULT
#define DM_DEFAULT
Definition: memory.h:130
devinit::machine
struct machine * machine
Definition: device.h:41
device.h
MEM_WRITE
#define MEM_WRITE
Definition: memory.h:117
SEQADDR1
#define SEQADDR1
Definition: aic7xxx_reg.h:1449
SEECTL
#define SEECTL
Definition: aic7xxx_reg.h:1285
KERNEL_QINPOS
#define KERNEL_QINPOS
Definition: aic7xxx_reg.h:1374
SCSICONF
#define SCSICONF
Definition: aic7xxx_reg.h:1417
fatal
void fatal(const char *fmt,...)
Definition: main.cc:152
SEQINT
#define SEQINT
Definition: aic7xxx_reg.h:1553
SCSIID
#define SCSIID
Definition: aic7xxx_reg.h:1129
INTSTAT
#define INTSTAT
Definition: aic7xxx_reg.h:1532
misc.h
memory_readmax64
uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
Definition: memory.cc:55
aic7xxx_reg.h
machine.h
SEERDY
#define SEERDY
Definition: aic7xxx_reg.h:1289
devinit::name
char * name
Definition: device.h:43
devinit
Definition: device.h:40
cpu.h
machine::memory
struct memory * memory
Definition: machine.h:126
CLRINT
#define CLRINT
Definition: aic7xxx_reg.h:1565
SEQADDR0
#define SEQADDR0
Definition: aic7xxx_reg.h:1447
DEVICE_ACCESS
DEVICE_ACCESS(ahc)
Definition: dev_ahc.cc:66
DEV_AHC_LENGTH
#define DEV_AHC_LENGTH
Definition: dev_ahc.cc:59
memory_writemax64
void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data)
Definition: memory.cc:89
cpu
Definition: cpu.h:326
memory.h
DEVINIT
DEVINIT(ahc)
Definition: dev_ahc.cc:192
CHECK_ALLOCATION
#define CHECK_ALLOCATION(ptr)
Definition: misc.h:239

Generated on Tue Aug 25 2020 19:25:06 for GXemul by doxygen 1.8.18