Revision 267002cd

b/hw/adb.c
1
/*
2
 * QEMU ADB support
3
 * 
4
 * Copyright (c) 2004 Fabrice Bellard
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 "vl.h"
25

  
26
/* ADB commands */
27
#define ADB_BUSRESET		0x00
28
#define ADB_FLUSH               0x01
29
#define ADB_WRITEREG		0x08
30
#define ADB_READREG		0x0c
31

  
32
/* ADB device commands */
33
#define ADB_CMD_SELF_TEST		0xff
34
#define ADB_CMD_CHANGE_ID		0xfe
35
#define ADB_CMD_CHANGE_ID_AND_ACT	0xfd
36
#define ADB_CMD_CHANGE_ID_AND_ENABLE	0x00
37

  
38
/* ADB default device IDs (upper 4 bits of ADB command byte) */
39
#define ADB_DONGLE	1
40
#define ADB_KEYBOARD	2
41
#define ADB_MOUSE	3
42
#define ADB_TABLET	4
43
#define ADB_MODEM	5
44
#define ADB_MISC	7
45

  
46
#define ADB_RET_OK			0
47
#define ADB_RET_INUSE			1
48
#define ADB_RET_NOTPRESENT		2
49
#define ADB_RET_TIMEOUT			3
50
#define ADB_RET_UNEXPECTED_RESULT	4
51
#define ADB_RET_REQUEST_ERROR		5
52
#define ADB_RET_BUS_ERROR		6
53

  
54

  
55
static void adb_send_packet1(ADBBusState *s, uint8_t reply)
56
{
57
    adb_send_packet(s, &reply, 1);
58
}
59

  
60
void adb_receive_packet(ADBBusState *s, const uint8_t *buf, int len)
61
{
62
    ADBDevice *d;
63
    int devaddr, cmd, i;
64
    uint8_t obuf[4];
65

  
66
    cmd = buf[1] & 0xf;
67
    devaddr = buf[1] >> 4;
68
    if (buf[1] == ADB_BUSRESET) {
69
        obuf[0] = 0x00;
70
        obuf[1] = 0x00;
71
        adb_send_packet(s, obuf, 2);
72
        return;
73
    }
74
    if (cmd == ADB_FLUSH) {
75
        obuf[0] = 0x00;
76
        obuf[1] = 0x00;
77
        adb_send_packet(s, obuf, 2);
78
        return;
79
    }
80

  
81
    for(i = 0; i < s->nb_devices; i++) {
82
        d = &s->devices[i];
83
        if (d->devaddr == devaddr) {
84
            d->receive_packet(d, buf, len);
85
            return;
86
        }
87
    }
88
    adb_send_packet1(s, ADB_RET_NOTPRESENT);
89
}
90

  
91
ADBDevice *adb_register_device(ADBBusState *s, int devaddr, 
92
                               ADBDeviceReceivePacket *receive_packet, 
93
                               void *opaque)
