Hi all,
Based on Idwer's RFC I tried adding ACPI to P2B-LS plus completing the rest of the PIIX4 function 3 initialization.
This is a summary of what I did:
* I used the DSDT table from the final vendor BIOS. Not provided here for obvious reasons, but I can tell you how to extract it. * I also replicated the content of the PIIX4 function 3 config space after booting with vendor BIOS, as below:
00:04.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 02) 00: 86 80 13 71 03 00 80 02 02 00 80 06 00 00 00 00 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40: 01 e4 00 00 00 00 00 20 1e 30 00 01 00 00 00 00 50: 00 58 19 00 c0 c8 3b 02 37 40 40 03 00 00 00 00 60: 90 02 e7 00 00 00 00 10 04 e4 11 00 00 00 00 00 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90: 01 e8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0: 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0: 00 00 00 00 00 00 00 00 30 0f 00 00 00 00 00 00
One exception is 0x90-0x91 which has the SMBus host base address. I kept it as 0x0f00.
* Idwer is trying to build ACPI 4.0 (!) tables. Since P2B-LS is shipped when ACPI was still at 1.0, that's what I did. For booting XP, even ACPI 2.0 compliance is sufficient.
This is a summary of what happens:
* I can no longer get POST codes on the PCI bus. POST codes still appear on the ISA bus. Glad I picked a POST card that works on both buses. * Power off does not work. The last POST code to show before complete kernel shutdown and hard drive spinning down is 0xF5. * I don't how how to enter soft suspend in Linux (silly me -_-! ), so I have not tested it. * the sensor appears on ISA bus port 0x290, just like vendor BIOS. * My SB AWE64 ISA card still got initialized and driver loaded, but no sound. In fact ALSA can't even do I/O to the card. That apparently is because PIIX4 needs to be configured to forward certain I/O port ranges to ISA, and some of those port ranges can be further configured. This would require detecting in runtime what ISA cards are installed, what are they, and what I/O port ranges they would use. Where in the source tree should I place such code? Southbridge?
The changes I made are described in two attached patches, one to southbridge/intel/i82371eb, one to mainboard/asus/p2bls. My coreboot and linux boot log is also attached.
This is also RFC and is not signed off at this point, but comments are welcome.
Regards Keith
On 4/14/10 5:54 AM, Keith Hui wrote:
irq 9: nobody cared (try booting with the "irqpoll" option)
This is caused by setting fadt->sci_int without an irqoverride source in the MADT.
current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) current, 0, 9, 9, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_HIGH);
Generally your fadt looks a bit off, still: + fadt->sci_int = 9; // APM_CNT This is not APM control but the sci interrupt + fadt->smi_cmd = 0; This should be APM_CNT + fadt->acpi_enable = 0xa1; // ACPI_ENABLE + fadt->acpi_disable = 0xa0; // ACPI_DISABLE These two should be zero unless you have an SMM handler + fadt->s4bios_req = 0x0; + fadt->pstate_cnt = 0x0;
With SMM it should look like this, assuming the APM_CNT port is 0xb2 on the 82371 too. (It is on the ICHx chips)
#define APM_CNT 0xb2 #define CST_CONTROL 0x85 #define PST_CONTROL 0x80 #define ACPI_DISABLE 0x1e #define ACPI_ENABLE 0xe1
fadt->sci_int = 0x9; fadt->smi_cmd = APM_CNT; fadt->acpi_enable = ACPI_ENABLE; fadt->acpi_disable = ACPI_DISABLE; fadt->s4bios_req = 0x0; fadt->pstate_cnt = PST_CONTROL; ... fadt->cst_cnt = CST_CONTROL;
HTH, Stefan
Hi Keith,
- I also replicated the content of the PIIX4 function 3 config space
after booting with vendor BIOS, as below:
00:04.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 02) 00: 86 80 13 71 03 00 80 02 02 00 80 06 00 00 00 00 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40: 01 e4 00 00 00 00 00 20 1e 30 00 01 00 00 00 00 50: 00 58 19 00 c0 c8 3b 02 37 40 40 03 00 00 00 00 60: 90 02 e7 00 00 00 00 10 04 e4 11 00 00 00 00 00 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90: 01 e8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0: 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0: 00 00 00 00 00 00 00 00 30 0f 00 00 00 00 00 00
Please do not blindly copy the BIOS settings. You dont need to use the old way to monitor device activity because ACPI is about OS driven power management and not HW driven powermanagement.
One exception is 0x90-0x91 which has the SMBus host base address. I kept it as 0x0f00.
- Idwer is trying to build ACPI 4.0 (!) tables. Since P2B-LS is
shipped when ACPI was still at 1.0, that's what I did. For booting XP, even ACPI 2.0 compliance is sufficient.
This is a summary of what happens:
- I can no longer get POST codes on the PCI bus. POST codes still
appear on the ISA bus. Glad I picked a POST card that works on both buses.
- Power off does not work. The last POST code to show before complete
kernel shutdown and hard drive spinning down is 0xF5.
I think you are trying to setup the SMI trap using the BIOS values you supplied.
- I don't how how to enter soft suspend in Linux (silly me -_-! ), so
I have not tested it.
You need to tweak memory controller for that. And other CPU stuff.
- the sensor appears on ISA bus port 0x290, just like vendor BIOS.
- My SB AWE64 ISA card still got initialized and driver loaded, but no
sound. In fact ALSA can't even do I/O to the card. That apparently is because PIIX4 needs to be configured to forward certain I/O port ranges to ISA, and some of those port ranges can be further configured. This would require detecting in runtime what ISA cards are installed, what are they, and what I/O port ranges they would use. Where in the source tree should I place such code? Southbridge?
I think the subtractive decoding is default, hence all IO which is not decoded by any PCI device should be send to ISA automatically.
Maybe you need to trigger EIO/ISA bit too.
Thanks, Rudolf
2010/4/14 Keith Hui buurin@gmail.com
Hi all,
Based on Idwer's RFC I tried adding ACPI to P2B-LS plus completing the rest of the PIIX4 function 3 initialization.
This is a summary of what I did:
- I used the DSDT table from the final vendor BIOS. Not provided here
for obvious reasons, but I can tell you how to extract it.
- I also replicated the content of the PIIX4 function 3 config space
after booting with vendor BIOS, as below:
00:04.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 02) 00: 86 80 13 71 03 00 80 02 02 00 80 06 00 00 00 00 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40: 01 e4 00 00 00 00 00 20 1e 30 00 01 00 00 00 00 50: 00 58 19 00 c0 c8 3b 02 37 40 40 03 00 00 00 00 60: 90 02 e7 00 00 00 00 10 04 e4 11 00 00 00 00 00 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90: 01 e8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0: 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0: 00 00 00 00 00 00 00 00 30 0f 00 00 00 00 00 00
One exception is 0x90-0x91 which has the SMBus host base address. I kept it as 0x0f00.
- Idwer is trying to build ACPI 4.0 (!) tables. Since P2B-LS is
shipped when ACPI was still at 1.0, that's what I did. For booting XP, even ACPI 2.0 compliance is sufficient.
Fixed the ACPI version, althought I'm not booting Windows.
This is a summary of what happens:
- I can no longer get POST codes on the PCI bus. POST codes still
appear on the ISA bus. Glad I picked a POST card that works on both buses.
What about POST codes on the serial port ? See http://www.coreboot.org/Coreboot_Options
- Power off does not work. The last POST code to show before complete
kernel shutdown and hard drive spinning down is 0xF5.
- I don't how how to enter soft suspend in Linux (silly me -_-! ), so
I have not tested it.
http://acpi.sourceforge.net/documentation/sleep.html
- the sensor appears on ISA bus port 0x290, just like vendor BIOS.
- My SB AWE64 ISA card still got initialized and driver loaded, but no
sound. In fact ALSA can't even do I/O to the card. That apparently is because PIIX4 needs to be configured to forward certain I/O port ranges to ISA, and some of those port ranges can be further configured. This would require detecting in runtime what ISA cards are installed, what are they, and what I/O port ranges they would use. Where in the source tree should I place such code? Southbridge?
The changes I made are described in two attached patches, one to southbridge/intel/i82371eb, one to mainboard/asus/p2bls. My coreboot and linux boot log is also attached.
Attached patch: coreboot_r5439_asus_p2b_ram+keithhui-pm+acpi-wip.patch coreboot's serial port log + dmesg and an incomplete bootlog from linux: http://coreboot.pastebin.com/x0QTfji7
This is also RFC and is not signed off at this point, but comments are welcome.
When is it okay to sign off :) probably when the major functions like standby and soft poweroff/reset work like they should and the ACPI tables are created. Oh, and irq routing..
Self quote:
Todo:
- create PRT objects
- finish/fix FADT
- finish all other ACPI tables (RSDT, RSDP, DSDT etcetera)
[ 0.000000] ACPI: RSDP 000f7b20 00014 (v00 CORE ) [ 0.000000] ACPI: RSDT 0fff1424 00034 (v01 CORE COREBOOT 00000000 CORE 00000000) [ 0.000000] ACPI: FACP 0fff1aa2 000F4 (v01 COREBO COREBOOT 00000000 CORE 0000002A) [ 0.000000] ACPI: DSDT 0fff1508 0059A (v01 LXBIOS LXB-DSDT 00000001 INTL 20090521) [ 0.000000] ACPI: FACS 0fff14c8 00040 [ 0.000000] ACPI: APIC 0fff1b96 0003E (v01 CORE COREBOOT 00000000 CORE 00000000) [ 0.000000] ACPI: MCFG 0fff1bd4 0002C (v01 CORE COREBOOT 00000000 CORE 00000000) [ 0.000000] ACPI: SRAT 0fff1c00 00030 (v01 CORE COREBOOT 00000000 CORE 00000000)
- PIRQ routing
[ 1.378731] irq 9: nobody cared (try booting with the "irqpoll" option) [ 1.380003] Pid: 1, comm: swapper Not tainted 2.6.32-21-generic #31-Ubuntu [ 1.380003] Call Trace: <snip> [ 1.380003] Disabling IRQ #9
[ 1.435077] ACPI: PCI Interrupt Link [LNKA] (IRQs) *15, disabled. [ 1.441889] ACPI: PCI Interrupt Link [LNKB] (IRQs 11) *15, disabled. [ 1.448908] ACPI: PCI Interrupt Link [LNKC] (IRQs 10) *15, disabled. [ 1.456644] ACPI: PCI Interrupt Link [LNKD] (IRQs 11) *15, disabled. [ 2.477092] ACPI: PCI Interrupt Link [LNKD] disabled and referenced, BIOS bug
[ 3.173723] irq 11: nobody cared (try booting with the "irqpoll" option) [ 3.176017] Pid: 1, comm: swapper Not tainted 2.6.32-21-generic #31-Ubuntu [ 3.176017] Call Trace: <snip> [ 3.176017] Disabling IRQ #11
- standby/suspend
[ 2.010407] input: Power Button as /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0 [ 2.025108] ACPI: Power Button [PWRF]
- ?
Regards Keith
Idwer
-- coreboot mailing list: coreboot@coreboot.org http://www.coreboot.org/mailman/listinfo/coreboot
On Wed, Apr 14, 2010 at 9:20 PM, Idwer Vollering vidwer@gmail.com wrote:
2010/4/14 Keith Hui buurin@gmail.com
Hi all,
Based on Idwer's RFC I tried adding ACPI to P2B-LS plus completing the rest of the PIIX4 function 3 initialization.
This is a summary of what I did:
- I used the DSDT table from the final vendor BIOS. Not provided here
for obvious reasons, but I can tell you how to extract it.
- I also replicated the content of the PIIX4 function 3 config space
after booting with vendor BIOS, as below:
00:04.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 02) 00: 86 80 13 71 03 00 80 02 02 00 80 06 00 00 00 00 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40: 01 e4 00 00 00 00 00 20 1e 30 00 01 00 00 00 00 50: 00 58 19 00 c0 c8 3b 02 37 40 40 03 00 00 00 00 60: 90 02 e7 00 00 00 00 10 04 e4 11 00 00 00 00 00 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90: 01 e8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0: 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0: 00 00 00 00 00 00 00 00 30 0f 00 00 00 00 00 00
One exception is 0x90-0x91 which has the SMBus host base address. I kept it as 0x0f00.
- Idwer is trying to build ACPI 4.0 (!) tables. Since P2B-LS is
shipped when ACPI was still at 1.0, that's what I did. For booting XP, even ACPI 2.0 compliance is sufficient.
Fixed the ACPI version, althought I'm not booting Windows.
Eventually we can make ACPI 2.0-compliant tables, maybe even add support for message LED, SMI button, and even "ATK0110" support.
This is a summary of what happens:
- I can no longer get POST codes on the PCI bus. POST codes still
appear on the ISA bus. Glad I picked a POST card that works on both buses.
What about POST codes on the serial port ? See http://www.coreboot.org/Coreboot_Options
- Power off does not work. The last POST code to show before complete
kernel shutdown and hard drive spinning down is 0xF5.
- I don't how how to enter soft suspend in Linux (silly me -_-! ), so
I have not tested it.
Thanks. I am indeed silly. :P
- the sensor appears on ISA bus port 0x290, just like vendor BIOS.
- My SB AWE64 ISA card still got initialized and driver loaded, but no
sound. In fact ALSA can't even do I/O to the card. That apparently is because PIIX4 needs to be configured to forward certain I/O port ranges to ISA, and some of those port ranges can be further configured. This would require detecting in runtime what ISA cards are installed, what are they, and what I/O port ranges they would use. Where in the source tree should I place such code? Southbridge?
The changes I made are described in two attached patches, one to southbridge/intel/i82371eb, one to mainboard/asus/p2bls. My coreboot and linux boot log is also attached.
Attached patch: coreboot_r5439_asus_p2b_ram+keithhui-pm+acpi-wip.patch coreboot's serial port log + dmesg and an incomplete bootlog from linux: http://coreboot.pastebin.com/x0QTfji7
This is also RFC and is not signed off at this point, but comments are welcome.
When is it okay to sign off :) probably when the major functions like standby and soft poweroff/reset work like they should and the ACPI tables are created. Oh, and irq routing..
I think when we reach a milestone eg. power off works, no ACPI warnings from Linux, and able to boot Windows 2000 AND XP.
The last point is because I have a laptop with an ACPI implementation that doesn't work with win2k, and I don't want that to happen.
Cheers Keith
On 15.04.2010 18:43, Keith Hui wrote:
On Wed, Apr 14, 2010 at 9:20 PM, Idwer Vollering vidwer@gmail.com wrote:
2010/4/14 Keith Hui buurin@gmail.com
This is also RFC and is not signed off at this point, but comments are welcome.
When is it okay to sign off :) probably when the major functions like standby and soft poweroff/reset work like they should and the ACPI tables are created. Oh, and irq routing..
I think when we reach a milestone eg. power off works, no ACPI warnings from Linux, and able to boot Windows 2000 AND XP.
Please do always add your signoff. This tells us that you didn't steal the code and that you have the right to release it.
If you think a patch is not ready, you can write that in the mail, or add [RFC] to the subject.
Regards, Carl-Daniel
I'll sign off on my next RFC, although as previously said, I'll say it's ready for commit only when I made a breakthrough like when I can power off.
At that time I'd also like to see Idwer sign off on it too. You can go ahead and construct ACPI 2.0 compliant tables. I'm working off a DSDT table derived from the vendor BIOS and that could be a problem, at least legally.
Now, technical question.
Stefan gave me these inputs:
-------------- Date: Wed, 14 Apr 2010 08:31:37 +0200 From: Stefan Reinauer stepan@coresystems.de To: coreboot@coreboot.org Subject: Re: [coreboot] [RFC] ACPI for ASUS P2B/P2B-LS (Intel 440BX/82371EB) Message-ID: 4BC56149.3030707@coresystems.de Content-Type: text/plain; charset="iso-8859-1"
On 4/14/10 5:54 AM, Keith Hui wrote:
irq 9: nobody cared (try booting with the "irqpoll" option)
This is caused by setting fadt->sci_int without an irqoverride source in the MADT.
current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) current, 0, 9, 9, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_HIGH);
Generally your fadt looks a bit off, still: + fadt->sci_int = 9; // APM_CNT This is not APM control but the sci interrupt + fadt->smi_cmd = 0; This should be APM_CNT + fadt->acpi_enable = 0xa1; // ACPI_ENABLE + fadt->acpi_disable = 0xa0; // ACPI_DISABLE These two should be zero unless you have an SMM handler + fadt->s4bios_req = 0x0; + fadt->pstate_cnt = 0x0;
With SMM it should look like this, assuming the APM_CNT port is 0xb2 on the 82371 too. (It is on the ICHx chips)
#define APM_CNT 0xb2 #define CST_CONTROL 0x85 #define PST_CONTROL 0x80 #define ACPI_DISABLE 0x1e #define ACPI_ENABLE 0xe1
fadt->sci_int = 0x9; fadt->smi_cmd = APM_CNT; fadt->acpi_enable = ACPI_ENABLE; fadt->acpi_disable = ACPI_DISABLE; fadt->s4bios_req = 0x0; fadt->pstate_cnt = PST_CONTROL; ... fadt->cst_cnt = CST_CONTROL;
-------------- I checked the PIIX4 datasheet, the APM_CNT is indeed at 0xb2, with 0xb3 also available to pass data. Writes to 0xb2 triggers SMI# when thus enabled and this ACPI enable/disable method expects writing one byte to one port to accomplish it all.
On our boards, this is still correct: #define ACPI_DISABLE 0xa0 #define ACPI_ENABLE 0xa1
I checked the OEM DSDT and found POST debug code. 0xF5 does indeed mean some DSDT code is called when the machine is about to be put into S5 - soft off. Of course, I was trying to power down.
It means I need to write an SMI handler. Anyone has an easily understandable primer on it? How is the coreboot architecture for SMI handler? I traced some files and don't see the RSM instruction anywhere?
PIIX4 supports only one 128KB SMRAM from 0xA0000-0xBFFFF. P6 family CPUs power up assuming this SMRAM is based at 0x30000. It can (and will have to be) relocated, but it can only be done INSIDE SMM mode ie. the SMI handler. I haven't dug deep enough at say the i82830 SMI handler, but any clean idea on how to do this? OEM BIOS has three instances of RSM instructions, implying 3 different SMI handlers for different purposes. Analysis is still ongoing.
Now, Idwer, when I am done, I'll need you to test it as well. I compared the ACPI tables of our boards - at least the ones I can extract straight out of the OEM BIOS images - and they are identical except for a longer PCI IRQ routing table for the added onboard peripherals. So the ACPI work of either of us, should work for us both, well me if the additional IRQ routing added back in.
Thanks Keith
2010/4/17 Keith Hui buurin@gmail.com
I'll sign off on my next RFC, although as previously said, I'll say it's ready for commit only when I made a breakthrough like when I can power off.
At that time I'd also like to see Idwer sign off on it too. You can go ahead and construct ACPI 2.0 compliant tables. I'm working off a DSDT table derived from the vendor BIOS and that could be a problem, at least legally.
Now, technical question.
Stefan gave me these inputs:
Date: Wed, 14 Apr 2010 08:31:37 +0200 From: Stefan Reinauer stepan@coresystems.de To: coreboot@coreboot.org Subject: Re: [coreboot] [RFC] ACPI for ASUS P2B/P2B-LS (Intel 440BX/82371EB) Message-ID: 4BC56149.3030707@coresystems.de Content-Type: text/plain; charset="iso-8859-1"
On 4/14/10 5:54 AM, Keith Hui wrote:
irq 9: nobody cared (try booting with the "irqpoll" option)
This is caused by setting fadt->sci_int without an irqoverride source in the MADT.
current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) current, 0, 9, 9, MP_IRQ_TRIGGER_LEVEL |
MP_IRQ_POLARITY_HIGH);
Generally your fadt looks a bit off, still:
- fadt->sci_int = 9; // APM_CNT
This is not APM control but the sci interrupt
- fadt->smi_cmd = 0;
smi_cmd means smi command port ?
This should be APM_CNT
- fadt->acpi_enable = 0xa1; // ACPI_ENABLE
- fadt->acpi_disable = 0xa0; // ACPI_DISABLE
These two should be zero unless you have an SMM handler
- fadt->s4bios_req = 0x0;
- fadt->pstate_cnt = 0x0;
With SMM it should look like this, assuming the APM_CNT port is 0xb2 on the 82371 too. (It is on the ICHx chips)
#define APM_CNT 0xb2 #define CST_CONTROL 0x85 #define PST_CONTROL 0x80 #define ACPI_DISABLE 0x1e #define ACPI_ENABLE 0xe1
This should be/go in i82371eb.h
fadt->sci_int = 0x9; fadt->smi_cmd = APM_CNT; fadt->acpi_enable = ACPI_ENABLE; fadt->acpi_disable = ACPI_DISABLE; fadt->s4bios_req = 0x0; fadt->pstate_cnt = PST_CONTROL; ... fadt->cst_cnt = CST_CONTROL;
I checked the PIIX4 datasheet, the APM_CNT is indeed at 0xb2, with 0xb3 also available to pass data. Writes to 0xb2 triggers SMI# when thus enabled and this ACPI enable/disable method expects writing one byte to one port to accomplish it all.
APMC at 0xb2 and APMS at 0xb3
On our boards, this is still correct: #define ACPI_DISABLE 0xa0 #define ACPI_ENABLE 0xa1
I checked the OEM DSDT and found POST debug code. 0xF5 does indeed mean some DSDT code is called when the machine is about to be put into S5 - soft off. Of course, I was trying to power down.
/* For now only define 2 power states: * - S0 which is fully on * - S5 which is soft off * Any others would involve declaring the wake up methods. */
/* intel i82371eb (piix4e) datasheet, section 7.2.3, page 142 */ /* 000b / 0x0: soft off/suspend to disk (soff/std) s5 001b / 0x1: suspend to ram (str) s3 010b / 0x2: powered on suspend, context lost (poscl) s1 011b / 0x3: powered on suspend, cpu context lost (posccl) s2 100b / 0x4: powered on suspend, context maintained (pos) s4 101b / 0x5: working (clock control) s0 110b / 0x6: reserved 111b / 0x7: reserved */ Name (_S0, Package () { 0x05, 0x05, 0x00, 0x00 }) Name (_S5, Package () { 0x00, 0x00, 0x00, 0x00 })
S0 and S5 should be correct but since there's no SMI *yet* poweroff doesn't work.
It means I need to write an SMI handler. Anyone has an easily understandable primer on it? How is the coreboot architecture for SMI handler? I traced some files and don't see the RSM instruction anywhere?
Sorry, I don't know anything about SMI and a little about ACPI. Have a look at SMI from, I believe, ICH7: http://tracker.coreboot.org/trac/coreboot/browser/trunk/src/southbridge/inte... http://tracker.coreboot.org/trac/coreboot/browser/trunk/src/southbridge/inte...
PIIX4 supports only one 128KB SMRAM from 0xA0000-0xBFFFF. P6 family CPUs power up assuming this SMRAM is based at 0x30000. It can (and will have to be) relocated, but it can only be done INSIDE SMM mode ie. the SMI handler. I haven't dug deep enough at say the i82830 SMI handler, but any clean idea on how to do this? OEM BIOS has three instances of RSM instructions, implying 3 different SMI handlers for different purposes. Analysis is still ongoing.
Now, Idwer, when I am done, I'll need you to test it as well. I compared the ACPI tables of our boards - at least the ones I can extract straight out of the OEM BIOS images - and they are identical except for a longer PCI IRQ routing table for the added onboard peripherals. So the ACPI work of either of us, should work for us both, well me if the additional IRQ routing added back in.
Thanks Keith
Still unfinished/WIP and unpolished; attaching my patch and signing off:
Signed-off-by: Idwer Vollering vidwer@gmail.com
On 4/26/10 3:55 AM, Idwer Vollering wrote:
Generally your fadt looks a bit off, still: + fadt->sci_int = 9; // APM_CNT This is not APM control but the sci interrupt + fadt->smi_cmd = 0;
smi_cmd means smi command port ?
yes
Updated against r6119, yet unfinished.
Signed-off-by: Idwer Vollering vidwer@gmail.com
Idwer Vollering wrote:
Updated against r6119, yet unfinished.
Here is my extended version, wip.
Index: src/southbridge/intel/i82371eb/i82371eb_fadt.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/southbridge/intel/i82371eb/i82371eb_fadt.c 2010-11-25 03:20:01.000000000 +0100 @@ -0,0 +1,167 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Nick Barker nick.barker9@btinternet.com + * Copyright (C) 2007, 2009 Rudolf Marek r.marek@assembler.cz + * Copyright (C) 2010 Idwer Vollering vidwer@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Based on src/southbridge/via/vt8237r/vt8237_fadt.c */ + +#include <string.h> +#include <arch/acpi.h> +#include <device/device.h> +#include <device/pci.h> +/* PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_SMB_ACPI */ +#include <device/pci_ids.h> +#include "i82371eb.h" /* PM_IO_BASE, PMCNTRL */ + +/** + * Create the Fixed ACPI Description Tables (FADT) for any board with this SB. + */ +void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt) +{ + acpi_header_t *header = &(fadt->header); + device_t dev; + + /* Power management controller */ + dev = dev_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB_SMB_ACPI, 0); /* pci_ids.h */ + + memset((void *) fadt, 0, sizeof(acpi_fadt_t)); + memcpy(header->signature, "FACP", 4); + header->length = 244; + header->revision = 1; + memcpy(header->oem_id, "CORE ", 6); + memcpy(header->oem_table_id, "COREBOOT", 8); + memcpy(header->asl_compiler_id, "CORE", 4); + header->asl_compiler_revision = 42; + + fadt->firmware_ctrl = (u32)facs; + fadt->dsdt = (u32)dsdt; + fadt->preferred_pm_profile = 0; + fadt->sci_int = 9; + fadt->smi_cmd = APM_CNT; + fadt->acpi_enable = ACPI_ENABLE; + fadt->acpi_disable = ACPI_DISABLE; + fadt->s4bios_req = 0x0; + fadt->pstate_cnt = 0x0; + + fadt->pm1a_evt_blk = PM_IO_BASE; /* PM_IO_BASE = 0xe400 */ + fadt->pm1b_evt_blk = 0x0; + fadt->pm1a_cnt_blk = PM_IO_BASE + PMCNTRL; /* PMCNTRL = 0x4 */ + fadt->pm1b_cnt_blk = 0x0; + + fadt->pm2_cnt_blk = 0x22; /* NB is hardwired to io 0x22 */ + fadt->pm_tmr_blk = PM_IO_BASE + PMTMR; /* PMTMR = 0x8 */ + fadt->gpe0_blk = PM_IO_BASE + GPSTS; /* GPSTS = 0xc */ + fadt->gpe1_blk = 0x0; + fadt->gpe1_base = 0; + fadt->gpe1_blk_len = 0; + + fadt->pm1_evt_len = 4; + fadt->pm1_cnt_len = 2; + fadt->pm2_cnt_len = 1; + fadt->pm_tmr_len = 4; + fadt->gpe0_blk_len = 4; + + fadt->cst_cnt = 0; + fadt->p_lvl2_lat = 101; /* >100 means not supported */ + fadt->p_lvl3_lat = 1001; /* >1000 means not supported */ + fadt->flush_size = 0; + fadt->flush_stride = 0; + fadt->duty_offset = 1; /* bit 1:3 in PCNTRL reg (pmbase+0x10) */ + fadt->duty_width = 3; /* 0 means not supported */ + fadt->day_alrm = 0x0d; + fadt->mon_alrm = 0x0; + fadt->century = 0x0; + /* We have legacy devices, 8042, VGA is ok to probe, MSI are not supported */ + fadt->iapc_boot_arch = 0xb; + /* check me */ + fadt->flags = 0xa5; + + fadt->reset_reg.space_id = 0; + fadt->reset_reg.bit_width = 0; + fadt->reset_reg.bit_offset = 0; + fadt->reset_reg.resv = 0; + fadt->reset_reg.addrl = 0x0; + fadt->reset_reg.addrh = 0x0; + + fadt->reset_value = 0; + fadt->x_firmware_ctl_l = (u32)facs; + fadt->x_firmware_ctl_h = 0; + fadt->x_dsdt_l = (u32)dsdt; + fadt->x_dsdt_h = 0; + + fadt->x_pm1a_evt_blk.space_id = 1; + fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8; + fadt->x_pm1a_evt_blk.bit_offset = 0; + fadt->x_pm1a_evt_blk.resv = 0; + fadt->x_pm1a_evt_blk.addrl = fadt->pm1a_evt_blk; + fadt->x_pm1a_evt_blk.addrh = 0x0; + + fadt->x_pm1b_evt_blk.space_id = 1; + fadt->x_pm1b_evt_blk.bit_width = fadt->pm1_evt_len * 8; + fadt->x_pm1b_evt_blk.bit_offset = 0; + fadt->x_pm1b_evt_blk.resv = 0; + fadt->x_pm1b_evt_blk.addrl = fadt->pm1b_evt_blk; + fadt->x_pm1b_evt_blk.addrh = 0x0; + + fadt->x_pm1a_cnt_blk.space_id = 1; + fadt->x_pm1a_cnt_blk.bit_width = fadt->pm1_cnt_len * 8; + fadt->x_pm1a_cnt_blk.bit_offset = 0; + fadt->x_pm1a_cnt_blk.resv = 0; + fadt->x_pm1a_cnt_blk.addrl = fadt->pm1a_cnt_blk; + fadt->x_pm1a_cnt_blk.addrh = 0x0; + + fadt->x_pm1b_cnt_blk.space_id = 1; + fadt->x_pm1b_cnt_blk.bit_width = fadt->pm1_cnt_len * 8; + fadt->x_pm1b_cnt_blk.bit_offset = 0; + fadt->x_pm1b_cnt_blk.resv = 0; + fadt->x_pm1b_cnt_blk.addrl = fadt->pm1b_cnt_blk; + fadt->x_pm1b_cnt_blk.addrh = 0x0; + + fadt->x_pm2_cnt_blk.space_id = 1; + fadt->x_pm2_cnt_blk.bit_width = fadt->pm2_cnt_len * 8; + fadt->x_pm2_cnt_blk.bit_offset = 0; + fadt->x_pm2_cnt_blk.resv = 0; + fadt->x_pm2_cnt_blk.addrl = fadt->pm2_cnt_blk; + fadt->x_pm2_cnt_blk.addrh = 0x0; + + fadt->x_pm_tmr_blk.space_id = 1; + fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8; + fadt->x_pm_tmr_blk.bit_offset = 0; + fadt->x_pm_tmr_blk.resv = 0; + fadt->x_pm_tmr_blk.addrl = fadt->pm_tmr_blk; + fadt->x_pm_tmr_blk.addrh = 0x0; + + fadt->x_gpe0_blk.space_id = 1; + fadt->x_gpe0_blk.bit_width = fadt->gpe0_blk_len * 8; + fadt->x_gpe0_blk.bit_offset = 0; + fadt->x_gpe0_blk.resv = 0; + fadt->x_gpe0_blk.addrl = fadt->gpe0_blk; + fadt->x_gpe0_blk.addrh = 0x0; + + fadt->x_gpe1_blk.space_id = 1; + fadt->x_gpe1_blk.bit_width = fadt->gpe1_blk_len * 8;; + fadt->x_gpe1_blk.bit_offset = 0; + fadt->x_gpe1_blk.resv = 0; + fadt->x_gpe1_blk.addrl = fadt->gpe1_blk; + fadt->x_gpe1_blk.addrh = 0x0; + + header->checksum = acpi_checksum((void *) fadt, sizeof(acpi_fadt_t)); +} Index: src/southbridge/intel/i82371eb/Makefile.inc =================================================================== --- src/southbridge/intel/i82371eb/Makefile.inc.orig 2010-11-25 03:18:26.000000000 +0100 +++ src/southbridge/intel/i82371eb/Makefile.inc 2010-11-25 03:20:01.000000000 +0100 @@ -2,6 +2,7 @@ ## This file is part of the coreboot project. ## ## Copyright (C) 2007 Uwe Hermann uwe@hermann-uwe.de +## Copyright (C) 2010 Idwer Vollering vidwer@gmail.com ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -24,7 +25,10 @@ driver-y += i82371eb_usb.c driver-y += i82371eb_smbus.c driver-y += i82371eb_reset.c +driver-$(CONFIG_HAVE_ACPI_TABLES) += i82371eb_fadt.c
romstage-y += i82371eb_early_pm.c romstage-y += i82371eb_early_smbus.c
+ramstage-$(CONFIG_HAVE_SMI_HANDLER) += i82371eb_smi.c +smm-$(CONFIG_HAVE_SMI_HANDLER) += i82371eb_smihandler.c Index: src/southbridge/intel/i82371eb/i82371eb.h =================================================================== --- src/southbridge/intel/i82371eb/i82371eb.h.orig 2010-11-25 03:18:26.000000000 +0100 +++ src/southbridge/intel/i82371eb/i82371eb.h 2010-11-25 03:38:02.000000000 +0100 @@ -2,6 +2,9 @@ * This file is part of the coreboot project. * * Copyright (C) 2007 Uwe Hermann uwe@hermann-uwe.de + * Copyright (C) 2010 Keith Hui buurin@gmail.com + * Copyright (C) 2010 Idwer Vollering vidwer@gmail.com + * Copyright (C) 2010 Tobias Diedrich ranma+coreboot@tdiedrich.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,8 +26,8 @@
#if !defined(ASSEMBLY) #if !defined(__PRE_RAM__) +#if !defined(ARCH_ROMCC_IO_H)
-#include <arch/io.h> #include <device/device.h> #include "chip.h"
@@ -33,6 +36,7 @@
#endif #endif +#endif
/* If 'cond' is true this macro sets the bit(s) specified by 'bits' in the * 'reg' variable, otherwise it clears those bits. @@ -59,10 +63,55 @@ #define SMBHSTCFG 0xd2 /* SMBus host configuration */
/* Power management (ACPI) */ +#define PMSTS 0x00 /* Power Management Status */ +#define PMEN 0x02 /* Power Management Resume Enable */ +#define PWRBTN_EN (1<<8) +#define GBL_EN (1<<5) +#define PMCNTRL 0x04 /* Power Management Control */ +#define SCI_EN (1<<0) +#define PMTMR 0x08 /* Power Management Timer */ +#define GPSTS 0x0c /* General Purpose Status */ +#define GPEN 0x0e /* General Purpose Enable */ +#define THRM_EN (1<<0) +#define GLBSTS 0x18 /* Global Status */ +#define IRQ_RSM_STS (1<<11) +#define EXTSMI_STS (1<<10) +#define GSTBY_STS (1<<8) +#define GP_STS (1<<7) +#define BM1_STS (1<<6) +#define APM_STS (1<<5) +#define DEV_STS (1<<4) +#define BIOS_EN (1<<1) /* GBL_RLS write triggers SMI */ +#define LEGACY_USB_EN (1<<0) /* Keyboard controller access triggers SMI */ +#define DEVSTS 0x1c /* Device Status */ +#define GLBEN 0x20 /* Global Enable */ +#define EXTSMI_EN (1<<10) /* EXTSMI# signal triggers SMI */ +#define GSTBY_EN (1<<8) +#define BM_TRP_EN (1<<1) +#define BIOS_EN (1<<1) /* GBL_RLS write triggers SMI */ +#define LEGACY_USB_EN (1<<0) /* Keyboard controller access triggers SMI */ +#define GLBCTL 0x28 /* Global Control */ +#define EOS (1<<16) /* End of SMI */ +#define SMI_EN (1<<0) /* SMI enable */ +#define DEVCTL 0x2c /* Device Control */ +#define TRP_EN_DEV12 (1<<24) /* SMI on dev12 trap */ + #define PMBA 0x40 /* Power management base address */ +#define PM_IO_BASE 0xe400 +#define DEFAULT_PMBASE PM_IO_BASE +#define DEVACTB 0x58 +#define APMC_EN (1<<25) +#define DEVRESE 0x68 #define PMREGMISC 0x80 /* Miscellaneous power management */
-#define PM_IO_BASE 0xe400 +#define APM_CNT 0xb2 /* APM control io */ +#define CST_CONTROL 0x85 +#define PST_CONTROL 0x80 +#define ACPI_DISABLE 0x1e +#define ACPI_ENABLE 0xe1 +#define GNVS_UPDATE 0xea +#define MBI_UPDATE 0xeb +#define APM_STS 0xb3 /* APM data io */
/* Bit definitions */ #define EXT_BIOS_ENABLE_1MB (1 << 9) /* 1-Meg Extended BIOS Enable */ Index: src/southbridge/intel/i82371eb/i82371eb_smbus.c =================================================================== --- src/southbridge/intel/i82371eb/i82371eb_smbus.c.orig 2010-11-25 03:18:26.000000000 +0100 +++ src/southbridge/intel/i82371eb/i82371eb_smbus.c 2010-11-25 03:20:01.000000000 +0100 @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2007 Uwe Hermann uwe@hermann-uwe.de + * Copyright (C) 2010 Keith Hui buurin@gmail.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +19,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+#include <arch/io.h> +#include <console/console.h> #include <stdint.h> #include <device/device.h> #include <device/pci.h> @@ -26,7 +29,90 @@ #include "i82371eb.h" #include "i82371eb_smbus.h"
-/* TODO: Needed later? */ +#define AS97127F_BASE 0x290 + +#define AS97127F_ADDR 5 +#define AS97127F_DATA 6 + +static void as97127f_write(u8 addr, u8 data) +{ + outb(addr, AS97127F_BASE+AS97127F_ADDR); + outb(data, AS97127F_BASE+AS97127F_DATA); +} + +static void pwrmgt_init(struct device *dev) +{ + u32 reg; + + /* Sets the base address of power management ports. */ + pci_write_config16(dev, PMBA, PM_IO_BASE | 1); + + /* Set Power Management IO Space Enable bit */ + u8 val = pci_read_config8(dev, PMREGMISC); + pci_write_config8(dev, PMREGMISC, val | 1); + + pci_write_config8(dev, 0x04, 0x03); + /* cnta */ + pci_write_config32(dev, 0x44, 0x20000000); + /* cntb */ + pci_write_config32(dev, 0x48, 0x0100301e); + + /* Set up pcs0# chipselect io decode on + * port 0x0290 */ + pci_write_config32(dev, 0x60, 0x00e70000|AS97127F_BASE); + + /* enable all alarm smi sources */ + as97127f_write(0x43, 0xff); + as97127f_write(0x44, 0x7f); + /* set fan divisor, gpio? */ + as97127f_write(0x47, 0xa0); + /* select 14.318MHz clock. */ + as97127f_write(0x4b, 0x40); + /* set bit 7 */ + as97127f_write(0x4d, 0x95); + + /* set global control: + * bit25 (lid_pol): 1=invert lid polarity + * bit24 (sm_freeze): 1=freeze idle and standby timers + * bit16 (end of smi): 0=disable smi assertion (cleared by hw) + * bits8-15,26: global standby timer inital count 127 * 4minutes + * bit2 (thrm_pol): 1=active low THRM# + * bit0 (smi_en): 1=disable smi generation upon smi event + */ + reg = inl(PM_IO_BASE + 0x28); + reg &= SMI_EN|EOS; /* keep smi state */ + reg |= (1<<25)|(1<<24)|(0xff<<8)|(1<<2); + outl(reg, PM_IO_BASE + 0x28); + + /* set processor control: + * bit12 (stpclk_en): 1=enable stopping of host clk on lvl3 + * bit11 (sleep_en): 1=enable slp# assertion on lvl3 + * bit9 (cc_en): 1=enable clk control with lvl2 and lvl3 regs + */ + outl(0, PM_IO_BASE + 0x10); + + /* Clear status events. */ + outw(0xffff, PM_IO_BASE + PMSTS); + outw(0xffff, PM_IO_BASE + GPSTS); + outw(0xffff, PM_IO_BASE + GLBSTS); + outl(0xffffffff, PM_IO_BASE + DEVSTS); + + int i; + for (i = 0; i < 64; i++) { + if ((i == 0x14) || (i == 0x15)) /* skip plvl2/plvl3 regs */ + continue; + printk(BIOS_SPEW, "pwrmgt_init: pm_io %02x is %02x\n", i, inb(PM_IO_BASE + i)); + } + +#if 0 +#if !defined(CONFIG_HAVE_SMI_HANDLER) + /* Set SCI_EN bit */ + u16 tmp = inw(PM_IO_BASE + 0x04); + outw(tmp|1, PM_IO_BASE + 0x04); +#endif +#endif +} + static const struct smbus_bus_operations lops_smbus_bus = { };
@@ -34,7 +120,7 @@ .read_resources = pci_dev_read_resources, .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources, - .init = 0, + .init = pwrmgt_init, .scan_bus = scan_static_bus, .enable = 0, .ops_pci = 0, /* No subsystem IDs on 82371EB! */ Index: src/mainboard/asus/p2b/Kconfig =================================================================== --- src/mainboard/asus/p2b/Kconfig.orig 2010-11-25 03:18:25.000000000 +0100 +++ src/mainboard/asus/p2b/Kconfig 2010-11-25 03:20:01.000000000 +0100 @@ -2,6 +2,7 @@ ## This file is part of the coreboot project. ## ## Copyright (C) 2009 Uwe Hermann uwe@hermann-uwe.de +## Copyright (C) 2010 Idwer Vollering vidwer@gmail.com ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -28,6 +29,8 @@ select HAVE_PIRQ_TABLE select UDELAY_TSC select BOARD_ROMSIZE_KB_256 + select HAVE_ACPI_TABLES + select HAVE_SMI_HANDLER
config MAINBOARD_DIR string Index: src/mainboard/asus/p2b/devicetree.cb =================================================================== --- src/mainboard/asus/p2b/devicetree.cb.orig 2010-11-25 03:18:26.000000000 +0100 +++ src/mainboard/asus/p2b/devicetree.cb 2010-11-25 03:20:01.000000000 +0100 @@ -39,7 +39,7 @@ end device pnp 3f0.9 on # GPIO 3 end - device pnp 3f0.a on # ACPI + device pnp 3f0.a off # ACPI end end end @@ -50,10 +50,10 @@ register "ide1_enable" = "1" register "ide_legacy_enable" = "1" # Enable UDMA/33 for higher speed if your IDE device(s) support it. - register "ide0_drive0_udma33_enable" = "0" - register "ide0_drive1_udma33_enable" = "0" - register "ide1_drive0_udma33_enable" = "0" - register "ide1_drive1_udma33_enable" = "0" + register "ide0_drive0_udma33_enable" = "1" + register "ide0_drive1_udma33_enable" = "1" + register "ide1_drive0_udma33_enable" = "1" + register "ide1_drive1_udma33_enable" = "1" end end end Index: src/mainboard/asus/p2b/acpi_tables.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/mainboard/asus/p2b/acpi_tables.c 2010-11-25 03:20:01.000000000 +0100 @@ -0,0 +1,118 @@ +/* + * This file is part of the coreboot project. + * + * Written by Stefan Reinauer stepan@openbios.org. + * ACPI FADT, FACS, and DSDT table support added by + * + * Copyright (C) 2004 Stefan Reinauer stepan@openbios.org + * Copyright (C) 2005 Nick Barker nick.barker9@btinternet.com + * Copyright (C) 2007 Rudolf Marek r.marek@assembler.cz + * Copyright (C) 2010 Idwer Vollering vidwer@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Based on src/mainboard/asus/a8v-e_se/acpi_tables.c */ + +#include <console/console.h> +#include <string.h> +#include <arch/acpi.h> +#include <arch/smp/mpspec.h> +#include <device/device.h> +#include <device/pci_ids.h> + +extern const unsigned char AmlCode[]; + +unsigned long acpi_fill_slit(unsigned long current) +{ + // Not implemented + return current; +} + +unsigned long acpi_fill_srat(unsigned long current) +{ + // Not implemented + return current; +} + +unsigned long acpi_fill_mcfg(unsigned long current) +{ + /* chipset doesn't have mmconfig */ + return current; +} + +unsigned long acpi_fill_madt(unsigned long current) +{ + /* mainboard has no ioapic */ + return current; +} + +unsigned long write_acpi_tables(unsigned long start) +{ + unsigned long current; + acpi_rsdp_t *rsdp; + acpi_rsdt_t *rsdt; + acpi_fadt_t *fadt; + acpi_facs_t *facs; + acpi_header_t *dsdt; + + /* Align ACPI tables to 16 byte. */ + start = (start + 0x0f) & -0x10; + current = start; + + printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx...\n", start); + + /* We need at least an RSDP and an RSDT table. */ + rsdp = (acpi_rsdp_t *) current; + current += sizeof(acpi_rsdp_t); + rsdt = (acpi_rsdt_t *) current; + current += sizeof(acpi_rsdt_t); + + /* Clear all table memory. */ + memset((void *) start, 0, current - start); + + acpi_write_rsdp(rsdp, rsdt, NULL); + acpi_write_rsdt(rsdt); + + /* We explicitly add these tables later on: */ + printk(BIOS_DEBUG, "ACPI: * FACS\n"); + + /* we should align FACS to 64B as per ACPI specs */ + current = ALIGN(current, 64); + facs = (acpi_facs_t *) current; + current += sizeof(acpi_facs_t); + acpi_create_facs(facs); + + dsdt = (acpi_header_t *)current; + memcpy(dsdt, &AmlCode, sizeof(acpi_header_t)); + current += dsdt->length; + memcpy(dsdt, &AmlCode, dsdt->length); + /* Don't trust iasl to get checksum right. */ + dsdt->checksum = 0; /* needs to be set to 0 first (part of csum) */ + dsdt->checksum = acpi_checksum((u8*)dsdt, dsdt->length); + printk(BIOS_DEBUG, "ACPI: * DSDT @ %p Length %x\n", dsdt, + dsdt->length); + printk(BIOS_DEBUG, "ACPI: * FADT\n"); + + fadt = (acpi_fadt_t *) current; + current += sizeof(acpi_fadt_t); + + acpi_create_fadt(fadt, facs, dsdt); + acpi_add_table(rsdp, fadt); + + /* no ioapic, so no madt */ + + printk(BIOS_INFO, "ACPI: done.\n"); + return current; +} Index: src/mainboard/asus/p2b/dsdt.asl =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/mainboard/asus/p2b/dsdt.asl 2010-11-25 03:20:01.000000000 +0100 @@ -0,0 +1,298 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Nick Barker Nick.Barker9@btinternet.com + * Copyright (C) 2007 Rudolf Marek r.marek@assembler.cz + * Copyright (C) 2010 Idwer Vollering vidwer@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Based on dsdt.asl from src/mainboard/asus/a8v-e_se */ + +/* + * ISA portions taken from QEMU acpi-dsdt.dsl. + */ + +DefinitionBlock ("DSDT.aml", "DSDT", 1, "CORE ", "COREBOOT", 1) +{ + /* Define the main processor.*/ + Scope (_PR) + { + /* Looks like the P_CNT field can't be a method or name + * and has to be hardcoded to 0xe410 or generated in SSDT */ + Processor (CPU0, 0x01, 0xe410, 0x06) {} + } + + /* For now only define 2 power states: + * - S0 which is fully on + * - S5 which is soft off + * Any others would involve declaring the wake up methods. + */ + + /* intel i82371eb (piix4e) datasheet, section 7.2.3, page 142 */ + /* + 000b / 0x0: soft off/suspend to disk (soff/std) s5 + 001b / 0x1: suspend to ram (str) s3 + 010b / 0x2: powered on suspend, context lost (poscl) s1 + 011b / 0x3: powered on suspend, cpu context lost (posccl) s2 + 100b / 0x4: powered on suspend, context maintained (pos) s4 + 101b / 0x5: working (clock control) s0 + 110b / 0x6: reserved + 111b / 0x7: reserved + */ + Name (_S0, Package () { 0x05, 0x05, 0x00, 0x00 }) + Name (_S5, Package () { 0x00, 0x00, 0x00, 0x00 }) + + /* Root of the bus hierarchy */ + Scope (_SB) + { + /* Top PCI device */ + Device (PCI0) + { + Name (_HID, EisaId ("PNP0A03")) + Name (_ADR, 0x00) + Name (_UID, 0x00) + Name (_BBN, 0x00) + + /* PCI Routing Table */ + Name (_PRT, Package () { + Package (0x04) { 0x0001FFFF, 0, LNKA, 0 }, + Package (0x04) { 0x0001FFFF, 1, LNKB, 0 }, + Package (0x04) { 0x0001FFFF, 2, LNKC, 0 }, + Package (0x04) { 0x0001FFFF, 3, LNKD, 0 }, + + Package (0x04) { 0x0004FFFF, 0, LNKA, 0 }, + Package (0x04) { 0x0004FFFF, 1, LNKB, 0 }, + Package (0x04) { 0x0004FFFF, 2, LNKC, 0 }, + Package (0x04) { 0x0004FFFF, 3, LNKD, 0 }, + + Package (0x04) { 0x0009FFFF, 0, LNKD, 0 }, + Package (0x04) { 0x0009FFFF, 1, LNKA, 0 }, + Package (0x04) { 0x0009FFFF, 2, LNKB, 0 }, + Package (0x04) { 0x0009FFFF, 3, LNKC, 0 }, + + Package (0x04) { 0x000AFFFF, 0, LNKC, 0 }, + Package (0x04) { 0x000AFFFF, 1, LNKD, 0 }, + Package (0x04) { 0x000AFFFF, 2, LNKA, 0 }, + Package (0x04) { 0x000AFFFF, 3, LNKB, 0 }, + + Package (0x04) { 0x000BFFFF, 0, LNKB, 0 }, + Package (0x04) { 0x000BFFFF, 1, LNKC, 0 }, + Package (0x04) { 0x000BFFFF, 2, LNKD, 0 }, + Package (0x04) { 0x000BFFFF, 3, LNKA, 0 }, + + Package (0x04) { 0x000CFFFF, 0, LNKA, 0 }, + Package (0x04) { 0x000CFFFF, 1, LNKB, 0 }, + Package (0x04) { 0x000CFFFF, 2, LNKC, 0 }, + Package (0x04) { 0x000CFFFF, 3, LNKD, 0 }, + + }) + + /* Northbridge */ + Device (NB) + { + Name(_ADR, 0x00000000) + OperationRegion(PCIC, PCI_Config, 0x00, 0x100) + } + + // Intel LPC Bus Device - 0:4.0 + Device (LPCB) + { + Name(_ADR, 0x00040000) + + OperationRegion(PCIC, PCI_Config, 0x00, 0x100) + + /* PS/2 keyboard (seems to be important for WinXP install) */ + Device (KBD) + { + Name (_HID, EisaId ("PNP0303")) + Method (_STA, 0, NotSerialized) + { + Return (0x0f) + } + Method (_CRS, 0, NotSerialized) + { + Name (TMP, ResourceTemplate () { + IO (Decode16, 0x0060, 0x0060, 0x01, 0x01) + IO (Decode16, 0x0064, 0x0064, 0x01, 0x01) + IRQNoFlags () {1} + }) + Return (TMP) + } + } + + /* PS/2 mouse */ + Device (MOU) + { + Name (_HID, EisaId ("PNP0F13")) + Method (_STA, 0, NotSerialized) + { + Return (0x0f) + } + Method (_CRS, 0, NotSerialized) + { + Name (TMP, ResourceTemplate () { + IRQNoFlags () {12} + }) + Return (TMP) + } + } + + /* PS/2 floppy controller */ + Device (FDC0) + { + Name (_HID, EisaId ("PNP0700")) + Method (_STA, 0, NotSerialized) + { + Return (0x0f) + } + Method (_CRS, 0, NotSerialized) + { + Name (BUF0, ResourceTemplate () { + IO (Decode16, 0x03F2, 0x03F2, 0x00, 0x04) + IO (Decode16, 0x03F7, 0x03F7, 0x00, 0x01) + IRQNoFlags () {6} + DMA (Compatibility, NotBusMaster, Transfer8) {2} + }) + Return (BUF0) + } + } + } + + Field (NB.PCIC, AnyAcc, NoLock, Preserve) + { + Offset (0x67), // DRB7 + DRB7, 8, + } + + Method(TOM1, 0) { + /* Multiply by 8MB to get TOM */ + Return(ShiftLeft(DRB7, 23)) + } + + Method(_CRS, 0) { + Name(TMP, ResourceTemplate() { + WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode, + 0x0000, // Granularity + 0x0000, // Range Minimum + 0x00FF, // Range Maximum + 0x0000, // Translation Offset + 0x0100, // Length + ,, + ) + IO(Decode16, 0x0CF8, 0x0CF8, 1, 8) + + WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, + 0x0000, /* address granularity */ + 0x0000, /* range minimum */ + 0x0CF7, /* range maximum */ + 0x0000, /* translation */ + 0x0CF8 /* length */ + ) + + WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, + 0x0000, /* address granularity */ + 0x0D00, /* range minimum */ + 0xFFFF, /* range maximum */ + 0x0000, /* translation */ + 0xF300 /* length */ + ) + + /* memory space for PCI BARs below 4GB */ + Memory32Fixed(ReadOnly, 0x00000000, 0x00000000, MMIO) + }) + CreateDWordField(TMP, MMIO._BAS, MM1B) + CreateDWordField(TMP, MMIO._LEN, MM1L) + /* + * Declare memory between TOM1 and 4GB as available + * for PCI MMIO. + * + * Use ShiftLeft to avoid 64bit constant (for XP). + * This will work even if the OS does 32bit arithmetic, as + * 32bit (0x00000000 - TOM1) will wrap and give the same + * result as 64bit (0x100000000 - TOM1). + */ + Store(TOM1, MM1B) + ShiftLeft(0x10000000, 4, Local0) + Subtract(Local0, TOM1, Local0) + Store(Local0, MM1L) + + Return(TMP) + } + } + + Field (PCI0.LPCB.PCIC, AnyAcc, NoLock, Preserve) + { + Offset (0x60), // Interrupt Routing Registers + PRTA, 8, + PRTB, 8, + PRTC, 8, + PRTD, 8, + } + + Name(IRQB, ResourceTemplate(){ + IRQ(Level,ActiveLow,Shared){15} + }) + + Name(IRQP, ResourceTemplate(){ + IRQ(Level,ActiveLow,Exclusive){3, 4, 5, 6, 7, 10, 11, 12} + }) + + /* adapted from ma78gm/dsdt.asl */ +#define PCI_INTX_DEV(intx, pinx, uid) \ + Device(intx) { \ + Name(_HID, EISAID("PNP0C0F")) \ + Name(_UID, uid) \ + \ + Method(_STA, 0) { \ + If (And(pinx, 0x80)) { \ + Return(0x09) \ + } \ + Return(0x0B) \ + } \ + \ + Method(_DIS ,0) { \ + Store(0x80, pinx) \ + } \ + \ + Method(_PRS ,0) { \ + Return(IRQP) \ + } \ + \ + Method(_CRS ,0) { \ + CreateWordField(IRQB, 1, IRQN) \ + ShiftLeft(1, And(pinx, 0x0f), IRQN) \ + Return(IRQB) \ + } \ + \ + Method(_SRS, 1) { \ + CreateWordField(ARG0, 1, IRQM) \ + \ + /* Use lowest available IRQ */ \ + FindSetRightBit(IRQM, Local0) \ + if (Local0) { \ + Decrement(Local0) \ + } \ + Store(Local0, pinx) \ + } \ + } \ + +PCI_INTX_DEV(LNKA, PRTA, 1) +PCI_INTX_DEV(LNKB, PRTB, 2) +PCI_INTX_DEV(LNKC, PRTC, 3) +PCI_INTX_DEV(LNKD, PRTD, 4) + } + +} Index: src/northbridge/intel/i440bx/northbridge.c =================================================================== --- src/northbridge/intel/i440bx/northbridge.c.orig 2010-11-25 03:18:26.000000000 +0100 +++ src/northbridge/intel/i440bx/northbridge.c 2010-11-25 03:20:01.000000000 +0100 @@ -1,3 +1,23 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Uwe Hermann uwe@hermann-uwe.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + #include <console/console.h> #include <arch/io.h> #include <stdint.h> @@ -15,7 +35,12 @@
static void northbridge_init(device_t dev) { + u8 reg8; printk(BIOS_SPEW, "Northbridge Init\n"); + /* set bit 6 of the Power Management Control Register + * to enable PM2 register at io 0x22 */ + reg8 = pci_read_config16(dev, 0x7a); + pci_write_config8(dev, 0x7a, reg8 | 0x40); }
static struct device_operations northbridge_operations = { Index: src/southbridge/intel/i82371eb/i82371eb_isa.c =================================================================== --- src/southbridge/intel/i82371eb/i82371eb_isa.c.orig 2010-11-25 03:18:26.000000000 +0100 +++ src/southbridge/intel/i82371eb/i82371eb_isa.c 2010-11-25 03:20:01.000000000 +0100 @@ -72,7 +72,9 @@ */ reg32 = pci_read_config32(dev, GENCFG); reg32 |= ISA; /* Select ISA, not EIO. */ - pci_write_config16(dev, GENCFG, reg32); + reg32 |= (1<<15); /* GPI11 instead of SMBALERT# */ + reg32 |= (1<<19); /* GPO18 instead of PCI_STP# */ + pci_write_config32(dev, GENCFG, reg32);
/* Initialize ISA DMA. */ isa_dma_init(); Index: src/cpu/x86/smm/smmrelocate.S =================================================================== --- src/cpu/x86/smm/smmrelocate.S.orig 2010-11-25 03:18:25.000000000 +0100 +++ src/cpu/x86/smm/smmrelocate.S 2010-11-25 03:26:20.000000000 +0100 @@ -30,6 +30,8 @@ #include "../../../southbridge/intel/i82801gx/i82801gx.h" #elif defined(CONFIG_SOUTHBRIDGE_INTEL_I82801DX) #include "../../../southbridge/intel/i82801dx/i82801dx.h" +#elif defined(CONFIG_SOUTHBRIDGE_INTEL_I82371EB) +#include "../../../southbridge/intel/i82371eb/i82371eb.h" #else #error "Southbridge needs SMM handler support." #endif @@ -93,6 +95,7 @@
smm_relocation_start: /* Check revision to see if AMD64 style SMM_BASE + * Intel PIII Tualatin?: 0x30002 * Intel Core Solo/Duo: 0x30007 * Intel Core2 Solo/Duo: 0x30100 * AMD64: 0x3XX64 @@ -116,6 +119,12 @@ addr32 movl (%esi), %ecx shr $24, %ecx
+ /* Uninitalized LAPIC? */ + cmp $0xff, %cl + jne 1f + mov $0, %cl /* assume cpu 0 */ +1: + /* calculate offset by multiplying the * apic ID by 1024 (0x400) */ @@ -130,6 +139,7 @@
/* The next section of code is potentially southbridge specific */
+#if 0 /* Clear SMI status */ movw $(DEFAULT_PMBASE + 0x34), %dx inw %dx, %ax @@ -145,6 +155,23 @@ inl %dx, %eax orl $(1 << 1), %eax outl %eax, %dx +#else + /* Clear SMI status */ + movw $(DEFAULT_PMBASE + 0x18), %dx + inw %dx, %ax + outw %ax, %dx + + /* Clear PM1 status */ + movw $(DEFAULT_PMBASE + 0x00), %dx + inw %dx, %ax + outw %ax, %dx + + /* Set EOS bit so other SMIs can occur */ + movw $(DEFAULT_PMBASE + 0x28), %dx + inl %dx, %eax + orl $(1 << 16), %eax + outl %eax, %dx +#endif
/* End of southbridge specific section. */
Index: src/southbridge/intel/i82371eb/i82371eb_smi.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/southbridge/intel/i82371eb/i82371eb_smi.c 2010-11-25 03:20:01.000000000 +0100 @@ -0,0 +1,206 @@ +/* + * This file is part of the coreboot project. + * + * Based on src/southbridge/intel/i82801dx/i82801dx_smi.c + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2010 Idwer Vollering vidwer@gmail.com + * Copyright (C) 2010 Tobias Diedrich ranma+coreboot@tdiedrich.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <device/device.h> +#include <device/pci.h> +#include <console/console.h> +#include <arch/io.h> +#include <cpu/cpu.h> +#include <cpu/x86/cache.h> +#include <cpu/x86/smm.h> +#include <string.h> + +#include "i82371eb.h" + +extern unsigned char _binary_smm_start; +extern unsigned char _binary_smm_size; + +/* I440BX */ +#define SMRAM 0x72 +#define D_OPEN (1 << 6) +#define D_CLS (1 << 5) +#define D_LCK (1 << 4) +#define G_SMRAME (1 << 3) +#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0)) + +/* While we read PMBASE dynamically in case it changed, let's + * initialize it with a sane value + */ +static u16 pmbase = PM_IO_BASE; + +/** + * @brief Set the EOS bit + */ +static void smi_set_eos(void) +{ + u32 reg; + + reg = inl(pmbase + GLBCTL); + reg |= EOS; + outl(reg, pmbase + GLBCTL); +} + +extern uint8_t smm_relocation_start, smm_relocation_end; + +static void smm_relocate(void) +{ + u32 glb_ctl; + u32 reg; + device_t acpi_dev = dev_find_slot(0, PCI_DEVFN(4, 3)); + + printk(BIOS_DEBUG, "Initializing SMM handler..."); + + pmbase = pci_read_config16(acpi_dev, PMBA) & 0xfffc; + if (pmbase == 0) { + /* Sets the base address of power management ports. */ + pci_write_config16(acpi_dev, PMBA, PM_IO_BASE | 1); + pmbase = PM_IO_BASE; + } + printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", pmbase); + + glb_ctl = inl(pmbase + GLBCTL); + if (glb_ctl & SMI_EN) { + printk(BIOS_INFO, "SMI# handler already enabled?\n"); + return; + } + + /* copy the SMM relocation code */ + memcpy((void *)0x38000, &smm_relocation_start, + &smm_relocation_end - &smm_relocation_start); + + /* Enable SMI generation: + * - on APMC writes (io 0xb2) + * - on writes to GBL_RLS (bios commands) + * - on EXTSMI# signal + * - on GSTBY and BM_TRP + */ + + reg = BIOS_EN|EXTSMI_EN|GSTBY_EN|BM_TRP_EN; +#if 0 + reg |= LEGACY_USB_EN; +#endif + outl(reg, pmbase + GLBEN); + + /* SMI on write to APMC */ + reg = pci_read_config32(acpi_dev, DEVACTB); + reg |= APMC_EN; + pci_write_config32(acpi_dev, DEVACTB, reg); + + /* SMI on write to pmbase+PMCNTRL */ + reg = 0x00110000 | (pmbase + PMCNTRL); + pci_write_config32(acpi_dev, DEVRESE, reg); + + reg = inl(pmbase + DEVCTL); + reg |= TRP_EN_DEV12; + outl(reg, pmbase + DEVCTL); + + /* SMI on power button */ + reg = inw(pmbase + PMEN); + reg |= PWRBTN_EN; + outw(reg, pmbase + PMEN); + + /* SMI on THRM# signal */ + reg = THRM_EN; + outw(reg, pmbase + GPEN); + + /* Clear status events. */ + outw(0xffff, pmbase + PMSTS); + outw(0xffff, pmbase + GPSTS); + outw(0xffff, pmbase + GLBSTS); + outl(0xffffffff, pmbase + DEVSTS); + + /* The following need to be on for SMIs to happen */ + glb_ctl |= EOS | SMI_EN; + outl(glb_ctl, pmbase + GLBCTL); + + /** + * There are several methods of raising a controlled SMI# via + * software, among them: + * - Writes to io 0xb2 (APMC) + * - Writes to the Local Apic ICR with Delivery mode SMI. + * + * Using the local apic is a bit more tricky. According to + * AMD Family 11 Processor BKDG no destination shorthand must be + * used. + * The whole SMM initialization is quite a bit hardware specific, so + * I'm not too worried about the better of the methods at the moment + */ + + /* raise an SMI interrupt */ + printk(BIOS_SPEW, " ... raise SMI#\n"); + outb(0x00, APM_CNT); +} + +static void smm_install(void) +{ + device_t dev = dev_find_slot(0, PCI_DEVFN(0, 0)); + /* enable the SMM memory window */ + pci_write_config8(dev, SMRAM, D_OPEN | G_SMRAME | C_BASE_SEG); + + /* copy the real SMM handler */ + memcpy((void *)0xa0000, &_binary_smm_start, (size_t)&_binary_smm_size); + wbinvd(); + + /* close the SMM memory window and enable normal SMM */ + pci_write_config8(dev, SMRAM, G_SMRAME | C_BASE_SEG); +} + +void smm_init(void) +{ + printk(BIOS_SPEW, "%s\n", __func__); + + /* Put SMM code to 0xa0000 */ + smm_install(); + + /* Put relocation code to 0x38000 and relocate SMBASE */ + smm_relocate(); + + /* We're done. Make sure SMIs can happen! */ + smi_set_eos(); + + printk(BIOS_SPEW, "%s done\n", __func__); +} + +void smm_lock(void) +{ + /* LOCK the SMM memory window and enable normal SMM. + * After running this function, only a full reset can + * make the SMM registers writable again. + */ + printk(BIOS_DEBUG, "Locking SMM.\n"); + pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM, + D_LCK | G_SMRAME | C_BASE_SEG); +} + +void smm_setup_structures(void *gnvs, void *tcg, void *smi1) +{ + /* The GDT or coreboot table is going to live here. But a long time + * after we relocated the GNVS, so this is not troublesome. + */ + *(u32 *)0x500 = (u32)gnvs; + *(u32 *)0x504 = (u32)tcg; + *(u32 *)0x508 = (u32)smi1; + /* raise SMI to notify the SMM handler */ + outb(0xea, APM_CNT); +} Index: src/southbridge/intel/i82371eb/i82371eb_smihandler.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/southbridge/intel/i82371eb/i82371eb_smihandler.c 2010-11-25 03:38:18.000000000 +0100 @@ -0,0 +1,380 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2010 Idwer Vollering vidwer@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <types.h> +#include <arch/io.h> +#include <arch/romcc_io.h> +#include <console/console.h> +#include <cpu/x86/cache.h> +#include <cpu/x86/smm.h> +#include <device/pci_def.h> + +#include "i82371eb.h" + + +/* While we read PMBASE dynamically in case it changed, let's + * initialize it with a sane value + */ +u16 pmbase = PM_IO_BASE; +u8 smm_initialized = 0; + +unsigned char *mbi = NULL; +u32 mbi_len; +u8 mbi_initialized = 0; + +void *tcg = (void *)0x0; +void *smi1 = (void *)0x0; + +int southbridge_io_trap_handler(int smif) +{ + switch (smif) { + case 0x32: + printk(BIOS_DEBUG, "OS Init\n"); + return 1; /* IO trap handled */ + } + + /* Not handled */ + return 0; +} + +void southbridge_smi_set_eos(void) +{ + u32 reg; + + reg = inl(pmbase + GLBCTL); + reg |= EOS; + outl(reg, pmbase + GLBCTL); +} + + +//static void busmaster_disable_on_bus(int bus) +//{ + // Not implemented +//} + +//static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *state_save) +//{ + // Not implemented +//} + +//static void southbridge_smi_apmc(unsigned int node, smm_state_save_area_t *state_save) +//{ + // Not implemented +//} + +//static void southbridge_smi_pm1(unsigned int node, smm_state_save_area_t *state_save) +//{ + // Not implemented +// u16 pm1_sts; + +// pm1_sts = reset_pm1_status(); +// dump_pm1_status(pm1_sts); +//} + +//static void southbridge_smi_gpe0(unsigned int node, smm_state_save_area_t *state_save) +//{ + // Not implemented +// u32 gpe0_sts; + +// gpe0_sts = reset_gpe0_status(); +// dump_gpe0_status(gpe0_sts); +//} + +//static void southbridge_smi_gpi(unsigned int node, smm_state_save_area_t *state_save) +//{ + // Not implemented +//} + +//static void southbridge_smi_mc(unsigned int node, smm_state_save_area_t *state_save) +//{ + // Not implemented +//} + +//static void southbridge_smi_tco(unsigned int node, smm_state_save_area_t *state_save) +//{ + // Not implemented +// u32 tco_sts; + +// tco_sts = reset_tco_status(); + +// if (!tco_sts) { +// dump_tco_status(tco_sts); +// } +//} + +//static void southbridge_smi_periodic(unsigned int node, smm_state_save_area_t *state_save) +//{ + // Not implemented +//} + +//static void southbridge_smi_monitor(unsigned int node, smm_state_save_area_t *state_save) +//{ + // Not implemented +//} + +/** + * @brief read and clear PMSTS + * @return PMSTS register + */ +static u16 reset_pm1_status(void) +{ + u16 reg16; + + reg16 = inw(pmbase + PMSTS); + /* set status bits are cleared by writing 1 to them */ + outw(reg16, pmbase + PMSTS); + + return reg16; +} + +static void dump_pm1_status(u16 pm1_sts) +{ + printk(BIOS_DEBUG, "PMSTS: "); + if (pm1_sts & (1 << 15)) printk(BIOS_DEBUG, "RSM_STS "); + if (pm1_sts & (1 << 11)) printk(BIOS_DEBUG, "PRBTNOR "); + if (pm1_sts & (1 << 10)) printk(BIOS_DEBUG, "RTC "); + if (pm1_sts & (1 << 8)) printk(BIOS_DEBUG, "PWRBTN "); + if (pm1_sts & (1 << 5)) printk(BIOS_DEBUG, "GBL "); + if (pm1_sts & (1 << 4)) printk(BIOS_DEBUG, "BM "); + if (pm1_sts & (1 << 0)) printk(BIOS_DEBUG, "TMROF "); + printk(BIOS_DEBUG, "\n"); +} + +/** + * @brief read and clear GPSTS + * @return GPSTS register + */ +static u16 reset_gp_status(void) +{ + u16 reg; + + reg = inw(pmbase + GPSTS); + /* set status bits are cleared by writing 1 to them */ + outw(reg, pmbase + GPSTS); + + return reg; +} + +static void dump_gp_status(u16 gp_sts) +{ + printk(BIOS_DEBUG, "GPSTS: "); + if (gp_sts & (1 << 11)) printk(BIOS_DEBUG, "LID "); + if (gp_sts & (1 << 10)) printk(BIOS_DEBUG, "RI "); + if (gp_sts & (1 << 9)) printk(BIOS_DEBUG, "GPI "); + if (gp_sts & (1 << 8)) printk(BIOS_DEBUG, "USB "); + if (gp_sts & (1 << 7)) printk(BIOS_DEBUG, "THRMOR "); + if (gp_sts & (1 << 0)) printk(BIOS_DEBUG, "THRM "); + printk(BIOS_DEBUG, "\n"); +} + + +/** + * @brief read and clear GLBSTS + * @return GLBSTS register + */ +static u16 reset_glb_status(void) +{ + u16 reg; + + reg = inw(pmbase + GLBSTS); + /* set status bits are cleared by writing 1 to them */ + outw(reg, pmbase + GLBSTS); + + return reg; +} + +static void dump_glb_status(u16 glb_sts) +{ + printk(BIOS_DEBUG, "GLBSTS: "); + if (glb_sts & (1 << 11)) printk(BIOS_DEBUG, "IRQ_RSM "); + if (glb_sts & (1 << 10)) printk(BIOS_DEBUG, "EXTSMI "); + if (glb_sts & (1 << 9)) printk(BIOS_DEBUG, "GSTBY "); + if (glb_sts & (1 << 8)) printk(BIOS_DEBUG, "SMB_WAK "); + if (glb_sts & (1 << 7)) printk(BIOS_DEBUG, "GP "); + if (glb_sts & (1 << 6)) printk(BIOS_DEBUG, "PM1 "); + if (glb_sts & (1 << 5)) printk(BIOS_DEBUG, "APM "); + if (glb_sts & (1 << 4)) printk(BIOS_DEBUG, "DEV "); + if (glb_sts & (1 << 2)) printk(BIOS_DEBUG, "P4MA "); + if (glb_sts & (1 << 1)) printk(BIOS_DEBUG, "LEGACY_USB "); + if (glb_sts & (1 << 0)) printk(BIOS_DEBUG, "BIOS "); + printk(BIOS_DEBUG, "\n"); +} + + +/** + * @brief read and clear DEVSTS + * @return DEVSTS register + */ +static u16 reset_dev_status(void) +{ + u32 reg; + + reg = inl(pmbase + DEVSTS); + /* set status bits are cleared by writing 1 to them */ + outl(reg, pmbase + DEVSTS); + + return reg; +} + +static void dump_dev_status(u32 dev_sts) +{ + int i; + printk(BIOS_DEBUG, "DEV_STS (%08x): ", dev_sts); + for (i=29; i<= 16; i--) { + if (dev_sts & (1 << i)) printk(BIOS_DEBUG, "TRP%d ", (i-16)); + } + for (i=11; i<= 0; i--) { + if (dev_sts & (1 << i)) printk(BIOS_DEBUG, "IDLE%d ", i); + } + printk(BIOS_DEBUG, "\n"); +} + +static void southbridge_smi_gp(unsigned int node, smm_state_save_area_t *state_save) +{ + u32 reg = reset_gp_status(); + printk(BIOS_DEBUG, "%s: %08x\n", __func__, reg); + dump_gp_status(reg); +} + +static void southbridge_smi_pm1(unsigned int node, smm_state_save_area_t *state_save) +{ + u32 reg = reset_pm1_status(); + printk(BIOS_DEBUG, "%s: %08x\n", __func__, reg); + dump_pm1_status(reg); +} + +static void southbridge_smi_dev(unsigned int node, smm_state_save_area_t *state_save) +{ + u32 reg = reset_dev_status(); + printk(BIOS_DEBUG, "%s: %08x\n", __func__, reg); + dump_dev_status(reg); +} + +static void southbridge_smi_apmc(unsigned int node, smm_state_save_area_t *state_save) +{ + u32 pmctrl; + u8 reg8; + + /* Emulate B2 register as the FADT / Linux expects it */ + + reg8 = inb(APM_CNT); + switch (reg8) { + case CST_CONTROL: + /* Calling this function seems to cause + * some kind of race condition in Linux + * and causes a kernel oops + */ + printk(BIOS_DEBUG, "C-state control\n"); + break; + case PST_CONTROL: + /* Calling this function seems to cause + * some kind of race condition in Linux + * and causes a kernel oops + */ + printk(BIOS_DEBUG, "P-state control\n"); + break; + case ACPI_DISABLE: + pmctrl = inl(pmbase + PMCNTRL); + pmctrl &= ~SCI_EN; + outl(pmctrl, pmbase + PMCNTRL); + printk(BIOS_DEBUG, "SMI#: ACPI disabled.\n"); + break; + case ACPI_ENABLE: + pmctrl = inl(pmbase + PMCNTRL); + pmctrl |= SCI_EN; + outl(pmctrl, pmbase + PMCNTRL); + printk(BIOS_DEBUG, "SMI#: ACPI enabled.\n"); + break; + case GNVS_UPDATE: + if (smm_initialized) { + printk(BIOS_DEBUG, "SMI#: SMM structures already initialized!\n"); + return; + } + tcg = *(void **)0x504; + smi1 = *(void **)0x508; + smm_initialized = 1; + printk(BIOS_DEBUG, "SMI#: Setting up structures to %p, %p\n", tcg, smi1); + break; + case MBI_UPDATE: // FIXME + if (mbi_initialized) { + printk(BIOS_DEBUG, "SMI#: mbi already registered!\n"); + return; + } + mbi = *(void **)0x500; + mbi_len = *(u32 *)0x504; + mbi_initialized = 1; + printk(BIOS_DEBUG, "SMI#: Registered MBI at %p (%d bytes)\n", mbi, mbi_len); + break; + + default: + printk(BIOS_DEBUG, "SMI#: Unknown function APM_CNT=%02x\n", reg8); + } +} + +typedef void (*smi_handler_t)(unsigned int node, + smm_state_save_area_t *state_save); + +smi_handler_t southbridge_smi[16] = { + NULL, // [0] BIOS_STS + NULL, // [1] LEGACY_USB_STS + NULL, // [2] P4MA_STS + NULL, // [3] reserved + southbridge_smi_dev, // [4] DEV_STS + southbridge_smi_apmc, // [5] APM_STS + southbridge_smi_pm1, // [6] PM1_STS + southbridge_smi_gp, // [7] GP_STS + NULL, // [8] GSTBY_STS + NULL, // [9] reserved + NULL, // [10] EXTSMI_STS + NULL, // [11] IRQ_RSM_STS + NULL, // [12] reserved + NULL, // [13] reserved + NULL, // [14] reserved + NULL, // [15] reserved +}; + +void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save) +{ + int i, dump=0; + u16 smi_sts; + + printk(BIOS_DEBUG, "%s\n", __func__); + + /* Update global variable pmbase */ + pmbase = pci_read_config16(PCI_DEV(0, 4, 3), PMBA) & 0xfffc; + + smi_sts = reset_glb_status(); + + /* Call SMI sub handler for each of the status bits */ + for (i = 0; i < 12; i++) { + if (smi_sts & (1 << i)) { + if (southbridge_smi[i]) + southbridge_smi[i](node, state_save); + else { + printk(BIOS_DEBUG, "SMI_STS[%d] occured, but no " + "handler available.\n", i); + dump=1; + } + } + } + + if (dump) + dump_glb_status(smi_sts); +} Index: src/cpu/x86/smm/smihandler.c =================================================================== --- src/cpu/x86/smm/smihandler.c.orig 2010-11-25 03:19:18.000000000 +0100 +++ src/cpu/x86/smm/smihandler.c 2010-11-25 03:20:01.000000000 +0100 @@ -73,8 +73,8 @@ if (southbridge_io_trap_handler(smif)) return;
- if (mainboard_io_trap_handler(smif)) - return; +// if (mainboard_io_trap_handler(smif)) +// return;
printk(BIOS_DEBUG, "Unknown function\n"); } Index: src/cpu/x86/smm/smmhandler.S =================================================================== --- src/cpu/x86/smm/smmhandler.S.orig 2010-11-25 03:19:18.000000000 +0100 +++ src/cpu/x86/smm/smmhandler.S 2010-11-25 03:26:11.000000000 +0100 @@ -102,6 +102,12 @@ movl (%esi), %ecx shr $24, %ecx
+ /* Uninitalized LAPIC? */ + cmp $0xff, %cl + jne 1f + mov $0, %cl /* assume cpu 0 */ +1: + /* calculate stack offset by multiplying the APIC ID * by 1024 (0x400), and save that offset in ebp. */
On 4/15/10 6:43 PM, Keith Hui wrote:
On Wed, Apr 14, 2010 at 9:20 PM, Idwer Vollering vidwer@gmail.com wrote:
This is also RFC and is not signed off at this point, but comments are welcome.
When is it okay to sign off :) probably when the major functions like standby and soft poweroff/reset work like they should and the ACPI tables are created. Oh, and irq routing..
Signed-off does NOT mean that the code is ready, or should be included, by any means.
Signed-off just means that the code is legally not problematic. As long as the code is not signed off, it might cause a legal issue for anyone working on it with you, in some weird country somewhere in the internet.
So, please, folks, if you think your code should end up on the mailing list: Do sign if off or consider not sending it.
http://www.coreboot.org/Development_Guidelines#Sign-off_Procedure
Thanks, Stefan
On Thu, 15 Apr 2010 23:18:32 +0200, Stefan Reinauer stepan@coresystems.de wrote:
On 4/15/10 6:43 PM, Keith Hui wrote:
On Wed, Apr 14, 2010 at 9:20 PM, Idwer Vollering vidwer@gmail.com
wrote:
This is also RFC and is not signed off at this point, but comments are welcome.
When is it okay to sign off :) probably when the major functions like standby and soft poweroff/reset work like they should and the ACPI
tables
are created. Oh, and irq routing..
Signed-off does NOT mean that the code is ready, or should be included, by any means.
Signed-off just means that the code is legally not problematic. As long as the code is not signed off, it might cause a legal issue for anyone working on it with you, in some weird country somewhere in the internet.
So, please, folks, if you think your code should end up on the mailing list: Do sign if off or consider not sending it.
http://www.coreboot.org/Development_Guidelines#Sign-off_Procedure
Hmm, So if your code is not quite complete (or not quite ready for commit) but you think other interested developers might be able to offer help or suggestions or reviews what do you do then?
On 4/15/10 11:51 PM, Joseph Smith wrote:
Hmm, So if your code is not quite complete (or not quite ready for commit) but you think other interested developers might be able to offer help or suggestions or reviews what do you do then?
Sign it off
On Thu, 15 Apr 2010 23:59:38 +0200, Stefan Reinauer stepan@coresystems.de wrote:
On 4/15/10 11:51 PM, Joseph Smith wrote:
Hmm, So if your code is not quite complete (or not quite ready for
commit)
but you think other interested developers might be able to offer help or suggestions or reviews what do you do then?
Sign it off
Ok thanks for clarifying. So it is ok to sign off, but just notate that it is not ready for commit yet?
On 16.04.2010 00:11, Joseph Smith wrote:
On Thu, 15 Apr 2010 23:59:38 +0200, Stefan Reinauer stepan@coresystems.de wrote:
On 4/15/10 11:51 PM, Joseph Smith wrote:
Hmm, So if your code is not quite complete (or not quite ready for commit) but you think other interested developers might be able to offer help or suggestions or reviews what do you do then?
Sign it off
Ok thanks for clarifying. So it is ok to sign off, but just notate that it is not ready for commit yet?
Absolutely YES!
Regards, Carl-Daniel