Commit 13ab5daa86d3b802fc3a2e5959ecc8cb1aadd310

Authored by bellard
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 }