twl_wrapsdk/build/libraries/fatfs/ARM7/portio.c
Shirait 4fe5688d29 add SD driver and FATFS library (tentative)
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/twl_wrapsdk/trunk@96 4ee2a332-4b2b-5046-8439-1ba90f034370
2007-05-30 10:22:28 +00:00

419 lines
14 KiB
C

/*
* portio.c
*
* ERTFS Porting layer peripheral input output functions. The user must port
* some or all of the routines in this file to his CPU environment according
* to the rules set forth in the ERTFS porting specification.
*
* Copyright EBS Inc , 1993-2003
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
*
* Generic implementation of IO porting layer
* Modify these routnes for your target environment.
* Note: Not all routines must be implemented. Only implement
* those routines that are required for your selected set of devices.
*/
#include <twl.h>
#include <rtfs.h>
#include <rtfs_target_os.h>
/*--- ctr modified ---*/
#include <rtfsconf.h>
#if (RTFS_DEBUG_PRINT_ON == 1)
#if (CTR_DEF_ENVIRONMENT_DSEMU == 1)
#define PRINTDEBUG osTPrintf
#else
#include <ctr/vlink.h>
#define PRINTDEBUG vlink_dos_printf
#endif
#else
#define PRINTDEBUG i_no_print
static void i_no_print( const char *fmt, ... );
static void i_no_print( const char *fmt, ... ){ return; }
#endif
/*--------------------*/
/* All of the IO in and out functions in this file call one of these four
macros to write or read the apprpriate IO location. If t is convenient
to use this scheme and it will work for you then please modify these
macros to do the appropriate IO operation for the register. If this can't
be accomplished just modfy the appropriate routines manually.
*/
#define RTFS_OUTBYTE(ADDRESS,VALUE)
#define RTFS_INBYTE(ADDRESS) 0
#define RTFS_OUTWORD(ADDRESS,VALUE)
#define RTFS_INWORD(ADDRESS) 0
#define RTFS_OUTDWORD(ADDRESS,VALUE)
/* The code below must be implemented for all targets */
/*rtfs_port_disable() and rtfs_port_enable()
Used by a few device drivers, floppy, flash chip and pcmctrl,
you may ignore it if not being called, but first check to see
if floppy, flash chip and pcmctrl are still the only drivers
using the functions */
/*This function must disable interrupts and return. */
void rtfs_port_disable(void)
{ /* ctr modified */
PRINTDEBUG( "fatfs : rtfs_port_disable) is called.\n");
OSAPI_DISABLEINTR();
}
/*This function must re-disable interrupts that were disabled via a call to
rtfs_port_disable(). */
void rtfs_port_enable(void)
{ /* ctr modified */
PRINTDEBUG( "rtfs_port_enable is called.\n");
OSAPI_ENABLEINTR();
}
#if (INCLUDE_82365_PCMCTRL)
/* These routines are required only if the 82365 pcmcia controller driver
is included (pcmctrl.c)
phys82365_to_virtual(byte * * virt, dword phys)
write_82365_index_register(byte value)
write_82365_data_register(byte value)
read_82365_data_register(void)
*/
/* This routine must take a physical linear 32 bit bus address passed in
the "phys" argument and convert it to an address adressable in the logical
space of the CPU, returning that value in "virt". Two sample methods are
provided, a flat version where the virtual address is simply the "phys"
address cast to a pointer and a second segmented version for X86
segmented applications.
*/
void phys82365_to_virtual(byte * * virt, dword phys)
{
*virt = (byte *) phys; /* example for flat unmapped address space */
}
/*
These routines write and read the 82365's index and data registers which,
in a standard PC environment, are located in IO space at address 0x3E0 and
0x3E1. Non PC architectures typically map these as memory mapped locations
somewhere high in memory such as 0xB10003E0 and 0xB10003E1.
*/
void write_82365_index_register(byte value)
{
RTFS_OUTBYTE(0x3e0,value); /* Defined for X86. Replace with your own */
}
void write_82365_data_register(byte value)
{
RTFS_OUTBYTE(0x3e1,value); /* Defined for X86. Replace with your own */
}
byte read_82365_data_register(void)
{
byte v;
v = RTFS_INBYTE(0x3e1); /* Defined for X86. Replace with your own */
return (v);
}
#endif /* (INCLUDE_82365_PCMCTRL) */
/*
These routines are only required if INCLUDE_IDE is turned on (ide_drv.c)
byte ide_rd_status(dword register_file_address)
byte ide_rd_sector_count(dword register_file_address)
byte ide_rd_alt_status(dword register_file_address,int contiguous_io_mode)
byte ide_rd_error(dword register_file_address)
byte ide_rd_sector_number(dword register_file_address)
byte ide_rd_cyl_low(dword register_file_address)
byte ide_rd_cyl_high(dword register_file_address)
byte ide_rd_drive_head(dword register_file_address)
byte ide_rd_drive_address(dword register_file_address,int contiguous_io_mode)
void ide_wr_dig_out(dword register_file_address, int contiguous_io_mode, byte value);
void ide_wr_sector_count(dword register_file_address, byte value)
void ide_wr_sector_number(dword register_file_address, byte value)
void ide_wr_cyl_low(dword register_file_address, byte value)
void ide_wr_cyl_high(dword register_file_address, byte value)
void ide_wr_drive_head(dword register_file_address, byte value)
void ide_wr_command(dword register_file_address, byte value)
void ide_wr_feature(dword register_file_address, byte value)
unsigned long rtfs_port_bus_address(void * p)
void ide_insw(dword register_file_address, unsigned short *p, int nwords)
void ide_outsw(dword register_file_address, unsigned short *p, int nwords)
These routines are only required if INCLUDE_IDE
and INCLUDE_UDMA are turned on
dword rtfs_port_ide_bus_master_address(int controller_number)
byte ide_rd_udma_status(dword bus_master_address)
void ide_wr_udma_status(dword bus_master_address, byte value)
byte ide_rd_udma_command(dword bus_master_address)
void ide_wr_udma_command(dword bus_master_address, byte value)
void ide_wr_udma_address(dword bus_master_address, dword bus_address)
*/
#if (INCLUDE_IDE)
/* These routines are required only if using the IDE device driver */
/* This function must return the byte in location 7 (IDE_OFF_STATUS)
of the ide register file at register_file_address */
byte ide_rd_status(dword register_file_address)
{
return(RTFS_INBYTE((word) (register_file_address + 7)));
}
/* This function must return the word in location 0 (IDE_OFF_DATA)
of the ide register file at register_file_address */
word ide_rd_data(dword register_file_address)
{
return(RTFS_INWORD((word)register_file_address));
}
/* This function must return the byte in location 2 (IDE_OFF_SECTOR_COUNT)
of the ide register file at register_file_address */
byte ide_rd_sector_count(dword register_file_address)
{
return(RTFS_INBYTE((word) (register_file_address + 2)));
}
/* This function must return the byte in location 0x206 (IDE_OFF_ALT_STATUS)
of the ide register file at register_file_address If the value of the
argument contiguous_io_mode is 1 then the register must be 14 rather
than 0x206.
*/
byte ide_rd_alt_status(dword register_file_address, int contiguous_io_mode)
{
if (contiguous_io_mode)
return(RTFS_INBYTE((word) (register_file_address + 14)));
else
return(RTFS_INBYTE((word) (register_file_address + 0x206)));
}
/* This function must return the byte in location 1 (IDE_OFF_ERROR)
of the ide register file at register_file_address.
*/
byte ide_rd_error(dword register_file_address)
{
return(RTFS_INBYTE((word) (register_file_address + 1)));
}
/* This function must return the byte in location 3 (IDE_OFF_SECTOR_NUMBER)
of the ide register file at register_file_address
*/
byte ide_rd_sector_number(dword register_file_address)
{
return(RTFS_INBYTE((word) (register_file_address + 3)));
}
/* This function must return the byte in location 4 (IDE_OFF_CYL_LOW)
of the ide register file. register_file_address
*/
byte ide_rd_cyl_low(dword register_file_address)
{
return(RTFS_INBYTE((word) (register_file_address + 4)));
}
/* This function must return the byte in location 5 (IDE_OFF_CYL_HIGH)
of the ide register file. register_file_address
*/
byte ide_rd_cyl_high(dword register_file_address)
{
return(RTFS_INBYTE((word) (register_file_address + 5)));
}
/* This function must return the byte in location 6 (IDE_OFF_DRIVE_HEAD)
of the ide register file. register_file_address
*/
byte ide_rd_drive_head(dword register_file_address)
{
return(RTFS_INBYTE((word) (register_file_address + 6)));
}
/* This function must return the byte in location 0x207 (IDE_OFF_DRIVE_ADDRESS)
of the ide register file at register_file_address.
If the value of the argument contiguous_io_mode is 1 then the register
must be 15 rather than 0x207.
*/
byte ide_rd_drive_address(dword register_file_address,int contiguous_io_mode)
{
if (contiguous_io_mode)
return(RTFS_INBYTE((word) (register_file_address + 15)));
else
return(RTFS_INBYTE((word) (register_file_address + 0x207)));
}
/* This function must place the byte in value at location
0x206 (IDE_OFF_ALT_STATUS) of the ide register file at
register_file_address. If the value of the argument contiguous_io_mode
is 1 then the register must be 14 rather than 0x206.
*/
void ide_wr_dig_out(dword register_file_address, int contiguous_io_mode, byte value)
{
if (contiguous_io_mode)
RTFS_OUTBYTE((word) (register_file_address + 14), value);
else
RTFS_OUTBYTE((word) (register_file_address + 0x206), value);
}
/* This function must place the word in location 0 (IDE_OFF_DATA)
of the ide register file at register_file_address */
void ide_wr_data(dword register_file_address, word value)
{
RTFS_OUTWORD((word)register_file_address, value);
}
/* This function must place the byte in value at location
2 (IDE_OFF_SECTOR_COUNT) of the ide register file at
register_file_address
*/
void ide_wr_sector_count(dword register_file_address, byte value)
{
RTFS_OUTBYTE((word) (register_file_address + 2), value);
}
/* This function must place the byte in value at location
3 (IDE_OFF_SECTOR_NUMBER) of the ide register file at
register_file_address
*/
void ide_wr_sector_number(dword register_file_address, byte value)
{
RTFS_OUTBYTE((word) (register_file_address + 3), value);
}
/* This function must place the byte in value at location
4 (IDE_OFF_CYL_LOW) of the ide register file at
register_file_address
*/
void ide_wr_cyl_low(dword register_file_address, byte value)
{
RTFS_OUTBYTE((word) (register_file_address + 4), value);
}
/* This function must place the byte in value at location
5 (IDE_OFF_CYL_HIGH) of the ide register file at register_file_address
*/
void ide_wr_cyl_high(dword register_file_address, byte value)
{
RTFS_OUTBYTE((word) (register_file_address + 5), value);
}
/* This function must place the byte in value at location
6 (IDE_OFF_DRIVE_HEAD) of the ide register file at register_file_address
*/
void ide_wr_drive_head(dword register_file_address, byte value)
{
RTFS_OUTBYTE((word) (register_file_address + 6), value);
}
/* This function must place the byte in value at location
7 (IDE_OFF_COMMAND) of the ide register file at register_file_address */
void ide_wr_command(dword register_file_address, byte value)
{
RTFS_OUTBYTE((word) (register_file_address + 7), value);
}
/* This function must place the byte in value at location
1 (IDE_OFF_FEATURE) of the ide register file at register_file_address
*/
void ide_wr_feature(dword register_file_address, byte value)
{
RTFS_OUTBYTE((word) (register_file_address + 1), value);
}
/* This function must read nwords 16 bit values from the data
register at offset 0 of the the ide register file and place
them in succesive memory locations starting at p. Since large
blocks of data are transferred from the drive in this way this
routine should be optimized. On x86 based systems the repinsw
instruction should be used, on non x86 platforms the loop should
be as tight as possible.
*/
void ide_insw(dword register_file_address, unsigned short *p, int nwords)
{
while (nwords--)
*p++ = (word)RTFS_INWORD(register_file_address);
}
/*
This function must write nwords 16 bit values to the data
register at offset 0 of the the ide register file. The data is
taken from succesive memory locations starting at p. Since large
blocks of data are transferred from the drive in this way this
routine should be optimized. On x86 based systems the repoutsw
instruction should be used, on non x86 platforms the loop should
be as tight as possible.
*/
void ide_outsw(dword register_file_address, unsigned short *p, int nwords)
{
while (nwords--)
RTFS_OUTWORD(register_file_address, *p++);
}
#if (INCLUDE_UDMA)
/* These routines are required only if using an ultra-dma controller. */
/* This function must determine if the specified controller is a PCI bus
mastering IDE controller and if so return the location of the
control and status region for that controller. If it is not a bus
bus master controller it should return zero.
*/
dword rtfs_port_ide_bus_master_address(int controller_number)
{
RTFS_ARGSUSED_INT(controller_number);
return (0); /* Must be implemented. 0 return val disables UDMA */
}
/* This function must read the status byte value at location
2 the bus master control region
*/
byte ide_rd_udma_status(dword bus_master_address)
{
byte value;
value = RTFS_INBYTE((word) (bus_master_address + 2));
return (value);
}
/* This function must write the byte value to location
2 of the bus master control region
*/
void ide_wr_udma_status(dword bus_master_address, byte value)
{
RTFS_OUTBYTE((word) (bus_master_address + 2), value);
}
/* This function must read the command byte value at location
0 of the bus master control region
*/
byte ide_rd_udma_command(dword bus_master_address)
{
byte value;
value = RTFS_INBYTE((word) bus_master_address);
return (value);
}
/* This function must write the byte value to location
0 of the bus master control region
*/
void ide_wr_udma_command(dword bus_master_address, byte value)
{
RTFS_OUTBYTE((word) bus_master_address, value);
}
/* This function must write the byte dword to location
4 of the bus master control region
*/
void ide_wr_udma_address(dword bus_master_address, dword bus_address)
{
RTFS_OUTDWORD((word)(bus_master_address+4), bus_address);
}
/* This function must take a logical pointer and convert it to an
unsigned long representation of its address on the system bus */
unsigned long rtfs_port_bus_address(void * p)
{
dword laddress;
laddress = (dword) p;
return(laddress);
}
#endif /* (INCLUDE_UDMA) */
#endif /* (INCLUDE_IDE) */