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

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc3/] [or1ksim/] [peripheral/] [atahost.c] - Blame information for rev 1019

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 919 rherveille
/* get a prototype for 'register_memoryarea()', and 'adjust_rw_delay()' */
23 876 rherveille
#include "abstract.h"
24
#include "sim-config.h"
25
#include "sched.h"
26
 
27 919 rherveille
/* all user defineable settings are in 'atahost_define.h'             */
28
#include "atahost_define.h"
29 876 rherveille
#include "atahost.h"
30
#include "messages.h"
31
 
32
static ata_host atas[MAX_ATAS];
33
 
34
/* reset and initialize ATA host core(s) */
35
void ata_reset(void)
36
{
37
   static int first_time=0;
38
 
39
   unsigned i;
40
   ata_host *ata;
41
 
42
   // for all ATA cores
43
   for (i=0; i < config.natas; i++)
44
   {
45
     ata = &(atas[i]);
46
 
47
     // reset the core registers
48
     ata->regs.ctrl  = 0x0001;
49 919 rherveille
     ata->regs.stat  = (DEV_ID << 28) | (REV << 24);
50 876 rherveille
     ata->regs.pctr  = (PIO_MODE0_TEOC << ATA_TEOC) | (PIO_MODE0_T4 << ATA_T4) | (PIO_MODE0_T2 << ATA_T2) | (PIO_MODE0_T1 << ATA_T1);
51
     ata->regs.pftr0 = (PIO_MODE0_TEOC << ATA_TEOC) | (PIO_MODE0_T4 << ATA_T4) | (PIO_MODE0_T2 << ATA_T2) | (PIO_MODE0_T1 << ATA_T1);
52
     ata->regs.pftr1 = (PIO_MODE0_TEOC << ATA_TEOC) | (PIO_MODE0_T4 << ATA_T4) | (PIO_MODE0_T2 << ATA_T2) | (PIO_MODE0_T1 << ATA_T1);
53
     ata->regs.dtr0  = (DMA_MODE0_TEOC << ATA_TEOC) | (DMA_MODE0_TD << ATA_TD) | (DMA_MODE0_TM << ATA_TM);
54
     ata->regs.dtr1  = (DMA_MODE0_TEOC << ATA_TEOC) | (DMA_MODE0_TD << ATA_TD) | (DMA_MODE0_TM << ATA_TM);
55
     ata->regs.txb   = 0;
56 919 rherveille
 
57 876 rherveille
     // copy the config settings
58
     ata->ata_number = i;
59
     ata->irq        = config.atas[i].irq;
60
     ata->baseaddr   = config.atas[i].baseaddr;
61
 
62
     ata->devices.device0.size   = config.atas[i].dev_size0;
63
     ata->devices.device0.type   = config.atas[i].dev_type0;
64
     ata->devices.device0.packet = config.atas[i].dev_packet0;
65
     ata->devices.device1.size   = config.atas[i].dev_size1;
66
     ata->devices.device1.type   = config.atas[i].dev_type1;
67
     ata->devices.device1.packet = config.atas[i].dev_packet1;
68
 
69 919 rherveille
     // inform simulator about new read/write delay timings
70
     adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.pctr), ata_pio_delay(ata->regs.pctr) );
71
 
72 876 rherveille
     /* initialize simulator & ata_devices                                */
73
     if (!first_time)
74
     {
75
       /* Connect ata_devices.                                            */
76
       ata_devices_init(&ata->devices, config.atas[i].dev_file0, config.atas[i].dev_file1);
77
 
78 970 simons
       register_memoryarea(ata->baseaddr, ATA_ADDR_SPACE, 4, 0, ata_read32, ata_write32);
79 876 rherveille
     }
80
 
81
     /* the reset bit in the control register 'ctrl' is set, reset connect ata-devices */
82
     ata_devices_hw_reset(&ata->devices, 1);
83
   }
84
 
85
   first_time++;
86
}
87
/* ========================================================================= */
88
 
89
 
90
/* Convert a memory address to a device struct and relative address.
91
 * Return nonzero on success */
