Ticket #8987: FixHandoverFromSMM.2.patch

File FixHandoverFromSMM.2.patch, 3.2 KB (added by x-ist, 12 years ago)
  • src/add-ons/kernel/busses/usb/ohci.cpp

    From 0f0a1880cf345acba4cad24a419e25de469de03e Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?J=C3=BCrgen=20Wall?= <fakeEmail@fakesite.fake>
    Date: Thu, 4 Oct 2012 21:17:45 +0000
    Subject: [PATCH] Fix ownership handover from SMM to OS.
    
    * Disabling all interrupts prior to ownership handover from SMM to OS
      can prevent propper OHCI and PS/2 functionality as described in
      #8987 and #8984. In that case SMM does not respond to the ownership
      change request. On the other hand not disabling the interrupts can
      lead to interrupt storms (discussed in #8085) since no interrupt
      handler is installed at that moment. As suggested by mmlr this patch
      attempts to address both issues by keeping the ownership change
      request interrupt enabled.
    
    * Removed an unnecessary reset upon non-responding SMM for now,
      since we reset a few lines later anyway and added TODOs respectively.
      That should safe a bit boot time.
    ---
     src/add-ons/kernel/busses/usb/ohci.cpp |   24 +++++++++++++++++-------
     1 file changed, 17 insertions(+), 7 deletions(-)
    
    diff --git a/src/add-ons/kernel/busses/usb/ohci.cpp b/src/add-ons/kernel/busses/usb/ohci.cpp
    index df38174..73bc769 100644
    a b OHCI::OHCI(pci_info *info, Stack *stack)  
    206206    fInterruptEndpoints[0]->next_physical_endpoint
    207207        = fDummyIsochronous->physical_address;
    208208
    209     // Disable all interrupts before handoff/reset
    210     _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS);
     209    // When the handover from SMM takes place, all interrupts are routed to the
     210    // OS. As we don't yet have an interrupt handler installed at this point,
     211    // this may cause interrupt storms if the firmware does not disable the
     212    // interrupts during handover. Therefore we disable interrupts before
     213    // requesting ownership. We have to keep the ownership change interrupt
     214    // enabled though, as otherwise the SMM will not be notified of the
     215    // ownership change request we trigger below.   
     216    _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS &
     217        ~OHCI_OWNERSHIP_CHANGE) ;
    211218
    212219    // Determine in what context we are running (Kindly copied from FreeBSD)
    213220    uint32 control = _ReadReg(OHCI_CONTROL);
    OHCI::OHCI(pci_info *info, Stack *stack)  
    221228        }
    222229
    223230        if ((control & OHCI_INTERRUPT_ROUTING) != 0) {
    224             TRACE_ERROR("smm does not respond. resetting...\n");
    225             _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
    226             snooze(USB_DELAY_BUS_RESET);
     231            TRACE_ERROR("smm does not respond.\n");
     232           
     233            // TODO: Enable this reset as soon as the non-specified
     234            // reset a few lines later is replaced by a better solution.
     235            //_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
     236            //snooze(USB_DELAY_BUS_RESET);
    227237        } else
    228238            TRACE_ALWAYS("ownership change successful\n");
    229239    } else {
    OHCI::OHCI(pci_info *info, Stack *stack)  
    231241        snooze(USB_DELAY_BUS_RESET);
    232242    }
    233243
    234     // This reset should not be necessary according to the OHCI spec, but
    235     // without it some controllers do not start.
     244    // TODO: This reset delays system boot time. It should not be necessary
     245    // according to the OHCI spec, but without it some controllers don't start.
    236246    _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
    237247    snooze(USB_DELAY_BUS_RESET);
    238248