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 1488

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

powered by: WebSVN 2.1.0

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