Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Dreamcast
DCInfo
Commits
d396bdc1
Commit
d396bdc1
authored
Feb 19, 2024
by
Donald Haase
Browse files
Clean up whitespaces/formatting
parent
f9139649
Changes
5
Hide whitespace changes
Inline
Side-by-side
DCInfo.c
View file @
d396bdc1
...
...
@@ -10,48 +10,48 @@ KOS_INIT_FLAGS(INIT_DEFAULT);
typedef info_mod_return int;
typedef struct info_mod {
info_mod_return (*mod_main)(int);
info_mod_return (*mod_main)(int);
info_mod_return (*mod_timeout)(int);
int mod_main_default;
int mod_timeout;
} info_mod_t;
*/
/* My patented awesome data output that I did for MapleTest */
void
awesome_data_print
(
unsigned
char
*
data
,
unsigned
int
size
)
{
/* Bytes Per Line */
#define BPL 16
unsigned
int
i
=
0
;
unsigned
int
j
=
0
;
/* Bytes Per Line */
#define BPL 16
unsigned
int
i
=
0
;
unsigned
int
j
=
0
;
for
(
i
=
0
;
i
<
size
;
i
+=
BPL
)
{
printf
(
"Data+0x%.3x | "
,
i
);
for
(
j
=
0
;
j
<
BPL
;
j
++
)
printf
(
"%.2x "
,
data
[
i
+
j
]);
for
(
i
=
0
;
i
<
size
;
i
+=
BPL
)
{
printf
(
"Data+0x%.3x | "
,
i
);
for
(
j
=
0
;
j
<
BPL
;
j
++
)
printf
(
"%.2x "
,
data
[
i
+
j
]);
printf
(
"| "
);
printf
(
"| "
);
for
(
j
=
0
;
j
<
BPL
;
j
++
)
printf
(
"%c"
,
isprint
(
data
[
i
+
j
])
?
data
[
i
+
j
]
:
' '
);
printf
(
"|
\n
"
);
}
for
(
j
=
0
;
j
<
BPL
;
j
++
)
printf
(
"%c"
,
isprint
(
data
[
i
+
j
])
?
data
[
i
+
j
]
:
' '
);
printf
(
"|
\n
"
);
}
}
int
main
(
void
)
{
/* Stuff from my old 'HOLLY' program */
printf
(
"SB_SBREV
: 0x%.2x
\n
"
,
in8
(
SB_SBREV
));
/*
0x00 indicates a prototype G2 bus
0x12 indicates any other
*/
printf
(
"SB_G2ID
: 0x%.8x
\n
"
,
in32
(
SB_G2ID
));
printf
(
"ID
: 0x%.8x
\n
"
,
in32
(
ID
));
printf
(
"REVISION
: 0x%.4x
\n
"
,
in16
(
REVISION
));
printf
(
"SB_SBREV
: 0x%.2x
\n
"
,
in8
(
SB_SBREV
));
/*
0x00 indicates a prototype G2 bus
0x12 indicates any other
*/
printf
(
"SB_G2ID
: 0x%.8x
\n
"
,
in32
(
SB_G2ID
));
printf
(
"ID
: 0x%.8x
\n
"
,
in32
(
ID
));
printf
(
"REVISION
: 0x%.4x
\n
"
,
in16
(
REVISION
));
gdinfo_print
();
print_all_device_allinfo
(
2
);
return
0
;
print_all_device_allinfo
(
2
);
return
0
;
}
\ No newline at end of file
DCInfo.h
View file @
d396bdc1
void
awesome_data_print
(
unsigned
char
*
data
,
unsigned
int
size
);
/*
Trying to set up a reusable simple way to protect a while loop that has
a risk of stalling. Replace a while(X) with wdt_timeout_while(X, time)
*/
static
volatile
bool
__wdt_timeout_running
=
true
;
static
void
__wdt_timeout_callback
(
void
*
)
{
__wdt_timeout_running
=
false
;
wdt_disable
();
}
#define wdt_timeout_while(COND, WAIT) \
__wdt_timeout_running
=
true
;
\
wdt_enable_timer
(
0
,(
WAIT
),
15
,
__wdt_timeout_callback
,
0
);
\
while
((
COND
)
&&
__wdt_timeout_running
)
void
awesome_data_print
(
unsigned
char
*
data
,
unsigned
int
size
);
/*
Trying to set up a reusable simple way to protect a while loop that has
a risk of stalling. Replace a while(X) with wdt_timeout_while(X, time)
*/
static
volatile
bool
__wdt_timeout_running
=
true
;
static
void
__wdt_timeout_callback
(
void
*
)
{
__wdt_timeout_running
=
false
;
wdt_disable
();
}
#define wdt_timeout_while(COND, WAIT) \
__wdt_timeout_running = true; \
wdt_enable_timer(0,(WAIT),15,__wdt_timeout_callback,0); \
while((COND) && __wdt_timeout_running)
MapleTest.c
View file @
d396bdc1
/*
Part of the upgraded dcutils by Donald Haase.
Part of the upgraded dcutils by Donald Haase.
I wrote this to try to probe maple devices for
information. The goal is to gather up this
information in order to hopefully find distinctions
between devices we normally identify as being the
same, such as third party peripherals.
I wrote this to try to probe maple devices for
information. The goal is to gather up this
information in order to hopefully find distinctions
between devices we normally identify as being the
same, such as third party peripherals.
*/
#include
<kos.h>
...
...
@@ -17,118 +17,118 @@
/* The spec size of the maple receive buffer is 1024. A bit is added, just in case */
#define MAPLE_BUFF_SIZE (1024 + 32)
/* Local copy of the returned buffer for maple stuff */
unsigned
char
recv_buff
[
MAPLE_BUFF_SIZE
]
__attribute__
((
aligned
(
32
)));
unsigned
char
recv_buff
[
MAPLE_BUFF_SIZE
]
__attribute__
((
aligned
(
32
)));
static
void
vbl_allinfo_callback
(
maple_frame_t
*
frm
)
static
void
vbl_allinfo_callback
(
maple_frame_t
*
frm
)
{
maple_response_t
*
resp
;
/* So.. did we get a response? */
resp
=
(
maple_response_t
*
)
frm
->
recv_buf
;
if
(
resp
->
response
==
MAPLE_RESPONSE_ALLINFO
)
{
printf
(
"Received proper maple response
\n
"
);
/* Copy in the new buff */
memcpy
(
recv_buff
,
resp
,
MAPLE_BUFF_SIZE
);
}
else
printf
(
"maple: bad response %d on device
\n
"
,
resp
->
response
);
maple_frame_unlock
(
frm
);
fflush
(
stdout
);
maple_response_t
*
resp
;
/* So.. did we get a response? */
resp
=
(
maple_response_t
*
)
frm
->
recv_buf
;
if
(
resp
->
response
==
MAPLE_RESPONSE_ALLINFO
)
{
printf
(
"Received proper maple response
\n
"
);
/* Copy in the new buff */
memcpy
(
recv_buff
,
resp
,
MAPLE_BUFF_SIZE
);
}
else
printf
(
"maple: bad response %d on device
\n
"
,
resp
->
response
);
maple_frame_unlock
(
frm
);
fflush
(
stdout
);
}
/* Send a ALLINFO command for the given port/unit */
static
void
vbl_send_allinfo
(
int
p
,
int
u
)
static
void
vbl_send_allinfo
(
int
p
,
int
u
)
{
maple_device_t
*
dev
;
maple_device_t
*
dev
;
dev
=
&
maple_state
.
ports
[
p
].
units
[
u
];
dev
=
&
maple_state
.
ports
[
p
].
units
[
u
];
/* Reserve access; if we don't get it, forget about it */
if
(
maple_frame_lock
(
&
dev
->
frame
)
<
0
)
return
;
/* Reserve access; if we don't get it, forget about it */
if
(
maple_frame_lock
(
&
dev
->
frame
)
<
0
)
return
;
/* Setup our autodetect frame to probe at a new device */
maple_frame_init
(
&
dev
->
frame
);
dev
->
frame
.
cmd
=
MAPLE_COMMAND_ALLINFO
;
dev
->
frame
.
length
=
0
;
dev
->
frame
.
dst_port
=
p
;
dev
->
frame
.
dst_unit
=
u
;
dev
->
frame
.
callback
=
vbl_allinfo_callback
;
maple_queue_frame
(
&
dev
->
frame
);
/* Setup our autodetect frame to probe at a new device */
maple_frame_init
(
&
dev
->
frame
);
dev
->
frame
.
cmd
=
MAPLE_COMMAND_ALLINFO
;
dev
->
frame
.
length
=
0
;
dev
->
frame
.
dst_port
=
p
;
dev
->
frame
.
dst_unit
=
u
;
dev
->
frame
.
callback
=
vbl_allinfo_callback
;
maple_queue_frame
(
&
dev
->
frame
);
}
/* Formatted output for the devinfo struct */
void
print_devinfo
(
maple_devinfo_t
*
info
)
{
/* Print each piece of info in an itemized fashion */
printf
(
"Function int 0: %.8lx
\n
"
,
info
->
functions
);
printf
(
"Function int 1: %.8lx
\n
"
,
info
->
function_data
[
0
]);
printf
(
"Function int 2: %.8lx
\n
"
,
info
->
function_data
[
1
]);
printf
(
"Function int 3: %.8lx
\n
"
,
info
->
function_data
[
2
]);
printf
(
"Region Code: %.2x
\n
"
,
info
->
area_code
);
printf
(
"Connection : %.2x
\n
"
,
info
->
connector_direction
);
printf
(
"Product Name: %.30s
\n
"
,
info
->
product_name
);
printf
(
"Product License: %.60s
\n
"
,
info
->
product_license
);
printf
(
"Standby current consumption: %.4x
\n
"
,
info
->
standby_power
);
printf
(
"Maximum current consumption: %.4x
\n
"
,
info
->
max_power
);
printf
(
"
\n
"
);
fflush
(
stdout
);
/* Print each piece of info in an itemized fashion */
printf
(
"Function int 0: %.8lx
\n
"
,
info
->
functions
);
printf
(
"Function int 1: %.8lx
\n
"
,
info
->
function_data
[
0
]);
printf
(
"Function int 2: %.8lx
\n
"
,
info
->
function_data
[
1
]);
printf
(
"Function int 3: %.8lx
\n
"
,
info
->
function_data
[
2
]);
printf
(
"Region Code: %.2x
\n
"
,
info
->
area_code
);
printf
(
"Connection : %.2x
\n
"
,
info
->
connector_direction
);
printf
(
"Product Name: %.30s
\n
"
,
info
->
product_name
);
printf
(
"Product License: %.60s
\n
"
,
info
->
product_license
);
printf
(
"Standby current consumption: %.4x
\n
"
,
info
->
standby_power
);
printf
(
"Maximum current consumption: %.4x
\n
"
,
info
->
max_power
);
printf
(
"
\n
"
);
fflush
(
stdout
);
}
/*
Get and print the data returned by the ALLINFO command,
if extra=0 do not print the Free Data
if extra=1 print the amount of Free Data the device says it has
if extra=2 print a little more than that (what I've noticed to be the 'right' amount
if extra=3 print the entire returned data buffer
At extra=2 or 3 there may be lots of junk data, but some devices
have other info in there too.
/*
Get and print the data returned by the ALLINFO command,
if extra=0 do not print the Free Data
if extra=1 print the amount of Free Data the device says it has
if extra=2 print a little more than that (what I've noticed to be the 'right' amount
if extra=3 print the entire returned data buffer
At extra=2 or 3 there may be lots of junk data, but some devices
have other info in there too.
*/
void
print_device_allinfo
(
maple_device_t
*
dev
,
int
extra
)
{
unsigned
int
size
=
0
;
unsigned
int
size
=
0
;
maple_response_t
*
resp
=
(
maple_response_t
*
)
recv_buff
;
if
(
dev
==
NULL
)
return
;
if
(
dev
==
NULL
)
return
;
/* Clear the old buffer */
memset
(
recv_buff
,
0
,
MAPLE_BUFF_SIZE
);
/* Clear the old buffer */
memset
(
recv_buff
,
0
,
MAPLE_BUFF_SIZE
);
printf
(
"Trying to get the allinfo for device %c%c:
\n
"
,
'A'
+
(
dev
->
port
),
'0'
+
(
dev
->
unit
));
fflush
(
stdout
);
vbl_send_allinfo
((
dev
->
port
),
(
dev
->
unit
));
timer_spin_sleep
(
750
);
printf
(
"Trying to get the allinfo for device %c%c:
\n
"
,
'A'
+
(
dev
->
port
),
'0'
+
(
dev
->
unit
));
fflush
(
stdout
);
vbl_send_allinfo
((
dev
->
port
),
(
dev
->
unit
));
timer_spin_sleep
(
750
);
size
=
(
resp
->
data_len
*
4
);
printf
(
"Recieved %d bytes of data. Here it is:
\n
"
,
size
);
fflush
(
stdout
);
print_devinfo
((
maple_devinfo_t
*
)
&
recv_buff
[
4
]);
if
(
extra
==
0
)
return
;
else
if
(
extra
==
1
)
size
+=
4
;
/* Just grab the amount told we were getting + tiny pad */
else
if
(
extra
==
2
)
size
=
((
size
+
64
)
<
MAPLE_BUFF_SIZE
)
?
(
size
+
64
)
:
MAPLE_BUFF_SIZE
;
/* Grab just a little more */
else
if
(
extra
==
3
)
size
=
MAPLE_BUFF_SIZE
;
/* Grab the max amount */
size
=
(
resp
->
data_len
*
4
);
printf
(
"Recieved %d bytes of data. Here it is:
\n
"
,
size
);
fflush
(
stdout
);
print_devinfo
((
maple_devinfo_t
*
)
&
recv_buff
[
4
]);
printf
(
"Extra data:
\n
"
);
if
(
extra
==
0
)
return
;
else
if
(
extra
==
1
)
size
+=
4
;
/* Just grab the amount told we were getting + tiny pad */
else
if
(
extra
==
2
)
size
=
((
size
+
64
)
<
MAPLE_BUFF_SIZE
)
?
(
size
+
64
)
:
MAPLE_BUFF_SIZE
;
/* Grab just a little more */
else
if
(
extra
==
3
)
size
=
MAPLE_BUFF_SIZE
;
/* Grab the max amount */
printf
(
"Extra data:
\n
"
);
/* Really disgusting loop to print out a pretty copy of the data first in hex then ascii (if it is) */
awesome_data_print
(
recv_buff
+
(
4
+
112
),
size
);
printf
(
"End of Extra data
\n\n
"
);
fflush
(
stdout
);
printf
(
"End of Extra data
\n\n
"
);
fflush
(
stdout
);
}
/*
Get the total number of maple devices,
then perform print_device_allinfo on each
/*
Get the total number of maple devices,
then perform print_device_allinfo on each
*/
void
print_all_device_allinfo
(
int
extra
)
{
int
i
=
0
,
num
=
maple_enum_count
();
printf
(
"Going to print info on all [%d] devices found:
\n
"
,
num
);
fflush
(
stdout
);
int
i
=
0
,
num
=
maple_enum_count
();
printf
(
"Going to print info on all [%d] devices found:
\n
"
,
num
);
fflush
(
stdout
);
for
(;
i
<
num
;
i
++
)
print_device_allinfo
(
maple_enum_type
(
i
,
0xffffffff
),
extra
);
for
(;
i
<
num
;
i
++
)
print_device_allinfo
(
maple_enum_type
(
i
,
0xffffffff
),
extra
);
printf
(
"That's all the devices attached.
\n
"
);
fflush
(
stdout
);
printf
(
"That's all the devices attached.
\n
"
);
fflush
(
stdout
);
}
gdinfo.c
View file @
d396bdc1
/*
This program, along with MapleTest will eventually go into some
sort of larger test/probing/hwinfo suite for the DC. For now, it
might help provide some info on differing DC GD infos.
The biggest reason to release it standalone is to allow for it to
get 'alpha tested', the core users with serial/bba who care to do
something like this is small, so yay.
Thanks go to drk||raziel for some bits of the code used here.
(c) Donald Haase 2008
*/
#include
<kos.h>
#include
"gdinfo.h"
#include
"DCInfo.h"
void
out32
(
unsigned
int
addr
,
unsigned
int
data
)
{
volatile
unsigned
int
*
p
=
(
volatile
unsigned
int
*
)
addr
;
*
p
=
data
;
}
void
out16
(
unsigned
int
addr
,
unsigned
short
data
)
{
volatile
unsigned
short
*
p
=
(
volatile
unsigned
short
*
)
addr
;
*
p
=
data
;
}
void
out8
(
unsigned
int
addr
,
unsigned
char
data
)
{
volatile
unsigned
char
*
p
=
(
volatile
unsigned
char
*
)
addr
;
*
p
=
data
;
}
unsigned
int
in32
(
unsigned
int
addr
)
{
volatile
unsigned
int
*
p
=
(
volatile
unsigned
int
*
)
addr
;
return
*
p
;
}
unsigned
short
in16
(
unsigned
int
addr
)
{
volatile
unsigned
short
*
p
=
(
volatile
unsigned
short
*
)
addr
;
return
*
p
;
}
unsigned
char
in8
(
unsigned
int
addr
)
{
volatile
unsigned
char
*
p
=
(
volatile
unsigned
char
*
)
addr
;
return
*
p
;
}
unsigned
int
gd_error
(
void
)
{
return
in8
(
GD_ALTSTAT_Read
)
&
ST_CHECK
;
}
void
gd_ack_cmdint
(
void
)
{
in8
(
GD_STATUS_Read
);
//reading status ack's the interrupt
}
/* wait for the interrupt */
void
gd_wait_cmdint
(
void
)
{
wdt_timeout_while
(((
in8
(
SB_ISTEXT
)
&
1
)
==
0
),
10000
);
gd_ack_cmdint
();
}
void
gd_wait_stat
(
unsigned
int
msk
,
unsigned
int
val
)
{
wdt_timeout_while
(
((
in8
(
GD_ALTSTAT_Read
)
&
msk
)
!=
val
),
10000
);
}
unsigned
int
gd_ATA_IDENTIFY_PACKET_DEV
(
unsigned
short
*
out
,
unsigned
int
*
out_size
)
{
unsigned
int
i
;
unsigned
int
data_to_Read
;
*
out_size
=
0
;
//ST_BSY,ST_DRQ -> 0
gd_wait_stat
(
ST_BSY
|
ST_DRQ
,
0
);
out8
(
GD_COMMAND_Write
,
ATA_IDENTIFY_PACKET_DEV
);
/* Wait until the data bit is ready. USB-GDROM spins here forever. */
gd_wait_stat
(
ST_DRQ
,
ST_DRQ
);
/* Check if data was prepared and is ready */
if
((
in8
(
GD_ALTSTAT_Read
)
&
ST_DRQ
)
==
0
)
{
printf
(
"gd_ATA_IDENTIFY_PACKET_DEV: controller has no data ready"
);
return
gd_error
();
}
/* Have to do these seperately to avoid optimization */
data_to_Read
=
in8
(
GD_BYCTLLO
);
data_to_Read
+=
in8
(
GD_BYCTLHI
)
<<
8
;
*
out_size
=
data_to_Read
;
data_to_Read
>>=
1
;
gd_ack_cmdint
();
//Read data !
for
(
i
=
0
;
i
<
data_to_Read
;
i
++
)
out
[
i
]
=
in16
(
GD_DATA
);
/* Wait until the command is done */
gd_wait_cmdint
();
return
gd_error
();
}
unsigned
int
gd_spi_pio
(
spi_p
*
cmd
,
unsigned
short
*
out
,
unsigned
int
*
out_size
)
{
unsigned
int
i
;
unsigned
int
data_to_Read
;
*
out_size
=
0
;
//ST_BSY,ST_DRQ -> 0
gd_wait_stat
(
ST_BSY
|
ST_DRQ
,
0
);
out8
(
GD_COMMAND_Write
,
ATA_SPI_PACKET
);
//CoD/IO -> not used , we wait on the DRQ
//DRQ -> 1
gd_wait_stat
(
ST_DRQ
,
ST_DRQ
);
gd_ack_cmdint
();
//Make sure the interrupt bit is _not_ set
//Write the command
for
(
i
=
0
;
i
<
6
;
i
++
)
out16
(
GD_DATA
,
cmd
->
w
[
i
]);
//wait for cmd interrupt to be raised
gd_wait_cmdint
();
/* Check if data was prepared and is ready */
if
((
in8
(
GD_ALTSTAT_Read
)
&
ST_DRQ
)
==
0
)
{
printf
(
"gd_spi_pio: controller has no data ready"
);
return
gd_error
();
}
data_to_Read
=
in8
(
GD_BYCTLLO
);
data_to_Read
+=
in8
(
GD_BYCTLHI
)
<<
8
;
*
out_size
=
data_to_Read
;
printf
(
"%d bytes to read from GDROM
\n
"
,
data_to_Read
);
data_to_Read
>>=
1
;
gd_ack_cmdint
();
/* Read data ! */
for
(
i
=
0
;
i
<
data_to_Read
;
i
++
)
out
[
i
]
=
in16
(
GD_DATA
);
/* Wait for interrupt :) */
gd_wait_cmdint
();
return
gd_error
();
}
/* Perform the Executive Device Diagnostic command. The return is read from the error register */
unsigned
int
gd_ATA_EXEC_DEV_DIAG
(
void
)
{
//ST_BSY,ST_DRQ -> 0
gd_wait_stat
(
ST_BSY
|
ST_DRQ
,
0
);
out8
(
GD_COMMAND_Write
,
ATA_EXEC_DEV_DIAG
);
gd_wait_stat
(
ST_BSY
,
0
);
return
in8
(
GD_ERROR_Read
);
}
/* Perform a Soft Reset The return is read from the error register */
unsigned
int
gd_ATA_SOFT_RESET
(
void
)
{
//ST_BSY,ST_DRQ -> 0
gd_wait_stat
(
ST_BSY
|
ST_DRQ
,
0
);
out8
(
GD_COMMAND_Write
,
ATA_SOFT_RESET
);
gd_wait_stat
(
ST_BSY
,
0
);
return
in8
(
GD_ERROR_Read
);
}
void
gd_REQ_MODE
(
unsigned
short
*
out
,
unsigned
int
*
out_size
)
{
spi_p
cmd
;
/* Zero the command */
cmd
.
d
[
0
]
=
0
;
cmd
.
d
[
1
]
=
0
;
cmd
.
d
[
2
]
=
0
;
/*
0 is the command, like all others
4 is the length like most others
*/
cmd
.
b
[
0
]
=
0x11
;
cmd
.
b
[
4
]
=
32
;
gd_spi_pio
(
&
cmd
,
out
,
out_size
);
}
void
gdinfo_print
(
void
)
{
unsigned
char
*
GD_INFO
;
unsigned
char
*
REQMODE
;
unsigned
int
size
=
0
;
/* Allocate the data */
GD_INFO
=
memalign
(
32
,
512
);
REQMODE
=
memalign
(
32
,
32
);
/* Issue the ATA Command 'Executive Device Diagnostic' */
/* 1 should be 'OK', all other values would be other problems */
printf
(
"gd_ATA_EXEC_DEV_DIAG returned: 0x%.2x
\n
"
,
gd_ATA_EXEC_DEV_DIAG
());
/* Issue the ATA Command 'Identify Packet Device' */
printf
(
"Running gd_ATA_IDENTIFY_PACKET_DEV: "
);
gd_ATA_IDENTIFY_PACKET_DEV
((
unsigned
short
*
)
GD_INFO
,
&
size
);
printf
(
"Got %d bytes of data back
\n
"
,
size
);
awesome_data_print
(
GD_INFO
,
size
);
/* Issue the SIP Command 'REQ MODE' */
printf
(
"Running gd_REQ_MODE: "
);
gd_REQ_MODE
((
unsigned
short
*
)
REQMODE
,
&
size
);
printf
(
"Got %d bytes of data back
\n
"
,
size
);
awesome_data_print
(
REQMODE
,
size
);
/* Free the allocated memory */
free
(
GD_INFO
);
free
(
REQMODE
);
return
;
}
/*
This program, along with MapleTest will eventually go into some
sort of larger test/probing/hwinfo suite for the DC. For now, it
might help provide some info on differing DC GD infos.
The biggest reason to release it standalone is to allow for it to
get 'alpha tested', the core users with serial/bba who care to do
something like this is small, so yay.
Thanks go to drk||raziel for some bits of the code used here.
(c) Donald Haase 2008
*/
#include
<kos.h>
#include
"gdinfo.h"
#include
"DCInfo.h"
void
out32
(
unsigned
int
addr
,
unsigned
int
data
)
{
volatile
unsigned
int
*
p
=
(
volatile
unsigned
int
*
)
addr
;
*
p
=
data
;
}
void
out16
(
unsigned
int
addr
,
unsigned
short
data
)
{
volatile
unsigned
short
*
p
=
(
volatile
unsigned
short
*
)
addr
;
*
p
=
data
;
}
void
out8
(
unsigned
int
addr
,
unsigned
char
data
)
{
volatile
unsigned
char
*
p
=
(
volatile
unsigned
char
*
)
addr
;
*
p
=
data
;
}
unsigned
int
in32
(
unsigned
int
addr
)
{
volatile
unsigned
int
*
p
=
(
volatile
unsigned
int
*
)
addr
;
return
*
p
;
}
unsigned
short
in16
(
unsigned
int
addr
)
{
volatile
unsigned
short
*
p
=
(
volatile
unsigned
short
*
)
addr
;
return
*
p
;
}
unsigned
char
in8
(
unsigned
int
addr
)
{
volatile
unsigned
char
*
p
=
(
volatile
unsigned
char
*
)
addr
;
return
*
p
;
}
unsigned
int
gd_error
(
void
)
{
return
in8
(
GD_ALTSTAT_Read
)
&
ST_CHECK
;
}
void
gd_ack_cmdint
(
void
)
{
in8
(
GD_STATUS_Read
);
//reading status ack's the interrupt
}
/* wait for the interrupt */
void
gd_wait_cmdint
(
void
)
{
wdt_timeout_while
(((
in8
(
SB_ISTEXT
)
&
1
)
==
0
),
10000
);
gd_ack_cmdint
();
}
void
gd_wait_stat
(
unsigned
int
msk
,
unsigned
int
val
)
{
wdt_timeout_while
(
((
in8
(
GD_ALTSTAT_Read
)
&
msk
)
!=
val
),
10000
);
}
unsigned
int
gd_ATA_IDENTIFY_PACKET_DEV
(
unsigned
short
*
out
,
unsigned
int
*
out_size
)
{
unsigned
int
i
;
unsigned
int
data_to_Read
;
*
out_size
=
0
;
//ST_BSY,ST_DRQ -> 0
gd_wait_stat
(
ST_BSY
|
ST_DRQ
,
0
);
out8
(
GD_COMMAND_Write
,
ATA_IDENTIFY_PACKET_DEV
);
/* Wait until the data bit is ready. USB-GDROM spins here forever. */
gd_wait_stat
(
ST_DRQ
,
ST_DRQ
);
/* Check if data was prepared and is ready */
if
((
in8
(
GD_ALTSTAT_Read
)
&
ST_DRQ
)
==
0
)
{
printf
(
"gd_ATA_IDENTIFY_PACKET_DEV: controller has no data ready"
);
return
gd_error
();
}
/* Have to do these seperately to avoid optimization */
data_to_Read
=
in8
(
GD_BYCTLLO
);
data_to_Read
+=
in8
(
GD_BYCTLHI
)
<<
8
;
*
out_size
=
data_to_Read
;
data_to_Read
>>=
1
;
gd_ack_cmdint
();
//Read data !
for
(
i
=
0
;
i
<
data_to_Read
;
i
++
)
out
[
i
]
=
in16
(
GD_DATA
);
/* Wait until the command is done */
gd_wait_cmdint
();
return
gd_error
();
}
unsigned
int
gd_spi_pio
(
spi_p
*
cmd
,
unsigned
short
*
out
,
unsigned
int
*
out_size
)
{
unsigned
int
i
;
unsigned
int
data_to_Read
;
*
out_size
=
0
;
//ST_BSY,ST_DRQ -> 0
gd_wait_stat
(
ST_BSY
|
ST_DRQ
,
0
);
out8
(
GD_COMMAND_Write
,
ATA_SPI_PACKET
);
//CoD/IO -> not used , we wait on the DRQ
//DRQ -> 1
gd_wait_stat
(
ST_DRQ
,
ST_DRQ
);
gd_ack_cmdint
();
//Make sure the interrupt bit is _not_ set
//Write the command
for
(
i
=
0
;
i
<
6
;
i
++
)
out16
(
GD_DATA
,
cmd
->
w
[
i
]);
//wait for cmd interrupt to be raised
gd_wait_cmdint
();
/* Check if data was prepared and is ready */
if
((
in8
(
GD_ALTSTAT_Read
)
&
ST_DRQ
)
==
0
)
{
printf
(
"gd_spi_pio: controller has no data ready"
);
return
gd_error
();
}
data_to_Read
=
in8
(
GD_BYCTLLO
);
data_to_Read
+=
in8
(
GD_BYCTLHI
)
<<
8
;
*
out_size
=
data_to_Read
;
printf
(
"%d bytes to read from GDROM
\n
"
,
data_to_Read
);
data_to_Read
>>=
1
;
gd_ack_cmdint
();
/* Read data ! */
for
(
i
=
0
;
i
<
data_to_Read
;
i
++
)
out
[
i
]
=
in16
(
GD_DATA
);
/* Wait for interrupt :) */
gd_wait_cmdint
();
return
gd_error
();
}
/* Perform the Executive Device Diagnostic command. The return is read from the error register */
unsigned
int
gd_ATA_EXEC_DEV_DIAG
(
void
)
{
//ST_BSY,ST_DRQ -> 0
gd_wait_stat
(
ST_BSY
|
ST_DRQ
,
0
);
out8
(
GD_COMMAND_Write
,
ATA_EXEC_DEV_DIAG
);
gd_wait_stat
(
ST_BSY
,
0
);
return
in8
(
GD_ERROR_Read
);
}
/* Perform a Soft Reset The return is read from the error register */
unsigned
int
gd_ATA_SOFT_RESET
(
void
)
{
//ST_BSY,ST_DRQ -> 0
gd_wait_stat
(
ST_BSY
|
ST_DRQ
,
0
);
out8
(
GD_COMMAND_Write
,
ATA_SOFT_RESET
);
gd_wait_stat
(
ST_BSY
,
0
);
return
in8
(
GD_ERROR_Read
);
}
void
gd_REQ_MODE
(
unsigned
short
*
out
,
unsigned
int
*
out_size
)
{
spi_p
cmd
;
/* Zero the command */
cmd
.
d
[
0
]
=
0
;
cmd
.
d
[
1
]
=
0
;
cmd
.
d
[
2
]
=
0
;
/*
0 is the command, like all others
4 is the length like most others
*/
cmd
.
b
[
0
]
=
0x11
;
cmd
.
b
[
4
]
=
32
;
gd_spi_pio
(
&
cmd
,
out
,
out_size
);
}
void
gdinfo_print
(
void
)
{
unsigned
char
*
GD_INFO
;
unsigned
char
*
REQMODE
;
unsigned
int
size
=
0
;
/* Allocate the data */
GD_INFO
=
memalign
(
32
,
512
);
REQMODE
=
memalign
(
32
,
32
);
/* Issue the ATA Command 'Executive Device Diagnostic' */
/* 1 should be 'OK', all other values would be other problems */
printf
(
"gd_ATA_EXEC_DEV_DIAG returned: 0x%.2x
\n
"
,
gd_ATA_EXEC_DEV_DIAG
());
/* Issue the ATA Command 'Identify Packet Device' */
printf
(
"Running gd_ATA_IDENTIFY_PACKET_DEV: "
);
gd_ATA_IDENTIFY_PACKET_DEV
((
unsigned
short
*
)
GD_INFO
,
&
size
);
printf
(
"Got %d bytes of data back
\n
"
,
size
);
awesome_data_print
(
GD_INFO
,
size
);
/* Issue the SIP Command 'REQ MODE' */
printf
(
"Running gd_REQ_MODE: "
);
gd_REQ_MODE
((
unsigned
short
*
)
REQMODE
,
&
size
);
printf
(
"Got %d bytes of data back
\n
"
,
size
);
awesome_data_print
(
REQMODE
,
size
);
/* Free the allocated memory */
free
(
GD_INFO
);
free
(
REQMODE
);
return
;
}
gdinfo.h
View file @
d396bdc1
/*
This header declares all the stuff needed to issue ATA and SPI commands
*/
typedef
union
{
unsigned
char
b
[
12
];
unsigned
short
w
[
6
];
unsigned
int
d
[
3
];
}
spi_p
;
/* GD Controller registers */
#define GD_ALTSTAT_Read
0xA05F7018
// (R) |BSY|DRDY|DF|DSC|DRQ|CORR|Reserved|CHECK|
#define GD_DEVCTRL_Write
0xA05F7018
// (W) Device Control |R|R|R|R|1|SRST|nIEN|0|
#define GD_DATA
0xA05F7080
// (RW)
Data / Data
#define GD_ERROR_Read
0xA05F7084
// (R) Error |SENSE(4)|MCR|ABRT|EOMF|ILI|
#define GD_FEATURES_Write
0xA05F7084
// (W) Features |Reserved(7)|DMA| or |SetClear|FeatNum(7)|
#define GD_IREASON_Read
0xA05F7088
// (R) Interrupt Reason |Reserved(6)|IO|CoD|
#define GD_SECTCNT_Write
0xA05F7088
// (W) Sector Count |XFerMode(4)|ModeVal(4)|
#define GD_SECTNUM
0xA05F708C
// (RW) Sector Number |DiscFmt(4)|Status(4)|
#define GD_BYCTLLO
0xA05F7090
// (RW) 0x005F7090
Byte Control Low / Byte Control Low
#define GD_BYCTLHI
0xA05F7094
// (RW) 0x005F7094
Byte Control High / Byte Control High
#define GD_DRVSEL
0xA05F7098
// (RW) Unused |1|R|1|0|LUN(4)|
#define GD_STATUS_Read
0xA05F709C
// (R) |BSY|DRDY|DF|DSC|DRQ|CORR|Reserved|CHECK|
#define GD_COMMAND_Write
0xA05F709C
// (W) Command
#define GDROM_REACTIVATE
0xA05F74E4
/* ATA Commands */
#define ATA_SOFT_RESET
0x08
#define ATA_EXEC_DEV_DIAG
0x90
#define ATA_SPI_PACKET
0xA0
#define ATA_IDENTIFY_PACKET_DEV
0xA1
#define SB_ISTNRM 0xA05F6900
//0x005F6900
SB_ISTNRM
RW
Normal interrupt status
#define SB_ISTEXT 0xA05F6904
//0x005F6904
SB_ISTEXT
R
al interrupt status
//BSY
DRDY
DF
DSC
DRQ
CORR
Reserved
CHECK
#define ST_BSY
(1<<7)
#define ST_DRDY
(1<<6)
#define ST_DF
(1<<5)
#define ST_DSC
(1<<4)
#define ST_DRQ
(1<<3)
#define ST_CORR
(1<<2)
#define ST_Reserved (1<<1)
#define ST_CHECK
(1<<0)
/* Macro functions for waiting for certain register info */
unsigned
int
gd_error
(
void
);
void
gd_ack_cmdint
(
void
);
void
gd_wait_cmdint
(
void
);
void
gd_wait_stat
(
unsigned
int
,
unsigned
int
);
/* Functions to send ATA commands to the GD */
unsigned
int
gd_ATA_IDENTIFY_PACKET_DEV
(
unsigned
short
*
out
,
unsigned
int
*
out_size
);
unsigned
int
gd_ATA_EXEC_DEV_DIAG
(
void
);
/* A function for sending PACKET commands, then a function that sends one */
unsigned
int
gd_spi_pio
(
spi_p
*
cmd
,
unsigned
short
*
out
,
unsigned
int
*
out_size
);
void
gd_REQ_MODE
(
unsigned
short
*
out
,
unsigned
int
*
out_size
);
void
gdinfo_print
(
void
);
/*
This header declares all the stuff needed to issue ATA and SPI commands
*/
typedef
union
{
unsigned
char
b
[
12
];
unsigned
short
w
[
6
];
unsigned
int
d
[
3
];
}
spi_p
;
/* GD Controller registers */
#define GD_ALTSTAT_Read
0xA05F7018
// (R) |BSY|DRDY|DF|DSC|DRQ|CORR|Reserved|CHECK|
#define GD_DEVCTRL_Write
0xA05F7018
// (W) Device Control |R|R|R|R|1|SRST|nIEN|0|
#define GD_DATA
0xA05F7080
// (RW)
Data / Data
#define GD_ERROR_Read
0xA05F7084
// (R) Error |SENSE(4)|MCR|ABRT|EOMF|ILI|
#define GD_FEATURES_Write
0xA05F7084
// (W) Features |Reserved(7)|DMA| or |SetClear|FeatNum(7)|
#define GD_IREASON_Read
0xA05F7088
// (R) Interrupt Reason |Reserved(6)|IO|CoD|
#define GD_SECTCNT_Write
0xA05F7088
// (W) Sector Count |XFerMode(4)|ModeVal(4)|
#define GD_SECTNUM
0xA05F708C
// (RW) Sector Number |DiscFmt(4)|Status(4)|
#define GD_BYCTLLO
0xA05F7090
// (RW) 0x005F7090
Byte Control Low / Byte Control Low
#define GD_BYCTLHI
0xA05F7094
// (RW) 0x005F7094
Byte Control High / Byte Control High
#define GD_DRVSEL
0xA05F7098
// (RW) Unused |1|R|1|0|LUN(4)|
#define GD_STATUS_Read
0xA05F709C
// (R) |BSY|DRDY|DF|DSC|DRQ|CORR|Reserved|CHECK|
#define GD_COMMAND_Write
0xA05F709C
// (W) Command
#define GDROM_REACTIVATE
0xA05F74E4
/* ATA Commands */
#define ATA_SOFT_RESET
0x08
#define ATA_EXEC_DEV_DIAG
0x90
#define ATA_SPI_PACKET
0xA0
#define ATA_IDENTIFY_PACKET_DEV
0xA1
#define SB_ISTNRM 0xA05F6900
//0x005F6900
SB_ISTNRM
RW
Normal interrupt status
#define SB_ISTEXT 0xA05F6904
//0x005F6904
SB_ISTEXT
R
al interrupt status
//BSY
DRDY
DF
DSC
DRQ
CORR
Reserved
CHECK
#define ST_BSY
(1<<7)
#define ST_DRDY
(1<<6)
#define ST_DF
(1<<5)
#define ST_DSC
(1<<4)
#define ST_DRQ
(1<<3)
#define ST_CORR
(1<<2)
#define ST_Reserved (1<<1)
#define ST_CHECK
(1<<0)
/* Macro functions for waiting for certain register info */
unsigned
int
gd_error
(
void
);
void
gd_ack_cmdint
(
void
);
void
gd_wait_cmdint
(
void
);
void
gd_wait_stat
(
unsigned
int
,
unsigned
int
);
/* Functions to send ATA commands to the GD */
unsigned
int
gd_ATA_IDENTIFY_PACKET_DEV
(
unsigned
short
*
out
,
unsigned
int
*
out_size
);
unsigned
int
gd_ATA_EXEC_DEV_DIAG
(
void
);
/* A function for sending PACKET commands, then a function that sends one */
unsigned
int
gd_spi_pio
(
spi_p
*
cmd
,
unsigned
short
*
out
,
unsigned
int
*
out_size
);
void
gd_REQ_MODE
(
unsigned
short
*
out
,
unsigned
int
*
out_size
);
void
gdinfo_print
(
void
);
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment