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

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_1_x/] [or1ksim/] [peripheral/] [atadevice.c] - Blame information for rev 1771

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

Line No. Rev Author Line
1 876 rherveille
/*
2
    atadevice.c -- ATA Device simulation
3
    Simulates a harddisk, using a local streams.
4
    Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
5
 
6
    This file is part of OpenRISC 1000 Architectural Simulator
7
 
8
    This program is free software; you can redistribute it and/or modify
9
    it under the terms of the GNU General Public License as published by
10
    the Free Software Foundation; either version 2 of the License, or
11
    (at your option) any later version
12
 
13
    This program is distributed in the hope that it will be useful,
14
    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
    GNU General Public License for more details.
17
 
18
    You should have received a copy of the GNU General Public License
19
    along with this program; if not, write to the Free Software
20
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
*/
22
 
23 1350 nogj
#include <string.h>
24
#include <stdarg.h>
25
 
26
#include "config.h"
27
 
28
#ifdef HAVE_INTTYPES_H
29
#include <inttypes.h>
30
#endif
31
 
32
#include "port.h"
33
#include "arch.h"
34 876 rherveille
#include "abstract.h"
35
#include "sched.h"
36
 
37
#include "messages.h"
38
#include "atadevice.h"
39
#include "atacmd.h"
40
#include "sim-config.h"
41
#include "atadevice_cmdi.h"
42
 
43
/*
44
 mandatory commands:
45 919 rherveille
 - execute device diagnostics       (done)
46 876 rherveille
 - flush cache
47 919 rherveille
 - identify device                  (done)
48
 - initialize device parameters     (done)
49 876 rherveille
 - read dma
50
 - read multiple
51 919 rherveille
 - read sector(s)                   (done)
52 876 rherveille
 - read verify sector(s)
53
 - seek
54
 - set features
55
 - set multiple mode
56
 - write dma
57
 - write multiple
58
 - write sector(s)
59
 
60
 
61
 optional commands:
62
 - download microcode
63
 - nop
64
 - read buffer
65
 - write buffer
66
 
67
 
68
 prohibited commands:
69
 - device reset
70
*/
71
 
72
 
73
/*
74
  D E V I C E S _ I N I T
75
*/
76
void ata_devices_init(ata_devices *devices, const char *filename0, const char *filename1)
77
{
78
  ata_device_init(&devices->device0, 0, filename0);
79
 
80
  if (devices->device0.type)
81
    ata_device_init(&devices->device1, ATA_DHR_DEV, filename1);
82
  else
83
    ata_device_init(&devices->device1,           0, filename1);
84
}
85
 
86
 
87
void ata_device_init(ata_device *device, int dev, const char *filename)
88
{
89
  /* set DeviceID                                                     */
90 1065 rherveille
  device->internals.dev = dev;
91 876 rherveille
 
92
  /* generate stream for hd_simulation                                */
93
  switch(device->type)
94
  {
95
    case TYPE_NO_CONNECT:
96
      MSG_NOTE("ata_device, using type NO_CONNECT.");
97
      device->stream = NULL;
98
      break;
99
 
100
    case TYPE_FILE:
101
      MSG_NOTE("ata_device, using device type FILE.");
102
      device->stream = open_file(&device->size, filename);
103
      break;
104
 
105
    case TYPE_LOCAL:
106
      MSG_NOTE("ata_device, using device type LOCAL.");
107
      device->stream = open_local();
108
      break;
109
 
110
    default:
111
      MSG_FATAL("ata_device, illegal device-type.");
112
      MSG_EMPTY("defaulting to type NO_CONNECT.");
113
      device->stream = NULL;
114
      break;
115
  }
116
}
117
 
