~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to hw/tc6393xb.c

  • Committer: blueswir1
  • Date: 2007-11-25 08:48:16 UTC
  • Revision ID: git-v1:b76482e76560345c00e7d6c89199ced204a926d2
 Fix buffer mux handling for unconnected serial ports


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3737 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Toshiba TC6393XB I/O Controller.
3
 
 * Found in Sharp Zaurus SL-6000 (tosa) or some
4
 
 * Toshiba e-Series PDAs.
5
 
 *
6
 
 * Most features are currently unsupported!!!
7
 
 *
8
 
 * This code is licensed under the GNU GPL v2.
9
 
 */
10
 
#include "hw.h"
11
 
#include "pxa.h"
12
 
#include "devices.h"
13
 
#include "flash.h"
14
 
#include "console.h"
15
 
#include "pixel_ops.h"
16
 
 
17
 
#define IRQ_TC6393_NAND         0
18
 
#define IRQ_TC6393_MMC          1
19
 
#define IRQ_TC6393_OHCI         2
20
 
#define IRQ_TC6393_SERIAL       3
21
 
#define IRQ_TC6393_FB           4
22
 
 
23
 
#define TC6393XB_NR_IRQS        8
24
 
 
25
 
#define TC6393XB_GPIOS  16
26
 
 
27
 
#define SCR_REVID       0x08            /* b Revision ID        */
28
 
#define SCR_ISR         0x50            /* b Interrupt Status   */
29
 
#define SCR_IMR         0x52            /* b Interrupt Mask     */
30
 
#define SCR_IRR         0x54            /* b Interrupt Routing  */
31
 
#define SCR_GPER        0x60            /* w GP Enable          */
32
 
#define SCR_GPI_SR(i)   (0x64 + (i))    /* b3 GPI Status        */
33
 
#define SCR_GPI_IMR(i)  (0x68 + (i))    /* b3 GPI INT Mask      */
34
 
#define SCR_GPI_EDER(i) (0x6c + (i))    /* b3 GPI Edge Detect Enable */
35
 
#define SCR_GPI_LIR(i)  (0x70 + (i))    /* b3 GPI Level Invert  */
36
 
#define SCR_GPO_DSR(i)  (0x78 + (i))    /* b3 GPO Data Set      */
37
 
#define SCR_GPO_DOECR(i) (0x7c + (i))   /* b3 GPO Data OE Control */
38
 
#define SCR_GP_IARCR(i) (0x80 + (i))    /* b3 GP Internal Active Register Control */
39
 
#define SCR_GP_IARLCR(i) (0x84 + (i))   /* b3 GP INTERNAL Active Register Level Control */
40
 
#define SCR_GPI_BCR(i)  (0x88 + (i))    /* b3 GPI Buffer Control */
41
 
#define SCR_GPA_IARCR   0x8c            /* w GPa Internal Active Register Control */
42
 
#define SCR_GPA_IARLCR  0x90            /* w GPa Internal Active Register Level Control */
43
 
#define SCR_GPA_BCR     0x94            /* w GPa Buffer Control */
44
 
#define SCR_CCR         0x98            /* w Clock Control      */
45
 
#define SCR_PLL2CR      0x9a            /* w PLL2 Control       */
46
 
#define SCR_PLL1CR      0x9c            /* l PLL1 Control       */
47
 
#define SCR_DIARCR      0xa0            /* b Device Internal Active Register Control */
48
 
#define SCR_DBOCR       0xa1            /* b Device Buffer Off Control */
49
 
#define SCR_FER         0xe0            /* b Function Enable    */
50
 
#define SCR_MCR         0xe4            /* w Mode Control       */
51
 
#define SCR_CONFIG      0xfc            /* b Configuration Control */
52
 
#define SCR_DEBUG       0xff            /* b Debug              */
53
 
 
54
 
#define NAND_CFG_COMMAND    0x04    /* w Command        */
55
 
#define NAND_CFG_BASE       0x10    /* l Control Base Address */
56
 
