Commit 4aed2c33eb0e2c98db0d6a6ad13997651fad06bf
1 parent
9ed1e667
M48T02 support (Robert Reif)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3872 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
40 additions
and
15 deletions
hw/m48t59.c
| @@ -36,13 +36,13 @@ | @@ -36,13 +36,13 @@ | ||
| 36 | #endif | 36 | #endif |
| 37 | 37 | ||
| 38 | /* | 38 | /* |
| 39 | - * The M48T08 and M48T59 chips are very similar. The newer '59 has | 39 | + * The M48T02, M48T08 and M48T59 chips are very similar. The newer '59 has |
| 40 | * alarm and a watchdog timer and related control registers. In the | 40 | * alarm and a watchdog timer and related control registers. In the |
| 41 | * PPC platform there is also a nvram lock function. | 41 | * PPC platform there is also a nvram lock function. |
| 42 | */ | 42 | */ |
| 43 | struct m48t59_t { | 43 | struct m48t59_t { |
| 44 | /* Model parameters */ | 44 | /* Model parameters */ |
| 45 | - int type; // 8 = m48t08, 59 = m48t59 | 45 | + int type; // 2 = m48t02, 8 = m48t08, 59 = m48t59 |
| 46 | /* Hardware parameters */ | 46 | /* Hardware parameters */ |
| 47 | qemu_irq IRQ; | 47 | qemu_irq IRQ; |
| 48 | int mem_index; | 48 | int mem_index; |
| @@ -210,9 +210,14 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) | @@ -210,9 +210,14 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) | ||
| 210 | 210 | ||
| 211 | if (addr > 0x1FF8 && addr < 0x2000) | 211 | if (addr > 0x1FF8 && addr < 0x2000) |
| 212 | NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, addr, val); | 212 | NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, addr, val); |
| 213 | - if (NVRAM->type == 8 && | ||
| 214 | - (addr >= 0x1ff0 && addr <= 0x1ff7)) | 213 | + |
| 214 | + /* check for NVRAM access */ | ||
| 215 | + if ((NVRAM->type == 2 && addr < 0x7f8) || | ||
| 216 | + (NVRAM->type == 8 && addr < 0x1ff8) || | ||
| 217 | + (NVRAM->type == 59 && addr < 0x1ff0)) | ||
| 215 | goto do_write; | 218 | goto do_write; |
| 219 | + | ||
| 220 | + /* TOD access */ | ||
| 216 | switch (addr) { | 221 | switch (addr) { |
| 217 | case 0x1FF0: | 222 | case 0x1FF0: |
| 218 | /* flags register : read-only */ | 223 | /* flags register : read-only */ |
| @@ -270,10 +275,12 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) | @@ -270,10 +275,12 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) | ||
| 270 | set_up_watchdog(NVRAM, val); | 275 | set_up_watchdog(NVRAM, val); |
| 271 | break; | 276 | break; |
| 272 | case 0x1FF8: | 277 | case 0x1FF8: |
| 278 | + case 0x07F8: | ||
| 273 | /* control */ | 279 | /* control */ |
| 274 | - NVRAM->buffer[0x1FF8] = (val & ~0xA0) | 0x90; | 280 | + NVRAM->buffer[addr] = (val & ~0xA0) | 0x90; |
| 275 | break; | 281 | break; |
| 276 | case 0x1FF9: | 282 | case 0x1FF9: |
| 283 | + case 0x07F9: | ||
| 277 | /* seconds (BCD) */ | 284 | /* seconds (BCD) */ |
| 278 | tmp = fromBCD(val & 0x7F); | 285 | tmp = fromBCD(val & 0x7F); |
| 279 | if (tmp >= 0 && tmp <= 59) { | 286 | if (tmp >= 0 && tmp <= 59) { |
| @@ -281,7 +288,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) | @@ -281,7 +288,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) | ||
| 281 | tm.tm_sec = tmp; | 288 | tm.tm_sec = tmp; |
| 282 | set_time(NVRAM, &tm); | 289 | set_time(NVRAM, &tm); |
| 283 | } | 290 | } |
| 284 | - if ((val & 0x80) ^ (NVRAM->buffer[0x1FF9] & 0x80)) { | 291 | + if ((val & 0x80) ^ (NVRAM->buffer[addr] & 0x80)) { |
| 285 | if (val & 0x80) { | 292 | if (val & 0x80) { |
| 286 | NVRAM->stop_time = time(NULL); | 293 | NVRAM->stop_time = time(NULL); |
| 287 | } else { | 294 | } else { |
| @@ -289,9 +296,10 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) | @@ -289,9 +296,10 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) | ||
| 289 | NVRAM->stop_time = 0; | 296 | NVRAM->stop_time = 0; |
| 290 | } | 297 | } |
| 291 | } | 298 | } |
| 292 | - NVRAM->buffer[0x1FF9] = val & 0x80; | 299 | + NVRAM->buffer[addr] = val & 0x80; |
| 293 | break; | 300 | break; |
| 294 | case 0x1FFA: | 301 | case 0x1FFA: |
| 302 | + case 0x07FA: | ||
| 295 | /* minutes (BCD) */ | 303 | /* minutes (BCD) */ |
| 296 | tmp = fromBCD(val & 0x7F); | 304 | tmp = fromBCD(val & 0x7F); |
| 297 | if (tmp >= 0 && tmp <= 59) { | 305 | if (tmp >= 0 && tmp <= 59) { |
| @@ -301,6 +309,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) | @@ -301,6 +309,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) | ||
| 301 | } | 309 | } |
| 302 | break; | 310 | break; |
| 303 | case 0x1FFB: | 311 | case 0x1FFB: |
| 312 | + case 0x07FB: | ||
| 304 | /* hours (BCD) */ | 313 | /* hours (BCD) */ |
| 305 | tmp = fromBCD(val & 0x3F); | 314 | tmp = fromBCD(val & 0x3F); |
| 306 | if (tmp >= 0 && tmp <= 23) { | 315 | if (tmp >= 0 && tmp <= 23) { |
| @@ -310,14 +319,16 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) | @@ -310,14 +319,16 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) | ||
| 310 | } | 319 | } |
| 311 | break; | 320 | break; |
| 312 | case 0x1FFC: | 321 | case 0x1FFC: |
| 322 | + case 0x07FC: | ||
| 313 | /* day of the week / century */ | 323 | /* day of the week / century */ |
| 314 | tmp = fromBCD(val & 0x07); | 324 | tmp = fromBCD(val & 0x07); |
| 315 | get_time(NVRAM, &tm); | 325 | get_time(NVRAM, &tm); |
| 316 | tm.tm_wday = tmp; | 326 | tm.tm_wday = tmp; |
| 317 | set_time(NVRAM, &tm); | 327 | set_time(NVRAM, &tm); |
| 318 | - NVRAM->buffer[0x1FFC] = val & 0x40; | 328 | + NVRAM->buffer[addr] = val & 0x40; |
| 319 | break; | 329 | break; |
| 320 | case 0x1FFD: | 330 | case 0x1FFD: |
| 331 | + case 0x07FD: | ||
| 321 | /* date */ | 332 | /* date */ |
| 322 | tmp = fromBCD(val & 0x1F); | 333 | tmp = fromBCD(val & 0x1F); |
| 323 | if (tmp != 0) { | 334 | if (tmp != 0) { |
| @@ -327,6 +338,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) | @@ -327,6 +338,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) | ||
| 327 | } | 338 | } |
| 328 | break; | 339 | break; |
| 329 | case 0x1FFE: | 340 | case 0x1FFE: |
| 341 | + case 0x07FE: | ||
| 330 | /* month */ | 342 | /* month */ |
| 331 | tmp = fromBCD(val & 0x1F); | 343 | tmp = fromBCD(val & 0x1F); |
| 332 | if (tmp >= 1 && tmp <= 12) { | 344 | if (tmp >= 1 && tmp <= 12) { |
| @@ -336,6 +348,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) | @@ -336,6 +348,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) | ||
| 336 | } | 348 | } |
| 337 | break; | 349 | break; |
| 338 | case 0x1FFF: | 350 | case 0x1FFF: |
| 351 | + case 0x07FF: | ||
| 339 | /* year */ | 352 | /* year */ |
| 340 | tmp = fromBCD(val); | 353 | tmp = fromBCD(val); |
| 341 | if (tmp >= 0 && tmp <= 99) { | 354 | if (tmp >= 0 && tmp <= 99) { |
| @@ -367,9 +380,13 @@ uint32_t m48t59_read (void *opaque, uint32_t addr) | @@ -367,9 +380,13 @@ uint32_t m48t59_read (void *opaque, uint32_t addr) | ||
| 367 | struct tm tm; | 380 | struct tm tm; |
| 368 | uint32_t retval = 0xFF; | 381 | uint32_t retval = 0xFF; |
| 369 | 382 | ||
| 370 | - if (NVRAM->type == 8 && | ||
| 371 | - (addr >= 0x1ff0 && addr <= 0x1ff7)) | 383 | + /* check for NVRAM access */ |
| 384 | + if ((NVRAM->type == 2 && addr < 0x078f) || | ||
| 385 | + (NVRAM->type == 8 && addr < 0x1ff8) || | ||
| 386 | + (NVRAM->type == 59 && addr < 0x1ff0)) | ||
| 372 | goto do_read; | 387 | goto do_read; |
| 388 | + | ||
| 389 | + /* TOD access */ | ||
| 373 | switch (addr) { | 390 | switch (addr) { |
| 374 | case 0x1FF0: | 391 | case 0x1FF0: |
| 375 | /* flags register */ | 392 | /* flags register */ |
| @@ -398,39 +415,47 @@ uint32_t m48t59_read (void *opaque, uint32_t addr) | @@ -398,39 +415,47 @@ uint32_t m48t59_read (void *opaque, uint32_t addr) | ||
| 398 | set_up_watchdog(NVRAM, NVRAM->buffer[0x1FF7]); | 415 | set_up_watchdog(NVRAM, NVRAM->buffer[0x1FF7]); |
| 399 | goto do_read; | 416 | goto do_read; |
| 400 | case 0x1FF8: | 417 | case 0x1FF8: |
| 418 | + case 0x07F8: | ||
| 401 | /* control */ | 419 | /* control */ |
| 402 | goto do_read; | 420 | goto do_read; |
| 403 | case 0x1FF9: | 421 | case 0x1FF9: |
| 422 | + case 0x07F9: | ||
| 404 | /* seconds (BCD) */ | 423 | /* seconds (BCD) */ |
| 405 | get_time(NVRAM, &tm); | 424 | get_time(NVRAM, &tm); |
| 406 | - retval = (NVRAM->buffer[0x1FF9] & 0x80) | toBCD(tm.tm_sec); | 425 | + retval = (NVRAM->buffer[addr] & 0x80) | toBCD(tm.tm_sec); |
| 407 | break; | 426 | break; |
| 408 | case 0x1FFA: | 427 | case 0x1FFA: |
| 428 | + case 0x07FA: | ||
| 409 | /* minutes (BCD) */ | 429 | /* minutes (BCD) */ |
| 410 | get_time(NVRAM, &tm); | 430 | get_time(NVRAM, &tm); |
| 411 | retval = toBCD(tm.tm_min); | 431 | retval = toBCD(tm.tm_min); |
| 412 | break; | 432 | break; |
| 413 | case 0x1FFB: | 433 | case 0x1FFB: |
| 434 | + case 0x07FB: | ||
| 414 | /* hours (BCD) */ | 435 | /* hours (BCD) */ |
| 415 | get_time(NVRAM, &tm); | 436 | get_time(NVRAM, &tm); |
| 416 | retval = toBCD(tm.tm_hour); | 437 | retval = toBCD(tm.tm_hour); |
| 417 | break; | 438 | break; |
| 418 | case 0x1FFC: | 439 | case 0x1FFC: |
| 440 | + case 0x07FC: | ||
| 419 | /* day of the week / century */ | 441 | /* day of the week / century */ |
| 420 | get_time(NVRAM, &tm); | 442 | get_time(NVRAM, &tm); |
| 421 | - retval = NVRAM->buffer[0x1FFC] | tm.tm_wday; | 443 | + retval = NVRAM->buffer[addr] | tm.tm_wday; |
| 422 | break; | 444 | break; |
| 423 | case 0x1FFD: | 445 | case 0x1FFD: |
| 446 | + case 0x07FD: | ||
| 424 | /* date */ | 447 | /* date */ |
| 425 | get_time(NVRAM, &tm); | 448 | get_time(NVRAM, &tm); |
| 426 | retval = toBCD(tm.tm_mday); | 449 | retval = toBCD(tm.tm_mday); |
| 427 | break; | 450 | break; |
| 428 | case 0x1FFE: | 451 | case 0x1FFE: |
| 452 | + case 0x07FE: | ||
| 429 | /* month */ | 453 | /* month */ |
| 430 | get_time(NVRAM, &tm); | 454 | get_time(NVRAM, &tm); |
| 431 | retval = toBCD(tm.tm_mon + 1); | 455 | retval = toBCD(tm.tm_mon + 1); |
| 432 | break; | 456 | break; |
| 433 | case 0x1FFF: | 457 | case 0x1FFF: |
| 458 | + case 0x07FF: | ||
| 434 | /* year */ | 459 | /* year */ |
| 435 | get_time(NVRAM, &tm); | 460 | get_time(NVRAM, &tm); |
| 436 | if (NVRAM->type == 8) | 461 | if (NVRAM->type == 8) |
| @@ -650,7 +675,7 @@ m48t59_t *m48t59_init (qemu_irq IRQ, target_phys_addr_t mem_base, | @@ -650,7 +675,7 @@ m48t59_t *m48t59_init (qemu_irq IRQ, target_phys_addr_t mem_base, | ||
| 650 | } | 675 | } |
| 651 | if (mem_base != 0) { | 676 | if (mem_base != 0) { |
| 652 | s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s); | 677 | s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s); |
| 653 | - cpu_register_physical_memory(mem_base, 0x4000, s->mem_index); | 678 | + cpu_register_physical_memory(mem_base, size, s->mem_index); |
| 654 | } | 679 | } |
| 655 | if (type == 59) { | 680 | if (type == 59) { |
| 656 | s->alrm_timer = qemu_new_timer(vm_clock, &alarm_cb, s); | 681 | s->alrm_timer = qemu_new_timer(vm_clock, &alarm_cb, s); |
hw/sun4m.c
| @@ -623,7 +623,7 @@ static void sun4c_hw_init(const struct hwdef *hwdef, int RAM_size, | @@ -623,7 +623,7 @@ static void sun4c_hw_init(const struct hwdef *hwdef, int RAM_size, | ||
| 623 | } | 623 | } |
| 624 | 624 | ||
| 625 | nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, | 625 | nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, |
| 626 | - hwdef->nvram_size, 8); | 626 | + hwdef->nvram_size, 2); |
| 627 | 627 | ||
| 628 | slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq], | 628 | slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq], |
| 629 | nographic); | 629 | nographic); |
| @@ -848,7 +848,7 @@ static const struct hwdef hwdefs[] = { | @@ -848,7 +848,7 @@ static const struct hwdef hwdefs[] = { | ||
| 848 | .sun4c_intctl_base = 0xf5000000, | 848 | .sun4c_intctl_base = 0xf5000000, |
| 849 | .sun4c_counter_base = 0xf3000000, | 849 | .sun4c_counter_base = 0xf3000000, |
| 850 | .vram_size = 0x00100000, | 850 | .vram_size = 0x00100000, |
| 851 | - .nvram_size = 0x2000, // XXX 0x800, | 851 | + .nvram_size = 0x800, |
| 852 | .esp_irq = 2, | 852 | .esp_irq = 2, |
| 853 | .le_irq = 3, | 853 | .le_irq = 3, |
| 854 | .clock_irq = 5, | 854 | .clock_irq = 5, |