void fault_handler() { printf("FAULT %d %08x\n", __builtin_nyuzi_read_control_reg(CR_FAULT_REASON), __builtin_nyuzi_read_control_reg(CR_FAULT_ADDRESS)); printf("data value = %08x\n", data_addr[PAGE_SIZE / sizeof(int)]); exit(0); }
int usleep(useconds_t delay) { int expire = __builtin_nyuzi_read_control_reg(6) + delay * CLOCKS_PER_US; while (__builtin_nyuzi_read_control_reg(6) < expire) ; return 0; }
void fault_handler() { printf("FAULT %d current flags %02x prev flags %02x\n", __builtin_nyuzi_read_control_reg(3), __builtin_nyuzi_read_control_reg(4), __builtin_nyuzi_read_control_reg(8)); exit(0); }
void fault_handler(void) { printf("FAULT %d addr %08x pc %08x\n", __builtin_nyuzi_read_control_reg(CR_FAULT_REASON), __builtin_nyuzi_read_control_reg(CR_FAULT_ADDRESS), __builtin_nyuzi_read_control_reg(CR_FAULT_PC)); exit(0); }
void fault_handler() { printf("FAULT %d %08x current flags %02x prev flags %02x\n", __builtin_nyuzi_read_control_reg(CR_FAULT_REASON), __builtin_nyuzi_read_control_reg(CR_FAULT_ADDRESS), __builtin_nyuzi_read_control_reg(CR_FLAGS), __builtin_nyuzi_read_control_reg(CR_SAVED_FLAGS)); exit(0); }
void faultHandler(void) { printf("FAULT %d current flags %02x prev flags %02x\n", __builtin_nyuzi_read_control_reg(3), __builtin_nyuzi_read_control_reg(4), __builtin_nyuzi_read_control_reg(8)); printf("scratchpad = %08x\n", __builtin_nyuzi_read_control_reg(11)); exit(0); }
void faultHandler() { __builtin_nyuzi_write_control_reg(CR_SCRATCHPAD0, 0x88cf70b4); __builtin_nyuzi_write_control_reg(CR_SCRATCHPAD1, 0x78662516); // This will cause a nested TLB miss fault *EXTPTR = 0; // We've returned from the TLB miss handler. Ensure all of the control registers // have been restored to the values for the original fault. printf("reason %d\n", __builtin_nyuzi_read_control_reg(CR_FAULT_REASON)); // CHECK: reason 2 printf("fault address %08x\n", __builtin_nyuzi_read_control_reg(CR_FAULT_ADDRESS)); // CHECK: 00000017 printf("flags %02x\n", __builtin_nyuzi_read_control_reg(CR_SAVED_FLAGS)); // CHECK: flags 06 printf("subcycle %d\n", __builtin_nyuzi_read_control_reg(CR_SUBCYCLE)); // CHECK: subcycle 6 if (__builtin_nyuzi_read_control_reg(CR_FAULT_PC) < (unsigned int) &tlb_miss_handler) printf("fault pc ok\n"); // CHECK: fault pc ok else printf("fault pc bad (%08x)\n", __builtin_nyuzi_read_control_reg(CR_FAULT_PC)); printf("CR_SCRATCHPAD0 %08x\n", __builtin_nyuzi_read_control_reg(CR_SCRATCHPAD0)); // CHECK: CR_SCRATCHPAD0 88cf70b4 printf("CR_SCRATCHPAD1 %08x\n", __builtin_nyuzi_read_control_reg(CR_SCRATCHPAD1)); // CHECK: CR_SCRATCHPAD1 78662516 exit(0); }
// Each thread starts here and performs 16 hashes simultaneously. With four // threads, there are 64 hashes in flight at a time. Each thread repeats this // four times. The total number of hashes performed is 256. int main() { __builtin_nyuzi_write_control_reg(30, 0xffffffff); // Start other threads const int kSourceBlockSize = 128; const int kHashSize = 32; const int kNumBuffers = 2; const int kNumLanes = 16; unsigned int basePtr = 0x100000 + __builtin_nyuzi_read_control_reg(0) * (kHashSize * kNumLanes * kNumBuffers) + (kSourceBlockSize * kNumLanes); const vecu16_t kStepVector = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; vecu16_t inputPtr = __builtin_nyuzi_makevectori(basePtr) + (kStepVector * __builtin_nyuzi_makevectori(kHashSize)); vecu16_t tmpPtr = inputPtr + __builtin_nyuzi_makevectori(kSourceBlockSize * kNumLanes); vecu16_t outputPtr = tmpPtr + __builtin_nyuzi_makevectori(kHashSize * kNumLanes); for (int i = 0; i < 4; i++) { // Double sha-2 hash sha2Hash(inputPtr, kSourceBlockSize / kHashSize, outputPtr); sha2Hash(tmpPtr, 1, outputPtr); } return 0; }
void general_fault_handler() { printf("general fault %d\n", __builtin_nyuzi_read_control_reg(3)); // Attempt to read from address that dtlbinsert was called on. // This should fault because TLB wasn't updated printf("FAIL: data is %08x\n", *data); }
void dump_interrupt_frame(const struct interrupt_frame *frame) { int reg; int trap_cause = __builtin_nyuzi_read_control_reg(CR_TRAP_CAUSE); int trap_type = trap_cause & 0xf; unsigned int trap_address = __builtin_nyuzi_read_control_reg(CR_TRAP_ADDR); if (trap_type <= TT_NOT_EXECUTABLE) { kprintf("%s ", TRAP_NAMES[trap_type]); if (trap_type == TT_UNALIGNED_ACCESS || trap_type == TT_PAGE_FAULT || trap_type == TT_TLB_MISS || trap_type == TT_SUPERVISOR_ACCESS) { kprintf("@%08x %s %s\n", trap_address, (trap_cause & 0x20) ? "dcache" : "icache", (trap_cause & 0x10) ? "store" : "load"); } } else kprintf("Unknown trap cause %02x\n", trap_cause); kprintf("REGISTERS\n"); for (reg = 0; reg < 32; reg++) { if (reg < 10) kprintf(" "); // Align single digit numbers kprintf("s%d %08x ", reg, frame->gpr[reg]); if (reg % 8 == 7) kprintf("\n"); } kprintf("pc %08x ", frame->pc); kprintf("Flags: "); if (frame->flags & 1) kprintf("I"); if (frame->flags & 2) kprintf("M"); if (frame->flags & 4) kprintf("S"); kprintf(" (%02x)\n\n", frame->flags); }
void handle_trap(struct interrupt_frame *frame) { unsigned int address; int trap_cause = __builtin_nyuzi_read_control_reg(CR_TRAP_CAUSE); switch (trap_cause & 0xf) { case TT_PAGE_FAULT: case TT_ILLEGAL_STORE: address = __builtin_nyuzi_read_control_reg(CR_TRAP_ADDR); enable_interrupts(); if (!handle_page_fault(address, (trap_cause & 0x10) != 0)) { // Jump to user_copy fault handler if set if (fault_handler[current_hw_thread()] != 0) frame->pc = fault_handler[current_hw_thread()]; else bad_fault(frame); } disable_interrupts(); break; case TT_SYSCALL: // Enable interrupts address = __builtin_nyuzi_read_control_reg(CR_TRAP_ADDR); enable_interrupts(); frame->gpr[0] = handle_syscall(frame->gpr[0], frame->gpr[1], frame->gpr[2], frame->gpr[3], frame->gpr[4], frame->gpr[5]); frame->pc += 4; // Next instruction disable_interrupts(); break; case TT_INTERRUPT: handle_interrupt(frame); break; default: bad_fault(frame); } }
static void handle_interrupt(struct interrupt_frame *frame) { unsigned int interrupt_bitmap = __builtin_nyuzi_read_control_reg(CR_INTERRUPT_PENDING); (void) frame; while (interrupt_bitmap) { int next_int = __builtin_ctz(interrupt_bitmap); interrupt_bitmap &= ~(1 << next_int); if (handlers[next_int] == 0) { kprintf("No handler for interrupt %d", next_int); panic("STOPPING"); } (*handlers[next_int])(); } }
int main() { veci16 *dest = (veci16*) region1Base + __builtin_nyuzi_read_control_reg(0) * LOOP_UNROLL; veci16 values = __builtin_nyuzi_makevectori(0xdeadbeef); int transferCount = kTransferSize / (64 * NUM_STRANDS * LOOP_UNROLL); do { dest[0] = values; dest[1] = values; dest[2] = values; dest[3] = values; dest[4] = values; dest[5] = values; dest[6] = values; dest[7] = values; dest += NUM_STRANDS * LOOP_UNROLL; } while (--transferCount); }
void reschedule(void) { int hwthread = __builtin_nyuzi_read_control_reg(CR_CURRENT_THREAD); struct thread *old_thread; struct thread *next_thread; // Put current thread back on ready queue acquire_spinlock(&thread_q_lock); old_thread = cur_thread[hwthread]; enqueue_thread(&ready_q, old_thread); next_thread = dequeue_thread(&ready_q); if (old_thread != next_thread) { cur_thread[hwthread] = next_thread; context_switch(&old_thread->current_stack, next_thread->current_stack, next_thread->map->page_dir, next_thread->map->asid); } release_spinlock(&thread_q_lock); }
// This is called after the MMU has been enabled struct vm_translation_map *vm_translation_map_init(void) { list_init(&map_list); kernel_map.page_dir = __builtin_nyuzi_read_control_reg(10); return &kernel_map; }
struct thread *current_thread(void) { int core = __builtin_nyuzi_read_control_reg(CR_CURRENT_THREAD); return cur_thread[core]; }
void boot_init_thread(struct vm_translation_map *map) { struct thread *th = slab_alloc(&thread_slab); th->map = map; cur_thread[__builtin_nyuzi_read_control_reg(CR_CURRENT_THREAD)] = th; }
int getTime() { return __builtin_nyuzi_read_control_reg(6); }
void do_trap(unsigned int *registers) { printf("trap %02x\n", __builtin_nyuzi_read_control_reg(3)); interruptCount++; }
void tlb_miss_handler() { printf("TLB miss %08x\n", __builtin_nyuzi_read_control_reg(CR_FAULT_ADDRESS)); exit(0); }
// All threads start execution here. int main() { if (__builtin_nyuzi_read_control_reg(0) != 0) workerThread(); // Set up resource data char *resourceData = readResourceFile(); const FileHeader *resourceHeader = (FileHeader*) resourceData; const TextureEntry *texHeader = (TextureEntry*)(resourceData + sizeof(FileHeader)); const MeshEntry *meshHeader = (MeshEntry*)(resourceData + sizeof(FileHeader) + resourceHeader->numTextures * sizeof(TextureEntry)); Texture **textures = new Texture*[resourceHeader->numTextures]; printf("%d textures %d meshes\n", resourceHeader->numTextures, resourceHeader->numMeshes); // Create texture objects for (unsigned int textureIndex = 0; textureIndex < resourceHeader->numTextures; textureIndex++) { #if TEST_TEXTURE textures[textureIndex] = createCheckerboardTexture(); #else textures[textureIndex] = new Texture(); textures[textureIndex]->enableBilinearFiltering(true); int offset = texHeader[textureIndex].offset; for (unsigned int mipLevel = 0; mipLevel < texHeader[textureIndex].mipLevels; mipLevel++) { int width = texHeader[textureIndex].width >> mipLevel; int height = texHeader[textureIndex].height >> mipLevel; Surface *surface = new Surface(width, height, resourceData + offset); textures[textureIndex]->setMipSurface(mipLevel, surface); offset += width * height * 4; } #endif } // Create Render Buffers RenderBuffer *vertexBuffers = new RenderBuffer[resourceHeader->numMeshes]; RenderBuffer *indexBuffers = new RenderBuffer[resourceHeader->numMeshes]; for (unsigned int meshIndex = 0; meshIndex < resourceHeader->numMeshes; meshIndex++) { const MeshEntry &entry = meshHeader[meshIndex]; vertexBuffers[meshIndex].setData(resourceData + entry.offset, entry.numVertices, sizeof(float) * kAttrsPerVertex); indexBuffers[meshIndex].setData(resourceData + entry.offset + entry.numVertices * kAttrsPerVertex * sizeof(float), entry.numIndices, sizeof(int)); } // Set up render state RenderContext *context = new RenderContext(0x1000000); RenderTarget *renderTarget = new RenderTarget(); Surface *colorBuffer = new Surface(FB_WIDTH, FB_HEIGHT, (void*) 0x200000); Surface *depthBuffer = new Surface(FB_WIDTH, FB_HEIGHT); renderTarget->setColorBuffer(colorBuffer); renderTarget->setDepthBuffer(depthBuffer); context->bindTarget(renderTarget); context->enableDepthBuffer(true); #if SHOW_DEPTH context->bindShader(new DepthShader()); #else context->bindShader(new TextureShader()); #endif context->setClearColor(0.52, 0.80, 0.98); Matrix projectionMatrix = Matrix::getProjectionMatrix(FB_WIDTH, FB_HEIGHT); TextureUniforms uniforms; uniforms.fLightDirection = Vec3(-1, -0.5, 1).normalized(); uniforms.fDirectional = 0.5f; uniforms.fAmbient = 0.4f; float theta = 0.0; startAllThreads(); for (int frame = 0; ; frame++) { Matrix modelViewMatrix = Matrix::lookAt(Vec3(cos(theta) * 6, 3, sin(theta) * 6), Vec3(0, 3.1, 0), Vec3(0, 1, 0)); theta = theta + M_PI / 8; if (theta > M_PI * 2) theta -= M_PI * 2; uniforms.fMVPMatrix = projectionMatrix * modelViewMatrix; uniforms.fNormalMatrix = modelViewMatrix.upper3x3(); context->clearColorBuffer(); for (unsigned int meshIndex = 0; meshIndex < resourceHeader->numMeshes; meshIndex++) { const MeshEntry &entry = meshHeader[meshIndex]; if (entry.textureId != 0xffffffff) { assert(entry.textureId < resourceHeader->numTextures); context->bindTexture(0, textures[entry.textureId]); uniforms.fHasTexture = true; } else uniforms.fHasTexture = false; context->bindUniforms(&uniforms, sizeof(uniforms)); context->bindVertexAttrs(&vertexBuffers[meshIndex]); context->drawElements(&indexBuffers[meshIndex]); } int startInstructions = __builtin_nyuzi_read_control_reg(6); context->finish(); printf("rendered frame in %d instructions\n", __builtin_nyuzi_read_control_reg(6) - startInstructions); } return 0; }
int currentThread() { return __builtin_nyuzi_read_control_reg(0); }