#define NAND_CFG_INTP       0x3d    /* b Interrupt Pin  */
57
 
#define NAND_CFG_INTE       0x48    /* b Int Enable     */
58
 
#define NAND_CFG_EC         0x4a    /* b Event Control  */
59
 
#define NAND_CFG_ICC        0x4c    /* b Internal Clock Control */
60
 
#define NAND_CFG_ECCC       0x5b    /* b ECC Control    */
61
 
#define NAND_CFG_NFTC       0x60    /* b NAND Flash Transaction Control */
62
 
#define NAND_CFG_NFM        0x61    /* b NAND Flash Monitor */
63
 
#define NAND_CFG_NFPSC      0x62    /* b NAND Flash Power Supply Control */
64
 
#define NAND_CFG_NFDC       0x63    /* b NAND Flash Detect Control */
65
 
 
66
 
#define NAND_DATA   0x00        /* l Data       */
67
 
#define NAND_MODE   0x04        /* b Mode       */
68
 
#define NAND_STATUS 0x05        /* b Status     */
69
 
#define NAND_ISR    0x06        /* b Interrupt Status */
70
 
#define NAND_IMR    0x07        /* b Interrupt Mask */
71
 
 
72
 
#define NAND_MODE_WP        0x80
73
 
#define NAND_MODE_CE        0x10
74
 
#define NAND_MODE_ALE       0x02
75
 
#define NAND_MODE_CLE       0x01
76
 
#define NAND_MODE_ECC_MASK  0x60
77
 
#define NAND_MODE_ECC_EN    0x20
78
 
#define NAND_MODE_ECC_READ  0x40
79
 
#define NAND_MODE_ECC_RST   0x60
80
 
 
81
 
struct tc6393xb_s {
82
 
    target_phys_addr_t target_base;
83
 
    qemu_irq irq;
84
 
    qemu_irq *sub_irqs;
85
 
    struct {
86
 
        uint8_t ISR;
87
 
        uint8_t IMR;
88
 
        uint8_t IRR;
89
 
        uint16_t GPER;
90
 
        uint8_t GPI_SR[3];
91
 
        uint8_t GPI_IMR[3];
92
 
        uint8_t GPI_EDER[3];
93
 
        uint8_t GPI_LIR[3];
94
 
        uint8_t GP_IARCR[3];
95
 
        uint8_t GP_IARLCR[3];
96
 
        uint8_t GPI_BCR[3];
97
 
        uint16_t GPA_IARCR;
98
 
        uint16_t GPA_IARLCR;
99
 
        uint16_t CCR;
100
 
        uint16_t PLL2CR;
101
 
        uint32_t PLL1CR;
102
 
        uint8_t DIARCR;
103
 
        uint8_t DBOCR;
104
 
        uint8_t FER;
105
 
        uint16_t MCR;
106
 
        uint8_t CONFIG;
107
 
        uint8_t DEBUG;
108
 
    } scr;
109
 
    uint32_t gpio_dir;
110
 
    uint32_t gpio_level;
111
 
    uint32_t prev_level;
112
 
    qemu_irq handler[TC6393XB_GPIOS];
113
 
    qemu_irq *gpio_in;
114
 
 
115
 
    struct {
116
 
        uint8_t mode;
117
 
        uint8_t isr;
118
 
        uint8_t imr;
119
 
    } nand;
120
 
    int nand_enable;
121
 
    uint32_t nand_phys;
122
 
    struct nand_flash_s *flash;
123
 
    struct ecc_state_s ecc;
124
 
 
125
 
    DisplayState *ds;
126
 
    QEMUConsole *console;
127
 
    ram_addr_t vram_addr;
128
 
    uint32_t scr_width, scr_height; /* in pixels */
129
 
    qemu_irq l3v;
130
 
    unsigned blank : 1,
131
 
             blanked : 1;
132
 
};
133
 
 
134
 
qemu_irq *tc6393xb_gpio_in_get(struct tc6393xb_s *s)
135
 