94
{
95
    ADBDevice *d;
96
    if (s->nb_devices >= MAX_ADB_DEVICES)
97
        return NULL;
98
    d = &s->devices[s->nb_devices++];
99
    d->bus = s;
100
    d->devaddr = devaddr;
101
    d->receive_packet = receive_packet;
102
    d->opaque = opaque;
103
    return d;
104
}
105

  
106
/***************************************************************/
107
/* Keyboard ADB device */
108

  
109
static const uint8_t pc_to_adb_keycode[256] = {
110
  0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
111
 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54,  0,  1,
112
  2,  3,  5,  4, 38, 40, 37, 41, 39, 50, 56, 42,  6,  7,  8,  9,
113
 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
114
 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
115
 84, 85, 82, 65,  0,  0, 10,103,111,  0,  0,  0,  0,  0,  0,  0,
116
 76,125, 75,105,124,110,115, 62,116, 59, 60,119, 61,121,114,117,
117
  0,  0,  0,  0,127, 81,  0,113,  0,  0,  0,  0, 95, 55,  0,  0,
118
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
119
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
120
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
121
  0,  0,  0,  0,  0, 94,  0, 93,  0,  0,  0,  0,  0,  0,104,102,
122
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
123
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
124
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
125
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
126
};
127

  
128
static void adb_kbd_put_keycode(void *opaque, int keycode)
129
{
130
    static int ext_keycode;
131
    ADBDevice *d = opaque;
132
    uint8_t buf[4];
133
    int adb_keycode;
134
    
135
    if (keycode == 0xe0) {
136
        ext_keycode = 1;
137
    } else {
138
        
139
        if (ext_keycode)
140
            adb_keycode =  pc_to_adb_keycode[keycode | 0x80];
141
        else
142
            adb_keycode =  pc_to_adb_keycode[keycode & 0x7f];
143
            
144
        buf[0] = 0x40;
145
        buf[1] = (d->devaddr << 4) | 0x0c;
146
        buf[2] = adb_keycode | (keycode & 0x80);
147
        buf[3] = 0xff;
148
        adb_send_packet(d->bus, buf, 4);
149
        ext_keycode = 0;
150
    }
151
}
152

  
153
static void adb_kbd_receive_packet(ADBDevice *d, const uint8_t *buf, int len)
154
{
155
    int cmd, reg;
156
    uint8_t obuf[4];
157

  
158
    cmd = buf[0] & 0xc;
159
    reg = buf[0] & 0x3;
160
    switch(cmd) {
161
    case ADB_WRITEREG:
162
        switch(reg) {
163
        case 2:
164
            /* LED status */
165
            adb_send_packet1(d->bus, ADB_RET_OK);
166
            break;
167
        case 3:
168
            switch(buf[2]) {
169
            case ADB_CMD_SELF_TEST:
170
                adb_send_packet1(d->bus, ADB_RET_OK);
171
                break;
172
            case ADB_CMD_CHANGE_ID:
173
            case ADB_CMD_CHANGE_ID_AND_ACT:
174
            case ADB_CMD_CHANGE_ID_AND_ENABLE:
175
                d->devaddr = buf[1] & 0xf;
176
                adb_send_packet1(d->bus, ADB_RET_OK);
177
                break;
178
            default:
179
                /* XXX: check this */
180
                d->devaddr = buf[1] & 0xf;
181
                d->handler = buf[2];
182
                adb_send_packet1(d->bus, ADB_RET_OK);
183
                break;
184
            }
185
        }
186
        break;
187
    case ADB_READREG:
188
        switch(reg) {
189
        case 1:
190
            adb_send_packet1(d->bus, ADB_RET_OK);
191
            break;
192
        case 2:
193
            obuf[0] = ADB_RET_OK;
194
            obuf[1] = 0x00; /* XXX: check this */
195
            obuf[2] = 0x07; /* led status */
196
            adb_send_packet(d->bus, obuf, 3);
197
            break;
198
        case 3:
199
            obuf[0] = ADB_RET_OK;
200
            obuf[1] = d->handler;
201
            obuf[2] = d->devaddr;
202
            adb_send_packet(d->bus, obuf, 3);
203
            break;
204
        }
205
        break;
206
    }
207
}
208

  
209
void adb_kbd_init(ADBBusState *bus)
210
{
211
    ADBDevice *d;
212

  
213
    d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_receive_packet, NULL);
214
    qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
215
}
216

  
217
/***************************************************************/
218
/* Mouse ADB device */
219

  
220
static void adb_mouse_event(void *opaque,
221
                            int dx1, int dy1, int dz1, int buttons_state)
