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

Subversion Repositories or1k

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

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1748 jeremybenn
/* atahost.c -- ATA Host code simulation
2 876 rherveille
 
3 1748 jeremybenn
   Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
4
   Copyright (C) 2008 Embecosm Limited
5 876 rherveille
 
6 1748 jeremybenn
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
7 876 rherveille
 
8 1748 jeremybenn
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
9 876 rherveille
 
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 876 rherveille
 
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 1364 nogj
 
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
 
23
/* 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 1350 nogj
 
34 1748 jeremybenn
/* Package includes */
35
#include "atahost.h"
36
#include "sim-config.h"
37
#include "debug.h"
38 876 rherveille
#include "abstract.h"
39 1726 nogj
#include "pic.h"
40 1748 jeremybenn
#include "toplevel-support.h"
41
#include "sim-cmd.h"
42 876 rherveille
 
43
 
44 1702 nogj
/* default timing reset values */
45
#define PIO_MODE0_T1 6
46
#define PIO_MODE0_T2 28
47
#define PIO_MODE0_T4 2
48
#define PIO_MODE0_TEOC 23
49
 
50
#define DMA_MODE0_TM 4
51
#define DMA_MODE0_TD 21
52
#define DMA_MODE0_TEOC 21
53
 
54 1748 jeremybenn
DEFAULT_DEBUG_CHANNEL (ata);
55 1713 nogj
 
56 876 rherveille
/* reset and initialize ATA host core(s) */
57 1748 jeremybenn
static void
58
ata_reset (void *dat)
59 876 rherveille
{
60 1748 jeremybenn
  struct ata_host *ata = dat;
61 876 rherveille
 
62 1748 jeremybenn
  // reset the core registers
63
  ata->regs.ctrl = 0x0001;
64
  ata->regs.stat = (ata->dev_id << 28) | (ata->rev << 24);
65
  ata->regs.pctr = (ata->pio_mode0_teoc << ATA_TEOC) |
66
    (ata->pio_mode0_t4 << ATA_T4) |
67
    (ata->pio_mode0_t2 << ATA_T2) | (ata->pio_mode0_t1 << ATA_T1);
68
  ata->regs.pftr0 = ata->regs.pctr;
69
  ata->regs.pftr1 = ata->regs.pctr;
70
  ata->regs.dtr0 = (ata->dma_mode0_teoc << ATA_TEOC) |
71
    (ata->dma_mode0_td << ATA_TD) | (ata->dma_mode0_tm << ATA_TM);
72
  ata->regs.dtr1 = ata->regs.dtr0;
73
  ata->regs.txb = 0;
74 876 rherveille
 
75 1748 jeremybenn
  // inform simulator about new read/write delay timings
76
  adjust_rw_delay (ata->mem, ata_pio_delay (ata->regs.pctr),
77
                   ata_pio_delay (ata->regs.pctr));
78
 
79
  /* the reset bit in the control register 'ctrl' is set, reset connect ata-devices */
80
  ata_devices_hw_reset (&ata->devices, 1);
81 876 rherveille
}
82 1748 jeremybenn
 
83 876 rherveille
/* ========================================================================= */
84
 
85
 
86 1726 nogj
/* Assert interrupt */
87 1748 jeremybenn
void
88
ata_int (void *dat)
89 1726 nogj
{
90 1748 jeremybenn
  struct ata_host *ata = dat;
91
  if (!(ata->regs.stat & ATA_IDEIS))
92
    {
93
      ata->regs.stat |= ATA_IDEIS;
94
      report_interrupt (ata->irq);
95
    }
96 1726 nogj
}
97 1748 jeremybenn
 
98 1726 nogj
/* ========================================================================= */
99
 
100
 
