Skip to content

Commit 21d0baf

Browse files
committed
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20200703' into staging
s390 update: - various fixes - cleanup in the s390x-ccw bios # gpg: Signature made Fri 03 Jul 2020 11:04:08 BST # gpg: using RSA key C3D0D66DC3624FF6A8C018CEDECF6B93C6F02FAF # gpg: issuer "[email protected]" # gpg: Good signature from "Cornelia Huck <[email protected]>" [marginal] # gpg: aka "Cornelia Huck <[email protected]>" [full] # gpg: aka "Cornelia Huck <[email protected]>" [full] # gpg: aka "Cornelia Huck <[email protected]>" [marginal] # gpg: aka "Cornelia Huck <[email protected]>" [marginal] # Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0 18CE DECF 6B93 C6F0 2FAF * remotes/cohuck/tags/s390x-20200703: s390x/pci: fix set_ind_atomic virtio-ccw: fix virtio_set_ind_atomic target/s390x: Fix SQXBR pc-bios/s390: Update s390-ccw bios binaries with the latest changes pc-bios/s390-ccw: Generate and include dependency files in the Makefile pc-bios: s390x: Make u32 ptr check explicit pc-bios: s390x: Use ebcdic2ascii table pc-bios: s390x: Move panic() into header and add infinite loop pc-bios: s390x: Use PSW masks where possible and introduce PSW_MASK_SHORT_ADDR pc-bios: s390x: Rename PSW_MASK_ZMODE to PSW_MASK_64 pc-bios: s390x: Get rid of magic offsets into the lowcore pc-bios: s390x: Move sleep and yield to helper.h pc-bios: s390x: Consolidate timing functions into time.h pc-bios: s390x: cio.c cleanup and compile fix Signed-off-by: Peter Maydell <[email protected]>
2 parents 7b75157 + f196f6a commit 21d0baf

22 files changed

+136
-126
lines changed

hw/s390x/s390-pci-bus.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -637,22 +637,24 @@ static AddressSpace *s390_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
637637

638638
static uint8_t set_ind_atomic(uint64_t ind_loc, uint8_t to_be_set)
639639
{
640-
uint8_t ind_old, ind_new;
640+
uint8_t expected, actual;
641641
hwaddr len = 1;
642-
uint8_t *ind_addr;
642+
/* avoid multiple fetches */
643+
uint8_t volatile *ind_addr;
643644

644645
ind_addr = cpu_physical_memory_map(ind_loc, &len, true);
645646
if (!ind_addr) {
646647
s390_pci_generate_error_event(ERR_EVENT_AIRERR, 0, 0, 0, 0);
647648
return -1;
648649
}
650+
actual = *ind_addr;
649651
do {
650-
ind_old = *ind_addr;
651-
ind_new = ind_old | to_be_set;
652-
} while (atomic_cmpxchg(ind_addr, ind_old, ind_new) != ind_old);
653-
cpu_physical_memory_unmap(ind_addr, len, 1, len);
652+
expected = actual;
653+
actual = atomic_cmpxchg(ind_addr, expected, expected | to_be_set);
654+
} while (actual != expected);
655+
cpu_physical_memory_unmap((void *)ind_addr, len, 1, len);
654656

655-
return ind_old;
657+
return actual;
656658
}
657659

658660
static void s390_msi_ctrl_write(void *opaque, hwaddr addr, uint64_t data,

hw/s390x/virtio-ccw.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -786,24 +786,26 @@ static inline VirtioCcwDevice *to_virtio_ccw_dev_fast(DeviceState *d)
786786
static uint8_t virtio_set_ind_atomic(SubchDev *sch, uint64_t ind_loc,
787787
uint8_t to_be_set)
788788
{
789-
uint8_t ind_old, ind_new;
789+
uint8_t expected, actual;
790790
hwaddr len = 1;
791-
uint8_t *ind_addr;
791+
/* avoid multiple fetches */
792+
uint8_t volatile *ind_addr;
792793

793794
ind_addr = cpu_physical_memory_map(ind_loc, &len, true);
794795
if (!ind_addr) {
795796
error_report("%s(%x.%x.%04x): unable to access indicator",
796797
__func__, sch->cssid, sch->ssid, sch->schid);
797798
return -1;
798799
}
800+
actual = *ind_addr;
799801
do {
800-
ind_old = *ind_addr;
801-
ind_new = ind_old | to_be_set;
802-
} while (atomic_cmpxchg(ind_addr, ind_old, ind_new) != ind_old);
803-
trace_virtio_ccw_set_ind(ind_loc, ind_old, ind_new);
804-
cpu_physical_memory_unmap(ind_addr, len, 1, len);
802+
expected = actual;
803+
actual = atomic_cmpxchg(ind_addr, expected, expected | to_be_set);
804+
} while (actual != expected);
805+
trace_virtio_ccw_set_ind(ind_loc, actual, actual | to_be_set);
806+
cpu_physical_memory_unmap((void *)ind_addr, len, 1, len);
805807

806-
return ind_old;
808+
return actual;
807809
}
808810

