URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/or1k/trunk/orpmon/cmds
- from Rev 1312 to Rev 1765
- ↔ Reverse comparison
Rev 1312 → Rev 1765
/load.c
0,0 → 1,594
#include "common.h" |
#include "support.h" |
#include "flash.h" |
#include "net.h" |
#include "uart.h" |
#include "spr_defs.h" |
|
#ifndef MAX_IMAGES |
#define MAX_IMAGES 20 |
#endif |
|
extern unsigned long fprog_addr; |
extern char *tftp_filename; |
|
static flash_cfg_struct __attribute__ ((section(".config"))) gcfg = { 0, 0, 0, 0 }; |
|
#define FLASH_IMAGES_BASE 0xf0300000 |
|
/* Buffer Address == for example internal RAM */ |
#define BUF_BASE_ADDR 0x00400000 - 0x00042000 |
#define BUF_LENGTH 4096 |
|
|
#define ALIGN(addr,size) ((addr + (size-1))&(~(size-1))) |
|
void copy_and_boot(unsigned long src, |
unsigned long dst, |
unsigned long len, |
int tx_next) |
{ |
__asm__ __volatile__(" ;\ |
l.addi r8,r0,0x1 ;\ |
l.mtspr r0,r8,0x11 ;\ |
l.nop ;\ |
l.nop ;\ |
l.nop ;\ |
l.nop ;\ |
l.nop ;\ |
2: ;\ |
l.sfgeu r4,r5 ;\ |
l.bf 1f ;\ |
l.nop ;\ |
l.lwz r8,0(r3) ;\ |
l.sw 0(r4),r8 ;\ |
l.addi r3,r3,4 ;\ |
l.j 2b ;\ |
l.addi r4,r4,4 ;\ |
1: l.sw 0x0(r0),r6 ;\ |
l.ori r8,r0,0x100 ;\ |
l.jr r8 ;\ |
l.nop"); |
} |
|
/* WARNING: stack and non-const globals should not be used in this function -- it may corrupt what have we loaded; |
start_addr should be 0xffffffff if only copying should be made |
no return, when start_addr != 0xffffffff, if successful */ |
int copy_memory_run (register unsigned long src_addr, register unsigned long dst_addr, register unsigned long length, register int erase, register unsigned long start_addr) |
{ |
unsigned long i, flags; |
|
register char *dst = (char *) dst_addr; |
register const char *src = (const char *) src_addr; |
|
if (dst_addr >= FLASH_BASE_ADDR) { |
if (dst_addr + length >= FLASH_BASE_ADDR + FLASH_SIZE) { |
printf ("error: region does not fit into flash.\n"); |
return 1; |
} |
#ifndef CFG_IN_FLASH |
fl_program (src_addr, dst_addr, length, erase, 1 /* do verify */); |
#else |
/* we must disable interrupts! */ |
flags=mfspr(SPR_SR); |
mtspr(SPR_SR,flags & ~(SPR_SR_TEE | SPR_SR_IEE)); |
|
printf("Unlocking flash... "); |
for(i = 0; i < length; i += FLASH_BLOCK_SIZE) |
fl_ext_unlock(dst_addr + i); |
printf("done\n"); |
|
printf("Erasing flash... "); |
for(i = 0; i < length; i += FLASH_BLOCK_SIZE) |
fl_ext_erase(dst_addr+i); |
printf("done\n"); |
|
printf("Programing flash:\n\t"); |
for (i = 0; i < length; i += INC_ADDR) { |
if(((i+INC_ADDR) % 1000) == 0) |
printf("#"); |
if((i % (65*1000)) == 0) |
printf("\n\t"); |
if (fl_ext_program (dst_addr + i, reg_read(src_addr + i))) { |
printf("error programing at 0x%08lx!\n", dst_addr+i); |
return 1; |
} |
} |
printf("Verifying flash... "); |
for(i = 0; i < length; i += INC_ADDR) { |
if( reg_read(dst_addr+i) != reg_read(src_addr + i)) { |
printf ("error at %08lx: %08lx != %08lx\n", src_addr + i, reg_read(src_addr + i), reg_read(dst_addr + i)); |
return 1; |
} |
} |
printf("OK!\n"); |
mtspr(SPR_SR, flags); |
#endif |
if(start_addr == 0xffffffff) |
return 0; |
} |
else { |
while (length--) *dst++ = *src++; |
if (start_addr == 0xffffffff) |
return 0; |
} |
/* Run the program */ |
((void (*)(void)) start_addr)(); |
return 0; /* just to satisfy the cc */ |
} |
|
void bf_jump(unsigned long addr) |
{ |
asm("l.jr r3"); |
asm("l.nop 0x0"); |
} |
|
int boot_flash_cmd(int argc, char *argv[]) |
{ |
unsigned long addr,val,jaddr; |
addr = 17; |
val = 0; |
/* clear SR */ |
|
asm("l.mtspr %0,%1,0": : "r" (addr), "r" (val)); |
/* jump */ |
if(argc == 0) |
bf_jump(FLASH_BASE_ADDR+0x100); |
else { |
jaddr = strtoul(argv[0], 0, 0); |
bf_jump(jaddr); |
} |
return 0; |
} |
|
void |
init_load (void) |
{ |
#ifdef CFG_IN_FLASH |
copy_memory_run((unsigned long)&fl_word_program, (unsigned long)&fprog_addr, |
95, 0, 0xffffffff); |
copy_memory_run((unsigned long)&fl_block_erase, (unsigned long)&fprog_addr+96, |
119, 0, 0xffffffff); |
copy_memory_run((unsigned long)&fl_unlock_one_block, |
(unsigned long)&fprog_addr+96+120, |
115, 0, 0xffffffff); |
|
fl_ext_program = (t_fl_ext_program)&fprog_addr; |
fl_ext_erase = (t_fl_erase)&fprog_addr+96; |
fl_ext_unlock = (t_fl_erase)&fprog_addr+96+120; |
|
#if 0 |
printf("fl_word_program(): 0x%x\tfl_ext_program(): 0x%x\n", |
&fl_word_program, fl_ext_program); |
printf("fl_block_erase: 0x%x\tfl_ext_erase(): 0x%x\n", |
&fl_block_erase, fl_ext_erase); |
printf("fl_unlock_one_block(): 0x%x\tfl_ext_unlock(): 0x%x\n", |
&fl_unlock_one_block, fl_ext_unlock); |
#endif |
|
#else /* not CFG_IN_FLASH */ |
fl_ext_program = (t_fl_ext_program)&fl_word_program; |
fl_ext_erase = (t_fl_erase)&fl_block_erase; |
fl_ext_unlock = (t_fl_erase)&fl_unlock_one_block; |
#endif /* CFG_IN_FLASH */ |
|
global.ip = gcfg.eth_ip; |
global.gw_ip = gcfg.eth_gw; |
global.mask = gcfg.eth_mask; |
global.srv_ip = gcfg.tftp_srv_ip; |
tftp_filename = "boot.img"; |
/*memcpy(tftp_filename, gcfg.tftp_filename, strlen(gcfg.tftp_filename)); |
tftp_filename[strlen(gcfg.tftp_filename)] = '\0';*/ |
} |
|
int tftp_cmd (int argc, char *argv[]) |
{ |
switch (argc) { |
case 0: tftp_filename = "boot.img"; |
break; |
case 3: global.src_addr = strtoul (argv[2], 0, 0); |
case 2: global.srv_ip = parse_ip (argv[1]); |
case 1: tftp_filename = &argv[0][0]; |
break; |
} |
NetLoop(TFTP); |
return 0; |
} |
|
int tftp_conf_cmd(int argc, char *argv[]) |
{ |
switch(argc) { |
case 0: |
printf("Image filename: %s", tftp_filename); |
printf("\nSrc addr: 0x%lx", global.src_addr); |
printf("\nServer IP: %s", inet_ntoa(global.srv_ip)); |
return 0; |
case 3: |
global.src_addr = strtoul(argv[2], 0, 0); |
global.srv_ip = inet_aton(argv[1]); |
tftp_filename = argv[0]; |
tftp_filename[strlen(argv[0])] = '\0'; |
break; |
case 2: |
global.srv_ip = inet_aton(argv[1]); |
tftp_filename = argv[0]; |
break; |
case 1: |
tftp_filename = argv[0]; |
break; |
} |
return 0; |
} |
|
void save_global_cfg(flash_cfg_struct cfg) |
{ |
unsigned long dst = (unsigned long)&gcfg, src = (unsigned long)&cfg; |
unsigned long i, end, flags; |
|
end = (unsigned long)&cfg + sizeof(flash_cfg_struct); |
|
printf("Saving global cfg from 0x%lx (end: 0x%lx) to 0x%lx...", src, end, dst); |
|
/* we must disable interrupts! */ |
flags=mfspr(SPR_SR); |
mtspr(SPR_SR,flags & ~(SPR_SR_TEE | SPR_SR_IEE)); |
/* printf("Unlocking... ");*/ |
for(i = 0; (src+i <= end); i += FLASH_BLOCK_SIZE) { |
fl_ext_unlock(dst+i); |
} |
/* printf("done\n");*/ |
/* printf("Erasing... ");*/ |
for(i = 0; (src+i <= end); i += FLASH_BLOCK_SIZE) |
fl_ext_erase(dst); |
/* printf("done\n");*/ |
/* printf("Programing... ");*/ |
for(i = 0; (src+i <= end); i +=INC_ADDR) { |
if(fl_ext_program(dst+i, reg_read(src+i))) { |
printf("Error ocurred while saving.\n"); |
return; |
} |
} |
printf("done\n"); |
|
/* and than enable it back */ |
mtspr(SPR_SR, flags); |
return; |
} |
|
int save_conf_cmd(int argc, char *argv[]) |
{ |
flash_cfg_struct newCfg; |
|
newCfg = gcfg; |
|
newCfg.eth_ip = global.ip; |
newCfg.eth_mask = global.mask; |
newCfg.eth_gw = global.gw_ip; |
newCfg.tftp_srv_ip = global.srv_ip; |
/* memcpy(newCfg.tftp_filename, tftp_filename, strlen(tftp_filename));*/ |
|
save_global_cfg(newCfg); |
return 0; |
} |
int copy_cmd (int argc, char *argv[]) |
{ |
switch (argc) { |
case 3: global.src_addr = strtoul (argv[2], 0, 0); |
case 2: global.length = strtoul (argv[2], 0, 0); |
case 1: global.src_addr = strtoul (argv[2], 0, 0); |
case 0: return copy_memory_run (global.src_addr, global.dst_addr, global.length, |
global.erase_method, 0xffffffff); |
} |
return -1; |
} |
|
void |
images_info(void) |
{ |
int i; |
printf("Number of images: 0x%lx\n", gcfg.img_number); |
for(i = 0; i < gcfg.img_number; i++) |
printf("%d. image size: 0x%lx (at 0x%08lx)\n", i+1, |
gcfg.img_length[i], gcfg.img_start_addr[i]); |
} |
|
/* |
* get_good_addr() |
* |
* Here we try to find the most suitable place for our image. We search for |
* a hole between images, that is big enough (but as small as possible). |
* |
*/ |
unsigned long |
get_good_addr(unsigned int size) |
{ |
unsigned long start_addr[MAX_IMAGES], end_addr[MAX_IMAGES]; |
unsigned long free[MAX_IMAGES], st_addr[MAX_IMAGES]; |
unsigned long tmpval; |
unsigned int i = 0, j; |
|
flash_cfg_struct myCfg; |
myCfg = gcfg; |
|
/* we are full */ |
if(gcfg.img_number == MAX_IMAGES) |
return 0xffffffff; |
|
if(gcfg.img_number == 0) |
return FLASH_IMAGES_BASE; |
|
for(i = 0; i < MAX_IMAGES; i++) { |
start_addr[i] = 0; |
end_addr[i] = 0; |
free[i] = 0; |
st_addr[i] = 0; |
} |
|
for(i = 0; i < myCfg.img_number; i++) { |
start_addr[i] = myCfg.img_start_addr[i]; |
end_addr[i] = ALIGN((myCfg.img_start_addr[i] + myCfg.img_length[i]), |
FLASH_BLOCK_SIZE); |
} |
/* printf("\n"); |
for(i = 0; i < myCfg.img_number; i++) |
printf("start: 0x%08x, end: 0x%08x\n", start_addr[i], end_addr[i]); |
printf("\n");*/ |
/* bubble sorting by start_addr */ |
|
for(j = myCfg.img_number - 1; j > 0; j--) |
for(i = 0; i < j; i++) |
if(start_addr[i] > start_addr[i+1]) { |
tmpval = start_addr[i]; |
start_addr[i] = start_addr[i+1]; |
start_addr[i+1] = tmpval; |
tmpval = end_addr[i]; |
end_addr[i] = end_addr[i+1]; |
end_addr[i+1] = tmpval; |
} |
|
/* for(i = 0; i < myCfg.img_number; i++) |
printf("start: 0x%08x, end: 0x%08x\n", start_addr[i], end_addr[i]); |
printf("\n");*/ |
|
/* now we calculate free space betwens segments */ |
for(i = 1; i < myCfg.img_number; i++) { |
st_addr[i] = end_addr[i - 1]; |
free[i] = start_addr[i] - end_addr[i - 1]; |
} |
|
/* here we calcuta first position (starting with FLASH_IMAGES_BASE)... */ |
st_addr[0] = FLASH_IMAGES_BASE + 0; |
free[0] = start_addr[0] - FLASH_IMAGES_BASE; |
/* ... and last one (ending with FLASH_IMAGES_BASE + FLASH_SIZE). */ |
st_addr[myCfg.img_number] = end_addr[myCfg.img_number-1]; |
free[myCfg.img_number] = (FLASH_IMAGES_BASE + FLASH_SIZE) - end_addr[myCfg.img_number-1]; |
|
/* for(i = 0; i < myCfg.img_number+1; i++) |
printf("start: 0x%08x, free: %x\n", st_addr[i], free[i]); |
printf("\n");*/ |
|
/* yet another bubble sort by free (space) */ |
for(j = myCfg.img_number; j > 0; j--) |
for(i = 0; i < j; i++) |
if(free[i] > free[i+1]) { |
tmpval = free[i]; |
free[i] = free[i+1]; |
free[i+1] = tmpval; |
tmpval = st_addr[i]; |
st_addr[i] = st_addr[i+1]; |
st_addr[i+1] = tmpval; |
} |
|
/* for(i = 0; i < myCfg.img_number+1; i++) |
printf("start: 0x%08x, free: %x\n", st_addr[i], free[i]); |
printf("\n");*/ |
|
/* now we pick the smallest but just big enough for our size */ |
for(i = 0; i <= myCfg.img_number; i++) |
if(free[i] >= size) |
return st_addr[i]; |
|
/* there is not enough space (in one segment) left */ |
return 0; |
} |
|
unsigned long |
prepare_img_data(unsigned int num, unsigned int size) |
{ |
int i; |
unsigned long addr=0; |
flash_cfg_struct newCfg; |
|
newCfg = gcfg; |
|
if(newCfg.img_number >= MAX_IMAGES) { |
printf("Maximum images exceeded: %d\n", MAX_IMAGES); |
return 0xffffffff; |
} |
|
newCfg.img_number++; |
|
if((num > newCfg.img_number) || (num == 0)) |
num = newCfg.img_number; |
|
addr = get_good_addr(size); |
if(addr == 0x00) { |
printf("Can not find suitable place in flash. (None of free segments are big enough)\n"); |
return 0xffffffff; |
} |
|
if(num < newCfg.img_number) |
for(i=newCfg.img_number-1; i >= num; i--) { |
newCfg.img_length[i] = newCfg.img_length[i-1]; |
newCfg.img_start_addr[i] = newCfg.img_start_addr[i-1]; |
} |
|
newCfg.img_length[num-1] = size; |
newCfg.img_start_addr[num-1] = addr; |
|
save_global_cfg(newCfg); |
return addr; |
} |
|
int |
del_image_cmd(int argc, char *argv[]) |
{ |
unsigned num, i; |
flash_cfg_struct newCfg = gcfg; |
|
newCfg.img_number = gcfg.img_number; |
for(i = 0; i < MAX_IMAGES; i++) |
newCfg.img_length[i] = gcfg.img_length[i]; |
|
printf("Number of images available: 0x%lx\n", newCfg.img_number); |
|
if(argc == 0) { |
newCfg.img_number = 0; |
for(i = 0; i < MAX_IMAGES; i++) { |
newCfg.img_length[i] = 0; |
newCfg.img_start_addr[i] = 0; |
} |
save_global_cfg(newCfg); |
return 0; |
} |
else { |
num = strtoul(argv[0], 0, 0); |
} |
|
if(newCfg.img_number == 0) { |
printf("Nothing to delete!\n"); |
return 0; |
} |
if((num == 0) || (num > newCfg.img_number)) |
num = newCfg.img_number; |
|
for(i=num-1; i < newCfg.img_number; i++) { |
newCfg.img_length[i] = newCfg.img_length[i+1]; |
newCfg.img_start_addr[i] = newCfg.img_start_addr[i+1]; |
} |
|
newCfg.img_number--; |
save_global_cfg(newCfg); |
return 0; |
} |
|
int |
boot_cmd(int argc, char *argv[]) |
{ |
int num; |
extern int tx_next; |
|
if(argc == 0) { |
images_info(); |
return 0; |
} |
|
num = strtoul(argv[0],0,0); |
if(gcfg.img_number < num) { |
printf("There are only %lu images, you requested %d!\n", gcfg.img_number, num); |
return -1; |
} |
|
printf("Copying image number %d from 0x%lx, size: 0x%lx...", |
num, gcfg.img_start_addr[num-1], gcfg.img_length[num-1]); |
|
printf("booting...\n"); |
copy_and_boot(gcfg.img_start_addr[num-1], 0x0, gcfg.img_length[num-1], tx_next); |
return 0; |
} |
|
int mGetData(unsigned long); |
|
int sboot_cmd (int argc, char *argv[]) |
{ |
int copied; |
unsigned int num = 0xffffffff, addr = 0x0; |
|
switch(argc) { |
case 0: |
num = 0xffffffff; |
break; |
case 1: |
num = strtoul(argv[0], 0, 0); |
break; |
} |
|
copied = mGetData(global.src_addr); |
if(copied <= 0) { |
printf("sboot: error while getting the image!"); |
return -1; |
} |
printf("image size: 0x%x\n", copied); |
|
if(num != 0xffffffff) { |
addr = prepare_img_data(num, copied); |
if(addr == 0xffffffff) |
printf("Image not written to flash!\n"); |
else { |
printf("Copying image to flash, image number: %d, dst_addr: 0x%x\n", |
num, addr); |
copy_memory_run(global.src_addr, gcfg.img_start_addr[num-1], copied, 2, 0xffffffff); |
} |
} |
|
return 0; |
} |
|
int tboot_cmd (int argc, char *argv[]) |
{ |
int copied; |
unsigned int num = 0xffffffff, addr = 0x0; |
extern int tx_next; |
|
switch (argc) { |
case 0: |
num = 0xffffffff; |
break; |
case 1: |
printf("argv[0] %p\n", argv[0]); |
num = strtoul(argv[0], 0, 0); |
printf("num %d\n", num); |
break; |
} |
|
// global.src_addr = (unsigned long)0x0; |
|
copied =NetLoop(TFTP); |
if (copied <= 0) { |
printf("tboot: error while getting the image '%s'", |
tftp_filename); |
return -1; |
} |
|
if(num != 0xffffffff) { |
addr = prepare_img_data(num, copied); |
if(addr == 0xffffffff) |
printf("Image not written to flash!\n"); |
else { |
printf("Copying image to flash, image number: %d, dst_addr: 0x%x\n", |
num, addr); |
copy_memory_run(global.src_addr, gcfg.img_start_addr[num-1], copied, 2, 0xffffffff); |
} |
} |
/* the point of no return */ |
printf("tboot: copying 0x%lx -> 0x0, image size 0x%x...\n", |
global.src_addr, copied); |
|
printf("tboot: jumping to 0x100, booting image ...\n"); |
copy_and_boot(global.src_addr, 0x0, 0x0 + copied, tx_next); |
return 0; |
} |
|
void module_load_init (void) |
{ |
register_command ("tftp", "[<file> [<srv_ip> [<src_addr>]]]", "TFTP download", tftp_cmd); |
register_command ("tftp_conf", "[ <file> [ <srv_ip> [ <src_addr>]]]", "TFTP configuration", tftp_conf_cmd); |
register_command ("copy", "[<dst_addr> [<src_addr [<length>]]]", "Copy memory", copy_cmd); |
register_command ("tboot", "[<image number>]", "Bootstrap image downloaded via tftp", tboot_cmd); |
register_command ("sboot", "[<image number>]", "Bootstrap image downloaded via serial (Y/X modem)", sboot_cmd); |
register_command ("boot", "[<image number>]", "Bootstrap image copied from flash.", boot_cmd); |
register_command ("del_image", "[<image number>]", "Delete image", del_image_cmd); |
register_command ("save_conf", "", "Save current configuration into flash", save_conf_cmd); |
register_command ("boot_flash", "[<start_addr>]", "Boot image from <start_addr> (default from flash)", boot_flash_cmd); |
init_load(); |
} |
load.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: eth.c
===================================================================
--- eth.c (nonexistent)
+++ eth.c (revision 1765)
@@ -0,0 +1,391 @@
+#include "common.h"
+#include "uart.h"
+#include "eth.h"
+#include "support.h"
+#include "spr_defs.h"
+#include "net.h"
+
+#if 0
+extern int tx_pointer_index;
+unsigned long dest_mac_addr[6];
+
+void show_tx_bd(int start, int max)
+{
+ int i;
+
+ for(i = start; i <= max; i++) {
+ /* Read Tx BD */
+ printf ("LEN:%04lx", REG32(ETH_BD_BASE + (i << 3)) >> 16);
+ printf (" RD:%04lx", (REG32(ETH_BD_BASE + (i << 3)) >> 15) & 0x1);
+ printf (" IRQ:%04lx", (REG32(ETH_BD_BASE + (i << 3)) >> 14) & 0x1);
+ printf (" WR:%04lx", (REG32(ETH_BD_BASE + (i << 3)) >> 13) & 0x1);
+ printf (" PAD:%04lx", (REG32(ETH_BD_BASE + (i << 3)) >> 12) & 0x1);
+ printf (" CRC:%04lx", (REG32(ETH_BD_BASE + (i << 3)) >> 11) & 0x1);
+ printf (" UR:%04lx", (REG32(ETH_BD_BASE + (i << 3)) >> 8) & 0x1);
+ printf (" RTRY:%04lx", (REG32(ETH_BD_BASE + (i << 3)) >> 4) & 0xf);
+ printf (" RL:%04lx", (REG32(ETH_BD_BASE + (i << 3)) >> 3) & 0x1);
+ printf (" LC:%04lx", (REG32(ETH_BD_BASE + (i << 3)) >> 2) & 0x1);
+ printf (" DF:%04lx", (REG32(ETH_BD_BASE + (i << 3)) >> 1) & 0x1);
+ printf (" CS:%04lx", (REG32(ETH_BD_BASE + (i << 3)) >> 0) & 0x1);
+ printf ("\nTx Buffer Pointer: %08lx\n", REG32(ETH_BD_BASE + (i << 3) + 4));
+ }
+}
+
+void show_rx_bd (int start, int max)
+{
+ int i;
+ unsigned long rx_bd_base, rx_bd_num;
+
+ rx_bd_num = REG32(ETH_REG_BASE + ETH_RXBD_NUM);
+ rx_bd_base = ETH_BD_BASE + (rx_bd_num << 2);
+
+ for(i = start; i <= max; i++){
+ /* Read Rx BD */
+ printf ("LEN:%04lx", REG32(rx_bd_base + (i << 3)) >> 16);
+ printf (" E:%04lx", (REG32(rx_bd_base + (i << 3)) >> 15) & 0x1);
+ printf (" IRQ:%04lx", (REG32(rx_bd_base + (i << 3)) >> 14) & 0x1);
+ printf (" WR:%04lx", (REG32(rx_bd_base + (i << 3)) >> 13) & 0x1);
+ printf (" M:%04lx", (REG32(rx_bd_base + (i << 3)) >> 7) & 0x1);
+ printf (" OR:%04lx", (REG32(rx_bd_base + (i << 3)) >> 6) & 0x1);
+ printf (" IS:%04lx", (REG32(rx_bd_base + (i << 3)) >> 5) & 0x1);
+ printf (" DN:%04lx", (REG32(rx_bd_base + (i << 3)) >> 4) & 0x1);
+ printf (" TL:%04lx", (REG32(rx_bd_base + (i << 3)) >> 3) & 0x1);
+ printf (" SF:%04lx", (REG32(rx_bd_base + (i << 3)) >> 2) & 0x1);
+ printf (" CRC:%04lx", (REG32(rx_bd_base + (i << 3)) >> 1) & 0x1);
+ printf (" LC:%04lx", (REG32(rx_bd_base + (i << 3)) >> 0) & 0x1);
+ printf ("\nRx Buffer Pointer: %08lx\n", REG32(rx_bd_base + (i << 3) + 4));
+ }
+}
+
+void show_buffer(unsigned long start_addr, unsigned long len)
+{
+ show_mem(start_addr, start_addr + len - 1);
+}
+
+void show_rx_buffs(int max, int show_all)
+{
+
+ int i;
+ unsigned long rx_bd_base, rx_bd_num;
+
+ rx_bd_num = REG32(ETH_REG_BASE + ETH_RXBD_NUM);
+ rx_bd_base = ETH_BD_BASE + (rx_bd_num << 2);
+
+ for(i=0; i<=max; i++)
+ {
+ if (!(REG32(rx_bd_base + (i << 3)) & ETH_RX_BD_EMPTY) || show_all)
+ {
+ printf ("Rx BD No. %04x located at %08lx\n", i, rx_bd_base + (i << 3));
+ show_rx_bd(i, i);
+ show_buffer(REG32(rx_bd_base + (i << 3) + 4), REG32(rx_bd_base + (i << 3)) >> 16);
+ printf ("\n");
+ }
+ if (REG32(rx_bd_base + (i << 3)) & ETH_RX_BD_WRAP)
+ return;
+ }
+}
+
+void show_tx_buffs(int max)
+{
+ int i;
+
+ for(i=0; i<=max; i++)
+ {
+ if (1)
+ {
+ printf ("Tx BD No. %04x located at %08x\n", i, ETH_BD_BASE + (i << 3));
+ show_tx_bd(i, i);
+ show_buffer(REG32(ETH_BD_BASE + (i << 3) + 4), REG32(ETH_BD_BASE + (i << 3)) >> 16);
+ printf ("\n");
+ }
+ if (REG32(ETH_BD_BASE + (i << 3)) & ETH_TX_BD_WRAP)
+ return;
+ }
+}
+
+void show_phy_reg (unsigned long start_addr, unsigned long stop_addr)
+{
+
+ unsigned long addr;
+
+ if (start_addr == stop_addr)
+ {
+ printf ("\nSet MII RGAD ADDRESS to %08lx", start_addr);
+ printf ("\nMII Command = Read Status\n");
+ }
+
+ for (addr = start_addr; addr <= stop_addr; addr++)
+ {
+ REG32(ETH_REG_BASE + ETH_MIIADDRESS) = addr<<8;
+ REG32(ETH_REG_BASE + ETH_MIICOMMAND) = ETH_MIICOMMAND_RSTAT;
+
+ printf ("PHY %04lx", REG32(ETH_REG_BASE + ETH_MIIADDRESS) & 0x1f);
+ printf (", addr %04lx", REG32(ETH_REG_BASE + ETH_MIIADDRESS) >> 8);
+ printf (": %08lx\n", REG32(ETH_REG_BASE + ETH_MIIRX_DATA));
+ }
+}
+
+void set_phy_reg (unsigned long addr, unsigned long val)
+{
+ printf ("\nSet MII RGAD ADDRESS to %08lx", addr);
+
+ REG32(ETH_REG_BASE + ETH_MIIADDRESS) = addr<<8;
+
+ printf ("\nMII Command = Write Control Data\n");
+ REG32(ETH_REG_BASE + ETH_MIICOMMAND) = ETH_MIICOMMAND_WCTRLDATA;
+
+ REG32(ETH_REG_BASE + ETH_MIITX_DATA) = val;
+
+ show_phy_reg(addr, addr);
+}
+
+void send_packet (unsigned long len, unsigned long start_data, int num_of_packets)
+{
+ unsigned long i, TxBD;
+
+ while (num_of_packets--) {
+ unsigned long *data = (unsigned long *)eth_get_tx_buf ();
+
+ /* Set dest & src address */
+ *data++ = dest_mac_addr[0] << 24 |
+ dest_mac_addr[1] << 16 |
+ dest_mac_addr[2] << 8 |
+ dest_mac_addr[3] << 0;
+
+ *data++ = dest_mac_addr[4] << 24 |
+ dest_mac_addr[5] << 16 |
+ ETH_MACADDR0 << 8 |
+ ETH_MACADDR1 << 0;
+
+ *data++ = ETH_MACADDR2 << 24 |
+ ETH_MACADDR3 << 16 |
+ ETH_MACADDR4 << 8 |
+ ETH_MACADDR5 << 0;
+
+ /* Write data to buffer */
+ for(i = 12; i < len; i += 4)
+ *data++ = (i + start_data - 12) << 24 | (i + start_data + 1 - 12) << 16 |
+ (i + start_data + 2 - 12) << 8 | (i + start_data + 3 - 12);
+
+ eth_send (data, len);
+ printf (".");
+ }
+}
+
+int eth_init_cmd (int argc, char *argv[])
+{
+ if (argc) return -1;
+ eth_init (0);
+ return 0;
+}
+
+int show_txbd_cmd (int argc, char *argv[])
+{
+ int i;
+ int start, max;
+
+ if (argc == 1) show_tx_bd (strtoul (argv[0], NULL, 0), strtoul (argv[0], NULL, 0));
+ else if (argc == 2) show_tx_bd (strtoul (argv[0], NULL, 0), strtoul (argv[1], NULL, 0));
+ else show_tx_bd (0, 63);
+ return 0;
+}
+
+int show_rxbd_cmd (int argc, char *argv[])
+{
+ if (argc == 1) show_rx_bd (strtoul (argv[0], NULL, 0), strtoul (argv[0], NULL, 0));
+ else if (argc == 2) show_rx_bd (strtoul (argv[0], NULL, 0), strtoul (argv[1], NULL, 0));
+ else show_rx_bd (0, 63);
+ return 0;
+}
+
+int send_packet_cmd (int argc, char *argv[])
+{
+ if (argc == 1) send_packet(strtoul (argv[0], NULL, 0), 31, 1);
+ else if (argc == 2) send_packet(strtoul (argv[0], NULL, 0), strtoul (argv[1], NULL, 0), 1);
+ else if (argc == 3) send_packet(strtoul (argv[0], NULL, 0), strtoul (argv[1], NULL, 0), strtoul (argv[2], NULL, 0));
+ else return -1;
+ return 0;
+}
+
+int set_dest_addr_cmd (int argc, char *argv[])
+{
+ if (argc == 3) {
+ dest_mac_addr[0] = (strtoul (argv[0], NULL, 0) >> 8) & 0xff;
+ dest_mac_addr[1] = (strtoul (argv[0], NULL, 0) >> 0) & 0xff;
+ dest_mac_addr[2] = (strtoul (argv[1], NULL, 0) >> 8) & 0xff;
+ dest_mac_addr[3] = (strtoul (argv[1], NULL, 0) >> 0) & 0xff;
+ dest_mac_addr[4] = (strtoul (argv[2], NULL, 0) >> 8) & 0xff;
+ dest_mac_addr[5] = (strtoul (argv[2], NULL, 0) >> 0) & 0xff;
+ } else return -1;
+ return 0;
+}
+
+int init_txbd_pool_cmd (int argc, char *argv[])
+{
+#if 0
+ if (argc == 1) init_tx_bd_pool(strtoul (argv[0], NULL, 0));
+ else return -1;
+#endif
+ return 0;
+}
+
+int init_rxbd_pool_cmd (int argc, char *argv[])
+{
+ if (argc == 1) init_rx_bd_pool(strtoul (argv[0], NULL, 0));
+ else return -1;
+ return 0;
+}
+
+int show_phy_reg_cmd (int argc, char *argv[])
+{
+ if (argc == 1) show_phy_reg(strtoul (argv[0], NULL, 0), strtoul (argv[0], NULL, 0));
+ else if (argc == 2) show_phy_reg(strtoul (argv[0], NULL, 0), strtoul (argv[1], NULL, 0));
+ else show_phy_reg(0, 30);
+ return 0;
+}
+
+int set_phy_reg_cmd (int argc, char *argv[])
+{
+ if (argc == 2) set_phy_reg(strtoul (argv[0], NULL, 0), strtoul (argv[1], NULL, 0));
+ else return -1;
+ return 0;
+}
+
+int show_mac_regs_cmd (int argc, char *argv[])
+{
+ if (argc) return -1;
+ printf ("\n %08x", ETH_REG_BASE + ETH_MODER);
+ printf (" MODER: %08lx",REG32(ETH_REG_BASE + ETH_MODER));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_INT);
+ printf (" INT: %08lx", REG32(ETH_REG_BASE + ETH_INT));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_INT_MASK);
+ printf (" INT_MASK: %08lx", REG32(ETH_REG_BASE + ETH_INT_MASK));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_IPGT);
+ printf (" IPGT: %08lx", REG32(ETH_REG_BASE + ETH_IPGT));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_IPGR1);
+ printf (" IPGR1: %08lx", REG32(ETH_REG_BASE + ETH_IPGR1));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_IPGR2);
+ printf (" IPGR2: %08lx", REG32(ETH_REG_BASE + ETH_IPGR2));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_PACKETLEN);
+ printf (" PACKETLEN: %08lx", REG32(ETH_REG_BASE + ETH_PACKETLEN));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_COLLCONF);
+ printf (" COLLCONF: %08lx", REG32(ETH_REG_BASE + ETH_COLLCONF));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_RXBD_NUM);
+ printf (" RX_BD_NUM: %08lx", REG32(ETH_REG_BASE + ETH_RXBD_NUM));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_CTRLMODER);
+ printf (" CTRLMODER: %08lx", REG32(ETH_REG_BASE + ETH_CTRLMODER));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_MIIMODER);
+ printf (" MIIMODER: %08lx", REG32(ETH_REG_BASE + ETH_MIIMODER));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_MIICOMMAND);
+ printf (" MIICOMMAND: %08lx", REG32(ETH_REG_BASE + ETH_MIICOMMAND));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_MIIADDRESS);
+ printf (" MIIADDRESS: %08lx", REG32(ETH_REG_BASE + ETH_MIIADDRESS));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_MIITX_DATA);
+ printf (" MIITX_DATA: %08lx", REG32(ETH_REG_BASE + ETH_MIITX_DATA));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_MIIRX_DATA);
+ printf (" MIIRX_DATA: %08lx", REG32(ETH_REG_BASE + ETH_MIIRX_DATA));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_MIISTATUS);
+ printf (" MIISTATUS: %08lx", REG32(ETH_REG_BASE + ETH_MIISTATUS));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_MAC_ADDR0);
+ printf (" MAC_ADDR0: %08lx", REG32(ETH_REG_BASE + ETH_MAC_ADDR0));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_MAC_ADDR1);
+ printf (" MAC_ADDR1: %08lx", REG32(ETH_REG_BASE + ETH_MAC_ADDR1));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_HASH_ADDR0);
+ printf (" ETH_HASH_ADDR0: %08lx", REG32(ETH_REG_BASE + ETH_HASH_ADDR0));
+
+ printf ("\n %08x", ETH_REG_BASE + ETH_HASH_ADDR1);
+ printf (" ETH_HASH_ADDR1: %08lx", REG32(ETH_REG_BASE + ETH_HASH_ADDR1));
+
+ printf ("\n");
+ return 0;
+}
+
+int eth_int_enable_cmd (int argc, char *argv[])
+{
+ if (argc) return -1;
+ eth_int_enable ();
+ return 0;
+}
+int show_rx_buffs_cmd (int argc, char *argv[])
+{
+ if (argc == 0) show_rx_buffs(63, 0);
+ else if (argc == 1) show_rx_buffs(63, 1);
+ else return -1;
+ return 0;
+}
+
+int show_tx_buffs_cmd (int argc, char *argv[])
+{
+ if (argc == 0) show_tx_buffs(63);
+ else return -1;
+ return 0;
+}
+#endif
+
+int eth_conf_cmd(int argc, char *argv[])
+{
+ switch(argc) {
+ case 0:
+ printf("IP: %s", inet_ntoa(global.ip));
+ printf("\nmask: %s", inet_ntoa(global.mask));
+ printf("\nGW: %s", inet_ntoa(global.gw_ip));
+ return 0;
+ case 3:
+ global.gw_ip = inet_aton(argv[2]);
+ case 2:
+ global.mask = inet_aton(argv[1]);
+ case 1:
+ global.ip = inet_aton(argv[0]);
+ break;
+ }
+ printf("Restarting network with new parameters...");
+ NetStartAgain();
+
+ return 0;
+}
+
+void module_eth_init (void)
+{
+#if 0
+ register_command ("eth_init", "", "init ethernet", eth_init_cmd);
+ register_command ("show_txbd", "[] []", "show Tx buffer desc", show_txbd_cmd);
+ register_command ("show_rxbd", "[] []", "show Rx buffer desc", show_rxbd_cmd);
+ register_command ("send_packet", " [] []", "create & send packet(s)", send_packet_cmd);
+ register_command ("set_dest_addr", " ", "set destination address (for send_packet)", set_dest_addr_cmd);
+ register_command ("init_txbd_pool", "", "initialize Tx buffer descriptors", init_txbd_pool_cmd);
+ register_command ("init_rxbd_pool", "", "initialize Rx buffer descriptors", init_rxbd_pool_cmd);
+ register_command ("show_phy_reg", "[] []", "show PHY registers", show_phy_reg_cmd);
+ register_command ("set_phy_reg", " ", "set PHY register", set_phy_reg_cmd);
+ register_command ("show_mac_regs", "", "show all MAC registers", show_mac_regs_cmd);
+ register_command ("eth_int_enable", "", "enable ethernet interrupt", eth_int_enable_cmd);
+ register_command ("show_rx_buffs", "[]", "show receive buffers (optional arg will also show empty buffers)", show_rx_buffs_cmd);
+ register_command ("show_tx_buffs", "", "show transmit buffers", show_rx_buffs_cmd);
+#endif
+ /* Initialize controller */
+ register_command ("eth_conf", "[ [ []]]", "Get/set ethernet configuration", eth_conf_cmd);
+#if 0
+ eth_init();
+ printf ("Ethernet not initialized (run eth_init command)\n");
+ init_rx_bd_pool(0);
+ init_tx_bd_pool(3);
+#endif
+}
+
Index: touch.c
===================================================================
--- touch.c (nonexistent)
+++ touch.c (revision 1765)
@@ -0,0 +1,51 @@
+#include "common.h"
+#include "support.h"
+#include "spi.h"
+
+int touch_cmd (int argc, char *argv[])
+{
+ unsigned long x, y, z1, z2;
+ float res;
+
+ if (argc == 0) {
+ printf("usage: -r read coordinates\n");
+ printf(" -c read coordinates in a loop (press any key to exit)\n");
+ }
+ else if (argc == 1) {
+ if (!strcmp(argv[0], "-r")) {
+ spi_init(0, 1000000, 21, 0, 1, 0);
+ printf("X = %.3lx\n", spi_xmit(0xd3l << 13) & 0xfff);
+ printf("Y = %.3lx\n", spi_xmit(0x93l << 13) & 0xfff);
+ }
+ else if (!strcmp(argv[0], "-c")) {
+ spi_init(0, 1000000, 21, 0, 1, 0);
+ while (1) {
+ x = spi_xmit(0xd3l << 13) & 0xfff;
+ z1 = spi_xmit(0xb3l << 13) & 0xfff;
+ z2 = spi_xmit(0xc3l << 13) & 0xfff;
+ res = (z2/z1) - 1;
+ res = ((float)x * res)/4096;
+ if ((int)res < 20) {
+ y = spi_xmit(0x93l << 13) & 0xfff;
+ printf("X = %.3lx\n", x);
+ printf("Y = %.3lx\n\n", y);
+ }
+ if (testc())
+ break;
+ }
+ }
+ }
+ else {
+ printf("usage: -r read coordinates\n");
+ printf(" -c read coordinates in a loop (press any key to exit)\n");
+ }
+
+ return 0;
+}
+
+void module_touch_init (void)
+{
+ register_command ("touch", "", "touch screen utility", touch_cmd);
+}
+
+
Index: memory.c
===================================================================
--- memory.c (nonexistent)
+++ memory.c (revision 1765)
@@ -0,0 +1,175 @@
+#include "common.h"
+#include "support.h"
+#include "spr_defs.h"
+
+void show_mem (int start, int stop)
+{
+ unsigned long i = start;
+ if ((i & 0xf) != 0x0) printf ("\n%08lx: ", i);
+ for(; i <= stop; i += 4) {
+ if ((i & 0xf) == 0x0) printf ("\n%08lx: ", i);
+ /* Read one word */
+ printf ("%08lx ", REG32(i));
+ }
+ printf ("\n");
+}
+
+void testram (unsigned long start_addr, unsigned long stop_addr, unsigned long testno)
+{
+ unsigned long addr;
+ unsigned long err_addr = 0;
+ unsigned long err_no = 0;
+
+ /* Test 1: Write locations with their addresses */
+ if ((testno == 1) || (testno == 0)) {
+ printf ("\n1. Writing locations with their addresses: ");
+ for (addr = start_addr; addr <= stop_addr; addr += 4)
+ REG32(addr) = addr;
+
+ /* Verify */
+ for (addr = start_addr; addr <= stop_addr; addr += 4)
+ if (REG32(addr) != addr) {
+ err_no++;
+ err_addr = addr;
+ }
+ if (err_no) printf ("%04lx times failed. Last at location %08lx", err_no, err_addr);
+ else printf ("Passed");
+ err_no = 0;
+ }
+
+ /* Test 2: Write locations with their inverse address */
+ if ((testno == 2) || (testno == 0)) {
+ printf ("\n2. Writing locations with their inverse addresses: ");
+ for (addr = start_addr; addr <= stop_addr; addr += 4)
+ REG32(addr) = ~addr;
+
+ /* Verify */
+ for (addr = start_addr; addr <= stop_addr; addr += 4)
+ if (REG32(addr) != ~addr) {
+ err_no++;
+ err_addr = addr;
+ }
+ if (err_no) printf ("%04lx times failed. Last at location %08lx", err_no, err_addr);
+ else printf ("Passed");
+ err_no = 0;
+ }
+
+ /* Test 3: Write locations with walking ones */
+ if ((testno == 3) || (testno == 0)) {
+ printf ("\n3. Writing locations with walking ones: ");
+ for (addr = start_addr; addr <= stop_addr; addr += 4)
+ REG32(addr) = 1 << (addr >> 2);
+
+ /* Verify */
+ for (addr = start_addr; addr <= stop_addr; addr += 4)
+ if (REG32(addr) != (1 << (addr >> 2))) {
+ err_no++;
+ err_addr = addr;
+ }
+ if (err_no) printf ("%04lx times failed. Last at location %08lx", err_no, err_addr);
+ else printf ("Passed");
+ err_no = 0;
+ }
+
+ /* Test 4: Write locations with walking zeros */
+ if ((testno == 4) || (testno == 0)) {
+ printf ("\n4. Writing locations with walking zeros: ");
+ for (addr = start_addr; addr <= stop_addr; addr += 4)
+ REG32(addr) = ~(1 << (addr >> 2));
+
+ /* Verify */
+ for (addr = start_addr; addr <= stop_addr; addr += 4)
+ if (REG32(addr) != ~(1 << (addr >> 2))) {
+ err_no++;
+ err_addr = addr;
+ }
+ if (err_no) printf ("%04lx times failed. Last at location %08lx", err_no, err_addr);
+ else printf ("Passed");
+ err_no = 0;
+ }
+}
+
+int dm_cmd (int argc, char *argv[])
+{
+ unsigned long a1,a2;
+ a1 = strtoul(argv[0], 0, 0);
+ switch (argc) {
+ case 1: show_mem (a1, a1); return 0;
+ case 2:
+ a2 = strtoul(argv[1], 0, 0);
+ show_mem (a1, a2); return 0;
+ default: return -1;
+ }
+}
+
+int pm_cmd (int argc, char *argv[])
+{
+ unsigned long addr, stop_addr, value;
+ if ((argc == 3) || (argc == 2)) {
+ addr = strtoul (argv[0], 0, 0);
+
+ if (argc == 2) {
+ stop_addr = strtoul (argv[0], 0, 0);
+ value = strtoul (argv[1], 0, 0);
+ } else {
+ stop_addr = strtoul (argv[1], 0, 0);
+ value = strtoul (argv[2], 0, 0);
+ }
+
+ for (; addr <= stop_addr; addr += 4) REG32(addr) = value;
+
+ /*show_mem(strtoul (argv[0], 0, 0), stop_addr);*/
+ } else return -1;
+ return 0;
+}
+
+int ram_test_cmd (int argc, char *argv[])
+{
+ switch (argc) {
+ case 2: testram(strtoul (argv[0], 0, 0), strtoul (argv[1], 0, 0), 0); return 0;
+ case 3: testram(strtoul (argv[0], 0, 0), strtoul (argv[1], 0, 0), strtoul (argv[2], 0, 0)); return 0;
+ default: return -1;
+ }
+}
+
+unsigned long crc32 (unsigned long crc, const unsigned char *buf, unsigned long len)
+{
+ /* Create bitwise CRC table first */
+ unsigned long crc_table[256];
+ int i, k;
+ for (i = 0; i < 256; i++) {
+ unsigned long c = (unsigned long)i;
+ for (k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >> 1) : c >> 1;
+ crc_table[i] = c;
+ }
+
+ /* Calculate crc on buf */
+ crc = crc ^ 0xffffffffL;
+ while (len--) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+ return crc ^ 0xffffffffL;
+}
+
+int crc_cmd (int argc, char *argv[])
+{
+ unsigned long addr = global.src_addr;
+ unsigned long len = global.length;
+ unsigned long init_crc = 0;
+
+ switch (argc) {
+ case 3: init_crc = strtoul (argv[2], 0, 0);
+ case 2: len = strtoul (argv[1], 0, 0);
+ case 1: addr = strtoul (argv[0], 0, 0);
+ case 0:
+ printf ("CRC [%08lx-%08lx] = %08lx\n", addr, addr + len - 1, crc32 (init_crc, (unsigned char *)addr, len));
+ return 0;
+ }
+ return -1;
+}
+
+void module_memory_init (void)
+{
+ register_command ("dm", " []", "display 32-bit memory location(s)", dm_cmd);
+ register_command ("pm", " [] ", "patch 32-bit memory location(s)", pm_cmd);
+ register_command ("ram_test", " []", "run a simple RAM test", ram_test_cmd);
+ register_command ("crc", "[ [ []]]", "Calculates a 32-bit CRC on specified memory region", crc_cmd);
+}
Index: atabug.c
===================================================================
--- atabug.c (nonexistent)
+++ atabug.c (revision 1765)
@@ -0,0 +1,682 @@
+/*
+ atabug.c -- ATA debugging
+ Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
+
+ This file is part of OpenRISC 1000 Reference Platform Monitor (ORPmon)
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include "support.h"
+#include "common.h"
+#include "atabug.h"
+#include "ata.h"
+
+#include
+
+static int ata_num_commands;
+static command_struct ata_command[MAX_ATA_COMMANDS];
+
+/* inode struct for ata */
+static struct inode _inode;
+static struct inode *inode = &_inode;
+
+/* file struct for ata */
+static struct file _filp;
+static struct file *filp = &_filp;
+
+/* buffer for ata-data */
+static unsigned char buf[512];
+
+
+/**********************************************************************/
+/* */
+/* A T A B U G */
+/* */
+/**********************************************************************/
+/*
+ A T A _ I N I T
+
+ initializes the ATA core, and registers it with ORPmon
+*/
+void module_ata_init (void)
+{
+ ata_num_commands = 0;
+
+ register_command ("atabug", "", "ATA debugger. Type 'atabug help' for help", atabug);
+
+ register_ata_command ("help", "", "Display this help message", atabug_help);
+ register_ata_command ("exit", "", "Exit atabug and return to ORPmon", atabug_exit);
+ register_ata_command ("open", " []", "Opens the requested device. Device=<0|1>, Mode=eadonly|readrite.", ata_open_cmd);
+ register_ata_command ("close", "", "Closes the device.", ata_close_cmd);
+ register_ata_command ("reset", "", "Reset ata device(s).", ata_reset_cmd);
+ register_ata_command ("enable", "", "Enables ATA host controller, clears all resets", ata_enable_cmd);
+ register_ata_command ("dump_dev_regs", "", "Dump the (readable) ata device registers.", ata_dump_device_regs_cmd);
+ register_ata_command ("dump_host_regs", "", "Dump the ata host registers.", ata_dump_host_regs_cmd);
+ register_ata_command ("exec_cmd", "", "Execute ata command (hex)", ata_exec_cmd_cmd);
+ register_ata_command ("identify_device", "", "Dumps device's IDENTIFY DEVICE block.", ata_identify_device_cmd);
+ register_ata_command ("program_timing", "", "Programs the device to the selected PIO mode.", ata_set_piomode_cmd);
+ register_ata_command ("read_sectors", " []", "Reads sector", ata_read_sectors_cmd);
+ register_ata_command ("read_mbr", "", "Reads the Master Boot Record.", ata_read_mbr_cmd);
+ register_ata_command ("read_dosboot", "", "Reads the device's bootsector (FAT).", ata_read_dosboot_cmd);
+ register_ata_command ("select_device", "", "Select ata device. device_no=<0|1>", ata_select_device_cmd);
+}
+
+
+int atabug(int argc, char **argv)
+{
+
+ /* take care of commandline options */
+ if (argc == 0)
+ {
+ /* start atabug */
+ while ( !ata_mon_command() );
+ }
+ else
+ return execute_ata_command(argv[0], argc -1, &argv[1]);
+
+ return 0;
+}
+
+int atabug_exit(int argc, char **argv)
+{
+ ata_close_cmd(argc, argv);
+ return -2;
+}
+
+/*
+ The next code is graceously taken from the "common.c" file
+ and slightly modified to suit the big list of ATA commands
+
+ Better would be if we could access the routines in 'common.c'
+ directly, using our own set of commands.
+*/
+
+/* Process command-line, generate arguments */
+int ata_mon_command(void)
+{
+ char c = '\0';
+ char str[1000];
+ char *pstr = str;
+ char *command_str;
+ char *argv[20];
+ int argc = 0;
+
+
+ /* Show prompt */
+ printf ("\natabug> ");
+
+
+ /* Get characters from UART */
+ c = getc();
+ while (c != '\r' && c != '\f' && c != '\n')
+ {
+ if (c == '\b')
+ pstr--;
+ else
+ *pstr++ = c;
+ putc(c);
+ c = getc();
+ }
+ *pstr = '\0';
+ printf ("\n");
+
+ /* Skip leading blanks */
+ pstr = str;
+ while ( isspace(*pstr) ) pstr++;
+
+ /* Get command from the string */
+ command_str = pstr;
+
+ while (1) {
+ /* Go to next argument */
+ while ( isgraph(*pstr) ) pstr++;
+ if (*pstr) {
+ *pstr++ = '\0';
+ while ( isspace(*pstr) ) pstr++;
+ argv[argc++] = pstr;
+ }
+ else
+ break;
+ }
+
+ return execute_ata_command(command_str, argc, argv);
+}
+
+
+int execute_ata_command(char *command_str, int argc, char **argv)
+{
+ int i, found = 0;
+
+ for (i = 0; i < ata_num_commands; i++)
+ if ( !strcmp(command_str, ata_command[i].name) )
+ {
+ switch ( ata_command[i].func(argc, argv) )
+ {
+ case -1:
+ printf ("Missing/wrong parameters, usage: %s %s\n", ata_command[i].name, ata_command[i].params);
+ break;
+
+ case -2:
+ return -1;
+ }
+
+ found++;
+ break;
+ }
+
+ if (!found)
+ printf ("Unknown command. Type 'ata help' for help.\n");
+
+ return 0;
+}
+
+
+void register_ata_command (const char *name, const char *params, const char *help, int (*func)(int argc, char *argv[]) )
+{
+ if (ata_num_commands < MAX_ATA_COMMANDS)
+ {
+ ata_command[ata_num_commands].name = name;
+ ata_command[ata_num_commands].params = params;
+ ata_command[ata_num_commands].help = help;
+ ata_command[ata_num_commands].func = func;
+ ata_num_commands++;
+ }
+ else
+ printf ("ata-command '%s' ignored; MAX_COMMANDS limit reached\n", name);
+}
+
+int atabug_help(int argc, char **argv)
+{
+ int i;
+
+ for (i = 0; i < ata_num_commands; i++)
+ printf ("%-15s %-17s -%s\n", ata_command[i].name, ata_command[i].params, ata_command[i].help);
+
+ return 0;
+}
+
+
+
+
+/**********************************************************************/
+/* */
+/* A T A B U G C O M M A N D S E T */
+/* */
+/**********************************************************************/
+
+/*
+ A T A _ C L O S E
+
+ closes the ata_device
+*/
+int ata_close_cmd(int argc, char **argv)
+{
+ inode->i_rdev = (ATA_BASE_ADDR >> 16) | (*argv[0] - '0');
+
+ return ata_release(inode, filp);
+}
+
+
+/*
+ A T A _ D U M P _ D E V I C E _ R E G S
+
+ Dumps the (readable) ata-registers.
+ Exception: status register is not read, this could mask an interrupt
+*/
+int ata_dump_device_regs_cmd(int argc, char **argv)
+{
+ if (argc)
+ printf("\nWARNING: Ignoring invalid argument(s)\n\n");
+
+
+ printf("Alternate status register : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_ASR) );
+ printf("Cylinder high register : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_CHR) );
+ printf("Cylinder low register : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_CLR) );
+ printf("Device head register : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_DHR) );
+ printf("Error register : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_ERR) );
+ printf("Sector count register : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_SCR) );
+ printf("Sector number register : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_SNR) );
+ printf("Status register (see alternate status register)\n" );
+
+ return 0;
+}
+
+
+/*
+ A T A _ D U M P _ H O S T _ R E G S
+
+ Dumps the ata-host registers
+*/
+int ata_dump_host_regs_cmd(int argc, char **argv)
+{
+ if (argc)
+ printf("\nWARNING: Ignoring invalid argument(s)\n\n");
+
+
+ printf("Control register CTRL : 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_CTRL) );
+ printf("Status register STAT : 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_STAT) );
+ printf("Pio command timing register PCTR : 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_PCTR) );
+ printf("Pio fast timing register (device0) PFTR0: 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_PFTR0) );
+ printf("Pio fast timing register (device1) PFTR1: 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_PFTR1) );
+ printf("Dma timing register (device0) DTR0 : 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_DTR0) );
+ printf("Dma timing register (device1) DTR1 : 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_DTR1) );
+
+ return 0;
+}
+
+
+/*
+ A T A _ E N A B L E
+
+ clears reset bits
+*/
+int ata_enable_cmd(int argc, char **argv)
+{
+ if (argc != 0)
+ printf("Ignoring invalid parameters\n");
+
+ inode->i_rdev = (ATA_BASE_ADDR >> 16);
+
+ // clear hardware reset bit
+ if ( ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, CLR | ARG_HW_RST) )
+ return -1;
+
+ // clear software reset bit
+ if ( ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, CLR | ARG_SW_RST) )
+ return -1;
+
+ // enable ATA Hostcontroller core
+ if ( ata_ioctl(inode, filp, ATA_IOCTL_ENABLE_HOST, 0) )
+ return -1;
+
+ printf("ATA host controller enabled\n");
+
+ return 0;
+}
+
+
+/*
+ A T A _ E X E C _ C M D
+
+ Executes the command; writes the command number in the command register
+*/
+int ata_exec_cmd_cmd(int argc, char **argv)
+{
+ if (argc != 1)
+ return -1;
+
+ inode->i_rdev = (ATA_BASE_ADDR >> 16);
+
+ ata_ioctl(inode, filp, ATA_IOCTL_EXEC_CMD, strtoul(*argv, argv, 16) );
+ return 0;
+}
+
+
+/*
+ A T A _ I D E N T I F Y _ D E V I C E
+
+ Reads the identify_device block and dumps it to the screen
+*/
+int ata_identify_device_cmd(int argc, char **argv)
+{
+ unsigned char checksum;
+
+ if (argc != 0)
+ printf("Ignoring invalid parameters\n");
+
+
+ /* check for busy flag */
+ if ( ata_dev_busy(ATA_BASE_ADDR) )
+ printf("Selected ata device busy, ignoring command\n");
+ else
+ {
+ /* execute identify device */
+ ata_ioctl(inode, filp, ATA_IOCTL_EXEC_CMD, IDENTIFY_DEVICE);
+
+ /* read block from ata-device */
+ buf[0] = 0;
+ buf[1] = 1;
+ ata_ioctl(inode, filp, ATA_IOCTL_READ, (unsigned long) buf);
+
+ /* dump data to the screen */
+ checksum = atabug_dump_data(buf, 512);
+
+ if (buf[512] == 0xa5)
+ printf("Checksum = 0x%02X (%s)\n", checksum, checksum ? "error" : "OK");
+ else
+ printf("No checksum supported\n");
+ }
+ return 0;
+}
+
+
+/*
+ A T A _ O P E N
+
+ opens the ata_device
+*/
+int ata_open_cmd(int argc, char **argv)
+{
+ inode->i_rdev = (ATA_BASE_ADDR >> 16) | (*argv[0] - '0');
+
+ filp->f_mode = FMODE_READ;
+
+ if (*argv[1] == 'w')
+ filp->f_mode |= FMODE_WRITE;
+
+ switch( ata_open(inode, filp) ) {
+ case EOPENIDEV:
+ printf( "Error: Invalid device (invalid MINOR %02X)\n", MINOR(inode->i_rdev) );
+ break;
+
+ case EOPENNODEV:
+ printf( "Error: Requested device not found\n" );
+ break;
+
+ case EOPENIHOST:
+ printf( "Error: Invalid host (invalid MAJOR %02X)\n", MAJOR(inode->i_rdev) );
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+
+/*
+ A T A _ S E T _ P I O M O D E
+
+ Sets the device to the requested PIO mode
+*/
+int ata_set_piomode_cmd(int argc, char **argv)
+{
+ return 0;
+}
+
+
+/*
+ A T A _ R E A D _ S E C T O R S
+
+ Reads 1 sector from the device and dumps it to the screen
+*/
+int ata_read_sectors_cmd(int argc, char **argv)
+{
+ struct request request;
+ unsigned long sector_cnt, sector;
+
+ sector = strtoul(argv[0], argv, 10);
+
+ switch (argc) {
+ case 2:
+ sector_cnt = strtoul(argv[1], argv, 10);
+ break;
+
+ case 1:
+ sector_cnt = 1;
+ break;
+
+ default:
+ return -1;
+ }
+
+ if ( !sector_cnt )
+ {
+ printf( "Invalid number of sectors.\n" );
+ return 0;
+ }
+
+ /* check for busy flag */
+ if ( ata_dev_busy(ATA_BASE_ADDR) )
+ printf("Selected ata device busy, ignoring command\n");
+ else
+ {
+ /* fill the request structure */
+ request.cmd = READ;
+ request.sector = sector;
+ request.nr_sectors = sector_cnt;
+ request.buffer = buf;
+
+ if ( ata_request(inode, filp, &request) )
+ {
+ printf("Error while executing READ_SECTOR(S) command\n");
+ printf("Status register = 0x%02lX, error register = 0x%02lX\n", ata_astatus(ATA_BASE_ADDR), ata_error(ATA_BASE_ADDR) );
+ }
+ else
+ {
+ /* dump data to the screen */
+ atabug_dump_data(buf, 512 * sector_cnt);
+ }
+ }
+ return 0;
+}
+
+
+/*
+ A T A _ R E A D _ M B R
+
+ Reads master boot record from the device and dumps it's contents to the screen
+*/
+int ata_read_mbr_cmd(int argc, char **argv)
+{
+ struct request request;
+ unsigned int partition;
+
+ // get requested partition number
+ partition = 0;
+ if (argc)
+ partition = strtoul(*argv, argv, 10);
+
+ /* check for busy flag */
+ if ( ata_dev_busy(ATA_BASE_ADDR) )
+ printf("Selected ata device busy, ignoring command\n");
+ else
+ {
+ /* fill the request structure */
+ request.cmd = READ;
+ request.sector = 0;
+ request.nr_sectors = 1;
+ request.buffer = buf;
+
+ if ( ata_request(inode, filp, &request) )
+ {
+ printf("Error while reading master boot sector.\n");
+ printf("Status register = 0x%02lX, error register = 0x%02lX\n", ata_astatus(ATA_BASE_ADDR), ata_error(ATA_BASE_ADDR) );
+ }
+ else
+ {
+ printf( "Skipping bootloader (446bytes)\n" );
+ printf( "Partition %1d:\n", partition);
+
+ // abuse partitionnumber to get offset in MBR record
+ partition *= 16;
+ partition += 446;
+
+ printf( "Bootindicator: 0x%2X (%s)\n", buf[partition], buf[partition] ? "bootable" : "non-bootable");
+ printf( "Partition start (head: 0x%02X cyl: 0x%03X sect: 0x%02X)\n",
+ buf[partition +1], (buf[partition +2] & 0xc0) << 2 | buf[partition +3] ,buf[partition +2] & 0x3f );
+ printf( "Systemindicator: 0x%02X (", buf[partition +4]);
+
+ switch (buf[partition +4])
+ {
+ case 0: printf ("Non DOS"); break;
+ case 1: printf ("DOS FAT12"); break;
+ case 4: printf ("DOS FAT16"); break;
+ case 5: printf ("DOS extended"); break;
+ case 6: printf ("DOS >32MByte"); break;
+
+ default : printf ("unkown");
+ };
+ printf (")\n");
+ printf( "Partition end (head: 0x%02X cyl: 0x%03X sect: 0x%02X)\n",
+ buf[partition +5], (buf[partition +6] & 0xc0) << 2 | buf[partition +7] ,buf[partition +6] & 0x3f );
+ printf( "Physical Startsector: 0x%08X\n", buf[partition +11] << 24 |
+ buf[partition +10] << 16 |
+ buf[partition +9] << 8 |
+ buf[partition +8]);
+ printf( "Sector count: 0x%08X\n", buf[partition +15] << 24 |
+ buf[partition +14] << 16 |
+ buf[partition +13] << 8 |
+ buf[partition +12]);
+ }
+ }
+ return 0;
+}
+
+
+/*
+ A T A _ R E A D _ D O S B O O T
+
+ Reads boot sector from the device and dumps it's contents to the screen
+*/
+int ata_read_dosboot_cmd(int argc, char **argv)
+{
+ struct request request;
+ unsigned int sector;
+ char txt[8];
+
+ sector = 0;
+ if (argc)
+ sector = strtoul(*argv, argv, 0);
+
+ /* check for busy flag */
+ if ( ata_dev_busy(ATA_BASE_ADDR) )
+ printf("Selected ata device busy, ignoring command\n");
+ else
+ {
+ /* fill the request structure */
+ request.cmd = READ;
+ request.sector = sector;
+ request.nr_sectors = 1;
+ request.buffer = buf;
+
+ if ( ata_request(inode, filp, &request) )
+ {
+ printf("Error whilereading boot sector 0x%02X.\n", sector);
+ printf("Status register = 0x%02lX, error register = 0x%02lX\n", ata_astatus(ATA_BASE_ADDR), ata_error(ATA_BASE_ADDR) );
+ }
+ else
+ {
+ printf( "Reading boot sector 0x%02X\n", sector );
+ printf( "ID number: 0x%2X%2X%2X\n", buf[0], buf[1], buf[2] );
+
+ printf( "OEM-name and number: " );
+ memcpy(txt, &buf[3], 8);
+ txt[8] = '\0';
+ printf( "%s\n", txt );
+
+ printf( "Bytes per sector: %5d\n", (buf[12]<<8) | buf[11] );
+ printf( "Sectors per cluster: %3d\n", buf[13] );
+ printf( "Reserved IM-sectors: %5d\n", (buf[15]<<8) | buf[14] );
+ printf( "Number of FATs: %3d\n", buf[16] );
+ printf( "Number of entries in the root-directory: %5d\n", (buf[18]<<8) | buf[17] );
+ printf( "Number of logical sectors: %5d\n", (buf[20]<<8) | buf[19] );
+ printf( "Medium descriptor byte: %02X\n", buf[21] );
+ printf( "Sectors per FAT: %5d\n", (buf[23]<<8) | buf[22] );
+ printf( "Sectors per track: %5d\n", (buf[25]<<8) | buf[24] );
+ printf( "Number of heads: %5d\n", (buf[27]<<8) | buf[26] );
+ printf( "Number of hidden sectors: %5d\n", (buf[29]<<8) | buf[28] );
+ }
+ }
+ return 0;
+}
+
+
+/*
+ A T A _ R E S E T
+
+ resets the ATA device, using the select method
+*/
+int ata_reset_cmd(int argc, char **argv)
+{
+ if (argc != 1)
+ return -1;
+
+ return ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, SET | (**argv - '0') );
+}
+
+
+/*
+ A T A _ S E L E C T _ D E V I C E
+
+ selects the ATA device; sets the DEV bit in the device/head register
+*/
+int ata_select_device_cmd(int argc, char **argv)
+{
+ if (argc != 1)
+ return -1;
+
+ inode->i_rdev = (ATA_BASE_ADDR >> 16) | (*argv[0] - '0');
+
+ ata_ioctl(inode, filp, ATA_IOCTL_SELECT_DEVICE, **argv - '0');
+
+ printf("Ata device %1d selected.\n", REG32(ATA_BASE_ADDR + ATA_DHR) & ATA_DHR_DEV ? 1 : 0);
+ return 0;
+}
+
+
+
+
+/**********************************************************************/
+/* */
+/* A T A B U G T O O L S */
+/* */
+/**********************************************************************/
+
+/*
+ D U M P _ D A T A
+
+ dumps byte-data in a buffer of type short to the screen
+ and returns the byte-checksum
+
+ *buffer = pointer to (short)buffer
+ cnt = number of bytes to display
+*/
+unsigned char atabug_dump_data(unsigned char *buffer, int cnt)
+{
+ int i, n, bytes_per_line = 16;
+ unsigned char c, checksum;
+ unsigned char *buf_ptr;
+
+ /* prepare stored data for display & calculate checksum */
+ checksum = 0;
+ buf_ptr = buffer;
+
+ /* display data */
+ for (i=0; i < cnt; i += bytes_per_line)
+ {
+ printf("%3X ", i);
+
+ /* print hexadecimal notation */
+ for (n=0; n < bytes_per_line; n++)
+ printf("%02X ", *buf_ptr++);
+
+ buf_ptr -= bytes_per_line; /* back to the start (of this block) */
+
+ /* print ASCII notation & calculate checksum */
+ for (n=0; n < bytes_per_line; n++)
+ {
+ c = *buf_ptr++;
+ printf("%c", isprint(c) ? c : '.');
+ checksum += c;
+ }
+ printf("\n");
+ }
+
+ return checksum;
+}
+
+
Index: hdbug.c
===================================================================
--- hdbug.c (nonexistent)
+++ hdbug.c (revision 1765)
@@ -0,0 +1,403 @@
+/*
+ hdbug.c -- harddisk debugging
+ Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
+
+ This file is part of OpenRISC 1000 Reference Platform Monitor (ORPmon)
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include "support.h"
+#include "common.h"
+#include "dos.h"
+#include "hdbug.h"
+#include
+
+
+static int hdbug_num_commands;
+static command_struct hdbug_command[MAX_HDBUG_COMMANDS];
+
+static struct dosparam _dos_params;
+static struct dosparam *dos_params = &_dos_params;
+
+
+/**********************************************************************/
+/* */
+/* H D B U G */
+/* */
+/**********************************************************************/
+/*
+ H D B U G _ I N I T
+
+ initializes the ata core, mounts the DOS file system, and
+ provides methods for accessing DOS drives
+*/
+void module_hdbug_init (void)
+{
+ hdbug_num_commands = 0;
+
+ register_command ("hdbug", " []", "Opens ata device & mounts DOS filesystem", hdbug_mount_cmd);
+ register_hdbug_command ("umount", "", "Unmounts DOS filesystem & Closes device", hdbug_umount_cmd);
+
+ register_hdbug_command ("dir", "", "dos 'dir' command.", hdbug_dir_cmd);
+ register_hdbug_command ("cd", "", "dos 'cd' command.", hdbug_cd_cmd);
+ register_hdbug_command ("help", "", "Display this help message", hdbug_help);
+ register_hdbug_command ("exit", "", "Exit hdbug and return to ORPmon", hdbug_umount_cmd);
+}
+
+
+/*
+ The next code is graceously taken from the "common.c" file
+ and slightly modified.
+
+ Better would be if we could access the routines in 'common.c'
+ directly, using our own set of commands.
+*/
+
+/* Process command-line, generate arguments */
+int hdbug_mon_command(void)
+{
+ char c = '\0';
+ char str[1000];
+ char *pstr = str;
+ char *command_str;
+ char *argv[20];
+ int argc = 0;
+
+
+ /* Show prompt */
+ printf ("\nhdbug> ");
+
+
+ /* Get characters from UART */
+ c = getc();
+ while (c != '\r' && c != '\f' && c != '\n')
+ {
+ if (c == '\b')
+ pstr--;
+ else
+ *pstr++ = c;
+ putc(c);
+ c = getc();
+ }
+ *pstr = '\0';
+ printf ("\n");
+
+ /* Skip leading blanks */
+ pstr = str;
+ while ( isspace(*pstr) ) pstr++;
+
+ /* Get command from the string */
+ command_str = pstr;
+
+ while (1) {
+ /* Go to next argument */
+ while ( isgraph(*pstr) ) pstr++;
+ if (*pstr) {
+ *pstr++ = '\0';
+ while ( isspace(*pstr) ) pstr++;
+ argv[argc++] = pstr;
+ }
+ else
+ break;
+ }
+
+ return execute_hdbug_command(command_str, argc, argv);
+}
+
+
+int execute_hdbug_command(char *command_str, int argc, char **argv)
+{
+ int i, found = 0;
+
+ for (i = 0; i < hdbug_num_commands; i++)
+ if ( !strcmp(command_str, hdbug_command[i].name) )
+ {
+ switch ( hdbug_command[i].func(argc, argv) )
+ {
+ case -1:
+ printf ("Missing/wrong parameters, usage: %s %s\n", hdbug_command[i].name, hdbug_command[i].params);
+ break;
+
+ case -2:
+ return -1;
+ }
+
+ found++;
+ break;
+ }
+
+ if (!found)
+ printf ("Unknown command. Type 'hdbug help' for help.\n");
+
+ return 0;
+}
+
+
+void register_hdbug_command (const char *name, const char *params, const char *help, int (*func)(int argc, char *argv[]) )
+{
+ if (hdbug_num_commands < MAX_HDBUG_COMMANDS)
+ {
+ hdbug_command[hdbug_num_commands].name = name;
+ hdbug_command[hdbug_num_commands].params = params;
+ hdbug_command[hdbug_num_commands].help = help;
+ hdbug_command[hdbug_num_commands].func = func;
+ hdbug_num_commands++;
+ }
+ else
+ printf ("hdbug-command '%s' ignored; MAX_COMMANDS limit reached\n", name);
+}
+
+int hdbug_help(int argc, char **argv)
+{
+ int i;
+
+ for (i = 0; i < hdbug_num_commands; i++)
+ printf ("%-15s %-17s -%s\n", hdbug_command[i].name, hdbug_command[i].params, hdbug_command[i].help);
+
+ return 0;
+}
+
+
+
+
+/**********************************************************************/
+/* */
+/* H D B U G C O M M A N D S E T */
+/* */
+/**********************************************************************/
+
+/*
+ H D B U G _ M O U N T
+
+ opens the ata-device and mounts the dos filesystem
+*/
+int hdbug_mount_cmd(int argc, char **argv)
+{
+ int error;
+
+ if (argc != 2)
+ return -1;
+
+
+ /* try to open the requested device (read-only) */
+ dos_params->inode.i_rdev = (ATA_BASE_ADDR >> 16) | (**argv - '0');
+ dos_params->filp.f_mode = FMODE_READ;
+
+ /* open device */
+ if ( (error = dos_open(dos_params)) )
+ {
+ switch (error) {
+ case EINVAL:
+ printf( "Error, device busy.\n" ); /* standard response to EINVAL */
+ break;
+
+ case EIOCTLIARG:
+ printf( "Error, invalid IOCTL call.\n" );
+ break;
+
+ case EOPENIDEV:
+ printf( "Error, invalid device.\n" );
+ break;
+
+ case EOPENIHOST:
+ printf( "Error, ata host controller not found.\n" );
+ break;
+
+ case EOPENNODEV:
+ printf( "Error, ata-device not found.\n" );
+ break;
+
+ default:
+ printf( "Unkown error.\n" );
+ break;
+ }
+ }
+ else
+ {
+ printf( "directory startsector: 0x%08lX\n", dos_params->ssector );
+ printf( "cluster startsector : 0x%08lX\n", dos_params->csector );
+ printf( "cluster startentry : 0x%08lX\n", dos_params->sentry );
+
+ /* device is opened, filesystem is mounted, start command prompt */
+ while ( !hdbug_mon_command() );
+ }
+
+ return 0;
+}
+
+
+/*
+ H D B U G _ U M O U N T
+
+ unmounts the dos filesystem and closes the ata-device
+*/
+int hdbug_umount_cmd(int argc, char **argv)
+{
+ dos_release(dos_params);
+
+ return -2;
+}
+
+
+/*
+ H D B U G _ C D
+*/
+int hdbug_cd_cmd(int argc, char **argv)
+{
+ struct dos_dir_entry *entry;
+
+ switch (argc) {
+ case 0:
+ /* display present working directory */
+ printf( "FIXME: present working directory\n" );
+ return 0;
+
+ case 1:
+ break;
+
+ default:
+ printf( "Too many arguments.\n" );
+ return 0;
+ }
+
+ /* search for the requested directory */
+ if ( !(entry = dos_dir_find_entry(dos_params, *argv)) )
+ {
+ printf( "The system cannot find the specified path.\n" );
+ return 0;
+ }
+
+
+ return 0;
+}
+
+
+/*
+ H D B U G _ D I R
+*/
+int hdbug_dir_cmd(int argc, char **argv)
+{
+ register int i;
+
+ /* read the directory structures from the current directory
+ and display the results */
+
+ /* TODO: Add sub-directories */
+
+ /* get first cluster of current directory */
+ dos_dir_cluster_reset(dos_params);
+
+ for (i=0; i < dos_params->root_entries; i++)
+ hdbug_dir_print( dos_dir_get_entry(dos_params, i) );
+
+ return 0;
+}
+
+
+int hdbug_dir_print(struct dos_dir_entry *entry)
+{
+ unsigned long ltmp;
+ unsigned short stmp;
+
+ char txt[9];
+
+ switch (entry->name[0]) {
+ case 0x00:
+ /* empty entry */
+ break;
+
+ case 0xe5:
+ /* deleted/removed entry */
+ break;
+
+ default:
+ /* check if entry is a label */
+ if (entry->attribute & ATT_LAB)
+ {
+ printf( "LABEL: " );
+ memcpy(txt, entry->name, 8);
+ txt[8] = '\0';
+ printf( "%s", txt);
+ memcpy(txt, entry->ext, 3);
+ txt[3] = '\0';
+ printf( "%s\n", txt);
+ }
+ else
+ {
+ /* display date & time */
+ stmp = entry->date;
+ swap(&stmp, sizeof(short) );
+ printf( "%02d-%02d-%4d ",stmp & 0x1f, (stmp >> 5) & 0xf, ((stmp >> 9) & 0xffff) +1980);
+
+ stmp = entry->time;
+ swap(&stmp, sizeof(short) );
+ printf( "%02d:%02d ", (stmp >> 11) & 0x1f, (stmp >> 5) & 0x3f );
+
+ /* display directory bit */
+ printf( "%s ", entry->attribute & ATT_DIR ? "" : " " );
+
+ /* display filesize */
+ ltmp = entry->size;
+ swap(<mp, sizeof(unsigned long) );
+ printf( "%12ld ", ltmp );
+
+ /* replace the first 'space' in the name by an null char */
+ *(char*)memchr(entry->name, 0x20, 8) = '\0';
+ printf( "%s", entry->name);
+
+ /* add extension */
+ if (entry->ext[0] != 0x20)
+ {
+ printf( ".%3s", entry->ext);
+ }
+
+ printf("\n");
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+ H D B U G T O O L S
+*/
+inline void *swap(void *var, size_t size)
+{
+ switch(size) {
+ case 1:
+ return var;
+
+ case 2:
+ {
+ unsigned short p = *(unsigned short*)var;
+ *(unsigned short*)var = (p << 8) | (p >> 8);
+ return var;
+ }
+
+ case 4:
+ {
+ unsigned long *p = (unsigned long*)var;
+ *p = (*p << 24) | ( (*p & 0x0000ff00) << 8) | ( (*p & 0x00ff0000) >> 8) | (*p >> 24);
+ return var;
+ }
+
+ default:
+ return NULL;
+ }
+}
Index: Makefile
===================================================================
--- Makefile (nonexistent)
+++ Makefile (revision 1765)
@@ -0,0 +1,12 @@
+
+LIB = cmds.o
+OBJS = dhry.o eth.o cpu.o camera.o load.o memory.o global.o touch.o atabug.o hdbug.o
+
+all: $(LIB)
+
+$(LIB): $(OBJS)
+ $(LD) -r -o $@ $(OBJS)
+
+.depend: Makefile $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+sinclude .depend
Index: camera.c
===================================================================
--- camera.c (nonexistent)
+++ camera.c (revision 1765)
@@ -0,0 +1,146 @@
+#include "common.h"
+#include "support.h"
+#include "spr_defs.h"
+
+/* Camera and CRT test.
+ Draws gray cross across the screen, few color boxes at top left and moves around camera captured screen left/right
+ in the middle. */
+
+#define CAMERA_BASE 0x88000000
+#define CRT_BASE 0xc0000000
+#define VIDEO_RAM_START 0xa8000000 /* till including a83ffffc */
+
+#define SCREEN_X 640
+#define SCREEN_Y 480
+
+#define CAMERA_X 352
+#define CAMERA_Y 288
+
+#define CAMERA_BUF(idx) (VIDEO_RAM_START + (idx) * CAMERA_X * CAMERA_Y)
+#define FRAME_BUF (CAMERA_BUF(2))
+
+#define CAMERA_POS (camera_pos_x + ((SCREEN_Y - CAMERA_Y) / 2) * SCREEN_X)
+
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+
+#define set_mem32(addr,val) (*((unsigned long *) (addr)) = (val))
+#define get_mem32(addr) (*((unsigned long *) (addr)))
+#define set_palette(idx,r,g,b) set_mem32 (CRT_BASE + 0x400 + (idx) * 4, (((r) >> 3) << 11) | (((g) >> 2) << 5) | (((b) >> 3) << 0))
+#define put_pixel(xx,yy,idx) (*(unsigned char *)(FRAME_BUF + (xx) + (yy) * SCREEN_X) = (idx))
+
+int camera_pos_x;
+int camera_move_speed = 1;
+int current_buf;
+
+void camera_int (void)
+{
+ /* Change base addresse of camera */
+ set_mem32 (CAMERA_BASE, CAMERA_BUF(current_buf)); /* Set address to store to */
+
+ /* Change base addresse of crt */
+ set_mem32 (CRT_BASE + 8, CAMERA_BUF(1 - current_buf)); /* Tell CRT when camera buffer is */
+ printf ("\n %08x\n ", CAMERA_BUF(current_buf));
+
+ current_buf = 1 - current_buf;
+
+ /* move the camera screen around */
+ camera_pos_x += camera_move_speed;
+ if (camera_pos_x >= SCREEN_X - CAMERA_X || camera_pos_x <= 0)
+ camera_move_speed = -camera_move_speed;
+ mtspr(SPR_PICSR, 0);
+}
+
+int crt_enable_cmd (int argc, char *argv[])
+{
+ int i, x, y;
+
+ if (argc) return -1;
+ /* Init CRT */
+ set_mem32 (CRT_BASE + 4, FRAME_BUF); /* Frame buffer start */
+ set_mem32 (CRT_BASE, get_mem32 (CRT_BASE) | 1); /* Enable CRT only */
+
+ /* Init palette */
+ for (i = 0; i < 32; i++) {
+ set_palette (8 * i + 0, 0x00, 0x00, 0x00); /* black */
+ set_palette (8 * i + 1, 0xff, 0xff, 0xff); /* white */
+ set_palette (8 * i + 2, 0x7f, 0x7f, 0x7f); /* gray */
+ set_palette (8 * i + 3, 0xff, 0x00, 0x00); /* red */
+ set_palette (8 * i + 4, 0x00, 0xff, 0x00); /* green */
+ set_palette (8 * i + 5, 0x00, 0x00, 0xff); /* blue */
+ set_palette (8 * i + 6, 0x00, 0xff, 0xff); /* cyan */
+ set_palette (8 * i + 7, 0xff, 0x00, 0xff); /* purple */
+ }
+ for (x = 0; x < SCREEN_X; x++)
+ for (y = 0; y < SCREEN_Y; y++)
+ put_pixel(x, y, 3);
+ return 0;
+}
+
+int crt_test_cmd (int argc, char *argv[])
+{
+ int i, x, y;
+ if (argc) return -1;
+ for (x = 0; x < SCREEN_X; x++)
+ for (y = 0; y < SCREEN_Y; y++)
+ put_pixel(x, y, 0);
+ /* Draw gray X */
+ for (i = 0; i < SCREEN_Y; i++) {
+ put_pixel (i, i, 2);
+ put_pixel (SCREEN_X - i - 1, i, 1);
+ }
+
+ /* Draw color boxes */
+ for (y = 0; y < 50; y++)
+ for (x = 0; x < 50; x++)
+ for (i = 0; i < 8; i++)
+ put_pixel (i * 50 + x, y, i);
+ return 0;
+}
+
+int crt_disable_cmd (int argc, char *argv[])
+{
+ if (argc) return -1;
+ set_mem32 (CRT_BASE, get_mem32 (CRT_BASE) & ~1); /* Disable CRT */
+ return 0;
+}
+
+int camera_enable_cmd (int argc, char *argv[])
+{
+ if (argc) return -1;
+ /* Init Camera */
+ set_mem32 (CAMERA_BASE, CAMERA_BUF(current_buf = 0)); /* Set address to store to */
+ set_mem32 (CAMERA_BASE + 4, 1); /* Enable it */
+
+ /* Init CRT to display camera */
+ set_mem32 (CRT_BASE + 8, CAMERA_BUF(1 - current_buf)); /* Tell CRT when camera buffer is */
+ camera_pos_x = 0;
+ set_mem32 (CRT_BASE + 0xc, CAMERA_POS);
+ set_mem32 (CRT_BASE, get_mem32 (CRT_BASE) | 2); /* Enable camera overlay */
+
+ /* Enable interrupts */
+ mtspr (SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE);
+ mtspr (SPR_PICMR, mfspr(SPR_PICSR) | (1 << 13));
+ return 0;
+}
+
+int camera_disable_cmd (int argc, char *argv[])
+{
+ if (argc) return -1;
+ /* Disable interrupts */
+ mtspr (SPR_SR, mfspr(SPR_SR) & ~SPR_SR_IEE);
+ mtspr (SPR_PICMR, mfspr(SPR_PICSR) & ~(1 << 13));
+
+ /* Disable Camera */
+ set_mem32 (CAMERA_BASE + 4, 1); /* Enable it */
+ set_mem32 (CRT_BASE, get_mem32 (CRT_BASE) & ~2); /* Disable camera overlay */
+ return 0;
+}
+
+void module_camera_init (void)
+{
+ register_command ("crt_enable", "", "enables CRT", crt_enable_cmd);
+ register_command ("crt_disable", "", "disables CRT", crt_disable_cmd);
+ register_command ("crt_test", "", "enables CRT and displays some test patterns", crt_test_cmd);
+ register_command ("camera_enable", "", "enables camera", camera_enable_cmd);
+ register_command ("camera_disable", "", "disables camera", camera_disable_cmd);
+}
Index: global.c
===================================================================
--- global.c (nonexistent)
+++ global.c (revision 1765)
@@ -0,0 +1,90 @@
+#include "common.h"
+#include "support.h"
+
+global_struct global;
+
+int src_addr_cmd (int argc, char *argv[])
+{
+ if (argc == 1) {
+ global.src_addr = strtoul (argv[0], 0, 0);
+ return 0;
+ } else return -1;
+}
+
+int dst_addr_cmd (int argc, char *argv[])
+{
+ if (argc == 1) {
+ global.dst_addr = strtoul (argv[0], 0, 0);
+ return 0;
+ } else return -1;
+}
+
+int length_cmd (int argc, char *argv[])
+{
+ if (argc == 1) {
+ global.length = strtoul (argv[0], 0, 0);
+ return 0;
+ } else return -1;
+}
+
+int ip_cmd (int argc, char *argv[])
+{
+ if (argc == 1) {
+ global.ip = parse_ip (argv[0]);
+ return 0;
+ } else return -1;
+}
+
+int srv_ip_cmd (int argc, char *argv[])
+{
+ if (argc == 1) {
+ global.srv_ip = parse_ip (argv[0]);
+ return 0;
+ } else return -1;
+}
+
+int erase_method_cmd (int argc, char *argv[])
+{
+ if (argc == 1) {
+ int a = strtoul (argv[0], 0, 0);
+ if (a < 0 || a > 2) return -1;
+ global.erase_method = a;
+ return 0;
+ } else return -1;
+}
+
+int start_addr_cmd (int argc, char *argv[])
+{
+ if (argc == 1) {
+ global.start_addr = strtoul (argv[0], 0, 0);
+ return 0;
+ } else return -1;
+}
+
+#if HELP_ENABLED
+int globals_cmd (int argc, char *argv[])
+{
+ const char *erase_method_desc[] = {"do not erase", "fully", "as needed"};
+ if (argc) return -1;
+ printf ("src_addr = %08lx\n", global.src_addr);
+ printf ("dst_addr = %08lx\n", global.dst_addr);
+ printf ("start_addr = %08lx\n", global.start_addr);
+ printf ("length = %08lx\n", global.length);
+ printf ("ip = %08lx\n", global.ip);
+ printf ("srv_ip = %08lx\n", global.srv_ip);
+ printf ("erase_method = %i (%s)\n", (int)global.erase_method, erase_method_desc[global.erase_method]);
+ return 0;
+}
+#endif /* HELP_ENABLED */
+
+void module_global_init (void)
+{
+ register_command ("src_addr", "", "sets global parameter source address", src_addr_cmd);
+ register_command ("dst_addr", "", "sets global parameter destination address", dst_addr_cmd);
+ register_command ("start_addr", "", "sets start address", start_addr_cmd);
+ register_command ("length", "", "sets global parameter length", length_cmd);
+ register_command ("ip", " ", "sets global parameter ip address", ip_cmd);
+ register_command ("srv_ip", " ", "sets global parameter server ip address", srv_ip_cmd);
+ register_command ("erase_method", " ", "sets flash erase method (0 = do not erase, 1 = fully, 2 = as needed)", erase_method_cmd);
+ if (HELP_ENABLED) register_command ("globals", "", "show globals", globals_cmd);
+}
Index: dhry.c
===================================================================
--- dhry.c (nonexistent)
+++ dhry.c (revision 1765)
@@ -0,0 +1,706 @@
+/*
+ ****************************************************************************
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry_1.c (part 2 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ *
+ ****************************************************************************
+ */
+#include "dhry.h"
+#include "spr_defs.h"
+#include "common.h"
+#include "support.h"
+
+#define DLX_FREQ 200 /* in MHz */
+#define PROC_6 0
+
+#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
+#define UNALIGNED(X, Y) \
+ (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+
+void start_timer(void)
+{
+ unsigned long val;
+
+ val = SPR_TTMR_SR | 0x0fffffff;
+ asm("l.mtspr r0,%0,%1": : "r" (val), "i" (SPR_TTMR));
+ val = 0;
+ asm("l.mtspr r0,%0,%1": : "r" (val), "i" (SPR_TTCR));
+}
+
+unsigned long read_timer(void)
+{
+ unsigned long val;
+
+ asm("l.mfspr %0,r0,%1": "=r" (val) : "i" (SPR_TTCR));
+ return val;
+}
+
+/* Global Variables: */
+
+Rec_Pointer Ptr_Glob,
+ Next_Ptr_Glob;
+int Int_Glob;
+Boolean Bool_Glob;
+char Ch_1_Glob,
+ Ch_2_Glob;
+int Arr_1_Glob [50];
+int Arr_2_Glob [50] [50];
+
+
+ /* forward declaration necessary since Enumeration may not simply be int */
+
+#ifndef REG
+ Boolean Reg = false;
+#define REG
+ /* REG becomes defined as empty */
+ /* i.e. no register variables */
+#else
+ Boolean Reg = true;
+#endif
+
+/* variables for time measurement: */
+
+#if DLX || OR1K
+#define Too_Small_Time DLX_FREQ
+#else
+#define Too_Small_Time 1
+#endif
+
+#define TIMER0 0
+#define TIMER1 1
+
+
+
+
+
+unsigned int Begin_Time,
+ End_Time,
+ User_Time,
+ Microseconds,
+ Dhrystones_Per_Second;
+
+/* end of variables for time measurement */
+
+
+void Proc_1(REG Rec_Pointer Ptr_Val_Par);
+void Proc_2(One_Fifty *Int_Par_Ref);
+void Proc_3(Rec_Pointer *Ptr_Ref_Par);
+void Proc_4(void);
+void Proc_5(void);
+void Proc_6(
+ Enumeration Enum_Val_Par,
+ Enumeration *Enum_Ref_Par);
+void Proc_7(
+ One_Fifty Int_1_Par_Val,
+ One_Fifty Int_2_Par_Val,
+ One_Fifty *Int_Par_Ref);
+void Proc_8(
+ Arr_1_Dim Arr_1_Par_Ref,
+ Arr_2_Dim Arr_2_Par_Ref,
+ int Int_1_Par_Val,
+ int Int_2_Par_Val);
+Enumeration Func_1(Capital_Letter Ch_1_Par_Val,
+ Capital_Letter Ch_2_Par_Val);
+Boolean Func_2(Str_30 Str_1_Par_Ref, Str_30 Str_2_Par_Ref);
+Boolean Func_3(Enumeration Enum_Par_Val);
+
+int dhry_main (int num_runs)
+/*****/
+
+ /* main program, corresponds to procedures */
+ /* Main and Proc_0 in the Ada version */
+{
+ One_Fifty Int_1_Loc;
+ REG One_Fifty Int_2_Loc;
+ One_Fifty Int_3_Loc;
+ REG char Ch_Index;
+ Enumeration Enum_Loc;
+ Str_30 Str_1_Loc;
+ Str_30 Str_2_Loc;
+ REG int Run_Index;
+ REG int Number_Of_Runs;
+ Rec_Type x, y;
+
+ /* Initializations */
+
+ Next_Ptr_Glob = (Rec_Pointer) &x;
+ Ptr_Glob = (Rec_Pointer) &y;
+
+ Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
+ Ptr_Glob->Discr = Ident_1;
+ Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
+ Ptr_Glob->variant.var_1.Int_Comp = 40;
+ strcpy (Ptr_Glob->variant.var_1.Str_Comp,
+ "DHRYSTONE PROGRAM, SOME STRING");
+ strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
+
+ Arr_2_Glob [8][7] = 10;
+ /* Was missing in published program. Without this statement, */
+ /* Arr_2_Glob [8][7] would have an undefined value. */
+ /* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
+ /* overflow may occur for this array element. */
+
+/* Initalize Data and Instruction Cache */
+
+
+/* printf ("\n");
+ printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
+ printf ("\n");
+ if (Reg)
+ {
+ printf ("Program compiled with 'register' attribute\n");
+ printf ("\n");
+ }
+ else
+ {
+ printf ("Program compiled without 'register' attribute\n");
+ printf ("\n");
+ }
+ printf ("Please give the number of runs through the benchmark: ");
+ */
+ {
+ int n;
+ /* scanf ("%d", &n);
+ */
+ n = num_runs;
+ Number_Of_Runs = n;
+ }
+ printf ("\n");
+
+ printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
+
+
+ /***************/
+ /* Start timer */
+ /***************/
+
+/* printf("%d", my_test2(Number_Of_Runs));*/
+ start_timer();
+ Begin_Time = read_timer();
+
+ for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
+ {
+
+ Proc_5();
+ Proc_4();
+ /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
+ Int_1_Loc = 2;
+ Int_2_Loc = 3;
+ strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
+ Enum_Loc = Ident_2;
+
+ Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
+ /* Bool_Glob == 1 */
+ while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
+ {
+ Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
+ /* Int_3_Loc == 7 */
+ Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
+ /* Int_3_Loc == 7 */
+ Int_1_Loc += 1;
+ } /* while */
+ /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+#if DBG
+ printf("a) Int_1_Loc: %x\n", Int_1_Loc);
+ printf("a) Int_2_Loc: %x\n", Int_2_Loc);
+ printf("a) Int_3_Loc: %x\n\n", Int_3_Loc);
+#endif
+ Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
+ /* Int_Glob == 5 */
+#if DBG
+ printf("b) Int_1_Loc: %x\n", Int_1_Loc);
+ printf("b) Int_2_Loc: %x\n", Int_2_Loc);
+ printf("b) Int_3_Loc: %x\n\n", Int_3_Loc);
+#endif
+
+ Proc_1 (Ptr_Glob);
+#if DBG
+ printf("c) Int_1_Loc: %x\n", Int_1_Loc);
+ printf("c) Int_2_Loc: %x\n", Int_2_Loc);
+ printf("c) Int_3_Loc: %x\n\n", Int_3_Loc);
+#endif
+
+ for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
+ /* loop body executed twice */
+ {
+ if (Enum_Loc == Func_1 (Ch_Index, 'C'))
+ /* then, not executed */
+ {
+ Proc_6 (Ident_1, &Enum_Loc);
+ strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
+ Int_2_Loc = Run_Index;
+ Int_Glob = Run_Index;
+#if DBG
+ printf("d) Int_1_Loc: %x\n", Int_1_Loc);
+ printf("d) Int_2_Loc: %x\n", Int_2_Loc);
+ printf("d) Int_3_Loc: %x\n\n", Int_3_Loc);
+#endif
+ }
+ }
+
+ /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+#if DBG
+ printf("e) Int_1_Loc: %x\n", Int_1_Loc);
+ printf("e) Int_2_Loc: %x\n", Int_2_Loc);
+ printf("e) Int_3_Loc: %x\n", Int_3_Loc);
+ printf("e) Ch_1_Glob: %c\n\n", Ch_1_Glob);
+#endif
+ Int_2_Loc = Int_2_Loc * Int_1_Loc;
+ Int_1_Loc = Int_2_Loc * Int_3_Loc;
+ Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
+ /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
+ Proc_2 (&Int_1_Loc);
+
+ /* Int_1_Loc == 5 */
+#if DBG
+ printf("f) Int_1_Loc: %x\n", Int_1_Loc);
+ printf("f) Int_2_Loc: %x\n", Int_2_Loc);
+ printf("f) Int_3_Loc: %x\n\n", Int_3_Loc);
+#endif
+
+ } /* loop "for Run_Index" */
+
+ /**************/
+ /* Stop timer */
+ /**************/
+
+ End_Time = read_timer();
+
+/* printf ("Execution ends\n");
+ printf ("\n");
+ printf ("Final values of the variables used in the benchmark:\n");
+ printf ("\n");
+ printf ("Int_Glob: %d\n", Int_Glob);
+ printf (" should be: %d\n", 5);
+ printf ("Bool_Glob: %d\n", Bool_Glob);
+ printf (" should be: %d\n", 1);
+ printf ("Ch_1_Glob: %c\n", Ch_1_Glob);
+ printf (" should be: %c\n", 'A');
+ printf ("Ch_2_Glob: %c\n", Ch_2_Glob);
+ printf (" should be: %c\n", 'B');
+ printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
+ printf (" should be: %d\n", 7);
+ printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
+ printf (" should be: Number_Of_Runs + 10\n");
+ printf ("Ptr_Glob->\n");
+ printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp);
+ printf (" should be: (implementation-dependent)\n");
+ printf (" Discr: %d\n", Ptr_Glob->Discr);
+ printf (" should be: %d\n", 0);
+ printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
+ printf (" should be: %d\n", 2);
+ printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp);
+ printf (" should be: %d\n", 17);
+ printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp);
+ printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
+ printf ("Next_Ptr_Glob->\n");
+ printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
+ printf (" should be: (implementation-dependent), same as above\n");
+ printf (" Discr: %d\n", Next_Ptr_Glob->Discr);
+ printf (" should be: %d\n", 0);
+ printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
+ printf (" should be: %d\n", 1);
+ printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
+ printf (" should be: %d\n", 18);
+ printf (" Str_Comp: %s\n",
+ Next_Ptr_Glob->variant.var_1.Str_Comp);
+ printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
+ printf ("Int_1_Loc: %d\n", Int_1_Loc);
+ printf (" should be: %d\n", 5);
+ printf ("Int_2_Loc: %d\n", Int_2_Loc);
+ printf (" should be: %d\n", 13);
+ printf ("Int_3_Loc: %d\n", Int_3_Loc);
+ printf (" should be: %d\n", 7);
+ printf ("Enum_Loc: %d\n", Enum_Loc);
+ printf (" should be: %d\n", 1);
+ printf ("Str_1_Loc: %s\n", Str_1_Loc);
+ printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
+ printf ("Str_2_Loc: %s\n", Str_2_Loc);
+ printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
+
+*/
+
+
+ User_Time = End_Time - Begin_Time;
+ /* microseconds */
+
+ printf("Begin Time = %d\n",Begin_Time);
+ printf("End Time = %d\n",End_Time);
+
+ printf ("\nNumber of Runs %i", num_runs);
+ printf ("\nBegin Time %i", Begin_Time);
+ printf ("\nEnd Time %i\n", End_Time);
+
+ if (User_Time < Too_Small_Time)
+ {
+ printf ("Measured time too small to obtain meaningful results\n");
+ printf ("Please increase number of runs\n");
+ printf ("\n");
+ }
+ else
+ {
+#if DLX || OR1K
+// User_Time /= DLX_FREQ;
+#if DLX
+ printf("DLX ");
+#else
+#if OR1K
+ printf("OR1K ");
+#else
+ printf("Unknown CPU ");
+#endif
+#endif
+ printf("at %u MHz ", DLX_FREQ);
+ if (PROC_6)
+ printf("(+PROC_6)");
+ printf("\n");
+#endif
+// Microseconds = User_Time / Number_Of_Runs;
+// Dhrystones_Per_Second = Number_Of_Runs * 1000 / User_Time;
+ printf ("Microseconds for one run through Dhrystone: ");
+ printf ("%d us / %d runs\n", User_Time,Number_Of_Runs);
+ printf ("Dhrystones per Second: ");
+ printf ("%d \n", Dhrystones_Per_Second);
+ }
+ return 0;
+}
+
+
+void Proc_1(Ptr_Val_Par)
+/******************/
+
+ REG Rec_Pointer Ptr_Val_Par;
+ /* executed once */
+{
+ REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
+ /* == Ptr_Glob_Next */
+ /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
+ /* corresponds to "rename" in Ada, "with" in Pascal */
+
+
+ structassign(*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
+ Ptr_Val_Par->variant.var_1.Int_Comp = 5;
+ Next_Record->variant.var_1.Int_Comp
+ = Ptr_Val_Par->variant.var_1.Int_Comp;
+ Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
+ Proc_3(&Next_Record->Ptr_Comp);
+ /*
+ * Ptr_Val_Par->Ptr_Comp->Ptr_Comp == Ptr_Glob->Ptr_Comp
+ */
+ if (Next_Record->Discr == Ident_1)
+ /* then, executed */
+ {
+ Next_Record->variant.var_1.Int_Comp = 6;
+ Proc_6(Ptr_Val_Par->variant.var_1.Enum_Comp,
+ &Next_Record->variant.var_1.Enum_Comp);
+ Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
+ Proc_7(Next_Record->variant.var_1.Int_Comp, 10,
+ &Next_Record->variant.var_1.Int_Comp);
+ } else /* not executed */
+ structassign(*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
+
+} /* Proc_1 */
+
+
+void
+ Proc_2(Int_Par_Ref)
+/******************/
+ /* executed once */
+ /* *Int_Par_Ref == 1, becomes 4 */
+
+ One_Fifty *Int_Par_Ref;
+{
+ One_Fifty Int_Loc;
+ Enumeration Enum_Loc = 0;
+
+
+ Int_Loc = *Int_Par_Ref + 10;
+ do /* executed once */
+ if (Ch_1_Glob == 'A')
+ /* then, executed */
+ {
+ Int_Loc -= 1;
+ *Int_Par_Ref = Int_Loc - Int_Glob;
+ Enum_Loc = Ident_1;
+ } /* if */
+ while (Enum_Loc != Ident_1);/* true */
+} /* Proc_2 */
+
+
+void
+ Proc_3(Ptr_Ref_Par)
+/******************/
+ /* executed once */
+ /* Ptr_Ref_Par becomes Ptr_Glob */
+
+ Rec_Pointer *Ptr_Ref_Par;
+
+{
+
+ if (Ptr_Glob != Null)
+ /* then, executed */
+ *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
+ Proc_7(10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
+} /* Proc_3 */
+
+
+void
+ Proc_4()
+{ /* without parameters */
+ /*******/
+ /* executed once */
+ Boolean Bool_Loc;
+
+
+ Bool_Loc = Ch_1_Glob == 'A';
+ Bool_Glob = Bool_Loc | Bool_Glob;
+ Ch_2_Glob = 'B';
+} /* Proc_4 */
+
+
+void
+ Proc_5()
+{ /* without parameters */
+ /*******/
+ /* executed once */
+
+ Ch_1_Glob = 'A';
+ Bool_Glob = false;
+} /* Proc_5 */
+
+/* @(#)dhry_2.c 1.2 92/05/28 14:44:54, AMD */
+/*
+ ****************************************************************************
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry_2.c (part 3 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ *
+ ****************************************************************************
+ */
+
+#ifndef REG
+#define REG
+ /* REG becomes defined as empty */
+ /* i.e. no register variables */
+#ifdef _AM29K
+#undef REG
+#define REG register /* Define REG; saves room on 127-char MS-DOS cmd line */
+#endif
+#endif
+
+
+void
+ Proc_6(Enum_Val_Par, Enum_Ref_Par)
+/*********************************/
+ /* executed once */
+ /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
+
+ Enumeration Enum_Val_Par;
+ Enumeration *Enum_Ref_Par;
+{
+#if PROC_6
+
+ *Enum_Ref_Par = Enum_Val_Par;
+ if (!Func_3(Enum_Val_Par))
+ /* then, not executed */
+ *Enum_Ref_Par = Ident_4;
+ switch (Enum_Val_Par) {
+ case Ident_1:
+ *Enum_Ref_Par = Ident_1;
+ break;
+ case Ident_2:
+ if (Int_Glob > 100)
+ /* then */
+ *Enum_Ref_Par = Ident_1;
+ else
+ *Enum_Ref_Par = Ident_4;
+ break;
+ case Ident_3: /* executed */
+ *Enum_Ref_Par = Ident_2;
+ break;
+ case Ident_4:
+ break;
+ case Ident_5:
+ *Enum_Ref_Par = Ident_3;
+ break;
+ } /* switch */
+#endif
+ return;
+} /* Proc_6 */
+
+void
+ Proc_7(Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
+/**********************************************/
+ /* executed three times */
+ /* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
+ /* Int_Par_Ref becomes 7 */
+ /* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
+ /* Int_Par_Ref becomes 17 */
+ /* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
+ /* Int_Par_Ref becomes 18 */
+ One_Fifty Int_1_Par_Val;
+ One_Fifty Int_2_Par_Val;
+ One_Fifty *Int_Par_Ref;
+{
+ One_Fifty Int_Loc;
+
+
+ Int_Loc = Int_1_Par_Val + 2;
+ *Int_Par_Ref = Int_2_Par_Val + Int_Loc;
+} /* Proc_7 */
+
+
+void
+ Proc_8(Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
+/*********************************************************************/
+ /* executed once */
+ /* Int_Par_Val_1 == 3 */
+ /* Int_Par_Val_2 == 7 */
+ Arr_1_Dim Arr_1_Par_Ref;
+ Arr_2_Dim Arr_2_Par_Ref;
+ int Int_1_Par_Val;
+ int Int_2_Par_Val;
+{
+ REG One_Fifty Int_Index;
+ REG One_Fifty Int_Loc;
+
+#if DBG
+ printf("X) Int_1_Par_Val: %x\n", Int_1_Par_Val);
+ printf("X) Int_2_Par_Val: %x\n", Int_2_Par_Val);
+#endif
+
+
+ Int_Loc = Int_1_Par_Val + 5;
+ Arr_1_Par_Ref[Int_Loc] = Int_2_Par_Val;
+ Arr_1_Par_Ref[Int_Loc + 1] = Arr_1_Par_Ref[Int_Loc];
+ Arr_1_Par_Ref[Int_Loc + 30] = Int_Loc;
+ for (Int_Index = Int_Loc; Int_Index <= Int_Loc + 1; ++Int_Index)
+ Arr_2_Par_Ref[Int_Loc][Int_Index] = Int_Loc;
+ Arr_2_Par_Ref[Int_Loc][Int_Loc - 1] += 1;
+ Arr_2_Par_Ref[Int_Loc + 20][Int_Loc] = Arr_1_Par_Ref[Int_Loc];
+ Int_Glob = 5;
+
+#if DBG
+ printf("Y) Int_1_Par_Val: %x\n", Int_1_Par_Val);
+ printf("Y) Int_2_Par_Val: %x\n", Int_2_Par_Val);
+#endif
+
+} /* Proc_8 */
+
+
+Enumeration
+ Func_1(Ch_1_Par_Val, Ch_2_Par_Val)
+/*************************************************/
+ /* executed three times */
+ /* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
+ /* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
+ /* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
+
+ Capital_Letter Ch_1_Par_Val;
+ Capital_Letter Ch_2_Par_Val;
+{
+ Capital_Letter Ch_1_Loc;
+ Capital_Letter Ch_2_Loc;
+
+
+ Ch_1_Loc = Ch_1_Par_Val;
+ Ch_2_Loc = Ch_1_Loc;
+ if (Ch_2_Loc != Ch_2_Par_Val)
+ /* then, executed */
+ return (Ident_1);
+ else { /* not executed */
+ Ch_1_Glob = Ch_1_Loc;
+ return (Ident_2);
+ }
+} /* Func_1 */
+
+
+Boolean
+ Func_2(Str_1_Par_Ref, Str_2_Par_Ref)
+/*************************************************/
+ /* executed once */
+ /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
+ /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
+
+ Str_30 Str_1_Par_Ref;
+ Str_30 Str_2_Par_Ref;
+{
+ REG One_Thirty Int_Loc;
+ Capital_Letter Ch_Loc = 0;
+
+
+ Int_Loc = 2;
+ while (Int_Loc <= 2) /* loop body executed once */
+ if (Func_1(Str_1_Par_Ref[Int_Loc],
+ Str_2_Par_Ref[Int_Loc + 1]) == Ident_1)
+ /* then, executed */
+ {
+ Ch_Loc = 'A';
+ Int_Loc += 1;
+ } /* if, while */
+
+ if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
+ /* then, not executed */
+ Int_Loc = 7;
+ if (Ch_Loc == 'R')
+ /* then, not executed */
+ return (true);
+ else { /* executed */
+ if (strcmp(Str_1_Par_Ref, Str_2_Par_Ref) > 0)
+ /* then, not executed */
+ {
+ Int_Loc += 7;
+ Int_Glob = Int_Loc;
+ return (true);
+ } else /* executed */
+ return (false);
+ } /* if Ch_Loc */
+} /* Func_2 */
+
+
+Boolean
+ Func_3(Enum_Par_Val)
+/***************************/
+ /* executed once */
+ /* Enum_Par_Val == Ident_3 */
+ Enumeration Enum_Par_Val;
+{
+ Enumeration Enum_Loc;
+
+ Enum_Loc = Enum_Par_Val;
+ if (Enum_Loc == Ident_3)
+ /* then, executed */
+ return (true);
+ else /* not executed */
+ return (false);
+} /* Func_3 */
+
+int dhry_cmd (int argc, char *argv[])
+{
+ if (argc == 1) dhry_main(strtoul (argv[0], 0, 0));
+ else if (argc == 0) dhry_main(20);
+ else return -1;
+ return 0;
+}
+
+void module_dhry_init (void)
+{
+ register_command ("dhry", "[]", "run dhrystone", dhry_cmd);
+}
Index: cpu.c
===================================================================
--- cpu.c (nonexistent)
+++ cpu.c (revision 1765)
@@ -0,0 +1,114 @@
+#include "common.h"
+#include "support.h"
+#include "spr_defs.h"
+
+int ic_enable_cmd (int argc, char *argv[])
+{
+ unsigned long addr;
+ unsigned long sr;
+
+ if (argc) return -1;
+ /* Invalidate IC */
+ for (addr = 0; addr < 8192; addr += 16)
+ asm("l.mtspr r0,%0,%1": : "r" (addr), "i" (SPR_ICBIR));
+
+ /* Enable IC */
+ asm("l.mfspr %0,r0,%1": "=r" (sr) : "i" (SPR_SR));
+ sr |= SPR_SR_ICE;
+ asm("l.mtspr r0,%0,%1": : "r" (sr), "i" (SPR_SR));
+ asm("l.nop");
+ asm("l.nop");
+ asm("l.nop");
+ asm("l.nop");
+ return 0;
+}
+
+int ic_disable_cmd (int argc, char *argv[])
+{
+ unsigned long sr;
+
+ if (argc) return -1;
+ /* Disable IC */
+ asm("l.mfspr %0,r0,%1": "=r" (sr) : "i" (SPR_SR));
+ sr &= ~SPR_SR_ICE;
+ asm("l.mtspr r0,%0,%1": : "r" (sr), "i" (SPR_SR));
+ asm("l.nop");
+ asm("l.nop");
+ asm("l.nop");
+ asm("l.nop");
+ return 0;
+}
+
+int dc_enable_cmd (int argc, char *argv[])
+{
+ unsigned long addr;
+ unsigned long sr;
+
+ if (argc) return -1;
+ /* Invalidate DC */
+ for (addr = 0; addr < 8192; addr += 16)
+ asm("l.mtspr r0,%0,%1": : "r" (addr), "i" (SPR_DCBIR));
+
+ /* Enable DC */
+ asm("l.mfspr %0,r0,%1": "=r" (sr) : "i" (SPR_SR));
+ sr |= SPR_SR_DCE;
+ asm("l.mtspr r0,%0,%1": : "r" (sr), "i" (SPR_SR));
+ asm("l.nop");
+ asm("l.nop");
+ asm("l.nop");
+ asm("l.nop");
+ return 0;
+}
+
+int dc_disable_cmd (int argc, char *argv[])
+{
+ unsigned long sr;
+
+ if (argc) return -1;
+ /* Disable DC */
+ asm("l.mfspr %0,r0,%1": "=r" (sr) : "i" (SPR_SR));
+ sr &= ~SPR_SR_DCE;
+ asm("l.mtspr r0,%0,%1": : "r" (sr), "i" (SPR_SR));
+ asm("l.nop");
+ asm("l.nop");
+ asm("l.nop");
+ asm("l.nop");
+ return 0;
+}
+
+int mfspr_cmd (int argc, char *argv[])
+{
+ unsigned long val, addr;
+
+ if (argc == 1) {
+ addr = strtoul (argv[0], 0, 0);
+ /* Read SPR */
+ asm("l.mfspr %0,%1,0": "=r" (val) : "r" (addr));
+ printf ("\nSPR %04lx: %08lx", addr, val);
+ } else return -1;
+ return 0;
+}
+
+int mtspr_cmd (int argc, char *argv[])
+{
+ unsigned long val, addr;
+ if (argc == 2) {
+ addr = strtoul (argv[0], 0, 0);
+ val = strtoul (argv[1], 0, 0);
+ /* Write SPR */
+ asm("l.mtspr %0,%1,0": : "r" (addr), "r" (val));
+ asm("l.mfspr %0,%1,0": "=r" (val) : "r" (addr));
+ printf ("\nSPR %04lx: %08lx", addr, val);
+ } else return -1;
+ return 0;
+}
+
+void module_cpu_init (void)
+{
+ register_command ("ic_enable", "", "enable instruction cache", ic_enable_cmd);
+ register_command ("ic_disable", "", "disable instruction cache", ic_disable_cmd);
+ register_command ("dc_enable", "", "enable data cache", dc_enable_cmd);
+ register_command ("dc_disable", "", "disable data cache", dc_disable_cmd);
+ register_command ("mfspr", "", "show SPR", mfspr_cmd);
+ register_command ("mtspr", " ", "set SPR", mtspr_cmd);
+}
Index: dhry.h
===================================================================
--- dhry.h (nonexistent)
+++ dhry.h (revision 1765)
@@ -0,0 +1,412 @@
+/*
+ ****************************************************************************
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry.h (part 1 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ * Siemens AG, AUT E 51
+ * Postfach 3220
+ * 8520 Erlangen
+ * Germany (West)
+ * Phone: [+49]-9131-7-20330
+ * (8-17 Central European Time)
+ * Usenet: ..!mcsun!unido!estevax!weicker
+ *
+ * Original Version (in Ada) published in
+ * "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
+ * pp. 1013 - 1030, together with the statistics
+ * on which the distribution of statements etc. is based.
+ *
+ * In this C version, the following C library functions are used:
+ * - strcpy, strcmp (inside the measurement loop)
+ * - printf, scanf (outside the measurement loop)
+ * In addition, Berkeley UNIX system calls "times ()" or "time ()"
+ * are used for execution time measurement. For measurements
+ * on other systems, these calls have to be changed.
+ *
+ * Updated January, 1997 Rick Cramer, Galileo(R) to work with
+ * the i960jx and Galileo-5 Reference Design.
+ *
+ *
+ * Collection of Results:
+ * Reinhold Weicker (address see above) and
+ *
+ * Rick Richardson
+ * PC Research. Inc.
+ * 94 Apple Orchard Drive
+ * Tinton Falls, NJ 07724
+ * Phone: (201) 389-8963 (9-17 EST)
+ * Usenet: ...!uunet!pcrat!rick
+ *
+ * Please send results to Rick Richardson and/or Reinhold Weicker.
+ * Complete information should be given on hardware and software used.
+ * Hardware information includes: Machine type, CPU, type and size
+ * of caches; for microprocessors: clock frequency, memory speed
+ * (number of wait states).
+ * Software information includes: Compiler (and runtime library)
+ * manufacturer and version, compilation switches, OS version.
+ * The Operating System version may give an indication about the
+ * compiler; Dhrystone itself performs no OS calls in the measurement loop.
+ *
+ * The complete output generated by the program should be mailed
+ * such that at least some checks for correctness can be made.
+ *
+ ***************************************************************************
+ *
+ * History: This version C/2.1 has been made for two reasons:
+ *
+ * 1) There is an obvious need for a common C version of
+ * Dhrystone, since C is at present the most popular system
+ * programming language for the class of processors
+ * (microcomputers, minicomputers) where Dhrystone is used most.
+ * There should be, as far as possible, only one C version of
+ * Dhrystone such that results can be compared without
+ * restrictions. In the past, the C versions distributed
+ * by Rick Richardson (Version 1.1) and by Reinhold Weicker
+ * had small (though not significant) differences.
+ *
+ * 2) As far as it is possible without changes to the Dhrystone
+ * statistics, optimizing compilers should be prevented from
+ * removing significant statements.
+ *
+ * This C version has been developed in cooperation with
+ * Rick Richardson (Tinton Falls, NJ), it incorporates many
+ * ideas from the "Version 1.1" distributed previously by
+ * him over the UNIX network Usenet.
+ * I also thank Chaim Benedelac (National Semiconductor),
+ * David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
+ * Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
+ * for their help with comments on earlier versions of the
+ * benchmark.
+ *
+ * Changes: In the initialization part, this version follows mostly
+ * Rick Richardson's version distributed via Usenet, not the
+ * version distributed earlier via floppy disk by Reinhold Weicker.
+ * As a concession to older compilers, names have been made
+ * unique within the first 8 characters.
+ * Inside the measurement loop, this version follows the
+ * version previously distributed by Reinhold Weicker.
+ *
+ * At several places in the benchmark, code has been added,
+ * but within the measurement loop only in branches that
+ * are not executed. The intention is that optimizing compilers
+ * should be prevented from moving code out of the measurement
+ * loop, or from removing code altogether. Since the statements
+ * that are executed within the measurement loop have NOT been
+ * changed, the numbers defining the "Dhrystone distribution"
+ * (distribution of statements, operand types and locality)
+ * still hold. Except for sophisticated optimizing compilers,
+ * execution times for this version should be the same as
+ * for previous versions.
+ *
+ * Since it has proven difficult to subtract the time for the
+ * measurement loop overhead in a correct way, the loop check
+ * has been made a part of the benchmark. This does have
+ * an impact - though a very minor one - on the distribution
+ * statistics which have been updated for this version.
+ *
+ * All changes within the measurement loop are described
+ * and discussed in the companion paper "Rationale for
+ * Dhrystone version 2".
+ *
+ * Because of the self-imposed limitation that the order and
+ * distribution of the executed statements should not be
+ * changed, there are still cases where optimizing compilers
+ * may not generate code for some statements. To a certain
+ * degree, this is unavoidable for small synthetic benchmarks.
+ * Users of the benchmark are advised to check code listings
+ * whether code is generated for all statements of Dhrystone.
+ *
+ * Version 2.1 is identical to version 2.0 distributed via
+ * the UNIX network Usenet in March 1988 except that it corrects
+ * some minor deficiencies that were found by users of version 2.0.
+ * The only change within the measurement loop is that a
+ * non-executed "else" part was added to the "if" statement in
+ * Func_3, and a non-executed "else" part removed from Proc_3.
+ *
+ ***************************************************************************
+ *
+ * Defines: The following "Defines" are possible:
+ * -DREG=register (default: Not defined)
+ * As an approximation to what an average C programmer
+ * might do, the "register" storage class is applied
+ * (if enabled by -DREG=register)
+ * - for local variables, if they are used (dynamically)
+ * five or more times
+ * - for parameters if they are used (dynamically)
+ * six or more times
+ * Note that an optimal "register" strategy is
+ * compiler-dependent, and that "register" declarations
+ * do not necessarily lead to faster execution.
+ * -DNOSTRUCTASSIGN (default: Not defined)
+ * Define if the C compiler does not support
+ * assignment of structures.
+ * -DNOENUMS (default: Not defined)
+ * Define if the C compiler does not support
+ * enumeration types.
+ * -DICACHEON (default: Not defined)
+ * Adjust performace by conditionally compiling
+ * these i960jx CACHE paramaters.
+ * -DICACHEOFF
+ * -DDCACHEON (default: Not defined)
+ * -DDCACHEOFF
+ *
+ * NOTE: Galileo-5 Board Frequency is set to 33Mhz in the
+ * file jx-timer.c. If the operating frequency is
+ * changed by replacing the crystal, then this #define
+ * must also be changed.
+ *
+ ***************************************************************************
+ *
+ * Compilation model and measurement (IMPORTANT):
+ *
+ * This C version of Dhrystone consists of four files:
+ * - dhry.h (this file, containing global definitions and comments)
+ * - dhry_1.c (containing the code corresponding to Ada package Pack_1)
+ * - dhry_2.c (containing the code corresponding to Ada package Pack_2)
+ * - jx-timer.c (containing the code to access the i960jx timer)
+ *
+ * The following "ground rules" apply for measurements:
+ * - No procedure merging
+ * - Otherwise, compiler optimizations are allowed but should be indicated
+ * - Default results are those without register declarations
+ * See the companion paper "Rationale for Dhrystone Version 2" for a more
+ * detailed discussion of these ground rules.
+ *
+ * For 16-Bit processors (e.g. 80186, 80286), times for all compilation
+ * models ("small", "medium", "large" etc.) should be given if possible,
+ * together with a definition of these models for the compiler system used.
+ *
+ * Example Intel 960jx compile syntax for Galileo-5.
+ *
+ * ic960 -AJA -Tgal5 -O2 -DREG=register dhry_1.c dhry_2.c jx-timer.c
+ *
+ **************************************************************************
+ *
+ * Dhrystone (C version) statistics:
+ *
+ * [Comment from the first distribution, updated for version 2.
+ * Note that because of language differences, the numbers are slightly
+ * different from the Ada version.]
+ *
+ * The following program contains statements of a high level programming
+ * language (here: C) in a distribution considered representative:
+ *
+ * assignments 52 (51.0 %)
+ * control statements 33 (32.4 %)
+ * procedure, function calls 17 (16.7 %)
+ *
+ * 103 statements are dynamically executed. The program is balanced with
+ * respect to the three aspects:
+ *
+ * - statement type
+ * - operand type
+ * - operand locality
+ * operand global, local, parameter, or constant.
+ *
+ * The combination of these three aspects is balanced only approximately.
+ *
+ * 1. Statement Type:
+ * ----------------- number
+ *
+ * V1 = V2 9
+ * (incl. V1 = F(..)
+ * V = Constant 12
+ * Assignment, 7
+ * with array element
+ * Assignment, 6
+ * with record component
+ * --
+ * 34 34
+ *
+ * X = Y +|-|"&&"|"|" Z 5
+ * X = Y +|-|"==" Constant 6
+ * X = X +|- 1 3
+ * X = Y *|/ Z 2
+ * X = Expression, 1
+ * two operators
+ * X = Expression, 1
+ * three operators
+ * --
+ * 18 18
+ *
+ * if .... 14
+ * with "else" 7
+ * without "else" 7
+ * executed 3
+ * not executed 4
+ * for ... 7 | counted every time
+ * while ... 4 | the loop condition
+ * do ... while 1 | is evaluated
+ * switch ... 1
+ * break 1
+ * declaration with 1
+ * initialization
+ * --
+ * 34 34
+ *
+ * P (...) procedure call 11
+ * user procedure 10
+ * library procedure 1
+ * X = F (...)
+ * function call 6
+ * user function 5
+ * library function 1
+ * --
+ * 17 17
+ * ---
+ * 103
+ *
+ * The average number of parameters in procedure or function calls
+ * is 1.82 (not counting the function values as implicit parameters).
+ *
+ *
+ * 2. Operators
+ * ------------
+ * number approximate
+ * percentage
+ *
+ * Arithmetic 32 50.8
+ *
+ * + 21 33.3
+ * - 7 11.1
+ * * 3 4.8
+ * / (int div) 1 1.6
+ *
+ * Comparison 27 42.8
+ *
+ * == 9 14.3
+ * /= 4 6.3
+ * > 1 1.6
+ * < 3 4.8
+ * >= 1 1.6
+ * <= 9 14.3
+ *
+ * Logic 4 6.3
+ *
+ * && (AND-THEN) 1 1.6
+ * | (OR) 1 1.6
+ * ! (NOT) 2 3.2
+ *
+ * -- -----
+ * 63 100.1
+ *
+ *
+ * 3. Operand Type (counted once per operand reference):
+ * ---------------
+ * number approximate
+ * percentage
+ *
+ * Integer 175 72.3 %
+ * Character 45 18.6 %
+ * Pointer 12 5.0 %
+ * String30 6 2.5 %
+ * Array 2 0.8 %
+ * Record 2 0.8 %
+ * --- -------
+ * 242 100.0 %
+ *
+ * When there is an access path leading to the final operand (e.g. a record
+ * component), only the final data type on the access path is counted.
+ *
+ *
+ * 4. Operand Locality:
+ * -------------------
+ * number approximate
+ * percentage
+ *
+ * local variable 114 47.1 %
+ * global variable 22 9.1 %
+ * parameter 45 18.6 %
+ * value 23 9.5 %
+ * reference 22 9.1 %
+ * function result 6 2.5 %
+ * constant 55 22.7 %
+ * --- -------
+ * 242 100.0 %
+ *
+ *
+ * The program does not compute anything meaningful, but it is syntactically
+ * and semantically correct. All variables have a value assigned to them
+ * before they are used as a source operand.
+ *
+ * There has been no explicit effort to account for the effects of a
+ * cache, or to balance the use of long or short displacements for code or
+ * data.
+ *
+ ***************************************************************************
+ */
+
+/* Compiler and system dependent definitions: */
+
+
+#define Mic_secs_Per_Second 1000000.0
+ /* Berkeley UNIX C returns process times in seconds/HZ */
+
+#ifdef NOSTRUCTASSIGN
+#define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
+#else
+#define structassign(d, s) d = s
+#endif
+
+#define NOENUM
+#ifdef NOENUM
+#define Ident_1 0
+#define Ident_2 1
+#define Ident_3 2
+#define Ident_4 3
+#define Ident_5 4
+ typedef int Enumeration;
+#else
+ typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
+ Enumeration;
+#endif
+ /* for boolean and enumeration types in Ada, Pascal */
+
+/* General definitions: */
+
+/* #include */
+ /* for strcpy, strcmp */
+
+#define Null 0
+ /* Value of a Null pointer */
+#define true 1
+#define false 0
+
+typedef int One_Thirty;
+typedef int One_Fifty;
+typedef char Capital_Letter;
+typedef int Boolean;
+typedef char Str_30 [31];
+typedef int Arr_1_Dim [50];
+typedef int Arr_2_Dim [50] [50];
+
+typedef struct record
+ {
+ struct record *Ptr_Comp;
+ Enumeration Discr;
+ union {
+ struct {
+ Enumeration Enum_Comp;
+ int Int_Comp;
+ char Str_Comp [31];
+ } var_1;
+ struct {
+ Enumeration E_Comp_2;
+ char Str_2_Comp [31];
+ } var_2;
+ struct {
+ char Ch_1_Comp;
+ char Ch_2_Comp;
+ } var_3;
+ } variant;
+ } Rec_Type, *Rec_Pointer;
+
+