92
int ata_find_device( unsigned long addr, ata_host **ata, unsigned long *reladdr )
93
{
94
  unsigned i;
95
  *ata = NULL;
96
 
97
  for ( i = 0; i < config.natas && *ata == NULL; ++ i ) {
98
    if ( (addr >= atas[i].baseaddr) && (addr < atas[i].baseaddr + ATA_ADDR_SPACE) )
99
      *ata = &(atas[i]);
100
  }
101
 
102
  /* verify we found a device */
103
  if ( *ata == NULL )
104
    return 0;
105
 
106
  /* Verify legal address */
107
  if ( (addr - (*ata)->baseaddr) % 4 != 0 )
108
    return 0;
109
 
110
  *reladdr = addr - (*ata) -> baseaddr;
111
  return 1;
112
}
113
/* ========================================================================= */
114
 
115
 
116
/*
117
  Read a register
118
*/
119
unsigned long ata_read32( unsigned long addr )
120
{
121
    ata_host *ata;
122
 
123
    if ( !ata_find_device( addr, &ata, &addr ) )    {
124
        fprintf(stderr, "ata_read32( 0x%08lX ): Not in registered range(s)\n", addr );
125
        return 0;
126
    }
127
 
128
    /* determine if ata_host or ata_device addressed */
129
    if (is_ata_hostadr(addr))
130 919 rherveille
    {
131
        // Accesses to internal register take 2cycles
132
        adjust_rw_delay( ata->baseaddr, 2, 2 );
133
 
134 876 rherveille
        switch( addr ) {
135
            case ATA_CTRL :
136
                return ata -> regs.ctrl;
137
 
138
            case ATA_STAT :
139
                return ata -> regs.stat;
140
 
141
            case ATA_PCTR :
142
                return ata -> regs.pctr;
143
 
144
#if (DEV_ID > 1)
145
            case ATA_PFTR0:
146
                return ata -> regs.pftr0;
147
 
148
            case ATA_PFTR1:
149
                return ata -> regs.pftr1;
150
#endif
151
 
152
#if (DEV_ID > 2)
153
            case ATA_DTR0 :
154
                return ata -> regs.dtr0;
155
 
156
            case ATA_DTR1 :
157
                return ata -> regs.dtr1;
158
 
159
            case ATA_RXB  :
160
                return ata -> regs.rxb;
161
#endif
162
 
163
            default:
164
                return 0;
165 919 rherveille
        }
166 876 rherveille
    }
167
    else
168 1019 rherveille
    /* check if the controller is enabled */
169
    if (ata->regs.ctrl & ATA_IDE_EN)
170 919 rherveille
    {
171
        // make sure simulator uses correct read/write delay timings
172
#if (DEV_ID > 1)
173
        if ( (addr & 0x7f) == ATA_DR)
174
        {
175
          if (ata->devices.dev)
176
              adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.ftcr1), ata_pio_delay(ata->regs.ftcr1) );
177
          else
178
              adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.ftcr0), ata_pio_delay(ata->regs.ftcr0) );
179
        }
180
        else
181
#endif
182
        adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.pctr), ata_pio_delay(ata->regs.pctr) );
183
 
184
        return ata_devices_read(&ata->devices, addr & 0x7f);
185
    }
186 876 rherveille
}
187
/* ========================================================================= */
188
 
189
 
