OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [rel-0-3-0-rc3/] [or1ksim/] [peripheral/] [ps2kbd.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 805 markom
/* ps2kbd.c -- Very simple (and limited) PS/2 keyboard simulation
2 1748 jeremybenn
 
3 805 markom
   Copyright (C) 2002 Marko Mlinar, markom@opencores.org
4 1748 jeremybenn
   Copyright (C) 2008 Embecosm Limited
5 684 lampret
 
6 1748 jeremybenn
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
7 805 markom
 
8 1748 jeremybenn
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
9 805 markom
 
10 1748 jeremybenn
   This program is free software; you can redistribute it and/or modify it
11
   under the terms of the GNU General Public License as published by the Free
12
   Software Foundation; either version 3 of the License, or (at your option)
13
   any later version.
14 805 markom
 
15 1748 jeremybenn
   This program is distributed in the hope that it will be useful, but WITHOUT
16
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18
   more details.
19 805 markom
 
20 1748 jeremybenn
   You should have received a copy of the GNU General Public License along
21
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22 1350 nogj
 
23 1748 jeremybenn
/* This program is commented throughout in a fashion suitable for processing
24
   with Doxygen. */
25
 
26
 
27
/* Autoconf and/or portability configuration */
28 1350 nogj
#include "config.h"
29 1748 jeremybenn
#include "port.h"
30 1350 nogj
 
31 1748 jeremybenn
/* System includes */
32
#include <stdlib.h>
33
#include <stdio.h>
34 1350 nogj
 
35 1748 jeremybenn
/* Package includes */
36 1350 nogj
#include "arch.h"
37 1748 jeremybenn
#include "pic.h"
38 805 markom
#include "sim-config.h"
39
#include "abstract.h"
40
#include "sched.h"
41 1748 jeremybenn
#include "toplevel-support.h"
42
#include "sim-cmd.h"
43 805 markom
 
44 1748 jeremybenn
 
45
/* Device registers */
46
#define KBD_CTRL              4
47
#define KBD_DATA              0
48
#define KBD_SPACE             8
49
 
50
/* Keyboard commands */
51
#define KBD_KCMD_RST       0xFF
52
#define KBD_KCMD_DK        0xF5
53
#define KBD_KCMD_EK        0xF4
54
#define KBD_KCMD_ECHO      0xFF
55
#define KBD_KCMD_SRL       0xED
56
 
57
/* Keyboard responses */
58
#define KBD_KRESP_RSTOK    0xAA
59
#define KBD_KRESP_ECHO     0xEE
60
#define KBD_KRESP_ACK      0xFA
61
 
62
/* Controller commands */
63
#define KBD_CCMD_RCB       0x20
64
#define KBD_CCMD_WCB       0x60
65
#define KBD_CCMD_ST1       0xAA
66
#define KBD_CCMD_ST2       0xAB
67
#define KBD_CCMD_DKI       0xAD
68
#define KBD_CCMD_EKI       0xAE
69
 
70
/* Status register bits */
71
#define KBD_STATUS_OBF     0x01
72
#define KBD_STATUS_IBF     0x02
73
#define KBD_STATUS_SYS     0x04
74
#define KBD_STATUS_A2      0x08
75
#define KBD_STATUS_INH     0x10
76
#define KBD_STATUS_MOBF    0x20
77
#define KBD_STATUS_TO      0x40
78
#define KBD_STATUS_PERR    0x80
79
 
80
/* Command byte register bits */
81
#define KBD_CCMDBYTE_INT   0x01
82
#define KBD_CCMDBYTE_INT2  0x02
83
#define KBD_CCMDBYTE_SYS   0x04
84
#define KBD_CCMDBYTE_EN    0x10
85
#define KBD_CCMDBYTE_EN2   0x20
86
#define KBD_CCMDBYTE_XLAT  0x40
87
 
88
/* Length of internal scan code fifo */
89
#define KBD_MAX_BUF       0x100
90
 
91
/* Keyboard is checked every KBD_SLOWDOWN cycle */
92
#define KBD_BAUD_RATE      1200
93
 
94 805 markom
/* ASCII to scan code conversion table */
95 1748 jeremybenn
const static struct
96
{
97 805 markom
  /* Whether shift must be pressed */
98
  unsigned char shift;
99
  /* Scan code to be generated */
100
  unsigned char code;
101 1748 jeremybenn
} scan_table[128] =
102
{
103 805 markom
/* 0 - 15 */
104 1748 jeremybenn
  {
105
  0, 0x00},
106
  {
107
  0, 0x00},
108
  {
109
  0, 0x00},
110
  {
111
  0, 0x00},
112
  {
113
  0, 0x00},
114
  {
115
  0, 0x00},
116
  {
117
  0, 0x00},
118
  {
119
  0, 0x00},
120
  {
121
  0, 0x0E},
122
  {
123
  0, 0x0F},
124
  {
125
  0, 0x1C},
126
  {
127
  0, 0x00},
128
  {
129
  0, 0x00},
130
  {
131
  0, 0x00},
132
  {
133
  0, 0x00},
134
  {
135
  0, 0x00},
136 805 markom
/* 16 - 31 */
137 1748 jeremybenn
  {
138
  0, 0x00},
139
  {
140
  0, 0x00},
141
  {
142
  0, 0x00},
143
  {
144
  0, 0x00},
145
  {
146
  0, 0x00},
147
  {
148
  0, 0x00},
149
  {
150
  0, 0x00},
151
  {
152
  0, 0x00},
153
  {
154
  0, 0x00},
155
  {
156
  0, 0x00},
157
  {
158
  0, 0x00},
159
  {
160
  0, 0x01},
161
  {
162
  0, 0x00},
163
  {
164
  0, 0x00},
165
  {
166
  0, 0x00},
167
  {
168
  0, 0x00},
169 805 markom
/* 32 - 47 */
170 1748 jeremybenn
  {
171
  0, 0x39},
172
  {
173
  1, 0x02},
174
  {
175
  1, 0x28},
176
  {
177
  1, 0x04},
178
  {
179
  1, 0x05},
180
  {
181
  1, 0x06},
182
  {
183
  1, 0x08},
184
  {
185
  0, 0x28},
186
  {
187
  1, 0x0A},
188
  {
189
  1, 0x0B},
190
  {
191
  1, 0x09},
192
  {
193
  1, 0x0D},
194
  {
195
  0, 0x33},
196
  {
197
  0, 0x0C},
198
  {
199
  0, 0x34},
200
  {
201
  0, 0x35},
202 805 markom
/* 48 - 63 */
203 1748 jeremybenn
  {
204
  0, 0x0B},
205
  {
206
  0, 0x02},
207
  {
208
  0, 0x03},
209
  {
210
  0, 0x04},
211
  {
212
  0, 0x05},
213
  {
214
  0, 0x06},
215
  {
216
  0, 0x07},
217
  {
218
  0, 0x08},
219
  {
220
  0, 0x09},
221
  {
222
  0, 0x0A},
223
  {
224
  1, 0x27},
225
  {
226
  0, 0x27},
227
  {
228
  1, 0x33},
229
  {
230
  0, 0x0D},
231
  {
232
  1, 0x34},
233
  {
234
  1, 0x35},
235 805 markom
/* 64 - 79 */
236 1748 jeremybenn
  {
237
  1, 0x03},
238
  {
239
  1, 0x1E},
240
  {
241
  1, 0x30},
242
  {
243
  1, 0x2E},
244
  {
245
  1, 0x20},
246
  {
247
  1, 0x12},
248
  {
249
  1, 0x21},
250
  {
251
  1, 0x22},
252
  {
253
  1, 0x23},
254
  {
255
  1, 0x17},
256
  {
257
  1, 0x24},
258
  {
259
  1, 0x25},
260
  {
261
  1, 0x26},
262
  {
263
  1, 0x32},
264
  {
265
  1, 0x31},
266
  {
267
  1, 0x18},
268 805 markom
/* 80 - 95 */
269 1748 jeremybenn
  {
270
  1, 0x19},
271
  {
272
  1, 0x10},
273
  {
274
  1, 0x13},
275
  {
276
  1, 0x1F},
277
  {
278
  1, 0x14},
279
  {
280
  1, 0x16},
281
  {
282
  1, 0x2F},
283
  {
284
  1, 0x11},
285
  {
286
  1, 0x2D},
287
  {
288
  1, 0x15},
289
  {
290
  1, 0x2C},
291
  {
292
  0, 0x1A},
293
  {
294
  0, 0x2B},
295
  {
296
  0, 0x1B},
297
  {
298
  1, 0x07},
299
  {
300
  1, 0x0C},
301 805 markom
/* 96 - 111 */
302 1748 jeremybenn
  {
303
  0, 0x29},
304
  {
305
  0, 0x1E},
306
  {
307
  0, 0x30},
308
  {
309
  0, 0x2E},
310
  {
311
  0, 0x20},
312
  {
313
  0, 0x12},
314
  {
315
  0, 0x21},
316
  {
317
  0, 0x22},
318
  {
319
  0, 0x23},
320
  {
321
  0, 0x17},
322
  {
323
  0, 0x24},
324
  {
325
  0, 0x25},
326
  {
327
  0, 0x26},
328
  {
329
  0, 0x32},
330
  {
331
  0, 0x31},
332
  {
333
  0, 0x18},
334 805 markom
/* 112 - 127 */
335 1748 jeremybenn
  {
336
  0, 0x19},
337
  {
338
  0, 0x10},
339
  {
340
  0, 0x13},
341
  {
342
  0, 0x1F},
343
  {
344
  0, 0x14},
345
  {
346
  0, 0x16},
347
  {
348
  0, 0x2F},
349
  {
350
  0, 0x11},
351
  {
352
  0, 0x2D},
353
  {
354
  0, 0x15},
355
  {
356
  0, 0x2C},
357
  {
358
  1, 0x1A},
359
  {
360
  1, 0x2B},
361
  {
362
  1, 0x1B},
363
  {
364
  1, 0x29},
365
  {
366
  0, 0x00}
367 805 markom
};
368
 
369 1748 jeremybenn
struct kbd_state
370
{
371 1371 nogj
  /* Temporary buffer to store incoming scan codes */
372
  uint8_t buf[KBD_MAX_BUF];
373 805 markom
 
374 1371 nogj
  /* Number of scan codes in buffer */
375
  unsigned long buf_count;
376
  unsigned long buf_head;
377
  unsigned long buf_tail;
378 805 markom
 
379 1371 nogj
  /* Input stream */
380
  FILE *rxfs;
381 805 markom
 
382 1371 nogj
  /* Controller Command (write into 0x64) */
383
  int ccmd;
384 684 lampret
 
385 1371 nogj
  /* Keyboard Command (write into 0x60) */
386
  uint8_t kcmd;
387 684 lampret
 
388 1371 nogj
  /* Controller Command Byte */
389
  uint8_t ccmdbyte;
390 684 lampret
 
391 1371 nogj
  /* Keyboard response pending */
392
  unsigned long kresp;
393 684 lampret
 
394 1371 nogj
  /* Keyboard slowdown factor */
395
  long slowdown;
396 805 markom
 
397 1371 nogj
  /* Cofiguration */
398 1461 nogj
  int enabled;
399 1371 nogj
  int irq;
400
  oraddr_t baseaddr;
401
  char *rxfile;
402
};
403
 
404 1748 jeremybenn
static void
405
kbd_put (struct kbd_state *kbd, unsigned char c)
406 805 markom
{
407 1748 jeremybenn
  if (kbd->buf_count >= KBD_MAX_BUF)
408
    {
409
      fprintf (stderr, "WARNING: Keyboard buffer overflow.\n");
410
    }
411
  else
412
    {
413
      kbd->buf[kbd->buf_head] = c;
414
      kbd->buf_head = (kbd->buf_head + 1) % KBD_MAX_BUF;
415
      kbd->buf_count++;
416
    }
417 805 markom
}
418
 
419
/* Decodes ascii code c into multiple scan codes, placed into buf, length is returned */
420 1748 jeremybenn
static void
421
scan_decode (struct kbd_state *kbd, unsigned char c)
422 805 markom
{
423
  /* Do not handle special characters and extended ascii */
424
  if (c >= 128 || !scan_table[c].code)
425
    return;
426 1748 jeremybenn
 
427 805 markom
  /* Make shift? */
428 1748 jeremybenn
  if (scan_table[c].shift)
429
    kbd_put (kbd, 0x2a);
430 805 markom
  /* Make char */
431 1371 nogj
  kbd_put (kbd, scan_table[c].code);
432 805 markom
  /* Break char */
433 1371 nogj
  kbd_put (kbd, scan_table[c].code | 0x80);
434 805 markom
  /* Break shift? */
435 1748 jeremybenn
  if (scan_table[c].shift)
436
    kbd_put (kbd, 0xaa);
437 805 markom
}
438
 
439
/* Write a register */
440 1748 jeremybenn
static void
441
kbd_write8 (oraddr_t addr, uint8_t value, void *dat)
442 805 markom
{
443 1371 nogj
  struct kbd_state *kbd = dat;
444 1748 jeremybenn
  switch (addr)
445
    {
446 684 lampret
    case KBD_CTRL:
447 1371 nogj
      kbd->ccmd = value & 0xff;
448
      if (kbd->ccmd == KBD_CCMD_RCB)
449 1748 jeremybenn
        kbd->kresp = 0x1;
450 1371 nogj
      if (kbd->ccmd == KBD_CCMD_ST1)
451 1748 jeremybenn
        kbd->kresp = 0x1;
452 1371 nogj
      if (kbd->ccmd == KBD_CCMD_ST2)
453 1748 jeremybenn
        kbd->kresp = 0x1;
454
      if (kbd->ccmd == KBD_CCMD_DKI)
455
        {
456
          clear_interrupt (kbd->irq);
457
          kbd->ccmdbyte |= KBD_CCMDBYTE_EN;
458
        }
459 1371 nogj
      if (kbd->ccmd == KBD_CCMD_EKI)
460 1748 jeremybenn
        kbd->ccmdbyte &= ~KBD_CCMDBYTE_EN;
461 684 lampret
      if (config.sim.verbose)
462 1751 jeremybenn
        PRINTF ("kbd_write8(%" PRIxADDR ") %02x\n", addr, value);
463 805 markom
      break;
464 684 lampret
    case KBD_DATA:
465 1748 jeremybenn
      if (kbd->ccmd == KBD_CCMD_WCB)
466
        {
467
          kbd->ccmdbyte = value & 0xff;
468
          kbd->ccmd = 0x00;
469
        }
470
      else
471
        kbd->kcmd = value & 0xff;
472 1371 nogj
      if (kbd->kcmd == KBD_KCMD_DK)
473 1748 jeremybenn
        kbd->ccmdbyte |= KBD_CCMDBYTE_EN;
474 1371 nogj
      if (kbd->kcmd == KBD_KCMD_EK)
475 1748 jeremybenn
        kbd->ccmdbyte &= ~KBD_CCMDBYTE_EN;
476 1371 nogj
      kbd->kresp = 0x1;
477
      kbd->ccmd = 0x00;
478 684 lampret
      if (config.sim.verbose)
479 1751 jeremybenn
        PRINTF ("kbd_write8(%" PRIxADDR ") %02x\n", addr, value);
480 805 markom
      break;
481
    default:
482 1748 jeremybenn
      fprintf (stderr, "Write out of keyboard space (0x%" PRIxADDR ")!\n",
483
               addr);
484 805 markom
      break;
485 1748 jeremybenn
    }
486 805 markom
}
487
 
488
/* Read a register */
489 1748 jeremybenn
static uint8_t
490
kbd_read8 (oraddr_t addr, void *dat)
491 805 markom
{
492 1371 nogj
  struct kbd_state *kbd = dat;
493 1748 jeremybenn
  switch (addr)
494
    {
495
    case KBD_CTRL:
496
      {
497
        unsigned long c = 0x0;
498
        if (kbd->kresp || kbd->buf_count)
499
          c |= KBD_STATUS_OBF;
500
        c |= kbd->ccmdbyte & KBD_CCMDBYTE_SYS;
501
        c |= KBD_STATUS_INH;
502
        if (config.sim.verbose)
503
          PRINTF ("kbd_read8(%" PRIxADDR ") %lx\n", addr, c);
504
        return c;
505
      }
506 684 lampret
    case KBD_DATA:
507 1748 jeremybenn
      clear_interrupt (kbd->irq);
508
      if (kbd->ccmd)
509
        {
510
          unsigned long rc = 0;
511
          if (kbd->ccmd == KBD_CCMD_RCB)
512
            rc = kbd->ccmdbyte;
513
          if (kbd->ccmd == KBD_CCMD_ST1)
514
            rc = 0x55;
515
          if (kbd->ccmd == KBD_CCMD_ST2)
516
            rc = 0x00;
517
          kbd->ccmd = 0x00;
518
          kbd->kresp = 0x0;
519
          if (config.sim.verbose)
520
            PRINTF ("kbd_read8(%" PRIxADDR ") %lx\n", addr, rc);
521
          return rc;
522
        }
523
      else if (kbd->kresp)
524
        {
525
          unsigned long rc;
526
          if (kbd->kresp == 0x2)
527
            {
528
              kbd->kresp = 0x0;
529
              rc = KBD_KRESP_RSTOK;
530
            }
531
          else if (kbd->kcmd == KBD_KCMD_RST)
532
            {
533
              kbd->kresp = 0x2;
534
              rc = KBD_KRESP_ACK;
535
            }
536
          else if (kbd->kcmd == KBD_KCMD_ECHO)
537
            {
538
              kbd->kresp = 0x0;
539
              rc = KBD_KRESP_ECHO;
540
            }
541
          else
542
            {
543
              kbd->kresp = 0x0;
544
              rc = KBD_KRESP_ACK;
545
            }
546
          kbd->kcmd = 0x00;
547
          if (config.sim.verbose)
548
            PRINTF ("kbd_read8(%" PRIxADDR ") %lx\n", addr, rc);
549
          return rc;
550
        }
551
      else if (kbd->buf_count)
552
        {
553
          unsigned long c = kbd->buf[kbd->buf_tail];
554
          kbd->buf_tail = (kbd->buf_tail + 1) % KBD_MAX_BUF;
555
          kbd->buf_count--;
556
          kbd->kresp = 0x0;
557
          if (config.sim.verbose)
558
            PRINTF ("kbd_read8(%" PRIxADDR ") %lx\n", addr, c);
559
          return c;
560
        }
561 1371 nogj
      kbd->kresp = 0x0;
562 684 lampret
      if (config.sim.verbose)
563 1748 jeremybenn
        PRINTF ("kbd_read8(%" PRIxADDR ") fifo empty\n", addr);
564 805 markom
      return 0;
565
    default:
566 1748 jeremybenn
      fprintf (stderr, "Read out of keyboard space (0x%" PRIxADDR ")!\n",
567
               addr);
568 805 markom
      return 0;
569 1748 jeremybenn
    }
570 805 markom
}
571
 
572
 
573
/* Simulation hook. Must be called every couple of clock cycles to simulate incomming data. */
574 1748 jeremybenn
static void
575
kbd_job (void *dat)
576 805 markom
{
577 1371 nogj
  struct kbd_state *kbd = dat;
578 805 markom
  int c;
579
  int kbd_int = 0;
580 1371 nogj
 
581 805 markom
  /* Check if there is something waiting, and decode it into kdb_buf */
582 1748 jeremybenn
  if ((c = fgetc (kbd->rxfs)) != EOF)
583
    {
584
      scan_decode (kbd, c);
585
    }
586
  kbd_int = kbd->kresp
587
    || kbd->buf_count ? kbd->ccmdbyte & KBD_CCMDBYTE_INT : 0;
588 1567 nogj
/*
589 805 markom
  if (config.sim.verbose && kbd_int)
590 1308 phoenix
    PRINTF("Keyboard Interrupt.... kbd_kresp %lx  kbd_buf_count %lx \n",
591 1371 nogj
           kbd->kresp, kbd->buf_count);
592 1567 nogj
*/
593 1748 jeremybenn
  if (kbd_int)
594
    report_interrupt (kbd->irq);
595
  SCHED_ADD (kbd_job, dat, kbd->slowdown);
596 805 markom
}
597
 
598 1350 nogj
/* Reset all (simulated) ps2 controlers/keyboards */
599 1748 jeremybenn
static void
600
kbd_reset (void *dat)
601 805 markom
{
602 1371 nogj
  struct kbd_state *kbd = dat;
603 1748 jeremybenn
  long int system_kfreq =
604
    (long) ((1000000000.0 / (double) config.sim.clkcycle_ps));
605 1371 nogj
 
606 1748 jeremybenn
  system_kfreq = (system_kfreq < 1) ? 1 : system_kfreq;
607
 
608 1371 nogj
  kbd->buf_count = 0;
609
  kbd->buf_head = 0;
610
  kbd->buf_tail = 0;
611
  kbd->kresp = 0x0;
612 1748 jeremybenn
  kbd->ccmdbyte = 0x65;         /* We reset into default normal operation. */
613
 
614
  if (!(kbd->rxfs = fopen (kbd->rxfile, "r"))
615
      && !(kbd->rxfs = fopen (kbd->rxfile, "r+")))
616
    {
617
      fprintf (stderr, "WARNING: Unable to open RX file stream.\n");
618
      return;
619
    }
620
  kbd->slowdown = (long) ((system_kfreq * 1000.0) / KBD_BAUD_RATE);
621
  if (kbd->slowdown <= 0)
622
    kbd->slowdown = 1;
623
  SCHED_ADD (kbd_job, dat, kbd->slowdown);
624 805 markom
}
625 684 lampret
 
626 805 markom
 
627 1748 jeremybenn
static void
628
kbd_info (void *dat)
629 684 lampret
{
630 1371 nogj
  struct kbd_state *kbd = dat;
631 1748 jeremybenn
  PRINTF ("kbd_kcmd: %x\n", kbd->kcmd);
632
  PRINTF ("kbd_ccmd: %x\n", kbd->ccmd);
633
  PRINTF ("kbd_ccmdbyte: %x\n", kbd->ccmdbyte);
634
  PRINTF ("kbd_kresp: %lx\n", kbd->kresp);
635
  PRINTF ("kbd_buf_count: %lx\n", kbd->buf_count);
636 684 lampret
}
637 1358 nogj
 
638
/*----------------------------------------------------[ KBD Configuration ]---*/
639 1748 jeremybenn
 
640
 
641
static void
642
kbd_enabled (union param_val val, void *dat)
643 1358 nogj
{
644 1371 nogj
  struct kbd_state *kbd = dat;
645 1748 jeremybenn
  kbd->enabled = val.int_val;
646 1358 nogj
}
647
 
648 1748 jeremybenn
 
649
static void
650
kbd_baseaddr (union param_val val, void *dat)
651 1358 nogj
{
652 1371 nogj
  struct kbd_state *kbd = dat;
653 1748 jeremybenn
  kbd->baseaddr = val.addr_val;
654 1358 nogj
}
655
 
656 1748 jeremybenn
 
657
static void
658
kbd_irq (union param_val val, void *dat)
659 1358 nogj
{
660 1371 nogj
  struct kbd_state *kbd = dat;
661 1748 jeremybenn
  kbd->irq = val.int_val;
662 1358 nogj
}
663
 
664 1748 jeremybenn
 
665
/*---------------------------------------------------------------------------*/
666
/*!Set the keyboard input file
667
 
668
   Free any previously allocated value.
669
 
670
   @param[in] val  The value to use
671
   @param[in] dat  The config data structure                                 */
672
/*---------------------------------------------------------------------------*/
673
static void
674
kbd_rxfile (union param_val val, void *dat)
675 1461 nogj
{
676
  struct kbd_state *kbd = dat;
677
 
678 1748 jeremybenn
  if (NULL != kbd->rxfile)
679
    {
680
      free (kbd->rxfile);
681
      kbd->rxfile = NULL;
682
    }
683
 
684
  if (!(kbd->rxfile = strdup (val.str_val)))
685
    {
686
      fprintf (stderr, "Peripheral KBD: Run out of memory\n");
687
      exit (-1);
688
    }
689
}                               /* kbd_rxfile() */
690
 
691
 
692
/*---------------------------------------------------------------------------*/
693
/*!Initialize a new keyboard configuration
694
 
695
   ALL parameters are set explicitly to default values.                      */
696
/*---------------------------------------------------------------------------*/
697
static void *
698
kbd_sec_start ()
699 1371 nogj
{
700 1748 jeremybenn
  struct kbd_state *new = malloc (sizeof (struct kbd_state));
701 1371 nogj
 
702 1748 jeremybenn
  if (!new)
703
    {
704
      fprintf (stderr, "Peripheral KBD: Run out of memory\n");
705
      exit (-1);
706
    }
707 1371 nogj
 
708 1748 jeremybenn
  new->enabled = 1;
709
  new->baseaddr = 0;
710
  new->irq = 0;
711
  new->rxfile = strdup ("kbd_in");
712
 
713 1371 nogj
  new->buf_count = 0;
714
  new->buf_head = 0;
715
  new->buf_tail = 0;
716
  new->rxfs = NULL;
717
 
718
  return new;
719
 
720 1748 jeremybenn
}                               /* kbd_sec_start() */
721
 
722
 
723
static void
724
kbd_sec_end (void *dat)
725 1371 nogj
{
726
  struct kbd_state *kbd = dat;
727 1486 nogj
  struct mem_ops ops;
728 1371 nogj
 
729 1748 jeremybenn
  if (!kbd->enabled)
730
    {
731
      free (kbd->rxfile);
732
      free (kbd);
733
      return;
734
    }
735 1461 nogj
 
736 1748 jeremybenn
  memset (&ops, 0, sizeof (struct mem_ops));
737 1486 nogj
 
738
  ops.readfunc8 = kbd_read8;
739
  ops.writefunc8 = kbd_write8;
740
  ops.read_dat8 = dat;
741
  ops.write_dat8 = dat;
742
 
743
  /* FIXME: Correct delay? */
744
  ops.delayr = 2;
745
  ops.delayw = 2;
746
 
747 1748 jeremybenn
  reg_mem_area (kbd->baseaddr, KBD_SPACE, 0, &ops);
748
  reg_sim_reset (kbd_reset, dat);
749
  reg_sim_stat (kbd_info, dat);
750 1371 nogj
}
751
 
752 1748 jeremybenn
void
753
reg_kbd_sec ()
754 1358 nogj
{
755 1748 jeremybenn
  struct config_section *sec =
756
    reg_config_sec ("kbd", kbd_sec_start, kbd_sec_end);
757 1358 nogj
 
758 1748 jeremybenn
  reg_config_param (sec, "baseaddr", paramt_addr, kbd_baseaddr);
759
  reg_config_param (sec, "enabled", paramt_int, kbd_enabled);
760
  reg_config_param (sec, "irq", paramt_int, kbd_irq);
761
  reg_config_param (sec, "rxfile", paramt_str, kbd_rxfile);
762 1358 nogj
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.