Files
s390-tools/zipl/boot/eckd2dump_sv.c
Mikhail Zaslonko 2363269c1c zipl/boot: Set the new version in the dumper and in the dump header
Since we are using the existing s390 extended dump format for compressed
dumps as well, set the version of the s390_ext dumper with compression
support and also dump header of the compressed dump to '2' (in order for
zgetdump to distinguish).

Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Acked-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-09-27 18:29:06 +02:00

161 lines
4.1 KiB
C

/*
* zipl - zSeries Initial Program Loader tool
*
* Single-volume ECKD DASD dump tool
*
* Copyright IBM Corp. 2013, 2023
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include "lib/zt_common.h"
#include "boot/boot_defs.h"
#include "boot/error.h"
#include "dump/s390_dump.h"
#include "eckd2dump.h"
#include "eckd2dump_zlib.h"
#include "stage2dump.h"
/*
* Magic number at start of dump record
*/
const uint64_t __section(.stage2.head) magic = 0x5845434b44363402ULL; /* "XECKD64", version 2 */
/*
* Get device characteristics from zipl parameter block
*/
void dt_device_parm_setup(void)
{
struct eckd_dump_param *parm = (void *) __stage2_desc;
device.blk_start = parm->blk_start;
device.blk_end = parm->blk_end;
device.blk_size = parm->blk_size;
device.num_heads = parm->num_heads;
device.bpt = parm->bpt;
device.sid = IPL_SC;
}
/*
* Enable DASD device
*/
void dt_device_enable(void)
{
io_irq_enable();
set_device(device.sid, ENABLED);
stage2dump_eckd_init();
}
static unsigned long dt_dump_mem_non_compressed(unsigned long addr,
unsigned long blk)
{
struct df_s390_dump_segm_hdr *dump_segm;
unsigned long end;
dump_segm = (void *)get_zeroed_page();
/* Write memory uncompressed */
end = dump_hdr->mem_size;
while (addr < end) {
addr = find_dump_segment(addr, end, 0, dump_segm);
blk = write_dump_segment(blk, dump_segm);
if (dump_segm->stop_marker) {
addr = end;
if (dump_segm->start + dump_segm->len < end)
progress_print(addr);
break;
}
}
free_page(__pa(dump_segm));
return blk;
}
static unsigned long dt_dump_mem_compressed(unsigned long addr,
unsigned long blk)
{
struct df_s390_dump_segm_hdr *dump_segm;
unsigned long end;
z_stream strm;
/* Write memory compressed with zlib deflate */
dump_segm = (void *)get_zeroed_page();
end = dump_hdr->mem_size;
/*
* Always write first megabyte of memory uncompressed in
* order to use it as zlib workarea
*/
dump_segm->start = addr;
dump_segm->len = ZLIB_WORKSPACE_LIMIT;
blk = write_dump_segment(blk, dump_segm);
addr += dump_segm->len;
/* Initialize zlib workarea, return value 0 is expected */
if (zlib_workarea_init(dump_segm->start, &strm)) {
printf("Zlib workarea initialization failed! Dumping without compression");
free_page(__pa(dump_segm));
return dt_dump_mem_non_compressed(addr, blk);
}
/*
* Compress on level 1 (hardware only) using default zlib
* wrapped stream.
*/
if (zlib_deflateInit2(&strm, 1, Z_DEFLATED, MAX_WBITS,
DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK) {
/*
* Could not allocate or initialyze a workarea for zlib deflate,
* continue dumping without compression.
*/
printf("Deflate initialization failed! Dumping without compression");
free_page(__pa(dump_segm));
return dt_dump_mem_non_compressed(addr, blk);
}
while (addr < end) {
/*
* Limit the max size of compressed dump segment in order to
* fit all the compressed chunk entries in the segment header.
*/
addr = find_dump_segment(addr, end, DUMP_SEGM_ZLIB_MAXLEN,
dump_segm);
blk = write_compressed_dump_segment(blk, dump_segm, &strm);
if (dump_segm->stop_marker) {
addr = end;
if (dump_segm->start + dump_segm->len < end)
progress_print(addr);
break;
}
}
zlib_deflateEnd(&strm);
free_page(__pa(dump_segm));
return blk;
}
/*
* Dump all memory to DASD partition.
* Use zlib compression if DFLTCC facility is available.
*/
void dt_dump_mem(void)
{
unsigned long blk, start, page;
total_dump_size = 0;
/* Write dump header */
blk = device.blk_start;
writeblock(blk, __pa(dump_hdr), m2b(DF_S390_HDR_SIZE), 0);
blk += m2b(DF_S390_HDR_SIZE);
/* Write memory starting from zero address */
start = 0;
/* Check for zlib flag in the dump header */
if (dump_hdr->zlib_version_s390) {
printf("DFLTCC facility available, using zlib compression");
blk = dt_dump_mem_compressed(start, blk);
} else {
blk = dt_dump_mem_non_compressed(start, blk);
}
/* Write end marker */
page = get_zeroed_page();
df_s390_em_page_init(page);
writeblock(blk, page, 1, 0);
blk++;
free_page(page);
}