aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorManish Ahuja <ahuja@austin.ibm.com>2008-03-21 19:45:22 -0400
committerPaul Mackerras <paulus@samba.org>2008-03-25 17:44:06 -0400
commita9c508dae10a821dc95653178eec018abc90482e (patch)
tree8f17ea4fcc58bc5d7209e4cb7acb98a68f8ba902 /arch/powerpc
parent599c1aa54f06da4fd277982be0731e96f0791caa (diff)
[POWERPC] pseries: phyp dump: Invalidate and print dump areas
This adds routines to a. invalidate dump b. calculate region that is reserved and needs to be freed. This is exported through sysfs interface. Unregister has been removed for now as it wasn't being used. Signed-off-by: Manish Ahuja <mahuja@us.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/platforms/pseries/phyp_dump.c83
1 files changed, 77 insertions, 6 deletions
diff --git a/arch/powerpc/platforms/pseries/phyp_dump.c b/arch/powerpc/platforms/pseries/phyp_dump.c
index 5cdba6a6f70c..df4870ec90d8 100644
--- a/arch/powerpc/platforms/pseries/phyp_dump.c
+++ b/arch/powerpc/platforms/pseries/phyp_dump.c
@@ -70,6 +70,10 @@ static struct phyp_dump_header phdr;
70#define DUMP_SOURCE_CPU 0x0001 70#define DUMP_SOURCE_CPU 0x0001
71#define DUMP_SOURCE_HPTE 0x0002 71#define DUMP_SOURCE_HPTE 0x0002
72#define DUMP_SOURCE_RMO 0x0011 72#define DUMP_SOURCE_RMO 0x0011
73#define DUMP_ERROR_FLAG 0x2000
74#define DUMP_TRIGGERED 0x4000
75#define DUMP_PERFORMED 0x8000
76
73 77
74/** 78/**
75 * init_dump_header() - initialize the header declaring a dump 79 * init_dump_header() - initialize the header declaring a dump
@@ -181,9 +185,15 @@ static void print_dump_header(const struct phyp_dump_header *ph)
181static void register_dump_area(struct phyp_dump_header *ph, unsigned long addr) 185static void register_dump_area(struct phyp_dump_header *ph, unsigned long addr)
182{ 186{
183 int rc; 187 int rc;
184 ph->cpu_data.destination_address += addr; 188
185 ph->hpte_data.destination_address += addr; 189 /* Add addr value if not initialized before */
186 ph->kernel_data.destination_address += addr; 190 if (ph->cpu_data.destination_address == 0) {
191 ph->cpu_data.destination_address += addr;
192 ph->hpte_data.destination_address += addr;
193 ph->kernel_data.destination_address += addr;
194 }
195
196 /* ToDo Invalidate kdump and free memory range. */
187 197
188 do { 198 do {
189 rc = rtas_call(ibm_configure_kernel_dump, 3, 1, NULL, 199 rc = rtas_call(ibm_configure_kernel_dump, 3, 1, NULL,
@@ -197,6 +207,30 @@ static void register_dump_area(struct phyp_dump_header *ph, unsigned long addr)
197 } 207 }
198} 208}
199 209
210static
211void invalidate_last_dump(struct phyp_dump_header *ph, unsigned long addr)
212{
213 int rc;
214
215 /* Add addr value if not initialized before */
216 if (ph->cpu_data.destination_address == 0) {
217 ph->cpu_data.destination_address += addr;
218 ph->hpte_data.destination_address += addr;
219 ph->kernel_data.destination_address += addr;
220 }
221
222 do {
223 rc = rtas_call(ibm_configure_kernel_dump, 3, 1, NULL,
224 2, ph, sizeof(struct phyp_dump_header));
225 } while (rtas_busy_delay(rc));
226
227 if (rc) {
228 printk(KERN_ERR "phyp-dump: unexpected error (%d) "
229 "on invalidate\n", rc);
230 print_dump_header(ph);
231 }
232}
233
200/* ------------------------------------------------- */ 234/* ------------------------------------------------- */
201/** 235/**
202 * release_memory_range -- release memory previously lmb_reserved 236 * release_memory_range -- release memory previously lmb_reserved
@@ -207,8 +241,8 @@ static void register_dump_area(struct phyp_dump_header *ph, unsigned long addr)
207 * lmb_reserved in early boot. The released memory becomes 241 * lmb_reserved in early boot. The released memory becomes
208 * available for genreal use. 242 * available for genreal use.
209 */ 243 */
210static void 244static void release_memory_range(unsigned long start_pfn,
211release_memory_range(unsigned long start_pfn, unsigned long nr_pages) 245 unsigned long nr_pages)
212{ 246{
213 struct page *rpage; 247 struct page *rpage;
214 unsigned long end_pfn; 248 unsigned long end_pfn;
@@ -269,8 +303,29 @@ static ssize_t store_release_region(struct kobject *kobj,
269 return count; 303 return count;
270} 304}
271 305
306static ssize_t show_release_region(struct kobject *kobj,
307 struct kobj_attribute *attr, char *buf)
308{
309 u64 second_addr_range;
310
311 /* total reserved size - start of scratch area */
312 second_addr_range = phyp_dump_info->init_reserve_size -
313 phyp_dump_info->reserved_scratch_size;
314 return sprintf(buf, "CPU:0x%lx-0x%lx: HPTE:0x%lx-0x%lx:"
315 " DUMP:0x%lx-0x%lx, 0x%lx-0x%lx:\n",
316 phdr.cpu_data.destination_address,
317 phdr.cpu_data.length_copied,
318 phdr.hpte_data.destination_address,
319 phdr.hpte_data.length_copied,
320 phdr.kernel_data.destination_address,
321 phdr.kernel_data.length_copied,
322 phyp_dump_info->init_reserve_start,
323 second_addr_range);
324}
325
272static struct kobj_attribute rr = __ATTR(release_region, 0600, 326static struct kobj_attribute rr = __ATTR(release_region, 0600,
273 NULL, store_release_region); 327 show_release_region,
328 store_release_region);
274 329
275static int __init phyp_dump_setup(void) 330static int __init phyp_dump_setup(void)
276{ 331{
@@ -313,6 +368,22 @@ static int __init phyp_dump_setup(void)
313 return 0; 368 return 0;
314 } 369 }
315 370
371 /* re-register the dump area, if old dump was invalid */
372 if ((dump_header) && (dump_header->status & DUMP_ERROR_FLAG)) {
373 invalidate_last_dump(&phdr, dump_area_start);
374 register_dump_area(&phdr, dump_area_start);
375 return 0;
376 }
377
378 if (dump_header) {
379 phyp_dump_info->reserved_scratch_addr =
380 dump_header->cpu_data.destination_address;
381 phyp_dump_info->reserved_scratch_size =
382 dump_header->cpu_data.source_length +
383 dump_header->hpte_data.source_length +
384 dump_header->kernel_data.source_length;
385 }
386
316 /* Should we create a dump_subsys, analogous to s390/ipl.c ? */ 387 /* Should we create a dump_subsys, analogous to s390/ipl.c ? */
317 rc = sysfs_create_file(kernel_kobj, &rr.attr); 388 rc = sysfs_create_file(kernel_kobj, &rr.attr);
318 if (rc) 389 if (rc)