From e27317f75d5518fde565e8b882ffd5548efa5588 Mon Sep 17 00:00:00 2001 From: schulz Date: Tue, 24 Mar 2009 21:57:06 +0000 Subject: [PATCH] RTAS support for AROS. git-svn-id: https://svn.aros.org/svn/aros/trunk/AROS@31005 fb15a70f-31f2-0310-bbcc-cdcc74a49acc --- arch/ppc-chrp/efika/kernel/intr.c | 4 +-- arch/ppc-chrp/efika/kernel/kernel_intern.h | 1 + arch/ppc-chrp/efika/kernel/mmakefile.src | 7 ++-- arch/ppc-chrp/efika/kernel/mmu.c | 28 +++++++++------- arch/ppc-chrp/efika/kernel/syscall.c | 51 ++++++++++++++++++++++++++++++ arch/ppc-chrp/efika/kernel/syscall.h | 1 + 6 files changed, 76 insertions(+), 16 deletions(-) diff --git a/arch/ppc-chrp/efika/kernel/intr.c b/arch/ppc-chrp/efika/kernel/intr.c index d6df325ac..ac19bf7ce 100644 --- a/arch/ppc-chrp/efika/kernel/intr.c +++ b/arch/ppc-chrp/efika/kernel/intr.c @@ -594,7 +594,7 @@ static void __attribute__((used)) __exception_template() "__tmpl_start: \n" " mtsprg1 %%r3 \n" /* save %r3 */ " mfcr %%r3 \n" /* copy CR to %r3 */ -" mtsprg2 %%r3 \n" /* save %r3 */ +" mtsprg3 %%r3 \n" /* save %r3 */ " mfmsr %%r3 \n" " ori %%r3,%%r3,%2 \n" /* Enable address translation for data */ @@ -621,7 +621,7 @@ static void __attribute__((used)) __exception_template() " stw %%r4, %[gpr4](%%r3) \n" /* because the exception vector is 256 bytes long */ " stw %%r0, %[gpr3](%%r3) \n" /* and shouldn't be used to anything else than */ " stw %%r5, %[gpr5](%%r3) \n" /* exception handler anyway ;) */ -" mfsprg2 %%r2 \n" +" mfsprg3 %%r2 \n" " mfsrr0 %%r0 \n" " mfsrr1 %%r1 \n" "__addr_hi: lis %%r5, 0xdeadbeef@ha\n" /* Load the address of an generic handler */ diff --git a/arch/ppc-chrp/efika/kernel/kernel_intern.h b/arch/ppc-chrp/efika/kernel/kernel_intern.h index e21e86f2f..4f6d1348e 100644 --- a/arch/ppc-chrp/efika/kernel/kernel_intern.h +++ b/arch/ppc-chrp/efika/kernel/kernel_intern.h @@ -127,6 +127,7 @@ void core_Schedule(regs_t *regs) __attribute__((noreturn)); void core_Dispatch(regs_t *regs) __attribute__((noreturn)); void core_ExitInterrupt(regs_t *regs) __attribute__((noreturn)); void core_Cause(struct ExecBase *SysBase); +int32_t core_Rtas(intptr_t rtas_args, intptr_t rtas_base, intptr_t rtas_entry); void intr_init(); void mmu_init(char *mmu_dir, uint32_t mmu_size); void ictl_init(void *); diff --git a/arch/ppc-chrp/efika/kernel/mmakefile.src b/arch/ppc-chrp/efika/kernel/mmakefile.src index 3eb9c169c..b797b25cc 100644 --- a/arch/ppc-chrp/efika/kernel/mmakefile.src +++ b/arch/ppc-chrp/efika/kernel/mmakefile.src @@ -3,11 +3,12 @@ include $(TOP)/config/make.cfg FILES := kernel_init tags debug intr mmu syscall scheduler ictl -#MM kernel-chrp-ppc-efika: setup-chrp-ppc-efika linklibs kernel-kernel-chrp-ppc-efika-kobj kernel-exec-kobj +#MM kernel-chrp-ppc-efika: setup-chrp-ppc-efika linklibs kernel-kernel-chrp-ppc-efika-kobj kernel-exec-kobj kernel-rtas-chrp-ppc-kobj + kernel-chrp-ppc-efika: $(BINDIR)/boot/aros-efika -$(BINDIR)/boot/aros-efika: $(KOBJSDIR)/kernel_resource.o $(KOBJSDIR)/exec_library.o - $(TARGET_LD) -Map $(OSGENDIR)/boot/kernel.map -T ldscript.lds -o $@ $(KOBJSDIR)/kernel_resource.o $(KOBJSDIR)/exec_library.o -L$(LIBDIR) -lrom -larosm -lautoinit -llibinit +$(BINDIR)/boot/aros-efika: $(KOBJSDIR)/kernel_resource.o $(KOBJSDIR)/exec_library.o $(KOBJSDIR)/rtas_resource.o + $(TARGET_LD) -Map $(OSGENDIR)/boot/kernel.map -T ldscript.lds -o $@ $(KOBJSDIR)/kernel_resource.o $(KOBJSDIR)/exec_library.o $(KOBJSDIR)/rtas_resource.o -L$(LIBDIR) -lrom -larosm -lautoinit -llibinit $(STRIP) --strip-unneeded $@ #MM kernel-kernel-chrp-ppc-efika : includes includes-copy-chrp-ppc-efika linklibs diff --git a/arch/ppc-chrp/efika/kernel/mmu.c b/arch/ppc-chrp/efika/kernel/mmu.c index baae0e69a..48e0e8fed 100644 --- a/arch/ppc-chrp/efika/kernel/mmu.c +++ b/arch/ppc-chrp/efika/kernel/mmu.c @@ -455,29 +455,35 @@ AROS_LH2(int, KrnUnmapGlobal, AROS_LIBFUNC_EXIT } +uintptr_t virt2phys(uintptr_t virt) +{ + uintptr_t phys = 0xffffffff; + pte_t *pte = find_pte(virt); + + if (pte) + { + phys = pte->rpn & ~0xfff; + phys |= virt & 0xfff; + } + + return phys; +} + AROS_LH1(void *, KrnVirtualToPhysical, AROS_LHA(void *, virtual, A0), struct KernelBase *, KernelBase, 0, Kernel) { AROS_LIBFUNC_INIT - pte_t *pte; uintptr_t virt = (uintptr_t)virtual; - uintptr_t phys = 0xffffffff; + uintptr_t phys; uint32_t msr = goSuper(); - pte = find_pte(virt); - - if (pte) - phys = pte->rpn & ~0xfff; + phys = virt2phys(virt); goUser(msr); - /* If the page has been found, add the offset taken from virtual address. */ - if (phys != 0xffffffff) - { - phys |= virt & 0xfff; - } + return (void*)phys; diff --git a/arch/ppc-chrp/efika/kernel/syscall.c b/arch/ppc-chrp/efika/kernel/syscall.c index 6780c7153..cf6cf9409 100644 --- a/arch/ppc-chrp/efika/kernel/syscall.c +++ b/arch/ppc-chrp/efika/kernel/syscall.c @@ -71,6 +71,10 @@ void __attribute__((noreturn)) syscall_handler(regs_t *ctx, uint8_t exception, v core_Schedule(ctx); break; + case SC_RTAS: + ctx->gpr[3] = core_Rtas(ctx->gpr[4], ctx->gpr[5], ctx->gpr[6]); + break; + case SC_INVALIDATED: { char *start = (char*)((IPTR)ctx->gpr[4] & 0xffffffe0); @@ -112,3 +116,50 @@ void __attribute__((noreturn)) syscall_handler(regs_t *ctx, uint8_t exception, v else core_LeaveInterrupt(ctx); } + +static void __attribute__((used)) __rtas_entry_template() +{ + asm volatile(".globl core_Rtas; .type core_Rtas,@function\n" +"core_Rtas: stwu %r1, -64(%r1)\n" /* Create proper stack frame */ +" mflr %r0\n" /* Store the link pointer */ +" stw %r0,68(%r1)\n" +" stw %r1,8(%r1)\n" /* Store the stack pointer for virtual space */ +" stw %r3,12(%r1)\n" /* Store the rtas call structure */ +" stw %r4,16(%r1)\n" /* Store the rtas base */ +" stw %r5,20(%r1)\n" /* Store the entry address */ +" mfmsr %r0\n" +" stw %r0,24(%r1)\n" +" lis %r0,virt2phys@ha\n" /* VirtualToPhysical function */ +" ori %r0, %r0, virt2phys@l\n" +" mtctr %r0\n" +" stw %r0,28(%r1)\n" +" lis %r3,1f@ha\n" /* Get the return point from rtas */ +" ori %r3, %r3, 1f@l\n" +" bctrl \n" +" stw %r3,32(%r1)\n" +" mr %r3, %r1\n" /* Convert the stack to physical address */ +" lwz %r0,28(%r1)\n" +" mtctr %r0\n" +" bctrl \n" +" mtsprg2 %r3\n" /* And store it in sprg2 */ +" lwz %r3,12(%r1)\n" +" lwz %r4,16(%r1)\n" +" lwz %r0,20(%r1)\n" +" mtsrr0 %r0\n" +" lwz %r0,32(%r1)\n" +" mtlr %r0\n" +" lwz %r0,24(%r1)\n" +" rlwinm %r0,%r0,0,28,25\n" +" mtsrr1 %r0\n" +" sync; isync;\n" +" rfi\n" +"1:\n" +" mfsprg2 %r5\n" /* We're back. Get the stack frame */ +" lwz %r4,24(%r5)\n" /* Old msr */ +" mtsrr1 %r4\n" +" lwz %r4,68(%r5)\n" /* Old link pointer */ +" mtsrr0 %r4\n" +" addi %r1, %r1, 64\n" +" sync; isync; rfi\n" + ); +} diff --git a/arch/ppc-chrp/efika/kernel/syscall.h b/arch/ppc-chrp/efika/kernel/syscall.h index c42960027..262be3ff5 100644 --- a/arch/ppc-chrp/efika/kernel/syscall.h +++ b/arch/ppc-chrp/efika/kernel/syscall.h @@ -10,6 +10,7 @@ #define SC_SUPERSTATE 0x006 #define SC_ISSUPERSTATE 0x007 #define SC_INVALIDATED 0x008 +#define SC_RTAS 0x009 #define SC_REBOOT 0x100 #endif /*SYSCALL_H_*/ -- 2.11.4.GIT