264 lines
5.6 KiB
C++
264 lines
5.6 KiB
C++
INTERFACE[arm]:
|
|
|
|
EXTENSION class Proc
|
|
{
|
|
private:
|
|
enum : unsigned
|
|
{
|
|
Status_FIQ_disabled = 0x40,
|
|
Status_IRQ_disabled = 0x80,
|
|
};
|
|
|
|
public:
|
|
enum : unsigned
|
|
{
|
|
Status_mode_user = 0x10,
|
|
Status_mode_supervisor = 0x13,
|
|
Status_mode_mask = 0x1f,
|
|
|
|
Status_interrupts_disabled = Status_FIQ_disabled | Status_IRQ_disabled,
|
|
Status_thumb = 0x20,
|
|
};
|
|
|
|
static Cpu_phys_id cpu_id();
|
|
};
|
|
|
|
INTERFACE[arm && !arm_em_tz && !arm_em_ns]:
|
|
|
|
EXTENSION class Proc
|
|
{
|
|
public:
|
|
enum : unsigned
|
|
{
|
|
Cli_mask = Status_interrupts_disabled,
|
|
Sti_mask = Status_interrupts_disabled,
|
|
Status_preempt_disabled = Status_IRQ_disabled,
|
|
Status_interrupts_mask = Status_interrupts_disabled,
|
|
Status_always_mask = 0,
|
|
};
|
|
};
|
|
|
|
INTERFACE[arm && arm_em_tz]:
|
|
|
|
EXTENSION class Proc
|
|
{
|
|
public:
|
|
enum : unsigned
|
|
{
|
|
Cli_mask = Status_FIQ_disabled,
|
|
Sti_mask = Status_FIQ_disabled,
|
|
Status_preempt_disabled = Status_FIQ_disabled,
|
|
Status_interrupts_mask = Status_FIQ_disabled,
|
|
Status_always_mask = Status_IRQ_disabled,
|
|
};
|
|
};
|
|
|
|
INTERFACE[arm && arm_em_ns]:
|
|
|
|
EXTENSION class Proc
|
|
{
|
|
public:
|
|
enum : unsigned
|
|
{
|
|
Cli_mask = Status_IRQ_disabled,
|
|
Sti_mask = Status_IRQ_disabled,
|
|
Status_preempt_disabled = Status_IRQ_disabled,
|
|
Status_interrupts_mask = Status_IRQ_disabled,
|
|
Status_always_mask = Status_FIQ_disabled,
|
|
};
|
|
};
|
|
|
|
IMPLEMENTATION[arm]:
|
|
|
|
#include "types.h"
|
|
#include "std_macros.h"
|
|
|
|
IMPLEMENT static inline
|
|
Mword Proc::stack_pointer()
|
|
{
|
|
Mword sp;
|
|
asm volatile ( "mov %0, sp \n" : "=r"(sp) );
|
|
return sp;
|
|
}
|
|
|
|
IMPLEMENT static inline
|
|
void Proc::stack_pointer(Mword sp)
|
|
{
|
|
asm volatile ( "mov sp, %0 \n" : : "r"(sp) );
|
|
}
|
|
|
|
IMPLEMENT static inline
|
|
Mword Proc::program_counter()
|
|
{
|
|
Mword pc;
|
|
asm ("mov %0, pc" : "=r" (pc));
|
|
return pc;
|
|
}
|
|
|
|
IMPLEMENT static inline
|
|
void Proc::cli()
|
|
{
|
|
Mword v;
|
|
asm volatile("mrs %0, cpsr \n"
|
|
"orr %0, %0, %1 \n"
|
|
"msr cpsr_c, %0 \n"
|
|
: "=r" (v)
|
|
: "I" (Cli_mask)
|
|
: "memory");
|
|
}
|
|
|
|
IMPLEMENT static inline
|
|
void Proc::sti()
|
|
{
|
|
Mword v;
|
|
asm volatile("mrs %0, cpsr \n"
|
|
"bic %0, %0, %1 \n"
|
|
"msr cpsr_c, %0 \n"
|
|
: "=r" (v)
|
|
: "I" (Sti_mask)
|
|
: "memory");
|
|
}
|
|
|
|
IMPLEMENT static inline
|
|
Proc::Status Proc::cli_save()
|
|
{
|
|
Status ret;
|
|
Mword v;
|
|
asm volatile("mrs %0, cpsr \n"
|
|
"orr %1, %0, %2 \n"
|
|
"msr cpsr_c, %1 \n"
|
|
: "=r" (ret), "=r" (v)
|
|
: "I" (Cli_mask)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
IMPLEMENT static inline
|
|
Proc::Status Proc::interrupts()
|
|
{
|
|
Status ret;
|
|
asm volatile("mrs %0, cpsr" : "=r" (ret));
|
|
return !(ret & Sti_mask);
|
|
}
|
|
|
|
IMPLEMENT static inline
|
|
void Proc::sti_restore(Status st)
|
|
{
|
|
if (!(st & Sti_mask))
|
|
sti();
|
|
}
|
|
|
|
IMPLEMENT static inline
|
|
void Proc::irq_chance()
|
|
{
|
|
asm volatile ("nop; nop;" : : : "memory");
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
IMPLEMENTATION[arm && !mp]:
|
|
|
|
IMPLEMENT static inline
|
|
Cpu_phys_id Proc::cpu_id()
|
|
{ return Cpu_phys_id(0); }
|
|
|
|
//----------------------------------------------------------------
|
|
IMPLEMENTATION[arm && mp]:
|
|
|
|
IMPLEMENT static inline
|
|
Cpu_phys_id Proc::cpu_id()
|
|
{
|
|
unsigned mpidr;
|
|
__asm__("mrc p15, 0, %0, c0, c0, 5": "=r" (mpidr));
|
|
return Cpu_phys_id(mpidr & 0x7); // mind gic softirq
|
|
}
|
|
|
|
//----------------------------------------------------------------
|
|
IMPLEMENTATION[arm && (pxa || sa1100 || s3c2410)]:
|
|
|
|
IMPLEMENT static inline
|
|
void Proc::halt()
|
|
{}
|
|
|
|
IMPLEMENT static inline
|
|
void Proc::pause()
|
|
{}
|
|
|
|
//----------------------------------------------------------------
|
|
IMPLEMENTATION[arm && 926]:
|
|
|
|
IMPLEMENT static inline
|
|
void Proc::pause()
|
|
{
|
|
}
|
|
|
|
IMPLEMENT static inline
|
|
void Proc::halt()
|
|
{
|
|
Status f = cli_save();
|
|
asm volatile("mov r0, #0 \n\t"
|
|
"mrc p15, 0, r1, c1, c0, 0 @ Read control register \n\t"
|
|
"mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer \n\t"
|
|
"bic r2, r1, #1 << 12 \n\t"
|
|
"mcr p15, 0, r2, c1, c0, 0 @ Disable I cache \n\t"
|
|
"mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt \n\t"
|
|
"mcr 15, 0, r1, c1, c0, 0 @ Restore ICache enable \n\t"
|
|
:::"memory",
|
|
"r0", "r1", "r2", "r3", "r4", "r5",
|
|
"r6", "r7", "r8", "r9", "r10", "r11",
|
|
"r12", "r13", "r14", "r15"
|
|
);
|
|
sti_restore(f);
|
|
}
|
|
|
|
//----------------------------------------------------------------
|
|
IMPLEMENTATION[arm && arm1136]:
|
|
|
|
IMPLEMENT static inline
|
|
void Proc::pause()
|
|
{}
|
|
|
|
IMPLEMENT static inline
|
|
void Proc::halt()
|
|
{
|
|
Status f = cli_save();
|
|
asm volatile("mcr p15, 0, r0, c7, c10, 4 @ DWB/DSB \n\t"
|
|
"mcr p15, 0, r0, c7, c0, 4 @ WFI \n\t");
|
|
sti_restore(f);
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
IMPLEMENTATION[arm && (arm1176 || mpcore)]:
|
|
|
|
IMPLEMENT static inline
|
|
void Proc::pause()
|
|
{}
|
|
|
|
IMPLEMENT static inline
|
|
void Proc::halt()
|
|
{
|
|
Status f = cli_save();
|
|
asm volatile("mcr p15, 0, r0, c7, c10, 4 @ DWB/DSB \n\t"
|
|
"wfi \n\t");
|
|
sti_restore(f);
|
|
}
|
|
|
|
//----------------------------------------------------------------
|
|
IMPLEMENTATION[arm && (armca8 || armca9)]:
|
|
|
|
IMPLEMENT static inline
|
|
void Proc::pause()
|
|
{
|
|
asm("yield");
|
|
}
|
|
|
|
IMPLEMENT static inline
|
|
void Proc::halt()
|
|
{
|
|
Status f = cli_save();
|
|
asm volatile("dsb \n\t"
|
|
"wfi \n\t");
|
|
sti_restore(f);
|
|
}
|