Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2354 → Rev 2355

/branches/arm/kernel/arch/arm32/include/exception.h
91,7 → 91,11
} istate_t;
 
 
 
/** Sets Program Counter member of given istate structure.
*
* @param istate istate structure
* @param retaddr new value of istate's PC member
*/
static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
{
istate->pc = retaddr;
98,13 → 102,13
}
 
 
/** Return true if exception happened while in userspace. */
/** Returns true if exception happened while in userspace. */
static inline int istate_from_uspace(istate_t *istate)
{
return (istate->spsr & STATUS_REG_MODE_MASK) == USER_MODE;
}
 
 
/** Returns Program Counter member of given istate structure. */
static inline unative_t istate_get_pc(istate_t *istate)
{
return istate->pc;
/branches/arm/kernel/arch/arm32/src/exception.c
56,28 → 56,13
extern uintptr_t supervisor_sp;
extern uintptr_t exc_stack;
 
 
/** Switches to kernel stack and saves all registers there.
*
* Temporary exception stack is used to save a few registers
* before stack switch takes place.
*/
inline static void setup_stack_and_save_regs()
{
/*
 
str r0, =exc_stack
str r1, =exc_stack + 4
mrs r0, cpsr
mrs r1, spsr
and r0, r0, #0x1f
and r1, r1, #0x1f
cmp r0, r1
be 3f
@different exception mode => preserve sp
ldr r1, [=exc_stack + 4]
ldr r0, [=exc_stack]
 
3:
mrs r0, spsr
stmfd sp!, {r0, sp, lr}
*/
asm volatile("ldr r13, =exc_stack \n\
stmfd r13!, {r0} \n\
mrs r0, spsr \n\
128,7 → 113,11
);
}
 
 
/** Returns from exception mode.
*
* Previously saved state of registers (including control register)
* is restored from the stack.
*/
inline static void load_regs()
{
asm volatile( "ldmfd r13!, {r0} \n\
159,32 → 148,15
);
}
 
 
 
/*#define SAVE_REGS_TO_STACK \
asm("stmfd r13!, {r0-r12, r13, lr}"); \
asm("mrs r14, spsr"); \
asm("stmfd r13!, {r14}");
*/
 
 
/** Calls exception dispatch routine. */
#define CALL_EXC_DISPATCH(exception) \
asm("mov r0, %0" : : "i" (exception)); \
asm("mov r1, r13"); \
asm("bl exc_dispatch");
 
 
/**Loads registers from the stack and resets SPSR before exitting exception
* handler.
#define LOAD_REGS_FROM_STACK \
asm("ldmfd r13!, {r14}"); \
asm("msr spsr, r14"); \
asm("ldmfd r13!, {r0-r12, r13, pc}^");
*/
 
/** General exception handler.
*
* Stores registers, dispatches the exception,
* and finally restores registers and returns from exception processing.
*
195,13 → 167,9
CALL_EXC_DISPATCH(exception) \
load_regs();
 
/* #define PROCESS_EXCEPTION(exception) \
SAVE_REGS_TO_STACK \
CALL_EXC_DISPATCH(exception) \
LOAD_REGS_FROM_STACK*/
 
 
/** Updates specified exception vector to jump to given handler.
*
* Addresses of handlers are stored in memory following exception vectors.
*/
static void install_handler (unsigned handler_addr, unsigned* vector)
264,7 → 232,12
}
 
 
/** Low-level Interrupt Exception handler. */
/** Low-level Interrupt Exception handler.
*
* CPU is switched to Undefined mode before further interrupt processing
* because of possible occurence of nested interrupt exception, which
* would overwrite (and thus spoil) stack pointer.
*/
static void irq_exception_entry()
{
asm("sub lr, lr, #4");
274,7 → 247,6
asm("stmfd sp!, {r0-r3}");
asm("mov r1, sp");
asm("mov r2, lr");
// asm("mrs r3, spsr");
asm("mrs r0, cpsr");
asm("bic r0, r0, #0x1f");
asm("orr r0, r0, #0x1b");
281,7 → 253,6
asm("msr cpsr_c, r0");
asm("mov sp, r1");
asm("mov lr, r2");
// asm("msr spsr, r3");
asm("ldmfd sp!, {r0-r3}");
 
CALL_EXC_DISPATCH(EXC_IRQ)
378,37 → 349,9
exc_register(EXC_PREFETCH_ABORT, "prefetch abort", (iroutine) prefetch_abort);
exc_register(EXC_DATA_ABORT, "data abort", (iroutine) data_abort);
exc_register(EXC_SWI, "software interrupt", (iroutine) swi_exception);
/* TODO add next */
}
 
 
/** Sets stack pointers in all supported exception modes. */
void setup_exception_stacks()
{
/* switch to particular mode and set "r13" there */
 
uint32_t cspr = current_status_reg_read();
 
/* IRQ stack */
current_status_reg_control_write(
(cspr & ~STATUS_REG_MODE_MASK) | IRQ_MODE
);
asm("ldr r13, =exc_stack");
 
/* abort stack */
current_status_reg_control_write(
(cspr & ~STATUS_REG_MODE_MASK) | ABORT_MODE
);
asm("ldr r13, =exc_stack");
 
/* TODO if you want to test other exceptions than IRQ,
make stack analogous to irq_stack (in start.S),
and then set stack pointer here */
 
current_status_reg_control_write(cspr);
}
 
 
/** Prints #istate_t structure content.
*
* @param istate Structure to be printed.
/branches/arm/kernel/arch/arm32/src/arm32.c
50,7 → 50,6
#include <userspace.h>
 
bootinfo_t bootinfo;
// // uintptr_t supervisor_sp /*__attribute__ ((section (".text")))*/;
extern uintptr_t supervisor_sp;
 
 
72,8 → 71,6
{
/* It is not assumed by default */
interrupts_disable();
 
setup_exception_stacks();
}
 
 
157,9 → 154,9
*/
void userspace(uspace_arg_t *kernel_uarg)
{
dprintf("Userspace: .uspace_uarg(%X), .uspace_entry(%X), .uspace_stack(%X)\n",
(unsigned int)(kernel_uarg->uspace_uarg), kernel_uarg->uspace_entry,
kernel_uarg->uspace_stack);
// dprintf("Userspace: .uspace_uarg(%X), .uspace_entry(%X), .uspace_stack(%X)\n",
// (unsigned int)(kernel_uarg->uspace_uarg), kernel_uarg->uspace_entry,
// kernel_uarg->uspace_stack);
 
volatile ustate_t ustate;
 
/branches/arm/kernel/arch/arm32/src/drivers/gxemul.c
45,7 → 45,7
#include <arch/debug/print.h>
 
 
/** Address of devices. */
/** Addresses of devices. */
#define GXEMUL_VIDEORAM 0x10000000
#define GXEMUL_KBD 0x10000000
#define GXEMUL_HALT_OFFSET 0x10
83,7 → 83,7
.read = gxemul_do_read,
};
 
