e31f08dc74
The stack array is only referenced from the start-up code (which is shared between the s390-ccw.img and the s390-netboot.img), but it is currently declared twice, once in main.c and once in netmain.c. It makes more sense to declare this in start.S instead - which will also be helpful in the next patch, since we need to mention the .bss section in start.S in that patch. While we're at it, let's also drop the huge alignment of the stack, since there is no technical requirement for aligning it to page boundaries. Message-Id: <20230627074703.99608-4-thuth@redhat.com> Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com> Reviewed-by: Eric Farman <farman@linux.ibm.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
179 lines
4.1 KiB
C
179 lines
4.1 KiB
C
/*
|
|
* S390 CCW boot loader
|
|
*
|
|
* Copyright (c) 2013 Alexander Graf <agraf@suse.de>
|
|
*
|
|
* This work is licensed under the terms of the GNU GPL, version 2 or (at
|
|
* your option) any later version. See the COPYING file in the top-level
|
|
* directory.
|
|
*/
|
|
|
|
#ifndef S390_CCW_H
|
|
#define S390_CCW_H
|
|
|
|
/* #define DEBUG */
|
|
|
|
typedef unsigned char u8;
|
|
typedef unsigned short u16;
|
|
typedef unsigned int u32;
|
|
typedef unsigned long long u64;
|
|
|
|
#define true 1
|
|
#define false 0
|
|
#define PAGE_SIZE 4096
|
|
|
|
#define EIO 1
|
|
#define EBUSY 2
|
|
#define ENODEV 3
|
|
|
|
#ifndef NULL
|
|
#define NULL 0
|
|
#endif
|
|
#ifndef MIN
|
|
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
|
#endif
|
|
#ifndef MIN_NON_ZERO
|
|
#define MIN_NON_ZERO(a, b) ((a) == 0 ? (b) : \
|
|
((b) == 0 ? (a) : (MIN(a, b))))
|
|
#endif
|
|
|
|
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
|
|
|
#include "cio.h"
|
|
#include "iplb.h"
|
|
|
|
/* start.s */
|
|
void disabled_wait(void) __attribute__ ((__noreturn__));
|
|
void consume_sclp_int(void);
|
|
void consume_io_int(void);
|
|
|
|
/* main.c */
|
|
void write_subsystem_identification(void);
|
|
void write_iplb_location(void);
|
|
unsigned int get_loadparm_index(void);
|
|
void main(void);
|
|
|
|
/* sclp.c */
|
|
void sclp_print(const char *string);
|
|
void sclp_set_write_mask(uint32_t receive_mask, uint32_t send_mask);
|
|
void sclp_setup(void);
|
|
void sclp_get_loadparm_ascii(char *loadparm);
|
|
int sclp_read(char *str, size_t count);
|
|
|
|
/* virtio.c */
|
|
unsigned long virtio_load_direct(unsigned long rec_list1, unsigned long rec_list2,
|
|
unsigned long subchan_id, void *load_addr);
|
|
bool virtio_is_supported(SubChannelId schid);
|
|
int virtio_blk_setup_device(SubChannelId schid);
|
|
int virtio_read(unsigned long sector, void *load_addr);
|
|
|
|
/* bootmap.c */
|
|
void zipl_load(void);
|
|
|
|
/* jump2ipl.c */
|
|
void write_reset_psw(uint64_t psw);
|
|
void jump_to_IPL_code(uint64_t address);
|
|
void jump_to_low_kernel(void);
|
|
|
|
/* menu.c */
|
|
void menu_set_parms(uint8_t boot_menu_flag, uint32_t boot_menu_timeout);
|
|
int menu_get_zipl_boot_index(const char *menu_data);
|
|
bool menu_is_enabled_zipl(void);
|
|
int menu_get_enum_boot_index(bool *valid_entries);
|
|
bool menu_is_enabled_enum(void);
|
|
|
|
#define MAX_BOOT_ENTRIES 31
|
|
|
|
__attribute__ ((__noreturn__))
|
|
static inline void panic(const char *string)
|
|
{
|
|
sclp_print(string);
|
|
disabled_wait();
|
|
}
|
|
|
|
static inline void fill_hex(char *out, unsigned char val)
|
|
{
|
|
const char hex[] = "0123456789abcdef";
|
|
|
|
out[0] = hex[(val >> 4) & 0xf];
|
|
out[1] = hex[val & 0xf];
|
|
}
|
|
|
|
static inline void fill_hex_val(char *out, void *ptr, unsigned size)
|
|
{
|
|
unsigned char *value = ptr;
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < size; i++) {
|
|
fill_hex(&out[i*2], value[i]);
|
|
}
|
|
}
|
|
|
|
static inline void print_int(const char *desc, u64 addr)
|
|
{
|
|
char out[] = ": 0xffffffffffffffff\n";
|
|
|
|
fill_hex_val(&out[4], &addr, sizeof(addr));
|
|
|
|
sclp_print(desc);
|
|
sclp_print(out);
|
|
}
|
|
|
|
static inline void debug_print_int(const char *desc, u64 addr)
|
|
{
|
|
#ifdef DEBUG
|
|
print_int(desc, addr);
|
|
#endif
|
|
}
|
|
|
|
static inline void debug_print_addr(const char *desc, void *p)
|
|
{
|
|
#ifdef DEBUG
|
|
debug_print_int(desc, (unsigned int)(unsigned long)p);
|
|
#endif
|
|
}
|
|
|
|
/***********************************************
|
|
* Hypercall functions *
|
|
***********************************************/
|
|
|
|
#define KVM_S390_VIRTIO_NOTIFY 0
|
|
#define KVM_S390_VIRTIO_RESET 1
|
|
#define KVM_S390_VIRTIO_SET_STATUS 2
|
|
#define KVM_S390_VIRTIO_CCW_NOTIFY 3
|
|
|
|
#define MAX_SECTOR_SIZE 4096
|
|
|
|
static inline void IPL_assert(bool term, const char *message)
|
|
{
|
|
if (!term) {
|
|
sclp_print("\n! ");
|
|
sclp_print(message);
|
|
panic(" !\n"); /* no return */
|
|
}
|
|
}
|
|
|
|
static inline void IPL_check(bool term, const char *message)
|
|
{
|
|
if (!term) {
|
|
sclp_print("\n! WARNING: ");
|
|
sclp_print(message);
|
|
sclp_print(" !\n");
|
|
}
|
|
}
|
|
|
|
extern const unsigned char ebc2asc[256];
|
|
static inline void ebcdic_to_ascii(const char *src,
|
|
char *dst,
|
|
unsigned int size)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < size; i++) {
|
|
unsigned c = src[i];
|
|
dst[i] = ebc2asc[c];
|
|
}
|
|
}
|
|
|
|
#endif /* S390_CCW_H */
|