/[gxemul]/upstream/0.3.1/devices/dev_ssc.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.1/devices/dev_ssc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (show annotations)
Mon Oct 8 16:17:52 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 6844 byte(s)
0.3.1
1 /*
2 * Copyright (C) 2003-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: dev_ssc.c,v 1.22 2005/02/21 07:18:09 debug Exp $
29 *
30 * Serial controller on DECsystem 5400 and 5800.
31 * Known as System Support Chip on VAX 3600 (KA650).
32 *
33 * Described around page 80 in the kn210tm1.pdf.
34 */
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 #include "console.h"
41 #include "cpu.h"
42 #include "devices.h"
43 #include "machine.h"
44 #include "memory.h"
45 #include "misc.h"
46
47
48 #define RX_INT_ENABLE 0x40
49 #define RX_AVAIL 0x80
50 #define TX_INT_ENABLE 0x40
51 #define TX_READY 0x80
52
53
54 /*
55 * _TXRX is for debugging putchar/getchar. The other
56 * one is more general.
57 */
58 /* #define SSC_DEBUG_TXRX */
59 #define SSC_DEBUG
60
61 struct ssc_data {
62 int irq_nr;
63 int console_handle;
64 int use_fb;
65
66 int rx_ctl;
67 int tx_ctl;
68
69 uint32_t *csrp;
70 };
71
72
73 /*
74 * dev_ssc_tick():
75 */
76 void dev_ssc_tick(struct cpu *cpu, void *extra)
77 {
78 struct ssc_data *d = extra;
79
80 d->tx_ctl |= TX_READY; /* transmitter always ready */
81
82 d->rx_ctl &= ~RX_AVAIL;
83 if (console_charavail(d->console_handle))
84 d->rx_ctl |= RX_AVAIL;
85
86 /* rx interrupts enabled, and char avail? */
87 if (d->rx_ctl & RX_INT_ENABLE && d->rx_ctl & RX_AVAIL) {
88 /* TODO: This is for 5800 only! */
89
90 if (d->csrp != NULL) {
91 unsigned char txvector = 0xf8;
92 (*d->csrp) |= 0x10000000;
93 cpu->memory_rw(cpu, cpu->mem, 0x40000050, &txvector,
94 1, MEM_WRITE, NO_EXCEPTIONS | PHYSICAL);
95 cpu_interrupt(cpu, 2);
96 }
97 }
98
99 /* tx interrupts enabled? */
100 if (d->tx_ctl & TX_INT_ENABLE) {
101 /* TODO: This is for 5800 only! */
102
103 if (d->csrp != NULL) {
104 unsigned char txvector = 0xfc;
105 (*d->csrp) |= 0x10000000;
106 cpu->memory_rw(cpu, cpu->mem, 0x40000050, &txvector,
107 1, MEM_WRITE, NO_EXCEPTIONS | PHYSICAL);
108 cpu_interrupt(cpu, 2);
109 }
110 }
111 }
112
113
114 /*
115 * dev_ssc_access():
116 */
117 int dev_ssc_access(struct cpu *cpu, struct memory *mem,
118 uint64_t relative_addr, unsigned char *data, size_t len,
119 int writeflag, void *extra)
120 {
121 uint64_t idata = 0, odata = 0;
122 struct ssc_data *d = extra;
123
124 idata = memory_readmax64(cpu, data, len);
125
126 dev_ssc_tick(cpu, extra);
127
128 switch (relative_addr) {
129 case 0x0080: /* receive status */
130 if (writeflag==MEM_READ) {
131 odata = d->rx_ctl;
132 #ifdef SSC_DEBUG_TXRX
133 debug("[ ssc: read from 0x%08lx: 0x%02x ]\n",
134 (long)relative_addr, (int)odata);
135 #endif
136 } else {
137 d->rx_ctl = idata;
138
139 /* TODO: This only works for 5800 */
140 if (d->csrp != NULL) {
141 (*d->csrp) &= ~0x10000000;
142 cpu_interrupt_ack(cpu, 2);
143 }
144 #ifdef SSC_DEBUG_TXRX
145 debug("[ ssc: write to 0x%08lx: 0x%02x ]\n",
146 (long)relative_addr, (int)idata);
147 #endif
148 }
149
150 break;
151 case 0x0084: /* receive data */
152 if (writeflag==MEM_READ) {
153 #ifdef SSC_DEBUG_TXRX
154 debug("[ ssc: read from 0x%08lx ]\n",
155 (long)relative_addr);
156 #endif
157 if (console_charavail(d->console_handle))
158 odata = console_readchar(d->console_handle);
159 } else {
160 #ifdef SSC_DEBUG_TXRX
161 debug("[ ssc: write to 0x%08lx: 0x%02x ]\n",
162 (long)relative_addr, (int)idata);
163 #endif
164 }
165
166 break;
167 case 0x0088: /* transmit status */
168 if (writeflag==MEM_READ) {
169 odata = d->tx_ctl;
170 #ifdef SSC_DEBUG_TXRX
171 debug("[ ssc: read from 0x%08lx: 0x%04x ]\n",
172 (long)relative_addr, (int)odata);
173 #endif
174 } else {
175 d->tx_ctl = idata;
176
177 /* TODO: This only works for 5800 */
178 if (d->csrp != NULL) {
179 (*d->csrp) &= ~0x10000000;
180 cpu_interrupt_ack(cpu, 2);
181 }
182 #ifdef SSC_DEBUG_TXRX
183 debug("[ ssc: write to 0x%08lx: 0x%02x ]\n",
184 (long)relative_addr, (int)idata);
185 #endif
186 }
187
188 break;
189 case 0x008c: /* transmit data */
190 if (writeflag==MEM_READ) {
191 debug("[ ssc: read from 0x%08lx ]\n",
192 (long)relative_addr);
193 } else {
194 /* debug("[ ssc: write to 0x%08lx: 0x%02x ]\n",
195 (long)relative_addr, (int)idata); */
196 console_putchar(d->console_handle, idata);
197 }
198
199 break;
200 case 0x0100:
201 if (writeflag==MEM_READ) {
202 odata = 128;
203 #ifdef SSC_DEBUG_TXRX
204 debug("[ ssc: read from 0x%08lx: 0x%08lx ]\n",
205 (long)relative_addr, (long)odata);
206 #endif
207 } else {
208 #ifdef SSC_DEBUG_TXRX
209 debug("[ ssc: write to 0x%08lx: 0x%08x ]\n",
210 (long)relative_addr, idata);
211 #endif
212 }
213
214 break;
215 case 0x0108:
216 if (writeflag==MEM_READ) {
217 debug("[ ssc: read from 0x%08lx ]\n",
218 (long)relative_addr);
219 } else {
220 #ifdef SSC_DEBUG
221 debug("[ ssc: write to 0x%08lx: 0x%08x ]\n",
222 (long)relative_addr, (int)idata);
223 #endif
224 }
225
226 break;
227 default:
228 if (writeflag==MEM_READ) {
229 debug("[ ssc: read from 0x%08lx ]\n",
230 (long)relative_addr);
231 } else {
232 debug("[ ssc: write to 0x%08lx: 0x%08x ]\n",
233 (long)relative_addr, (int)idata);
234 }
235 }
236
237 dev_ssc_tick(cpu, extra);
238
239 if (writeflag == MEM_READ)
240 memory_writemax64(cpu, data, len, odata);
241
242 return 1;
243 }
244
245
246 /*
247 * dev_ssc_init():
248 */
249 void dev_ssc_init(struct machine *machine, struct memory *mem,
250 uint64_t baseaddr, int irq_nr, int use_fb, uint32_t *csrp)
251 {
252 struct ssc_data *d;
253
254 d = malloc(sizeof(struct ssc_data));
255 if (d == NULL) {
256 fprintf(stderr, "out of memory\n");
257 exit(1);
258 }
259 memset(d, 0, sizeof(struct ssc_data));
260 d->irq_nr = irq_nr;
261 d->use_fb = use_fb;
262 d->csrp = csrp;
263 d->console_handle = console_start_slave(machine, "SSC");
264
265 memory_device_register(mem, "ssc", baseaddr, DEV_SSC_LENGTH,
266 dev_ssc_access, d, MEM_DEFAULT, NULL);
267
268 machine_add_tickfunction(machine, dev_ssc_tick, d, 14);
269 }
270

  ViewVC Help
Powered by ViewVC 1.1.26