Revision 502a5395 hw/versatilepb.c

b/hw/versatilepb.c
10 10
#include "vl.h"
11 11
#include "arm_pic.h"
12 12

  
13
#define LOCK_VALUE 0xa05f
14

  
13 15
/* Primary interrupt controller.  */
14 16

  
15 17
typedef struct vpb_sic_state
......
145 147
    return s;
146 148
}
147 149

  
150
/* System controller.  */
151

  
152
typedef struct {
153
    uint32_t base;
154
    uint32_t leds;
155
    uint16_t lockval;
156
    uint32_t cfgdata1;
157
    uint32_t cfgdata2;
158
    uint32_t flags;
159
    uint32_t nvflags;
160
    uint32_t resetlevel;
161
} vpb_sys_state;
162

  
163
static uint32_t vpb_sys_read(void *opaque, target_phys_addr_t offset)
164
{
165
    vpb_sys_state *s = (vpb_sys_state *)opaque;
166

  
167
    offset -= s->base;
168
    switch (offset) {
169
    case 0x00: /* ID */
170
        return 0x41007004;
171
    case 0x04: /* SW */
172
        /* General purpose hardware switches.
173
           We don't have a useful way of exposing these to the user.  */
174
        return 0;
175
    case 0x08: /* LED */
176
        return s->leds;
177
    case 0x20: /* LOCK */
178
        return s->lockval;
179
    case 0x0c: /* OSC0 */
180
    case 0x10: /* OSC1 */
181
    case 0x14: /* OSC2 */
182
    case 0x18: /* OSC3 */
183
    case 0x1c: /* OSC4 */
184
    case 0x24: /* 100HZ */
185
        /* ??? Implement these.  */
186
        return 0;
187
    case 0x28: /* CFGDATA1 */
188
        return s->cfgdata1;
189
    case 0x2c: /* CFGDATA2 */
190
        return s->cfgdata2;
191
    case 0x30: /* FLAGS */
192
        return s->flags;
193
    case 0x38: /* NVFLAGS */
194
        return s->nvflags;
195
    case 0x40: /* RESETCTL */
196
        return s->resetlevel;
197
    case 0x44: /* PCICTL */
198
        return 1;
199
    case 0x48: /* MCI */
200
        return 0;
201
    case 0x4c: /* FLASH */
202
        return 0;
203
    case 0x50: /* CLCD */
204
        return 0x1000;
205
    case 0x54: /* CLCDSER */
206
        return 0;
207
    case 0x58: /* BOOTCS */
208
        return 0;
209
    case 0x5c: /* 24MHz */
210
        /* ??? not implemented.  */
211
        return 0;
212
    case 0x60: /* MISC */
213
        return 0;
214
    case 0x64: /* DMAPSR0 */
215
    case 0x68: /* DMAPSR1 */
216
    case 0x6c: /* DMAPSR2 */
217
    case 0x8c: /* OSCRESET0 */
218
    case 0x90: /* OSCRESET1 */
219
    case 0x94: /* OSCRESET2 */
220
    case 0x98: /* OSCRESET3 */
221
    case 0x9c: /* OSCRESET4 */
222
    case 0xc0: /* SYS_TEST_OSC0 */
223
    case 0xc4: /* SYS_TEST_OSC1 */
224
    case 0xc8: /* SYS_TEST_OSC2 */
225
    case 0xcc: /* SYS_TEST_OSC3 */
226
    case 0xd0: /* SYS_TEST_OSC4 */
227
        return 0;
228
    default:
229
        printf ("vpb_sys_read: Bad register offset 0x%x\n", offset);
230
        return 0;
231
    }
232
}
233

  
234
static void vpb_sys_write(void *opaque, target_phys_addr_t offset,
235
                          uint32_t val)
