static uint32_t get_uint32_t(void) { struct vc_msg_uint32_t vc_msg __attribute__((aligned(16))); vc_msg.msg_size = sizeof(struct vc_msg_uint32_t); vc_msg.request_code = 0; vc_msg.tag.tag_id = RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF; vc_msg.tag.buffer_size = 4; vc_msg.tag.data_size = 0; vc_msg.tag.value = 0; vc_msg.end_tag = 0; clean_data_cache(); dsb(); dmb(); bcm2835_mailbox_flush(); bcm2835_mailbox_write(BCM2835_MAILBOX_PROP_CHANNEL, GPU_MEM_BASE + (uint32_t)&vc_msg); (void)bcm2835_mailbox_read(BCM2835_MAILBOX_PROP_CHANNEL); dmb(); invalidate_data_cache(); dsb(); if (vc_msg.request_code != BCM2835_MAILBOX_SUCCESS) { return 0; } return vc_msg.tag.value; }
static void item_preface(struct item_data *data, const struct p_bench_item *item) { invalidate_data_cache(); data->start = platform_clock(); }
void firmlaunch_arm9hax() { invalidate_data_cache(); invalidate_instruction_cache(); print("Invalidated instruction and data cache"); uint32_t code_offset = 0x3F00000; asm_memcpy((void *)(fw->fcram_address + code_offset), (void *)(fw->fcram_address + APP_CFW_OFFSET), ARM9_PAYLOAD_MAXSIZE); print("Copied arm9 code"); setup_gpu(); asm_memcpy((void *)fw->jump_table_address, &jump_table, (&jump_table_end - &jump_table + 1) * 4); print("Copied jump table"); *(uint32_t *)(fw->jump_table_address + (&jt_return - &jump_table) * 4) = fw->func_patch_return; *(uint32_t *)(fw->jump_table_address + (&jt_pdn_regs - &jump_table) * 4) = fw->pdn_regs; *(uint32_t *)(fw->jump_table_address + (&jt_pxi_regs - &jump_table) * 4) = fw->pxi_regs; print("Written firmware specific offsets"); *(uint32_t *)fw->func_patch_address = 0xE51FF004; *(uint32_t *)(fw->func_patch_address + 4) = 0xFFFF0C80; *(uint32_t *)fw->reboot_patch_address = 0xE51FF004; *(uint32_t *)(fw->reboot_patch_address + 4) = 0x1FFF4C80+4; print("Patched arm11 functions"); invalidate_data_cache(); print("Invalidated data cache"); print("Triggering reboot"); ((void (*)())fw->reboot_func_address)(0, 0, 2, 0); while (1) {}; }
bool HardwareBaremetal::Reboot(void) { hardware_led_set(1); h3_watchdog_enable(); invalidate_instruction_cache(); flush_branch_target_cache(); flush_prefetch_buffer(); clean_data_cache(); invalidate_data_cache(); for (;;) ; __builtin_unreachable (); return true; }
int main(void) { unsigned i, j, esize, cycle, x = 0; _SPM unsigned * elem; SPM_BTE_Buffer bte; const unsigned check = 0xbeef0000; unsigned run_limit = 1000; #ifdef PATMOS data_spm = SPM_BASE; #endif /* Always call spm_init as a first step */ spm_init(); printf("SPM location 0x%x\n", (unsigned) DATA_SPM_BASE); printf("off_chip location 0x%x size %u words\n", (unsigned) off_chip, MAX_TEST_SIZE); printf("Expected SPM size: %u words, %u bytes\n", DATA_SPM_WORDS, DATA_SPM_SIZE); spm_size_test(); printf("basic tests\n"); tester(0, 1024, 4, 1024); tester(0, 1, 4, 1024); tester(1, 1024, 4, 1024); tester(0, 1, 8, 512); mysrand(1000); for (cycle = 0; cycle < 100; cycle++) { do { esize = 1 << (myrand() % 8); } while (((DATA_SPM_SIZE / 2) % (esize * 4)) != 0); printf("%u writing test pattern, element size %u\n", cycle, esize); for (i = MAX_ITEMS; i < (MAX_ITEMS + (DATA_SPM_WORDS * 2)); i++) { off_chip[i] = check | i; } elem = spm_bte_init(&bte, off_chip, data_spm, DATA_SPM_SIZE, esize * 4); mysrand(cycle + 1); for (i = 0; i < MAX_ITEMS; ) { for (j = 0; j < esize; i++, j++) { elem[j] = (cycle == 0) ? i : (myrand() + 1); } elem = spm_bte_produce(&bte); } spm_bte_finish(&bte); invalidate_data_cache(); printf("%u checking test pattern, element size %u\n", cycle, esize); mysrand(cycle + 1); x = 0; for (i = 0; i < MAX_ITEMS; i++) { j = (cycle == 0) ? i : (myrand() + 1); if (off_chip[i] != j) { printf("off_chip[%08x] = %08x should be %08x\n", i, off_chip[i], j); x++; assert(x < 10); } } assert(!x); x = 0; for (i = 0; i < (DATA_SPM_WORDS * 2); i++) { if (off_chip[i + MAX_ITEMS] != (check | i)) { x = i; } } printf("producer overshot by %u (%u)\n", x, DATA_SPM_WORDS * 2); printf("%u single buffer tests\n", cycle); mysrand(cycle + 0x2000); for (i = 0; (i < (3 + cycle)) && (i < 25); i++) { unsigned elem_size = 4 << (myrand() % 4); unsigned spm_elems = DATA_SPM_SIZE / elem_size; unsigned total_elems; spm_elems /= 1 << (myrand() % 4); if (spm_elems < 2) { spm_elems = 2; } total_elems = (myrand() % MAX_ITEMS) + 1; tester((myrand() % total_elems) % 256, total_elems, elem_size, spm_elems * elem_size); } mysrand(cycle + 0x1000); printf("%u multi-buffer tests, myrand %04x\n", cycle, myrand() & 0xffff); multibuf(myrand(), 2 + (myrand() % 15), run_limit); for (i = 2; i <= 16; i++) { multibuf(1024, i, run_limit); } multibuf(myrand(), 2 + (myrand() % 15), run_limit); for (i = 2; i <= 8; i++) { multibuf(2048, i, run_limit); } run_limit *= 10; if (run_limit > MAX_TEST_SIZE) { run_limit = MAX_TEST_SIZE; } } return 0; }