// 15 modify here========<modify
void SBFAST_Log_Blocks::partialMergeForSEQ (long newestBlockWithSameDataLBNInSEQ, vector<long> blocksWithSameDataLBNInSEQ)
{
    //cout<<"Partial Merge For SEQ Log, Erase = 1 For Data."<<endl;
    eraseBlock(newestBlockWithSameDataLBNInSEQ); // We do "Log erase", but in fact we are going to erase "data log"
    PM_SBFAST++;
    updateVictimLBN();
}
Exemple #2
0
void Core99NVRAM::sync(void)
{
  Core99NVRAMHeader *header;
  unsigned char     *tmpBuffer;
  
  // Don't write the BootROM if nothing has changed.
  if (!bcmp(nvramShadow, nvramCurrent, kCore99NVRAMSize)) return;
  
  header = (Core99NVRAMHeader *)nvramShadow;
  
  header->generation = ++generation;
  
  header->checksum = chrpCheckSum(nvramShadow);
  
  header->adler32 = adler32(nvramShadow + kCore99NVRAMAdlerStart,
			    kCore99NVRAMAdlerSize);
  
  if (eraseBlock() != kIOReturnSuccess) return;
  
  if (writeBlock(nvramShadow) != kIOReturnSuccess) return;
  
  tmpBuffer = (unsigned char *)nvramCurrent;
  nvramCurrent = nvramNext;
  nvramNext = tmpBuffer;
}
/**
 * Free a memory block in an expanded heap
 */
void
MEMFreeToExpHeap(ExpandedHeap *heap, void *block)
{
   ScopedSpinLock lock(&heap->lock);
   auto base = mem::untranslate(block);

   if (!base) {
      return;
   }

   if (base < heap->bottom || base >= heap->top) {
      gLog->warn("FreeToExpHeap outside heap region; {:08x} not within {:08x}-{:08x}", base, heap->bottom, heap->top);
      return;
   }

   // Get the block header
   base = base - static_cast<uint32_t>(sizeof(ExpandedHeapBlock));

   // Remove used blocked
   auto usedBlock = make_virtual_ptr<ExpandedHeapBlock>(base);
   auto addr = usedBlock->addr;
   auto size = usedBlock->size;
   eraseBlock(heap->usedBlockList, usedBlock);

   // Create free block
   auto freeBlock = make_virtual_ptr<ExpandedHeapBlock>(addr);
   freeBlock->addr = addr;
   freeBlock->size = size;
   insertBlock(heap->freeBlockList, freeBlock);

   // Merge with next free if contiguous
   auto nextFree = freeBlock->next;

   if (nextFree && nextFree->addr == freeBlock->addr + freeBlock->size) {
      freeBlock->size += nextFree->size;
      eraseBlock(heap->freeBlockList, nextFree);
   }

   // Merge with previous free if contiguous
   auto prevFree = freeBlock->prev;

   if (prevFree && freeBlock->addr == prevFree->addr + prevFree->size) {
      prevFree->size += freeBlock->size;
      eraseBlock(heap->freeBlockList, freeBlock);
   }
}
Exemple #4
0
void
MEMFreeToExpHeap(ExpandedHeap *heap, void *address)
{
   ScopedSpinLock lock(&heap->lock);
   auto base = gMemory.untranslate(address);

   if (!base) {
      return;
   }

   // Get the block header
   base = base - static_cast<uint32_t>(sizeof(ExpandedHeapBlock));

   // Remove used blocked
   auto usedBlock = make_p32<ExpandedHeapBlock>(base);
   auto addr = usedBlock->addr;
   auto size = usedBlock->size;
   eraseBlock(heap->usedBlockList, usedBlock);

   // Create free block
   auto freeBlock = make_p32<ExpandedHeapBlock>(addr);
   freeBlock->addr = addr;
   freeBlock->size = size;
   insertBlock(heap->freeBlockList, freeBlock);

   // Merge with next free if contiguous
   auto nextFree = freeBlock->next;

   if (nextFree && nextFree->addr == freeBlock->addr + freeBlock->size) {
      freeBlock->size += nextFree->size;
      eraseBlock(heap->freeBlockList, nextFree);
   }

   // Merge with previous free if contiguous
   auto prevFree = freeBlock->prev;

   if (prevFree && freeBlock->addr == prevFree->addr + prevFree->size) {
      prevFree->size += freeBlock->size;
      eraseBlock(heap->freeBlockList, freeBlock);
   }
}
// 17
void SBFAST_Log_Blocks::fullMergeForRND(long victimLBN, long pageValue)
{
    // Calculate the number of associated blocks
    long inputPageNeedToBeMerge=0;
    long Associated_Blocks_Num=0;
    set<long> Associated_Blocks;
    for (long i=0; i<_Pages_Per_Block; i++)
    {
        if((_Log_Blocks[victimLBN][i]!=FREE)&&(_Log_Blocks[victimLBN][i]!=INVALID))
        {
            Associated_Blocks.insert(_Log_Blocks[victimLBN][i]/_Pages_Per_Block);
        }
        if (_Log_Blocks[victimLBN][i]==pageValue)
        {
            inputPageNeedToBeMerge=1;
        }
    }
    Associated_Blocks_Num=(long)Associated_Blocks.size();
    

    
    
    // markInvalidToSameAddressPages
    for (long i=0; i<_Pages_Per_Block; i++)
    {
        if((_Log_Blocks[victimLBN][i]!=FREE)&&(_Log_Blocks[victimLBN][i]!=INVALID))
        {
            markInvalidToSameAddressPages(_Log_Blocks[victimLBN][i]);
        }
    }
    
    
    
    
    // eraseCount
    //cout<<"Before, the eraseCount is "<<Erase_SBFAST<<endl;
    Erase_SBFAST=Erase_SBFAST+Associated_Blocks_Num; //data erase
    //cout<<"We have "<<Associated_Blocks_Num<<" associated blocks, and we need to do "<<Associated_Blocks_Num<<"(Data blocks)+1(Log block) erases."<<endl;
    //cout<<"We are erasing "<<Associated_Blocks_Num<<" log blocks now."<<endl;

    FMinRLB_SBFAST+=Associated_Blocks_Num;
    //cout<<"We erase the 1 log block now."<<endl;
    eraseBlock(victimLBN);
    //cout<<"fullMergeForRND calls updateVictim()."<<endl;
    updateVictimLBN();
    
    // Append the input page to the new block if it is not in the erased victim block
    if (inputPageNeedToBeMerge!=1)
    {
        writePage(victimLBN, 0, pageValue);
        //_Log_Blocks[victimLBN][0]=pageValue;
    }
}
Exemple #6
0
// L'immagine del firmware dell'A3818 � di circa 1716 KB
int eraseFirmware(uint32_t handle, uint32_t baseAddress, uint32_t fwcopy) {
	int i;

	if (fwcopy == 0) {
		// Cancella i primi 4 blocchi da 32KB = 128KB
		for (i = 0; i < 4; i++) {
			eraseBlock(handle, baseAddress + (i * (16 * 1024)));
#ifdef PRINT_POINTS

			printf(".");
			fflush(stdout);
#endif             
		}
		// Cancella 13 blocchi da 128KB
		for (i = 4; i < 18; i++) {
			eraseBlock(handle, baseAddress + ((i - 3) * (64 * 1024)));
#ifdef PRINT_POINTS             
			printf(".");
			fflush(stdout);
#endif             
		}
	} else {
		// Cancella 15 blocchi da 128KB = cancella 15*128K = 1920KB
		for (i = 0; i < 14; i++) {
			eraseBlock(handle, baseAddress + (i * (64 * 1024)));
#ifdef PRINT_POINTS             
			printf(".");
			fflush(stdout);
#endif             
		}
	}

	// Ritorna in modalit� Read Array Mode
	bpi_flash_write(handle, 0x0, P30_READ_ARRAY);
	return 0;
}
/**
 * Trim free blocks from the end of the expanded heap.
 *
 * Reduces the size of the heap memory region to the end of the last allocated block.
 * Returns the new size of the heap.
 */
