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

Subversion Repositories or1k

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

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 919 rherveille
/* get a prototype for 'register_memoryarea()', and 'adjust_rw_delay()' */
33 876 rherveille
#include "abstract.h"
34
#include "sim-config.h"
35
#include "sched.h"
36
 
37 919 rherveille
/* all user defineable settings are in 'atahost_define.h'             */
38
#include "atahost_define.h"
39 876 rherveille
#include "atahost.h"
40
#include "messages.h"
41
 
42
/* reset and initialize ATA host core(s) */
43 1364 nogj
void ata_reset(void *dat)
44 876 rherveille
{
45 1364 nogj
   ata_host *ata = dat;
46 876 rherveille
 
47 1364 nogj
   // reset the core registers
48
   ata->regs.ctrl  = 0x0001;
49
   ata->regs.stat  = (DEV_ID << 28) | (REV << 24);
50
   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 1364 nogj
   // inform simulator about new read/write delay timings
58
   adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.pctr), ata_pio_delay(ata->regs.pctr) );
59 876 rherveille
 
60 1364 nogj
   /* the reset bit in the control register 'ctrl' is set, reset connect ata-devices */
61
   ata_devices_hw_reset(&ata->devices, 1);
62 876 rherveille
}
63
/* ========================================================================= */
64
 
65
 
66
/*
67
  Read a register
68
*/
69 1359 nogj
uint32_t ata_read32( oraddr_t addr, void *dat )
70 876 rherveille
{
71 1364 nogj
    ata_host *ata = dat;
72 876 rherveille
 
73 1364 nogj
    addr -= ata->baseaddr;
74 876 rherveille
 
75
    /* determine if ata_host or ata_device addressed */
76
    if (is_ata_hostadr(addr))
77 919 rherveille
    {
78
        // Accesses to internal register take 2cycles
79
        adjust_rw_delay( ata->baseaddr, 2, 2 );
80
 
81 876 rherveille
        switch( addr ) {
82
            case ATA_CTRL :
83
                return ata -> regs.ctrl;
84
 
85
            case ATA_STAT :
86
                return ata -> regs.stat;
87
 
88
            case ATA_PCTR :
89
                return ata -> regs.pctr;
90
 
91
#if (DEV_ID > 1)
92
            case ATA_PFTR0:
93
                return ata -> regs.pftr0;
94
 
95
            case ATA_PFTR1:
96
                return ata -> regs.pftr1;
97
#endif
98
 
99
#if (DEV_ID > 2)
100
            case ATA_DTR0 :
101
                return ata -> regs.dtr0;
102
 
103
            case ATA_DTR1 :
104
                return ata -> regs.dtr1;
105
 
106
            case ATA_RXB  :
107
                return ata -> regs.rxb;
108
#endif
109
 
110
            default:
111
                return 0;
112 919 rherveille
        }
113 876 rherveille
    }
114
    else
115 1019 rherveille
    /* check if the controller is enabled */
116
    if (ata->regs.ctrl & ATA_IDE_EN)
117 919 rherveille
    {
118
        // make sure simulator uses correct read/write delay timings
119
#if (DEV_ID > 1)
120
        if ( (addr & 0x7f) == ATA_DR)
121
        {
122
          if (ata->devices.dev)
123
              adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.ftcr1), ata_pio_delay(ata->regs.ftcr1) );
124
          else
125
              adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.ftcr0), ata_pio_delay(ata->regs.ftcr0) );
126
        }
127
        else
128
#endif
129
        adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.pctr), ata_pio_delay(ata->regs.pctr) );
130
 
131
        return ata_devices_read(&ata->devices, addr & 0x7f);
132
    }
133 876 rherveille
}
134
/* ========================================================================= */
135
 
136
 
