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

Subversion Repositories or1k

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

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

Line No. Rev Author Line
1 876 rherveille
/*
2
    atahost.c -- ATA Host code simulation
3
    Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
4
 
5
    This file is part of OpenRISC 1000 Architectural Simulator
6
 
7
    This program is free software; you can redistribute it and/or modify
8
    it under the terms of the GNU General Public License as published by
9
    the Free Software Foundation; either version 2 of the License, or
10
    (at your option) any later version
11
 
12
    This program is distributed in the hope that it will be useful,
13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
    GNU General Public License for more details.
16
 
17
    You should have received a copy of the GNU General Public License
18
    along with this program; if not, write to the Free Software
19
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
*/
21
 
22 1364 nogj
#include <string.h>
23
 
24 1350 nogj
#include "config.h"
25
 
26
#ifdef HAVE_INTTYPES_H
27
#include <inttypes.h>
28
#endif
29
 
30
#include "port.h"
31
#include "arch.h"
32 1486 nogj
/* get a prototype for 'reg_mem_area()', and 'adjust_rw_delay()' */
33 876 rherveille
#include "abstract.h"
34
#include "sim-config.h"
35
#include "sched.h"
36
 
37
#include "atahost.h"
38
 
39 1702 nogj
/* default timing reset values */
40
#define PIO_MODE0_T1 6
41
#define PIO_MODE0_T2 28
42
#define PIO_MODE0_T4 2
43
#define PIO_MODE0_TEOC 23
44
 
45
#define DMA_MODE0_TM 4
46
#define DMA_MODE0_TD 21
47
#define DMA_MODE0_TEOC 21
48
 
49 876 rherveille
/* reset and initialize ATA host core(s) */
50 1649 nogj
static void ata_reset(void *dat)
51 876 rherveille
{
52 1364 nogj
   ata_host *ata = dat;
53 876 rherveille
 
54 1364 nogj
   // reset the core registers
55
   ata->regs.ctrl  = 0x0001;
56 1701 nogj
   ata->regs.stat  = (ata->dev_id << 28) | (ata->rev << 24);
57 1702 nogj
   ata->regs.pctr  = (ata->pio_mode0_teoc << ATA_TEOC) |
58
                     (ata->pio_mode0_t4 << ATA_T4) |
59
                     (ata->pio_mode0_t2 << ATA_T2) |
60
                     (ata->pio_mode0_t1 << ATA_T1);
61
   ata->regs.pftr0 = ata->regs.pctr;
62
   ata->regs.pftr1 = ata->regs.pctr;
63
   ata->regs.dtr0  = (ata->dma_mode0_teoc << ATA_TEOC) |
64
                     (ata->dma_mode0_td << ATA_TD) |
65
                     (ata->dma_mode0_tm << ATA_TM);
66
   ata->regs.dtr1  = ata->regs.dtr0;
67 1364 nogj
   ata->regs.txb   = 0;
68 919 rherveille
 
69 1364 nogj
   // inform simulator about new read/write delay timings
70 1486 nogj
   adjust_rw_delay( ata->mem, ata_pio_delay(ata->regs.pctr), ata_pio_delay(ata->regs.pctr) );
71 876 rherveille
 
72 1364 nogj
   /* the reset bit in the control register 'ctrl' is set, reset connect ata-devices */
73
   ata_devices_hw_reset(&ata->devices, 1);
74 876 rherveille
}
75
/* ========================================================================= */
76
 
77
 
