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

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_2_x/] [or1ksim/] [peripheral/] [atahost.c] - Blame information for rev 1557

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

powered by: WebSVN 2.1.0

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