~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to hw/m48t59.c

  • Committer: pbrook
  • Date: 2007-03-04 00:52:16 UTC
  • Revision ID: git-v1:7a2d6d9650ed16b2cdb0b4876fe9efce7ef8ea6d
64bit->win32 cross build fix.


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

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * QEMU M48T59 and M48T08 NVRAM emulation for PPC PREP and Sparc platforms
3
 
 *
4
 
 * Copyright (c) 2003-2005, 2007 Jocelyn Mayer
5
 
 *
 
3
 * 
 
4
 * Copyright (c) 2003-2005 Jocelyn Mayer
 
5
 * 
6
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
 * of this software and associated documentation files (the "Software"), to deal
8
8
 * in the Software without restriction, including without limitation the rights
21
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
22
 * THE SOFTWARE.
23
23
 */
24
 
#include "hw.h"
25
 
#include "nvram.h"
26
 
#include "isa.h"
27
 
#include "qemu-timer.h"
28
 
#include "sysemu.h"
 
24
#include "vl.h"
 
25
#include "m48t59.h"
29
26
 
30
27
//#define DEBUG_NVRAM
31
28
 
36
33
#endif
37
34
 
38
35
/*
39
 
 * The M48T02, M48T08 and M48T59 chips are very similar. The newer '59 has
 
36
 * The M48T08 and M48T59 chips are very similar. The newer '59 has
40
37
 * alarm and a watchdog timer and related control registers. In the
41
38
 * PPC platform there is also a nvram lock function.
42
39
 */
43
40
struct m48t59_t {
44
41
    /* Model parameters */
45
 
    int type; // 2 = m48t02, 8 = m48t08, 59 = m48t59
 
42
    int type; // 8 = m48t08, 59 = m48t59
46
43
    /* Hardware parameters */
47
 
    qemu_irq IRQ;
 
44
    int      IRQ;
48
45
    int mem_index;
49
 
    target_phys_addr_t mem_base;
 
46
    uint32_t mem_base;
50
47
    uint32_t io_base;
51
48
    uint16_t size;
52
49
    /* RTC management */
53
50
    time_t   time_offset;
54
51
    time_t   stop_time;
55
52
    /* Alarm & watchdog */
56
 
    struct tm alarm;
 
53
    time_t   alarm;
57
54
    struct QEMUTimer *alrm_timer;
58
55
    struct QEMUTimer *wd_timer;
59
56
    /* NVRAM storage */
74
71
    return ((BCD >> 4) * 10) + (BCD & 0x0F);
75
72
}
76
73
 
 
74
/* RTC management helpers */
 
75
static void get_time (m48t59_t *NVRAM, struct tm *tm)
 
76
{
 
77
    time_t t;
 
78
 
 
79
    t = time(NULL) + NVRAM->time_offset;
 
80
#ifdef _WIN32
 
81
    memcpy(tm,localtime(&t),sizeof(*tm));
 
82
#else
 
83
    localtime_r (&t, tm) ;
 
84
#endif
 
85
}
 
86
 
 
87
static void set_time (m48t59_t *NVRAM, struct tm *tm)
 
88
{
 
89
    time_t now, new_time;
 
90
    
 
91
    new_time = mktime(tm);
 
92
    now = time(NULL);
 
93
    NVRAM->time_offset = new_time - now;
 
94
}
 
95
 