78
/*
79
  Read a register
80
*/
81 1649 nogj
static uint32_t ata_read32( oraddr_t addr, void *dat )
82 876 rherveille
{
83 1364 nogj
    ata_host *ata = dat;
84 876 rherveille
 
85
    /* determine if ata_host or ata_device addressed */
86
    if (is_ata_hostadr(addr))
87 919 rherveille
    {
88
        // Accesses to internal register take 2cycles
89 1486 nogj
        adjust_rw_delay( ata->mem, 2, 2 );
90 919 rherveille
 
91 876 rherveille
        switch( addr ) {
92
            case ATA_CTRL :
93
                return ata -> regs.ctrl;
94
 
95
            case ATA_STAT :
96
                return ata -> regs.stat;
97
 
98
            case ATA_PCTR :
99
                return ata -> regs.pctr;
100
 
101
            case ATA_PFTR0:
102 1701 nogj
                return ata->dev_id > 1 ? ata->regs.pftr0 : 0;
103 876 rherveille
 
104
            case ATA_PFTR1:
105 1701 nogj
                return ata->dev_id > 1 ? ata->regs.pftr1 : 0;
106 876 rherveille
 
107
            case ATA_DTR0 :
108 1701 nogj
                return ata->dev_id > 2 ? ata->regs.dtr0 : 0;
109 876 rherveille
 
110
            case ATA_DTR1 :
111 1701 nogj
                return ata->dev_id > 2 ? ata->regs.dtr1 : 0;
112 876 rherveille
 
113
            case ATA_RXB  :
114 1701 nogj
                return ata->dev_id > 2 ? ata->regs.rxb : 0;
115 876 rherveille
 
116
            default:
117
                return 0;
118 919 rherveille
        }
119 876 rherveille
    }
120 1701 nogj
 
121 1019 rherveille
    /* check if the controller is enabled */
122 1701 nogj
    if(ata->regs.ctrl & ATA_IDE_EN) {
123 919 rherveille
        // make sure simulator uses correct read/write delay timings
124 1701 nogj
        if(((addr & 0x7f) == ATA_DR) && ata->dev_id > 1) {
125
          if(ata->dev_sel)
126
              adjust_rw_delay(ata->mem, ata_pio_delay(ata->regs.pftr1), ata_pio_delay(ata->regs.pftr1));
127 919 rherveille
          else
128 1701 nogj
              adjust_rw_delay(ata->mem, ata_pio_delay(ata->regs.pftr0), ata_pio_delay(ata->regs.pftr0));
129 919 rherveille
        }
130
        else
131 1701 nogj
          adjust_rw_delay(ata->mem, ata_pio_delay(ata->regs.pctr), ata_pio_delay(ata->regs.pctr));
132 919 rherveille
 
133
        return ata_devices_read(&ata->devices, addr & 0x7f);
134
    }
135 1557 nogj
    return 0;
136 876 rherveille
}
137
/* ========================================================================= */
138
 
139
 
140
/*
141
  Write a register
142
*/
143 1649 nogj
static void ata_write32( oraddr_t addr, uint32_t value, void *dat )
144 876 rherveille
{
145 1364 nogj
    ata_host *ata = dat;
146 876 rherveille
 
147
    /* determine if ata_host or ata_device addressed */
148
    if (is_ata_hostadr(addr))
149 919 rherveille
    {
150
       // Accesses to internal register take 2cycles
151 1486 nogj
       adjust_rw_delay( ata->mem, 2, 2 );
152 919 rherveille
 
153 876 rherveille
        switch( addr ) {
154
            case ATA_CTRL :
155
                ata -> regs.ctrl =  value;
156
 
157
                /* check if reset bit set, if so reset ata-devices    */
158
                if (value & ATA_RST)
159
                  ata_devices_hw_reset(&ata->devices, 1);
160
                else
161
                  ata_devices_hw_reset(&ata->devices, 0);
162
                break;
163
 
164
            case ATA_STAT :
165
                ata -> regs.stat = (ata -> regs.stat & ~ATA_IDEIS) | (ata -> regs.stat & ATA_IDEIS & value);
166
                break;
167
 
168
            case ATA_PCTR :
169
                ata -> regs.pctr = value;
170
                break;
171
 
172
            case ATA_PFTR0:
173
                ata -> regs.pftr0 = value;
174
                break;
175
 
176
            case ATA_PFTR1:
177
                ata -> regs.pftr1 = value;
178
                break;
179
 
180
            case ATA_DTR0 :
181
                ata -> regs.dtr0  = value;
182
                break;
183
 
184
            case ATA_DTR1 :
185
                ata -> regs.dtr1  = value;
186
                break;
187
 
188
            case ATA_TXB  :
189
                ata -> regs.txb   = value;
190
                break;
191
 
192
            default:
193
                /* ERROR-macro currently only supports simple strings. */
194
                /*
195
                  fprintf(stderr, "ERROR  : Unknown register for OCIDEC(%1d).\n", DEV_ID );
196
 
197
                  Tried to show some useful info here.
198
                  But when using 'DM'-simulator-command, the screen gets filled with these messages.
199
                  Thereby eradicating the usefulness of the message
200
                */
201
                break;
202
        }
203 1701 nogj
        return;
204 919 rherveille
    }
205 1701 nogj
 
206 1019 rherveille
    /* check if the controller is enabled */
207 1701 nogj
    if(ata->regs.ctrl & ATA_IDE_EN) {
208 919 rherveille
        // make sure simulator uses correct read/write delay timings
209 1701 nogj
        if(((addr & 0x7f) == ATA_DR) && (ata->dev_id > 1)) {
210
          if(ata->dev_sel)
211
            adjust_rw_delay(ata->mem, ata_pio_delay(ata->regs.pftr1), ata_pio_delay(ata->regs.pftr1));
212 919 rherveille
          else
213 1701 nogj
            adjust_rw_delay(ata->mem, ata_pio_delay(ata->regs.pftr0), ata_pio_delay(ata->regs.pftr0));
214
        } else
215
          adjust_rw_delay( ata->mem, ata_pio_delay(ata->regs.pctr), ata_pio_delay(ata->regs.pctr) );
216 919 rherveille
 
217 1701 nogj
        if((addr & 0x7f) == ATA_DHR)
218
          ata->dev_sel = value & ATA_DHR_DEV;
219
 
220 876 rherveille
        ata_devices_write(&ata->devices, addr & 0x7f, value);
221 919 rherveille
    }
222 876 rherveille
}
223
/* ========================================================================= */
224
 
