/*
* Copyright (c) 2007 Michal Kebrt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @addtogroup arm32
* @{
*/
/** @file
*/
#include <arch.h>
#include <arch/boot.h>
#include <config.h>
#include <arch/console.h>
#include <ddi/device.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
#include <ddi/irq.h>
#include <arch/debug_print/print.h>
#include <print.h>
#include <config.h>
#include <interrupt.h>
#include <arch/regutils.h>
#include <arch/drivers/gxemul.h>
#include <userspace.h>
bootinfo_t bootinfo;
// // uintptr_t supervisor_sp /*__attribute__ ((section (".text")))*/;
extern uintptr_t supervisor_sp;
//TODO: Remove include and move into exceptio.c
#include <arch/exception.h>
#include <syscall/syscall.h>
void tmp_swi_exception(int exc_no, istate_t* istate);
void tmp_swi_exception(int exc_no, istate_t* istate)
{
ASSERT(exc_no == EXC_SWI);
ASSERT(istate);
// TODO: Alf ... remove aftet swi_exception is tested
dprintf("\nSWI - istate dump input :\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 r8:%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->r12, istate->prev_lr, istate->prev_sp);
// call kernel to serve syscall
istate->r0 = syscall_handler(
istate->r0,
istate->r1,
istate->r2,
istate->r3,
istate->r4);
// TODO: Alf ... remove aftet swi_exception is tested
dprintf("\nSWI - Istate dump after :\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 r8:%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->r12, istate->prev_lr, istate->prev_sp);
}
void arch_pre_main(void)
{
dprintf("arch_pre_main\n");
int i;
init.cnt = bootinfo.cnt;
for (i = 0; i < bootinfo.cnt; ++i) {
init.tasks[i].addr = bootinfo.tasks[i].addr;
init.tasks[i].size = bootinfo.tasks[i].size;
}
}
void arch_pre_mm_init(void)
{
dprintf("arch_pre_mm_init\n");
/* It is not assumed by default */
interrupts_disable();
setup_exception_stacks();
}
void prefetch_exception_generator(void);
void arch_post_mm_init(void)
{
// dprintf("arch_post_mm_init start()\n");
gxemul_hw_map_init();
/* Initialize dispatch table */
exception_init();
// drivers_init();
interrupt_init();
console_init(device_assign_devno());
//fb_init(0x12000000, 640, 480, 1920, VISUAL_RGB_8_8_8);
interrupts_enable();
dprintf("arch_post_mm_init end()\n");
}
void arch_post_cpu_init(void)
{
/* TODO */
}
void arch_pre_smp_init(void)
{
/* TODO */
}
void arch_post_smp_init(void)
{
/* TODO */
}
/** Perform arm32 specific tasks needed before the new task is run. */
void before_task_runs_arch(void)
{
/* TODO */
}
/** Perform arm32 specific tasks needed before the new thread is scheduled. */
void before_thread_runs_arch(void)
{
supervisor_sp = (uintptr_t) &THREAD->kstack/*[THREAD_STACK_SIZE-SP_DELTA]*/;
}
void after_thread_ran_arch(void)
{
/* TODO */
}
/** Struct to hold general purpose register values */
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 pc;
} ustate_t;
void prefetch_exception_generator(void) {
asm __volatile__ (
"ldr pc, =0x7000000"
);
}
/** Change processor mode and jump into addres specified in
* kernel_uarg.uspace_entry
* \param kernel_uarg information needed for correct setting of userspace
*/
void userspace(uspace_arg_t *kernel_uarg)
{
// WILL be changed .. after exception return .. eret will be done
/*
volatile ustate_t ustate;
dprintf("userspce krnl_uard .uspace_uarg(%X), .uspace_entry(%X), .uspace_stack(%X)\n",
(unsigned int)(kernel_uarg->uspace_uarg),
kernel_uarg->uspace_entry,
kernel_uarg->uspace_stack);
// Step 1 ... prepare user space environmen
// set first paramater
ustate.r0 = (uintptr_t) kernel_uarg->uspace_uarg;
// clear other registers
ustate.r1 = ustate.r2 = ustate.r3 = ustate.r4 =
ustate.r5 = ustate.r6 = ustate.r7 = ustate.r8 =
ustate.r9 = ustate.r10 = ustate.r11 = ustate.r12 = 1;
ustate.lr = 3;
// set user stack
ustate.sp = ((uint32_t)kernel_uarg->uspace_stack)+PAGE_SIZE;
// set where uspace executin starts
ustate.pc = (uintptr_t) kernel_uarg->uspace_entry;
// status register in user mode
ipl_t cpsr = current_status_reg_read();
cpsr &= ~STATUS_REG_MODE_MASK | USER_MODE;
//
ipl_t tmpsr = (cpsr & ~STATUS_REG_MODE_MASK) | ABORT_MODE;
asm __volatile__ (
"mov r0, %0 \n" // save pointer into ustate struct
"mov r1, %1 \n" // save cspr
"msr cpsr_c, %2 \n" // change mode into any exception mode
"msr spsr_c, r1 \n" // set saved cpsr ... as user mode
"ldmfd r0, {r0-r12, sp, lr, pc}^\n" // jump into user mode
: // no output
: "r"(&ustate), "r"(cpsr), "r"(tmpsr) //
: "r0","r1"
);
*/
while(1)
;
}
/** @}
*/