File: p3

package info (click to toggle)
palo 2.29
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 524 kB
  • sloc: ansic: 6,381; asm: 218; makefile: 198; sh: 61
file content (101 lines) | stat: -rw-r--r-- 2,981 bytes parent folder | download | duplicates (3)
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