{
136
 
    return s->gpio_in;
137
 
}
138
 
 
139
 
static void tc6393xb_gpio_set(void *opaque, int line, int level)
140
 
{
141
 
//    struct tc6393xb_s *s = opaque;
142
 
 
143
 
    if (line > TC6393XB_GPIOS) {
144
 
        printf("%s: No GPIO pin %i\n", __FUNCTION__, line);
145
 
        return;
146
 
    }
147
 
 
148
 
    // FIXME: how does the chip reflect the GPIO input level change?
149
 
}
150
 
 
151
 
void tc6393xb_gpio_out_set(struct tc6393xb_s *s, int line,
152
 
                    qemu_irq handler)
153
 
{
154
 
    if (line >= TC6393XB_GPIOS) {
155
 
        fprintf(stderr, "TC6393xb: no GPIO pin %d\n", line);
156
 
        return;
157
 
    }
158
 
 
159
 
    s->handler[line] = handler;
160
 
}
161
 
 
162
 
static void tc6393xb_gpio_handler_update(struct tc6393xb_s *s)
163
 
{
164
 
    uint32_t level, diff;
165
 
    int bit;
166
 
 
167
 
    level = s->gpio_level & s->gpio_dir;
168
 
 
169
 
    for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
170
 
        bit = ffs(diff) - 1;
171
 
        qemu_set_irq(s->handler[bit], (level >> bit) & 1);
172
 
    }
173
 
 
174
 
    s->prev_level = level;
175
 
}
176
 
 
177
 
qemu_irq tc6393xb_l3v_get(struct tc6393xb_s *s)
178
 
{
179
 
    return s->l3v;
180
 
}
181
 
 
182
 
static void tc6393xb_l3v(void *opaque, int line, int level)
183
 
{
184
 
    struct tc6393xb_s *s = opaque;
185
 
    s->blank = !level;
186
 
    fprintf(stderr, "L3V: %d\n", level);
187
 
}
188
 
 
189
 
static void tc6393xb_sub_irq(void *opaque, int line, int level) {
190
 
    struct tc6393xb_s *s = opaque;
191
 
    uint8_t isr = s->scr.ISR;
192
 
    if (level)
193
 
        isr |= 1 << line;
194
 
    else
195
 
        isr &= ~(1 << line);
196
 
    s->scr.ISR = isr;
197
 
    qemu_set_irq(s->irq, isr & s->scr.IMR);
198
 
}
199
 
 
200
 
#define SCR_REG_B(N)                            \
201
 
    case SCR_ ##N: return s->scr.N
202
 
#define SCR_REG_W(N)                            \
203
 
    case SCR_ ##N: return s->scr.N;             \
204
 
    case SCR_ ##N + 1: return s->scr.N >> 8;
205
 
#define SCR_REG_L(N)                            \
206
 
    case SCR_ ##N: return s->scr.N;             \
207
 
    case SCR_ ##N + 1: return s->scr.N >> 8;    \
208
 
    case SCR_ ##N + 2: return s->scr.N >> 16;   \
209
 
    case SCR_ ##N + 3: return s->scr.N >> 24;
210
 
#define SCR_REG_A(N)                            \
211
 
    case SCR_ ##N(0): return s->scr.N[0];       \
212
 
    case SCR_ ##N(1): return s->scr.N[1];       \
213
 
    case SCR_ ##N(2): return s->scr.N[2]
214
 
 
215
 
static uint32_t tc6393xb_scr_readb(struct tc6393xb_s *s, target_phys_addr_t addr)
216
 