101 876 rherveille
/*
102
  Read a register
103
*/
104 1748 jeremybenn
static uint32_t
105
ata_read32 (oraddr_t addr, void *dat)
106 876 rherveille
{
107 1748 jeremybenn
  struct ata_host *ata = dat;
108 876 rherveille
 
109 1748 jeremybenn
  /* determine if ata_host or ata_device addressed */
110
  if (is_ata_hostadr (addr))
111 919 rherveille
    {
112 1748 jeremybenn
      // Accesses to internal register take 2cycles
113
      adjust_rw_delay (ata->mem, 2, 2);
114 919 rherveille
 
115 1748 jeremybenn
      switch (addr)
116
        {
117
        case ATA_CTRL:
118
          TRACE ("Read control register: %" PRIx32 "\n", ata->regs.ctrl);
119
          return ata->regs.ctrl;
120 876 rherveille
 
121 1748 jeremybenn
        case ATA_STAT:
122
          return ata->regs.stat;
123 876 rherveille
 
124 1748 jeremybenn
        case ATA_PCTR:
125
          return ata->regs.pctr;
126 876 rherveille
 
127 1748 jeremybenn
        case ATA_PFTR0:
128
          return ata->dev_id > 1 ? ata->regs.pftr0 : 0;
129 876 rherveille
 
130 1748 jeremybenn
        case ATA_PFTR1:
131
          return ata->dev_id > 1 ? ata->regs.pftr1 : 0;
132 876 rherveille
 
133 1748 jeremybenn
        case ATA_DTR0:
134
          return ata->dev_id > 2 ? ata->regs.dtr0 : 0;
135 876 rherveille
 
136 1748 jeremybenn
        case ATA_DTR1:
137
          return ata->dev_id > 2 ? ata->regs.dtr1 : 0;
138 876 rherveille
 
139 1748 jeremybenn
        case ATA_RXB:
140
          return ata->dev_id > 2 ? ata->regs.rxb : 0;
141 876 rherveille
 
142 1748 jeremybenn
        default:
143
          return 0;
144
        }
145 876 rherveille
    }
146 1701 nogj
 
147 1748 jeremybenn
  /* check if the controller is enabled */
148
  if (ata->regs.ctrl & ATA_IDE_EN)
149
    {
150
      // make sure simulator uses correct read/write delay timings
151
      if (((addr & 0x7f) == ATA_DR) && ata->dev_id > 1)
152
        {
153
          if (ata->dev_sel)
154
            adjust_rw_delay (ata->mem, ata_pio_delay (ata->regs.pftr1),
155
                             ata_pio_delay (ata->regs.pftr1));
156 919 rherveille
          else
157 1748 jeremybenn
            adjust_rw_delay (ata->mem, ata_pio_delay (ata->regs.pftr0),
158
                             ata_pio_delay (ata->regs.pftr0));
159 919 rherveille
        }
160 1748 jeremybenn
      else
161
        adjust_rw_delay (ata->mem, ata_pio_delay (ata->regs.pctr),
162
                         ata_pio_delay (ata->regs.pctr));
163 919 rherveille
 
164 1748 jeremybenn
      return ata_devices_read (&ata->devices, addr & 0x7f);
165 919 rherveille
    }
166 1748 jeremybenn
  return 0;
167 876 rherveille
}
168 1748 jeremybenn
 
169 876 rherveille
/* ========================================================================= */
170
 
171
 
