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

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_1_0/] [or1ksim/] [peripheral/] [atahost.c] - Blame information for rev 1780

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

powered by: WebSVN 2.1.0

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