{
217
 
    switch (addr) {
218
 
        case SCR_REVID:
219
 
            return 3;
220
 
        case SCR_REVID+1:
221
 
            return 0;
222
 
        SCR_REG_B(ISR);
223
 
        SCR_REG_B(IMR);
224
 
        SCR_REG_B(IRR);
225
 
        SCR_REG_W(GPER);
226
 
        SCR_REG_A(GPI_SR);
227
 
        SCR_REG_A(GPI_IMR);
228
 
        SCR_REG_A(GPI_EDER);
229
 
        SCR_REG_A(GPI_LIR);
230
 
        case SCR_GPO_DSR(0):
231
 
        case SCR_GPO_DSR(1):
232
 
        case SCR_GPO_DSR(2):
233
 
            return (s->gpio_level >> ((addr - SCR_GPO_DSR(0)) * 8)) & 0xff;
234
 
        case SCR_GPO_DOECR(0):
235
 
        case SCR_GPO_DOECR(1):
236
 
        case SCR_GPO_DOECR(2):
237
 
            return (s->gpio_dir >> ((addr - SCR_GPO_DOECR(0)) * 8)) & 0xff;
238
 
        SCR_REG_A(GP_IARCR);
239
 
        SCR_REG_A(GP_IARLCR);
240
 
        SCR_REG_A(GPI_BCR);
241
 
        SCR_REG_W(GPA_IARCR);
242
 
        SCR_REG_W(GPA_IARLCR);
243
 
        SCR_REG_W(CCR);
244
 
        SCR_REG_W(PLL2CR);
245
 
        SCR_REG_L(PLL1CR);
246
 
        SCR_REG_B(DIARCR);
247
 
        SCR_REG_B(DBOCR);
248
 
        SCR_REG_B(FER);
249
 
        SCR_REG_W(MCR);
250
 
        SCR_REG_B(CONFIG);
251
 
        SCR_REG_B(DEBUG);
252
 
    }
253
 
    fprintf(stderr, "tc6393xb_scr: unhandled read at %08x\n", (uint32_t) addr);
254
 
    return 0;
255
 
}
256
 
#undef SCR_REG_B
257
 
#undef SCR_REG_W
258
 
#undef SCR_REG_L
259
 
#undef SCR_REG_A
260
 
 
261
 
#define SCR_REG_B(N)                                \
262
 
    case SCR_ ##N: s->scr.N = value; return;
263
 
#define SCR_REG_W(N)                                \
264
 
    case SCR_ ##N: s->scr.N = (s->scr.N & ~0xff) | (value & 0xff); return; \
265
 
    case SCR_ ##N + 1: s->scr.N = (s->scr.N & 0xff) | (value << 8); return
266
 
#define SCR_REG_L(N)                                \
267
 
    case SCR_ ##N: s->scr.N = (s->scr.N & ~0xff) | (value & 0xff); return;   \
268
 
    case SCR_ ##N + 1: s->scr.N = (s->scr.N & ~(0xff << 8)) | (value & (0xff << 8)); return;     \
269
 
    case SCR_ ##N + 2: s->scr.N = (s->scr.N & ~(0xff << 16)) | (value & (0xff << 16)); return;   \
270
 
    case SCR_ ##N + 3: s->scr.N = (s->scr.N & ~(0xff << 24)) | (value & (0xff << 24)); return;
271
 
#define SCR_REG_A(N)                                \
272
 
    case SCR_ ##N(0): s->scr.N[0] = value; return;   \
273
 
    case SCR_ ##N(1): s->scr.N[1] = value; return;   \
274
 
    case SCR_ ##N(2): s->scr.N[2] = value; return
275
 
 
276
 
static void tc6393xb_scr_writeb(struct tc6393xb_s *s, target_phys_addr_t addr, uint32_t value)
277
 
