📄 tmmon.c
字号:
/*
* +-------------------------------------------------------------------+
* | Copyright (c) 1995-1999 by Philips Semiconductors. |
* | |
* | This software is furnished under a license and may only be used |
* | and copied in accordance with the terms and conditions of such a |
* | license and with the inclusion of this copyright notice. This |
* | software or any other copies of this software may not be provided |
* | or otherwise made available to any other person. The ownership |
* | and title of this software is not transferred. |
* | |
* | The information in this software is subject to change without |
* | any prior notice and should not be construed as a commitment by |
* | Philips Semiconductors. |
* | |
* | This code and information is provided "as is" without any |
* | warranty of any kind, either expressed or implied, including but |
* | not limited to the implied warranties of merchantability and/or |
* | fitness for any particular purpose. |
* +-------------------------------------------------------------------+
*
*
* Module name : tmmon.c 1.23
*
* Last update : 14:57:09 - 99/02/22
*
* Description :
*
* This module implements a interactive program to download and run
* executables on one or more TM-1000 s with a Mac as host
*
* Revision :
*/
/*-----------------------------includes-------------------------------------*/
#include <PCI.h>
#include <ToolUtils.h>
#include <SIOUX.h>
#include <Threads.h>
#include <Processes.h>
#include <Strings.h>
#include <fcntl.h>
#include <stat.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "mmio.h"
#include "OpenDll.h"
#include "TM1stuff.h"
#include "TMObj.h"
/*------------------------------defines---------------------------------------*/
#define NAME_NODE_SIZE 132
#define MIN_MEMORY_SIZE (1200 * 1024) /* For tmmon, a guess. */
#define Period 46
#define ISQUOTE(a) ((a) == '\'')
#define MEMORY_BLOCKS 100
#define kMaxMatches 5 // Max number of matches in one pass
#define kOptBufferSize (16 * 1024) // Cache size to speed up search
#define kPathNameSeparator ':' /* 0x3A */
/*------------------------------local-prototypes------------------------------*/
static void PrintTM (int i);
static void PrintTMs (int n);
static int UserCancelled (void);
static void ShowGDevices (void);
static int GetProcessInfo (char *processName, ProcessInfoRecPtr procInfo);
static Boolean EnoughRoomToLoad (char *filename);
static void Help (void);
static void DisplayMemoryIOConfig (UInt32 StartAddress, UInt32 DisplayLength, UInt8 TransType);
static OSStatus FindPropertyWithValue (const RegPropertyName *propertyName, const void *propertyValue, const RegPropertyValueSize propertySize, RegEntryID *foundEntry);
static OSStatus FindNameWithUnitAddr (const void *nodeNameValue, const RegPropertyValueSize nodeNameSize, const UInt32 unitAddr, RegEntryID *foundEntry);
static OSStatus MessageDeviceUnderTest (const RegEntryID *theEntry);
static OSStatus DisplayConfiguration (const RegEntryID *theEntry);
static void ToUpperString (char *theString);
static pascal voidPtr rpcserv_thread (void *threadParam);
static void getTCSpath (char *path);
static OSErr fss2path (FSSpecPtr spec, char *pathName, Boolean keepname);
static void copy_pascal_to_c_str (StringPtr src, char * dst);
static void PrepareToLoad (char *filename, int argc, char *argv[], char *actualFilename, int *actualArgc, char *actualArgv[]);
/*-----------------------------GLOBALS----------------------------------------*/
/* location of the communication buffer, so far 2 4-byte pointers */
extern volatile Address *_HostCall_commvar;
static char tcspath[FILENAME_MAX + 1];
/*------------------------------functions-------------------------------------*/
/* Fill in the help menu when you add a new command */
void Help()
{
printf("--------------------------------------------------------------------------------\n");
printf("COMMANDS:\n\n");
printf("\tA <nbytes> --> Allocate <nbytes> of host memory.\n");
printf("\tC --> Show all TM PCI Configuration Headers\n");
printf("\t (first 64 bytes of Configuration Space).\n");
printf("\tC <node> --> Show PCI Configuration Header on TM node <node>.\n");
printf("\n");
printf("\tF <freq> <node> --> Set frequency for TM node <node>.\n");
printf("\tF <freq> --> Set frequency for all TM nodes.\n");
printf("\tF --> Show frequency for all TM nodes.\n");
printf("\n");
printf("\tG --> Run TM executable(s) on all loaded TM nodes.\n");
printf("\tG <node> --> Run TM executable on TM node <node>.\n");
printf("\t Command-period will abort TriMedia executable,\n");
printf("\t if possible.\n");
printf("\n");
printf("\tI --> Show info about all TM nodes.\n");
printf("\tI <node> --> Show info about TM nodes <node>.\n");
printf("\n");
printf("\tL <file_0> <arg0_0> ... <argM0_0> - ... - <file_N> <arg0_N> ... <argM_N>\n");
printf("\t --> Load executable(s) and arguments for TriMedia\n");
printf("\t node(s) 0 through N.\n");
printf("\n");
printf("\tM --> Show information on monitors (framebuffers).\n");
printf("\n");
printf("\tP <location> [<nbytes>] --> Show memory contents.\n");
printf("\n");
printf("\tR --> Reset all TM nodes.\n");
printf("\tR <node> --> Reset TM node <node>.\n");
printf("\n");
printf("\tSE <filename> --> Redirect stderr to <filename>.\n");
printf("\tSE --> Redirect stderr to console.\n");
printf("\n");
printf("\tSI <filename> --> Redirect stdin from <filename>.\n");
printf("\tSI --> Redirect stdin from console.\n");
printf("\n");
printf("\tSIZE <size> <node> --> Set SDRAM size for TM node <node>.\n");
printf("\tSIZE <size> --> Set SDRAM size for all TM nodes.\n");
printf("\tSIZE --> Show SDRAM size for all TM nodes.\n");
printf("\n");
printf("\tSO <filename> --> Redirect stdout to <filename>.\n");
printf("\tSO --> Redirect stdout to console.\n");
printf("\n");
printf("\tH --> Show this menu\n");
printf("\t? --> Show this menu\n");
printf("\n");
printf("NOTES:\n\n");
printf("\t(1) Filenames can be full or partial pathnames with white spaces. E.g.:\n\n");
printf("\t>load a.out\n");
printf("\t>load :junk:a.out\n");
printf("\t>load 'Wroclaw:bugs:have space.out'\n\n");
printf("\t(2) Redirected stdin/stdout/stderr are opened when executable is loaded.\n");
printf("--------------------------------------------------------------------------------\n");
printf("\n");
}
void
PrintTM(int i)
{
unsigned long sdram_limit;
sdram_limit = TMInfo[i].sdram_base + TMInfo[i].sdram_size;
printf("%2d: 0x%x 0x%x 0x%x %9d %-4s ",
i, TMInfo[i].sdram_base, sdram_limit, TMInfo[i].mmio_base, TMInfo[i].frequency, TMInfo[i].slot);
if ( strcmp(TMInfo[i].node_name, "pci1131,1") == 0 && TMInfo[i].sdram_size == 0x800000)
{
printf("IREF board\n");
}
else
if ( strcmp(TMInfo[i].node_name, "pci1131,5400") == 0 && TMInfo[i].sdram_size == 0x400000)
{
printf("Apple board\n");
}
else
{
printf("????\n");
}
}
void
PrintTMs(int n)
{
int i;
if (n == ALL_NODES)
{
printf("\nThe available TM-1000's in this Mac are:\n");
}
printf("No. sdram base sdram limit mmio base frequency slot type\n");
printf(" __________ __________ __________ _________ ____ __________\n");
if (n == ALL_NODES)
{
for(i=0; i< NumberOfTMs; i++)
{
PrintTM(i);
}
}
else
{
PrintTM(n);
}
}
OSStatus DisplayConfiguration(const RegEntryID *theEntry)
{
OSStatus err;
UInt8 ConfigHeader[64];
int i;
err = noErr;
i = 0;
while ((err == noErr) & (i < 64))
{
err = ExpMgrConfigReadByte((RegEntryIDPtr)theEntry, (LogicalAddress)i, &ConfigHeader[i]);
i++;
}
if (err != noErr)
{
printf("ERROR: Bad call to ExpMgrConfigReadByte. Error Code = %d\n", err);
return err;
}
/* common to all PCI Devices (first 16 bytes) */
printf("Vendor ID = %02X%02X | 0x00\n", ConfigHeader[0x01],ConfigHeader[0x00]);
printf("Device ID = %02X%02X | 0x02\n", ConfigHeader[0x03],ConfigHeader[0x02]);
printf("Command = %02X%02X | 0x04\n", ConfigHeader[0x05],ConfigHeader[0x04]);
printf("Status = %02X%02X | 0x06\n", ConfigHeader[0x07],ConfigHeader[0x06]);
printf("Revision ID = %02X | 0x08\n",ConfigHeader[0x08]);
printf("Class Code = %02X%02X%02X | 0x09\n", ConfigHeader[0x0B],ConfigHeader[0x0A],ConfigHeader[0x09]);
printf("Cache line size = %02X | 0x0C\n",ConfigHeader[0x0C]);
printf("Latency = %02X | 0x0D\n",ConfigHeader[0x0D]);
printf("Header type = %02X | 0x0E\n",ConfigHeader[0x0E]);
printf("BIST = %02X | 0x0F\n",ConfigHeader[0x0F]);
/* rest of standard header */
if ((ConfigHeader[0xE] & 0x01) == 0x00)
{
printf("Base addr 0 = %02X%02X%02X%02X | 0x10\n", ConfigHeader[0x13],ConfigHeader[0x12],ConfigHeader[0x11],ConfigHeader[0x10]);
printf("Base addr 1 = %02X%02X%02X%02X | 0x14\n", ConfigHeader[0x17],ConfigHeader[0x16],ConfigHeader[0x15],ConfigHeader[0x14]);
printf("Base addr 2 = %02X%02X%02X%02X | 0x18\n", ConfigHeader[0x1B],ConfigHeader[0x1A],ConfigHeader[0x19],ConfigHeader[0x18]);
printf("Base addr 3 = %02X%02X%02X%02X | 0x1C\n", ConfigHeader[0x1F],ConfigHeader[0x1E],ConfigHeader[0x1D],ConfigHeader[0x1C]);
printf("Base addr 4 = %02X%02X%02X%02X | 0x20\n", ConfigHeader[0x23],ConfigHeader[0x22],ConfigHeader[0x21],ConfigHeader[0x20]);
printf("Base addr 5 = %02X%02X%02X%02X | 0x24\n", ConfigHeader[0x27],ConfigHeader[0x26],ConfigHeader[0x25],ConfigHeader[0x24]);
printf("Cardbus CIS Ptr = %02X%02X%02X%02X | 0x28\n", ConfigHeader[0x2B],ConfigHeader[0x2A],ConfigHeader[0x29],ConfigHeader[0x28]);
printf("Subsys Vendor ID = %02X%02X | 0x2C\n", ConfigHeader[0x2D],ConfigHeader[0x2C]);
printf("Subsys ID = %02X%02X | 0x2E\n", ConfigHeader[0x2F],ConfigHeader[0x2E]);
printf("ROM base = %02X%02X%02X%02X | 0x30\n", ConfigHeader[0x33],ConfigHeader[0x32],ConfigHeader[0x31],ConfigHeader[0x30]);
printf("Reserved = %02X%02X%02X%02X | 0x34\n", ConfigHeader[0x37],ConfigHeader[0x36],ConfigHeader[0x35],ConfigHeader[0x34]);
printf("Reserved = %02X%02X%02X%02X | 0x38\n", ConfigHeader[0x3B],ConfigHeader[0x3A],ConfigHeader[0x39],ConfigHeader[0x38]);
printf("Interrupt line = %02X | 0x3C\n",ConfigHeader[0x3C]);
printf("Interrupt pin = %02X | 0x3D\n",ConfigHeader[0x3D]);
printf("Min_Gnt = %02X | 0x3E\n",ConfigHeader[0x3E]);
printf("Max_Lat = %02X | 0x3F\n",ConfigHeader[0x3F]);
}
/* rest of PCI 2 PCI header */
else if ((ConfigHeader[0xE] & 0x01) == 0x01)
{
printf("Base addr 0 = %02X%02X%02X%02X | 0x10\n", ConfigHeader[0x13],ConfigHeader[0x12],ConfigHeader[0x11],ConfigHeader[0x10]);
printf("Base addr 1 = %02X%02X%02X%02X | 0x14\n", ConfigHeader[0x17],ConfigHeader[0x16],ConfigHeader[0x15],ConfigHeader[0x14]);
printf("Primary Bus # = %02X | 0x18\n",ConfigHeader[0x18]);
printf("2ndary Bus # = %02X | 0x19\n",ConfigHeader[0x19]);
printf("Subordinate Bus# = %02X | 0x1A\n",ConfigHeader[0x1A]);
printf("2ndary Lat Timer = %02X | 0x1B\n",ConfigHeader[0x1B]);
printf("IO Base = %02X | 0x1C\n",ConfigHeader[0x1C]);
printf("IO Limit = %02X | 0x1D\n",ConfigHeader[0x1D]);
printf("2ndary Status = %02X%02X | 0x1E\n", ConfigHeader[0x1F],ConfigHeader[0x1E]);
printf("Memory Base = %02X%02X | 0x20\n", ConfigHeader[0x21],ConfigHeader[0x20]);
printf("Memory Limit = %02X%02X | 0x22\n", ConfigHeader[0x23],ConfigHeader[0x22]);
printf("Prefetch Mem Base= %02X%02X | 0x24\n", ConfigHeader[0x25],ConfigHeader[0x24]);
printf("Prefetch Mem Lim = %02X%02X | 0x26\n", ConfigHeader[0x27],ConfigHeader[0x26]);
printf("Pftch Base Upr 32= %02X%02X%02X%02X | 0x28\n", ConfigHeader[0x2B],ConfigHeader[0x2A],ConfigHeader[0x29],ConfigHeader[0x28]);
printf("Pftch Lim Upr 32= %02X%02X%02X%02X | 0x2C\n", ConfigHeader[0x2F],ConfigHeader[0x2E],ConfigHeader[0x2D],ConfigHeader[0x2C]);
printf("IO Base Upper 16 = %02X%02X | 0x30\n", ConfigHeader[0x31],ConfigHeader[0x30]);
printf("IO Lim Upper 16 = %02X%02X | 0x32\n", ConfigHeader[0x33],ConfigHeader[0x32]);
printf("Reserved = %02X%02X%02X%02X | 0x34\n", ConfigHeader[0x37],ConfigHeader[0x36],ConfigHeader[0x35],ConfigHeader[0x34]);
printf("ROM base = %02X%02X%02X%02X | 0x38\n", ConfigHeader[0x3B],ConfigHeader[0x3A],ConfigHeader[0x39],ConfigHeader[0x38]);
printf("Interrupt line = %02X | 0x3C\n",ConfigHeader[0x3C]);
printf("Interrupt pin = %02X | 0x3D\n",ConfigHeader[0x3D]);
printf("Bridge Control = %02X%02X | 0x3E\n", ConfigHeader[0x3F],ConfigHeader[0x3E]);
}
/* rest of unknown header */
else
{
printf("!! Unknown Header Type !! Listing below is just addresses and longword data,ConfigHeader\n");
for (i = 16; i < 64; i=i+4)
{
printf(" = %02X%02X%02X%02X | 0x%02X\n",ConfigHeader[i+3],ConfigHeader[i+2],ConfigHeader[i+1],ConfigHeader[i],i);
}
}
return err;
}
void ToUpperString(char* theString)
{
short lengthOfString ;
lengthOfString = strlen(theString);
UpperText(theString, lengthOfString); /* from TextUtils.h */
}
/* Display information about GDevices on this Macintosh. */
static void ShowGDevices(void)
{
GDHandle gdev;
GDHandle maingdev;
Rect r;
int w;
int h;
int depth;
int stride;
int i;
unsigned long baseAddress;
printf("Frame buffers on this Macintosh:\n\n");
maingdev = GetMainDevice(); /* Main, or menubar scren. */
gdev = GetDeviceList();
i = 1;
do
{
printf("Monitor %d", i++);
if (maingdev == gdev)
printf(" (Menubar screen):");
r = (*gdev)->gdRect;
w = r.right - r.left;
h = r.bottom - r.top;
depth = (**(**(gdev)).gdPMap).pixelSize;
stride = ((**(**(gdev)).gdPMap).rowBytes & 0x7FFF);
baseAddress = (unsigned long) (**(**(gdev)).gdPMap).baseAddr;
printf("\nWidth = %d, height = %d, base address = 0x%08x\n", w, h, baseAddress);
printf("Stride (rowbytes) = 0x%08x (%d decimal)\n", stride, stride);
printf("Current pixel depth = %d\n", depth);
} while (gdev = (GDevice **)(*gdev)->gdNextGD);
}
/* Get information about a process. Return nonzero if process not found. */
static int GetProcessInfo (char *processName, ProcessInfoRecPtr procInfo)
{
auto OSErr osErr = noErr;
auto ProcessSerialNumber process;
auto Str255 procName;
FSSpec appFSSpec;
process.highLongOfPSN = kNoProcess;
process.lowLongOfPSN = kNoProcess;
procInfo->processInfoLength = sizeof(ProcessInfoRec);
procInfo->processName = procName;
procInfo->processAppSpec = &appFSSpec;
while (procNotFound != (osErr = GetNextProcess(&process)))
{
if (noErr == (osErr = GetProcessInformation(&process, procInfo)))
{
if ('\0' == procName[1])
procName[1] = '0';
P2CStr(procName);
if (strcmp((char *)procName, processName) == 0)
{
return 0;
}
}
}
return -1;
}
static Boolean EnoughRoomToLoad(char *filename)
{
int status;
ProcessInfoRec procInfo;
struct stat sbuf;
unsigned long filesize = 0;
int result;
int f = 0;
unsigned long memory_needed;
/* Get file size. */
f = open (filename, O_RDONLY);
if (f > 0)
{
result = fstat (f, &sbuf);
if (result < 0)
{
printf("###fstat failed trying to get file size, errno = %d\n", errno);
close (f);
return false;
}
else
{
filesize = sbuf.st_size;
close (f);
}
}
else
{
printf("###Couldn't open file <%s>\n", filename);
return false;
}
memory_needed = MIN_MEMORY_SIZE + filesize;
status = GetProcessInfo ("tmmon", &procInfo);
if (memory_needed > procInfo.processSize)
{
printf("###You don't have enough memory allocated to tmmon (%dK) to load '%s'.\n", procInfo.processSize / 1024, filename);
printf("###You need at least %dK.\n", memory_needed / 1024);
/* printf("The largest file you can load is %dK bytes.\n", procInfo.processFreeMem / 1024); */
printf("###The largest file you can load is %dK bytes.\n", (procInfo.processSize - MIN_MEMORY_SIZE) / 1024);
printf("###To allocate more memory to tmmmon:\n");
printf("\t(1) Quit tmmon.\n");
printf("\t(2) Select it in the Finder (click on it once).\n");
printf("\t(3) Choose Get Info from the File menu.\n");
printf("\t(4) Enter the Preferred Size in the Memory Requirements text edit field.\n");
printf("\t(5) Re-launch tmmon -- you can change its memory requirement only if it's not running.\n");
return false;
}
return true;
}
/* Check if user typed Command-period to cancel an operation. */
int UserCancelled(void)
{
EventRecord event;
short key;
if (WaitNextEvent(keyDownMask, &event, 10, 0L) != nullEvent)
/* if (EventAvail(keyDownMask, &event) != nullEvent) */
{
if (event.what == keyDown || event.what == autoKey)
{
key = event.message & charCodeMask;
if (key == Period && (event.modifiers & cmdKey))
{
FlushEvents(keyDownMask, 0); /* Remove all keydown events. */
printf("###Operation cancelled by Command-period.\n");
return 1;
}
}
}
return 0;
}
/*** Run thread ***/
pascal voidPtr rpcserv_thread(void *threadParam)
{
Int32 *whichNode;
Int32 i;
whichNode = (Int32 *) threadParam;
if (*whichNode == ALL_NODES) /* Start all nodes. */
{
for (i = 0; i < nodesLoaded; i++)
StartTM(i);
}
else /* Start only this node. */
StartTM(*whichNode);
StartTMHostComm();
return NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -