Commit e33d8cdb556cf20b0452d24cee82562ee5ee9ada

Authored by balrog
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
Makefile.target
@@ -585,7 +585,7 @@ OBJS+= arm-semi.o @@ -585,7 +585,7 @@ OBJS+= arm-semi.o
585 OBJS+= pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o 585 OBJS+= pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o
586 OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o 586 OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o
587 OBJS+= pflash_cfi01.o gumstix.o 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 OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o 589 OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o
590 OBJS+= omap2.o omap_dss.o 590 OBJS+= omap2.o omap_dss.o
591 OBJS+= palm.o tsc210x.o 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,6 +16,7 @@
16 #include "flash.h" 16 #include "flash.h"
17 #include "qemu-timer.h" 17 #include "qemu-timer.h"
18 #include "devices.h" 18 #include "devices.h"
  19 +#include "sharpsl.h"
19 #include "console.h" 20 #include "console.h"
20 #include "block.h" 21 #include "block.h"
21 #include "audio/audio.h" 22 #include "audio/audio.h"
@@ -520,238 +521,6 @@ static void spitz_keyboard_register(struct pxa2xx_state_s *cpu) @@ -520,238 +521,6 @@ static void spitz_keyboard_register(struct pxa2xx_state_s *cpu)
520 spitz_keyboard_save, spitz_keyboard_load, s); 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 /* LCD backlight controller */ 524 /* LCD backlight controller */
756 525
757 #define LCDTG_RESCTL 0x00 526 #define LCDTG_RESCTL 0x00
@@ -1050,21 +819,21 @@ static void spitz_out_switch(void *opaque, int line, int level) @@ -1050,21 +819,21 @@ static void spitz_out_switch(void *opaque, int line, int level)
1050 #define SPITZ_SCP2_MIC_BIAS 9 819 #define SPITZ_SCP2_MIC_BIAS 9
1051 820
1052 static void spitz_scoop_gpio_setup(struct pxa2xx_state_s *cpu, 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 qemu_irq *outsignals = qemu_allocate_irqs(spitz_out_switch, cpu, 8); 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 #define SPITZ_GPIO_HSYNC 22 839 #define SPITZ_GPIO_HSYNC 22
@@ -1134,49 +903,6 @@ static void spitz_gpio_setup(struct pxa2xx_state_s *cpu, int slots) @@ -1134,49 +903,6 @@ static void spitz_gpio_setup(struct pxa2xx_state_s *cpu, int slots)
1134 spitz_gpio_invert[4]); 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 /* Board init. */ 906 /* Board init. */
1181 enum spitz_model_e { spitz, akita, borzoi, terrier }; 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,7 +920,7 @@ static void spitz_common_init(ram_addr_t ram_size, int vga_ram_size,
1194 const char *cpu_model, enum spitz_model_e model, int arm_id) 920 const char *cpu_model, enum spitz_model_e model, int arm_id)
1195 { 921 {
1196 struct pxa2xx_state_s *cpu; 922 struct pxa2xx_state_s *cpu;
1197 - struct scoop_info_s *scp; 923 + struct scoop_info_s *scp0, *scp1 = NULL;
1198 924
1199 if (!cpu_model) 925 if (!cpu_model)
1200 cpu_model = (model == terrier) ? "pxa270-c5" : "pxa270-c0"; 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,9 +943,12 @@ static void spitz_common_init(ram_addr_t ram_size, int vga_ram_size,
1217 943
1218 spitz_ssp_attach(cpu); 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 spitz_gpio_setup(cpu, (model == akita) ? 1 : 2); 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 +}