change default debug setting:no debug output
[qemu/qemu-loongson.git] / hw / mips_gdium.c
blob666b8367eea04ee4e5d3cda69644a105cd86ebcb
1 /*
2 * QEMU gdium 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.
26 * Gdium is a loongson 2f CPU based notebook. http://www.gdium.com/
29 #include "hw.h"
30 #include "pc.h"
31 #include "fdc.h"
32 #include "net.h"
33 #include "boards.h"
34 #include "smbus.h"
35 #include "block.h"
36 #include "flash.h"
37 #include "mips.h"
38 #include "qemu-char.h"
39 #include "sysemu.h"
40 #include "audio/audio.h"
41 #include "boards.h"
42 #include "mips_loongson2f.h"
43 #include "sm502.h"
45 //#define DEBUG /*global debug on/off */
46 #define DEBUG_BOARD_INIT (1<<0x0)
47 #define DEBUG_I2C_EMU (1<<0x1)
49 #define DEBUG_ALL (0xffffffff)
50 #define DEBUG_FLAG DEBUG_BOARD_INIT
52 #ifdef DEBUG
53 #define debug_out(flag,out) {\
54 if (flag & DEBUG_FLAG) printf out; \
55 } while(0);
56 #else
57 #define debug_out(flag,out)
58 #endif
60 #ifdef BIOS_SIZE
61 #undef BIOS_SIZE
62 #endif
63 #define BIOS_SIZE (512 * 1024)
64 #define BIOS_SECTOR_BITS (12)
65 #define GDIUM_SDRAM_SIZE (512*1024*1024)
67 #define SM502_DEV_NO 14
68 #define GDIUM_PCI_MEM_BASE (0x10000000)
70 #define GDIUM_GPIO_SCL 6
71 #define GDIUM_GPIO_SDA 13
73 #define IDLE 1
74 #define START 2
75 #define RECV_DATA 3
76 #define SEND_DATA 4
77 #define SEND_ACK 5
79 struct emu_i2c
81 i2c_bus *emu_i2c_bus;
82 qemu_irq *emu_i2c_cbs;
83 qemu_irq sda_irq;
85 uint8_t out_data;
86 int8_t out_offset;
87 uint8_t in_data;
88 int8_t in_offset;
90 uint8_t scl;
91 uint8_t i2c_state;
92 uint8_t waiting_ack;
93 uint8_t is_slave_addr;
95 uint8_t slave_addr;
99 struct gdium_s
101 CPUState *env;
102 PCIBus *pci_bus;
103 struct sm502_s *sm502;
104 uint8_t *eeprom_buf;
106 struct emu_i2c *emu_i2c;
109 static void main_cpu_reset(void *opaque)
111 CPUState *env = opaque;
112 cpu_reset(env);
114 /* gdium stuff */
117 /*SCL=1 SDA:1->0*/
118 static int is_start(struct emu_i2c *emu_i2c, int line, int level)
120 if ((line == GDIUM_GPIO_SDA) && (!level) && (emu_i2c->scl))
121 return 1;
122 return 0;
125 /*SCL=1 SDA:0->1*/
126 static int is_stop(struct emu_i2c *emu_i2c, int line, int level)
128 if ((line == GDIUM_GPIO_SDA) && (level) && (emu_i2c->scl))
129 return 1;
130 return 0;
133 /*SCL: 0->1*/
134 static int one_cycle(struct emu_i2c *emu_i2c, int line, int level)
136 if ((line == GDIUM_GPIO_SCL) && (level))
137 return 1;
138 return 0;
141 /*PMON puts the data on GPIO SDA line*/
142 static void send_bit(struct gdium_s *s, int line, int level)
144 s->emu_i2c->out_data |=
145 sm502_gpio_get_pin(s->sm502,
146 GDIUM_GPIO_SDA) << (s->emu_i2c->out_offset);
147 s->emu_i2c->out_offset--;
150 /*prepare ack to cheat pmon*/
151 static void prepare_ack(struct gdium_s *s)
153 /*Set SDA=0 means we received ACK from slave */
154 sm502_gpio_set_pin(s->sm502, GDIUM_GPIO_SDA, 0);
157 static void recv_bit(struct gdium_s *s, int line, int level)
159 if (s->emu_i2c->in_offset == 7)
161 s->emu_i2c->in_data = i2c_recv(s->emu_i2c->emu_i2c_bus);
164 /*SCL:0->1 */
165 qemu_set_irq(s->emu_i2c->sda_irq,
166 (s->emu_i2c->in_data >> (s->emu_i2c->in_offset)) & 0x1);
167 s->emu_i2c->in_offset--;
170 static void i2c_emu_cb(void *opaque, int line, int level)
172 struct gdium_s *s = (struct gdium_s *) opaque;
174 if (line == GDIUM_GPIO_SCL)
175 s->emu_i2c->scl = level;
177 debug_out(DEBUG_I2C_EMU,
178 ("line %s LEVEL %d \n", line == GDIUM_GPIO_SCL ? "SCL" : "SDA",
179 level));
181 /*if we are waiting ack from slave address */
182 if (s->emu_i2c->waiting_ack)
184 debug_out(DEBUG_I2C_EMU, ("waiting_ack \n"));
185 prepare_ack(s);
186 if (one_cycle(s->emu_i2c, line, level))
188 s->emu_i2c->waiting_ack = 0;
190 return;
193 /*it means after sending ack, pmon writes to SDA-> wants STOP */
194 if ((line == GDIUM_GPIO_SDA) && (s->emu_i2c->i2c_state == RECV_DATA))
196 s->emu_i2c->i2c_state = IDLE;
197 return;
200 if ((s->emu_i2c->i2c_state == IDLE) || (s->emu_i2c->i2c_state == SEND_DATA))
202 /*check whether start signal */
203 if (is_start(s->emu_i2c, line, level))
205 s->emu_i2c->i2c_state = SEND_DATA;
206 /*is_slave_addr=1 means the next byte is slave addreses */
207 s->emu_i2c->is_slave_addr = 1;
208 s->emu_i2c->i2c_state = SEND_DATA;
209 debug_out(DEBUG_I2C_EMU,
210 ("I2C Start. state %d \n", s->emu_i2c->i2c_state));
211 s->emu_i2c->out_offset = 7;
212 s->emu_i2c->out_data = 0;
213 s->emu_i2c->slave_addr = 0;
215 return;
218 if (is_stop(s->emu_i2c, line, level))
220 debug_out(DEBUG_I2C_EMU, ("STOP \n"));
221 s->emu_i2c->i2c_state = IDLE;
222 i2c_end_transfer(s->emu_i2c->emu_i2c_bus);
223 return;
226 if (one_cycle(s->emu_i2c, line, level))
228 debug_out(DEBUG_I2C_EMU, ("one cycle \n"));
229 switch (s->emu_i2c->i2c_state)
231 case IDLE:
232 debug_out(DEBUG_I2C_EMU, ("IDLE \n"));
233 break;
234 case SEND_DATA:
235 send_bit(s, line, level);
236 if (s->emu_i2c->out_offset < 0)
238 debug_out(DEBUG_I2C_EMU,
239 ("slave_addr %d out data %d \n",
240 s->emu_i2c->slave_addr, s->emu_i2c->out_data));
241 if (s->emu_i2c->is_slave_addr)
243 /*first send is slave address */
244 s->emu_i2c->slave_addr = s->emu_i2c->out_data;
245 i2c_start_transfer(s->emu_i2c->
246 emu_i2c_bus,
247 s->emu_i2c->slave_addr & 0xfe,
248 s->emu_i2c->slave_addr & 0x1);
249 debug_out(DEBUG_I2C_EMU,
250 ("slave_addr %d \n", s->emu_i2c->slave_addr));
252 s->emu_i2c->is_slave_addr = 0;
254 else
256 /*send reg address or data */
257 i2c_send(s->emu_i2c->emu_i2c_bus, s->emu_i2c->out_data);
259 s->emu_i2c->out_offset = 7;
260 s->emu_i2c->out_data = 0;
261 if (s->emu_i2c->slave_addr & 0x1)
263 s->emu_i2c->in_offset = 7;
264 s->emu_i2c->i2c_state = RECV_DATA;
266 else
267 s->emu_i2c->i2c_state = SEND_DATA;
268 s->emu_i2c->waiting_ack = 1;
271 break;
272 case RECV_DATA:
273 /*RECV. TODO */
274 recv_bit(s, line, level);
275 if (s->emu_i2c->in_offset < 0)
276 s->emu_i2c->i2c_state = SEND_ACK;
277 break;
278 case SEND_ACK:
279 debug_out(DEBUG_I2C_EMU, ("SEND_ACK \n"));
280 s->emu_i2c->in_offset = 7;
281 s->emu_i2c->i2c_state = RECV_DATA;
282 i2c_nack(s->emu_i2c->emu_i2c_bus);
283 break;
284 default:
285 fprintf(stderr, "unknown state %d \n", s->emu_i2c->i2c_state);
286 exit(-1);
293 /*gdium uses SM502 GPIO 6/13 to emulate I2C.*/
294 static void mips_gdium_i2c_emu(struct gdium_s *s)
296 s->emu_i2c->emu_i2c_cbs = qemu_allocate_irqs(i2c_emu_cb, s, 32);
297 sm502_gpio_out_set(s->sm502, GDIUM_GPIO_SCL,
298 s->emu_i2c->emu_i2c_cbs[GDIUM_GPIO_SCL]);
299 sm502_gpio_out_set(s->sm502, GDIUM_GPIO_SDA,
300 s->emu_i2c->emu_i2c_cbs[GDIUM_GPIO_SDA]);
302 s->emu_i2c->i2c_state = IDLE;
304 s->emu_i2c->sda_irq = sm502_gpio_in_get(s->sm502, GDIUM_GPIO_SDA)[0];
307 /*dumped from my gdium pcb*/
308 uint8_t gdium_spd[0x80] = {
309 0x80, 0x08, 0x08, 0x0e, 0x0a, 0x60, 0x40, 0x00, /*0x00-0x07 */
310 0x05, 0x3d, 0x50, 0x00, 0x82, 0x00, 0x00, 0x00, /*0x08-0x0f */
311 0x0c, 0x04, 0x38, 0x00, 0x04, 0x00, 0x01, 0x3d, /*0x10-0x17 */
312 0x50, 0x50, 0x60, 0x3c, 0x1e, 0x3c, 0x2d, 0x80, /*0x18-0x1f */
313 0x25, 0x37, 0x10, 0x22, 0x3c, 0x1e, 0x13, 0x00, /*0x20-0x27 */
314 0x00, 0x3c, 0x69, 0x80, 0x1e, 0x28, 0x00, 0x00, /*0x28-0x2f */
315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x30-0x37 */
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb2, /*0x38-0x3f */
317 0x7f, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x40-0x47 */
318 0x54, 0x4a, 0x4d, 0x35, 0x33, 0x33, 0x51, 0x53, /*0x48-0x4f */
319 0x4a, 0x2d, 0x35, 0x31, 0x32, 0x4d, 0x20, 0x20, /*0x50-0x57 */
320 0x20, 0x20, 0x20, 0x00, 0x00, 0x07, 0x47, 0x00, /*0x58-0x5f */
321 0x07, 0x00, 0xb1, 0x98, 0x00, 0x00, 0x00, 0x00, /*0x60-0x67 */
322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x68-0x6f */
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x70-0x77 */
324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x78-0x7f */
327 static
328 void mips_gdium_init(ram_addr_t ram_size, int vga_ram_size,
329 const char *boot_device,
330 const char *kernel_filename,
331 const char *kernel_cmdline,
332 const char *initrd_filename, const char *cpu_model)
334 int index;
335 unsigned long bios_offset;
336 uint8_t *eeprom_buf;
338 struct gdium_s *s = qemu_mallocz(sizeof(*s));
340 if (cpu_model == NULL)
342 cpu_model = "Loongson-2F";
344 s->env = cpu_init(cpu_model);
345 if (!s->env)
347 fprintf(stderr, "Unable to find CPU definition\n");
348 exit(1);
350 /*set bit 5:7 of status registerto 1.
351 * Loongson 2f does not have 32bit address space and ux/sx/kx is not used in loongson
352 * But qemu needs this. So just set these bits to 1
354 s->env->CP0_Status |= 0xe0;
356 register_savevm("cpu", 0, 3, cpu_save, cpu_load, s->env);
357 qemu_register_reset(main_cpu_reset, s->env);
359 /* allocate RAM */
360 if (ram_size > (GDIUM_SDRAM_SIZE))
362 fprintf(stderr,
363 "qemu: Too much memory for this machine: %d MB, maximum 512 MB\n",
364 ((unsigned int) ram_size / (1 << 20)));
365 exit(1);
367 cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
369 bios_offset = ram_size + vga_ram_size;
370 cpu_register_physical_memory(0x1fc00000LL, BIOS_SIZE,
371 bios_offset | IO_MEM_ROM);
373 /*sst39vf040 flash */
374 index = drive_get_index(IF_PFLASH, 0, 0);
375 if (index == -1)
377 fprintf(stderr,
378 "A flash image must be given with the " "'pflash' parameter\n");
379 exit(1);
382 debug_out(DEBUG_BOARD_INIT, ("Register sst39vf040 size %x at "
383 "offset %08lx addr %08llx '%s' %x\n",
384 BIOS_SIZE, bios_offset, 0x1fc00000LL,
385 bdrv_get_device_name(drives_table[index].bdrv),
386 (BIOS_SIZE >> BIOS_SECTOR_BITS)));
387 pflash_cfi02_register(0x1fc00000LL, bios_offset, drives_table[index].bdrv,
388 (1 << BIOS_SECTOR_BITS),
389 BIOS_SIZE >> BIOS_SECTOR_BITS, 1, 1, 0xbf, 0xd7,
390 0x0000, 0x0000, 0x555, 0xaaa);
392 cpu_mips_irq_init_cpu(s->env);
393 cpu_mips_clock_init(s->env);
395 s->pci_bus = bonito_init(s->env);
396 s->sm502 = sm502_init(s->pci_bus, SM502_DEV_NO << 3, 0x10000000);
397 loongson_ddr2_init();
398 loongson_addwin_init();
400 s->emu_i2c = qemu_mallocz(sizeof(*s->emu_i2c));
401 s->emu_i2c->emu_i2c_bus = i2c_init_bus();
402 /*DDR SPD EEPROM */
403 eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
404 memcpy(eeprom_buf, gdium_spd, sizeof(gdium_spd));
405 smbus_eeprom_device_init(s->emu_i2c->emu_i2c_bus, 0xa2, eeprom_buf);
407 /*rtc */
408 m41t80_init(s->emu_i2c->emu_i2c_bus, NULL, 0xd0);
409 /*temperature sensors */
410 stds75_init(s->emu_i2c->emu_i2c_bus, NULL, 0x90);
412 mips_gdium_i2c_emu(s);
416 QEMUMachine mips_gdium_machine = {
417 .name = "gdium",
418 .desc = "MIPS Gdium notebook",
419 .init = mips_gdium_init,
420 .ram_require = VGA_RAM_SIZE + BIOS_SIZE,
421 .nodisk_ok = 1,