diff options
author | Helge Deller <deller@gmx.de> | 2013-06-11 22:02:36 +0200 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2013-06-11 22:02:36 +0200 |
commit | fdbef9495401ef71d20d3dd628035deba881f64a (patch) | |
tree | a44d346b2261ebd5e4cd9119b258692a2d6301c8 | |
parent | 570a4f2d72180f72f6637500f9aa2f20900cfb75 (diff) | |
download | palo-fdbef9495401ef71d20d3dd628035deba881f64a.tar.gz |
Add boot menu option "x" to reset/reboot the machine.
This was useful for me when I booted a bootloader with an 64bit kernel, while
the machine was only capable to run 32bit kernels.
-rw-r--r-- | ipl/bootloader.h | 1 | ||||
-rw-r--r-- | ipl/ipl.c | 4 | ||||
-rw-r--r-- | ipl/pdc_bootio.c | 2 | ||||
-rw-r--r-- | ipl/pdc_misc.c | 28 |
4 files changed, 34 insertions, 1 deletions
diff --git a/ipl/bootloader.h b/ipl/bootloader.h index 6df180a..1529ba8 100644 --- a/ipl/bootloader.h +++ b/ipl/bootloader.h @@ -38,6 +38,7 @@ int pdc_os_bits(); #define OS_64 0x1 int pdc_iodc_bootin(unsigned devaddr, char *memaddr, unsigned size); int pdc_read_conspath(unsigned char *memaddr); +int pdc_do_reset(void); typedef void (*describe_t)(int fd, int *bufalign, int *blocksize); typedef int (*read_t)(int fd, char *buf, unsigned nbytes, unsigned devaddr); @@ -331,6 +331,7 @@ interact(char *commandline, int *ok) "'b' boot with this command line\n" "'r' restore command line\n" "'l' list dir\n" + "'x' reset and reboot machine\n" "? "); numbuf[0] = '0'; numbuf[1] = '\0'; @@ -356,6 +357,9 @@ interact(char *commandline, int *ok) continue; } + if (numbuf[0] == 'x') + pdc_do_reset(); + editfield = parse_number(numbuf, &p); if (editfield < argc) diff --git a/ipl/pdc_bootio.c b/ipl/pdc_bootio.c index 00055c6..7b6a92a 100644 --- a/ipl/pdc_bootio.c +++ b/ipl/pdc_bootio.c @@ -62,7 +62,7 @@ static int pdc_bootdev_read(int fd, if ((count = pdc_iodc_bootin(devaddr, dest, nseek)) < 0) { die("pdc_iodc_bootin() died during seekread\r\n"); - while(1); + pdc_do_reset(); } devaddr += count; } diff --git a/ipl/pdc_misc.c b/ipl/pdc_misc.c index b78ef69..1d6e342 100644 --- a/ipl/pdc_misc.c +++ b/ipl/pdc_misc.c @@ -23,6 +23,10 @@ #define HPHW_A_DIRECT 5 #define MUX_SVERSION 0x0d +#define F_EXTEND(x) ((unsigned long)((x) | (0xffffffff00000000ULL))) +#define COMMAND_GLOBAL F_EXTEND(0xfffe0030) +#define CMD_RESET 5 /* reset any module */ + void die(const char *s) { puts(s); @@ -349,3 +353,27 @@ pdc_read_conspath(unsigned char *memaddr) } return r; /* r < 0; error */ } + +static inline void gsc_writel(unsigned int val, unsigned long addr) +{ + __asm__ __volatile__( + " stwas %0,0(%1)\n" + : : "r" (val), "r" (addr) ); +} + +int +pdc_do_reset(void) +{ + printf("Resetting machine.\n"); + + /* reset the machine - this call will most likely not return. */ + firmware_call(mem_pdc, PDC_BROADCAST_RESET, PDC_DO_RESET); + + /* Nope...box should reset with just CMD_RESET now */ + gsc_writel(CMD_RESET, COMMAND_GLOBAL); + + /* Wait for RESET to lay us to rest. */ + while (1) /* wait */; + + return -1; +} |