// 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(); }
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); } }
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; } }
// 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; }
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; }
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; }
//--------------------------------------------- //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); }
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); }
//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; }
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; }