{
278
 
    switch (addr) {
279
 
        SCR_REG_B(ISR);
280
 
        SCR_REG_B(IMR);
281
 
        SCR_REG_B(IRR);
282
 
        SCR_REG_W(GPER);
283
 
        SCR_REG_A(GPI_SR);
284
 
        SCR_REG_A(GPI_IMR);
285
 
        SCR_REG_A(GPI_EDER);
286
 
        SCR_REG_A(GPI_LIR);
287
 
        case SCR_GPO_DSR(0):
288
 
        case SCR_GPO_DSR(1):
289
 
        case SCR_GPO_DSR(2):
290
 
            s->gpio_level = (s->gpio_level & ~(0xff << ((addr - SCR_GPO_DSR(0))*8))) | ((value & 0xff) << ((addr - SCR_GPO_DSR(0))*8));
291
 
            tc6393xb_gpio_handler_update(s);
292
 
            return;
293
 
        case SCR_GPO_DOECR(0):
294
 
        case SCR_GPO_DOECR(1):
295
 
        case SCR_GPO_DOECR(2):
296
 
            s->gpio_dir = (s->gpio_dir & ~(0xff << ((addr - SCR_GPO_DOECR(0))*8))) | ((value & 0xff) << ((addr - SCR_GPO_DOECR(0))*8));
297
 
            tc6393xb_gpio_handler_update(s);
298
 
            return;
299
 
        SCR_REG_A(GP_IARCR);
300
 
        SCR_REG_A(GP_IARLCR);
301
 
        SCR_REG_A(GPI_BCR);
302
 
        SCR_REG_W(GPA_IARCR);
303
 
        SCR_REG_W(GPA_IARLCR);
304
 
        SCR_REG_W(CCR);
305
 
        SCR_REG_W(PLL2CR);
306
 
        SCR_REG_L(PLL1CR);
307
 
        SCR_REG_B(DIARCR);
308
 
        SCR_REG_B(DBOCR);
309
 
        SCR_REG_B(FER);
310
 
        SCR_REG_W(MCR);
311
 
        SCR_REG_B(CONFIG);
312
 
        SCR_REG_B(DEBUG);
313
 
    }
314
 
    fprintf(stderr, "tc6393xb_scr: unhandled write at %08x: %02x\n",
315
 
                                        (uint32_t) addr, value & 0xff);
316
 
}
317
 
#undef SCR_REG_B
318
 
#undef SCR_REG_W
319
 
#undef SCR_REG_L
320
 
#undef SCR_REG_A
321
 
 
322
 
static void tc6393xb_nand_irq(struct tc6393xb_s *s) {
323
 
    qemu_set_irq(s->sub_irqs[IRQ_TC6393_NAND],
324
 
            (s->nand.imr & 0x80) && (s->nand.imr & s->nand.isr));
325
 
}
326
 
 
327
 
static uint32_t tc6393xb_nand_cfg_readb(struct tc6393xb_s *s, target_phys_addr_t addr) {
328
 
    switch (addr) {
329
 
        case NAND_CFG_COMMAND:
330
 
            return s->nand_enable ? 2 : 0;
331
 
        case NAND_CFG_BASE:
332
 
        case NAND_CFG_BASE + 1:
333
 
        case NAND_CFG_BASE + 2:
334
 
        case NAND_CFG_BASE + 3:
335
 
            return s->nand_phys >> (addr - NAND_CFG_BASE);
336
 
    }
337
 
    fprintf(stderr, "tc6393xb_nand_cfg: unhandled read at %08x\n", (uint32_t) addr);
338
 
    return 0;
339
 
}
340
 
static void tc6393xb_nand_cfg_writeb(struct tc6393xb_s *s, target_phys_addr_t addr, uint32_t value) {
341
 
    switch (addr) {
342
 
        case NAND_CFG_COMMAND:
343
 
            s->nand_enable = (value & 0x2);
344
 
            return;
345
 
        case NAND_CFG_BASE:
346
 
        case NAND_CFG_BASE + 1:
347
 
        case NAND_CFG_BASE + 2:
348
 
        case NAND_CFG_BASE + 3:
349
 
            s->nand_phys &= ~(0xff << ((addr - NAND_CFG_BASE) * 8));
350
 
            s->nand_phys |= (value & 0xff) << ((addr - NAND_CFG_BASE) * 8);
351
 
            return;
352
 
    }
353
 
    fprintf(stderr, "tc6393xb_nand_cfg: unhandled write at %08x: %02x\n",
354
 
                                        (uint32_t) addr, value & 0xff);
355
 
}
356
 
 
357
 
