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

Subversion Repositories or1k

[/] [or1k/] [tags/] [rel-0-3-0-rc3/] [or1ksim/] [peripheral/] [atahost.c] - Blame information for rev 1701

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

powered by: WebSVN 2.1.0

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