Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2282 → Rev 2284

/branches/arm/kernel/arch/arm32/include/exception.h
66,25 → 66,26
#define EXC_FIQ 6
 
 
 
typedef struct {
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
uint32_t r8;
uint32_t r9;
uint32_t r10;
uint32_t r11;
uint32_t r12;
uint32_t sp;
uint32_t lr;
uint32_t spsr;
uint32_t prev_sp;
uint32_t prev_lr;
 
uint32_t spsr;
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
uint32_t r8;
uint32_t r9;
uint32_t r10;
uint32_t r11;
uint32_t r12;
uint32_t sp;
uint32_t lr;
} istate_t;
 
static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
/branches/arm/kernel/arch/arm32/src/exception.c
40,6 → 40,7
#include <interrupt.h>
#include <arch/drivers/gxemul.h>
#include <arch/mm/page_fault.h>
#include <print.h>
 
#define PREFETCH_OFFSET 0x8
#define BRANCH_OPCODE 0xea000000
48,34 → 49,128
#define EXC_VECTORS_SIZE 0x20
#define EXC_VECTORS 0x8
 
extern uintptr_t supervisor_sp;
extern uintptr_t exc_stack;
 
inline static void setup_stack_and_save_regs()
{
asm volatile( "ldr r13, =exc_stack \n\
stmfd r13!, {r0} \n\
mrs r0, spsr \n\
and r0, r0, #0x1f \n\
cmp r0, #0x10 \n\
bne 1f \n\
\n\
@prev mode was usermode \n\
ldmfd r13!, {r0} \n\
ldr r13, =supervisor_sp \n\
stmfd r13!, {r0-r12, r13, lr} \n\
stmfd r13!, {r13, lr}^ \n\
mrs r0, spsr \n\
stmfd r13!, {r0} \n\
b 2f \n\
\n\
@prev mode was not usermode \n\
1: \n\
stmfd r13!, {r1, r2, r3} \n\
mrs r1, cpsr \n\
mov r2, lr \n\
bic r1, r1, #0x1f \n\
orr r1, r1, r0 \n\
mrs r0, cpsr \n\
msr cpsr_c, r1 \n\
\n\
mov r3, r13 \n\
stmfd r13!, {r2} \n\
stmfd r13!, {r3} \n\
stmfd r13!, {r4-r12} \n\
mov r2, lr \n\
mov r1, r13 \n\
msr cpsr_c, r0 \n\
\n\
ldmfd r13!, {r4, r5, r6, r7} \n\
stmfd r1!, {r4, r5, r6} \n\
stmfd r1!, {r7} \n\
stmfd r1!, {r2} \n\
stmfd r1!, {r3} \n\
mrs r0, spsr \n\
stmfd r1!, {r0} \n\
mov r13, r1 \n\
2:"
);
}
 
 
inline static void load_regs()
{
asm volatile( "ldmfd r13!, {r0} \n\
msr spsr, r0 \n\
and r0, r0, #0x1f \n\
cmp r0, #0x10 \n\
bne 3f \n\
\n\
@return to user mode \n\
ldmfd r13!, {r13, lr}^ \n\
b 4f \n\
\n\
@return to non-user mode \n\
3: \n\
ldmfd r13!, {r1, r2} \n\
mrs r3, cpsr \n\
bic r3, r3, #0x1f \n\
orr r3, r3, r0 \n\
mrs r0, cpsr \n\
msr cpsr_c, r3 \n\
\n\
mov r13, r1 \n\
mov lr, r2 \n\
msr cpsr_c, r0 \n\
\n\
@actual return \n\
4: \n\
ldmfd r13!, {r0-r12, r13, pc}^"
);
}
 
 
#define SAVE_REGS_TO_STACK \
asm("stmfd sp!, {r0-r12, sp, lr}"); \
asm("stmfd r13!, {r0-r12, r13, lr}"); \
asm("mrs r14, spsr"); \
asm("stmfd sp!, {r14}");
asm("stmfd r13!, {r14}");
 
 
 
