symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/zaurus.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 #undef REG_FMT
       
    25 #if TARGET_PHYS_ADDR_BITS == 32
       
    26 #define REG_FMT			"0x%02x"
       
    27 #else
       
    28 #define REG_FMT			"0x%02lx"
       
    29 #endif
       
    30 
       
    31 /* SCOOP devices */
       
    32 
       
    33 struct scoop_info_s {
       
    34     qemu_irq handler[16];
       
    35     qemu_irq *in;
       
    36     uint16_t status;
       
    37     uint16_t power;
       
    38     uint32_t gpio_level;
       
    39     uint32_t gpio_dir;
       
    40     uint32_t prev_level;
       
    41 
       
    42     uint16_t mcr;
       
    43     uint16_t cdr;
       
    44     uint16_t ccr;
       
    45     uint16_t irr;
       
    46     uint16_t imr;
       
    47     uint16_t isr;
       
    48 };
       
    49 
       
    50 #define SCOOP_MCR	0x00
       
    51 #define SCOOP_CDR	0x04
       
    52 #define SCOOP_CSR	0x08
       
    53 #define SCOOP_CPR	0x0c
       
    54 #define SCOOP_CCR	0x10
       
    55 #define SCOOP_IRR_IRM	0x14
       
    56 #define SCOOP_IMR	0x18
       
    57 #define SCOOP_ISR	0x1c
       
    58 #define SCOOP_GPCR	0x20
       
    59 #define SCOOP_GPWR	0x24
       
    60 #define SCOOP_GPRR	0x28
       
    61 
       
    62 static inline void scoop_gpio_handler_update(struct scoop_info_s *s) {
       
    63     uint32_t level, diff;
       
    64     int bit;
       
    65     level = s->gpio_level & s->gpio_dir;
       
    66 
       
    67     for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
       
    68         bit = ffs(diff) - 1;
       
    69         qemu_set_irq(s->handler[bit], (level >> bit) & 1);
       
    70     }
       
    71 
       
    72     s->prev_level = level;
       
    73 }
       
    74 
       
    75 static uint32_t scoop_readb(void *opaque, target_phys_addr_t addr)
       
    76 {
       
    77     struct scoop_info_s *s = (struct scoop_info_s *) opaque;
       
    78 
       
    79     switch (addr) {
       
    80     case SCOOP_MCR:
       
    81         return s->mcr;
       
    82     case SCOOP_CDR:
       
    83         return s->cdr;
       
    84     case SCOOP_CSR:
       
    85         return s->status;
       
    86     case SCOOP_CPR:
       
    87         return s->power;
       
    88     case SCOOP_CCR:
       
    89         return s->ccr;
       
    90     case SCOOP_IRR_IRM:
       
    91         return s->irr;
       
    92     case SCOOP_IMR:
       
    93         return s->imr;
       
    94     case SCOOP_ISR:
       
    95         return s->isr;
       
    96     case SCOOP_GPCR:
       
    97         return s->gpio_dir;
       
    98     case SCOOP_GPWR:
       
    99     case SCOOP_GPRR:
       
   100         return s->gpio_level;
       
   101     default:
       
   102         zaurus_printf("Bad register offset " REG_FMT "\n", addr);
       
   103     }
       
   104 
       
   105     return 0;
       
   106 }
       
   107 
       
   108 static void scoop_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
       
   109 {
       
   110     struct scoop_info_s *s = (struct scoop_info_s *) opaque;
       
   111     value &= 0xffff;
       
   112 
       
   113     switch (addr) {
       
   114     case SCOOP_MCR:
       
   115         s->mcr = value;
       
   116         break;
       
   117     case SCOOP_CDR:
       
   118         s->cdr = value;
       
   119         break;
       
   120     case SCOOP_CPR:
       
   121         s->power = value;
       
   122         if (value & 0x80)
       
   123             s->power |= 0x8040;
       
   124         break;
       
   125     case SCOOP_CCR:
       
   126         s->ccr = value;
       
   127         break;
       
   128     case SCOOP_IRR_IRM:
       
   129         s->irr = value;
       
   130         break;
       
   131     case SCOOP_IMR:
       
   132         s->imr = value;
       
   133         break;
       
   134     case SCOOP_ISR:
       
   135         s->isr = value;
       
   136         break;
       
   137     case SCOOP_GPCR:
       
   138         s->gpio_dir = value;
       
   139         scoop_gpio_handler_update(s);
       
   140         break;
       
   141     case SCOOP_GPWR:
       
   142     case SCOOP_GPRR:	/* GPRR is probably R/O in real HW */
       
   143         s->gpio_level = value & s->gpio_dir;
       
   144         scoop_gpio_handler_update(s);
       
   145         break;
       
   146     default:
       
   147         zaurus_printf("Bad register offset " REG_FMT "\n", addr);
       
   148     }
       
   149 }
       
   150 
       
   151 static CPUReadMemoryFunc *scoop_readfn[] = {
       
   152     scoop_readb,
       
   153     scoop_readb,
       
   154     scoop_readb,
       
   155 };
       
   156 static CPUWriteMemoryFunc *scoop_writefn[] = {
       
   157     scoop_writeb,
       
   158     scoop_writeb,
       
   159     scoop_writeb,
       
   160 };
       
   161 
       
   162 void scoop_gpio_set(void *opaque, int line, int level)
       
   163 {
       
   164     struct scoop_info_s *s = (struct scoop_info_s *) s;
       
   165 
       
   166     if (level)
       
   167         s->gpio_level |= (1 << line);
       
   168     else
       
   169         s->gpio_level &= ~(1 << line);
       
   170 }
       
   171 
       
   172 qemu_irq *scoop_gpio_in_get(struct scoop_info_s *s)
       
   173 {
       
   174     return s->in;
       
   175 }
       
   176 
       
   177 void scoop_gpio_out_set(struct scoop_info_s *s, int line,
       
   178                 qemu_irq handler) {
       
   179     if (line >= 16) {
       
   180         fprintf(stderr, "No GPIO pin %i\n", line);
       
   181         exit(-1);
       
   182     }
       
   183 
       
   184     s->handler[line] = handler;
       
   185 }
       
   186 
       
   187 static void scoop_save(QEMUFile *f, void *opaque)
       
   188 {
       
   189     struct scoop_info_s *s = (struct scoop_info_s *) opaque;
       
   190     qemu_put_be16s(f, &s->status);
       
   191     qemu_put_be16s(f, &s->power);
       
   192     qemu_put_be32s(f, &s->gpio_level);
       
   193     qemu_put_be32s(f, &s->gpio_dir);
       
   194     qemu_put_be32s(f, &s->prev_level);
       
   195     qemu_put_be16s(f, &s->mcr);
       
   196     qemu_put_be16s(f, &s->cdr);
       
   197     qemu_put_be16s(f, &s->ccr);
       
   198     qemu_put_be16s(f, &s->irr);
       
   199     qemu_put_be16s(f, &s->imr);
       
   200     qemu_put_be16s(f, &s->isr);
       
   201 }
       
   202 
       
   203 static int scoop_load(QEMUFile *f, void *opaque, int version_id)
       
   204 {
       
   205     uint16_t dummy;
       
   206     struct scoop_info_s *s = (struct scoop_info_s *) opaque;
       
   207     qemu_get_be16s(f, &s->status);
       
   208     qemu_get_be16s(f, &s->power);
       
   209     qemu_get_be32s(f, &s->gpio_level);
       
   210     qemu_get_be32s(f, &s->gpio_dir);
       
   211     qemu_get_be32s(f, &s->prev_level);
       
   212     qemu_get_be16s(f, &s->mcr);
       
   213     qemu_get_be16s(f, &s->cdr);
       
   214     qemu_get_be16s(f, &s->ccr);
       
   215     qemu_get_be16s(f, &s->irr);
       
   216     qemu_get_be16s(f, &s->imr);
       
   217     qemu_get_be16s(f, &s->isr);
       
   218     if (version_id < 1)
       
   219 	    qemu_get_be16s(f, &dummy);
       
   220 
       
   221     return 0;
       
   222 }
       
   223 
       
   224 struct scoop_info_s *scoop_init(struct pxa2xx_state_s *cpu,
       
   225 		int instance,
       
   226 		target_phys_addr_t target_base) {
       
   227     int iomemtype;
       
   228     struct scoop_info_s *s;
       
   229 
       
   230     s = (struct scoop_info_s *)
       
   231             qemu_mallocz(sizeof(struct scoop_info_s));
       
   232     memset(s, 0, sizeof(struct scoop_info_s));
       
   233 
       
   234     s->status = 0x02;
       
   235     s->in = qemu_allocate_irqs(scoop_gpio_set, s, 16);
       
   236     iomemtype = cpu_register_io_memory(0, scoop_readfn,
       
   237                     scoop_writefn, s);
       
   238     cpu_register_physical_memory(target_base, 0x1000, iomemtype);
       
   239     register_savevm("scoop", instance, 1, scoop_save, scoop_load, s);
       
   240 
       
   241     return s;
       
   242 }
       
   243 
       
   244 /* Write the bootloader parameters memory area.  */
       
   245 
       
   246 #define MAGIC_CHG(a, b, c, d)	((d << 24) | (c << 16) | (b << 8) | a)
       
   247 
       
   248 static struct __attribute__ ((__packed__)) sl_param_info {
       
   249     uint32_t comadj_keyword;
       
   250     int32_t comadj;
       
   251 
       
   252     uint32_t uuid_keyword;
       
   253     char uuid[16];
       
   254 
       
   255     uint32_t touch_keyword;
       
   256     int32_t touch_xp;
       
   257     int32_t touch_yp;
       
   258     int32_t touch_xd;
       
   259     int32_t touch_yd;
       
   260 
       
   261     uint32_t adadj_keyword;
       
   262     int32_t adadj;
       
   263 
       
   264     uint32_t phad_keyword;
       
   265     int32_t phadadj;
       
   266 } zaurus_bootparam = {
       
   267     .comadj_keyword	= MAGIC_CHG('C', 'M', 'A', 'D'),
       
   268     .comadj		= 125,
       
   269     .uuid_keyword	= MAGIC_CHG('U', 'U', 'I', 'D'),
       
   270     .uuid		= { -1 },
       
   271     .touch_keyword	= MAGIC_CHG('T', 'U', 'C', 'H'),
       
   272     .touch_xp		= -1,
       
   273     .adadj_keyword	= MAGIC_CHG('B', 'V', 'A', 'D'),
       
   274     .adadj		= -1,
       
   275     .phad_keyword	= MAGIC_CHG('P', 'H', 'A', 'D'),
       
   276     .phadadj		= 0x01,
       
   277 };
       
   278 
       
   279 void sl_bootparam_write(uint32_t ptr)
       
   280 {
       
   281     /* FIXME: This is broken if it spans multiple RAM regions.  */
       
   282     memcpy(host_ram_addr(ptr), &zaurus_bootparam,
       
   283                     sizeof(struct sl_param_info));
       
   284 }