172
/*
173
  Write a register
174
*/
175 1748 jeremybenn
static void
176
ata_write32 (oraddr_t addr, uint32_t value, void *dat)
177 876 rherveille
{
178 1748 jeremybenn
  struct ata_host *ata = dat;
179 876 rherveille
 
180 1748 jeremybenn
  /* determine if ata_host or ata_device addressed */
181
  if (is_ata_hostadr (addr))
182 919 rherveille
    {
183 1748 jeremybenn
      // Accesses to internal register take 2cycles
184
      adjust_rw_delay (ata->mem, 2, 2);
185 919 rherveille
 
186 1748 jeremybenn
      switch (addr)
187
        {
188
        case ATA_CTRL:
189
          TRACE ("Writting control register: %" PRIx32 "\n", value);
190
          ata->regs.ctrl = value;
191 876 rherveille
 
192 1748 jeremybenn
          /* check if reset bit set, if so reset ata-devices    */
193
          if (value & ATA_RST)
194
            ata_devices_hw_reset (&ata->devices, 1);
195
          else
196
            ata_devices_hw_reset (&ata->devices, 0);
197
          break;
198 876 rherveille
 
199 1748 jeremybenn
        case ATA_STAT:
200
          if (!(value & ATA_IDEIS) && (ata->regs.stat & ATA_IDEIS))
201
            {
202
              clear_interrupt (ata->irq);
203
              ata->regs.stat &= ~ATA_IDEIS;
204
            }
205
          break;
206 876 rherveille
 
207 1748 jeremybenn
        case ATA_PCTR:
208
          TRACE ("PCTR: Toec = %d, t4 = %d, t2 = %d, t1 = %d\n",
209
                 value >> 24, (value >> 16) & 0xff, (value >> 8) & 0xff,
210
                 value & 0xff);
211
          ata->regs.pctr = value;
212
          break;
213 876 rherveille
 
214 1748 jeremybenn
        case ATA_PFTR0:
215
          TRACE ("PFTR0: Toec = %d, t4 = %d, t2 = %d, t1 = %d\n",
216
                 value >> 24, (value >> 16) & 0xff, (value >> 8) & 0xff,
217
                 value & 0xff);
218
          ata->regs.pftr0 = value;
219
          break;
220 876 rherveille
 
221 1748 jeremybenn
        case ATA_PFTR1:
222
          TRACE ("PFTR1: Toec = %d, t4 = %d, t2 = %d, t1 = %d\n",
223
                 value >> 24, (value >> 16) & 0xff, (value >> 8) & 0xff,
224
                 value & 0xff);
225
          ata->regs.pftr1 = value;
226
          break;
227 876 rherveille
 
228 1748 jeremybenn
        case ATA_DTR0:
229
          ata->regs.dtr0 = value;
230
          break;
231 876 rherveille
 
232 1748 jeremybenn
        case ATA_DTR1:
233
          ata->regs.dtr1 = value;
234
          break;
235 876 rherveille
 
236 1748 jeremybenn
        case ATA_TXB:
237
          ata->regs.txb = value;
238
          break;
239 876 rherveille
 
240 1748 jeremybenn
        default:
241
          /* ERROR-macro currently only supports simple strings. */
242
          /*
243
             fprintf(stderr, "ERROR  : Unknown register for OCIDEC(%1d).\n", DEV_ID );
244 876 rherveille
 
245 1748 jeremybenn
             Tried to show some useful info here.
246
             But when using 'DM'-simulator-command, the screen gets filled with these messages.
247
             Thereby eradicating the usefulness of the message
248
           */
249
          break;
250
        }
251
      return;
252 919 rherveille
    }
253 1701 nogj
 
254 1748 jeremybenn
  /* check if the controller is enabled */
255
  if (ata->regs.ctrl & ATA_IDE_EN)
256
    {
257
      // make sure simulator uses correct read/write delay timings
258
      if (((addr & 0x7f) == ATA_DR) && (ata->dev_id > 1))
259
        {
260
          if (ata->dev_sel)
261
            adjust_rw_delay (ata->mem, ata_pio_delay (ata->regs.pftr1),
262
                             ata_pio_delay (ata->regs.pftr1));
263 919 rherveille
          else
264 1748 jeremybenn
            adjust_rw_delay (ata->mem, ata_pio_delay (ata->regs.pftr0),
265
                             ata_pio_delay (ata->regs.pftr0));
266
        }
267
      else
268
        adjust_rw_delay (ata->mem, ata_pio_delay (ata->regs.pctr),
269
                         ata_pio_delay (ata->regs.pctr));
270 919 rherveille
 
271 1748 jeremybenn
      if ((addr & 0x7f) == ATA_DHR)
272
        ata->dev_sel = value & ATA_DHR_DEV;
273 1701 nogj
 
274 1748 jeremybenn
      ata_devices_write (&ata->devices, addr & 0x7f, value);
275 919 rherveille
    }
276 876 rherveille
}
277 1748 jeremybenn
 
278 876 rherveille
/* ========================================================================= */
279
 
280
 
