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