mirror of
https://github.com/SDL-Hercules-390/hyperion.git
synced 2026-04-20 18:57:06 +02:00
console race fix, cleanup warnings
git-svn-id: file:///home/jj/hercules.svn/trunk@2118 956126f8-22a0-4046-8f4a-272fa8102e63
This commit is contained in:
5
CHANGES
5
CHANGES
@@ -1,5 +1,10 @@
|
||||
#### Don't forget to change the version number in configure.ac! ####
|
||||
|
||||
29 Nov 2003 Fix race condition in console.c recv_3270_data causing 100%
|
||||
CPU utilization, zero MIPS" Hercules hang symptom (version
|
||||
in configure.ac version bumped to 3.00a.5) - Fish
|
||||
29 Nov 2003 Fix "passing arg n of <function> from incompatible pointer type"
|
||||
warnings in codepage.c, dat.h, stack.c, xstore.c - Fish
|
||||
29 Nov 2003 Fix reset_channel_path - Mark Drummond by Greg Smith
|
||||
28 Nov 2003 Flush Buffer On lost data condition in 2703 handler - Ivan Warren
|
||||
27 Nov 2003 CTCI/LCS: fix enqueue full frame buffer loop; enable thread
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
AC_INIT(hercules.h)
|
||||
AC_CONFIG_AUX_DIR(autoconf)
|
||||
|
||||
AM_INIT_AUTOMAKE(hercules,3.00a.4)
|
||||
AM_INIT_AUTOMAKE(hercules,3.00a.5)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
|
||||
121
console.c
121
console.c
@@ -383,7 +383,7 @@ int m, n, c;
|
||||
} /* end for */
|
||||
|
||||
if (n < m) {
|
||||
TNSDEBUG3("%d IAC bytes removed, newlen=%d\n", m-n, n);
|
||||
TNSDEBUG3("DBG001: %d IAC bytes removed, newlen=%d\n", m-n, n);
|
||||
packet_trace (buf, n);
|
||||
}
|
||||
|
||||
@@ -410,7 +410,7 @@ int m, n, x, newlen;
|
||||
|
||||
/* Insert extra IAC bytes backwards from the end of the buffer */
|
||||
newlen = len + x;
|
||||
TNSDEBUG3("%d IAC bytes added, newlen=%d\n", x, newlen);
|
||||
TNSDEBUG3("DBG002: %d IAC bytes added, newlen=%d\n", x, newlen);
|
||||
for (n=newlen, m=len; n > m; ) {
|
||||
buf[--n] = buf[--m];
|
||||
if (buf[n] == IAC) buf[--n] = IAC;
|
||||
@@ -449,14 +449,14 @@ send_packet (int csock, BYTE *buf, int len, char *caption)
|
||||
int rc; /* Return code */
|
||||
|
||||
if (caption != NULL) {
|
||||
TNSDEBUG2("Sending %s\n", caption);
|
||||
TNSDEBUG2("DBG003: Sending %s\n", caption);
|
||||
packet_trace (buf, len);
|
||||
}
|
||||
|
||||
rc = send (csock, buf, len, 0);
|
||||
|
||||
if (rc < 0) {
|
||||
TNSERROR("send: %s\n", strerror(errno));
|
||||
TNSERROR("DBG021: send: %s\n", strerror(errno));
|
||||
return -1;
|
||||
} /* end if(rc) */
|
||||
|
||||
@@ -493,12 +493,12 @@ int rcvlen=0; /* Length of data received */
|
||||
rc = recv (csock, buf + rcvlen, reqlen - rcvlen, 0);
|
||||
|
||||
if (rc < 0) {
|
||||
TNSERROR("recv: %s\n", strerror(errno));
|
||||
TNSERROR("DBG022: recv: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
TNSDEBUG1("Connection closed by client\n");
|
||||
TNSDEBUG1("DBG004: Connection closed by client\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -509,7 +509,7 @@ int rcvlen=0; /* Length of data received */
|
||||
break;
|
||||
}
|
||||
|
||||
TNSDEBUG2("Packet received length=%d\n", rcvlen);
|
||||
TNSDEBUG2("DBG005: Packet received length=%d\n", rcvlen);
|
||||
packet_trace (buf, rcvlen);
|
||||
|
||||
return rcvlen;
|
||||
@@ -547,10 +547,10 @@ static BYTE will_bin[] = { IAC, WILL, BINARY, IAC, DO, BINARY };
|
||||
if (memcmp(buf, expected, len) != 0)
|
||||
#endif
|
||||
{
|
||||
TNSDEBUG2("Expected %s\n", caption);
|
||||
TNSDEBUG2("DBG006: Expected %s\n", caption);
|
||||
return -1;
|
||||
}
|
||||
TNSDEBUG2("Received %s\n", caption);
|
||||
TNSDEBUG2("DBG007: Received %s\n", caption);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -642,12 +642,12 @@ static BYTE will_naws[] = { IAC, WILL, NAWS };
|
||||
if (rc < (int)(sizeof(type_is) + 2)
|
||||
|| memcmp(buf, type_is, sizeof(type_is)) != 0
|
||||
|| buf[rc-2] != IAC || buf[rc-1] != SE) {
|
||||
TNSDEBUG2("Expected IAC SB TERMINAL_TYPE IS\n");
|
||||
TNSDEBUG2("DBG008: Expected IAC SB TERMINAL_TYPE IS\n");
|
||||
return -1;
|
||||
}
|
||||
buf[rc-2] = '\0';
|
||||
termtype = buf + sizeof(type_is);
|
||||
TNSDEBUG2("Received IAC SB TERMINAL_TYPE IS %s IAC SE\n",
|
||||
TNSDEBUG2("DBG009: Received IAC SB TERMINAL_TYPE IS %s IAC SE\n",
|
||||
termtype);
|
||||
|
||||
/* Check terminal type string for device name suffix */
|
||||
@@ -780,12 +780,44 @@ int eor = 0; /* 1=End of record received */
|
||||
dev->readpending = 0;
|
||||
}
|
||||
|
||||
TNSDEBUG1("DBG031: verifying data is available...\n");
|
||||
{
|
||||
|
||||
fd_set readset;
|
||||
struct timeval tv = {0,0}; /* (non-blocking poll) */
|
||||
|
||||
FD_ZERO( &readset );
|
||||
FD_SET( dev->fd, &readset );
|
||||
|
||||
while ( (rc = select ( dev->fd+1, &readset, NULL, NULL, &tv )) < 0
|
||||
&& EINTR == errno )
|
||||
; /* NOP (keep retrying if EINTR) */
|
||||
|
||||
if (rc < 0)
|
||||
{
|
||||
TNSERROR("DBG032: select failed: %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
ASSERT(rc <= 1);
|
||||
|
||||
if (!FD_ISSET(dev->fd, &readset))
|
||||
{
|
||||
ASSERT(rc == 0);
|
||||
TNSDEBUG1("DBG033: no data available; returning 0...\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ASSERT(rc == 1);
|
||||
}
|
||||
TNSDEBUG1("DBG034: data IS available; attempting recv...\n");
|
||||
|
||||
/* Receive bytes from client */
|
||||
rc = recv (dev->fd, dev->buf + dev->rlen3270,
|
||||
BUFLEN_3270 - dev->rlen3270, 0);
|
||||
|
||||
if (rc < 0) {
|
||||
TNSERROR("recv: %s\n", strerror(errno));
|
||||
TNSERROR("DBG023: recv: %s\n", strerror(errno));
|
||||
dev->sense[0] = SENSE_EC;
|
||||
return (CSW_ATTN | CSW_UC);
|
||||
}
|
||||
@@ -822,16 +854,17 @@ int eor = 0; /* 1=End of record received */
|
||||
/* If record is incomplete, test for buffer full */
|
||||
if (eor == 0 && dev->rlen3270 >= BUFLEN_3270)
|
||||
{
|
||||
TNSDEBUG1("3270 buffer overflow\n");
|
||||
TNSDEBUG1("DBG010: 3270 buffer overflow\n");
|
||||
dev->sense[0] = SENSE_DC;
|
||||
return (CSW_ATTN | CSW_UC);
|
||||
}
|
||||
|
||||
/* Return zero status if record is incomplete */
|
||||
if (eor == 0) return 0;
|
||||
if (eor == 0)
|
||||
return 0;
|
||||
|
||||
/* Trace the complete 3270 data packet */
|
||||
TNSDEBUG2("Packet received length=%d\n", dev->rlen3270);
|
||||
TNSDEBUG2("DBG011: Packet received length=%d\n", dev->rlen3270);
|
||||
packet_trace (dev->buf, dev->rlen3270);
|
||||
|
||||
/* Strip off the telnet EOR marker */
|
||||
@@ -896,7 +929,7 @@ BYTE buf[32]; /* tn3270 write buffer */
|
||||
do {
|
||||
len = dev->rlen3270;
|
||||
rc = recv_3270_data (dev);
|
||||
TNSDEBUG2("read buffer: %d bytes received\n",
|
||||
TNSDEBUG2("DBG012: read buffer: %d bytes received\n",
|
||||
dev->rlen3270 - len);
|
||||
} while(rc == 0);
|
||||
|
||||
@@ -948,7 +981,7 @@ BYTE c; /* Character work area */
|
||||
|
||||
/* Return unit check if error on receive */
|
||||
if (num < 0) {
|
||||
TNSERROR("recv: %s\n", strerror(errno));
|
||||
TNSERROR("DBG024: recv: %s\n", strerror(errno));
|
||||
dev->sense[0] = SENSE_EC;
|
||||
return (CSW_ATTN | CSW_UC);
|
||||
}
|
||||
@@ -962,7 +995,7 @@ BYTE c; /* Character work area */
|
||||
}
|
||||
|
||||
/* Trace the bytes received */
|
||||
TNSDEBUG2("Bytes received length=%d\n", num);
|
||||
TNSDEBUG2("DBG013: Bytes received length=%d\n", num);
|
||||
packet_trace (buf, num);
|
||||
|
||||
/* Copy received bytes to keyboard buffer */
|
||||
@@ -985,7 +1018,7 @@ BYTE c; /* Character work area */
|
||||
/* Return unit check if buffer is full */
|
||||
if (dev->keybdrem >= BUFLEN_1052)
|
||||
{
|
||||
TNSDEBUG1("Console keyboard buffer overflow\n");
|
||||
TNSDEBUG1("DBG014: Console keyboard buffer overflow\n");
|
||||
dev->keybdrem = 0;
|
||||
dev->sense[0] = SENSE_EC;
|
||||
return (CSW_ATTN | CSW_UC);
|
||||
@@ -1042,7 +1075,7 @@ BYTE c; /* Character work area */
|
||||
&& dev->buf[dev->keybdrem - 1] == '\n'
|
||||
&& i < num - 1)
|
||||
{
|
||||
TNSDEBUG1("Console keyboard buffer overrun\n");
|
||||
TNSDEBUG1("DBG015: Console keyboard buffer overrun\n");
|
||||
dev->keybdrem = 0;
|
||||
dev->sense[0] = SENSE_OR;
|
||||
return (CSW_ATTN | CSW_UC);
|
||||
@@ -1057,7 +1090,7 @@ BYTE c; /* Character work area */
|
||||
return 0;
|
||||
|
||||
/* Trace the complete keyboard data packet */
|
||||
TNSDEBUG2("Packet received length=%d\n", dev->keybdrem);
|
||||
TNSDEBUG2("DBG016: Packet received length=%d\n", dev->keybdrem);
|
||||
packet_trace (dev->buf, dev->keybdrem);
|
||||
|
||||
/* Strip off the CRLF sequence */
|
||||
@@ -1071,7 +1104,7 @@ BYTE c; /* Character work area */
|
||||
} /* end for(i) */
|
||||
|
||||
/* Trace the EBCDIC input data */
|
||||
TNSDEBUG2("Input data line length=%d\n", dev->keybdrem);
|
||||
TNSDEBUG2("DBG017: Input data line length=%d\n", dev->keybdrem);
|
||||
packet_trace (dev->buf, dev->keybdrem);
|
||||
|
||||
/* Return attention status */
|
||||
@@ -1130,7 +1163,7 @@ BYTE rejmsg[256]; /* Rejection message */
|
||||
clientname = "host name unknown";
|
||||
}
|
||||
|
||||
TNSDEBUG1("Received connection from %s (%s)\n",
|
||||
TNSDEBUG1("DBG018: Received connection from %s (%s)\n",
|
||||
clientip, clientname);
|
||||
|
||||
/* Negotiate telnet parameters */
|
||||
@@ -1228,7 +1261,7 @@ BYTE rejmsg[256]; /* Rejection message */
|
||||
"Connection rejected, device %4.4X unavailable",
|
||||
devnum);
|
||||
|
||||
TNSDEBUG1( "%s\n", rejmsg);
|
||||
TNSDEBUG1( "DBG019: %s\n", rejmsg);
|
||||
|
||||
/* Send connection rejection message to client */
|
||||
if (class != 'K')
|
||||
@@ -1335,7 +1368,7 @@ BYTE unitstat; /* Status after receive data */
|
||||
|
||||
if (lsock < 0)
|
||||
{
|
||||
TNSERROR("socket: %s\n", strerror(errno));
|
||||
TNSERROR("DBG025: socket: %s\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1366,7 +1399,7 @@ BYTE unitstat; /* Status after receive data */
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
TNSERROR("bind: %s\n", strerror(errno));
|
||||
TNSERROR("DBG026: bind: %s\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1375,7 +1408,7 @@ BYTE unitstat; /* Status after receive data */
|
||||
|
||||
if (rc < 0)
|
||||
{
|
||||
TNSERROR("listen: %s\n", strerror(errno));
|
||||
TNSERROR("DBG027: listen: %s\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1445,7 +1478,7 @@ BYTE unitstat; /* Status after receive data */
|
||||
if (rc < 0 )
|
||||
{
|
||||
if (errno == EINTR) continue;
|
||||
TNSERROR("select: %s\n", strerror(errno));
|
||||
TNSERROR("DBG028: select: %s\n", strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1457,7 +1490,7 @@ BYTE unitstat; /* Status after receive data */
|
||||
|
||||
if (csock < 0)
|
||||
{
|
||||
TNSERROR("accept: %s\n", strerror(errno));
|
||||
TNSERROR("DBG029: accept: %s\n", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1465,7 +1498,7 @@ BYTE unitstat; /* Status after receive data */
|
||||
if ( create_thread (&tidneg, &sysblk.detattr,
|
||||
connect_client, &csock) )
|
||||
{
|
||||
TNSERROR("connect_client create_thread: %s\n",
|
||||
TNSERROR("DBG030: connect_client create_thread: %s\n",
|
||||
strerror(errno));
|
||||
close (csock);
|
||||
}
|
||||
@@ -1518,26 +1551,27 @@ BYTE unitstat; /* Status after receive data */
|
||||
release_lock (&dev->lock);
|
||||
|
||||
/* Raise attention interrupt for the device */
|
||||
|
||||
/* Do not raise attention interrupt for 3287 */
|
||||
/* Otherwise zVM loops after ENABLE ccuu */
|
||||
/* Following 5 lines are repeated on Hercules console: */
|
||||
/* console: sending 3270 data */
|
||||
/* +0000 F5C2FFEF */
|
||||
/* console: Packet received length=7 */
|
||||
/* +0000 016CD902 00FFEF */
|
||||
/* I do not know what is this */
|
||||
/* console: CCUU attention requests raised */
|
||||
/* +0000 F5C2FFEF */
|
||||
/* console: Packet received length=7 */
|
||||
/* +0000 016CD902 00FFEF */
|
||||
/* I do not know what is this */
|
||||
/* console: CCUU attention requests raised */
|
||||
if (dev->devtype != 0x3287)
|
||||
{
|
||||
if(dev->connected) /* *ISW3274DR* - Added */
|
||||
{ /* *ISW3274DR - Added */
|
||||
rc = device_attention (dev, unitstat);
|
||||
rc = device_attention (dev, unitstat);
|
||||
} /* *ISW3274DR - Added */
|
||||
|
||||
/* Trace the attention request */
|
||||
TNSDEBUG2("%4.4X attention request %s\n",
|
||||
dev->devnum,
|
||||
(rc == 0 ? "raised" : "rejected"));
|
||||
/* Trace the attention request */
|
||||
TNSDEBUG2("DBG020: %4.4X attention request %s; rc=%d\n",
|
||||
dev->devnum,
|
||||
(rc == 0 ? "raised" : "rejected"), rc);
|
||||
}
|
||||
continue;
|
||||
} /* end if(data available) */
|
||||
@@ -2206,6 +2240,10 @@ BYTE buf[BUFLEN_3270]; /* tn3270 write buffer */
|
||||
|
||||
/* Release the device lock */
|
||||
release_lock (&dev->lock);
|
||||
|
||||
/* Signal connection thread to redrive its select loop */
|
||||
signal_thread (sysblk.cnsltid, SIGUSR2);
|
||||
|
||||
break;
|
||||
|
||||
case L3270_RM:
|
||||
@@ -2234,6 +2272,9 @@ BYTE buf[BUFLEN_3270]; /* tn3270 write buffer */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set AID in buffer flag */
|
||||
aid = 1;
|
||||
|
||||
dev->aid3270 = dev->buf[0];
|
||||
if(dev->pos3270 != 0 && dev->aid3270 != SF3270_AID)
|
||||
{
|
||||
|
||||
108
dat.h
108
dat.h
@@ -21,7 +21,7 @@
|
||||
/* ESAME ASN authorization and ALET translation - Roger Bowler */
|
||||
/*-------------------------------------------------------------------*/
|
||||
|
||||
#if !defined(OPTION_NO_INLINE_DAT) || defined(_DAT_C)
|
||||
#if !defined(OPTION_NO_INLINE_DAT) || defined(_DAT_C)
|
||||
#if defined(FEATURE_DUAL_ADDRESS_SPACE)
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* Translate ASN to produce address-space control parameters */
|
||||
@@ -1000,7 +1000,7 @@ TLBE *tlbp; /* -> TLB entry */
|
||||
tlbp->common = (ste & SEGTAB_COMMON) ? 1 : 0;
|
||||
tlbp->valid = regs->tlbID;
|
||||
}
|
||||
|
||||
|
||||
} /* end if(!TLB) */
|
||||
|
||||
/* Set the protection indicator if page protection is active */
|
||||
@@ -1012,7 +1012,7 @@ TLBE *tlbp; /* -> TLB entry */
|
||||
index of the virtual address to form the real address */
|
||||
*raddr = (pte & PAGETAB_PFRA) | (vaddr & 0xFFF);
|
||||
else
|
||||
/* In the case of lock page, return the address of the
|
||||
/* In the case of lock page, return the address of the
|
||||
pagetable entry */
|
||||
*raddr = pto;
|
||||
|
||||
@@ -1097,27 +1097,27 @@ TLBE *tlbp; /* -> TLB entry */
|
||||
rfx = (vaddr >> 50) & 0x3FF8;
|
||||
rsx = (vaddr >> 39) & 0x3FF8;
|
||||
rtx = (vaddr >> 28) & 0x3FF8;
|
||||
|
||||
|
||||
/* Extract the 11-bit segment index from the virtual address,
|
||||
and shift it into bits 2-12 of a 16-bit integer, ready
|
||||
for addition to the segment table origin */
|
||||
sx = (vaddr >> 17) & 0x3FF8;
|
||||
|
||||
|
||||
/* Extract the 8-bit page index from the virtual address,
|
||||
and shift it into bits 2-12 of a 16-bit integer, ready
|
||||
for addition to the page table origin */
|
||||
px = (vaddr >> 9) & 0x07F8;
|
||||
|
||||
|
||||
/* ASCE-type exception if the virtual address is too large
|
||||
for the table type designated by the ASCE */
|
||||
if ((rfx != 0 && tt < TT_R1TABL)
|
||||
|| (rsx != 0 && tt < TT_R2TABL)
|
||||
|| (rtx != 0 && tt < TT_R3TABL))
|
||||
goto asce_type_excp;
|
||||
|
||||
|
||||
/* Perform region translation */
|
||||
switch (tt) {
|
||||
|
||||
|
||||
/* Perform region-first translation */
|
||||
case TT_R1TABL:
|
||||
|
||||
@@ -1125,203 +1125,203 @@ TLBE *tlbp; /* -> TLB entry */
|
||||
less than high-order 2 bits of region-first index */
|
||||
if (tl < (rfx >> 12))
|
||||
goto reg_first_excp;
|
||||
|
||||
|
||||
/* Add the region-first index (with three low-order zeroes)
|
||||
to the region-first table origin, giving the address of
|
||||
the region-first table entry */
|
||||
rto += rfx;
|
||||
|
||||
|
||||
/* Addressing exception if outside main storage */
|
||||
if (rto > regs->mainlim)
|
||||
goto address_excp;
|
||||
|
||||
|
||||
/* Fetch region-first table entry from absolute storage.
|
||||
All bytes must be fetched concurrently as observed by
|
||||
other CPUs */
|
||||
rte = ARCH_DEP(fetch_doubleword_absolute) (rto, regs);
|
||||
// logmsg("r1te:%16.16llX=>%16.16llX\n",rto,rte);
|
||||
|
||||
|
||||
/* Region-first translation exception if the bit 58 of
|
||||
the region-first table entry is set (region invalid) */
|
||||
if (rte & REGTAB_I)
|
||||
goto reg_first_excp;
|
||||
|
||||
|
||||
/* Translation specification exception if bits 60-61 of
|
||||
the region-first table entry do not indicate the
|
||||
correct type of region table */
|
||||
if ((rte & REGTAB_TT) != TT_R1TABL)
|
||||
goto tran_spec_excp;
|
||||
|
||||
|
||||
/* Extract the region-second table origin, offset, and
|
||||
length from the region-first table entry */
|
||||
rto = rte & REGTAB_TO;
|
||||
tf = (rte & REGTAB_TF) >> 6;
|
||||
tl = rte & REGTAB_TL;
|
||||
|
||||
|
||||
/* Fall through to perform region-second translation */
|
||||
|
||||
|
||||
/* Perform region-second translation */
|
||||
case TT_R2TABL:
|
||||
|
||||
|
||||
/* Region-second translation exception if table offset is
|
||||
greater than high-order 2 bits of region-second index */
|
||||
if (tf > (rsx >> 12))
|
||||
goto reg_second_excp;
|
||||
|
||||
|
||||
/* Region-second translation exception if table length is
|
||||
less than high-order 2 bits of region-second index */
|
||||
if (tl < (rsx >> 12))
|
||||
goto reg_second_excp;
|
||||
|
||||
|
||||
/* Add the region-second index (with three low-order zeroes)
|
||||
to the region-second table origin, giving the address of
|
||||
the region-second table entry */
|
||||
rto += rsx;
|
||||
|
||||
|
||||
/* Addressing exception if outside main storage */
|
||||
if (rto > regs->mainlim)
|
||||
goto address_excp;
|
||||
|
||||
|
||||
/* Fetch region-second table entry from absolute storage.
|
||||
All bytes must be fetched concurrently as observed by
|
||||
other CPUs */
|
||||
rte = ARCH_DEP(fetch_doubleword_absolute) (rto, regs);
|
||||
// logmsg("r2te:%16.16llX=>%16.16llX\n",rto,rte);
|
||||
|
||||
|
||||
/* Region-second translation exception if the bit 58 of
|
||||
the region-second table entry is set (region invalid) */
|
||||
if (rte & REGTAB_I)
|
||||
goto reg_second_excp;
|
||||
|
||||
|
||||
/* Translation specification exception if bits 60-61 of
|
||||
the region-second table entry do not indicate the
|
||||
correct type of region table */
|
||||
if ((rte & REGTAB_TT) != TT_R2TABL)
|
||||
goto tran_spec_excp;
|
||||
|
||||
|
||||
/* Extract the region-third table origin, offset, and
|
||||
length from the region-second table entry */
|
||||
rto = rte & REGTAB_TO;
|
||||
tf = (rte & REGTAB_TF) >> 6;
|
||||
tl = rte & REGTAB_TL;
|
||||
|
||||
|
||||
/* Fall through to perform region-third translation */
|
||||
|
||||
|
||||
/* Perform region-third translation */
|
||||
case TT_R3TABL:
|
||||
|
||||
|
||||
/* Region-third translation exception if table offset is
|
||||
greater than high-order 2 bits of region-third index */
|
||||
if (tf > (rtx >> 12))
|
||||
goto reg_third_excp;
|
||||
|
||||
|
||||
/* Region-third translation exception if table length is
|
||||
less than high-order 2 bits of region-third index */
|
||||
if (tl < (rtx >> 12))
|
||||
goto reg_third_excp;
|
||||
|
||||
|
||||
/* Add the region-third index (with three low-order zeroes)
|
||||
to the region-third table origin, giving the address of
|
||||
the region-third table entry */
|
||||
rto += rtx;
|
||||
|
||||
|
||||
/* Addressing exception if outside main storage */
|
||||
if (rto > regs->mainlim)
|
||||
goto address_excp;
|
||||
|
||||
|
||||
/* Fetch region-third table entry from absolute storage.
|
||||
All bytes must be fetched concurrently as observed by
|
||||
other CPUs */
|
||||
rte = ARCH_DEP(fetch_doubleword_absolute) (rto, regs);
|
||||
// logmsg("r3te:%16.16llX=>%16.16llX\n",rto,rte);
|
||||
|
||||
|
||||
/* Region-third translation exception if the bit 58 of
|
||||
the region-third table entry is set (region invalid) */
|
||||
if (rte & REGTAB_I)
|
||||
goto reg_third_excp;
|
||||
|
||||
|
||||
/* Translation specification exception if bits 60-61 of
|
||||
the region-third table entry do not indicate the
|
||||
correct type of region table */
|
||||
if ((rte & REGTAB_TT) != TT_R3TABL)
|
||||
goto tran_spec_excp;
|
||||
|
||||
|
||||
/* Extract the segment table origin, offset, and
|
||||
length from the region-third table entry */
|
||||
sto = rte & REGTAB_TO;
|
||||
tf = (rte & REGTAB_TF) >> 6;
|
||||
tl = rte & REGTAB_TL;
|
||||
|
||||
|
||||
/* Fall through to perform segment translation */
|
||||
} /* end switch(tt) */
|
||||
|
||||
|
||||
/* Perform ESAME segment translation */
|
||||
|
||||
|
||||
/* Add the segment index (with three low-order zeroes)
|
||||
to the segment table origin, giving the address of
|
||||
the segment table entry */
|
||||
sto += sx;
|
||||
|
||||
|
||||
/* Segment translation exception if table offset is
|
||||
greater than high-order 2 bits of segment index */
|
||||
if (tf > (sx >> 12))
|
||||
goto seg_tran_length;
|
||||
|
||||
|
||||
/* Segment translation exception if table length is
|
||||
less than high-order 2 bits of segment index */
|
||||
if (tl < (sx >> 12))
|
||||
goto seg_tran_length;
|
||||
|
||||
|
||||
/* Addressing exception if outside real storage */
|
||||
if (sto > regs->mainlim)
|
||||
goto address_excp;
|
||||
|
||||
|
||||
/* Fetch segment table entry from absolute storage. All bytes
|
||||
must be fetched concurrently as observed by other CPUs */
|
||||
ste = ARCH_DEP(fetch_doubleword_absolute) (sto, regs);
|
||||
// logmsg("ste:%16.16llX=>%16.16llX\n",sto,ste);
|
||||
|
||||
|
||||
/* Segment translation exception if segment invalid */
|
||||
if (ste & ZSEGTAB_I)
|
||||
goto seg_tran_invalid;
|
||||
|
||||
|
||||
/* Translation specification exception if bits 60-61 of
|
||||
the segment table entry do not indicate segment table */
|
||||
if ((ste & ZSEGTAB_TT) != TT_SEGTAB)
|
||||
goto tran_spec_excp;
|
||||
|
||||
|
||||
/* Translation specification exception if the ASCE
|
||||
indicates a private space, and the segment table
|
||||
entry indicates a common segment */
|
||||
if (private && (ste & ZSEGTAB_C))
|
||||
goto tran_spec_excp;
|
||||
|
||||
|
||||
/* Extract the page table origin from segment table entry */
|
||||
pto = ste & ZSEGTAB_PTO;
|
||||
|
||||
|
||||
/* Perform ESAME page translation */
|
||||
|
||||
|
||||
/* Add the page index (with three low-order zeroes) to the
|
||||
page table origin, giving address of page table entry */
|
||||
pto += px;
|
||||
|
||||
|
||||
/* Addressing exception if outside real storage */
|
||||
if (pto > regs->mainlim)
|
||||
goto address_excp;
|
||||
|
||||
|
||||
/* Fetch the page table entry from absolute storage. All bytes
|
||||
must be fetched concurrently as observed by other CPUs */
|
||||
pte = ARCH_DEP(fetch_doubleword_absolute) (pto, regs);
|
||||
// logmsg("pte:%16.16llX=>%16.16llX\n",pto,pte);
|
||||
|
||||
|
||||
/* Page translation exception if page invalid */
|
||||
if (pte & ZPGETAB_I)
|
||||
goto page_tran_invalid;
|
||||
|
||||
|
||||
/* Check that all the reserved bits in the PTE are zero */
|
||||
if (pte & ZPGETAB_RESV)
|
||||
goto tran_spec_excp;
|
||||
|
||||
|
||||
} /* end else(ASCE_R) */
|
||||
|
||||
/* [3.11.4.2] Place the translated address in the TLB */
|
||||
@@ -1750,7 +1750,7 @@ int protect = 0;
|
||||
}
|
||||
#endif /*defined(FEATURE_PER2)*/
|
||||
|
||||
#if !defined(OPTION_NO_INLINE_LOGICAL) || defined(_DAT_C)
|
||||
#if !defined(OPTION_NO_INLINE_LOGICAL) || defined(_DAT_C)
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* Convert logical address to absolute address and check protection */
|
||||
/* */
|
||||
@@ -1833,7 +1833,7 @@ int aeind;
|
||||
#if defined(_FEATURE_SIE)
|
||||
if(regs->sie_state && !regs->sie_pref)
|
||||
{
|
||||
U32 sie_stid;
|
||||
int sie_stid;
|
||||
U16 sie_xcode;
|
||||
int sie_private;
|
||||
|
||||
|
||||
4
opcode.h
4
opcode.h
@@ -272,7 +272,7 @@ _if: \
|
||||
(_ip) = (_regs)->inst; \
|
||||
(_regs)->ip = (_ip); \
|
||||
ARCH_DEP(instfetch) ((_regs)->inst, (_regs)->psw.IA, (_regs)); \
|
||||
(regs)->instvalid = 1; \
|
||||
(_regs)->instvalid = 1; \
|
||||
(_pe) = ((_regs)->psw.IA & ~0x7FF) + (0x800 - 6); \
|
||||
pagestart = (_regs)->mainstor + (_regs)->AI; \
|
||||
goto _ex; \
|
||||
@@ -622,7 +622,7 @@ do { \
|
||||
#undef SET_AENOARN
|
||||
#if defined(FEATURE_ACCESS_REGISTERS)
|
||||
#define SET_AENOARN(_regs) \
|
||||
(_regs)->aenoarn = !(ACCESS_REGISTER_MODE(®s->psw))
|
||||
(_regs)->aenoarn = !(ACCESS_REGISTER_MODE(&(_regs)->psw))
|
||||
#else
|
||||
#define SET_AENOARN(_regs) \
|
||||
(_regs)->aenoarn = 1
|
||||
|
||||
24
stack.c
24
stack.c
@@ -126,7 +126,7 @@ QWORD trap_psw;
|
||||
int i;
|
||||
|
||||
if ( REAL_MODE(®s->psw)
|
||||
|| !(PRIMARY_SPACE_MODE(®s->psw)
|
||||
|| !(PRIMARY_SPACE_MODE(®s->psw)
|
||||
|| ACCESS_REGISTER_MODE(®s->psw)) )
|
||||
ARCH_DEP(program_interrupt) (regs, PGM_SPECIAL_OPERATION_EXCEPTION);
|
||||
|
||||
@@ -170,7 +170,7 @@ int i;
|
||||
trap_ia &= 0x7FFFFFFF;
|
||||
|
||||
/* Calculate last byte stored */
|
||||
lastbyte = tsao + 95
|
||||
lastbyte = tsao + 95
|
||||
#if defined(FEATURE_ESAME)
|
||||
+ ((tcba0 & TCB0_R) ? 64 : 0)
|
||||
#endif /*defined(FEATURE_ESAME)*/
|
||||
@@ -200,7 +200,7 @@ int i;
|
||||
#endif /*FEATURE_TRACING*/
|
||||
|
||||
#if defined(FEATURE_PER)
|
||||
if( EN_IC_PER_SB(regs)
|
||||
if( EN_IC_PER_SB(regs)
|
||||
#if defined(FEATURE_PER2)
|
||||
&& ( !(regs->CR(9) & CR9_BAC)
|
||||
|| PER_RANGE_CHECK(trap_ia,regs->CR(10),regs->CR(11)) )
|
||||
@@ -286,13 +286,13 @@ int i;
|
||||
if((tsaa1 & PAGEFRAME_BYTEMASK) == 0)
|
||||
tsaa1 = tsaa2;
|
||||
}
|
||||
|
||||
|
||||
/* Load the Trap Control Block Address in gr15 */
|
||||
regs->GR_L(15) = duct11 & DUCT11_TCBA;
|
||||
|
||||
|
||||
/* Set the Trap program address as a 31 bit instruction address */
|
||||
#if defined(FEATURE_ESAME)
|
||||
regs->psw.amode64 = 0;
|
||||
regs->psw.amode64 = 0;
|
||||
#endif /*defined(FEATURE_ESAME)*/
|
||||
regs->psw.amode = 1;
|
||||
regs->psw.AMASK = AMASK31;
|
||||
@@ -358,7 +358,7 @@ U16 xcode; /* Exception code */
|
||||
#if defined(_FEATURE_SIE)
|
||||
if(regs->sie_state && !regs->sie_pref)
|
||||
{
|
||||
U32 sie_stid;
|
||||
int sie_stid;
|
||||
U16 sie_xcode;
|
||||
int sie_private;
|
||||
|
||||
@@ -377,13 +377,13 @@ U16 xcode; /* Exception code */
|
||||
goto trap_prot;
|
||||
#endif /*defined(_FEATURE_SIE)*/
|
||||
|
||||
if (!((regs->psw.pkey == 0)
|
||||
if (!((regs->psw.pkey == 0)
|
||||
|| ((regs->CR(0) & CR0_STORE_OVRD)
|
||||
&& ((STORAGE_KEY(aaddr, regs) & STORKEY_KEY) == 0x90))))
|
||||
{
|
||||
protect = 0; /* clear ALE, PTE protect flag */
|
||||
/* Check Key protection for store */
|
||||
if (acctype == ACCTYPE_WRITE
|
||||
if (acctype == ACCTYPE_WRITE
|
||||
&& ((STORAGE_KEY(aaddr, regs) & STORKEY_KEY) != regs->psw.pkey))
|
||||
goto trap_prot;
|
||||
|
||||
@@ -491,7 +491,7 @@ U16 xcode; /* Exception code */
|
||||
#if defined(_FEATURE_SIE)
|
||||
if(regs->sie_state && !regs->sie_pref)
|
||||
{
|
||||
U32 sie_stid;
|
||||
int sie_stid;
|
||||
U16 sie_xcode;
|
||||
int sie_private;
|
||||
|
||||
@@ -724,7 +724,7 @@ int i; /* Array subscript */
|
||||
STORE_FW(regs->mainstor + abs, regs->AR(i));
|
||||
|
||||
#ifdef STACK_DEBUG
|
||||
logmsg (_("stack: AR%d=" F_AREG " stored at V:" F_VADR
|
||||
logmsg (_("stack: AR%d=" F_AREG " stored at V:" F_VADR
|
||||
" A:" F_RADR "\n"), i, regs->AR(i), lsea, abs);
|
||||
#endif /*STACK_DEBUG*/
|
||||
|
||||
@@ -912,7 +912,7 @@ int i; /* Array subscript */
|
||||
STORE_FW(regs->mainstor + abs, regs->AR(i));
|
||||
|
||||
#ifdef STACK_DEBUG
|
||||
logmsg (_("stack: AR%d=" F_AREG " stored at V:" F_VADR
|
||||
logmsg (_("stack: AR%d=" F_AREG " stored at V:" F_VADR
|
||||
" A:" F_RADR "\n"), i, regs->AR(i), lsea, abs);
|
||||
#endif /*STACK_DEBUG*/
|
||||
|
||||
|
||||
18
xstore.c
18
xstore.c
@@ -74,7 +74,7 @@ U32 xaddr; /* Expanded storage address */
|
||||
/* cc0 means pgin ok */
|
||||
regs->psw.cc = 0;
|
||||
|
||||
}
|
||||
}
|
||||
#endif /*defined(FEATURE_EXPANDED_STORAGE)*/
|
||||
|
||||
|
||||
@@ -286,7 +286,7 @@ BYTE xpkey1 = 0, xpkey2 = 0; /* Expanded storage keys */
|
||||
#if defined(_FEATURE_SIE)
|
||||
if(regs->sie_state && !regs->sie_pref)
|
||||
{
|
||||
U32 sie_stid;
|
||||
int sie_stid;
|
||||
U16 sie_xcode;
|
||||
int sie_private;
|
||||
|
||||
@@ -340,14 +340,14 @@ BYTE xpkey1 = 0, xpkey2 = 0; /* Expanded storage keys */
|
||||
#if defined(FEATURE_ESAME)
|
||||
2048;
|
||||
#else /*!defined(FEATURE_ESAME)*/
|
||||
/* For ESA/390 mode, the XPTE lies directly beyond
|
||||
/* For ESA/390 mode, the XPTE lies directly beyond
|
||||
the PTE, and each entry is 12 bytes long, we must
|
||||
therefor add 1024 + 8 times the page index */
|
||||
1024 + ((vaddr2 & 0x000FF000) >> 9);
|
||||
#endif /*!defined(FEATURE_ESAME)*/
|
||||
if (xpkeya > regs->mainlim)
|
||||
ARCH_DEP(program_interrupt) (regs, PGM_ADDRESSING_EXCEPTION);
|
||||
xpkey2 = regs->mainstor[xpkeya];
|
||||
xpkey2 = regs->mainstor[xpkeya];
|
||||
|
||||
/*DEBUG logmsg("MVPG pte2 = " F_CREG ", xkey2 = %2.2X, xpblk2 = %5.5X, akey2 = %2.2X\n",
|
||||
pte2,xpkey2,xpblk2,akey2); */
|
||||
@@ -386,7 +386,7 @@ BYTE xpkey1 = 0, xpkey2 = 0; /* Expanded storage keys */
|
||||
#if defined(_FEATURE_SIE)
|
||||
if(regs->sie_state && !regs->sie_pref)
|
||||
{
|
||||
U32 sie_stid;
|
||||
int sie_stid;
|
||||
U16 sie_xcode;
|
||||
int sie_private;
|
||||
|
||||
@@ -440,14 +440,14 @@ BYTE xpkey1 = 0, xpkey2 = 0; /* Expanded storage keys */
|
||||
#if defined(FEATURE_ESAME)
|
||||
2048;
|
||||
#else /*!defined(FEATURE_ESAME)*/
|
||||
/* For ESA/390 mode, the XPTE lies directly beyond
|
||||
/* For ESA/390 mode, the XPTE lies directly beyond
|
||||
the PTE, and each entry is 12 bytes long, we must
|
||||
therefor add 1024 + 8 times the page index */
|
||||
1024 + ((vaddr1 & 0x000FF000) >> 9);
|
||||
#endif /*!defined(FEATURE_ESAME)*/
|
||||
if (xpkeya > regs->mainlim)
|
||||
ARCH_DEP(program_interrupt) (regs, PGM_ADDRESSING_EXCEPTION);
|
||||
xpkey1 = regs->mainstor[xpkeya];
|
||||
xpkey1 = regs->mainstor[xpkeya];
|
||||
|
||||
/*DEBUG logmsg("MVPG pte1 = " F_CREG ", xkey1 = %2.2X, xpblk1 = %5.5X, akey1 = %2.2X\n",
|
||||
pte1,xpkey1,xpblk1,akey1); */
|
||||
@@ -543,7 +543,7 @@ BYTE xpkey1 = 0, xpkey2 = 0; /* Expanded storage keys */
|
||||
#endif /*defined(FEATURE_EXPANDED_STORAGE)*/
|
||||
{
|
||||
/* Obtain absolute address of main storage block,
|
||||
check protection, and set reference bit.
|
||||
check protection, and set reference bit.
|
||||
Use last byte of page to avoid FPO area. */
|
||||
aaddr2 = LOGICAL_TO_ABS (vaddr2 + 0xFFF, r2, regs,
|
||||
ACCTYPE_READ, akey2);
|
||||
@@ -559,7 +559,7 @@ BYTE xpkey1 = 0, xpkey2 = 0; /* Expanded storage keys */
|
||||
|
||||
/* Set Expanded Storage reference bit in the PTE */
|
||||
STORE_W(regs->mainstor + raddr2, pte2 | PAGETAB_ESREF);
|
||||
|
||||
|
||||
|
||||
/* Move 4K bytes from expanded storage to main storage */
|
||||
memcpy (regs->mainstor + aaddr1,
|
||||
|
||||
Reference in New Issue
Block a user