/[gxemul]/upstream/0.3.3.2/src/devices/dev_8259.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.3.2/src/devices/dev_8259.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9 - (show annotations)
Mon Oct 8 16:18:22 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 6096 byte(s)
0.3.3.2
1 /*
2 * Copyright (C) 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_8259.c,v 1.9 2005/06/02 17:11:35 debug Exp $
29 *
30 * 8259 Programmable Interrupt Controller.
31 *
32 * This is mostly bogus. TODO. See the following URL for more details:
33 * http://www.nondot.org/sabre/os/files/MiscHW/8259pic.txt
34 */
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 #include "cpu.h"
41 #include "device.h"
42 #include "devices.h"
43 #include "emul.h"
44 #include "machine.h"
45 #include "memory.h"
46 #include "misc.h"
47
48
49 #define DEV_8259_LENGTH 2
50
51
52 /*
53 * dev_8259_access():
54 */
55 int dev_8259_access(struct cpu *cpu, struct memory *mem,
56 uint64_t relative_addr, unsigned char *data, size_t len,
57 int writeflag, void *extra)
58 {
59 struct pic8259_data *d = (struct pic8259_data *) extra;
60 uint64_t idata = 0, odata = 0;
61
62 idata = memory_readmax64(cpu, data, len);
63
64 switch (relative_addr) {
65 case 0x00:
66 if (writeflag == MEM_WRITE) {
67 if ((idata & 0x10) == 0x10) {
68 /* Bit 3: 0=edge, 1=level */
69 if (idata & 0x08)
70 fatal("[ 8259: TODO: Level "
71 "triggered (MCA bus) ]\n");
72 if (idata & 0x04)
73 fatal("[ 8259: WARNING: Bit 2 set ]\n");
74 /* Bit 1: 0=cascade, 1=single */
75 /* Bit 0: 1=4th init byte */
76 if (!(idata & 0x01))
77 fatal("[ 8259: WARNING: Bit 0 NOT set!"
78 "!! ]\n");
79 d->init_state = 1;
80 break;
81 }
82
83 /* TODO: Is it ok to abort init state when there
84 is a non-init command? */
85 if (d->init_state)
86 fatal("[ 8259: WARNING: Was in init-state, but"
87 " it was aborted? ]\n");
88 d->init_state = 0;
89
90 switch (idata) {
91 case 0x0a:
92 d->current_command = 0x0a;
93 break;
94 case 0x0b:
95 d->current_command = 0x0b;
96 break;
97 case 0x20: /* End Of Interrupt */
98 d->irr &= ~d->isr;
99 d->isr = 0;
100 /* Recalculate interrupt assertions: */
101 cpu_interrupt(cpu, 16);
102 break;
103 case 0x60:
104 case 0x61:
105 case 0x62:
106 case 0x63:
107 case 0x64:
108 case 0x65:
109 case 0x66:
110 case 0x67: /* Specific EOI */
111 d->irr &= ~(1 << (idata & 7));
112 d->isr &= ~(1 << (idata & 7));
113 /* Recalculate interrupt assertions: */
114 cpu_interrupt(cpu, 16);
115 break;
116 case 0x68: /* Set Special Mask Mode */
117 /* TODO */
118 break;
119 case 0xc0:
120 case 0xc1:
121 case 0xc2:
122 case 0xc3:
123 case 0xc4:
124 case 0xc5:
125 case 0xc6:
126 case 0xc7: /* Set IRQ Priority Order */
127 /* TODO */
128 break;
129 default:
130 fatal("[ 8259: unimplemented command 0x%02x"
131 " ]\n", idata);
132 cpu->running = 0;
133 }
134 } else {
135 switch (d->current_command) {
136 case 0x0a:
137 odata = d->irr;
138 break;
139 case 0x0b:
140 odata = d->isr;
141 break;
142 default:
143 fatal("[ 8259: unimplemented command 0x%02x"
144 " while reading ]\n", d->current_command);
145 cpu->running = 0;
146 }
147 }
148 break;
149 case 0x01:
150 if (d->init_state > 0) {
151 if (d->init_state == 1) {
152 d->irq_base = idata & 0xf8;
153 if (idata & 7)
154 fatal("[ 8259: WARNING! Lowest"
155 " bits in Init Cmd 1 are"
156 " non-zero! ]\n");
157 d->init_state = 2;
158 } else if (d->init_state == 2) {
159 /* Slave attachment. TODO */
160 d->init_state = 3;
161 } else if (d->init_state == 3) {
162 if (idata & 0x02)
163 fatal("[ 8259: WARNING! Bit 1 i"
164 "n Init Cmd 4 is set! ]\n");
165 if (!(idata & 0x01))
166 fatal("[ 8259: WARNING! Bit 0 "
167 "in Init Cmd 4 is not"
168 " set! ]\n");
169 d->init_state = 0;
170 }
171 break;
172 }
173
174 if (writeflag == MEM_WRITE) {
175 d->ier = idata;
176 /* Recalculate interrupt assertions: */
177 cpu_interrupt(cpu, 16);
178 } else {
179 odata = d->ier;
180 }
181 break;
182 default:
183 if (writeflag == MEM_WRITE) {
184 fatal("[ 8259: unimplemented write to address 0x%x"
185 " data=0x%02x ]\n", (int)relative_addr, (int)idata);
186 cpu->running = 0;
187 } else {
188 fatal("[ 8259: unimplemented read from address 0x%x "
189 "]\n", (int)relative_addr);
190 cpu->running = 0;
191 }
192 }
193
194 if (writeflag == MEM_READ)
195 memory_writemax64(cpu, data, len, odata);
196
197 return 1;
198 }
199
200
201 /*
202 * devinit_8259():
203 */
204 int devinit_8259(struct devinit *devinit)
205 {
206 struct pic8259_data *d = malloc(sizeof(struct pic8259_data));
207 char *name2;
208 int nlen = 40;
209
210 if (d == NULL) {
211 fprintf(stderr, "out of memory\n");
212 exit(1);
213 }
214 memset(d, 0, sizeof(struct pic8259_data));
215 d->irq_nr = devinit->irq_nr;
216
217 name2 = malloc(nlen);
218 snprintf(name2, nlen, "%s", devinit->name);
219 if ((devinit->addr & 0xfff) == 0xa0)
220 strcat(name2, " [secondary]");
221
222 memory_device_register(devinit->machine->memory, name2,
223 devinit->addr, DEV_8259_LENGTH, dev_8259_access, (void *)d,
224 MEM_DEFAULT, NULL);
225
226 devinit->return_ptr = d;
227 return 1;
228 }
229

  ViewVC Help
Powered by ViewVC 1.1.26