1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #include "hw.h"
25: #include "sun4m.h"
26:
27:
28:
29:
30:
31:
32:
33: #define CS_MAXADDR 0x3f
34: #define CS_SIZE (CS_MAXADDR + 1)
35: #define CS_REGS 16
36: #define CS_DREGS 32
37: #define CS_MAXDREG (CS_DREGS - 1)
38:
39: typedef struct CSState {
40: uint32_t regs[CS_REGS];
41: uint8_t dregs[CS_DREGS];
42: void *intctl;
43: } CSState;
44:
45: #define CS_RAP(s) ((s)->regs[0] & CS_MAXDREG)
46: #define CS_VER 0xa0
47: #define CS_CDC_VER 0x8a
48:
49: #ifdef DEBUG_CS
50: #define DPRINTF(fmt, args...) \
51: do { printf("CS: " fmt , ##args); } while (0)
52: #else
53: #define DPRINTF(fmt, args...)
54: #endif
55:
56: static void cs_reset(void *opaque)
57: {
58: CSState *s = opaque;
59:
60: memset(s->regs, 0, CS_REGS * 4);
61: memset(s->dregs, 0, CS_DREGS);
62: s->dregs[12] = CS_CDC_VER;
63: s->dregs[25] = CS_VER;
64: }
65:
66: static uint32_t cs_mem_readl(void *opaque, target_phys_addr_t addr)
67: {
68: CSState *s = opaque;
69: uint32_t saddr, ret;
70:
71: saddr = (addr & CS_MAXADDR) >> 2;
72: switch (saddr) {
73: case 1:
74: switch (CS_RAP(s)) {
75: case 3:
76: ret = 0;
77: break;
78: default:
79: ret = s->dregs[CS_RAP(s)];
80: break;
81: }
82: DPRINTF("read dreg[%d]: 0x%8.8x\n", CS_RAP(s), ret);
83: break;
84: default:
85: ret = s->regs[saddr];
86: DPRINTF("read reg[%d]: 0x%8.8x\n", saddr, ret);
87: break;
88: }
89: return ret;
90: }
91:
92: static void cs_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
93: {
94: CSState *s = opaque;
95: uint32_t saddr;
96:
97: saddr = (addr & CS_MAXADDR) >> 2;
98: DPRINTF("write reg[%d]: 0x%8.8x -> 0x%8.8x\n", saddr, s->regs[saddr], val);
99: switch (saddr) {
100: case 1:
101: DPRINTF("write dreg[%d]: 0x%2.2x -> 0x%2.2x\n", CS_RAP(s), s->dregs[CS_RAP(s)], val);
102: switch(CS_RAP(s)) {
103: case 11:
104: case 25:
105: break;
106: case 12:
107: val &= 0x40;
108: val |= CS_CDC_VER;
109: s->dregs[CS_RAP(s)] = val;
110: break;
111: default:
112: s->dregs[CS_RAP(s)] = val;
113: break;
114: }
115: break;
116: case 2:
117: break;
118: case 4:
119: if (val & 1)
120: cs_reset(s);
121: val &= 0x7f;
122: s->regs[saddr] = val;
123: break;
124: default:
125: s->regs[saddr] = val;
126: break;
127: }
128: }
129:
130: static CPUReadMemoryFunc *cs_mem_read[3] = {
131: cs_mem_readl,
132: cs_mem_readl,
133: cs_mem_readl,
134: };
135:
136: static CPUWriteMemoryFunc *cs_mem_write[3] = {
137: cs_mem_writel,
138: cs_mem_writel,
139: cs_mem_writel,
140: };
141:
142: static void cs_save(QEMUFile *f, void *opaque)
143: {
144: CSState *s = opaque;
145: unsigned int i;
146:
147: for (i = 0; i < CS_REGS; i++)
148: qemu_put_be32s(f, &s->regs[i]);
149:
150: qemu_put_buffer(f, s->dregs, CS_DREGS);
151: }
152:
153: static int cs_load(QEMUFile *f, void *opaque, int version_id)
154: {
155: CSState *s = opaque;
156: unsigned int i;
157:
158: if (version_id > 1)
159: return -EINVAL;
160:
161: for (i = 0; i < CS_REGS; i++)
162: qemu_get_be32s(f, &s->regs[i]);
163:
164: qemu_get_buffer(f, s->dregs, CS_DREGS);
165: return 0;
166: }
167:
168: void cs_init(target_phys_addr_t base, int irq, void *intctl)
169: {
170: int cs_io_memory;
171: CSState *s;
172:
173: s = qemu_mallocz(sizeof(CSState));
174: if (!s)
175: return;
176:
177: cs_io_memory = cpu_register_io_memory(0, cs_mem_read, cs_mem_write, s);
178: cpu_register_physical_memory(base, CS_SIZE, cs_io_memory);
179: register_savevm("cs4231", base, 1, cs_save, cs_load, s);
180: qemu_register_reset(cs_reset, s);
181: cs_reset(s);
182: }