/** Return the mask of active interrupts. */
/** Returns the mask of active interrupts. */
static inline uint32_t gxemul_irqc_get_sources(void)
{
return *(uint32_t*) gxemul_hw_map.irqc;
238,6 → 238,10
return IRQ_ACCEPT;
}
 
/** Timer interrupt handler.
*
* @param irq interrupt information
*/
static void gxemul_timer_irq_handler(irq_t *irq, void *arg, ...)
{
/* TODO time drifts ??
269,8 → 273,7
*/
}
 
/**
* Initializes and registers timer interrupt handler.
/** Initializes and registers timer interrupt handler.
*/
static void gxemul_timer_irq_init()
{
283,6 → 286,11
irq_register(&gxemul_timer_irq);
}
 
/** Starts timer.
*
* Initiates regular timer interrupts after initializing
* corresponding interrupt handler.
*/
void machine_timer_irq_start()
{
gxemul_timer_irq_init();
289,6 → 297,10
gxemul_timer_start(GXEMUL_TIMER_FREQ);
}
 
/** Returns the size of emulated memory.
*
* @return size in bytes
*/
size_t machine_get_memory_size(void)
{
return *((int*)(GXEMUL_MP + GXEMUL_MP_MEMSIZE_OFFSET));
306,6 → 318,7
*(addr) = ch;
}
 
/** Stops gxemul. */
void machine_cpu_halt(void)
{
char * addr = 0;
318,26 → 331,16
*(addr + GXEMUL_HALT_OFFSET) = '\0';
}
 
/** Gxemul specific interrupt exception handler.
*
* Determines sources of the interrupt from interrupt controller and
* calls high-level handlers for them.
*
* @param exc_no interrupt exception number
* @param istate saved processor state
*/
void machine_irq_exception(int exc_no, istate_t *istate)
{
/* switch to Undefined mode */
/*
asm volatile(
"stmfd sp!, {r0-r3}\n"
"mov r1, sp\n"
"mov r2, lr\n"
"mrs r3, spsr\n"
"mrs r0, cpsr\n"
"bic r0, r0, #0x1f\n"
"orr r0, r0, #0x1b\n"
"msr cpsr_c, r0\n"
"mov sp, r1\n"
"mov lr, r2\n"
"msr spsr, r3\n"
"ldmfd sp!, {r0-r3}\n"
);
*/
 
uint32_t sources = gxemul_irqc_get_sources();
int i = 0;
for (; i < GXEMUL_IRQC_MAX_IRQ; i++) {
353,28 → 356,6
}
}
}
/* TODO remove after testing the above code
noirq = 0;
if (i == CONSOLE_IRQ) {
char readchar = *(char*)0x10000000;
if (readchar == 0) {
aux_puts("?");
}
else {
dprintf("%c", readchar);
}
}
else if (i == TIMER_IRQ) {
dprintf("\n.\n");
//acknowledge
*(uint32_t*)0x15000110 = 0;
}
}
}
 
if (noirq)
aux_puts("IRQ exception without source\n");*/
}