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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_70/] [or1ksim/] [peripheral/] [atadevice.c] - Blame information for rev 1765

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

powered by: WebSVN 2.1.0

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