Page 2 of 2

Re: USB MSD : how to turn BIOS "emulation" off ?

Posted: Sun Feb 08, 2015 4:47 pm
by Czernobyl
Nable wrote:You are mixing things.
Beg your pardon - I don't think so !
SMM code is for emulation of i8042: this code emulates presence of 8042 with PS/2 keyboard and mouse when you have only USB ones (and no physical 8042 IC even as a part of LPC chip).
PS2 keyboard & mouse emulation is part of SMM code.
BIOS USB-MSD interface is just another of (several) uses of SMM code. There are many more functions generally done in SMM, including low level stuff for use by APM-ACPI hardware control.
But access to USB storage devices via 0x13 is just an API, it doesn't bring any emulated I/O ports.
Right, it doesn't emulate (floppy/IDE/ATA) disk controller ports.
I see it's my use of the word "emulation" that is causing some confusion. I should have found another term albeit to avoid your - or Brendan's - critique. Maybe, we'll refer to USB MSD being "driven" by BIOS, rather than emulated.

Re: USB MSD : how to turn BIOS "emulation" off ?

Posted: Sun Feb 08, 2015 5:27 pm
by Nable
I don't see any reason for using SMM for USB MSD access.

But I should also agree that hardware vendors often choose hard ways of doing things.
Your PC may be "special", i.e. its hardware and/or BIOS require some quirks in order to correctly pass functions to OS.
One can look here: http://lxr.free-electrons.com/source/dr ... i-quirks.c (Ctrl+F: "handoff"), there are several ways to "signal to the BIOS that the OS wants control of the host controller" and it doesn't seem that there is some versatile solution for this problem.

Re: USB MSD : how to turn BIOS "emulation" off ?

