symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/ppc4xx_devs.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * QEMU PowerPC 4xx embedded processors shared devices emulation
       
     3  *
       
     4  * Copyright (c) 2007 Jocelyn Mayer
       
     5  *
       
     6  * Permission is hereby granted, free of charge, to any person obtaining a copy
       
     7  * of this software and associated documentation files (the "Software"), to deal
       
     8  * in the Software without restriction, including without limitation the rights
       
     9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       
    10  * copies of the Software, and to permit persons to whom the Software is
       
    11  * furnished to do so, subject to the following conditions:
       
    12  *
       
    13  * The above copyright notice and this permission notice shall be included in
       
    14  * all copies or substantial portions of the Software.
       
    15  *
       
    16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       
    17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       
    18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
       
    19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       
    20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
       
    21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
       
    22  * THE SOFTWARE.
       
    23  */
       
    24 #include "hw.h"
       
    25 #include "ppc.h"
       
    26 #include "ppc4xx.h"
       
    27 #include "sysemu.h"
       
    28 #include "qemu-log.h"
       
    29 
       
    30 //#define DEBUG_MMIO
       
    31 //#define DEBUG_UNASSIGNED
       
    32 #define DEBUG_UIC
       
    33 
       
    34 /*****************************************************************************/
       
    35 /* Generic PowerPC 4xx processor instanciation */
       
    36 CPUState *ppc4xx_init (const char *cpu_model,
       
    37                        clk_setup_t *cpu_clk, clk_setup_t *tb_clk,
       
    38                        uint32_t sysclk)
       
    39 {
       
    40     CPUState *env;
       
    41 
       
    42     /* init CPUs */
       
    43     env = cpu_init(cpu_model);
       
    44     if (!env) {
       
    45         fprintf(stderr, "Unable to find PowerPC %s CPU definition\n",
       
    46                 cpu_model);
       
    47         exit(1);
       
    48     }
       
    49     cpu_clk->cb = NULL; /* We don't care about CPU clock frequency changes */
       
    50     cpu_clk->opaque = env;
       
    51     /* Set time-base frequency to sysclk */
       
    52     tb_clk->cb = ppc_emb_timers_init(env, sysclk);
       
    53     tb_clk->opaque = env;
       
    54     ppc_dcr_init(env, NULL, NULL);
       
    55     /* Register qemu callbacks */
       
    56     qemu_register_reset(&cpu_ppc_reset, env);
       
    57 
       
    58     return env;
       
    59 }
       
    60 
       
    61 /*****************************************************************************/
       
    62 /* Fake device used to map multiple devices in a single memory page */
       
    63 #define MMIO_AREA_BITS 8
       
    64 #define MMIO_AREA_LEN (1 << MMIO_AREA_BITS)
       
    65 #define MMIO_AREA_NB (1 << (TARGET_PAGE_BITS - MMIO_AREA_BITS))
       
    66 #define MMIO_IDX(addr) (((addr) >> MMIO_AREA_BITS) & (MMIO_AREA_NB - 1))
       
    67 struct ppc4xx_mmio_t {
       
    68     target_phys_addr_t base;
       
    69     CPUReadMemoryFunc **mem_read[MMIO_AREA_NB];
       
    70     CPUWriteMemoryFunc **mem_write[MMIO_AREA_NB];
       
    71     void *opaque[MMIO_AREA_NB];
       
    72 };
       
    73 
       
    74 static uint32_t unassigned_mmio_readb (void *opaque, target_phys_addr_t addr)
       
    75 {
       
    76 #ifdef DEBUG_UNASSIGNED
       
    77     ppc4xx_mmio_t *mmio;
       
    78 
       
    79     mmio = opaque;
       
    80     printf("Unassigned mmio read 0x" PADDRX " base " PADDRX "\n",
       
    81            addr, mmio->base);
       
    82 #endif
       
    83 
       
    84     return 0;
       
    85 }
       
    86 
       
    87 static void unassigned_mmio_writeb (void *opaque,
       
    88                                     target_phys_addr_t addr, uint32_t val)
       
    89 {
       
    90 #ifdef DEBUG_UNASSIGNED
       
    91     ppc4xx_mmio_t *mmio;
       
    92 
       
    93     mmio = opaque;
       
    94     printf("Unassigned mmio write 0x" PADDRX " = 0x%x base " PADDRX "\n",
       
    95            addr, val, mmio->base);
       
    96 #endif
       
    97 }
       
    98 
       
    99 static CPUReadMemoryFunc *unassigned_mmio_read[3] = {
       
   100     unassigned_mmio_readb,
       
   101     unassigned_mmio_readb,
       
   102     unassigned_mmio_readb,
       
   103 };
       
   104 
       
   105 static CPUWriteMemoryFunc *unassigned_mmio_write[3] = {
       
   106     unassigned_mmio_writeb,
       
   107     unassigned_mmio_writeb,
       
   108     unassigned_mmio_writeb,
       
   109 };
       
   110 
       
   111 static uint32_t mmio_readlen (ppc4xx_mmio_t *mmio,
       
   112                               target_phys_addr_t addr, int len)
       
   113 {
       
   114     CPUReadMemoryFunc **mem_read;
       
   115     uint32_t ret;
       
   116     int idx;
       
   117 
       
   118     idx = MMIO_IDX(addr);
       
   119 #if defined(DEBUG_MMIO)
       
   120     printf("%s: mmio %p len %d addr " PADDRX " idx %d\n", __func__,
       
   121            mmio, len, addr, idx);
       
   122 #endif
       
   123     mem_read = mmio->mem_read[idx];
       
   124     ret = (*mem_read[len])(mmio->opaque[idx], addr);
       
   125 
       
   126     return ret;
       
   127 }
       
   128 
       
   129 static void mmio_writelen (ppc4xx_mmio_t *mmio,
       
   130                            target_phys_addr_t addr, uint32_t value, int len)
       
   131 {
       
   132     CPUWriteMemoryFunc **mem_write;
       
   133     int idx;
       
   134 
       
   135     idx = MMIO_IDX(addr);
       
   136 #if defined(DEBUG_MMIO)
       
   137     printf("%s: mmio %p len %d addr " PADDRX " idx %d value %08" PRIx32 "\n",
       
   138            __func__, mmio, len, addr, idx, value);
       
   139 #endif
       
   140     mem_write = mmio->mem_write[idx];
       
   141     (*mem_write[len])(mmio->opaque[idx], addr, value);
       
   142 }
       
   143 
       
   144 static uint32_t mmio_readb (void *opaque, target_phys_addr_t addr)
       
   145 {
       
   146 #if defined(DEBUG_MMIO)
       
   147     printf("%s: addr " PADDRX "\n", __func__, addr);
       
   148 #endif
       
   149 
       
   150     return mmio_readlen(opaque, addr, 0);
       
   151 }
       
   152 
       
   153 static void mmio_writeb (void *opaque,
       
   154                          target_phys_addr_t addr, uint32_t value)
       
   155 {
       
   156 #if defined(DEBUG_MMIO)
       
   157     printf("%s: addr " PADDRX " val %08" PRIx32 "\n", __func__, addr, value);
       
   158 #endif
       
   159     mmio_writelen(opaque, addr, value, 0);
       
   160 }
       
   161 
       
   162 static uint32_t mmio_readw (void *opaque, target_phys_addr_t addr)
       
   163 {
       
   164 #if defined(DEBUG_MMIO)
       
   165     printf("%s: addr " PADDRX "\n", __func__, addr);
       
   166 #endif
       
   167 
       
   168     return mmio_readlen(opaque, addr, 1);
       
   169 }
       
   170 
       
   171 static void mmio_writew (void *opaque,
       
   172                          target_phys_addr_t addr, uint32_t value)
       
   173 {
       
   174 #if defined(DEBUG_MMIO)
       
   175     printf("%s: addr " PADDRX " val %08" PRIx32 "\n", __func__, addr, value);
       
   176 #endif
       
   177     mmio_writelen(opaque, addr, value, 1);
       
   178 }
       
   179 
       
   180 static uint32_t mmio_readl (void *opaque, target_phys_addr_t addr)
       
   181 {
       
   182 #if defined(DEBUG_MMIO)
       
   183     printf("%s: addr " PADDRX "\n", __func__, addr);
       
   184 #endif
       
   185 
       
   186     return mmio_readlen(opaque, addr, 2);
       
   187 }
       
   188 
       
   189 static void mmio_writel (void *opaque,
       
   190                          target_phys_addr_t addr, uint32_t value)
       
   191 {
       
   192 #if defined(DEBUG_MMIO)
       
   193     printf("%s: addr " PADDRX " val %08" PRIx32 "\n", __func__, addr, value);
       
   194 #endif
       
   195     mmio_writelen(opaque, addr, value, 2);
       
   196 }
       
   197 
       
   198 static CPUReadMemoryFunc *mmio_read[] = {
       
   199     &mmio_readb,
       
   200     &mmio_readw,
       
   201     &mmio_readl,
       
   202 };
       
   203 
       
   204 static CPUWriteMemoryFunc *mmio_write[] = {
       
   205     &mmio_writeb,
       
   206     &mmio_writew,
       
   207     &mmio_writel,
       
   208 };
       
   209 
       
   210 int ppc4xx_mmio_register (CPUState *env, ppc4xx_mmio_t *mmio,
       
   211                           target_phys_addr_t offset, uint32_t len,
       
   212                           CPUReadMemoryFunc **mem_read,
       
   213                           CPUWriteMemoryFunc **mem_write, void *opaque)
       
   214 {
       
   215     target_phys_addr_t end;
       
   216     int idx, eidx;
       
   217 
       
   218     if ((offset + len) > TARGET_PAGE_SIZE)
       
   219         return -1;
       
   220     idx = MMIO_IDX(offset);
       
   221     end = offset + len - 1;
       
   222     eidx = MMIO_IDX(end);
       
   223 #if defined(DEBUG_MMIO)
       
   224     printf("%s: offset " PADDRX " len %08" PRIx32 " " PADDRX " %d %d\n",
       
   225            __func__, offset, len, end, idx, eidx);
       
   226 #endif
       
   227     for (; idx <= eidx; idx++) {
       
   228         mmio->mem_read[idx] = mem_read;
       
   229         mmio->mem_write[idx] = mem_write;
       
   230         mmio->opaque[idx] = opaque;
       
   231     }
       
   232 
       
   233     return 0;
       
   234 }
       
   235 
       
   236 ppc4xx_mmio_t *ppc4xx_mmio_init (CPUState *env, target_phys_addr_t base)
       
   237 {
       
   238     ppc4xx_mmio_t *mmio;
       
   239     int mmio_memory;
       
   240 
       
   241     mmio = qemu_mallocz(sizeof(ppc4xx_mmio_t));
       
   242     if (mmio != NULL) {
       
   243         mmio->base = base;
       
   244         mmio_memory = cpu_register_io_memory(0, mmio_read, mmio_write, mmio);
       
   245 #if defined(DEBUG_MMIO)
       
   246         printf("%s: base " PADDRX " len %08x %d\n", __func__,
       
   247                base, TARGET_PAGE_SIZE, mmio_memory);
       
   248 #endif
       
   249         cpu_register_physical_memory(base, TARGET_PAGE_SIZE, mmio_memory);
       
   250         ppc4xx_mmio_register(env, mmio, 0, TARGET_PAGE_SIZE,
       
   251                              unassigned_mmio_read, unassigned_mmio_write,
       
   252                              mmio);
       
   253     }
       
   254 
       
   255     return mmio;
       
   256 }
       
   257 
       
   258 /*****************************************************************************/
       
   259 /* "Universal" Interrupt controller */
       
   260 enum {
       
   261     DCR_UICSR  = 0x000,
       
   262     DCR_UICSRS = 0x001,
       
   263     DCR_UICER  = 0x002,
       
   264     DCR_UICCR  = 0x003,
       
   265     DCR_UICPR  = 0x004,
       
   266     DCR_UICTR  = 0x005,
       
   267     DCR_UICMSR = 0x006,
       
   268     DCR_UICVR  = 0x007,
       
   269     DCR_UICVCR = 0x008,
       
   270     DCR_UICMAX = 0x009,
       
   271 };
       
   272 
       
   273 #define UIC_MAX_IRQ 32
       
   274 typedef struct ppcuic_t ppcuic_t;
       
   275 struct ppcuic_t {
       
   276     uint32_t dcr_base;
       
   277     int use_vectors;
       
   278     uint32_t level;  /* Remembers the state of level-triggered interrupts. */
       
   279     uint32_t uicsr;  /* Status register */
       
   280     uint32_t uicer;  /* Enable register */
       
   281     uint32_t uiccr;  /* Critical register */
       
   282     uint32_t uicpr;  /* Polarity register */
       
   283     uint32_t uictr;  /* Triggering register */
       
   284     uint32_t uicvcr; /* Vector configuration register */
       
   285     uint32_t uicvr;
       
   286     qemu_irq *irqs;
       
   287 };
       
   288 
       
   289 static void ppcuic_trigger_irq (ppcuic_t *uic)
       
   290 {
       
   291     uint32_t ir, cr;
       
   292     int start, end, inc, i;
       
   293 
       
   294     /* Trigger interrupt if any is pending */
       
   295     ir = uic->uicsr & uic->uicer & (~uic->uiccr);
       
   296     cr = uic->uicsr & uic->uicer & uic->uiccr;
       
   297 #ifdef DEBUG_UIC
       
   298     if (loglevel & CPU_LOG_INT) {
       
   299         fprintf(logfile, "%s: uicsr %08" PRIx32 " uicer %08" PRIx32
       
   300                 " uiccr %08" PRIx32 "\n"
       
   301                 "   %08" PRIx32 " ir %08" PRIx32 " cr %08" PRIx32 "\n",
       
   302                 __func__, uic->uicsr, uic->uicer, uic->uiccr,
       
   303                 uic->uicsr & uic->uicer, ir, cr);
       
   304     }
       
   305 #endif
       
   306     if (ir != 0x0000000) {
       
   307 #ifdef DEBUG_UIC
       
   308         if (loglevel & CPU_LOG_INT) {
       
   309             fprintf(logfile, "Raise UIC interrupt\n");
       
   310         }
       
   311 #endif
       
   312         qemu_irq_raise(uic->irqs[PPCUIC_OUTPUT_INT]);
       
   313     } else {
       
   314 #ifdef DEBUG_UIC
       
   315         if (loglevel & CPU_LOG_INT) {
       
   316             fprintf(logfile, "Lower UIC interrupt\n");
       
   317         }
       
   318 #endif
       
   319         qemu_irq_lower(uic->irqs[PPCUIC_OUTPUT_INT]);
       
   320     }
       
   321     /* Trigger critical interrupt if any is pending and update vector */
       
   322     if (cr != 0x0000000) {
       
   323         qemu_irq_raise(uic->irqs[PPCUIC_OUTPUT_CINT]);
       
   324         if (uic->use_vectors) {
       
   325             /* Compute critical IRQ vector */
       
   326             if (uic->uicvcr & 1) {
       
   327                 start = 31;
       
   328                 end = 0;
       
   329                 inc = -1;
       
   330             } else {
       
   331                 start = 0;
       
   332                 end = 31;
       
   333                 inc = 1;
       
   334             }
       
   335             uic->uicvr = uic->uicvcr & 0xFFFFFFFC;
       
   336             for (i = start; i <= end; i += inc) {
       
   337                 if (cr & (1 << i)) {
       
   338                     uic->uicvr += (i - start) * 512 * inc;
       
   339                     break;
       
   340                 }
       
   341             }
       
   342         }
       
   343 #ifdef DEBUG_UIC
       
   344         if (loglevel & CPU_LOG_INT) {
       
   345             fprintf(logfile, "Raise UIC critical interrupt - "
       
   346                     "vector %08" PRIx32 "\n", uic->uicvr);
       
   347         }
       
   348 #endif
       
   349     } else {
       
   350 #ifdef DEBUG_UIC
       
   351         if (loglevel & CPU_LOG_INT) {
       
   352             fprintf(logfile, "Lower UIC critical interrupt\n");
       
   353         }
       
   354 #endif
       
   355         qemu_irq_lower(uic->irqs[PPCUIC_OUTPUT_CINT]);
       
   356         uic->uicvr = 0x00000000;
       
   357     }
       
   358 }
       
   359 
       
   360 static void ppcuic_set_irq (void *opaque, int irq_num, int level)
       
   361 {
       
   362     ppcuic_t *uic;
       
   363     uint32_t mask, sr;
       
   364 
       
   365     uic = opaque;
       
   366     mask = 1 << (31-irq_num);
       
   367 #ifdef DEBUG_UIC
       
   368     if (loglevel & CPU_LOG_INT) {
       
   369         fprintf(logfile, "%s: irq %d level %d uicsr %08" PRIx32
       
   370                 " mask %08" PRIx32 " => %08" PRIx32 " %08" PRIx32 "\n",
       
   371                 __func__, irq_num, level,
       
   372                 uic->uicsr, mask, uic->uicsr & mask, level << irq_num);
       
   373     }
       
   374 #endif
       
   375     if (irq_num < 0 || irq_num > 31)
       
   376         return;
       
   377     sr = uic->uicsr;
       
   378 
       
   379     /* Update status register */
       
   380     if (uic->uictr & mask) {
       
   381         /* Edge sensitive interrupt */
       
   382         if (level == 1)
       
   383             uic->uicsr |= mask;
       
   384     } else {
       
   385         /* Level sensitive interrupt */
       
   386         if (level == 1) {
       
   387             uic->uicsr |= mask;
       
   388             uic->level |= mask;
       
   389         } else {
       
   390             uic->uicsr &= ~mask;
       
   391             uic->level &= ~mask;
       
   392         }
       
   393     }
       
   394 #ifdef DEBUG_UIC
       
   395     if (loglevel & CPU_LOG_INT) {
       
   396         fprintf(logfile, "%s: irq %d level %d sr %" PRIx32 " => "
       
   397                 "%08" PRIx32 "\n", __func__, irq_num, level, uic->uicsr, sr);
       
   398     }
       
   399 #endif
       
   400     if (sr != uic->uicsr)
       
   401         ppcuic_trigger_irq(uic);
       
   402 }
       
   403 
       
   404 static target_ulong dcr_read_uic (void *opaque, int dcrn)
       
   405 {
       
   406     ppcuic_t *uic;
       
   407     target_ulong ret;
       
   408 
       
   409     uic = opaque;
       
   410     dcrn -= uic->dcr_base;
       
   411     switch (dcrn) {
       
   412     case DCR_UICSR:
       
   413     case DCR_UICSRS:
       
   414         ret = uic->uicsr;
       
   415         break;
       
   416     case DCR_UICER:
       
   417         ret = uic->uicer;
       
   418         break;
       
   419     case DCR_UICCR:
       
   420         ret = uic->uiccr;
       
   421         break;
       
   422     case DCR_UICPR:
       
   423         ret = uic->uicpr;
       
   424         break;
       
   425     case DCR_UICTR:
       
   426         ret = uic->uictr;
       
   427         break;
       
   428     case DCR_UICMSR:
       
   429         ret = uic->uicsr & uic->uicer;
       
   430         break;
       
   431     case DCR_UICVR:
       
   432         if (!uic->use_vectors)
       
   433             goto no_read;
       
   434         ret = uic->uicvr;
       
   435         break;
       
   436     case DCR_UICVCR:
       
   437         if (!uic->use_vectors)
       
   438             goto no_read;
       
   439         ret = uic->uicvcr;
       
   440         break;
       
   441     default:
       
   442     no_read:
       
   443         ret = 0x00000000;
       
   444         break;
       
   445     }
       
   446 
       
   447     return ret;
       
   448 }
       
   449 
       
   450 static void dcr_write_uic (void *opaque, int dcrn, target_ulong val)
       
   451 {
       
   452     ppcuic_t *uic;
       
   453 
       
   454     uic = opaque;
       
   455     dcrn -= uic->dcr_base;
       
   456 #ifdef DEBUG_UIC
       
   457     if (loglevel & CPU_LOG_INT) {
       
   458         fprintf(logfile, "%s: dcr %d val " ADDRX "\n", __func__, dcrn, val);
       
   459     }
       
   460 #endif
       
   461     switch (dcrn) {
       
   462     case DCR_UICSR:
       
   463         uic->uicsr &= ~val;
       
   464         uic->uicsr |= uic->level;
       
   465         ppcuic_trigger_irq(uic);
       
   466         break;
       
   467     case DCR_UICSRS:
       
   468         uic->uicsr |= val;
       
   469         ppcuic_trigger_irq(uic);
       
   470         break;
       
   471     case DCR_UICER:
       
   472         uic->uicer = val;
       
   473         ppcuic_trigger_irq(uic);
       
   474         break;
       
   475     case DCR_UICCR:
       
   476         uic->uiccr = val;
       
   477         ppcuic_trigger_irq(uic);
       
   478         break;
       
   479     case DCR_UICPR:
       
   480         uic->uicpr = val;
       
   481         break;
       
   482     case DCR_UICTR:
       
   483         uic->uictr = val;
       
   484         ppcuic_trigger_irq(uic);
       
   485         break;
       
   486     case DCR_UICMSR:
       
   487         break;
       
   488     case DCR_UICVR:
       
   489         break;
       
   490     case DCR_UICVCR:
       
   491         uic->uicvcr = val & 0xFFFFFFFD;
       
   492         ppcuic_trigger_irq(uic);
       
   493         break;
       
   494     }
       
   495 }
       
   496 
       
   497 static void ppcuic_reset (void *opaque)
       
   498 {
       
   499     ppcuic_t *uic;
       
   500 
       
   501     uic = opaque;
       
   502     uic->uiccr = 0x00000000;
       
   503     uic->uicer = 0x00000000;
       
   504     uic->uicpr = 0x00000000;
       
   505     uic->uicsr = 0x00000000;
       
   506     uic->uictr = 0x00000000;
       
   507     if (uic->use_vectors) {
       
   508         uic->uicvcr = 0x00000000;
       
   509         uic->uicvr = 0x0000000;
       
   510     }
       
   511 }
       
   512 
       
   513 qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs,
       
   514                        uint32_t dcr_base, int has_ssr, int has_vr)
       
   515 {
       
   516     ppcuic_t *uic;
       
   517     int i;
       
   518 
       
   519     uic = qemu_mallocz(sizeof(ppcuic_t));
       
   520     if (uic != NULL) {
       
   521         uic->dcr_base = dcr_base;
       
   522         uic->irqs = irqs;
       
   523         if (has_vr)
       
   524             uic->use_vectors = 1;
       
   525         for (i = 0; i < DCR_UICMAX; i++) {
       
   526             ppc_dcr_register(env, dcr_base + i, uic,
       
   527                              &dcr_read_uic, &dcr_write_uic);
       
   528         }
       
   529         qemu_register_reset(ppcuic_reset, uic);
       
   530         ppcuic_reset(uic);
       
   531     }
       
   532 
       
   533     return qemu_allocate_irqs(&ppcuic_set_irq, uic, UIC_MAX_IRQ);
       
   534 }
       
   535 
       
   536 /*****************************************************************************/
       
   537 /* SDRAM controller */
       
   538 typedef struct ppc4xx_sdram_t ppc4xx_sdram_t;
       
   539 struct ppc4xx_sdram_t {
       
   540     uint32_t addr;
       
   541     int nbanks;
       
   542     target_phys_addr_t ram_bases[4];
       
   543     target_phys_addr_t ram_sizes[4];
       
   544     uint32_t besr0;
       
   545     uint32_t besr1;
       
   546     uint32_t bear;
       
   547     uint32_t cfg;
       
   548     uint32_t status;
       
   549     uint32_t rtr;
       
   550     uint32_t pmit;
       
   551     uint32_t bcr[4];
       
   552     uint32_t tr;
       
   553     uint32_t ecccfg;
       
   554     uint32_t eccesr;
       
   555     qemu_irq irq;
       
   556 };
       
   557 
       
   558 enum {
       
   559     SDRAM0_CFGADDR = 0x010,
       
   560     SDRAM0_CFGDATA = 0x011,
       
   561 };
       
   562 
       
   563 /* XXX: TOFIX: some patches have made this code become inconsistent:
       
   564  *      there are type inconsistencies, mixing target_phys_addr_t, target_ulong
       
   565  *      and uint32_t
       
   566  */
       
   567 static uint32_t sdram_bcr (target_phys_addr_t ram_base,
       
   568                            target_phys_addr_t ram_size)
       
   569 {
       
   570     uint32_t bcr;
       
   571 
       
   572     switch (ram_size) {
       
   573     case (4 * 1024 * 1024):
       
   574         bcr = 0x00000000;
       
   575         break;
       
   576     case (8 * 1024 * 1024):
       
   577         bcr = 0x00020000;
       
   578         break;
       
   579     case (16 * 1024 * 1024):
       
   580         bcr = 0x00040000;
       
   581         break;
       
   582     case (32 * 1024 * 1024):
       
   583         bcr = 0x00060000;
       
   584         break;
       
   585     case (64 * 1024 * 1024):
       
   586         bcr = 0x00080000;
       
   587         break;
       
   588     case (128 * 1024 * 1024):
       
   589         bcr = 0x000A0000;
       
   590         break;
       
   591     case (256 * 1024 * 1024):
       
   592         bcr = 0x000C0000;
       
   593         break;
       
   594     default:
       
   595         printf("%s: invalid RAM size " PADDRX "\n", __func__, ram_size);
       
   596         return 0x00000000;
       
   597     }
       
   598     bcr |= ram_base & 0xFF800000;
       
   599     bcr |= 1;
       
   600 
       
   601     return bcr;
       
   602 }
       
   603 
       
   604 static always_inline target_phys_addr_t sdram_base (uint32_t bcr)
       
   605 {
       
   606     return bcr & 0xFF800000;
       
   607 }
       
   608 
       
   609 static target_ulong sdram_size (uint32_t bcr)
       
   610 {
       
   611     target_ulong size;
       
   612     int sh;
       
   613 
       
   614     sh = (bcr >> 17) & 0x7;
       
   615     if (sh == 7)
       
   616         size = -1;
       
   617     else
       
   618         size = (4 * 1024 * 1024) << sh;
       
   619 
       
   620     return size;
       
   621 }
       
   622 
       
   623 static void sdram_set_bcr (uint32_t *bcrp, uint32_t bcr, int enabled)
       
   624 {
       
   625     if (*bcrp & 0x00000001) {
       
   626         /* Unmap RAM */
       
   627 #ifdef DEBUG_SDRAM
       
   628         printf("%s: unmap RAM area " PADDRX " " ADDRX "\n",
       
   629                __func__, sdram_base(*bcrp), sdram_size(*bcrp));
       
   630 #endif
       
   631         cpu_register_physical_memory(sdram_base(*bcrp), sdram_size(*bcrp),
       
   632                                      IO_MEM_UNASSIGNED);
       
   633     }
       
   634     *bcrp = bcr & 0xFFDEE001;
       
   635     if (enabled && (bcr & 0x00000001)) {
       
   636 #ifdef DEBUG_SDRAM
       
   637         printf("%s: Map RAM area " PADDRX " " ADDRX "\n",
       
   638                __func__, sdram_base(bcr), sdram_size(bcr));
       
   639 #endif
       
   640         cpu_register_physical_memory(sdram_base(bcr), sdram_size(bcr),
       
   641                                      sdram_base(bcr) | IO_MEM_RAM);
       
   642     }
       
   643 }
       
   644 
       
   645 static void sdram_map_bcr (ppc4xx_sdram_t *sdram)
       
   646 {
       
   647     int i;
       
   648 
       
   649     for (i = 0; i < sdram->nbanks; i++) {
       
   650         if (sdram->ram_sizes[i] != 0) {
       
   651             sdram_set_bcr(&sdram->bcr[i],
       
   652                           sdram_bcr(sdram->ram_bases[i], sdram->ram_sizes[i]),
       
   653                           1);
       
   654         } else {
       
   655             sdram_set_bcr(&sdram->bcr[i], 0x00000000, 0);
       
   656         }
       
   657     }
       
   658 }
       
   659 
       
   660 static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram)
       
   661 {
       
   662     int i;
       
   663 
       
   664     for (i = 0; i < sdram->nbanks; i++) {
       
   665 #ifdef DEBUG_SDRAM
       
   666         printf("%s: Unmap RAM area " PADDRX " " ADDRX "\n",
       
   667                __func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i]));
       
   668 #endif
       
   669         cpu_register_physical_memory(sdram_base(sdram->bcr[i]),
       
   670                                      sdram_size(sdram->bcr[i]),
       
   671                                      IO_MEM_UNASSIGNED);
       
   672     }
       
   673 }
       
   674 
       
   675 static target_ulong dcr_read_sdram (void *opaque, int dcrn)
       
   676 {
       
   677     ppc4xx_sdram_t *sdram;
       
   678     target_ulong ret;
       
   679 
       
   680     sdram = opaque;
       
   681     switch (dcrn) {
       
   682     case SDRAM0_CFGADDR:
       
   683         ret = sdram->addr;
       
   684         break;
       
   685     case SDRAM0_CFGDATA:
       
   686         switch (sdram->addr) {
       
   687         case 0x00: /* SDRAM_BESR0 */
       
   688             ret = sdram->besr0;
       
   689             break;
       
   690         case 0x08: /* SDRAM_BESR1 */
       
   691             ret = sdram->besr1;
       
   692             break;
       
   693         case 0x10: /* SDRAM_BEAR */
       
   694             ret = sdram->bear;
       
   695             break;
       
   696         case 0x20: /* SDRAM_CFG */
       
   697             ret = sdram->cfg;
       
   698             break;
       
   699         case 0x24: /* SDRAM_STATUS */
       
   700             ret = sdram->status;
       
   701             break;
       
   702         case 0x30: /* SDRAM_RTR */
       
   703             ret = sdram->rtr;
       
   704             break;
       
   705         case 0x34: /* SDRAM_PMIT */
       
   706             ret = sdram->pmit;
       
   707             break;
       
   708         case 0x40: /* SDRAM_B0CR */
       
   709             ret = sdram->bcr[0];
       
   710             break;
       
   711         case 0x44: /* SDRAM_B1CR */
       
   712             ret = sdram->bcr[1];
       
   713             break;
       
   714         case 0x48: /* SDRAM_B2CR */
       
   715             ret = sdram->bcr[2];
       
   716             break;
       
   717         case 0x4C: /* SDRAM_B3CR */
       
   718             ret = sdram->bcr[3];
       
   719             break;
       
   720         case 0x80: /* SDRAM_TR */
       
   721             ret = -1; /* ? */
       
   722             break;
       
   723         case 0x94: /* SDRAM_ECCCFG */
       
   724             ret = sdram->ecccfg;
       
   725             break;
       
   726         case 0x98: /* SDRAM_ECCESR */
       
   727             ret = sdram->eccesr;
       
   728             break;
       
   729         default: /* Error */
       
   730             ret = -1;
       
   731             break;
       
   732         }
       
   733         break;
       
   734     default:
       
   735         /* Avoid gcc warning */
       
   736         ret = 0x00000000;
       
   737         break;
       
   738     }
       
   739 
       
   740     return ret;
       
   741 }
       
   742 
       
   743 static void dcr_write_sdram (void *opaque, int dcrn, target_ulong val)
       
   744 {
       
   745     ppc4xx_sdram_t *sdram;
       
   746 
       
   747     sdram = opaque;
       
   748     switch (dcrn) {
       
   749     case SDRAM0_CFGADDR:
       
   750         sdram->addr = val;
       
   751         break;
       
   752     case SDRAM0_CFGDATA:
       
   753         switch (sdram->addr) {
       
   754         case 0x00: /* SDRAM_BESR0 */
       
   755             sdram->besr0 &= ~val;
       
   756             break;
       
   757         case 0x08: /* SDRAM_BESR1 */
       
   758             sdram->besr1 &= ~val;
       
   759             break;
       
   760         case 0x10: /* SDRAM_BEAR */
       
   761             sdram->bear = val;
       
   762             break;
       
   763         case 0x20: /* SDRAM_CFG */
       
   764             val &= 0xFFE00000;
       
   765             if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) {
       
   766 #ifdef DEBUG_SDRAM
       
   767                 printf("%s: enable SDRAM controller\n", __func__);
       
   768 #endif
       
   769                 /* validate all RAM mappings */
       
   770                 sdram_map_bcr(sdram);
       
   771                 sdram->status &= ~0x80000000;
       
   772             } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) {
       
   773 #ifdef DEBUG_SDRAM
       
   774                 printf("%s: disable SDRAM controller\n", __func__);
       
   775 #endif
       
   776                 /* invalidate all RAM mappings */
       
   777                 sdram_unmap_bcr(sdram);
       
   778                 sdram->status |= 0x80000000;
       
   779             }
       
   780             if (!(sdram->cfg & 0x40000000) && (val & 0x40000000))
       
   781                 sdram->status |= 0x40000000;
       
   782             else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000))
       
   783                 sdram->status &= ~0x40000000;
       
   784             sdram->cfg = val;
       
   785             break;
       
   786         case 0x24: /* SDRAM_STATUS */
       
   787             /* Read-only register */
       
   788             break;
       
   789         case 0x30: /* SDRAM_RTR */
       
   790             sdram->rtr = val & 0x3FF80000;
       
   791             break;
       
   792         case 0x34: /* SDRAM_PMIT */
       
   793             sdram->pmit = (val & 0xF8000000) | 0x07C00000;
       
   794             break;
       
   795         case 0x40: /* SDRAM_B0CR */
       
   796             sdram_set_bcr(&sdram->bcr[0], val, sdram->cfg & 0x80000000);
       
   797             break;
       
   798         case 0x44: /* SDRAM_B1CR */
       
   799             sdram_set_bcr(&sdram->bcr[1], val, sdram->cfg & 0x80000000);
       
   800             break;
       
   801         case 0x48: /* SDRAM_B2CR */
       
   802             sdram_set_bcr(&sdram->bcr[2], val, sdram->cfg & 0x80000000);
       
   803             break;
       
   804         case 0x4C: /* SDRAM_B3CR */
       
   805             sdram_set_bcr(&sdram->bcr[3], val, sdram->cfg & 0x80000000);
       
   806             break;
       
   807         case 0x80: /* SDRAM_TR */
       
   808             sdram->tr = val & 0x018FC01F;
       
   809             break;
       
   810         case 0x94: /* SDRAM_ECCCFG */
       
   811             sdram->ecccfg = val & 0x00F00000;
       
   812             break;
       
   813         case 0x98: /* SDRAM_ECCESR */
       
   814             val &= 0xFFF0F000;
       
   815             if (sdram->eccesr == 0 && val != 0)
       
   816                 qemu_irq_raise(sdram->irq);
       
   817             else if (sdram->eccesr != 0 && val == 0)
       
   818                 qemu_irq_lower(sdram->irq);
       
   819             sdram->eccesr = val;
       
   820             break;
       
   821         default: /* Error */
       
   822             break;
       
   823         }
       
   824         break;
       
   825     }
       
   826 }
       
   827 
       
   828 static void sdram_reset (void *opaque)
       
   829 {
       
   830     ppc4xx_sdram_t *sdram;
       
   831 
       
   832     sdram = opaque;
       
   833     sdram->addr = 0x00000000;
       
   834     sdram->bear = 0x00000000;
       
   835     sdram->besr0 = 0x00000000; /* No error */
       
   836     sdram->besr1 = 0x00000000; /* No error */
       
   837     sdram->cfg = 0x00000000;
       
   838     sdram->ecccfg = 0x00000000; /* No ECC */
       
   839     sdram->eccesr = 0x00000000; /* No error */
       
   840     sdram->pmit = 0x07C00000;
       
   841     sdram->rtr = 0x05F00000;
       
   842     sdram->tr = 0x00854009;
       
   843     /* We pre-initialize RAM banks */
       
   844     sdram->status = 0x00000000;
       
   845     sdram->cfg = 0x00800000;
       
   846     sdram_unmap_bcr(sdram);
       
   847 }
       
   848 
       
   849 void ppc4xx_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
       
   850                         target_phys_addr_t *ram_bases,
       
   851                         target_phys_addr_t *ram_sizes,
       
   852                         int do_init)
       
   853 {
       
   854     ppc4xx_sdram_t *sdram;
       
   855 
       
   856     sdram = qemu_mallocz(sizeof(ppc4xx_sdram_t));
       
   857     if (sdram != NULL) {
       
   858         sdram->irq = irq;
       
   859         sdram->nbanks = nbanks;
       
   860         memset(sdram->ram_bases, 0, 4 * sizeof(target_phys_addr_t));
       
   861         memcpy(sdram->ram_bases, ram_bases,
       
   862                nbanks * sizeof(target_phys_addr_t));
       
   863         memset(sdram->ram_sizes, 0, 4 * sizeof(target_phys_addr_t));
       
   864         memcpy(sdram->ram_sizes, ram_sizes,
       
   865                nbanks * sizeof(target_phys_addr_t));
       
   866         sdram_reset(sdram);
       
   867         qemu_register_reset(&sdram_reset, sdram);
       
   868         ppc_dcr_register(env, SDRAM0_CFGADDR,
       
   869                          sdram, &dcr_read_sdram, &dcr_write_sdram);
       
   870         ppc_dcr_register(env, SDRAM0_CFGDATA,
       
   871                          sdram, &dcr_read_sdram, &dcr_write_sdram);
       
   872         if (do_init)
       
   873             sdram_map_bcr(sdram);
       
   874     }
       
   875 }
       
   876 
       
   877 /* Fill in consecutive SDRAM banks with 'ram_size' bytes of memory.
       
   878  *
       
   879  * sdram_bank_sizes[] must be 0-terminated.
       
   880  *
       
   881  * The 4xx SDRAM controller supports a small number of banks, and each bank
       
   882  * must be one of a small set of sizes. The number of banks and the supported
       
   883  * sizes varies by SoC. */
       
   884 ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks,
       
   885                                target_phys_addr_t ram_bases[],
       
   886                                target_phys_addr_t ram_sizes[],
       
   887                                const unsigned int sdram_bank_sizes[])
       
   888 {
       
   889     ram_addr_t ram_end = 0;
       
   890     int i;
       
   891     int j;
       
   892 
       
   893     for (i = 0; i < nr_banks; i++) {
       
   894         for (j = 0; sdram_bank_sizes[j] != 0; j++) {
       
   895             unsigned int bank_size = sdram_bank_sizes[j];
       
   896 
       
   897             if (bank_size <= ram_size) {
       
   898                 ram_bases[i] = ram_end;
       
   899                 ram_sizes[i] = bank_size;
       
   900                 ram_end += bank_size;
       
   901                 ram_size -= bank_size;
       
   902                 break;
       
   903             }
       
   904         }
       
   905 
       
   906         if (!ram_size) {
       
   907             /* No need to use the remaining banks. */
       
   908             break;
       
   909         }
       
   910     }
       
   911 
       
   912     if (ram_size)
       
   913         printf("Truncating memory to %d MiB to fit SDRAM controller limits.\n",
       
   914                (int)(ram_end >> 20));
       
   915 
       
   916     return ram_end;
       
   917 }