staticstruct read_info_sccb __bootdata(sclp_info_sccb); staticint __bootdata(sclp_info_sccb_valid); char *__bootdata_preserved(sclp_early_sccb); int sclp_init_state = sclp_init_state_uninitialized; /* * Used to keep track of the size of the event masks. Qemu until version 2.11 * only supports 4 and needs a workaround.
*/ bool sclp_mask_compat_mode;
/* * Output one or more lines of text on the SCLP console (VT220 and / * or line-mode).
*/ void __sclp_early_printk(constchar *str, unsignedint len)
{ int have_linemode, have_vt220;
if (sclp_init_state != sclp_init_state_uninitialized) return; if (sclp_early_setup(0, &have_linemode, &have_vt220) != 0) return; if (have_linemode)
sclp_early_print_lm(str, len); if (have_vt220)
sclp_early_print_vt220(str, len);
sclp_early_setup(1, &have_linemode, &have_vt220);
}
/* * Use sclp_emergency_printk() to print a string when the system is in a * state where regular console drivers cannot be assumed to work anymore. * * Callers must make sure that no concurrent SCLP requests are outstanding * and all other CPUs are stopped, or at least disabled for external * interrupts.
*/ void sclp_emergency_printk(constchar *str)
{ int have_linemode, have_vt220; unsignedint len;
len = strlen(str); /* * Don't care about return values; if requests fail, just ignore and * continue to have a rather high chance that anything is printed.
*/
sclp_early_setup(0, &have_linemode, &have_vt220);
sclp_early_print_lm(str, len);
sclp_early_print_vt220(str, len);
sclp_early_setup(1, &have_linemode, &have_vt220);
}
/* * We can't pass sclp_info_sccb to sclp_early_cmd() here directly, * because it might not fulfil the requiremets for a SCLP communication buffer: * - lie below 2G in memory * - be page-aligned * Therefore, we use the buffer sclp_early_sccb (which fulfils all those * requirements) temporarily for communication and copy a received response * back into the buffer sclp_info_sccb upon successful completion.
*/ int __init sclp_early_read_info(void)
{ int i; int length = test_facility(140) ? EXT_SCCB_READ_SCP : PAGE_SIZE; struct read_info_sccb *sccb = (struct read_info_sccb *)sclp_early_sccb;
sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED,
SCLP_CMDW_READ_SCP_INFO};
for (i = 0; i < ARRAY_SIZE(commands); i++) {
memset(sccb, 0, length);
sccb->header.length = length;
sccb->header.function_code = 0x80;
sccb->header.control_mask[2] = 0x80; if (sclp_early_cmd(commands[i], sccb)) break; if (sccb->header.response_code == 0x10) {
memcpy(&sclp_info_sccb, sccb, length);
sclp_info_sccb_valid = 1; return 0;
} if (sccb->header.response_code != 0x1f0) break;
} return -EIO;
}
struct read_info_sccb * __init sclp_early_get_info(void)
{ if (!sclp_info_sccb_valid) return NULL;
if (!sclp_info_sccb_valid) return; if (sccb->fac85 & 0x02)
set_machine_feature(MFEATURE_ESOP); if (sccb->fac91 & 0x40)
set_machine_feature(MFEATURE_TLB_GUEST);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.