ACPI Handover and SCI/EC

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
johnsa
Member
Member
Posts: 321
Joined: Mon Oct 15, 2007 3:04 pm

ACPI Handover and SCI/EC

Post by johnsa »

Hey,

Out of boredom and finally having some spare time in life I decided to start dabbling again in my OS code again.

To give some context, whilst I fully appreciate the value of having an AML interpreter to manage ACPI (ideally self-written) and the simplicity of just dropping in an existing solution like acpica etc, I took the rather more painful approach of looking to build a dedicate chipset/firmware driver that effectively replaces all the logic in ACPI. The reasons were several, ASL/AML spec is dreadful and as a language it's pretty awful to manage and is full of bugs/edge-cases etc. Secondly, even if one were to write an ACPI runtime, having done one by hand at least once is probably a really valuable exercise to understand the expectations of handling thermal events, SCI, device init, _Qxx methods, SMM interfacing etc etc. From what I've found, even if you had a 100% working ACPI runtime, the firmware AML is full of bugs and quirks, Linux and Windows seem to work around this by either hot-patching DSDT/SSDTs, reverting to vendor drivers over ACPI or maintaining vast lists of quirks - so at the end of the day, it sort of puts you back into the position of having to handle each platform/chipset combo to some extent.

I have initiated the ACPI->OS handover, setup an SCI IRQ handler and mapped according, initalised the fixed pm events and cleared all the GPEs. I've registered the EC (Embedded Controller) and it's associated GPE. The SCI IRQ fires absolutely fine, I am receiving the standard PM fixed events for Power, PM timer wrap etc, ack'ing those and returning. My problems comes with how to handle the EC and the GPE/SCI it's suppose to raise.
Speaking of ACPI quirks and bugs, even at this point there is already one - the firmware says my SCI IRQ is 0x09, and should be mapped level active-low, which is wrong. If I refer to the Alder Lake 600 series PCH datasheet, it clearly says that it should be active-high if the mapping is 9,10,11 .. but low if mapped to IRQ 20+.

The EC on this particular Dell machine seems particular complex I must note, in that a lot of it is arbitrated via SMM calls and not port i/o to the EC itself. I am trying to reverse engineer the AML as I go so it's almost entirely guaranteed I've either made a mistake somewhere, or some part of my understanding is flawed.

I can get the EC/SCI IRQ into several different situations, none of them right.
1. I can get the SCI to fire, and I can read some form of EC status code which reflects AC adapter in/out, lid open/close, power button etc.
2. Depending on where I clear the GPE status (before) - I get a storm of SCI EC IRQs as if it either is missing an ACK, or constantly re-generates new IRQs by virtue of the port reads, but the status is 0. If I clear the GPE after handling the EC, it never fires again.

My understanding was as follows:
EC has an event, it raises an SCI and sets the corresponding GPE. The SCI IRQ handler checks the EC STATUS PORT for SCI_EVT being set (on my machine this never ever happens although the SCI IRQ still triggers, even if the GPE is masked) - so it's possible something in my handover/setup is missing - possibly some SMM interaction to ACK the EC to OS control. The event should return a code like 0x66 (corresponding to _Q66 AML method) invocation required. I would then dispatch that event, and in my case, for Q66 I can read some EC registers which give me the event sub type (as described above for power/ac/lid etc).

I realise that longer term, I want to move queries from the EC into a work queue that are processed outside of the IRQ so it doesn't jam up, but for now there's no reason it shouldn't just work inside the IRQ.

Curious if anyone else has any experience getting this working, trying to get step 1 right before I continue rolling out the other methods for thermal trips/hot-plug/wake etc etc.

My ACPI init logic is:
1. Write ACPI_ENABLE to SMI Command Port.
2. Wait 1 second.
3. Poll SCI_EN for enable.
4. Write Operating System constant (firmware specific) into the NVRAM area OSYS variable (0x7df).
5. Clear all fixed PM status bits (W1C) and mask all events.
6. Clear all GPE status bits and mask them.
7. Allocate an interrupt and lapic.
8. Assign SCI IRQ to the interrupt via IO APIC as level/active-high.
9. Enable ACPI Fixed Power events + Global.
10. [ tried various AML dervied methods here derived from _INI and _REG methods to prod the EC via SMM ]
11. unmask the EC GPE (0x6e)

My SMM call seems to work fine, as I was able to test it using the Backlight command and the value sticks (although oddly it only reflects after reboot, not live - not sure if this is part of the symptomatic issue or just another Dell ACPI issue as I've found a million reports of people having Backlight ACPI issues online even in Windows and Linux!)

My expectation is that SCI_EVT should get set, and that is the initiator of the whole event process, right now it feels like things are half in SMI, half in SCI land given the SCI triggers - the GPE status bit seems to completely ignore the GPE enable mask, so I land up processing an endless storm of SCIs even when there is no SCI event pending.

Happy to share code and bounce this around if anyone is interested or has some thoughts on it :)
johnsa
Member
Member
Posts: 321
Joined: Mon Oct 15, 2007 3:04 pm

Re: ACPI Handover and SCI/EC

Post by johnsa »

I was able to solve this - I was missing a step from the _REG method as part of my init sequence :)

It uses a combination of SMM calls AND direct writes to the EC (Embedded Controller):

Code: Select all

    ec_write_byte(0x05, 0x01)
    ec_write_byte(0x01, 0x80)
    EISC(0x81, 0x16, 0x02)
    GENS(0x2d, 0, 0)
    EISC(0x81, 0xb8, 0x01)
I'm now getting fixed PM events and all the interesting stuff from the EC (Thermal Traps, Lid, AC Power, Backlight Changes, Battery Low, Dock etc).
Still a ton to get right unpicking all the relevant EC, SMM and NVS stores to fully implement each of those methods - but getting there.
Post Reply