1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * PC Console driver File: dev_pcconsole2.c 5 * 6 * A console driver for a PC-style keyboard and mouse 7 * 8 * This version is for USB keyboards. Someday we'll consolidate 9 * everything. 10 * 11 * Author: Mitch Lichtenberg 12 * 13 ********************************************************************* 14 * 15 * Copyright 2000,2001,2002,2003 16 * Broadcom Corporation. All rights reserved. 17 * 18 * This software is furnished under license and may be used and 19 * copied only in accordance with the following terms and 20 * conditions. Subject to these conditions, you may download, 21 * copy, install, use, modify and distribute modified or unmodified 22 * copies of this software in source and/or binary form. No title 23 * or ownership is transferred hereby. 24 * 25 * 1) Any source code used, modified or distributed must reproduce 26 * and retain this copyright notice and list of conditions 27 * as they appear in the source file. 28 * 29 * 2) No right is granted to use any trade name, trademark, or 30 * logo of Broadcom Corporation. The "Broadcom Corporation" 31 * name may not be used to endorse or promote products derived 32 * from this software without the prior written permission of 33 * Broadcom Corporation. 34 * 35 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 36 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 37 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 38 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 39 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 40 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 41 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 42 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 43 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 44 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 45 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 46 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 47 * THE POSSIBILITY OF SUCH DAMAGE. 48 ********************************************************************* */ 49 50 51 52#include "cfe.h" 53#include "sbmips.h" 54 55#include "lib_physio.h" 56 57#include "vga_subr.h" 58 59#include "pcireg.h" 60#include "pcivar.h" 61 62/* ********************************************************************* 63 * Constants 64 ********************************************************************* */ 65 66#define KBD_RXFULL 1 /* bit set if kb has data */ 67#define KBD_TXFULL 2 /* bit set if we can send cmd */ 68#define VGA_TEXTBUF_COLOR 0xB8000 /* VGA frame buffer */ 69 70/* XXX SB1250 specific */ 71#define __ISAaddr(x)(0x40000000+(x)) 72 73/* ********************************************************************* 74 * Forward references 75 ********************************************************************* */ 76 77int pcconsole_enqueue(uint8_t ch); 78 79static void pcconsole_probe(cfe_driver_t *drv, 80 unsigned long probe_a, unsigned long probe_b, 81 void *probe_ptr); 82 83 84static int pcconsole_open(cfe_devctx_t *ctx); 85static int pcconsole_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 86static int pcconsole_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat); 87static int pcconsole_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 88static int pcconsole_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 89static int pcconsole_close(cfe_devctx_t *ctx); 90static void pcconsole_poll(cfe_devctx_t *ctx,int64_t ticks); 91 92const static cfe_devdisp_t pcconsole_dispatch = { 93 pcconsole_open, 94 pcconsole_read, 95 pcconsole_inpstat, 96 pcconsole_write, 97 pcconsole_ioctl, 98 pcconsole_close, 99 pcconsole_poll, 100 NULL 101}; 102 103const cfe_driver_t pcconsole2 = { 104 "PC Console (USB)", 105 "pcconsole", 106 CFE_DEV_SERIAL, 107 &pcconsole_dispatch, 108 pcconsole_probe 109}; 110 111 112/* ********************************************************************* 113 * Structures 114 ********************************************************************* */ 115 116#define KBD_QUEUE_LEN 32 117 118typedef struct pcconsole_s { 119 vga_term_t vga; 120 int kbd_in; 121 int kbd_out; 122 uint8_t kbd_data[KBD_QUEUE_LEN]; 123} pcconsole_t; 124 125static pcconsole_t *pcconsole_current = NULL; 126 127/* ********************************************************************* 128 * pcconsole_poll(ctx,ticks) 129 * 130 * Poll routine - check for new keyboard events 131 * 132 * Input parameters: 133 * ctx - device context 134 * ticks - current time 135 * 136 * Return value: 137 * nothing 138 ********************************************************************* */ 139 140 141static void pcconsole_poll(cfe_devctx_t *ctx,int64_t ticks) 142{ 143 /* No polling needed, USB will do the work for us */ 144} 145 146 147 148/* ********************************************************************* 149 * pcconsole_probe(drv,probe_a,probe_b,probe_ptr) 150 * 151 * Probe routine. This routine sets up the pcconsole device 152 * 153 * Input parameters: 154 * drv - driver structure 155 * probe_a 156 * probe_b 157 * probe_ptr 158 * 159 * Return value: 160 * nothing 161 ********************************************************************* */ 162 163static void pcconsole_probe(cfe_driver_t *drv, 164 unsigned long probe_a, unsigned long probe_b, 165 void *probe_ptr) 166{ 167 pcconsole_t *softc; 168 char descr[80]; 169 170 /* 171 * probe_a is 172 * probe_b is 173 * probe_ptr is 174 */ 175 176 softc = (pcconsole_t *) KMALLOC(sizeof(pcconsole_t),0); 177 if (softc) { 178 179 memset(softc,0,sizeof(pcconsole_t)); 180 181 /* 182 * XXX this should not be hardwired 183 */ 184 vga_init(&(softc->vga),__ISAaddr(VGA_TEXTBUF_COLOR),outb); 185 186 xsprintf(descr,"%s",drv->drv_description,probe_a,probe_b); 187 cfe_attach(drv,softc,NULL,descr); 188 } 189 190} 191 192 193static int pcconsole_open(cfe_devctx_t *ctx) 194{ 195 pcconsole_t *softc = ctx->dev_softc; 196 197 pcconsole_current = softc; 198 199 softc->kbd_in = 0; 200 softc->kbd_out = 0; 201 202 vga_clear(&(softc->vga)); 203 vga_setcursor(&(softc->vga),0,0); 204 205 return 0; 206} 207 208static int pcconsole_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer) 209{ 210 pcconsole_t *softc = ctx->dev_softc; 211 hsaddr_t bptr; 212 uint8_t b; 213 int blen; 214 215 bptr = buffer->buf_ptr; 216 blen = buffer->buf_length; 217 218 while ((blen > 0) && (softc->kbd_in != softc->kbd_out)) { 219 b = softc->kbd_data[softc->kbd_out]; 220 hs_write8(bptr,b); 221 bptr++ ; 222 softc->kbd_out++; 223 if (softc->kbd_out >= KBD_QUEUE_LEN) { 224 softc->kbd_out = 0; 225 } 226 blen--; 227 } 228 229 buffer->buf_retlen = buffer->buf_length - blen; 230 return 0; 231} 232 233static int pcconsole_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat) 234{ 235 pcconsole_t *softc = ctx->dev_softc; 236 237 POLL(); 238 239 inpstat->inp_status = (softc->kbd_in != softc->kbd_out); 240 241 return 0; 242} 243 244static int pcconsole_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer) 245{ 246 pcconsole_t *softc = ctx->dev_softc; 247 hsaddr_t bptr; 248 int blen; 249 250 bptr = buffer->buf_ptr; 251 blen = buffer->buf_length; 252 253 vga_writestr(&(softc->vga),bptr,7,blen); 254 255 buffer->buf_retlen = buffer->buf_length; 256 return 0; 257} 258 259static int pcconsole_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer) 260{ 261/* pcconsole_t *softc = ctx->dev_softc;*/ 262 263 return -1; 264} 265 266static int pcconsole_close(cfe_devctx_t *ctx) 267{ 268/* pcconsole_t *softc = ctx->dev_softc;*/ 269 pcconsole_current = NULL; 270 271 return 0; 272} 273 274/* 275 * Called by USB system to queue characters. 276 */ 277int pcconsole_enqueue(uint8_t ch) 278{ 279 int newidx; 280 281 if (!pcconsole_current) return -1; 282 283 newidx = pcconsole_current->kbd_in+1; 284 if (newidx >= KBD_QUEUE_LEN) newidx = 0; 285 286 if (newidx == pcconsole_current->kbd_out) return -1; 287 288 pcconsole_current->kbd_data[pcconsole_current->kbd_in] = ch; 289 pcconsole_current->kbd_in = newidx; 290 291 return 0; 292} 293