#ifndef _CORTEXA8_HH_ #define _CORTEXA8_HH_ #include #include #include #define CORTEXA8_CPUID_MAINID 0 #define CORTEXA8_CPUID_CACHETYPE 1 #define CORTEXA8_CPUID_TLBTYPE 2 #define CORTEXA8_CPUID_PFR0 3 #define CORTEXA8_CPUID_PFR1 4 // Implemented in cortexa8_asm.s extern "C" { void cortexa8_ena_int(); void cortexa8_dis_int(); bool cortexa8_get_int(); void cortexa8_set_usr_sp(void *sp); void cortexa8_set_abt_sp(void *sp); void cortexa8_set_und_sp(void *sp); void cortexa8_set_irq_sp(void *sp); void cortexa8_set_fiq_sp(void *sp); uint32_t cortexa8_get_spsr(); uint32_t cortexa8_get_cpsr(); } namespace cortexa8 { void init_mode(); uint32_t read_cpuid(int reg) noexcept; void enable_icache() noexcept; void enable_dcache() noexcept; void disable_icache() noexcept; void disable_dcache() noexcept; void errata() noexcept; void init_mmu() noexcept; void init_handlers() noexcept; void map_pages(uintptr_t virt, uintptr_t phys, unsigned count); void unmap_pages(uintptr_t virt, unsigned count); struct thread_cb { thread_cb() : regs{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, cpsr{0}, newlibReent _REENT_INIT(newlibReent) { } uint32_t regs[16]; uint32_t cpsr; struct _reent newlibReent; }; thread_cb *get_cur_thread(); void set_cur_thread(thread_cb* tcb); void exit_svc(); void yield_svc(); bool in_handler(); // Wrapper to handle safe disabling/enabling of interrupts class ScopedSetIF { public: ScopedSetIF(bool enableInts = false) : savedIF_{cortexa8_get_int()}, done_{false} { if(enableInts) cortexa8_ena_int(); else cortexa8_dis_int(); } ~ScopedSetIF() { if(done_) return; if(savedIF_) cortexa8_ena_int(); else cortexa8_dis_int(); } void restore() { assert(!done_); if(savedIF_) cortexa8_ena_int(); else cortexa8_dis_int(); done_ = true; } private: bool savedIF_, done_; }; } #endif