From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from e35.co.us.ibm.com (e35.co.us.ibm.com [32.97.110.153]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "e35.co.us.ibm.com", Issuer "Equifax" (verified OK)) by ozlabs.org (Postfix) with ESMTP id 2CEC2DDE33 for ; Tue, 12 Feb 2008 18:14:45 +1100 (EST) Received: from d03relay04.boulder.ibm.com (d03relay04.boulder.ibm.com [9.17.195.106]) by e35.co.us.ibm.com (8.13.8/8.13.8) with ESMTP id m1C7Eg8o010790 for ; Tue, 12 Feb 2008 02:14:42 -0500 Received: from d03av03.boulder.ibm.com (d03av03.boulder.ibm.com [9.17.195.169]) by d03relay04.boulder.ibm.com (8.13.8/8.13.8/NCO v8.7) with ESMTP id m1C7Eg1W178452 for ; Tue, 12 Feb 2008 00:14:42 -0700 Received: from d03av03.boulder.ibm.com (loopback [127.0.0.1]) by d03av03.boulder.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id m1C7EfE8016789 for ; Tue, 12 Feb 2008 00:14:42 -0700 Message-ID: <47B14760.2030001@austin.ibm.com> Date: Tue, 12 Feb 2008 01:14:40 -0600 From: Manish Ahuja MIME-Version: 1.0 To: linuxppc-dev@ozlabs.org, paulus@samba.org Subject: [PATCH 4/8] pseries: phyp dump: register dump area. References: <4782B985.2090508@austin.ibm.com> <47B13D2E.1070001@austin.ibm.com> In-Reply-To: <47B13D2E.1070001@austin.ibm.com> Content-Type: text/plain; charset=us-ascii Cc: mahuja@us.ibm.com, linasvepstas@gmail.com List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Set up the actual dump header, register it with the hypervisor. Signed-off-by: Manish Ahuja Signed-off-by: Linas Vepstas ------ arch/powerpc/platforms/pseries/phyp_dump.c | 136 +++++++++++++++++++++++++++-- 1 file changed, 129 insertions(+), 7 deletions(-) Index: 2.6.24-rc5/arch/powerpc/platforms/pseries/phyp_dump.c =================================================================== --- 2.6.24-rc5.orig/arch/powerpc/platforms/pseries/phyp_dump.c 2008-02-12 06:12:55.000000000 -0600 +++ 2.6.24-rc5/arch/powerpc/platforms/pseries/phyp_dump.c 2008-02-12 06:13:01.000000000 -0600 @@ -30,6 +30,117 @@ struct phyp_dump *phyp_dump_info = &phyp static int ibm_configure_kernel_dump; /* ------------------------------------------------- */ +/* RTAS interfaces to declare the dump regions */ + +struct dump_section { + u32 dump_flags; + u16 source_type; + u16 error_flags; + u64 source_address; + u64 source_length; + u64 length_copied; + u64 destination_address; +}; + +struct phyp_dump_header { + u32 version; + u16 num_of_sections; + u16 status; + + u32 first_offset_section; + u32 dump_disk_section; + u64 block_num_dd; + u64 num_of_blocks_dd; + u32 offset_dd; + u32 maxtime_to_auto; + /* No dump disk path string used */ + + struct dump_section cpu_data; + struct dump_section hpte_data; + struct dump_section kernel_data; +}; + +/* The dump header *must be* in low memory, so .bss it */ +static struct phyp_dump_header phdr; + +#define NUM_DUMP_SECTIONS 3 +#define DUMP_HEADER_VERSION 0x1 +#define DUMP_REQUEST_FLAG 0x1 +#define DUMP_SOURCE_CPU 0x0001 +#define DUMP_SOURCE_HPTE 0x0002 +#define DUMP_SOURCE_RMO 0x0011 + +/** + * init_dump_header() - initialize the header declaring a dump + * Returns: length of dump save area. + * + * When the hypervisor saves crashed state, it needs to put + * it somewhere. The dump header tells the hypervisor where + * the data can be saved. + */ +static unsigned long init_dump_header(struct phyp_dump_header *ph) +{ + unsigned long addr_offset = 0; + + /* Set up the dump header */ + ph->version = DUMP_HEADER_VERSION; + ph->num_of_sections = NUM_DUMP_SECTIONS; + ph->status = 0; + + ph->first_offset_section = + (u32)offsetof(struct phyp_dump_header, cpu_data); + ph->dump_disk_section = 0; + ph->block_num_dd = 0; + ph->num_of_blocks_dd = 0; + ph->offset_dd = 0; + + ph->maxtime_to_auto = 0; /* disabled */ + + /* The first two sections are mandatory */ + ph->cpu_data.dump_flags = DUMP_REQUEST_FLAG; + ph->cpu_data.source_type = DUMP_SOURCE_CPU; + ph->cpu_data.source_address = 0; + ph->cpu_data.source_length = phyp_dump_info->cpu_state_size; + ph->cpu_data.destination_address = addr_offset; + addr_offset += phyp_dump_info->cpu_state_size; + + ph->hpte_data.dump_flags = DUMP_REQUEST_FLAG; + ph->hpte_data.source_type = DUMP_SOURCE_HPTE; + ph->hpte_data.source_address = 0; + ph->hpte_data.source_length = phyp_dump_info->hpte_region_size; + ph->hpte_data.destination_address = addr_offset; + addr_offset += phyp_dump_info->hpte_region_size; + + /* This section describes the low kernel region */ + ph->kernel_data.dump_flags = DUMP_REQUEST_FLAG; + ph->kernel_data.source_type = DUMP_SOURCE_RMO; + ph->kernel_data.source_address = PHYP_DUMP_RMR_START; + ph->kernel_data.source_length = PHYP_DUMP_RMR_END; + ph->kernel_data.destination_address = addr_offset; + addr_offset += ph->kernel_data.source_length; + + return addr_offset; +} + +static void register_dump_area(struct phyp_dump_header *ph, unsigned long addr) +{ + int rc; + ph->cpu_data.destination_address += addr; + ph->hpte_data.destination_address += addr; + ph->kernel_data.destination_address += addr; + + do { + rc = rtas_call(ibm_configure_kernel_dump, 3, 1, NULL, + 1, ph, sizeof(struct phyp_dump_header)); + } while (rtas_busy_delay(rc)); + + if (rc) + { + printk (KERN_ERR "phyp-dump: unexpected error (%d) on register\n", rc); + } +} + +/* ------------------------------------------------- */ /** * release_memory_range -- release memory previously lmb_reserved * @start_pfn: starting physical frame number @@ -113,7 +224,9 @@ static struct subsys_attribute rr = __AT static int __init phyp_dump_setup(void) { struct device_node *rtas; - const int *dump_header; + const struct phyp_dump_header *dump_header; + unsigned long dump_area_start; + unsigned long dump_area_length; int header_len = 0; int rc; @@ -126,22 +239,31 @@ static int __init phyp_dump_setup(void) return -ENOSYS; } - /* Is there dump data waiting for us? */ + /* Is there dump data waiting for us? If there isn't, + * then register a new dump area, and release all of + * the rest of the reserved ram. + * + * The /rtas/ibm,kernel-dump rtas node is present only + * if there is dump data waiting for us. + */ rtas = of_find_node_by_path("/rtas"); dump_header = of_get_property(rtas, "ibm,kernel-dump", &header_len); + of_node_put(rtas); + + dump_area_length = init_dump_header(&phdr); + dump_area_start = phyp_dump_info->init_reserve_start & PAGE_MASK; /* align down */ + if (dump_header == NULL) { - release_all(); + register_dump_area(&phdr, dump_area_start); return 0; } /* Should we create a dump_subsys, analogous to s390/ipl.c ? */ rc = subsys_create_file(&kernel_subsys, &rr); - if (rc) { + if (rc) printk (KERN_ERR "phyp-dump: unable to create sysfs file (%d)\n", rc); - release_all(); - return 0; - } + /* ToDo: re-register the dump area, for next time. */ return 0; } subsys_initcall(phyp_dump_setup);