Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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) {};
}
Ejemplo n.º 3
0
long xexec(WORD flag, char *path, char *tail, char *env)
{
    PD *p;
    PGMHDR01 hdr;
    MD *m, *env_md;
    LONG rc;
    long max, needed;
    FH fh;

    KDEBUG(("BDOS xexec: flag or mode = %d\n",flag));

    /* first branch - actions that do not require loading files */
    switch(flag) {
#if DETECT_NATIVE_FEATURES
    case PE_RELOCATE:   /* internal use only, see bootstrap() in bios/bios.c */
        p = (PD *) tail;
        rc = kpgm_relocate(p, (long)path);
        if (rc) {
            KDEBUG(("BDOS xexec: kpgm_reloc returned %ld (0x%lx)\n",rc,rc));
            return rc;
        }

        /* invalidate instruction cache for the TEXT segment only
         * programs that jump into their DATA, BSS or HEAP are kindly invited
         * to do their cache management themselves.
         */
        invalidate_instruction_cache( p+1, p->p_tlen);

        return (long)p;
#endif
    case PE_BASEPAGE:           /* just create a basepage */
        path = (char *) 0L;     /* (same as basepage+flags with flags set to zero) */
    /* drop thru */
    case PE_BASEPAGEFLAGS:      /* create a basepage, respecting the flags */
        env_md = alloc_env(env);
        if (env_md == NULL) {
            KDEBUG(("BDOS xexec: not enough memory!\n"));
            return ENSMEM;
        }
        m = alloc_tpa((ULONG)path,sizeof(PD),&max);

        if (m == NULL) {    /* not even enough memory for basepage */
            freeit(env_md, &pmd);
            KDEBUG(("BDOS xexec: No memory for basepage\n"));
            return ENSMEM;
        }

        p = (PD *) m->m_start;

        /* memory ownership */
        m->m_own = env_md->m_own = run;

        /* initialize the PD */
        init_pd_fields(p, tail, max, env_md);
        p->p_flags = (ULONG)path;   /* set the flags */
        init_pd_files(p);

        return (long)p;
    case PE_GOTHENFREE:
        /* set the owner of the memory to be this process */
        p = (PD *) tail;
        set_owner(p, p, find_mpb(p));
        set_owner(p->p_env, p, find_mpb(p->p_env));
    /* fall through */
    case PE_GO:
        p = (PD *) tail;
        proc_go(p);
        /* should not return ? */
        return (long)p;
    case PE_LOADGO:
    case PE_LOAD:
        break;
    default:
        return EINVFN;
    }

    /* we now need to load a file */
    KDEBUG(("BDOS xexec: trying to find the command ...\n"));
    if (ixsfirst(path,0,0L)) {
        KDEBUG(("BDOS xexec: command %s not found!!!\n",path));
        return EFILNF;      /*  file not found      */
    }

    /* load the header - if I/O error occurs now, the longjmp in rwabs will
     * jump directly back to bdosmain.c, which is not a problem because
     * we haven't allocated anything yet.
     */
    rc = kpgmhdrld(path, &hdr, &fh);
    if (rc) {
        KDEBUG(("BDOS xexec: kpgmhdrld returned %ld (0x%lx)\n",rc,rc));
        return rc;
    }

    /* allocate the environment first, always in ST RAM */
    env_md = alloc_env(env);
    if (env_md == NULL) {
        KDEBUG(("BDOS xexec: not enough memory!\n"));
        return ENSMEM;
    }

    /* allocate the basepage depending on memory policy */
    needed = hdr.h01_tlen + hdr.h01_dlen + hdr.h01_blen + sizeof(PD);
    m = alloc_tpa(hdr.h01_flags,needed,&max);

    /* if failed, free env_md and return */
    if (m == NULL) {
        KDEBUG(("BDOS xexec: no memory for TPA\n"));
        freeit(env_md, &pmd);
        return ENSMEM;
    }

    p = (PD *) m->m_start;

    /* memory ownership - the owner is either the new process being created,
     * or the parent
     */
    if (flag == PE_LOADGO) {
        m->m_own = env_md->m_own = p;
    } else {
        m->m_own = env_md->m_own = run;
    }

    /* initialize the fields in the PD structure */
    init_pd_fields(p, tail, max, env_md);

    /* set the flags (must be done after init_pd) */
    p->p_flags = hdr.h01_flags;

    /* use static variable to avoid the obscure longjmp warning */
    cur_p = p;
    cur_m = m;
    cur_env_md = env_md;

    /* we have now allocated memory, so we need to intercept longjmp. */
    memcpy(bakbuf, errbuf, sizeof(errbuf));
    if (setjmp(errbuf)) {

        KDEBUG(("Error and longjmp in xexec()!\n"));

        /* free any memory allocated yet */
        freeit(cur_env_md, &pmd);
        freeit(cur_m, find_mpb(cur_m->m_start));

        /* we still have to jump back to bdosmain.c so that the proper error
         * handling can occur.
         */
        longjmp(bakbuf, 1);
    }

    /* now, load the rest of the program and perform relocation */
    rc = kpgmld(cur_p, fh, &hdr);
    if (rc) {
        KDEBUG(("BDOS xexec: kpgmld returned %ld (0x%lx)\n",rc,rc));
        /* free any memory allocated yet */
        freeit(cur_env_md, &pmd);
        freeit(cur_m, find_mpb(cur_m->m_start));

        return rc;
    }

    /* at this point the program has been correctly loaded in memory, and
     * more I/O errors cannot occur, so it is safe now to finish initializing
     * the new process.
     */
    init_pd_files(cur_p);

    /* invalidate instruction cache for the TEXT segment only
     * programs that jump into their DATA, BSS or HEAP are kindly invited
     * to do their cache management themselves.
     */
    invalidate_instruction_cache(((char *)cur_p) + sizeof(PD), hdr.h01_tlen);

    if (flag != PE_LOAD)
        proc_go(cur_p);
    return (long)cur_p;
}