Fix typo
[qemu-kvm/fedora.git] / hw / stellaris.c
blob999cb5059326370b0b600a2028f864e71b3dd9e0
1 /*
2 * Luminary Micro Stellaris peripherals
4 * Copyright (c) 2006 CodeSourcery.
5 * Written by Paul Brook
7 * This code is licenced under the GPL.
8 */
10 #include "hw.h"
11 #include "arm-misc.h"
12 #include "primecell.h"
13 #include "devices.h"
14 #include "qemu-timer.h"
15 #include "i2c.h"
16 #include "net.h"
17 #include "sd.h"
18 #include "sysemu.h"
19 #include "boards.h"
21 #define GPIO_A 0
22 #define GPIO_B 1
23 #define GPIO_C 2
24 #define GPIO_D 3
25 #define GPIO_E 4
26 #define GPIO_F 5
27 #define GPIO_G 6
29 #define BP_OLED_I2C 0x01
30 #define BP_OLED_SSI 0x02
31 #define BP_GAMEPAD 0x04
33 typedef const struct {
34 const char *name;
35 uint32_t did0;
36 uint32_t did1;
37 uint32_t dc0;
38 uint32_t dc1;
39 uint32_t dc2;
40 uint32_t dc3;
41 uint32_t dc4;
42 uint32_t peripherals;
43 } stellaris_board_info;
45 /* General purpose timer module. */
47 typedef struct gptm_state {
48 uint32_t config;
49 uint32_t mode[2];
50 uint32_t control;
51 uint32_t state;
52 uint32_t mask;
53 uint32_t load[2];
54 uint32_t match[2];
55 uint32_t prescale[2];
56 uint32_t match_prescale[2];
57 uint32_t rtc;
58 int64_t tick[2];
59 struct gptm_state *opaque[2];
60 uint32_t base;
61 QEMUTimer *timer[2];
62 /* The timers have an alternate output used to trigger the ADC. */
63 qemu_irq trigger;
64 qemu_irq irq;
65 } gptm_state;
67 static void gptm_update_irq(gptm_state *s)
69 int level;
70 level = (s->state & s->mask) != 0;
71 qemu_set_irq(s->irq, level);
74 static void gptm_stop(gptm_state *s, int n)
76 qemu_del_timer(s->timer[n]);
79 static void gptm_reload(gptm_state *s, int n, int reset)
81 int64_t tick;
82 if (reset)
83 tick = qemu_get_clock(vm_clock);
84 else
85 tick = s->tick[n];
87 if (s->config == 0) {
88 /* 32-bit CountDown. */
89 uint32_t count;
90 count = s->load[0] | (s->load[1] << 16);
91 tick += (int64_t)count * system_clock_scale;
92 } else if (s->config == 1) {
93 /* 32-bit RTC. 1Hz tick. */
94 tick += ticks_per_sec;
95 } else if (s->mode[n] == 0xa) {
96 /* PWM mode. Not implemented. */
97 } else {
98 cpu_abort(cpu_single_env, "TODO: 16-bit timer mode 0x%x\n",
99 s->mode[n]);
101 s->tick[n] = tick;
102 qemu_mod_timer(s->timer[n], tick);
105 static void gptm_tick(void *opaque)
107 gptm_state **p = (gptm_state **)opaque;
108 gptm_state *s;
109 int n;
111 s = *p;
112 n = p - s->opaque;
113 if (s->config == 0) {
114 s->state |= 1;
115 if ((s->control & 0x20)) {
116 /* Output trigger. */
117 qemu_irq_raise(s->trigger);
118 qemu_irq_lower(s->trigger);
120 if (s->mode[0] & 1) {
121 /* One-shot. */
122 s->control &= ~1;
123 } else {
124 /* Periodic. */
125 gptm_reload(s, 0, 0);
127 } else if (s->config == 1) {
128 /* RTC. */
129 uint32_t match;
130 s->rtc++;
131 match = s->match[0] | (s->match[1] << 16);
132 if (s->rtc > match)
133 s->rtc = 0;
134 if (s->rtc == 0) {
135 s->state |= 8;
137 gptm_reload(s, 0, 0);
138 } else if (s->mode[n] == 0xa) {
139 /* PWM mode. Not implemented. */
140 } else {
141 cpu_abort(cpu_single_env, "TODO: 16-bit timer mode 0x%x\n",
142 s->mode[n]);
144 gptm_update_irq(s);
147 static uint32_t gptm_read(void *opaque, target_phys_addr_t offset)
149 gptm_state *s = (gptm_state *)opaque;
151 offset -= s->base;
152 switch (offset) {
153 case 0x00: /* CFG */
154 return s->config;
155 case 0x04: /* TAMR */
156 return s->mode[0];
157 case 0x08: /* TBMR */
158 return s->mode[1];
159 case 0x0c: /* CTL */
160 return s->control;
161 case 0x18: /* IMR */
162 return s->mask;
163 case 0x1c: /* RIS */
164 return s->state;
165 case 0x20: /* MIS */
166 return s->state & s->mask;
167 case 0x24: /* CR */
168 return 0;
169 case 0x28: /* TAILR */
170 return s->load[0] | ((s->config < 4) ? (s->load[1] << 16) : 0);
171 case 0x2c: /* TBILR */
172 return s->load[1];
173 case 0x30: /* TAMARCHR */
174 return s->match[0] | ((s->config < 4) ? (s->match[1] << 16) : 0);
175 case 0x34: /* TBMATCHR */
176 return s->match[1];
177 case 0x38: /* TAPR */
178 return s->prescale[0];
179 case 0x3c: /* TBPR */
180 return s->prescale[1];
181 case 0x40: /* TAPMR */
182 return s->match_prescale[0];
183 case 0x44: /* TBPMR */
184 return s->match_prescale[1];
185 case 0x48: /* TAR */
186 if (s->control == 1)
187 return s->rtc;
188 case 0x4c: /* TBR */
189 cpu_abort(cpu_single_env, "TODO: Timer value read\n");
190 default:
191 cpu_abort(cpu_single_env, "gptm_read: Bad offset 0x%x\n", (int)offset);
192 return 0;
196 static void gptm_write(void *opaque, target_phys_addr_t offset, uint32_t value)
198 gptm_state *s = (gptm_state *)opaque;
199 uint32_t oldval;
201 offset -= s->base;
202 /* The timers should be disabled before changing the configuration.
203 We take advantage of this and defer everything until the timer
204 is enabled. */
205 switch (offset) {
206 case 0x00: /* CFG */
207 s->config = value;
208 break;
209 case 0x04: /* TAMR */
210 s->mode[0] = value;
211 break;
212 case 0x08: /* TBMR */
213 s->mode[1] = value;
214 break;
215 case 0x0c: /* CTL */
216 oldval = s->control;
217 s->control = value;
218 /* TODO: Implement pause. */
219 if ((oldval ^ value) & 1) {
220 if (value & 1) {
221 gptm_reload(s, 0, 1);
222 } else {
223 gptm_stop(s, 0);
226 if (((oldval ^ value) & 0x100) && s->config >= 4) {
227 if (value & 0x100) {
228 gptm_reload(s, 1, 1);
229 } else {
230 gptm_stop(s, 1);
233 break;
234 case 0x18: /* IMR */
235 s->mask = value & 0x77;
236 gptm_update_irq(s);
237 break;
238 case 0x24: /* CR */
239 s->state &= ~value;
240 break;
241 case 0x28: /* TAILR */
242 s->load[0] = value & 0xffff;
243 if (s->config < 4) {
244 s->load[1] = value >> 16;
246 break;
247 case 0x2c: /* TBILR */
248 s->load[1] = value & 0xffff;
249 break;
250 case 0x30: /* TAMARCHR */
251 s->match[0] = value & 0xffff;
252 if (s->config < 4) {
253 s->match[1] = value >> 16;
255 break;
256 case 0x34: /* TBMATCHR */
257 s->match[1] = value >> 16;
258 break;
259 case 0x38: /* TAPR */
260 s->prescale[0] = value;
261 break;
262 case 0x3c: /* TBPR */
263 s->prescale[1] = value;
264 break;
265 case 0x40: /* TAPMR */
266 s->match_prescale[0] = value;
267 break;
268 case 0x44: /* TBPMR */
269 s->match_prescale[0] = value;
270 break;
271 default:
272 cpu_abort(cpu_single_env, "gptm_write: Bad offset 0x%x\n", (int)offset);
274 gptm_update_irq(s);
277 static CPUReadMemoryFunc *gptm_readfn[] = {
278 gptm_read,
279 gptm_read,
280 gptm_read
283 static CPUWriteMemoryFunc *gptm_writefn[] = {
284 gptm_write,
285 gptm_write,
286 gptm_write
289 static void gptm_save(QEMUFile *f, void *opaque)
291 gptm_state *s = (gptm_state *)opaque;
293 qemu_put_be32(f, s->config);
294 qemu_put_be32(f, s->mode[0]);
295 qemu_put_be32(f, s->mode[1]);
296 qemu_put_be32(f, s->control);
297 qemu_put_be32(f, s->state);
298 qemu_put_be32(f, s->mask);
299 qemu_put_be32(f, s->mode[0]);
300 qemu_put_be32(f, s->mode[0]);
301 qemu_put_be32(f, s->load[0]);
302 qemu_put_be32(f, s->load[1]);
303 qemu_put_be32(f, s->match[0]);
304 qemu_put_be32(f, s->match[1]);
305 qemu_put_be32(f, s->prescale[0]);
306 qemu_put_be32(f, s->prescale[1]);
307 qemu_put_be32(f, s->match_prescale[0]);
308 qemu_put_be32(f, s->match_prescale[1]);
309 qemu_put_be32(f, s->rtc);
310 qemu_put_be64(f, s->tick[0]);
311 qemu_put_be64(f, s->tick[1]);
312 qemu_put_timer(f, s->timer[0]);
313 qemu_put_timer(f, s->timer[1]);
316 static int gptm_load(QEMUFile *f, void *opaque, int version_id)
318 gptm_state *s = (gptm_state *)opaque;
320 if (version_id != 1)
321 return -EINVAL;
323 s->config = qemu_get_be32(f);
324 s->mode[0] = qemu_get_be32(f);
325 s->mode[1] = qemu_get_be32(f);
326 s->control = qemu_get_be32(f);
327 s->state = qemu_get_be32(f);
328 s->mask = qemu_get_be32(f);
329 s->mode[0] = qemu_get_be32(f);
330 s->mode[0] = qemu_get_be32(f);
331 s->load[0] = qemu_get_be32(f);
332 s->load[1] = qemu_get_be32(f);
333 s->match[0] = qemu_get_be32(f);
334 s->match[1] = qemu_get_be32(f);
335 s->prescale[0] = qemu_get_be32(f);
336 s->prescale[1] = qemu_get_be32(f);
337 s->match_prescale[0] = qemu_get_be32(f);
338 s->match_prescale[1] = qemu_get_be32(f);
339 s->rtc = qemu_get_be32(f);
340 s->tick[0] = qemu_get_be64(f);
341 s->tick[1] = qemu_get_be64(f);
342 qemu_get_timer(f, s->timer[0]);
343 qemu_get_timer(f, s->timer[1]);
345 return 0;
348 static void stellaris_gptm_init(uint32_t base, qemu_irq irq, qemu_irq trigger)
350 int iomemtype;
351 gptm_state *s;
353 s = (gptm_state *)qemu_mallocz(sizeof(gptm_state));
354 s->base = base;
355 s->irq = irq;
356 s->trigger = trigger;
357 s->opaque[0] = s->opaque[1] = s;
359 iomemtype = cpu_register_io_memory(0, gptm_readfn,
360 gptm_writefn, s);
361 cpu_register_physical_memory(base, 0x00001000, iomemtype);
362 s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]);
363 s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]);
364 register_savevm("stellaris_gptm", -1, 1, gptm_save, gptm_load, s);
368 /* System controller. */
370 typedef struct {
371 uint32_t base;
372 uint32_t pborctl;
373 uint32_t ldopctl;
374 uint32_t int_status;
375 uint32_t int_mask;
376 uint32_t resc;
377 uint32_t rcc;
378 uint32_t rcgc[3];
379 uint32_t scgc[3];
380 uint32_t dcgc[3];
381 uint32_t clkvclr;
382 uint32_t ldoarst;
383 uint32_t user0;
384 uint32_t user1;
385 qemu_irq irq;
386 stellaris_board_info *board;
387 } ssys_state;
389 static void ssys_update(ssys_state *s)
391 qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0);
394 static uint32_t pllcfg_sandstorm[16] = {
395 0x31c0, /* 1 Mhz */
396 0x1ae0, /* 1.8432 Mhz */
397 0x18c0, /* 2 Mhz */
398 0xd573, /* 2.4576 Mhz */
399 0x37a6, /* 3.57954 Mhz */
400 0x1ae2, /* 3.6864 Mhz */
401 0x0c40, /* 4 Mhz */
402 0x98bc, /* 4.906 Mhz */
403 0x935b, /* 4.9152 Mhz */
404 0x09c0, /* 5 Mhz */
405 0x4dee, /* 5.12 Mhz */
406 0x0c41, /* 6 Mhz */
407 0x75db, /* 6.144 Mhz */
408 0x1ae6, /* 7.3728 Mhz */
409 0x0600, /* 8 Mhz */
410 0x585b /* 8.192 Mhz */
413 static uint32_t pllcfg_fury[16] = {
414 0x3200, /* 1 Mhz */
415 0x1b20, /* 1.8432 Mhz */
416 0x1900, /* 2 Mhz */
417 0xf42b, /* 2.4576 Mhz */
418 0x37e3, /* 3.57954 Mhz */
419 0x1b21, /* 3.6864 Mhz */
420 0x0c80, /* 4 Mhz */
421 0x98ee, /* 4.906 Mhz */
422 0xd5b4, /* 4.9152 Mhz */
423 0x0a00, /* 5 Mhz */
424 0x4e27, /* 5.12 Mhz */
425 0x1902, /* 6 Mhz */
426 0xec1c, /* 6.144 Mhz */
427 0x1b23, /* 7.3728 Mhz */
428 0x0640, /* 8 Mhz */
429 0xb11c /* 8.192 Mhz */
432 static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
434 ssys_state *s = (ssys_state *)opaque;
436 offset -= s->base;
437 switch (offset) {
438 case 0x000: /* DID0 */
439 return s->board->did0;
440 case 0x004: /* DID1 */
441 return s->board->did1;
442 case 0x008: /* DC0 */
443 return s->board->dc0;
444 case 0x010: /* DC1 */
445 return s->board->dc1;
446 case 0x014: /* DC2 */
447 return s->board->dc2;
448 case 0x018: /* DC3 */
449 return s->board->dc3;
450 case 0x01c: /* DC4 */
451 return s->board->dc4;
452 case 0x030: /* PBORCTL */
453 return s->pborctl;
454 case 0x034: /* LDOPCTL */
455 return s->ldopctl;
456 case 0x040: /* SRCR0 */
457 return 0;
458 case 0x044: /* SRCR1 */
459 return 0;
460 case 0x048: /* SRCR2 */
461 return 0;
462 case 0x050: /* RIS */
463 return s->int_status;
464 case 0x054: /* IMC */
465 return s->int_mask;
466 case 0x058: /* MISC */
467 return s->int_status & s->int_mask;
468 case 0x05c: /* RESC */
469 return s->resc;
470 case 0x060: /* RCC */
471 return s->rcc;
472 case 0x064: /* PLLCFG */
474 int xtal;
475 xtal = (s->rcc >> 6) & 0xf;
476 if (s->board->did0 & (1 << 16)) {
477 return pllcfg_fury[xtal];
478 } else {
479 return pllcfg_sandstorm[xtal];
482 case 0x100: /* RCGC0 */
483 return s->rcgc[0];
484 case 0x104: /* RCGC1 */
485 return s->rcgc[1];
486 case 0x108: /* RCGC2 */
487 return s->rcgc[2];
488 case 0x110: /* SCGC0 */
489 return s->scgc[0];
490 case 0x114: /* SCGC1 */
491 return s->scgc[1];
492 case 0x118: /* SCGC2 */
493 return s->scgc[2];
494 case 0x120: /* DCGC0 */
495 return s->dcgc[0];
496 case 0x124: /* DCGC1 */
497 return s->dcgc[1];
498 case 0x128: /* DCGC2 */
499 return s->dcgc[2];
500 case 0x150: /* CLKVCLR */
501 return s->clkvclr;
502 case 0x160: /* LDOARST */
503 return s->ldoarst;
504 case 0x1e0: /* USER0 */
505 return s->user0;
506 case 0x1e4: /* USER1 */
507 return s->user1;
508 default:
509 cpu_abort(cpu_single_env, "ssys_read: Bad offset 0x%x\n", (int)offset);
510 return 0;
514 static void ssys_calculate_system_clock(ssys_state *s)
516 system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
519 static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value)
521 ssys_state *s = (ssys_state *)opaque;
523 offset -= s->base;
524 switch (offset) {
525 case 0x030: /* PBORCTL */
526 s->pborctl = value & 0xffff;
527 break;
528 case 0x034: /* LDOPCTL */
529 s->ldopctl = value & 0x1f;
530 break;
531 case 0x040: /* SRCR0 */
532 case 0x044: /* SRCR1 */
533 case 0x048: /* SRCR2 */
534 fprintf(stderr, "Peripheral reset not implemented\n");
535 break;
536 case 0x054: /* IMC */
537 s->int_mask = value & 0x7f;
538 break;
539 case 0x058: /* MISC */
540 s->int_status &= ~value;
541 break;
542 case 0x05c: /* RESC */
543 s->resc = value & 0x3f;
544 break;
545 case 0x060: /* RCC */
546 if ((s->rcc & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
547 /* PLL enable. */
548 s->int_status |= (1 << 6);
550 s->rcc = value;
551 ssys_calculate_system_clock(s);
552 break;
553 case 0x100: /* RCGC0 */
554 s->rcgc[0] = value;
555 break;
556 case 0x104: /* RCGC1 */
557 s->rcgc[1] = value;
558 break;
559 case 0x108: /* RCGC2 */
560 s->rcgc[2] = value;
561 break;
562 case 0x110: /* SCGC0 */
563 s->scgc[0] = value;
564 break;
565 case 0x114: /* SCGC1 */
566 s->scgc[1] = value;
567 break;
568 case 0x118: /* SCGC2 */
569 s->scgc[2] = value;
570 break;
571 case 0x120: /* DCGC0 */
572 s->dcgc[0] = value;
573 break;
574 case 0x124: /* DCGC1 */
575 s->dcgc[1] = value;
576 break;
577 case 0x128: /* DCGC2 */
578 s->dcgc[2] = value;
579 break;
580 case 0x150: /* CLKVCLR */
581 s->clkvclr = value;
582 break;
583 case 0x160: /* LDOARST */
584 s->ldoarst = value;
585 break;
586 default:
587 cpu_abort(cpu_single_env, "ssys_write: Bad offset 0x%x\n", (int)offset);
589 ssys_update(s);
592 static CPUReadMemoryFunc *ssys_readfn[] = {
593 ssys_read,
594 ssys_read,
595 ssys_read
598 static CPUWriteMemoryFunc *ssys_writefn[] = {
599 ssys_write,
600 ssys_write,
601 ssys_write
604 static void ssys_reset(void *opaque)
606 ssys_state *s = (ssys_state *)opaque;
608 s->pborctl = 0x7ffd;
609 s->rcc = 0x078e3ac0;
610 s->rcgc[0] = 1;
611 s->scgc[0] = 1;
612 s->dcgc[0] = 1;
615 static void ssys_save(QEMUFile *f, void *opaque)
617 ssys_state *s = (ssys_state *)opaque;
619 qemu_put_be32(f, s->pborctl);
620 qemu_put_be32(f, s->ldopctl);
621 qemu_put_be32(f, s->int_mask);
622 qemu_put_be32(f, s->int_status);
623 qemu_put_be32(f, s->resc);
624 qemu_put_be32(f, s->rcc);
625 qemu_put_be32(f, s->rcgc[0]);
626 qemu_put_be32(f, s->rcgc[1]);
627 qemu_put_be32(f, s->rcgc[2]);
628 qemu_put_be32(f, s->scgc[0]);
629 qemu_put_be32(f, s->scgc[1]);
630 qemu_put_be32(f, s->scgc[2]);
631 qemu_put_be32(f, s->dcgc[0]);
632 qemu_put_be32(f, s->dcgc[1]);
633 qemu_put_be32(f, s->dcgc[2]);
634 qemu_put_be32(f, s->clkvclr);
635 qemu_put_be32(f, s->ldoarst);
638 static int ssys_load(QEMUFile *f, void *opaque, int version_id)
640 ssys_state *s = (ssys_state *)opaque;
642 if (version_id != 1)
643 return -EINVAL;
645 s->pborctl = qemu_get_be32(f);
646 s->ldopctl = qemu_get_be32(f);
647 s->int_mask = qemu_get_be32(f);
648 s->int_status = qemu_get_be32(f);
649 s->resc = qemu_get_be32(f);
650 s->rcc = qemu_get_be32(f);
651 s->rcgc[0] = qemu_get_be32(f);
652 s->rcgc[1] = qemu_get_be32(f);
653 s->rcgc[2] = qemu_get_be32(f);
654 s->scgc[0] = qemu_get_be32(f);
655 s->scgc[1] = qemu_get_be32(f);
656 s->scgc[2] = qemu_get_be32(f);
657 s->dcgc[0] = qemu_get_be32(f);
658 s->dcgc[1] = qemu_get_be32(f);
659 s->dcgc[2] = qemu_get_be32(f);
660 s->clkvclr = qemu_get_be32(f);
661 s->ldoarst = qemu_get_be32(f);
662 ssys_calculate_system_clock(s);
664 return 0;
667 static void stellaris_sys_init(uint32_t base, qemu_irq irq,
668 stellaris_board_info * board,
669 uint8_t *macaddr)
671 int iomemtype;
672 ssys_state *s;
674 s = (ssys_state *)qemu_mallocz(sizeof(ssys_state));
675 s->base = base;
676 s->irq = irq;
677 s->board = board;
678 /* Most devices come preprogrammed with a MAC address in the user data. */
679 s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
680 s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
682 iomemtype = cpu_register_io_memory(0, ssys_readfn,
683 ssys_writefn, s);
684 cpu_register_physical_memory(base, 0x00001000, iomemtype);
685 ssys_reset(s);
686 register_savevm("stellaris_sys", -1, 1, ssys_save, ssys_load, s);
690 /* I2C controller. */
692 typedef struct {
693 i2c_bus *bus;
694 qemu_irq irq;
695 uint32_t base;
696 uint32_t msa;
697 uint32_t mcs;
698 uint32_t mdr;
699 uint32_t mtpr;
700 uint32_t mimr;
701 uint32_t mris;
702 uint32_t mcr;
703 } stellaris_i2c_state;
705 #define STELLARIS_I2C_MCS_BUSY 0x01
706 #define STELLARIS_I2C_MCS_ERROR 0x02
707 #define STELLARIS_I2C_MCS_ADRACK 0x04
708 #define STELLARIS_I2C_MCS_DATACK 0x08
709 #define STELLARIS_I2C_MCS_ARBLST 0x10
710 #define STELLARIS_I2C_MCS_IDLE 0x20
711 #define STELLARIS_I2C_MCS_BUSBSY 0x40
713 static uint32_t stellaris_i2c_read(void *opaque, target_phys_addr_t offset)
715 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
717 offset -= s->base;
718 switch (offset) {
719 case 0x00: /* MSA */
720 return s->msa;
721 case 0x04: /* MCS */
722 /* We don't emulate timing, so the controller is never busy. */
723 return s->mcs | STELLARIS_I2C_MCS_IDLE;
724 case 0x08: /* MDR */
725 return s->mdr;
726 case 0x0c: /* MTPR */
727 return s->mtpr;
728 case 0x10: /* MIMR */
729 return s->mimr;
730 case 0x14: /* MRIS */
731 return s->mris;
732 case 0x18: /* MMIS */
733 return s->mris & s->mimr;
734 case 0x20: /* MCR */
735 return s->mcr;
736 default:
737 cpu_abort(cpu_single_env, "strllaris_i2c_read: Bad offset 0x%x\n",
738 (int)offset);
739 return 0;
743 static void stellaris_i2c_update(stellaris_i2c_state *s)
745 int level;
747 level = (s->mris & s->mimr) != 0;
748 qemu_set_irq(s->irq, level);
751 static void stellaris_i2c_write(void *opaque, target_phys_addr_t offset,
752 uint32_t value)
754 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
756 offset -= s->base;
757 switch (offset) {
758 case 0x00: /* MSA */
759 s->msa = value & 0xff;
760 break;
761 case 0x04: /* MCS */
762 if ((s->mcr & 0x10) == 0) {
763 /* Disabled. Do nothing. */
764 break;
766 /* Grab the bus if this is starting a transfer. */
767 if ((value & 2) && (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
768 if (i2c_start_transfer(s->bus, s->msa >> 1, s->msa & 1)) {
769 s->mcs |= STELLARIS_I2C_MCS_ARBLST;
770 } else {
771 s->mcs &= ~STELLARIS_I2C_MCS_ARBLST;
772 s->mcs |= STELLARIS_I2C_MCS_BUSBSY;
775 /* If we don't have the bus then indicate an error. */
776 if (!i2c_bus_busy(s->bus)
777 || (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
778 s->mcs |= STELLARIS_I2C_MCS_ERROR;
779 break;
781 s->mcs &= ~STELLARIS_I2C_MCS_ERROR;
782 if (value & 1) {
783 /* Transfer a byte. */
784 /* TODO: Handle errors. */
785 if (s->msa & 1) {
786 /* Recv */
787 s->mdr = i2c_recv(s->bus) & 0xff;
788 } else {
789 /* Send */
790 i2c_send(s->bus, s->mdr);
792 /* Raise an interrupt. */
793 s->mris |= 1;
795 if (value & 4) {
796 /* Finish transfer. */
797 i2c_end_transfer(s->bus);
798 s->mcs &= ~STELLARIS_I2C_MCS_BUSBSY;
800 break;
801 case 0x08: /* MDR */
802 s->mdr = value & 0xff;
803 break;
804 case 0x0c: /* MTPR */
805 s->mtpr = value & 0xff;
806 break;
807 case 0x10: /* MIMR */
808 s->mimr = 1;
809 break;
810 case 0x1c: /* MICR */
811 s->mris &= ~value;
812 break;
813 case 0x20: /* MCR */
814 if (value & 1)
815 cpu_abort(cpu_single_env,
816 "stellaris_i2c_write: Loopback not implemented\n");
817 if (value & 0x20)
818 cpu_abort(cpu_single_env,
819 "stellaris_i2c_write: Slave mode not implemented\n");
820 s->mcr = value & 0x31;
821 break;
822 default:
823 cpu_abort(cpu_single_env, "stellaris_i2c_write: Bad offset 0x%x\n",
824 (int)offset);
826 stellaris_i2c_update(s);
829 static void stellaris_i2c_reset(stellaris_i2c_state *s)
831 if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
832 i2c_end_transfer(s->bus);
834 s->msa = 0;
835 s->mcs = 0;
836 s->mdr = 0;
837 s->mtpr = 1;
838 s->mimr = 0;
839 s->mris = 0;
840 s->mcr = 0;
841 stellaris_i2c_update(s);
844 static CPUReadMemoryFunc *stellaris_i2c_readfn[] = {
845 stellaris_i2c_read,
846 stellaris_i2c_read,
847 stellaris_i2c_read
850 static CPUWriteMemoryFunc *stellaris_i2c_writefn[] = {
851 stellaris_i2c_write,
852 stellaris_i2c_write,
853 stellaris_i2c_write
856 static void stellaris_i2c_save(QEMUFile *f, void *opaque)
858 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
860 qemu_put_be32(f, s->msa);
861 qemu_put_be32(f, s->mcs);
862 qemu_put_be32(f, s->mdr);
863 qemu_put_be32(f, s->mtpr);
864 qemu_put_be32(f, s->mimr);
865 qemu_put_be32(f, s->mris);
866 qemu_put_be32(f, s->mcr);
869 static int stellaris_i2c_load(QEMUFile *f, void *opaque, int version_id)
871 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
873 if (version_id != 1)
874 return -EINVAL;
876 s->msa = qemu_get_be32(f);
877 s->mcs = qemu_get_be32(f);
878 s->mdr = qemu_get_be32(f);
879 s->mtpr = qemu_get_be32(f);
880 s->mimr = qemu_get_be32(f);
881 s->mris = qemu_get_be32(f);
882 s->mcr = qemu_get_be32(f);
884 return 0;
887 static void stellaris_i2c_init(uint32_t base, qemu_irq irq, i2c_bus *bus)
889 stellaris_i2c_state *s;
890 int iomemtype;
892 s = (stellaris_i2c_state *)qemu_mallocz(sizeof(stellaris_i2c_state));
893 s->base = base;
894 s->irq = irq;
895 s->bus = bus;
897 iomemtype = cpu_register_io_memory(0, stellaris_i2c_readfn,
898 stellaris_i2c_writefn, s);
899 cpu_register_physical_memory(base, 0x00001000, iomemtype);
900 /* ??? For now we only implement the master interface. */
901 stellaris_i2c_reset(s);
902 register_savevm("stellaris_i2c", -1, 1,
903 stellaris_i2c_save, stellaris_i2c_load, s);
906 /* Analogue to Digital Converter. This is only partially implemented,
907 enough for applications that use a combined ADC and timer tick. */
909 #define STELLARIS_ADC_EM_CONTROLLER 0
910 #define STELLARIS_ADC_EM_COMP 1
911 #define STELLARIS_ADC_EM_EXTERNAL 4
912 #define STELLARIS_ADC_EM_TIMER 5
913 #define STELLARIS_ADC_EM_PWM0 6
914 #define STELLARIS_ADC_EM_PWM1 7
915 #define STELLARIS_ADC_EM_PWM2 8
917 #define STELLARIS_ADC_FIFO_EMPTY 0x0100
918 #define STELLARIS_ADC_FIFO_FULL 0x1000
920 typedef struct
922 uint32_t base;
923 uint32_t actss;
924 uint32_t ris;
925 uint32_t im;
926 uint32_t emux;
927 uint32_t ostat;
928 uint32_t ustat;
929 uint32_t sspri;
930 uint32_t sac;
931 struct {
932 uint32_t state;
933 uint32_t data[16];
934 } fifo[4];
935 uint32_t ssmux[4];
936 uint32_t ssctl[4];
937 uint32_t noise;
938 qemu_irq irq;
939 } stellaris_adc_state;
941 static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
943 int tail;
945 tail = s->fifo[n].state & 0xf;
946 if (s->fifo[n].state & STELLARIS_ADC_FIFO_EMPTY) {
947 s->ustat |= 1 << n;
948 } else {
949 s->fifo[n].state = (s->fifo[n].state & ~0xf) | ((tail + 1) & 0xf);
950 s->fifo[n].state &= ~STELLARIS_ADC_FIFO_FULL;
951 if (tail + 1 == ((s->fifo[n].state >> 4) & 0xf))
952 s->fifo[n].state |= STELLARIS_ADC_FIFO_EMPTY;
954 return s->fifo[n].data[tail];
957 static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
958 uint32_t value)
960 int head;
962 head = (s->fifo[n].state >> 4) & 0xf;
963 if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) {
964 s->ostat |= 1 << n;
965 return;
967 s->fifo[n].data[head] = value;
968 head = (head + 1) & 0xf;
969 s->fifo[n].state &= ~STELLARIS_ADC_FIFO_EMPTY;
970 s->fifo[n].state = (s->fifo[n].state & ~0xf0) | (head << 4);
971 if ((s->fifo[n].state & 0xf) == head)
972 s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL;
975 static void stellaris_adc_update(stellaris_adc_state *s)
977 int level;
979 level = (s->ris & s->im) != 0;
980 qemu_set_irq(s->irq, level);
983 static void stellaris_adc_trigger(void *opaque, int irq, int level)
985 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
987 if ((s->actss & 1) == 0) {
988 return;
991 /* Some applications use the ADC as a random number source, so introduce
992 some variation into the signal. */
993 s->noise = s->noise * 314159 + 1;
994 /* ??? actual inputs not implemented. Return an arbitrary value. */
995 stellaris_adc_fifo_write(s, 0, 0x200 + ((s->noise >> 16) & 7));
996 s->ris |= 1;
997 stellaris_adc_update(s);
1000 static void stellaris_adc_reset(stellaris_adc_state *s)
1002 int n;
1004 for (n = 0; n < 4; n++) {
1005 s->ssmux[n] = 0;
1006 s->ssctl[n] = 0;
1007 s->fifo[n].state = STELLARIS_ADC_FIFO_EMPTY;
1011 static uint32_t stellaris_adc_read(void *opaque, target_phys_addr_t offset)
1013 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1015 /* TODO: Implement this. */
1016 offset -= s->base;
1017 if (offset >= 0x40 && offset < 0xc0) {
1018 int n;
1019 n = (offset - 0x40) >> 5;
1020 switch (offset & 0x1f) {
1021 case 0x00: /* SSMUX */
1022 return s->ssmux[n];
1023 case 0x04: /* SSCTL */
1024 return s->ssctl[n];
1025 case 0x08: /* SSFIFO */
1026 return stellaris_adc_fifo_read(s, n);
1027 case 0x0c: /* SSFSTAT */
1028 return s->fifo[n].state;
1029 default:
1030 break;
1033 switch (offset) {
1034 case 0x00: /* ACTSS */
1035 return s->actss;
1036 case 0x04: /* RIS */
1037 return s->ris;
1038 case 0x08: /* IM */
1039 return s->im;
1040 case 0x0c: /* ISC */
1041 return s->ris & s->im;
1042 case 0x10: /* OSTAT */
1043 return s->ostat;
1044 case 0x14: /* EMUX */
1045 return s->emux;
1046 case 0x18: /* USTAT */
1047 return s->ustat;
1048 case 0x20: /* SSPRI */
1049 return s->sspri;
1050 case 0x30: /* SAC */
1051 return s->sac;
1052 default:
1053 cpu_abort(cpu_single_env, "strllaris_adc_read: Bad offset 0x%x\n",
1054 (int)offset);
1055 return 0;
1059 static void stellaris_adc_write(void *opaque, target_phys_addr_t offset,
1060 uint32_t value)
1062 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1064 /* TODO: Implement this. */
1065 offset -= s->base;
1066 if (offset >= 0x40 && offset < 0xc0) {
1067 int n;
1068 n = (offset - 0x40) >> 5;
1069 switch (offset & 0x1f) {
1070 case 0x00: /* SSMUX */
1071 s->ssmux[n] = value & 0x33333333;
1072 return;
1073 case 0x04: /* SSCTL */
1074 if (value != 6) {
1075 cpu_abort(cpu_single_env, "ADC: Unimplemented sequence %x\n",
1076 value);
1078 s->ssctl[n] = value;
1079 return;
1080 default:
1081 break;
1084 switch (offset) {
1085 case 0x00: /* ACTSS */
1086 s->actss = value & 0xf;
1087 if (value & 0xe) {
1088 cpu_abort(cpu_single_env,
1089 "Not implemented: ADC sequencers 1-3\n");
1091 break;
1092 case 0x08: /* IM */
1093 s->im = value;
1094 break;
1095 case 0x0c: /* ISC */
1096 s->ris &= ~value;
1097 break;
1098 case 0x10: /* OSTAT */
1099 s->ostat &= ~value;
1100 break;
1101 case 0x14: /* EMUX */
1102 s->emux = value;
1103 break;
1104 case 0x18: /* USTAT */
1105 s->ustat &= ~value;
1106 break;
1107 case 0x20: /* SSPRI */
1108 s->sspri = value;
1109 break;
1110 case 0x28: /* PSSI */
1111 cpu_abort(cpu_single_env, "Not implemented: ADC sample initiate\n");
1112 break;
1113 case 0x30: /* SAC */
1114 s->sac = value;
1115 break;
1116 default:
1117 cpu_abort(cpu_single_env, "stellaris_adc_write: Bad offset 0x%x\n",
1118 (int)offset);
1120 stellaris_adc_update(s);
1123 static CPUReadMemoryFunc *stellaris_adc_readfn[] = {
1124 stellaris_adc_read,
1125 stellaris_adc_read,
1126 stellaris_adc_read
1129 static CPUWriteMemoryFunc *stellaris_adc_writefn[] = {
1130 stellaris_adc_write,
1131 stellaris_adc_write,
1132 stellaris_adc_write
1135 static void stellaris_adc_save(QEMUFile *f, void *opaque)
1137 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1138 int i;
1139 int j;
1141 qemu_put_be32(f, s->actss);
1142 qemu_put_be32(f, s->ris);
1143 qemu_put_be32(f, s->im);
1144 qemu_put_be32(f, s->emux);
1145 qemu_put_be32(f, s->ostat);
1146 qemu_put_be32(f, s->ustat);
1147 qemu_put_be32(f, s->sspri);
1148 qemu_put_be32(f, s->sac);
1149 for (i = 0; i < 4; i++) {
1150 qemu_put_be32(f, s->fifo[i].state);
1151 for (j = 0; j < 16; j++) {
1152 qemu_put_be32(f, s->fifo[i].data[j]);
1154 qemu_put_be32(f, s->ssmux[i]);
1155 qemu_put_be32(f, s->ssctl[i]);
1157 qemu_put_be32(f, s->noise);
1160 static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id)
1162 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1163 int i;
1164 int j;
1166 if (version_id != 1)
1167 return -EINVAL;
1169 s->actss = qemu_get_be32(f);
1170 s->ris = qemu_get_be32(f);
1171 s->im = qemu_get_be32(f);
1172 s->emux = qemu_get_be32(f);
1173 s->ostat = qemu_get_be32(f);
1174 s->ustat = qemu_get_be32(f);
1175 s->sspri = qemu_get_be32(f);
1176 s->sac = qemu_get_be32(f);
1177 for (i = 0; i < 4; i++) {
1178 s->fifo[i].state = qemu_get_be32(f);
1179 for (j = 0; j < 16; j++) {
1180 s->fifo[i].data[j] = qemu_get_be32(f);
1182 s->ssmux[i] = qemu_get_be32(f);
1183 s->ssctl[i] = qemu_get_be32(f);
1185 s->noise = qemu_get_be32(f);
1187 return 0;
1190 static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq irq)
1192 stellaris_adc_state *s;
1193 int iomemtype;
1194 qemu_irq *qi;
1196 s = (stellaris_adc_state *)qemu_mallocz(sizeof(stellaris_adc_state));
1197 s->base = base;
1198 s->irq = irq;
1200 iomemtype = cpu_register_io_memory(0, stellaris_adc_readfn,
1201 stellaris_adc_writefn, s);
1202 cpu_register_physical_memory(base, 0x00001000, iomemtype);
1203 stellaris_adc_reset(s);
1204 qi = qemu_allocate_irqs(stellaris_adc_trigger, s, 1);
1205 register_savevm("stellaris_adc", -1, 1,
1206 stellaris_adc_save, stellaris_adc_load, s);
1207 return qi[0];
1210 /* Some boards have both an OLED controller and SD card connected to
1211 the same SSI port, with the SD card chip select connected to a
1212 GPIO pin. Technically the OLED chip select is connected to the SSI
1213 Fss pin. We do not bother emulating that as both devices should
1214 never be selected simultaneously, and our OLED controller ignores stray
1215 0xff commands that occur when deselecting the SD card. */
1217 typedef struct {
1218 ssi_xfer_cb xfer_cb[2];
1219 void *opaque[2];
1220 qemu_irq irq;
1221 int current_dev;
1222 } stellaris_ssi_bus_state;
1224 static void stellaris_ssi_bus_select(void *opaque, int irq, int level)
1226 stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1228 s->current_dev = level;
1231 static int stellaris_ssi_bus_xfer(void *opaque, int val)
1233 stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1235 return s->xfer_cb[s->current_dev](s->opaque[s->current_dev], val);
1238 static void stellaris_ssi_bus_save(QEMUFile *f, void *opaque)
1240 stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1242 qemu_put_be32(f, s->current_dev);
1245 static int stellaris_ssi_bus_load(QEMUFile *f, void *opaque, int version_id)
1247 stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1249 if (version_id != 1)
1250 return -EINVAL;
1252 s->current_dev = qemu_get_be32(f);
1254 return 0;
1257 static void *stellaris_ssi_bus_init(qemu_irq *irqp,
1258 ssi_xfer_cb cb0, void *opaque0,
1259 ssi_xfer_cb cb1, void *opaque1)
1261 qemu_irq *qi;
1262 stellaris_ssi_bus_state *s;
1264 s = (stellaris_ssi_bus_state *)qemu_mallocz(sizeof(stellaris_ssi_bus_state));
1265 s->xfer_cb[0] = cb0;
1266 s->opaque[0] = opaque0;
1267 s->xfer_cb[1] = cb1;
1268 s->opaque[1] = opaque1;
1269 qi = qemu_allocate_irqs(stellaris_ssi_bus_select, s, 1);
1270 *irqp = *qi;
1271 register_savevm("stellaris_ssi_bus", -1, 1,
1272 stellaris_ssi_bus_save, stellaris_ssi_bus_load, s);
1273 return s;
1276 /* Board init. */
1277 static stellaris_board_info stellaris_boards[] = {
1278 { "LM3S811EVB",
1280 0x0032000e,
1281 0x001f001f, /* dc0 */
1282 0x001132bf,
1283 0x01071013,
1284 0x3f0f01ff,
1285 0x0000001f,
1286 BP_OLED_I2C
1288 { "LM3S6965EVB",
1289 0x10010002,
1290 0x1073402e,
1291 0x00ff007f, /* dc0 */
1292 0x001133ff,
1293 0x030f5317,
1294 0x0f0f87ff,
1295 0x5000007f,
1296 BP_OLED_SSI | BP_GAMEPAD
1300 static void stellaris_init(const char *kernel_filename, const char *cpu_model,
1301 DisplayState *ds, stellaris_board_info *board)
1303 static const int uart_irq[] = {5, 6, 33, 34};
1304 static const int timer_irq[] = {19, 21, 23, 35};
1305 static const uint32_t gpio_addr[7] =
1306 { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
1307 0x40024000, 0x40025000, 0x40026000};
1308 static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
1310 qemu_irq *pic;
1311 qemu_irq *gpio_in[5];
1312 qemu_irq *gpio_out[5];
1313 qemu_irq adc;
1314 int sram_size;
1315 int flash_size;
1316 i2c_bus *i2c;
1317 int i;
1319 flash_size = ((board->dc0 & 0xffff) + 1) << 1;
1320 sram_size = (board->dc0 >> 18) + 1;
1321 pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
1323 if (board->dc1 & (1 << 16)) {
1324 adc = stellaris_adc_init(0x40038000, pic[14]);
1325 } else {
1326 adc = NULL;
1328 for (i = 0; i < 4; i++) {
1329 if (board->dc2 & (0x10000 << i)) {
1330 stellaris_gptm_init(0x40030000 + i * 0x1000,
1331 pic[timer_irq[i]], adc);
1335 stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr);
1337 for (i = 0; i < 7; i++) {
1338 if (board->dc4 & (1 << i)) {
1339 gpio_in[i] = pl061_init(gpio_addr[i], pic[gpio_irq[i]],
1340 &gpio_out[i]);
1344 if (board->dc2 & (1 << 12)) {
1345 i2c = i2c_init_bus();
1346 stellaris_i2c_init(0x40020000, pic[8], i2c);
1347 if (board->peripherals & BP_OLED_I2C) {
1348 ssd0303_init(ds, i2c, 0x3d);
1352 for (i = 0; i < 4; i++) {
1353 if (board->dc2 & (1 << i)) {
1354 pl011_init(0x4000c000 + i * 0x1000, pic[uart_irq[i]],
1355 serial_hds[i], PL011_LUMINARY);
1358 if (board->dc2 & (1 << 4)) {
1359 if (board->peripherals & BP_OLED_SSI) {
1360 void * oled;
1361 void * sd;
1362 void *ssi_bus;
1363 int index;
1365 oled = ssd0323_init(ds, &gpio_out[GPIO_C][7]);
1366 index = drive_get_index(IF_SD, 0, 0);
1367 sd = ssi_sd_init(drives_table[index].bdrv);
1369 ssi_bus = stellaris_ssi_bus_init(&gpio_out[GPIO_D][0],
1370 ssi_sd_xfer, sd,
1371 ssd0323_xfer_ssi, oled);
1373 pl022_init(0x40008000, pic[7], stellaris_ssi_bus_xfer, ssi_bus);
1374 /* Make sure the select pin is high. */
1375 qemu_irq_raise(gpio_out[GPIO_D][0]);
1376 } else {
1377 pl022_init(0x40008000, pic[7], NULL, NULL);
1380 if (board->dc4 & (1 << 28)) {
1381 /* FIXME: Obey network model. */
1382 stellaris_enet_init(&nd_table[0], 0x40048000, pic[42]);
1384 if (board->peripherals & BP_GAMEPAD) {
1385 qemu_irq gpad_irq[5];
1386 static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
1388 gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */
1389 gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */
1390 gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */
1391 gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */
1392 gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */
1394 stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
1398 /* FIXME: Figure out how to generate these from stellaris_boards. */
1399 static void lm3s811evb_init(ram_addr_t ram_size, int vga_ram_size,
1400 const char *boot_device, DisplayState *ds,
1401 const char *kernel_filename, const char *kernel_cmdline,
1402 const char *initrd_filename, const char *cpu_model)
1404 stellaris_init(kernel_filename, cpu_model, ds, &stellaris_boards[0]);
1407 static void lm3s6965evb_init(ram_addr_t ram_size, int vga_ram_size,
1408 const char *boot_device, DisplayState *ds,
1409 const char *kernel_filename, const char *kernel_cmdline,
1410 const char *initrd_filename, const char *cpu_model)
1412 stellaris_init(kernel_filename, cpu_model, ds, &stellaris_boards[1]);
1415 QEMUMachine lm3s811evb_machine = {
1416 "lm3s811evb",
1417 "Stellaris LM3S811EVB",
1418 lm3s811evb_init,
1419 (64 * 1024 + 8 * 1024) | RAMSIZE_FIXED,
1422 QEMUMachine lm3s6965evb_machine = {
1423 "lm3s6965evb",
1424 "Stellaris LM3S6965EVB",
1425 lm3s6965evb_init,
1426 (256 * 1024 + 64 * 1024) | RAMSIZE_FIXED,