809811
static void virtio_ccw_notify(DeviceState *d, uint16_t vector)

pc-bios/s390-ccw.img

0 Bytes
Binary file not shown.

pc-bios/s390-ccw/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,8 @@ s390-netboot.img:
3838
@echo "s390-netboot.img not built since roms/SLOF/ is not available."
3939
endif
4040

41+
ALL_OBJS = $(sort $(OBJECTS) $(NETOBJS) $(LIBCOBJS) $(LIBNETOBJS))
42+
-include $(ALL_OBJS:%.o=%.d)
43+
4144
clean:
4245
rm -f *.o *.d *.img *.elf *~ *.a

pc-bios/s390-ccw/bootmap.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,7 @@ static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode)
328328
msg[0] = '2';
329329
break;
330330
default:
331-
msg[0] = vlbl->LDL_version;
332-
msg[0] &= 0x0f; /* convert EBCDIC */
333-
msg[0] |= 0x30; /* to ASCII (digit) */
331+
msg[0] = ebc2asc[vlbl->LDL_version];
334332
msg[1] = '?';
335333
break;
336334
}

pc-bios/s390-ccw/cio.c

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ void enable_subchannel(SubChannelId schid)
4949

5050
uint16_t cu_type(SubChannelId schid)
5151
{
52-
Ccw1 sense_id_ccw;
5352
SenseId sense_data;
54-
55-
sense_id_ccw.cmd_code = CCW_CMD_SENSE_ID;
56-
sense_id_ccw.cda = ptr2u32(&sense_data);
57-
sense_id_ccw.count = sizeof(sense_data);
58-
sense_id_ccw.flags |= CCW_FLAG_SLI;
53+
Ccw1 sense_id_ccw = {
54+
.cmd_code = CCW_CMD_SENSE_ID,
55+
.flags = CCW_FLAG_SLI,
56+
.count = sizeof(sense_data),
57+
.cda = ptr2u32(&sense_data),
58+
};
5959

6060
if (do_cio(schid, CU_TYPE_UNKNOWN, ptr2u32(&sense_id_ccw), CCW_FMT1)) {
6161
panic("Failed to run SenseID CCw\n");
@@ -67,13 +67,13 @@ uint16_t cu_type(SubChannelId schid)
6767
int basic_sense(SubChannelId schid, uint16_t cutype, void *sense_data,
6868
uint16_t data_size)
6969
{
70-
Ccw1 senseCcw;
70+
Ccw1 senseCcw = {
71+
.cmd_code = CCW_CMD_BASIC_SENSE,
72+
.count = data_size,
73+
.cda = ptr2u32(sense_data),
74+
};
7175
Irb irb;
7276

73-
senseCcw.cmd_code = CCW_CMD_BASIC_SENSE;
74-
senseCcw.cda = ptr2u32(sense_data);
75-
senseCcw.count = data_size;
76-
7777
return __do_cio(schid, ptr2u32(&senseCcw), CCW_FMT1, &irb);
7878
}
7979

@@ -314,7 +314,17 @@ static void print_irb_err(Irb *irb)
314314
*/
315315
static int __do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt, Irb *irb)
316316
{
317-
CmdOrb orb = {};
317+
/*
318+
* QEMU's CIO implementation requires prefetch and 64-bit idaws. We
319+
* allow all paths.
320+
*/
321+
CmdOrb orb = {
322+
.fmt = fmt,
323+
.pfch = 1,
324+
.c64 = 1,
325+
.lpm = 0xFF,
326+
.cpa = ccw_addr,
327+
};
318328
int rc;
319329

320330
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)
324334
IPL_assert(ccw_addr <= 0xFFFFFF - 8, "Invalid ccw address");
325335
}
326336

