On Mon, Jan 20, 2014 at 04:25:18PM -0500, Gabriel L. Somlo wrote: > On Mon, Jan 20, 2014 at 10:31:56PM +0200, Michael S. Tsirkin wrote: > > > And later: > > > > > > Device (HPET) { > > > ... > > > Method (_STA, 0, NotSerialized) { > > > If (LGreaterEqual (OSYS, 0x07D1)) { > > > If (HPAE) { > > > Return (0x0F) > > > } > > > } Else { > > > If (HPAE) { > > > > and where does HPAE come from? > > e.g, on the MBP2,2: > > OperationRegion (RCRB, SystemMemory, 0xFED1C000, 0x4000) > Field (RCRB, DWordAcc, Lock, Preserve) > { > Offset (0x1000), > Offset (0x3000), > Offset (0x3404), > HPAS, 2, > , 5, > HPAE, 1, > ... > } > > i.e., I think it's something similar to how VEND and PRD are > checked in HPET._STA on qemu and seabios to decide whether to > return 0x00 or 0x0F. > > > For example, this msdn article at microsoft.com: > > http://msdn.microsoft.com/en-us/library/windows/hardware/gg463275.aspx > > "How to Identify the Windows Version in ACPI by Using _OSI" > > > > at the end it states: > > the operating system makes features available based on the > > string argument to the _OSI method. > > The full text of that goes: > > "Implementation Note > Place the routine that identifies the operating system in an _INI method > under the \_SB scope so that _OSI can run as early as possible. This > placement is important because the operating system makes features > available based on the string argument to the _OSI method." > > It all depends on what the document's author meant by "the operating > system" which "makes features available". Because somewhere earlier in > the document they say: > > "Recent versions of the ACPI spec have extended the use cases of > the _OSI method beyond host operating system version identification. > However, Windows supports _OSI only for the use of identifying the host > version of Windows that is running on the system." > > So my interpretation would be "call _OSI early during some _INI method > under the \_SB scope, so you know how to tweak the various other ACPI > nodes and methods". Kinda like the Apple OSYS example. > > So I got curious, and looked through the DSDT.dsl on my other machines. > Both Dells also have \_SB._INI methods which liberally check _OSI, like > e.g. from my Dell R410 server: > > Name (TOOS, 0x00) > Method (INIC, 0, NotSerialized) { > If (CondRefOf (_OSI, Local0)) { > If (\_OSI ("Windows 2001")) { > Store (0x05, TOOS) > } > > ... > > If (\_OSI ("Linux")) { > Store (0x01, TOOS) > } > } Else { > Store (\_OS, Local0) > Store (SCMP (Local0, "Microsoft Windows NT"), Local1) > If (Not (Local1)) { > Store (0x04, TOOS) > } Else { > Store (SCMP (Local0, "Microsoft Windows"), Local2) > If (Not (Local2)) { > Store (0x02, TOOS) > } Else { > Store (SCMP (Local0, "Microsoft WindowsME:Millennium > Edition"), Local3) > If (Not (Local3)) { > Store (0x03, TOOS) > } > } > } > } > } > > My Dell D630 laptop also does it. I'm wondering if there is any > non-apple, non-dell hardware that does NOT do this. This feels to > me like "circumstantial evidence" in favor of my interpretation > above, but see below...
Yes, my server boxes don't have any _OSI in the DSDT. Unlike laptop which really mostly cares about the windows version that ships with it, these guys sometimes care about running non windows OS-es. It actually does call _OSI later, but in a way that has no effect: Method (_STA, 0, NotSerialized) { Store (\_OS, Local0) Mid (Local0, Zero, 0x09, Local1) If (LEqual (Local1, "Microsoft")) { If (CondRefOf (_OSI, Local2)) { If (\_OSI ("Windows 2009")) { Return (0x0F) } Else { Return (Zero) } } Else { Return (Zero) } } Else { Return (0x0F) } } So this is a nice trick: it checks prefix of _OS *then* calls _OSI. Of course I'm not sure it won't crash if _OS is shorter than 9 bytes but we can write this more defensively. > > I'm not sure why it's a problem to refer to SMC._STA > > but if it is, we can just patch in another variable > > in the HPET scope instead of _OSI. > > Not a problem per se; just that, being relatively new to ACPI, I wasn't > strongly in favor or against either of the two possible ways to do this. > > I didn't even know about _OSI until Paolo mentioned it somewhere earlier > in the conversation, so my only hammer used to be: > > If (CondRefOf(\_SB.PCI0.ISA.SMC)) > > to determine whether to include IRQNoFlags in HPET._CRS or not. Now that > I know about _OSI, tying the HPET to the SMC feels a bit hacky. Of > course, if you're right and it's bad voodoo to call _OSI, then it may > yet be the lesser of two evils. So assuming people don't want to tie this to SMC (which I still like best) second best I like the idea of looking at the prefix of _OS - like code above does - then checking _OSI to make sure. This way this won't affect microsoft or linux guests. We probably call this in init though. Could you find out what are _OS values for OSX? > It's just that all DSDTs I have access to (apple and dell) already do > call _OSI with impunity, so I'm not sure just how bad the voodoo is... Not sure I trust what firmware developers do. From what I saw they basically ship it and then software has to find work arounds. > > > Not sure we want to "complicate" the rest of the HPET (e.g. return > > > different values for bit2, "show device in acpi u/i" depending on > > > _OSI, the way Apple machines do). > > > > They seem to clear this bit for linux? > > No idea why they do this - want to try looking into > > linux source to figure out? > > According to the ACPI docs, the bit is labeled "show device in the u/i", > and at least on XP, the only side effect is listing the HPET in the > device tree or not, sort-of like a "hidden bit". I'll check the linux > source to see if anything is done with that bit, and if so, what. > > Thanks, > --Gabriel