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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [peripheral/] [atahost.c] - Blame information for rev 1765

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

powered by: WebSVN 2.1.0

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