remove dead code and change debug output from file to console
[qemu/qemu-loongson.git] / hw / sm502.c
blobb277bb108b40a74196f49914ff177778f6daed1f
1 /*
2 * QEMU sm502 emulation
4 * Copyright (c) 2009 yajin <yajin@vm-kernel.org>
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
25 /*sm502 is used in gdium system.*/
27 #include <stdio.h>
28 #include <assert.h>
29 #include "hw.h"
30 #include "pc.h"
31 #include "pci.h"
32 #include "console.h"
33 #include "devices.h"
34 #include "sm502.h"
36 #define DEBUG
37 #define DEBUG_PCICONF (1<<0x0)
38 #define DEBUG_CONF (1<<0x1)
39 #define DEBUG_GPIO (1<<0x2)
41 #define DEBUG_ALL (0xffffffff)
42 #define DEBUG_FLAG DEBUG_ALL
44 #ifdef DEBUG
45 #define debug_out(flag,out) {\
46 if (flag & DEBUG_FLAG) printf out; \
47 } while(0);
48 #else
49 #define debug_out(flag,out)
50 #endif
51 #if 0
52 static uint32_t sm502_badwidth_read8(void *opaque, target_phys_addr_t addr)
54 SM502_8B_REG(addr);
55 /*to make debug easy */
56 exit(-1);
57 return 0;
60 static void sm502_badwidth_write8(void *opaque, target_phys_addr_t addr,
61 uint32_t value)
63 SM502_8B_REG(addr);
64 exit(-1);
67 static uint32_t sm502_badwidth_read16(void *opaque, target_phys_addr_t addr)
69 SM502_16B_REG(addr);
70 /*to make debug easy */
71 exit(-1);
72 return 0;
74 static void sm502_badwidth_write16(void *opaque, target_phys_addr_t addr,
75 uint32_t value)
77 SM502_16B_REG(addr);
78 exit(-1);
80 #endif
81 static uint32_t sm502_badwidth_read32(void *opaque, target_phys_addr_t addr)
83 SM502_32B_REG(addr);
84 /*to make debug easy */
85 exit(-1);
86 return 0;
88 static void sm502_badwidth_write32(void *opaque, target_phys_addr_t addr,
89 uint32_t value)
91 SM502_32B_REG(addr);
92 exit(-1);
95 void sm502_gpio_out_set(struct sm502_s *s, int line, qemu_irq handler)
97 if (line >= 64 || line < 0)
98 cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
99 s->out_handler[line & 63] = handler;
102 qemu_irq *sm502_gpio_in_get(struct sm502_s *s, int line)
104 if (line >= 64 || line < 0)
105 cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
106 return s->in_handler + (line & 31);
109 void sm502_gpio_set_pin(struct sm502_s *s, int line, int level)
111 if (line >= 64 || line < 0)
112 cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
113 if (level)
115 if (line < 32)
116 s->gpio_data_low |= level << line;
117 else
118 s->gpio_data_high |= level << (line - 32);
120 else
122 if (line < 32)
123 s->gpio_data_low &= (~(1 << line));
124 else
125 s->gpio_data_high &= (~(1 << (line - 32)));
129 int sm502_gpio_get_pin(struct sm502_s *s, int line)
131 if (line >= 64 || line < 0)
132 cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
133 if (line < 32)
134 return (s->gpio_data_low & (1 << line)) >> line;
135 else
136 return (s->gpio_data_high & (1 << line)) >> line;
139 static void sm502_gpio_set(void *opaque, int line, int level)
141 struct sm502_s *s = (struct sm502_s *) opaque;
142 if (line >= 64 || line < 0)
143 cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
144 sm502_gpio_set_pin(s, line, level);
147 static void sm502_gpio_init(struct sm502_s *s)
149 s->in_handler = qemu_allocate_irqs(sm502_gpio_set, s, 64);
152 static uint32_t sm502_read32(void *opaque, target_phys_addr_t addr)
154 struct sm502_s *s = (struct sm502_s *) opaque;
156 debug_out(DEBUG_CONF,
157 ("%s addr " TARGET_FMT_plx " pc " TARGET_FMT_plx "\n",
158 __FUNCTION__, addr, cpu_single_env->active_tc.PC));
160 switch (addr)
162 case 0x0:
163 return s->system_control;
164 case 0x4:
165 return s->misc_control;
166 case 0x08:
167 return s->gpio_low32;
168 case 0x0c:
169 return s->gpio_high32;
170 case 0x10:
171 return s->dram_control;
172 case 0x14:
173 return s->arb_control;
174 case 0x24:
175 return s->command_list_status;
176 case 0x28:
177 return s->raw_int_status;
178 case 0x2c:
179 return s->int_status;
180 case 0x30:
181 return s->int_mask;
182 case 0x34:
183 return s->debug_control;
184 case 0x38:
185 return s->current_gate;
186 case 0x3c:
187 return s->current_clock;
188 case 0x40:
189 return s->power0_gate;
190 case 0x44:
191 return s->power0_clock;
192 case 0x48:
193 return s->power1_gate;
194 case 0x4c:
195 return s->power1_clock;
196 case 0x50:
197 return s->sleep_gate;
198 case 0x54:
199 return s->power_control;
200 case 0x58:
201 return s->pci_master_base;
202 case 0x5c:
203 return s->endian_control;
204 case 0x60:
205 return s->device_id;
206 case 0x64:
207 return s->pll_clock_count;
208 case 0x68:
209 return s->misc_timing;
210 case 0x6c:
211 return s->current_sdram_clock;
212 case 0x70:
213 return s->non_cache_address;
214 case 0x74:
215 return s->pll_control;
216 case 0x10000:
217 return s->gpio_data_low;
218 case 0x10004:
219 return s->gpio_data_high;
220 case 0x10008:
221 return s->gpio_datadir_low;
222 case 0x1000c:
223 return s->gpio_datadir_high;
224 case 0x10010:
225 return s->gpio_int_setup;
226 case 0x10014:
227 return s->gpio_int_status;
228 default:
229 cpu_abort(cpu_single_env,
230 "%s undefined addr " TARGET_FMT_plx
231 " pc " TARGET_FMT_plx "\n", __FUNCTION__, addr,
232 cpu_single_env->active_tc.PC);
238 static void sm502_write32(void *opaque, target_phys_addr_t addr, uint32_t value)
240 struct sm502_s *s = (struct sm502_s *) opaque;
241 uint32_t diff;
242 int ln;
244 debug_out(DEBUG_CONF,
245 ("%s addr " TARGET_FMT_plx " value %x pc " TARGET_FMT_plx "\n",
246 __FUNCTION__, addr, value, cpu_single_env->active_tc.PC));
249 switch (addr)
251 case 0x24:
252 case 0x38:
253 case 0x3c:
254 case 0x60:
255 case 0x64:
256 case 0x6c:
257 SM502_RO_REG(addr);
258 break;
259 case 0x0:
260 s->system_control = value & 0xff00b8f7;
261 break;
262 case 0x4:
263 s->misc_control = value & 0xff7fff10;
264 break;
265 case 0x08:
266 s->gpio_low32 = value;
267 break;
268 case 0x0c:
269 s->gpio_high32 = value;
270 break;
271 case 0x10:
272 s->dram_control = value & 0x7fffffc3;
273 break;
274 case 0x14:
275 s->arb_control = value & 0x77777777;
276 break;
277 case 0x28:
278 s->raw_int_status &= (~(value & 0x7f));
279 break;
280 case 0x2c:
281 s->int_status = value & 0x400000;
282 break;
283 case 0x30:
284 s->int_mask = value & 0xffdf3f5f;
285 break;
286 case 0x34:
287 s->debug_control = value & 0xff;
288 break;
289 case 0x40:
290 s->power0_gate = value & 0x71dff;
291 break;
292 case 0x44:
293 s->power0_clock = value & 0xff3f1f1f;
294 break;
295 case 0x48:
296 s->power1_gate = value & 0x61dff;
297 break;
298 case 0x4c:
299 s->power1_clock = value & 0xff3f1f1f;
300 break;
301 case 0x50:
302 s->sleep_gate = value & 0x786000;
303 break;
304 case 0x54:
305 s->power_control = value & 0x7;
306 break;
307 case 0x58:
308 s->pci_master_base = value & 0xfff00000;
309 break;
310 case 0x5c:
311 s->endian_control = value & 0x1;
312 break;
313 case 0x68:
314 s->misc_timing = value & 0xf1f1f4f;
315 break;
316 case 0x70:
317 s->non_cache_address = value & 0x3fff;
318 break;
319 case 0x74:
320 s->pll_control = value & 0x1fffff;
321 break;
322 case 0x10000:
323 diff = (s->gpio_data_low ^ value) & s->gpio_datadir_low;
324 s->gpio_data_low = value;
325 while ((ln = ffs(diff)))
327 ln--;
328 if (s->out_handler[ln])
329 qemu_set_irq(s->out_handler[ln], (value >> ln) & 1);
330 diff &= ~(1 << ln);
332 break;
333 case 0x10004:
334 diff = (s->gpio_datadir_high ^ value) & s->gpio_datadir_high;
335 s->gpio_data_high = value;
336 while ((ln = ffs(diff)))
338 ln--;
339 if (s->out_handler[ln + 32])
340 qemu_set_irq(s->out_handler[ln + 32], (value >> ln) & 1);
341 diff &= ~(1 << ln);
343 break;
344 case 0x10008:
345 s->gpio_datadir_low = value;
346 break;
347 case 0x1000c:
348 s->gpio_datadir_high = value;
349 break;
350 case 0x10010:
351 s->gpio_int_setup = value & 0x7f7f7f;
352 break;
353 case 0x10014:
354 s->gpio_int_status &= (~(value & 0x7f0000));
355 break;
356 default:
357 cpu_abort(cpu_single_env,
358 "%s undefined addr " TARGET_FMT_plx
359 " value %x pc " TARGET_FMT_plx "\n", __FUNCTION__, addr,
360 value, cpu_single_env->active_tc.PC);
368 static CPUReadMemoryFunc *sm502_readfn[] = {
369 sm502_badwidth_read32,
370 sm502_badwidth_read32,
371 sm502_read32,
374 static CPUWriteMemoryFunc *sm502_writefn[] = {
375 sm502_badwidth_write32,
376 sm502_badwidth_write32,
377 sm502_write32,
380 static uint32_t sm502_read_config(PCIDevice * d, uint32_t address, int len)
382 uint32_t val = 0;
384 debug_out(DEBUG_PCICONF, ("%s addr 0x%x len %x pc " TARGET_FMT_plx "\n",
385 __FUNCTION__, address, len,
386 cpu_single_env->active_tc.PC));
388 switch (len)
390 default:
391 case 4:
392 if (address <= 0xfc)
393 val = le32_to_cpu(*(uint32_t *) (d->config + address));
394 break;
396 case 2:
397 if (address <= 0xfe)
398 val = le16_to_cpu(*(uint16_t *) (d->config + address));
399 break;
400 case 1:
401 val = d->config[address];
402 break;
404 return val;
408 static void sm502_write_config(PCIDevice * d, uint32_t address, uint32_t val,
409 int len)
411 int can_write, i;
412 uint32_t addr;
413 uint32_t new_sm502_mm_io;
414 int iomemtype;
416 struct sm502_s *s = (struct sm502_s *) d;
418 debug_out(DEBUG_PCICONF,
419 ("%s addr 0x%x value %x len %x pc " TARGET_FMT_plx "\n",
420 __FUNCTION__, address, val, len, cpu_single_env->active_tc.PC));
422 /* not efficient, but simple */
423 addr = address;
424 for (i = 0; i < len; i++)
426 /* default read/write accesses */
427 switch (addr)
429 case 0x00:
430 case 0x01:
431 case 0x02:
432 case 0x03:
433 case 0x08:
434 case 0x09:
435 case 0x0a:
436 case 0x0b:
437 case 0x0c:
438 case 0x0d:
439 case 0x2c:
440 case 0x2d:
441 case 0x2e:
442 case 0x2f:
443 case 0x34:
444 case 0x35:
445 case 0x36:
446 case 0x37:
447 case 0x40:
448 case 0x41:
449 case 0x42:
450 case 0x43:
451 can_write = 0;
452 break;
453 case 0x04:
454 case 0x05:
455 case 0x06:
456 case 0x07:
457 case 0x10:
458 case 0x11:
459 case 0x12:
460 case 0x13:
461 case 0x14:
462 case 0x15:
463 case 0x16:
464 case 0x17:
465 case 0x30:
466 case 0x31:
467 case 0x32:
468 case 0x33:
469 case 0x3c:
470 case 0x3d:
471 case 0x3e:
472 case 0x3f:
473 case 0x44:
474 case 0x45:
475 case 0x46:
476 case 0x47:
477 can_write = 1;
478 break;
479 default:
480 /*reserved */
481 can_write = 2;
482 break;
484 if (can_write == 1)
486 d->config[addr] = (val & 0xff);
487 if (addr == (0x14 + len - 1))
489 /*write the last byte of mmio */
490 new_sm502_mm_io = le32_to_cpu(*(uint32_t *) (d->config + 0x14));
491 if (s->sm502_mm_io != new_sm502_mm_io)
493 /*remapped the Control register to CPU memory space */
494 iomemtype =
495 cpu_register_io_memory(0, sm502_readfn,
496 sm502_writefn, s);
497 cpu_register_physical_memory(new_sm502_mm_io +
498 s->pci_mem_base, 0x200000,
499 iomemtype);
500 printf("new_sm502_mm_io %x pci_mem _base %llx\n",
501 new_sm502_mm_io, s->pci_mem_base);
502 if (s->sm502_mm_io != 0)
503 cpu_register_physical_memory(s->sm502_mm_io +
504 pci_mem_base, 0x200000,
505 IO_MEM_UNASSIGNED);
506 s->sm502_mm_io = new_sm502_mm_io;
510 else if (can_write == 0)
512 fprintf(stderr,
513 "warnning. %s :write to read only pci conf register addr %x\n",
514 __FUNCTION__, addr);
516 else if (can_write == 2)
518 fprintf(stderr,
519 "warnning. %s :write to reserved pci conf register addr %x\n",
520 __FUNCTION__, addr);
522 if (++addr > 0xff)
523 break;
524 val >>= 8;
528 static void sm502_reset(struct sm502_s *s)
530 s->config[0] = 0x6F;
531 s->config[1] = 0x12;
532 s->config[2] = 0x01;
533 s->config[3] = 0x05;
534 s->config[6] = 0x30;
535 s->config[7] = 0x02;
536 s->config[10] = 0x30;
537 s->config[11] = 0x02;
538 s->config[0x34] = 0x40;
539 s->config[0x40] = 0x01;
540 s->config[0x42] = 0x01;
541 s->config[0x43] = 0x06;
543 s->arb_control = 0x05146732;
544 s->current_gate = 0x00021807;
545 s->current_clock = 0x2a1a0a09;
546 s->power0_gate = 0x00021807;
547 s->power0_clock = 0x2a1a0a09;
548 s->power1_gate = 0x00021807;
549 s->power1_clock = 0x2a1a0a09;
550 s->sleep_gate = 0x00018000;
551 s->endian_control = 0x1;
552 s->device_id = 0x050100a0;
553 s->non_cache_address = 0x0000ffff;
554 s->pll_control = 0x0000ffff;
558 struct sm502_s *sm502_init(PCIBus * bus, int devfn,
559 target_phys_addr_t pci_mem_base)
561 struct sm502_s *s = (struct sm502_s *) qemu_mallocz(sizeof(*s));
563 s = (struct sm502_s *) pci_register_device(bus, "SM502 PCI",
564 sizeof(struct sm502_s), devfn,
565 sm502_read_config,
566 sm502_write_config);
567 s->pci_mem_base = pci_mem_base;
569 sm502_gpio_init(s);
571 sm502_reset(s);
573 return s;