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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [mn10300/] [dv-mn103iop.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*  This file is part of the program GDB, the GNU debugger.
2
 
3
    Copyright (C) 1998 Free Software Foundation, Inc.
4
    Contributed by Cygnus Solutions.
5
 
6
    This program is free software; you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation; either version 2 of the License, or
9
    (at your option) any later version.
10
 
11
    This program is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with this program; if not, write to the Free Software
18
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
 
20
    */
21
 
22
#include "sim-main.h"
23
#include "hw-main.h"
24
 
25
/* DEVICE
26
 
27
 
28
   mn103iop - mn103002 I/O ports 0-3.
29
 
30
 
31
   DESCRIPTION
32
 
33
   Implements the mn103002 i/o ports as described in the mn103002 user guide.
34
 
35
 
36
   PROPERTIES
37
 
38
   reg = <ioport-addr> <ioport-size> ...
39
 
40
 
41
   BUGS
42
 
43
   */
44
 
45
 
46
/* The I/O ports' registers' address block */
47
 
48
struct mn103iop_block {
49
  unsigned_word base;
50
  unsigned_word bound;
51
};
52
 
53
 
54
 
55
enum io_port_register_types {
56
  P0OUT,
57
  P1OUT,
58
  P2OUT,
59
  P3OUT,
60
  P0MD,
61
  P1MD,
62
  P2MD,
63
  P3MD,
64
  P2SS,
65
  P4SS,
66
  P0DIR,
67
  P1DIR,
68
  P2DIR,
69
  P3DIR,
70
  P0IN,
71
  P1IN,
72
  P2IN,
73
  P3IN,
74
};
75
 
76
#define NR_PORTS  4
77
 
78
enum {
79
  OUTPUT_BLOCK,
80
  MODE_BLOCK,
81
  DED_CTRL_BLOCK,
82
  CTRL_BLOCK,
83
  PIN_BLOCK,
84
  NR_BLOCKS
85
};
86
 
87
typedef struct _mn10300_ioport {
88
  unsigned8 output, output_mode, control, pin;
89
  struct hw_event *event;
90
} mn10300_ioport;
91
 
92
 
93
 
94
struct mn103iop {
95
  struct mn103iop_block block[NR_BLOCKS];
96
  mn10300_ioport port[NR_PORTS];
97
  unsigned8      p2ss, p4ss;
98
};
99
 
100
 
101
/* Finish off the partially created hw device.  Attach our local
102
   callbacks.  Wire up our port names etc */
103
 
104
static hw_io_read_buffer_method mn103iop_io_read_buffer;
105
static hw_io_write_buffer_method mn103iop_io_write_buffer;
106
 
107
static void
108
attach_mn103iop_regs (struct hw *me,
109
                      struct mn103iop *io_port)
110
{
111
  int i;
112
  unsigned_word attach_address;
113
  int attach_space;
114
  unsigned attach_size;
115
  reg_property_spec reg;
116
 
117
  if (hw_find_property (me, "reg") == NULL)
118
    hw_abort (me, "Missing \"reg\" property");
119
 
120
  for (i=0; i < NR_BLOCKS; ++i )
121
    {
122
      if (!hw_find_reg_array_property (me, "reg", i, &reg))
123
        hw_abort (me, "\"reg\" property must contain five addr/size entries");
124
      hw_unit_address_to_attach_address (hw_parent (me),
125
                                         &reg.address,
126
                                         &attach_space,
127
                                         &attach_address,
128
                                         me);
129
      io_port->block[i].base = attach_address;
130
      hw_unit_size_to_attach_size (hw_parent (me),
131
                                   &reg.size,
132
                                   &attach_size, me);
133
      io_port->block[i].bound = attach_address + (attach_size - 1);
134
      hw_attach_address (hw_parent (me),
135
                         0,
136
                         attach_space, attach_address, attach_size,
137
                         me);
138
    }
139
}
140
 
141
static void
142
mn103iop_finish (struct hw *me)
143
{
144
  struct mn103iop *io_port;
145
  int i;
146
 
147
  io_port = HW_ZALLOC (me, struct mn103iop);
148
  set_hw_data (me, io_port);
149
  set_hw_io_read_buffer (me, mn103iop_io_read_buffer);
150
  set_hw_io_write_buffer (me, mn103iop_io_write_buffer);
151
 
152
  /* Attach ourself to our parent bus */
153
  attach_mn103iop_regs (me, io_port);
154
 
155
  /* Initialize the i/o port registers. */
156
  for ( i=0; i<NR_PORTS; ++i )
157
    {
158
      io_port->port[i].output = 0;
159
      io_port->port[i].output_mode = 0;
160
      io_port->port[i].control = 0;
161
      io_port->port[i].pin = 0;
162
    }
163
  io_port->port[2].output_mode = 0xff;
164
  io_port->p2ss = 0;
165
  io_port->p4ss = 0x0f;
166
}
167
 
168
 
169
/* read and write */
170
 
171
static int
172
decode_addr (struct hw *me,
173
             struct mn103iop *io_port,
174
             unsigned_word address)
175
{
176
  unsigned_word offset;
177
  offset = address - io_port->block[0].base;
178
  switch (offset)
179
    {
180
    case 0x00: return P0OUT;
181
    case 0x01: return P1OUT;
182
    case 0x04: return P2OUT;
183
    case 0x05: return P3OUT;
184
    case 0x20: return P0MD;
185
    case 0x21: return P1MD;
186
    case 0x24: return P2MD;
187
    case 0x25: return P3MD;
188
    case 0x44: return P2SS;
189
    case 0x48: return P4SS;
190
    case 0x60: return P0DIR;
191
    case 0x61: return P1DIR;
192
    case 0x64: return P2DIR;
193
    case 0x65: return P3DIR;
194
    case 0x80: return P0IN;
195
    case 0x81: return P1IN;
196
    case 0x84: return P2IN;
197
    case 0x85: return P3IN;
198
    default:
199
      {
200
        hw_abort (me, "bad address");
201
        return -1;
202
      }
203
    }
204
}
205
 
206
 
207
static void
208
read_output_reg (struct hw *me,
209
                 struct mn103iop *io_port,
210
                 unsigned_word io_port_reg,
211
                 const void *dest,
212
                 unsigned  nr_bytes)
213
{
214
  if ( nr_bytes == 1 )
215
    {
216
      *(unsigned8 *)dest = io_port->port[io_port_reg].output;
217
    }
218
  else
219
    {
220
      hw_abort (me, "bad read size of %d bytes from P%dOUT.", nr_bytes,
221
                io_port_reg);
222
    }
223
}
224
 
225
 
226
static void
227
read_output_mode_reg (struct hw *me,
228
                      struct mn103iop *io_port,
229
                      unsigned_word io_port_reg,
230
                      const void *dest,
231
                      unsigned  nr_bytes)
232
{
233
  if ( nr_bytes == 1 )
234
    {
235
      /* check if there are fields which can't be written and
236
         take appropriate action depending what bits are set */
237
      *(unsigned8 *)dest = io_port->port[io_port_reg].output_mode;
238
    }
239
  else
240
    {
241
      hw_abort (me, "bad read size of %d bytes to P%dMD.", nr_bytes,
242
                io_port_reg);
243
    }
244
}
245
 
246
 
247
static void
248
read_control_reg (struct hw *me,
249
                  struct mn103iop *io_port,
250
                  unsigned_word io_port_reg,
251
                  const void *dest,
252
                  unsigned  nr_bytes)
253
{
254
  if ( nr_bytes == 1 )
255
    {
256
      *(unsigned8 *)dest = io_port->port[io_port_reg].control;
257
    }
258
  else
259
    {
260
      hw_abort (me, "bad read size of %d bytes to P%dDIR.", nr_bytes,
261
                io_port_reg);
262
    }
263
}
264
 
265
 
266
static void
267
read_pin_reg (struct hw *me,
268
              struct mn103iop *io_port,
269
              unsigned_word io_port_reg,
270
              const void *dest,
271
              unsigned  nr_bytes)
272
{
273
  if ( nr_bytes == 1 )
274
    {
275
      *(unsigned8 *)dest = io_port->port[io_port_reg].pin;
276
    }
277
  else
278
    {
279
      hw_abort (me, "bad read size of %d bytes to P%dIN.", nr_bytes,
280
                io_port_reg);
281
    }
282
}
283
 
284
 
285
static void
286
read_dedicated_control_reg (struct hw *me,
287
                            struct mn103iop *io_port,
288
                            unsigned_word io_port_reg,
289
                            const void *dest,
290
                            unsigned  nr_bytes)
291
{
292
  if ( nr_bytes == 1 )
293
    {
294
      /* select on io_port_reg: */
295
      if ( io_port_reg == P2SS )
296
        {
297
          *(unsigned8 *)dest = io_port->p2ss;
298
        }
299
      else
300
        {
301
          *(unsigned8 *)dest = io_port->p4ss;
302
        }
303
    }
304
  else
305
    {
306
      hw_abort (me, "bad read size of %d bytes to PSS.", nr_bytes);
307
    }
308
}
309
 
310
 
311
static unsigned
312
mn103iop_io_read_buffer (struct hw *me,
313
                         void *dest,
314
                         int space,
315
                         unsigned_word base,
316
                         unsigned nr_bytes)
317
{
318
  struct mn103iop *io_port = hw_data (me);
319
  enum io_port_register_types io_port_reg;
320
  HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
321
 
322
  io_port_reg = decode_addr (me, io_port, base);
323
  switch (io_port_reg)
324
    {
325
    /* Port output registers */
326
    case P0OUT:
327
    case P1OUT:
328
    case P2OUT:
329
    case P3OUT:
330
      read_output_reg(me, io_port, io_port_reg-P0OUT, dest, nr_bytes);
331
      break;
332
 
333
    /* Port output mode registers */
334
    case P0MD:
335
    case P1MD:
336
    case P2MD:
337
    case P3MD:
338
      read_output_mode_reg(me, io_port, io_port_reg-P0MD, dest, nr_bytes);
339
      break;
340
 
341
    /* Port control registers */
342
    case P0DIR:
343
    case P1DIR:
344
    case P2DIR:
345
    case P3DIR:
346
      read_control_reg(me, io_port, io_port_reg-P0DIR, dest, nr_bytes);
347
      break;
348
 
349
    /* Port pin registers */
350
    case P0IN:
351
    case P1IN:
352
    case P2IN:
353
      read_pin_reg(me, io_port, io_port_reg-P0IN, dest, nr_bytes);
354
      break;
355
 
356
    case P2SS:
357
    case P4SS:
358
      read_dedicated_control_reg(me, io_port, io_port_reg, dest, nr_bytes);
359
      break;
360
 
361
    default:
362
      hw_abort(me, "invalid address");
363
    }
364
 
365
  return nr_bytes;
366
}
367
 
368
 
369
static void
370
write_output_reg (struct hw *me,
371
                  struct mn103iop *io_port,
372
                  unsigned_word io_port_reg,
373
                  const void *source,
374
                  unsigned  nr_bytes)
375
{
376
  unsigned8 buf = *(unsigned8 *)source;
377
  if ( nr_bytes == 1 )
378
    {
379
      if ( io_port_reg == 3 && (buf & 0xfc) != 0 )
380
        {
381
          hw_abort(me, "Cannot write to read-only bits of P3OUT.");
382
        }
383
      else
384
        {
385
          io_port->port[io_port_reg].output = buf;
386
        }
387
    }
388
  else
389
    {
390
      hw_abort (me, "bad read size of %d bytes from P%dOUT.", nr_bytes,
391
                io_port_reg);
392
    }
393
}
394
 
395
 
396
static void
397
write_output_mode_reg (struct hw *me,
398
                       struct mn103iop *io_port,
399
                       unsigned_word io_port_reg,
400
                       const void *source,
401
                       unsigned  nr_bytes)
402
{
403
  unsigned8 buf = *(unsigned8 *)source;
404
  if ( nr_bytes == 1 )
405
    {
406
      /* check if there are fields which can't be written and
407
         take appropriate action depending what bits are set */
408
      if ( ( io_port_reg == 3 && (buf & 0xfc) != 0 )
409
           || ( (io_port_reg == 0 || io_port_reg == 1)  && (buf & 0xfe) != 0 ) )
410
        {
411
          hw_abort(me, "Cannot write to read-only bits of output mode register.");
412
        }
413
      else
414
        {
415
          io_port->port[io_port_reg].output_mode = buf;
416
        }
417
    }
418
  else
419
    {
420
      hw_abort (me, "bad write size of %d bytes to P%dMD.", nr_bytes,
421
                io_port_reg);
422
    }
423
}
424
 
425
 
426
static void
427
write_control_reg (struct hw *me,
428
                   struct mn103iop *io_port,
429
                   unsigned_word io_port_reg,
430
                   const void *source,
431
                   unsigned  nr_bytes)
432
{
433
  unsigned8 buf = *(unsigned8 *)source;
434
  if ( nr_bytes == 1 )
435
    {
436
      if ( io_port_reg == 3 && (buf & 0xfc) != 0 )
437
        {
438
          hw_abort(me, "Cannot write to read-only bits of P3DIR.");
439
        }
440
      else
441
        {
442
          io_port->port[io_port_reg].control = buf;
443
        }
444
    }
445
  else
446
    {
447
      hw_abort (me, "bad write size of %d bytes to P%dDIR.", nr_bytes,
448
                io_port_reg);
449
    }
450
}
451
 
452
 
453
static void
454
write_dedicated_control_reg (struct hw *me,
455
                             struct mn103iop *io_port,
456
                             unsigned_word io_port_reg,
457
                             const void *source,
458
                             unsigned  nr_bytes)
459
{
460
  unsigned8 buf = *(unsigned8 *)source;
461
  if ( nr_bytes == 1 )
462
    {
463
      /* select on io_port_reg: */
464
      if ( io_port_reg == P2SS )
465
        {
466
          if ( (buf && 0xfc)  != 0 )
467
            {
468
              hw_abort(me, "Cannot write to read-only bits in p2ss.");
469
            }
470
          else
471
            {
472
              io_port->p2ss = buf;
473
            }
474
        }
475
      else
476
        {
477
          if ( (buf && 0xf0) != 0 )
478
            {
479
              hw_abort(me, "Cannot write to read-only bits in p4ss.");
480
            }
481
          else
482
            {
483
              io_port->p4ss = buf;
484
            }
485
        }
486
    }
487
  else
488
    {
489
      hw_abort (me, "bad write size of %d bytes to PSS.", nr_bytes);
490
    }
491
}
492
 
493
 
494
static unsigned
495
mn103iop_io_write_buffer (struct hw *me,
496
                          const void *source,
497
                          int space,
498
                          unsigned_word base,
499
                          unsigned nr_bytes)
500
{
501
  struct mn103iop *io_port = hw_data (me);
502
  enum io_port_register_types io_port_reg;
503
  HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
504
 
505
  io_port_reg = decode_addr (me, io_port, base);
506
  switch (io_port_reg)
507
    {
508
    /* Port output registers */
509
    case P0OUT:
510
    case P1OUT:
511
    case P2OUT:
512
    case P3OUT:
513
      write_output_reg(me, io_port, io_port_reg-P0OUT, source, nr_bytes);
514
      break;
515
 
516
    /* Port output mode registers */
517
    case P0MD:
518
    case P1MD:
519
    case P2MD:
520
    case P3MD:
521
      write_output_mode_reg(me, io_port, io_port_reg-P0MD, source, nr_bytes);
522
      break;
523
 
524
    /* Port control registers */
525
    case P0DIR:
526
    case P1DIR:
527
    case P2DIR:
528
    case P3DIR:
529
      write_control_reg(me, io_port, io_port_reg-P0DIR, source, nr_bytes);
530
      break;
531
 
532
    /* Port pin registers */
533
    case P0IN:
534
    case P1IN:
535
    case P2IN:
536
      hw_abort(me, "Cannot write to pin register.");
537
      break;
538
 
539
    case P2SS:
540
    case P4SS:
541
      write_dedicated_control_reg(me, io_port, io_port_reg, source, nr_bytes);
542
      break;
543
 
544
    default:
545
      hw_abort(me, "invalid address");
546
    }
547
 
548
  return nr_bytes;
549
}
550
 
551
 
552
const struct hw_descriptor dv_mn103iop_descriptor[] = {
553
  { "mn103iop", mn103iop_finish, },
554
  { NULL },
555
};

powered by: WebSVN 2.1.0

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