225
 
226
/* Dump status */
227 1649 nogj
static void ata_status( void *dat )
228 876 rherveille
{
229 1364 nogj
  ata_host *ata = dat;
230 876 rherveille
 
231 1364 nogj
  if ( ata->baseaddr == 0 )
232
    return;
233 876 rherveille
 
234 1701 nogj
  PRINTF( "\nOCIDEC-%1d at: 0x%"PRIxADDR"\n", ata->dev_id, ata->baseaddr );
235 1364 nogj
  PRINTF( "ATA CTRL     : 0x%08X\n", ata->regs.ctrl  );
236
  PRINTF( "ATA STAT     : 0x%08x\n", ata->regs.stat  );
237
  PRINTF( "ATA PCTR     : 0x%08x\n", ata->regs.pctr  );
238 876 rherveille
 
239 1701 nogj
  if(ata->dev_id > 1) {
240
    PRINTF( "ATA FCTR0    : 0x%08x\n", ata->regs.pftr0 );
241
    PRINTF( "ATA FCTR1    : 0x%08x\n", ata->regs.pftr1 );
242
  }
243 876 rherveille
 
244 1701 nogj
  if(ata->dev_id > 2) {
245
    PRINTF( "ATA DTR0     : 0x%08x\n", ata->regs.dtr0  );
246
    PRINTF( "ATA DTR1     : 0x%08x\n", ata->regs.dtr1  );
247
    PRINTF( "ATA TXD      : 0x%08x\n", ata->regs.txb   );
248
    PRINTF( "ATA RXD      : 0x%08x\n", ata->regs.rxb   );
249
  }
250 876 rherveille
}
251
/* ========================================================================= */
252 1358 nogj
 
253
/*----------------------------------------------------[ ATA Configuration ]---*/
254 1703 nogj
static unsigned int conf_dev;
255
 
256 1649 nogj
static void ata_baseaddr(union param_val val, void *dat)
257 1358 nogj
{
258 1364 nogj
  ata_host *ata = dat;
259
  ata->baseaddr = val.addr_val;
260 1358 nogj
}
261
 
262 1649 nogj
static void ata_irq(union param_val val, void *dat)
263 1358 nogj
{
264 1364 nogj
  ata_host *ata = dat;
265
  ata->irq = val.int_val;
266 1358 nogj
}
267
 
268 1701 nogj
static void ata_dev_id(union param_val val, void *dat)
269
{
270
  ata_host *ata = dat;
271
  if(val.int_val < 1 || val.int_val > 3) {
272
    fprintf(stderr, "Peripheral ATA: Unknown device id %d, useing 1\n",
273
            val.int_val);
274
    ata->dev_id = 1;
275
    return;
276
  }
277
 
278
  ata->dev_id = val.int_val;
279
}
280
 
281
static void ata_rev(union param_val val, void *dat)
282
{
283
  ata_host *ata = dat;
284
  ata->rev = val.int_val;
285
}
286
 
287 1702 nogj
static void ata_pio_mode0_t1(union param_val val, void *dat)
288
{
289
  ata_host *ata = dat;
290
 
291
  if(val.int_val < 0 || val.int_val > 255) {
292
    fprintf(stderr, "Peripheral ATA: Invalid pio_mode0_t1: %d\n", val.int_val);
293
    return;
294
  }
295
 
296
  ata->pio_mode0_t1 = val.int_val;
297
}
298
 
299
static void ata_pio_mode0_t2(union param_val val, void *dat)
300
{
301
  ata_host *ata = dat;
302
 
303
  if(val.int_val < 0 || val.int_val > 255) {
304
    fprintf(stderr, "Peripheral ATA: Invalid pio_mode0_t2: %d\n", val.int_val);
305
    return;
306
  }
307
 
308
  ata->pio_mode0_t2 = val.int_val;
309
}
310
 
311
static void ata_pio_mode0_t4(union param_val val, void *dat)
312
{
313
  ata_host *ata = dat;
314
 
315
  if(val.int_val < 0 || val.int_val > 255) {
316
    fprintf(stderr, "Peripheral ATA: Invalid pio_mode0_t4: %d\n", val.int_val);
317
    return;
318
  }
319
 
320
  ata->pio_mode0_t4 = val.int_val;
321
}
322
 
323
static void ata_pio_mode0_teoc(union param_val val, void *dat)
324
{
325
  ata_host *ata = dat;
326
 
327
  if(val.int_val < 0 || val.int_val > 255) {
328
    fprintf(stderr, "Peripheral ATA: Invalid pio_mode0_teoc: %d\n", val.int_val);
329
    return;
330
  }
331
 
332
  ata->pio_mode0_teoc = val.int_val;
333
}
334
 
335
static void ata_dma_mode0_tm(union param_val val, void *dat)
336
{
337
  ata_host *ata = dat;
338
 
339
  if(val.int_val < 0 || val.int_val > 255) {
340
    fprintf(stderr, "Peripheral ATA: Invalid dma_mode0_tm: %d\n", val.int_val);
341
    return;
342
  }
343
 
344
  ata->dma_mode0_tm = val.int_val;
345
}
346
 
347
static void ata_dma_mode0_td(union param_val val, void *dat)
348
{
349
  ata_host *ata = dat;
350
 
351
  if(val.int_val < 0 || val.int_val > 255) {
352
    fprintf(stderr, "Peripheral ATA: Invalid dma_mode0_td: %d\n", val.int_val);
353
    return;
354
  }
355
 
356
  ata->dma_mode0_td = val.int_val;
357
}
358
 
359
static void ata_dma_mode0_teoc(union param_val val, void *dat)
360
{
361
  ata_host *ata = dat;
362
 
363
  if(val.int_val < 0 || val.int_val > 255) {
364
    fprintf(stderr, "Peripheral ATA: Invalid dma_mode0_teoc: %d\n", val.int_val);
365
    return;
366
  }
367
 
368
  ata->dma_mode0_teoc = val.int_val;
369
}
370
 
371 1703 nogj
static void ata_type(union param_val val, void *dat)
372 1358 nogj
{
373 1364 nogj
  ata_host *ata = dat;
374 1703 nogj
  if(conf_dev <= 1)
375
    ata->devices.device[conf_dev].conf.type = val.int_val;
376 1358 nogj
}
377
 
378 1703 nogj
static void ata_file(union param_val val, void *dat)
379 1358 nogj
{
380 1364 nogj
  ata_host *ata = dat;
381 1358 nogj
 
382 1703 nogj
  if(conf_dev <= 1)
383
    if(!(ata->devices.device[conf_dev].conf.file = strdup(val.str_val))) {
384
      fprintf(stderr, "Peripheral ATA: Run out of memory\n");
385
      exit(-1);
386
    }
387 1358 nogj
}
388
 
