1----------P00260027-------------------------- 2PORT 0026-0027 - INTEL 82347 POWER MANAGEMENT PERIPHERAL 3SeeAlso: PORT 0178h-0179h 4 50026 -W index for data port (see #P0377) 60027 RW power management data 7 8(Table P0377) 9Values for Intel 82437 Power Management Peripheral register index: 10 C0h suspend/wakeup status, system state 11 C1h power supply and activity status, general-purpose output/control 12 C2h control bits 13 C3h activity mask 14 C4h NMI mask 15 C5h I/O range for activity monitor 16 C6h power output control bits, ON state 17 C7h power output control bits, Doze state 18 C8h power output control bits, Sleep state 19 C9h power output control bits, Suspend state 20 CAh power control bits polarity control 21 CBh current output bits 22 CCh Doze timeout 23 CDh Sleep timeout 24 CEh Suspend timeout 25 CFh LCD display power timeout 26 D0h EL display power timeout
1----------P01780179-------------------------- 2PORT 0178-0179 - Power Management 3SeeAlso: PORT 0026h,#P0377 4 50178 -W index selection for data port 60179 RW power management data
So perhaps a Intel 82437 mapped at both addresses?
Input pins:
LBAT: low battery
GPIO 0: full battery
RI from modem
Outputs:
PWGOUT and NMI to CPU
So, connected power pins are (PWR bits):
VP0 to LCD panel 5V
VP1 to LCD backlight
VP2 to power supply
VP4 to RS232
VP5 to modem (input ring on RI)?
PWRon drives almost all pins directly, inverted by POLARITY.
The polarity of it being 'on' in the PWR registers is determined by POLARITY. Setting a bit turns the VP setting high is the bit is that value (affecting the PWR registers) on the output of the chip. OUTPUT gives the result before applying the POLARITY register.
OK. I've implemented the chip according to the found documentation fully (minus some CPU and outputs being handled by hardware (they're calculated though).
I see it using SMM a few times during boot. As well as when using the test program to try a shutdown. It also enters SMM when executing the quit.com program.
I see no port I/O though?
During POST itself, I see lots of addresses I need to filter out (various sound hardware and misc cards). Some interesting ones I see:
13f4h
fffch
fffdh
42ech-42efh. SMM executed immediately after?
Edit: Looking at the SMM code, it returns from the first two calls, then some interesting stuff happens on the power off command by the .COM program:
113f4 2fffc 3fffd 442ec-42ef. SMM immediately after? 5 6SMM: 7PCI 80000090? 8-> address 91? Read 11h? 9-> 90 write 000000000h 10-> address 91 write 11h? 11PCI 800008a8? 12offset 2, so 8ac in PCI memory. 13read ae of device #0 function #1. =STPCLK high timer. 14device #1 function 0 select register A0. read 01h. 15Mask with FEh. 16Write back 00h. 17Select register 59h on device #0 function #0. Read it. Value =30h. 18Read register 58h of device #0. 19And register 59h. 20Write 30h to register 59. 21Select register 0 on device #0. 22Select device 1 register A8h. 23Read register AAh. Read 80h. Cause is write to APM control register. 24Detected. So got to 9F67:9A20. 25Load 9A24 into SI(9C01). 26Jump to 9F67:9A24 27More lookup tables... 28Jump to 9F67:9A82. 29Select device 1 register A0h. 30Read register A0h. Read 00h. 31Write 00h to it. 32Read port 03CCh. VGA misc output register. Read 67h. 33Select device 1 register A0h. 34Write register A2 value A0h. Trap on Fast Off-Timer and APMC Write. 35Select A0 register again on PIIX. 36Set it to 08h. 37Select register A8 on PIIX. 38Write value 00h to it. 39Select A0h register again. Read 08h. 40Select A0h. 41Write 00h to it (SMI control). 42Some port 61h read/writing. 43Read back A0-A3 registers. Read 80000000h. 44Select register 58h on on device #0. 45Read register 59h (30h). 46Set register to 10h. Reads from RAM, writes to PCI. 47Select register 00h. 48Select device 01h register A8h. 49Clear register AAh (SMI request cause). 50Write 01h to port B3 (was 0x01) 51Select register A0h. Read 00h. 52Write 01h to register A0h (enable SMI gate). 53Select device #0 register 58h. 54Write 59h value 30h (map BIOS to RAM r/w). 55Reset PCI to register 00h. 56RSM. 57 58... 59 60BIOS read 58h on device #0 (30h).
…Show last 19 lines
61Set to 10h. 62 63... 64 65Returns to software. 66 67Function 530e called into BIOS. 68Returns with carry flag clear. 69 70Function call 5307h to turn off the system at 0F76:011A (using MS-DOS 6.22 without any drivers). 71 72Select device #1 register 78h. 73Write register 79h with 13h. 74Select register 78h again. 75Write register 78h with F0h. So Programmable Chip-Select Control register address 13F0? 76Select port 13F0 in DX. 77Write F0 to it. ??? What is this? 78
So the function call 5307h is interesting. It sets PIIX Programmable Chip-Select Control register to I/O port 13F0 (selected by register 78h/79h), then writes 13F0 to it, using byte operations?
That's supposed to be the powerdown sequence?
What chip is it using on PIIX programmable chip-select?
Final INT15h call by the quit.com program:
The attachment i440fx_shutdown_sequence_finalINT15only.zip is no longer available
Btw, the program has an error with the string termination being 0, instead of $ required by MS-DOS, so it dumps garbage after the end of the string printed it failed "APM error or not available" followed by garbage.
I added some logging, I see the following before the i440fx memory testing:
1Read from 21h, base address 20h, 16-bytes size. 2Write to 21h, value FFh x2. 3... 4Write to 21h, value FEh. 5Write to 29h, value 20h x2. 6Write to 21h, value FFh. 7Write to 21h, value 00h. 8Read from 21h. 9Write to 21h, value B8h. 10- Memory test.
Edit: Implemented the PCS to log writes to it's (if enabled) I/O port range:
From 07:24:44 it's the shutdown commmand executing.
So it enables the PCS I/O range and writes F0h to byte I/O port PCS+00h to perform a shutdown somehow?
What really is the PCS chip?
Edit: Looking at the BIOS code for shutdown executing:
f000:0000802c 34 E4 xor ah,ah
AL from request being less or equal to 13h.
Lookup AL entry number in word-sized table into SI. Thus SI points to entry point of function number 07h (set power state).
return point at 8038h.
That function puts d9a0 into AX and adds F0h to AH.
That's loaded into DS (FD9A).
It eventually calls the loaded function number (from input AL into INT 15h):
f000:000082c5 is the start of the full poweroff being detected by the BIOS.
It checks CX for the requested state again, according to http://www.ctyme.com/intr/rb-1401.htm#Table475 (checks for CX=0006h).
That calls function f000:0000888b from function f000:0008921.
That function setting up of that PCS chip at 13h into the high port number.
Then it returns to function f000:0000888b at:
It then sets AL to F0h and calls the function f000:0000888b again.
That then writes F0h to the low PCS register, enabling the register for 4-byte access at address 13F0h.
That once again returns to function f000:0000888b again.
This time the function writes to the base port that's setup just now, completing the action:
It's returned success by clearing the carry flag and returns to the caller.
It then returns back to caller through each stack frame, keeps checking CF for errors (which is cleared for no error) until it reaches the INT 15h function call IRET.
The quit.com program at segment 0f76 (returned to 0f76:00000125) then proceeds to halt the system to wait for the power supply to terminate power. Carry flag is indeed cleared, so the BIOS thinks it's just requested a poweroff from the hardware.
So it looks like the writing of the byte F0h to the base address of the PCS chip (whatever chip it is) really is supposed to cut off the power to the motherboard (the BIOS returning success is confirming that).
Last edited by superfury on 2024-03-17, 15:56. Edited 4 times in total.
There is no power down sequence for the PIIX3, but Intel boards set up the PC87306 Super I/O chip to do a power down when the power supply is ATX, on ports 78h and 79h (the Super I/O chip's GPIO registers).
But looking at what the BIOS does doesn't match anything sane with what the program is requesting and what the BIOS writes to register address 0 on said device?
The port written by the request is at 13F0 (configured to 13F0) with value F0 written to that address.
Looking at the address x0 on said chip you've mentioned doesn't match anything that would match the top 4 bits set and bottom bits cleared with a full poweroff request?
The writing of the register really confirms that the chip at PCS is actually performing power supply poweroff, probably even more.
Though I'd need a COM program to check what the other power states do with said registers to be sure.
Luckily the source code is open-sourced, so it's easy to adapt.
Perhaps loop through setting the 4 power states (0,1,2,3) and observe what's written to the chip for each value to confirm?
If I'm correct, I should see the value in said register change for every INT 15h call.
The PCS written is a relative offset to the PCS base btw, F0h is the value written to said port. So it's writing F0 to port 13F0, just like the shutdown program.
Added an extra 'green button' option to the settings to trigger EXTSMI# on the chipset (both i82347 and PIIX/PIIX3 chipsets). i82347 will only take effect if 'activated' by writing it's registers after a hard reset (which is a PCI reset and during poweron). So both ways can work in harmony with each other.
Just added an extra mapping of the i82347 mapping to address base+2 and base+3 of the PCS chipset. Then I also added mapping writes at the PCS base address +0 to write C0 to address +2 and the value written to address +3(thus the F0h write writes to the first register of the i82347). It also adjusts value F0 to FF when it detects it being written (thus triggering a shutdown).
It temporarily moves the chip to address 0 and back to it's original mapping when it's done handling such a write to the PCS I/O range.
Since the addrsel is 0 in all other cases (it uses special case 3(disabled) and 4(enabled custom mapping) to map internally), it will revert it's behaviour after a read or write is performed using the special PCS window.
So the i82347 chip is visible at (since addrsel is 0) 26h/27h range, as well as PCS +2/+3. And PCS+0 is turned into a write to PCS+2(C0h) and a write to PCS+3 with the value written to archieve the proper effect. Value F0 is also turned into FFh when written to PCS+0 (to archieve a shutdown request).