mirror of
https://github.com/rvtr/twl_wrapsdk.git
synced 2025-10-31 06:11:10 -04:00
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/twl_wrapsdk/trunk@96 4ee2a332-4b2b-5046-8439-1ba90f034370
419 lines
14 KiB
C
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) */
|
|
|