1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-03-10 20:34:47 +00:00

KA10: Cleaned up FE support, ITS IMP now working.

This commit is contained in:
Richard Cornwell
2019-09-25 19:46:16 -04:00
parent a31b200c57
commit 94709e1fab
5 changed files with 750 additions and 364 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -157,6 +157,7 @@ int pi_enable; /* Interrupts enabled */
int parity_irq; /* Parity interupt */
int pi_pending; /* Interrupt pending. */
int pi_enc; /* Flag for pi */
int pi_vect; /* Last pi location used for IRQ */
int apr_irq; /* Apr Irq level */
int clk_en; /* Enable clock interrupts */
int clk_irq; /* Clock interrupt */
@@ -266,6 +267,8 @@ int32 tmxr_poll = 10000;
/* Physical address range for auxiliary PDP-6. */
#define AUXCPURANGE(addr) ((addr) >= 03000000 && (addr) < 03040000)
/* List of RH10 & RH20 devices */
DEVICE *rh_devs[] = {
#if (NUM_DEVS_RS > 0)
&rsa_dev,
@@ -287,16 +290,10 @@ DEVICE *rh_devs[] = {
#endif
NULL,
};
struct rh_dev rh[] = {
{ 0270, NULL, },
{ 0274, NULL, },
{ 0360, NULL, },
{ 0364, NULL, },
{ 0370, NULL, },
{ 0374, NULL, },
{ 0, NULL, },
};
/* RH10 device numbers */
int rh_nums[] = { 0270, 0274, 0360, 0364, 0370, 0374, 0};
/* Maps RH10 & RH20 device number to DEVICE structure */
struct rh_dev rh[8];
typedef struct {
uint32 pc;
@@ -2355,7 +2352,7 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context, int fetch
/* Check for access error */
if ((data & RSIGN) == 0 || (wr & ((data & 0100000) == 0))) {
fprintf(stderr, "Page fault %06o a=%o wr=%o w=%o %06o\n\r", addr, (data & RSIGN) == 0, wr, (data & 0100000) == 0, data);
//fprintf(stderr, "Page fault %06o a=%o wr=%o w=%o %06o\n\r", addr, (data & RSIGN) == 0, wr, (data & 0100000) == 0, data);
fault_data = BIT8 | (uint64)addr;
#if KLB
if (QKLB)
@@ -2462,7 +2459,7 @@ int Mem_read(int flag, int cur_context, int fetch) {
fault_data = (027LL << 30) | (uint64)addr | (((uint64)sect) << 18);
if (USER==0) /* U */
fault_data |= SMASK; /* BIT0 */
fprintf(stderr, "Invalid section %012llo\n\r", fault_data);
//fprintf(stderr, "Invalid section %012llo\n\r", fault_data);
page_fault = 1;
return 0;
}
@@ -2508,7 +2505,7 @@ int Mem_write(int flag, int cur_context) {
fault_data = (027LL << 30) | (uint64)addr | (((uint64)sect) << 18);
if (USER==0) /* U */
fault_data |= SMASK; /* BIT0 */
fprintf(stderr, "Invalid section %012llo\n\r", fault_data);
//fprintf(stderr, "Invalid section %012llo\n\r", fault_data);
page_fault = 1;
return 0;
}
@@ -2615,12 +2612,12 @@ int Mem_deposit_word(int n, int wrd, uint64 *data) {
/*
* Read in 16 bits of data from a byte pointer.
*/
int Mem_read_byte(int n, uint16 *data) {
int Mem_read_byte(int n, uint16 *data, int byte) {
int addr;
uint64 val;
uint64 msk;
int p, s, np;
int need = 16;
int need = byte? 8: 16;
*data = 0;
while (need > 0) {
@@ -4222,18 +4219,23 @@ st_pi:
* hit at a given level.
*/
for (f = 0; f < 128; f++) {
if (dev_irqv[f] != 0)
sim_debug(DEBUG_IRQ, &cpu_dev, "vect irq %o %03o \n",
pi_enc, dev_irq[f]);
if (dev_irqv[f] != 0 && dev_irq[f] & (0200 >> pi_enc)) {
AB = dev_irqv[f](f << 2, AB);
if (dev_irqv[f] != 0)
sim_debug(DEBUG_IRQ, &cpu_dev, "vect irq %o %03o %06o\n",
pi_enc, dev_irq[f], AB);
break;
}
}
AB |= eb_ptr;
if (AB & RSIGN)
AB &= 0777;
else
AB |= eb_ptr;
pi_vect = AB;
Mem_read_nopage();
goto no_fetch;
#else
pi_vect = AB;
goto fetch;
#endif
}
@@ -7022,7 +7024,6 @@ xjrstf:
if (QKLB) {
pc_sect = (AR >> 18) & 07777;
prev_sect = BR & 037;
fprintf(stderr, "xjrstf %012llo %012llo\n\r", BR, AR);
}
#endif
BR = BR >> 23; /* Move flags into position */
@@ -8409,7 +8410,7 @@ last:
#if KI | KL
if (page_enable && page_fault) {
page_fault = 0;
fprintf(stderr, "Page fault trap %06o\n\r", PC);
//fprintf(stderr, "Page fault trap %06o\n\r", PC);
pi_cycle = 0;
#if KI
inout_fail = 1;
@@ -8428,9 +8429,8 @@ fprintf(stderr, "Page fault trap %06o\n\r", PC);
if ((!pi_hold) & f_inst_fetch) {
pi_cycle = 0;
} else {
AB = 040 | (pi_enc << 1) | pi_ov | maoff;
AB = pi_vect | pi_ov;
#if KI | KL
AB |= eb_ptr;
Mem_read_nopage();
#else
Mem_read(1, 0, 1);
@@ -8441,11 +8441,10 @@ fprintf(stderr, "Page fault trap %06o\n\r", PC);
if ((IR & 0700) == 0700) {
(void)check_irq_level();
}
AB = 040 | (pi_enc << 1) | pi_ov | maoff;
AB = pi_vect | pi_ov;
pi_ov = 0;
pi_hold = 0;
#if KI | KL
AB |= eb_ptr;
Mem_read_nopage();
#else
Mem_read(1, 0, 1);
@@ -9572,7 +9571,7 @@ t_bool build_dev_tab (void)
DEVICE *dptr;
DIB *dibp;
uint32 i, j, d;
int rh20 = 0540;
int rh20;
/* Set trap offset based on MAOFF flag */
maoff = (cpu_unit[0].flags & UNIT_MAOFF)? 0100 : 0;
@@ -9626,15 +9625,23 @@ if (QBBN)
dev_tab[024>>2] = &dev_pag;
#endif
/* Assign all RH10 devices */
/* Assign all RH10 & RH20 devices */
rh20 = 0540;
for (j = i = 0; (dptr = rh_devs[i]) != NULL; i++) {
dibp = (DIB *) dptr->ctxt;
if (dibp && !(dptr->flags & DEV_DIS)) { /* enabled? */
if (rh[j].dev_num == 0)
break;
d = rh[j].dev_num;
d = dibp->dev_num; /* Check type */
if (d & RH10_DEV) { /* Skip RH10 devices */
d = rh_nums[j];
if (d == 0)
break;
} else if (d & RH20_DEV) { /* RH20, grab next device */
d = rh20;
rh20 += 4;
}
dev_tab[(d >> 2)] = dibp->io;
dev_irqv[(d >> 2)] = dibp->irq;
rh[j].dev_num = d;
rh[j].dev = dptr;
j++;
}
@@ -9653,12 +9660,8 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) {
for (j = 0; j < dibp->num_devs; j++) { /* loop thru disp */
if (dibp->io) { /* any dispatch? */
d = dibp->dev_num;
if (d & RH10_DEV) /* Skip RH10 devices */
if (d & (RH10_DEV|RH20_DEV)) /* Skip RH10 & RH20 devices */
continue;
if (d & RH20_DEV) { /* RH20, grab next device */
d = rh20;
rh20 += 4;
}
if (dev_tab[(d >> 2) + j] != &null_dev) {
/* already filled? */
sim_printf ("%s device number conflict at %02o\n",

View File

@@ -376,7 +376,7 @@ extern UNIT auxcpu_unit[];
/* DTE memory access functions, n = DTE# */
extern int Mem_examine_word(int n, int wrd, uint64 *data);
extern int Mem_deposit_word(int n, int wrd, uint64 *data);
extern int Mem_read_byte(int n, uint16 *data);
extern int Mem_read_byte(int n, uint16 *data, int byte);
extern int Mem_write_byte(int n, uint16 *data);
extern DEVICE dte_dev;
extern DEVICE tty_dev;
@@ -541,7 +541,7 @@ int auxcpu_write (int addr, t_uint64);
#define NUM_DEVS_TEN11 ITS
#define NUM_DEVS_AUXCPU ITS
#define NUM_DEVS_IMP 1
#define NUM_DEVS_CH10 ITS
#define NUM_DEVS_CH10 ITS | KL_ITS
#define NUM_DEVS_DPK ITS
#define NUM_DEVS_AI ITS
#endif

View File

@@ -145,7 +145,7 @@
#endif
#endif
#define IMP_ARPTAB_SIZE 8
#define IMP_ARPTAB_SIZE 64
#define IMP_ARP_MAX_AGE 100
uint32 mask[] = {
@@ -199,6 +199,12 @@ struct tcp {
uint32 seq; /* Sequence number */
uint32 ack; /* Ack number */
uint16 flags; /* Flags */
#define TCP_FL_FIN 0x01
#define TCP_FL_SYN 0x02
#define TCP_FL_RST 0x04
#define TCP_FL_PSH 0x08
#define TCP_FL_ACK 0x10
#define TCP_FL_URG 0x20
uint16 window; /* Window size */
uint16 chksum; /* packet checksum */
uint16 urgent; /* Urgent pointer */
@@ -445,6 +451,7 @@ static CONST ETH_MAC broadcast_ethaddr = {0xff,0xff,0xff,0xff,0xff,0xff};
static CONST in_addr_T broadcast_ipaddr = {0xffffffff};
t_stat imp_devio(uint32 dev, uint64 *data);
t_stat imp_devirq(uint32 dev, int addr);
t_stat imp_srv(UNIT *);
t_stat imp_eth_srv(UNIT *);
t_stat imp_tim_srv(UNIT *);
@@ -473,6 +480,8 @@ void imp_arp_arpin(struct imp_device *imp, ETH_PACK *packet);
void imp_arp_arpout(struct imp_device *imp, in_addr_T ipaddr);
struct arp_entry * imp_arp_lookup(struct imp_device *imp, in_addr_T ipaddr);
void imp_packet_out(struct imp_device *imp, ETH_PACK *packet);
void imp_packet_debug(struct imp_device *imp, const char *action, ETH_PACK *packet);
void imp_write(struct imp_device *imp, ETH_PACK *packet);
void imp_do_dhcp_client(struct imp_device *imp, ETH_PACK *packet);
void imp_dhcp_timer(struct imp_device *imp);
void imp_dhcp_discover(struct imp_device *imp);
@@ -495,7 +504,13 @@ UNIT imp_unit[] = {
{UDATA(imp_eth_srv, UNIT_IDLE+UNIT_DIS, 0)}, /* 0 */
{UDATA(imp_tim_srv, UNIT_IDLE+UNIT_DIS, 0)}, /* 0 */
};
DIB imp_dib = {IMP_DEVNUM, 1, &imp_devio, NULL};
DIB imp_dib = {IMP_DEVNUM, 1, &imp_devio,
#if KL
&imp_devirq,
#else
NULL
#endif
};
MTAB imp_mod[] = {
{ MTAB_XTD|MTAB_VDV|MTAB_VALR|MTAB_NC, 0, "MAC", "MAC=xx:xx:xx:xx:xx:xx",
@@ -529,11 +544,38 @@ MTAB imp_mod[] = {
{ 0 }
};
/* Simulator debug controls */
DEBTAB imp_debug[] = {
{"CMD", DEBUG_CMD, "Show command execution to devices"},
{"DATA", DEBUG_DATA, "Show data transfers"},
{"DETAIL", DEBUG_DETAIL, "Show details about device"},
{"EXP", DEBUG_EXP, "Show exception information"},
{"CONI", DEBUG_CONI, "Show coni instructions"},
{"CONO", DEBUG_CONO, "Show coni instructions"},
{"DATAIO", DEBUG_DATAIO, "Show datai and datao instructions"},
{"IRQ", DEBUG_IRQ, "Show IRQ requests"},
#define DEBUG_DHCP (DEBUG_IRQ<<1)
{"DHCP", DEBUG_DHCP, "Show DHCP activities"},
#define DEBUG_ARP (DEBUG_DHCP<<1)
{"ARP", DEBUG_ARP, "Show ARP activities"},
#define DEBUG_TCP (DEBUG_ARP<<1)
{"TCP", DEBUG_TCP, "Show TCP packet activities"},
#define DEBUG_UDP (DEBUG_TCP<<1)
{"UDP", DEBUG_UDP, "Show UDP packet activities"},
#define DEBUG_ICMP (DEBUG_UDP<<1)
{"ICMP", DEBUG_ICMP, "Show ICMP packet activities"},
#define DEBUG_ETHER (DEBUG_ICMP<<1)
{"ETHER", DEBUG_ETHER, "Show ETHER activities"},
{0, 0}
};
DEVICE imp_dev = {
"IMP", imp_unit, NULL, imp_mod,
3, 8, 0, 1, 8, 36,
NULL, NULL, &imp_reset, NULL, &imp_attach, &imp_detach,
&imp_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG, 0, dev_debug,
&imp_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG, 0, imp_debug,
NULL, NULL, &imp_help, NULL, NULL, &imp_description
};
#define IMP_OCHN 0000007
@@ -600,6 +642,7 @@ t_stat imp_devio(uint32 dev, uint64 *data)
uptr->STATUS |= IMPIHE;
if (*data & IMPLHW) /* Last host word. */
uptr->STATUS |= IMPLHW;
check_interrupts(uptr);
break;
case TYPE_BBN:
break;
@@ -696,6 +739,20 @@ t_stat imp_devio(uint32 dev, uint64 *data)
return SCPE_OK;
}
#if KL
/* Handle KL style interrupt vectors for ITS */
int
imp_devirq(uint32 dev, int addr) {
if ((cpu_unit[0].flags & UNIT_ITSPAGE) != 0 && (imp_data.pia & 7) == 1) {
if (imp_unit[0].STATUS & IMPID && (imp_unit[0].STATUS & IMPLW) == 0)
return 070|RSIGN;
if (imp_unit[0].STATUS & IMPOD)
return 072|RSIGN;
}
return addr;
}
#endif
t_stat imp_srv(UNIT * uptr)
{
DEVICE *dptr = find_dev_from_unit(uptr);
@@ -831,8 +888,8 @@ t_stat imp_eth_srv(UNIT * uptr)
imp_data.dhcp_state != DHCP_STATE_REBINDING &&
imp_data.dhcp_state != DHCP_STATE_RENEWING)
return SCPE_OK;
sim_debug(DEBUG_DETAIL, &imp_dev, "IMP init Nop %d\n",
imp_data.init_state);
sim_debug(DEBUG_DETAIL, &imp_dev, "IMP init Nop %d\n",
imp_data.init_state);
if (imp_unit[0].ILEN == 0) {
/* Queue up a nop packet */
imp_data.rbuffer[0] = 0x4;
@@ -922,6 +979,7 @@ imp_packet_in(struct imp_device *imp)
}
return;
}
imp_packet_debug(imp, "Received", &read_buffer);
hdr = (struct imp_eth_hdr *)(&read_buffer.msg[0]);
type = ntohs(hdr->type);
if (type == ETHTYPE_ARP) {
@@ -1083,9 +1141,11 @@ imp_packet_in(struct imp_device *imp)
/* Lastly check if ICMP */
} else if (ip_hdr->ip_p == ICMP_PROTO) {
struct icmp *icmp_hdr = (struct icmp *)payload;
checksumadjust((uint8 *)&icmp_hdr->chksum,
(uint8 *)(&ip_hdr->ip_src), sizeof(in_addr_T),
(uint8 *)(&imp_data.hostip), sizeof(in_addr_T));
if ((icmp_hdr->type != 0) && /* Not Echo Reply */
(icmp_hdr->type != 8)) /* and Not Echo */
checksumadjust((uint8 *)&icmp_hdr->chksum,
(uint8 *)(&ip_hdr->ip_src), sizeof(in_addr_T),
(uint8 *)(&imp_data.hostip), sizeof(in_addr_T));
}
checksumadjust((uint8 *)&ip_hdr->ip_sum,
(uint8 *)(&ip_hdr->ip_dst), sizeof(in_addr_T),
@@ -1309,9 +1369,11 @@ imp_packet_out(struct imp_device *imp, ETH_PACK *packet) {
/* Lastly check if ICMP */
} else if (pkt->iphdr.ip_p == ICMP_PROTO) {
struct icmp *icmp_hdr = (struct icmp *)payload;
checksumadjust((uint8 *)&icmp_hdr->chksum,
(uint8 *)(&pkt->iphdr.ip_src), sizeof(in_addr_T),
(uint8 *)(&imp->ip), sizeof(in_addr_T));
if ((icmp_hdr->type != 0) && /* Not Echo Reply */
(icmp_hdr->type != 8)) /* and Not Echo */
checksumadjust((uint8 *)&icmp_hdr->chksum,
(uint8 *)(&pkt->iphdr.ip_src), sizeof(in_addr_T),
(uint8 *)(&imp->ip), sizeof(in_addr_T));
}
/* Lastly update the header and IP address */
checksumadjust((uint8 *)&pkt->iphdr.ip_sum,
@@ -1337,7 +1399,7 @@ imp_packet_out(struct imp_device *imp, ETH_PACK *packet) {
memcpy(&pkt->ethhdr.dest, &tabptr->ethaddr, 6);
memcpy(&pkt->ethhdr.src, &imp->mac, 6);
pkt->ethhdr.type = htons(ETHTYPE_IP);
eth_write(&imp->etherface, packet, NULL);
imp_write(imp, packet);
imp->rfnm_count++;
return;
}
@@ -1357,6 +1419,259 @@ imp_packet_out(struct imp_device *imp, ETH_PACK *packet) {
}
void imp_packet_debug(struct imp_device *imp, const char *action, ETH_PACK *packet) {
struct imp_eth_hdr *eth = (struct imp_eth_hdr *)&packet->msg[0];
struct arp_hdr *arp = (struct arp_hdr *)eth;
struct ip *ip = (struct ip *)&packet->msg[sizeof(struct imp_eth_hdr)];
struct udp *udp;
struct tcp *tcp;
struct icmp *icmp;
uint8 *payload;
struct in_addr ipaddr;
size_t len;
int flag;
char src_ip[20];
char dst_ip[20];
char src_port[8];
char dst_port[8];
char mac_buf[20];
char flags[64];
static struct tcp_flag_bits {
const char *name;
uint16 bitmask;
} bits[] = {
{"FIN", TCP_FL_FIN},
{"SYN", TCP_FL_SYN},
{"RST", TCP_FL_RST},
{"PSH", TCP_FL_PSH},
{"ACK", TCP_FL_ACK},
{"URG", TCP_FL_URG},
{NULL, 0}
};
static const char *icmp_types[] = {
"Echo Reply", // Type 0
"Type 1 - Unassigned",
"Type 2 - Unassigned",
"Destination Unreachable", // Type 3
"Source Quench (Deprecated)", // Type 4
"Redirect", // Type 5
"Type 6 - Alternate Host Address (Deprecated)",
"Type 7 - Unassigned",
"Echo Request", // Type 8
"Router Advertisement", // Type 9
"Router Selection", // Type 10
"Time Exceeded", // Type 11
"Type 12 - Parameter Problem",
"Type 13 - Timestamp",
"Type 14 - Timestamp Reply",
"Type 15 - Information Request (Deprecated)",
"Type 16 - Information Reply (Deprecated)",
"Type 17 - Address Mask Request (Deprecated)",
"Type 18 - Address Mask Reply (Deprecated)",
"Type 19 - Reserved (for Security)",
"Type 20 - Reserved (for Robustness Experiment)",
"Type 21 - Reserved (for Robustness Experiment)",
"Type 22 - Reserved (for Robustness Experiment)",
"Type 23 - Reserved (for Robustness Experiment)",
"Type 24 - Reserved (for Robustness Experiment)",
"Type 25 - Reserved (for Robustness Experiment)",
"Type 26 - Reserved (for Robustness Experiment)",
"Type 27 - Reserved (for Robustness Experiment)",
"Type 28 - Reserved (for Robustness Experiment)",
"Type 29 - Reserved (for Robustness Experiment)",
"Type 30 - Traceroute (Deprecated)",
"Type 31 - Datagram Conversion Error (Deprecated)",
"Type 32 - Mobile Host Redirect (Deprecated)",
"Type 33 - IPv6 Where-Are-You (Deprecated)",
"Type 34 - IPv6 I-Am-Here (Deprecated)",
"Type 35 - Mobile Registration Request (Deprecated)",
"Type 36 - Mobile Registration Reply (Deprecated)",
"Type 37 - Domain Name Request (Deprecated)",
"Type 38 - Domain Name Reply (Deprecated)",
"Type 39 - SKIP (Deprecated)",
"Type 40 - Photuris",
"Type 41 - ICMP messages utilized by experimental mobility protocols such as Seamoby",
"Type 42 - Extended Echo Request",
"Type 43 - Extended Echo Reply"
};
if (ntohs(eth->type) == ETHTYPE_ARP) {
struct in_addr in_addr;
const char *arp_op = (ARP_REQUEST == ntohs(arp->opcode)) ? "REQUEST" : ((ARP_REPLY == ntohs(arp->opcode)) ? "REPLY" : "Unknown");
char eth_src[20], eth_dst[20];
char arp_shwaddr[20], arp_dhwaddr[20];
char arp_sipaddr[20], arp_dipaddr[20];
if (!(imp_dev.dctrl & DEBUG_ARP))
return;
eth_mac_fmt(&arp->ethhdr.src, eth_src);
eth_mac_fmt(&arp->ethhdr.dest, eth_dst);
eth_mac_fmt(&arp->shwaddr, arp_shwaddr);
memcpy(&in_addr, &arp->sipaddr, sizeof(in_addr));
strlcpy(arp_sipaddr, ipv4_inet_ntoa(in_addr), sizeof(arp_sipaddr));
eth_mac_fmt(&arp->dhwaddr, arp_dhwaddr);
memcpy(&in_addr, &arp->dipaddr, sizeof(in_addr));
strlcpy(arp_dipaddr, ipv4_inet_ntoa(in_addr), sizeof(arp_dipaddr));
sim_debug(DEBUG_ARP, &imp_dev,
"%s %s EthDst=%s EthSrc=%s shwaddr=%s sipaddr=%s dhwaddr=%s dipaddr=%s\n",
action, arp_op, eth_dst, eth_src, arp_shwaddr, arp_sipaddr, arp_dhwaddr, arp_dipaddr);
return;
}
if (ntohs(eth->type) != ETHTYPE_IP)
return;
if (!(imp_dev.dctrl & (DEBUG_TCP|DEBUG_UDP|DEBUG_ICMP)))
return;
memcpy(&ipaddr, &ip->ip_src, sizeof(ipaddr));
strlcpy(src_ip, ipv4_inet_ntoa(ipaddr), sizeof(src_ip));
memcpy(&ipaddr, &ip->ip_dst, sizeof(ipaddr));
strlcpy(dst_ip, ipv4_inet_ntoa(ipaddr), sizeof(dst_ip));
payload = (uint8 *)&packet->msg[sizeof(struct imp_eth_hdr) + (ip->ip_v_hl & 0xf) * 4];
switch (ip->ip_p) {
case UDP_PROTO:
udp = (struct udp *)payload;
snprintf(src_port, sizeof(src_port), "%d", ntohs(udp->udp_sport));
snprintf(dst_port, sizeof(dst_port), "%d", ntohs(udp->udp_dport));
sim_debug(DEBUG_UDP, &imp_dev, "%s %d byte packet from %s:%s to %s:%s\n", action,
ntohs(udp->len), src_ip, src_port, dst_ip, dst_port);
if ((imp_dev.dctrl & DEBUG_DHCP) &&
(((ntohs(udp->udp_sport) == DHCP_UDP_PORT_CLIENT) &&
(ntohs(udp->udp_dport) == DHCP_UDP_PORT_SERVER)) ||
((ntohs(udp->udp_dport) == DHCP_UDP_PORT_CLIENT) &&
(ntohs(udp->udp_sport) == DHCP_UDP_PORT_SERVER)))) {
struct dhcp *dhcp = (struct dhcp *)(payload + sizeof(struct udp));
uint8 *opt = &dhcp->options[0];
sim_debug(DEBUG_DHCP, &imp_dev, "%s XID=%08X",
(dhcp->op == DHCP_BOOTREQUEST) ? "REQUEST" :
(dhcp->op == DHCP_BOOTREPLY) ? "REPLY" :
"??????",
dhcp->xid);
if (dhcp->ciaddr) {
memcpy(&ipaddr, &dhcp->ciaddr, sizeof(ipaddr));
sim_debug(DEBUG_DHCP, &imp_dev, ", ciaddr=%s", ipv4_inet_ntoa(ipaddr));
}
if (dhcp->yiaddr) {
memcpy(&ipaddr, &dhcp->yiaddr, sizeof(ipaddr));
sim_debug(DEBUG_DHCP, &imp_dev, ", yiaddr=%s", ipv4_inet_ntoa(ipaddr));
}
if (dhcp->siaddr) {
memcpy(&ipaddr, &dhcp->siaddr, sizeof(ipaddr));
sim_debug(DEBUG_DHCP, &imp_dev, ", siaddr=%s", ipv4_inet_ntoa(ipaddr));
}
if (dhcp->giaddr) {
memcpy(&ipaddr, &dhcp->giaddr, sizeof(ipaddr));
sim_debug(DEBUG_DHCP, &imp_dev, ", giaddr=%s", ipv4_inet_ntoa(ipaddr));
}
eth_mac_fmt((ETH_MAC*)&dhcp->chaddr, mac_buf);
sim_debug(DEBUG_DHCP, &imp_dev, ", chaddr=%s Options: ", mac_buf);
while (*opt != DHCP_OPTION_END) {
int opt_len;
u_long numeric;
static const char *opr_names[] = {
"", "DISCOVER", "OFFER", "REQUEST",
"DECLINE", "ACK", "NAK", "RELEASE",
"INFORM"
};
switch(*opt++) {
case DHCP_OPTION_PAD:
break;
default:
opt_len = *opt++;
opt += opt_len;
break;
case DHCP_OPTION_SUBNET_MASK:
opt_len = *opt++;
memcpy(&ipaddr, opt, 4);
sim_debug(DEBUG_DHCP, &imp_dev, ", mask=%s", ipv4_inet_ntoa(ipaddr));
opt += opt_len;
break;
case DHCP_OPTION_ROUTER:
opt_len = *opt++;
memcpy(&ipaddr, opt, 4);
sim_debug(DEBUG_DHCP, &imp_dev, ", router=%s", ipv4_inet_ntoa(ipaddr));
opt += opt_len;
break;
case DHCP_OPTION_REQUESTED_IP:
opt_len = *opt++;
memcpy(&ipaddr, opt, 4);
sim_debug(DEBUG_DHCP, &imp_dev, ", requested-ip=%s", ipv4_inet_ntoa(ipaddr));
opt += opt_len;
break;
case DHCP_OPTION_LEASE_TIME:
opt_len = *opt++;
memcpy(&numeric, opt, 4);
sim_debug(DEBUG_DHCP, &imp_dev, ", lease-time=%d", ntohl(numeric));
opt += opt_len;
break;
case DHCP_OPTION_T1:
opt_len = *opt++;
memcpy(&numeric, opt, 4);
sim_debug(DEBUG_DHCP, &imp_dev, ", renew-time=%d", ntohl(numeric));
opt += opt_len;
break;
case DHCP_OPTION_T2:
opt_len = *opt++;
memcpy(&numeric, opt, 4);
sim_debug(DEBUG_DHCP, &imp_dev, ", rebind-time=%d", ntohl(numeric));
opt += opt_len;
break;
case DHCP_OPTION_SERVER_ID:
opt_len = *opt++;
memcpy(&ipaddr, opt, 4);
sim_debug(DEBUG_DHCP, &imp_dev, ", server-ip=%s", ipv4_inet_ntoa(ipaddr));
opt += opt_len;
break;
case DHCP_OPTION_MESSAGE_TYPE:
opt_len = *opt++;
sim_debug(DEBUG_DHCP, &imp_dev, "MessageType=%s", opr_names[*opt]);
opt += opt_len;
break;
}
}
sim_debug(DEBUG_DHCP, &imp_dev, "\n");
} else {
if (udp->len && (imp_dev.dctrl & DEBUG_UDP))
sim_data_trace(&imp_dev, imp_unit, payload + sizeof(struct udp), "",
ntohs(udp->len), "", DEBUG_DATA);
}
break;
case TCP_PROTO:
tcp = (struct tcp *)payload;
snprintf(src_port, sizeof(src_port), "%d", ntohs(tcp->tcp_sport));
snprintf(dst_port, sizeof(dst_port), "%d", ntohs(tcp->tcp_dport));
strlcpy(flags, "", sizeof(flags));
for (flag=0; bits[flag].name; flag++) {
if (ntohs(tcp->flags) & bits[flag].bitmask) {
if (*flags)
strlcat(flags, ",", sizeof(flags));
strlcat(flags, bits[flag].name, sizeof(flags));
}
}
len = ntohs(ip->ip_len) - ((ip->ip_v_hl & 0xf) * 4 + (ntohs(tcp->flags) >> 12) * 4);
sim_debug(DEBUG_TCP, &imp_dev, "%s %s%s %d byte packet from %s:%s to %s:%s\n", action,
flags, *flags ? ":" : "", (int)len, src_ip, src_port, dst_ip, dst_port);
if (len && (imp_dev.dctrl & DEBUG_TCP))
sim_data_trace(&imp_dev, imp_unit, payload + 4 * (ntohs(tcp->flags) >> 12), "", len, "", DEBUG_DATA);
break;
case ICMP_PROTO:
icmp = (struct icmp *)payload;
len = ntohs(ip->ip_len) - (ip->ip_v_hl & 0xf) * 4;
sim_debug(DEBUG_ICMP, &imp_dev, "%s %s %d byte packet from %s to %s\n", action,
(icmp->type < sizeof(icmp_types)/sizeof(icmp_types[0])) ? icmp_types[icmp->type] : "", (int)len, src_ip, dst_ip);
if (len && (imp_dev.dctrl & DEBUG_ICMP))
sim_data_trace(&imp_dev, imp_unit, payload + sizeof(struct icmp), "", len, "", DEBUG_DATA);
break;
}
}
void imp_write(struct imp_device *imp, ETH_PACK *packet) {
imp_packet_debug(imp, "Sending", packet);
eth_write(&imp->etherface, packet, NULL);
}
/*
* Update the ARP table, first use free entry, else use oldest.
*/
@@ -1365,6 +1680,7 @@ imp_arp_update(struct imp_device *imp, in_addr_T ipaddr, ETH_MAC *ethaddr, int a
{
struct arp_entry *tabptr;
int i;
char mac_buf[20];
/* Check if entry already in the table. */
for (i = 0; i < IMP_ARPTAB_SIZE; i++) {
@@ -1372,7 +1688,13 @@ imp_arp_update(struct imp_device *imp, in_addr_T ipaddr, ETH_MAC *ethaddr, int a
if (tabptr->ipaddr != 0) {
if (tabptr->ipaddr == ipaddr) {
memcpy(&tabptr->ethaddr, ethaddr, sizeof(ETH_MAC));
if (0 != memcmp(&tabptr->ethaddr, ethaddr, sizeof(ETH_MAC))) {
memcpy(&tabptr->ethaddr, ethaddr, sizeof(ETH_MAC));
eth_mac_fmt(ethaddr, mac_buf);
sim_debug(DEBUG_ARP, &imp_dev,
"updating entry for IP %s to %s\n",
ipv4_inet_ntoa(*((struct in_addr *)&ipaddr)), mac_buf);
}
if (tabptr->age != ARP_DONT_AGE)
tabptr->age = age;
return;
@@ -1402,10 +1724,14 @@ imp_arp_update(struct imp_device *imp, in_addr_T ipaddr, ETH_MAC *ethaddr, int a
tabptr = &imp->arp_table[fnd];
}
/* Now update the entry */
/* Now save the entry */
memcpy(&tabptr->ethaddr, ethaddr, sizeof(ETH_MAC));
tabptr->ipaddr = ipaddr;
tabptr->age = age;
eth_mac_fmt(ethaddr, mac_buf);
sim_debug(DEBUG_ARP, &imp_dev,
"creating entry for IP %s to %s, initial age=%d\n",
ipv4_inet_ntoa(*((struct in_addr *)&ipaddr)), mac_buf, age);
}
/*
@@ -1423,6 +1749,12 @@ void imp_arp_age(struct imp_device *imp)
tabptr->age++; /* Age it */
/* expire too old entries */
if (tabptr->age > IMP_ARP_MAX_AGE) {
char mac_buf[20];
eth_mac_fmt(&tabptr->ethaddr, mac_buf);
sim_debug(DEBUG_ARP, &imp_dev,
"discarding ARP entry for IP %s %s after %d seconds\n",
ipv4_inet_ntoa(*((struct in_addr *)&tabptr->ipaddr)), mac_buf, IMP_ARP_MAX_AGE);
memset(tabptr, 0, sizeof(*tabptr));
}
}
@@ -1438,18 +1770,20 @@ void
imp_arp_arpin(struct imp_device *imp, ETH_PACK *packet)
{
struct arp_hdr *arp;
struct in_addr in_addr;
int op;
char mac_buf[20];
/* Ignore packet if too short */
if (packet->len < sizeof(struct arp_hdr))
return;
arp = (struct arp_hdr *)(&packet->msg[0]);
op = ntohs(arp->opcode);
imp_arp_update(imp, arp->sipaddr, &arp->shwaddr, 0);
switch (op) {
case ARP_REQUEST:
if (arp->dipaddr == imp->ip) {
imp_arp_update(imp, arp->sipaddr, &arp->shwaddr, 0);
arp->opcode = htons(ARP_REPLY);
memcpy(&arp->dhwaddr, &arp->shwaddr, 6);
@@ -1461,7 +1795,10 @@ imp_arp_arpin(struct imp_device *imp, ETH_PACK *packet)
arp->sipaddr = imp->ip;
arp->ethhdr.type = htons(ETHTYPE_ARP);
packet->len = sizeof(struct arp_hdr);
eth_write(&imp->etherface, packet, NULL);
imp_write(imp, packet);
eth_mac_fmt(&arp->dhwaddr, mac_buf);
sim_debug(DEBUG_ARP, &imp_dev, "replied to received request for IP %s from %s\n",
ipv4_inet_ntoa(*((struct in_addr *)&imp->ip)), mac_buf);
}
break;
@@ -1469,7 +1806,11 @@ imp_arp_arpin(struct imp_device *imp, ETH_PACK *packet)
/* Check if this is our address */
if (arp->dipaddr == imp->ip) {
struct imp_packet *nq = NULL; /* New send queue */
imp_arp_update(imp, arp->sipaddr, &arp->shwaddr, 0);
eth_mac_fmt(&arp->shwaddr, mac_buf);
memcpy(&in_addr, &arp->sipaddr, sizeof(in_addr));
sim_debug(DEBUG_ARP, &imp_dev, "received reply for IP %s as %s\n",
ipv4_inet_ntoa(in_addr), mac_buf);
/* Scan send queue, and send all packets for this host */
while (imp->sendq != NULL) {
struct imp_packet *temp = imp->sendq;
@@ -1481,7 +1822,7 @@ imp_arp_arpin(struct imp_device *imp, ETH_PACK *packet)
memcpy(&pkt->ethhdr.dest, &arp->shwaddr, 6);
memcpy(&pkt->ethhdr.src, &imp->mac, 6);
pkt->ethhdr.type = htons(ETHTYPE_IP);
eth_write(&imp->etherface, &temp->packet, NULL);
imp_write(imp, &temp->packet);
imp->rfnm_count++;
imp_free_packet(imp, temp);
} else {
@@ -1522,7 +1863,8 @@ imp_arp_arpout(struct imp_device *imp, in_addr_T ipaddr)
arp->protolen = 4;
arp_pkt.len = sizeof(struct arp_hdr);
eth_write(&imp->etherface, &arp_pkt, NULL);
imp_write(imp, &arp_pkt);
sim_debug(DEBUG_ARP, &imp_dev, "sending request for IP %s\n", ipv4_inet_ntoa(*((struct in_addr *)&ipaddr)));
}
/*
@@ -1625,7 +1967,9 @@ imp_do_send_dhcp(struct imp_device *imp,
struct ip_hdr *pkt;
struct udp *udp;
struct udp_hdr udp_hdr;
struct in_addr in_addr;
int len;
char mac_buf[20];
pkt = (struct ip_hdr *)(&packet->msg[0]);
udp = (struct udp *)(&packet->msg[sizeof(struct imp_eth_hdr) +
@@ -1658,9 +2002,13 @@ imp_do_send_dhcp(struct imp_device *imp,
checksumadjust((uint8 *)&udp->chksum, (uint8 *)(&udp_hdr), 0,
(uint8 *)(&udp_hdr), sizeof(udp_hdr));
packet->len = len + sizeof(struct ip_hdr);
eth_write(&imp->etherface, packet, NULL);
sim_debug(DEBUG_DETAIL, &imp_dev,
"DHCP client sent %s packet\n", op);
imp_write(imp, packet);
eth_mac_fmt (&pkt->ethhdr.dest, mac_buf);
memcpy(&in_addr, &udp_hdr.ip_dst, sizeof(in_addr));
sim_debug(DEBUG_DHCP, &imp_dev,
"client sent %s packet to: %s:%d(%s)\n",
op, ipv4_inet_ntoa(in_addr), ntohs(udp->udp_dport), mac_buf);
}
/* Handle incoming DCHP offer and other requests */
@@ -1674,6 +2022,7 @@ imp_do_dhcp_client(struct imp_device *imp, ETH_PACK *read_buffer)
struct dhcp *dhcp;
struct udp *upkt;
struct udp_hdr udp_hdr;
struct in_addr in_addr;
uint8 *opt;
uint16 sum;
int len;
@@ -1685,6 +2034,7 @@ imp_do_dhcp_client(struct imp_device *imp, ETH_PACK *read_buffer)
int rebind_time = 0; /* Rebind time */
in_addr_T dhcpip = 0; /* DHCP server address */
int opr = -1; /* DHCP operation */
char mac_buf[20]; /* Source MAC address */
upkt = (struct udp *)(&((uint8 *)(ip_hdr))[hl]);
dhcp = (struct dhcp *)(&((uint8 *)(upkt))[sizeof(struct udp)]);
@@ -1771,10 +2121,13 @@ imp_do_dhcp_client(struct imp_device *imp, ETH_PACK *read_buffer)
}
}
sim_debug(DEBUG_DETAIL, &imp_dev,
"DHCP client incoming %s packet: dhcp_state=%s - wait_time=%d\n",
eth_mac_fmt(&eth->src, mac_buf);
memcpy(&in_addr, &udp_hdr.ip_src, sizeof(in_addr));
sim_debug(DEBUG_DHCP, &imp_dev,
"client incoming %s packet: dhcp_state=%s - wait_time=%d from: %s:%d(%s)\n",
(opr == -1) ? "" : dhcp_opr_names[opr],
dhcp_state_names[imp->dhcp_state], imp->dhcp_wait_time);
dhcp_state_names[imp->dhcp_state], imp->dhcp_wait_time,
ipv4_inet_ntoa(in_addr), ntohs(upkt->udp_sport), mac_buf);
/* Process an offer message */
if (opr == DHCP_OFFER && imp->dhcp_state == DHCP_STATE_SELECTING) {
@@ -1829,7 +2182,7 @@ imp_do_dhcp_client(struct imp_device *imp, ETH_PACK *read_buffer)
arp->hwlen = 6;
arp->protolen = 4;
arp_pkt.len = sizeof(struct arp_hdr);
eth_write(&imp->etherface, &arp_pkt, NULL);
imp_write(imp, &arp_pkt);
}
}
if (opr == DHCP_NAK && (imp->dhcp_state == DHCP_STATE_REQUESTING ||
@@ -2338,7 +2691,7 @@ t_stat imp_attach(UNIT* uptr, CONST char* cptr)
if (tptr == NULL) return SCPE_MEM;
strcpy(tptr, cptr);
status = eth_open(&imp_data.etherface, cptr, &imp_dev, 0xFFFF);
status = eth_open(&imp_data.etherface, cptr, &imp_dev, DEBUG_ETHER);
if (status != SCPE_OK) {
free(tptr);
return status;

View File

@@ -107,10 +107,11 @@ ifneq (,$(findstring besm6,$(MAKECMDGOALS)))
VIDEO_USEFUL = true
BESM6_BUILD = true
endif
# building the KA10 needs video support
# building the PDP6, KA10 or KI10 needs video support
ifneq (,$(or $(findstring pdp6,$(MAKECMDGOALS)),$(findstring pdp10-ka,$(MAKECMDGOALS)),$(findstring pdp10-ki,$(MAKECMDGOALS))))
VIDEO_USEFUL = true
endif
# building the KA10, KI10 or KL10 networking can be used.
ifneq (,$(or $(findstring pdp10-ka,$(MAKECMDGOALS)),$(findstring pdp10-ki,$(MAKECMDGOALS),$(findstring pdp10-kl,$MAKECMDGOALS))))
NETWORK_USEFUL = true
endif
@@ -1269,7 +1270,7 @@ KL10D = PDP10
KL10 = ${KL10D}/kx10_cpu.c ${KL10D}/kx10_sys.c ${KL10D}/kx10_df.c \
${KL10D}/kx10_mt.c ${KL10D}/kx10_dc.c ${KL10D}/kx10_rp.c \
${KL10D}/kx10_tu.c ${KL10D}/kx10_rs.c ${KL10D}/kx10_imp.c \
${KL10D}/kl10_fe.c ${KL10D}/ka10_pd.c
${KL10D}/kl10_fe.c ${KL10D}/ka10_pd.c ${KL10D}/ka10_ch10.c
KL10_OPT = -DKL=1 -DUSE_INT64 -I $(KL10D) -DUSE_SIM_CARD ${NETWORK_OPT}
PDP1D = PDP1