aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/boot/addnote.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2005-05-01 11:58:45 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-01 11:58:45 -0400
commit66faf9845a05905d75da380767e93455f3e6d620 (patch)
treed58eb784e69f952ae7ac28271fd8482fee727e6b /arch/ppc64/boot/addnote.c
parent58366af5861eee1479426380e3c91ecb334c301d (diff)
[PATCH] ppc64: tell firmware about kernel capabilities
On pSeries systems, according to the platform architecture specs, we are supposed to be supplying a structure to firmware that tells firmware about our capabilities, such as which version of the data structures that describe available memory we are expecting to see. The way we end up having to supply this data structure is a bit gross, since it was designed for AIX and doesn't suit us very well. This patch adds the code to supply this data structure to the firmware. Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ppc64/boot/addnote.c')
-rw-r--r--arch/ppc64/boot/addnote.c60
1 files changed, 50 insertions, 10 deletions
diff --git a/arch/ppc64/boot/addnote.c b/arch/ppc64/boot/addnote.c
index 66ff8103bf4d..719663a694bb 100644
--- a/arch/ppc64/boot/addnote.c
+++ b/arch/ppc64/boot/addnote.c
@@ -19,6 +19,7 @@
19#include <unistd.h> 19#include <unistd.h>
20#include <string.h> 20#include <string.h>
21 21
22/* CHRP note section */
22char arch[] = "PowerPC"; 23char arch[] = "PowerPC";
23 24
24#define N_DESCR 6 25#define N_DESCR 6
@@ -31,6 +32,29 @@ unsigned int descr[N_DESCR] = {
31 0x4000, /* load-base */ 32 0x4000, /* load-base */
32}; 33};
33 34
35/* RPA note section */
36char rpaname[] = "IBM,RPA-Client-Config";
37
38/*
39 * Note: setting ignore_my_client_config *should* mean that OF ignores
40 * all the other fields, but there is a firmware bug which means that
41 * it looks at the splpar field at least. So these values need to be
42 * reasonable.
43 */
44#define N_RPA_DESCR 8
45unsigned int rpanote[N_RPA_DESCR] = {
46 0, /* lparaffinity */
47 64, /* min_rmo_size */
48 0, /* min_rmo_percent */
49 40, /* max_pft_size */
50 1, /* splpar */
51 -1, /* min_load */
52 0, /* new_mem_def */
53 1, /* ignore_my_client_config */
54};
55
56#define ROUNDUP(len) (((len) + 3) & ~3)
57
34unsigned char buf[512]; 58unsigned char buf[512];
35 59
36#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) 60#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1]))
@@ -69,7 +93,7 @@ main(int ac, char **av)
69{ 93{
70 int fd, n, i; 94 int fd, n, i;
71 int ph, ps, np; 95 int ph, ps, np;
72 int nnote, ns; 96 int nnote, nnote2, ns;
73 97
74 if (ac != 2) { 98 if (ac != 2) {
75 fprintf(stderr, "Usage: %s elf-file\n", av[0]); 99 fprintf(stderr, "Usage: %s elf-file\n", av[0]);
@@ -81,7 +105,8 @@ main(int ac, char **av)
81 exit(1); 105 exit(1);
82 } 106 }
83 107
84 nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4; 108 nnote = 12 + ROUNDUP(strlen(arch) + 1) + sizeof(descr);
109 nnote2 = 12 + ROUNDUP(strlen(rpaname) + 1) + sizeof(rpanote);
85 110
86 n = read(fd, buf, sizeof(buf)); 111 n = read(fd, buf, sizeof(buf));
87 if (n < 0) { 112 if (n < 0) {
@@ -104,7 +129,7 @@ main(int ac, char **av)
104 np = GET_16BE(E_PHNUM); 129 np = GET_16BE(E_PHNUM);
105 if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) 130 if (ph < E_HSIZE || ps < PH_HSIZE || np < 1)
106 goto notelf; 131 goto notelf;
107 if (ph + (np + 1) * ps + nnote > n) 132 if (ph + (np + 2) * ps + nnote + nnote2 > n)
108 goto nospace; 133 goto nospace;
109 134
110 for (i = 0; i < np; ++i) { 135 for (i = 0; i < np; ++i) {
@@ -117,12 +142,12 @@ main(int ac, char **av)
117 } 142 }
118 143
119 /* XXX check that the area we want to use is all zeroes */ 144 /* XXX check that the area we want to use is all zeroes */
120 for (i = 0; i < ps + nnote; ++i) 145 for (i = 0; i < 2 * ps + nnote + nnote2; ++i)
121 if (buf[ph + i] != 0) 146 if (buf[ph + i] != 0)
122 goto nospace; 147 goto nospace;
123 148
124 /* fill in the program header entry */ 149 /* fill in the program header entry */
125 ns = ph + ps; 150 ns = ph + 2 * ps;
126 PUT_32BE(ph + PH_TYPE, PT_NOTE); 151 PUT_32BE(ph + PH_TYPE, PT_NOTE);
127 PUT_32BE(ph + PH_OFFSET, ns); 152 PUT_32BE(ph + PH_OFFSET, ns);
128 PUT_32BE(ph + PH_FILESZ, nnote); 153 PUT_32BE(ph + PH_FILESZ, nnote);
@@ -134,11 +159,26 @@ main(int ac, char **av)
134 PUT_32BE(ns + 8, 0x1275); 159 PUT_32BE(ns + 8, 0x1275);
135 strcpy(&buf[ns + 12], arch); 160 strcpy(&buf[ns + 12], arch);
136 ns += 12 + strlen(arch) + 1; 161 ns += 12 + strlen(arch) + 1;
137 for (i = 0; i < N_DESCR; ++i) 162 for (i = 0; i < N_DESCR; ++i, ns += 4)
138 PUT_32BE(ns + i * 4, descr[i]); 163 PUT_32BE(ns, descr[i]);
164
165 /* fill in the second program header entry and the RPA note area */
166 ph += ps;
167 PUT_32BE(ph + PH_TYPE, PT_NOTE);
168 PUT_32BE(ph + PH_OFFSET, ns);
169 PUT_32BE(ph + PH_FILESZ, nnote2);
170
171 /* fill in the note area we point to */
172 PUT_32BE(ns, strlen(rpaname) + 1);
173 PUT_32BE(ns + 4, sizeof(rpanote));
174 PUT_32BE(ns + 8, 0x12759999);
175 strcpy(&buf[ns + 12], rpaname);
176 ns += 12 + ROUNDUP(strlen(rpaname) + 1);
177 for (i = 0; i < N_RPA_DESCR; ++i, ns += 4)
178 PUT_32BE(ns, rpanote[i]);
139 179
140 /* Update the number of program headers */ 180 /* Update the number of program headers */
141 PUT_16BE(E_PHNUM, np + 1); 181 PUT_16BE(E_PHNUM, np + 2);
142 182
143 /* write back */ 183 /* write back */
144 lseek(fd, (long) 0, SEEK_SET); 184 lseek(fd, (long) 0, SEEK_SET);
@@ -155,11 +195,11 @@ main(int ac, char **av)
155 exit(0); 195 exit(0);
156 196
157 notelf: 197 notelf:
158 fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]); 198 fprintf(stderr, "%s does not appear to be an ELF file\n", av[1]);
159 exit(1); 199 exit(1);
160 200
161 nospace: 201 nospace:
162 fprintf(stderr, "sorry, I can't find space in %s to put the note\n", 202 fprintf(stderr, "sorry, I can't find space in %s to put the note\n",
163 av[0]); 203 av[1]);
164 exit(1); 204 exit(1);
165} 205}