Commit 6e44ba7fa22389896be6c21b68b53778a0775821

Authored by bellard
1 parent 6986f88c

cmos return current date - current irq priority in PIC (L4 Pistachio support) - help fixes


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@557 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 125 additions and 68 deletions
... ... @@ -525,6 +525,28 @@ void cmos_ioport_write(CPUState *env, uint32_t addr, uint32_t data)
525 525 }
526 526 }
527 527  
  528 +static inline int to_bcd(int a)
  529 +{
  530 + return ((a / 10) << 4) | (a % 10);
  531 +}
  532 +
  533 +static void cmos_update_time(void)
  534 +{
  535 + struct tm *tm;
  536 + time_t ti;
  537 +
  538 + ti = time(NULL);
  539 + tm = gmtime(&ti);
  540 + cmos_data[RTC_SECONDS] = to_bcd(tm->tm_sec);
  541 + cmos_data[RTC_MINUTES] = to_bcd(tm->tm_min);
  542 + cmos_data[RTC_HOURS] = to_bcd(tm->tm_hour);
  543 + cmos_data[RTC_DAY_OF_WEEK] = to_bcd(tm->tm_wday);
  544 + cmos_data[RTC_DAY_OF_MONTH] = to_bcd(tm->tm_mday);
  545 + cmos_data[RTC_MONTH] = to_bcd(tm->tm_mon + 1);
  546 + cmos_data[RTC_YEAR] = to_bcd(tm->tm_year % 100);
  547 + cmos_data[REG_IBM_CENTURY_BYTE] = to_bcd((tm->tm_year / 100) + 19);
  548 +}
  549 +
528 550 uint32_t cmos_ioport_read(CPUState *env, uint32_t addr)
529 551 {
530 552 int ret;
... ... @@ -532,17 +554,32 @@ uint32_t cmos_ioport_read(CPUState *env, uint32_t addr)
532 554 if (addr == 0x70) {
533 555 return 0xff;
534 556 } else {
535   - ret = cmos_data[cmos_index];
536 557 switch(cmos_index) {
  558 + case RTC_SECONDS:
  559 + case RTC_MINUTES:
  560 + case RTC_HOURS:
  561 + case RTC_DAY_OF_WEEK:
  562 + case RTC_DAY_OF_MONTH:
  563 + case RTC_MONTH:
  564 + case RTC_YEAR:
  565 + case REG_IBM_CENTURY_BYTE:
  566 + cmos_update_time();
  567 + ret = cmos_data[cmos_index];
  568 + break;
537 569 case RTC_REG_A:
  570 + ret = cmos_data[cmos_index];
538 571 /* toggle update-in-progress bit for Linux (same hack as
539 572 plex86) */
540 573 cmos_data[RTC_REG_A] ^= 0x80;
541 574 break;
542 575 case RTC_REG_C:
  576 + ret = cmos_data[cmos_index];
543 577 pic_set_irq(8, 0);
544 578 cmos_data[RTC_REG_C] = 0x00;
545 579 break;
  580 + default:
  581 + ret = cmos_data[cmos_index];
  582 + break;
546 583 }
547 584 #ifdef DEBUG_CMOS
548 585 printf("cmos: read index=0x%02x val=0x%02x\n",
... ... @@ -552,27 +589,11 @@ uint32_t cmos_ioport_read(CPUState *env, uint32_t addr)
552 589 }
553 590 }
554 591  
555   -
556   -static inline int to_bcd(int a)
557   -{
558   - return ((a / 10) << 4) | (a % 10);
559   -}
560   -
561 592 void cmos_init(void)
562 593 {
563   - struct tm *tm;
564   - time_t ti;
565 594 int val;
566 595  
567   - ti = time(NULL);
568   - tm = gmtime(&ti);
569   - cmos_data[RTC_SECONDS] = to_bcd(tm->tm_sec);
570   - cmos_data[RTC_MINUTES] = to_bcd(tm->tm_min);
571   - cmos_data[RTC_HOURS] = to_bcd(tm->tm_hour);
572   - cmos_data[RTC_DAY_OF_WEEK] = to_bcd(tm->tm_wday);
573   - cmos_data[RTC_DAY_OF_MONTH] = to_bcd(tm->tm_mday);
574   - cmos_data[RTC_MONTH] = to_bcd(tm->tm_mon + 1);
575   - cmos_data[RTC_YEAR] = to_bcd(tm->tm_year % 100);
  596 + cmos_update_time();
576 597  
577 598 cmos_data[RTC_REG_A] = 0x26;
578 599 cmos_data[RTC_REG_B] = 0x02;
... ... @@ -580,7 +601,6 @@ void cmos_init(void)
580 601 cmos_data[RTC_REG_D] = 0x80;
581 602  
582 603 /* various important CMOS locations needed by PC/Bochs bios */
583   - cmos_data[REG_IBM_CENTURY_BYTE] = to_bcd((tm->tm_year / 100) + 19);
584 604  
585 605 cmos_data[REG_EQUIPMENT_BYTE] = 0x02; /* FPU is there */
586 606 cmos_data[REG_EQUIPMENT_BYTE] |= 0x04; /* PS/2 mouse installed */
... ... @@ -676,14 +696,15 @@ typedef struct PicState {
676 696 uint8_t irr; /* interrupt request register */
677 697 uint8_t imr; /* interrupt mask register */
678 698 uint8_t isr; /* interrupt service register */
679   - uint8_t priority_add; /* used to compute irq priority */
  699 + uint8_t priority_add; /* highest irq priority */
680 700 uint8_t irq_base;
681 701 uint8_t read_reg_select;
682 702 uint8_t poll;
683 703 uint8_t special_mask;
684 704 uint8_t init_state;
685 705 uint8_t auto_eoi;
686   - uint8_t rotate_on_autoeoi;
  706 + uint8_t rotate_on_auto_eoi;
  707 + uint8_t special_fully_nested_mode;
687 708 uint8_t init4; /* true if 4 byte init */
688 709 } PicState;
689 710  
... ... @@ -705,14 +726,16 @@ static inline void pic_set_irq1(PicState *s, int irq, int level)
705 726 }
706 727 }
707 728  
  729 +/* return the highest priority found in mask (highest = smallest
  730 + number). Return 8 if no irq */