281
/* Dump status */
282 1748 jeremybenn
static void
283
ata_status (void *dat)
284 876 rherveille
{
285 1748 jeremybenn
  struct ata_host *ata = dat;
286 876 rherveille
 
287 1748 jeremybenn
  if (ata->baseaddr == 0)
288 1364 nogj
    return;
289 876 rherveille
 
290 1748 jeremybenn
  PRINTF ("\nOCIDEC-%1d at: 0x%" PRIxADDR "\n", ata->dev_id, ata->baseaddr);
291
  PRINTF ("ATA CTRL     : 0x%08X\n", ata->regs.ctrl);
292
  PRINTF ("ATA STAT     : 0x%08x\n", ata->regs.stat);
293
  PRINTF ("ATA PCTR     : 0x%08x\n", ata->regs.pctr);
294 876 rherveille
 
295 1748 jeremybenn
  if (ata->dev_id > 1)
296
    {
297
      PRINTF ("ATA FCTR0    : 0x%08x\n", ata->regs.pftr0);
298
      PRINTF ("ATA FCTR1    : 0x%08x\n", ata->regs.pftr1);
299
    }
300 876 rherveille
 
301 1748 jeremybenn
  if (ata->dev_id > 2)
302
    {
303
      PRINTF ("ATA DTR0     : 0x%08x\n", ata->regs.dtr0);
304
      PRINTF ("ATA DTR1     : 0x%08x\n", ata->regs.dtr1);
305
      PRINTF ("ATA TXD      : 0x%08x\n", ata->regs.txb);
306
      PRINTF ("ATA RXD      : 0x%08x\n", ata->regs.rxb);
307
    }
308 876 rherveille
}
309 1748 jeremybenn
 
310 876 rherveille
/* ========================================================================= */
311 1358 nogj
 
312
/*----------------------------------------------------[ ATA Configuration ]---*/
313 1703 nogj
static unsigned int conf_dev;
314
 
315 1748 jeremybenn
static void
316
ata_baseaddr (union param_val val, void *dat)
317 1358 nogj
{
318 1748 jeremybenn
  struct ata_host *ata = dat;
319 1364 nogj
  ata->baseaddr = val.addr_val;
320 1358 nogj
}
321
 
322 1748 jeremybenn
static void
323
ata_irq (union param_val val, void *dat)
324 1358 nogj
{
325 1748 jeremybenn
  struct ata_host *ata = dat;
326 1364 nogj
  ata->irq = val.int_val;
327 1358 nogj
}
328
 
329 1748 jeremybenn
static void
330
ata_dev_id (union param_val val, void *dat)
331 1701 nogj
{
332 1748 jeremybenn
  struct ata_host *ata = dat;
333
  if (val.int_val < 1 || val.int_val > 3)
334
    {
335
      fprintf (stderr, "Peripheral ATA: Unknown device id %d, useing 1\n",
336
               val.int_val);
337
      ata->dev_id = 1;
338
      return;
339
    }
340
 
341 1701 nogj
  ata->dev_id = val.int_val;
342
}
343
 
344 1748 jeremybenn
 
345
/*---------------------------------------------------------------------------*/
346
/*!Set the ATA revision
347
 
348
   This must be in the range 0-15, to fit in the relevant field. Anything
349
   larger is truncated with a warning.
350
 
351
   @param[in] val  The value to use
352
   @param[in] dat  The config data structure                                 */
353
/*---------------------------------------------------------------------------*/
354
static void
355
ata_rev (union param_val val, void *dat)
356 1701 nogj
{
357 1748 jeremybenn
  struct ata_host *ata = dat;
358
 
359
  if (val.int_val > 0xf)
360
    {
361
      fprintf (stderr, "Warning: ATA rev > 4 bits: truncated\n");
362
    }
363
 
364
  ata->rev = val.int_val & 0xf;
365 1701 nogj
}
366
 
367 1748 jeremybenn
static void
368
ata_pio_mode0_t1 (union param_val val, void *dat)
369 1702 nogj
{
370 1748 jeremybenn
  struct ata_host *ata = dat;
371 1702 nogj
 
372 1748 jeremybenn
  if (val.int_val < 0 || val.int_val > 255)
373
    {
374
      fprintf (stderr, "Peripheral ATA: Invalid pio_mode0_t1: %d\n",
375
               val.int_val);
376
      return;
377
    }
378 1702 nogj
 
379
  ata->pio_mode0_t1 = val.int_val;
380
}
381
 
382 1748 jeremybenn
static void
383
ata_pio_mode0_t2 (union param_val val, void *dat)
384 1702 nogj
{
385 1748 jeremybenn
  struct ata_host *ata = dat;
386 1702 nogj
 
387 1748 jeremybenn
  if (val.int_val < 0 || val.int_val > 255)
388
    {
389
      fprintf (stderr, "Peripheral ATA: Invalid pio_mode0_t2: %d\n",
390
               val.int_val);
391
      return;
392
    }
393 1702 nogj
 
394
  ata->pio_mode0_t2 = val.int_val;
395
}
396
 
397 1748 jeremybenn
static void
398
ata_pio_mode0_t4 (union param_val val, void *dat)
399 1702 nogj
{
400 1748 jeremybenn
  struct ata_host *ata = dat;
401 1702 nogj
 
402 1748 jeremybenn
  if (val.int_val < 0 || val.int_val > 255)
403
    {
404
      fprintf (stderr, "Peripheral ATA: Invalid pio_mode0_t4: %d\n",
405
               val.int_val);
406
      return;
407
    }
408 1702 nogj
 
409
  ata->pio_mode0_t4 = val.int_val;
410
}
411
 
412 1748 jeremybenn
static void
413
ata_pio_mode0_teoc (union param_val val, void *dat)
414 1702 nogj
{
415 1748 jeremybenn
  struct ata_host *ata = dat;
416 1702 nogj
 
417 1748 jeremybenn
  if (val.int_val < 0 || val.int_val > 255)
418
    {
419
      fprintf (stderr, "Peripheral ATA: Invalid pio_mode0_teoc: %d\n",
420
               val.int_val);
421
      return;
422
    }
423 1702 nogj
 
424
  ata->pio_mode0_teoc = val.int_val;
425
}
426
 
427 1748 jeremybenn
static void
428
ata_dma_mode0_tm (union param_val val, void *dat)
429 1702 nogj
{
430 1748 jeremybenn
  struct ata_host *ata = dat;
431 1702 nogj
 
432 1748 jeremybenn
  if (val.int_val < 0 || val.int_val > 255)
433
    {
434
      fprintf (stderr, "Peripheral ATA: Invalid dma_mode0_tm: %d\n",
435
               val.int_val);
436
      return;
437
    }
438 1702 nogj
 
439
  ata->dma_mode0_tm = val.int_val;
440
}
441
 
442 1748 jeremybenn
static void
443
ata_dma_mode0_td (union param_val val, void *dat)
444 1702 nogj
{
445 1748 jeremybenn
  struct ata_host *ata = dat;
446 1702 nogj
 
447 1748 jeremybenn
  if (val.int_val < 0 || val.int_val > 255)
448
    {
449
      fprintf (stderr, "Peripheral ATA: Invalid dma_mode0_td: %d\n",
450
               val.int_val);
451
      return;
452
    }
453 1702 nogj
 
454
  ata->dma_mode0_td = val.int_val;
455
}
456
 
457 1748 jeremybenn
static void
458
ata_dma_mode0_teoc (union param_val val, void *dat)
459 1702 nogj
{
460 1748 jeremybenn
  struct ata_host *ata = dat;
461 1702 nogj
 
462 1748 jeremybenn
  if (val.int_val < 0 || val.int_val > 255)
463
    {
464
      fprintf (stderr, "Peripheral ATA: Invalid dma_mode0_teoc: %d\n",
465
               val.int_val);
466
      return;
467
    }
468 1702 nogj
 
469
  ata->dma_mode0_teoc = val.int_val;
470
}
471
 
472 1748 jeremybenn
static void
473
ata_type (union param_val val, void *dat)
474 1358 nogj
{
475 1748 jeremybenn
  struct ata_host *ata = dat;
476
  if (conf_dev <= 1)
477 1703 nogj
    ata->devices.device[conf_dev].conf.type = val.int_val;
478 1358 nogj
}
479
 
480 1748 jeremybenn
 
481
/*---------------------------------------------------------------------------*/
482
/*!Set the ATA file
483
 
484
   Free any previously allocated value. Only used if device type is 1.
485
 
486
   @param[in] val  The value to use
487
   @param[in] dat  The config data structure                                 */