389 1703 nogj
static void ata_size(union param_val val, void *dat)
390 1358 nogj
{
391 1364 nogj
  ata_host *ata = dat;
392 1703 nogj
  if(conf_dev <= 1)
393
    ata->devices.device[conf_dev].conf.size = val.int_val << 20;
394 1358 nogj
}
395
 
396 1703 nogj
static void ata_packet(union param_val val, void *dat)
397 1358 nogj
{
398 1364 nogj
  ata_host *ata = dat;
399 1703 nogj
  if(conf_dev <= 1)
400
    ata->devices.device[conf_dev].conf.packet = val.int_val;
401 1358 nogj
}
402
 
403 1703 nogj
static void ata_enabled(union param_val val, void *dat)
404 1358 nogj
{
405 1364 nogj
  ata_host *ata = dat;
406 1703 nogj
  ata->enabled = val.int_val;
407 1358 nogj
}
408
 
409 1712 nogj
static void ata_heads(union param_val val, void *dat)
410
{
411
  ata_host *ata = dat;
412
  if(conf_dev <= 1)
413
    ata->devices.device[conf_dev].conf.heads = val.int_val;
414
}
415
 
416
static void ata_sectors(union param_val val, void *dat)
417
{
418
  ata_host *ata = dat;
419
  if(conf_dev <= 1)
420
    ata->devices.device[conf_dev].conf.sectors = val.int_val;
421
}
422
 
423
static void ata_firmware(union param_val val, void *dat)
424
{
425
  ata_host *ata = dat;
426
  if(conf_dev <= 1)
427
    if(!(ata->devices.device[conf_dev].conf.firmware = strdup(val.str_val))) {
428
      fprintf(stderr, "Peripheral ATA: Run out of memory\n");
429
      exit(-1);
430
    }
431
}
432
 
433
static void ata_mwdma(union param_val val, void *dat)
434
{
435
  ata_host *ata = dat;
436
  if(conf_dev <= 1)
437
    ata->devices.device[conf_dev].conf.mwdma = val.int_val;
438
}
439
 
440
static void ata_pio(union param_val val, void *dat)
441
{
442
  ata_host *ata = dat;
443
  if(conf_dev <= 1)
444
    ata->devices.device[conf_dev].conf.pio = val.int_val;
445
}
446
 
447
 
448 1703 nogj
static void ata_start_device(union param_val val, void *dat)
449 1358 nogj
{
450 1703 nogj
  conf_dev = val.int_val;
451 1358 nogj
 
452 1703 nogj
  if(conf_dev > 1)
453
    fprintf(stderr, "Device %d out-of-range\n", conf_dev);
454 1358 nogj
}
455
 
456 1703 nogj
static void ata_enddevice(union param_val val, void *dat)
457 1461 nogj
{
458 1703 nogj
  conf_dev = 2;
459 1461 nogj
}
460
 
461 1649 nogj
static void *ata_sec_start(void)
462 1364 nogj
{
463
  ata_host *new = malloc(sizeof(ata_host));
464
 
465
  if(!new) {
466
    fprintf(stderr, "Peripheral ATA: Run out of memory\n");
467
    exit(-1);
468
  }
469
 
470
  memset(new, 0, sizeof(ata_host));
471 1461 nogj
  new->enabled = 1;
472 1701 nogj
  new->dev_id = 1;
473
 
474 1702 nogj
  new->pio_mode0_t1 = PIO_MODE0_T1;
475
  new->pio_mode0_t2 = PIO_MODE0_T2;
476
  new->pio_mode0_t4 = PIO_MODE0_T4;
477
  new->pio_mode0_teoc = PIO_MODE0_TEOC;
478
 
479
  new->dma_mode0_tm = DMA_MODE0_TM;
480
  new->dma_mode0_td = DMA_MODE0_TD;
481
  new->dma_mode0_teoc = DMA_MODE0_TEOC;
482
 
483 1712 nogj
  new->devices.device[0].conf.heads = 7;
484
  new->devices.device[0].conf.sectors = 32;
485
  new->devices.device[0].conf.firmware = "02207031";
486
  new->devices.device[0].conf.mwdma = 2;
487
  new->devices.device[0].conf.pio = 4;
488
 
489
  new->devices.device[1].conf.heads = 7;
490
  new->devices.device[1].conf.sectors = 32;
491
  new->devices.device[1].conf.firmware = "02207031";
492
  new->devices.device[1].conf.mwdma = 2;
493
  new->devices.device[1].conf.pio = 4;
494
 
495 1364 nogj
  return new;
496
}
497
 
