diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2006-05-19 03:04:12 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-05-24 02:08:57 -0400 |
commit | 72a14eafb243b1f31118ea55a7e8c2588b5ad468 (patch) | |
tree | 718a1f016ed660e9445d18106ba77c582416f81f /arch/powerpc | |
parent | c4e3ea2553308ba65fea582dc9a42221ef8b49e5 (diff) |
[PATCH] powerpc: make iSeries flattened device tree dynamic - part 2
This actually simplies things as we just figure out how much space we
used at the end and adjust klimit then.
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/platforms/iseries/dt.c | 62 |
1 files changed, 19 insertions, 43 deletions
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c index 0371329f82e1..2a51ec1e3359 100644 --- a/arch/powerpc/platforms/iseries/dt.c +++ b/arch/powerpc/platforms/iseries/dt.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <asm/machdep.h> | 27 | #include <asm/machdep.h> |
28 | #include <asm/prom.h> | 28 | #include <asm/prom.h> |
29 | #include <asm/lppaca.h> | 29 | #include <asm/lppaca.h> |
30 | #include <asm/page.h> | ||
31 | #include <asm/cputable.h> | 30 | #include <asm/cputable.h> |
32 | #include <asm/abs_addr.h> | 31 | #include <asm/abs_addr.h> |
33 | #include <asm/system.h> | 32 | #include <asm/system.h> |
@@ -51,15 +50,10 @@ | |||
51 | extern char __dt_strings_start[]; | 50 | extern char __dt_strings_start[]; |
52 | extern char __dt_strings_end[]; | 51 | extern char __dt_strings_end[]; |
53 | 52 | ||
54 | struct blob { | ||
55 | unsigned char data[PAGE_SIZE * 2]; | ||
56 | unsigned long next; | ||
57 | }; | ||
58 | |||
59 | struct iseries_flat_dt { | 53 | struct iseries_flat_dt { |
60 | struct boot_param_header header; | 54 | struct boot_param_header header; |
61 | u64 reserve_map[2]; | 55 | u64 reserve_map[2]; |
62 | struct blob *dt; | 56 | void *data; |
63 | }; | 57 | }; |
64 | 58 | ||
65 | static struct iseries_flat_dt *iseries_dt; | 59 | static struct iseries_flat_dt *iseries_dt; |
@@ -76,15 +70,12 @@ static struct iseries_flat_dt * __init dt_init(void) | |||
76 | dt->header.off_dt_strings = ALIGN(sizeof(*dt), 8); | 70 | dt->header.off_dt_strings = ALIGN(sizeof(*dt), 8); |
77 | dt->header.off_dt_struct = dt->header.off_dt_strings | 71 | dt->header.off_dt_struct = dt->header.off_dt_strings |
78 | + ALIGN(str_len, 8); | 72 | + ALIGN(str_len, 8); |
79 | dt->dt = (struct blob *)((unsigned long)dt + dt->header.off_dt_struct); | 73 | dt->data = (void *)((unsigned long)dt + dt->header.off_dt_struct); |
80 | klimit = ALIGN((unsigned long)(dt->dt) + sizeof(struct blob), 8); | ||
81 | dt->header.totalsize = klimit - (unsigned long)dt; | ||
82 | dt->header.dt_strings_size = str_len; | 74 | dt->header.dt_strings_size = str_len; |
83 | 75 | ||
84 | /* There is no notion of hardware cpu id on iSeries */ | 76 | /* There is no notion of hardware cpu id on iSeries */ |
85 | dt->header.boot_cpuid_phys = smp_processor_id(); | 77 | dt->header.boot_cpuid_phys = smp_processor_id(); |
86 | 78 | ||
87 | dt->dt->next = (unsigned long)&dt->dt->data; | ||
88 | memcpy((char *)dt + dt->header.off_dt_strings, __dt_strings_start, | 79 | memcpy((char *)dt + dt->header.off_dt_strings, __dt_strings_start, |
89 | str_len); | 80 | str_len); |
90 | 81 | ||
@@ -98,54 +89,37 @@ static struct iseries_flat_dt * __init dt_init(void) | |||
98 | return dt; | 89 | return dt; |
99 | } | 90 | } |
100 | 91 | ||
101 | static void __init dt_check_blob(struct blob *b) | ||
102 | { | ||
103 | if (b->next >= (unsigned long)&b->next) { | ||
104 | DBG("Ran out of space in flat device tree blob!\n"); | ||
105 | BUG(); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | static void __init dt_push_u32(struct iseries_flat_dt *dt, u32 value) | 92 | static void __init dt_push_u32(struct iseries_flat_dt *dt, u32 value) |
110 | { | 93 | { |
111 | *((u32*)dt->dt->next) = value; | 94 | *((u32 *)dt->data) = value; |
112 | dt->dt->next += sizeof(u32); | 95 | dt->data += sizeof(u32); |
113 | |||
114 | dt_check_blob(dt->dt); | ||
115 | } | 96 | } |
116 | 97 | ||
117 | #ifdef notyet | 98 | #ifdef notyet |
118 | static void __init dt_push_u64(struct iseries_flat_dt *dt, u64 value) | 99 | static void __init dt_push_u64(struct iseries_flat_dt *dt, u64 value) |
119 | { | 100 | { |
120 | *((u64*)dt->dt->next) = value; | 101 | *((u64 *)dt->data) = value; |
121 | dt->dt->next += sizeof(u64); | 102 | dt->data += sizeof(u64); |
122 | |||
123 | dt_check_blob(dt->dt); | ||
124 | } | 103 | } |
125 | #endif | 104 | #endif |
126 | 105 | ||
127 | static unsigned long __init dt_push_bytes(struct blob *blob, char *data, int len) | 106 | static void __init dt_push_bytes(struct iseries_flat_dt *dt, char *data, |
107 | int len) | ||
128 | { | 108 | { |
129 | unsigned long start = blob->next - (unsigned long)blob->data; | 109 | memcpy(dt->data, data, len); |
130 | 110 | dt->data += ALIGN(len, 4); | |
131 | memcpy((char *)blob->next, data, len); | ||
132 | blob->next = _ALIGN(blob->next + len, 4); | ||
133 | |||
134 | dt_check_blob(blob); | ||
135 | |||
136 | return start; | ||
137 | } | 111 | } |
138 | 112 | ||
139 | static void __init dt_start_node(struct iseries_flat_dt *dt, char *name) | 113 | static void __init dt_start_node(struct iseries_flat_dt *dt, char *name) |
140 | { | 114 | { |
141 | dt_push_u32(dt, OF_DT_BEGIN_NODE); | 115 | dt_push_u32(dt, OF_DT_BEGIN_NODE); |
142 | dt_push_bytes(dt->dt, name, strlen(name) + 1); | 116 | dt_push_bytes(dt, name, strlen(name) + 1); |
143 | } | 117 | } |
144 | 118 | ||
145 | #define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE) | 119 | #define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE) |
146 | 120 | ||
147 | static void __init dt_prop(struct iseries_flat_dt *dt, char *name, | 121 | static void __init dt_prop(struct iseries_flat_dt *dt, char *name, |
148 | char *data, int len) | 122 | void *data, int len) |
149 | { | 123 | { |
150 | unsigned long offset; | 124 | unsigned long offset; |
151 | 125 | ||
@@ -160,7 +134,7 @@ static void __init dt_prop(struct iseries_flat_dt *dt, char *name, | |||
160 | dt_push_u32(dt, (u32)offset); | 134 | dt_push_u32(dt, (u32)offset); |
161 | 135 | ||
162 | /* The actual data. */ | 136 | /* The actual data. */ |
163 | dt_push_bytes(dt->dt, data, len); | 137 | dt_push_bytes(dt, data, len); |
164 | } | 138 | } |
165 | 139 | ||
166 | static void __init dt_prop_str(struct iseries_flat_dt *dt, char *name, | 140 | static void __init dt_prop_str(struct iseries_flat_dt *dt, char *name, |
@@ -171,24 +145,24 @@ static void __init dt_prop_str(struct iseries_flat_dt *dt, char *name, | |||
171 | 145 | ||
172 | static void __init dt_prop_u32(struct iseries_flat_dt *dt, char *name, u32 data) | 146 | static void __init dt_prop_u32(struct iseries_flat_dt *dt, char *name, u32 data) |
173 | { | 147 | { |
174 | dt_prop(dt, name, (char *)&data, sizeof(u32)); | 148 | dt_prop(dt, name, &data, sizeof(u32)); |
175 | } | 149 | } |
176 | 150 | ||
177 | static void __init dt_prop_u64(struct iseries_flat_dt *dt, char *name, u64 data) | 151 | static void __init dt_prop_u64(struct iseries_flat_dt *dt, char *name, u64 data) |
178 | { | 152 | { |
179 | dt_prop(dt, name, (char *)&data, sizeof(u64)); | 153 | dt_prop(dt, name, &data, sizeof(u64)); |
180 | } | 154 | } |
181 | 155 | ||
182 | static void __init dt_prop_u64_list(struct iseries_flat_dt *dt, char *name, | 156 | static void __init dt_prop_u64_list(struct iseries_flat_dt *dt, char *name, |
183 | u64 *data, int n) | 157 | u64 *data, int n) |
184 | { | 158 | { |
185 | dt_prop(dt, name, (char *)data, sizeof(u64) * n); | 159 | dt_prop(dt, name, data, sizeof(u64) * n); |
186 | } | 160 | } |
187 | 161 | ||
188 | static void __init dt_prop_u32_list(struct iseries_flat_dt *dt, char *name, | 162 | static void __init dt_prop_u32_list(struct iseries_flat_dt *dt, char *name, |
189 | u32 *data, int n) | 163 | u32 *data, int n) |
190 | { | 164 | { |
191 | dt_prop(dt, name, (char *)data, sizeof(u32) * n); | 165 | dt_prop(dt, name, data, sizeof(u32) * n); |
192 | } | 166 | } |
193 | 167 | ||
194 | #ifdef notyet | 168 | #ifdef notyet |
@@ -595,6 +569,8 @@ static void __init dt_pci_devices(struct iseries_flat_dt *dt) | |||
595 | static void dt_finish(struct iseries_flat_dt *dt) | 569 | static void dt_finish(struct iseries_flat_dt *dt) |
596 | { | 570 | { |
597 | dt_push_u32(dt, OF_DT_END); | 571 | dt_push_u32(dt, OF_DT_END); |
572 | dt->header.totalsize = (unsigned long)dt->data - (unsigned long)dt; | ||
573 | klimit = ALIGN((unsigned long)dt->data, 8); | ||
598 | } | 574 | } |
599 | 575 | ||
600 | void * __init build_flat_dt(unsigned long phys_mem_size) | 576 | void * __init build_flat_dt(unsigned long phys_mem_size) |