1. fix the bug of sm502 pci configuration r/w
[qemu/qemu-loongson.git] / hw / mips_gdium.c
blobcbbcfd4114728443a3db7f13fab316b68117adea
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)
48 #define DEBUG_RAM_MAPPING (1<<0x2)
50 #define DEBUG_ALL (0xffffffff)
51 #define DEBUG_FLAG (DEBUG_BOARD_INIT|DEBUG_RAM_MAPPING)
53 #ifdef DEBUG
54 #define debug_out(flag,out) {\
55 if (flag & DEBUG_FLAG) printf out; \
56 } while(0);
57 #else
58 #define debug_out(flag,out)
59 #endif
61 #ifdef BIOS_SIZE
62 #undef BIOS_SIZE
63 #endif
64 #define BIOS_SIZE (512 * 1024)
65 #define BIOS_SECTOR_BITS (12)
66 #define GDIUM_SDRAM_SIZE (512*1024*1024)
68 #define SM502_DEV_NO 14
69 #define GDIUM_PCI_MEM_BASE (0x10000000)
71 #define GDIUM_GPIO_SCL 6
72 #define GDIUM_GPIO_SDA 13
74 #define IDLE 1
75 #define START 2
76 #define RECV_DATA 3
77 #define SEND_DATA 4
78 #define SEND_ACK 5
80 struct emu_i2c
82 i2c_bus *emu_i2c_bus;
83 qemu_irq *emu_i2c_cbs;
84 qemu_irq sda_irq;
86 uint8_t out_data;
87 int8_t out_offset;
88 uint8_t in_data;
89 int8_t in_offset;
91 uint8_t scl;
92 uint8_t i2c_state;
93 uint8_t waiting_ack;
94 uint8_t is_slave_addr;
96 uint8_t slave_addr;
100 struct gdium_s
102 CPUState *env;
103 PCIBus *pci_bus;
104 struct sm502_s *sm502;
105 uint8_t *eeprom_buf;
107 struct emu_i2c *emu_i2c;
110 static void main_cpu_reset(void *opaque)
112 CPUState *env = opaque;
113 cpu_reset(env);
115 /* gdium stuff */
118 /*SCL=1 SDA:1->0*/
119 static int is_start(struct emu_i2c *emu_i2c, int line, int level)
121 if ((line == GDIUM_GPIO_SDA) && (!level) && (emu_i2c->scl))
122 return 1;
123 return 0;
126 /*SCL=1 SDA:0->1*/
127 static int is_stop(struct emu_i2c *emu_i2c, int line, int level)
129 if ((line == GDIUM_GPIO_SDA) && (level) && (emu_i2c->scl))
130 return 1;
131 return 0;
134 /*SCL: 0->1*/
135 static int one_cycle(struct emu_i2c *emu_i2c, int line, int level)
137 if ((line == GDIUM_GPIO_SCL) && (level))
138 return 1;
139 return 0;
142 /*PMON puts the data on GPIO SDA line*/
143 static void send_bit(struct gdium_s *s, int line, int level)
145 s->emu_i2c->out_data |=
146 sm502_gpio_get_pin(s->sm502,
147 GDIUM_GPIO_SDA) << (s->emu_i2c->out_offset);
148 s->emu_i2c->out_offset--;
151 /*prepare ack to cheat pmon*/
152 static void prepare_ack(struct gdium_s *s)
154 /*Set SDA=0 means we received ACK from slave */
155 sm502_gpio_set_pin(s->sm502, GDIUM_GPIO_SDA, 0);
158 static void recv_bit(struct gdium_s *s, int line, int level)
160 if (s->emu_i2c->in_offset == 7)
162 s->emu_i2c->in_data = i2c_recv(s->emu_i2c->emu_i2c_bus);
165 /*SCL:0->1 */
166 qemu_set_irq(s->emu_i2c->sda_irq,
167 (s->emu_i2c->in_data >> (s->emu_i2c->in_offset)) & 0x1);
168 s->emu_i2c->in_offset--;
171 static void i2c_emu_cb(void *opaque, int line, int level)
173 struct gdium_s *s = (struct gdium_s *) opaque;
175 if (line == GDIUM_GPIO_SCL)
176 s->emu_i2c->scl = level;
178 debug_out(DEBUG_I2C_EMU,
179 ("line %s LEVEL %d \n", line == GDIUM_GPIO_SCL ? "SCL" : "SDA",
180 level));
182 /*if we are waiting ack from slave address */
183 if (s->emu_i2c->waiting_ack)
185 debug_out(DEBUG_I2C_EMU, ("waiting_ack \n"));
186 prepare_ack(s);
187 if (one_cycle(s->emu_i2c, line, level))
189 s->emu_i2c->waiting_ack = 0;
191 return;
194 /*it means after sending ack, pmon writes to SDA-> wants STOP */
195 if ((line == GDIUM_GPIO_SDA) && (s->emu_i2c->i2c_state == RECV_DATA))
197 s->emu_i2c->i2c_state = IDLE;
198 return;
201 if ((s->emu_i2c->i2c_state == IDLE) || (s->emu_i2c->i2c_state == SEND_DATA))
203 /*check whether start signal */
204 if (is_start(s->emu_i2c, line, level))
206 s->emu_i2c->i2c_state = SEND_DATA;
207 /*is_slave_addr=1 means the next byte is slave addreses */
208 s->emu_i2c->is_slave_addr = 1;
209 s->emu_i2c->i2c_state = SEND_DATA;
210 debug_out(DEBUG_I2C_EMU,
211 ("I2C Start. state %d \n", s->emu_i2c->i2c_state));
212 s->emu_i2c->out_offset = 7;
213 s->emu_i2c->out_data = 0;
214 s->emu_i2c->slave_addr = 0;
216 return;
219 if (is_stop(s->emu_i2c, line, level))
221 debug_out(DEBUG_I2C_EMU, ("STOP \n"));
222 s->emu_i2c->i2c_state = IDLE;
223 i2c_end_transfer(s->emu_i2c->emu_i2c_bus);
224 return;
227 if (one_cycle(s->emu_i2c, line, level))
229 debug_out(DEBUG_I2C_EMU, ("one cycle \n"));
230 switch (s->emu_i2c->i2c_state)
232 case IDLE:
233 debug_out(DEBUG_I2C_EMU, ("IDLE \n"));
234 break;
235 case SEND_DATA:
236 send_bit(s, line, level);
237 if (s->emu_i2c->out_offset < 0)
239 debug_out(DEBUG_I2C_EMU,
240 ("slave_addr %d out data %d \n",
241 s->emu_i2c->slave_addr, s->emu_i2c->out_data));
242 if (s->emu_i2c->is_slave_addr)
244 /*first send is slave address */
245 s->emu_i2c->slave_addr = s->emu_i2c->out_data;
246 i2c_start_transfer(s->emu_i2c->
247 emu_i2c_bus,
248 s->emu_i2c->slave_addr & 0xfe,
249 s->emu_i2c->slave_addr & 0x1);
250 debug_out(DEBUG_I2C_EMU,
251 ("slave_addr %d \n", s->emu_i2c->slave_addr));
253 s->emu_i2c->is_slave_addr = 0;
255 else
257 /*send reg address or data */
258 i2c_send(s->emu_i2c->emu_i2c_bus, s->emu_i2c->out_data);
260 s->emu_i2c->out_offset = 7;
261 s->emu_i2c->out_data = 0;
262 if (s->emu_i2c->slave_addr & 0x1)
264 s->emu_i2c->in_offset = 7;
265 s->emu_i2c->i2c_state = RECV_DATA;
267 else
268 s->emu_i2c->i2c_state = SEND_DATA;
269 s->emu_i2c->waiting_ack = 1;
272 break;
273 case RECV_DATA:
274 /*RECV. TODO */
275 recv_bit(s, line, level);
276 if (s->emu_i2c->in_offset < 0)
277 s->emu_i2c->i2c_state = SEND_ACK;
278 break;
279 case SEND_ACK:
280 debug_out(DEBUG_I2C_EMU, ("SEND_ACK \n"));
281 s->emu_i2c->in_offset = 7;
282 s->emu_i2c->i2c_state = RECV_DATA;
283 i2c_nack(s->emu_i2c->emu_i2c_bus);
284 break;
285 default:
286 fprintf(stderr, "unknown state %d \n", s->emu_i2c->i2c_state);
287 exit(-1);
294 /*gdium uses SM502 GPIO 6/13 to emulate I2C.*/
295 static void mips_gdium_i2c_emu(struct gdium_s *s)
297 s->emu_i2c->emu_i2c_cbs = qemu_allocate_irqs(i2c_emu_cb, s, 32);
298 sm502_gpio_out_set(s->sm502, GDIUM_GPIO_SCL,
299 s->emu_i2c->emu_i2c_cbs[GDIUM_GPIO_SCL]);
300 sm502_gpio_out_set(s->sm502, GDIUM_GPIO_SDA,
301 s->emu_i2c->emu_i2c_cbs[GDIUM_GPIO_SDA]);
303 s->emu_i2c->i2c_state = IDLE;
305 s->emu_i2c->sda_irq = sm502_gpio_in_get(s->sm502, GDIUM_GPIO_SDA)[0];
308 /*dumped from my gdium pcb*/
309 uint8_t gdium_spd[0x80] = {
310 0x80, 0x08, 0x08, 0x0e, 0x0a, 0x60, 0x40, 0x00, /*0x00-0x07 */
311 0x05, 0x3d, 0x50, 0x00, 0x82, 0x00, 0x00, 0x00, /*0x08-0x0f */
312 0x0c, 0x04, 0x38, 0x00, 0x04, 0x00, 0x01, 0x3d, /*0x10-0x17 */
313 0x50, 0x50, 0x60, 0x3c, 0x1e, 0x3c, 0x2d, 0x80, /*0x18-0x1f */
314 0x25, 0x37, 0x10, 0x22, 0x3c, 0x1e, 0x13, 0x00, /*0x20-0x27 */
315 0x00, 0x3c, 0x69, 0x80, 0x1e, 0x28, 0x00, 0x00, /*0x28-0x2f */
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x30-0x37 */
317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb2, /*0x38-0x3f */
318 0x7f, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x40-0x47 */
319 0x54, 0x4a, 0x4d, 0x35, 0x33, 0x33, 0x51, 0x53, /*0x48-0x4f */
320 0x4a, 0x2d, 0x35, 0x31, 0x32, 0x4d, 0x20, 0x20, /*0x50-0x57 */
321 0x20, 0x20, 0x20, 0x00, 0x00, 0x07, 0x47, 0x00, /*0x58-0x5f */
322 0x07, 0x00, 0xb1, 0x98, 0x00, 0x00, 0x00, 0x00, /*0x60-0x67 */
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x68-0x6f */
324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x70-0x77 */
325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x78-0x7f */
328 static
329 void mips_gdium_init(ram_addr_t ram_size, int vga_ram_size,
330 const char *boot_device,
331 const char *kernel_filename,
332 const char *kernel_cmdline,
333 const char *initrd_filename, const char *cpu_model)
335 int index;
336 unsigned long bios_offset;
337 uint8_t *eeprom_buf;
339 struct gdium_s *s = qemu_mallocz(sizeof(*s));
341 if (cpu_model == NULL)
343 cpu_model = "Loongson-2F";
345 s->env = cpu_init(cpu_model);
346 if (!s->env)
348 fprintf(stderr, "Unable to find CPU definition\n");
349 exit(1);
352 /*set bit 5:7 of status registerto 1.
353 * Loongson 2f does not have 32bit address space and ux/sx/kx is not used in loongson
354 * But qemu needs this. So just set these bits to 1
356 s->env->CP0_Status |= 0xe0;
358 register_savevm("cpu", 0, 3, cpu_save, cpu_load, s->env);
359 qemu_register_reset(main_cpu_reset, s->env);
361 /* allocate RAM */
362 if (ram_size > (GDIUM_SDRAM_SIZE))
364 fprintf(stderr,
365 "qemu: Too much memory for this machine: %d MB, maximum 512 MB\n",
366 ((unsigned int) ram_size / (1 << 20)));
367 exit(1);
370 /*CPU ADDRESS:[0:256M]<->DDR [0:256M]
371 * DDR_ADDR[256M:512M] mapping determined by loongson 2f address windows configuration.
373 if (ram_size > (256 * 1024 * 1024))
375 debug_out(DEBUG_RAM_MAPPING, ("Mapping first 256M RAM\n"));
376 cpu_register_physical_memory(0, (256 * 1024 * 1024), IO_MEM_RAM);
378 else
379 cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
381 bios_offset = ram_size + vga_ram_size;
382 cpu_register_physical_memory(0x1fc00000LL, BIOS_SIZE,
383 bios_offset | IO_MEM_ROM);
385 /*sst39vf040 flash */
386 index = drive_get_index(IF_PFLASH, 0, 0);
387 if (index == -1)
389 fprintf(stderr,
390 "A flash image must be given with the " "'pflash' parameter\n");
391 exit(1);
394 debug_out(DEBUG_BOARD_INIT, ("Register sst39vf040 size %x at "
395 "offset %08lx addr %08llx '%s' %x\n",
396 BIOS_SIZE, bios_offset, 0x1fc00000LL,
397 bdrv_get_device_name(drives_table[index].bdrv),
398 (BIOS_SIZE >> BIOS_SECTOR_BITS)));
399 pflash_cfi02_register(0x1fc00000LL, bios_offset, drives_table[index].bdrv,
400 (1 << BIOS_SECTOR_BITS),
401 BIOS_SIZE >> BIOS_SECTOR_BITS, 1, 1, 0xbf, 0xd7,
402 0x0000, 0x0000, 0x555, 0xaaa);
404 cpu_mips_irq_init_cpu(s->env);
405 cpu_mips_clock_init(s->env);
407 s->pci_bus = bonito_init(s->env);
408 s->sm502 = sm502_init(s->pci_bus, SM502_DEV_NO << 3, 0x10000000);
409 loongson_ddr2_init();
410 loongson_addwin_init();
412 s->emu_i2c = qemu_mallocz(sizeof(*s->emu_i2c));
413 s->emu_i2c->emu_i2c_bus = i2c_init_bus();
414 /*DDR SPD EEPROM */
415 eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
416 memcpy(eeprom_buf, gdium_spd, sizeof(gdium_spd));
417 smbus_eeprom_device_init(s->emu_i2c->emu_i2c_bus, 0xa2, eeprom_buf);
419 /*rtc */
420 m41t80_init(s->emu_i2c->emu_i2c_bus, NULL, 0xd0);
421 /*temperature sensors */
422 stds75_init(s->emu_i2c->emu_i2c_bus, NULL, 0x90);
424 mips_gdium_i2c_emu(s);
428 QEMUMachine mips_gdium_machine = {
429 .name = "gdium",
430 .desc = "MIPS Gdium notebook",
431 .init = mips_gdium_init,
432 .ram_require = VGA_RAM_SIZE + BIOS_SIZE,
433 .nodisk_ok = 1,