static uint32_t tc6393xb_nand_readb(struct tc6393xb_s *s, target_phys_addr_t addr) {
358
 
    switch (addr) {
359
 
        case NAND_DATA + 0:
360
 
        case NAND_DATA + 1:
361
 
        case NAND_DATA + 2:
362
 
        case NAND_DATA + 3:
363
 
            return nand_getio(s->flash);
364
 
        case NAND_MODE:
365
 
            return s->nand.mode;
366
 
        case NAND_STATUS:
367
 
            return 0x14;
368
 
        case NAND_ISR:
369
 
            return s->nand.isr;
370
 
        case NAND_IMR:
371
 
            return s->nand.imr;
372
 
    }
373
 
    fprintf(stderr, "tc6393xb_nand: unhandled read at %08x\n", (uint32_t) addr);
374
 
    return 0;
375
 
}
376
 
static void tc6393xb_nand_writeb(struct tc6393xb_s *s, target_phys_addr_t addr, uint32_t value) {
377
 
//    fprintf(stderr, "tc6393xb_nand: write at %08x: %02x\n",
378
 
//                                      (uint32_t) addr, value & 0xff);
379
 
    switch (addr) {
380
 
        case NAND_DATA + 0:
381
 
        case NAND_DATA + 1:
382
 
        case NAND_DATA + 2:
383
 
        case NAND_DATA + 3:
384
 
            nand_setio(s->flash, value);
385
 
            s->nand.isr &= 1;
386
 
            tc6393xb_nand_irq(s);
387
 
            return;
388
 
        case NAND_MODE:
389
 
            s->nand.mode = value;
390
 
            nand_setpins(s->flash,
391
 
                    value & NAND_MODE_CLE,
392
 
                    value & NAND_MODE_ALE,
393
 
                    !(value & NAND_MODE_CE),
394
 
                    value & NAND_MODE_WP,
395
 
                    0); // FIXME: gnd
396
 
            switch (value & NAND_MODE_ECC_MASK) {
397
 
                case NAND_MODE_ECC_RST:
398
 
                    ecc_reset(&s->ecc);
399
 
                    break;
400
 
                case NAND_MODE_ECC_READ:
401
 
                    // FIXME
402
 
                    break;
403
 
                case NAND_MODE_ECC_EN:
404
 
                    ecc_reset(&s->ecc);
405
 
            }
406
 
            return;
407
 
        case NAND_ISR:
408
 
            s->nand.isr = value;
409
 
            tc6393xb_nand_irq(s);
410
 
            return;
411
 
        case NAND_IMR:
412
 
            s->nand.imr = value;
413
 
            tc6393xb_nand_irq(s);
414
 
            return;
415
 
    }
416
 
    fprintf(stderr, "tc6393xb_nand: unhandled write at %08x: %02x\n",
417
 
                                        (uint32_t) addr, value & 0xff);
418
 
}
419
 
 
420
 
#define BITS 8
421
 
#include "tc6393xb_template.h"
422
 
#define BITS 15
423
 
#include "tc6393xb_template.h"
424
 
#define BITS 16
425
 
#include "tc6393xb_template.h"
426
 
#define BITS 24
427
 
#include "tc6393xb_template.h"
428
 
#define BITS 32
429
 
#include "tc6393xb_template.h"
430
 
 
431
 
static void tc6393xb_draw_graphic(struct tc6393xb_s *s, int full_update)
432
 
{
433
 
    switch (s->ds->depth) {
434
 
        case 8:
435
 
            tc6393xb_draw_graphic8(s);
436
 
            break;
437
 
        case 15:
438
 
            tc6393xb_draw_graphic15(s);
439
 
            break;
440
 
        case 16:
441
 
            tc6393xb_draw_graphic16(s);
442
 
            break;
443
 
        case 24:
444
 
            tc6393xb_draw_graphic24(s);
445
 
            break;
446
 
        case 32:
447
 
            tc6393xb_draw_graphic32(s);
448
 
            break;
449
 
        default:
450
 
            printf("tc6393xb: unknown depth %d\n", s->ds->depth);
451
 
            return;
452
 
    }
453
 
 
454
 
    dpy_update(s->ds, 0, 0, s->scr_width, s->scr_height);
455
 
}
456
 
 
457
 
