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,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 uint32_t cmos_ioport_read(CPUState *env, uint32_t addr) 550 uint32_t cmos_ioport_read(CPUState *env, uint32_t addr)
529 { 551 {
530 int ret; 552 int ret;
@@ -532,17 +554,32 @@ uint32_t cmos_ioport_read(CPUState *env, uint32_t addr) @@ -532,17 +554,32 @@ uint32_t cmos_ioport_read(CPUState *env, uint32_t addr)
532 if (addr == 0x70) { 554 if (addr == 0x70) {
533 return 0xff; 555 return 0xff;
534 } else { 556 } else {
535 - ret = cmos_data[cmos_index];  
536 switch(cmos_index) { 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 case RTC_REG_A: 569 case RTC_REG_A:
  570 + ret = cmos_data[cmos_index];
538 /* toggle update-in-progress bit for Linux (same hack as 571 /* toggle update-in-progress bit for Linux (same hack as
539 plex86) */ 572 plex86) */
540 cmos_data[RTC_REG_A] ^= 0x80; 573 cmos_data[RTC_REG_A] ^= 0x80;
541 break; 574 break;
542 case RTC_REG_C: 575 case RTC_REG_C:
  576 + ret = cmos_data[cmos_index];
543 pic_set_irq(8, 0); 577 pic_set_irq(8, 0);
544 cmos_data[RTC_REG_C] = 0x00; 578 cmos_data[RTC_REG_C] = 0x00;
545 break; 579 break;
  580 + default:
  581 + ret = cmos_data[cmos_index];
  582 + break;
546 } 583 }
547 #ifdef DEBUG_CMOS 584 #ifdef DEBUG_CMOS
548 printf("cmos: read index=0x%02x val=0x%02x\n", 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,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 void cmos_init(void) 592 void cmos_init(void)
562 { 593 {
563 - struct tm *tm;  
564 - time_t ti;  
565 int val; 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 cmos_data[RTC_REG_A] = 0x26; 598 cmos_data[RTC_REG_A] = 0x26;
578 cmos_data[RTC_REG_B] = 0x02; 599 cmos_data[RTC_REG_B] = 0x02;
@@ -580,7 +601,6 @@ void cmos_init(void) @@ -580,7 +601,6 @@ void cmos_init(void)
580 cmos_data[RTC_REG_D] = 0x80; 601 cmos_data[RTC_REG_D] = 0x80;
581 602
582 /* various important CMOS locations needed by PC/Bochs bios */ 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 cmos_data[REG_EQUIPMENT_BYTE] = 0x02; /* FPU is there */ 605 cmos_data[REG_EQUIPMENT_BYTE] = 0x02; /* FPU is there */
586 cmos_data[REG_EQUIPMENT_BYTE] |= 0x04; /* PS/2 mouse installed */ 606 cmos_data[REG_EQUIPMENT_BYTE] |= 0x04; /* PS/2 mouse installed */
@@ -676,14 +696,15 @@ typedef struct PicState { @@ -676,14 +696,15 @@ typedef struct PicState {
676 uint8_t irr; /* interrupt request register */ 696 uint8_t irr; /* interrupt request register */
677 uint8_t imr; /* interrupt mask register */ 697 uint8_t imr; /* interrupt mask register */
678 uint8_t isr; /* interrupt service register */ 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 uint8_t irq_base; 700 uint8_t irq_base;
681 uint8_t read_reg_select; 701 uint8_t read_reg_select;
682 uint8_t poll; 702 uint8_t poll;
683 uint8_t special_mask; 703 uint8_t special_mask;
684 uint8_t init_state; 704 uint8_t init_state;
685 uint8_t auto_eoi; 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 uint8_t init4; /* true if 4 byte init */ 708 uint8_t init4; /* true if 4 byte init */
688 } PicState; 709 } PicState;
689 710
@@ -705,14 +726,16 @@ static inline void pic_set_irq1(PicState *s, int irq, int level) @@ -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 static inline int get_priority(PicState *s, int mask) 731 static inline int get_priority(PicState *s, int mask)
709 { 732 {
710 int priority; 733 int priority;
711 if (mask == 0) 734 if (mask == 0)
712 - return -1;  
713 - priority = 7; 735 + return 8;
  736 + priority = 0;
714 while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0) 737 while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0)
715 - priority--; 738 + priority++;
716 return priority; 739 return priority;
717 } 740 }
718 741
@@ -723,13 +746,18 @@ static int pic_get_irq(PicState *s) @@ -723,13 +746,18 @@ static int pic_get_irq(PicState *s)
723 746
724 mask = s->irr & ~s->imr; 747 mask = s->irr & ~s->imr;
725 priority = get_priority(s, mask); 748 priority = get_priority(s, mask);
726 - if (priority < 0) 749 + if (priority == 8)
727 return -1; 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 /* higher priority found: an irq should be generated */ 759 /* higher priority found: an irq should be generated */
732 - return priority; 760 + return (priority + s->priority_add) & 7;
733 } else { 761 } else {
734 return -1; 762 return -1;
735 } 763 }
@@ -758,6 +786,17 @@ void pic_update_irq(void) @@ -758,6 +786,17 @@ void pic_update_irq(void)
758 /* from master pic */ 786 /* from master pic */
759 pic_irq_requested = irq; 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 cpu_interrupt(global_env, CPU_INTERRUPT_HARD); 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,6 +826,18 @@ void pic_set_irq(int irq, int level)
787 pic_update_irq(); 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 int cpu_x86_get_pic_interrupt(CPUState *env) 841 int cpu_x86_get_pic_interrupt(CPUState *env)
791 { 842 {
792 int irq, irq2, intno; 843 int irq, irq2, intno;
@@ -804,22 +855,20 @@ int cpu_x86_get_pic_interrupt(CPUState *env) @@ -804,22 +855,20 @@ int cpu_x86_get_pic_interrupt(CPUState *env)
804 855
805 if (irq >= 8) { 856 if (irq >= 8) {
806 irq2 = irq & 7; 857 irq2 = irq & 7;
807 - pics[1].isr |= (1 << irq2);  
808 - pics[1].irr &= ~(1 << irq2); 858 + pic_intack(&pics[1], irq2);
809 irq = 2; 859 irq = 2;
810 intno = pics[1].irq_base + irq2; 860 intno = pics[1].irq_base + irq2;
811 } else { 861 } else {
812 intno = pics[0].irq_base + irq; 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 return intno; 865 return intno;
817 } 866 }
818 867
819 void pic_ioport_write(CPUState *env, uint32_t addr, uint32_t val) 868 void pic_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
820 { 869 {
821 PicState *s; 870 PicState *s;
822 - int priority; 871 + int priority, cmd, irq;
823 872
824 #ifdef DEBUG_PIC 873 #ifdef DEBUG_PIC
825 printf("pic_write: addr=0x%02x val=0x%02x\n", addr, val); 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,45 +886,48 @@ void pic_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
837 if (val & 0x08) 886 if (val & 0x08)
838 hw_error("level sensitive irq not supported"); 887 hw_error("level sensitive irq not supported");
839 } else if (val & 0x08) { 888 } else if (val & 0x08) {
840 - if (val & 0x04) { 889 + if (val & 0x04)
841 s->poll = 1; 890 s->poll = 1;
842 - } else {  
843 if (val & 0x02) 891 if (val & 0x02)
844 s->read_reg_select = val & 1; 892 s->read_reg_select = val & 1;
845 if (val & 0x40) 893 if (val & 0x40)
846 s->special_mask = (val >> 5) & 1; 894 s->special_mask = (val >> 5) & 1;
847 - }  
848 } else { 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 break; 901 break;
854 - case 0x20: /* end of interrupt */  
855 - case 0xa0: 902 + case 1: /* end of interrupt */
  903 + case 5:
856 priority = get_priority(s, s->isr); 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 break; 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 pic_update_irq(); 916 pic_update_irq();
868 break; 917 break;
869 - case 0xc0 ... 0xc7: 918 + case 6:
870 s->priority_add = (val + 1) & 7; 919 s->priority_add = (val + 1) & 7;
871 pic_update_irq(); 920 pic_update_irq();
872 break; 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 pic_update_irq(); 926 pic_update_irq();
878 break; 927 break;
  928 + default:
  929 + /* no operation */
  930 + break;
879 } 931 }
880 } 932 }
881 } else { 933 } else {
@@ -897,6 +949,7 @@ void pic_ioport_write(CPUState *env, uint32_t addr, uint32_t val) @@ -897,6 +949,7 @@ void pic_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
897 } 949 }
898 break; 950 break;
899 case 3: 951 case 3:
  952 + s->special_fully_nested_mode = (val >> 4) & 1;