236
{
237
    vpb_sys_state *s = (vpb_sys_state *)opaque;
238
    offset -= s->base;
239

  
240
    switch (offset) {
241
    case 0x08: /* LED */
242
        s->leds = val;
243
    case 0x0c: /* OSC0 */
244
    case 0x10: /* OSC1 */
245
    case 0x14: /* OSC2 */
246
    case 0x18: /* OSC3 */
247
    case 0x1c: /* OSC4 */
248
        /* ??? */
249
        break;
250
    case 0x20: /* LOCK */
251
        if (val == LOCK_VALUE)
252
            s->lockval = val;
253
        else
254
            s->lockval = val & 0x7fff;
255
        break;
256
    case 0x28: /* CFGDATA1 */
257
        /* ??? Need to implement this.  */
258
        s->cfgdata1 = val;
259
        break;
260
    case 0x2c: /* CFGDATA2 */
261
        /* ??? Need to implement this.  */
262
        s->cfgdata2 = val;
263
        break;
264
    case 0x30: /* FLAGSSET */
265
        s->flags |= val;
266
        break;
267
    case 0x34: /* FLAGSCLR */
268
        s->flags &= ~val;
269
        break;
270
    case 0x38: /* NVFLAGSSET */
271
        s->nvflags |= val;
272
        break;
273
    case 0x3c: /* NVFLAGSCLR */
274
        s->nvflags &= ~val;
275
        break;
276
    case 0x40: /* RESETCTL */
277
        if (s->lockval == LOCK_VALUE) {
278
            s->resetlevel = val;
279
            if (val & 0x100)
280
                cpu_abort(cpu_single_env, "Board reset\n");
281
        }
282
        break;
283
    case 0x44: /* PCICTL */
284
        /* nothing to do.  */
285
        break;
286
    case 0x4c: /* FLASH */
287
    case 0x50: /* CLCD */
288
    case 0x54: /* CLCDSER */
289
    case 0x64: /* DMAPSR0 */
290
    case 0x68: /* DMAPSR1 */
291
    case 0x6c: /* DMAPSR2 */
292
    case 0x8c: /* OSCRESET0 */
293
    case 0x90: /* OSCRESET1 */
294
    case 0x94: /* OSCRESET2 */
295
    case 0x98: /* OSCRESET3 */
296
    case 0x9c: /* OSCRESET4 */
297
        break;
298
    default:
299
        printf ("vpb_sys_write: Bad register offset 0x%x\n", offset);
300
        return;
301
    }
302
}
303

  
304
static CPUReadMemoryFunc *vpb_sys_readfn[] = {
305
   vpb_sys_read,
306
   vpb_sys_read,
307
   vpb_sys_read
308
};
309

  
310
static CPUWriteMemoryFunc *vpb_sys_writefn[] = {
311
   vpb_sys_write,
312
   vpb_sys_write,
313
   vpb_sys_write
314
};
315

  
316
static vpb_sys_state *vpb_sys_init(uint32_t base)
317
{
318
    vpb_sys_state *s;
319
    int iomemtype;
320

  
321
    s = (vpb_sys_state *)qemu_mallocz(sizeof(vpb_sys_state));
322
    if (!s)
323
        return NULL;
324
    s->base = base;
325
    iomemtype = cpu_register_io_memory(0, vpb_sys_readfn,
326
                                       vpb_sys_writefn, s);
327
    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
328
    /* ??? Save/restore.  */
329
    return s;
330
}
331

  
148 332
/* Board init.  */
149 333

  
150 334
/* The AB and PB boards both use the same core, just with different
......
159 343
    CPUState *env;
160 344
    void *pic;
161 345
    void *sic;
346
    PCIBus *pci_bus;
347
    NICInfo *nd;
348
    int n;
349
    int done_smc = 0;
162 350

  
163 351
    env = cpu_init();
164 352
    cpu_arm_set_model(env, ARM_CPUID_ARM926);
......
166 354
    /* SDRAM at address zero.  */
167 355
    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
168 356

  
357
    vpb_sys_init(0x10000000);
169 358
    pic = arm_pic_init_cpu(env);
170 359
    pic = pl190_init(0x10140000, pic, ARM_PIC_CPU_IRQ, ARM_PIC_CPU_FIQ);
171 360
    sic = vpb_sic_init(0x10003000, pic, 31);
172 361
    pl050_init(0x10006000, sic, 3, 0);
173 362
    pl050_init(0x10007000, sic, 4, 1);
174 363

  
175
    /* TODO: Init PCI NICs.  */
176
    if (nd_table[0].vlan) {
177
        if (nd_table[0].model == NULL
178
            || strcmp(nd_table[0].model, "smc91c111") == 0) {
179
            smc91c111_init(&nd_table[0], 0x10010000, sic, 25);
364
    pci_bus = pci_vpb_init(sic);
365
    /* The Versatile PCI bridge does not provide access to PCI IO space,
366
       so many of the qemu PCI devices are not useable.  */
367
    for(n = 0; n < nb_nics; n++) {
368
        nd = &nd_table[n];
369
        if (!nd->model)
370
            nd->model = done_smc ? "rtl8139" : "smc91c111";
371
        if (strcmp(nd->model, "smc91c111") == 0) {
372
            smc91c111_init(nd, 0x10010000, sic, 25);
180 373
        } else {
181
            fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
182
            exit (1);
374
            pci_nic_init(pci_bus, nd);
183 375
        }
184 376
    }
185 377

  

Also available in: Unified diff