bool SlutTable::read_slut(SlutType type, bool force_reread)
{
    bool result = false;
    assert(readergp_ != NULL);
    if (readergp_ == NULL) return false;

    if(entries_ && this->type == type && !force_reread)
    {
        // we've read the s**t of this type and we're not being forced to do it again, so we're done.
        return true;
    }

    invalidate();
    this->type = type;

    struct SlutLocation
    {
        bool (SlutTable::* read_function)(GenericPointer, bool);
        GenericPointer gp;
    };


    static const size_t MAX_SLUT_POSSIBILITIES = 4;

    /* Define SlutLocation constants for the various candidate addresses of S***s */
    static const SlutLocation raw_prebc7 = { &SlutTable::read_slut_bc, GenericPointer(Mem_RawData, 0x100) };
    static const SlutLocation raw_bc7plus = { &SlutTable::read_slut_bc, GenericPointer(Mem_RawData, 0x80) };
    static const SlutLocation loader_prebc7 = { &SlutTable::read_slut_bc, GenericPointer(Mem_Flash, 0x100) };
    static const SlutLocation loader_bc7plus = { &SlutTable::read_slut_bc_loader, GenericPointer(Mem_Flash, 0x80) };
    static const SlutLocation stack_prebc7 = { &SlutTable::read_slut_bc, GenericPointer(Mem_Flash, 0x4100) };
    static const SlutLocation stack_bc7plus_monolithic = { &SlutTable::read_slut_bc_stack, GenericPointer(Mem_Flash, 0x80) };
    static const SlutLocation stack_bc7plus = { &SlutTable::read_slut_bc, GenericPointer(Mem_Flash, 0x4080) };

    size_t num_slut_possibilities = 0;
    const SlutLocation *slut_possibilities[MAX_SLUT_POSSIBILITIES];

    switch(type)
    {
    case SlutType_Raw:
        num_slut_possibilities = 2;
        slut_possibilities[0] = &raw_prebc7;
        slut_possibilities[1] = &raw_bc7plus;
        if(xap_helper_ && xap_helper_->IsReadyForUse())
        {
            switch(xap_helper_->GetChipFamily())
            {
            case CHIP_FAMILY_BLUECORE:
                num_slut_possibilities = 1;
                slut_possibilities[0] = xap_helper_->IsPreBc7() ? &raw_prebc7 : &raw_bc7plus;
                break;
            default:
            {
                break;
            }
            }
        }
        else
        {
        }
        break;
    case SlutType_FlashLoader:

        num_slut_possibilities = 2;
        slut_possibilities[0] = &loader_prebc7;
        slut_possibilities[1] = &loader_bc7plus;
        if(xap_helper_ && xap_helper_->IsReadyForUse())
        {
            if(xap_helper_->CanHaveLoader())
            {
                switch(xap_helper_->GetChipFamily())
                {
                case CHIP_FAMILY_BLUECORE:
                    num_slut_possibilities = 1;
                    slut_possibilities[0] = xap_helper_->IsPreBc7() ? &loader_prebc7 : &loader_bc7plus;
                    break;
                default:
                    // Not a chip type we recognise. Read the full set of s**t possibilities for this s**t type.
                    break;
                }
            }
            else
            {
                // this chip cannot contain a loader s**t.
                num_slut_possibilities = 0;
            }
        }
        break;
    case SlutType_FlashStack:
        num_slut_possibilities = 3;
        slut_possibilities[0] = &stack_prebc7;
        slut_possibilities[1] = &stack_bc7plus_monolithic;
        slut_possibilities[2] = &stack_bc7plus;
        if(xap_helper_ && xap_helper_->IsReadyForUse())
        {
            switch(xap_helper_->GetChipFamily())
            {
            case CHIP_FAMILY_BLUECORE:
                if (xap_helper_->IsPreBc7())
                {
                    num_slut_possibilities = 1;
                    slut_possibilities[0] = &stack_prebc7;
                }
                else
                {
                    if (xap_helper_->CanHaveLoader())
                    {
                        num_slut_possibilities = 2;
                        slut_possibilities[0] = &stack_bc7plus;
                        slut_possibilities[1] = &stack_bc7plus_monolithic;
                    }
                    else
                    {
                        num_slut_possibilities = 1;
                        slut_possibilities[0] = &stack_bc7plus_monolithic;
                    }
                }
                break;
            default:
                // Not a chip type we recognise. Read the full set of s**t possibilities for this s**t type.
                break;
            }
        }
        break;
    case SlutType_Rom:
        break;
    default:
        // a s**t type we don't recognise. in release mode don't read anything. in debug assert as this is probably an internal error.
        assert(false);
    }

    // go through the s**t possibilities and try to read them.
    for(size_t i = 0; i < num_slut_possibilities && !result; ++i)
    {
        // if this is the only s**t then retry because we expect it to be there.
        // if not then don't retry to go through the possibilities quicker.
#       define CALL_MEMBER_FN(fn) (this->*(fn))
        if (CALL_MEMBER_FN(slut_possibilities[i]->read_function)(slut_possibilities[i]->gp, num_slut_possibilities == 1))
        {
            result = true;
        }
    }
    return result;
}
Example #2
0
/*********************************************************
  NAME         : UpdateExpression
  DESCRIPTION  : Given a bloaded expression buffer,
                   this routine refreshes the pointers
                   in the expression array
  INPUTS       : 1) a bloaded expression buffer
                 2) the index of the expression to refresh
  RETURNS      : Nothing useful
  SIDE EFFECTS : Expression updated
  NOTES        : None
 *********************************************************/
