Skip to content

Commit

Permalink
s390/sclp: make early sclp code readable
Browse files Browse the repository at this point in the history
This patch

 - unifies the old sclp early code and the sclp early printk code, so
   they can use common functions

 - makes sure all sclp early functions and variables have the same
   "sclp_early" prefix

 - converts the sclp early printk code into readable code by using
   existing data structures instead of hard coded magic arrays

 - splits the early sclp code into two files: sclp_early.c and
   sclp_early_core.c. The core file contains everything that is
   required by the kernel decompressor and may not call functions not
   contained within the core file. Otherwise the result would be a
   link error.

 - changes interrupt handling to be completely synchronous. The old
   early sclp code had a small window which allowed to receive several
   interrupts instead of exactly the single expected interrupt. This
   did hide a subtle potential bug, which is fixed with this large
   rework.

 - contains a couple of small cleanups.

Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
  • Loading branch information
Heiko Carstens authored and Martin Schwidefsky committed Feb 8, 2017
1 parent 76fdf14 commit d5ab7a3
Show file tree
Hide file tree
Showing 10 changed files with 244 additions and 295 deletions.
2 changes: 1 addition & 1 deletion arch/s390/boot/compressed/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static unsigned long free_mem_end_ptr;

static int puts(const char *s)
{
_sclp_print_early(s);
sclp_early_printk(s);
return 0;
}

Expand Down
13 changes: 7 additions & 6 deletions arch/s390/include/asm/sclp.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,12 @@ struct zpci_report_error_header {
u8 data[0]; /* Subsequent Data passed verbatim to SCLP ET 24 */
} __packed;

int _sclp_get_core_info_early(struct sclp_core_info *info);
int sclp_early_get_core_info(struct sclp_core_info *info);
void sclp_early_get_ipl_info(struct sclp_ipl_info *info);
void sclp_early_detect(void);
void sclp_early_printk(const char *s);
void __sclp_early_printk(const char *s, unsigned int len);

int _sclp_get_core_info(struct sclp_core_info *info);
int sclp_core_configure(u8 core);
int sclp_core_deconfigure(u8 core);
Expand All @@ -110,21 +115,17 @@ int sclp_sdias_copy(void *dest, int blk_num, int nr_blks);
int sclp_chp_configure(struct chp_id chpid);
int sclp_chp_deconfigure(struct chp_id chpid);
int sclp_chp_read_info(struct sclp_chp_info *info);
void sclp_get_ipl_info(struct sclp_ipl_info *info);
int sclp_pci_configure(u32 fid);
int sclp_pci_deconfigure(u32 fid);
int sclp_pci_report(struct zpci_report_error_header *report, u32 fh, u32 fid);
int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count);
int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count);
void sclp_early_detect(void);
void _sclp_print_early(const char *);
void __sclp_print_early(const char *s, unsigned int len);
void sclp_ocf_cpc_name_copy(char *dst);

static inline int sclp_get_core_info(struct sclp_core_info *info, int early)
{
if (early)
return _sclp_get_core_info_early(info);
return sclp_early_get_core_info(info);
return _sclp_get_core_info(info);
}

Expand Down
10 changes: 5 additions & 5 deletions arch/s390/kernel/als.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ static void __init print_machine_type(void)
get_cpu_id(&id);
u16_to_hex(type_str, id.machine);
strcat(mach_str, type_str);
_sclp_print_early(mach_str);
sclp_early_printk(mach_str);
}

static void __init u16_to_decimal(char *str, u16 val)
Expand Down Expand Up @@ -79,21 +79,21 @@ static void __init print_missing_facilities(void)
* z/VM adds a four character prefix.
*/
if (strlen(als_str) > 70) {
_sclp_print_early(als_str);
sclp_early_printk(als_str);
*als_str = '\0';
}
u16_to_decimal(val_str, i * BITS_PER_LONG + j);
strcat(als_str, val_str);
first = 0;
}
}
_sclp_print_early(als_str);
_sclp_print_early("See Principles of Operations for facility bits");
sclp_early_printk(als_str);
sclp_early_printk("See Principles of Operations for facility bits");
}