327-
orb.fmt = fmt;
328-
orb.pfch = 1; /* QEMU's cio implementation requires prefetch */
329-
orb.c64 = 1; /* QEMU's cio implementation requires 64-bit idaws */
330-
orb.lpm = 0xFF; /* All paths allowed */
331-
orb.cpa = ccw_addr;
332-
333337
rc = ssch(schid, &orb);
334338
if (rc == 1 || rc == 2) {
335339
/* Subchannel status pending or busy. Eat status and ask for retry. */

pc-bios/s390-ccw/cio.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,17 @@ typedef struct schib {
122122
} __attribute__ ((packed, aligned(4))) Schib;
123123

124124
typedef struct subchannel_id {
125-
__u32 cssid:8;
126-
__u32:4;
127-
__u32 m:1;
128-
__u32 ssid:2;
129-
__u32 one:1;
130-
__u32 sch_no:16;
125+
union {
126+
struct {
127+
__u16 cssid:8;
128+
__u16 reserved:4;
129+
__u16 m:1;
130+
__u16 ssid:2;
131+
__u16 one:1;
132+
};
133+
__u16 sch_id;
134+
};
135+
__u16 sch_no;
131136
} __attribute__ ((packed, aligned(4))) SubChannelId;
132137

133138
struct chsc_header {

pc-bios/s390-ccw/helper.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@
1414
#define S390_CCW_HELPER_H
1515

1616
#include "s390-ccw.h"
17+
#include "s390-time.h"
1718

1819
/* Avoids compiler warnings when casting a pointer to a u32 */
1920
static inline uint32_t ptr2u32(void *ptr)
2021
{
21-
IPL_assert((uint64_t)ptr <= 0xffffffff, "ptr2u32: ptr too large");
22+
IPL_assert((uint64_t)ptr <= 0xffffffffull, "ptr2u32: ptr too large");
2223
return (uint32_t)(uint64_t)ptr;
2324
}
2425

@@ -28,4 +29,20 @@ static inline void *u32toptr(uint32_t n)
2829
return (void *)(uint64_t)n;
2930
}
3031

32+
static inline void yield(void)
33+
{
34+
asm volatile ("diag 0,0,0x44"
35+
: :
36+
: "memory", "cc");
37+
}
38+
39+
static inline void sleep(unsigned int seconds)
40+
{
41+
ulong target = get_time_seconds() + seconds;
42+
43+
while (get_time_seconds() < target) {
44+
yield();
45+
}
46+
}
47+
3148
#endif

pc-bios/s390-ccw/jump2ipl.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@
88

99
#include "libc.h"
1010
#include "s390-ccw.h"
11+
#include "s390-arch.h"
1112

1213
#define KERN_IMAGE_START 0x010000UL
13-
#define PSW_MASK_64 0x0000000100000000ULL
14-
#define PSW_MASK_32 0x0000000080000000ULL
15-
#define PSW_MASK_SHORTPSW 0x0008000000000000ULL
16-
#define RESET_PSW_MASK (PSW_MASK_SHORTPSW | PSW_MASK_32 | PSW_MASK_64)
14+
#define RESET_PSW_MASK (PSW_MASK_SHORTPSW | PSW_MASK_64)
1715

1816
typedef struct ResetInfo {
1917
uint64_t ipl_psw;
@@ -54,7 +52,7 @@ void jump_to_IPL_code(uint64_t address)
5452

5553
current->ipl_psw = (uint64_t) &jump_to_IPL_2;
5654
current->ipl_psw |= RESET_PSW_MASK;
57-
current->ipl_continue = address & 0x7fffffff;
55+
current->ipl_continue = address & PSW_MASK_SHORT_ADDR;
5856

5957
debug_print_int("set IPL addr to", current->ipl_continue);
6058

@@ -86,7 +84,7 @@ void jump_to_low_kernel(void)
8684

8785
/* Trying to get PSW at zero address */
8886
if (*((uint64_t *)0) & RESET_PSW_MASK) {
89-
jump_to_IPL_code((*((uint64_t *)0)) & 0x7fffffff);
87+
jump_to_IPL_code((*((uint64_t *)0)) & PSW_MASK_SHORT_ADDR);
9088
}
9189

9290
/* No other option left, so use the Linux kernel start address */

pc-bios/s390-ccw/main.c

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,25 +36,16 @@ LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
3636
*/
3737
void write_subsystem_identification(void)
3838
{
39-
SubChannelId *schid = (SubChannelId *) 184;
40-
uint32_t *zeroes = (uint32_t *) 188;
41-
42-
*schid = blk_schid;
43-
*zeroes = 0;
39+
lowcore->subchannel_id = blk_schid.sch_id;
40+
lowcore->subchannel_nr = blk_schid.sch_no;
41+
lowcore->io_int_parm = 0;
4442
}
4543

4644
void write_iplb_location(void)
4745
{
4846
lowcore->ptr_iplb = ptr2u32(&iplb);
4947
}
5048

51-
void panic(const char *string)
52-
{
53-
sclp_print(string);
54-
disabled_wait();
55-
while (1) { }
56-
}
57-
5849
unsigned int get_loadparm_index(void)
5950
{
6051
return atoui(loadparm_str);

0 commit comments

Comments
 (0)