From 8ede2cddb46396bd969cfd5f42a39814f4e92271 Mon Sep 17 00:00:00 2001 From: schulz Date: Sat, 11 Apr 2015 20:35:17 +0000 Subject: [PATCH] SC_CACHECLEARE syscall implementation git-svn-id: https://svn.aros.org/svn/aros/trunk/AROS@50338 fb15a70f-31f2-0310-bbcc-cdcc74a49acc --- arch/arm-native/kernel/syscall.c | 52 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/arch/arm-native/kernel/syscall.c b/arch/arm-native/kernel/syscall.c index 58fc4ec657..908f3ac42c 100644 --- a/arch/arm-native/kernel/syscall.c +++ b/arch/arm-native/kernel/syscall.c @@ -53,6 +53,44 @@ asm ( VECTCOMMON_END ); +void cache_clear_e(void *addr, uint32_t length, uint32_t flags) +{ + uint32_t count = 0; + + if (addr == NULL && length == 0xffffffff) + { + count = 0x8000000; + } + else + { + void *end_addr = ((uintptr_t)addr + length + 31) & ~31; + addr = (void *)((uintptr_t)addr & ~31); + count = (uintptr_t)(end_addr - addr) >> 5; + } + + D(bug("[KRN] CacheClearE from %p length %d count %d, flags %x\n", addr, length, count, flags)); + + while (count--) + { + if (flags & CACRF_ClearD) + { + __asm__ __volatile__("mcr p15, 0, %0, c7, c14, 1"::"r"(addr)); + } + if (flags & CACRF_ClearI) + { + __asm__ __volatile__("mcr p15, 0, %0, c7, c5, 1"::"r"(addr)); + } + if (flags & CACRF_InvalidateD) + { + __asm__ __volatile__("mcr p15, 0, %0, c7, c6, 1"::"r"(addr)); + } + + addr += 32; + } + + __asm__ __volatile__("mcr p15, 0, %0, c7, c10, 4"::"r"(addr)); +} + void handle_syscall(void *regs) { register unsigned int addr; @@ -75,7 +113,7 @@ void handle_syscall(void *regs) D(bug("[KRN] ## SWI : ILLEGAL ACCESS!\n")); return; } - if (swi_no <= 0x0a || swi_no == 0x100) + if (swi_no <= 0x0b || swi_no == 0x100) { DREGS(cpu_DumpRegs(regs)); @@ -118,6 +156,18 @@ void handle_syscall(void *regs) asm volatile ("mov pc, #0\n"); // Jump to the reset vector.. break; } + + case SC_CACHECLEARE: + { + D(bug("[KRN] ## CACHECLEARE...\n")); + void * address = ((void **)regs)[0]; + uint32_t length = ((uint32_t *)regs)[1]; + uint32_t flags = ((uint32_t *)regs)[2]; + + cache_clear_e(address, length, flags); + + break; + } default: core_SysCall(swi_no, regs); break; -- 2.11.4.GIT