symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/arm_sysctl.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * Status and system control registers for ARM RealView/Versatile boards.
       
     3  *
       
     4  * Copyright (c) 2006-2007 CodeSourcery.
       
     5  * Written by Paul Brook
       
     6  *
       
     7  * This code is licenced under the GPL.
       
     8  */
       
     9 
       
    10 #include "hw.h"
       
    11 #include "primecell.h"
       
    12 #include "sysemu.h"
       
    13 
       
    14 #define LOCK_VALUE 0xa05f
       
    15 
       
    16 typedef struct {
       
    17     uint32_t sys_id;
       
    18     uint32_t leds;
       
    19     uint16_t lockval;
       
    20     uint32_t cfgdata1;
       
    21     uint32_t cfgdata2;
       
    22     uint32_t flags;
       
    23     uint32_t nvflags;
       
    24     uint32_t resetlevel;
       
    25 } arm_sysctl_state;
       
    26 
       
    27 static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset)
       
    28 {
       
    29     arm_sysctl_state *s = (arm_sysctl_state *)opaque;
       
    30 
       
    31     switch (offset) {
       
    32     case 0x00: /* ID */
       
    33         return s->sys_id;
       
    34     case 0x04: /* SW */
       
    35         /* General purpose hardware switches.
       
    36            We don't have a useful way of exposing these to the user.  */
       
    37         return 0;
       
    38     case 0x08: /* LED */
       
    39         return s->leds;
       
    40     case 0x20: /* LOCK */
       
    41         return s->lockval;
       
    42     case 0x0c: /* OSC0 */
       
    43     case 0x10: /* OSC1 */
       
    44     case 0x14: /* OSC2 */
       
    45     case 0x18: /* OSC3 */
       
    46     case 0x1c: /* OSC4 */
       
    47     case 0x24: /* 100HZ */
       
    48         /* ??? Implement these.  */
       
    49         return 0;
       
    50     case 0x28: /* CFGDATA1 */
       
    51         return s->cfgdata1;
       
    52     case 0x2c: /* CFGDATA2 */
       
    53         return s->cfgdata2;
       
    54     case 0x30: /* FLAGS */
       
    55         return s->flags;
       
    56     case 0x38: /* NVFLAGS */
       
    57         return s->nvflags;
       
    58     case 0x40: /* RESETCTL */
       
    59         return s->resetlevel;
       
    60     case 0x44: /* PCICTL */
       
    61         return 1;
       
    62     case 0x48: /* MCI */
       
    63         return 0;
       
    64     case 0x4c: /* FLASH */
       
    65         return 0;
       
    66     case 0x50: /* CLCD */
       
    67         return 0x1000;
       
    68     case 0x54: /* CLCDSER */
       
    69         return 0;
       
    70     case 0x58: /* BOOTCS */
       
    71         return 0;
       
    72     case 0x5c: /* 24MHz */
       
    73         /* ??? not implemented.  */
       
    74         return 0;
       
    75     case 0x60: /* MISC */
       
    76         return 0;
       
    77     case 0x84: /* PROCID0 */
       
    78         /* ??? Don't know what the proper value for the core tile ID is.  */
       
    79         return 0x02000000;
       
    80     case 0x88: /* PROCID1 */
       
    81         return 0xff000000;
       
    82     case 0x64: /* DMAPSR0 */
       
    83     case 0x68: /* DMAPSR1 */
       
    84     case 0x6c: /* DMAPSR2 */
       
    85     case 0x70: /* IOSEL */
       
    86     case 0x74: /* PLDCTL */
       
    87     case 0x80: /* BUSID */
       
    88     case 0x8c: /* OSCRESET0 */
       
    89     case 0x90: /* OSCRESET1 */
       
    90     case 0x94: /* OSCRESET2 */
       
    91     case 0x98: /* OSCRESET3 */
       
    92     case 0x9c: /* OSCRESET4 */
       
    93     case 0xc0: /* SYS_TEST_OSC0 */
       
    94     case 0xc4: /* SYS_TEST_OSC1 */
       
    95     case 0xc8: /* SYS_TEST_OSC2 */
       
    96     case 0xcc: /* SYS_TEST_OSC3 */
       
    97     case 0xd0: /* SYS_TEST_OSC4 */
       
    98         return 0;
       
    99     default:
       
   100         printf ("arm_sysctl_read: Bad register offset 0x%x\n", (int)offset);
       
   101         return 0;
       
   102     }
       
   103 }
       
   104 
       
   105 static void arm_sysctl_write(void *opaque, target_phys_addr_t offset,
       
   106                           uint32_t val)
       
   107 {
       
   108     arm_sysctl_state *s = (arm_sysctl_state *)opaque;
       
   109 
       
   110     switch (offset) {
       
   111     case 0x08: /* LED */
       
   112         s->leds = val;
       
   113     case 0x0c: /* OSC0 */
       
   114     case 0x10: /* OSC1 */
       
   115     case 0x14: /* OSC2 */
       
   116     case 0x18: /* OSC3 */
       
   117     case 0x1c: /* OSC4 */
       
   118         /* ??? */
       
   119         break;
       
   120     case 0x20: /* LOCK */
       
   121         if (val == LOCK_VALUE)
       
   122             s->lockval = val;
       
   123         else
       
   124             s->lockval = val & 0x7fff;
       
   125         break;
       
   126     case 0x28: /* CFGDATA1 */
       
   127         /* ??? Need to implement this.  */
       
   128         s->cfgdata1 = val;
       
   129         break;
       
   130     case 0x2c: /* CFGDATA2 */
       
   131         /* ??? Need to implement this.  */
       
   132         s->cfgdata2 = val;
       
   133         break;
       
   134     case 0x30: /* FLAGSSET */
       
   135         s->flags |= val;
       
   136         break;
       
   137     case 0x34: /* FLAGSCLR */
       
   138         s->flags &= ~val;
       
   139         break;
       
   140     case 0x38: /* NVFLAGSSET */
       
   141         s->nvflags |= val;
       
   142         break;
       
   143     case 0x3c: /* NVFLAGSCLR */
       
   144         s->nvflags &= ~val;
       
   145         break;
       
   146     case 0x40: /* RESETCTL */
       
   147         if (s->lockval == LOCK_VALUE) {
       
   148             s->resetlevel = val;
       
   149             if (val & 0x100)
       
   150                 qemu_system_reset_request ();
       
   151         }
       
   152         break;
       
   153     case 0x44: /* PCICTL */
       
   154         /* nothing to do.  */
       
   155         break;
       
   156     case 0x4c: /* FLASH */
       
   157     case 0x50: /* CLCD */
       
   158     case 0x54: /* CLCDSER */
       
   159     case 0x64: /* DMAPSR0 */
       
   160     case 0x68: /* DMAPSR1 */
       
   161     case 0x6c: /* DMAPSR2 */
       
   162     case 0x70: /* IOSEL */
       
   163     case 0x74: /* PLDCTL */
       
   164     case 0x80: /* BUSID */
       
   165     case 0x84: /* PROCID0 */
       
   166     case 0x88: /* PROCID1 */
       
   167     case 0x8c: /* OSCRESET0 */
       
   168     case 0x90: /* OSCRESET1 */
       
   169     case 0x94: /* OSCRESET2 */
       
   170     case 0x98: /* OSCRESET3 */
       
   171     case 0x9c: /* OSCRESET4 */
       
   172         break;
       
   173     default:
       
   174         printf ("arm_sysctl_write: Bad register offset 0x%x\n", (int)offset);
       
   175         return;
       
   176     }
       
   177 }
       
   178 
       
   179 static CPUReadMemoryFunc *arm_sysctl_readfn[] = {
       
   180    arm_sysctl_read,
       
   181    arm_sysctl_read,
       
   182    arm_sysctl_read
       
   183 };
       
   184 
       
   185 static CPUWriteMemoryFunc *arm_sysctl_writefn[] = {
       
   186    arm_sysctl_write,
       
   187    arm_sysctl_write,
       
   188    arm_sysctl_write
       
   189 };
       
   190 
       
   191 void arm_sysctl_init(uint32_t base, uint32_t sys_id)
       
   192 {
       
   193     arm_sysctl_state *s;
       
   194     int iomemtype;
       
   195 
       
   196     s = (arm_sysctl_state *)qemu_mallocz(sizeof(arm_sysctl_state));
       
   197     if (!s)
       
   198         return;
       
   199     s->sys_id = sys_id;
       
   200     /* The MPcore bootloader uses these flags to start secondary CPUs.
       
   201        We don't use a bootloader, so do this here.  */
       
   202     s->flags = 3;
       
   203     iomemtype = cpu_register_io_memory(0, arm_sysctl_readfn,
       
   204                                        arm_sysctl_writefn, s);
       
   205     cpu_register_physical_memory(base, 0x00001000, iomemtype);
       
   206     /* ??? Save/restore.  */
       
   207 }