1. fix the bug of sm502 pci configuration r/w
[qemu/qemu-loongson.git] / hw / sm502.c
blobd1587516add03b4ad4854f8afed03a33217a4b14
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)
40 #define DEBUG_MMIO (1<<0x3)
42 #define DEBUG_ALL (0xffffffff)
43 #define DEBUG_FLAG DEBUG_MMIO
45 #ifdef DEBUG
46 #define debug_out(flag,out) {\
47 if (flag & DEBUG_FLAG) printf out; \
48 } while(0);
49 #else
50 #define debug_out(flag,out)
51 #endif
53 //#define PRINT_WARNNING
55 #if 0
56 static uint32_t sm502_badwidth_read8(void *opaque, target_phys_addr_t addr)
58 SM502_8B_REG(addr);
59 /*to make debug easy */
60 exit(-1);
61 return 0;
64 static void sm502_badwidth_write8(void *opaque, target_phys_addr_t addr,
65 uint32_t value)
67 SM502_8B_REG(addr);
68 exit(-1);
71 static uint32_t sm502_badwidth_read16(void *opaque, target_phys_addr_t addr)
73 SM502_16B_REG(addr);
74 /*to make debug easy */
75 exit(-1);
76 return 0;
78 static void sm502_badwidth_write16(void *opaque, target_phys_addr_t addr,
79 uint32_t value)
81 SM502_16B_REG(addr);
82 exit(-1);
84 #endif
85 static uint32_t sm502_badwidth_read32(void *opaque, target_phys_addr_t addr)
87 SM502_32B_REG(addr);
88 /*to make debug easy */
89 exit(-1);
90 return 0;
92 static void sm502_badwidth_write32(void *opaque, target_phys_addr_t addr,
93 uint32_t value)
95 SM502_32B_REG(addr);
96 exit(-1);
99 void sm502_gpio_out_set(struct sm502_s *s, int line, qemu_irq handler)
101 if (line >= 64 || line < 0)
102 cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
103 s->out_handler[line & 63] = handler;
106 qemu_irq *sm502_gpio_in_get(struct sm502_s *s, int line)
108 if (line >= 64 || line < 0)
109 cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
110 return s->in_handler + (line & 31);
113 void sm502_gpio_set_pin(struct sm502_s *s, int line, int level)
115 if (line >= 64 || line < 0)
116 cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
117 if (level)
119 if (line < 32)
120 s->gpio_data_low |= level << line;
121 else
122 s->gpio_data_high |= level << (line - 32);
124 else
126 if (line < 32)
127 s->gpio_data_low &= (~(1 << line));
128 else
129 s->gpio_data_high &= (~(1 << (line - 32)));
133 int sm502_gpio_get_pin(struct sm502_s *s, int line)
135 if (line >= 64 || line < 0)
136 cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
137 if (line < 32)
138 return (s->gpio_data_low & (1 << line)) >> line;
139 else
140 return (s->gpio_data_high & (1 << line)) >> line;
143 static void sm502_gpio_set(void *opaque, int line, int level)
145 struct sm502_s *s = (struct sm502_s *) opaque;
146 if (line >= 64 || line < 0)
147 cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
148 sm502_gpio_set_pin(s, line, level);
151 static void sm502_gpio_init(struct sm502_s *s)
153 s->in_handler = qemu_allocate_irqs(sm502_gpio_set, s, 64);
156 static uint32_t sm502_read32(void *opaque, target_phys_addr_t addr)
158 struct sm502_s *s = (struct sm502_s *) opaque;
160 debug_out(DEBUG_CONF,
161 ("%s addr " TARGET_FMT_plx " pc " TARGET_FMT_plx "\n",
162 __FUNCTION__, addr, cpu_single_env->active_tc.PC));
164 switch (addr)
166 case 0x0:
167 return s->system_control;
168 case 0x4:
169 return s->misc_control;
170 case 0x08:
171 return s->gpio_low32;
172 case 0x0c:
173 return s->gpio_high32;
174 case 0x10:
175 return s->dram_control;
176 case 0x14:
177 return s->arb_control;
178 case 0x24:
179 return s->command_list_status;
180 case 0x28:
181 return s->raw_int_status;
182 case 0x2c:
183 return s->int_status;
184 case 0x30:
185 return s->int_mask;
186 case 0x34:
187 return s->debug_control;
188 case 0x38:
189 return s->current_gate;
190 case 0x3c:
191 return s->current_clock;
192 case 0x40:
193 return s->power0_gate;
194 case 0x44:
195 return s->power0_clock;
196 case 0x48:
197 return s->power1_gate;
198 case 0x4c:
199 return s->power1_clock;
200 case 0x50:
201 return s->sleep_gate;
202 case 0x54:
203 return s->power_control;
204 case 0x58:
205 return s->pci_master_base;
206 case 0x5c:
207 return s->endian_control;
208 case 0x60:
209 return s->device_id;
210 case 0x64:
211 return s->pll_clock_count;
212 case 0x68:
213 return s->misc_timing;
214 case 0x6c:
215 return s->current_sdram_clock;
216 case 0x70:
217 return s->non_cache_address;
218 case 0x74:
219 return s->pll_control;
220 case 0x10000:
221 return s->gpio_data_low;
222 case 0x10004:
223 return s->gpio_data_high;
224 case 0x10008:
225 return s->gpio_datadir_low;
226 case 0x1000c:
227 return s->gpio_datadir_high;
228 case 0x10010:
229 return s->gpio_int_setup;
230 case 0x10014:
231 return s->gpio_int_status;
232 default:
233 cpu_abort(cpu_single_env,
234 "%s undefined addr " TARGET_FMT_plx
235 " pc " TARGET_FMT_plx "\n", __FUNCTION__, addr,
236 cpu_single_env->active_tc.PC);
242 static void sm502_write32(void *opaque, target_phys_addr_t addr, uint32_t value)
244 struct sm502_s *s = (struct sm502_s *) opaque;
245 uint32_t diff;
246 int ln;
248 debug_out(DEBUG_CONF,
249 ("%s addr " TARGET_FMT_plx " value %x pc " TARGET_FMT_plx "\n",
250 __FUNCTION__, addr, value, cpu_single_env->active_tc.PC));
253 switch (addr)
255 case 0x24:
256 case 0x38:
257 case 0x3c:
258 case 0x60:
259 case 0x64:
260 case 0x6c:
261 SM502_RO_REG(addr);
262 break;
263 case 0x0:
264 s->system_control = value & 0xff00b8f7;
265 break;
266 case 0x4:
267 s->misc_control = value & 0xff7fff10;
268 break;
269 case 0x08:
270 s->gpio_low32 = value;
271 break;
272 case 0x0c:
273 s->gpio_high32 = value;
274 break;
275 case 0x10:
276 s->dram_control = value & 0x7fffffc3;
277 break;
278 case 0x14:
279 s->arb_control = value & 0x77777777;
280 break;
281 case 0x28:
282 s->raw_int_status &= (~(value & 0x7f));
283 break;
284 case 0x2c:
285 s->int_status = value & 0x400000;
286 break;
287 case 0x30:
288 s->int_mask = value & 0xffdf3f5f;
289 break;
290 case 0x34:
291 s->debug_control = value & 0xff;
292 break;
293 case 0x40:
294 s->power0_gate = value & 0x71dff;
295 break;
296 case 0x44:
297 s->power0_clock = value & 0xff3f1f1f;
298 break;
299 case 0x48:
300 s->power1_gate = value & 0x61dff;
301 break;
302 case 0x4c:
303 s->power1_clock = value & 0xff3f1f1f;
304 break;
305 case 0x50:
306 s->sleep_gate = value & 0x786000;
307 break;
308 case 0x54:
309 s->power_control = value & 0x7;
310 break;
311 case 0x58:
312 s->pci_master_base = value & 0xfff00000;
313 break;
314 case 0x5c:
315 s->endian_control = value & 0x1;
316 break;
317 case 0x68:
318 s->misc_timing = value & 0xf1f1f4f;
319 break;
320 case 0x70:
321 s->non_cache_address = value & 0x3fff;
322 break;
323 case 0x74:
324 s->pll_control = value & 0x1fffff;
325 break;
326 case 0x10000:
327 diff = (s->gpio_data_low ^ value) & s->gpio_datadir_low;
328 s->gpio_data_low = value;
329 while ((ln = ffs(diff)))
331 ln--;
332 if (s->out_handler[ln])
333 qemu_set_irq(s->out_handler[ln], (value >> ln) & 1);
334 diff &= ~(1 << ln);
336 break;
337 case 0x10004:
338 diff = (s->gpio_datadir_high ^ value) & s->gpio_datadir_high;
339 s->gpio_data_high = value;
340 while ((ln = ffs(diff)))
342 ln--;
343 if (s->out_handler[ln + 32])
344 qemu_set_irq(s->out_handler[ln + 32], (value >> ln) & 1);
345 diff &= ~(1 << ln);
347 break;
348 case 0x10008:
349 s->gpio_datadir_low = value;
350 break;
351 case 0x1000c:
352 s->gpio_datadir_high = value;
353 break;
354 case 0x10010:
355 s->gpio_int_setup = value & 0x7f7f7f;
356 break;
357 case 0x10014:
358 s->gpio_int_status &= (~(value & 0x7f0000));
359 break;
360 default:
361 cpu_abort(cpu_single_env,
362 "%s undefined addr " TARGET_FMT_plx
363 " value %x pc " TARGET_FMT_plx "\n", __FUNCTION__, addr,
364 value, cpu_single_env->active_tc.PC);
372 static CPUReadMemoryFunc *sm502_readfn[] = {
373 sm502_badwidth_read32,
374 sm502_badwidth_read32,
375 sm502_read32,
378 static CPUWriteMemoryFunc *sm502_writefn[] = {
379 sm502_badwidth_write32,
380 sm502_badwidth_write32,
381 sm502_write32,
384 static uint32_t sm502_read_config(PCIDevice * d, uint32_t address, int len)
386 uint32_t val = 0;
388 debug_out(DEBUG_PCICONF, ("%s addr 0x%x len %x pc " TARGET_FMT_plx "\n",
389 __FUNCTION__, address, len,
390 cpu_single_env->active_tc.PC));
392 switch (len)
394 default:
395 case 4:
396 if (address <= 0xfc)
397 val = le32_to_cpu(*(uint32_t *) (d->config + address));
398 break;
400 case 2:
401 if (address <= 0xfe)
402 val = le16_to_cpu(*(uint16_t *) (d->config + address));
403 break;
404 case 1:
405 val = d->config[address];
406 break;
408 return val;
412 static void sm502_write_config(PCIDevice * d, uint32_t address, uint32_t val,
413 int len)
415 int can_write, i;
416 uint32_t addr;
417 uint32_t new_sm502_mm_io;
418 uint8_t write_mask;
420 struct sm502_s *s = (struct sm502_s *) d;
422 debug_out(DEBUG_PCICONF,
423 ("%s addr 0x%x value %x len %x pc " TARGET_FMT_plx "\n",
424 __FUNCTION__, address, val, len, cpu_single_env->active_tc.PC));
426 /* not efficient, but simple */
427 addr = address;
428 can_write = 1;
429 write_mask = 0xff;
430 for (i = 0; i < len; i++)
432 /* default read/write accesses */
433 switch (addr)
435 case 0x00:
436 case 0x01:
437 case 0x02:
438 case 0x03:
439 case 0x08:
440 case 0x09:
441 case 0x0a:
442 case 0x0b:
443 case 0x0c:
444 case 0x0d:
445 case 0x2c:
446 case 0x2d:
447 case 0x2e:
448 case 0x2f:
449 case 0x34:
450 case 0x35:
451 case 0x36:
452 case 0x37:
453 case 0x40:
454 case 0x41:
455 case 0x42:
456 case 0x43:
457 can_write = 0;
458 break;
460 case 0x05:
461 case 0x06:
462 case 0x07:
463 case 0x10:
464 case 0x11:
465 case 0x12: /*[23:21] of reg10 -> 0x0? */
466 case 0x14:
467 case 0x15:
468 case 0x31:
469 case 0x3d:
470 case 0x3e:
471 case 0x3f:
472 case 0x46:
473 case 0x47:
474 write_mask = 0;
475 break;
476 case 0x04:
477 write_mask = 0x36;
478 break;
479 case 0x13:
480 write_mask = 0xfe;
481 break;
482 case 0x16:
483 write_mask = 0xe0;
484 break;
485 case 0x17:
486 write_mask = 0xff;
487 break;
488 case 0x30:
489 if (d->config[4] & 0x2)
490 write_mask = 0x1;
491 else
492 write_mask = 0x0;
493 break;
494 case 0x32:
495 case 0x33:
496 if (d->config[4] & 0x2)
497 write_mask = 0xff;
498 else
499 write_mask = 0x0;
500 break;
501 case 0x3c:
502 case 0x44:
503 case 0x45:
504 write_mask = 0xff;
505 break;
506 default:
507 /*reserved */
508 can_write = 2;
509 break;
511 if (can_write == 1)
513 d->config[addr] = (val & write_mask);
514 if (addr == (0x14 + len - 1))
516 /*write the last byte of mmio */
517 new_sm502_mm_io = le32_to_cpu(*(uint32_t *) (d->config + 0x14));
518 if ((s->sm502_mm_io != new_sm502_mm_io)
519 && ((pci_mem_base + new_sm502_mm_io) < 0xffffffff))
521 if (s->mmio_index != 0)
523 cpu_register_physical_memory(pci_mem_base +
524 s->sm502_mm_io, 0x200000,
525 IO_MEM_UNASSIGNED);
526 cpu_unregister_io_memory(s->mmio_index);
528 /*remapped the Control register to CPU memory space */
529 s->mmio_index =
530 cpu_register_io_memory(0, sm502_readfn,
531 sm502_writefn, s);
532 cpu_register_physical_memory(pci_mem_base +
533 new_sm502_mm_io, 0x200000,
534 s->mmio_index);
535 debug_out(DEBUG_MMIO,
536 ("new_sm502_mm_io %x pci_mem _base %llx\n",
537 new_sm502_mm_io, pci_mem_base));
541 else if (can_write == 0)
543 #ifdef PRINT_WARNNING
544 fprintf(stderr,
545 "warnning. %s :write to read only pci conf register addr %x\n",
546 __FUNCTION__, addr);
547 #endif
549 else if (can_write == 2)
551 #ifdef PRINT_WARNNING
552 fprintf(stderr,
553 "warnning. %s :write to reserved pci conf register addr %x\n",
554 __FUNCTION__, addr);
555 #endif
557 if (++addr > 0xff)
558 break;
559 val >>= 8;
563 static void sm502_reset(struct sm502_s *s)
565 uint8_t *pci_conf;
567 pci_conf = s->dev.config;
568 memset(pci_conf, 0, 256);
570 pci_conf[0] = 0x6F;
571 pci_conf[1] = 0x12;
572 pci_conf[2] = 0x01;
573 pci_conf[3] = 0x05;
574 pci_conf[6] = 0x30;
575 pci_conf[7] = 0x02;
576 pci_conf[8] = 0xc0;
577 pci_conf[10] = 0x80;
578 pci_conf[11] = 0x03;
579 pci_conf[0x34] = 0x40;
580 pci_conf[0x40] = 0x01;
581 pci_conf[0x42] = 0x01;
582 pci_conf[0x43] = 0x06;
584 s->arb_control = 0x05146732;
585 s->current_gate = 0x00021807;
586 s->current_clock = 0x2a1a0a09;
587 s->power0_gate = 0x00021807;
588 s->power0_clock = 0x2a1a0a09;
589 s->power1_gate = 0x00021807;
590 s->power1_clock = 0x2a1a0a09;
591 s->sleep_gate = 0x00018000;
592 s->endian_control = 0x1;
593 s->device_id = 0x050100a0;
594 s->non_cache_address = 0x0000ffff;
595 s->pll_control = 0x0000ffff;
599 struct sm502_s *sm502_init(PCIBus * bus, int devfn, target_phys_addr_t pci_base)
601 struct sm502_s *s = (struct sm502_s *) qemu_mallocz(sizeof(*s));
603 s = (struct sm502_s *) pci_register_device(bus, "SM502 PCI",
604 sizeof(struct sm502_s), devfn,
605 sm502_read_config,
606 sm502_write_config);
607 pci_mem_base = pci_base;
609 sm502_gpio_init(s);
611 sm502_reset(s);
613 return s;