#define CALL_EXC_DISPATCH(exception) \
asm("mov r0, %0" : : "i" (exception)); \
asm("mov r1, sp"); \
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 sp!, {r14}"); \
asm("ldmfd r13!, {r14}"); \
asm("msr spsr, r14"); \
asm("ldmfd sp!, {r0-r12, sp, pc}^");
asm("ldmfd r13!, {r0-r12, r13, pc}^");
 
 
/** General exception handler.
* Stores registers, dispatches the exception,
* and finally restores registers and returns from exception processing.
*/
 
#define PROCESS_EXCEPTION(exception) \
SAVE_REGS_TO_STACK \
setup_stack_and_save_regs(); \
CALL_EXC_DISPATCH(exception) \
LOAD_REGS_FROM_STACK
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.
*/
91,8 → 186,10
/* store handler's address */
*(vector + EXC_VECTORS) = handler_addr;
 
}
 
 
static void reset_exception_entry()
{
PROCESS_EXCEPTION(EXC_RESET);
135,10 → 232,27
static void irq_exception_entry()
{
asm("sub lr, lr, #4");
// SAVE_REGS_TO_STACK
// CALL_EXC_DISPATCH(EXC_IRQ)
// LOAD_REGS_FROM_STACK;
PROCESS_EXCEPTION(EXC_IRQ);
}
 
// static void prefetch_abort_exception(int exc_no, istate_t* istate)
// {
// dputs("(PREFETCH|DATA) ABORT exception caught, not processed.\n");
// }
 
static void swi_exception(int exc_no, istate_t* istate)
{
dprintf("\nIstate dump:\n");
dprintf(" r0:%X r1:%X r2:%X r3:%X\n", istate->r0, istate->r1, istate->r2, istate->r3);
dprintf(" r4:%X r5:%X r6:%X r7:%X\n", istate->r4, istate->r5, istate->r6, istate->r7);
dprintf(" r8:%X r9:%X r10:%X r11:%X\n", istate->r8, istate->r9, istate->r10, istate->r11);
dprintf(" r12:%X r13:%X lr:%X spsr:%X\n", istate->r12, istate->sp, istate->lr, istate->spsr);
dprintf(" prev_lr:%X prev_sp:%X\n", istate->prev_lr, istate->prev_sp);
}
 
/** Interrupt Exception handler.
* Determines the sources of interrupt, and calls their handlers.
*/
206,7 → 320,7
install_handler((unsigned)data_abort_exception_entry,
(unsigned*)EXC_DATA_ABORT_VEC);
install_handler((unsigned)irq_exception_entry,
install_handler((unsigned)irq_exception_entry,
(unsigned*)EXC_IRQ_VEC);
install_handler((unsigned)fiq_exception_entry,
213,6 → 327,7
(unsigned*)EXC_FIQ_VEC);
}
 
#ifdef HIGH_EXCEPTION_VECTORS
/** Activates using high exception vectors addresses. */
static void high_vectors()
{
225,8 → 340,8
asm volatile( "mcr p15, 0, %0, c1, c1" : : "r" (control_reg));
}
#endif
 
 
/** Initializes exception handling.
*
* Installs low-level exception handlers and then registers
237,39 → 352,42
#ifdef HIGH_EXCEPTION_VECTORS
high_vectors();
#endif
 
install_exception_handlers();
exc_register(EXC_IRQ, "interrupt", (iroutine) irq_exception);
exc_register(EXC_PREFETCH_ABORT, "prefetch abort", (iroutine) prefetch_abort);
exc_register(EXC_DATA_ABORT, "data abort", (iroutine) data_abort);
/* TODO add next */
exc_register(EXC_SWI, "software interrupt", (iroutine) swi_exception);
/* TODO add next */
}
 
/* TODO change soon, temporary hack. */
/** Sets stack pointers in all supported exception modes.
*
* @param stack_ptr stack pointer
*/
void setup_exception_stacks()
{
/* switch to particular mode and set "sp" there */
/* switch to particular mode and set "r13" there */
 
uint32_t cspr = current_status_reg_read();
uint32_t cspr = current_status_reg_read();
 
/* IRQ stack */
current_status_reg_control_write(
(cspr & ~STATUS_REG_MODE_MASK) | IRQ_MODE
);
asm("ldr sp, =irq_stack");
/* 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 sp, =abort_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 */
/* 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);
current_status_reg_control_write( cspr);
 
}
 
/branches/arm/kernel/arch/arm32/src/arm32.c
47,9 → 47,10
#include <config.h>
#include <interrupt.h>
#include <arch/regutils.h>
//#include <arch/drivers/init.h>
#include <arch/drivers/gxemul.h>
#include <userspace.h>
bootinfo_t bootinfo;
uintptr_t supervisor_sp /*__attribute__ ((section (".text")))*/;
 
//TODO: Remove include and move into exceptio.c
#include <arch/exception.h>
96,9 → 97,6
init.tasks[i].addr = bootinfo.tasks[i].addr;
init.tasks[i].size = bootinfo.tasks[i].size;
}
 