900 s->auto_eoi = (val >> 1) & 1; 953 s->auto_eoi = (val >> 1) & 1;
901 s->init_state = 0; 954 s->init_state = 0;
902 break; 955 break;
@@ -935,18 +988,18 @@ uint32_t pic_ioport_read(CPUState *env, uint32_t addr1) @@ -935,18 +988,18 @@ uint32_t pic_ioport_read(CPUState *env, uint32_t addr1)
935 addr = addr1; 988 addr = addr1;
936 s = &pics[addr >> 7]; 989 s = &pics[addr >> 7];
937 addr &= 1; 990 addr &= 1;
938 - if (s->poll == 1) { 991 + if (s->poll) {
939 ret = pic_poll_read(s, addr1); 992 ret = pic_poll_read(s, addr1);
940 s->poll = 0; 993 s->poll = 0;
941 } else { 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 #ifdef DEBUG_PIC 1004 #ifdef DEBUG_PIC
952 printf("pic_read: addr=0x%02x val=0x%02x\n", addr1, ret); 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,6 +1782,9 @@ void serial_received_byte(SerialState *s, int ch)
1729 fflush(stdout); 1782 fflush(stdout);
1730 term_command = 1; 1783 term_command = 1;
1731 break; 1784 break;
  1785 + case 'd':
  1786 + cpu_set_log(CPU_LOG_ALL);
  1787 + break;
1732 case TERM_ESCAPE: 1788 case TERM_ESCAPE:
1733 goto send_char; 1789 goto send_char;
1734 } 1790 }
@@ -3180,7 +3236,7 @@ void help(void) @@ -3180,7 +3236,7 @@ void help(void)
3180 "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n" 3236 "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n"
3181 "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n" 3237 "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
3182 "-cdrom file use 'file' as IDE cdrom 2 image\n" 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 "-snapshot write to temporary files instead of disk image files\n" 3240 "-snapshot write to temporary files instead of disk image files\n"
3185 "-m megs set virtual RAM size to megs MB\n" 3241 "-m megs set virtual RAM size to megs MB\n"
3186 "-n script set network init script [default=%s]\n" 3242 "-n script set network init script [default=%s]\n"
@@ -3195,7 +3251,7 @@ void help(void) @@ -3195,7 +3251,7 @@ void help(void)
3195 "Debug/Expert options:\n" 3251 "Debug/Expert options:\n"
3196 "-s wait gdb connection to port %d\n" 3252 "-s wait gdb connection to port %d\n"
3197 "-p port change gdb connection port\n" 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 "-hdachs c,h,s force hard disk 0 geometry (usually qemu can guess it)\n" 3255 "-hdachs c,h,s force hard disk 0 geometry (usually qemu can guess it)\n"
3200 "-L path set the directory for the BIOS and VGA BIOS\n" 3256 "-L path set the directory for the BIOS and VGA BIOS\n"
3201 "\n" 3257 "\n"
@@ -3206,7 +3262,8 @@ void help(void) @@ -3206,7 +3262,8 @@ void help(void)
3206 "qemu-fast", 3262 "qemu-fast",
3207 #endif 3263 #endif
3208 DEFAULT_NETWORK_SCRIPT, 3264 DEFAULT_NETWORK_SCRIPT,
3209 - DEFAULT_GDBSTUB_PORT); 3265 + DEFAULT_GDBSTUB_PORT,
  3266 + "/tmp/qemu.log");
3210 term_print_help(); 3267 term_print_help();
3211 #ifndef CONFIG_SOFTMMU 3268 #ifndef CONFIG_SOFTMMU
3212 printf("\n" 3269 printf("\n"