Table of Contents

About

Depending on the hardware, Mac computers can be configured to power-up after a power-failure. Commonly this has been done by toggling a register value on the LPC Bridge using the setpci command. Unfortunately, the command has to be issued after every reboot such that it is a good idea to place the command early on during boot. However, the grub boot-manager has a setpci module that could instead be used to set the value of the register very early on during the boot process (right from the bootloader).

Requirements

The grub bootloader has to have the setpci module which is part of the grub-pc-bin package on Debian. Modules are placed in /boot/grub/i386-pc and you can check that setpci.mod exists in that directory.

Figuring out Which Register to Toggle

First look for the LCP bridge:

lspci | grep LPC

that should list the device:

00:03.0 ISA bridge: NVIDIA Corporation MCP89 LPC Bridge (rev a2)

Next would be to find a datasheet for the MCP89 LPC Bridge controller in order to figure out which control bit to set after a power failure such that the machine restarts.

For the MCP89 LPC Bridge the 0x7b register has to be set to 19. The setpci command that you would thus have to run in order for the machine to restart after a power failure would be:

setpci -s 00:03.0 0x7b.b=19

Setting PCI Registers from Grub

Depending on your Linux distribution, editing /boot/grub.cfg directly may pose problems with scripts that automatically generate that file. Fortunately, distributions such as Debian provide a /etc/grub.d/ directory where scripts are processed when the update-grub command is run in order to generate /boot/grub.cfg.

The /etc/grub.d/ directory contains something like:

00_header
05_debian_theme
10_linux
20_linux_xen
30_os-prober
30_uefi-firmware
40_custom
41_custom

Where the files start with a two digit value indicating their priority when the /boot/grub.cfg is generated. The 00_header file has to be always first and, as such, we will be adding a new file /etc/grub.d/01_setpci that will be loading the grub setpci module and executing commands. Note that the files in /etc/grub.d/ are in fact shell scripts that generate grub commands.

Based on the above, create a file at /etc/grub.d/01_setpci with the following contents:

#! /bin/sh
set +e

cat <<EOF
insmod tga
setpci -s 00:03.0 0x7b.b=19
EOF

and save the file.

After that, issue the grub-update command:

update-grub

and we can restart in order to check that the register is set.

Checking the Value of the Register after a Reboot

After the system has rebooted, you can check whether the register is set using lspci:

lspci -s 00:03.0 -vvvxxxx

which should output the device registers (amongst other information):

00: de 10 80 0d 0f 00 a0 00 a2 00 01 06 00 00 80 00
10: 01 21 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 6b 10 89 cb
30: 00 00 00 00 00 00 00 00 00 00 00 00 ff 00 00 00
40: 6b 10 89 cb 00 00 d0 fe 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 5a 62 02 00 00 00 05 ff 0b 3c 04
60: 00 00 00 00 00 00 00 00 00 00 00 00 18 01 01 00
70: 50 00 ff ff 4d 04 17 00 00 14 44 19 00 00 00 00
80: 00 00 00 ff 00 00 00 00 00 00 40 07 ff 00 00 00
90: 00 7c 00 00 ff ff 0f 00 00 00 00 00 ce f1 d7 d9
a0: 03 00 00 31 00 00 01 00 00 03 1f 03 00 07 ff 07
b0: 00 00 00 00 00 00 00 00 00 00 00 00 fd fb 33 6e
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: fd 00 00 00 00 00 00 00 f8 0c 00 fc 00 73 00 30
e0: 83 74 0b 29 ac 39 af 5a 09 00 c0 5c 00 00 00 00
f0: 80 00 00 fc fd 00 00 00 10 00 80 80 00 00 00 00

Now we have to look for 0x7b - so that's column 70 and row b (11th row starting from 0, since b is 11 in decimal) and looking up in the table we find 19 meaning that the register is set.