/* TODO this code just setups irq testing bed */
setup_exception_stacks();
}
 
void arch_pre_mm_init(void)
107,6 → 105,9
 
/* It is not assumed by default */
interrupts_disable();
 
setup_exception_stacks();
 
}
 
114,29 → 115,22
 
void arch_post_mm_init(void)
{
dprintf("arch_post_mm_init start()\n");
/* Initialize dispatch table
Note: Have to be after page_init() */
// dprintf("arch_post_mm_init start()\n");
gxemul_hw_map_init();
 
/* Initialize dispatch table */
exception_init();
 
// drivers_init();
// drivers_init();
interrupt_init();
// console_init(device_assign_devno());
console_init(device_assign_devno());
//fb_init(0x12000000, 640, 480, 1920, VISUAL_RGB_8_8_8);
// interrupts_enable();
// asm __volatile__ ("ldr pc, =0x70000000"); // prefetch exception
//while(1);
/*
uspace_arg_t uspace;
uspace.uspace_entry = (void*)prefetch_exception_generator;
uspace.uspace_stack = (void*)0x6000000;
uspace.uspace_uarg = &uspace;
interrupts_enable();
dprintf("arch_post_mm_init end()\n");
// while(1);
userspace(&uspace);
*/
dprintf("arch_post_mm_init end()\n");
}
 
void arch_post_cpu_init(void)
163,7 → 157,7
/** Perform arm32 specific tasks needed before the new thread is scheduled. */
void before_thread_runs_arch(void)
{
/* TODO */
supervisor_sp = (uintptr_t) &THREAD->kstack/*[THREAD_STACK_SIZE-SP_DELTA]*/;
}
 
void after_thread_ran_arch(void)
/branches/arm/kernel/arch/arm32/src/mm/page_fault.c
38,6 → 38,7
#include <mm/as.h>
#include <genarch/mm/page_pt.h>
#include <arch.h>
#include <interrupt.h>
 
 
//TODO: remove in final version
137,17 → 138,17
// get instruction op code
instruction_t i_code = *(tmp.instr);
 
dprintf("get_instruction_memmory_access\n");
dprintf(" instr_addr:%X\n",instr_addr);
dprintf(" i_code:%X\n",i_code);
dprintf(" i_code.condition:%d\n", i_code.condition);
dprintf(" i_code.instr_type:%d\n",i_code.instr_type);
dprintf(" i_code.opcode:%d\n",i_code.opcode);
dprintf(" i_code.acess:%d\n", i_code.access);
dprintf(" i_code.dummy:%d\n", i_code.dummy);
dprintf(" i_code.bits567%d\n", i_code.bits567);
dprintf(" i_code.bit4:%d\n", i_code.bit4);
dprintf(" i_code.dummy1:%d\n", i_code.dummy1);
// dprintf("get_instruction_memmory_access\n");
// dprintf(" instr_addr:%X\n",instr_addr);
// dprintf(" i_code:%X\n",i_code);
// dprintf(" i_code.condition:%d\n", i_code.condition);
// dprintf(" i_code.instr_type:%d\n",i_code.instr_type);
// dprintf(" i_code.opcode:%d\n",i_code.opcode);
// dprintf(" i_code.acess:%d\n", i_code.access);
// dprintf(" i_code.dummy:%d\n", i_code.dummy);
// dprintf(" i_code.bits567%d\n", i_code.bits567);
// dprintf(" i_code.bit4:%d\n", i_code.bit4);
// dprintf(" i_code.dummy1:%d\n", i_code.dummy1);
 
 
// undefined instructions ... (or special instructions)
209,11 → 210,11
 
