Revision 3387bf55

b/hw/omap_gpmc.c
54 54
    qemu_set_irq(s->irq, s->irqen & s->irqst);
55 55
}
56 56

  
57
static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask)
57
static void omap_gpmc_cs_map(struct omap_gpmc_s *s, int cs)
58 58
{
59
    struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
60
    uint32_t mask = (f->config[6] >> 8) & 0xf;
61
    uint32_t base = f->config[6] & 0x3f;
59 62
    uint32_t size;
60 63

  
61 64
    if (!f->iomem) {
62 65
        return;
63 66
    }
64 67

  
68
    if (!(f->config[6] & (1 << 6))) {
69
        /* Do nothing unless CSVALID */
70
        return;
71
    }
72

  
65 73
    /* TODO: check for overlapping regions and report access errors */
66 74
    if ((mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf) ||
67
                    (base < 0 || base >= 0x40) ||
68
                    (base & 0x0f & ~mask)) {
75
        (base & 0x0f & ~mask)) {
69 76
        fprintf(stderr, "%s: wrong cs address mapping/decoding!\n",
70 77
                        __FUNCTION__);
71 78
        return;
......
83 90
                                &f->container);
84 91
}
85 92

  
86
static void omap_gpmc_cs_unmap(struct omap_gpmc_cs_file_s *f)
93
static void omap_gpmc_cs_unmap(struct omap_gpmc_s *s, int cs)
87 94
{
95
    struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
96
    if (!(f->config[6] & (1 << 6))) {
97
        /* Do nothing unless CSVALID */
98
        return;
99
    }
88 100
    if (!f->iomem) {
89 101
        return;
90 102
    }
......
110 122
    s->preffifo = 0;
111 123
    s->prefcount = 0;
112 124
    for (i = 0; i < 8; i ++) {
113
        if (s->cs_file[i].config[6] & (1 << 6))			/* CSVALID */
114
            omap_gpmc_cs_unmap(s->cs_file + i);
115
        s->cs_file[i].config[0] = i ? 1 << 12 : 0;
125
        omap_gpmc_cs_unmap(s, i);
116 126
        s->cs_file[i].config[1] = 0x101001;
117 127
        s->cs_file[i].config[2] = 0x020201;
118 128
        s->cs_file[i].config[3] = 0x10031003;
119 129
        s->cs_file[i].config[4] = 0x10f1111;
120 130
        s->cs_file[i].config[5] = 0;
121 131
        s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6);
122
        if (s->cs_file[i].config[6] & (1 << 6))			/* CSVALID */
123
            omap_gpmc_cs_map(&s->cs_file[i],
124
                            s->cs_file[i].config[6] & 0x1f,	/* MASKADDR */
125
                        (s->cs_file[i].config[6] >> 8 & 0xf));	/* BASEADDR */
132

  
133
        s->cs_file[i].config[6] = 0xf00;
134
        /* In theory we could probe attached devices for some CFG1
135
         * bits here, but we just retain them across resets as they
136
         * were set initially by omap_gpmc_attach().
137
         */
138
        if (i == 0) {
139
            s->cs_file[i].config[0] &= 0x00433e00;
140
            s->cs_file[i].config[6] |= 1 << 6; /* CSVALID */
141
            omap_gpmc_cs_map(s, i);
142
        } else {
143
            s->cs_file[i].config[0] &= 0x00403c00;
144
        }
126 145
    }
127 146
    s->ecc_cs = 0;
128 147
    s->ecc_ptr = 0;
......
311 330
                break;
312 331
            case 0x78:	/* GPMC_CONFIG7 */
313 332
                if ((f->config[6] ^ value) & 0xf7f) {
314
                    if (f->config[6] & (1 << 6))		/* CSVALID */
315
                        omap_gpmc_cs_unmap(f);
316
                    if (value & (1 << 6))			/* CSVALID */
317
                        omap_gpmc_cs_map(f, value & 0x1f,	/* MASKADDR */
318
                                        (value >> 8 & 0xf));	/* BASEADDR */
333
                    omap_gpmc_cs_unmap(s, cs);
334
                    f->config[6] = value & 0x00000f7f;
335
                    omap_gpmc_cs_map(s, cs);
319 336
                }
320
                f->config[6] = value & 0x00000f7f;
321 337
                break;
322 338
            case 0x7c:	/* GPMC_NAND_COMMAND */
323 339
            case 0x80:	/* GPMC_NAND_ADDRESS */
......
407 423
    }
408 424
    f = &s->cs_file[cs];
409 425

  
426
    omap_gpmc_cs_unmap(s, cs);
410 427
    f->iomem = iomem;
411

  
412
    if (f->config[6] & (1 << 6))				/* CSVALID */
413
        omap_gpmc_cs_map(f, f->config[6] & 0x1f,		/* MASKADDR */
414
                        (f->config[6] >> 8 & 0xf));		/* BASEADDR */
428
    omap_gpmc_cs_map(s, cs);
415 429
}

Also available in: Unified diff