static void UpdateExpression(
  Environment *theEnv,
  void *buf,
  unsigned long obji)
  {
   BSAVE_EXPRESSION *bexp;
   unsigned long theIndex;

   bexp = (BSAVE_EXPRESSION *) buf;
   ExpressionData(theEnv)->ExpressionArray[obji].type = bexp->type;
   switch(bexp->type)
     {
      case FCALL:
        ExpressionData(theEnv)->ExpressionArray[obji].value = BloadData(theEnv)->FunctionArray[bexp->value];
        break;

      case GCALL:
#if DEFGENERIC_CONSTRUCT
        ExpressionData(theEnv)->ExpressionArray[obji].value = GenericPointer(bexp->value);
#else
        ExpressionData(theEnv)->ExpressionArray[obji].value = NULL;
#endif
        break;

      case PCALL:
#if DEFFUNCTION_CONSTRUCT
        ExpressionData(theEnv)->ExpressionArray[obji].value = DeffunctionPointer(bexp->value);
#else
        ExpressionData(theEnv)->ExpressionArray[obji].value = NULL;
#endif
        break;

      case DEFTEMPLATE_PTR:
#if DEFTEMPLATE_CONSTRUCT
        ExpressionData(theEnv)->ExpressionArray[obji].value = DeftemplatePointer(bexp->value);
#else
        ExpressionData(theEnv)->ExpressionArray[obji].value = NULL;
#endif
        break;

     case DEFCLASS_PTR:
#if OBJECT_SYSTEM
        ExpressionData(theEnv)->ExpressionArray[obji].value = DefclassPointer(bexp->value);
#else
        ExpressionData(theEnv)->ExpressionArray[obji].value = NULL;
#endif
        break;

      case DEFGLOBAL_PTR:

#if DEFGLOBAL_CONSTRUCT
        ExpressionData(theEnv)->ExpressionArray[obji].value = DefglobalPointer(bexp->value);
#else
        ExpressionData(theEnv)->ExpressionArray[obji].value = NULL;
#endif
        break;


      case INTEGER_TYPE:
        ExpressionData(theEnv)->ExpressionArray[obji].value = SymbolData(theEnv)->IntegerArray[bexp->value];
        IncrementIntegerCount(ExpressionData(theEnv)->ExpressionArray[obji].integerValue);
        break;

      case FLOAT_TYPE:
        ExpressionData(theEnv)->ExpressionArray[obji].value = SymbolData(theEnv)->FloatArray[bexp->value];
        IncrementFloatCount(ExpressionData(theEnv)->ExpressionArray[obji].floatValue);
        break;

      case INSTANCE_NAME_TYPE:
#if ! OBJECT_SYSTEM
        ExpressionData(theEnv)->ExpressionArray[obji].type = SYMBOL_TYPE;
#endif
      case GBL_VARIABLE:
      case SYMBOL_TYPE:
      case STRING_TYPE:
        ExpressionData(theEnv)->ExpressionArray[obji].value = SymbolData(theEnv)->SymbolArray[bexp->value];
        IncrementLexemeCount(ExpressionData(theEnv)->ExpressionArray[obji].lexemeValue);
        break;

#if DEFTEMPLATE_CONSTRUCT
      case FACT_ADDRESS_TYPE:
        ExpressionData(theEnv)->ExpressionArray[obji].value = &FactData(theEnv)->DummyFact;
        RetainFact((Fact *) ExpressionData(theEnv)->ExpressionArray[obji].value);
        break;
#endif

#if OBJECT_SYSTEM
      case INSTANCE_ADDRESS_TYPE:
        ExpressionData(theEnv)->ExpressionArray[obji].value = &InstanceData(theEnv)->DummyInstance;
        RetainInstance((Instance *) ExpressionData(theEnv)->ExpressionArray[obji].value);
        break;
#endif

      case EXTERNAL_ADDRESS_TYPE:
        ExpressionData(theEnv)->ExpressionArray[obji].value = NULL;
        break;

      case VOID_TYPE:
        break;

      default:
        if (EvaluationData(theEnv)->PrimitivesArray[bexp->type] == NULL) break;
        if (EvaluationData(theEnv)->PrimitivesArray[bexp->type]->bitMap)
          {
           ExpressionData(theEnv)->ExpressionArray[obji].value = SymbolData(theEnv)->BitMapArray[bexp->value];
           IncrementBitMapCount((CLIPSBitMap *) ExpressionData(theEnv)->ExpressionArray[obji].value);
          }
        break;
     }

   theIndex = bexp->nextArg;
   if (theIndex == ULONG_MAX)
     { ExpressionData(theEnv)->ExpressionArray[obji].nextArg = NULL; }
   else
     { ExpressionData(theEnv)->ExpressionArray[obji].nextArg = (struct expr *) &ExpressionData(theEnv)->ExpressionArray[theIndex]; }

   theIndex = bexp->argList;
   if (theIndex == ULONG_MAX)
     { ExpressionData(theEnv)->ExpressionArray[obji].argList = NULL; }
   else
     { ExpressionData(theEnv)->ExpressionArray[obji].argList = (struct expr *) &ExpressionData(theEnv)->ExpressionArray[theIndex]; }
  }