Posted: Sun Feb 08, 2015 5:58 pm
by Czernobyl
Nable wrote:I don't see any reason for using SMM for USB MSD access.
Seen in two unrelated BIOses. The real mode BIOS calls down those routines in SMM by outputting a function byte to the SMI-command port (often port #B2h with Intel chipsets, different with others). Reasons that I can see for its use :
1. limited space in standard BIOS reserved upper memory regions (often, E0000-FFFFF or less).
2. some routines might be used by the low-level implemention of ACPI, ???(edit : upon rethinkig, this was far-fetched, don't take it over seriously ).
But I should also agree that hardware vendors often choose hard ways of doing things.
Your PC may be "special", i.e. its hardware and/or BIOS require some quirks in order to correctly pass functions to OS.
One can look here: http://lxr.free-electrons.com/source/dr ... i-quirks.c (Ctrl+F: "handoff"), there are several ways to "signal to the BIOS that the OS wants control of the host controller" and it doesn't seem that there is some versatile solution for this problem.
Shall have a peek. thank you !

Re: USB MSD : how to turn BIOS "emulation" off ?

Posted: Sun Feb 08, 2015 7:44 pm
by Brendan
Hi,
Czernobyl wrote:Brendan, with all due respect, ... it IS an emulation. There is no reason not to call it as such, and indeed it is analogous in many respects to BIOS El torito CD/DVD booting : BIOS has a USB stack, most of the lower level routines being in SMM protected RAM (for no special technical reason except there might not be enough room in regular "visible" BIOS ROM space). The int 13 "high level" API calls down to the appropriate hardware routines according to the medium type, like you say. I don't see why on earth it couldn't be called an "emulation" when flash RAM thru USB is "disguised" by the BIOS as a floppy (or hard disk) with some unusual parameters nut... that's me, and it's only a matter of wording.
It's analogous to "no emulation El Torito". The only reason for SMM to be involved would be to avoid "split brain" problems caused by both PS/2 emulation and the "int 0x13" trying to use the same USB controller (for different USB devices) at the same time.
Czernobyl wrote:
There's no BIOS function to "release" the USB storage device

Yet the BIOS will release it as part a reboot sequence (be it "warm"). there evidently IS a routine that does the orderly release, including the flushing of buffers (and YES the BIOS must maintain at least one sector buffer, just stop to think a minute ! I've LOCATED such buffer in BIOS-managed RAM on this machine I'm now at ...
If you remove a SATA hard drive and do a warm boot does that mean the hard drive was "released"?

Please note that I never said there wasn't any sector buffer, and only said that if there is a sector buffer it doesn't require flushing, because the transfer must complete before the BIOS can determine if the read/write succeeded, which must happen before the BIOS can return status back to the caller.

The only reason I can think of for a sector buffer to be needed is if the USB controller's DMA transfers require some sort of alignment, where the hardware can't transfer sectors directly to/from the address the caller specified if that address doesn't meet the USB controller's alignment requirements. There are no such alignment restrictions for OHCI, UHCI, EHCI or xHCI USB controllers.

It's far more likely that what you think you saw is actually an area that the USB controller uses to store "transfer descriptors" that are used to arrange DMA transfers between the device and RAM. All USB controllers (that I know of) require something like that. Note: "transfer descriptors" is a massive oversimplification and it's typically more like an elaborate system of lists containing many different type of entries where only some of those are for data transfers.
Czernobyl wrote:So, what you said can only have one sensible meaning, id est, there is no public, BIOS independent, interface for USER to ask BIOS to release the USB emulation.

Sadly this is a possibility : are you CERTAIN or just guessing ?
Unfortunately for the last 10 or 15 years more and more interfaces have gone opaque, as in : reserved to industry comity members.
If you asked me if unicorns actually exist, I'd tell you "no" and I'd be certain, but I would also be guessing (it's impossible to prove that unicorns don't exist somewhere in the universe). In the same way, I'm both certain and guessing that what you're hoping for doesn't exist - there's no evidence to suggest it exists and no reason for it to exist, but it's impossible to prove that (e.g.) some strange Compaq machine didn't have it as an obscure and undocumented feature back in 1992.


Cheers,

Brendan

Re: USB MSD : how to turn BIOS "emulation" off ?

Posted: Tue Mar 03, 2015 5:35 pm
by ehenkes
The hc driver module has to fight with the BIOS for the steering wheel. :D

I show you an example of our ehci code in PrettyOS:

Code: Select all

static void ehci_deactivateLegacySupport(ehci_t* e)
{
    pciDev_t* dev = e->PCIdevice;
    uint8_t eecp = BYTE2(e->CapRegs->HCCPARAMS);
    //   eecp     // RO - This field identifies the extended capability.
                  //      01h identifies the capability as Legacy Support.
    if (eecp >= 0x40)
    {
        uint8_t eecp_id=0;

        while (eecp) // 00h indicates end of the ext. cap. list.
        {
            eecp_id = pci_configRead(dev, eecp, 1);
            if (eecp_id == 1) { break; }
            eecp = pci_configRead(dev, eecp + 1, 1);
        }

        uint8_t BIOSownedSemaphore = eecp + 2; // R/W - only Bit 16 (Bit 23:17 Reserved, must be set to zero)
        uint8_t OSownedSemaphore   = eecp + 3; // R/W - only Bit 24 (Bit 31:25 Reserved, must be set to zero)
        uint8_t USBLEGCTLSTS       = eecp + 4; // USB Legacy Support Control/Status (DWORD, cf. EHCI 1.0 spec, 2.1.8)

        // Legacy-Support-EC found? BIOS-Semaphore set?
        if (eecp_id == 1 && (pci_configRead(dev, BIOSownedSemaphore, 1) & 0x01))
        {
              pci_configWrite_byte(dev, OSownedSemaphore, 0x01);

            WAIT_FOR_CONDITION((pci_configRead(dev, BIOSownedSemaphore, 1) & 0x01) == 0, 250, 10, "BIOS-Semaphore still set.\n");
            WAIT_FOR_CONDITION((pci_configRead(dev, OSownedSemaphore, 1) & 0x01) != 0, 250, 10, "OS-Semaphore still cleared.\n");

            // USB SMI Enable R/W. 0=Default.
            // The OS tries to set SMI to disabled in case that BIOS bit stays at one.
            pci_configWrite_dword(dev, USBLEGCTLSTS, 0x0); // USB SMI disabled
        }
    }
}