77
96
/* Alarm management */
78
97
static void alarm_cb (void *opaque)
79
98
{
80
 
    struct tm tm;
 
99
    struct tm tm, tm_now;
81
100
    uint64_t next_time;
82
101
    m48t59_t *NVRAM = opaque;
83
102
 
84
 
    qemu_set_irq(NVRAM->IRQ, 1);
85
 
    if ((NVRAM->buffer[0x1FF5] & 0x80) == 0 &&
 
103
    pic_set_irq(NVRAM->IRQ, 1);
 
104
    if ((NVRAM->buffer[0x1FF5] & 0x80) == 0 && 
86
105
        (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
87
106
        (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
88
107
        (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
89
 
        /* Repeat once a month */
90
 
        qemu_get_timedate(&tm, NVRAM->time_offset);
91
 
        tm.tm_mon++;
92
 
        if (tm.tm_mon == 13) {
93
 
            tm.tm_mon = 1;
94
 
            tm.tm_year++;
95
 
        }
96
 
        next_time = qemu_timedate_diff(&tm) - NVRAM->time_offset;
 
108
        /* Repeat once a month */
 
109
        get_time(NVRAM, &tm_now);
 
110
        memcpy(&tm, &tm_now, sizeof(struct tm));
 
111
        tm.tm_mon++;
 
112
        if (tm.tm_mon == 13) {
 
113
            tm.tm_mon = 1;
 
114
            tm.tm_year++;
 
115
        }
 
116
        next_time = mktime(&tm);
97
117
    } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
98
118
               (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
99
119
               (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
100
120
               (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
101
 
        /* Repeat once a day */
102
 
        next_time = 24 * 60 * 60;
 
121
        /* Repeat once a day */
 
122
        next_time = 24 * 60 * 60 + mktime(&tm_now);
103
123
    } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
104
124
               (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
105
125
               (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
106
126
               (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
107
 
        /* Repeat once an hour */
108
 
        next_time = 60 * 60;
 
127
        /* Repeat once an hour */
 
128
        next_time = 60 * 60 + mktime(&tm_now);
109
129
    } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
110
130
               (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
111
131
               (NVRAM->buffer[0x1FF3] & 0x80) != 0 &&
112
132
               (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
113
 
        /* Repeat once a minute */
114
 
        next_time = 60;
 
133
        /* Repeat once a minute */
 
134
        next_time = 60 + mktime(&tm_now);
115
135
    } else {
116
 
        /* Repeat once a second */
117
 
        next_time = 1;
 
136
        /* Repeat once a second */
 
137
        next_time = 1 + mktime(&tm_now);
118
138
    }
119
 
    qemu_mod_timer(NVRAM->alrm_timer, qemu_get_clock(vm_clock) +
120
 
                    next_time * 1000);
121
 
    qemu_set_irq(NVRAM->IRQ, 0);
122
 
}
123
 
 
124
 
static void set_alarm (m48t59_t *NVRAM)
125
 
{
126
 
    int diff;
 
139
    qemu_mod_timer(NVRAM->alrm_timer, next_time * 1000);
 
140
    pic_set_irq(NVRAM->IRQ, 0);
 
141
}
 
142
 
 
143
 
 
144
static void get_alarm (m48t59_t *NVRAM, struct tm *tm)
 
145
{
 
146
#ifdef _WIN32
 
147
    memcpy(tm,localtime(&NVRAM->alarm),sizeof(*tm));
 
148
#else
 
149
    localtime_r (&NVRAM->alarm, tm);
 
150
#endif
 
151
}
 
152
 
 
153
static void set_alarm (m48t59_t *NVRAM, struct tm *tm)
 
154
{
 
155
    NVRAM->alarm = mktime(tm);
127
156
    if (NVRAM->alrm_timer != NULL) {
128
157
        qemu_del_timer(NVRAM->alrm_timer);
129
 
        diff = qemu_timedate_diff(&NVRAM->alarm) - NVRAM->time_offset;
130
 
        if (diff > 0)
131
 
            qemu_mod_timer(NVRAM->alrm_timer, diff * 1000);
 
158
        NVRAM->alrm_timer = NULL;
132
159
    }
133
 
}
134
 
 
135
 
/* RTC management helpers */
136
 
static inline void get_time (m48t59_t *NVRAM, struct tm *tm)
137
 
{
138
 
    qemu_get_timedate(tm, NVRAM->time_offset);
139
 
}
140
 
 
141
 
static void set_time (m48t59_t *NVRAM, struct tm *tm)
142
 
{
143
 
    NVRAM->time_offset = qemu_timedate_diff(tm);
144
 
    set_alarm(NVRAM);
 
160
    if (NVRAM->alarm - time(NULL) > 0)
 
161
        qemu_mod_timer(NVRAM->alrm_timer, NVRAM->alarm * 1000);
145
162
}
146
163
 
147
164
/* Watchdog management */
156
173
        /* May it be a hw CPU Reset instead ? */
157
174
        qemu_system_reset_request();
158
175
    } else {
159
 
        qemu_set_irq(NVRAM->IRQ, 1);
160
 
        qemu_set_irq(NVRAM->IRQ, 0);
 
176
        pic_set_irq(NVRAM->IRQ, 1);
 
177
        pic_set_irq(NVRAM->IRQ, 0);
161
178
    }
162
179
}
163
180
 
165
182
{
166
183
    uint64_t interval; /* in 1/16 seconds */
167
184
 
 
185
    if (NVRAM->wd_timer != NULL) {
 
186
        qemu_del_timer(NVRAM->wd_timer);
 
187
        NVRAM->wd_timer = NULL;
 
188
    }
168
189
    NVRAM->buffer[0x1FF0] &= ~0x80;
169
 
    if (NVRAM->wd_timer != NULL) {
170
 
        qemu_del_timer(NVRAM->wd_timer);
171
 
        if (value != 0) {
172
 
            interval = (1 << (2 * (value & 0x03))) * ((value >> 2) & 0x1F);
173
 
            qemu_mod_timer(NVRAM->wd_timer, ((uint64_t)time(NULL) * 1000) +
174
 
                           ((interval * 1000) >> 4));
175
 
        }
 
190
    if (value != 0) {
 
191
        interval = (1 << (2 * (value & 0x03))) * ((value >> 2) & 0x1F);
 
192
        qemu_mod_timer(NVRAM->wd_timer, ((uint64_t)time(NULL) * 1000) +
 
193
                       ((interval * 1000) >> 4));
176
194
    }
177
195
}
178
196
 
179
197
/* Direct access to NVRAM */
180
 
void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
 
198
void m48t59_write (m48t59_t *NVRAM, uint32_t addr, uint32_t val)
181
199
{
182
 
    m48t59_t *NVRAM = opaque;
183
200
    struct tm tm;
184
201
    int tmp;
185
202
 
186
203
    if (addr > 0x1FF8 && addr < 0x2000)
187
204
        NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, addr, val);
188
 
 
189
 
    /* check for NVRAM access */
190
 
    if ((NVRAM->type == 2 && addr < 0x7f8) ||
191
 
        (NVRAM->type == 8 && addr < 0x1ff8) ||
192
 
        (NVRAM->type == 59 && addr < 0x1ff0))
 
205
    if (NVRAM->type == 8 && 
 
206
        (addr >= 0x1ff0 && addr <= 0x1ff7))
193
207
        goto do_write;
194
 
 
195
 
    /* TOD access */
196
208
    switch (addr) {
197
209
    case 0x1FF0:
198
210
        /* flags register : read-only */
204
216
        /* alarm seconds */
205
217
        tmp = fromBCD(val & 0x7F);
206
218
        if (tmp >= 0 && tmp <= 59) {
207
 
            NVRAM->alarm.tm_sec = tmp;
 
219
            get_alarm(NVRAM, &tm);
 
220
            tm.tm_sec = tmp;
208
221
            NVRAM->buffer[0x1FF2] = val;
209
 
            set_alarm(NVRAM);
 
222
            set_alarm(NVRAM, &tm);
210
223
        }
211
224
        break;
212
225
    case 0x1FF3:
213
226
        /* alarm minutes */
214
227
        tmp = fromBCD(val & 0x7F);
215
228
        if (tmp >= 0 && tmp <= 59) {
216
 
            NVRAM->alarm.tm_min = tmp;
 
229
            get_alarm(NVRAM, &tm);
 
230
            tm.tm_min = tmp;
217
231
            NVRAM->buffer[0x1FF3] = val;
218
 
            set_alarm(NVRAM);
 
232
            set_alarm(NVRAM, &tm);
219
233
        }
220
234
        break;
221
235
    case 0x1FF4:
222
236
        /* alarm hours */
223
237
        tmp = fromBCD(val & 0x3F);
224
238
        if (tmp >= 0 && tmp <= 23) {
225
 
            NVRAM->alarm.tm_hour = tmp;
 
239
            get_alarm(NVRAM, &tm);
 
240
            tm.tm_hour = tmp;
226
241
            NVRAM->buffer[0x1FF4] = val;
227
 
            set_alarm(NVRAM);
 
242
            set_alarm(NVRAM, &tm);
228
243
        }
229
244
        break;
230
245
    case 0x1FF5:
231
246
        /* alarm date */
232
247
        tmp = fromBCD(val & 0x1F);
233
248
        if (tmp != 0) {
234
 
            NVRAM->alarm.tm_mday = tmp;
 
249
            get_alarm(NVRAM, &tm);
 
250
            tm.tm_mday = tmp;
235
251
            NVRAM->buffer[0x1FF5] = val;
236
 
            set_alarm(NVRAM);
 
252
            set_alarm(NVRAM, &tm);
237
253
        }
238
254
        break;
239
255
    case 0x1FF6:
246
262
        set_up_watchdog(NVRAM, val);
247
263
        break;
248
264
    case 0x1FF8:
249
 
    case 0x07F8:
250
265
        /* control */
251
 
       NVRAM->buffer[addr] = (val & ~0xA0) | 0x90;
 
266
        NVRAM->buffer[0x1FF8] = (val & ~0xA0) | 0x90;
252
267
        break;
253
268
    case 0x1FF9:
254
 
    case 0x07F9:
255
269
        /* seconds (BCD) */
256
270
        tmp = fromBCD(val & 0x7F);
257
271
        if (tmp >= 0 && tmp <= 59) {
259
273
            tm.tm_sec = tmp;
260
274
            set_time(NVRAM, &tm);
261
275
        }
262
 
        if ((val & 0x80) ^ (NVRAM->buffer[addr] & 0x80)) {
 
276
        if ((val & 0x80) ^ (NVRAM->buffer[0x1FF9] & 0x80)) {
263
277
            if (val & 0x80) {
264
278
                NVRAM->stop_time = time(NULL);
265
279
            } else {
267
281
                NVRAM->stop_time = 0;
268
282
            }
269
283
        }
270
 
        NVRAM->buffer[addr] = val & 0x80;
 
284
        NVRAM->buffer[0x1FF9] = val & 0x80;
271
285
        break;
272
286
    case 0x1FFA:
273
 
    case 0x07FA:
274
287
        /* minutes (BCD) */
275
288
        tmp = fromBCD(val & 0x7F);
276
289
        if (tmp >= 0 && tmp <= 59) {
280
293
        }
281
294
        break;
282
295
    case 0x1FFB:
283
 
    case 0x07FB:
284
296
        /* hours (BCD) */
285
297
        tmp = fromBCD(val & 0x3F);
286
298
        if (tmp >= 0 && tmp <= 23) {
290
302
        }
291
303
        break;
292
304
    case 0x1FFC:
293
 
    case 0x07FC:
294
305
        /* day of the week / century */
295
306
        tmp = fromBCD(val & 0x07);
296
307
        get_time(NVRAM, &tm);
297
308
        tm.tm_wday = tmp;
298
309
        set_time(NVRAM, &tm);
299
 
        NVRAM->buffer[addr] = val & 0x40;
 
310
        NVRAM->buffer[0x1FFC] = val & 0x40;
300
311
        break;
301
312
    case 0x1FFD:
302
 
    case 0x07FD:
303
313
        /* date */
304
314
        tmp = fromBCD(val & 0x1F);
305
315
        if (tmp != 0) {
309
319
        }
310
320
        break;
311
321
    case 0x1FFE:
312
 
    case 0x07FE:
313
322
        /* month */
314
323
        tmp = fromBCD(val & 0x1F);
315
324
        if (tmp >= 1 && tmp <= 12) {
319
328
        }
320
329
        break;
321
330
    case 0x1FFF:
322
 
    case 0x07FF:
323
331
        /* year */
324
332
        tmp = fromBCD(val);
325
333
        if (tmp >= 0 && tmp <= 99) {
345
353
    }
346
354
}
347
355
 
348
 
uint32_t m48t59_read (void *opaque, uint32_t addr)
 
356
uint32_t m48t59_read (m48t59_t *NVRAM, uint32_t addr)
349
357
{
350
 
    m48t59_t *NVRAM = opaque;
351
358
    struct tm tm;
352
359
    uint32_t retval = 0xFF;
353
360
 
354
 
    /* check for NVRAM access */
355
 
    if ((NVRAM->type == 2 && addr < 0x078f) ||
356
 
        (NVRAM->type == 8 && addr < 0x1ff8) ||
357
 
        (NVRAM->type == 59 && addr < 0x1ff0))
 
361
    if (NVRAM->type == 8 && 
 
362
        (addr >= 0x1ff0 && addr <= 0x1ff7))
358
363
        goto do_read;
359
 
 
360
 
    /* TOD access */
361
364
    switch (addr) {
362
365
    case 0x1FF0:
363
366
        /* flags register */
386
389
        set_up_watchdog(NVRAM, NVRAM->buffer[0x1FF7]);
387
390
        goto do_read;
388
391
    case 0x1FF8:
389
 
    case 0x07F8:
390
392
        /* control */
391
393
        goto do_read;
392
394
    case 0x1FF9:
393
 
    case 0x07F9:
394
395
        /* seconds (BCD) */
395
396
        get_time(NVRAM, &tm);
396
 
        retval = (NVRAM->buffer[addr] & 0x80) | toBCD(tm.tm_sec);
 
397
        retval = (NVRAM->buffer[0x1FF9] & 0x80) | toBCD(tm.tm_sec);
397
398
        break;
398
399
    case 0x1FFA:
399
 
    case 0x07FA:
400
400
        /* minutes (BCD) */
401
401
        get_time(NVRAM, &tm);
402
402
        retval = toBCD(tm.tm_min);
403
403
        break;
404
404
    case 0x1FFB:
405
 
    case 0x07FB:
406
405
        /* hours (BCD) */
407
406
        get_time(NVRAM, &tm);
408
407
        retval = toBCD(tm.tm_hour);
409
408
        break;
410
409
    case 0x1FFC:
411
 
    case 0x07FC:
412
410
        /* day of the week / century */
413
411
        get_time(NVRAM, &tm);
414
 
        retval = NVRAM->buffer[addr] | tm.tm_wday;
 
412
        retval = NVRAM->buffer[0x1FFC] | tm.tm_wday;
415
413
        break;
416
414
    case 0x1FFD:
417
 
    case 0x07FD:
418
415
        /* date */
419
416
        get_time(NVRAM, &tm);
420
417
        retval = toBCD(tm.tm_mday);
421
418
        break;
422
419
    case 0x1FFE:
423
 
    case 0x07FE:
424
420
        /* month */
425
421
        get_time(NVRAM, &tm);
426
422
        retval = toBCD(tm.tm_mon + 1);
427
423
        break;
428
424
    case 0x1FFF:
429
 
    case 0x07FF:
430
425
        /* year */
431
426
        get_time(NVRAM, &tm);
432
 
        if (NVRAM->type == 8)
 
427
        if (NVRAM->type == 8) 
433
428
            retval = toBCD(tm.tm_year - 68); // Base year is 1968
434
429
        else
435
430
            retval = toBCD(tm.tm_year);
447
442
        break;
448
443
    }
449
444
    if (addr > 0x1FF9 && addr < 0x2000)
450
 
       NVRAM_PRINTF("%s: 0x%08x <= 0x%08x\n", __func__, addr, retval);
 
445
        NVRAM_PRINTF("0x%08x <= 0x%08x\n", addr, retval);
451
446
 
452
447
    return retval;
453
448
}
454
449
 
455
 
void m48t59_set_addr (void *opaque, uint32_t addr)
 
450
void m48t59_set_addr (m48t59_t *NVRAM, uint32_t addr)
456
451
{
457
 
    m48t59_t *NVRAM = opaque;
458
 
 
459
452
    NVRAM->addr = addr;
460
453
}
461
454
 
462
 
void m48t59_toggle_lock (void *opaque, int lock)
 
455
void m48t59_toggle_lock (m48t59_t *NVRAM, int lock)
463
456
{
464
 
    m48t59_t *NVRAM = opaque;
465
 
 
466
457
    NVRAM->lock ^= 1 << lock;
467
458
}
468
459
 
472
463
    m48t59_t *NVRAM = opaque;
473
464
 
474
465
    addr -= NVRAM->io_base;
475
 
    NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, addr, val);
 
466
    NVRAM_PRINTF("0x%08x => 0x%08x\n", addr, val);
476
467
    switch (addr) {
477
468
    case 0:
478
469
        NVRAM->addr &= ~0x00FF;
505
496
        retval = -1;
506
497
        break;
507
498
    }
508
 
    NVRAM_PRINTF("%s: 0x%08x <= 0x%08x\n", __func__, addr, retval);
 
499
    NVRAM_PRINTF("0x%08x <= 0x%08x\n", addr, retval);
509
500
 
510
501
    return retval;
511
502
}
513
504
static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
514
505
{
515
506
    m48t59_t *NVRAM = opaque;
516
 
 
 
507
    
517
508
    addr -= NVRAM->mem_base;
518
509
    m48t59_write(NVRAM, addr, value & 0xff);
519
510
}
521
512
static void nvram_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
522
513
{
523
514
    m48t59_t *NVRAM = opaque;
524
 
 
 
515
    
525
516
    addr -= NVRAM->mem_base;
526
517
    m48t59_write(NVRAM, addr, (value >> 8) & 0xff);
527
518
    m48t59_write(NVRAM, addr + 1, value & 0xff);
530
521
static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
531
522
{
532
523
    m48t59_t *NVRAM = opaque;
533
 
 
 
524
    
534
525
    addr -= NVRAM->mem_base;
535
526
    m48t59_write(NVRAM, addr, (value >> 24) & 0xff);
536
527
    m48t59_write(NVRAM, addr + 1, (value >> 16) & 0xff);
542
533
{
543
534
    m48t59_t *NVRAM = opaque;
544
535
    uint32_t retval;
545
 
 
 
536
    
546
537
    addr -= NVRAM->mem_base;
547
538
    retval = m48t59_read(NVRAM, addr);
548
539
    return retval;
552
543
{
553
544
    m48t59_t *NVRAM = opaque;
554
545
    uint32_t retval;
555
 
 
 
546
    
556
547
    addr -= NVRAM->mem_base;
557
548
    retval = m48t59_read(NVRAM, addr) << 8;
558
549
    retval |= m48t59_read(NVRAM, addr + 1);
584
575
    &nvram_readl,
585
576
};
586
577
 
587
 
static void m48t59_save(QEMUFile *f, void *opaque)
588
 
{
589
 
    m48t59_t *s = opaque;
590
 
 
591
 
    qemu_put_8s(f, &s->lock);
592
 
    qemu_put_be16s(f, &s->addr);
593
 
    qemu_put_buffer(f, s->buffer, s->size);
594
 
}
595
 
 
596
 
static int m48t59_load(QEMUFile *f, void *opaque, int version_id)
597
 
{
598
 
    m48t59_t *s = opaque;
599
 
 
600
 
    if (version_id != 1)
601
 
        return -EINVAL;
602
 
 
603
 
    qemu_get_8s(f, &s->lock);
604
 
    qemu_get_be16s(f, &s->addr);
605
 
    qemu_get_buffer(f, s->buffer, s->size);
606
 
 
607
 
    return 0;
608
 
}
609
 
 
610
 
static void m48t59_reset(void *opaque)
611
 
{
612
 
    m48t59_t *NVRAM = opaque;
613
 
 
614
 
    if (NVRAM->alrm_timer != NULL)
615
 
        qemu_del_timer(NVRAM->alrm_timer);
616
 
 
617
 
    if (NVRAM->wd_timer != NULL)
618
 
        qemu_del_timer(NVRAM->wd_timer);
619
 
}
620
 
 
621
578
/* Initialisation routine */
622
 
m48t59_t *m48t59_init (qemu_irq IRQ, target_phys_addr_t mem_base,
 
579
m48t59_t *m48t59_init (int IRQ, target_ulong mem_base,
623
580
                       uint32_t io_base, uint16_t size,
624
581
                       int type)
625
582
{
626
583
    m48t59_t *s;
627
 
    target_phys_addr_t save_base;
628
584
 
629
585
    s = qemu_mallocz(sizeof(m48t59_t));
630
586
    if (!s)
646
602
    }
647
603
    if (mem_base != 0) {
648
604
        s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);
649
 
        cpu_register_physical_memory(mem_base, size, s->mem_index);
 
605
        cpu_register_physical_memory(mem_base, 0x4000, s->mem_index);
650
606
    }
651
607
    if (type == 59) {
652
608
        s->alrm_timer = qemu_new_timer(vm_clock, &alarm_cb, s);
653
609
        s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s);
654
610
    }
655
611
    s->lock = 0;
656
 
    qemu_get_timedate(&s->alarm, 0);
657
 
 
658
 
    qemu_register_reset(m48t59_reset, s);
659
 
    save_base = mem_base ? mem_base : io_base;
660
 
    register_savevm("m48t59", save_base, 1, m48t59_save, m48t59_load, s);
661
612
 
662
613
    return s;
663
614
}