708 731 static inline int get_priority(PicState *s, int mask)
709 732 {
710 733 int priority;
711 734 if (mask == 0)
712   - return -1;
713   - priority = 7;
  735 + return 8;
  736 + priority = 0;
714 737 while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0)
715   - priority--;
  738 + priority++;
716 739 return priority;
717 740 }
718 741  
... ... @@ -723,13 +746,18 @@ static int pic_get_irq(PicState *s)
723 746  
724 747 mask = s->irr & ~s->imr;
725 748 priority = get_priority(s, mask);
726   - if (priority < 0)
  749 + if (priority == 8)
727 750 return -1;
728   - /* compute current priority */
729   - cur_priority = get_priority(s, s->isr);
730   - if (priority > cur_priority) {
  751 + /* compute current priority. If special fully nested mode on the
  752 + master, the IRQ coming from the slave is not taken into account
  753 + for the priority computation. */
  754 + mask = s->isr;
  755 + if (s->special_fully_nested_mode && s == &pics[0])
  756 + mask &= ~(1 << 2);
  757 + cur_priority = get_priority(s, mask);
  758 + if (priority < cur_priority) {
731 759 /* higher priority found: an irq should be generated */
732   - return priority;
  760 + return (priority + s->priority_add) & 7;
733 761 } else {
734 762 return -1;
735 763 }
... ... @@ -758,6 +786,17 @@ void pic_update_irq(void)
758 786 /* from master pic */
759 787 pic_irq_requested = irq;
760 788 }
  789 +#if defined(DEBUG_PIC)
  790 + {
  791 + int i;
  792 + for(i = 0; i < 2; i++) {
  793 + printf("pic%d: imr=%x irr=%x padd=%d\n",
  794 + i, pics[i].imr, pics[i].irr, pics[i].priority_add);
  795 +
  796 + }
  797 + }
  798 + printf("pic: cpu_interrupt req=%d\n", pic_irq_requested);
  799 +#endif
