Commit 13ab5daa86d3b802fc3a2e5959ecc8cb1aadd310
1 parent
ef792f9d
NVRAM fixes (Jocelyn Mayer)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@815 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
37 additions
and
6 deletions
hw/m48t59.c
| @@ -24,9 +24,9 @@ | @@ -24,9 +24,9 @@ | ||
| 24 | #include "vl.h" | 24 | #include "vl.h" |
| 25 | #include "m48t59.h" | 25 | #include "m48t59.h" |
| 26 | 26 | ||
| 27 | -//#define NVRAM_DEBUG | 27 | +//#define DEBUG_NVRAM |
| 28 | 28 | ||
| 29 | -#if defined(NVRAM_DEBUG) | 29 | +#if defined(DEBUG_NVRAM) |
| 30 | #define NVRAM_PRINTF(fmt, args...) do { printf(fmt , ##args); } while (0) | 30 | #define NVRAM_PRINTF(fmt, args...) do { printf(fmt , ##args); } while (0) |
| 31 | #else | 31 | #else |
| 32 | #define NVRAM_PRINTF(fmt, args...) do { } while (0) | 32 | #define NVRAM_PRINTF(fmt, args...) do { } while (0) |
| @@ -45,6 +45,7 @@ struct m48t59_t { | @@ -45,6 +45,7 @@ struct m48t59_t { | ||
| 45 | struct QEMUTimer *alrm_timer; | 45 | struct QEMUTimer *alrm_timer; |
| 46 | struct QEMUTimer *wd_timer; | 46 | struct QEMUTimer *wd_timer; |
| 47 | /* NVRAM storage */ | 47 | /* NVRAM storage */ |
| 48 | + uint8_t lock; | ||
| 48 | uint16_t addr; | 49 | uint16_t addr; |
| 49 | uint8_t *buffer; | 50 | uint8_t *buffer; |
| 50 | }; | 51 | }; |
| @@ -152,7 +153,10 @@ static void watchdog_cb (void *opaque) | @@ -152,7 +153,10 @@ static void watchdog_cb (void *opaque) | ||
| 152 | if (NVRAM->buffer[0x1FF7] & 0x80) { | 153 | if (NVRAM->buffer[0x1FF7] & 0x80) { |
| 153 | NVRAM->buffer[0x1FF7] = 0x00; | 154 | NVRAM->buffer[0x1FF7] = 0x00; |
| 154 | NVRAM->buffer[0x1FFC] &= ~0x40; | 155 | NVRAM->buffer[0x1FFC] &= ~0x40; |
| 155 | - // reset_CPU(); | 156 | + /* May it be a hw CPU Reset instead ? */ |
| 157 | + reset_requested = 1; | ||
| 158 | + printf("Watchdog reset...\n"); | ||
| 159 | + cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); | ||
| 156 | } else { | 160 | } else { |
| 157 | pic_set_irq(NVRAM->IRQ, 1); | 161 | pic_set_irq(NVRAM->IRQ, 1); |
| 158 | pic_set_irq(NVRAM->IRQ, 0); | 162 | pic_set_irq(NVRAM->IRQ, 0); |
| @@ -315,6 +319,11 @@ void m48t59_write (m48t59_t *NVRAM, uint32_t val) | @@ -315,6 +319,11 @@ void m48t59_write (m48t59_t *NVRAM, uint32_t val) | ||
| 315 | } | 319 | } |
| 316 | break; | 320 | break; |
| 317 | default: | 321 | default: |
| 322 | + /* Check lock registers state */ | ||
| 323 | + if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1)) | ||
| 324 | + break; | ||
| 325 | + if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2)) | ||
| 326 | + break; | ||
| 318 | if (NVRAM->addr < 0x1FF0 || | 327 | if (NVRAM->addr < 0x1FF0 || |
| 319 | (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) { | 328 | (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) { |
| 320 | NVRAM->buffer[NVRAM->addr] = val & 0xFF; | 329 | NVRAM->buffer[NVRAM->addr] = val & 0xFF; |
| @@ -394,6 +403,11 @@ uint32_t m48t59_read (m48t59_t *NVRAM) | @@ -394,6 +403,11 @@ uint32_t m48t59_read (m48t59_t *NVRAM) | ||
| 394 | retval = toBCD(tm.tm_year); | 403 | retval = toBCD(tm.tm_year); |
| 395 | break; | 404 | break; |
| 396 | default: | 405 | default: |
| 406 | + /* Check lock registers state */ | ||
| 407 | + if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1)) | ||
| 408 | + break; | ||
| 409 | + if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2)) | ||
| 410 | + break; | ||
| 397 | if (NVRAM->addr < 0x1FF0 || | 411 | if (NVRAM->addr < 0x1FF0 || |
| 398 | (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) { | 412 | (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) { |
| 399 | do_read: | 413 | do_read: |
| @@ -412,12 +426,18 @@ void m48t59_set_addr (m48t59_t *NVRAM, uint32_t addr) | @@ -412,12 +426,18 @@ void m48t59_set_addr (m48t59_t *NVRAM, uint32_t addr) | ||
| 412 | NVRAM->addr = addr; | 426 | NVRAM->addr = addr; |
| 413 | } | 427 | } |
| 414 | 428 | ||
| 429 | +void m48t59_toggle_lock (m48t59_t *NVRAM, int lock) | ||
| 430 | +{ | ||
| 431 | + NVRAM->lock ^= 1 << lock; | ||
| 432 | +} | ||
| 433 | + | ||
| 415 | /* IO access to NVRAM */ | 434 | /* IO access to NVRAM */ |
| 416 | static void NVRAM_writeb (void *opaque, uint32_t addr, uint32_t val) | 435 | static void NVRAM_writeb (void *opaque, uint32_t addr, uint32_t val) |
| 417 | { | 436 | { |
| 418 | m48t59_t *NVRAM = opaque; | 437 | m48t59_t *NVRAM = opaque; |
| 419 | 438 | ||
| 420 | addr -= NVRAM->io_base; | 439 | addr -= NVRAM->io_base; |
| 440 | + NVRAM_PRINTF("0x%08x => 0x%08x\n", addr, val); | ||
| 421 | switch (addr) { | 441 | switch (addr) { |
| 422 | case 0: | 442 | case 0: |
| 423 | NVRAM->addr &= ~0x00FF; | 443 | NVRAM->addr &= ~0x00FF; |
| @@ -439,11 +459,20 @@ static void NVRAM_writeb (void *opaque, uint32_t addr, uint32_t val) | @@ -439,11 +459,20 @@ static void NVRAM_writeb (void *opaque, uint32_t addr, uint32_t val) | ||
| 439 | static uint32_t NVRAM_readb (void *opaque, uint32_t addr) | 459 | static uint32_t NVRAM_readb (void *opaque, uint32_t addr) |
| 440 | { | 460 | { |
| 441 | m48t59_t *NVRAM = opaque; | 461 | m48t59_t *NVRAM = opaque; |
| 462 | + uint32_t retval; | ||
| 442 | 463 | ||
| 443 | - if (addr == NVRAM->io_base + 3) | ||
| 444 | - return m48t59_read(NVRAM); | 464 | + addr -= NVRAM->io_base; |
| 465 | + switch (addr) { | ||
| 466 | + case 3: | ||
| 467 | + retval = m48t59_read(NVRAM); | ||
| 468 | + break; | ||
| 469 | + default: | ||
| 470 | + retval = -1; | ||
| 471 | + break; | ||
| 472 | + } | ||
| 473 | + NVRAM_PRINTF("0x%08x <= 0x%08x\n", addr, retval); | ||
| 445 | 474 | ||
| 446 | - return 0xFF; | 475 | + return retval; |
| 447 | } | 476 | } |
| 448 | 477 | ||
| 449 | /* Initialisation routine */ | 478 | /* Initialisation routine */ |
| @@ -467,5 +496,7 @@ m48t59_t *m48t59_init (int IRQ, uint32_t io_base, uint16_t size) | @@ -467,5 +496,7 @@ m48t59_t *m48t59_init (int IRQ, uint32_t io_base, uint16_t size) | ||
| 467 | register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, s); | 496 | register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, s); |
| 468 | s->alrm_timer = qemu_new_timer(vm_clock, &alarm_cb, s); | 497 | s->alrm_timer = qemu_new_timer(vm_clock, &alarm_cb, s); |
| 469 | s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s); | 498 | s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s); |
| 499 | + s->lock = 0; | ||
| 500 | + | ||
| 470 | return s; | 501 | return s; |
| 471 | } | 502 | } |