137
/*
138
  Write a register
139
*/
140 1359 nogj
void ata_write32( oraddr_t addr, uint32_t value, void *dat )
141 876 rherveille
{
142 1364 nogj
    ata_host *ata = dat;
143 876 rherveille
 
144 1364 nogj
    addr -= ata->baseaddr;
145 876 rherveille
 
146
    /* determine if ata_host or ata_device addressed */
147
    if (is_ata_hostadr(addr))
148 919 rherveille
    {
149
       // Accesses to internal register take 2cycles
150
       adjust_rw_delay( ata->baseaddr, 2, 2 );
151
 
152 876 rherveille
        switch( addr ) {
153
            case ATA_CTRL :
154
                ata -> regs.ctrl =  value;
155
 
156
                /* check if reset bit set, if so reset ata-devices    */
157
                if (value & ATA_RST)
158
                  ata_devices_hw_reset(&ata->devices, 1);
159
                else
160
                  ata_devices_hw_reset(&ata->devices, 0);
161
                break;
162
 
163
            case ATA_STAT :
164
                ata -> regs.stat = (ata -> regs.stat & ~ATA_IDEIS) | (ata -> regs.stat & ATA_IDEIS & value);
165
                break;
166
 
167
            case ATA_PCTR :
168
                ata -> regs.pctr = value;
169
                break;
170
 
171
            case ATA_PFTR0:
172
                ata -> regs.pftr0 = value;
173
                break;
174
 
175
            case ATA_PFTR1:
176
                ata -> regs.pftr1 = value;
177
                break;
178
 
179
            case ATA_DTR0 :
180
                ata -> regs.dtr0  = value;
181
                break;
182
 
183
            case ATA_DTR1 :
184
                ata -> regs.dtr1  = value;
185
                break;
186
 
187
            case ATA_TXB  :
188
                ata -> regs.txb   = value;
189
                break;
190
 
191
            default:
192
                /* ERROR-macro currently only supports simple strings. */
193
                /*
194
                  fprintf(stderr, "ERROR  : Unknown register for OCIDEC(%1d).\n", DEV_ID );
195
 
196
                  Tried to show some useful info here.
197
                  But when using 'DM'-simulator-command, the screen gets filled with these messages.
198
                  Thereby eradicating the usefulness of the message
199
                */
200
                break;
201
        }
202 919 rherveille
    }
203 876 rherveille
    else
204 1019 rherveille
    /* check if the controller is enabled */
205
    if (ata->regs.ctrl & ATA_IDE_EN)
206 919 rherveille
    {
207
        // make sure simulator uses correct read/write delay timings
208
#if (DEV_ID > 1)
209
        if ( (addr & 0x7f) == ATA_DR)
210
        {
211
          if (ata->devices.dev)
212
              adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.ftcr1), ata_pio_delay(ata->regs.ftcr1) );
213
          else
214
              adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.ftcr0), ata_pio_delay(ata->regs.ftcr0) );
215
        }
216
        else
217
#endif
218
        adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.pctr), ata_pio_delay(ata->regs.pctr) );
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 1364 nogj
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 1364 nogj
  PRINTF( "\nOCIDEC-%1d at: 0x%"PRIxADDR"\n", DEV_ID, ata->baseaddr );
235
  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
#if (DEV_ID > 1)
240 1364 nogj
  PRINTF( "ATA FCTR0    : 0x%08lx\n", ata->regs.pftr0 );
241
  PRINTF( "ATA FCTR1    : 0x%08lx\n", ata->regs.pftr1 );
242 876 rherveille
#endif
243
 
244
#if (DEV_ID > 2)
245 1364 nogj
  PRINTF( "ATA DTR0     : 0x%08lx\n", ata->regs.dtr0  );
246
  PRINTF( "ATA DTR1     : 0x%08lx\n", ata->regs.dtr1  );
247
  PRINTF( "ATA TXD      : 0x%08lx\n", ata->regs.txb   );
248
  PRINTF( "ATA RXD      : 0x%08lx\n", ata->regs.rxb   );
249 876 rherveille
#endif
250
}
251
/* ========================================================================= */
252 1358 nogj
 
253
/*----------------------------------------------------[ ATA Configuration ]---*/
254
void ata_baseaddr(union param_val val, void *dat)
255
{
256 1364 nogj
  ata_host *ata = dat;
257
  ata->baseaddr = val.addr_val;
258 1358 nogj
}
259
 
260
void ata_irq(union param_val val, void *dat)
261
{
262 1364 nogj
  ata_host *ata = dat;
263
  ata->irq = val.int_val;
264 1358 nogj
}
265
 
