OpenCores
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; + +

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.