488
/*---------------------------------------------------------------------------*/
489
static void
490
ata_file (union param_val val, void *dat)
491 1358 nogj
{
492 1748 jeremybenn
  struct ata_host *ata = dat;
493 1358 nogj
 
494 1748 jeremybenn
  if (conf_dev <= 1)
495
    {
496
      if (NULL != ata->devices.device[conf_dev].conf.file)
497
        {
498
          free (ata->devices.device[conf_dev].conf.file);
499
          ata->devices.device[conf_dev].conf.file = NULL;
500
        }
501
 
502
      if (!(ata->devices.device[conf_dev].conf.file = strdup (val.str_val)))
503
        {
504
          fprintf (stderr, "Peripheral ATA: Run out of memory\n");
505
          exit (-1);
506
        }
507 1703 nogj
    }
508 1748 jeremybenn
}       /* ata_file() */
509 1358 nogj
 
510 1748 jeremybenn
 
511
static void
512
ata_size (union param_val val, void *dat)
513 1358 nogj
{
514 1748 jeremybenn
  struct ata_host *ata = dat;
515
  if (conf_dev <= 1)
516 1703 nogj
    ata->devices.device[conf_dev].conf.size = val.int_val << 20;
517 1358 nogj
}
518
 
519 1748 jeremybenn
static void
520
ata_packet (union param_val val, void *dat)
521 1358 nogj
{
522 1748 jeremybenn
  struct ata_host *ata = dat;
523
  if (conf_dev <= 1)
524 1703 nogj
    ata->devices.device[conf_dev].conf.packet = val.int_val;
525 1358 nogj
}
526
 
527 1748 jeremybenn
static void
528
ata_enabled (union param_val val, void *dat)
529 1358 nogj
{
530 1748 jeremybenn
  struct ata_host *ata = dat;
531 1703 nogj
  ata->enabled = val.int_val;
532 1358 nogj
}
533
 
534 1748 jeremybenn
static void
535
ata_heads (union param_val val, void *dat)
536 1712 nogj
{
537 1748 jeremybenn
  struct ata_host *ata = dat;
538
  if (conf_dev <= 1)
539 1712 nogj
    ata->devices.device[conf_dev].conf.heads = val.int_val;
540
}
541
 
542 1748 jeremybenn
static void
543
ata_sectors (union param_val val, void *dat)
544 1712 nogj
{
545 1748 jeremybenn
  struct ata_host *ata = dat;
546
  if (conf_dev <= 1)
547 1712 nogj
    ata->devices.device[conf_dev].conf.sectors = val.int_val;
548
}
549
 
550 1748 jeremybenn
static void
551
ata_firmware (union param_val val, void *dat)
552 1712 nogj
{
553 1748 jeremybenn
  struct ata_host *ata = dat;
554
  if (conf_dev <= 1)
555
    if (!(ata->devices.device[conf_dev].conf.firmware = strdup (val.str_val)))
556
      {
557
        fprintf (stderr, "Peripheral ATA: Run out of memory\n");
558
        exit (-1);
559
      }
560 1712 nogj
}
561
 
562 1748 jeremybenn
 
563
/*---------------------------------------------------------------------------*/
564
/*!Set the ATA multi-word DMA mode
565
 
566
   Must be -1, 0, 1 or 2.
567
 
568
   @param[in] val  The value to use
569
   @param[in] dat  The config data structure                                 */
570
/*---------------------------------------------------------------------------*/
571
static void
572
ata_mwdma (union param_val  val,
573
           void            *dat)
574 1712 nogj
{
575 1748 jeremybenn
  struct ata_host *ata = dat;
576 1712 nogj
 
577 1748 jeremybenn
  if ((val.int_val >= -1) && (val.int_val <= 2))
578
    {
579
      ata->devices.device[conf_dev].conf.mwdma = val.int_val;
580
    }
581
  else
582
    {
583
      fprintf (stderr, "Warning: invalid ATA multi-word DMA mode: ignored\n");
584
    }
585
}       /* ata_mwdma() */
586
 
587
 
588
/*---------------------------------------------------------------------------*/
589
/*!Set the ATA programmed I/O mode
590
 
591
   Must be 0, 1, 2, 3 or 4.
592
 
593
   @param[in] val  The value to use
594
   @param[in] dat  The config data structure                                 */
