Date: Sat, 4 Feb 2012 11:22:32 GMT From: Robert Watson <rwatson@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 205675 for review Message-ID: <201202041122.q14BMWRp044633@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@205675?ac=10 Change 205675 by rwatson@rwatson_svr_ctsrd_mipsbuild on 2012/02/04 11:22:06 Take a first cut at adapting the Deimos Altera JTAG UART for use in FreeBSD. It still relies on direct reads/writes to the xkphys space rather than going through appropriate bus routines, but now interfaces with the FreeBSD low-level console driver interface. Affected files ... .. //depot/projects/ctsrd/beribsd/src/sys/mips/beri/files.beri#3 edit .. //depot/projects/ctsrd/beribsd/src/sys/mips/beri/uart_altera.c#2 edit Differences ... ==== //depot/projects/ctsrd/beribsd/src/sys/mips/beri/files.beri#3 (text+ko) ==== @@ -1,4 +1,5 @@ # $FreeBSD$ mips/beri/beri_machdep.c standard +mips/beri/uart_altera.c standard mips/mips/intr_machdep.c standard mips/mips/tick.c standard ==== //depot/projects/ctsrd/beribsd/src/sys/mips/beri/uart_altera.c#2 (text+ko) ==== @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2011 Robert N. M. Watson + * Copyright (c) 2011-2012 Robert N. M. Watson * All rights reserved. * * This software was developed by SRI International and the University of @@ -28,19 +28,88 @@ * SUCH DAMAGE. */ -#include "include/cheri.h" -#include "include/mips.h" +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/cons.h> +#include <sys/endian.h> +#include <sys/systm.h> +#include <sys/kernel.h> + +static cn_probe_t aj_uart_cnprobe; +static cn_init_t aj_uart_cninit; +static cn_term_t aj_uart_cnterm; +static cn_getc_t aj_uart_cngetc; +static cn_putc_t aj_uart_cnputc; +static cn_grab_t aj_uart_cngrab; +static cn_ungrab_t aj_uart_cnungrab; + +/* + * I/O routines lifted from Deimos. + * + * XXXRW: Should be using FreeBSD's bus routines here. + */ +#define MIPS_XKPHYS_UNCACHED_BASE 0x9000000000000000 + +typedef uint64_t paddr_t; +typedef uint64_t vaddr_t; + +static inline vaddr_t +mips_phys_to_uncached(paddr_t phys) +{ + + return (phys | MIPS_XKPHYS_UNCACHED_BASE); +} + +static inline uint32_t +mips_ioread_uint32(vaddr_t vaddr) +{ + uint32_t v; + + __asm__ __volatile__ ("lw %0, 0(%1)" : "=r" (v) : "r" (vaddr)); + return (v); +} + +static inline void +mips_iowrite_uint32(vaddr_t vaddr, uint32_t v) +{ + + __asm__ __volatile__ ("sw %0, 0(%1)" : : "r" (v), "r" (vaddr)); +} + +/* + * Little-endian versions of 32-bit I/O routines. + */ +static inline uint32_t +mips_ioread_uint32le(vaddr_t vaddr) +{ + + return (le32toh(mips_ioread_uint32(vaddr))); +} + +static inline void +mips_iowrite_uint32le(vaddr_t vaddr, uint32_t v) +{ + + mips_iowrite_uint32(vaddr, htole32(v)); +} -#include "dev/uart/uart.h" +/* + * Base physical address of the JTAG UART in BERI. + * + * XXXRW: Should be set using FDT and/or device.hints. + */ +#define BERI_UART_BASE 0x7f000000 /* JTAG UART */ /*- - * Routines for interacting with the CHERI console UART. Programming details - * from the June 2011 "Embedded Peripherals User Guide" by Altera + * Routines for interacting with the BERI console JTAG UART. Programming + * details from the June 2011 "Embedded Peripherals User Guide" by Altera * Corporation, tables 6-2 (JTAG UART Core Register Map), 6-3 (Data Register * Bits), and 6-4 (Control Register Bits). * * Offsets of data and control registers relative to the base. Altera - * conventions are maintained in CHERI. + * conventions are maintained in BERI. */ #define ALTERA_JTAG_UART_DATA_OFF 0x00000000 #define ALTERA_JTAG_UART_CONTROL_OFF 0x00000004 @@ -92,52 +161,56 @@ * endian, so we byte swap 32-bit reads and writes. */ static inline uint32_t -uart_data_read(void) +aj_uart_data_read(void) { - return (mips_ioread_uint32le(mips_phys_to_uncached(CHERI_UART_BASE + + return (mips_ioread_uint32le(mips_phys_to_uncached(BERI_UART_BASE + ALTERA_JTAG_UART_DATA_OFF))); } static inline void -uart_data_write(uint32_t v) +aj_uart_data_write(uint32_t v) { - mips_iowrite_uint32le(mips_phys_to_uncached(CHERI_UART_BASE + + mips_iowrite_uint32le(mips_phys_to_uncached(BERI_UART_BASE + ALTERA_JTAG_UART_DATA_OFF), v); } static inline uint32_t -uart_control_read(void) +aj_uart_control_read(void) { - return (mips_ioread_uint32le(mips_phys_to_uncached(CHERI_UART_BASE + + return (mips_ioread_uint32le(mips_phys_to_uncached(BERI_UART_BASE + ALTERA_JTAG_UART_CONTROL_OFF))); } static inline void -uart_control_write(uint32_t v) +aj_uart_control_write(uint32_t v) { - mips_iowrite_uint32le(mips_phys_to_uncached(CHERI_UART_BASE + + mips_iowrite_uint32le(mips_phys_to_uncached(BERI_UART_BASE + ALTERA_JTAG_UART_DATA_OFF), v); } -int -uart_writable(void) +/* + * Slightly higher-level routines aware of buffering and flow control. + */ +static int +aj_uart_writable(void) { - return ((uart_control_read() & ALTERA_JTAG_UART_CONTROL_WSPACE) != 0); + return ((aj_uart_control_read() & + ALTERA_JTAG_UART_CONTROL_WSPACE) != 0); } -int -uart_readable(void) +static int +aj_uart_readable(void) { uint32_t v; if (buffer_valid) return (1); - v = uart_data_read(); + v = aj_uart_data_read(); if ((v & ALTERA_JTAG_UART_DATA_RVALID) != 0) { buffer_valid = 1; buffer_data = (v & ALTERA_JTAG_UART_DATA_DATA); @@ -145,25 +218,70 @@ return (0); } -char -uart_read(void) +static void +aj_uart_write(char ch) +{ + + while (!aj_uart_writable()); + aj_uart_data_write(ch); +} + +static char +aj_uart_read(void) { - while (!uart_readable()); + while (!aj_uart_readable()); buffer_valid = 0; return (buffer_data); } -void -uart_write(char ch) +/* + * Implementation of a FreeBSD low-level, polled console driver. + */ +static void +aj_uart_cnprobe(struct consdev *cp) +{ + + sprintf(cp->cn_name, "aj_uart"); + cp->cn_pri = CN_NORMAL; +} + +static void +aj_uart_cninit(struct consdev *cp) +{ + +} + +static void +aj_uart_cnterm(struct consdev *cp) +{ + +} + +static int +aj_uart_cngetc(struct consdev *cp) +{ + + return (aj_uart_read()); +} + +static void +aj_uart_cnputc(struct consdev *cp, int c) +{ + + aj_uart_write(c); +} + +static void +aj_uart_cngrab(struct consdev *cp) { - uart_data_write(ch); } -void -uart_init(void) +static void +aj_uart_cnungrab(struct consdev *cp) { - /* Nothing required. */ } + +CONSOLE_DRIVER(aj_uart);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202041122.q14BMWRp044633>