bool GravDataSet::loadFile(std::string file) { empty(); std::string::size_type fp; std::string::size_type sp; std::string line; std::stringstream sstr; std::ifstream ifs; ifs.open(file.c_str(), std::ios::in); // | std::ios::binary); if (!ifs) { debugout("loadFile() - No File found!", 99); return false; } if (std::getline(ifs, line)) { fp = line.find_first_not_of(DELIMDATA); // find letter after first seperator /* to avoid failures with empty lines */ if (fp != std::string::npos && !line.substr(fp, line.length()-1-fp).empty() ) { sp = line.find_first_of(DELIMDATA, fp); // find next seperator if (sp != std::string::npos) { strVersion = line.substr(fp, sp-fp); //extract strVersion line.erase(0, sp); //cut line } else { debugout("loadFile() - Failure 1", 99); return false; } fp = line.find_first_not_of(DELIMDATA); // find letter after first seperator sp = line.find_first_of(DELIMDATA, fp); // find next seperator if (sp != std::string::npos) { sstr.str(strEmpty); sstr.clear(); // clear Flags sstr << line.substr(fp, sp-fp); //extract numSteps sstr >> llnumSteps; line.erase(0, sp); //cut line } else {
bool GravStep::savetofile(std::ofstream& ofs, const unsigned int stepid) { if (!ofs) { debugout("savetofile() - No File found!", 99); return false; } debugout("savetofile() - Objectlist", objects, 15); ofs << "#" << stepid << ";" << numObjects << DELIMLINE; ofs.precision(DATAPRECISION); //Add Data of each object to datafile std::vector<GravObject*>::iterator i; for (i = objects.begin(); i != objects.end(); ++i) { if (*i) { //[Objekt ID];[Masse];[Radius];[Geschw.Vektor x];[Geschw.Vektor y];[Geschw.Vektor z]; //[Beschl.Vektor x];[Beschl.Vektor y];[Beschl.Vektor z];[Position x];[Position y];[Position z] //debugout("Model - AddStep() - Adding data to file No"+i); ofs << (*i)->id << DELIMDATA; ofs << (*i)->mass << DELIMDATA; ofs << (*i)->radius << DELIMDATA; ofs << (*i)->vel.x << DELIMDATA; ofs << (*i)->vel.y << DELIMDATA; ofs << (*i)->vel.z << DELIMDATA; ofs << (*i)->pos.x << DELIMDATA; ofs << (*i)->pos.y << DELIMDATA; ofs << (*i)->pos.z << DELIMLINE; } } debugout("savetofile() - Step successfully saved!", 40); return true; }
void GravStep::add(GravObject* pgo) { if(pgo != NULL) { numObjects++; objects.push_back(pgo); debugout("GravStep::add - Object added", 5); } else debugout("GravStep::add - Tried to add NULL", 90); }
/* Returns false on an error */ static rbool decode_args(int ip,op_rec *oprec) { rbool grammer_arg; /* Have NOUN/OBJECT that is 0 and so failed argok tests */ if (oprec->errmsg!=NULL) { if (!PURE_ERROR) writeln(oprec->errmsg); return 0; } if (DEBUG_AGT_CMD && !supress_debug) { if (oprec->negate) { /* Output NOT */ debug_cmd_out(ip,108,0,0,0); ip++; } } if (DEBUG_AGT_CMD && !supress_debug) debug_cmd_out(ip,oprec->op,oprec->arg1,oprec->arg2,oprec->optype); /* This checks and translates the arguments */ if (!argok(oprec->opdata,&(oprec->arg1),&(oprec->arg2), oprec->optype,&grammer_arg)) { /* Don't report errors for null NOUN/OBJECT/ACTOR arguments used in conditional tokens */ if (grammer_arg && oprec->op<=MAX_COND) return 0; if (!PURE_ERROR) { if (DEBUG_AGT_CMD && !supress_debug) debugout("\n"); writeln("GAME ERROR: Invalid argument to metacommand token."); } return 0; } return 1; }
/* This is called from the disassembler */ void print_tos(void) { if (sp>0) dbgprintf("TOS(%d)",stack[sp-1]); else debugout("TOS(xxx)"); }
//---------------------------------------------------------------------- // Perform a scratchpad match using provided data. Fixed data length // of 20 bytes. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'data' - data to use in match scratch operation // 'resume' - if true, device access is resumed using the RESUME // ROM command (0xA5). Otherwise, a a MATCH ROM is // used along with the device's entire address number. // // Return: TRUE - valid match // FALSE - no match or device not present // SMALLINT MatchScratchpadSHA18(int portnum, uchar* data, SMALLINT resume) { short send_cnt=0; uchar send_block[50]; int i; ushort lastcrc16; if(!resume) { // access the device OWASSERT( SelectSHA(portnum), OWERROR_ACCESS_FAILED, FALSE ); } else { // transmit RESUME command send_block[send_cnt++] = ROM_CMD_RESUME; } setcrc16(portnum,0); // match scratchpad command send_block[send_cnt] = CMD_MATCH_SCRATCHPAD; lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // send 20 data bytes for (i = 0; i < 20; i++) { send_block[send_cnt] = data[i]; lastcrc16 = docrc16(portnum,send_block[send_cnt++]); } // send two crc bytes and verification byte //for (i = 0; i < 3; i++) // send_block[send_cnt++] = 0xFF; memset(&send_block[send_cnt], 0x0FF, 3); send_cnt += 3; // now send the block OWASSERT( owBlock(portnum,resume,send_block,send_cnt), OWERROR_BLOCK_FAILED, FALSE ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // check the CRC for (i = (send_cnt - 3); i < (send_cnt - 1); i++) lastcrc16 = docrc16(portnum,send_block[i]); // verify CRC16 is correct OWASSERT( lastcrc16==0xB001, OWERROR_CRC_FAILED, FALSE ); // check verification if(send_block[send_cnt - 1] != (uchar)0xFF) return TRUE; else return FALSE; }
//---------------------------------------------------------------------- // Read the scratchpad with CRC16 verification for DS1963S. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'address' - pointer to address that is read from scratchpad // 'es' - pointer to offset byte read from scratchpad // 'data' - pointer data buffer read from scratchpad // 'resume' - if true, device access is resumed using the RESUME // ROM command (0xA5). Otherwise, a a MATCH ROM is // used along with the device's entire address number. // // Return: TRUE - scratch read, address, es, and data returned // FALSE - error reading scratch, device not present // // SMALLINT ReadScratchpadSHA18(int portnum, int* address, uchar* es, uchar* data, SMALLINT resume) { short send_cnt=0; uchar send_block[40]; SMALLINT i; ushort lastcrc16; if(!resume) { // access the device OWASSERT( SelectSHA(portnum), OWERROR_ACCESS_FAILED, FALSE ); } else { // transmit RESUME command send_block[send_cnt++] = ROM_CMD_RESUME; resume = 1; // for addition later } // read scratchpad command send_block[send_cnt++] = CMD_READ_SCRATCHPAD; // now add the read bytes for data bytes and crc16 //for (i = 0; i < 37; i++) // send_block[send_cnt++] = 0xFF; memset(&send_block[send_cnt], 0x0FF, 37); send_cnt += 37; // now send the block OWASSERT( owBlock(portnum,resume,send_block,send_cnt), OWERROR_BLOCK_FAILED, FALSE ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // calculate CRC16 of result setcrc16(portnum,0); for (i = resume; i < send_cnt ; i++) lastcrc16 = docrc16(portnum,send_block[i]); // verify CRC16 is correct OWASSERT( lastcrc16==0xB001, OWERROR_CRC_FAILED, FALSE ); // copy data to return buffers if(address) *address = (send_block[2+resume] << 8) | send_block[1+resume]; if(es) *es = send_block[3+resume]; memcpy(data, &send_block[4+resume], 32); // success return TRUE; }
GravObject* GravStep::addnew(GravObject* pgo) { GravObject* newone = new GravObject(pgo->id, pgo->mass, pgo->radius); newone->setSpeed(pgo->vel); newone->setCoord(pgo->pos); objects.push_back(newone); debugout("GravStep::add - new Object added", 5); numObjects++; return newone; }
void debug_newline(integer op, rbool first_nl) { rbool early_nl; if (!dbg_nomsg) return; early_nl=(op==1008||op==1027||op==1083||op==1105 ||(op>=1126&&op<=1131)); if (early_nl==first_nl) debugout("\n"); }
//---------------------------------------------------------------------- // Copy the scratchpad with verification for DS1963S. Assume that the // data was padded to get the CRC16 verification on write scratchpad. // This will result in the 'es' byte to be 0x1F. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'address' - address of destination // 'len' - length of data // 'resume' - if true, device access is resumed using the RESUME // ROM command (0xA5). Otherwise, a a MATCH ROM is // used along with the device's entire address number. // // Return: TRUE - copy scratch verified // FALSE - error during copy scratch, device not present, or HIDE // flag is in incorrect state for address being written. // SMALLINT CopyScratchpadSHA18(int portnum, int address, SMALLINT len, SMALLINT resume) { short send_cnt=0; uchar send_block[10]; int num_verf; uchar es = (address + len - 1) & 0x1F; if(!resume) { // access the device OWASSERT( SelectSHA(portnum), OWERROR_ACCESS_FAILED, FALSE ); } else { // transmit RESUME command send_block[send_cnt++] = ROM_CMD_RESUME; } // change number of verification bytes if in overdrive num_verf = (in_overdrive[portnum&0x0FF]) ? 4 : 2; // copy scratchpad command send_block[send_cnt++] = CMD_COPY_SCRATCHPAD; // address 1 send_block[send_cnt++] = (uchar)(address & 0xFF); // address 2 send_block[send_cnt++] = (uchar)((address >> 8) & 0xFF); // es send_block[send_cnt++] = es; // verification bytes //for (i = 0; i < num_verf; i++) // send_block[send_cnt++] = 0xFF; memset(&send_block[send_cnt], 0x0FF, num_verf); send_cnt += (short)num_verf; // now send the block OWASSERT( owBlock(portnum,resume,send_block,send_cnt), OWERROR_BLOCK_FAILED, FALSE ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // check verification OWASSERT( ((send_block[send_cnt-1] & 0xF0) == 0x50) || ((send_block[send_cnt-1] & 0xF0) == 0xA0), OWERROR_NO_COMPLETION_BYTE, FALSE ); return TRUE; }
virtual void _output_initialize() { if (SUCCEEDED(_file.Create(_T("debug.txt"), GENERIC_WRITE, FILE_SHARE_READ, OPEN_ALWAYS))) { SYSTEMTIME st; ::GetLocalTime(&st); debugout(_T("----- %04d-%02d-%02d %02d:%02d:%02d -----"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); } else _out_type = DEBUGOUT_STRING; }
void dbgprintf(const char *fmt,...) { va_list vp; char buff[300]; va_start(vp,fmt); vsprintf(buff,fmt,vp); va_end(vp); debugout(buff); }
static void scan_dbg(int vcode) { char buff[220]; word w; if (vcode>=BASE_VERB && vcode<BASE_VERB+DUMB_VERB && syntbl[synlist[vcode]]!=0) w=syntbl[synlist[vcode]]; else w=syntbl[auxsyn[vcode]]; if (strlen(dict[w])>200) return; /* Just in case... */ sprintf(buff,"+++++Scanning %s\n",dict[w]); debugout(buff); }
static void print_msg(descr_ptr dp) { int j; descr_line *txt; txt=read_descr(dp.start,dp.size); if (txt!=NULL) { for(j=0;txt[j]!=NULL;j++) { dbgprintf("\n"); debugout(txt[j]); } } free_descr(txt); }
/* * Generalized send routine. Sends a message on message queue. */ int send_message(int id, mtyp_t type, char *text) { int rc; Msgbuf sndbuf; strcpy(sndbuf.mtext, text); sndbuf.mtyp = type; while (TRUE) { rc = msgsnd(id, &sndbuf, sizeof(struct messagebuf), IPC_NOWAIT); if (rc == -1 && errno == EAGAIN) { debugout("msgqueue %d of mtyp %d not ready to send\n", msgid, type); errno = 0; } else return (rc); } }
void Viewer::dynamicsMenuCallback(GLMotif::ToggleButton::ValueChangedCallbackData *cbData) { bool popup=false; // delete current dynamical model if (model != NULL) delete model; GLMotif::WidgetManager::Transformation oldTrans; // delete current parameter dialog if (parameterDialog != NULL) { // save the old transformation oldTrans=parameterDialog->getTransformation(); // if dialog is currently shown hide before deleting if (parameterDialog->state() == CaveDialog::ACTIVE) { parameterDialog->hide(); // set flag to popup after creating new dialog popup=true; } delete parameterDialog; } std::string name=cbData->toggle->getName(); // create the key from the toggle name std::string key(name); key.erase(key.find("toggle")); debugout() << " toggle: " << name << "\tkey: " << key << std::endl; // create the dynamical model model=Factory[key](); // create/assign parameter dialog parameterDialog=model->createParameterDialog(mainMenu); parameterDialog->setTransformation(oldTrans); // popup parameter dialog if previously shown or system requests it if (popup) parameterDialog->show(); else if (model->autoShowParameterDialog()) { showParameterDialogToggle->setToggle(true); parameterDialog->show(); } // update the integration step size double step_size=IntegrationStepSize::instance()->getSavedValue(key); if (step_size > 0.0) { masterout() << key << ":restoring step size [" << step_size << "]" << std::endl; } else { // set the integration step size to the default value step_size=IntegrationStepSize::DefaultStepSize; masterout() << key << ":integration step size not set." << " Setting to default (" << step_size << ")" << std::endl; } IntegrationStepSize::instance()->setValue(step_size); // iterate through tools and sets dynamical integrator for (ToolList::iterator tool=tools.begin(); tool != tools.end(); ++tool) { (*tool)->setIntegrator(model); } // fake radio-button behavior setRadioToggles(dynamicsToggleButtons, name); }
int scan_metacommand(integer m_actor,int vcode, integer m_dobj, word m_prep, integer m_iobj, int *redir_flag) /* Return codes: 0=end of this cycle, 1=end of all commands 2=end of turn */ /* If doing disambiguation, then -2=end of cycle, something happened; 0 or 1=end of cycle; nothing happened; 2=end of turn, nothing happened. */ /* If redir_flag is non-NULL, it is set when redirection occurs: 1+=Redirection occured 2=Grammar-changing redirection occured. */ { int i, oldi; word m_verb; int scanend; int redir_offset; /* Used for multiple redirects in the same metacommand (which can occur in AGATE-style commands)-- this is used to hold the offset of the given redirect. */ long redirect_count; /* This is a safety measure: this keeps track of how many redirections have occured on a single turn, and if there are "too many" it will issue an error message and stop. This is to prevent the system from getting into a redirection loop. The number should be set high enough not to prevent deliberate loops, however. */ rfree(substack); subcnt=0; subsize=0; redirect_count=0; if (mars_fix) if (vcode==0 || m_actor==2) return 0; /* Don't explicity scan ANY metacommands if MARS fix is active. */ if (m_actor==-ext_code[weverybody]) m_actor=2; if (DEBUG_AGT_CMD && DEBUG_SCAN &&!supress_debug) scan_dbg(vcode); m_verb=syntbl[auxsyn[vcode]]; if (m_actor==0) { i=verbptr[vcode]; scanend=verbend[vcode]; } else scan_for_actor(m_actor,&i,&scanend); for(;i<scanend;i++) if ( command[i].actor<0) {/* REDIRECT data; skip over it */;} else if (cm_command(&command[i],m_actor,m_verb,m_dobj,m_prep,m_iobj)) switch (run_metacommand(i,&redir_offset)) { case -2:rfree(substack); return -2; /* We are doing disambiguation and reached an action token */ case 0:break; /* Go onto next metacommand */ case 1:rfree(substack); return 1; /* Done with metacommands */ case 2:rfree(substack); return 2; /* Done with turn */ /* -------- REDIRECTION ------------ */ /* This handles RedirectTo tokens */ case 3: oldi=i; i+=redir_offset; if (i==last_cmd || command[i].actor>0) { if (!PURE_ERROR) writeln("GAME ERROR: Invalid REDIRECT token."); rfree(substack); return 2; } if (MAX_REDIR!=0 && ++redirect_count>MAX_REDIR) { if (!PURE_ERROR) writeln("GAME ERROR: Infinite REDIRECT loop."); rfree(substack); return 2; } if (DEBUG_AGT_CMD && !supress_debug) { debugout(" ==>"); debug_head(i); } /* REDIRECT :If we do a redirect from a broader grammar to a narrower grammer, it will be noted so that certain types of grammer checking can be disabled. */ if (redir_flag!=NULL) { if (*redir_flag<2 && redir_narrows_grammar(&command[oldi],&command[i])) *redir_flag=2; /* Set *redir_flag to at least 1 if we do *any* redirection. */ if (!*redir_flag) *redir_flag=1; } /* REDIRECT: Do the actual redirection, building the new command header and shuffling around nouns and verbs as neccessary */ redirect_exec(&command[i],&m_actor,&vcode, &m_dobj,&m_prep,&m_iobj); /* REDIRECT: Start scanning again from the beginning */ if (!mars_fix) {/* In MARS, we *don't* go back to the top */ if (m_actor!=0) scan_for_actor(m_actor,&i,&scanend); else { i=verbptr[vcode]; scanend=verbend[vcode]; } i--; /* Back up one so that the following i++ we'll be at the right location */ } /* So when i is incremented, we start back at the correct start: i.e. we start scanning again from the beginning. It's even possible to use REDIRECT to run verb commands from an AFTER command, although it precludes other AFTER commands from running. */ m_verb=syntbl[auxsyn[vcode]]; break; /* -------- SUBROUTINE CALL ------------ */ case 4: /* Subroutine Call -- same idea as RedirectTo, but less complicated */ push_subcall_grammar(m_actor,vcode,m_dobj,m_prep,m_iobj,i); vcode=verb_code(sub_name[subcall_arg-1]); m_actor=m_dobj=m_iobj=0; m_prep=0; if (!mars_fix) /* In MARS, we *don't* go back to the top */ i=verbptr[vcode]-1; scanend=verbend[vcode]; m_verb=syntbl[auxsyn[vcode]]; break; /* -------- RETURN ------------ */ case 5: /* Return: pop grammar state, then ... ? */ if (!pop_subcall_grammar(&m_actor,&vcode, &m_dobj,&m_prep,&m_iobj,&i)) { writeln("GAME ERROR: Return without DoSubroutine."); rfree(substack); return 2; } if (m_actor==0) scanend=verbend[vcode]; else scan_for_actor(m_actor,NULL,&scanend); m_verb=syntbl[auxsyn[vcode]]; i--; /* Cause the last command to restart, at which point run_command will pop the rest of the stack. */ break; } rfree(substack); return 0; /* Done with this cycle of metacommands */ }
/** * Create the indirect sector with the DAPS entries * @param daps_table Where to store the entries * @param size Size of the whole image in bytes * @param pers_sector_count Count of sectors to skip after MBR for the persistent environment storage * @return 0 on success * * This routine calculates the DAPS entries for the case the whole * barebox images fits into the MBR itself and the sectors after it. * This means the start of the first partition must keep enough sectors * unused. * It also skips 'pers_sector_count' sectors after the MBR for special * usage if given. */ static int barebox_linear_image(struct DAPS *daps_table, off_t size, long pers_sector_count) { unsigned offset = LOAD_AREA, next_offset; unsigned segment = LOAD_SEGMENT; unsigned chunk_size, i = 0; uint64_t lba = 2 + pers_sector_count; int rc; /* * We can load up to 127 sectors in one chunk. What a bad number... * So, we will load in chunks of 32 kiB. */ /* at runtime two sectors from the image are already loaded: MBR and indirect */ size -= 2 * SECTOR_SIZE; /* and now round up to multiple of sector size */ size = (size + SECTOR_SIZE - 1) & ~(SECTOR_SIZE - 1); /* * The largest image we can load with this method is: * (SECTOR_SIZE / sizeof(DAPS) - 1) * 32 kiB * For a 512 byte sector and a 16 byte DAPS: * (512 / 16 - 1) * 32 kiB = 992 kiB * Note: '- 1' to consider one entry is required to pad to a 32 kiB boundary */ if (size >= (SECTOR_SIZE / sizeof(struct DAPS) - 1) * 32 * 1024) { fprintf(stderr, "Image too large to boot. Max size is %zu kiB, image size is %lu kiB\n", (SECTOR_SIZE / sizeof(struct DAPS) - 1) * 32, size / 1024); return -1; } if (size > 32 * 1024) { /* first fill up until the next 32 k boundary */ next_offset = (offset + 32 * 1024 -1) & ~0x7fff; chunk_size = next_offset - offset; if (chunk_size & (SECTOR_SIZE-1)) { fprintf(stderr, "Unable to pad from %X to %X in multiple of sectors\n", offset, next_offset); return -1; } rc = fill_daps(&daps_table[i], chunk_size / SECTOR_SIZE, offset, segment, lba); if (rc != 0) return -1; debugout(&daps_table[i], 0); /* calculate values to enter the loop for the other entries */ size -= chunk_size; i++; lba += chunk_size / SECTOR_SIZE; offset += chunk_size; if (offset >= 0x10000) { segment += 4096; offset = 0; } /* * Now load the remaining image part in 32 kiB chunks */ while (size) { if (size >= 32 * 1024 ) { if (i >= (SECTOR_SIZE / sizeof(struct DAPS))) { fprintf(stderr, "Internal tool error: Too many DAPS entries!\n"); return -1; } rc = fill_daps(&daps_table[i], 64, offset, segment, lba); if (rc != 0) return -1; debugout(&daps_table[i], 0); size -= 32 * 1024; lba += 64; offset += 32 * 1024; if (offset >= 0x10000) { segment += 4096; offset = 0; } i++; } else { if (i >= (SECTOR_SIZE / sizeof(struct DAPS))) { fprintf(stderr, "Internal tool error: Too many DAPS entries!\n"); return -1; } rc = fill_daps(&daps_table[i], size / SECTOR_SIZE, offset, segment, lba); if (rc != 0) return -1; debugout(&daps_table[i], 0); size = 0; /* finished */ i++; } }; } else { /* less than 32 kiB. Very small image... */ rc = fill_daps(&daps_table[i], size / SECTOR_SIZE, offset, segment, lba); if (rc != 0) return -1; debugout(&daps_table[i], 0); i++; } /* * Do not mark an entry as invalid if the buffer is full. The * boot code stops if all entries of a buffer are read. */ if (i >= (SECTOR_SIZE / sizeof(struct DAPS))) return 0; /* mark the last DAPS invalid */ invalidate_daps(&daps_table[i]); debugout(&daps_table[i], 0); return 0; }
/* * This is the meat and potatoes of the program. Spawn creates a tree * of processes with Dval depth and Bval breadth. Each parent will spawn * Bval children. Each child will store information about themselves * in shared memory. The leaf nodes will communicate the existence * of one another through message queues, once each leaf node has * received communication from all of her siblings she will reduce * the semaphore count and exit. Meanwhile all parents are waiting * to hear from their children through the use of semaphores. When * the semaphore count reaches zero then the parent knows all the * children have talked to one another. Locking of the connter semaphore * is provided by the use of another (binary) semaphore. */ int spawn(int val) { extern int sem_count; /* used to keep track of childern */ extern int sem_lock; /* used to lock access to sem_count semaphore */ int i; /* Breadth counter */ static int level = 0; /* level counter */ int lvlflg = 0; /* level toggle, limits parental spawning to one generation */ int pslot = 0; #ifdef __64LDT__ pid_t pid; /* pid of child process */ #else int pid; /* pid of child process */ #endif Pinfo *pinfo; /* pointer to process information in shared mem */ int semval; /* value of semaphore ( equals BVAL initially */ static int tval = 1; /* tree node value of child. */ char foo[1024]; level++; for (i = 1; i <= BVAL; i++) { tval = (val * BVAL) + i; if (!lvlflg) { pid = fork(); if (!pid) { /* CHILD */ if (AUSDEBUG) { sprintf(foo, "%sslot%d", SLOTDIR, tval); debugfp = fopen(foo, "a+"); } pinfo = put_proc_info(tval); debugout ("pid: %-6d ppid: %-6d lev: %-2d i: %-2d val: %-3d\n", pinfo->pid, pinfo->ppid, level, i, tval); set_timer(); /* set up signal handlers and initialize pgrp */ if (level < DVAL) { if (spawn(tval) == -1) { pslot = semoper(tval, sem_lock, -1); semarg.val = 0; /* to fix problem with 4th arg of semctl in 64 bits MARIOG */ semval = semctl(sem_count, pslot, GETVAL, semarg); semarg.val = --semval; /* to fix problem with 4th arg of semctl in 64 bits MARIOG */ semctl(sem_count, pslot, SETVAL, semarg); semarg.val = 1; /* to fix problem with 4th arg of semctl in 64 bits MARIOG */ semctl(sem_lock, pslot, SETVAL, semarg); } lvlflg++; } else { /* leaf node */ notify(tval); return (-1); } } #ifdef __64LDT__ else if (pid > 0 && i >= BVAL) { /* PARENT */ #else else if (pid > (pid_t) 0 && i >= BVAL) { /* PARENT */ #endif pslot = semoper(tval, sem_count, 0); pslot = semoper(pslot, sem_lock, -1); semarg.val = 0; /* to fix problem with 4th arg of semctl in 64 bits MARIOG */ semval = semctl(sem_count, pslot, GETVAL, semarg); semarg.val = --semval; /* to fix problem with 4th arg of semctl in 64 bits MARIOG */ semctl(sem_count, pslot, SETVAL, semarg); semarg.val = 1; /* to fix problem with 4th arg of semctl in 64 bits MARIOG */ semctl(sem_lock, pslot, SETVAL, semarg); (shmaddr + val)->msg++; } #ifdef __64LDT__ else if (pid < (pid_t) 0) { #else else if (pid < 0) { #endif perror("spawn: fork failed"); severe ("spawn: fork failed, exiting with errno %d\n", errno); exit(1); } else (shmaddr + val)->msg++; } } return (pslot); } /* * Allocate message queues. */ void setup_msgqueue(void) { extern int msgid; extern int msgerr; msgid = msgget(IPC_PRIVATE, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (msgid == -1) { perror("msgget msgid failed"); fprintf(stderr, " SEVERE : msgget msgid failed: errno %d\n", errno); exit(1); } msgerr = msgget(IPC_PRIVATE, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (msgerr == -1) { perror("msgget msgerr failed"); fprintf(stderr, " SEVERE : msgget msgerr failed: errno %d\n", errno); exit(1); } } /* * Set up and initialize all semaphores */ void setup_semaphores(void) { extern int sem_count; extern int sem_lock; int i; int rc; prtln(); sem_lock = semget(IPC_PRIVATE, nodesum - 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); dprt("nodesum = %d, sem_lock = %d\n", nodesum, sem_lock); prtln(); if (sem_lock == -1) { perror("semget failed for sem_lock"); fprintf(stderr, " SEVERE : semget failed for sem_lock, errno: %d\n", errno); rm_shmseg(); exit(1); } prtln(); sem_count = semget(IPC_PRIVATE, nodesum - 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (sem_count == -1) { perror("semget failed for sem_count"); fprintf(stderr, " SEVERE : semget failed for sem_count, errno: %d\n", errno); rm_shmseg(); exit(1); } prtln(); for (i = 0; i < (nodesum - 1); i++) { semarg.val = 1; /* to fix problem with 4th arg of semctl in 64 bits MARIOG */ rc = semctl(sem_lock, i, SETVAL, semarg); prtln(); if (rc == -1) { perror("semctl failed for sem_lock failed"); fprintf(stderr, " SEVERE : semctl failed for sem_lock, errno: %d\n", errno); rm_shmseg(); exit(1); } semarg.val = BVAL; /* to fix problem with 4th arg of semctl in 64 bits MARIOG */ rc = semctl(sem_count, i, SETVAL, semarg); prtln(); if (rc == -1) { perror("semctl failed for sem_lock failed"); fprintf(stderr, " SEVERE : semctl failed for sem_lock, errno: %d\n", errno); rm_shmseg(); exit(1); } } } /* * Set up and allocate shared memory. */ void setup_shm(void) { extern int nodesum; /* global shared memory id */ extern int shmid; /* global shared memory id */ extern Pinfo *shmaddr; int i, j; /* counters */ Pinfo *shmad = NULL; /* ptr to start of shared memory. */ Pinfo *pinfo = NULL; /* ptr to struct in shared memory. */ debugout("size = %d, size (in hex) = %#x nodes: %d\n", sizeof(Pinfo) * nodesum + (nodesum * BVAL * sizeof(int)), sizeof(Pinfo) * nodesum + (nodesum * BVAL * sizeof(int)), nodesum); /* Get shared memory id */ shmid = shmget(IPC_PRIVATE, sizeof(Pinfo) * nodesum + (nodesum * BVAL * sizeof(int)), IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (shmid < 0) { perror("shmget failed"); fprintf(stderr, " SEVERE : shmget failed: errno %d\n", errno); exit(1); } /* allocate shared memory */ if ((shmad = shmat(shmid, (char *)shmad, 0)) == MAP_FAILED) { printf("SEVERE : shmat failed\n"); exit(1); } else { shmctl(shmid, IPC_RMID, NULL); } /* set all fields in shared memory to -1 */ for (pinfo = shmad, i = 0; i < nodesum; i++, pinfo++) { #ifdef __64LDT__ pinfo->pid = (pid_t) - 1; pinfo->ppid = (pid_t) - 1; #else pinfo->pid = -1; pinfo->ppid = -1; #endif pinfo->msg = -1; pinfo->err = -1; /* Changed 10/9/97 */ /* pinfo->list = (int *)((ulong)shmad + nodesum * sizeof(Pinfo) + (sizeof(int) * BVAL * i)); */ pinfo->list = (int *)((long)shmad + nodesum * sizeof(Pinfo) + (sizeof(int) * BVAL * i)); for (j = 0; j < BVAL; j++) *(pinfo->list + j) = -1; } shmaddr = shmad; } /* * Set up Signal handler and which signals to catch */ void set_signals(void *sighandler()) { int i; int rc; struct sigaction action; /* list of signals we want to catch */ static struct signalinfo { int signum; char *signame; } siginfo[] = { { SIGHUP, "SIGHUP"}, { SIGINT, "SIGINT"}, { SIGQUIT, "SIGQUIT"}, { SIGABRT, "SIGABRT"}, { SIGBUS, "SIGBUS"}, { SIGSEGV, "SIGSEGV"}, { SIGALRM, "SIGALRM"}, { SIGUSR1, "SIGUSR1"}, { SIGUSR2, "SIGUSR2"}, { -1, "ENDSIG"} }; char tmpstr[1024]; action.sa_handler = (void *)sighandler; #ifdef _LINUX sigfillset(&action.sa_mask); #else SIGINITSET(action.sa_mask); #endif action.sa_flags = 0; /* Set the signal handler up */ #ifdef _LINUX sigaddset(&action.sa_mask, SIGTERM); #else SIGADDSET(action.sa_mask, SIGTERM); #endif for (i = 0; siginfo[i].signum != -1; i++) { #ifdef _LINUX sigaddset(&action.sa_mask, siginfo[i].signum); #else SIGADDSET(action.sa_mask, siginfo[i].signum); #endif rc = sigaction(siginfo[i].signum, &action, NULL); if (rc == -1) { sprintf(tmpstr, "sigaction: %s\n", siginfo[i].signame); perror(tmpstr); fprintf(stderr, " SEVERE : Could not set %s signal action, errno=%d.", siginfo[i].signame, errno); exit(1); } } }
//---------------------------------------------------------------------- // Copies hidden scratchpad data into specified secret. Resume command // is used by default. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'secretnum' - secret number to replace with scratchpad data. // // Return: TRUE - copy secret succeeded // FALSE - error or device not present // SMALLINT CopySecretSHA18(int portnum, SMALLINT secretnum) { // change number of verification bytes if in overdrive SMALLINT num_verf = (in_overdrive[portnum&0x0FF]) ? 10 : 2; // each page has 4 secrets, so look at 2 LS bits to // determine offset in the page. SMALLINT secret_offset = (secretnum&3) << 3; // secrets 0-3 are stored starting at address 0200h // and 4-7 are stored starting at address 0220h. int address = (secretnum<4 ? 0x0200 : 0x0220) + secret_offset; SMALLINT length = 32 - secret_offset; SMALLINT send_cnt = 0, i; uchar send_block[38]; ushort lastcrc16; //Since other functions must be called before this one //that are communicating with the button, resume is assumed. send_block[send_cnt++] = ROM_CMD_RESUME; send_block[send_cnt++] = CMD_WRITE_SCRATCHPAD; send_block[send_cnt++] = (uchar)address; send_block[send_cnt++] = (uchar)(address>>8); //for(i=0; i<length+2; i++) // send_block[send_cnt++] = (uchar)0x0FF; memset(&send_block[send_cnt], 0x0FF, 2+length); send_cnt += 2+length; // now send the block OWASSERT( owBlock(portnum,TRUE,send_block,send_cnt), OWERROR_BLOCK_FAILED, FALSE ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // calculate CRC16 of result setcrc16(portnum,0); for (i = 1; i < send_cnt ; i++) lastcrc16 = docrc16(portnum,send_block[i]); // verify CRC16 is correct OWASSERT( lastcrc16==0xB001, OWERROR_CRC_FAILED, FALSE ); // Now read TA1/TA2 and ES, but not rest of data; send_cnt = 1; send_block[send_cnt++] = CMD_READ_SCRATCHPAD; //for(i=0; i<3; i++) // send_block[send_cnt++] = (uchar)0x0FF; memset(&send_block[send_cnt], 0x0FF, 3); send_cnt += 3; // now send the block to get TA1/TA2 and ES OWASSERT( owBlock(portnum,TRUE,send_block,send_cnt), OWERROR_BLOCK_FAILED, FALSE ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // Use the same buffer to call copyScratchpad with proper // authorization bytes. send_block[1] = CMD_COPY_SCRATCHPAD; //for(i=0; i<num_verf; i++) // send_block[send_cnt++] = (uchar)0x0FF; memset(&send_block[send_cnt], 0x0FF, num_verf); send_cnt += num_verf; // now send the block OWASSERT( owBlock(portnum,TRUE,send_block,send_cnt), OWERROR_BLOCK_FAILED, FALSE ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // check verification OWASSERT( ((send_block[send_cnt-1] & 0xF0) == 0x50) || ((send_block[send_cnt-1] & 0xF0) == 0xA0), OWERROR_NO_COMPLETION_BYTE, FALSE ); return TRUE; }
/** * Prepare the MBR and indirect sector for runtime * @param fd_barebox barebox image to use * @param fd_hd Hard disk image to prepare * @param pers_sector_count Count of sectors to skip after MBR for the persistent environment storage * @return 0 on success * * This routine expects a prepared hard disk image file with a partition table * in its first sector. This method only is currently supported. */ static int barebox_overlay_mbr(int fd_barebox, int fd_hd, long pers_sector_count) { const void *barebox_image; void *hd_image; int rc; struct stat sb; struct DAPS *embed; /* part of the MBR */ struct DAPS *indirect; /* sector with indirect DAPS */ off_t required_size; if (fstat(fd_barebox, &sb) == -1) { perror("fstat"); return -1; } /* the barebox image won't be touched */ barebox_image = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd_barebox, 0); if (barebox_image == MAP_FAILED) { perror("mmap"); return -1; } rc = check_for_valid_mbr(barebox_image, sb.st_size); if (rc != 0) { fprintf(stderr, "barebox image seems not valid: Bad MBR signature\n"); goto on_error_hd; } /* * the persistent environment storage is in front of the main * barebox image. To handle both, we need more space in front of the * the first partition. */ required_size = sb.st_size + pers_sector_count * SECTOR_SIZE; /* the hd image will be modified */ hd_image = mmap(NULL, required_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_hd, 0); if (hd_image == MAP_FAILED) { perror("mmap"); rc = -1; goto on_error_hd; } /* check for space */ rc = check_for_space(hd_image, required_size); if (rc != 0) goto on_error_space; /* embed barebox's boot code into the disk drive image */ memcpy(hd_image, barebox_image, OFFSET_OF_PARTITION_TABLE); /* * embed the barebox main image into the disk drive image, * but keep the persistent environment storage untouched * (if defined), e.g. store the main image behind this special area. */ memcpy(hd_image + ((pers_sector_count + 1) * SECTOR_SIZE), barebox_image + SECTOR_SIZE, sb.st_size - SECTOR_SIZE); /* now, prepare this hard disk image for BIOS based booting */ embed = hd_image + PATCH_AREA; indirect = hd_image + ((pers_sector_count + 1) * SECTOR_SIZE); /* * Fill the embedded DAPS to let the basic boot code find the * indirect sector at runtime */ #ifdef DEBUG printf("Debug: Fill in embedded DAPS\n"); #endif rc = fill_daps(embed, 1, INDIRECT_AREA, INDIRECT_SEGMENT, 1 + pers_sector_count); if (rc != 0) goto on_error_space; debugout(embed, 1); #ifdef DEBUG printf("Debug: Fill in indirect sector\n"); #endif /* * fill the indirect sector with the remaining DAPS to load the * whole barebox image at runtime */ rc = barebox_linear_image(indirect, sb.st_size, pers_sector_count); if (rc != 0) goto on_error_space; /* * TODO: Replace the fixed LBA starting number by a calculated one, * to support barebox as a chained loader in a different start * sector than the MBR */ rc = store_pers_env_info(embed, 1, pers_sector_count); if (rc != 0) goto on_error_space; on_error_space: munmap(hd_image, required_size); on_error_hd: munmap((void*)barebox_image, sb.st_size); return rc; }
//---------------------------------------------------------------------- // Compute sha command based on control_byte and page address. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'control_byte' - control byte used in sha operation // 'address' - address used in compute sha operation // 'resume' - if true, device access is resumed using the RESUME // ROM command (0xA5). Otherwise, a a MATCH ROM is // used along with the device's entire address number. // // Return: TRUE - compute sha finished // FALSE - CRC error, device not present // SMALLINT SHAFunction18(int portnum, uchar control_byte, int address, SMALLINT resume) { short send_cnt=0; uchar send_block[18]; int i,num_verf; ushort lastcrc16; if(!resume) { // access the device OWASSERT( SelectSHA(portnum), OWERROR_ACCESS_FAILED, FALSE ); } else { // transmit RESUME command send_block[send_cnt++] = ROM_CMD_RESUME; } setcrc16(portnum,0); // change number of verification bytes if in overdrive num_verf = (in_overdrive[portnum&0x0FF]) ? 10 : 2; // Compute SHA Command send_block[send_cnt] = CMD_COMPUTE_SHA; lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // address 1 send_block[send_cnt] = (uchar)(address & 0xFF); lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // address 2 send_block[send_cnt] = (uchar)((address >> 8) & 0xFF); lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // control byte send_block[send_cnt] = control_byte; lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // now read bytes crc16, and verification //for (i = 0; i < 2 + num_verf; i++) // send_block[send_cnt++] = 0xFF; memset(&send_block[send_cnt], 0x0FF, 2+num_verf); send_cnt += 2+num_verf; // now send the block OWASSERT( owBlock(portnum,resume,send_block,send_cnt), OWERROR_BLOCK_FAILED, FALSE ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // check the CRC for (i = resume?5:4; i < (send_cnt - num_verf); i++) lastcrc16 = docrc16(portnum,send_block[i]); // verify CRC16 is correct OWASSERT( lastcrc16==0xB001, OWERROR_CRC_FAILED, FALSE ); // check verification OWASSERT( ((send_block[send_cnt-1] & 0xF0) == 0x50) || ((send_block[send_cnt-1] & 0xF0) == 0xA0), OWERROR_NO_COMPLETION_BYTE, FALSE ); return TRUE; }
//---------------------------------------------------------------------- // Read Authenticated Page for DS1963S. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'pagenum' - page number to do a read authenticate // 'data' - buffer to read into from page // 'sign' - buffer for storing sha computation // 'resume' - if true, device access is resumed using the RESUME // ROM command (0xA5). Otherwise, a a MATCH ROM is // used along with the device's entire address number. // // Return: Value of write cycle counter for the page // -1 for error // int ReadAuthPageSHA18(int portnum, SMALLINT pagenum, uchar* data, uchar* sign, SMALLINT resume) { short send_cnt=0; uchar send_block[56]; short num_verf; SMALLINT i; ushort lastcrc16; int address = pagenum*32, wcc = -1; if(!resume) { // access the device OWASSERT( SelectSHA(portnum), OWERROR_ACCESS_FAILED, -1 ); } else { // transmit RESUME command send_block[send_cnt++] = ROM_CMD_RESUME; } //seed the crc setcrc16(portnum,0); // change number of verification bytes if in overdrive num_verf = (in_overdrive[portnum&0x0FF]) ? 10 : 2; // create the send block // Read Authenticated Page command send_block[send_cnt] = CMD_READ_AUTH_PAGE; lastcrc16 = docrc16(portnum, send_block[send_cnt++]); // TA1 send_block[send_cnt] = (uchar)(address & 0xFF); lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // TA2 send_block[send_cnt] = (uchar)((address >> 8) & 0xFF); lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // now add the read bytes for data bytes, counter, and crc16, verification //for (i = 0; i < (42 + num_verf); i++) // send_block[send_cnt++] = 0xFF; memset(&send_block[send_cnt], 0x0FF, 42+num_verf); send_cnt += 42+num_verf; // now send the block OWASSERT( owBlock(portnum,resume,send_block,send_cnt), OWERROR_BLOCK_FAILED, -1 ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // check the CRC for (i = resume?4:3; i < (send_cnt - num_verf); i++) lastcrc16 = docrc16(portnum,send_block[i]); // verify CRC16 is correct OWASSERT( lastcrc16==0xB001, OWERROR_CRC_FAILED, -1); // check verification OWASSERT( ((send_block[send_cnt-1] & 0xF0) == 0x50) || ((send_block[send_cnt-1] & 0xF0) == 0xA0), OWERROR_NO_COMPLETION_BYTE, -1); // transfer results //cnt = 0; //for (i = send_cnt - 42 - num_verf; i < (send_cnt - 10 - num_verf); i++) // data[cnt++] = send_block[i]; memcpy(data, &send_block[send_cnt-42-num_verf], 32); wcc = BytesToInt(&send_block[send_cnt-10-num_verf], 4); if(sign!=NULL) { OWASSERT( ReadScratchpadSHA18(portnum, 0, 0, send_block, TRUE), OWERROR_READ_SCRATCHPAD_FAILED, FALSE ); //for(i=0; i<20; i++) // sign[i] = send_block[i+8]; memcpy(sign, &send_block[8], 20); } return wcc; }
static int run_metacommand(int cnum, int *redir_offset) /* cnum=command number to run. */ /* *redir_offset=offset of redirect header, if we exit with redirection. */ /* Return 0 to go on to next metacommand, 1 to stop running metacommands, and 2 to end the turn. 3 indicates that redirection has just occured 4 indicates a subcall has just occured. 5 Is used to go on to the next metacommand after a Return. -2 means we're doing disambiguation and just hit an action token. */ { int ip, oip; /* ip=Instruction pointer, oip=Old instruction pointer */ int r; /* Used to hold return value from token execution */ int fail_addr; /* What address to jump to on failure */ rbool fail; /* Last token was a conditional token that failed */ rbool ortrue, blocktrue, orflag; /* OR stuff orflag: Are we in an OR group? ortrue: Is current OR group true? blocktrue: Is current block w/in OR true? */ static rbool restart=0; /* Restarting after subroutine? */ op_rec currop; /* Information on the current token and its args */ fail_addr=32000; /* Fall off the end when we fail */ fail=0; ip=0; orflag=blocktrue=ortrue=0; *redir_offset=1; /* Default: This is what RedirectTo does. Only XRedirect can send a different value */ if (restart) /* finish up Return from subroutine */ pop_subcall(&cnum,&ip,&fail_addr); if (DEBUG_AGT_CMD && !supress_debug) { debug_head(cnum); if (restart) debugout(" (Resuming after subroutine)\n"); } restart=0; /* ========== Main Loop ================= */ while(ip<command[cnum].cmdsize) { oip=ip; ip+=decode_instr(&currop,command[cnum].data+ip,command[cnum].cmdsize-ip); /* ------- OR Logic --------------- */ if (currop.op==109) { /* OR */ if (!orflag) { /* First OR; set things up */ orflag=1; ortrue=0; blocktrue=1; } blocktrue=blocktrue && !fail; /* Was the previous token true? */ fail=0; ortrue=ortrue||blocktrue; /* OR in last block */ blocktrue=1; /* New block starts out true. */ } else if (orflag) { /* we're in the middle of a block */ blocktrue=blocktrue&&!fail; /* Add in previous token */ fail=0; if (currop.endor) { /* i.e. not a conditional token */ orflag=0; /* End of OR block */ ortrue=ortrue||blocktrue; /* OR in last block */ fail=!ortrue; /* Success of whole group */ } } /* ------------ FAILMESSAGE handling ------------- */ if (currop.failmsg) { /* Is the current token a Fail... token? */ if (!fail) continue; /* Skip it; look at next instruction */ /* ErrMessage and ErrStdMessage: set disambiguation score */ if (do_disambig) { if (currop.op==1130 || currop.op==1131) { if (!decode_args(oip,&currop)) return 2; disambig_score=currop.arg1; return 2; } else return -2; /* FailMessage counts as an action token */ } /* Then run the failmessage, skipping the following step... */ } /* -------- Failure routines -------------------- */ else if (fail) { /* ... and not failmessage */ /* consequences of failure */ fail=0; /* In case fail_addr doesn't point off the edge of the world */ ip=fail_addr; fail_addr=32000; /* Reset fail_addr */ continue; /* Usually fail_addr will fall off the end, causing this to return 0 */ } /* - Finish decoding arguments and print out debugging message - */ if (!decode_args(oip,&currop)) { if (currop.op<1000) fail=currop.negate ? 0 : 1; continue; /* return 2;*/ } /* -------- Commands that need to be handled specially -------------- */ if (currop.op==109) { /* OR */ if (DEBUG_AGT_CMD && !supress_debug) debug_newline(op,0); continue; /* OR: skip further processing */ } if (currop.op==1037) { /* DoSubroutine */ if (!push_subcall(cnum,ip,fail_addr)) { writeln("GAME ERROR: Subroutine stack overflow."); return 2; } subcall_arg=currop.arg1; if (DEBUG_AGT_CMD && !supress_debug) debugout("--> Call\n"); return 4; } if (currop.op==1038) { /* Return */ restart=1; if (DEBUG_AGT_CMD && !supress_debug) debugout("--> Return\n"); return 5; } if (currop.op==1149) { /* Goto */ ip=currop.arg1; if (DEBUG_AGT_CMD && !supress_debug) debugout("\n"); continue; } if (currop.op==1150) { /* OnFailGoto */ fail_addr=currop.arg1; if (DEBUG_AGT_CMD && !supress_debug) debugout("\n"); continue; } if (currop.op==1152) /* XRedirect */ *redir_offset=currop.arg1; /* ---------- Disambiguation Success -------------- */ if (do_disambig && currop.disambig) { if (DEBUG_AGT_CMD && !supress_debug) debugout("==> ACTION\n"); return -2; } /* ---------- Run normal metacommands -------------- */ switch(r=exec_instr(&currop)) { case 0: /* Normal action token or successful conditional token */ if (DEBUG_AGT_CMD && !supress_debug) debug_newline(op,0); continue; case 1: /* Conditional token: fail */ if (DEBUG_AGT_CMD && !supress_debug) { if (orflag) debugout(" (-->FAIL)\n"); else debugout("--->FAIL\n"); } fail=1; continue; default: /* Return explicit value */ if (DEBUG_AGT_CMD && !supress_debug) { if (r==103) debugout("-->Redirect\n"); else debugout("==> END\n"); } return r-100; } } return 0; }
/* This routine sends a message from the current process to all of her * siblings and then waits to receive responses from them. A timer is * set so that if a message is lost or not received for some reason * we can exit gracefully. */ int notify(int slot) { extern int msgid; extern Pinfo *shmaddr; int i; int rc; int tslot; int *listp = (shmaddr + slot)->list; int cldcnt = 1; int ndx = 0; #ifdef __64LDT__ pid_t pid = 0; #else int pid = 0; #endif char mtext[80]; Msgbuf rcvbuf; for (i = 1, listp++; i < BVAL; i++, listp++) { sprintf(mtext, "%d %d %d", i, slot, (shmaddr + slot)->pid); rc = send_message(msgid, (mtyp_t) * listp, mtext); if (rc == -1) { severe ("notify: send_message Failed: %d msgid %d mtyp %d mtext %d\n", errno, msgid, *listp, mtext); exit(1); } } while (cldcnt < BVAL) { rc = msgrcv(msgid, &rcvbuf, sizeof(struct messagebuf), slot, 0); if (rc == -1) { switch (errno) { case EAGAIN: printf("msgqueue %d not ready to receive\n", msgid); fflush(stdout); errno = 0; break; case ENOMSG: printf("msgqueue %d no message\n", msgid); fflush(stdout); errno = 0; break; default: perror("msgrcv failed"); severe("msgrcv failed, errno: %d\n", errno); exit(1); } } else { sscanf(rcvbuf.mtext, "%d %d %d", &ndx, &tslot, &pid); if (*((shmaddr + tslot)->list + ndx) == slot && (shmaddr + tslot)->pid == pid) { debugout ("MSGRCV:slot: %d ndx: %d tslot: %d pid: %d\n", slot, ndx, tslot, pid); (shmaddr + slot)->msg++; cldcnt++; } else { (shmaddr + slot)->err--; debugout ("MSGRCV: slot: %d ndx: %d tslot: %d pid: %d\n", slot, ndx, tslot, pid); } } } return 0; }
//---------------------------------------------------------------------- // Write the scratchpad with CRC16 verification for DS1963S. The data // is padded until the offset is 0x1F so that the CRC16 is retrieved. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'address' - address to write data to // 'data' - data to write // 'data_len' - number of bytes of data to write // 'resume' - if true, device access is resumed using the RESUME // ROM command (0xA5). Otherwise, a a MATCH ROM is // used along with the device's entire address number. // // Return: TRUE - write to scratch verified // FALSE - error writing scratch, device not present, or HIDE // flag is in incorrect state for address being written. // SMALLINT WriteScratchpadSHA18(int portnum, int address, uchar *data, SMALLINT data_len, SMALLINT resume) { uchar send_block[50]; short send_cnt=0,i; ushort lastcrc16; if(!resume) { // access the device OWASSERT( SelectSHA(portnum), OWERROR_ACCESS_FAILED, FALSE ); } else { // transmit RESUME command send_block[send_cnt++] = ROM_CMD_RESUME; } setcrc16(portnum,0); // write scratchpad command send_block[send_cnt] = CMD_WRITE_SCRATCHPAD; lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // address 1 send_block[send_cnt] = (uchar)(address & 0xFF); lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // address 2 send_block[send_cnt] = (uchar)((address >> 8) & 0xFF); lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // data for (i = 0; i < data_len; i++) { send_block[send_cnt] = data[i]; lastcrc16 = docrc16(portnum,send_block[send_cnt++]); } // pad if needed for (i = 0; i < (0x1F - ((address + data_len - 1) & 0x1F)); i++) { send_block[send_cnt] = 0xFF; lastcrc16 = docrc16(portnum,send_block[send_cnt++]); } // CRC16 send_block[send_cnt++] = 0xFF; send_block[send_cnt++] = 0xFF; // now send the block OWASSERT( owBlock(portnum,resume,send_block,send_cnt), OWERROR_BLOCK_FAILED, FALSE ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // perform CRC16 of last 2 byte in packet for (i = send_cnt - 2; i < send_cnt; i++) lastcrc16 = docrc16(portnum,send_block[i]); // verify CRC16 is correct OWASSERT( lastcrc16==0xB001, OWERROR_CRC_FAILED, FALSE ); // success return TRUE; }