266
void ata_dev_type0(union param_val val, void *dat)
267
{
268 1364 nogj
  ata_host *ata = dat;
269
  ata->devices.device0.type = val.int_val;
270 1358 nogj
}
271
 
272
void ata_dev_file0(union param_val val, void *dat)
273
{
274 1364 nogj
  ata_host *ata = dat;
275
  if(!(ata->devices.device0.file = strdup(val.str_val))) {
276
    fprintf(stderr, "Peripheral ATA: Run out of memory\n");
277
    exit(-1);
278
  }
279 1358 nogj
}
280
 
281
void ata_dev_size0(union param_val val, void *dat)
282
{
283 1364 nogj
  ata_host *ata = dat;
284
  ata->devices.device0.size = val.int_val;
285 1358 nogj
}
286
 
287
void ata_dev_packet0(union param_val val, void *dat)
288
{
289 1364 nogj
  ata_host *ata = dat;
290
  ata->devices.device0.packet = val.int_val;
291 1358 nogj
}
292
 
293
void ata_dev_type1(union param_val val, void *dat)
294
{
295 1364 nogj
  ata_host *ata = dat;
296
  ata->devices.device1.packet = val.int_val;
297 1358 nogj
}
298
 
299
void ata_dev_file1(union param_val val, void *dat)
300
{
301 1364 nogj
  ata_host *ata = dat;
302
  if(!(ata->devices.device1.file = strdup(val.str_val))) {
303
    fprintf(stderr, "Peripheral ATA: Run out of memory\n");
304
    exit(-1);
305
  }
306 1358 nogj
}
307
 
308
void ata_dev_size1(union param_val val, void *dat)
309
{
310 1364 nogj
  ata_host *ata = dat;
311
  ata->devices.device1.size = val.int_val;
312 1358 nogj
}
313
 
314
void ata_dev_packet1(union param_val val, void *dat)
315
{
316 1364 nogj
  ata_host *ata = dat;
317
  ata->devices.device1.packet = val.int_val;
318 1358 nogj
}
319
 
320 1364 nogj
void *ata_sec_start(void)
321
{
322
  ata_host *new = malloc(sizeof(ata_host));
323
 
324
  if(!new) {
325
    fprintf(stderr, "Peripheral ATA: Run out of memory\n");
326
    exit(-1);
327
  }
328
 
329
  memset(new, 0, sizeof(ata_host));
330
  return new;
331
}
332
 
333
void ata_sec_end(void *dat)
334
{
335
  ata_host *ata = dat;
336
 
337
  /* Connect ata_devices.                                            */
338
  ata_devices_init(&ata->devices);
339
 
340
  register_memoryarea(ata->baseaddr, ATA_ADDR_SPACE, 4, 0, ata_read32, ata_write32, dat);
341
 
342
  reg_sim_reset(ata_reset, dat);
343
  reg_sim_stat(ata_status, dat);
344
}
345
 
346 1358 nogj
void reg_ata_sec(void)
347
{
348 1364 nogj
  struct config_section *sec = reg_config_sec("ata", ata_sec_start, ata_sec_end);
349 1358 nogj
 
350
  reg_config_param(sec, "baseaddr", paramt_addr, ata_baseaddr);
351
  reg_config_param(sec, "irq", paramt_int, ata_irq);
352
  reg_config_param(sec, "dev_type0", paramt_int, ata_dev_type0);
353
  reg_config_param(sec, "dev_file0", paramt_str, ata_dev_file0);
354
  reg_config_param(sec, "dev_size0", paramt_int, ata_dev_size0);
355
  reg_config_param(sec, "dev_packet0", paramt_int, ata_dev_packet0);
356
  reg_config_param(sec, "dev_type1", paramt_int, ata_dev_type1);
357
  reg_config_param(sec, "dev_file1", paramt_str, ata_dev_file1);
358
  reg_config_param(sec, "dev_size1", paramt_int, ata_dev_size1);
359
  reg_config_param(sec, "dev_packet1", paramt_int, ata_dev_packet1);
360
}

powered by: WebSVN 2.1.0

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