static void __init facility_mismatch(void)
{
_sclp_print_early("The Linux kernel requires more recent processor hardware");
sclp_early_printk("The Linux kernel requires more recent processor hardware");
print_machine_type();
print_missing_facilities();
disabled_wait(0x8badcccc);
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/kernel/early_printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

static void sclp_early_write(struct console *con, const char *s, unsigned int len)
{
__sclp_print_early(s, len);
__sclp_early_printk(s, len);
}

static struct console sclp_early_console = {
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/kernel/ipl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1864,7 +1864,7 @@ static int __init s390_ipl_init(void)
{
char str[8] = {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40};

sclp_get_ipl_info(&sclp_ipl_info);
sclp_early_get_ipl_info(&sclp_ipl_info);
/*
* Fix loadparm: There are systems where the (SCSI) LOADPARM
* returned by read SCP info is invalid (contains EBCDIC blanks)
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/kernel/swsusp.S
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ pgm_check_entry:
larl %r15,init_thread_union
ahi %r15,1<<(PAGE_SHIFT+THREAD_SIZE_ORDER)
larl %r2,.Lpanic_string
larl %r3,_sclp_print_early
larl %r3,sclp_early_printk
lghi %r1,0
sam31
sigp %r1,%r0,SIGP_SET_ARCHITECTURE
Expand Down
25 changes: 0 additions & 25 deletions drivers/s390/char/sclp.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,31 +140,6 @@ static void __sclp_make_read_req(void);
static int sclp_init_mask(int calculate);
static int sclp_init(void);

/* Perform service call. Return 0 on success, non-zero otherwise. */
int
sclp_service_call(sclp_cmdw_t command, void *sccb)
{
int cc = 4; /* Initialize for program check handling */

asm volatile(
"0: .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */
"1: ipm %0\n"
" srl %0,28\n"
"2:\n"
EX_TABLE(0b, 2b)
EX_TABLE(1b, 2b)
: "+&d" (cc) : "d" (command), "a" (__pa(sccb))
: "cc", "memory");
if (cc == 4)
return -EINVAL;
if (cc == 3)
return -EIO;
if (cc == 2)
return -EBUSY;
return 0;
}


static void
__sclp_queue_read_req(void)
{
Expand Down
34 changes: 33 additions & 1 deletion drivers/s390/char/sclp.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,6 @@ void sclp_unregister(struct sclp_register *reg);
int sclp_remove_processed(struct sccb_header *sccb);
int sclp_deactivate(void);
int sclp_reactivate(void);
int sclp_service_call(sclp_cmdw_t command, void *sccb);
int sclp_sync_request(sclp_cmdw_t command, void *sccb);
int sclp_sync_request_timeout(sclp_cmdw_t command, void *sccb, int timeout);

Expand All @@ -222,8 +221,41 @@ extern int sclp_console_pages;
extern int sclp_console_drop;
extern unsigned long sclp_console_full;

extern char sclp_early_sccb[PAGE_SIZE];

void sclp_early_wait_irq(void);
int sclp_early_cmd_sync(sclp_cmdw_t cmd, void *sccb);
int sclp_early_cmd(sclp_cmdw_t cmd, void *sccb);
unsigned int sclp_early_con_check_linemode(struct init_sccb *sccb);
int sclp_early_set_event_mask(struct init_sccb *sccb,
unsigned long receive_mask,
unsigned long send_mask);

/* useful inlines */

/* Perform service call. Return 0 on success, non-zero otherwise. */
static inline int sclp_service_call(sclp_cmdw_t command, void *sccb)
{
int cc = 4; /* Initialize for program check handling */

asm volatile(
"0: .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */
"1: ipm %0\n"
" srl %0,28\n"
"2:\n"
EX_TABLE(0b, 2b)
EX_TABLE(1b, 2b)
: "+&d" (cc) : "d" (command), "a" ((unsigned long)sccb)
: "cc", "memory");
if (cc == 4)
return -EINVAL;
if (cc == 3)
return -EIO;
if (cc == 2)
return -EBUSY;
return 0;
}

/* VM uses EBCDIC 037, LPAR+native(SE+HMC) use EBCDIC 500 */
/* translate single character from ASCII to EBCDIC */
static inline unsigned char
Expand Down
Loading

0 comments on commit d5ab7a3

Please sign in to comment.