190
/*
191
  Write a register
192
*/
193
void ata_write32( unsigned long addr, unsigned long value )
194
{
195
    ata_host *ata;
196
 
197
    if ( !ata_find_device( addr, &ata, &addr ) )
198
    {
199
        fprintf(stderr, "ata_write32( 0x%08lX ): Not in registered range(s)\n", addr );
200
        return;
201
    }
202
 
203
    /* determine if ata_host or ata_device addressed */
204
    if (is_ata_hostadr(addr))
205 919 rherveille
    {
206
       // Accesses to internal register take 2cycles
207
       adjust_rw_delay( ata->baseaddr, 2, 2 );
208
 
209 876 rherveille
        switch( addr ) {
210
            case ATA_CTRL :
211
                ata -> regs.ctrl =  value;
212
 
213
                /* check if reset bit set, if so reset ata-devices    */
214
                if (value & ATA_RST)
215
                  ata_devices_hw_reset(&ata->devices, 1);
216
                else
217
                  ata_devices_hw_reset(&ata->devices, 0);
218
                break;
219
 
220
            case ATA_STAT :
221
                ata -> regs.stat = (ata -> regs.stat & ~ATA_IDEIS) | (ata -> regs.stat & ATA_IDEIS & value);
222
                break;
223
 
224
            case ATA_PCTR :
225
                ata -> regs.pctr = value;
226
                break;
227
 
228
            case ATA_PFTR0:
229
                ata -> regs.pftr0 = value;
230
                break;
231
 
232
            case ATA_PFTR1:
233
                ata -> regs.pftr1 = value;
234
                break;
235
 
236
            case ATA_DTR0 :
237
                ata -> regs.dtr0  = value;
238
                break;
239
 
240
            case ATA_DTR1 :
241
                ata -> regs.dtr1  = value;
242
                break;
243
 
244
            case ATA_TXB  :
245
                ata -> regs.txb   = value;
246
                break;
247
 
248
            default:
249
                /* ERROR-macro currently only supports simple strings. */
250
                /*
251
                  fprintf(stderr, "ERROR  : Unknown register for OCIDEC(%1d).\n", DEV_ID );
252
 
253
                  Tried to show some useful info here.
254
                  But when using 'DM'-simulator-command, the screen gets filled with these messages.
255
                  Thereby eradicating the usefulness of the message
256
                */
257
                break;
258
        }
259 919 rherveille
    }
260 876 rherveille
    else
261 1019 rherveille
    /* check if the controller is enabled */
262
    if (ata->regs.ctrl & ATA_IDE_EN)
263 919 rherveille
    {
264
        // make sure simulator uses correct read/write delay timings
265
#if (DEV_ID > 1)
266
        if ( (addr & 0x7f) == ATA_DR)
267
        {
268
          if (ata->devices.dev)
269
              adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.ftcr1), ata_pio_delay(ata->regs.ftcr1) );
270
          else
271
              adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.ftcr0), ata_pio_delay(ata->regs.ftcr0) );
272
        }
273
        else
274
#endif
275
        adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.pctr), ata_pio_delay(ata->regs.pctr) );
276
 
277 876 rherveille
        ata_devices_write(&ata->devices, addr & 0x7f, value);
278 919 rherveille
    }
279 876 rherveille
}
280
/* ========================================================================= */
281
 
282
 
283
/* Dump status */
284
void ata_status( void )
285
{
286
  unsigned i;
287
  ata_host *ata;
288
 
289
  for ( i = 0; i < config.natas; i++ ) {
290
      ata = &(atas[i]);
291
 
292
      if ( ata->baseaddr == 0 )
293
         continue;
294
 
295 997 markom
       PRINTF( "\nOCIDEC-%1d %u at: 0x%08X\n", DEV_ID, i, ata->baseaddr );
296
       PRINTF( "ATA CTRL     : 0x%08lX\n", ata->regs.ctrl  );
297
       PRINTF( "ATA STAT     : 0x%08lx\n", ata->regs.stat  );
298
       PRINTF( "ATA PCTR     : 0x%08lx\n", ata->regs.pctr  );
299 876 rherveille
 
300
#if (DEV_ID > 1)
301 997 markom
       PRINTF( "ATA FCTR0    : 0x%08lx\n", ata->regs.pftr0 );
302
       PRINTF( "ATA FCTR1    : 0x%08lx\n", ata->regs.pftr1 );
303 876 rherveille
#endif
304
 
305
#if (DEV_ID > 2)
306 997 markom
       PRINTF( "ATA DTR0     : 0x%08lx\n", ata->regs.dtr0  );
307
       PRINTF( "ATA DTR1     : 0x%08lx\n", ata->regs.dtr1  );
308
       PRINTF( "ATA TXD      : 0x%08lx\n", ata->regs.txb   );
309
       PRINTF( "ATA RXD      : 0x%08lx\n", ata->regs.rxb   );
310 876 rherveille
#endif
311
  }
312
}
313
/* ========================================================================= */

powered by: WebSVN 2.1.0

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