498 1649 nogj
static void ata_sec_end(void *dat)
499 1364 nogj
{
500
  ata_host *ata = dat;
501 1486 nogj
  struct mem_ops ops;
502 1364 nogj
 
503 1461 nogj
  if(!ata->enabled) {
504
    free(dat);
505
    return;
506
  }
507
 
508 1364 nogj
  /* Connect ata_devices.                                            */
509
  ata_devices_init(&ata->devices);
510
 
511 1486 nogj
  memset(&ops, 0, sizeof(struct mem_ops));
512 1364 nogj
 
513 1486 nogj
  ops.readfunc32 = ata_read32;
514
  ops.read_dat32 = dat;
515
  ops.writefunc32 = ata_write32;
516
  ops.write_dat32 = dat;
517
 
518
  /* Delays will be readjusted later */
519
  ops.delayr = 2;
520
  ops.delayw = 2;
521
 
522
  ata->mem = reg_mem_area(ata->baseaddr, ATA_ADDR_SPACE, 0, &ops);
523
 
524 1364 nogj
  reg_sim_reset(ata_reset, dat);
525
  reg_sim_stat(ata_status, dat);
526
}
527
 
528 1358 nogj
void reg_ata_sec(void)
529
{
530 1364 nogj
  struct config_section *sec = reg_config_sec("ata", ata_sec_start, ata_sec_end);
531 1358 nogj
 
532 1461 nogj
  reg_config_param(sec, "enabled", paramt_int, ata_enabled);
533 1358 nogj
  reg_config_param(sec, "baseaddr", paramt_addr, ata_baseaddr);
534
  reg_config_param(sec, "irq", paramt_int, ata_irq);
535 1701 nogj
  reg_config_param(sec, "dev_id", paramt_int, ata_dev_id);
536
  reg_config_param(sec, "rev", paramt_int, ata_rev);
537
 
538 1702 nogj
  reg_config_param(sec, "pio_mode0_t1", paramt_int, ata_pio_mode0_t1);
539
  reg_config_param(sec, "pio_mode0_t2", paramt_int, ata_pio_mode0_t2);
540
  reg_config_param(sec, "pio_mode0_t4", paramt_int, ata_pio_mode0_t4);
541
  reg_config_param(sec, "pio_mode0_teoc", paramt_int, ata_pio_mode0_teoc);
542
 
543
  reg_config_param(sec, "dma_mode0_tm", paramt_int, ata_dma_mode0_tm);
544
  reg_config_param(sec, "dma_mode0_td", paramt_int, ata_dma_mode0_td);
545
  reg_config_param(sec, "dma_mode0_teoc", paramt_int, ata_dma_mode0_teoc);
546
 
547 1703 nogj
  reg_config_param(sec, "device", paramt_int, ata_start_device);
548
  reg_config_param(sec, "enddevice", paramt_int, ata_enddevice);
549
 
550
  reg_config_param(sec, "type", paramt_int, ata_type);
551
  reg_config_param(sec, "file", paramt_str, ata_file);
552
  reg_config_param(sec, "size", paramt_int, ata_size);
553
  reg_config_param(sec, "packet", paramt_int, ata_packet);
554 1712 nogj
  reg_config_param(sec, "heads", paramt_int, ata_heads);
555
  reg_config_param(sec, "sectors", paramt_int, ata_sectors);
556
  reg_config_param(sec, "firmware", paramt_int, ata_firmware);
557
  reg_config_param(sec, "mwdma", paramt_int, ata_mwdma);
558
  reg_config_param(sec, "pio", paramt_int, ata_pio);
559 1358 nogj
}

powered by: WebSVN 2.1.0

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