761 800 cpu_interrupt(global_env, CPU_INTERRUPT_HARD);
762 801 }
763 802 }
... ... @@ -787,6 +826,18 @@ void pic_set_irq(int irq, int level)
787 826 pic_update_irq();
788 827 }
789 828  
  829 +/* acknowledge interrupt 'irq' */
  830 +static inline void pic_intack(PicState *s, int irq)
  831 +{
  832 + if (s->auto_eoi) {
  833 + if (s->rotate_on_auto_eoi)
  834 + s->priority_add = (irq + 1) & 7;
  835 + } else {
  836 + s->isr |= (1 << irq);
  837 + }
  838 + s->irr &= ~(1 << irq);
  839 +}
  840 +
790 841 int cpu_x86_get_pic_interrupt(CPUState *env)
791 842 {
792 843 int irq, irq2, intno;
... ... @@ -804,22 +855,20 @@ int cpu_x86_get_pic_interrupt(CPUState *env)
804 855  
805 856 if (irq >= 8) {
806 857 irq2 = irq & 7;
807   - pics[1].isr |= (1 << irq2);
808   - pics[1].irr &= ~(1 << irq2);
  858 + pic_intack(&pics[1], irq2);
809 859 irq = 2;
810 860 intno = pics[1].irq_base + irq2;
811 861 } else {
812 862 intno = pics[0].irq_base + irq;
813 863 }
814   - pics[0].isr |= (1 << irq);
815   - pics[0].irr &= ~(1 << irq);
  864 + pic_intack(&pics[0], irq);
816 865 return intno;
817 866 }
818 867  
819 868 void pic_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
820 869 {
821 870 PicState *s;
822   - int priority;
  871 + int priority, cmd, irq;
823 872  
824 873 #ifdef DEBUG_PIC
825 874 printf("pic_write: addr=0x%02x val=0x%02x\n", addr, val);
... ... @@ -837,45 +886,48 @@ void pic_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
837 886 if (val & 0x08)
838 887 hw_error("level sensitive irq not supported");
839 888 } else if (val & 0x08) {
840   - if (val & 0x04) {
  889 + if (val & 0x04)
841 890 s->poll = 1;
842   - } else {
843 891 if (val & 0x02)
844 892 s->read_reg_select = val & 1;
845 893 if (val & 0x40)
846 894 s->special_mask = (val >> 5) & 1;
847   - }
848 895 } else {
849   - switch(val) {
850   - case 0x00:
851   - case 0x80:
852   - s->rotate_on_autoeoi = val >> 7;
  896 + cmd = val >> 5;
  897 + switch(cmd) {
  898 + case 0:
  899 + case 4:
  900 + s->rotate_on_auto_eoi = cmd >> 2;
853 901 break;
854   - case 0x20: /* end of interrupt */
855   - case 0xa0:
  902 + case 1: /* end of interrupt */
  903 + case 5:
856 904 priority = get_priority(s, s->isr);
857   - if (priority >= 0) {
858   - s->isr &= ~(1 << ((priority + s->priority_add) & 7));
  905 + if (priority != 8) {
  906 + irq = (priority + s->priority_add) & 7;
  907 + s->isr &= ~(1 << irq);
  908 + if (cmd == 5)
  909 + s->priority_add = (irq + 1) & 7;
  910 + pic_update_irq();
859 911 }
860   - if (val == 0xa0)
861   - s->priority_add = (s->priority_add + 1) & 7;
862   - pic_update_irq();
863 912 break;
864   - case 0x60 ... 0x67:
865   - priority = val & 7;
866   - s->isr &= ~(1 << priority);
  913 + case 3:
  914 + irq = val & 7;
  915 + s->isr &= ~(1 << irq);
867 916 pic_update_irq();
868 917 break;
869   - case 0xc0 ... 0xc7:
  918 + case 6:
870 919 s->priority_add = (val + 1) & 7;
871 920 pic_update_irq();
872 921 break;
873   - case 0xe0 ... 0xe7:
874   - priority = val & 7;
875   - s->isr &= ~(1 << priority);
876   - s->priority_add = (priority + 1) & 7;
  922 + case 7:
  923 + irq = val & 7;
  924 + s->isr &= ~(1 << irq);
  925 + s->priority_add = (irq + 1) & 7;
877 926 pic_update_irq();
878 927 break;
  928 + default:
  929 + /* no operation */
  930 + break;
879 931 }
880 932 }
881 933 } else {
... ... @@ -897,6 +949,7 @@ void pic_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
897 949 }
898 950 break;
899 951 case 3:
  952 + s->special_fully_nested_mode = (val >> 4) & 1;
900 953 s->auto_eoi = (val >> 1) & 1;
901 954 s->init_state = 0;
902 955 break;
... ... @@ -935,18 +988,18 @@ uint32_t pic_ioport_read(CPUState *env, uint32_t addr1)
935 988 addr = addr1;
936 989 s = &pics[addr >> 7];
937 990 addr &= 1;
938   - if (s->poll == 1) {
  991 + if (s->poll) {
939 992 ret = pic_poll_read(s, addr1);
940 993 s->poll = 0;
941 994 } else {
942   - if (addr == 0) {
943   - if (s->read_reg_select)
944   - ret = s->isr;
945   - else
946   - ret = s->irr;
947   - } else {
948   - ret = s->imr;
949   - }
  995 + if (addr == 0) {
  996 + if (s->read_reg_select)
  997 + ret = s->isr;
  998 + else
  999 + ret = s->irr;
  1000 + } else {
  1001 + ret = s->imr;
  1002 + }
950 1003 }
951 1004 #ifdef DEBUG_PIC
952 1005 printf("pic_read: addr=0x%02x val=0x%02x\n", addr1, ret);
... ... @@ -1729,6 +1782,9 @@ void serial_received_byte(SerialState *s, int ch)
1729 1782 fflush(stdout);
1730 1783 term_command = 1;
1731 1784 break;
  1785 + case 'd':
  1786 + cpu_set_log(CPU_LOG_ALL);
  1787 + break;
1732 1788 case TERM_ESCAPE:
1733 1789 goto send_char;
1734 1790 }
... ... @@ -3180,7 +3236,7 @@ void help(void)
3180 3236 "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n"
3181 3237 "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
3182 3238 "-cdrom file use 'file' as IDE cdrom 2 image\n"
3183   - "-boot [c|d] boot on hard disk (c) or CD-ROM (d)\n"
  3239 + "-boot [a|b|c|d] boot on floppy (a, b), hard disk (c) or CD-ROM (d)\n"
3184 3240 "-snapshot write to temporary files instead of disk image files\n"
3185 3241 "-m megs set virtual RAM size to megs MB\n"
3186 3242 "-n script set network init script [default=%s]\n"
... ... @@ -3195,7 +3251,7 @@ void help(void)
3195 3251 "Debug/Expert options:\n"
3196 3252 "-s wait gdb connection to port %d\n"
3197 3253 "-p port change gdb connection port\n"
3198   - "-d output log in /tmp/vl.log\n"
  3254 + "-d output log to %s\n"
3199 3255 "-hdachs c,h,s force hard disk 0 geometry (usually qemu can guess it)\n"
3200 3256 "-L path set the directory for the BIOS and VGA BIOS\n"
3201 3257 "\n"
... ... @@ -3206,7 +3262,8 @@ void help(void)
3206 3262 "qemu-fast",
3207 3263 #endif
3208 3264 DEFAULT_NETWORK_SCRIPT,
3209   - DEFAULT_GDBSTUB_PORT);
  3265 + DEFAULT_GDBSTUB_PORT,
  3266 + "/tmp/qemu.log");
3210 3267 term_print_help();
3211 3268 #ifndef CONFIG_SOFTMMU
3212 3269 printf("\n"
... ...