/*
|
/*
|
atahost.c -- ATA Host code simulation
|
atahost.c -- ATA Host code simulation
|
Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
|
Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
|
|
|
This file is part of OpenRISC 1000 Architectural Simulator
|
This file is part of OpenRISC 1000 Architectural Simulator
|
|
|
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
(at your option) any later version
|
(at your option) any later version
|
|
|
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
GNU General Public License for more details.
|
GNU General Public License for more details.
|
|
|
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
*/
|
*/
|
|
|
#include "config.h"
|
#include "config.h"
|
|
|
#ifdef HAVE_INTTYPES_H
|
#ifdef HAVE_INTTYPES_H
|
#include <inttypes.h>
|
#include <inttypes.h>
|
#endif
|
#endif
|
|
|
#include "port.h"
|
#include "port.h"
|
#include "arch.h"
|
#include "arch.h"
|
/* get a prototype for 'register_memoryarea()', and 'adjust_rw_delay()' */
|
/* get a prototype for 'register_memoryarea()', and 'adjust_rw_delay()' */
|
#include "abstract.h"
|
#include "abstract.h"
|
#include "sim-config.h"
|
#include "sim-config.h"
|
#include "sched.h"
|
#include "sched.h"
|
|
|
/* all user defineable settings are in 'atahost_define.h' */
|
/* all user defineable settings are in 'atahost_define.h' */
|
#include "atahost_define.h"
|
#include "atahost_define.h"
|
#include "atahost.h"
|
#include "atahost.h"
|
#include "messages.h"
|
#include "messages.h"
|
|
|
static ata_host atas[MAX_ATAS];
|
static ata_host atas[MAX_ATAS];
|
|
|
/* reset and initialize ATA host core(s) */
|
/* reset and initialize ATA host core(s) */
|
void ata_reset(void)
|
void ata_reset(void)
|
{
|
{
|
static int first_time=0;
|
static int first_time=0;
|
|
|
unsigned i;
|
unsigned i;
|
ata_host *ata;
|
ata_host *ata;
|
|
|
// for all ATA cores
|
// for all ATA cores
|
for (i=0; i < config.natas; i++)
|
for (i=0; i < config.natas; i++)
|
{
|
{
|
ata = &(atas[i]);
|
ata = &(atas[i]);
|
|
|
// reset the core registers
|
// reset the core registers
|
ata->regs.ctrl = 0x0001;
|
ata->regs.ctrl = 0x0001;
|
ata->regs.stat = (DEV_ID << 28) | (REV << 24);
|
ata->regs.stat = (DEV_ID << 28) | (REV << 24);
|
ata->regs.pctr = (PIO_MODE0_TEOC << ATA_TEOC) | (PIO_MODE0_T4 << ATA_T4) | (PIO_MODE0_T2 << ATA_T2) | (PIO_MODE0_T1 << ATA_T1);
|
ata->regs.pctr = (PIO_MODE0_TEOC << ATA_TEOC) | (PIO_MODE0_T4 << ATA_T4) | (PIO_MODE0_T2 << ATA_T2) | (PIO_MODE0_T1 << ATA_T1);
|
ata->regs.pftr0 = (PIO_MODE0_TEOC << ATA_TEOC) | (PIO_MODE0_T4 << ATA_T4) | (PIO_MODE0_T2 << ATA_T2) | (PIO_MODE0_T1 << ATA_T1);
|
ata->regs.pftr0 = (PIO_MODE0_TEOC << ATA_TEOC) | (PIO_MODE0_T4 << ATA_T4) | (PIO_MODE0_T2 << ATA_T2) | (PIO_MODE0_T1 << ATA_T1);
|
ata->regs.pftr1 = (PIO_MODE0_TEOC << ATA_TEOC) | (PIO_MODE0_T4 << ATA_T4) | (PIO_MODE0_T2 << ATA_T2) | (PIO_MODE0_T1 << ATA_T1);
|
ata->regs.pftr1 = (PIO_MODE0_TEOC << ATA_TEOC) | (PIO_MODE0_T4 << ATA_T4) | (PIO_MODE0_T2 << ATA_T2) | (PIO_MODE0_T1 << ATA_T1);
|
ata->regs.dtr0 = (DMA_MODE0_TEOC << ATA_TEOC) | (DMA_MODE0_TD << ATA_TD) | (DMA_MODE0_TM << ATA_TM);
|
ata->regs.dtr0 = (DMA_MODE0_TEOC << ATA_TEOC) | (DMA_MODE0_TD << ATA_TD) | (DMA_MODE0_TM << ATA_TM);
|
ata->regs.dtr1 = (DMA_MODE0_TEOC << ATA_TEOC) | (DMA_MODE0_TD << ATA_TD) | (DMA_MODE0_TM << ATA_TM);
|
ata->regs.dtr1 = (DMA_MODE0_TEOC << ATA_TEOC) | (DMA_MODE0_TD << ATA_TD) | (DMA_MODE0_TM << ATA_TM);
|
ata->regs.txb = 0;
|
ata->regs.txb = 0;
|
|
|
// copy the config settings
|
// copy the config settings
|
ata->ata_number = i;
|
ata->ata_number = i;
|
ata->irq = config.atas[i].irq;
|
ata->irq = config.atas[i].irq;
|
ata->baseaddr = config.atas[i].baseaddr;
|
ata->baseaddr = config.atas[i].baseaddr;
|
|
|
ata->devices.device0.size = config.atas[i].dev_size0;
|
ata->devices.device0.size = config.atas[i].dev_size0;
|
ata->devices.device0.type = config.atas[i].dev_type0;
|
ata->devices.device0.type = config.atas[i].dev_type0;
|
ata->devices.device0.packet = config.atas[i].dev_packet0;
|
ata->devices.device0.packet = config.atas[i].dev_packet0;
|
ata->devices.device1.size = config.atas[i].dev_size1;
|
ata->devices.device1.size = config.atas[i].dev_size1;
|
ata->devices.device1.type = config.atas[i].dev_type1;
|
ata->devices.device1.type = config.atas[i].dev_type1;
|
ata->devices.device1.packet = config.atas[i].dev_packet1;
|
ata->devices.device1.packet = config.atas[i].dev_packet1;
|
|
|
// inform simulator about new read/write delay timings
|
// inform simulator about new read/write delay timings
|
adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.pctr), ata_pio_delay(ata->regs.pctr) );
|
adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.pctr), ata_pio_delay(ata->regs.pctr) );
|
|
|
/* initialize simulator & ata_devices */
|
/* initialize simulator & ata_devices */
|
if (!first_time)
|
if (!first_time)
|
{
|
{
|
/* Connect ata_devices. */
|
/* Connect ata_devices. */
|
ata_devices_init(&ata->devices, config.atas[i].dev_file0, config.atas[i].dev_file1);
|
ata_devices_init(&ata->devices, config.atas[i].dev_file0, config.atas[i].dev_file1);
|
|
|
register_memoryarea(ata->baseaddr, ATA_ADDR_SPACE, 4, 0, ata_read32, ata_write32);
|
register_memoryarea(ata->baseaddr, ATA_ADDR_SPACE, 4, 0, ata_read32, ata_write32, NULL);
|
}
|
}
|
|
|
/* the reset bit in the control register 'ctrl' is set, reset connect ata-devices */
|
/* the reset bit in the control register 'ctrl' is set, reset connect ata-devices */
|
ata_devices_hw_reset(&ata->devices, 1);
|
ata_devices_hw_reset(&ata->devices, 1);
|
}
|
}
|
|
|
first_time++;
|
first_time++;
|
}
|
}
|
/* ========================================================================= */
|
/* ========================================================================= */
|
|
|
|
|
/* Convert a memory address to a device struct and relative address.
|
/* Convert a memory address to a device struct and relative address.
|
* Return nonzero on success */
|
* Return nonzero on success */
|
int ata_find_device( oraddr_t addr, ata_host **ata, oraddr_t *reladdr )
|
int ata_find_device( oraddr_t addr, ata_host **ata, oraddr_t *reladdr )
|
{
|
{
|
unsigned i;
|
unsigned i;
|
*ata = NULL;
|
*ata = NULL;
|
|
|
for ( i = 0; i < config.natas && *ata == NULL; ++ i ) {
|
for ( i = 0; i < config.natas && *ata == NULL; ++ i ) {
|
if ( (addr >= atas[i].baseaddr) && (addr < atas[i].baseaddr + ATA_ADDR_SPACE) )
|
if ( (addr >= atas[i].baseaddr) && (addr < atas[i].baseaddr + ATA_ADDR_SPACE) )
|
*ata = &(atas[i]);
|
*ata = &(atas[i]);
|
}
|
}
|
|
|
/* verify we found a device */
|
/* verify we found a device */
|
if ( *ata == NULL )
|
if ( *ata == NULL )
|
return 0;
|
return 0;
|
|
|
/* Verify legal address */
|
/* Verify legal address */
|
if ( (addr - (*ata)->baseaddr) % 4 != 0 )
|
if ( (addr - (*ata)->baseaddr) % 4 != 0 )
|
return 0;
|
return 0;
|
|
|
*reladdr = addr - (*ata) -> baseaddr;
|
*reladdr = addr - (*ata) -> baseaddr;
|
return 1;
|
return 1;
|
}
|
}
|
/* ========================================================================= */
|
/* ========================================================================= */
|
|
|
|
|
/*
|
/*
|
Read a register
|
Read a register
|
*/
|
*/
|
uint32_t ata_read32( oraddr_t addr )
|
uint32_t ata_read32( oraddr_t addr, void *dat )
|
{
|
{
|
ata_host *ata;
|
ata_host *ata;
|
|
|
if ( !ata_find_device( addr, &ata, &addr ) ) {
|
if ( !ata_find_device( addr, &ata, &addr ) ) {
|
fprintf(stderr, "ata_read32( 0x%"PRIxADDR" ): Not in registered range(s)\n", addr );
|
fprintf(stderr, "ata_read32( 0x%"PRIxADDR" ): Not in registered range(s)\n", addr );
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/* determine if ata_host or ata_device addressed */
|
/* determine if ata_host or ata_device addressed */
|
if (is_ata_hostadr(addr))
|
if (is_ata_hostadr(addr))
|
{
|
{
|
// Accesses to internal register take 2cycles
|
// Accesses to internal register take 2cycles
|
adjust_rw_delay( ata->baseaddr, 2, 2 );
|
adjust_rw_delay( ata->baseaddr, 2, 2 );
|
|
|
switch( addr ) {
|
switch( addr ) {
|
case ATA_CTRL :
|
case ATA_CTRL :
|
return ata -> regs.ctrl;
|
return ata -> regs.ctrl;
|
|
|
case ATA_STAT :
|
case ATA_STAT :
|
return ata -> regs.stat;
|
return ata -> regs.stat;
|
|
|
case ATA_PCTR :
|
case ATA_PCTR :
|
return ata -> regs.pctr;
|
return ata -> regs.pctr;
|
|
|
#if (DEV_ID > 1)
|
#if (DEV_ID > 1)
|
case ATA_PFTR0:
|
case ATA_PFTR0:
|
return ata -> regs.pftr0;
|
return ata -> regs.pftr0;
|
|
|
case ATA_PFTR1:
|
case ATA_PFTR1:
|
return ata -> regs.pftr1;
|
return ata -> regs.pftr1;
|
#endif
|
#endif
|
|
|
#if (DEV_ID > 2)
|
#if (DEV_ID > 2)
|
case ATA_DTR0 :
|
case ATA_DTR0 :
|
return ata -> regs.dtr0;
|
return ata -> regs.dtr0;
|
|
|
case ATA_DTR1 :
|
case ATA_DTR1 :
|
return ata -> regs.dtr1;
|
return ata -> regs.dtr1;
|
|
|
case ATA_RXB :
|
case ATA_RXB :
|
return ata -> regs.rxb;
|
return ata -> regs.rxb;
|
#endif
|
#endif
|
|
|
default:
|
default:
|
return 0;
|
return 0;
|
}
|
}
|
}
|
}
|
else
|
else
|
/* check if the controller is enabled */
|
/* check if the controller is enabled */
|
if (ata->regs.ctrl & ATA_IDE_EN)
|
if (ata->regs.ctrl & ATA_IDE_EN)
|
{
|
{
|
// make sure simulator uses correct read/write delay timings
|
// make sure simulator uses correct read/write delay timings
|
#if (DEV_ID > 1)
|
#if (DEV_ID > 1)
|
if ( (addr & 0x7f) == ATA_DR)
|
if ( (addr & 0x7f) == ATA_DR)
|
{
|
{
|
if (ata->devices.dev)
|
if (ata->devices.dev)
|
adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.ftcr1), ata_pio_delay(ata->regs.ftcr1) );
|
adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.ftcr1), ata_pio_delay(ata->regs.ftcr1) );
|
else
|
else
|
adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.ftcr0), ata_pio_delay(ata->regs.ftcr0) );
|
adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.ftcr0), ata_pio_delay(ata->regs.ftcr0) );
|
}
|
}
|
else
|
else
|
#endif
|
#endif
|
adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.pctr), ata_pio_delay(ata->regs.pctr) );
|
adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.pctr), ata_pio_delay(ata->regs.pctr) );
|
|
|
return ata_devices_read(&ata->devices, addr & 0x7f);
|
return ata_devices_read(&ata->devices, addr & 0x7f);
|
}
|
}
|
}
|
}
|
/* ========================================================================= */
|
/* ========================================================================= */
|
|
|
|
|
/*
|
/*
|
Write a register
|
Write a register
|
*/
|
*/
|
void ata_write32( oraddr_t addr, uint32_t value )
|
void ata_write32( oraddr_t addr, uint32_t value, void *dat )
|
{
|
{
|
ata_host *ata;
|
ata_host *ata;
|
|
|
if ( !ata_find_device( addr, &ata, &addr ) )
|
if ( !ata_find_device( addr, &ata, &addr ) )
|
{
|
{
|
fprintf(stderr, "ata_write32( 0x%"PRIxADDR" ): Not in registered range(s)\n", addr );
|
fprintf(stderr, "ata_write32( 0x%"PRIxADDR" ): Not in registered range(s)\n", addr );
|
return;
|
return;
|
}
|
}
|
|
|
/* determine if ata_host or ata_device addressed */
|
/* determine if ata_host or ata_device addressed */
|
if (is_ata_hostadr(addr))
|
if (is_ata_hostadr(addr))
|
{
|
{
|
// Accesses to internal register take 2cycles
|
// Accesses to internal register take 2cycles
|
adjust_rw_delay( ata->baseaddr, 2, 2 );
|
adjust_rw_delay( ata->baseaddr, 2, 2 );
|
|
|
switch( addr ) {
|
switch( addr ) {
|
case ATA_CTRL :
|
case ATA_CTRL :
|
ata -> regs.ctrl = value;
|
ata -> regs.ctrl = value;
|
|
|
/* check if reset bit set, if so reset ata-devices */
|
/* check if reset bit set, if so reset ata-devices */
|
if (value & ATA_RST)
|
if (value & ATA_RST)
|
ata_devices_hw_reset(&ata->devices, 1);
|
ata_devices_hw_reset(&ata->devices, 1);
|
else
|
else
|
ata_devices_hw_reset(&ata->devices, 0);
|
ata_devices_hw_reset(&ata->devices, 0);
|
break;
|
break;
|
|
|
case ATA_STAT :
|
case ATA_STAT :
|
ata -> regs.stat = (ata -> regs.stat & ~ATA_IDEIS) | (ata -> regs.stat & ATA_IDEIS & value);
|
ata -> regs.stat = (ata -> regs.stat & ~ATA_IDEIS) | (ata -> regs.stat & ATA_IDEIS & value);
|
break;
|
break;
|
|
|
case ATA_PCTR :
|
case ATA_PCTR :
|
ata -> regs.pctr = value;
|
ata -> regs.pctr = value;
|
break;
|
break;
|
|
|
case ATA_PFTR0:
|
case ATA_PFTR0:
|
ata -> regs.pftr0 = value;
|
ata -> regs.pftr0 = value;
|
break;
|
break;
|
|
|
case ATA_PFTR1:
|
case ATA_PFTR1:
|
ata -> regs.pftr1 = value;
|
ata -> regs.pftr1 = value;
|
break;
|
break;
|
|
|
case ATA_DTR0 :
|
case ATA_DTR0 :
|
ata -> regs.dtr0 = value;
|
ata -> regs.dtr0 = value;
|
break;
|
break;
|
|
|
case ATA_DTR1 :
|
case ATA_DTR1 :
|
ata -> regs.dtr1 = value;
|
ata -> regs.dtr1 = value;
|
break;
|
break;
|
|
|
case ATA_TXB :
|
case ATA_TXB :
|
ata -> regs.txb = value;
|
ata -> regs.txb = value;
|
break;
|
break;
|
|
|
default:
|
default:
|
/* ERROR-macro currently only supports simple strings. */
|
/* ERROR-macro currently only supports simple strings. */
|
/*
|
/*
|
fprintf(stderr, "ERROR : Unknown register for OCIDEC(%1d).\n", DEV_ID );
|
fprintf(stderr, "ERROR : Unknown register for OCIDEC(%1d).\n", DEV_ID );
|
|
|
Tried to show some useful info here.
|
Tried to show some useful info here.
|
But when using 'DM'-simulator-command, the screen gets filled with these messages.
|
But when using 'DM'-simulator-command, the screen gets filled with these messages.
|
Thereby eradicating the usefulness of the message
|
Thereby eradicating the usefulness of the message
|
*/
|
*/
|
break;
|
break;
|
}
|
}
|
}
|
}
|
else
|
else
|
/* check if the controller is enabled */
|
/* check if the controller is enabled */
|
if (ata->regs.ctrl & ATA_IDE_EN)
|
if (ata->regs.ctrl & ATA_IDE_EN)
|
{
|
{
|
// make sure simulator uses correct read/write delay timings
|
// make sure simulator uses correct read/write delay timings
|
#if (DEV_ID > 1)
|
#if (DEV_ID > 1)
|
if ( (addr & 0x7f) == ATA_DR)
|
if ( (addr & 0x7f) == ATA_DR)
|
{
|
{
|
if (ata->devices.dev)
|
if (ata->devices.dev)
|
adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.ftcr1), ata_pio_delay(ata->regs.ftcr1) );
|
adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.ftcr1), ata_pio_delay(ata->regs.ftcr1) );
|
else
|
else
|
adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.ftcr0), ata_pio_delay(ata->regs.ftcr0) );
|
adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.ftcr0), ata_pio_delay(ata->regs.ftcr0) );
|
}
|
}
|
else
|
else
|
#endif
|
#endif
|
adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.pctr), ata_pio_delay(ata->regs.pctr) );
|
adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.pctr), ata_pio_delay(ata->regs.pctr) );
|
|
|
ata_devices_write(&ata->devices, addr & 0x7f, value);
|
ata_devices_write(&ata->devices, addr & 0x7f, value);
|
}
|
}
|
}
|
}
|
/* ========================================================================= */
|
/* ========================================================================= */
|
|
|
|
|
/* Dump status */
|
/* Dump status */
|
void ata_status( void )
|
void ata_status( void )
|
{
|
{
|
unsigned i;
|
unsigned i;
|
ata_host *ata;
|
ata_host *ata;
|
|
|
for ( i = 0; i < config.natas; i++ ) {
|
for ( i = 0; i < config.natas; i++ ) {
|
ata = &(atas[i]);
|
ata = &(atas[i]);
|
|
|
if ( ata->baseaddr == 0 )
|
if ( ata->baseaddr == 0 )
|
continue;
|
continue;
|
|
|
PRINTF( "\nOCIDEC-%1d %u at: 0x%"PRIxADDR"\n", DEV_ID, i, ata->baseaddr );
|
PRINTF( "\nOCIDEC-%1d %u at: 0x%"PRIxADDR"\n", DEV_ID, i, ata->baseaddr );
|
PRINTF( "ATA CTRL : 0x%08X\n", ata->regs.ctrl );
|
PRINTF( "ATA CTRL : 0x%08X\n", ata->regs.ctrl );
|
PRINTF( "ATA STAT : 0x%08x\n", ata->regs.stat );
|
PRINTF( "ATA STAT : 0x%08x\n", ata->regs.stat );
|
PRINTF( "ATA PCTR : 0x%08x\n", ata->regs.pctr );
|
PRINTF( "ATA PCTR : 0x%08x\n", ata->regs.pctr );
|
|
|
#if (DEV_ID > 1)
|
#if (DEV_ID > 1)
|
PRINTF( "ATA FCTR0 : 0x%08lx\n", ata->regs.pftr0 );
|
PRINTF( "ATA FCTR0 : 0x%08lx\n", ata->regs.pftr0 );
|
PRINTF( "ATA FCTR1 : 0x%08lx\n", ata->regs.pftr1 );
|
PRINTF( "ATA FCTR1 : 0x%08lx\n", ata->regs.pftr1 );
|
#endif
|
#endif
|
|
|
#if (DEV_ID > 2)
|
#if (DEV_ID > 2)
|
PRINTF( "ATA DTR0 : 0x%08lx\n", ata->regs.dtr0 );
|
PRINTF( "ATA DTR0 : 0x%08lx\n", ata->regs.dtr0 );
|
PRINTF( "ATA DTR1 : 0x%08lx\n", ata->regs.dtr1 );
|
PRINTF( "ATA DTR1 : 0x%08lx\n", ata->regs.dtr1 );
|
PRINTF( "ATA TXD : 0x%08lx\n", ata->regs.txb );
|
PRINTF( "ATA TXD : 0x%08lx\n", ata->regs.txb );
|
PRINTF( "ATA RXD : 0x%08lx\n", ata->regs.rxb );
|
PRINTF( "ATA RXD : 0x%08lx\n", ata->regs.rxb );
|
#endif
|
#endif
|
}
|
}
|
}
|
}
|
/* ========================================================================= */
|
/* ========================================================================= */
|
|
|
/*----------------------------------------------------[ ATA Configuration ]---*/
|
/*----------------------------------------------------[ ATA Configuration ]---*/
|
void ata_natas(union param_val val, void *dat)
|
void ata_natas(union param_val val, void *dat)
|
{
|
{
|
if (val.int_val >= 0 && val.int_val < MAX_ATAS)
|
if (val.int_val >= 0 && val.int_val < MAX_ATAS)
|
config.natas = val.int_val;
|
config.natas = val.int_val;
|
else
|
else
|
CONFIG_ERROR("invalid number of devices.");
|
CONFIG_ERROR("invalid number of devices.");
|
}
|
}
|
|
|
void ata_baseaddr(union param_val val, void *dat)
|
void ata_baseaddr(union param_val val, void *dat)
|
{
|
{
|
if (current_device >= 0 && current_device < config.natas)
|
if (current_device >= 0 && current_device < config.natas)
|
config.atas[current_device].baseaddr = val.addr_val;
|
config.atas[current_device].baseaddr = val.addr_val;
|
else
|
else
|
CONFIG_ERROR("invalid device number.");
|
CONFIG_ERROR("invalid device number.");
|
}
|
}
|
|
|
void ata_irq(union param_val val, void *dat)
|
void ata_irq(union param_val val, void *dat)
|
{
|
{
|
if (current_device >= 0 && current_device < config.natas)
|
if (current_device >= 0 && current_device < config.natas)
|
config.atas[current_device].irq = val.int_val;
|
config.atas[current_device].irq = val.int_val;
|
else
|
else
|
CONFIG_ERROR("invalid device number.");
|
CONFIG_ERROR("invalid device number.");
|
}
|
}
|
|
|
void ata_dev_type0(union param_val val, void *dat)
|
void ata_dev_type0(union param_val val, void *dat)
|
{
|
{
|
if (current_device >= 0 && current_device < config.natas)
|
if (current_device >= 0 && current_device < config.natas)
|
config.atas[current_device].dev_type0 = val.int_val;
|
config.atas[current_device].dev_type0 = val.int_val;
|
else
|
else
|
CONFIG_ERROR("invalid device number.");
|
CONFIG_ERROR("invalid device number.");
|
}
|
}
|
|
|
void ata_dev_file0(union param_val val, void *dat)
|
void ata_dev_file0(union param_val val, void *dat)
|
{
|
{
|
if (current_device >= 0 && current_device < config.natas)
|
if (current_device >= 0 && current_device < config.natas)
|
strcpy (config.atas[current_device].dev_file0, val.str_val);
|
strcpy (config.atas[current_device].dev_file0, val.str_val);
|
else
|
else
|
CONFIG_ERROR("invalid device number.");
|
CONFIG_ERROR("invalid device number.");
|
}
|
}
|
|
|
void ata_dev_size0(union param_val val, void *dat)
|
void ata_dev_size0(union param_val val, void *dat)
|
{
|
{
|
if (current_device >= 0 && current_device < config.natas)
|
if (current_device >= 0 && current_device < config.natas)
|
config.atas[current_device].dev_size0 = val.int_val;
|
config.atas[current_device].dev_size0 = val.int_val;
|
else
|
else
|
CONFIG_ERROR("invalid device number.");
|
CONFIG_ERROR("invalid device number.");
|
}
|
}
|
|
|
void ata_dev_packet0(union param_val val, void *dat)
|
void ata_dev_packet0(union param_val val, void *dat)
|
{
|
{
|
if (current_device >= 0 && current_device < config.natas)
|
if (current_device >= 0 && current_device < config.natas)
|
config.atas[current_device].dev_packet0 = val.int_val;
|
config.atas[current_device].dev_packet0 = val.int_val;
|
else
|
else
|
CONFIG_ERROR("invalid device number.");
|
CONFIG_ERROR("invalid device number.");
|
}
|
}
|
|
|
void ata_dev_type1(union param_val val, void *dat)
|
void ata_dev_type1(union param_val val, void *dat)
|
{
|
{
|
if (current_device >= 0 && current_device < config.natas)
|
if (current_device >= 0 && current_device < config.natas)
|
config.atas[current_device].dev_type1 = val.int_val;
|
config.atas[current_device].dev_type1 = val.int_val;
|
else
|
else
|
CONFIG_ERROR("invalid device number.");
|
CONFIG_ERROR("invalid device number.");
|
}
|
}
|
|
|
void ata_dev_file1(union param_val val, void *dat)
|
void ata_dev_file1(union param_val val, void *dat)
|
{
|
{
|
if (current_device >= 0 && current_device < config.natas)
|
if (current_device >= 0 && current_device < config.natas)
|
strcpy (config.atas[current_device].dev_file1, val.str_val);
|
strcpy (config.atas[current_device].dev_file1, val.str_val);
|
else
|
else
|
CONFIG_ERROR("invalid device number.");
|
CONFIG_ERROR("invalid device number.");
|
}
|
}
|
|
|
void ata_dev_size1(union param_val val, void *dat)
|
void ata_dev_size1(union param_val val, void *dat)
|
{
|
{
|
if (current_device >= 0 && current_device < config.natas)
|
if (current_device >= 0 && current_device < config.natas)
|
config.atas[current_device].dev_size1 = val.int_val;
|
config.atas[current_device].dev_size1 = val.int_val;
|
else
|
else
|
CONFIG_ERROR("invalid device number.");
|
CONFIG_ERROR("invalid device number.");
|
}
|
}
|
|
|
void ata_dev_packet1(union param_val val, void *dat)
|
void ata_dev_packet1(union param_val val, void *dat)
|
{
|
{
|
if (current_device >= 0 && current_device < config.natas)
|
if (current_device >= 0 && current_device < config.natas)
|
config.atas[current_device].dev_packet1 = val.int_val;
|
config.atas[current_device].dev_packet1 = val.int_val;
|
else
|
else
|
CONFIG_ERROR("invalid device number.");
|
CONFIG_ERROR("invalid device number.");
|
}
|
}
|
|
|
void reg_ata_sec(void)
|
void reg_ata_sec(void)
|
{
|
{
|
struct config_section *sec = reg_config_sec("ata", NULL, NULL);
|
struct config_section *sec = reg_config_sec("ata", NULL, NULL);
|
|
|
reg_config_param(sec, "natas", paramt_int, ata_natas);
|
reg_config_param(sec, "natas", paramt_int, ata_natas);
|
reg_config_param(sec, "device", paramt_int, change_device);
|
reg_config_param(sec, "device", paramt_int, change_device);
|
reg_config_param(sec, "baseaddr", paramt_addr, ata_baseaddr);
|
reg_config_param(sec, "baseaddr", paramt_addr, ata_baseaddr);
|
reg_config_param(sec, "irq", paramt_int, ata_irq);
|
reg_config_param(sec, "irq", paramt_int, ata_irq);
|
reg_config_param(sec, "dev_type0", paramt_int, ata_dev_type0);
|
reg_config_param(sec, "dev_type0", paramt_int, ata_dev_type0);
|
reg_config_param(sec, "dev_file0", paramt_str, ata_dev_file0);
|
reg_config_param(sec, "dev_file0", paramt_str, ata_dev_file0);
|
reg_config_param(sec, "dev_size0", paramt_int, ata_dev_size0);
|
reg_config_param(sec, "dev_size0", paramt_int, ata_dev_size0);
|
reg_config_param(sec, "dev_packet0", paramt_int, ata_dev_packet0);
|
reg_config_param(sec, "dev_packet0", paramt_int, ata_dev_packet0);
|
reg_config_param(sec, "dev_type1", paramt_int, ata_dev_type1);
|
reg_config_param(sec, "dev_type1", paramt_int, ata_dev_type1);
|
reg_config_param(sec, "dev_file1", paramt_str, ata_dev_file1);
|
reg_config_param(sec, "dev_file1", paramt_str, ata_dev_file1);
|
reg_config_param(sec, "dev_size1", paramt_int, ata_dev_size1);
|
reg_config_param(sec, "dev_size1", paramt_int, ata_dev_size1);
|
reg_config_param(sec, "dev_packet1", paramt_int, ata_dev_packet1);
|
reg_config_param(sec, "dev_packet1", paramt_int, ata_dev_packet1);
|
reg_config_param(sec, "enddevice", paramt_none, end_device);
|
reg_config_param(sec, "enddevice", paramt_none, end_device);
|
}
|
}
|
|
|