Commit e33d8cdb556cf20b0452d24cee82562ee5ee9ada
1 parent
5c49b363
Factor out common SharpSL PDA code (Dmitry Baryshkov).
Factor out to sharpsl code to support devices that are present not only in spitz-family PDAs but also in outher Sharp Zaurus PDAs Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4642 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
324 additions
and
288 deletions
Makefile.target
... | ... | @@ -585,7 +585,7 @@ OBJS+= arm-semi.o |
585 | 585 | OBJS+= pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o |
586 | 586 | OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o |
587 | 587 | OBJS+= pflash_cfi01.o gumstix.o |
588 | -OBJS+= spitz.o ide.o serial.o nand.o ecc.o | |
588 | +OBJS+= spitz.o zaurus.o ide.o serial.o nand.o ecc.o | |
589 | 589 | OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o |
590 | 590 | OBJS+= omap2.o omap_dss.o |
591 | 591 | OBJS+= palm.o tsc210x.o | ... | ... |
hw/sharpsl.h
0 → 100644
1 | +#ifndef QEMU_SHARPSL_H | |
2 | +#define QEMU_SHARPSL_H | |
3 | + | |
4 | +/* zaurus.c */ | |
5 | +struct scoop_info_s *scoop_init(struct pxa2xx_state_s *cpu, | |
6 | + int instance, target_phys_addr_t target_base); | |
7 | +void scoop_gpio_set(void *opaque, int line, int level); | |
8 | +qemu_irq *scoop_gpio_in_get(struct scoop_info_s *s); | |
9 | +void scoop_gpio_out_set(struct scoop_info_s *s, int line, | |
10 | + qemu_irq handler); | |
11 | + | |
12 | +#define SL_PXA_PARAM_BASE 0xa0000a00 | |
13 | +void sl_bootparam_write(uint32_t ptr); | |
14 | + | |
15 | +#endif | ... | ... |
hw/spitz.c
... | ... | @@ -16,6 +16,7 @@ |
16 | 16 | #include "flash.h" |
17 | 17 | #include "qemu-timer.h" |
18 | 18 | #include "devices.h" |
19 | +#include "sharpsl.h" | |
19 | 20 | #include "console.h" |
20 | 21 | #include "block.h" |
21 | 22 | #include "audio/audio.h" |
... | ... | @@ -520,238 +521,6 @@ static void spitz_keyboard_register(struct pxa2xx_state_s *cpu) |
520 | 521 | spitz_keyboard_save, spitz_keyboard_load, s); |
521 | 522 | } |
522 | 523 | |
523 | -/* SCOOP devices */ | |
524 | - | |
525 | -struct scoop_info_s { | |
526 | - target_phys_addr_t target_base; | |
527 | - qemu_irq handler[16]; | |
528 | - qemu_irq *in; | |
529 | - uint16_t status; | |
530 | - uint16_t power; | |
531 | - uint32_t gpio_level; | |
532 | - uint32_t gpio_dir; | |
533 | - uint32_t prev_level; | |
534 | - | |
535 | - uint16_t mcr; | |
536 | - uint16_t cdr; | |
537 | - uint16_t ccr; | |
538 | - uint16_t irr; | |
539 | - uint16_t imr; | |
540 | - uint16_t isr; | |
541 | - uint16_t gprr; | |
542 | -}; | |
543 | - | |
544 | -#define SCOOP_MCR 0x00 | |
545 | -#define SCOOP_CDR 0x04 | |
546 | -#define SCOOP_CSR 0x08 | |
547 | -#define SCOOP_CPR 0x0c | |
548 | -#define SCOOP_CCR 0x10 | |
549 | -#define SCOOP_IRR_IRM 0x14 | |
550 | -#define SCOOP_IMR 0x18 | |
551 | -#define SCOOP_ISR 0x1c | |
552 | -#define SCOOP_GPCR 0x20 | |
553 | -#define SCOOP_GPWR 0x24 | |
554 | -#define SCOOP_GPRR 0x28 | |
555 | - | |
556 | -static inline void scoop_gpio_handler_update(struct scoop_info_s *s) { | |
557 | - uint32_t level, diff; | |
558 | - int bit; | |
559 | - level = s->gpio_level & s->gpio_dir; | |
560 | - | |
561 | - for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) { | |
562 | - bit = ffs(diff) - 1; | |
563 | - qemu_set_irq(s->handler[bit], (level >> bit) & 1); | |
564 | - } | |
565 | - | |
566 | - s->prev_level = level; | |
567 | -} | |
568 | - | |
569 | -static uint32_t scoop_readb(void *opaque, target_phys_addr_t addr) | |
570 | -{ | |
571 | - struct scoop_info_s *s = (struct scoop_info_s *) opaque; | |
572 | - addr -= s->target_base; | |
573 | - | |
574 | - switch (addr) { | |
575 | - case SCOOP_MCR: | |
576 | - return s->mcr; | |
577 | - case SCOOP_CDR: | |
578 | - return s->cdr; | |
579 | - case SCOOP_CSR: | |
580 | - return s->status; | |
581 | - case SCOOP_CPR: | |
582 | - return s->power; | |
583 | - case SCOOP_CCR: | |
584 | - return s->ccr; | |
585 | - case SCOOP_IRR_IRM: | |
586 | - return s->irr; | |
587 | - case SCOOP_IMR: | |
588 | - return s->imr; | |
589 | - case SCOOP_ISR: | |
590 | - return s->isr; | |
591 | - case SCOOP_GPCR: | |
592 | - return s->gpio_dir; | |
593 | - case SCOOP_GPWR: | |
594 | - return s->gpio_level; | |
595 | - case SCOOP_GPRR: | |
596 | - return s->gprr; | |
597 | - default: | |
598 | - spitz_printf("Bad register offset " REG_FMT "\n", addr); | |
599 | - } | |
600 | - | |
601 | - return 0; | |
602 | -} | |
603 | - | |
604 | -static void scoop_writeb(void *opaque, target_phys_addr_t addr, uint32_t value) | |
605 | -{ | |
606 | - struct scoop_info_s *s = (struct scoop_info_s *) opaque; | |
607 | - addr -= s->target_base; | |
608 | - value &= 0xffff; | |
609 | - | |
610 | - switch (addr) { | |
611 | - case SCOOP_MCR: | |
612 | - s->mcr = value; | |
613 | - break; | |
614 | - case SCOOP_CDR: | |
615 | - s->cdr = value; | |
616 | - break; | |
617 | - case SCOOP_CPR: | |
618 | - s->power = value; | |
619 | - if (value & 0x80) | |
620 | - s->power |= 0x8040; | |
621 | - break; | |
622 | - case SCOOP_CCR: | |
623 | - s->ccr = value; | |
624 | - break; | |
625 | - case SCOOP_IRR_IRM: | |
626 | - s->irr = value; | |
627 | - break; | |
628 | - case SCOOP_IMR: | |
629 | - s->imr = value; | |
630 | - break; | |
631 | - case SCOOP_ISR: | |
632 | - s->isr = value; | |
633 | - break; | |
634 | - case SCOOP_GPCR: | |
635 | - s->gpio_dir = value; | |
636 | - scoop_gpio_handler_update(s); | |
637 | - break; | |
638 | - case SCOOP_GPWR: | |
639 | - s->gpio_level = value & s->gpio_dir; | |
640 | - scoop_gpio_handler_update(s); | |
641 | - break; | |
642 | - case SCOOP_GPRR: | |
643 | - s->gprr = value; | |
644 | - break; | |
645 | - default: | |
646 | - spitz_printf("Bad register offset " REG_FMT "\n", addr); | |
647 | - } | |
648 | -} | |
649 | - | |
650 | -CPUReadMemoryFunc *scoop_readfn[] = { | |
651 | - scoop_readb, | |
652 | - scoop_readb, | |
653 | - scoop_readb, | |
654 | -}; | |
655 | -CPUWriteMemoryFunc *scoop_writefn[] = { | |
656 | - scoop_writeb, | |
657 | - scoop_writeb, | |
658 | - scoop_writeb, | |
659 | -}; | |
660 | - | |
661 | -static void scoop_gpio_set(void *opaque, int line, int level) | |
662 | -{ | |
663 | - struct scoop_info_s *s = (struct scoop_info_s *) s; | |
664 | - | |
665 | - if (level) | |
666 | - s->gpio_level |= (1 << line); | |
667 | - else | |
668 | - s->gpio_level &= ~(1 << line); | |
669 | -} | |
670 | - | |
671 | -static inline qemu_irq *scoop_gpio_in_get(struct scoop_info_s *s) | |
672 | -{ | |
673 | - return s->in; | |
674 | -} | |
675 | - | |
676 | -static inline void scoop_gpio_out_set(struct scoop_info_s *s, int line, | |
677 | - qemu_irq handler) { | |
678 | - if (line >= 16) { | |
679 | - spitz_printf("No GPIO pin %i\n", line); | |
680 | - return; | |
681 | - } | |
682 | - | |
683 | - s->handler[line] = handler; | |
684 | -} | |
685 | - | |
686 | -static void scoop_save(QEMUFile *f, void *opaque) | |
687 | -{ | |
688 | - struct scoop_info_s *s = (struct scoop_info_s *) opaque; | |
689 | - qemu_put_be16s(f, &s->status); | |
690 | - qemu_put_be16s(f, &s->power); | |
691 | - qemu_put_be32s(f, &s->gpio_level); | |
692 | - qemu_put_be32s(f, &s->gpio_dir); | |
693 | - qemu_put_be32s(f, &s->prev_level); | |
694 | - qemu_put_be16s(f, &s->mcr); | |
695 | - qemu_put_be16s(f, &s->cdr); | |
696 | - qemu_put_be16s(f, &s->ccr); | |
697 | - qemu_put_be16s(f, &s->irr); | |
698 | - qemu_put_be16s(f, &s->imr); | |
699 | - qemu_put_be16s(f, &s->isr); | |
700 | - qemu_put_be16s(f, &s->gprr); | |
701 | -} | |
702 | - | |
703 | -static int scoop_load(QEMUFile *f, void *opaque, int version_id) | |
704 | -{ | |
705 | - struct scoop_info_s *s = (struct scoop_info_s *) opaque; | |
706 | - qemu_get_be16s(f, &s->status); | |
707 | - qemu_get_be16s(f, &s->power); | |
708 | - qemu_get_be32s(f, &s->gpio_level); | |
709 | - qemu_get_be32s(f, &s->gpio_dir); | |
710 | - qemu_get_be32s(f, &s->prev_level); | |
711 | - qemu_get_be16s(f, &s->mcr); | |
712 | - qemu_get_be16s(f, &s->cdr); | |
713 | - qemu_get_be16s(f, &s->ccr); | |
714 | - qemu_get_be16s(f, &s->irr); | |
715 | - qemu_get_be16s(f, &s->imr); | |
716 | - qemu_get_be16s(f, &s->isr); | |
717 | - qemu_get_be16s(f, &s->gprr); | |
718 | - | |
719 | - return 0; | |
720 | -} | |
721 | - | |
722 | -static struct scoop_info_s *spitz_scoop_init(struct pxa2xx_state_s *cpu, | |
723 | - int count) { | |
724 | - int iomemtype; | |
725 | - struct scoop_info_s *s; | |
726 | - | |
727 | - s = (struct scoop_info_s *) | |
728 | - qemu_mallocz(sizeof(struct scoop_info_s) * 2); | |
729 | - memset(s, 0, sizeof(struct scoop_info_s) * count); | |
730 | - s[0].target_base = 0x10800000; | |
731 | - s[1].target_base = 0x08800040; | |
732 | - | |
733 | - /* Ready */ | |
734 | - s[0].status = 0x02; | |
735 | - s[1].status = 0x02; | |
736 | - | |
737 | - s[0].in = qemu_allocate_irqs(scoop_gpio_set, &s[0], 16); | |
738 | - iomemtype = cpu_register_io_memory(0, scoop_readfn, | |
739 | - scoop_writefn, &s[0]); | |
740 | - cpu_register_physical_memory(s[0].target_base, 0x1000, iomemtype); | |
741 | - register_savevm("scoop", 0, 0, scoop_save, scoop_load, &s[0]); | |
742 | - | |
743 | - if (count < 2) | |
744 | - return s; | |
745 | - | |
746 | - s[1].in = qemu_allocate_irqs(scoop_gpio_set, &s[1], 16); | |
747 | - iomemtype = cpu_register_io_memory(0, scoop_readfn, | |
748 | - scoop_writefn, &s[1]); | |
749 | - cpu_register_physical_memory(s[1].target_base, 0x1000, iomemtype); | |
750 | - register_savevm("scoop", 1, 0, scoop_save, scoop_load, &s[1]); | |
751 | - | |
752 | - return s; | |
753 | -} | |
754 | - | |
755 | 524 | /* LCD backlight controller */ |
756 | 525 | |
757 | 526 | #define LCDTG_RESCTL 0x00 |
... | ... | @@ -1050,21 +819,21 @@ static void spitz_out_switch(void *opaque, int line, int level) |
1050 | 819 | #define SPITZ_SCP2_MIC_BIAS 9 |
1051 | 820 | |
1052 | 821 | static void spitz_scoop_gpio_setup(struct pxa2xx_state_s *cpu, |
1053 | - struct scoop_info_s *scp, int num) | |
822 | + struct scoop_info_s *scp0, struct scoop_info_s *scp1) | |
1054 | 823 | { |
1055 | 824 | qemu_irq *outsignals = qemu_allocate_irqs(spitz_out_switch, cpu, 8); |
1056 | 825 | |
1057 | - scoop_gpio_out_set(&scp[0], SPITZ_SCP_CHRG_ON, outsignals[0]); | |
1058 | - scoop_gpio_out_set(&scp[0], SPITZ_SCP_JK_B, outsignals[1]); | |
1059 | - scoop_gpio_out_set(&scp[0], SPITZ_SCP_LED_GREEN, outsignals[2]); | |
1060 | - scoop_gpio_out_set(&scp[0], SPITZ_SCP_LED_ORANGE, outsignals[3]); | |
826 | + scoop_gpio_out_set(scp0, SPITZ_SCP_CHRG_ON, outsignals[0]); | |
827 | + scoop_gpio_out_set(scp0, SPITZ_SCP_JK_B, outsignals[1]); | |
828 | + scoop_gpio_out_set(scp0, SPITZ_SCP_LED_GREEN, outsignals[2]); | |
829 | + scoop_gpio_out_set(scp0, SPITZ_SCP_LED_ORANGE, outsignals[3]); | |
1061 | 830 | |
1062 | - if (num >= 2) { | |
1063 | - scoop_gpio_out_set(&scp[1], SPITZ_SCP2_BACKLIGHT_CONT, outsignals[4]); | |
1064 | - scoop_gpio_out_set(&scp[1], SPITZ_SCP2_BACKLIGHT_ON, outsignals[5]); | |
831 | + if (scp1) { | |
832 | + scoop_gpio_out_set(scp1, SPITZ_SCP2_BACKLIGHT_CONT, outsignals[4]); | |
833 | + scoop_gpio_out_set(scp1, SPITZ_SCP2_BACKLIGHT_ON, outsignals[5]); | |
1065 | 834 | } |
1066 | 835 | |
1067 | - scoop_gpio_out_set(&scp[0], SPITZ_SCP_ADC_TEMP_ON, outsignals[6]); | |
836 | + scoop_gpio_out_set(scp0, SPITZ_SCP_ADC_TEMP_ON, outsignals[6]); | |
1068 | 837 | } |
1069 | 838 | |
1070 | 839 | #define SPITZ_GPIO_HSYNC 22 |
... | ... | @@ -1134,49 +903,6 @@ static void spitz_gpio_setup(struct pxa2xx_state_s *cpu, int slots) |
1134 | 903 | spitz_gpio_invert[4]); |
1135 | 904 | } |
1136 | 905 | |
1137 | -/* Write the bootloader parameters memory area. */ | |
1138 | - | |
1139 | -#define MAGIC_CHG(a, b, c, d) ((d << 24) | (c << 16) | (b << 8) | a) | |
1140 | - | |
1141 | -struct __attribute__ ((__packed__)) sl_param_info { | |
1142 | - uint32_t comadj_keyword; | |
1143 | - int32_t comadj; | |
1144 | - | |
1145 | - uint32_t uuid_keyword; | |
1146 | - char uuid[16]; | |
1147 | - | |
1148 | - uint32_t touch_keyword; | |
1149 | - int32_t touch_xp; | |
1150 | - int32_t touch_yp; | |
1151 | - int32_t touch_xd; | |
1152 | - int32_t touch_yd; | |
1153 | - | |
1154 | - uint32_t adadj_keyword; | |
1155 | - int32_t adadj; | |
1156 | - | |
1157 | - uint32_t phad_keyword; | |
1158 | - int32_t phadadj; | |
1159 | -} spitz_bootparam = { | |
1160 | - .comadj_keyword = MAGIC_CHG('C', 'M', 'A', 'D'), | |
1161 | - .comadj = 125, | |
1162 | - .uuid_keyword = MAGIC_CHG('U', 'U', 'I', 'D'), | |
1163 | - .uuid = { -1 }, | |
1164 | - .touch_keyword = MAGIC_CHG('T', 'U', 'C', 'H'), | |
1165 | - .touch_xp = -1, | |
1166 | - .adadj_keyword = MAGIC_CHG('B', 'V', 'A', 'D'), | |
1167 | - .adadj = -1, | |
1168 | - .phad_keyword = MAGIC_CHG('P', 'H', 'A', 'D'), | |
1169 | - .phadadj = 0x01, | |
1170 | -}; | |
1171 | - | |
1172 | -static void sl_bootparam_write(uint32_t ptr) | |
1173 | -{ | |
1174 | - memcpy(phys_ram_base + ptr, &spitz_bootparam, | |
1175 | - sizeof(struct sl_param_info)); | |
1176 | -} | |
1177 | - | |
1178 | -#define SL_PXA_PARAM_BASE 0xa0000a00 | |
1179 | - | |
1180 | 906 | /* Board init. */ |
1181 | 907 | enum spitz_model_e { spitz, akita, borzoi, terrier }; |
1182 | 908 | |
... | ... | @@ -1194,7 +920,7 @@ static void spitz_common_init(ram_addr_t ram_size, int vga_ram_size, |
1194 | 920 | const char *cpu_model, enum spitz_model_e model, int arm_id) |
1195 | 921 | { |
1196 | 922 | struct pxa2xx_state_s *cpu; |
1197 | - struct scoop_info_s *scp; | |
923 | + struct scoop_info_s *scp0, *scp1 = NULL; | |
1198 | 924 | |
1199 | 925 | if (!cpu_model) |
1200 | 926 | cpu_model = (model == terrier) ? "pxa270-c5" : "pxa270-c0"; |
... | ... | @@ -1217,9 +943,12 @@ static void spitz_common_init(ram_addr_t ram_size, int vga_ram_size, |
1217 | 943 | |
1218 | 944 | spitz_ssp_attach(cpu); |
1219 | 945 | |
1220 | - scp = spitz_scoop_init(cpu, (model == akita) ? 1 : 2); | |
946 | + scp0 = scoop_init(cpu, 0, 0x10800000); | |
947 | + if (model != akita) { | |
948 | + scp1 = scoop_init(cpu, 1, 0x08800040); | |
949 | + } | |
1221 | 950 | |
1222 | - spitz_scoop_gpio_setup(cpu, scp, (model == akita) ? 1 : 2); | |
951 | + spitz_scoop_gpio_setup(cpu, scp0, scp1); | |
1223 | 952 | |
1224 | 953 | spitz_gpio_setup(cpu, (model == akita) ? 1 : 2); |
1225 | 954 | ... | ... |
hw/zaurus.c
0 → 100644
1 | +/* | |
2 | + * Copyright (c) 2006-2008 Openedhand Ltd. | |
3 | + * Written by Andrzej Zaborowski <balrog@zabor.org> | |
4 | + * | |
5 | + * This program is free software; you can redistribute it and/or | |
6 | + * modify it under the terms of the GNU General Public License as | |
7 | + * published by the Free Software Foundation; either version 2 or | |
8 | + * (at your option) version 3 of the License. | |
9 | + * | |
10 | + * This program is distributed in the hope that it will be useful, | |
11 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | + * GNU General Public License for more details. | |
14 | + * | |
15 | + * You should have received a copy of the GNU General Public License | |
16 | + * along with this program; if not, write to the Free Software | |
17 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
18 | + * MA 02111-1307 USA | |
19 | + */ | |
20 | +#include "hw.h" | |
21 | +#include "pxa.h" | |
22 | +#include "sharpsl.h" | |
23 | + | |
24 | +#define zaurus_printf(format, ...) \ | |
25 | + fprintf(stderr, "%s: " format, __FUNCTION__, ##__VA_ARGS__) | |
26 | +#undef REG_FMT | |
27 | +#if TARGET_PHYS_ADDR_BITS == 32 | |
28 | +#define REG_FMT "0x%02x" | |
29 | +#else | |
30 | +#define REG_FMT "0x%02lx" | |
31 | +#endif | |
32 | + | |
33 | +/* SCOOP devices */ | |
34 | + | |
35 | +struct scoop_info_s { | |
36 | + target_phys_addr_t target_base; | |
37 | + qemu_irq handler[16]; | |
38 | + qemu_irq *in; | |
39 | + uint16_t status; | |
40 | + uint16_t power; | |
41 | + uint32_t gpio_level; | |
42 | + uint32_t gpio_dir; | |
43 | + uint32_t prev_level; | |
44 | + | |
45 | + uint16_t mcr; | |
46 | + uint16_t cdr; | |
47 | + uint16_t ccr; | |
48 | + uint16_t irr; | |
49 | + uint16_t imr; | |
50 | + uint16_t isr; | |
51 | + uint16_t gprr; | |
52 | +}; | |
53 | + | |
54 | +#define SCOOP_MCR 0x00 | |
55 | +#define SCOOP_CDR 0x04 | |
56 | +#define SCOOP_CSR 0x08 | |
57 | +#define SCOOP_CPR 0x0c | |
58 | +#define SCOOP_CCR 0x10 | |
59 | +#define SCOOP_IRR_IRM 0x14 | |
60 | +#define SCOOP_IMR 0x18 | |
61 | +#define SCOOP_ISR 0x1c | |
62 | +#define SCOOP_GPCR 0x20 | |
63 | +#define SCOOP_GPWR 0x24 | |
64 | +#define SCOOP_GPRR 0x28 | |
65 | + | |
66 | +static inline void scoop_gpio_handler_update(struct scoop_info_s *s) { | |
67 | + uint32_t level, diff; | |
68 | + int bit; | |
69 | + level = s->gpio_level & s->gpio_dir; | |
70 | + | |
71 | + for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) { | |
72 | + bit = ffs(diff) - 1; | |
73 | + qemu_set_irq(s->handler[bit], (level >> bit) & 1); | |
74 | + } | |
75 | + | |
76 | + s->prev_level = level; | |
77 | +} | |
78 | + | |
79 | +static uint32_t scoop_readb(void *opaque, target_phys_addr_t addr) | |
80 | +{ | |
81 | + struct scoop_info_s *s = (struct scoop_info_s *) opaque; | |
82 | + addr -= s->target_base; | |
83 | + | |
84 | + switch (addr) { | |
85 | + case SCOOP_MCR: | |
86 | + return s->mcr; | |
87 | + case SCOOP_CDR: | |
88 | + return s->cdr; | |
89 | + case SCOOP_CSR: | |
90 | + return s->status; | |
91 | + case SCOOP_CPR: | |
92 | + return s->power; | |
93 | + case SCOOP_CCR: | |
94 | + return s->ccr; | |
95 | + case SCOOP_IRR_IRM: | |
96 | + return s->irr; | |
97 | + case SCOOP_IMR: | |
98 | + return s->imr; | |
99 | + case SCOOP_ISR: | |
100 | + return s->isr; | |
101 | + case SCOOP_GPCR: | |
102 | + return s->gpio_dir; | |
103 | + case SCOOP_GPWR: | |
104 | + return s->gpio_level; | |
105 | + case SCOOP_GPRR: | |
106 | + return s->gprr; | |
107 | + default: | |
108 | + zaurus_printf("Bad register offset " REG_FMT "\n", addr); | |
109 | + } | |
110 | + | |
111 | + return 0; | |
112 | +} | |
113 | + | |
114 | +static void scoop_writeb(void *opaque, target_phys_addr_t addr, uint32_t value) | |
115 | +{ | |
116 | + struct scoop_info_s *s = (struct scoop_info_s *) opaque; | |
117 | + addr -= s->target_base; | |
118 | + value &= 0xffff; | |
119 | + | |
120 | + switch (addr) { | |
121 | + case SCOOP_MCR: | |
122 | + s->mcr = value; | |
123 | + break; | |
124 | + case SCOOP_CDR: | |
125 | + s->cdr = value; | |
126 | + break; | |
127 | + case SCOOP_CPR: | |
128 | + s->power = value; | |
129 | + if (value & 0x80) | |
130 | + s->power |= 0x8040; | |
131 | + break; | |
132 | + case SCOOP_CCR: | |
133 | + s->ccr = value; | |
134 | + break; | |
135 | + case SCOOP_IRR_IRM: | |
136 | + s->irr = value; | |
137 | + break; | |
138 | + case SCOOP_IMR: | |
139 | + s->imr = value; | |
140 | + break; | |
141 | + case SCOOP_ISR: | |
142 | + s->isr = value; | |
143 | + break; | |
144 | + case SCOOP_GPCR: | |
145 | + s->gpio_dir = value; | |
146 | + scoop_gpio_handler_update(s); | |
147 | + break; | |
148 | + case SCOOP_GPWR: | |
149 | + s->gpio_level = value & s->gpio_dir; | |
150 | + scoop_gpio_handler_update(s); | |
151 | + break; | |
152 | + case SCOOP_GPRR: | |
153 | + s->gprr = value; | |
154 | + break; | |
155 | + default: | |
156 | + zaurus_printf("Bad register offset " REG_FMT "\n", addr); | |
157 | + } | |
158 | +} | |
159 | + | |
160 | +CPUReadMemoryFunc *scoop_readfn[] = { | |
161 | + scoop_readb, | |
162 | + scoop_readb, | |
163 | + scoop_readb, | |
164 | +}; | |
165 | +CPUWriteMemoryFunc *scoop_writefn[] = { | |
166 | + scoop_writeb, | |
167 | + scoop_writeb, | |
168 | + scoop_writeb, | |
169 | +}; | |
170 | + | |
171 | +void scoop_gpio_set(void *opaque, int line, int level) | |
172 | +{ | |
173 | + struct scoop_info_s *s = (struct scoop_info_s *) s; | |
174 | + | |
175 | + if (level) | |
176 | + s->gpio_level |= (1 << line); | |
177 | + else | |
178 | + s->gpio_level &= ~(1 << line); | |
179 | +} | |
180 | + | |
181 | +qemu_irq *scoop_gpio_in_get(struct scoop_info_s *s) | |
182 | +{ | |
183 | + return s->in; | |
184 | +} | |
185 | + | |
186 | +void scoop_gpio_out_set(struct scoop_info_s *s, int line, | |
187 | + qemu_irq handler) { | |
188 | + if (line >= 16) { | |
189 | + fprintf(stderr, "No GPIO pin %i\n", line); | |
190 | + exit(-1); | |
191 | + } | |
192 | + | |
193 | + s->handler[line] = handler; | |
194 | +} | |
195 | + | |
196 | +static void scoop_save(QEMUFile *f, void *opaque) | |
197 | +{ | |
198 | + struct scoop_info_s *s = (struct scoop_info_s *) opaque; | |
199 | + qemu_put_be16s(f, &s->status); | |
200 | + qemu_put_be16s(f, &s->power); | |
201 | + qemu_put_be32s(f, &s->gpio_level); | |
202 | + qemu_put_be32s(f, &s->gpio_dir); | |
203 | + qemu_put_be32s(f, &s->prev_level); | |
204 | + qemu_put_be16s(f, &s->mcr); | |
205 | + qemu_put_be16s(f, &s->cdr); | |
206 | + qemu_put_be16s(f, &s->ccr); | |
207 | + qemu_put_be16s(f, &s->irr); | |
208 | + qemu_put_be16s(f, &s->imr); | |
209 | + qemu_put_be16s(f, &s->isr); | |
210 | + qemu_put_be16s(f, &s->gprr); | |
211 | +} | |
212 | + | |
213 | +static int scoop_load(QEMUFile *f, void *opaque, int version_id) | |
214 | +{ | |
215 | + struct scoop_info_s *s = (struct scoop_info_s *) opaque; | |
216 | + qemu_get_be16s(f, &s->status); | |
217 | + qemu_get_be16s(f, &s->power); | |
218 | + qemu_get_be32s(f, &s->gpio_level); | |
219 | + qemu_get_be32s(f, &s->gpio_dir); | |
220 | + qemu_get_be32s(f, &s->prev_level); | |
221 | + qemu_get_be16s(f, &s->mcr); | |
222 | + qemu_get_be16s(f, &s->cdr); | |
223 | + qemu_get_be16s(f, &s->ccr); | |
224 | + qemu_get_be16s(f, &s->irr); | |
225 | + qemu_get_be16s(f, &s->imr); | |
226 | + qemu_get_be16s(f, &s->isr); | |
227 | + qemu_get_be16s(f, &s->gprr); | |
228 | + | |
229 | + return 0; | |
230 | +} | |
231 | + | |
232 | +struct scoop_info_s *scoop_init(struct pxa2xx_state_s *cpu, | |
233 | + int instance, | |
234 | + target_phys_addr_t target_base) { | |
235 | + int iomemtype; | |
236 | + struct scoop_info_s *s; | |
237 | + | |
238 | + s = (struct scoop_info_s *) | |
239 | + qemu_mallocz(sizeof(struct scoop_info_s)); | |
240 | + memset(s, 0, sizeof(struct scoop_info_s)); | |
241 | + | |
242 | + s->target_base = target_base; | |
243 | + s->status = 0x02; | |
244 | + s->in = qemu_allocate_irqs(scoop_gpio_set, s, 16); | |
245 | + iomemtype = cpu_register_io_memory(0, scoop_readfn, | |
246 | + scoop_writefn, s); | |
247 | + cpu_register_physical_memory(s->target_base, 0x1000, iomemtype); | |
248 | + register_savevm("scoop", instance, 0, scoop_save, scoop_load, s); | |
249 | + | |
250 | + return s; | |
251 | +} | |
252 | + | |
253 | +/* Write the bootloader parameters memory area. */ | |
254 | + | |
255 | +#define MAGIC_CHG(a, b, c, d) ((d << 24) | (c << 16) | (b << 8) | a) | |
256 | + | |
257 | +struct __attribute__ ((__packed__)) sl_param_info { | |
258 | + uint32_t comadj_keyword; | |
259 | + int32_t comadj; | |
260 | + | |
261 | + uint32_t uuid_keyword; | |
262 | + char uuid[16]; | |
263 | + | |
264 | + uint32_t touch_keyword; | |
265 | + int32_t touch_xp; | |
266 | + int32_t touch_yp; | |
267 | + int32_t touch_xd; | |
268 | + int32_t touch_yd; | |
269 | + | |
270 | + uint32_t adadj_keyword; | |
271 | + int32_t adadj; | |
272 | + | |
273 | + uint32_t phad_keyword; | |
274 | + int32_t phadadj; | |
275 | +} zaurus_bootparam = { | |
276 | + .comadj_keyword = MAGIC_CHG('C', 'M', 'A', 'D'), | |
277 | + .comadj = 125, | |
278 | + .uuid_keyword = MAGIC_CHG('U', 'U', 'I', 'D'), | |
279 | + .uuid = { -1 }, | |
280 | + .touch_keyword = MAGIC_CHG('T', 'U', 'C', 'H'), | |
281 | + .touch_xp = -1, | |
282 | + .adadj_keyword = MAGIC_CHG('B', 'V', 'A', 'D'), | |
283 | + .adadj = -1, | |
284 | + .phad_keyword = MAGIC_CHG('P', 'H', 'A', 'D'), | |
285 | + .phadadj = 0x01, | |
286 | +}; | |
287 | + | |
288 | +void sl_bootparam_write(uint32_t ptr) | |
289 | +{ | |
290 | + memcpy(phys_ram_base + ptr, &zaurus_bootparam, | |
291 | + sizeof(struct sl_param_info)); | |
292 | +} | ... | ... |