Date: Fri, 6 Jul 2012 22:40:09 GMT From: Robert Watson <rwatson@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 213999 for review Message-ID: <201207062240.q66Me9Oq083692@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@213999?ac=10 Change 213999 by rwatson@rwatson_svr_ctsrd_mipsbuild on 2012/07/06 22:39:08 Integrate CheriBSD branch to brin in Altera JTAG UART driver improvements, significant demo application work. Affected files ... .. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/Makefile#2 integrate .. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/de4tc.c#2 integrate .. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/de4tc.h#2 integrate .. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/syscons-fonts.c#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libvuln_magic/Makefile#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libvuln_magic/config.h#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libvuln_magic/funcs.c#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/Makefile#3 integrate .. //depot/projects/ctsrd/cheribsd/src/ctsrd/browser/Makefile#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/browser/browser.c#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/browser/images/Makefile#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/browser/images/browser.png#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/browser/images/icons.png#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/cycle_led/Makefile#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/cycle_led/cycle_led.sh#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/flashit/flashit.sh#2 integrate .. //depot/projects/ctsrd/cheribsd/src/ctsrd/minifile/Makefile#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/minifile/minifile.c#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/pictview/Makefile#2 integrate .. //depot/projects/ctsrd/cheribsd/src/ctsrd/pictview/pictview.c#3 integrate .. //depot/projects/ctsrd/cheribsd/src/ctsrd/showimage/Makefile#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/showimage/images/Makefile#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/showimage/images/booting.png#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/showimage/images/upgrade-complete.png#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/showimage/images/upgrade-inprogress.png#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/showimage/showimage.c#1 branch .. //depot/projects/ctsrd/cheribsd/src/ctsrd/spinner/spinner.c#2 integrate .. //depot/projects/ctsrd/cheribsd/src/etc/mtree/BSD.usr.dist#2 integrate .. //depot/projects/ctsrd/cheribsd/src/etc/rc#2 integrate .. //depot/projects/ctsrd/cheribsd/src/etc/rc.subr#2 integrate .. //depot/projects/ctsrd/cheribsd/src/sys/conf/options.mips#4 integrate .. //depot/projects/ctsrd/cheribsd/src/sys/dev/altera/avgen/altera_avgen.c#2 integrate .. //depot/projects/ctsrd/cheribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart.h#2 integrate .. //depot/projects/ctsrd/cheribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart_cons.c#2 integrate .. //depot/projects/ctsrd/cheribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart_tty.c#2 integrate .. //depot/projects/ctsrd/cheribsd/src/sys/dev/terasic/de4led/terasic_de4led.c#2 integrate .. //depot/projects/ctsrd/cheribsd/src/sys/mips/conf/BERI_DE4.hints#2 integrate .. //depot/projects/ctsrd/cheribsd/src/sys/mips/conf/BERI_DE4_MDROOT#2 integrate .. //depot/projects/ctsrd/cheribsd/src/sys/mips/conf/BERI_DE4_SDROOT#2 integrate .. //depot/projects/ctsrd/cheribsd/src/sys/mips/conf/BERI_SIM_MDROOT#2 integrate .. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/stack_machdep.c#2 integrate .. //depot/projects/ctsrd/cheribsd/src/usr.sbin/isfctl/isfctl.c#2 integrate Differences ... ==== //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/Makefile#2 (text+ko) ==== @@ -5,12 +5,15 @@ LIB= de4tc SHLIB_MAJOR= 1 -SRCS= de4tc.c +SRCS= de4tc.c syscons-fonts.c INCS= de4tc.h +.PATH: ${.CURDIR}/../../usr.sbin/vidcontrol +CFLAGS+=-I${.CURDIR}/../../usr.sbin/vidcontrol +SRCS+= decode.c + CFLAGS+= -I${.CURDIR}/../libvuln_png/ -#LDADD+= -L../libvuln_png/ -lvuln_png -lz -lm #WARNS?= 0 ==== //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/de4tc.c#2 (text+ko) ==== @@ -52,7 +52,7 @@ static int dispfd; static int textfd; static int fademode=0; -static volatile u_int32_t *pfbp; +volatile u_int32_t *pfbp; static volatile u_int16_t *tfbp; static volatile u_int32_t *mtlctrl; @@ -62,7 +62,10 @@ // number of lines in the line pattern static const int num_lines_pattern = 600; +const int fb_height = 480; +const int fb_width = 800; + /***************************************************************************** * hack around endian issue * TODO: replace with endian library call (but not present in Linux?) @@ -208,6 +211,17 @@ void +fb_fill_region(u_int32_t colour, int x, int y, int w, int h) +{ + int col, row; + + for (row = 0; row < h; row++) + for (col = 0; col < w; col++) + pfbp[(y + row) * fb_width + (x + col)] = colour; +} + + +void fb_post(u_int32_t *buf) { int addr; @@ -217,6 +231,17 @@ void +fb_post_region(u_int32_t *buf, int x, int y, int w, int h) +{ + int col, row; + + for (row = 0; row < h; row++) + for (col = 0; col < w; col++) + pfbp[(y + row) * fb_width + (x + col)] = buf[row * w + col]; +} + + +void fb_blend(int blend_text_bg, int blend_text_fg, int blend_pixel, int wash __unused) { mtlctrl[0] = ==== //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/de4tc.h#2 (text+ko) ==== @@ -1,5 +1,6 @@ /*- * Copyright (c) 2012 Simon W. Moore + * Copyright (c) 2012 SRI International * All rights reserved. * * This software was developed by SRI International and the University of @@ -38,8 +39,8 @@ extern int touch_gesture; extern int touch_count; -const int fb_height = 480; -const int fb_width = 800; +extern const int fb_height; +extern const int fb_width; void multitouch_pole(void); void multitouch_filter(void); @@ -49,7 +50,9 @@ u_int32_t fb_colour(int r, int g, int b); void fb_putpixel(int px, int py, int colour); void fb_fill(int col); +void fb_fill_region(u_int32_t colour, int x, int y, int w, int h); void fb_post(u_int32_t *buf); +void fb_post_region(u_int32_t *buf, int x, int y, int w, int h); void fb_blend(int blend_text_bg, int blend_text_fg, int blend_pixel, int wash); void fb_text_cursor(int x, int y); void fb_fade2off(void); @@ -58,4 +61,10 @@ void plot_line(int x1, int y1, int x2, int y2, unsigned int colour); void read_png_file(const char* file_name, u_int32_t* imgbuf, int maxwidth, int maxheight); +void fb_load_syscons_font(const char *type, const char *filename); +int fb_get_font_height(void); +int fb_get_font_width(void); +void fb_render_text(const char *string, int expand, u_int32_t con, u_int32_t coff, + u_int32_t *buffer, int w, int h); + #endif /* !_DE4TC_H_ */ ==== //depot/projects/ctsrd/cheribsd/src/ctsrd/Makefile#3 (text+ko) ==== @@ -1,7 +1,11 @@ .include <bsd.own.mk> -SUBDIR= flashit \ +SUBDIR= browser \ + cycle_led \ + flashit \ + minifile \ pictview \ + showimage \ spinner .include <bsd.arch.inc.mk> ==== //depot/projects/ctsrd/cheribsd/src/ctsrd/flashit/flashit.sh#2 (text+ko) ==== @@ -1,24 +1,26 @@ #!/bin/sh +isf0_DEV=isf0 +isf0_OFFSET=0 +isf0_MAXLEN=0x02000000 + +isf1_DEV=isf1 +isf1_OFFSET=0 +isf1_MAXLEN=0x02000000 + fpga_DEV=isf0 fpga_OFFSET=0x00020000 -fpga_MAXLEN=0x00FE0000 +fpga_MAXLEN=0x00C00000 fpga_SKIP=0x20000 -# New kernel location on isf0 -kernel_DEV=isf0 -kernel_OFFSET=0x01000000 -kernel_MAXLEN=0x01000000 +fpga2_DEV=isf0 +fpga2_OFFSET=0x00C20000 +fpga2_MAXLEN=0x00C00000 +fpga2_SKIP=0x20000 -# Old kernel location on isf1 -kernel2_DEV=isf1 -kernel2_OFFSET=0x01000000 -kernel2_MAXLEN=0x01000000 - -# Proposed root location -root_DEV=isf1 -root_OFFSET=0x00000000 -root_MAXLEN=0x02000000 +kernel_DEV=isf1 +kernel_OFFSET=0x00000000 +kernel_MAXLEN=0x02000000 TARGETS="fpga:kernel:kernel2:root" @@ -114,11 +116,17 @@ case "${source}" in *.bz2) + if [ -z "${tmpdir}" ]; then + err 1 "Can't make a temporary directory, is /tmp writable?" + fi binfile="${tmpdir}/${src_name%.bz2}" echo "Extracting to ${binfile}" bunzip2 -c "${source}" > "${binfile}" ;; *.gz) + if [ -z "${tmpdir}" ]; then + err 1 "Can't make a temporary directory, is /tmp writable?" + fi binfile="${tmpdir}/${src_name%.gz}" echo "Extracting to ${binfile}" gunzip -c "${source}" > "${binfile}" ==== //depot/projects/ctsrd/cheribsd/src/ctsrd/pictview/Makefile#2 (text+ko) ==== @@ -9,7 +9,7 @@ WARNS= 0 -LDADD+= -lde4tc -lvuln_png -lz -lm +LDADD+= -lde4tc -lvuln_png -lz -lm -lutil # Disable the stack protector, we want to be vulnerable SSP_CFLAGS= ==== //depot/projects/ctsrd/cheribsd/src/ctsrd/pictview/pictview.c#3 (text+ko) ==== @@ -29,16 +29,22 @@ */ #include <sys/types.h> +#include <sys/ioctl.h> #include <sys/stat.h> +#include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <syslog.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <libutil.h> +#include <poll.h> #include <stdarg.h> -#include <fcntl.h> +#include <stdbool.h> +#include <string.h> +#include <termios.h> #include <unistd.h> -#include <errno.h> -#include <err.h> -#include <stdbool.h> #include <de4tc.h> @@ -48,8 +54,6 @@ u_int32_t *fb_buf; - - void pen_drawing_clear_screen(void) { @@ -140,6 +144,20 @@ read_png_file("/usr/share/images/keyboardC.png", keyboard_imgs[3], keyboard_width, keyboard_height); } +static void +writeall(int fd, const char *buf, size_t len) +{ + int wlen = 0, n; + + while (wlen != len) { + n = write(fd, buf + wlen, len - wlen); + if (n < 0) { + syslog(LOG_ALERT, "write failed: %s", strerror(errno)); + err(1, "write"); + } + wlen += n; + } +} void keyboard_on(void) @@ -152,6 +170,16 @@ int prev_keymode = -1; int keyYpos = fb_height-keyboard_height; + const int poll_timeout = touch_timeout; + int wait_poll_timeout = poll_timeout; + + static int pmaster; + static pid_t pid; + int pslave, n; + char *devpath, buf[1024]; + ssize_t rlen; + struct pollfd pfd[1]; + // extra mapping codes: // ctrl key = \xff -> keymode=3 // num key = \xfe -> keymode=2 @@ -180,6 +208,28 @@ keymap[1][1][3] = '\xff'; keymap[2][1][3] = '\xff'; + if (kbdfd < 0) { + /* XXX: need to handle the case of the shell exiting. */ + if (openpty(&pmaster, &pslave, NULL, NULL, NULL) == -1) + err(1, "openpty"); + pid = fork(); + if (pid < 0) + err(1, "fork()"); + else if (pid > 0) { + close(pslave); + kbdfd = pmaster; + } else { + close(pmaster); + if (login_tty(pslave) < 0) { + syslog(LOG_ALERT, "login_tty failed in child: %s", strerror(errno)); + err(1, "tty_login"); + } + execl("/bin/sh", "sh", NULL); + syslog(LOG_ALERT, "exec of /bin/sh failed: %s", strerror(errno)); + err(1, "execl()"); + } + } + fb_fade2off(); fb_fade2text(127); do { @@ -236,9 +286,7 @@ } if(ic < 0x80) { // printf("key = \"%c\" = 0x%02x\n", c, ic); - /* XXX: should handle full buffers */ - if (write(kbdfd, &c, 1) == -1) - err(1, "write"); + writeall(kbdfd, &c, 1); // cancel shift and ctrl modes after character sent if((keymode==1) || (keymode==3)) keymode=0; @@ -256,6 +304,43 @@ keyYpos -= fb_height; // put on screen prev_keymode = -1; // redraw keyboard } + + if (kbdfd != 0) { + if (wait_poll_timeout > 0) { + wait_poll_timeout--; + continue; + } + wait_poll_timeout = poll_timeout; + + /* + * If the child has exited, reset the state and return to the + * main screen. + */ + if (wait4(pid, NULL, WNOHANG, NULL) != 0) { + kbdfd = -1; + close(pmaster); + break; + } + + /* Check for output from the child and post it if needed */ + pfd[0].fd = pmaster; + pfd[0].events = POLLIN; + n = poll(pfd, 1, 0); + if (n == 0) + continue; + if (n < 0) { + syslog(LOG_ALERT, "poll failed with %s", strerror(errno)); + err(1, "poll"); + } + if (pfd[0].revents & POLLIN) { + rlen = read(pfd[0].fd, buf, sizeof(buf)); + if (rlen < 0) { + syslog(LOG_ALERT, "read failed: %s", strerror(errno)); + err(1, "read"); + } else if (rlen > 0) + writeall(0, buf, rlen); + } + } } while(!((touch_count==2) && (touch_gesture==0x49))); } @@ -551,8 +636,7 @@ int main(int argc, char *argv[]) { - int ofd, pipefds[2]; - pid_t pid; + int tty; char *devpath; fb_buf = malloc(sizeof(*fb_buf) * fb_width * fb_height); @@ -571,34 +655,19 @@ if (argc > 2) errx(1, "usage: pictview [tty]"); if (argc == 2) { - if (pipe(pipefds) == -1) - err(1, "pipe()"); - pid = fork(); - if (pid < 0) - return (pid); - else if (pid > 0) { - /* XXX: should probably wait a bit and see if the child fails quickly */ - kbdfd=pipefds[0]; - } else { - if (dup2(pipefds[1], 0) == -1) - err(1, "dup2(%d, 0)", pipefds[1]); - if (argv[1][0] != '/') - asprintf(&devpath, "/dev/%s", argv[1]); - else - devpath = argv[1]; - ofd = open(devpath, O_WRONLY); - if (ofd < 0) - err(1, "open(%s)", argv[1]); - if (dup2(ofd, 1) == -1) { - syslog(LOG_ALERT, "redir: dup2(%d, 1) failed with %d", ofd, errno); - exit(1); - } - if (dup2(ofd, 2) == -1) { - syslog(LOG_ALERT, "redir: dup2(%d, 2) failed with %d", ofd, errno); - exit(1); - } - execl("/bin/sh", "sh", "-i", NULL); - err(1, "execl()"); + kbdfd = -1; + if (argv[1][0] != '/') + asprintf(&devpath, "/dev/%s", argv[1]); + else + devpath = argv[1]; + if ((tty = open(devpath, O_RDWR)) < 0) { + syslog(LOG_ALERT, "open failed with %s", strerror(errno)); + err(1, "open(%s)", devpath); + } + + if (login_tty(tty) < 0) { + syslog(LOG_ALERT, "login_tty failed: %s", strerror(errno)); + err(1, "login_tty()"); } } ==== //depot/projects/ctsrd/cheribsd/src/ctsrd/spinner/spinner.c#2 (text+ko) ==== @@ -80,7 +80,7 @@ main(int argc, char *argv[]) { int alpha, ch, i, ofd; - pid_t pid; + pid_t pid = 0; char *ep; char imgpath[MAXPATHLEN]; u_int32_t *bottom, *top; @@ -164,7 +164,8 @@ for (i = 0; i < NSPINNERS; i++) { - poll_child(pid); + if (pid != 0) + poll_child(pid); snprintf(imgpath, sizeof(imgpath), "%s/spinner%02d.png", IMGDIR, i); read_png_file(imgpath, spinners[i], fb_width, fb_height); @@ -191,7 +192,8 @@ if (i >= NSPINNERS) i = 0; fb_post(spinners[i]); - poll_child(pid); + if (pid != 0) + poll_child(pid); } fb_fade2off(); ==== //depot/projects/ctsrd/cheribsd/src/etc/mtree/BSD.usr.dist#2 (text+ko) ==== @@ -322,6 +322,8 @@ fortune .. .. + images + .. info .. i18n ==== //depot/projects/ctsrd/cheribsd/src/etc/rc#2 (text+ko) ==== @@ -82,7 +82,11 @@ # Do a first pass to get everything up to $early_late_divider so that # we can do a second pass that includes $local_startup directories # -files=`rcorder ${skip} /etc/rc.d/* 2>/dev/null` +if [ -r /etc/rcorder.start ]; then + files=`read_fixed_rcorder /etc/rcorder.start` +else + files=`rcorder ${skip} /etc/rc.d/* 2>/dev/null` +fi _rc_elem_done=' ' for _rc_elem in ${files}; do @@ -104,7 +108,11 @@ *) find_local_scripts_new ;; esac -files=`rcorder ${skip} /etc/rc.d/* ${local_rc} 2>/dev/null` +if [ -r /etc/rcorder.start ]; then + files=`read_fixed_rcorder /etc/rcorder.start` +else + files=`rcorder ${skip} /etc/rc.d/* ${local_rc} 2>/dev/null` +fi for _rc_elem in ${files}; do case "$_rc_elem_done" in *" $_rc_elem "*) continue ;; ==== //depot/projects/ctsrd/cheribsd/src/etc/rc.subr#2 (text+ko) ==== @@ -1738,6 +1738,20 @@ esac } +read_fixed_rcorder() +{ + local _files _file + + _files="" + while read _file; do + if [ -r ${_file} ]; then + _files="${_files} ${_file}" + fi + done < $1 + + echo ${_files} +} + fi # [ -z "${_rc_subr_loaded}" ] _rc_subr_loaded=: ==== //depot/projects/ctsrd/cheribsd/src/sys/conf/options.mips#4 (text+ko) ==== ==== //depot/projects/ctsrd/cheribsd/src/sys/dev/altera/avgen/altera_avgen.c#2 (text+ko) ==== @@ -382,16 +382,18 @@ device_printf(dev, "couldn't map memory\n"); return (ENXIO); } - if (rman_get_size(sc->avg_res) % PAGE_SIZE != 0) { - device_printf(dev, - "memory region not even multiple of page size\n"); - error = ENXIO; - goto error; - } - if (rman_get_start(sc->avg_res) % PAGE_SIZE != 0) { - device_printf(dev, "memory region not page-aligned\n"); - error = ENXIO; - goto error; + if (rman_get_size(sc->avg_res) >= PAGE_SIZE || str_mmapio != NULL) { + if (rman_get_size(sc->avg_res) % PAGE_SIZE != 0) { + device_printf(dev, + "memory region not even multiple of page size\n"); + error = ENXIO; + goto error; + } + if (rman_get_start(sc->avg_res) % PAGE_SIZE != 0) { + device_printf(dev, "memory region not page-aligned\n"); + error = ENXIO; + goto error; + } } /* Device node allocation. */ ==== //depot/projects/ctsrd/cheribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart.h#2 (text+ko) ==== @@ -56,7 +56,8 @@ u_int ajus_flags; struct mtx *ajus_lockp; struct mtx ajus_lock; - struct callout ajus_callout; + struct callout ajus_io_callout; + struct callout ajus_ac_callout; /* * One-character buffer required because it's not possible to peek at @@ -66,6 +67,10 @@ int *ajus_buffer_validp; uint8_t ajus_buffer_data; uint8_t *ajus_buffer_datap; + int ajus_jtag_present; + int *ajus_jtag_presentp; + u_int ajus_jtag_missed; + u_int *ajus_jtag_missedp; }; #define AJU_TTYNAME "ttyu" @@ -126,6 +131,8 @@ extern struct mtx aju_cons_lock; extern char aju_cons_buffer_data; extern int aju_cons_buffer_valid; +extern int aju_cons_jtag_present; +extern u_int aju_cons_jtag_missed; /* * Base physical address of the JTAG UART in BERI. ==== //depot/projects/ctsrd/cheribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart_cons.c#2 (text+ko) ==== @@ -55,6 +55,8 @@ */ char aju_cons_buffer_data; int aju_cons_buffer_valid; +int aju_cons_jtag_present; +u_int aju_cons_jtag_missed; struct mtx aju_cons_lock; /* @@ -69,6 +71,16 @@ static cn_ungrab_t aju_cnungrab; /* + * JTAG sets the ALTERA_JTAG_UART_CONTROL_AC bit whenever it accesses the + * FIFO. This allows us to (sort of) tell when JTAG is present, so that we + * can adopt lossy, rather than blocking, behaviour when JTAG isn't there. + * When it is present, we do full flow control. This delay is how long we + * wait to see if JTAG has really disappeared when finding a full buffer and + * no AC bit set. + */ +#define ALTERA_JTAG_UART_AC_POLL_DELAY 10000 + +/* * I/O routines lifted from Deimos. This is not only MIPS-specific, but also * BERI-specific, as we're hard coding the the address at which we expect to * find the Altera JTAG UART and using it unconditionally. We use these @@ -154,17 +166,17 @@ ALTERA_JTAG_UART_CONTROL_OFF))); } -/* - * Slightly higher-level routines aware of buffering and flow control. - */ -static int -aju_cons_writable(void) +static inline void +aju_cons_control_write(uint32_t v) { - return ((aju_cons_control_read() & - ALTERA_JTAG_UART_CONTROL_WSPACE) != 0); + mips_iowrite_uint32le(mips_phys_to_uncached(BERI_UART_BASE + + ALTERA_JTAG_UART_CONTROL_OFF), v); } +/* + * Slightly higher-level routines aware of buffering and flow control. + */ static int aju_cons_readable(void) { @@ -186,10 +198,46 @@ static void aju_cons_write(char ch) { + uint32_t v; AJU_CONSOLE_LOCK_ASSERT(); - while (!aju_cons_writable()); + /* + * The flow control logic here is somewhat subtle: we want to wait for + * write buffer space only while JTAG is present. However, we can't + * directly ask if JTAG is present -- just whether it's been seen + * since we last cleared the ALTERA_JTAG_UART_CONTROL_AC bit. As + * such, implement a polling loop in which we both wait for space and + * try to decide whether JTAG has disappeared on us. We will have to + * wait one complete polling delay to detect that JTAG has gone away, + * but otherwise shouldn't wait any further once it has gone. And we + * had to wait for buffer space anyway, if it was there. + * + * If JTAG is spotted, reset the TTY-layer miss counter so console- + * layer clearing of the bit doesn't trigger a TTY-layer + * disconnection. + * + * XXXRW: The polling delay may require tuning. + */ + v = aju_cons_control_read(); + if (v & ALTERA_JTAG_UART_CONTROL_AC) { + aju_cons_jtag_present = 1; + aju_cons_jtag_missed = 0; + v &= ~ALTERA_JTAG_UART_CONTROL_AC; + aju_cons_control_write(v); + } + while ((v & ALTERA_JTAG_UART_CONTROL_WSPACE) == 0) { + if (!aju_cons_jtag_present) + return; + DELAY(ALTERA_JTAG_UART_AC_POLL_DELAY); + v = aju_cons_control_read(); + if (v & ALTERA_JTAG_UART_CONTROL_AC) { + aju_cons_jtag_present = 1; + v &= ~ALTERA_JTAG_UART_CONTROL_AC; + aju_cons_control_write(v); + } else + aju_cons_jtag_present = 0; + } aju_cons_data_write(ch); } @@ -218,8 +266,15 @@ static void aju_cninit(struct consdev *cp) { + uint32_t v; AJU_CONSOLE_LOCK_INIT(); + + AJU_CONSOLE_LOCK(); + v = aju_cons_control_read(); + v &= ~ALTERA_JTAG_UART_CONTROL_AC; + aju_cons_control_write(v); + AJU_CONSOLE_UNLOCK(); } static void ==== //depot/projects/ctsrd/cheribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart_tty.c#2 (text+ko) ==== @@ -55,7 +55,8 @@ static struct altera_jtag_uart_softc *aju_cons_sc; static tsw_outwakeup_t aju_outwakeup; -static void aju_timeout(void *); +static void aju_ac_callout(void *); +static void aju_io_callout(void *); static struct ttydevsw aju_ttydevsw = { .tsw_flags = TF_NOPREFIX, @@ -63,9 +64,16 @@ }; /* - * Poll for new input every (aju_pollinterval) ticks. + * When polling for the AC bit, the number of times we have to not see it + * before assuming JTAG has disappeared on us. By default, one second. + */ +#define AJU_JTAG_MAXMISS 5 + +/* + * Polling intervals for input/output and JTAG connection events. */ -static u_int aju_pollinterval = 1; +#define AJU_IO_POLLINTERVAL (hz/100) +#define AJU_AC_POLLINTERVAL (hz/5) /* * Low-level read and write register routines; the Altera UART is little @@ -232,6 +240,7 @@ static void aju_handle_output(struct altera_jtag_uart_softc *sc, struct tty *tp) { + uint32_t v; uint8_t ch; tty_lock_assert(tp, MA_OWNED); @@ -240,14 +249,31 @@ AJU_UNLOCK(sc); while (ttydisc_getc_poll(tp) != 0) { AJU_LOCK(sc); - if (aju_writable(sc)) { + v = aju_control_read(sc); + if ((v & ALTERA_JTAG_UART_CONTROL_WSPACE) != 0) { AJU_UNLOCK(sc); if (ttydisc_getc(tp, &ch, sizeof(ch)) != sizeof(ch)) panic("%s: ttydisc_getc", __func__); AJU_LOCK(sc); aju_data_write(sc, ch); } else { - aju_intr_writable_enable(sc); + /* + * If JTAG is not present, then we will drop this + * character instead of perhaps scheduling an + * interrupt to let us know when there is buffer + * space. Otherwise we might get a write interrupt + * later even though we aren't interested in sending + * anymore. Loop to drain TTY-layer buffer. + */ + if (*sc->ajus_jtag_presentp == 0) { + if (ttydisc_getc(tp, &ch, sizeof(ch)) != + sizeof(ch)) + panic("%s: ttydisc_getc 2", __func__); + AJU_UNLOCK(sc); + continue; + } + if (sc->ajus_irq_res != NULL) + aju_intr_writable_enable(sc); return; } AJU_UNLOCK(sc); @@ -269,7 +295,7 @@ } static void -aju_timeout(void *arg) +aju_io_callout(void *arg) { struct altera_jtag_uart_softc *sc = arg; struct tty *tp = sc->ajus_ttyp; @@ -293,7 +319,39 @@ * pending in the output buffer, or have we recently had input, but we * don't. */ - callout_reset(&sc->ajus_callout, aju_pollinterval, aju_timeout, sc); + callout_reset(&sc->ajus_io_callout, AJU_IO_POLLINTERVAL, + aju_io_callout, sc); + AJU_UNLOCK(sc); + tty_unlock(tp); +} + +static void +aju_ac_callout(void *arg) +{ + struct altera_jtag_uart_softc *sc = arg; + struct tty *tp = sc->ajus_ttyp; + uint32_t v; + + tty_lock(tp); + AJU_LOCK(sc); + v = aju_control_read(sc); + if (v & ALTERA_JTAG_UART_CONTROL_AC) { + v &= ~ALTERA_JTAG_UART_CONTROL_AC; + aju_control_write(sc, v); + if (*sc->ajus_jtag_presentp == 0) { + *sc->ajus_jtag_missedp = 0; + *sc->ajus_jtag_presentp = 1; + aju_handle_output(sc, tp); + } + } else if (*sc->ajus_jtag_presentp != 0) { + (*sc->ajus_jtag_missedp)++; + if (*sc->ajus_jtag_missedp >= AJU_JTAG_MAXMISS) { + *sc->ajus_jtag_presentp = 0; + aju_handle_output(sc, tp); + } + } + callout_reset(&sc->ajus_ac_callout, AJU_AC_POLLINTERVAL, + aju_ac_callout, sc); AJU_UNLOCK(sc); tty_unlock(tp); } @@ -333,11 +391,15 @@ sc->ajus_lockp = &aju_cons_lock; sc->ajus_buffer_validp = &aju_cons_buffer_valid; sc->ajus_buffer_datap = &aju_cons_buffer_data; + sc->ajus_jtag_presentp = &aju_cons_jtag_present; + sc->ajus_jtag_missedp = &aju_cons_jtag_missed; sc->ajus_flags |= ALTERA_JTAG_UART_FLAG_CONSOLE; } else { sc->ajus_lockp = &sc->ajus_lock; sc->ajus_buffer_validp = &sc->ajus_buffer_valid; sc->ajus_buffer_datap = &sc->ajus_buffer_data; + sc->ajus_jtag_presentp = &sc->ajus_jtag_present; + sc->ajus_jtag_missedp = &sc->ajus_jtag_missed; } /* @@ -376,10 +438,13 @@ aju_intr_readable_enable(sc); AJU_UNLOCK(sc); } else { - callout_init(&sc->ajus_callout, CALLOUT_MPSAFE); - callout_reset(&sc->ajus_callout, aju_pollinterval, - aju_timeout, sc); + callout_init(&sc->ajus_io_callout, CALLOUT_MPSAFE); + callout_reset(&sc->ajus_io_callout, AJU_IO_POLLINTERVAL, + aju_io_callout, sc); } + callout_init(&sc->ajus_ac_callout, CALLOUT_MPSAFE); + callout_reset(&sc->ajus_ac_callout, AJU_AC_POLLINTERVAL, + aju_ac_callout, sc); return (0); } @@ -399,7 +464,8 @@ bus_teardown_intr(sc->ajus_dev, sc->ajus_irq_res, sc->ajus_irq_cookie); } else - callout_drain(&sc->ajus_callout); + callout_drain(&sc->ajus_io_callout); + callout_drain(&sc->ajus_ac_callout); if (sc->ajus_flags & ALTERA_JTAG_UART_FLAG_CONSOLE) aju_cons_sc = NULL; tty_lock(tp); ==== //depot/projects/ctsrd/cheribsd/src/sys/dev/terasic/de4led/terasic_de4led.c#2 (text+ko) ==== @@ -63,56 +63,56 @@ } static void -led_1(void *arg, int onoff) +led_0(void *arg, int onoff) { led_update(arg, 0, onoff); } static void -led_2(void *arg, int onoff) +led_1(void *arg, int onoff) { led_update(arg, 1, onoff); } static void -led_3(void *arg, int onoff) +led_2(void *arg, int onoff) { led_update(arg, 2, onoff); } static void -led_4(void *arg, int onoff) +led_3(void *arg, int onoff) { led_update(arg, 3, onoff); } static void -led_5(void *arg, int onoff) +led_4(void *arg, int onoff) { led_update(arg, 4, onoff); } static void -led_6(void *arg, int onoff) +led_5(void *arg, int onoff) { led_update(arg, 5, onoff); } static void -led_7(void *arg, int onoff) +led_6(void *arg, int onoff) { led_update(arg, 6, onoff); } static void -led_8(void *arg, int onoff) +led_7(void *arg, int onoff) { led_update(arg, 7, onoff); >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201207062240.q66Me9Oq083692>