595
/*---------------------------------------------------------------------------*/
596
static void
597
ata_pio (union param_val  val,
598
         void            *dat)
599 1712 nogj
{
600 1748 jeremybenn
  struct ata_host *ata = dat;
601 1712 nogj
 
602 1748 jeremybenn
  if ((val.int_val >= 0) && (val.int_val <= 4))
603
    {
604
      ata->devices.device[conf_dev].conf.pio = val.int_val;
605
    }
606
  else
607
    {
608
      fprintf (stderr, "Warning: invalid ATA programmed I/O mode: ignored\n");
609
    }
610
}       /* ata_pio() */
611 1712 nogj
 
612 1748 jeremybenn
 
613
static void
614
ata_start_device (union param_val val, void *dat)
615 1358 nogj
{
616 1703 nogj
  conf_dev = val.int_val;
617 1358 nogj
 
618 1748 jeremybenn
  if (conf_dev > 1)
619
    fprintf (stderr, "Device %d out-of-range\n", conf_dev);
620 1358 nogj
}
621
 
622 1748 jeremybenn
static void
623
ata_enddevice (union param_val val, void *dat)
624 1461 nogj
{
625 1703 nogj
  conf_dev = 2;
626 1461 nogj
}
627
 
628 1748 jeremybenn
/*---------------------------------------------------------------------------*/
629
/*!Initialize a new ATA configuration
630
 
631
   ALL parameters are set explicitly to default values.                      */
632
/*---------------------------------------------------------------------------*/
633
static void *
634
ata_sec_start (void)
635 1364 nogj
{
636 1748 jeremybenn
  struct ata_host *new = malloc (sizeof (struct ata_host));
637 1364 nogj
 
638 1748 jeremybenn
  if (!new)
639
    {
640
      fprintf (stderr, "Peripheral ATA: Run out of memory\n");
641
      exit (-1);
642
    }
643 1364 nogj
 
644 1748 jeremybenn
  memset (new, 0, sizeof (struct ata_host));
645 1701 nogj
 
646 1748 jeremybenn
  new->enabled        = 1;
647
  new->baseaddr       = 0;
648
  new->irq            = 0;
649
  new->dev_id         = 1;
650
  new->rev            = 0;
651
 
652
  new->pio_mode0_t1   = PIO_MODE0_T1;
653
  new->pio_mode0_t2   = PIO_MODE0_T2;
654
  new->pio_mode0_t4   = PIO_MODE0_T4;
655 1702 nogj
  new->pio_mode0_teoc = PIO_MODE0_TEOC;
656
 
657 1748 jeremybenn
  new->dma_mode0_tm   = DMA_MODE0_TM;
658
  new->dma_mode0_td   = DMA_MODE0_TD;
659 1702 nogj
  new->dma_mode0_teoc = DMA_MODE0_TEOC;
660
 
661 1748 jeremybenn
  new->devices.device[0].conf.type     = 0;
662
  new->devices.device[0].conf.file     = strdup ("ata_file0");
663
  new->devices.device[0].conf.size     = 0;
664
  new->devices.device[0].conf.packet   = 0;
665
  new->devices.device[0].conf.heads    = 7;
666
  new->devices.device[0].conf.sectors  = 32;
667 1712 nogj
  new->devices.device[0].conf.firmware = "02207031";
668 1748 jeremybenn
  new->devices.device[0].conf.mwdma    = 2;
669
  new->devices.device[0].conf.pio      = 4;
670 1712 nogj
 
671 1748 jeremybenn
  new->devices.device[1].conf.type     = 0;
672
  new->devices.device[1].conf.file     = strdup ("ata_file1");
673
  new->devices.device[1].conf.size     = 0;
674
  new->devices.device[1].conf.packet   = 0;
675
  new->devices.device[1].conf.heads    = 7;
676
  new->devices.device[1].conf.sectors  = 32;
677 1712 nogj
  new->devices.device[1].conf.firmware = "02207031";
678 1748 jeremybenn
  new->devices.device[1].conf.mwdma    = 2;
679
  new->devices.device[1].conf.pio      = 4;
680 1712 nogj
 
681 1364 nogj
  return new;
682
 
683 1748 jeremybenn
}       /* ata_sec_start() */
684
 
