Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reboot / halt / shutdown support #67

Closed
nickb834 opened this issue Feb 9, 2022 · 6 comments
Closed

reboot / halt / shutdown support #67

nickb834 opened this issue Feb 9, 2022 · 6 comments
Labels
good first issue Good for newcomers

Comments

@nickb834
Copy link

nickb834 commented Feb 9, 2022

I've noticed that reboot / shutdown / halt doesn't work - I'm guessing this is something to do with the busybox source needs a patch to deal with the hardware on a PS2 - I've had a quick look through this repo but I can't tell if halt / reboot etc are actually expected to be supported.

Is there a workaround? or is it the case that it's unsupported or is this an issue with my build?

@frno7
Copy link
Owner

frno7 commented Feb 10, 2022

Powering off is indeed supported, try poweroff -f. It may be the swiftest shutdown you’ve ever seen for a Linux machine. :-) Likewise halt -f, but reboot -f isn’t serviceable as of yet. Confer commit 92375ad for details.

If memory serves me the -f option skips a failed attempt by Busybox to run a shutdown script via init, that I suppose isn’t installed with your INITRAMFS. Such scripts normally unmount filesystems, etc. We ought to write a note about this on the Busybox wiki page.

@frno7 frno7 added the good first issue Good for newcomers label Feb 10, 2022
@uyjulian
Copy link

IIRC poweroff scmd won't work if dev9 is turned on.

Also, on older SCPH-1xxxx hardware, poweroff scmd won't work at all since the mechacon on those consoles does not support that command.

@frno7
Copy link
Owner

frno7 commented Feb 10, 2022

@uyjulian, yes, disclaimers apply. :-) The SCPH-1xxxx models are currently listed as incompatible, mainly due to issue #28, and we’ve got (for scmd_read_machine_name)

linux/arch/mips/ps2/scmd.c

Lines 226 to 227 in 59a11ab

* Machines SCPH-10000 and SCPH-15000 do not implement this command. Late
* SCPH-10000 and all SCPH-15000 have the name in rom0:OSDSYS instead.

and we’ll eventually need to do something similar to

/*
* ROM version 1.00 is always SCPH-10000. Later machines with
* ROM version 1.0x have the machine name in the ROM0 file OSDSYS
* at offset 0x8c808. These are late SCPH-10000 and all SCPH-15000.
* Even later machines have a system command (SCMD) to read the
* machine name.
*/
if (rom_version_number >= 0x110)
err = set_machine_name_by_scmd(); /* ver >= 1.10 */
else if (rom_version_number > 0x100)
err = set_machine_name_by_osdsys(); /* 1.10 > ver > 1.00 */
else if (rom_version_number == 0x100)
mips_set_machine_name("SCPH-10000"); /* ver = 1.00 */
else
err = -ENODEV;

for scmd_power_off too...

IIRC poweroff scmd won't work if dev9 is turned on.

Hmm, it works in combination with the expansion bay ATA driver, which surely needs dev9 powered on, doesn’t it? See comment #18 (comment) et al.

@uyjulian
Copy link

Hmm, it works in combination with the expansion bay ATA driver, which surely needs dev9 powered on, doesn’t it? See comment #18 (comment) et al.

On the expansion bay connector there is the PWR_CTRL / POW_CTRL signal tied to the syscon and this appears to be tied to the value of the register 0xBF80146C. In this case I'll refer to this as dev9 power.
This, among other things, controls the power off behavior (e.g. what happens when you press the power button or the power off scmd is sent). IIRC sending the power off scmd with dev9 powered on will result in nothing happening, so it needs to be powered off e.g. https://github.com/ps2dev/ps2sdk/blob/f4e8415ebd4146f414670150a92f472dca9ddba3/iop/dev9/dev9/src/ps2dev9.c#L359 before sending the power off scmd.

@frno7
Copy link
Owner

frno7 commented Feb 14, 2022

Yes, we have the corresponding power operations in the Linux kernel here:

static int iop_dev9_power(bool * const power)
{
u16 raw;
int err;
err = iop_dev9_read_power(&raw);
if (err < 0) {
*power = false;
return err;
}
*power = ((raw & 0x4) != 0);
return 0;
}
static int __init exp_dev_probe(void)
{
u16 reg_1462;
int err;
err = iop_dev9_read_1462(&reg_1462);
if (err < 0)
return err;
return (reg_1462 & 0x1) ? -ENODEV : 0;
}
static int __init exp_dev_reset(void)
{
u16 reg_power;
u16 reg_1460;
int err;
err = exp_dev_probe();
if (err < 0)
return err;
err = iop_dev9_read_power(&reg_power); /* FIXME: iop_dev9_ -> dev9_ */
if (err < 0)
return err;
err = iop_dev9_write_power((reg_power & ~0x1) | 0x4);
if (err < 0)
return err;
msleep(500); /* FIXME */
err = iop_dev9_read_1460(&reg_1460);
if (err < 0)
return err;
err = iop_dev9_write_1460(reg_1460 | 0x1);
if (err < 0)
return err;
err = iop_dev9_read_power(&reg_power);
if (err < 0)
return err;
err = iop_dev9_write_power(reg_power | 0x1);
if (err < 0)
return err;
msleep(500); /* FIXME */
return 0;
}
static int __init exp_dev_init(void)
{
bool power;
int err;
err = iop_ssbus_write_1420(0x51011);
if (err < 0)
return err;
err = iop_ssbus_write_1418(0xe01a3043);
if (err < 0)
return err;
err = iop_ssbus_write_141c(0xef1a3043);
if (err < 0)
return err;
err = iop_dev9_power(&power);
if (err < 0)
return err;
if (!power)
{
u16 reg_1464;
printk("dev9: Expansion device power on\n"); /* FIXME */
err = iop_dev9_write_1466(1);
if (err < 0)
return err;
err = iop_dev9_write_1464(0);
if (err < 0)
return err;
err = iop_dev9_read_1464(&reg_1464);
if (err < 0)
return err;
err = iop_dev9_write_1460(reg_1464);
if (err < 0)
return err;
err = exp_dev_reset();
if (err < 0)
return err;
} else {
printk("dev9: Expansion device already powered on\n"); /* FIXME */
}
#if 0
err = iop_dev9_write_1464(0x103 & 0x3f); /* ??? */
if (err < 0)
return err;
#endif
err = iop_dev9_write_1466(0);
if (err < 0)
return err;
iop_set_dma_dpcr2(IOP_DMA_DPCR2_DEV9);
return 0;
}

It’s supposed to be powered off by iop_dev9_exit

static void __exit iop_dev9_exit(void)
{
int err = 0;
if (pc_card()) {
/* FIXME */
} else if (exp_dev()) {
u16 reg_power;
u16 reg_1464;
printk("dev9: Expansion device power off\n"); /* FIXME */
err = iop_dev9_write_1466(1);
if (err < 0)
goto out;
err = iop_dev9_write_1464(0);
if (err < 0)
goto out;
err = iop_dev9_read_1464(&reg_1464);
if (err < 0)
goto out;
err = iop_dev9_write_1460(reg_1464);
if (err < 0)
goto out;
err = iop_dev9_read_power(&reg_power);
if (err < 0)
goto out;
err = iop_dev9_write_power(reg_power & ~0x4);
if (err < 0)
goto out;
err = iop_dev9_read_power(&reg_power);
if (err < 0)
goto out;
err = iop_dev9_write_power(reg_power & ~0x1);
if (err < 0)
goto out;
}
out:
if (err)
printk("dev9: Exit failed with %d\n", err);
}

but I’m not completely sure that’s needed for powering off the system via SCMD.

A lot of the dev9 is presently unclear, including the names and purposes of most registers, unfortunately. Is there a good, reliable and reasonably complete write up of it somewhere? I’ve seen DEV9C.txt 2017-02-11 by Wisi.

@uyjulian
Copy link

DEV9C.txt and SPEED.txt in IOP_DMAC_DEV9_SPEED_docs_2017.02.11.zip are pretty much the documents out there.

DEV9C.txt is related to the Dev9 controller on the PS2 side, which would be physically located near the expansion bay connector.
SPEED.txt is related to the SPEED chip physically located in the network adapter attached to the expansion bay connector.

It also helps if you also refer to the service manual for the SCPH-39000 as the aforementioned documents refer to signals as written in the schematics in the service manual.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

3 participants