Author: neel
Date: Sat Dec 20 04:57:45 2014
New Revision: 275952
URL: https://svnweb.freebsd.org/changeset/base/275952

Log:
  Various 8259 device model improvements:
  
  - implement 8259 "polled" mode.
  - set 'atpic->sfn' if bit 4 in ICW4 is set during master initialization.
  - report error if guest tries to enable the "special mask" mode.
  
  Differential Revision:        https://reviews.freebsd.org/D1328
  Reviewed by:          tychon
  Reported by:          grehan
  Tested by:            grehan
  MFC after:            1 week

Modified:
  head/sys/amd64/vmm/io/vatpic.c

Modified: head/sys/amd64/vmm/io/vatpic.c
==============================================================================
--- head/sys/amd64/vmm/io/vatpic.c      Sat Dec 20 04:24:40 2014        
(r275951)
+++ head/sys/amd64/vmm/io/vatpic.c      Sat Dec 20 04:57:45 2014        
(r275952)
@@ -112,6 +112,16 @@ struct vatpic {
 
 static void vatpic_set_pinstate(struct vatpic *vatpic, int pin, bool newstate);
 
+static __inline bool
+master_atpic(struct vatpic *vatpic, struct atpic *atpic)
+{
+
+       if (atpic == &vatpic->atpic[0])
+               return (true);
+       else
+               return (false);
+}
+
 static __inline int
 vatpic_get_highest_isrpin(struct atpic *atpic)
 {
@@ -250,6 +260,7 @@ vatpic_icw1(struct vatpic *vatpic, struc
        atpic->mask = 0;
        atpic->lowprio = 7;
        atpic->rd_cmd_reg = 0;
+       atpic->poll = 0;
 
        if ((val & ICW1_SNGL) != 0) {
                VATPIC_CTR0(vatpic, "vatpic cascade mode required");
@@ -301,6 +312,15 @@ vatpic_icw4(struct vatpic *vatpic, struc
        if ((val & ICW4_AEOI) != 0)
                atpic->aeoi = true;
 
+       if ((val & ICW4_SFNM) != 0) {
+               if (master_atpic(vatpic, atpic)) {
+                       atpic->sfn = true;
+               } else {
+                       VATPIC_CTR1(vatpic, "Ignoring special fully nested "
+                           "mode on slave atpic: %#x", val);
+               }
+       }
+
        atpic->icw_num = 0;
        atpic->ready = true;
 
@@ -354,11 +374,17 @@ vatpic_ocw3(struct vatpic *vatpic, struc
 {
        VATPIC_CTR1(vatpic, "atpic ocw3 0x%x", val);
 
-       atpic->poll = ((val & OCW3_P) != 0);
+       if (val & OCW3_ESMM) {
+               VATPIC_CTR0(vatpic, "atpic special mask mode not implemented");
+               return (-1);
+       }
 
        if (val & OCW3_RR) {
                /* read register command */
                atpic->rd_cmd_reg = val & OCW3_RIS;
+
+               /* Polling mode */
+               atpic->poll = ((val & OCW3_P) != 0);
        }
 
        return (0);
@@ -578,12 +604,19 @@ static int
 vatpic_read(struct vatpic *vatpic, struct atpic *atpic, bool in, int port,
            int bytes, uint32_t *eax)
 {
+       int pin;
+
        VATPIC_LOCK(vatpic);
 
        if (atpic->poll) {
-               VATPIC_CTR0(vatpic, "vatpic polled mode not supported");
-               VATPIC_UNLOCK(vatpic);
-               return (-1);
+               atpic->poll = 0;
+               pin = vatpic_get_highest_irrpin(atpic);
+               if (pin >= 0) {
+                       vatpic_pin_accepted(atpic, pin);
+                       *eax = 0x80 | pin;
+               } else {
+                       *eax = 0;
+               }
        } else {
                if (port & ICU_IMR_OFFSET) {
                        /* read interrrupt mask register */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to