uint32_t
MEMAdjustExpHeap(ExpandedHeap *heap)
{
   ScopedSpinLock lock(&heap->lock);

   // Find the last free block
   auto lastFree = getTail(heap->freeBlockList);

   if (!lastFree) {
      return heap->size;
   }

   // Erase the last free block
   heap->size -= lastFree->size;
   eraseBlock(heap->freeBlockList, lastFree);

   return heap->size;
}
Exemple #8
0
int main()
{
    int fbfd = 0;
    struct fb_var_screeninfo vinfo;
    struct fb_fix_screeninfo finfo;
    long int screensize = 0;
    char *fbp = 0;
    int x = 0, y = 0;
    long int location = 0;

    #define background_red 235
    #define background_green 138
    #define background_blue 163

    void makeBackground(){
        for (y = 0; y < 236; y++)//maks 236
            for (x = 0; x < 800; x++) {//maks 800

                location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
                           (y+vinfo.yoffset) * finfo.line_length;

                if (vinfo.bits_per_pixel == 32) { // color information
                    *(fbp + location) = background_blue;        // blue
                    *(fbp + location + 1) = background_green;     // green
                    *(fbp + location + 2) = background_red;    // red
                    *(fbp + location + 3) = 0;      // No transparency
                } else { 
                    printf("can't write\n");
                }
            }
    }

    void drawBlock(int absis, int ordinat, int red, int green, int blue){
        for (y = ordinat; y < ordinat+10; y++)//maks 236
            for (x = absis; x < ordinat+10; x++) {//maks 800

                location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
                           (y+vinfo.yoffset) * finfo.line_length;

                if (vinfo.bits_per_pixel == 32) { // color information
                    *(fbp + location) = blue;        // blue
                    *(fbp + location + 1) = green;     // green
                    *(fbp + location + 2) = red;    // red
                    *(fbp + location + 3) = 0;      // No transparency
                } else  { 
                printf("can't write\n");
                }
            }
    }
    void eraseBlock(int absis, int ordinat){
        for (y = ordinat; y < ordinat+10; y++)//maks 236
            for (x = absis; x < ordinat+10; x++) {//maks 800

                location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
                           (y+vinfo.yoffset) * finfo.line_length;

                if (vinfo.bits_per_pixel == 32) { // color information
                    *(fbp + location) = background_blue;        // blue
                    *(fbp + location + 1) = background_green;     // green
                    *(fbp + location + 2) = background_red;    // red
                    *(fbp + location + 3) = 0;      // No transparency
                } else { 
                    printf("can't write\n");
                }
            }
    }

    void fly(int red, int green, int blue){
        for(int i = 0; i<10; i++){
            drawBlock(10*i,10*i,red,green,blue);
            printf("Heiho\n");
            sleep(1000);
            eraseBlock(10*i,10*i);
        }
    }
    

    // Open the file for reading and writing
    fbfd = open("/dev/fb0", O_RDWR);
    if (fbfd == -1) {
        perror("Error: cannot open framebuffer device");
        exit(1);
    }
    printf("The framebuffer device was opened successfully.\n");

    // Get fixed screen information
    if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) {
        perror("Error reading fixed information");
        exit(2);
    }

    // Get variable screen information
    if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
        perror("Error reading variable information");
        exit(3);
    }

    printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);

    // Figure out the size of the screen in bytes
    screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
    printf("Screensize: %d", screensize);

    // Map the device to memory
    fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
    if ((int)fbp == -1) {
        perror("Error: failed to map framebuffer device to memory");
        exit(4);
    }
    printf("The framebuffer device was mapped to memory successfully.\n");

    makeBackground(0, 200, 255);
    drawBlock(0, 0, 200, 100, 0);
    fly(200,100,0);
    munmap(fbp, screensize);
    close(fbfd);
    return 0;
}
Exemple #9
0
int main(int argc, const char **argv)
{

	MemServerRequestProxy *hostMemServerRequest = new MemServerRequestProxy(IfcNames_HostMemServerRequest);
	MMURequestProxy *dmap = new MMURequestProxy(IfcNames_HostMMURequest);
	DmaManager *dma = new DmaManager(dmap);
	MemServerIndication *hostMemServerIndication = new MemServerIndication(hostMemServerRequest, IfcNames_HostMemServerIndication);
	MMUIndication *hostMMUIndication = new MMUIndication(dma, IfcNames_HostMMUIndication);

	fprintf(stderr, "Main::allocating memory...\n");

	device = new FlashRequestProxy(IfcNames_FlashRequest);
	FlashIndication *deviceIndication = new FlashIndication(IfcNames_FlashIndication);
	
	srcAlloc = portalAlloc(srcAlloc_sz);
	dstAlloc = portalAlloc(dstAlloc_sz);
	srcBuffer = (unsigned int *)portalMmap(srcAlloc, srcAlloc_sz);
	dstBuffer = (unsigned int *)portalMmap(dstAlloc, dstAlloc_sz);

	fprintf(stderr, "dstAlloc = %x\n", dstAlloc); 
	fprintf(stderr, "srcAlloc = %x\n", srcAlloc); 
	
	pthread_mutex_init(&flashReqMutex, NULL);
	pthread_cond_init(&flashFreeTagCond, NULL);

	printf( "Done initializing hw interfaces\n" ); fflush(stdout);

	portalExec_start();
	printf( "Done portalExec_start\n" ); fflush(stdout);

	portalDCacheFlushInval(dstAlloc, dstAlloc_sz, dstBuffer);
	portalDCacheFlushInval(srcAlloc, srcAlloc_sz, srcBuffer);
	ref_dstAlloc = dma->reference(dstAlloc);
	ref_srcAlloc = dma->reference(srcAlloc);

	for (int t = 0; t < NUM_TAGS; t++) {
		readTagTable[t].busy = false;
		writeTagTable[t].busy = false;
		int byteOffset = t * PAGE_SIZE;
		device->addDmaWriteRefs(ref_dstAlloc, byteOffset, t);
		device->addDmaReadRefs(ref_srcAlloc, byteOffset, t);
		readBuffers[t] = dstBuffer + byteOffset/sizeof(unsigned int);
		writeBuffers[t] = srcBuffer + byteOffset/sizeof(unsigned int);
	}
	
	for (int blk=0; blk<BLOCKS_PER_CHIP; blk++) {
		for (int c=0; c<CHIPS_PER_BUS; c++) {
			for (int bus=0; bus< CHIPS_PER_BUS; bus++) {
				flashStatus[bus][c][blk] = UNINIT;
			}
		}
	}


	for (int t = 0; t < NUM_TAGS; t++) {
		for ( int i = 0; i < PAGE_SIZE/sizeof(unsigned int); i++ ) {
			readBuffers[t][i] = 0;
			writeBuffers[t][i] = 0;
		}
	}

	device->start(0);
	device->setDebugVals(0,0); //flag, delay

	device->debugDumpReq(0);
	sleep(1);
	device->debugDumpReq(0);
	sleep(1);
	//TODO: test writes and erases
	

	
	//test erases
	for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
		for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
			for (int bus = 0; bus < NUM_BUSES; bus++){
				eraseBlock(bus, chip, blk, waitIdleEraseTag());
			}
		}
	}

	while (true) {
		usleep(100);
		if ( getNumErasesInFlight() == 0 ) break;
	}
	
	
	//read back erased pages
	for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
		for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
			for (int bus = 0; bus < NUM_BUSES; bus++){
				int page = 0;
				readPage(bus, chip, blk, page, waitIdleReadBuffer());
			}
		}
	}
	while (true) {
		usleep(100);
		if ( getNumReadsInFlight() == 0 ) break;
	}


	//write pages
	//FIXME: in old xbsv, simulatneous DMA reads using multiple readers cause kernel panic
	//Issue each bus separately for now
	for (int bus = 0; bus < NUM_BUSES; bus++){
	
		for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
			for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
				int page = 0;
				//get free tag
				int freeTag = waitIdleWriteBuffer();
				//fill write memory
				for (int w=0; w<PAGE_SIZE/sizeof(unsigned int); w++) {
					writeBuffers[freeTag][w] = hashAddrToData(bus, chip, blk, w);
				}
				//send request
				writePage(bus, chip, blk, page, freeTag);
			}
			while (true) {
				usleep(100);
				if ( getNumWritesInFlight() == 0 ) break;
			}
		}
		
		
	} //each bus
	

	timespec start, now;
	clock_gettime(CLOCK_REALTIME, & start);

	for (int repeat = 0; repeat < 1; repeat++){
		for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
			for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
				for (int bus = 0; bus < NUM_BUSES; bus++){

				//int blk = rand() % 1024;
				//int chip = rand() % 8;
				//int bus = rand() % 8;
					int page = 0;
					readPage(bus, chip, blk, page, waitIdleReadBuffer());
				}
			}
		}
	}
	
	int elapsed = 0;
	while (true) {
		usleep(100);
		if (elapsed == 0) {
			elapsed=10000;
			device->debugDumpReq(0);
		}
		else {
			elapsed--;
		}
		if ( getNumReadsInFlight() == 0 ) break;
	}
	device->debugDumpReq(0);

	clock_gettime(CLOCK_REALTIME, & now);
	fprintf(stderr, "LOG: finished reading from page! %f\n", timespec_diff_sec(start, now) );

	for ( int t = 0; t < NUM_TAGS; t++ ) {
		for ( int i = 0; i < PAGE_SIZE/sizeof(unsigned int); i++ ) {
			fprintf(stderr,  "%x %x %x\n", t, i, readBuffers[t][i] );
		}
	}
	if (testPass==1) {
		fprintf(stderr, "LOG: TEST PASSED!\n");
	}
	else {
		fprintf(stderr, "LOG: **ERROR: TEST FAILED!\n");
	}


}
int makeMemoryFile(char *name, unsigned int address, unsigned int length, char accessType, securityIdType securityID ) {

int i;
unsigned int catalogBlock;
struct { 
	unsigned int address;
	unsigned int size;
	char accessType;

	} *memoryFileInfo;

	// if no filename give, return error
	if ( name == 0 ) {

		return ERROR_BAD_VALUE;

	}

	// if the root directory is invalid, return error
	if ( rootDir == 0 ) {

		return ERROR_INIT;

	}

	// if the file already exists, return error
	if ( statusFile(name, 0) == 0 ) {

		return ERROR_FILE_EXISTS;

	}


	// find the first empty directory entry
	for ( i = 0; i < rootDir->maxEntries; ++i ) {

		if ( rootDir->entry[i].name[0] == 0) {

			strncpy(rootDir->entry[i].name, name, MAX_FILENAME_LEN);
			rootDir->entry[i].fileSize = length;
			rootDir->entry[i].fileType = 0x3 + accessType;
			rootDir->entry[i].securityID = securityID;
			rootDir->entry[i].othersPermissions = 0;

			// now allocate a block for its first catalog block

			if (findFreeBlock(&catalogBlock) == 0 ) {

				eraseBlock(catalogBlock);

				setBlockInUse(catalogBlock);

				rootDir->entry[i].firstCatalogBlock = catalogBlock;

			}
			else {

				return ERROR_NO_BLOCKS;
			
			}

			rootDir->numEntries++;

			readBlock(catalogBlock, (void **)&memoryFileInfo);

			memoryFileInfo->address = address;
			memoryFileInfo->size = length;
			memoryFileInfo->accessType = accessType;

			writeBlock(memoryFileInfo, catalogBlock);

			return NO_ERROR;

		} // if strcmp

	}  // for

	return ERROR_MAX_EXCEEDED;

}
Exemple #11
0
//---------------------------------------------
//Local erase, read, write, read test
//---------------------------------------------
void local_test(bool check, int read_repeat, int debug_lvl ) {
	LOG(0, "LOG: starting local_test...\n");
	g_checkdata = check;
	g_debuglevel = debug_lvl;
	g_testpass = true;
	int node = myid;

	timespec start, now;
	double timeElapsed = 0; 
	double bw = 0;
	//erase all blocks
	for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
		for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
			for (int bus = 0; bus < NUM_BUSES; bus++){
				eraseBlock(node, bus, chip, blk, waitIdleEraseTag());
			}
		}
	}

	while (true) {
		if ( getNumErasesInFlight() == 0 ) break;
	}

	//read back erased pages
	for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
		for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
			for (int bus = 0; bus < NUM_BUSES; bus++){
				int page = 0;
				readPage(node, bus, chip, blk, page, waitIdleReadBuffer());
			}
		}
	}

	while (true) {
		if ( getNumReadsInFlight() == 0 ) break;
	}


	int pagesWritten = 0;
	clock_gettime(CLOCK_REALTIME, & start);
	//write pages
	for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
		for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
			for (int bus = 0; bus < NUM_BUSES; bus++){
				int page = 0;
				int freeTag = waitIdleWriteBuffer();
				if (g_checkdata) {
					//fill write memory only if we're doing readback checks
					for (int w=0; w<PAGE_SIZE/sizeof(unsigned int); w++) {
						writeBuffers[freeTag][w] = hashAddrToData(node, bus, chip, blk, w);
					}
				}
				//send request
				writePage(node, bus, chip, blk, page, freeTag); 
				pagesWritten++;
			}
		}
	}
	while (true) {
		if ( getNumWritesInFlight() == 0 ) break;
	}
	clock_gettime(CLOCK_REALTIME, & now);
	timeElapsed = timespec_diff_sec(start, now);
	bw = (pagesWritten*8)/timeElapsed/1024; //MB/s
	//double latency = timeElapsed/pagesWritten;
	//double latency_us = latency*1000000;
	LOG(0, "LOG: finished writing to page. Time=%f, NumPages=%d, BW=%f MB/s\n", 
							timeElapsed, pagesWritten, bw);


	int pagesRead = 0;
	clock_gettime(CLOCK_REALTIME, & start);
	for (int rep = 0; rep < read_repeat; rep++) {
		for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
			for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
				for (int bus = 0; bus < NUM_BUSES; bus++){
					int page = 0;
					readPage(node, bus, chip, blk, page, waitIdleReadBuffer());
					pagesRead++;
				}
			}
		}
	}
	while (true) {
		if ( getNumReadsInFlight() == 0 ) break;
	}
	clock_gettime(CLOCK_REALTIME, & now);
	timeElapsed = timespec_diff_sec(start, now);
	bw = (pagesRead*8)/timeElapsed/1024; //MB/s

	LOG(0, "LOG: reading from page. Time=%f, NumPages=%d, BW=%f MB/s\n", 
							timeElapsed, pagesRead, bw);

	device->debugDumpReq(0);
	sleep(1);

	for ( int t = 0; t < NUM_TAGS; t++ ) {
		for ( int i = 0; i < PAGE_SIZE/sizeof(unsigned int); i++ ) {
			LOG(1, "%x %x %x\n", t, i, readBuffers[t][i] );
		}
	}

	if (g_checkdata) {
		if (g_testpass) {
			LOG(0, "LOG: local_test passed!\n");
		}
		else {
			LOG(0, "LOG: **ERROR: local_test FAILED!\n");
		}
	} else {
			LOG(0, "LOG: local_test complete. No checks done\n");
	}
}
/**
 * Resize an allocated memory block.
 */
uint32_t
MEMResizeForMBlockExpHeap(ExpandedHeap *heap, uint8_t *mblock, uint32_t size)
{
   ScopedSpinLock lock(&heap->lock);

   // Get the block header
   auto address = mem::untranslate(mblock);
   auto base = address - static_cast<uint32_t>(sizeof(ExpandedHeapBlock));

   auto block = make_virtual_ptr<ExpandedHeapBlock>(base);
   auto nextAddr = block->addr + block->size;

   auto freeBlock = findBlock(heap->freeBlockList, nextAddr);
   auto freeBlockSize = 0u;

   auto dataSize = (block->addr + block->size) - address;
   auto difSize = static_cast<int32_t>(size) - static_cast<int32_t>(dataSize);
   auto newSize = block->size + difSize;

   if (difSize == 0) {
      // No difference, return current size
      return size;
   } else if (difSize > 0) {
      if (!freeBlock) {
         // No free block to expand into, return fail
         return 0;
      } else if (freeBlock->size < static_cast<uint32_t>(difSize)) {
         // Free block is too small, return fail
         return 0;
      } else {
         if (freeBlock->size - difSize < sMinimumBlockSize) {
            // The free block will be smaller than minimum size, so just absorb it completely
            freeBlockSize = 0;
            newSize = freeBlock->size;
         } else {
            // Free block is large enough, we just reduce its size
            freeBlockSize = freeBlock->size - difSize;
         }
      }
   } else if (difSize < 0) {
      if (freeBlock) {
         // Increase size of free block
         freeBlockSize = freeBlock->size - difSize;
      } else if (difSize < sMinimumBlockSize) {
         // We can't fit a new free block in the gap, so return current size
         return block->size;
      } else {
         // Create a new free block in the gap
         freeBlockSize = -difSize;
      }
   }

   // Update free block
   if (freeBlockSize) {
      auto old = freeBlock;
      freeBlock = make_virtual_ptr<ExpandedHeapBlock>(block->addr + newSize);
      freeBlock->addr = block->addr + newSize;
      freeBlock->size = freeBlockSize;
      replaceBlock(heap->freeBlockList, old, freeBlock);
   } else {
      // We have totally consumed the free block
      eraseBlock(heap->freeBlockList, freeBlock);
   }

   // Resize block
   block->size = newSize;
   return size;
}
/**
 * Allocate aligned memory from an expanded heap
 *
 * Sets the memory block group ID to the current active group ID.
 * If alignment is negative the memory is allocated from the top of the heap.
 * If alignment is positive the memory is allocated from the bottom of the heap.
 */
void *
MEMAllocFromExpHeapEx(ExpandedHeap *heap, uint32_t size, int alignment)
{
   ScopedSpinLock lock(&heap->lock);
   virtual_ptr<ExpandedHeapBlock> freeBlock, usedBlock;
   auto direction = MEMExpHeapDirection::FromBottom;
   uint32_t base;

   if (alignment < 0) {
      alignment = -alignment;
      direction = MEMExpHeapDirection::FromTop;
   }

   // Add size for block header and alignment
   uint32_t originalSize = size;
   size += sizeof(ExpandedHeapBlock);
   size += alignment;

   if (heap->mode == MEMExpHeapMode::FirstFree) {
      if (direction == MEMExpHeapDirection::FromBottom) {
         // Find first block large enough from bottom of heap
         for (auto block = heap->freeBlockList; block; block = block->next) {
            if (block->size < size) {
               continue;
            }

            freeBlock = block;
            break;
         }
      } else {  // direction == MEMExpHeapDirection::FromTop
         // Find first block large enough from top of heap
         for (auto block = getTail(heap->freeBlockList); block; block = block->prev) {
            if (block->size < size) {
               continue;
            }

            freeBlock = block;
            break;
         }
      }
   } else if (heap->mode == MEMExpHeapMode::NearestSize) {
      uint32_t nearestSize = -1;

      if (direction == MEMExpHeapDirection::FromBottom) {
         // Find block nearest in size from bottom of heap
         for (auto block = heap->freeBlockList; block; block = block->next) {
            if (block->size < size) {
               continue;
            }

            if (block->size - size < nearestSize) {
               nearestSize = block->size - size;
               freeBlock = block;
            }
         }
      } else {  // direction == MEMExpHeapDirection::FromTop
         // Find block nearest in size from top of heap
         for (auto block = getTail(heap->freeBlockList); block; block = block->prev) {
            if (block->size < size) {
               continue;
            }

            if (block->size - size < nearestSize) {
               nearestSize = block->size - size;
               freeBlock = block;
            }
         }
      }
   }

   if (!freeBlock) {
      gLog->error("MEMAllocFromExpHeapEx failed, no free block found for size {:08x} ({:08x}+{:x}+{:x})", size, originalSize, sizeof(ExpandedHeapBlock), alignment);
      MEMiDumpExpHeap(heap);
      return nullptr;
   }

   if (direction == MEMExpHeapDirection::FromBottom) {
      // Reduce freeblock size
      base = freeBlock->addr;
      freeBlock->size -= size;

      if (freeBlock->size < sMinimumBlockSize) {
         // Absorb free block as it is too small
         size += freeBlock->size;
         eraseBlock(heap->freeBlockList, freeBlock);
      } else {
         auto freeSize = freeBlock->size;

         // Replace free block
         auto old = freeBlock;
         freeBlock = make_virtual_ptr<ExpandedHeapBlock>(base + size);
         freeBlock->addr = base + size;
         freeBlock->size = freeSize;
         replaceBlock(heap->freeBlockList, old, freeBlock);
      }
   } else {  // direction == MEMExpHeapDirection::FromTop
      // Reduce freeblock size
      freeBlock->size -= size;
      base = freeBlock->addr + freeBlock->size;

      if (freeBlock->size < sMinimumBlockSize) {
         // Absorb free block as it is too small
         size += freeBlock->size;
         eraseBlock(heap->freeBlockList, freeBlock);
      }
   }

   // Create a new used block
   auto aligned = align_up(base + static_cast<uint32_t>(sizeof(ExpandedHeapBlock)), alignment);
   usedBlock = make_virtual_ptr<ExpandedHeapBlock>(aligned - static_cast<uint32_t>(sizeof(ExpandedHeapBlock)));
   usedBlock->addr = base;
   usedBlock->size = size;
   usedBlock->group = heap->group;
   usedBlock->direction = direction;
   insertBlock(heap->usedBlockList, usedBlock);
   return make_virtual_ptr<void>(aligned);
}
Exemple #14
0
int main(int argc, const char **argv)
{
	testPassed=true;

	fprintf(stderr, "Initializing Connectal & DMA...\n");

	device = new FlashRequestProxy(IfcNames_FlashRequestS2H);
	FlashIndication deviceIndication(IfcNames_FlashIndicationH2S);
    DmaManager *dma = platformInit();

	fprintf(stderr, "Main::allocating memory...\n");
	
	// Memory for DMA
	srcAlloc = portalAlloc(srcAlloc_sz, 0);
	dstAlloc = portalAlloc(dstAlloc_sz, 0);
	srcBuffer = (unsigned int *)portalMmap(srcAlloc, srcAlloc_sz); // Host->Flash Write
	dstBuffer = (unsigned int *)portalMmap(dstAlloc, dstAlloc_sz); // Flash->Host Read

	// Memory for FTL
	blkmapAlloc = portalAlloc(blkmapAlloc_sz * 2, 0);
	char *ftlPtr = (char*)portalMmap(blkmapAlloc, blkmapAlloc_sz * 2);
	blkmap      = (uint16_t(*)[NUM_LOGBLKS]) (ftlPtr);  // blkmap[Seg#][LogBlk#]
	blkmgr      = (uint16_t(*)[NUM_CHIPS][NUM_BLOCKS])  (ftlPtr+blkmapAlloc_sz); // blkmgr[Bus][Chip][Block]

	fprintf(stderr, "dstAlloc = %x\n", dstAlloc); 
	fprintf(stderr, "srcAlloc = %x\n", srcAlloc); 
	fprintf(stderr, "blkmapAlloc = %x\n", blkmapAlloc); 
	
	pthread_mutex_init(&flashReqMutex, NULL);
	pthread_cond_init(&flashFreeTagCond, NULL);

	printf( "Done initializing hw interfaces\n" ); fflush(stdout);

	portalCacheFlush(dstAlloc, dstBuffer, dstAlloc_sz, 1);
	portalCacheFlush(srcAlloc, srcBuffer, srcAlloc_sz, 1);
	portalCacheFlush(blkmapAlloc, blkmap, blkmapAlloc_sz*2, 1);

	ref_dstAlloc = dma->reference(dstAlloc);
	ref_srcAlloc = dma->reference(srcAlloc);
	ref_blkmapAlloc = dma->reference(blkmapAlloc);

	device->setDmaWriteRef(ref_dstAlloc);
	device->setDmaReadRef(ref_srcAlloc);
	device->setDmaMapRef(ref_blkmapAlloc);

	for (int t = 0; t < NUM_TAGS; t++) {
		readTagTable[t].busy = false;
		writeTagTable[t].busy = false;
		eraseTagTable[t].busy = false;

		int byteOffset = t * FPAGE_SIZE;
		readBuffers[t] = dstBuffer + byteOffset/sizeof(unsigned int);
		writeBuffers[t] = srcBuffer + byteOffset/sizeof(unsigned int);
	}

	for (int lpa=0; lpa < NUM_SEGMENTS*NUM_LOGBLKS*NUM_PAGES_PER_BLK; lpa++) {
		flashStatus[lpa] = UNINIT;
	}

	for (int t = 0; t < NUM_TAGS; t++) {
		for ( unsigned int i = 0; i < FPAGE_SIZE/sizeof(unsigned int); i++ ) {
			readBuffers[t][i] = 0xDEADBEEF;
			writeBuffers[t][i] = 0xBEEFDEAD;
		}
	}

	long actualFrequency=0;
	long requestedFrequency=1e9/MainClockPeriod;
	int status = setClockFrequency(0, requestedFrequency, &actualFrequency);
	fprintf(stderr, "Requested Freq: %5.2f, Actual Freq: %5.2f, status=%d\n"
			,(double)requestedFrequency*1.0e-6
			,(double)actualFrequency*1.0e-6,status);

	printf( "Start!\n" ); fflush(stdout);
	device->start(0);
	device->setDebugVals(0,0); //flag, delay

	device->debugDumpReq(0);
	sleep(1);

	printf( "Read initial FTL table from table.dump.0\n" ); fflush(stdout);
	// Read Initial FTL table
	if (readFTLfromFile("table.dump.0", ftlPtr) != 0) {
		fprintf(stderr, "Read Failure\n");
		return -1;
	}
	printf( "Done reading table.dump.0\n" ); fflush(stdout);

	printf( "MAP Upload to HW!\n" ); fflush(stdout);
	device->uploadMap();

	timespec start, now;
	clock_gettime(CLOCK_REALTIME, & start);

	printf( "Test Write!\n" ); fflush(stdout);

	for (int logblk = 0; logblk < NUM_LOGBLKS; logblk++){
		// test only 1024 segments due to some bad blocks (cannot allocate full 4096 segments)
		for (int segnum = 0; segnum < 1024; segnum++) {
			// assuming page_ofs = 0
			int lpa = (segnum<<14) + logblk;
			int freeTag = waitIdleWriteBuffer();

			// fill write memory
			for (unsigned int w=0; w<FPAGE_SIZE_VALID/sizeof(unsigned int); w++) {
				writeBuffers[freeTag][w] = hashAddrToData(lpa, w);
			}

			writePage(freeTag, lpa);
		}
	}

	while (true) {
		usleep(100);
		if ( getNumWritesInFlight() == 0 ) break;
	}

	// read back Map and Save to table.dump.1
	device->downloadMap(); // read table from FPGA
	if(writeFTLtoFile("table.dump.1", ftlPtr) != 0) {
		fprintf(stderr, "Write Failure\n");
		return -1;
	}

	printf( "Test Read!\n" ); fflush(stdout);
	
	for (int logblk = 0; logblk < NUM_LOGBLKS; logblk++){
		// test only 1024 segments due to some bad blocks (cannot allocate full 4096 segments)
		for (int segnum = 0; segnum < 1024; segnum++) {
			// assuming page_ofs = 0
			int lpa = (segnum<<14) + logblk;
			readPage(waitIdleReadBuffer(), lpa);
		}
	}

	while (true) {
		usleep(100);
		if ( getNumReadsInFlight() == 0 ) break;
	}

	printf( "Test Erase!\n" ); fflush(stdout);
	for (int logblk = 0; logblk < NUM_LOGBLKS; logblk++){
		// test only 1024 segments due to some bad blocks (cannot allocate full 4096 segments)
		for (int segnum = 0; segnum < 1024; segnum++) {
			// assuming page_ofs = 0
			int lpa = (segnum<<14) + logblk;
			eraseBlock(waitIdleEraseTag(), lpa);
		}
	}

	while (true) {
		usleep(100);
		if ( getNumErasesInFlight() == 0 ) break;
	}

	int elapsed = 0;
	while (true) {
		usleep(100);
		if (elapsed == 0) {
			elapsed=10000;
			device->debugDumpReq(0);
		}
		else {
			elapsed--;
		}
		if ( getNumReadsInFlight() == 0 ) break;
	}
	device->debugDumpReq(0);

	clock_gettime(CLOCK_REALTIME, & now);
	fprintf(stderr, "LOG: finished reading from page! %f\n", timespec_diff_sec(start, now) );

	sleep(2);
}
Exemple #15
0
//main
int main() {
  REG_DISPCNT = MODE_3 | BG2_ENABLE;

  enum GBAState state = START;
  enum GBAState prevState = state;

  while(1) {
		waitForVblank();
		switch(state) {
		case START:
			drawImage3(0,0,SPLASH_WIDTH,SPLASH_HEIGHT,splash);
			prevState = START;
			state = NODRAW;
			break;
		case NODRAW:

			if (prevState == START) {
				if (KEY_DOWN_NOW(BUTTON_START)) {
					state = GAME;
				}
				if (KEY_DOWN_NOW(BUTTON_A)) {
					state = HELP;
				}
			}
			if (prevState == HELP) {
				if (KEY_DOWN_NOW(BUTTON_SELECT)) {
					state = START;
				}
			}
			if (prevState == GAMEOVER) {
				if (KEY_DOWN_NOW(BUTTON_SELECT)) {
					state = START;
				}
			}

			break;
		case GAME:
			drawImage3(0,0,GAME2_WIDTH,GAME2_HEIGHT,game2);

			char stuff[4] = "000\0";
		  stuff[0] = 48 + (clearedRows/100)%10;
		  stuff[1] = 48 + (clearedRows/10)%10;
		  stuff[2] = 48 + clearedRows%10;
		  drawImagePartial(25, 180, 20, 30, GAME2_WIDTH, game2);
		  drawString(25,180,stuff, WHITE);

      block curr = randomBlock();
			block next = randomBlock();
      drawBlock(curr);
			int button = 0;
      while(1) {
				delay(20);
        if (KEY_DOWN_NOW(BUTTON_SELECT)) {
					prevState = GAME;
					state = START;
          break;
        }

        block old = curr;
        tick++;
        if (collisionDetectBottom(curr) == 1) {
          rowCheck(curr);
					curr = next;
					next = randomBlock();
					if(collisionDetect(curr) == 1) {
						prevState = GAME;
						state = GAMEOVER;
						break;
					}
        } else {
          if(KEY_DOWN_NOW(BUTTON_LEFT) && collisionDetectLeft(curr) == 0){
              curr.x--;
          } else if(KEY_DOWN_NOW(BUTTON_RIGHT) && collisionDetectRight(curr) == 0){
              curr.x++;
          } else if(KEY_DOWN_NOW(BUTTON_DOWN) && collisionDetectBottom(curr) == 0){
              curr.y--;
          } else if(button == 0 && KEY_DOWN_NOW(BUTTON_UP) && rotationDetect(curr) == 0){
							button = 1;
              rotateBlock(&curr);
          } else if (tick > 20) {
            tick = 0;
            curr.y--;
          } else if (!KEY_DOWN_NOW(BUTTON_DOWN)){
						//drawString(25,70,"stuff stuff", WHITE);
						button = 0;
					}
          waitForVblank();
          eraseBlock(old);
          drawBlock(curr);
        }
      }
      clearBoard();
      drawRect(4,4,70,10, BLACK);
			break;
		case GAMEOVER:
      drawImage3(0,0,END_WIDTH,END_HEIGHT,end);
			prevState = GAMEOVER;
			state = NODRAW;
			break;
		case HELP:
			drawImage3(0,0,HELP_WIDTH,HELP_HEIGHT,help);
			prevState = HELP;
			state = NODRAW;
			break;
		}
	}

  return 0;
}
Exemple #16
0
int main(int argc, const char **argv)
{

	int myid = 0;

	fprintf(stderr, "Main: myid=%d\n", myid);

	MemServerRequestProxy *hostMemServerRequest = new MemServerRequestProxy(IfcNames_HostMemServerRequest);
	MMURequestProxy *dmap = new MMURequestProxy(IfcNames_HostMMURequest);
	DmaManager *dma = new DmaManager(dmap);
	MemServerIndication *hostMemServerIndication = new MemServerIndication(hostMemServerRequest, IfcNames_HostMemServerIndication);
	MMUIndication *hostMMUIndication = new MMUIndication(dma, IfcNames_HostMMUIndication);

	fprintf(stderr, "Main::allocating memory...\n");

	device = new FlashRequestProxy(IfcNames_FlashRequest);
	FlashIndication *deviceIndication = new FlashIndication(IfcNames_FlashIndication);
	
	srcAlloc = portalAlloc(srcAlloc_sz);
	dstAlloc = portalAlloc(dstAlloc_sz);
	srcBuffer = (unsigned int *)portalMmap(srcAlloc, srcAlloc_sz);
	dstBuffer = (unsigned int *)portalMmap(dstAlloc, dstAlloc_sz);

	fprintf(stderr, "dstAlloc = %x\n", dstAlloc); 
	fprintf(stderr, "srcAlloc = %x\n", srcAlloc); 
	
	pthread_mutex_init(&flashReqMutex, NULL);
	pthread_cond_init(&flashFreeTagCond, NULL);

	printf( "Done initializing hw interfaces\n" ); fflush(stdout);

	portalExec_start();
	printf( "Done portalExec_start\n" ); fflush(stdout);

	portalDCacheFlushInval(dstAlloc, dstAlloc_sz, dstBuffer);
	portalDCacheFlushInval(srcAlloc, srcAlloc_sz, srcBuffer);
	ref_dstAlloc = dma->reference(dstAlloc);
	ref_srcAlloc = dma->reference(srcAlloc);

	device->setDmaWriteRef(ref_dstAlloc);
	device->setDmaReadRef(ref_srcAlloc);
	for (int t = 0; t < NUM_TAGS; t++) {
		readTagTable[t].busy = false;
		writeTagTable[t].busy = false;
		int byteOffset = t * PAGE_SIZE;
		printf("byteOffset=%x\n", byteOffset); fflush(stdout);
		readBuffers[t] = dstBuffer + byteOffset/sizeof(unsigned int);
		writeBuffers[t] = srcBuffer + byteOffset/sizeof(unsigned int);
	}
	
	for (int node=0; node<NUM_NODES; node++) {
		for (int blk=0; blk<BLOCKS_PER_CHIP; blk++) {
			for (int c=0; c<CHIPS_PER_BUS; c++) {
				for (int bus=0; bus< CHIPS_PER_BUS; bus++) {
					flashStatus[node][bus][c][blk] = UNINIT;
				}
			}
		}
	}


	for (int t = 0; t < NUM_TAGS; t++) {
		for ( int i = 0; i < PAGE_SIZE/sizeof(unsigned int); i++ ) {
			readBuffers[t][i] = 0;
			writeBuffers[t][i] = 0;
		}
	}


	//Start ext aurora
	auroraifc_start(myid);

	device->start(0);
	device->setDebugVals(0,0); //flag, delay

	device->debugDumpReq(0);
	sleep(1);
	device->debugDumpReq(0);
	sleep(1);

	if (myid==0) {

		
		timespec start, now;
		double timeElapsed = 0;
		int node = myid;

		if (doerasewrites) {
			//test erases
			//for (int node=NUM_NODES-1; node >= 1; node--) 
			//for (int node=DST_NODE; node == DST_NODE; node++) 
				for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
					for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
						for (int bus = 0; bus < NUM_BUSES; bus++){
							eraseBlock(node, bus, chip, blk, waitIdleEraseTag());
						}
					}
				}

			while (true) {
				usleep(100);
				if ( getNumErasesInFlight() == 0 ) break;
			}


			//read back erased pages
			//for (int node=NUM_NODES-1; node >= 1; node--) 
			//for (int node=DST_NODE; node == DST_NODE; node++) 
				for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
					for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
						for (int bus = 0; bus < NUM_BUSES; bus++){
							int page = 0;
							readPage(node, bus, chip, blk, page, waitIdleReadBuffer());
						}
					}
				}

			while (true) {
				usleep(100);
				if ( getNumReadsInFlight() == 0 ) break;
			}
			

			//write pages
			//FIXME: in old xbsv, simulatneous DMA reads using multiple readers cause kernel panic
			//Issue each bus separately for now

			int pagesWritten = 0;
			clock_gettime(CLOCK_REALTIME, & start);
			//for (int node=NUM_NODES-1; node >= 1; node--) 
			//for (int node=DST_NODE; node == DST_NODE; node++) 
				for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
					for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
						for (int bus = 0; bus < NUM_BUSES; bus++){
							int page = 0;
							//get free tag
							int freeTag = waitIdleWriteBuffer();
							//fill write memory; REMOVE THIS FOR PERFORMANCE TESTING!
							for (int w=0; w<PAGE_SIZE/sizeof(unsigned int); w++) {
								writeBuffers[freeTag][w] = hashAddrToData(node, bus, chip, blk, w);
							}
							//send request
							writePage(node, bus, chip, blk, page, freeTag); 
							pagesWritten++;
						}
					}
				}
			while (true) {
				usleep(100);
				if ( getNumWritesInFlight() == 0 ) break;
			}

			clock_gettime(CLOCK_REALTIME, & now);
			timeElapsed = timespec_diff_sec(start, now);
			fprintf(stderr, "LOG: finished writing! time=%f, numPages=%d, bandwidth=%f MB/s\n", timeElapsed, pagesWritten, (pagesWritten*8)/timeElapsed/1024  );

		} //doerasewrites

	
		sleep(1);
	
		int pagesRead = 0;
		clock_gettime(CLOCK_REALTIME, & start);
		
	
		//for (int node=NUM_NODES-1; node >= 1; node--) {
		//for (int node=DST_NODE; node == DST_NODE; node++) {
		for (int repeat = 0; repeat < 10; repeat++){
			for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
				for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
					for (int bus = 0; bus < NUM_BUSES; bus++){
						pagesRead++;
						int page = 0;
						readPage(node, bus, chip, blk, page, waitIdleReadBuffer());
					}
				}
			}
		}
		//}

		while (true) {
			if ( getNumReadsInFlight() == 0 ) break;
			usleep(100);
		}

		clock_gettime(CLOCK_REALTIME, & now);
		timeElapsed = timespec_diff_sec(start, now);
		fprintf(stderr, "LOG: finished SEQUENTIAL reads! time=%f, numPages=%d, bandwidth=%f MB/s\n", timeElapsed, pagesRead, (pagesRead*8)/timeElapsed/1024  );

		sleep(1);

		pagesRead=0;
		clock_gettime(CLOCK_REALTIME, & start);
		for (int repeat = 0; repeat < 100000; repeat++){
			int bus = rand()%NUM_BUSES;
			int chip = rand()%CHIPS_PER_BUS;
			int blk = rand()%BLOCKS_PER_CHIP;
			int page = rand()%PAGES_PER_BLOCK;
			readPage(node, bus, chip, blk, page, waitIdleReadBuffer());
			pagesRead++;

		}

		while (true) {
			if ( getNumReadsInFlight() == 0 ) break;
			usleep(100);
		}

		clock_gettime(CLOCK_REALTIME, & now);
		timeElapsed = timespec_diff_sec(start, now);
		fprintf(stderr, "LOG: finished RANDOM reads! time=%f, numPages=%d, bandwidth=%f MB/s\n", timeElapsed, pagesRead, (pagesRead*8)/timeElapsed/1024  );




		device->debugDumpReq(0);
		sleep(1);
		


		for ( int t = 0; t < NUM_TAGS; t++ ) {
			for ( int i = 0; i < PAGE_SIZE/sizeof(unsigned int); i++ ) {
				fprintf(stderr,  "%x %x %x\n", t, i, readBuffers[t][i] );
			}
		}
		if (!verbose) {
			fprintf(stderr, "LOG: DONE! data check skipped\n");
		} 
		else if (testPass==1) {
			fprintf(stderr, "LOG: TEST PASSED!\n");
		}
		else {
			fprintf(stderr, "LOG: **ERROR: TEST FAILED!\n");
		}
		

	} 
	else {
		fprintf(stderr, "Sleeping infinitely...\n");
		while (true) {
		device->debugDumpReq(0);
		sleep(1);
		}
		sleep(1000000);
	}
}
int truncateFile( fileHandleType fh, securityIdType securityID ) {

unsigned int dirEntry;
unsigned int *catalogBlock;
unsigned int *entryPtr;
int retval;

	if (fh > MAX_OPEN_FILES) {

		return ERROR_BAD_HANDLE;
	}

	if (fileCursors[fh].inUse == 0) {

		return ERROR_BAD_HANDLE;
	}

	// if its a memory file, just return
	if (fileCursors[fh].fileType > 2 ) {

		return NO_ERROR;

	}

	if ( (securityID != fileCursors[fh].securityID) && securityID != ROOT_ID && (fileCursors[fh].othersPermissions&0x01) == 0) {

		return ERROR_NO_PERMISSION;

	}

	// read the catalog of blocks for this file
	dirEntry = fileCursors[fh].dirEntryNum;
	
	// read the catalog for this file
	retval = readBlock(rootDir->entry[dirEntry].firstCatalogBlock, (void **)&catalogBlock);

	if (retval != 0) {

		return ERROR_READ_ERROR;

	}

	entryPtr = catalogBlock;

	while(*entryPtr != 0) {

		eraseBlock(*entryPtr);

		setBlockAsFree(*entryPtr);

		++entryPtr;
	}

	deallocate((void *)catalogBlock, masterBlocks->mblock0.blockSize);

	eraseBlock(rootDir->entry[dirEntry].firstCatalogBlock);

	rootDir->entry[dirEntry].fileSize = 0;

	fileCursors[fh].writePos = 0;
	fileCursors[fh].readPos = 0;
	fileCursors[fh].readBlockNum = 0;
	fileCursors[fh].writeBlockNum = 0;
	fileCursors[fh].fileSize = 0;

	return NO_ERROR;
}
int deleteFile( fileHandleType fh, securityIdType securityID ) {

unsigned int dirEntry;
unsigned int *catalogBlock;
unsigned int *entryPtr;
int retval;

struct memoryFileInfo { 
	unsigned int address;
	unsigned int size;
	char accessType;

	} *memoryInfo;

	if (fh > MAX_OPEN_FILES) {

		return ERROR_BAD_HANDLE;
	}

	if (fileCursors[fh].inUse == 0) {

		return ERROR_BAD_HANDLE;
	}

	if ( (securityID != fileCursors[fh].securityID) && securityID != ROOT_ID && (fileCursors[fh].othersPermissions&0x01) == 0) {

		return ERROR_NO_PERMISSION;

	}

	// read the catalog of blocks for this file
	dirEntry = fileCursors[fh].dirEntryNum;
	
	// read the catalog for this file
	retval = readBlock(rootDir->entry[dirEntry].firstCatalogBlock, (void **)&catalogBlock);

	if (retval != 0) {

		return ERROR_READ_ERROR;

	}

	if ( fileCursors[fh].fileType > 2 ) {

		memoryInfo = (struct memoryFileInfo *)catalogBlock;

		if (memoryInfo->address > 0 ) {

			free((void *)memoryInfo->address);

		}

	}
	else {
	entryPtr = catalogBlock;

		while(*entryPtr != 0) {

			eraseBlock(*entryPtr);
			setBlockAsFree(*entryPtr);
			++entryPtr;
		}
	}

	deallocate((void *)catalogBlock, masterBlocks->mblock0.blockSize);

	eraseBlock(rootDir->entry[dirEntry].firstCatalogBlock);

	setBlockAsFree(rootDir->entry[dirEntry].firstCatalogBlock);

	rootDir->entry[dirEntry].name[0] = 0;
	rootDir->entry[dirEntry].fileSize = 0;
	rootDir->entry[dirEntry].firstCatalogBlock = 0;
	rootDir->numEntries--;

	fileCursors[fh].dirEntryNum = 0;
	fileCursors[fh].inUse = 0;
	fileCursors[fh].writePos = 0;
	fileCursors[fh].readPos = 0;
	fileCursors[fh].fileSize = 0;
	fileCursors[fh].othersPermissions = 0;

	return NO_ERROR;
}
int createFile(char *name, enum fileTypes type, securityIdType securityID) {

int i;
unsigned int catalogBlock;


	// if no filename give, return error
	if ( name == 0 ) {

		return ERROR_BAD_VALUE;

	}

	// if the root directory is invalid, return error
	if ( rootDir == 0 ) {

		return ERROR_INIT;

	}

	// if the file already exists, return error
	if ( statusFile(name, 0) == 0 ) {

		return ERROR_FILE_EXISTS;

	}

	// find the first empty directory entry

	for ( i = 0; i < masterBlocks->mblock0.dirEntriesPerBlock; ++i ) {

		if ( rootDir->entry[i].name[0] == 0) {

			strncpy(rootDir->entry[i].name, name, MAX_FILENAME_LEN);
			rootDir->entry[i].fileSize = 0;
			rootDir->entry[i].fileType = type;
			rootDir->entry[i].securityID = securityID;
			rootDir->entry[i].othersPermissions = 0;

			// now allocate a block for its first catalog block

			if (findFreeBlock(&catalogBlock) == 0 ) {

				eraseBlock(catalogBlock);

				setBlockInUse(catalogBlock);

				rootDir->entry[i].firstCatalogBlock = catalogBlock;

			}
			else {

				return ERROR_NO_BLOCKS;
			
			}

			rootDir->numEntries++;
			return NO_ERROR;

		} // if strcmp

	}  // for

	return ERROR_MAX_EXCEEDED;

}