mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zipl: Extend DASD stand-alone dumpers to drop zero pages
Update zipl DASD standalone dumpers for single-volume, multi-volume and FBA to drop the sets of zero pages when dumping memory to disk. Thus, all continuous sets of zero-megabytes in the memory are dropped during the dump stage. Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
54519b4465
commit
ac0ac48f6f
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Common ECKD dump I/O functions
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2017
|
||||
* Copyright IBM Corp. 2013, 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -444,6 +444,34 @@ void readblock(unsigned long blk, unsigned long addr, unsigned long blk_count)
|
||||
io_block(cmd, blk, addr, blk_count, 0, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write dump segment with the header to DASD and return the next free
|
||||
* block number
|
||||
*/
|
||||
unsigned long write_dump_segment(unsigned long blk,
|
||||
struct df_s390_dump_segm_hdr *segm,
|
||||
unsigned long zero_page)
|
||||
{
|
||||
unsigned long addr, start_blk, blk_count;
|
||||
|
||||
/* Write the dump segment header itself (1 page) */
|
||||
writeblock(blk, (unsigned long)segm, m2b(PAGE_SIZE), zero_page);
|
||||
blk += m2b(PAGE_SIZE);
|
||||
/* Write the dump segment */
|
||||
addr = segm->start;
|
||||
start_blk = blk;
|
||||
while (addr < segm->start + segm->len) {
|
||||
/* Remaining blocks to write */
|
||||
blk_count = m2b(segm->len) - (blk - start_blk);
|
||||
blk_count = MIN(blk_count, eckd_blk_max);
|
||||
writeblock(blk, addr, blk_count, zero_page);
|
||||
progress_print(addr);
|
||||
blk += blk_count;
|
||||
addr += b2m(blk_count);
|
||||
}
|
||||
return blk;
|
||||
}
|
||||
|
||||
/*
|
||||
* Init ECKD common
|
||||
*/
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Common ECKD dump I/O functions
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2017
|
||||
* Copyright IBM Corp. 2013, 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -12,6 +12,7 @@
|
||||
#define ECKD2DUMP_H
|
||||
|
||||
#include "cio.h"
|
||||
#include "stage2dump.h"
|
||||
|
||||
struct eckd_device {
|
||||
uint32_t blk_start;
|
||||
@@ -46,5 +47,8 @@ void stage2dump_eckd_init();
|
||||
void writeblock(unsigned long blk, unsigned long addr, unsigned long blk_count,
|
||||
unsigned long zero_page);
|
||||
void readblock(unsigned long blk, unsigned long addr, unsigned long blk_count);
|
||||
unsigned long write_dump_segment(unsigned long blk,
|
||||
struct df_s390_dump_segm_hdr *segm,
|
||||
unsigned long zero_page);
|
||||
|
||||
#endif /* ECKD2DUMP_H */
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Multi-volume ECKD DASD dump tool
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2017
|
||||
* Copyright IBM Corp. 2013, 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -13,14 +13,14 @@
|
||||
#include "error.h"
|
||||
#include "stage2dump.h"
|
||||
|
||||
#define MVDUMP_SIZE 0x3000 /* Size of dump record */
|
||||
#define MVDUMP_TOOL_SIZE 0x3000 /* Size of dump record */
|
||||
#define MAX_DUMP_VOLUMES 32 /* Up to 32 dump volumes possible */
|
||||
|
||||
/*
|
||||
* Magic number at start of dump record
|
||||
*/
|
||||
uint64_t magic __attribute__((section(".stage2.head")))
|
||||
= 0x5a4d554c54363405ULL; /* ZMULT64, version 5 */
|
||||
= 0x584d554c54363401ULL; /* XMULT64, version 1 */
|
||||
|
||||
/*
|
||||
* Parameter format for ECKD MV dumper (13 bytes):
|
||||
@@ -188,73 +188,117 @@ void dt_device_enable(void)
|
||||
stage2dump_eckd_init();
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for the volume timestamp and validate the dump signature
|
||||
* before writing a dump.
|
||||
*/
|
||||
static void check_volume(unsigned long page)
|
||||
{
|
||||
struct mvdump_parm_table *mvdump_table_new;
|
||||
struct df_s390_hdr *hdr_new;
|
||||
|
||||
/*
|
||||
* Check whether parameter table on dump device has a valid
|
||||
* time stamp. The parameter table is located right behind
|
||||
* the dump tool, the corresponding block number is:
|
||||
* MAGIC_BLK_ECKD + (MVDUMP_TOOL_SIZE / blocksize)
|
||||
*/
|
||||
mvdump_table_new = (void *) page;
|
||||
readblock(DF_S390_MAGIC_BLK_ECKD + m2b(MVDUMP_TOOL_SIZE),
|
||||
__pa(mvdump_table_new), 1);
|
||||
/*
|
||||
* Check if time stamps match
|
||||
*/
|
||||
if (mvdump_table.tod != mvdump_table_new->tod)
|
||||
panic(ENOTIME, "Inconsistent time stamps");
|
||||
/*
|
||||
* Check if dump partition has a valid dump signature.
|
||||
* Bypass signature check if "--force" had been specified during
|
||||
* zipl -M.
|
||||
*/
|
||||
hdr_new = (void *) page;
|
||||
if (!parm_tail.mvdump_force) {
|
||||
readblock(device.blk_start, __pa(hdr_new), 1);
|
||||
if (dump_hdr->magic != hdr_new->mvdump_sign)
|
||||
panic(ENOSIGN, "Wrong signature");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the dump header and memory to the current volume and return the next
|
||||
* address to write for the next volume or memory size if the dump ended
|
||||
* on this volume
|
||||
*/
|
||||
static unsigned long write_volume(unsigned long addr, unsigned long page,
|
||||
struct df_s390_dump_segm_hdr *dump_segm)
|
||||
{
|
||||
unsigned long free_space, blk;
|
||||
|
||||
/*
|
||||
* Write dump header
|
||||
*/
|
||||
blk = device.blk_start;
|
||||
writeblock(blk, __pa(dump_hdr), m2b(DF_S390_HDR_SIZE), 0);
|
||||
blk += m2b(DF_S390_HDR_SIZE);
|
||||
/*
|
||||
* The free space left on the volume minus 2 blocks (for the segment
|
||||
* header and the end marker)
|
||||
*/
|
||||
free_space = b2m(device.blk_end - blk + 1) - b2m(2);
|
||||
memset((void *) page, 0, PAGE_SIZE);
|
||||
/*
|
||||
* Write dump data
|
||||
*/
|
||||
while (addr < dump_hdr->mem_size) {
|
||||
/*
|
||||
* Find the next non-zero dump segment with the limit
|
||||
* of segment length set to the amount of free space left
|
||||
*/
|
||||
addr = find_dump_segment(addr, dump_hdr->mem_size,
|
||||
ROUND_DOWN(free_space, MIB),
|
||||
dump_segm);
|
||||
blk = write_dump_segment(blk, dump_segm, page);
|
||||
/* Update free space left on vol */
|
||||
free_space -= dump_segm->len;
|
||||
/* Reserve one block for the next segment header */
|
||||
if (free_space)
|
||||
free_space -= b2m(1);
|
||||
total_dump_size += dump_segm->len;
|
||||
/* Check if no more dump segments follow */
|
||||
if (dump_segm->stop_marker) {
|
||||
/* Write end marker */
|
||||
df_s390_em_page_init(page);
|
||||
writeblock(blk, page, 1, 0);
|
||||
return dump_hdr->mem_size;
|
||||
}
|
||||
/*
|
||||
* Go to the new volume if not enough space
|
||||
*/
|
||||
if (free_space < MIB)
|
||||
break;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump all memory to multiple DASD partitions
|
||||
*/
|
||||
void dt_dump_mem(void)
|
||||
{
|
||||
unsigned long blk, addr, addr_end, blk_num, dev_mem_size, page;
|
||||
struct mvdump_parm_table *mvdump_table_new;
|
||||
struct df_s390_hdr *hdr_new;
|
||||
struct df_s390_dump_segm_hdr *dump_segm;
|
||||
unsigned long addr, page;
|
||||
|
||||
dump_hdr->mvdump_sign = DF_S390_MAGIC;
|
||||
dump_hdr->mvdump_sign = DF_S390_MAGIC_EXT;
|
||||
dump_hdr->mvdump = 1;
|
||||
addr = 0;
|
||||
|
||||
total_dump_size = 0;
|
||||
page = get_zeroed_page();
|
||||
do {
|
||||
dump_segm = (void *)get_zeroed_page();
|
||||
|
||||
while (1) {
|
||||
printf("Dumping to: 0.%x.%04x", device.sid.ssid, device.devno);
|
||||
|
||||
/*
|
||||
* Check whether parameter table on dump device has a valid
|
||||
* time stamp. The parameter table is located right behind
|
||||
* the dump tool, the corresponding block number is:
|
||||
* MAGIC_BLOCK_OFFSET + (MVDUMP_TOOL_SIZE / blocksize)
|
||||
* So dump tool starts on track 0, block 3
|
||||
*/
|
||||
mvdump_table_new = (void *) page;
|
||||
readblock(3 + MVDUMP_SIZE / 0x1000,
|
||||
__pa(mvdump_table_new), m2b(0x1000));
|
||||
/*
|
||||
* Check if time stamps match
|
||||
*/
|
||||
if (mvdump_table.tod != mvdump_table_new->tod)
|
||||
panic(ENOTIME, "Inconsistent time stamps");
|
||||
|
||||
/*
|
||||
* Check if dump partition has a valid dump signature.
|
||||
* Bypass signature check if "--force" had been specified during
|
||||
* zipl -M.
|
||||
*/
|
||||
hdr_new = (void *) page;
|
||||
if (!parm_tail.mvdump_force) {
|
||||
readblock(device.blk_start, __pa(hdr_new), 1);
|
||||
if (dump_hdr->magic != hdr_new->mvdump_sign)
|
||||
panic(ENOSIGN, "Wrong signature");
|
||||
}
|
||||
|
||||
/*
|
||||
* Write dump header
|
||||
*/
|
||||
blk = device.blk_start;
|
||||
writeblock(blk, __pa(dump_hdr), m2b(DF_S390_HDR_SIZE), 0);
|
||||
blk += m2b(DF_S390_HDR_SIZE);
|
||||
|
||||
dev_mem_size = b2m(device.blk_end - blk + 1);
|
||||
addr_end = MIN(dump_hdr->mem_size, addr + dev_mem_size);
|
||||
|
||||
/*
|
||||
* Write memory
|
||||
*/
|
||||
memset((void *) page, 0, PAGE_SIZE);
|
||||
while (addr < addr_end) {
|
||||
blk_num = MIN(eckd_blk_max, device.blk_end - blk + 1);
|
||||
blk_num = MIN(m2b(addr_end - addr), blk_num);
|
||||
writeblock(blk, addr, blk_num, page);
|
||||
progress_print(addr);
|
||||
blk += blk_num;
|
||||
addr += b2m(blk_num);
|
||||
}
|
||||
check_volume(page);
|
||||
addr = write_volume(addr, page, dump_segm);
|
||||
if (addr == dump_hdr->mem_size)
|
||||
break;
|
||||
/*
|
||||
@@ -267,12 +311,8 @@ void dt_dump_mem(void)
|
||||
dt_device_parm_setup();
|
||||
set_device(device.sid, DISABLED);
|
||||
dt_device_enable();
|
||||
} while (1);
|
||||
}
|
||||
progress_print(addr);
|
||||
/*
|
||||
* Write end marker
|
||||
*/
|
||||
df_s390_em_page_init(page);
|
||||
writeblock(blk, page, 1, 0);
|
||||
free_page(page);
|
||||
free_page(__pa(dump_segm));
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Single-volume ECKD DASD dump tool
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2017
|
||||
* Copyright IBM Corp. 2013, 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -17,7 +17,7 @@
|
||||
* Magic number at start of dump record
|
||||
*/
|
||||
uint64_t magic __attribute__((section(".stage2.head"))) =
|
||||
0x5a45434b44363404ULL; /* "ZECKD64", version 4 */
|
||||
0x5845434b44363401ULL; /* "XECKD64", version 1 */
|
||||
|
||||
/*
|
||||
* ECKD parameter block passed by zipl
|
||||
@@ -61,20 +61,29 @@ void dt_device_enable(void)
|
||||
*/
|
||||
void dt_dump_mem(void)
|
||||
{
|
||||
unsigned long blk, addr, page;
|
||||
unsigned long blk, addr, end, page;
|
||||
struct df_s390_dump_segm_hdr *dump_segm;
|
||||
|
||||
blk = device.blk_start;
|
||||
page = get_zeroed_page();
|
||||
dump_segm = (void *)get_zeroed_page();
|
||||
|
||||
/* Write dump header */
|
||||
writeblock(blk, __pa(dump_hdr), m2b(DF_S390_HDR_SIZE), 0);
|
||||
blk += m2b(DF_S390_HDR_SIZE);
|
||||
|
||||
/* Write memory */
|
||||
for (addr = 0; addr < dump_hdr->mem_size; addr += b2m(eckd_blk_max)) {
|
||||
writeblock(blk, addr, eckd_blk_max, page);
|
||||
progress_print(addr);
|
||||
blk += eckd_blk_max;
|
||||
addr = 0;
|
||||
total_dump_size = 0;
|
||||
end = dump_hdr->mem_size;
|
||||
while (addr < end) {
|
||||
addr = find_dump_segment(addr, end, 0, dump_segm);
|
||||
blk = write_dump_segment(blk, dump_segm, page);
|
||||
total_dump_size += dump_segm->len;
|
||||
if (dump_segm->stop_marker) {
|
||||
addr = end;
|
||||
break;
|
||||
}
|
||||
}
|
||||
progress_print(addr);
|
||||
|
||||
@@ -82,4 +91,5 @@ void dt_dump_mem(void)
|
||||
df_s390_em_page_init(page);
|
||||
writeblock(blk, page, 1, 0);
|
||||
free_page(page);
|
||||
free_page(__pa(dump_segm));
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Single-volume FBA DASD dump tool
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2017
|
||||
* Copyright IBM Corp. 2013, 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -13,14 +13,15 @@
|
||||
#include "fba.h"
|
||||
#include "stage2dump.h"
|
||||
|
||||
#define BLK_PWRT 64 /* Blocks per write */
|
||||
#define BLK_SIZE 0x200 /* FBA block size */
|
||||
#define BLK_PWRT 64 /* Blocks per write */
|
||||
#define BLK_SIZE 0x200 /* FBA block size */
|
||||
#define BLK_PER_PAGE (PAGE_SIZE / BLK_SIZE) /* FBA blocks per page */
|
||||
|
||||
/*
|
||||
* Magic number at start of dump record
|
||||
*/
|
||||
uint64_t magic __attribute__((section(".stage2.head")))
|
||||
= 0x5a44464241363404ULL; /* ZDFBA64, version 4 */
|
||||
= 0x5844464241363401ULL; /* XDFBA64, version 1 */
|
||||
|
||||
/*
|
||||
* FBA dump device partition specification
|
||||
@@ -120,8 +121,8 @@ void dt_device_enable(void)
|
||||
/*
|
||||
* Write memory with number of blocks to start block
|
||||
*/
|
||||
static void writeblock(unsigned long blk, unsigned long addr, unsigned long blk_count,
|
||||
unsigned long zero_page)
|
||||
static void writeblock_fba(unsigned long blk, unsigned long addr,
|
||||
unsigned long blk_count, unsigned long zero_page)
|
||||
{
|
||||
unsigned long blk_end;
|
||||
|
||||
@@ -135,6 +136,35 @@ static void writeblock(unsigned long blk, unsigned long addr, unsigned long blk_
|
||||
start_io(IPL_SC, &irb, &orb, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write dump segment with the header to FBA and return the next free
|
||||
* block number
|
||||
*/
|
||||
unsigned long write_dump_segment_fba(unsigned long blk,
|
||||
struct df_s390_dump_segm_hdr *dump_segm,
|
||||
unsigned long zero_page)
|
||||
{
|
||||
unsigned long addr, start_blk, blk_count;
|
||||
|
||||
/* Write the dump segment header itself (1 page) */
|
||||
writeblock_fba(blk, __pa(dump_segm), BLK_PER_PAGE, zero_page);
|
||||
blk += BLK_PER_PAGE;
|
||||
/* Write the dump segment */
|
||||
addr = dump_segm->start;
|
||||
start_blk = blk;
|
||||
while (addr < dump_segm->start + dump_segm->len) {
|
||||
/* Remaining blocks to write */
|
||||
blk_count = m2b(dump_segm->len) - (blk - start_blk);
|
||||
blk_count = MIN(blk_count, BLK_PWRT);
|
||||
writeblock_fba(blk, addr, blk_count, zero_page);
|
||||
progress_print(addr);
|
||||
blk += blk_count;
|
||||
addr += b2m(blk_count);
|
||||
}
|
||||
return blk;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the CCW program
|
||||
*/
|
||||
@@ -163,26 +193,36 @@ static void ccw_program_init(void)
|
||||
*/
|
||||
void dt_dump_mem(void)
|
||||
{
|
||||
unsigned long blk, addr, page;
|
||||
struct df_s390_dump_segm_hdr *dump_segm;
|
||||
unsigned long blk, addr, end, page;
|
||||
|
||||
ccw_program_init();
|
||||
blk = device.blk_start;
|
||||
page = get_zeroed_page();
|
||||
dump_segm = (void *)get_zeroed_page();
|
||||
|
||||
/* Write dump header */
|
||||
writeblock(blk, __pa(dump_hdr), m2b(DF_S390_HDR_SIZE), 0);
|
||||
blk += DF_S390_HDR_SIZE / BLK_SIZE;
|
||||
writeblock_fba(blk, __pa(dump_hdr), m2b(DF_S390_HDR_SIZE), 0);
|
||||
blk += m2b(DF_S390_HDR_SIZE);
|
||||
|
||||
/* Write memory */
|
||||
for (addr = 0; addr < dump_hdr->mem_size; addr += b2m(BLK_PWRT)) {
|
||||
writeblock(blk, addr, BLK_PWRT, page);
|
||||
progress_print(addr);
|
||||
blk += BLK_PWRT;
|
||||
addr = 0;
|
||||
total_dump_size = 0;
|
||||
end = dump_hdr->mem_size;
|
||||
while (addr < end) {
|
||||
addr = find_dump_segment(addr, end, 0, dump_segm);
|
||||
blk = write_dump_segment_fba(blk, dump_segm, page);
|
||||
total_dump_size += dump_segm->len;
|
||||
if (dump_segm->stop_marker) {
|
||||
addr = end;
|
||||
break;
|
||||
}
|
||||
}
|
||||
progress_print(addr);
|
||||
|
||||
/* Write end marker */
|
||||
df_s390_em_page_init(page);
|
||||
writeblock(blk, page, 1, 0);
|
||||
writeblock_fba(blk, page, 1, 0);
|
||||
free_page(page);
|
||||
free_page(__pa(dump_segm));
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Common functions for stand-alone dump tools
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2017
|
||||
* Copyright IBM Corp. 2013, 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -45,6 +45,7 @@ struct stage2dump_parm_tail parm_tail
|
||||
* Globals
|
||||
*/
|
||||
struct df_s390_hdr *dump_hdr;
|
||||
unsigned long total_dump_size;
|
||||
|
||||
/*
|
||||
* Init dumper: Allocate standard pages, set timers
|
||||
@@ -86,6 +87,112 @@ void progress_print(unsigned long addr)
|
||||
progress_next_addr += progress_inc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if one MB memory after addr is zero
|
||||
*/
|
||||
static int __is_zero_mb(unsigned long addr)
|
||||
{
|
||||
register unsigned long _addr1 asm("2") = (unsigned long) addr;
|
||||
register unsigned long _len1 asm("3") = (unsigned long) MIB;
|
||||
register unsigned long _addr2 asm("4") = (unsigned long) addr;
|
||||
register unsigned long _len2 asm("5") = (unsigned long) 0;
|
||||
unsigned int ipm;
|
||||
|
||||
asm volatile(
|
||||
"0: clcle %1,%3,0(0)\n"
|
||||
" jo 0b\n"
|
||||
" ipm %0\n"
|
||||
" srl %0,28\n"
|
||||
: "=d" (ipm), "+d" (_addr1), "+d" (_len1), "+d" (_addr2), "+d" (_len2)
|
||||
:
|
||||
: "cc");
|
||||
return !ipm;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the megabyte contains all zeroes.
|
||||
*/
|
||||
int is_zero_mb(unsigned long addr)
|
||||
{
|
||||
if (!page_is_valid(addr))
|
||||
return 1;
|
||||
if (__is_zero_mb(addr))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find next non-zero megabyte in the address range
|
||||
*/
|
||||
static unsigned long find_next_non_zero(unsigned long start, unsigned long end)
|
||||
{
|
||||
while (start < end) {
|
||||
if (!is_zero_mb(start))
|
||||
break;
|
||||
start += MIB;
|
||||
}
|
||||
if (start > end)
|
||||
start = end;
|
||||
return start;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find next zero megabyte in the address range
|
||||
*/
|
||||
static unsigned long find_next_zero(unsigned long start, unsigned long end)
|
||||
{
|
||||
while (start < end) {
|
||||
if (is_zero_mb(start))
|
||||
break;
|
||||
start += MIB;
|
||||
}
|
||||
if (start > end)
|
||||
start = end;
|
||||
return start;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find first continuous set of non-zero megabytes in the specified
|
||||
* address range and update *dump_segm structure accordingly. The segment's
|
||||
* length is truncated to max_len if required. Afterwards, look for the next
|
||||
* non-zero megabyte. Return the address of the next non-zero megabyte or zero
|
||||
* if no more follow.
|
||||
*/
|
||||
unsigned long find_dump_segment(unsigned long start, unsigned long end,
|
||||
unsigned long max_len,
|
||||
struct df_s390_dump_segm_hdr *dump_segm)
|
||||
{
|
||||
unsigned long addr, limit;
|
||||
|
||||
memset(dump_segm, 0, sizeof(*dump_segm));
|
||||
/* Check the input values for MB alingment */
|
||||
if (!IS_ALIGNED(start, MIB) || !IS_ALIGNED(max_len, MIB))
|
||||
panic(EINTERNAL, "start or max_len not MB aligned");
|
||||
/* Search for dump segment start */
|
||||
addr = find_next_non_zero(start, end);
|
||||
if (addr == end)
|
||||
goto out;
|
||||
dump_segm->start = addr;
|
||||
/* Search for dump segment end */
|
||||
limit = end;
|
||||
if (max_len)
|
||||
limit = MIN(addr + max_len, end);
|
||||
addr = find_next_zero(dump_segm->start, limit);
|
||||
dump_segm->len = addr - dump_segm->start;
|
||||
/* Search for next dump segment start */
|
||||
addr = find_next_non_zero(addr, end);
|
||||
/* Return the start address of the next segment */
|
||||
if (addr < end)
|
||||
return addr;
|
||||
out:
|
||||
/*
|
||||
* Set the stop-marker indicating no more non-zero
|
||||
* segments in the address range
|
||||
*/
|
||||
dump_segm->stop_marker = -1UL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create IDA list starting at "addr" with "len" bytes
|
||||
*/
|
||||
@@ -113,11 +220,11 @@ static void df_s390_dump_init(void)
|
||||
{
|
||||
struct df_s390_hdr *dh = dump_hdr;
|
||||
|
||||
dh->magic = DF_S390_MAGIC;
|
||||
dh->magic = DF_S390_MAGIC_EXT;
|
||||
dh->hdr_size = DF_S390_HDR_SIZE;
|
||||
dh->page_size = PAGE_SIZE;
|
||||
dh->dump_level = 4;
|
||||
dh->version = 5;
|
||||
dh->version = 1;
|
||||
dh->mem_start = 0;
|
||||
dh->arch = DF_S390_ARCH_64;
|
||||
dh->build_arch = DF_S390_ARCH_64;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Common dump functions
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2017
|
||||
* Copyright IBM Corp. 2013, 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "s390.h"
|
||||
|
||||
#define IPL_SC *((struct subchannel_id *) &S390_lowcore.subchannel_id)
|
||||
#define ROUND_DOWN(x, a) ((x) & ~((typeof(x))(a) - 1))
|
||||
#define IS_ALIGNED(x, a) ~((x) & ((typeof(x))(a) - 1))
|
||||
|
||||
/*
|
||||
* zipl parameters passed at tail of dump tools
|
||||
@@ -33,6 +35,7 @@ extern struct stage2dump_parm_tail parm_tail
|
||||
* S390 dump format defines
|
||||
*/
|
||||
#define DF_S390_MAGIC 0xa8190173618f23fdULL
|
||||
#define DF_S390_MAGIC_EXT 0xa8190173618f23feULL
|
||||
#define DF_S390_HDR_SIZE 0x1000
|
||||
#define DF_S390_EM_SIZE 16
|
||||
#define DF_S390_EM_MAGIC 0x44554d505f454e44ULL
|
||||
@@ -85,6 +88,15 @@ struct df_s390_em {
|
||||
uint64_t tod;
|
||||
} __packed __aligned(16);
|
||||
|
||||
/*
|
||||
* Dump segment header
|
||||
*/
|
||||
struct df_s390_dump_segm_hdr {
|
||||
uint64_t start;
|
||||
uint64_t len;
|
||||
uint64_t stop_marker;
|
||||
};
|
||||
|
||||
/*
|
||||
* Linker script defined symbols
|
||||
*/
|
||||
@@ -95,6 +107,7 @@ extern char __stage2_desc[];
|
||||
* Dump common globals
|
||||
*/
|
||||
extern struct df_s390_hdr *dump_hdr;
|
||||
extern unsigned long total_dump_size;
|
||||
|
||||
/*
|
||||
* Common functions
|
||||
@@ -105,6 +118,10 @@ void init_progress_print(void);
|
||||
void progress_print(unsigned long addr);
|
||||
void df_s390_em_page_init(unsigned long page);
|
||||
void pgm_check_handler(void);
|
||||
int is_zero_mb(unsigned long addr);
|
||||
unsigned long find_dump_segment(unsigned long start, unsigned long end,
|
||||
unsigned long max_len,
|
||||
struct df_s390_dump_segm_hdr *dump_segm);
|
||||
|
||||
/*
|
||||
* Dump tool backend functions
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Functions handling the installation of the boot loader code onto disk
|
||||
*
|
||||
* Copyright IBM Corp. 2001, 2017
|
||||
* Copyright IBM Corp. 2001, 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -636,7 +636,7 @@ overwrite_partition_start(int fd, struct disk_info* info, int mv_dump_magic)
|
||||
unsigned int bytes = 65536;
|
||||
char* buffer;
|
||||
const char dump_magic[] = {0xa8, 0x19, 0x01, 0x73,
|
||||
0x61, 0x8f, 0x23, 0xfd};
|
||||
0x61, 0x8f, 0x23, 0xfe};
|
||||
|
||||
if (misc_seek(fd, info->geo.start * info->phy_block_size))
|
||||
return -1;
|
||||
|
||||
Reference in New Issue
Block a user