118
/* Use a file to simulate a hard-disk                                 */
119
FILE *open_file(unsigned long *size, const char *filename)
120
{
121
   FILE *fp;
122
   unsigned long  n;
123
 
124
   // TODO:
125
 
126
   /* check if a file with name 'filename' already exists             */
127
   if ( !(fp = fopen(filename, "rb+")) )
128
     if ( !(fp = fopen(filename, "wb+")) )
129
     {
130
       MSG_FATAL( strcat("ata_open_file, cannot open hd-file ", filename) );
131
       return NULL;
132
     }
133
     else
134
     {
135
       /* TODO create a file 'size' large */
136
       /* create a file 'size' large                                  */
137
       MSG_NOTE("ata_device; generating a new hard disk file.");
138
       MSG_EMPTY("This may take a while, depending on the requested size.");
139
       for (n=0; n < (*size << 20); n++)
140
         fputc(0, fp);
141
     }
142
   else /* file already exist                                         */
143
     fprintf(stderr, "file %s already exists. Using existing file.\n", filename);
144
 
145
 
146
   ata_device_debug(1, "requested filesize was: %d (MBytes).\n", *size);
147
 
148
   /* get the size of the file. This is also the size of the harddisk*/
149
   fseek(fp, 0, SEEK_END);
150
   *size = ftell(fp);
151
 
152
   ata_device_debug(1, "actual filesize is: %d (MBytes).\n", *size >> 20);
153
 
154
   return fp;
155
}
156
 
157
 
158
/* Use a the local filesystem as a hard-disk                          */
159
FILE *open_local(void)
160
{
161
 // TODO:
162
 MSG_WARNING("ata_device; device type LOCAL is not supported yet.");
163
 MSG_EMPTY("defaulting to device type NO_CONNECT.");
164
 return NULL;
165
}
166
 
167
 
168
 
169
 
170
/*
171
  D E V I C E S _ H W _ R E S E T
172
*/
173
/* power-on and hardware reset                                        */
174
void ata_devices_hw_reset(ata_devices *devices, int reset_signal)
175
{
176
  /* display debug information                                        */
177 919 rherveille
  ata_device_debug(2, "ata_devices_hw_reset.\n");
178 876 rherveille
 
179
  /* find device 0                                                    */
180
  if ( (devices->device0.stream) && (devices->device1.stream) )
181
  {
182
    /* this one is simple, device0 is device0                         */
183
 
184
    /* 1) handle device1 first                                        */
185 1065 rherveille
    ata_device_hw_reset(&devices->device1, reset_signal,
186
                        1,   /* assert dasp, this is device1          */
187
                        0,   /* negate pdiag input, no more devices   */
188 876 rherveille
                        0);  /* negate dasp input, no more devices    */
189
 
190
    /* 2) Then handle device0                                         */
191 1065 rherveille
    ata_device_hw_reset(&devices->device0, reset_signal,
192
                        0,
193
                        devices->device1.sigs.pdiago,
194 876 rherveille
                        devices->device1.sigs.daspo);
195
  }
196
  else if (devices->device0.stream)
197
  {
198
    /* device0 is device0, there's no device1                         */
199 1065 rherveille
    ata_device_hw_reset(&devices->device0, reset_signal,
200
                        0,   /* negate dasp, this is device0          */
201
                        0,   /* negate pdiag input, there's no device1*/
202 876 rherveille
                        0);  /* negate dasp input, there's no device1 */
203
  }
204
  else if (devices->device1.stream)
205
  {
206
    /* device1 is (logical) device0, there's no (physical) device0    */
207 1065 rherveille
    ata_device_hw_reset(&devices->device1, reset_signal,
208
                        0,   /* negate dasp, this is device0          */
209
                        0,   /* negate pdiag input, there's no device1*/
210 876 rherveille
                        0);  /* negate dasp input, there's no device1 */
211
  }
212
  else
213
  {
214
    /* no devices connected                                           */
215
    ata_device_debug(1, "ata_device_hw_reset, no devices connected.\n");
216
  }
217
}
218
 
219 1065 rherveille
void ata_device_hw_reset(ata_device *device, int reset_signal,
220 876 rherveille
  int daspo, int pdiagi, int daspi)