222
{
223
    ADBDevice *d = opaque;
224
    uint8_t buf[4];
225
    int dx, dy;
226

  
227
    dx = dx1;
228
    if (dx < -63)
229
        dx = -63;
230
    else if (dx > 63)
231
        dx = 63;
232

  
233
    dy = dy1;
234
    if (dy < -63)
235
        dy = -63;
236
    else if (dy > 63)
237
        dy = 63;
238

  
239
    dx &= 0x7f;
240
    dy &= 0x7f;
241

  
242
    if (buttons_state & MOUSE_EVENT_LBUTTON)
243
        dy |= 0x80;
244
    if (buttons_state & MOUSE_EVENT_RBUTTON)
245
        dx |= 0x80;
246

  
247
    buf[0] = 0x40;
248
    buf[1] = (d->devaddr << 4) | 0x0c;
249
    buf[2] = dy;
250
    buf[3] = dx;
251
    adb_send_packet(d->bus, buf, 4);
252
}
253

  
254
static void adb_mouse_receive_packet(ADBDevice *d, const uint8_t *buf, int len)
255
{
256
    int cmd, reg;
257
    uint8_t obuf[4];
258

  
259
    cmd = buf[0] & 0xc;
260
    reg = buf[0] & 0x3;
261
    switch(cmd) {
262
    case ADB_WRITEREG:
263
        switch(reg) {
264
        case 2:
265
            adb_send_packet1(d->bus, ADB_RET_OK);
266
            break;
267
        case 3:
268
            switch(buf[2]) {
269
            case ADB_CMD_SELF_TEST:
270
                adb_send_packet1(d->bus, ADB_RET_OK);
271
                break;
272
            case ADB_CMD_CHANGE_ID:
273
            case ADB_CMD_CHANGE_ID_AND_ACT:
274
            case ADB_CMD_CHANGE_ID_AND_ENABLE:
275
                d->devaddr = buf[1] & 0xf;
276
                adb_send_packet1(d->bus, ADB_RET_OK);
277
                break;
278
            default:
279
                /* XXX: check this */
280
                d->devaddr = buf[1] & 0xf;
281
                adb_send_packet1(d->bus, ADB_RET_OK);
282
                break;
283
            }
284
        }
285
        break;
286
    case ADB_READREG:
287
        switch(reg) {
288
        case 1:
289
            adb_send_packet1(d->bus, ADB_RET_OK);
290
            break;
291
        case 3:
292
            obuf[0] = ADB_RET_OK;
293
            obuf[1] = d->handler;
294
            obuf[2] = d->devaddr;
295
            adb_send_packet(d->bus, obuf, 3);
296
            break;
297
        }
298
        break;
299
    }
300
}
301

  
302
void adb_mouse_init(ADBBusState *bus)
303
{
304
    ADBDevice *d;
305

  
306
    d = adb_register_device(bus, ADB_MOUSE, adb_mouse_receive_packet, NULL);
307
    qemu_add_mouse_event_handler(adb_mouse_event, d);
308
}
b/hw/cuda.c
1
/*
2
 * QEMU CUDA support
3
 * 
4
 * Copyright (c) 2004 Fabrice Bellard
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 "vl.h"
25

  
26
/* Bits in B data register: all active low */
27
#define TREQ		0x08		/* Transfer request (input) */
28
#define TACK		0x10		/* Transfer acknowledge (output) */
29
#define TIP		0x20		/* Transfer in progress (output) */
30

  
31
/* Bits in ACR */
32
#define SR_CTRL		0x1c		/* Shift register control bits */
33
#define SR_EXT		0x0c		/* Shift on external clock */
34
#define SR_OUT		0x10		/* Shift out if 1 */
35

  
36
/* Bits in IFR and IER */
37
#define IER_SET		0x80		/* set bits in IER */
38
#define IER_CLR		0		/* clear bits in IER */
39
#define SR_INT		0x04		/* Shift register full/empty */
40
#define T1_INT          0x40            /* Timer 1 interrupt */
41

  
42
/* Bits in ACR */
43
#define T1MODE          0xc0            /* Timer 1 mode */
44
#define T1MODE_CONT     0x40            /*  continuous interrupts */
45

  
46
/* commands (1st byte) */
47
#define ADB_PACKET	0
48
#define CUDA_PACKET	1
49
#define ERROR_PACKET	2
50
#define TIMER_PACKET	3
51
#define POWER_PACKET	4
52
#define MACIIC_PACKET	5
53
#define PMU_PACKET	6
54

  
55

  
56
/* CUDA commands (2nd byte) */
57
#define CUDA_WARM_START			0x0
58
#define CUDA_AUTOPOLL			0x1
59
#define CUDA_GET_6805_ADDR		0x2
60
#define CUDA_GET_TIME			0x3
61
#define CUDA_GET_PRAM			0x7
62
#define CUDA_SET_6805_ADDR		0x8
63
#define CUDA_SET_TIME			0x9
64
#define CUDA_POWERDOWN			0xa
65
#define CUDA_POWERUP_TIME		0xb
66
#define CUDA_SET_PRAM			0xc
67
#define CUDA_MS_RESET			0xd
68
#define CUDA_SEND_DFAC			0xe
69
#define CUDA_BATTERY_SWAP_SENSE		0x10
70
#define CUDA_RESET_SYSTEM		0x11
71
#define CUDA_SET_IPL			0x12
72
#define CUDA_FILE_SERVER_FLAG		0x13
73
#define CUDA_SET_AUTO_RATE		0x14
74
#define CUDA_GET_AUTO_RATE		0x16
75
#define CUDA_SET_DEVICE_LIST		0x19
76
#define CUDA_GET_DEVICE_LIST		0x1a
77
#define CUDA_SET_ONE_SECOND_MODE	0x1b
78
#define CUDA_SET_POWER_MESSAGES		0x21
79
#define CUDA_GET_SET_IIC		0x22
80
#define CUDA_WAKEUP			0x23
81
#define CUDA_TIMER_TICKLE		0x24
82
#define CUDA_COMBINED_FORMAT_IIC	0x25
83

  
84
#define CUDA_TIMER_FREQ (4700000 / 6)
85

  
86
typedef struct CUDATimer {
87
    unsigned int latch;
88
    uint16_t counter_value; /* counter value at load time */
89
    int64_t load_time;
90
    int64_t next_irq_time;
91
    QEMUTimer *timer;
92
} CUDATimer;
93

  
94
typedef struct CUDAState {
95
    /* cuda registers */
96
    uint8_t b;      /* B-side data */
97
    uint8_t a;      /* A-side data */
98
    uint8_t dirb;   /* B-side direction (1=output) */
99
    uint8_t dira;   /* A-side direction (1=output) */
100
    uint8_t sr;     /* Shift register */
101
    uint8_t acr;    /* Auxiliary control register */
102
    uint8_t pcr;    /* Peripheral control register */
103
    uint8_t ifr;    /* Interrupt flag register */
104
    uint8_t ier;    /* Interrupt enable register */
105
    uint8_t anh;    /* A-side data, no handshake */
106

  
107
    CUDATimer timers[2];
108
    
109
    uint8_t last_b; /* last value of B register */
110
    uint8_t last_acr; /* last value of B register */
111
    
112
    int data_in_size;
113
    int data_in_index;
114
    int data_out_index;
115

  
116
    int irq;
117
    uint8_t autopoll;
118
    uint8_t data_in[128];
119
    uint8_t data_out[16];
120
} CUDAState;
121

  
122
static CUDAState cuda_state;
123
ADBBusState adb_bus;
124

  
125
static void cuda_update(CUDAState *s);
126
static void cuda_receive_packet_from_host(CUDAState *s, 
127
                                          const uint8_t *data, int len);