static void tc6393xb_draw_blank(struct tc6393xb_s *s, int full_update)
458
 
{
459
 
    int i, w;
460
 
    uint8_t *d;
461
 
 
462
 
    if (!full_update)
463
 
        return;
464
 
 
465
 
    w = s->scr_width * ((s->ds->depth + 7) >> 3);
466
 
    d = s->ds->data;
467
 
    for(i = 0; i < s->scr_height; i++) {
468
 
        memset(d, 0, w);
469
 
        d += s->ds->linesize;
470
 
    }
471
 
 
472
 
    dpy_update(s->ds, 0, 0, s->scr_width, s->scr_height);
473
 
}
474
 
 
475
 
static void tc6393xb_update_display(void *opaque)
476
 
{
477
 
    struct tc6393xb_s *s = opaque;
478
 
    int full_update;
479
 
 
480
 
    if (s->scr_width == 0 || s->scr_height == 0)
481
 
        return;
482
 
 
483
 
    full_update = 0;
484
 
    if (s->blanked != s->blank) {
485
 
        s->blanked = s->blank;
486
 
        full_update = 1;
487
 
    }
488
 
    if (s->scr_width != s->ds->width || s->scr_height != s->ds->height) {
489
 
        qemu_console_resize(s->console, s->scr_width, s->scr_height);
490
 
        full_update = 1;
491
 
    }
492
 
    if (s->blanked)
493
 
        tc6393xb_draw_blank(s, full_update);
494
 
    else
495
 
        tc6393xb_draw_graphic(s, full_update);
496
 
}
497
 
 
498
 
 
499
 
static uint32_t tc6393xb_readb(void *opaque, target_phys_addr_t addr) {
500
 
    struct tc6393xb_s *s = opaque;
501
 
    addr -= s->target_base;
502
 
 
503
 
    switch (addr >> 8) {
504
 
        case 0:
505
 
            return tc6393xb_scr_readb(s, addr & 0xff);
506
 
        case 1:
507
 
            return tc6393xb_nand_cfg_readb(s, addr & 0xff);
508
 
    };
509
 
 
510
 
    if ((addr &~0xff) == s->nand_phys && s->nand_enable) {
511
 
//        return tc6393xb_nand_readb(s, addr & 0xff);
512
 
        uint8_t d = tc6393xb_nand_readb(s, addr & 0xff);
513
 
//        fprintf(stderr, "tc6393xb_nand: read at %08x: %02hhx\n", (uint32_t) addr, d);
514
 
        return d;
515
 
    }
516
 
 
517
 
//    fprintf(stderr, "tc6393xb: unhandled read at %08x\n", (uint32_t) addr);
518
 
    return 0;
519
 
}
520
 
 
521
 
static void tc6393xb_writeb(void *opaque, target_phys_addr_t addr, uint32_t value) {
522
 
    struct tc6393xb_s *s = opaque;
523
 
    addr -= s->target_base;
524
 
 
525
 
    switch (addr >> 8) {
526
 
        case 0:
527
 
            tc6393xb_scr_writeb(s, addr & 0xff, value);
528
 
            return;
529
 
        case 1:
530
 
            tc6393xb_nand_cfg_writeb(s, addr & 0xff, value);
531
 
            return;
532
 
    };
533
 
 
534
 
    if ((addr &~0xff) == s->nand_phys && s->nand_enable)
535
 
        tc6393xb_nand_writeb(s, addr & 0xff, value);
536
 
    else
537
 
        fprintf(stderr, "tc6393xb: unhandled write at %08x: %02x\n",
538
 
                                        (uint32_t) addr, value & 0xff);
539
 
}
540
 
 
541
 