221
{
222
    /* check ata-device state                                         */
223 1065 rherveille
    if (device->internals.state == ATA_STATE_HW_RST)
224 876 rherveille
    {
225
      if (!reset_signal)
226
      {
227
        /* hardware reset finished                                    */
228 1065 rherveille
 
229 876 rherveille
        /* set sectors_per_track & heads_per_cylinders                */
230 1065 rherveille
        device->internals.sectors_per_track = SECTORS;
231
        device->internals.heads_per_cylinder = HEADS;
232 876 rherveille
 
233
        /* set device1 input signals                                  */
234
        device->sigs.pdiagi = pdiagi;
235
        device->sigs.daspi  = daspi;
236
 
237
        ata_execute_device_diagnostics_cmd(device);
238
 
239
        /* clear busy bit                                             */
240
        device->regs.status &= ~ATA_SR_BSY;
241
 
242
        /* set DRDY bit, when not a PACKET device                     */
243
        if (!device->packet)
244
            device->regs.status |= ATA_SR_DRDY;
245
 
246
        /* set new state                                              */
247 1065 rherveille
        device->internals.state = ATA_STATE_IDLE;
248 876 rherveille
      }
249
    }
250
    else
251
      if (reset_signal)
252
      {
253
        /* hardware reset signal asserted, stop what we are doing     */
254
 
255
        /* negate bus signals                                         */
256
        device->sigs.iordy  = 0;
257
        device->sigs.intrq  = 0;
258
        device->sigs.dmarq  = 0;
259
        device->sigs.pdiago = 0;
260
        device->sigs.daspo  = daspo;
261
 
262
        /* set busy bit                                               */
263
        device->regs.status |= ATA_SR_BSY;
264 997 markom
        PRINTF("setting status register BSY 0x%2X\n", device->regs.status);
265 876 rherveille
 
266
        /* set new state                                              */
267 1065 rherveille
        device->internals.state = ATA_STATE_HW_RST;
268 876 rherveille
      }
269
}
270
 
271
 
272
/*
273
  D E V I C E S _ D O _ C O N T R O L _ R E G I S T E R
274
 
275
  Handles - software reset
276
          - Interrupt enable bit
277
*/
278
void ata_device_do_control_register(ata_device *device)
279
{
280
    /* TODO respond to new values of nIEN */
281
    /* if device not selected, respond to new values of nIEN & SRST */
282
 
283
  /* check if SRST bit is set                                         */
284
  if (device->regs.device_control & ATA_DCR_RST)
285
  {
286 1065 rherveille
    if (device->internals.state == ATA_STATE_IDLE)
287 876 rherveille
    {   /* start software reset                                       */
288
        /* negate bus signals                                         */
289
        device->sigs.pdiago = 0;
290
        device->sigs.intrq  = 0;
291
        device->sigs.iordy  = 0;
292
        device->sigs.dmarq  = 0;
293
 
294
        /* set busy bit                                               */
295
        device->regs.status |= ATA_SR_BSY;
296
 
297
        /* set new state                                              */
298 1065 rherveille
        device->internals.state = ATA_STATE_SW_RST;
299 876 rherveille
 
300
        /* display debug information                                  */
301
        ata_device_debug(2, "ata_device_sw_reset initiated.\n");
302
    }
303
  }
304 1065 rherveille
  else if (device->internals.state == ATA_STATE_SW_RST)
305 876 rherveille
  {   /* are we doing a software reset ??                             */
306
      /* SRST bit cleared, end of software reset                      */
307
 
308
      /*execute device diagnostics                                    */
309
      ata_execute_device_diagnostics_cmd(device);
310
 
311
      /* clear busy bit                                               */
312
      device->regs.status &= ~ATA_SR_BSY;
313
 
314
      /* set DRDY bit, when not a PACKET device                       */
315
      if (!device->packet)
316
        device->regs.status |= ATA_SR_DRDY;
317
 
318
      /* set new state                                                */
319 1065 rherveille
      device->internals.state = ATA_STATE_IDLE;
320 876 rherveille
 
321
      /* display debug information                                    */
322
      ata_device_debug(2, "ata_device_sw_reset done.\n");
323
  }
324
  /*
325
  <else> We are doing a hardware reset (or similar)
326
         ignore command
327
  */
328
}
329
 
330
 
331
/*
332
  D E V I C E S _ D O _ C O M M A N D _ R E G I S T E R
333
*/
334
void ata_device_do_command_register(ata_device *device)
335
{
336
  /* check BSY & DRQ                                                  */
337
  if ( (device->regs.status & ATA_SR_BSY) || (device->regs.status & ATA_SR_DRQ) )
338
     if (device->regs.command != DEVICE_RESET)
339
        MSG_WARNING("ata_device_write, writing a command while BSY or DRQ asserted.");
340
 
341
  /* check if device selected                                         */
342 1065 rherveille
  if ( (device->regs.device_head & ATA_DHR_DEV) == device->internals.dev )
343 876 rherveille
      ata_device_execute_cmd(device);
344
  else
345
  {
346
      /* if not selected, only respond to EXECUTE DEVICE DIAGNOSTICS  */
347
      if (device->regs.command == EXECUTE_DEVICE_DIAGNOSTICS)
348
          ata_device_execute_cmd(device);
349
  }
350
}
351
 