128

  
129
static void cuda_update_irq(CUDAState *s)
130
{
131
    if (s->ifr & s->ier & SR_INT) {
132
        pic_set_irq(s->irq, 1);
133
    } else {
134
        pic_set_irq(s->irq, 0);
135
    }
136
}
137

  
138
static unsigned int get_counter(CUDATimer *s)
139
{
140
    int64_t d;
141
    unsigned int counter;
142

  
143
    d = muldiv64(qemu_get_clock(vm_clock) - s->load_time, 
144
                 CUDA_TIMER_FREQ, ticks_per_sec);
145
    if (d <= s->counter_value) {
146
        counter = d;
147
    } else {
148
        counter = s->latch - 1 - ((d - s->counter_value) % s->latch);
149
    }
150
    return counter;
151
}
152

  
153
static void set_counter(CUDATimer *s, unsigned int val)
154
{
155
    s->load_time = qemu_get_clock(vm_clock);
156
    s->counter_value = val;
157
}
158

  
159
static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time)
160
{
161
    int64_t d, next_time, base;
162
    /* current counter value */
163
    d = muldiv64(current_time - s->load_time, 
164
                 CUDA_TIMER_FREQ, ticks_per_sec);
165
    if (d <= s->counter_value) {
166
        next_time = s->counter_value + 1;
167
    } else {
168
        base = ((d - s->counter_value) % s->latch);
169
        base = (base * s->latch) + s->counter_value;
170
        next_time = base + s->latch;
171
    }
172
    next_time = muldiv64(next_time, ticks_per_sec, CUDA_TIMER_FREQ) + 
173
        s->load_time;
174
    if (next_time <= current_time)
175
        next_time = current_time + 1;
176
    return next_time;
177
}
178

  
179
static void cuda_timer1(void *opaque)
180
{
181
    CUDAState *s = opaque;
182
    CUDATimer *ti = &s->timers[0];
183

  
184
    ti->next_irq_time = get_next_irq_time(ti, ti->next_irq_time);
185
    qemu_mod_timer(ti->timer, ti->next_irq_time);
186
    s->ifr |= T1_INT;
187
    cuda_update_irq(s);
188
}
189

  
190
static uint32_t cuda_readb(void *opaque, target_phys_addr_t addr)
191
{
192
    CUDAState *s = opaque;
193
    uint32_t val;
194

  
195
    addr = (addr >> 9) & 0xf;
196
    switch(addr) {
197
    case 0:
198
        val = s->b;
199
        break;
200
    case 1:
201
        val = s->a;
202
        break;
203
    case 2:
204
        val = s->dirb;
205
        break;
206
    case 3:
207
        val = s->dira;
208
        break;
209
    case 4:
210
        val = get_counter(&s->timers[0]) & 0xff;
211
        s->ifr &= ~T1_INT;
212
        cuda_update_irq(s);
213
        break;
214
    case 5:
215
        val = get_counter(&s->timers[0]) >> 8;
216
        s->ifr &= ~T1_INT;
217
        cuda_update_irq(s);
218
        break;
219
    case 6:
220
        val = s->timers[0].latch & 0xff;
221
        break;
222
    case 7:
223
        val = (s->timers[0].latch >> 8) & 0xff;
224
        break;
225
    case 8:
226
        val = get_counter(&s->timers[1]) & 0xff;
227
        break;
228
    case 9:
229
        val = get_counter(&s->timers[1]) >> 8;
230
        break;
231
    case 10:
232
        if (s->data_in_index < s->data_in_size) {
233
            val = s->data_in[s->data_in_index];
234
        } else {
235
            val = 0;
236
        }
237
        break;
238
    case 11:
239
        val = s->acr;
240
        break;
241
    case 12:
242
        val = s->pcr;
243
        break;
244
    case 13:
245
        val = s->ifr;
246
        break;
247
    case 14:
248
        val = s->ier;
249
        break;
250
    default:
251
    case 15:
252
        val = s->anh;
253
        break;
254
    }
255
#ifdef DEBUG_CUDA
256
    printf("cuda: read: reg=0x%x val=%02x\n", addr, val);
257
#endif
258
    return val;
259
}
260

  
261
static void cuda_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
262
{
263
    CUDAState *s = opaque;
264
    
265
    addr = (addr >> 9) & 0xf;
266
#ifdef DEBUG_CUDA
267
    printf("cuda: write: reg=0x%x val=%02x\n", addr, val);
268
#endif
269

  
270
    switch(addr) {
271
    case 0:
272
        s->b = val;
273
        cuda_update(s);
274
        break;
275
    case 1:
276
        s->a = val;
277
        break;
278
    case 2:
279
        s->dirb = val;
280
        break;
281
    case 3:
282
        s->dira = val;
283
        break;
284
    case 4:
285
        val = val | (get_counter(&s->timers[0]) & 0xff00);
286
        set_counter(&s->timers[0], val);
287
        break;
288
    case 5:
289
        val = (val << 8) |  (get_counter(&s->timers[0]) & 0xff);
290
        set_counter(&s->timers[0], val);
291
        break;
292
    case 6:
293
        s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
294
        break;
295
    case 7:
296
        s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
297
        break;
298
    case 8:
299
        val = val | (get_counter(&s->timers[1]) & 0xff00);
300
        set_counter(&s->timers[1], val);
301
        break;
302
    case 9:
303
        val = (val << 8) |  (get_counter(&s->timers[1]) & 0xff);
304
        set_counter(&s->timers[1], val);
305
        break;
306
    case 10:
307
        s->sr = val;
308
        break;
309
    case 11:
310
        s->acr = val;
311
        if ((s->acr & T1MODE) == T1MODE_CONT) {
312
            if ((s->last_acr & T1MODE) != T1MODE_CONT) {
313
                CUDATimer *ti = &s->timers[0];
314
                /* activate timer interrupt */
315
                ti->next_irq_time = get_next_irq_time(ti, qemu_get_clock(vm_clock));
316
                qemu_mod_timer(ti->timer, ti->next_irq_time);
317
            }
318
        } else {
319
            if ((s->last_acr & T1MODE) == T1MODE_CONT) {
320
                CUDATimer *ti = &s->timers[0];
321
                qemu_del_timer(ti->timer);
322
            }
323
        }
324
        cuda_update(s);
325
        break;
326
    case 12:
327
        s->pcr = val;
328
        break;
329
    case 13:
330
        /* reset bits */
331
        s->ifr &= ~val;
332
        cuda_update_irq(s);
333
        break;
334
    case 14:
335
        if (val & IER_SET) {
336
            /* set bits */
337
            s->ier |= val & 0x7f;
338
        } else {
339
            /* reset bits */
340
            s->ier &= ~val;
341
        }
342
        cuda_update_irq(s);
343
        break;
344
    default:
345
    case 15:
346
        s->anh = val;
347
        break;
348
    }
349
}
350

  
351
/* NOTE: TIP and TREQ are negated */
352
static void cuda_update(CUDAState *s)
353
{
354
    if (s->data_in_index < s->data_in_size) {
355
        /* data input */
356
        if (!(s->b & TIP) && 
357
            (s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
358
            s->sr = s->data_in[s->data_in_index++];
359
            s->ifr |= SR_INT;
360
            cuda_update_irq(s);
361
        }
362
    }
363
    if (s->data_in_index < s->data_in_size) {
364
        /* there is some data to read */
365
        s->b = (s->b & ~TREQ);
366
    } else {
367
        s->b = (s->b | TREQ);
368
    }
369

  
370
    if (s->acr & SR_OUT) {
371
        /* data output */
372
        if (!(s->b & TIP) && 
373
            (s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
374
            if (s->data_out_index < sizeof(s->data_out)) {
375
                s->data_out[s->data_out_index++] = s->sr;
376
            }
377
            s->ifr |= SR_INT;
378
            cuda_update_irq(s);
379
        }
380
    }
381

  
382
    /* check end of data output */
383
    if (!(s->acr & SR_OUT) && (s->last_acr & SR_OUT)) {
384
        if (s->data_out_index > 0)
385
            cuda_receive_packet_from_host(s, s->data_out, s->data_out_index);
386
        s->data_out_index = 0;
387
    }
388
    s->last_acr = s->acr;
389
    s->last_b = s->b;
390
}
391

  
392
static void cuda_send_packet_to_host(CUDAState *s, 
393
                                     const uint8_t *data, int len)
394
{
395
    memcpy(s->data_in, data, len);
396
    s->data_in_size = len;
397
    s->data_in_index = 0;
398
    cuda_update(s);
399
    s->ifr |= SR_INT;
400
    cuda_update_irq(s);
401
}
402

  
403
void adb_send_packet(ADBBusState *bus, const uint8_t *buf, int len)
404
{
405
    CUDAState *s = &cuda_state;
406
    uint8_t data[16];
407

  
408
    memcpy(data + 1, buf, len);
409
    data[0] = ADB_PACKET;
410
    cuda_send_packet_to_host(s, data, len + 1);
411
}
412

  
413
static void cuda_receive_packet(CUDAState *s, 
414
                                const uint8_t *data, int len)
415
{
416
    uint8_t obuf[16];
417
    int ti;
418

  
419
    switch(data[0]) {
420
    case CUDA_AUTOPOLL:
421
        s->autopoll = data[1];
422
        obuf[0] = CUDA_PACKET;
423
        obuf[1] = data[1];
424
        cuda_send_packet_to_host(s, obuf, 2);
425
        break;
426
    case CUDA_GET_TIME:
427
        /* XXX: add time support ? */
428
        ti = 0;
429
        obuf[0] = CUDA_PACKET;
430
        obuf[1] = 0;
431
        obuf[2] = 0;
432
        obuf[3] = ti >> 24;
433
        obuf[4] = ti >> 16;
434
        obuf[5] = ti >> 8;
435
        obuf[6] = ti;
436
        cuda_send_packet_to_host(s, obuf, 7);
437
        break;
438
    case CUDA_SET_TIME:
439
    case CUDA_FILE_SERVER_FLAG:
440
    case CUDA_SET_DEVICE_LIST:
441
    case CUDA_SET_AUTO_RATE:
442
    case CUDA_SET_POWER_MESSAGES:
443
        obuf[0] = CUDA_PACKET;
444
        obuf[1] = 0;
445
        cuda_send_packet_to_host(s, obuf, 2);
446
        break;
447
    default:
448
        break;
449
    }
450
}
451

  
452
static void cuda_receive_packet_from_host(CUDAState *s, 
453
                                          const uint8_t *data, int len)
454
{
455
    switch(data[0]) {
456
    case ADB_PACKET:
457
        adb_receive_packet(&adb_bus, data + 1, len - 1);
458
        break;
459
    case CUDA_PACKET:
460
        cuda_receive_packet(s, data + 1, len - 1);
461
        break;
462
    }
463
}
464

  
465
static void cuda_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
466
{
467
}
468

  
469
static void cuda_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
470
{
471
}
472

  
473
static uint32_t cuda_readw (void *opaque, target_phys_addr_t addr)
474
{
475
    return 0;
476
}
477

  
478
static uint32_t cuda_readl (void *opaque, target_phys_addr_t addr)
479
{
480
    return 0;
481
}
482

  
483
static CPUWriteMemoryFunc *cuda_write[] = {
484
    &cuda_writeb,
485
    &cuda_writew,
486
    &cuda_writel,
487
};
488

  
489
static CPUReadMemoryFunc *cuda_read[] = {
490
    &cuda_readb,
491
    &cuda_readw,
492
    &cuda_readl,
493
};
494

  
495
int cuda_init(void)
496
{
497
    CUDAState *s = &cuda_state;
498
    int cuda_mem_index;
499

  
500
    s->timers[0].latch = 0x10000;
501
    set_counter(&s->timers[0], 0xffff);
502
    s->timers[0].timer = qemu_new_timer(vm_clock, cuda_timer1, s);
503
    s->timers[1].latch = 0x10000;
504
    set_counter(&s->timers[1], 0xffff);
505
    cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s);
506
    return cuda_mem_index;
507
}
b/hw/ppc_chrp.c
26 26
#define BIOS_FILENAME "ppc_rom.bin"
27 27
#define NVRAM_SIZE        0x2000
28 28

  
29
/* MacIO devices (mapped inside the MacIO address space): CUDA, DBDMA,
30
   NVRAM (not implemented).  */
31

  
32
static int dbdma_mem_index;
33
static int cuda_mem_index;
34

  
35
/* DBDMA: currently no op - should suffice right now */
36

  
37
static void dbdma_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
38
{
39
}
40

  
41
static void dbdma_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
42
{
43
}
44

  
45
static void dbdma_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
46
{
47
}
48

  
49
static uint32_t dbdma_readb (void *opaque, target_phys_addr_t addr)
50
{
51
    return 0;
52
}
53

  
54
static uint32_t dbdma_readw (void *opaque, target_phys_addr_t addr)
55
{
56
    return 0;
57
}
58

  
59
static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr)
60
{
61
    return 0;
62
}
63

  
64
static CPUWriteMemoryFunc *dbdma_write[] = {
65
    &dbdma_writeb,
66
    &dbdma_writew,
67
    &dbdma_writel,
68
};
69

  
70
static CPUReadMemoryFunc *dbdma_read[] = {
71
    &dbdma_readb,
72
    &dbdma_readw,
73
    &dbdma_readl,
74
};
75

  
76
static void macio_map(PCIDevice *pci_dev, int region_num, 
77
                      uint32_t addr, uint32_t size, int type)