bool SlutTable::read_slut_bc(GenericPointer slut_location, bool retry)
{
    GenericPointer slut_ptr;
    uint16 data_buf[IMemoryReaderGP::MAX_BLOCK_SIZE];
    uint32 location;
    uint16 slut_key;
    uint16 slut_val;
    bool stack = false;

    if(!read_slut_header(slut_location, data_buf, retry))
    {
        return false;
    }

    // If we don't find the magic value then give up.
    if (data_buf[0] != SLUT_MAGIC)
        return false;

    // Check if we're looking in the stack.
    if (slut_location.Mem() == Mem_Flash && (int)slut_location >= 0x4000)
        stack = true;

    // If we're looking in the stack part of flash then offset the
    // 16-bit location so that it is also in the stack.
    location = data_buf[1];
    if (stack) location += 0x4000;

    // Create a pointer to the actual S**T.
    slut_ptr = slut_location = GenericPointer(slut_location.Mem(), location);

    unifiSlut = false;
    entries_ = new Entries;
    assert(entries_);

    do
    {
        if (!readergp_->read_mem(slut_ptr, IMemoryReaderGP::MAX_BLOCK_SIZE, data_buf))
        {
            invalidate();
            return false;
        }
        int i;
        for (i = 0; i < IMemoryReaderGP::MAX_BLOCK_SIZE; i+= 2)
        {
            slut_key = data_buf[i];
            slut_val = data_buf[i + 1];

            // If the value is a pointer add an offset.
            if (slut_key == bluecore::SLUTID_ID_STRING ||
                    slut_key == bluecore::SLUTID_ID_INTEGER ||
                    slut_key == bluecore::SLUTID_ID_STRING_FULL)
            {
                if (stack) slut_val += 0x4000;
            }

            if (slut_key == bluecore::SLUTID_NONE)
                break;
            entries_->add(slut_key, slut_val);
        }
        slut_ptr += i;
    } while ((slut_key != bluecore::SLUTID_NONE) && ((int)slut_ptr - (int)slut_location < 256));
    return true;
}