pf_access_t access = get_memmory_access_type( istate->lr, page);
 
print_istate(istate);
// print_istate(istate);
dprintf(" page fault : ip:%X, va:%X, status:%x(%x), access:%d\n", istate->lr, page, fsr.status,fsr, access);
 
/* Alf: Will be commented until stack problem will be solved ...
as_page_fault make consequent page faults
as_page_fault make consequent page faults*/
 
int ret = as_page_fault(page, access, istate);
dprintf(" as_page_fault ret:%d\n", ret);
222,7 → 223,7
 
panic("page fault\n");
}
*/
 
// TODO: Remove this ... now for testing purposes ... it's bad to test page faults in kernel, where no page faults should occures
panic("page fault ... solved\n");
 
240,7 → 241,7
dprintf(" prefetch_abourt ... instruction on adress:%x can't be fetched\n", istate->lr);
 
/* Alf: Will be commented until stack problem will be solved ...
as_page_fault make consequent page faults
as_page_fault make consequent page faults*/
 
int ret = as_page_fault(istate->lr, PF_ACCESS_EXEC, istate);
dprintf(" as_page_fault ret:%d\n", ret);
247,8 → 248,8
if (ret == AS_PF_FAULT) {
panic("page fault - instruction fetch at addr:%X\n", istate->lr);
}
*/
 
 
panic("Prefetch abourt ... solved");
}
 
/branches/arm/kernel/arch/arm32/src/mm/page.c
74,9 → 74,15
// TODO: move to the kernel space
// page_mapping_insert(AS_KERNEL, 0xffff0000, 0x00000000, flags);
// TODO: remove when aux_printf not needed
page_mapping_insert(AS_KERNEL, 0x10000000, 0x10000000, flags);
// page_mapping_insert(AS_KERNEL, 0x0000000, 0x0000000, flags);
page_mapping_insert(AS_KERNEL, 0x1000000, 0x1000000, flags);
// page_mapping_insert(AS_KERNEL, 0x1100000, 0x1100000, flags);
// page_mapping_insert(AS_KERNEL, 0x1500000, 0x1500000, flags);
// page_mapping_insert(AS_KERNEL, 0x1600000, 0x1600000, flags);
 
// page_mapping_insert(AS_KERNEL, 0xffff0000, 0xffff0000, flags);
 
 
as_switch(NULL, AS_KERNEL);
 
}
/branches/arm/kernel/arch/arm32/src/drivers/gxemul.c
79,7 → 79,7
 
 
/** Initializes #gxemul_hw_map. */
void machine_hw_map_init(void)
void gxemul_hw_map_init(void)
{
gxemul_hw_map.videoram = hw_map(GXEMUL_VIDEORAM, PAGE_SIZE);
gxemul_hw_map.kbd = hw_map(GXEMUL_KBD, PAGE_SIZE);
143,8 → 143,7
ch = '\n';
if (ch == 0x7f)
ch = '\b';
//chardev_push_character(&console, ch);
printf("%c", ch);
chardev_push_character(&console, ch);
}
}
 
254,8 → 253,7
* Release the lock, call clock() and reacquire the lock again.
*/
spinlock_unlock(&irq->lock);
//clock();
puts(" ");
// clock();
spinlock_lock(&irq->lock);
 
/* acknowledge tick */
293,7 → 291,9
}
 
void gxemul_debug_putc(char ch) {
*((volatile char *) GXEMUL_KBD) = ch;
// *((volatile char *) GXEMUL_KBD) = ch;
//TODO commented version doesn't work, don't know why (as ??
*((char *) gxemul_hw_map.videoram) = ch;
}
 
/** @}
/branches/arm/kernel/arch/arm32/src/start.S
31,11 → 31,11
.text
 
.global kernel_image_start
.global irq_stack
.global abort_stack
.global exc_stack
.global exc_stack
.global supervisor_sp
 
 
kernel_image_start:
 
ldr sp, =end_stack
67,12 → 67,7
.space TEMP_STACK_SIZE
end_stack:
.space 1024
irq_stack:
.space 1024
abort_stack:
.space 1024
exc_stack:
 
.space 4
supervisor_sp:
.space 4