352
 
353
/*
354
  D E V I C E S _ R E A D
355
*/
356
/* Read from devices                                                  */
357
short ata_devices_read(ata_devices *devices, char adr)
358
{
359
    ata_device *device;
360
 
361
    /* check for no connected devices                                 */
362
    if ( (!devices->device0.stream) && (!devices->device1.stream) )
363 919 rherveille
        MSG_ERROR("ata_devices_read, no ata devices connected.");
364 876 rherveille
    else
365
    {
366
      /* check if both device0 and device1 are connected              */
367
      if ( (devices->device0.stream) && (devices->device1.stream) )
368
      {
369
          /* get the current active device                            */
370
          if (devices->device1.regs.device_head & ATA_DHR_DEV)
371
              device = &devices->device1;
372
          else
373
              device = &devices->device0;
374
      }
375
      else
376
      {
377
          /* only one device connected                                */
378
          if (devices->device1.stream)
379
              device = &devices->device1;
380
          else
381
              device = &devices->device0;
382
      }
383
 
384
      /* return data provided by selected device                      */
385
      switch (adr) {
386
        case ATA_ASR :
387 919 rherveille
          ata_device_debug(4, "alternate_status register read\n");
388 1065 rherveille
          if ( (device->regs.device_head & ATA_DHR_DEV) ==  device->internals.dev )
389 876 rherveille
              return device -> regs.status;
390
          else
391
          {
392
              ata_device_debug(2, "device0 responds for device1, asr = 0x00\n");
393
              return 0; // return 0 when device0 responds for device1
394
          }
395
 
396
        case ATA_CHR :
397 1065 rherveille
          ata_device_debug(4, "cylinder_high register read, value = 0x%02X\n",
398 876 rherveille
                 device->regs.cylinder_high);
399
          return device -> regs.cylinder_high;
400
 
401
        case ATA_CLR :
402 1065 rherveille
          ata_device_debug(4, "cylinder_low register read, value = 0x%02X\n",
403 876 rherveille
                 device->regs.cylinder_low);
404
          return device -> regs.cylinder_low;
405
 
406
        case ATA_DR  :
407 1065 rherveille
          if (!device->regs.status & ATA_SR_DRQ)
408
          {
409
             ata_device_debug(1, "data register read, while DRQ bit negated\n" );
410
             return 0;
411
          }
412
          else
413
          {
414
              ata_device_debug(4, "data register read, value = 0x%04X, cnt = %3d\n",
415
                     *device->internals.dbuf_ptr, device->internals.dbuf_cnt);
416
              if (!--device->internals.dbuf_cnt)
417
                   device->regs.status &= ~ATA_SR_DRQ;
418
              return *device -> internals.dbuf_ptr++;
419
          }
420 876 rherveille
 
421
        case ATA_DHR :
422 1065 rherveille
          ata_device_debug(4, "device_head register read, value = 0x%02X\n",
423 876 rherveille
                 device->regs.device_head);
424
          return device -> regs.device_head;
425
 
426
        case ATA_ERR :
427 1065 rherveille
          ata_device_debug(4, "error register read, value = 0x%02X\n",
428 876 rherveille
                 device->regs.error);
429
          return device -> regs.error;
430
 
431
        case ATA_SCR :
432 1065 rherveille
          ata_device_debug(4, "sectorcount register read, value = 0x%02X\n",
433 876 rherveille
                 device->regs.sector_count);
434
          return device -> regs.sector_count;
435
 
436
        case ATA_SNR :
437 1065 rherveille
          ata_device_debug(4, "sectornumber register read, value = 0x%02X\n",
438 876 rherveille
                 device->regs.sector_number);
439
          return device -> regs.sector_number;
440
 
441
        case ATA_SR  :
442 919 rherveille
          ata_device_debug(4, "status register read\n");
443 1065 rherveille
          if ( (device->regs.device_head & ATA_DHR_DEV) ==  device->internals.dev)
444 876 rherveille
              return device -> regs.status;
445
          else
446
          {
447
              ata_device_debug(2, "device0 responds for device1, sr = 0x00\n");
448
              return 0; // return 0 when device0 responds for device1
449
          }
450
 
451
//        case ATA_DA   :
452
//          return device -> regs.status;
453
      }
454
    }
455
}
456
 