685
 
686
static void
687
ata_sec_end (void *dat)
688 1364 nogj
{
689 1748 jeremybenn
  struct ata_host *ata = dat;
690 1486 nogj
  struct mem_ops ops;
691 1364 nogj
 
692 1748 jeremybenn
  if (!ata->enabled)
693
    {
694
      free (dat);
695
      return;
696
    }
697 1461 nogj
 
698 1364 nogj
  /* Connect ata_devices.                                            */
699 1748 jeremybenn
  ata_devices_init (&ata->devices);
700 1726 nogj
  ata->devices.device[0].internals.host = ata;
701
  ata->devices.device[1].internals.host = ata;
702 1364 nogj
 
703 1748 jeremybenn
  memset (&ops, 0, sizeof (struct mem_ops));
704 1364 nogj
 
705 1486 nogj
  ops.readfunc32 = ata_read32;
706
  ops.read_dat32 = dat;
707
  ops.writefunc32 = ata_write32;
708
  ops.write_dat32 = dat;
709
 
710
  /* Delays will be readjusted later */
711
  ops.delayr = 2;
712
  ops.delayw = 2;
713
 
714 1748 jeremybenn
  ata->mem = reg_mem_area (ata->baseaddr, ATA_ADDR_SPACE, 0, &ops);
715 1486 nogj
 
716 1748 jeremybenn
  reg_sim_reset (ata_reset, dat);
717
  reg_sim_stat (ata_status, dat);
718 1364 nogj
}
719
 
720 1748 jeremybenn
void
721
reg_ata_sec ()
722 1358 nogj
{
723 1748 jeremybenn
  struct config_section *sec =
724
    reg_config_sec ("ata", ata_sec_start, ata_sec_end);
725 1358 nogj
 
726 1748 jeremybenn
  reg_config_param (sec, "enabled", paramt_int, ata_enabled);
727
  reg_config_param (sec, "baseaddr", paramt_addr, ata_baseaddr);
728
  reg_config_param (sec, "irq", paramt_int, ata_irq);
729
  reg_config_param (sec, "dev_id", paramt_int, ata_dev_id);
730
  reg_config_param (sec, "rev", paramt_int, ata_rev);
731 1701 nogj
 
732 1748 jeremybenn
  reg_config_param (sec, "pio_mode0_t1", paramt_int, ata_pio_mode0_t1);
733
  reg_config_param (sec, "pio_mode0_t2", paramt_int, ata_pio_mode0_t2);
734
  reg_config_param (sec, "pio_mode0_t4", paramt_int, ata_pio_mode0_t4);
735
  reg_config_param (sec, "pio_mode0_teoc", paramt_int, ata_pio_mode0_teoc);
736 1702 nogj
 
737 1748 jeremybenn
  reg_config_param (sec, "dma_mode0_tm", paramt_int, ata_dma_mode0_tm);
738
  reg_config_param (sec, "dma_mode0_td", paramt_int, ata_dma_mode0_td);
739
  reg_config_param (sec, "dma_mode0_teoc", paramt_int, ata_dma_mode0_teoc);
740 1703 nogj
 
741 1748 jeremybenn
  reg_config_param (sec, "device", paramt_int, ata_start_device);
742
  reg_config_param (sec, "enddevice", paramt_int, ata_enddevice);
743
 
744
  reg_config_param (sec, "type", paramt_int, ata_type);
745
  reg_config_param (sec, "file", paramt_str, ata_file);
746
  reg_config_param (sec, "size", paramt_int, ata_size);
747
  reg_config_param (sec, "packet", paramt_int, ata_packet);
748
  reg_config_param (sec, "heads", paramt_int, ata_heads);
749
  reg_config_param (sec, "sectors", paramt_int, ata_sectors);
750
  reg_config_param (sec, "firmware", paramt_str, ata_firmware);
751
  reg_config_param (sec, "mwdma", paramt_int, ata_mwdma);
752
  reg_config_param (sec, "pio", paramt_int, ata_pio);
753 1358 nogj
}

powered by: WebSVN 2.1.0

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