78
{
79
    cpu_register_physical_memory(addr + 0x08000, 0x1000, dbdma_mem_index);
80
    cpu_register_physical_memory(addr + 0x16000, 0x2000, cuda_mem_index);
81
}
82

  
83
static void macio_init(void)
84
{
85
    PCIDevice *d;
86

  
87
    d = pci_register_device("macio", sizeof(PCIDevice),
88
                            0, -1, 
89
                            NULL, NULL);
90
    /* Note: this code is strongly inspirated from the corresponding code
91
       in PearPC */
92
    d->config[0x00] = 0x6b; // vendor_id
93
    d->config[0x01] = 0x10;
94
    d->config[0x02] = 0x17;
95
    d->config[0x03] = 0x00;
96

  
97
    d->config[0x0a] = 0x00; // class_sub = pci2pci
98
    d->config[0x0b] = 0xff; // class_base = bridge
99
    d->config[0x0e] = 0x00; // header_type
100

  
101
    d->config[0x3d] = 0x01; // interrupt on pin 1
102
    
103
    dbdma_mem_index = cpu_register_io_memory(0, dbdma_read, dbdma_write, NULL);
104

  
105
    pci_register_io_region(d, 0, 0x80000, 
106
                           PCI_ADDRESS_SPACE_MEM, macio_map);
107
}
108

  
29 109
/* PowerPC PREP hardware initialisation */
30 110
void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
31 111
		   DisplayState *ds, const char **fd_filename, int snapshot,
......
86 166

  
87 167
    pci_ide_init(bs_table);
88 168

  
89
    kbd_init();
169
    /* cuda also initialize ADB */
170
    cuda_mem_index = cuda_init();
171

  
172
    adb_kbd_init(&adb_bus);
173
    adb_mouse_init(&adb_bus);
174
    
175
    macio_init();
90 176

  
91 177
    nvram = m48t59_init(8, 0x0074, NVRAM_SIZE);
92 178

  

Also available in: Unified diff