pcrtc.c (177651) | pcrtc.c (178169) |
---|---|
1/*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * William Jolitz and Don Ahn. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 19 unchanged lines hidden (view full) --- 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 33 */ 34 35#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * William Jolitz and Don Ahn. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 19 unchanged lines hidden (view full) --- 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 33 */ 34 35#include <sys/cdefs.h> |
36__FBSDID("$FreeBSD: head/sys/pc98/cbus/pcrtc.c 177651 2008-03-26 22:12:00Z phk $"); | 36__FBSDID("$FreeBSD: head/sys/pc98/cbus/pcrtc.c 178169 2008-04-13 06:18:34Z nyan $"); |
37 38/* 39 * Routines to handle clock hardware. 40 */ 41 42/* 43 * inittodr, settodr and support routines written 44 * by Christoph Robitschko <chmr@edvz.tu-graz.ac.at> --- 69 unchanged lines hidden (view full) --- 114 115/* Values for timerX_state: */ 116#define RELEASED 0 117#define RELEASE_PENDING 1 118#define ACQUIRED 2 119#define ACQUIRE_PENDING 3 120 121static u_char timer1_state; | 37 38/* 39 * Routines to handle clock hardware. 40 */ 41 42/* 43 * inittodr, settodr and support routines written 44 * by Christoph Robitschko <chmr@edvz.tu-graz.ac.at> --- 69 unchanged lines hidden (view full) --- 114 115/* Values for timerX_state: */ 116#define RELEASED 0 117#define RELEASE_PENDING 1 118#define ACQUIRED 2 119#define ACQUIRE_PENDING 3 120 121static u_char timer1_state; |
122static void rtc_serialcombit(int); 123static void rtc_serialcom(int); 124static int rtc_inb(void); 125static void rtc_outb(int); | |
126 127static unsigned i8254_get_timecount(struct timecounter *tc); 128static unsigned i8254_simple_get_timecount(struct timecounter *tc); 129static void set_i8254_freq(u_int freq, int intr_freq); 130 131static struct timecounter i8254_timecounter = { 132 i8254_get_timecount, /* get_timecount */ 133 0, /* no poll_pps */ --- 261 unchanged lines hidden (view full) --- 395{ 396 397 set_i8254_freq(i8254_freq, hz); 398 tc_init(&i8254_timecounter); 399 400 init_TSC(); 401} 402 | 122 123static unsigned i8254_get_timecount(struct timecounter *tc); 124static unsigned i8254_simple_get_timecount(struct timecounter *tc); 125static void set_i8254_freq(u_int freq, int intr_freq); 126 127static struct timecounter i8254_timecounter = { 128 i8254_get_timecount, /* get_timecount */ 129 0, /* no poll_pps */ --- 261 unchanged lines hidden (view full) --- 391{ 392 393 set_i8254_freq(i8254_freq, hz); 394 tc_init(&i8254_timecounter); 395 396 init_TSC(); 397} 398 |
403static void 404rtc_serialcombit(int i) 405{ 406 outb(IO_RTC, ((i&0x01)<<5)|0x07); 407 DELAY(1); 408 outb(IO_RTC, ((i&0x01)<<5)|0x17); 409 DELAY(1); 410 outb(IO_RTC, ((i&0x01)<<5)|0x07); 411 DELAY(1); 412} 413 414static void 415rtc_serialcom(int i) 416{ 417 rtc_serialcombit(i&0x01); 418 rtc_serialcombit((i&0x02)>>1); 419 rtc_serialcombit((i&0x04)>>2); 420 rtc_serialcombit((i&0x08)>>3); 421 outb(IO_RTC, 0x07); 422 DELAY(1); 423 outb(IO_RTC, 0x0f); 424 DELAY(1); 425 outb(IO_RTC, 0x07); 426 DELAY(1); 427} 428 429static void 430rtc_outb(int val) 431{ 432 int s; 433 int sa = 0; 434 435 for (s=0;s<8;s++) { 436 sa = ((val >> s) & 0x01) ? 0x27 : 0x07; 437 outb(IO_RTC, sa); /* set DI & CLK 0 */ 438 DELAY(1); 439 outb(IO_RTC, sa | 0x10); /* CLK 1 */ 440 DELAY(1); 441 } 442 outb(IO_RTC, sa & 0xef); /* CLK 0 */ 443} 444 445static int 446rtc_inb(void) 447{ 448 int s; 449 int sa = 0; 450 451 for (s=0;s<8;s++) { 452 sa |= ((inb(0x33) & 0x01) << s); 453 outb(IO_RTC, 0x17); /* CLK 1 */ 454 DELAY(1); 455 outb(IO_RTC, 0x07); /* CLK 0 */ 456 DELAY(2); 457 } 458 return sa; 459} 460 | |
461/* | 399/* |
462 * Initialize the time of day register, based on the time base which is, e.g. 463 * from a filesystem. 464 */ 465void 466inittodr(time_t base) 467{ 468 struct timespec ts; 469 struct clocktime ct; 470 int i; 471 472 if (base) { 473 ts.tv_sec = base; 474 ts.tv_nsec = 0; 475 tc_setclock(&ts); 476 } 477 478 rtc_serialcom(0x03); /* Time Read */ 479 rtc_serialcom(0x01); /* Register shift command. */ 480 DELAY(20); 481 482 ct.nsec = 0; 483 ct.sec = bcd2bin(rtc_inb() & 0xff); /* sec */ 484 ct.min = bcd2bin(rtc_inb() & 0xff); /* min */ 485 ct.hour = bcd2bin(rtc_inb() & 0xff); /* hour */ 486 ct.day = bcd2bin(rtc_inb() & 0xff); /* date */ 487 i = rtc_inb(); 488 ct.dow = i & 0x0f; /* dow */ 489 ct.mon = (i >> 4) & 0x0f; /* month */ 490 ct.year = bcd2bin(rtc_inb() & 0xff) + 1900; /* year */ 491 if (ct.year < 1995) 492 ct.year += 100; 493 /* Set dow = -1 because some clocks don't set it correctly. */ 494 ct.dow = -1; 495 if (clock_ct_to_ts(&ct, &ts)) { 496 printf("Invalid time in clock: check and reset the date!\n"); 497 return; 498 } 499 ts.tv_sec += utc_offset(); 500 tc_setclock(&ts); 501} 502 503/* 504 * Write system time back to RTC 505 */ 506void 507resettodr() 508{ 509 struct timespec ts; 510 struct clocktime ct; 511 512 if (disable_rtc_set) 513 return; 514 515 getnanotime(&ts); 516 ts.tv_sec -= utc_offset(); 517 clock_ts_to_ct(&ts, &ct); 518 519 rtc_serialcom(0x01); /* Register shift command. */ 520 521 rtc_outb(bin2bcd(ct.sec)); /* Write back Seconds */ 522 rtc_outb(bin2bcd(ct.min)); /* Write back Minutes */ 523 rtc_outb(bin2bcd(ct.hour)); /* Write back Hours */ 524 525 rtc_outb(bin2bcd(ct.day)); /* Write back Day */ 526 rtc_outb((ct.mon << 4) | ct.dow); /* Write back Month and DOW */ 527 rtc_outb(bin2bcd(ct.year % 100)); /* Write back Year */ 528 529 rtc_serialcom(0x02); /* Time set & Counter hold command. */ 530 rtc_serialcom(0x00); /* Register hold command. */ 531} 532 533 534/* | |
535 * Start both clocks running. 536 */ 537void 538cpu_initclocks() 539{ 540 541#ifdef DEV_APIC 542 using_lapic_timer = lapic_setup_clock(); --- 71 unchanged lines hidden (view full) --- 614 /* Select timer0 and latch counter value. */ 615 outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); 616 617 low = inb(TIMER_CNTR0); 618 high = inb(TIMER_CNTR0); 619 count = i8254_max_count - ((high << 8) | low); 620 if (count < i8254_lastcount || 621 (!i8254_ticked && (clkintr_pending || | 400 * Start both clocks running. 401 */ 402void 403cpu_initclocks() 404{ 405 406#ifdef DEV_APIC 407 using_lapic_timer = lapic_setup_clock(); --- 71 unchanged lines hidden (view full) --- 479 /* Select timer0 and latch counter value. */ 480 outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); 481 482 low = inb(TIMER_CNTR0); 483 high = inb(TIMER_CNTR0); 484 count = i8254_max_count - ((high << 8) | low); 485 if (count < i8254_lastcount || 486 (!i8254_ticked && (clkintr_pending || |
622 ((count < 20 || (!(eflags & PSL_I) && count < i8254_max_count / 2u)) && | 487 ((count < 20 || (!(eflags & PSL_I) && 488 count < i8254_max_count / 2u)) && |
623 i8254_pending != NULL && i8254_pending(i8254_intsrc))))) { 624 i8254_ticked = 1; 625 i8254_offset += i8254_max_count; 626 } 627 i8254_lastcount = count; 628 count += i8254_offset; 629 mtx_unlock_spin(&clock_lock); 630 return (count); 631} 632 633#ifdef DEV_ISA 634/* | 489 i8254_pending != NULL && i8254_pending(i8254_intsrc))))) { 490 i8254_ticked = 1; 491 i8254_offset += i8254_max_count; 492 } 493 i8254_lastcount = count; 494 count += i8254_offset; 495 mtx_unlock_spin(&clock_lock); 496 return (count); 497} 498 499#ifdef DEV_ISA 500/* |
635 * Attach to the ISA PnP descriptors for the timer and realtime clock. | 501 * Attach to the ISA PnP descriptors for the timer |
636 */ 637static struct isa_pnp_id attimer_ids[] = { 638 { 0x0001d041 /* PNP0100 */, "AT timer" }, | 502 */ 503static struct isa_pnp_id attimer_ids[] = { 504 { 0x0001d041 /* PNP0100 */, "AT timer" }, |
639 { 0x000bd041 /* PNP0B00 */, "AT realtime clock" }, | |
640 { 0 } 641}; 642 643static int 644attimer_probe(device_t dev) 645{ 646 int result; 647 | 505 { 0 } 506}; 507 508static int 509attimer_probe(device_t dev) 510{ 511 int result; 512 |
648 if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, attimer_ids)) <= 0) | 513 result = ISA_PNP_PROBE(device_get_parent(dev), dev, attimer_ids); 514 if (result <= 0) |
649 device_quiet(dev); 650 return(result); 651} 652 653static int 654attimer_attach(device_t dev) 655{ 656 return(0); 657} 658 659static device_method_t attimer_methods[] = { 660 /* Device interface */ 661 DEVMETHOD(device_probe, attimer_probe), 662 DEVMETHOD(device_attach, attimer_attach), 663 DEVMETHOD(device_detach, bus_generic_detach), 664 DEVMETHOD(device_shutdown, bus_generic_shutdown), | 515 device_quiet(dev); 516 return(result); 517} 518 519static int 520attimer_attach(device_t dev) 521{ 522 return(0); 523} 524 525static device_method_t attimer_methods[] = { 526 /* Device interface */ 527 DEVMETHOD(device_probe, attimer_probe), 528 DEVMETHOD(device_attach, attimer_attach), 529 DEVMETHOD(device_detach, bus_generic_detach), 530 DEVMETHOD(device_shutdown, bus_generic_shutdown), |
665 DEVMETHOD(device_suspend, bus_generic_suspend), /* XXX stop statclock? */ 666 DEVMETHOD(device_resume, bus_generic_resume), /* XXX restart statclock? */ | 531 DEVMETHOD(device_suspend, bus_generic_suspend), 532 DEVMETHOD(device_resume, bus_generic_resume), |
667 { 0, 0 } 668}; 669 670static driver_t attimer_driver = { 671 "attimer", 672 attimer_methods, 673 1, /* no softc */ 674}; 675 676static devclass_t attimer_devclass; 677 678DRIVER_MODULE(attimer, isa, attimer_driver, attimer_devclass, 0, 0); | 533 { 0, 0 } 534}; 535 536static driver_t attimer_driver = { 537 "attimer", 538 attimer_methods, 539 1, /* no softc */ 540}; 541 542static devclass_t attimer_devclass; 543 544DRIVER_MODULE(attimer, isa, attimer_driver, attimer_devclass, 0, 0); |
545 |
|
679#endif /* DEV_ISA */ | 546#endif /* DEV_ISA */ |
547 548#ifdef DEV_ISA 549 550/********************************************************************** 551 * RTC driver for subr_rtc 552 */ 553 554#include "clock_if.h" 555 556#include <sys/rman.h> 557 558static void rtc_serialcombit(int); 559static void rtc_serialcom(int); 560static int rtc_inb(void); 561static void rtc_outb(int); 562 563static void 564rtc_serialcombit(int i) 565{ 566 outb(IO_RTC, ((i&0x01)<<5)|0x07); 567 DELAY(1); 568 outb(IO_RTC, ((i&0x01)<<5)|0x17); 569 DELAY(1); 570 outb(IO_RTC, ((i&0x01)<<5)|0x07); 571 DELAY(1); 572} 573 574static void 575rtc_serialcom(int i) 576{ 577 rtc_serialcombit(i&0x01); 578 rtc_serialcombit((i&0x02)>>1); 579 rtc_serialcombit((i&0x04)>>2); 580 rtc_serialcombit((i&0x08)>>3); 581 outb(IO_RTC, 0x07); 582 DELAY(1); 583 outb(IO_RTC, 0x0f); 584 DELAY(1); 585 outb(IO_RTC, 0x07); 586 DELAY(1); 587} 588 589static void 590rtc_outb(int val) 591{ 592 int s; 593 int sa = 0; 594 595 for (s=0;s<8;s++) { 596 sa = ((val >> s) & 0x01) ? 0x27 : 0x07; 597 outb(IO_RTC, sa); /* set DI & CLK 0 */ 598 DELAY(1); 599 outb(IO_RTC, sa | 0x10); /* CLK 1 */ 600 DELAY(1); 601 } 602 outb(IO_RTC, sa & 0xef); /* CLK 0 */ 603} 604 605static int 606rtc_inb(void) 607{ 608 int s; 609 int sa = 0; 610 611 for (s=0;s<8;s++) { 612 sa |= ((inb(0x33) & 0x01) << s); 613 outb(IO_RTC, 0x17); /* CLK 1 */ 614 DELAY(1); 615 outb(IO_RTC, 0x07); /* CLK 0 */ 616 DELAY(2); 617 } 618 return sa; 619} 620 621struct pcrtc_softc { 622 int port_rid1, port_rid2; 623 struct resource *port_res1, *port_res2; 624}; 625 626/* 627 * Attach to the ISA PnP descriptors for the timer and realtime clock. 628 */ 629static struct isa_pnp_id pcrtc_ids[] = { 630 { 0x000bd041 /* PNP0B00 */, "AT realtime clock" }, 631 { 0 } 632}; 633 634static int 635pcrtc_probe(device_t dev) 636{ 637 int result; 638 639 device_set_desc(dev, "PC Real Time Clock"); 640 result = ISA_PNP_PROBE(device_get_parent(dev), dev, pcrtc_ids); 641 /* ENXIO if wrong PnP-ID, ENOENT ifno PnP-ID, zero if good PnP-iD */ 642 if (result != ENOENT) 643 return(result); 644 /* All PC's have an RTC, and we're hosed without it, so... */ 645 return (BUS_PROBE_LOW_PRIORITY); 646} 647 648static int 649pcrtc_attach(device_t dev) 650{ 651 struct pcrtc_softc *sc; 652 653 /* 654 * Not that we need them or anything, but grab our resources 655 * so they show up, correctly attributed, in the big picture. 656 */ 657 sc = device_get_softc(dev); 658 sc->port_rid1 = 0; 659 bus_set_resource(dev, SYS_RES_IOPORT, sc->port_rid1, IO_RTC, 1); 660 if (!(sc->port_res1 = bus_alloc_resource(dev, SYS_RES_IOPORT, 661 &sc->port_rid1, IO_RTC, IO_RTC, 1, RF_ACTIVE))) 662 device_printf(dev, "Warning: Couldn't map I/O.\n"); 663 sc->port_rid2 = 1; 664 bus_set_resource(dev, SYS_RES_IOPORT, sc->port_rid2, 0x33, 1); 665 if (!(sc->port_res2 = bus_alloc_resource(dev, SYS_RES_IOPORT, 666 &sc->port_rid2, 0x33, 0x33, 1, RF_ACTIVE))) 667 device_printf(dev, "Warning: Couldn't map I/O.\n"); 668 669 clock_register(dev, 1000000); 670 return(0); 671} 672 673static int 674pcrtc_settime(device_t dev __unused, struct timespec *ts) 675{ 676 struct clocktime ct; 677 678 clock_ts_to_ct(ts, &ct); 679 680 rtc_serialcom(0x01); /* Register shift command. */ 681 682 rtc_outb(bin2bcd(ct.sec)); /* Write back Seconds */ 683 rtc_outb(bin2bcd(ct.min)); /* Write back Minutes */ 684 rtc_outb(bin2bcd(ct.hour)); /* Write back Hours */ 685 686 rtc_outb(bin2bcd(ct.day)); /* Write back Day */ 687 rtc_outb((ct.mon << 4) | ct.dow); /* Write back Month and DOW */ 688 rtc_outb(bin2bcd(ct.year % 100)); /* Write back Year */ 689 690 rtc_serialcom(0x02); /* Time set & Counter hold command. */ 691 rtc_serialcom(0x00); /* Register hold command. */ 692 693 return (0); 694} 695 696static int 697pcrtc_gettime(device_t dev, struct timespec *ts) 698{ 699 struct clocktime ct; 700 int i; 701 702 rtc_serialcom(0x03); /* Time Read */ 703 rtc_serialcom(0x01); /* Register shift command. */ 704 DELAY(20); 705 706 ct.nsec = 0; 707 ct.sec = bcd2bin(rtc_inb() & 0xff); /* sec */ 708 ct.min = bcd2bin(rtc_inb() & 0xff); /* min */ 709 ct.hour = bcd2bin(rtc_inb() & 0xff); /* hour */ 710 ct.day = bcd2bin(rtc_inb() & 0xff); /* date */ 711 i = rtc_inb(); 712 ct.dow = i & 0x0f; /* dow */ 713 ct.mon = (i >> 4) & 0x0f; /* month */ 714 ct.year = bcd2bin(rtc_inb() & 0xff) + 1900; /* year */ 715 if (ct.year < 1995) 716 ct.year += 100; 717 718 /* Set dow = -1 because some clocks don't set it correctly. */ 719 ct.dow = -1; 720 721 return (clock_ct_to_ts(&ct, ts)); 722} 723 724static device_method_t pcrtc_methods[] = { 725 /* Device interface */ 726 DEVMETHOD(device_probe, pcrtc_probe), 727 DEVMETHOD(device_attach, pcrtc_attach), 728 DEVMETHOD(device_detach, bus_generic_detach), 729 DEVMETHOD(device_shutdown, bus_generic_shutdown), 730 DEVMETHOD(device_suspend, bus_generic_suspend), 731 /* XXX stop statclock? */ 732 DEVMETHOD(device_resume, bus_generic_resume), 733 /* XXX restart statclock? */ 734 735 /* clock interface */ 736 DEVMETHOD(clock_gettime, pcrtc_gettime), 737 DEVMETHOD(clock_settime, pcrtc_settime), 738 739 { 0, 0 } 740}; 741 742static driver_t pcrtc_driver = { 743 "pcrtc", 744 pcrtc_methods, 745 sizeof(struct pcrtc_softc), 746}; 747 748static devclass_t pcrtc_devclass; 749 750DRIVER_MODULE(pcrtc, isa, pcrtc_driver, pcrtc_devclass, 0, 0); 751 752#endif /* DEV_ISA */ |
|