mirror of
https://github.com/drasko/codezero.git
synced 2026-03-19 18:51:49 +01:00
Kernel updates since December 2009
This commit is contained in:
@@ -1,78 +1,57 @@
|
||||
/*
|
||||
* Definitions for exception support on ARM
|
||||
* Common definitions for exceptions
|
||||
* across ARM sub-architectures.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
* Copyright (C) 2010 B Labs Ltd.
|
||||
*/
|
||||
#ifndef __ARCH_EXCEPTIONS_H__
|
||||
#define __ARCH_EXCEPTIONS_H__
|
||||
|
||||
#ifndef __EXCEPTION_H__
|
||||
#define __EXCEPTION_H__
|
||||
|
||||
#include INC_SUBARCH(exception.h)
|
||||
#include INC_ARCH(asm.h)
|
||||
|
||||
|
||||
static inline void enable_irqs()
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"mrs r0, cpsr_fc\n"
|
||||
"bic r0, r0, #0x80\n" /* ARM_IRQ_BIT */
|
||||
"msr cpsr_fc, r0\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
static inline void disable_irqs()
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"mrs r0, cpsr_fc\n"
|
||||
"orr r0, r0, #0x80\n" /* ARM_IRQ_BIT */
|
||||
"msr cpsr_fc, r0\n"
|
||||
);
|
||||
}
|
||||
|
||||
int irqs_enabled();
|
||||
|
||||
/* Disable the irqs unconditionally, but also keep the previous state such that
|
||||
* if it was already disabled before the call, the restore call would retain
|
||||
* this state. */
|
||||
void irq_local_disable_save(unsigned long *state);
|
||||
#if 0
|
||||
{
|
||||
unsigned long temp;
|
||||
__asm__ __volatile__ (
|
||||
"mrs %0, cpsr_fc\n"
|
||||
"orr %2, %0, #0x80\n"
|
||||
"msr cpsr_fc, %2\n"
|
||||
: "=r" (*state)
|
||||
: "r" (*state),"r" (temp)
|
||||
);
|
||||
}
|
||||
/* Abort debugging conditions */
|
||||
//#define DEBUG_ABORTS
|
||||
#if defined (DEBUG_ABORTS)
|
||||
#define dbg_abort(...) printk(__VA_ARGS__)
|
||||
#else
|
||||
#define dbg_abort(...)
|
||||
#endif
|
||||
|
||||
/* Simply change it back to original state supplied in @flags. This might enable
|
||||
* or retain disabled state of the irqs for example. Useful for nested calls. */
|
||||
void irq_local_restore(unsigned long state);
|
||||
/* Codezero-specific abort type */
|
||||
#define ABORT_TYPE_PREFETCH 1
|
||||
#define ABORT_TYPE_DATA 0
|
||||
|
||||
static inline void irq_local_enable()
|
||||
{
|
||||
enable_irqs();
|
||||
}
|
||||
/* If abort is handled and resolved in check_aborts */
|
||||
#define ABORT_HANDLED 1
|
||||
|
||||
/* Codezero makes use of bit 8 (Always Zero) of FSR to define which type of abort */
|
||||
#define set_abort_type(fsr, x) { fsr &= ~(1 << 8); fsr |= ((x & 1) << 8); }
|
||||
#define is_prefetch_abort(fsr) ((fsr >> 8) & 0x1)
|
||||
#define is_data_abort(fsr) (!is_prefetch_abort(fsr))
|
||||
|
||||
/* Kernel's data about the fault */
|
||||
typedef struct fault_kdata {
|
||||
u32 faulty_pc; /* In DABT: Aborting PC, In PABT: Same as FAR */
|
||||
u32 fsr; /* In DABT: DFSR, In PABT: IFSR */
|
||||
u32 far; /* In DABT: DFAR, in PABT: IFAR */
|
||||
pte_t pte; /* Faulty page table entry */
|
||||
} __attribute__ ((__packed__)) fault_kdata_t;
|
||||
|
||||
static inline void irq_local_disable()
|
||||
{
|
||||
disable_irqs();
|
||||
}
|
||||
|
||||
/* This is filled on entry to irq handler, only if a process was interrupted.*/
|
||||
extern unsigned int preempted_psr;
|
||||
|
||||
/*
|
||||
* FIXME: TASK_IN_KERNEL works for non-current tasks, in_kernel() works for current task?
|
||||
* in_kernel() is for irq, since normally in process context you know if you are in kernel or not :-)
|
||||
*/
|
||||
|
||||
/* Implementing these as functions cause circular include dependency for tcb.h */
|
||||
#define TASK_IN_KERNEL(tcb) (((tcb)->context.spsr & ARM_MODE_MASK) == ARM_MODE_SVC)
|
||||
#define TASK_IN_USER(tcb) (!TASK_IN_KERNEL(tcb))
|
||||
|
||||
static inline int is_user_mode(u32 spsr)
|
||||
{
|
||||
return ((spsr & ARM_MODE_MASK) == ARM_MODE_USR);
|
||||
}
|
||||
|
||||
static inline int in_kernel()
|
||||
{
|
||||
return (((preempted_psr & ARM_MODE_MASK) == ARM_MODE_SVC)) ? 1 : 0;
|
||||
@@ -86,4 +65,9 @@ static inline int in_user()
|
||||
int pager_pagein_request(unsigned long vaddr, unsigned long size,
|
||||
unsigned int flags);
|
||||
|
||||
#endif
|
||||
int fault_ipc_to_pager(u32 faulty_pc, u32 fsr, u32 far, u32 ipc_tag);
|
||||
|
||||
int is_kernel_abort(u32 faulted_pc, u32 fsr, u32 far, u32 spsr);
|
||||
int check_abort_type(u32 faulted_pc, u32 fsr, u32 far, u32 spsr);
|
||||
|
||||
#endif /* __EXCEPTION_H__ */
|
||||
|
||||
Reference in New Issue
Block a user