aboutsummaryrefslogtreecommitdiff
path: root/pc-bios
diff options
context:
space:
mode:
Diffstat (limited to 'pc-bios')
-rw-r--r--pc-bios/s390-ccw.imgbin42608 -> 42608 bytes
-rw-r--r--pc-bios/s390-ccw/Makefile3
-rw-r--r--pc-bios/s390-ccw/bootmap.c4
-rw-r--r--pc-bios/s390-ccw/cio.c40
-rw-r--r--pc-bios/s390-ccw/cio.h17
-rw-r--r--pc-bios/s390-ccw/helper.h19
-rw-r--r--pc-bios/s390-ccw/jump2ipl.c10
-rw-r--r--pc-bios/s390-ccw/main.c15
-rw-r--r--pc-bios/s390-ccw/menu.c1
-rw-r--r--pc-bios/s390-ccw/netboot.mak13
-rw-r--r--pc-bios/s390-ccw/netmain.c23
-rw-r--r--pc-bios/s390-ccw/s390-arch.h4
-rw-r--r--pc-bios/s390-ccw/s390-ccw.h27
-rw-r--r--pc-bios/s390-ccw/s390-time.h23
-rw-r--r--pc-bios/s390-ccw/start.S5
-rw-r--r--pc-bios/s390-ccw/virtio-net.c2
-rw-r--r--pc-bios/s390-ccw/virtio-scsi.c2
-rw-r--r--pc-bios/s390-ccw/virtio.c18
-rw-r--r--pc-bios/s390-netboot.imgbin67232 -> 67232 bytes
19 files changed, 116 insertions, 110 deletions
diff --git a/pc-bios/s390-ccw.img b/pc-bios/s390-ccw.img
index b9da9d8ecb..3074686a8c 100644
--- a/pc-bios/s390-ccw.img
+++ b/pc-bios/s390-ccw.img
Binary files differ
diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
index a048b6b077..50bc880272 100644
--- a/pc-bios/s390-ccw/Makefile
+++ b/pc-bios/s390-ccw/Makefile
@@ -38,5 +38,8 @@ s390-netboot.img:
@echo "s390-netboot.img not built since roms/SLOF/ is not available."
endif
+ALL_OBJS = $(sort $(OBJECTS) $(NETOBJS) $(LIBCOBJS) $(LIBNETOBJS))
+-include $(ALL_OBJS:%.o=%.d)
+
clean:
rm -f *.o *.d *.img *.elf *~ *.a
diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index d13b7cbd15..97205674e5 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -328,9 +328,7 @@ static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode)
msg[0] = '2';
break;
default:
- msg[0] = vlbl->LDL_version;
- msg[0] &= 0x0f; /* convert EBCDIC */
- msg[0] |= 0x30; /* to ASCII (digit) */
+ msg[0] = ebc2asc[vlbl->LDL_version];
msg[1] = '?';
break;
}
diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c
index 339ec5fbe7..83ca27ab41 100644
--- a/pc-bios/s390-ccw/cio.c
+++ b/pc-bios/s390-ccw/cio.c
@@ -49,13 +49,13 @@ void enable_subchannel(SubChannelId schid)
uint16_t cu_type(SubChannelId schid)
{
- Ccw1 sense_id_ccw;
SenseId sense_data;
-
- sense_id_ccw.cmd_code = CCW_CMD_SENSE_ID;
- sense_id_ccw.cda = ptr2u32(&sense_data);
- sense_id_ccw.count = sizeof(sense_data);
- sense_id_ccw.flags |= CCW_FLAG_SLI;
+ Ccw1 sense_id_ccw = {
+ .cmd_code = CCW_CMD_SENSE_ID,
+ .flags = CCW_FLAG_SLI,
+ .count = sizeof(sense_data),
+ .cda = ptr2u32(&sense_data),
+ };
if (do_cio(schid, CU_TYPE_UNKNOWN, ptr2u32(&sense_id_ccw), CCW_FMT1)) {
panic("Failed to run SenseID CCw\n");
@@ -67,13 +67,13 @@ uint16_t cu_type(SubChannelId schid)
int basic_sense(SubChannelId schid, uint16_t cutype, void *sense_data,
uint16_t data_size)
{
- Ccw1 senseCcw;
+ Ccw1 senseCcw = {
+ .cmd_code = CCW_CMD_BASIC_SENSE,
+ .count = data_size,
+ .cda = ptr2u32(sense_data),
+ };
Irb irb;
- senseCcw.cmd_code = CCW_CMD_BASIC_SENSE;
- senseCcw.cda = ptr2u32(sense_data);
- senseCcw.count = data_size;
-
return __do_cio(schid, ptr2u32(&senseCcw), CCW_FMT1, &irb);
}
@@ -314,7 +314,17 @@ static void print_irb_err(Irb *irb)
*/
static int __do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt, Irb *irb)
{
- CmdOrb orb = {};
+ /*
+ * QEMU's CIO implementation requires prefetch and 64-bit idaws. We
+ * allow all paths.
+ */
+ CmdOrb orb = {
+ .fmt = fmt,
+ .pfch = 1,
+ .c64 = 1,
+ .lpm = 0xFF,
+ .cpa = ccw_addr,
+ };
int rc;
IPL_assert(fmt == 0 || fmt == 1, "Invalid ccw format");
@@ -324,12 +334,6 @@ static int __do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt, Irb *irb)
IPL_assert(ccw_addr <= 0xFFFFFF - 8, "Invalid ccw address");
}
- orb.fmt = fmt;
- orb.pfch = 1; /* QEMU's cio implementation requires prefetch */
- orb.c64 = 1; /* QEMU's cio implementation requires 64-bit idaws */
- orb.lpm = 0xFF; /* All paths allowed */
- orb.cpa = ccw_addr;
-
rc = ssch(schid, &orb);
if (rc == 1 || rc == 2) {
/* Subchannel status pending or busy. Eat status and ask for retry. */
diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h
index aaa432dedd..1e5d4e92e1 100644
--- a/pc-bios/s390-ccw/cio.h
+++ b/pc-bios/s390-ccw/cio.h
@@ -122,12 +122,17 @@ typedef struct schib {
} __attribute__ ((packed, aligned(4))) Schib;
typedef struct subchannel_id {
- __u32 cssid:8;
- __u32:4;
- __u32 m:1;
- __u32 ssid:2;
- __u32 one:1;
- __u32 sch_no:16;
+ union {
+ struct {
+ __u16 cssid:8;
+ __u16 reserved:4;
+ __u16 m:1;
+ __u16 ssid:2;
+ __u16 one:1;
+ };
+ __u16 sch_id;
+ };
+ __u16 sch_no;
} __attribute__ ((packed, aligned(4))) SubChannelId;
struct chsc_header {
diff --git a/pc-bios/s390-ccw/helper.h b/pc-bios/s390-ccw/helper.h
index 78d5bc7442..dfcfea0ff0 100644
--- a/pc-bios/s390-ccw/helper.h
+++ b/pc-bios/s390-ccw/helper.h
@@ -14,11 +14,12 @@
#define S390_CCW_HELPER_H
#include "s390-ccw.h"
+#include "s390-time.h"
/* Avoids compiler warnings when casting a pointer to a u32 */
static inline uint32_t ptr2u32(void *ptr)
{
- IPL_assert((uint64_t)ptr <= 0xffffffff, "ptr2u32: ptr too large");
+ IPL_assert((uint64_t)ptr <= 0xffffffffull, "ptr2u32: ptr too large");
return (uint32_t)(uint64_t)ptr;
}
@@ -28,4 +29,20 @@ static inline void *u32toptr(uint32_t n)
return (void *)(uint64_t)n;
}
+static inline void yield(void)
+{
+ asm volatile ("diag 0,0,0x44"
+ : :
+ : "memory", "cc");
+}
+
+static inline void sleep(unsigned int seconds)
+{
+ ulong target = get_time_seconds() + seconds;
+
+ while (get_time_seconds() < target) {
+ yield();
+ }
+}
+
#endif
diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
index 4eba2510b0..767012bf0c 100644
--- a/pc-bios/s390-ccw/jump2ipl.c
+++ b/pc-bios/s390-ccw/jump2ipl.c
@@ -8,12 +8,10 @@
#include "libc.h"
#include "s390-ccw.h"
+#include "s390-arch.h"
#define KERN_IMAGE_START 0x010000UL
-#define PSW_MASK_64 0x0000000100000000ULL
-#define PSW_MASK_32 0x0000000080000000ULL
-#define PSW_MASK_SHORTPSW 0x0008000000000000ULL
-#define RESET_PSW_MASK (PSW_MASK_SHORTPSW | PSW_MASK_32 | PSW_MASK_64)
+#define RESET_PSW_MASK (PSW_MASK_SHORTPSW | PSW_MASK_64)
typedef struct ResetInfo {
uint64_t ipl_psw;
@@ -54,7 +52,7 @@ void jump_to_IPL_code(uint64_t address)
current->ipl_psw = (uint64_t) &jump_to_IPL_2;
current->ipl_psw |= RESET_PSW_MASK;
- current->ipl_continue = address & 0x7fffffff;
+ current->ipl_continue = address & PSW_MASK_SHORT_ADDR;
debug_print_int("set IPL addr to", current->ipl_continue);
@@ -86,7 +84,7 @@ void jump_to_low_kernel(void)
/* Trying to get PSW at zero address */
if (*((uint64_t *)0) & RESET_PSW_MASK) {
- jump_to_IPL_code((*((uint64_t *)0)) & 0x7fffffff);
+ jump_to_IPL_code((*((uint64_t *)0)) & PSW_MASK_SHORT_ADDR);
}
/* No other option left, so use the Linux kernel start address */
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 4e65b411e1..146a50760b 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -36,11 +36,9 @@ LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
*/
void write_subsystem_identification(void)
{
- SubChannelId *schid = (SubChannelId *) 184;
- uint32_t *zeroes = (uint32_t *) 188;
-
- *schid = blk_schid;
- *zeroes = 0;
+ lowcore->subchannel_id = blk_schid.sch_id;
+ lowcore->subchannel_nr = blk_schid.sch_no;
+ lowcore->io_int_parm = 0;
}
void write_iplb_location(void)
@@ -48,13 +46,6 @@ void write_iplb_location(void)
lowcore->ptr_iplb = ptr2u32(&iplb);
}
-void panic(const char *string)
-{
- sclp_print(string);
- disabled_wait();
- while (1) { }
-}
-
unsigned int get_loadparm_index(void)
{
return atoui(loadparm_str);
diff --git a/pc-bios/s390-ccw/menu.c b/pc-bios/s390-ccw/menu.c
index ce3815b201..de8260a5d6 100644
--- a/pc-bios/s390-ccw/menu.c
+++ b/pc-bios/s390-ccw/menu.c
@@ -12,6 +12,7 @@
#include "libc.h"
#include "s390-ccw.h"
#include "sclp.h"
+#include "s390-time.h"
#define KEYCODE_NO_INP '\0'
#define KEYCODE_ESCAPE '\033'
diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak
index 5eefb7c289..577c023afe 100644
--- a/pc-bios/s390-ccw/netboot.mak
+++ b/pc-bios/s390-ccw/netboot.mak
@@ -1,8 +1,7 @@
SLOF_DIR := $(SRC_PATH)/roms/SLOF
-NETOBJS := start.o sclp.o cio.o virtio.o virtio-net.o jump2ipl.o netmain.o \
- libnet.a libc.a
+NETOBJS := start.o sclp.o cio.o virtio.o virtio-net.o jump2ipl.o netmain.o
LIBC_INC := -nostdinc -I$(SLOF_DIR)/lib/libc/include
LIBNET_INC := -I$(SLOF_DIR)/lib/libnet
@@ -11,15 +10,16 @@ NETLDFLAGS := $(LDFLAGS) -Ttext=0x7800000
$(NETOBJS): QEMU_CFLAGS += $(LIBC_INC) $(LIBNET_INC)
-s390-netboot.elf: $(NETOBJS)
- $(call quiet-command,$(CC) $(NETLDFLAGS) -o $@ $(NETOBJS),"BUILD","$(TARGET_DIR)$@")
+s390-netboot.elf: $(NETOBJS) libnet.a libc.a
+ $(call quiet-command,$(CC) $(NETLDFLAGS) -o $@ $^,"BUILD","$(TARGET_DIR)$@")
s390-netboot.img: s390-netboot.elf
$(call quiet-command,$(STRIP) --strip-unneeded $< -o $@,"STRIP","$(TARGET_DIR)$@")
# libc files:
-LIBC_CFLAGS := $(QEMU_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC)
+LIBC_CFLAGS = $(QEMU_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \
+ -MMD -MP -MT $@ -MF $(@:%.o=%.d)
CTYPE_OBJS = isdigit.o isxdigit.o toupper.o
%.o : $(SLOF_DIR)/lib/libc/ctype/%.c
@@ -52,7 +52,8 @@ libc.a: $(LIBCOBJS)
LIBNETOBJS := args.o dhcp.o dns.o icmpv6.o ipv6.o tcp.o udp.o bootp.o \
dhcpv6.o ethernet.o ipv4.o ndp.o tftp.o pxelinux.o
-LIBNETCFLAGS := $(QEMU_CFLAGS) $(CFLAGS) -DDHCPARCH=0x1F $(LIBC_INC) $(LIBNET_INC)
+LIBNETCFLAGS = $(QEMU_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \
+ -DDHCPARCH=0x1F -MMD -MP -MT $@ -MF $(@:%.o=%.d)
%.o : $(SLOF_DIR)/lib/libnet/%.c
$(call quiet-command,$(CC) $(LIBNETCFLAGS) -c -o $@ $<,"CC","$(TARGET_DIR)$@")
diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
index 309ffa30d9..056e93a818 100644
--- a/pc-bios/s390-ccw/netmain.c
+++ b/pc-bios/s390-ccw/netmain.c
@@ -35,6 +35,7 @@
#include "s390-ccw.h"
#include "cio.h"
#include "virtio.h"
+#include "s390-time.h"
#define DEFAULT_BOOT_RETRIES 10
#define DEFAULT_TFTP_RETRIES 20
@@ -57,24 +58,14 @@ static SubChannelId net_schid = { .one = 1 };
static uint8_t mac[6];
static uint64_t dest_timer;
-static uint64_t get_timer_ms(void)
-{
- uint64_t clk;
-
- asm volatile(" stck %0 " : : "Q"(clk) : "memory");
-
- /* Bit 51 is incremented each microsecond */
- return (clk >> (63 - 51)) / 1000;
-}
-
void set_timer(int val)
{
- dest_timer = get_timer_ms() + val;
+ dest_timer = get_time_ms() + val;
}
int get_timer(void)
{
- return dest_timer - get_timer_ms();
+ return dest_timer - get_time_ms();
}
int get_sec_ticks(void)
@@ -448,14 +439,6 @@ static int net_try_direct_tftp_load(filename_ip_t *fn_ip)
return rc;
}
-void panic(const char *string)
-{
- sclp_print(string);
- for (;;) {
- disabled_wait();
- }
-}
-
void write_subsystem_identification(void)
{
SubChannelId *schid = (SubChannelId *) 184;
diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h
index 5f36361c02..6da44d4436 100644
--- a/pc-bios/s390-ccw/s390-arch.h
+++ b/pc-bios/s390-ccw/s390-arch.h
@@ -26,10 +26,12 @@ _Static_assert(sizeof(struct PSWLegacy) == 8, "PSWLegacy size incorrect");
/* s390 psw bit masks */
#define PSW_MASK_IOINT 0x0200000000000000ULL
+#define PSW_MASK_SHORTPSW 0x0008000000000000ULL
#define PSW_MASK_WAIT 0x0002000000000000ULL
#define PSW_MASK_EAMODE 0x0000000100000000ULL
#define PSW_MASK_BAMODE 0x0000000080000000ULL
-#define PSW_MASK_ZMODE (PSW_MASK_EAMODE | PSW_MASK_BAMODE)
+#define PSW_MASK_SHORT_ADDR 0x000000007fffffffULL
+#define PSW_MASK_64 (PSW_MASK_EAMODE | PSW_MASK_BAMODE)
/* Low core mapping */
typedef struct LowCore {
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index 21f27e7990..36b884cced 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -50,12 +50,11 @@ typedef unsigned long long __u64;
#include "iplb.h"
/* start.s */
-void disabled_wait(void);
+void disabled_wait(void) __attribute__ ((__noreturn__));
void consume_sclp_int(void);
void consume_io_int(void);
/* main.c */
-void panic(const char *string);
void write_subsystem_identification(void);
void write_iplb_location(void);
extern char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
@@ -74,8 +73,6 @@ unsigned long virtio_load_direct(ulong rec_list1, ulong rec_list2,
bool virtio_is_supported(SubChannelId schid);
void virtio_blk_setup_device(SubChannelId schid);
int virtio_read(ulong sector, void *load_addr);
-u64 get_clock(void);
-ulong get_second(void);
/* bootmap.c */
void zipl_load(void);
@@ -93,6 +90,12 @@ bool menu_is_enabled_enum(void);
#define MAX_BOOT_ENTRIES 31
+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";
@@ -144,24 +147,8 @@ static inline void debug_print_addr(const char *desc, void *p)
#define KVM_S390_VIRTIO_SET_STATUS 2
#define KVM_S390_VIRTIO_CCW_NOTIFY 3
-static inline void yield(void)
-{
- asm volatile ("diag 0,0,0x44"
- : :
- : "memory", "cc");
-}
-
#define MAX_SECTOR_SIZE 4096
-static inline void sleep(unsigned int seconds)
-{
- ulong target = get_second() + seconds;
-
- while (get_second() < target) {
- yield();
- }
-}
-
static inline void IPL_assert(bool term, const char *message)
{
if (!term) {
diff --git a/pc-bios/s390-ccw/s390-time.h b/pc-bios/s390-ccw/s390-time.h
new file mode 100644
index 0000000000..ed6d982371
--- /dev/null
+++ b/pc-bios/s390-ccw/s390-time.h
@@ -0,0 +1,23 @@
+#ifndef TIME_H
+#define TIME_H
+
+static inline u64 get_clock(void)
+{
+ u64 r;
+
+ asm volatile("stck %0" : "=Q" (r) : : "cc");
+ return r;
+}
+
+static inline u64 get_time_ms(void)
+{
+ /* Bit 51 is incremented each microsecond */
+ return (get_clock() >> 12) / 1000;
+}
+
+static inline u64 get_time_seconds(void)
+{
+ return get_time_ms() / 1000;
+}
+
+#endif
diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S
index aa8fceb19d..ce519300a1 100644
--- a/pc-bios/s390-ccw/start.S
+++ b/pc-bios/s390-ccw/start.S
@@ -47,8 +47,9 @@ memsetxc:
*/
.globl disabled_wait
disabled_wait:
- larl %r1,disabled_wait_psw
- lpswe 0(%r1)
+ larl %r1,disabled_wait_psw
+ lpswe 0(%r1)
+1: j 1b
/*
diff --git a/pc-bios/s390-ccw/virtio-net.c b/pc-bios/s390-ccw/virtio-net.c
index ff7f4dad25..2fcb0a58c5 100644
--- a/pc-bios/s390-ccw/virtio-net.c
+++ b/pc-bios/s390-ccw/virtio-net.c
@@ -19,6 +19,8 @@
#include <ethernet.h>
#include "s390-ccw.h"
#include "virtio.h"
+#include "s390-time.h"
+#include "helper.h"
#ifndef DEBUG_VIRTIO_NET
#define DEBUG_VIRTIO_NET 0
diff --git a/pc-bios/s390-ccw/virtio-scsi.c b/pc-bios/s390-ccw/virtio-scsi.c
index 4fe4b9d261..eddfb8a7ad 100644
--- a/pc-bios/s390-ccw/virtio-scsi.c
+++ b/pc-bios/s390-ccw/virtio-scsi.c
@@ -14,6 +14,8 @@
#include "virtio.h"
#include "scsi.h"
#include "virtio-scsi.h"
+#include "s390-time.h"
+#include "helper.h"
static ScsiDevice default_scsi_device;
static VirtioScsiCmdReq req;
diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
index fb40ca9828..ab49840db8 100644
--- a/pc-bios/s390-ccw/virtio.c
+++ b/pc-bios/s390-ccw/virtio.c
@@ -15,6 +15,7 @@
#include "virtio-scsi.h"
#include "bswap.h"
#include "helper.h"
+#include "s390-time.h"
#define VRING_WAIT_REPLY_TIMEOUT 30
@@ -157,19 +158,6 @@ void vring_send_buf(VRing *vr, void *p, int len, int flags)
}
}
-u64 get_clock(void)
-{
- u64 r;
-
- asm volatile("stck %0" : "=Q" (r) : : "cc");
- return r;
-}
-
-ulong get_second(void)
-{
- return (get_clock() >> 12) / 1000000;
-}
-
int vr_poll(VRing *vr)
{
if (vr->used->idx == vr->used_idx) {
@@ -194,7 +182,7 @@ int vr_poll(VRing *vr)
*/
int vring_wait_reply(void)
{
- ulong target_second = get_second() + vdev.wait_reply_timeout;
+ ulong target_second = get_time_seconds() + vdev.wait_reply_timeout;
/* Wait for any queue to be updated by the host */
do {
@@ -207,7 +195,7 @@ int vring_wait_reply(void)
if (r) {
return 0;
}
- } while (!vdev.wait_reply_timeout || (get_second() < target_second));
+ } while (!vdev.wait_reply_timeout || (get_time_seconds() < target_second));
return 1;
}
diff --git a/pc-bios/s390-netboot.img b/pc-bios/s390-netboot.img
index 6bb5c86eb0..d9c319604b 100644
--- a/pc-bios/s390-netboot.img
+++ b/pc-bios/s390-netboot.img
Binary files differ