1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
diff --git a/ipl/ipl.c b/ipl/ipl.c
index fae2342..f2f7286 100644
--- a/ipl/ipl.c
+++ b/ipl/ipl.c
@@ -10,6 +10,7 @@
#include <asm/pdc.h>
#include <asm/byteorder.h>
#include "load.h"
+#include <stdint.h>
#undef PAGE0
#define PAGE0 ((struct zeropage *)0x00000000)
@@ -356,6 +357,35 @@ ls(char *path)
* the current one's data structures ... */
}
+struct pdc_table {
+ uint16_t id;
+ uint16_t unknown2;
+ uint32_t unknown4;
+ uint64_t nvram;
+ uint64_t defaults;
+};
+
+static uint64_t get_stable_rp34xx(uint64_t tab0, uint64_t tab1, uint16_t id)
+{
+ struct pdc_table *table;
+
+ table = (struct pdc_table *) (uintptr_t) tab0;
+ if (table->id == id) {
+ if (Debug)
+ printf("%p: %04x %016llx %016llx\n", table, table->id, table->nvram, table->defaults);
+ return table->nvram;
+ }
+ table = (struct pdc_table *) (uintptr_t) tab1;
+ while (table->id) {
+ if (Debug)
+ printf("%p: %04x %016llx %016llx\n", table, table->id, table->nvram, table->defaults);
+ if (table->id == id)
+ return table->nvram;
+ table++;
+ }
+ return 0;
+}
+
static void
interact(int *ok)
{
@@ -441,15 +471,46 @@ interact(int *ok)
if (numbuf[0] == 'x')
pdc_do_reset();
- /* turn on firmware manufacturing mode on C8000 workstation */
+ /* turn on firmware manufacturing mode (if possible) */
if (numbuf[0] == 'm') { /* hidden option! */
const char *model = get_machine_model();
+ unsigned char *mode_byte;
+ uint64_t addr;
+
join(commandline, argc, argv, ok);
+
+ printf("This machine: %s\n", model);
+ Debug = 1; // XXX: Enable Debug mode
+
+ /* check for C8000 workstation */
if (strncmp(model, "9000/785/C8000", 14) == 0) {
- *(unsigned char *)0xfffffff0f04300a0 = 0x4d;
+ mode_byte = (void *)0xfffffff0f04300a0;
+ enable_manufacture_mode:
+ *mode_byte = 'M';
+ printf("Manufacturing mode enabled. Be careful. Rebooting to activate...\n");
pdc_do_reset();
}
- printf("unknown machine - can not enable manufacturing mode\n");
+
+ /* check for rp3410/rp3440 server. PDC versions 46.34 and 50.40 */
+ if (strncmp(model, "9000/800/rp34", 13) == 0) {
+ addr = get_stable_rp34xx(0xfffffff0f04151f8, 0xfffffff0f0415210, 0x100);
+ enable_manufacture_mode_rp34xx:
+ if (Debug)
+ printf("got nvram addr %016llx\n", addr);
+ // add offset to get mode_byte address
+ mode_byte = (unsigned char *) (uintptr_t) (addr + 0x20);
+ if (addr && (*mode_byte == 0 || *mode_byte == 'N'))
+ goto enable_manufacture_mode;
+ continue;
+ }
+
+ /* check for rp4410/rp4440 server, PDC version 50.40 */
+ if (strncmp(model, "9000/800/rp44", 13) == 0) { /* PDC version 40.50 */
+ addr = get_stable_rp34xx(0xfffffff0f0420498, 0xfffffff0f04204b0, 0x100);
+ goto enable_manufacture_mode_rp34xx;
+ }
+
+ printf("Unknown machine - not enabling manufacturing mode.\n");
continue;
}
diff --git a/iplboot b/iplboot
index 3e717b7..e58ef19 100644
Binary files a/iplboot and b/iplboot differ
|