457
 
458
/*
459
  D E V I C E S _ W R I T E
460
*/
461
/* Write to devices                                                   */
462
void ata_devices_write(ata_devices *devices, char adr, short value)
463
{
464
    /* check for no connected devices                                 */
465
    if (!devices->device0.stream && !devices->device1.stream)
466 919 rherveille
        MSG_ERROR("ata_devices_write, no ata devices connected.");
467 876 rherveille
    else
468
    {
469
      /* first device                                                 */
470
      if (devices->device0.stream)
471
          ata_device_write(&devices->device0, adr, value);
472
 
473
      /* second device                                                */
474
      if (devices->device1.stream)
475
          ata_device_write(&devices->device1, adr, value);
476
    }
477
}
478
 
479
/* write to a single device                                           */
480
void ata_device_write(ata_device *device, char adr, short value)
481
{
482
    switch (adr) {
483
        case ATA_CR  :
484
            /*display debug information                               */
485 919 rherveille
            ata_device_debug(4, "command register written, value = 0x%02X\n", value);
486 876 rherveille
 
487
            device->regs.command = value;
488
 
489
            /* check command register settings and execute command    */
490
            ata_device_do_command_register(device);
491
            break;
492
 
493
 
494
        case ATA_CHR :
495
            /*display debug information                               */
496 919 rherveille
            ata_device_debug(4, "cylinder high register written, value = 0x%02X\n", value);
497 876 rherveille
 
498
            device->regs.cylinder_high = value;
499
            break;
500
 
501
        case ATA_CLR :
502
            /*display debug information                               */
503 919 rherveille
            ata_device_debug(4, "cylinder low register written, value = 0x%02X\n", value);
504 876 rherveille
 
505
            device->regs.cylinder_low = value;
506
            break;
507
 
508
        case ATA_DR :
509
            /*display debug information                               */
510 919 rherveille
            ata_device_debug(4, "data register written, value = 0x%04X\n", value);
511 876 rherveille
 
512
            device->regs.dataport_i = value;
513
            break;
514
 
515
        case ATA_DCR :
516
            /*display debug information                               */
517 919 rherveille
            ata_device_debug(4, "device control register written, value = 0x%02X\n", value);
518 876 rherveille
 
519
            device->regs.device_control = value;
520
            ata_device_do_control_register(device);
521
            break;
522
 
523
        case ATA_DHR :
524
            /*display debug information                               */
525 919 rherveille
            ata_device_debug(4, "device head register written, value = 0x%02X\n", value);
526 876 rherveille
 
527
            device->regs.device_head = value;
528
            break;
529
 
530
        case ATA_FR  :
531
            /*display debug information                               */
532 919 rherveille
            ata_device_debug(4, "features register written, value = 0x%02X\n", value);
533 876 rherveille
 
534
            device->regs.features = value;
535
            break;
536
 
537
        case ATA_SCR :
538
            /*display debug information                               */
539 919 rherveille
            ata_device_debug(4, "sectorcount register written, value = 0x%02X\n", value);
540 876 rherveille
 
541
            device->regs.sector_count = value;
542
            break;
543
 
544
        case ATA_SNR :
545
            /*display debug information                               */
546 919 rherveille
            ata_device_debug(4, "sectornumber register written, value = 0x%02X\n", value);
547 876 rherveille
 
548
            device->regs.sector_number = value;
549
            break;
550
 
551
    } //endcase
552
}
553
 
554
 
555
/* --------------------------                                         */
556
/* -- print debug messages --                                         */
557
/* --------------------------                                         */
558
int ata_device_debug(int lvl, char *format, ...)
559
{
560
  va_list ap;
561
 
562
  va_start(ap, format);
563
 
564
  if (ATA_DEVICE_DEBUG_LVL >= lvl)
565
  {
566
    fprintf(stderr, "ata_device_debug: ");
567
    vfprintf(stderr, format, ap);
568
  }
569
 
570
  va_end(ap);
571
  return 0;
572
}

powered by: WebSVN 2.1.0

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