From owner-p4-projects@FreeBSD.ORG Sat Feb 4 11:22:33 2012 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0E04D1065673; Sat, 4 Feb 2012 11:22:33 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BBC3D1065670 for ; Sat, 4 Feb 2012 11:22:32 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id A70B78FC08 for ; Sat, 4 Feb 2012 11:22:32 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id q14BMWnU044636 for ; Sat, 4 Feb 2012 11:22:32 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id q14BMWRp044633 for perforce@freebsd.org; Sat, 4 Feb 2012 11:22:32 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Sat, 4 Feb 2012 11:22:32 GMT Message-Id: <201202041122.q14BMWRp044633@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 205675 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 04 Feb 2012 11:22:33 -0000 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +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);