Lines Matching +full:dc +full:- +full:to +full:- +full:dc

1 /*-
2 * SPDX-License-Identifier: BSD-4-Clause
21 * may be used to endorse or promote products derived from this software
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
87 #define IS_CONSOLE(p) ((p)->port == DCONS_CON)
88 #define IS_GDB(p) ((p)->port == DCONS_GDB)
122 struct timespec to; member
132 dread(struct dcons_state *dc, void *buf, size_t n, off_t offset) in dread() argument
134 switch (dc->type) { in dread()
136 return (pread(dc->fd, buf, n, offset)); in dread()
138 return (kvm_read(dc->kd, offset, buf, n)); in dread()
140 return (-1); in dread()
144 dwrite(struct dcons_state *dc, void *buf, size_t n, off_t offset) in dwrite() argument
146 if ((dc->flags & F_RD_ONLY) != 0) in dwrite()
149 switch (dc->type) { in dwrite()
151 return (pwrite(dc->fd, buf, n, offset)); in dwrite()
153 return (kvm_write(dc->kd, offset, buf, n)); in dwrite()
155 return (-1); in dwrite()
159 dconschat_reset_target(struct dcons_state *dc, struct dcons_port *p) in dconschat_reset_target() argument
162 if (dc->reset == 0) in dconschat_reset_target()
167 (intmax_t)dc->reset); in dconschat_reset_target()
168 write(p->outfd, buf, strlen(buf)); in dconschat_reset_target()
170 dwrite(dc, (void *)buf, PAGE_SIZE, dc->reset); in dconschat_reset_target()
175 dconschat_suspend(struct dcons_state *dc, struct dcons_port *p) in dconschat_suspend() argument
177 if (p->sport != 0) in dconschat_suspend()
181 tcsetattr(STDIN_FILENO, TCSADRAIN, &dc->tsave); in dconschat_suspend()
187 tcsetattr(STDIN_FILENO, TCSADRAIN, &dc->traw); in dconschat_suspend()
200 write(p->outfd, buf, strlen(buf)); in dconschat_sigchld()
205 EV_SET(&kev, p->infd, EVFILT_READ, EV_ADD, NOTE_LOWAT, 1, (void *)p); in dconschat_sigchld()
210 dconschat_fork_gdb(struct dcons_state *dc, struct dcons_port *p) in dconschat_fork_gdb() argument
219 write(p->outfd, buf, strlen(buf)); in dconschat_fork_gdb()
226 tcsetattr(STDIN_FILENO, TCSADRAIN, &dc->tsave); in dconschat_fork_gdb()
228 snprintf(com, sizeof(buf), "kgdb -r :%d kernel", in dconschat_fork_gdb()
229 dc->port[DCONS_GDB].sport); in dconschat_fork_gdb()
231 write(p->outfd, buf, strlen(buf)); in dconschat_fork_gdb()
233 execl("/bin/sh", "/bin/sh", "-c", com, NULL); in dconschat_fork_gdb()
236 write(p->outfd, buf, strlen(buf)); in dconschat_fork_gdb()
239 tcsetattr(STDIN_FILENO, TCSADRAIN, &dc->traw); in dconschat_fork_gdb()
244 EV_SET(&kev, p->infd, EVFILT_READ, EV_DELETE, 0, 0, NULL); in dconschat_fork_gdb()
253 struct dcons_state *dc; in dconschat_cleanup() local
256 dc = ≻ in dconschat_cleanup()
258 tcsetattr(STDIN_FILENO, TCSADRAIN, &dc->tsave); in dconschat_cleanup()
270 dconschat_get_crom(struct dcons_state *dc) in dconschat_get_crom() argument
281 if (dread(dc, &buf, 4, addr + i) < 0) { in dconschat_get_crom()
288 printf("%d %02x %06x\n", state, reg->key, reg->val); in dconschat_get_crom()
291 if (reg->key == CSRKEY_SPEC && in dconschat_get_crom()
292 reg->val == CSRVAL_VENDOR_PRIVATE) in dconschat_get_crom()
296 if (reg->key == CSRKEY_VER && in dconschat_get_crom()
297 reg->val == DCONS_CSR_VAL_VER) in dconschat_get_crom()
301 switch (reg->key) { in dconschat_get_crom()
303 hi = reg->val; in dconschat_get_crom()
306 lo = reg->val; in dconschat_get_crom()
309 reset_hi = reg->val; in dconschat_get_crom()
312 reset_lo = reg->val; in dconschat_get_crom()
326 dc->paddr = ((off_t)hi << 24) | lo; in dconschat_get_crom()
327 dc->reset = ((off_t)reset_hi << 24) | reset_lo; in dconschat_get_crom()
328 if (dc->paddr == 0) in dconschat_get_crom()
329 return (-1); in dconschat_get_crom()
335 dconschat_ready(struct dcons_state *dc, int ready, char *reason) in dconschat_ready() argument
340 old = (dc->flags & F_READY) ? 1 : 0; in dconschat_ready()
343 dc->flags |= F_READY; in dconschat_ready()
348 dc->flags &= ~F_READY; in dconschat_ready()
357 dconschat_fetch_header(struct dcons_state *dc) in dconschat_fetch_header() argument
364 if (dc->paddr == 0 && (dc->flags & F_USE_CROM) != 0) { in dconschat_fetch_header()
365 if (dconschat_get_crom(dc)) { in dconschat_fetch_header()
366 dconschat_ready(dc, 0, "get crom failed"); in dconschat_fetch_header()
367 return (-1); in dconschat_fetch_header()
372 if (dread(dc, &dbuf, DCONS_HEADER_SIZE, dc->paddr) < 0) { in dconschat_fetch_header()
373 dconschat_ready(dc, 0, "read header failed"); in dconschat_fetch_header()
374 return (-1); in dconschat_fetch_header()
377 if ((dc->flags & F_USE_CROM) !=0) in dconschat_fetch_header()
378 dc->paddr = 0; in dconschat_fetch_header()
380 dconschat_ready(dc, 0, ebuf); in dconschat_fetch_header()
381 return (-1); in dconschat_fetch_header()
388 dconschat_ready(dc, 0, ebuf); in dconschat_fetch_header()
389 return (-1); in dconschat_fetch_header()
397 o = &dc->port[j].o; in dconschat_fetch_header()
398 newbuf = dc->paddr + ntohl(dbuf.ooffset[j]); in dconschat_fetch_header()
399 o->size = ntohl(dbuf.osize[j]); in dconschat_fetch_header()
401 if (newbuf != o->buf) { in dconschat_fetch_header()
404 o->gen = ntohl(dbuf.optr[j]) >> DCONS_GEN_SHIFT; in dconschat_fetch_header()
405 o->pos = ntohl(dbuf.optr[j]) & DCONS_POS_MASK; in dconschat_fetch_header()
406 o->buf = newbuf; in dconschat_fetch_header()
409 i = &dc->port[j].i; in dconschat_fetch_header()
410 i->size = ntohl(dbuf.isize[j]); in dconschat_fetch_header()
411 i->gen = ntohl(dbuf.iptr[j]) >> DCONS_GEN_SHIFT; in dconschat_fetch_header()
412 i->pos = ntohl(dbuf.iptr[j]) & DCONS_POS_MASK; in dconschat_fetch_header()
413 i->buf = dc->paddr + ntohl(dbuf.ioffset[j]); in dconschat_fetch_header()
419 o->size, ntohl(dbuf.ooffset[j]), o->gen, o->pos, in dconschat_fetch_header()
420 i->size, ntohl(dbuf.ioffset[j]), i->gen, i->pos); in dconschat_fetch_header()
423 if (IS_CONSOLE(&dc->port[j]) && new && in dconschat_fetch_header()
424 (dc->flags & F_REPLAY) !=0) { in dconschat_fetch_header()
425 if (o->gen > 0) in dconschat_fetch_header()
426 o->gen --; in dconschat_fetch_header()
428 o->pos = 0; in dconschat_fetch_header()
431 dconschat_ready(dc, 1, NULL); in dconschat_fetch_header()
436 dconschat_get_ptr (struct dcons_state *dc) { in dconschat_get_ptr() argument
443 dlen = dread(dc, &ptr, sizeof(ptr), in dconschat_get_ptr()
444 dc->paddr + __offsetof(struct dcons_buf, magic)); in dconschat_get_ptr()
448 if (retry -- > 0) in dconschat_get_ptr()
450 dconschat_ready(dc, 0, "get ptr failed"); in dconschat_get_ptr()
451 return(-1); in dconschat_get_ptr()
454 if ((dc->flags & F_USE_CROM) !=0) in dconschat_get_ptr()
455 dc->paddr = 0; in dconschat_get_ptr()
457 dconschat_ready(dc, 0, ebuf); in dconschat_get_ptr()
458 return(-1); in dconschat_get_ptr()
462 dc->port[i].optr = ntohl(ptr[i + 1]); in dconschat_get_ptr()
463 dc->port[i].iptr = ntohl(ptr[DCONS_NPORT + i + 1]); in dconschat_get_ptr()
470 dconschat_read_dcons(struct dcons_state *dc, int port, char *buf, int len) in dconschat_read_dcons() argument
477 ch = &dc->port[port].o; in dconschat_read_dcons()
478 ptr = dc->port[port].optr; in dconschat_read_dcons()
481 if (gen == ch->gen && pos == ch->pos) in dconschat_read_dcons()
482 return (-1); in dconschat_read_dcons()
484 next_gen = DCONS_NEXT_GEN(ch->gen); in dconschat_read_dcons()
486 if (gen == ch->gen) { in dconschat_read_dcons()
487 if (pos > ch->pos) in dconschat_read_dcons()
489 lost = ch->size * DCONS_GEN_MASK - ch->pos; in dconschat_read_dcons()
490 ch->pos = 0; in dconschat_read_dcons()
492 if (pos <= ch->pos) in dconschat_read_dcons()
494 lost = pos - ch->pos; in dconschat_read_dcons()
495 ch->pos = pos; in dconschat_read_dcons()
497 lost = gen - ch->gen; in dconschat_read_dcons()
502 lost = lost * ch->size - ch->pos; in dconschat_read_dcons()
503 ch->pos = 0; in dconschat_read_dcons()
504 ch->gen = gen; in dconschat_read_dcons()
511 if (gen == ch->gen) in dconschat_read_dcons()
512 rlen = pos - ch->pos; in dconschat_read_dcons()
514 rlen = ch->size - ch->pos; in dconschat_read_dcons()
529 dlen = dread(dc, buf, rlen, ch->buf + ch->pos); in dconschat_read_dcons()
532 if (retry -- > 0) in dconschat_read_dcons()
534 dconschat_ready(dc, 0, "read buffer failed"); in dconschat_read_dcons()
535 return(-1); in dconschat_read_dcons()
539 ch->pos += dlen; in dconschat_read_dcons()
540 if (ch->pos >= ch->size) { in dconschat_read_dcons()
541 ch->gen = next_gen; in dconschat_read_dcons()
542 ch->pos = 0; in dconschat_read_dcons()
544 printf("read_dcons: gen=%d", ch->gen); in dconschat_read_dcons()
550 dconschat_write_dcons(struct dcons_state *dc, int port, char *buf, int blen) in dconschat_write_dcons() argument
557 ch = &dc->port[port].i; in dconschat_write_dcons()
558 ptr = dc->port[port].iptr; in dconschat_write_dcons()
561 ch->gen = ptr >> DCONS_GEN_SHIFT; in dconschat_write_dcons()
562 ch->pos = ptr & DCONS_POS_MASK; in dconschat_write_dcons()
565 wlen = MIN(blen, ch->size - ch->pos); in dconschat_write_dcons()
567 len = dwrite(dc, buf, wlen, ch->buf + ch->pos); in dconschat_write_dcons()
570 if (retry -- > 0) in dconschat_write_dcons()
572 dconschat_ready(dc, 0, "write buffer failed"); in dconschat_write_dcons()
573 return(-1); in dconschat_write_dcons()
575 ch->pos += len; in dconschat_write_dcons()
577 blen -= len; in dconschat_write_dcons()
578 if (ch->pos >= ch->size) { in dconschat_write_dcons()
579 ch->gen = DCONS_NEXT_GEN(ch->gen); in dconschat_write_dcons()
580 ch->pos = 0; in dconschat_write_dcons()
582 printf("write_dcons: gen=%d", ch->gen); in dconschat_write_dcons()
588 dc->port[port].iptr = ptr; in dconschat_write_dcons()
593 len = dwrite(dc, &ptr, sizeof(u_int32_t), in dconschat_write_dcons()
594 dc->paddr + __offsetof(struct dcons_buf, iptr[port])); in dconschat_write_dcons()
597 if (retry -- > 0) in dconschat_write_dcons()
599 dconschat_ready(dc, 0, "write ptr failed"); in dconschat_write_dcons()
600 return(-1); in dconschat_write_dcons()
612 printf("<- %s\n", buf); in dconschat_write_socket()
618 dconschat_init_socket(struct dcons_state *dc, int port, char *host, int sport) in dconschat_init_socket() argument
626 p = &dc->port[port]; in dconschat_init_socket()
627 p->port = port; in dconschat_init_socket()
628 p->sport = sport; in dconschat_init_socket()
629 p->infd = p->outfd = -1; in dconschat_init_socket()
637 p->infd = STDIN_FILENO; in dconschat_init_socket()
638 p->outfd = STDOUT_FILENO; in dconschat_init_socket()
639 p->s = -1; in dconschat_init_socket()
641 tcgetattr(STDIN_FILENO, &dc->tsave) == 0) { in dconschat_init_socket()
642 dc->traw = dc->tsave; in dconschat_init_socket()
643 cfmakeraw(&dc->traw); in dconschat_init_socket()
644 tcsetattr(STDIN_FILENO, TCSADRAIN, &dc->traw); in dconschat_init_socket()
647 EV_SET(&kev, p->infd, EVFILT_READ, EV_ADD, NOTE_LOWAT, 1, in dconschat_init_socket()
649 kevent(dc->kq, &kev, 1, NULL, 0, &dc->zero); in dconschat_init_socket()
670 p->res = res; in dconschat_init_socket()
671 p->s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); in dconschat_init_socket()
672 if (p->s < 0) in dconschat_init_socket()
674 setsockopt(p->s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); in dconschat_init_socket()
676 if (bind(p->s, p->res->ai_addr, p->res->ai_addrlen) < 0) { in dconschat_init_socket()
679 if (listen(p->s, 1) < 0) in dconschat_init_socket()
681 EV_SET(&kev, p->s, EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, (void *)p); in dconschat_init_socket()
682 error = kevent(dc->kq, &kev, 1, NULL, 0, &dc->to); in dconschat_init_socket()
688 dconschat_accept_socket(struct dcons_state *dc, struct dcons_port *p) in dconschat_accept_socket() argument
695 addrlen = p->res->ai_addrlen; in dconschat_accept_socket()
696 ns = accept(p->s, p->res->ai_addr, &addrlen); in dconschat_accept_socket()
700 printf("port%d accepted\n", p->port); in dconschat_accept_socket()
706 if (IS_CONSOLE(p) && (dc->flags & F_TELNET) != 0) { in dconschat_accept_socket()
716 p->skip_read = 0; in dconschat_accept_socket()
724 while ((len = dconschat_read_dcons(dc, DCONS_GDB, &buf[0], in dconschat_accept_socket()
730 p->infd = p->outfd = ns; in dconschat_accept_socket()
732 kevent(dc->kq, &kev, 1, NULL, 0, &dc->zero); in dconschat_accept_socket()
737 dconschat_read_filter(struct dcons_state *dc, struct dcons_port *p, in dconschat_read_filter() argument
746 if ((dc->flags & F_TELNET) != 0) { in dconschat_read_filter()
748 if (p->skip_read -- > 0) { in dconschat_read_filter()
750 slen --; in dconschat_read_filter()
756 p->skip_read = 2; in dconschat_read_filter()
758 slen --; in dconschat_read_filter()
765 slen --; in dconschat_read_filter()
769 switch (dc->escape_state) { in dconschat_read_filter()
771 if (*sp == dc->escape) { in dconschat_read_filter()
773 dc->escape_state = STATE2; in dconschat_read_filter()
775 dc->escape_state = STATE0; in dconschat_read_filter()
778 dc->escape_state = STATE0; in dconschat_read_filter()
788 dconschat_fork_gdb(dc, p); in dconschat_read_filter()
790 && (dc->reset != 0)) { in dconschat_read_filter()
791 dc->escape_state = STATE3; in dconschat_read_filter()
792 buf = "\r\n[Are you sure to reset target? (y/N)]"; in dconschat_read_filter()
793 write(p->outfd, buf, strlen(buf)); in dconschat_read_filter()
795 dconschat_suspend(dc, p); in dconschat_read_filter()
798 *dp++ = dc->escape; in dconschat_read_filter()
803 dc->escape_state = STATE0; in dconschat_read_filter()
806 dconschat_reset_target(dc, p); in dconschat_read_filter()
808 write(p->outfd, sp, 1); in dconschat_read_filter()
809 write(p->outfd, "\r\n", 2); in dconschat_read_filter()
814 dc->escape_state = STATE1; in dconschat_read_filter()
816 /* GDB: ^C -> CR+~+^B */ in dconschat_read_filter()
817 if (*sp == CTRL('C') && (dc->flags & F_ALT_BREAK) != 0) { in dconschat_read_filter()
832 slen --; in dconschat_read_filter()
839 dconschat_read_socket(struct dcons_state *dc, struct dcons_port *p) in dconschat_read_socket() argument
845 if ((len = read(p->infd, rbuf, sizeof(rbuf))) > 0) { in dconschat_read_socket()
847 dconschat_read_filter(dc, p, rbuf, len, wbuf, &wlen); in dconschat_read_socket()
849 if (wlen > 0 && (dc->flags & F_READY) != 0) { in dconschat_read_socket()
850 dconschat_write_dcons(dc, p->port, wbuf, wlen); in dconschat_read_socket()
853 printf("-> %s\n", wbuf); in dconschat_read_socket()
862 warnx("port%d: closed", p->port); in dconschat_read_socket()
864 warn("port%d: read", p->port); in dconschat_read_socket()
866 EV_SET(&kev, p->infd, EVFILT_READ, in dconschat_read_socket()
868 kevent(dc->kq, &kev, 1, NULL, 0, &dc->zero); in dconschat_read_socket()
869 close(p->infd); in dconschat_read_socket()
870 close(p->outfd); in dconschat_read_socket()
872 EV_SET(&kev, p->s, EVFILT_READ, in dconschat_read_socket()
874 kevent(dc->kq, &kev, 1, NULL, 0, &dc->zero); in dconschat_read_socket()
875 p->infd = p->outfd = -1; in dconschat_read_socket()
881 dconschat_proc_socket(struct dcons_state *dc) in dconschat_proc_socket() argument
887 n = kevent(dc->kq, NULL, 0, elist, NEVENT, &dc->to); in dconschat_proc_socket()
890 p = (struct dcons_port *)e->udata; in dconschat_proc_socket()
891 if (e->ident == p->s) { in dconschat_proc_socket()
892 dconschat_accept_socket(dc, p); in dconschat_proc_socket()
894 dconschat_read_socket(dc, p); in dconschat_proc_socket()
901 dconschat_proc_dcons(struct dcons_state *dc) in dconschat_proc_dcons() argument
907 err = dconschat_get_ptr(dc); in dconschat_proc_dcons()
913 p = &dc->port[port]; in dconschat_proc_dcons()
914 if (p->infd < 0) in dconschat_proc_dcons()
916 while ((len = dconschat_read_dcons(dc, port, buf, in dconschat_proc_dcons()
918 dconschat_write_socket(p->outfd, buf, len); in dconschat_proc_dcons()
919 if ((err = dconschat_get_ptr(dc))) in dconschat_proc_dcons()
922 if ((dc->flags & F_ONE_SHOT) != 0 && len <= 0) in dconschat_proc_dcons()
929 dconschat_start_session(struct dcons_state *dc) in dconschat_start_session() argument
939 if (((dc->flags & F_READY) == 0) && ++counter > retry_unit) { in dconschat_start_session()
948 dconschat_fetch_header(dc); in dconschat_start_session()
950 if ((dc->flags & F_READY) != 0) { in dconschat_start_session()
954 dconschat_proc_dcons(dc); in dconschat_start_session()
956 dconschat_proc_socket(dc); in dconschat_start_session()
965 "usage: dconschat [-brvwRT1] [-h hz] [-C port] [-G port]\n" in usage()
966 "\t\t\t[-M core] [-N system]\n" in usage()
967 "\t\t\t[-u unit] [-a address] [-t target_eui64]\n" in usage()
968 "\t-b translate ctrl-C to CR+~+ctrl-B on gdb port\n" in usage()
969 "\t-v verbose\n" in usage()
970 "\t-w listen on wildcard address rather than localhost\n" in usage()
971 "\t-r replay old buffer on connection\n" in usage()
972 "\t-R read-only\n" in usage()
973 "\t-T enable Telnet protocol workaround on console port\n" in usage()
974 "\t-1 one shot: read buffer and exit\n" in usage()
975 "\t-h polling rate\n" in usage()
976 "\t-C port number for console port\n" in usage()
977 "\t-G port number for gdb port\n" in usage()
979 "\t-M core file\n" in usage()
980 "\t-N system file\n" in usage()
982 "\t-u specify unit number of the bus\n" in usage()
983 "\t-t EUI64 of target host (must be specified)\n" in usage()
984 "\t-a physical address of dcons buffer on target host\n" in usage()
991 struct dcons_state *dc; in main() local
1000 dc = &sc; in main()
1001 dc->flags |= USE_CROM ? F_USE_CROM : 0; in main()
1005 port[1] = -1; /* disable gdb port */ in main()
1008 dc->escape = KEY_TILDE; in main()
1010 while ((ch = getopt(argc, argv, "a:be:h:rt:u:vwC:G:M:N:RT1")) != -1) { in main()
1013 dc->paddr = strtoull(optarg, NULL, 0); in main()
1014 dc->flags &= ~F_USE_CROM; in main()
1017 dc->flags |= F_ALT_BREAK; in main()
1020 dc->escape = optarg[0]; in main()
1028 dc->flags |= F_REPLAY; in main()
1036 dc->type = TYPE_FW; in main()
1060 dc->flags |= F_RD_ONLY; in main()
1063 dc->flags |= F_TELNET; in main()
1066 dc->flags |= F_ONE_SHOT | F_REPLAY; in main()
1072 if (dc->paddr == 0 && (dc->flags & F_USE_CROM) == 0) { in main()
1089 switch (dc->type) { in main()
1095 dc->fd = open(devname, O_RDWR); in main()
1096 if (dc->fd >= 0) in main()
1101 error = ioctl(dc->fd, FW_SDEUI64, &eui); in main()
1110 dc->kd = kvm_open(system, core, NULL, in main()
1111 (dc->flags & F_RD_ONLY) ? O_RDONLY : O_RDWR, "dconschat"); in main()
1112 if (dc->kd == NULL) in main()
1115 if (kvm_nlist(dc->kd, nl) < 0) in main()
1116 errx(1, "kvm_nlist: %s", kvm_geterr(dc->kd)); in main()
1118 if (kvm_read(dc->kd, nl[0].n_value, &dcons_buf, in main()
1120 errx(1, "kvm_read: %s", kvm_geterr(dc->kd)); in main()
1121 dc->paddr = (uintptr_t)dcons_buf; in main()
1123 printf("dcons_buf: 0x%x\n", (uint)dc->paddr); in main()
1127 dconschat_fetch_header(dc); in main()
1130 dc->kq = kqueue(); in main()
1132 dc->to.tv_sec = 1; in main()
1133 dc->to.tv_nsec = 0; in main()
1135 dc->to.tv_sec = 0; in main()
1136 dc->to.tv_nsec = 1000 * 1000 * 1000 / poll_hz; in main()
1138 dc->zero.tv_sec = 0; in main()
1139 dc->zero.tv_nsec = 0; in main()
1141 dconschat_init_socket(dc, i, in main()
1144 dconschat_start_session(dc); in main()
1147 freeaddrinfo(dc->port[i].res); in main()