static uint32_t tc6393xb_readw(void *opaque, target_phys_addr_t addr)
542
 
{
543
 
    return (tc6393xb_readb(opaque, addr) & 0xff) |
544
 
        (tc6393xb_readb(opaque, addr + 1) << 8);
545
 
}
546
 
 
547
 
static uint32_t tc6393xb_readl(void *opaque, target_phys_addr_t addr)
548
 
{
549
 
    return (tc6393xb_readb(opaque, addr) & 0xff) |
550
 
        ((tc6393xb_readb(opaque, addr + 1) & 0xff) << 8) |
551
 
        ((tc6393xb_readb(opaque, addr + 2) & 0xff) << 16) |
552
 
        ((tc6393xb_readb(opaque, addr + 3) & 0xff) << 24);
553
 
}
554
 
 
555
 
static void tc6393xb_writew(void *opaque, target_phys_addr_t addr, uint32_t value)
556
 
{
557
 
    tc6393xb_writeb(opaque, addr, value);
558
 
    tc6393xb_writeb(opaque, addr + 1, value >> 8);
559
 
}
560
 
 
561
 
static void tc6393xb_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
562
 
{
563
 
    tc6393xb_writeb(opaque, addr, value);
564
 
    tc6393xb_writeb(opaque, addr + 1, value >> 8);
565
 
    tc6393xb_writeb(opaque, addr + 2, value >> 16);
566
 
    tc6393xb_writeb(opaque, addr + 3, value >> 24);
567
 
}
568
 
 
569
 
struct tc6393xb_s *tc6393xb_init(uint32_t base, qemu_irq irq, DisplayState *ds)
570
 
{
571
 
    int iomemtype;
572
 
    struct tc6393xb_s *s;
573
 
    CPUReadMemoryFunc *tc6393xb_readfn[] = {
574
 
        tc6393xb_readb,
575
 
        tc6393xb_readw,
576
 
        tc6393xb_readl,
577
 
    };
578
 
    CPUWriteMemoryFunc *tc6393xb_writefn[] = {
579
 
        tc6393xb_writeb,
580
 
        tc6393xb_writew,
581
 
        tc6393xb_writel,
582
 
    };
583
 
 
584
 
    s = (struct tc6393xb_s *) qemu_mallocz(sizeof(struct tc6393xb_s));
585
 
    s->target_base = base;
586
 
    s->irq = irq;
587
 
    s->gpio_in = qemu_allocate_irqs(tc6393xb_gpio_set, s, TC6393XB_GPIOS);
588
 
 
589
 
    s->l3v = *qemu_allocate_irqs(tc6393xb_l3v, s, 1);
590
 
    s->blanked = 1;
591
 
 
592
 
    s->sub_irqs = qemu_allocate_irqs(tc6393xb_sub_irq, s, TC6393XB_NR_IRQS);
593
 
 
594
 
    s->flash = nand_init(NAND_MFR_TOSHIBA, 0x76);
595
 
 
596
 
    iomemtype = cpu_register_io_memory(0, tc6393xb_readfn,
597
 
                    tc6393xb_writefn, s);
598
 
    cpu_register_physical_memory(s->target_base, 0x10000, iomemtype);
599
 
 
600
 
    if (ds) {
601
 
        s->ds = ds;
602
 
        s->vram_addr = qemu_ram_alloc(0x100000);
603
 
        cpu_register_physical_memory(s->target_base + 0x100000, 0x100000, s->vram_addr);
604
 
        s->scr_width = 480;
605
 
        s->scr_height = 640;
606
 
        s->console = graphic_console_init(ds,
607
 
                tc6393xb_update_display,
608
 
                NULL, /* invalidate */
609
 
                NULL, /* screen_dump */
610
 
                NULL, /* text_update */
611
 
                s);
612
 
    }
613
 
 
614
 
    return s;
615
 
}