From: John Hodge Date: Tue, 27 Sep 2011 02:43:00 +0000 (+0800) Subject: Kernel/armv7 - Renamed to reduce confusion X-Git-Tag: rel0.11~45 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=acc4756d2e22346862ec098be4a18f52846f6dc4;p=tpg%2Facess2.git Kernel/armv7 - Renamed to reduce confusion --- diff --git a/Kernel/arch/arm7/Makefile b/Kernel/arch/arm7/Makefile deleted file mode 100644 index 21da1726..00000000 --- a/Kernel/arch/arm7/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# -# Acess2 Kernel -# arm7 Architecture Makefile -# arch/arm7/Makefile - -CPPFLAGS = -CFLAGS = -ASFLAGS = - -PCI_ADDRESS=0 -ifeq ($(ARCH),integrator-cp) - MMU_PRESENT=1 -else - MMU_PRESENT=1 -endif - - - -#ASFLAGS += -D USE_MP=$(USE_MP) -D USE_PAE=$(USE_PAE) -CPPFLAGS += -DMMU_PRESENT=$(MMU_PRESENT) -DPCI_ADDRESS=$(PCI_ADDRESS) -LDFLAGS += `$(CC) --print-libgcc-file-name` - -A_OBJ = start.ao main.o lib.o time.o pci.o debug.o -A_OBJ += mm_phys.o mm_virt.o proc.o proc.ao - -main.c: Makefile.BuildNum.$(ARCH) - diff --git a/Kernel/arch/arm7/debug.c b/Kernel/arch/arm7/debug.c deleted file mode 100644 index d75048ed..00000000 --- a/Kernel/arch/arm7/debug.c +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Acess2 - * - By John Hodge (thePowersGang) - * - * arch/arm7/debug.c - * - ARM7 Debug output - * NOTE: Currently designed for the realview-pb-a8 emulated by Qemu - */ -#include - -// === CONSTANTS === -//#define UART0_BASE 0x10009000 -#define UART0_BASE 0xF1000000 // Boot time mapped - -// === PROTOTYPES === -void KernelPanic_SetMode(void); -void KernelPanic_PutChar(char Ch); -void StartupPrint(const char *str); - -// === GLOBALS === - int giDebug_SerialInitialised = 0; - -// === CODE === -void Debug_PutCharDebug(char ch) -{ -// while( *(volatile Uint32*)(SERIAL_BASE + SERIAL_REG_FLAG) & SERIAL_FLAG_FULL ) - ; - -// *(volatile Uint32*)(SERIAL_BASE + SERIAL_REG_DATA) = ch; - *(volatile Uint32*)(UART0_BASE) = ch; -} - -void Debug_PutStringDebug(const char *str) -{ - for( ; *str; str++ ) - Debug_PutCharDebug( *str ); -} - -void KernelPanic_SetMode(void) -{ -} - -void KernelPanic_PutChar(char ch) -{ -// Debug_PutCharDebug(ch); -} - -void StartupPrint(const char *str) -{ -} - diff --git a/Kernel/arch/arm7/include/arch.h b/Kernel/arch/arm7/include/arch.h deleted file mode 100644 index 36c1a3f3..00000000 --- a/Kernel/arch/arm7/include/arch.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Acess2 - * ARM7 Architecture Header - */ -#ifndef _ARCH_H_ -#define _ARCH_H_ - -// === CONSTANTS === -#define INVLPTR ((void*)-1) -#define BITS 32 -#define PAGE_SIZE 0x1000 -#define KERNEL_BASE 0x80000000 // 2GiB - -// === TYPES === -typedef unsigned int Uint; -typedef unsigned char Uint8; -typedef unsigned short Uint16; -typedef unsigned long Uint32; -typedef unsigned long long Uint64; -typedef signed int Sint; -typedef signed char Sint8; -typedef signed short Sint16; -typedef signed long Sint32; -typedef signed long long Sint64; - -typedef int size_t; -typedef char BOOL; - -typedef Uint32 tVAddr; -typedef Uint32 tPAddr; - -#include "lock.h" - -// --- Debug -extern void Debug_PutCharDebug(char Ch); -extern void Debug_PutStringDebug(const char *String); - -// This should be elsewhere, but CBF -extern void MM_SetupPhys(void); -extern int MM_InitialiseVirtual(void); - -#endif diff --git a/Kernel/arch/arm7/include/lock.h b/Kernel/arch/arm7/include/lock.h deleted file mode 100644 index 627726b5..00000000 --- a/Kernel/arch/arm7/include/lock.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Acess2 - * ARM7 Architecture - * - * lock.h - Hardware level spinlocks - */ -#ifndef _LOCK_H_ -#define _LOCK_H_ - -// === CODE === -struct sShortSpinlock { - int Lock; -}; - -// --- Spinlocks --- -static inline int IS_LOCKED(struct sShortSpinlock *Lock) -{ - return !!Lock->Lock; -} - -static inline int CPU_HAS_LOCK(struct sShortSpinlock *Lock) -{ - // TODO: Handle multiple CPUs - return !!Lock->Lock; -} - -static inline int SHORTLOCK(struct sShortSpinlock *Lock) -{ - #if 1 - // Coped from linux, yes, but I know what it does now :) - Uint tmp; - __asm__ __volatile__ ( - "1: ldrex %0, [%1]\n" // Exclusive LOAD - " teq %0, #0\n" // Check if zero - " strexeq %0, %2, [%1]\n" // Set to one if it is zero (releasing lock on the memory) - " teqeq %0, #0\n" // If the lock was avaliable, check if the write succeeded - " bne 1b" // If the lock was unavaliable, or the write failed, loop - : "=&r" (tmp) // Temp - : "r" (&Lock->Lock), "r" (1) - : "cc" // Condition codes clobbered - ); - #else - int v = 1; - while( v ) - __asm__ __volatile__ ( - "swp %0, [%1]" - : "=r" (v) : "r" (&Lock->Lock) - : "cc" - ); - #endif - return 1; -} - -static inline void SHORTREL(struct sShortSpinlock *Lock) -{ - Lock->Lock = 0; -} - -#endif - diff --git a/Kernel/arch/arm7/include/mm_virt.h b/Kernel/arch/arm7/include/mm_virt.h deleted file mode 100644 index b57e45c3..00000000 --- a/Kernel/arch/arm7/include/mm_virt.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Acess2 - * ARM7 Virtual Memory Manager Header - */ -#ifndef _MM_VIRT_H_ -#define _MM_VIRT_H_ - -#define MM_USER_MIN 0x00001000 -#define USER_LIB_MAX 0x7F800000 -#define MM_PPD_HANDLES 0x7F800000 -#define MM_TABLE0USER 0x7F900000 // 2 GiB - 16 KiB -#define MM_TABLE1USER 0x7FC00000 // 2 GiB - 4 MiB - -// Page Blocks are 12-bits wide (12 address bits used) -// Hence, the table is 16KiB large (and must be so aligned) -// and each block addresses 1MiB of data - -// First level table is aligned to 16KiB (restriction of TTBR reg) -// - VMSAv6 uses two TTBR regs, determined by bit 31 - -//#define KERNEL_BASE 0x80000000 // 2GiB - -#define MM_KHEAP_BASE 0x80800000 // 8MiB of kernel code -#define MM_KHEAP_MAX 0xC0000000 // ~1GiB of kernel heap - -#define MM_MODULE_MIN 0xC0000000 // - 0xD0000000 -#define MM_MODULE_MAX 0xD0000000 - -// PMM Data, giving it 256MiB is overkill, but it's unused atm -#define MM_MAXPHYSPAGE (1024*1024) -// 2^(32-12) max pages -// 8.125 bytes per page (for bitmap allocation) -// = 8.125 MiB -#define MM_PMM_BASE 0xE0000000 -#define MM_PMM_END 0xF0000000 - -#define MM_HWMAP_BASE 0xF0000000 // Ent 0xF00 -#define MM_HWMAP_END 0xFE000000 -#define MM_TMPMAP_BASE 0xFE000000 -#define MM_TMPMAP_END 0xFF000000 - -#define MM_KERNEL_VFS 0xFF000000 // -#define MM_TABLE1KERN 0xFF800000 // - 0x???????? 4MiB -#define MM_TABLE0KERN 0xFFC00000 // - 0xFFE04000 16KiB - -#endif diff --git a/Kernel/arch/arm7/include/proc.h b/Kernel/arch/arm7/include/proc.h deleted file mode 100644 index 1dd9b0f4..00000000 --- a/Kernel/arch/arm7/include/proc.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Acess2 - * ARM7 Architecture - * - * proc.h - Arch-Dependent Process Management - */ -#ifndef _PROC_H_ -#define _PROC_H_ - -#define MAX_CPUS 4 - -// === STRUCTURES === -typedef struct { - Uint32 IP, SP; - Uint32 UserIP, UserSP; -} tTaskState; - -typedef struct { - Uint32 Base; -} tMemoryState; - -typedef struct { - union { - Uint32 Num; - Uint32 Error; - }; - union { - Uint32 Arg1; - Uint32 Return; - }; - union { - Uint32 Arg2; - Uint32 RetHi; - }; - Uint32 Arg3; - Uint32 Arg4; - Uint32 Arg5; - Uint32 Arg6; // R6 - Uint32 Unused[13-6]; - Uint32 StackPointer; // R13 - Uint32 _lr; - Uint32 _ip; -} tSyscallRegs; - -// === MACROS === -#define HALT() do{}while(0) - -// === PROTOTYPES === - -#endif - diff --git a/Kernel/arch/arm7/lib.c b/Kernel/arch/arm7/lib.c deleted file mode 100644 index 94c1a3af..00000000 --- a/Kernel/arch/arm7/lib.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Acess2 ARM7 Port - * - * lib.c - Library Functions - */ -#include - -// === PROTOTYPES === -Uint64 __divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem); -Uint64 __udivdi3(Uint64 Num, Uint64 Den); -Uint64 __umoddi3(Uint64 Num, Uint64 Den); -Uint32 __udivsi3(Uint32 Num, Uint32 Den); -Uint32 __umodsi3(Uint32 Num, Uint32 Den); -Sint32 __divsi3(Sint32 Num, Sint32 Den); -Sint32 __modsi3(Sint32 Num, Sint32 Den); - -// === CODE === -void *memcpy(void *_dest, const void *_src, size_t _length) -{ - Uint32 *dst; - const Uint32 *src; - Uint8 *dst8 = _dest; - const Uint8 *src8 = _src; - - // Handle small copies / Non-aligned - if( _length < 4 || ((tVAddr)_dest & 3) != ((tVAddr)_src & 3) ) - { - for( ; _length--; dst8++,src8++ ) - *dst8 = *src8; - return _dest; - } - - // Force alignment - while( (tVAddr)dst8 & 3 ) *dst8 ++ = *src8++; - dst = (void *)dst8; src = (void *)src8; - - // DWORD copies - for( ; _length > 3; _length -= 4) - *dst++ = *src++; - - // Trailing bytes - dst8 = (void*)dst; src8 = (void*)src; - for( ; _length; _length -- ) - *dst8 ++ = *src8 ++; - - return _dest; -} - -int memcmp(const void *_m1, const void *_m2, size_t _length) -{ - const Uint32 *m1, *m2; - const Uint8 *m1_8 = _m1, *m2_8 = _m2; - - // Handle small copies / Non-aligned - if( _length < 4 || ((tVAddr)_m1 & 3) != ((tVAddr)_m1 & 3) ) - { - for( ; _length--; m1_8++,m2_8++ ) { - if(*m1_8 != *m2_8) return *m1_8 - *m2_8; - } - return 0; - } - - // Force alignment - for( ; (tVAddr)m1_8 & 3; m1_8 ++, m2_8 ++) { - if(*m1_8 != *m2_8) return *m1_8 - *m2_8; - } - m1 = (void *)m1_8; m2 = (void *)m2_8; - - // DWORD copies - for( ; _length > 3; _length -= 4, m1++, m2++) - if(*m1 != *m2) return *m1 - *m2; - - // Trailing bytes - m1_8 = (void*)m1; m2_8 = (void*)m2; - for( ; _length; _length --, m1_8++, m2_8++ ) - if(*m1_8 != *m2_8) return *m1_8 - *m2_8; - - return 0; -} - -void *memset(void *_dest, int _value, size_t _length) -{ - Uint32 *dst, val32; - Uint8 *dst8 = _dest; - - _value = (Uint8)_value; - - // Handle small copies / Non-aligned - if( _length < 4 ) - { - for( ; _length--; dst8++ ) - *dst8 = _value; - return _dest; - } - - val32 = _value; - val32 |= val32 << 8; - val32 |= val32 << 16; - - // Force alignment - while( (tVAddr)dst8 & 3 ) *dst8 ++ = _value; - dst = (void *)dst8; - - // DWORD copies - for( ; _length > 3; _length -= 4) - *dst++ = val32; - - // Trailing bytes - dst8 = (void*)dst; - for( ; _length; _length -- ) - *dst8 ++ = _value; - - return _dest; -} - -Uint64 __divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem) -{ - Uint64 ret, add; - - ret = 0; - add = 1; - - // Find what power of two times Den is > Num - while( Num >= Den ) - { - Den <<= 1; - add <<= 1; - } - - // Search backwards - while( add > 1 ) - { - add >>= 1; - Den >>= 1; - // If the numerator is > Den, subtract and add to return value - if( Num > Den ) - { - ret += add; - Num -= Den; - } - } - if(Rem) *Rem = Num; - return ret; -} - -Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem) -{ - Uint64 ret; - if(Den == 0) return 0; // TODO: #div0 - if(Num == 0) { - if(Rem) *Rem = 0; - return 0; - } - if(Den == 1) { - if(Rem) *Rem = 0; - return Num; - } - if(Den == 2) { - if(Rem) *Rem = Num & 1; - return Num >> 1; - } - if(Den == 16) { - if(Rem) *Rem = Num & 0xF; - return Num >> 4; - } - if(Den == 32) { - if(Rem) *Rem = Num & 0x1F; - return Num >> 5; - } - if(Den == 0x1000) { - if(Rem) *Rem = Num & 0xFFF; - return Num >> 12; - } - - #if 0 - { - // http://www.tofla.iconbar.com/tofla/arm/arm02/index.htm - Uint64 tmp = 1; - __asm__ __volatile__( - "1:" - "cmpl %2,%1" - "movls %2,%2,lsl#1" - "movls %3,%3,lsl#1" - "bls 1b" - "2:" - "cmpl %" - while(Num > Den) { - Den <<= 1; - tmp <<= 1; - } - Den >>= 1; tmp >>= 1; - while( - } - if(Rem) *Rem = Num; - return ret; - #elif 0 - for( ret = 0; Num > Den; ret ++, Num -= Den) ; - if(Rem) *Rem = Num; - return ret; - #else - ret = __divmod64(Num, Den, Rem); - return ret; - #endif -} - -// Unsigned Divide 64-bit Integer -Uint64 __udivdi3(Uint64 Num, Uint64 Den) -{ - return DivMod64U(Num, Den, NULL); - #if 0 -// if( Den == 0 ) return 5 / (Uint32)Den; // Force a #DIV0 - if( Den == 16 ) return Num >> 4; - if( Den == 256 ) return Num >> 8; - if( Den == 512 ) return Num >> 9; - if( Den == 1024 ) return Num >> 10; - if( Den == 2048 ) return Num >> 11; - if( Den == 4096 ) return Num >> 12; - if( Num < Den ) return 0; - if( Num <= 0xFFFFFFFF && Den <= 0xFFFFFFFF ) - return (Uint32)Num / (Uint32)Den; - - #if 0 - if( Den <= 0xFFFFFFFF ) { - (Uint32)(Num >> 32) / (Uint32)Den - } - #endif - Uint64 ret = 0; - for( ret = 0; Num > Den; ret ++, Num -= Den ); - return ret; - #endif -} - -// Unsigned Modulus 64-bit Integer -Uint64 __umoddi3(Uint64 Num, Uint64 Den) -{ - Uint64 ret = 0; - DivMod64U(Num, Den, &ret); - return ret; - #if 0 - if( Den == 0 ) return 5 / (Uint32)Den; // Force a #DIV0 - if( Num < Den ) return Num; - if( Den == 1 ) return 0; - if( Den == 2 ) return Num & 1; - if( Den == 16 ) return Num & 3; - if( Den == 256 ) return Num & 0xFF; - if( Den == 512 ) return Num & 0x1FF; - if( Den == 1024 ) return Num & 0x3FF; - if( Den == 2048 ) return Num & 0x7FF; - if( Den == 4096 ) return Num & 0xFFF; -// if( Num <= 0xFFFFFFFF && Den <= 0xFFFFFFFF ) -// return (Uint32)Num % (Uint32)Den; - - #if 0 - if( Den <= 0xFFFFFFFF ) { - (Uint32)(Num >> 32) / (Uint32)Den - } - #endif - for( ; Num > Den; Num -= Den ); - return Num; - #endif -} - -#define _divide_s_32(Num, Den, rem) __asm__ __volatile__ ( \ - "mov %0, #0\n" \ - " adds %1, %1, %1\n" \ - " .rept 32\n" \ - " adcs %0, %2, %0, lsl #1\n" \ - " subcc %0, %0, %3\n" \ - " adcs %1, %1, %1\n" \ - " .endr\n" \ - : "=r" (rem), "=r" (Num) \ - : "r" (Den) \ - : "cc" \ - ) -Uint32 __udivsi3(Uint32 Num, Uint32 Den) -{ - register Uint32 ret; - Uint64 P, D; - int i; - - if( Num == 0 ) return 0; - if( Den == 0 ) return 0xFFFFFFFF; // TODO: Throw an error - if( Den == 1 ) return Num; - - D = ((Uint64)Den) << 32; - - for( i = 32; i --; ) - { - P = 2*P - D; - if( P >= 0 ) - ret |= 1; - else - P += D; - ret <<= 1; - } - -// _divide_s_32(Num, Den, rem); - return Num; -} - -Uint32 __umodsi3(Uint32 Num, Uint32 Den) -{ - return Num - __udivsi3(Num, Den)*Den; -} - -Sint32 __divsi3(Sint32 Num, Sint32 Den) -{ - if( (Num < 0) && (Den < 0) ) - return __udivsi3(-Num, -Den); - else if( Num < 0 ) - return __udivsi3(-Num, Den); - else if( Den < 0 ) - return __udivsi3(Den, -Den); - else - return __udivsi3(Den, Den); -} - -Sint32 __modsi3(Sint32 Num, Sint32 Den) -{ - //register Sint32 rem; - //_divide_s_32(Num, Den, rem); - return Num - __divsi3(Num, Den) * Den; -} diff --git a/Kernel/arch/arm7/link.ld b/Kernel/arch/arm7/link.ld deleted file mode 100644 index 329bc9bd..00000000 --- a/Kernel/arch/arm7/link.ld +++ /dev/null @@ -1,37 +0,0 @@ -ENTRY (_start) - -_kernel_base = 0x80000000; - -SECTIONS -{ - . = 0; - .init : - { - *(.init) - } - . += _kernel_base; - .text : AT( ADDR(.text) - _kernel_base ) - { - *(.text*) - *(.rodata*) - } - .data ALIGN(0x4000) : AT( ADDR(.data) - _kernel_base ) - { - *(.padata) - *(.data*) - - gKernelSymbols = .; - *(KEXPORT) - gKernelSymbolsEnd = .; - - gKernelModules = .; - *(KMODULES) - gKernelModulesEnd = .; - } - .bss : AT( ADDR(.bss) - _kernel_base ) - { - *(.bss*) - *(COMMON*) - } - gKernelEnd = .; -} diff --git a/Kernel/arch/arm7/main.c b/Kernel/arch/arm7/main.c deleted file mode 100644 index b6186bbe..00000000 --- a/Kernel/arch/arm7/main.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Acess2 - * - * ARM7 Entrypoint - * arch/arm7/main.c - */ -#include - -// === IMPORTS === -extern void Interrupts_Setup(void); -extern void Arch_LoadBootModules(void); -extern void Heap_Install(void); -extern void Threads_Init(void); -extern void System_Init(const char *Commandline); - -// === PROTOTYPES === - int kmain(void); - -// === CODE === -int kmain(void) -{ - LogF("Acess2 ARMv7 v"EXPAND_STR(KERNEL_VERSION)"\n"); - LogF(" Build %i\n", BUILD_NUM); -// Interrupts_Setup(); - - MM_SetupPhys(); - - LogF("Heap Setup...\n"); - Heap_Install(); - - LogF("Threads Init...\n"); - Threads_Init(); - - LogF("VFS Init...\n"); - VFS_Init(); - - // Boot modules? - - // - LogF("Moving to arch-independent init\n"); - System_Init(""); - //TODO: - LogF("End of kmain(), for(;;);\n"); - for(;;); -} - -void Arch_LoadBootModules(void) -{ -} - diff --git a/Kernel/arch/arm7/mm_phys.c b/Kernel/arch/arm7/mm_phys.c deleted file mode 100644 index 0a7632ce..00000000 --- a/Kernel/arch/arm7/mm_phys.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Acess2 - * - * ARM7 Physical Memory Manager - * arch/arm7/mm_phys.c - */ -#define DEBUG 0 - -#include -#include - -#define MM_NUM_RANGES 1 // Single range -#define MM_RANGE_MAX 0 - -#define NUM_STATIC_ALLOC 4 - -char gStaticAllocPages[NUM_STATIC_ALLOC][PAGE_SIZE] __attribute__ ((section(".padata"))); -tPAddr gaiStaticAllocPages[NUM_STATIC_ALLOC] = { - (tPAddr)(&gStaticAllocPages[0]) - KERNEL_BASE, - (tPAddr)(&gStaticAllocPages[1]) - KERNEL_BASE, - (tPAddr)(&gStaticAllocPages[2]) - KERNEL_BASE, - (tPAddr)(&gStaticAllocPages[3]) - KERNEL_BASE -}; -extern char gKernelEnd[]; - -#include - -void MM_SetupPhys(void) -{ - MM_Tpl_InitPhys( 16*1024*1024/0x1000, NULL ); -} - -int MM_int_GetMapEntry( void *Data, int Index, tPAddr *Start, tPAddr *Length ) -{ - switch(Index) - { - case 0: - *Start = ((tVAddr)&gKernelEnd - KERNEL_BASE + 0xFFF) & ~0xFFF; - *Length = 16*1024*1024 - *Start; - return 1; - default: - return 0; - } -} - -/** - * \brief Takes a physical address and returns the ID of its range - * \param Addr Physical address of page - * \return Range ID from eMMPhys_Ranges - */ -int MM_int_GetRangeID( tPAddr Addr ) -{ - return MM_RANGE_MAX; // ARM doesn't need ranges -} diff --git a/Kernel/arch/arm7/mm_virt.c b/Kernel/arch/arm7/mm_virt.c deleted file mode 100644 index c191c683..00000000 --- a/Kernel/arch/arm7/mm_virt.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Acess2 - * - * ARM7 Virtual Memory Manager - * - arch/arm7/mm_virt.c - */ -#define DEBUG 0 -#include -#include -#include - -#define AP_KRW_ONLY 0x1 -#define AP_KRO_ONLY 0x5 -#define AP_RW_BOTH 0x3 -#define AP_RO_BOTH 0x6 - -// === IMPORTS === -extern Uint32 kernel_table0[]; - -// === TYPES === -typedef struct -{ - tPAddr PhysAddr; - Uint8 Size; - Uint8 Domain; - BOOL bExecutable; - BOOL bGlobal; - BOOL bShared; - int AP; -} tMM_PageInfo; - -//#define FRACTAL(table1, addr) ((table1)[ (0xFF8/4*1024) + ((addr)>>20)]) -#define FRACTAL(table1, addr) ((table1)[ (0xFF8/4*1024) + ((addr)>>22)]) -#define TLBIALL() __asm__ __volatile__ ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0)) - -// === PROTOTYPES === -void MM_int_GetTables(tVAddr VAddr, Uint32 **Table0, Uint32 **Table1); - int MM_int_AllocateCoarse(tVAddr VAddr, int Domain); - int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi); - int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi); -tVAddr MM_NewKStack(int bGlobal); - -// === GLOBALS === - -// === CODE === -int MM_InitialiseVirtual(void) -{ - return 0; -} - -void MM_int_GetTables(tVAddr VAddr, Uint32 **Table0, Uint32 **Table1) -{ - if(VAddr & 0x80000000) { - *Table0 = (void*)&kernel_table0; // Level 0 - *Table1 = (void*)MM_TABLE1KERN; // Level 1 - } - else { - *Table0 = (void*)MM_TABLE0USER; - *Table1 = (void*)MM_TABLE1USER; - } -} - -int MM_int_AllocateCoarse(tVAddr VAddr, int Domain) -{ - Uint32 *table0, *table1; - Uint32 *desc; - tPAddr paddr; - - ENTER("xVAddr iDomain", VAddr, Domain); - - MM_int_GetTables(VAddr, &table0, &table1); - - VAddr &= ~(0x400000-1); // 4MiB per "block", 1 Page - - desc = &table0[ VAddr>>20]; - LOG("desc = %p", desc); - - // table0: 4 bytes = 1 MiB - - LOG("desc[0] = %x", desc[0]); - LOG("desc[1] = %x", desc[1]); - LOG("desc[2] = %x", desc[2]); - LOG("desc[3] = %x", desc[3]); - - if( (desc[0] & 3) != 0 || (desc[1] & 3) != 0 - || (desc[2] & 3) != 0 || (desc[3] & 3) != 0 ) - { - // Error? - LEAVE('i', 1); - return 1; - } - - paddr = MM_AllocPhys(); - if( !paddr ) - { - // Error - LEAVE('i', 2); - return 2; - } - - *desc = paddr | (Domain << 5) | 1; - desc[1] = desc[0] + 0x400; - desc[2] = desc[0] + 0x800; - desc[3] = desc[0] + 0xC00; - - FRACTAL(table1, VAddr) = paddr | 3; - - // TLBIALL - TLBIALL(); - - LEAVE('i', 0); - return 0; -} - -int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi) -{ - Uint32 *table0, *table1; - Uint32 *desc; - - ENTER("pVADdr ppi", VAddr, pi); - - MM_int_GetTables(VAddr, &table0, &table1); - - desc = &table0[ VAddr >> 20 ]; - LOG("desc = %p", desc); - - switch(pi->Size) - { - case 12: // Small Page - case 16: // Large Page - LOG("Page"); - if( (*desc & 3) == 0 ) { - MM_int_AllocateCoarse( VAddr, pi->Domain ); - } - desc = &table1[ VAddr >> 12 ]; - LOG("desc (2) = %p", desc); - if( pi->Size == 12 ) - { - // Small page - // - Error if overwriting a large page - if( (*desc & 3) == 1 ) LEAVE_RET('i', 1); - if( pi->PhysAddr == 0 ) { - *desc = 0; - LEAVE('i', 0); - return 0; - } - - *desc = (pi->PhysAddr & 0xFFFFF000) | 2; - if(!pi->bExecutable) *desc |= 1; // XN - if(!pi->bGlobal) *desc |= 1 << 11; // NG - if( pi->bShared) *desc |= 1 << 10; // S - *desc |= (pi->AP & 3) << 4; // AP - *desc |= ((pi->AP >> 2) & 1) << 9; // APX - LEAVE('i', 0); - return 0; - } - else - { - // Large page - // TODO: - } - break; - case 20: // Section or unmapped - Warning("TODO: Implement sections"); - break; - case 24: // Supersection - // Error if not aligned - if( VAddr & 0xFFFFFF ) { - LEAVE('i', 1); - return 1; - } - if( (*desc & 3) == 0 || ((*desc & 3) == 2 && (*desc & (1 << 18))) ) - { - if( pi->PhysAddr == 0 ) { - *desc = 0; - // TODO: Apply to all entries - LEAVE('i', 0); - return 0; - } - // Apply - *desc = pi->PhysAddr & 0xFF000000; -// *desc |= ((pi->PhysAddr >> 32) & 0xF) << 20; -// *desc |= ((pi->PhysAddr >> 36) & 0x7) << 5; - *desc |= 2 | (1 << 18); - // TODO: Apply to all entries - LEAVE('i', 0); - return 0; - } - // TODO: What here? - LEAVE('i', 1); - return 1; - } - - LEAVE('i', 1); - return 1; -} - -extern tShortSpinlock glDebug_Lock; - -int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi) -{ - Uint32 *table0, *table1; - Uint32 desc; - - MM_int_GetTables(VAddr, &table0, &table1); - - desc = table0[ VAddr >> 20 ]; - -// if( VAddr > 0x90000000) -// LOG("table0 desc(%p) = %x", &table0[ VAddr >> 20 ], desc); - - pi->bExecutable = 1; - pi->bGlobal = 0; - pi->bShared = 0; - - - switch( (desc & 3) ) - { - // 0: Unmapped - case 0: - pi->PhysAddr = 0; - pi->Size = 20; - pi->Domain = 0; - return 1; - - // 1: Coarse page table - case 1: - // Domain from top level table - pi->Domain = (desc >> 5) & 7; - // Get next level - desc = table1[ VAddr >> 12 ]; -// LOG("table1 desc(%p) = %x", &table1[ VAddr >> 12 ], desc); - switch( desc & 3 ) - { - // 0: Unmapped - case 0: - pi->Size = 12; - return 1; - // 1: Large Page (64KiB) - case 1: - pi->Size = 16; - pi->PhysAddr = desc & 0xFFFF0000; - return 0; - // 2/3: Small page - case 2: - case 3: - pi->Size = 12; - pi->PhysAddr = desc & 0xFFFFF000; - pi->bExecutable = desc & 1; - pi->bGlobal = !(desc >> 11); - pi->bShared = (desc >> 10) & 1; - return 0; - } - return 1; - - // 2: Section (or Supersection) - case 2: - if( desc & (1 << 18) ) { - // Supersection - pi->PhysAddr = desc & 0xFF000000; - pi->PhysAddr |= (Uint64)((desc >> 20) & 0xF) << 32; - pi->PhysAddr |= (Uint64)((desc >> 5) & 0x7) << 36; - pi->Size = 24; - pi->Domain = 0; // Superpages default to zero - return 0; - } - - // Section - pi->PhysAddr = desc & 0xFFF80000; - pi->Size = 20; - pi->Domain = (desc >> 5) & 7; - return 0; - - // 3: Reserved (invalid) - case 3: - pi->PhysAddr = 0; - pi->Size = 20; - pi->Domain = 0; - return 2; - } - return 2; -} - -// --- Exports --- -tPAddr MM_GetPhysAddr(tVAddr VAddr) -{ - tMM_PageInfo pi; - if( MM_int_GetPageInfo(VAddr, &pi) ) - return 0; - return pi.PhysAddr | (VAddr & ((1 << pi.Size)-1)); -} - -Uint MM_GetFlags(tVAddr VAddr) -{ - tMM_PageInfo pi; - int ret; - - if( MM_int_GetPageInfo(VAddr, &pi) ) - return 0; - - ret = 0; - - switch(pi.AP) - { - case AP_KRW_ONLY: - ret |= MM_PFLAG_KERNEL; - break; - case AP_KRO_ONLY: - ret |= MM_PFLAG_KERNEL|MM_PFLAG_RO; - break; - case AP_RW_BOTH: - break; - case AP_RO_BOTH: - ret |= MM_PFLAG_RO; - break; - } - - if( pi.bExecutable ) ret |= MM_PFLAG_EXEC; - return ret; -} - -void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask) -{ - tMM_PageInfo pi; - if( MM_int_GetPageInfo(VAddr, &pi) ) - return; - - - -} - -int MM_Map(tVAddr VAddr, tPAddr PAddr) -{ - tMM_PageInfo pi = {0}; - pi.PhysAddr = PAddr; - pi.Size = 12; - pi.AP = AP_KRW_ONLY; // Kernel Read/Write - pi.bExecutable = 1; - if( MM_int_SetPageInfo(VAddr, &pi) ) { - MM_DerefPhys(pi.PhysAddr); - return 0; - } - return pi.PhysAddr; -} - -tPAddr MM_Allocate(tVAddr VAddr) -{ - tMM_PageInfo pi = {0}; - - ENTER("pVAddr", VAddr); - - pi.PhysAddr = MM_AllocPhys(); - if( pi.PhysAddr == 0 ) LEAVE_RET('i', 0); - pi.Size = 12; - pi.AP = AP_KRW_ONLY; // Kernel Read/Write - pi.bExecutable = 1; - if( MM_int_SetPageInfo(VAddr, &pi) ) { - MM_DerefPhys(pi.PhysAddr); - LEAVE('i', 0); - return 0; - } - LEAVE('x', pi.PhysAddr); - return pi.PhysAddr; -} - -void MM_Deallocate(tVAddr VAddr) -{ - tMM_PageInfo pi; - - if( MM_int_GetPageInfo(VAddr, &pi) ) return ; - - if( pi.PhysAddr == 0 ) return; - MM_DerefPhys(pi.PhysAddr); - - pi.PhysAddr = 0; - pi.AP = 0; - pi.bExecutable = 0; - MM_int_SetPageInfo(VAddr, &pi); -} - -tPAddr MM_ClearUser(void) -{ - // TODO: Implement ClearUser - return 0; -} - -tVAddr MM_MapTemp(tPAddr PAddr) -{ - // TODO: Implement MapTemp - return 0; -} - -void MM_FreeTemp(tVAddr VAddr) -{ - // TODO: Implement FreeTemp -} - -tVAddr MM_NewKStack(int bGlobal) -{ - // TODO: Implement NewKStack - // TODO: Should I support global stacks? if only for the idle thread - return 0; -} - -void MM_DumpTables(tVAddr Start, tVAddr End) -{ - -} - diff --git a/Kernel/arch/arm7/pci.c b/Kernel/arch/arm7/pci.c deleted file mode 100644 index 0d25049f..00000000 --- a/Kernel/arch/arm7/pci.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - */ -#include - -// Realview -//#define PCI_BASE 0x60000000 - -//#define PCI_BASE 0xF0400000 // VMM Mapping -#define PCI_BASE 0 - -// === PROTOTYPES === -#if 1 -void PCI_CfgWriteDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset, Uint32 data); -Uint32 PCI_CfgReadDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset); -Uint16 PCI_CfgReadWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset); -Uint8 PCI_CfgReadByte(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset); -#endif - -// === CODE === -void PCI_CfgWriteDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset, Uint32 data) -{ - #if PCI_BASE - Uint32 address = PCI_BASE | ((Uint)bus<<16) | ((Uint)dev<<11) | ((Uint)func<<8) | (offset&0xFC); - *(Uint32*)(address) = data; - #else - #endif -} - -Uint32 PCI_CfgReadDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset) -{ - #if PCI_BASE - Uint32 address = PCI_BASE | ((Uint)bus<<16) | ((Uint)dev<<11) | ((Uint)func<<8) | (offset&0xFC); - return *(Uint32*)address; - #else - return 0xFFFFFFFF; - #endif -} - -Uint16 PCI_CfgReadWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset) -{ - return PCI_CfgReadDWord(bus, dev, func, offset & ~3) >> (8*(offset&2)); -} - -Uint8 PCI_CfgReadByte(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset) -{ - return PCI_CfgReadDWord(bus, dev, func, offset & ~3) >> (8*(offset&3)); -} diff --git a/Kernel/arch/arm7/proc.S b/Kernel/arch/arm7/proc.S deleted file mode 100644 index 841764b6..00000000 --- a/Kernel/arch/arm7/proc.S +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Acess2 ARM - * - By John Hodge (thePowersGang) - * - * arch/arm7/proc.S - * - Process management assembly - */ - -#define PUSH_GPRS \ - str r0, [sp,#-1*4];\ - str r1, [sp,#-2*4];\ - str r2, [sp,#-3*4];\ - str r3, [sp,#-4*4];\ - str r4, [sp,#-5*4];\ - str r5, [sp,#-6*4];\ - str r6, [sp,#-7*4];\ - str r7, [sp,#-8*4];\ - str r8, [sp,#-9*4];\ - str r9, [sp,#-10*4];\ - str r10, [sp,#-11*4];\ - str r11, [sp,#-12*4];\ - str r12, [sp,#-13*4];\ - str sp, [sp,#-14*4];\ - str lr, [sp,#-15*4];\ - sub sp, #16*4 - -#define POP_GPRS add sp, #16*4; \ - ldr r0, [sp,#-1*4]; \ - ldr r1, [sp,#-2*4]; \ - ldr r2, [sp,#-3*4]; \ - ldr r3, [sp,#-4*4]; \ - ldr r4, [sp,#-5*4]; \ - ldr r5, [sp,#-6*4]; \ - ldr r6, [sp,#-7*4]; \ - ldr r7, [sp,#-8*4]; \ - ldr r8, [sp,#-9*4]; \ - ldr r9, [sp,#-10*4]; \ - ldr r10, [sp,#-11*4]; \ - ldr r11, [sp,#-12*4]; \ - ldr r12, [sp,#-13*4]; \ - ldr lr, [sp,#-15*4]; - -.globl KernelThreadHeader -@ SP+12: Argument 1 -@ SP+8: Argument Count -@ SP+4: Function -@ SP+0: Thread Pointer -KernelThreadHeader: - ldr r0, [sp],#4 - @ TODO: Do something with the thread pointer - - ldr r4, [sp],#4 @ Function - ldr r5, [sp],#4 - @ Get arguments - sub r5, #1 - ldrhs r0, [sp],#4 - sub r5, #1 - ldrhs r1, [sp],#4 - sub r5, #1 - ldrhs r2, [sp],#4 - sub r5, #1 - ldrhs r3, [sp],#4 - - mov lr, pc - mov pc, r4 - - ldr r0, =0 - bl Threads_Exit - b . - -.globl SwitchTask -@ R0: New stack -@ R1: Pointer to where to save old stack -@ R2: New IP -@ R3: Pointer to save old IP -@ SP+0: New address space -SwitchTask: - PUSH_GPRS - - ldr r4, =.return - str r4, [r3] - str sp, [r1] - mov r0, sp - - @ Only update TTBR0 if the task has an explicit address space - ldr r0, [sp,#0x40] - tst r0, r0 - mcrne p15, 0, r0, c2, c0, 0 @ Set TTBR0 to r0 - - mov pc, r2 - -.return: - POP_GPRS - bx lr - diff --git a/Kernel/arch/arm7/proc.c b/Kernel/arch/arm7/proc.c deleted file mode 100644 index f4025cca..00000000 --- a/Kernel/arch/arm7/proc.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Acess2 - * - By John Hodge (thePowersGang) - * - * arch/arm7/proc. - * - ARM7 Process Switching - */ -#include -#include -#include - -// === IMPORTS === -extern tThread gThreadZero; -extern void SwitchTask(Uint32 NewSP, Uint32 *OldSP, Uint32 NewIP, Uint32 *OldIP, Uint32 MemPtr); -extern void KernelThreadHeader(void); // Actually takes args -extern tVAddr MM_NewKStack(int bGlobal); // TODO: Move out into a header - -// === PROTOTYPES === -void Proc_IdleThread(void *unused); -tTID Proc_NewKThread( void (*Fnc)(void*), void *Ptr ); - -// === GLOBALS === -tThread *gpCurrentThread = &gThreadZero; -tThread *gpIdleThread = NULL; - -// === CODE === -void ArchThreads_Init(void) -{ -} - -void Proc_IdleThread(void *unused) -{ - for(;;) - Proc_Reschedule(); -} - -void Proc_Start(void) -{ - tTID tid; - - tid = Proc_NewKThread( Proc_IdleThread, NULL ); - gpIdleThread = Threads_GetThread(tid); -} - -int GetCPUNum(void) -{ - return 0; -} - -tThread *Proc_GetCurThread(void) -{ - return gpCurrentThread; -} - -tTID Proc_Clone(Uint Flags) -{ - return -1; -} - -void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize) -{ -} - -tTID Proc_SpawnWorker( void (*Fnc)(void*), void *Ptr ) -{ - return -1; -} - -tTID Proc_NewKThread( void (*Fnc)(void*), void *Ptr ) -{ - tThread *new; - Uint32 sp; - - new = Threads_CloneTCB(NULL, 0); - if(!new) return -1; - - new->KernelStack = MM_NewKStack(0); - if(!new->KernelStack) { - // TODO: Delete thread - return -1; - } - - sp = new->KernelStack; - - *(Uint32*)(sp -= 4) = (Uint)new; - *(Uint32*)(sp -= 4) = (Uint)Fnc; - *(Uint32*)(sp -= 4) = 1; - *(Uint32*)(sp -= 4) = (Uint)Ptr; - - new->SavedState.SP = sp; - new->SavedState.IP = (Uint)KernelThreadHeader; - - Threads_AddActive(new); - - return new->TID; -} - -void Proc_CallFaultHandler(tThread *Thread) -{ - -} - -void Proc_Reschedule(void) -{ - tThread *cur, *next; - - cur = gpCurrentThread; - - next = Threads_GetNextToRun(0, cur); - if(!next) next = gpIdleThread; - if(!next || next == cur) return; - - SwitchTask( - next->SavedState.SP, &cur->SavedState.SP, - next->SavedState.IP, &cur->SavedState.IP, - next->MemState.Base - ); - -} - -void Proc_DumpThreadCPUState(tThread *Thread) -{ - -} - diff --git a/Kernel/arch/arm7/start.S b/Kernel/arch/arm7/start.S deleted file mode 100644 index 718131c0..00000000 --- a/Kernel/arch/arm7/start.S +++ /dev/null @@ -1,124 +0,0 @@ -KERNEL_BASE = 0x80000000 -PCI_PADDR = 0x60000000 @ Realview -UART0_PADDR = 0x10009000 @ Realview -@ -@ Exception defs taken from ARM DDI 0406B -@ -.section .init -interrupt_vector_table: - b _start @ Reset - b . @ #UD - b SyscallHandler @ SVC (SWI assume) - b . @ Prefetch abort - b . @ Data abort - b . @ Not Used - b IRQHandler @ IRQ - b . @ FIQ (Fast interrupt) - -.globl _start -_start: - ldr r0, =kernel_table0-KERNEL_BASE - mcr p15, 0, r0, c2, c0, 1 @ Set TTBR1 to r0 - mcr p15, 0, r0, c2, c0, 0 @ Set TTBR0 to r0 too (for identity) - - mov r0, #1 - mcr p15, 0, r0, c2, c0, 2 @ Set TTCR to 1 (50/50 split) - - mov r0, #3 - mcr p15, 0, r0, c3, c0, 0 @ Set Domain 0 to Manager - - mrc p15, 0, r0, c1, c0, 0 - orr r0, r0, #1 - orr r0, r0, #1 << 23 - mcr p15, 0, r0, c1, c0, 0 - - ldr sp, =stack+0x10000 @ Set up stack - ldr r0, =kmain - mov pc, r0 -1: b 1b @ Infinite loop -_ptr_kmain: - .long kmain - -.comm stack, 0x10000 @ ; 64KiB Stack - -SyscallHandler: - b . - -IRQHandler: - b . - -.section .padata -.globl kernel_table0 - -kernel_table0: - .long 0x00000002 @ Identity map the first 1 MiB - .rept 0x800 - 1 - .long 0 - .endr - .long 0x00000002 @ Map first 4 MiB to 2GiB - .long 0x00100002 @ - .long 0x00200002 @ - .long 0x00300002 @ - .rept 0xF00 - 0x800 - 4 - .long 0 - .endr -#if PCI_PADDR - .long PCI_PADDR + 0*(1 << 20) + 2 @ Map PCI config space - .long PCI_PADDR + 1*(1 << 20) + 2 - .long PCI_PADDR + 2*(1 << 20) + 2 - .long PCI_PADDR + 3*(1 << 20) + 2 - .long PCI_PADDR + 4*(1 << 20) + 2 - .long PCI_PADDR + 5*(1 << 20) + 2 - .long PCI_PADDR + 6*(1 << 20) + 2 - .long PCI_PADDR + 7*(1 << 20) + 2 - .long PCI_PADDR + 8*(1 << 20) + 2 - .long PCI_PADDR + 9*(1 << 20) + 2 - .long PCI_PADDR + 10*(1 << 20) + 2 - .long PCI_PADDR + 11*(1 << 20) + 2 - .long PCI_PADDR + 12*(1 << 20) + 2 - .long PCI_PADDR + 13*(1 << 20) + 2 - .long PCI_PADDR + 14*(1 << 20) + 2 - .long PCI_PADDR + 15*(1 << 20) + 2 -#else - .rept 16 - .long 0 - .endr -#endif - .long hwmap_table_0 + 0x000 - KERNEL_BASE + 1 - .long hwmap_table_0 + 0x400 - KERNEL_BASE + 1 - .long hwmap_table_0 + 0x800 - KERNEL_BASE + 1 - .long hwmap_table_0 + 0xC00 - KERNEL_BASE + 1 - .rept 0xFF8 - 0xF00 - 16 - 4 - .long 0 - .endr - @ Page fractals - .long kernel_table1_map + 0x000 - KERNEL_BASE + 1 - .long kernel_table1_map + 0x400 - KERNEL_BASE + 1 - .long kernel_table1_map + 0x800 - KERNEL_BASE + 1 - .long kernel_table1_map + 0xC00 - KERNEL_BASE + 1 - @ Top level fractals - .long 0 @ removed for alignment constraints, using the KERNEL_BASE identity mapping instead - .rept 0x1000 - 0xFF8 - 5 - .long 0 - .endr - -.globl kernel_table1_map -kernel_table1_map: @ Size = 4KiB - .rept 0xF00/4 - .long 0 - .endr - .long hwmap_table_0 - KERNEL_BASE + (1 << 4) + 3 - .rept 0xFF8/4 - 0xF00/4 - 1 - .long 0 - .endr - .long kernel_table1_map - KERNEL_BASE + (1 << 4) + 3 - .long 0 - -@ Hardware mappings -.globl hwmap_table_0 -hwmap_table_0: - .long UART0_PADDR + (1 << 4) + 3 @ UART0 - .rept 1024 - 1 - .long 0 - .endr - diff --git a/Kernel/arch/arm7/time.c b/Kernel/arch/arm7/time.c deleted file mode 100644 index d4ae4fa6..00000000 --- a/Kernel/arch/arm7/time.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Acess2 - * - * ARM7 Time code - * arch/arm7/time.c - */ -#include - -// === GLOBALS === -tTime giTimestamp; - -// === CODE === -tTime now(void) -{ - return giTimestamp; -} diff --git a/Kernel/arch/armv7/Makefile b/Kernel/arch/armv7/Makefile new file mode 100644 index 00000000..21da1726 --- /dev/null +++ b/Kernel/arch/armv7/Makefile @@ -0,0 +1,27 @@ +# +# Acess2 Kernel +# arm7 Architecture Makefile +# arch/arm7/Makefile + +CPPFLAGS = +CFLAGS = +ASFLAGS = + +PCI_ADDRESS=0 +ifeq ($(ARCH),integrator-cp) + MMU_PRESENT=1 +else + MMU_PRESENT=1 +endif + + + +#ASFLAGS += -D USE_MP=$(USE_MP) -D USE_PAE=$(USE_PAE) +CPPFLAGS += -DMMU_PRESENT=$(MMU_PRESENT) -DPCI_ADDRESS=$(PCI_ADDRESS) +LDFLAGS += `$(CC) --print-libgcc-file-name` + +A_OBJ = start.ao main.o lib.o time.o pci.o debug.o +A_OBJ += mm_phys.o mm_virt.o proc.o proc.ao + +main.c: Makefile.BuildNum.$(ARCH) + diff --git a/Kernel/arch/armv7/debug.c b/Kernel/arch/armv7/debug.c new file mode 100644 index 00000000..d75048ed --- /dev/null +++ b/Kernel/arch/armv7/debug.c @@ -0,0 +1,51 @@ +/** + * Acess2 + * - By John Hodge (thePowersGang) + * + * arch/arm7/debug.c + * - ARM7 Debug output + * NOTE: Currently designed for the realview-pb-a8 emulated by Qemu + */ +#include + +// === CONSTANTS === +//#define UART0_BASE 0x10009000 +#define UART0_BASE 0xF1000000 // Boot time mapped + +// === PROTOTYPES === +void KernelPanic_SetMode(void); +void KernelPanic_PutChar(char Ch); +void StartupPrint(const char *str); + +// === GLOBALS === + int giDebug_SerialInitialised = 0; + +// === CODE === +void Debug_PutCharDebug(char ch) +{ +// while( *(volatile Uint32*)(SERIAL_BASE + SERIAL_REG_FLAG) & SERIAL_FLAG_FULL ) + ; + +// *(volatile Uint32*)(SERIAL_BASE + SERIAL_REG_DATA) = ch; + *(volatile Uint32*)(UART0_BASE) = ch; +} + +void Debug_PutStringDebug(const char *str) +{ + for( ; *str; str++ ) + Debug_PutCharDebug( *str ); +} + +void KernelPanic_SetMode(void) +{ +} + +void KernelPanic_PutChar(char ch) +{ +// Debug_PutCharDebug(ch); +} + +void StartupPrint(const char *str) +{ +} + diff --git a/Kernel/arch/armv7/include/arch.h b/Kernel/arch/armv7/include/arch.h new file mode 100644 index 00000000..36c1a3f3 --- /dev/null +++ b/Kernel/arch/armv7/include/arch.h @@ -0,0 +1,42 @@ +/* + * Acess2 + * ARM7 Architecture Header + */ +#ifndef _ARCH_H_ +#define _ARCH_H_ + +// === CONSTANTS === +#define INVLPTR ((void*)-1) +#define BITS 32 +#define PAGE_SIZE 0x1000 +#define KERNEL_BASE 0x80000000 // 2GiB + +// === TYPES === +typedef unsigned int Uint; +typedef unsigned char Uint8; +typedef unsigned short Uint16; +typedef unsigned long Uint32; +typedef unsigned long long Uint64; +typedef signed int Sint; +typedef signed char Sint8; +typedef signed short Sint16; +typedef signed long Sint32; +typedef signed long long Sint64; + +typedef int size_t; +typedef char BOOL; + +typedef Uint32 tVAddr; +typedef Uint32 tPAddr; + +#include "lock.h" + +// --- Debug +extern void Debug_PutCharDebug(char Ch); +extern void Debug_PutStringDebug(const char *String); + +// This should be elsewhere, but CBF +extern void MM_SetupPhys(void); +extern int MM_InitialiseVirtual(void); + +#endif diff --git a/Kernel/arch/armv7/include/lock.h b/Kernel/arch/armv7/include/lock.h new file mode 100644 index 00000000..627726b5 --- /dev/null +++ b/Kernel/arch/armv7/include/lock.h @@ -0,0 +1,60 @@ +/* + * Acess2 + * ARM7 Architecture + * + * lock.h - Hardware level spinlocks + */ +#ifndef _LOCK_H_ +#define _LOCK_H_ + +// === CODE === +struct sShortSpinlock { + int Lock; +}; + +// --- Spinlocks --- +static inline int IS_LOCKED(struct sShortSpinlock *Lock) +{ + return !!Lock->Lock; +} + +static inline int CPU_HAS_LOCK(struct sShortSpinlock *Lock) +{ + // TODO: Handle multiple CPUs + return !!Lock->Lock; +} + +static inline int SHORTLOCK(struct sShortSpinlock *Lock) +{ + #if 1 + // Coped from linux, yes, but I know what it does now :) + Uint tmp; + __asm__ __volatile__ ( + "1: ldrex %0, [%1]\n" // Exclusive LOAD + " teq %0, #0\n" // Check if zero + " strexeq %0, %2, [%1]\n" // Set to one if it is zero (releasing lock on the memory) + " teqeq %0, #0\n" // If the lock was avaliable, check if the write succeeded + " bne 1b" // If the lock was unavaliable, or the write failed, loop + : "=&r" (tmp) // Temp + : "r" (&Lock->Lock), "r" (1) + : "cc" // Condition codes clobbered + ); + #else + int v = 1; + while( v ) + __asm__ __volatile__ ( + "swp %0, [%1]" + : "=r" (v) : "r" (&Lock->Lock) + : "cc" + ); + #endif + return 1; +} + +static inline void SHORTREL(struct sShortSpinlock *Lock) +{ + Lock->Lock = 0; +} + +#endif + diff --git a/Kernel/arch/armv7/include/mm_virt.h b/Kernel/arch/armv7/include/mm_virt.h new file mode 100644 index 00000000..b57e45c3 --- /dev/null +++ b/Kernel/arch/armv7/include/mm_virt.h @@ -0,0 +1,46 @@ +/* + * Acess2 + * ARM7 Virtual Memory Manager Header + */ +#ifndef _MM_VIRT_H_ +#define _MM_VIRT_H_ + +#define MM_USER_MIN 0x00001000 +#define USER_LIB_MAX 0x7F800000 +#define MM_PPD_HANDLES 0x7F800000 +#define MM_TABLE0USER 0x7F900000 // 2 GiB - 16 KiB +#define MM_TABLE1USER 0x7FC00000 // 2 GiB - 4 MiB + +// Page Blocks are 12-bits wide (12 address bits used) +// Hence, the table is 16KiB large (and must be so aligned) +// and each block addresses 1MiB of data + +// First level table is aligned to 16KiB (restriction of TTBR reg) +// - VMSAv6 uses two TTBR regs, determined by bit 31 + +//#define KERNEL_BASE 0x80000000 // 2GiB + +#define MM_KHEAP_BASE 0x80800000 // 8MiB of kernel code +#define MM_KHEAP_MAX 0xC0000000 // ~1GiB of kernel heap + +#define MM_MODULE_MIN 0xC0000000 // - 0xD0000000 +#define MM_MODULE_MAX 0xD0000000 + +// PMM Data, giving it 256MiB is overkill, but it's unused atm +#define MM_MAXPHYSPAGE (1024*1024) +// 2^(32-12) max pages +// 8.125 bytes per page (for bitmap allocation) +// = 8.125 MiB +#define MM_PMM_BASE 0xE0000000 +#define MM_PMM_END 0xF0000000 + +#define MM_HWMAP_BASE 0xF0000000 // Ent 0xF00 +#define MM_HWMAP_END 0xFE000000 +#define MM_TMPMAP_BASE 0xFE000000 +#define MM_TMPMAP_END 0xFF000000 + +#define MM_KERNEL_VFS 0xFF000000 // +#define MM_TABLE1KERN 0xFF800000 // - 0x???????? 4MiB +#define MM_TABLE0KERN 0xFFC00000 // - 0xFFE04000 16KiB + +#endif diff --git a/Kernel/arch/armv7/include/proc.h b/Kernel/arch/armv7/include/proc.h new file mode 100644 index 00000000..1dd9b0f4 --- /dev/null +++ b/Kernel/arch/armv7/include/proc.h @@ -0,0 +1,51 @@ +/* + * Acess2 + * ARM7 Architecture + * + * proc.h - Arch-Dependent Process Management + */ +#ifndef _PROC_H_ +#define _PROC_H_ + +#define MAX_CPUS 4 + +// === STRUCTURES === +typedef struct { + Uint32 IP, SP; + Uint32 UserIP, UserSP; +} tTaskState; + +typedef struct { + Uint32 Base; +} tMemoryState; + +typedef struct { + union { + Uint32 Num; + Uint32 Error; + }; + union { + Uint32 Arg1; + Uint32 Return; + }; + union { + Uint32 Arg2; + Uint32 RetHi; + }; + Uint32 Arg3; + Uint32 Arg4; + Uint32 Arg5; + Uint32 Arg6; // R6 + Uint32 Unused[13-6]; + Uint32 StackPointer; // R13 + Uint32 _lr; + Uint32 _ip; +} tSyscallRegs; + +// === MACROS === +#define HALT() do{}while(0) + +// === PROTOTYPES === + +#endif + diff --git a/Kernel/arch/armv7/lib.c b/Kernel/arch/armv7/lib.c new file mode 100644 index 00000000..94c1a3af --- /dev/null +++ b/Kernel/arch/armv7/lib.c @@ -0,0 +1,323 @@ +/* + * Acess2 ARM7 Port + * + * lib.c - Library Functions + */ +#include + +// === PROTOTYPES === +Uint64 __divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem); +Uint64 __udivdi3(Uint64 Num, Uint64 Den); +Uint64 __umoddi3(Uint64 Num, Uint64 Den); +Uint32 __udivsi3(Uint32 Num, Uint32 Den); +Uint32 __umodsi3(Uint32 Num, Uint32 Den); +Sint32 __divsi3(Sint32 Num, Sint32 Den); +Sint32 __modsi3(Sint32 Num, Sint32 Den); + +// === CODE === +void *memcpy(void *_dest, const void *_src, size_t _length) +{ + Uint32 *dst; + const Uint32 *src; + Uint8 *dst8 = _dest; + const Uint8 *src8 = _src; + + // Handle small copies / Non-aligned + if( _length < 4 || ((tVAddr)_dest & 3) != ((tVAddr)_src & 3) ) + { + for( ; _length--; dst8++,src8++ ) + *dst8 = *src8; + return _dest; + } + + // Force alignment + while( (tVAddr)dst8 & 3 ) *dst8 ++ = *src8++; + dst = (void *)dst8; src = (void *)src8; + + // DWORD copies + for( ; _length > 3; _length -= 4) + *dst++ = *src++; + + // Trailing bytes + dst8 = (void*)dst; src8 = (void*)src; + for( ; _length; _length -- ) + *dst8 ++ = *src8 ++; + + return _dest; +} + +int memcmp(const void *_m1, const void *_m2, size_t _length) +{ + const Uint32 *m1, *m2; + const Uint8 *m1_8 = _m1, *m2_8 = _m2; + + // Handle small copies / Non-aligned + if( _length < 4 || ((tVAddr)_m1 & 3) != ((tVAddr)_m1 & 3) ) + { + for( ; _length--; m1_8++,m2_8++ ) { + if(*m1_8 != *m2_8) return *m1_8 - *m2_8; + } + return 0; + } + + // Force alignment + for( ; (tVAddr)m1_8 & 3; m1_8 ++, m2_8 ++) { + if(*m1_8 != *m2_8) return *m1_8 - *m2_8; + } + m1 = (void *)m1_8; m2 = (void *)m2_8; + + // DWORD copies + for( ; _length > 3; _length -= 4, m1++, m2++) + if(*m1 != *m2) return *m1 - *m2; + + // Trailing bytes + m1_8 = (void*)m1; m2_8 = (void*)m2; + for( ; _length; _length --, m1_8++, m2_8++ ) + if(*m1_8 != *m2_8) return *m1_8 - *m2_8; + + return 0; +} + +void *memset(void *_dest, int _value, size_t _length) +{ + Uint32 *dst, val32; + Uint8 *dst8 = _dest; + + _value = (Uint8)_value; + + // Handle small copies / Non-aligned + if( _length < 4 ) + { + for( ; _length--; dst8++ ) + *dst8 = _value; + return _dest; + } + + val32 = _value; + val32 |= val32 << 8; + val32 |= val32 << 16; + + // Force alignment + while( (tVAddr)dst8 & 3 ) *dst8 ++ = _value; + dst = (void *)dst8; + + // DWORD copies + for( ; _length > 3; _length -= 4) + *dst++ = val32; + + // Trailing bytes + dst8 = (void*)dst; + for( ; _length; _length -- ) + *dst8 ++ = _value; + + return _dest; +} + +Uint64 __divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem) +{ + Uint64 ret, add; + + ret = 0; + add = 1; + + // Find what power of two times Den is > Num + while( Num >= Den ) + { + Den <<= 1; + add <<= 1; + } + + // Search backwards + while( add > 1 ) + { + add >>= 1; + Den >>= 1; + // If the numerator is > Den, subtract and add to return value + if( Num > Den ) + { + ret += add; + Num -= Den; + } + } + if(Rem) *Rem = Num; + return ret; +} + +Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem) +{ + Uint64 ret; + if(Den == 0) return 0; // TODO: #div0 + if(Num == 0) { + if(Rem) *Rem = 0; + return 0; + } + if(Den == 1) { + if(Rem) *Rem = 0; + return Num; + } + if(Den == 2) { + if(Rem) *Rem = Num & 1; + return Num >> 1; + } + if(Den == 16) { + if(Rem) *Rem = Num & 0xF; + return Num >> 4; + } + if(Den == 32) { + if(Rem) *Rem = Num & 0x1F; + return Num >> 5; + } + if(Den == 0x1000) { + if(Rem) *Rem = Num & 0xFFF; + return Num >> 12; + } + + #if 0 + { + // http://www.tofla.iconbar.com/tofla/arm/arm02/index.htm + Uint64 tmp = 1; + __asm__ __volatile__( + "1:" + "cmpl %2,%1" + "movls %2,%2,lsl#1" + "movls %3,%3,lsl#1" + "bls 1b" + "2:" + "cmpl %" + while(Num > Den) { + Den <<= 1; + tmp <<= 1; + } + Den >>= 1; tmp >>= 1; + while( + } + if(Rem) *Rem = Num; + return ret; + #elif 0 + for( ret = 0; Num > Den; ret ++, Num -= Den) ; + if(Rem) *Rem = Num; + return ret; + #else + ret = __divmod64(Num, Den, Rem); + return ret; + #endif +} + +// Unsigned Divide 64-bit Integer +Uint64 __udivdi3(Uint64 Num, Uint64 Den) +{ + return DivMod64U(Num, Den, NULL); + #if 0 +// if( Den == 0 ) return 5 / (Uint32)Den; // Force a #DIV0 + if( Den == 16 ) return Num >> 4; + if( Den == 256 ) return Num >> 8; + if( Den == 512 ) return Num >> 9; + if( Den == 1024 ) return Num >> 10; + if( Den == 2048 ) return Num >> 11; + if( Den == 4096 ) return Num >> 12; + if( Num < Den ) return 0; + if( Num <= 0xFFFFFFFF && Den <= 0xFFFFFFFF ) + return (Uint32)Num / (Uint32)Den; + + #if 0 + if( Den <= 0xFFFFFFFF ) { + (Uint32)(Num >> 32) / (Uint32)Den + } + #endif + Uint64 ret = 0; + for( ret = 0; Num > Den; ret ++, Num -= Den ); + return ret; + #endif +} + +// Unsigned Modulus 64-bit Integer +Uint64 __umoddi3(Uint64 Num, Uint64 Den) +{ + Uint64 ret = 0; + DivMod64U(Num, Den, &ret); + return ret; + #if 0 + if( Den == 0 ) return 5 / (Uint32)Den; // Force a #DIV0 + if( Num < Den ) return Num; + if( Den == 1 ) return 0; + if( Den == 2 ) return Num & 1; + if( Den == 16 ) return Num & 3; + if( Den == 256 ) return Num & 0xFF; + if( Den == 512 ) return Num & 0x1FF; + if( Den == 1024 ) return Num & 0x3FF; + if( Den == 2048 ) return Num & 0x7FF; + if( Den == 4096 ) return Num & 0xFFF; +// if( Num <= 0xFFFFFFFF && Den <= 0xFFFFFFFF ) +// return (Uint32)Num % (Uint32)Den; + + #if 0 + if( Den <= 0xFFFFFFFF ) { + (Uint32)(Num >> 32) / (Uint32)Den + } + #endif + for( ; Num > Den; Num -= Den ); + return Num; + #endif +} + +#define _divide_s_32(Num, Den, rem) __asm__ __volatile__ ( \ + "mov %0, #0\n" \ + " adds %1, %1, %1\n" \ + " .rept 32\n" \ + " adcs %0, %2, %0, lsl #1\n" \ + " subcc %0, %0, %3\n" \ + " adcs %1, %1, %1\n" \ + " .endr\n" \ + : "=r" (rem), "=r" (Num) \ + : "r" (Den) \ + : "cc" \ + ) +Uint32 __udivsi3(Uint32 Num, Uint32 Den) +{ + register Uint32 ret; + Uint64 P, D; + int i; + + if( Num == 0 ) return 0; + if( Den == 0 ) return 0xFFFFFFFF; // TODO: Throw an error + if( Den == 1 ) return Num; + + D = ((Uint64)Den) << 32; + + for( i = 32; i --; ) + { + P = 2*P - D; + if( P >= 0 ) + ret |= 1; + else + P += D; + ret <<= 1; + } + +// _divide_s_32(Num, Den, rem); + return Num; +} + +Uint32 __umodsi3(Uint32 Num, Uint32 Den) +{ + return Num - __udivsi3(Num, Den)*Den; +} + +Sint32 __divsi3(Sint32 Num, Sint32 Den) +{ + if( (Num < 0) && (Den < 0) ) + return __udivsi3(-Num, -Den); + else if( Num < 0 ) + return __udivsi3(-Num, Den); + else if( Den < 0 ) + return __udivsi3(Den, -Den); + else + return __udivsi3(Den, Den); +} + +Sint32 __modsi3(Sint32 Num, Sint32 Den) +{ + //register Sint32 rem; + //_divide_s_32(Num, Den, rem); + return Num - __divsi3(Num, Den) * Den; +} diff --git a/Kernel/arch/armv7/link.ld b/Kernel/arch/armv7/link.ld new file mode 100644 index 00000000..329bc9bd --- /dev/null +++ b/Kernel/arch/armv7/link.ld @@ -0,0 +1,37 @@ +ENTRY (_start) + +_kernel_base = 0x80000000; + +SECTIONS +{ + . = 0; + .init : + { + *(.init) + } + . += _kernel_base; + .text : AT( ADDR(.text) - _kernel_base ) + { + *(.text*) + *(.rodata*) + } + .data ALIGN(0x4000) : AT( ADDR(.data) - _kernel_base ) + { + *(.padata) + *(.data*) + + gKernelSymbols = .; + *(KEXPORT) + gKernelSymbolsEnd = .; + + gKernelModules = .; + *(KMODULES) + gKernelModulesEnd = .; + } + .bss : AT( ADDR(.bss) - _kernel_base ) + { + *(.bss*) + *(COMMON*) + } + gKernelEnd = .; +} diff --git a/Kernel/arch/armv7/main.c b/Kernel/arch/armv7/main.c new file mode 100644 index 00000000..b6186bbe --- /dev/null +++ b/Kernel/arch/armv7/main.c @@ -0,0 +1,50 @@ +/* + * Acess2 + * + * ARM7 Entrypoint + * arch/arm7/main.c + */ +#include + +// === IMPORTS === +extern void Interrupts_Setup(void); +extern void Arch_LoadBootModules(void); +extern void Heap_Install(void); +extern void Threads_Init(void); +extern void System_Init(const char *Commandline); + +// === PROTOTYPES === + int kmain(void); + +// === CODE === +int kmain(void) +{ + LogF("Acess2 ARMv7 v"EXPAND_STR(KERNEL_VERSION)"\n"); + LogF(" Build %i\n", BUILD_NUM); +// Interrupts_Setup(); + + MM_SetupPhys(); + + LogF("Heap Setup...\n"); + Heap_Install(); + + LogF("Threads Init...\n"); + Threads_Init(); + + LogF("VFS Init...\n"); + VFS_Init(); + + // Boot modules? + + // + LogF("Moving to arch-independent init\n"); + System_Init(""); + //TODO: + LogF("End of kmain(), for(;;);\n"); + for(;;); +} + +void Arch_LoadBootModules(void) +{ +} + diff --git a/Kernel/arch/armv7/mm_phys.c b/Kernel/arch/armv7/mm_phys.c new file mode 100644 index 00000000..0a7632ce --- /dev/null +++ b/Kernel/arch/armv7/mm_phys.c @@ -0,0 +1,54 @@ +/* + * Acess2 + * + * ARM7 Physical Memory Manager + * arch/arm7/mm_phys.c + */ +#define DEBUG 0 + +#include +#include + +#define MM_NUM_RANGES 1 // Single range +#define MM_RANGE_MAX 0 + +#define NUM_STATIC_ALLOC 4 + +char gStaticAllocPages[NUM_STATIC_ALLOC][PAGE_SIZE] __attribute__ ((section(".padata"))); +tPAddr gaiStaticAllocPages[NUM_STATIC_ALLOC] = { + (tPAddr)(&gStaticAllocPages[0]) - KERNEL_BASE, + (tPAddr)(&gStaticAllocPages[1]) - KERNEL_BASE, + (tPAddr)(&gStaticAllocPages[2]) - KERNEL_BASE, + (tPAddr)(&gStaticAllocPages[3]) - KERNEL_BASE +}; +extern char gKernelEnd[]; + +#include + +void MM_SetupPhys(void) +{ + MM_Tpl_InitPhys( 16*1024*1024/0x1000, NULL ); +} + +int MM_int_GetMapEntry( void *Data, int Index, tPAddr *Start, tPAddr *Length ) +{ + switch(Index) + { + case 0: + *Start = ((tVAddr)&gKernelEnd - KERNEL_BASE + 0xFFF) & ~0xFFF; + *Length = 16*1024*1024 - *Start; + return 1; + default: + return 0; + } +} + +/** + * \brief Takes a physical address and returns the ID of its range + * \param Addr Physical address of page + * \return Range ID from eMMPhys_Ranges + */ +int MM_int_GetRangeID( tPAddr Addr ) +{ + return MM_RANGE_MAX; // ARM doesn't need ranges +} diff --git a/Kernel/arch/armv7/mm_virt.c b/Kernel/arch/armv7/mm_virt.c new file mode 100644 index 00000000..c191c683 --- /dev/null +++ b/Kernel/arch/armv7/mm_virt.c @@ -0,0 +1,409 @@ +/* + * Acess2 + * + * ARM7 Virtual Memory Manager + * - arch/arm7/mm_virt.c + */ +#define DEBUG 0 +#include +#include +#include + +#define AP_KRW_ONLY 0x1 +#define AP_KRO_ONLY 0x5 +#define AP_RW_BOTH 0x3 +#define AP_RO_BOTH 0x6 + +// === IMPORTS === +extern Uint32 kernel_table0[]; + +// === TYPES === +typedef struct +{ + tPAddr PhysAddr; + Uint8 Size; + Uint8 Domain; + BOOL bExecutable; + BOOL bGlobal; + BOOL bShared; + int AP; +} tMM_PageInfo; + +//#define FRACTAL(table1, addr) ((table1)[ (0xFF8/4*1024) + ((addr)>>20)]) +#define FRACTAL(table1, addr) ((table1)[ (0xFF8/4*1024) + ((addr)>>22)]) +#define TLBIALL() __asm__ __volatile__ ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0)) + +// === PROTOTYPES === +void MM_int_GetTables(tVAddr VAddr, Uint32 **Table0, Uint32 **Table1); + int MM_int_AllocateCoarse(tVAddr VAddr, int Domain); + int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi); + int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi); +tVAddr MM_NewKStack(int bGlobal); + +// === GLOBALS === + +// === CODE === +int MM_InitialiseVirtual(void) +{ + return 0; +} + +void MM_int_GetTables(tVAddr VAddr, Uint32 **Table0, Uint32 **Table1) +{ + if(VAddr & 0x80000000) { + *Table0 = (void*)&kernel_table0; // Level 0 + *Table1 = (void*)MM_TABLE1KERN; // Level 1 + } + else { + *Table0 = (void*)MM_TABLE0USER; + *Table1 = (void*)MM_TABLE1USER; + } +} + +int MM_int_AllocateCoarse(tVAddr VAddr, int Domain) +{ + Uint32 *table0, *table1; + Uint32 *desc; + tPAddr paddr; + + ENTER("xVAddr iDomain", VAddr, Domain); + + MM_int_GetTables(VAddr, &table0, &table1); + + VAddr &= ~(0x400000-1); // 4MiB per "block", 1 Page + + desc = &table0[ VAddr>>20]; + LOG("desc = %p", desc); + + // table0: 4 bytes = 1 MiB + + LOG("desc[0] = %x", desc[0]); + LOG("desc[1] = %x", desc[1]); + LOG("desc[2] = %x", desc[2]); + LOG("desc[3] = %x", desc[3]); + + if( (desc[0] & 3) != 0 || (desc[1] & 3) != 0 + || (desc[2] & 3) != 0 || (desc[3] & 3) != 0 ) + { + // Error? + LEAVE('i', 1); + return 1; + } + + paddr = MM_AllocPhys(); + if( !paddr ) + { + // Error + LEAVE('i', 2); + return 2; + } + + *desc = paddr | (Domain << 5) | 1; + desc[1] = desc[0] + 0x400; + desc[2] = desc[0] + 0x800; + desc[3] = desc[0] + 0xC00; + + FRACTAL(table1, VAddr) = paddr | 3; + + // TLBIALL + TLBIALL(); + + LEAVE('i', 0); + return 0; +} + +int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi) +{ + Uint32 *table0, *table1; + Uint32 *desc; + + ENTER("pVADdr ppi", VAddr, pi); + + MM_int_GetTables(VAddr, &table0, &table1); + + desc = &table0[ VAddr >> 20 ]; + LOG("desc = %p", desc); + + switch(pi->Size) + { + case 12: // Small Page + case 16: // Large Page + LOG("Page"); + if( (*desc & 3) == 0 ) { + MM_int_AllocateCoarse( VAddr, pi->Domain ); + } + desc = &table1[ VAddr >> 12 ]; + LOG("desc (2) = %p", desc); + if( pi->Size == 12 ) + { + // Small page + // - Error if overwriting a large page + if( (*desc & 3) == 1 ) LEAVE_RET('i', 1); + if( pi->PhysAddr == 0 ) { + *desc = 0; + LEAVE('i', 0); + return 0; + } + + *desc = (pi->PhysAddr & 0xFFFFF000) | 2; + if(!pi->bExecutable) *desc |= 1; // XN + if(!pi->bGlobal) *desc |= 1 << 11; // NG + if( pi->bShared) *desc |= 1 << 10; // S + *desc |= (pi->AP & 3) << 4; // AP + *desc |= ((pi->AP >> 2) & 1) << 9; // APX + LEAVE('i', 0); + return 0; + } + else + { + // Large page + // TODO: + } + break; + case 20: // Section or unmapped + Warning("TODO: Implement sections"); + break; + case 24: // Supersection + // Error if not aligned + if( VAddr & 0xFFFFFF ) { + LEAVE('i', 1); + return 1; + } + if( (*desc & 3) == 0 || ((*desc & 3) == 2 && (*desc & (1 << 18))) ) + { + if( pi->PhysAddr == 0 ) { + *desc = 0; + // TODO: Apply to all entries + LEAVE('i', 0); + return 0; + } + // Apply + *desc = pi->PhysAddr & 0xFF000000; +// *desc |= ((pi->PhysAddr >> 32) & 0xF) << 20; +// *desc |= ((pi->PhysAddr >> 36) & 0x7) << 5; + *desc |= 2 | (1 << 18); + // TODO: Apply to all entries + LEAVE('i', 0); + return 0; + } + // TODO: What here? + LEAVE('i', 1); + return 1; + } + + LEAVE('i', 1); + return 1; +} + +extern tShortSpinlock glDebug_Lock; + +int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi) +{ + Uint32 *table0, *table1; + Uint32 desc; + + MM_int_GetTables(VAddr, &table0, &table1); + + desc = table0[ VAddr >> 20 ]; + +// if( VAddr > 0x90000000) +// LOG("table0 desc(%p) = %x", &table0[ VAddr >> 20 ], desc); + + pi->bExecutable = 1; + pi->bGlobal = 0; + pi->bShared = 0; + + + switch( (desc & 3) ) + { + // 0: Unmapped + case 0: + pi->PhysAddr = 0; + pi->Size = 20; + pi->Domain = 0; + return 1; + + // 1: Coarse page table + case 1: + // Domain from top level table + pi->Domain = (desc >> 5) & 7; + // Get next level + desc = table1[ VAddr >> 12 ]; +// LOG("table1 desc(%p) = %x", &table1[ VAddr >> 12 ], desc); + switch( desc & 3 ) + { + // 0: Unmapped + case 0: + pi->Size = 12; + return 1; + // 1: Large Page (64KiB) + case 1: + pi->Size = 16; + pi->PhysAddr = desc & 0xFFFF0000; + return 0; + // 2/3: Small page + case 2: + case 3: + pi->Size = 12; + pi->PhysAddr = desc & 0xFFFFF000; + pi->bExecutable = desc & 1; + pi->bGlobal = !(desc >> 11); + pi->bShared = (desc >> 10) & 1; + return 0; + } + return 1; + + // 2: Section (or Supersection) + case 2: + if( desc & (1 << 18) ) { + // Supersection + pi->PhysAddr = desc & 0xFF000000; + pi->PhysAddr |= (Uint64)((desc >> 20) & 0xF) << 32; + pi->PhysAddr |= (Uint64)((desc >> 5) & 0x7) << 36; + pi->Size = 24; + pi->Domain = 0; // Superpages default to zero + return 0; + } + + // Section + pi->PhysAddr = desc & 0xFFF80000; + pi->Size = 20; + pi->Domain = (desc >> 5) & 7; + return 0; + + // 3: Reserved (invalid) + case 3: + pi->PhysAddr = 0; + pi->Size = 20; + pi->Domain = 0; + return 2; + } + return 2; +} + +// --- Exports --- +tPAddr MM_GetPhysAddr(tVAddr VAddr) +{ + tMM_PageInfo pi; + if( MM_int_GetPageInfo(VAddr, &pi) ) + return 0; + return pi.PhysAddr | (VAddr & ((1 << pi.Size)-1)); +} + +Uint MM_GetFlags(tVAddr VAddr) +{ + tMM_PageInfo pi; + int ret; + + if( MM_int_GetPageInfo(VAddr, &pi) ) + return 0; + + ret = 0; + + switch(pi.AP) + { + case AP_KRW_ONLY: + ret |= MM_PFLAG_KERNEL; + break; + case AP_KRO_ONLY: + ret |= MM_PFLAG_KERNEL|MM_PFLAG_RO; + break; + case AP_RW_BOTH: + break; + case AP_RO_BOTH: + ret |= MM_PFLAG_RO; + break; + } + + if( pi.bExecutable ) ret |= MM_PFLAG_EXEC; + return ret; +} + +void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask) +{ + tMM_PageInfo pi; + if( MM_int_GetPageInfo(VAddr, &pi) ) + return; + + + +} + +int MM_Map(tVAddr VAddr, tPAddr PAddr) +{ + tMM_PageInfo pi = {0}; + pi.PhysAddr = PAddr; + pi.Size = 12; + pi.AP = AP_KRW_ONLY; // Kernel Read/Write + pi.bExecutable = 1; + if( MM_int_SetPageInfo(VAddr, &pi) ) { + MM_DerefPhys(pi.PhysAddr); + return 0; + } + return pi.PhysAddr; +} + +tPAddr MM_Allocate(tVAddr VAddr) +{ + tMM_PageInfo pi = {0}; + + ENTER("pVAddr", VAddr); + + pi.PhysAddr = MM_AllocPhys(); + if( pi.PhysAddr == 0 ) LEAVE_RET('i', 0); + pi.Size = 12; + pi.AP = AP_KRW_ONLY; // Kernel Read/Write + pi.bExecutable = 1; + if( MM_int_SetPageInfo(VAddr, &pi) ) { + MM_DerefPhys(pi.PhysAddr); + LEAVE('i', 0); + return 0; + } + LEAVE('x', pi.PhysAddr); + return pi.PhysAddr; +} + +void MM_Deallocate(tVAddr VAddr) +{ + tMM_PageInfo pi; + + if( MM_int_GetPageInfo(VAddr, &pi) ) return ; + + if( pi.PhysAddr == 0 ) return; + MM_DerefPhys(pi.PhysAddr); + + pi.PhysAddr = 0; + pi.AP = 0; + pi.bExecutable = 0; + MM_int_SetPageInfo(VAddr, &pi); +} + +tPAddr MM_ClearUser(void) +{ + // TODO: Implement ClearUser + return 0; +} + +tVAddr MM_MapTemp(tPAddr PAddr) +{ + // TODO: Implement MapTemp + return 0; +} + +void MM_FreeTemp(tVAddr VAddr) +{ + // TODO: Implement FreeTemp +} + +tVAddr MM_NewKStack(int bGlobal) +{ + // TODO: Implement NewKStack + // TODO: Should I support global stacks? if only for the idle thread + return 0; +} + +void MM_DumpTables(tVAddr Start, tVAddr End) +{ + +} + diff --git a/Kernel/arch/armv7/pci.c b/Kernel/arch/armv7/pci.c new file mode 100644 index 00000000..0d25049f --- /dev/null +++ b/Kernel/arch/armv7/pci.c @@ -0,0 +1,48 @@ +/* + * + */ +#include + +// Realview +//#define PCI_BASE 0x60000000 + +//#define PCI_BASE 0xF0400000 // VMM Mapping +#define PCI_BASE 0 + +// === PROTOTYPES === +#if 1 +void PCI_CfgWriteDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset, Uint32 data); +Uint32 PCI_CfgReadDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset); +Uint16 PCI_CfgReadWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset); +Uint8 PCI_CfgReadByte(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset); +#endif + +// === CODE === +void PCI_CfgWriteDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset, Uint32 data) +{ + #if PCI_BASE + Uint32 address = PCI_BASE | ((Uint)bus<<16) | ((Uint)dev<<11) | ((Uint)func<<8) | (offset&0xFC); + *(Uint32*)(address) = data; + #else + #endif +} + +Uint32 PCI_CfgReadDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset) +{ + #if PCI_BASE + Uint32 address = PCI_BASE | ((Uint)bus<<16) | ((Uint)dev<<11) | ((Uint)func<<8) | (offset&0xFC); + return *(Uint32*)address; + #else + return 0xFFFFFFFF; + #endif +} + +Uint16 PCI_CfgReadWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset) +{ + return PCI_CfgReadDWord(bus, dev, func, offset & ~3) >> (8*(offset&2)); +} + +Uint8 PCI_CfgReadByte(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset) +{ + return PCI_CfgReadDWord(bus, dev, func, offset & ~3) >> (8*(offset&3)); +} diff --git a/Kernel/arch/armv7/proc.S b/Kernel/arch/armv7/proc.S new file mode 100644 index 00000000..841764b6 --- /dev/null +++ b/Kernel/arch/armv7/proc.S @@ -0,0 +1,95 @@ +/* + * Acess2 ARM + * - By John Hodge (thePowersGang) + * + * arch/arm7/proc.S + * - Process management assembly + */ + +#define PUSH_GPRS \ + str r0, [sp,#-1*4];\ + str r1, [sp,#-2*4];\ + str r2, [sp,#-3*4];\ + str r3, [sp,#-4*4];\ + str r4, [sp,#-5*4];\ + str r5, [sp,#-6*4];\ + str r6, [sp,#-7*4];\ + str r7, [sp,#-8*4];\ + str r8, [sp,#-9*4];\ + str r9, [sp,#-10*4];\ + str r10, [sp,#-11*4];\ + str r11, [sp,#-12*4];\ + str r12, [sp,#-13*4];\ + str sp, [sp,#-14*4];\ + str lr, [sp,#-15*4];\ + sub sp, #16*4 + +#define POP_GPRS add sp, #16*4; \ + ldr r0, [sp,#-1*4]; \ + ldr r1, [sp,#-2*4]; \ + ldr r2, [sp,#-3*4]; \ + ldr r3, [sp,#-4*4]; \ + ldr r4, [sp,#-5*4]; \ + ldr r5, [sp,#-6*4]; \ + ldr r6, [sp,#-7*4]; \ + ldr r7, [sp,#-8*4]; \ + ldr r8, [sp,#-9*4]; \ + ldr r9, [sp,#-10*4]; \ + ldr r10, [sp,#-11*4]; \ + ldr r11, [sp,#-12*4]; \ + ldr r12, [sp,#-13*4]; \ + ldr lr, [sp,#-15*4]; + +.globl KernelThreadHeader +@ SP+12: Argument 1 +@ SP+8: Argument Count +@ SP+4: Function +@ SP+0: Thread Pointer +KernelThreadHeader: + ldr r0, [sp],#4 + @ TODO: Do something with the thread pointer + + ldr r4, [sp],#4 @ Function + ldr r5, [sp],#4 + @ Get arguments + sub r5, #1 + ldrhs r0, [sp],#4 + sub r5, #1 + ldrhs r1, [sp],#4 + sub r5, #1 + ldrhs r2, [sp],#4 + sub r5, #1 + ldrhs r3, [sp],#4 + + mov lr, pc + mov pc, r4 + + ldr r0, =0 + bl Threads_Exit + b . + +.globl SwitchTask +@ R0: New stack +@ R1: Pointer to where to save old stack +@ R2: New IP +@ R3: Pointer to save old IP +@ SP+0: New address space +SwitchTask: + PUSH_GPRS + + ldr r4, =.return + str r4, [r3] + str sp, [r1] + mov r0, sp + + @ Only update TTBR0 if the task has an explicit address space + ldr r0, [sp,#0x40] + tst r0, r0 + mcrne p15, 0, r0, c2, c0, 0 @ Set TTBR0 to r0 + + mov pc, r2 + +.return: + POP_GPRS + bx lr + diff --git a/Kernel/arch/armv7/proc.c b/Kernel/arch/armv7/proc.c new file mode 100644 index 00000000..f4025cca --- /dev/null +++ b/Kernel/arch/armv7/proc.c @@ -0,0 +1,125 @@ +/* + * Acess2 + * - By John Hodge (thePowersGang) + * + * arch/arm7/proc. + * - ARM7 Process Switching + */ +#include +#include +#include + +// === IMPORTS === +extern tThread gThreadZero; +extern void SwitchTask(Uint32 NewSP, Uint32 *OldSP, Uint32 NewIP, Uint32 *OldIP, Uint32 MemPtr); +extern void KernelThreadHeader(void); // Actually takes args +extern tVAddr MM_NewKStack(int bGlobal); // TODO: Move out into a header + +// === PROTOTYPES === +void Proc_IdleThread(void *unused); +tTID Proc_NewKThread( void (*Fnc)(void*), void *Ptr ); + +// === GLOBALS === +tThread *gpCurrentThread = &gThreadZero; +tThread *gpIdleThread = NULL; + +// === CODE === +void ArchThreads_Init(void) +{ +} + +void Proc_IdleThread(void *unused) +{ + for(;;) + Proc_Reschedule(); +} + +void Proc_Start(void) +{ + tTID tid; + + tid = Proc_NewKThread( Proc_IdleThread, NULL ); + gpIdleThread = Threads_GetThread(tid); +} + +int GetCPUNum(void) +{ + return 0; +} + +tThread *Proc_GetCurThread(void) +{ + return gpCurrentThread; +} + +tTID Proc_Clone(Uint Flags) +{ + return -1; +} + +void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize) +{ +} + +tTID Proc_SpawnWorker( void (*Fnc)(void*), void *Ptr ) +{ + return -1; +} + +tTID Proc_NewKThread( void (*Fnc)(void*), void *Ptr ) +{ + tThread *new; + Uint32 sp; + + new = Threads_CloneTCB(NULL, 0); + if(!new) return -1; + + new->KernelStack = MM_NewKStack(0); + if(!new->KernelStack) { + // TODO: Delete thread + return -1; + } + + sp = new->KernelStack; + + *(Uint32*)(sp -= 4) = (Uint)new; + *(Uint32*)(sp -= 4) = (Uint)Fnc; + *(Uint32*)(sp -= 4) = 1; + *(Uint32*)(sp -= 4) = (Uint)Ptr; + + new->SavedState.SP = sp; + new->SavedState.IP = (Uint)KernelThreadHeader; + + Threads_AddActive(new); + + return new->TID; +} + +void Proc_CallFaultHandler(tThread *Thread) +{ + +} + +void Proc_Reschedule(void) +{ + tThread *cur, *next; + + cur = gpCurrentThread; + + next = Threads_GetNextToRun(0, cur); + if(!next) next = gpIdleThread; + if(!next || next == cur) return; + + SwitchTask( + next->SavedState.SP, &cur->SavedState.SP, + next->SavedState.IP, &cur->SavedState.IP, + next->MemState.Base + ); + +} + +void Proc_DumpThreadCPUState(tThread *Thread) +{ + +} + diff --git a/Kernel/arch/armv7/start.S b/Kernel/arch/armv7/start.S new file mode 100644 index 00000000..718131c0 --- /dev/null +++ b/Kernel/arch/armv7/start.S @@ -0,0 +1,124 @@ +KERNEL_BASE = 0x80000000 +PCI_PADDR = 0x60000000 @ Realview +UART0_PADDR = 0x10009000 @ Realview +@ +@ Exception defs taken from ARM DDI 0406B +@ +.section .init +interrupt_vector_table: + b _start @ Reset + b . @ #UD + b SyscallHandler @ SVC (SWI assume) + b . @ Prefetch abort + b . @ Data abort + b . @ Not Used + b IRQHandler @ IRQ + b . @ FIQ (Fast interrupt) + +.globl _start +_start: + ldr r0, =kernel_table0-KERNEL_BASE + mcr p15, 0, r0, c2, c0, 1 @ Set TTBR1 to r0 + mcr p15, 0, r0, c2, c0, 0 @ Set TTBR0 to r0 too (for identity) + + mov r0, #1 + mcr p15, 0, r0, c2, c0, 2 @ Set TTCR to 1 (50/50 split) + + mov r0, #3 + mcr p15, 0, r0, c3, c0, 0 @ Set Domain 0 to Manager + + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #1 + orr r0, r0, #1 << 23 + mcr p15, 0, r0, c1, c0, 0 + + ldr sp, =stack+0x10000 @ Set up stack + ldr r0, =kmain + mov pc, r0 +1: b 1b @ Infinite loop +_ptr_kmain: + .long kmain + +.comm stack, 0x10000 @ ; 64KiB Stack + +SyscallHandler: + b . + +IRQHandler: + b . + +.section .padata +.globl kernel_table0 + +kernel_table0: + .long 0x00000002 @ Identity map the first 1 MiB + .rept 0x800 - 1 + .long 0 + .endr + .long 0x00000002 @ Map first 4 MiB to 2GiB + .long 0x00100002 @ + .long 0x00200002 @ + .long 0x00300002 @ + .rept 0xF00 - 0x800 - 4 + .long 0 + .endr +#if PCI_PADDR + .long PCI_PADDR + 0*(1 << 20) + 2 @ Map PCI config space + .long PCI_PADDR + 1*(1 << 20) + 2 + .long PCI_PADDR + 2*(1 << 20) + 2 + .long PCI_PADDR + 3*(1 << 20) + 2 + .long PCI_PADDR + 4*(1 << 20) + 2 + .long PCI_PADDR + 5*(1 << 20) + 2 + .long PCI_PADDR + 6*(1 << 20) + 2 + .long PCI_PADDR + 7*(1 << 20) + 2 + .long PCI_PADDR + 8*(1 << 20) + 2 + .long PCI_PADDR + 9*(1 << 20) + 2 + .long PCI_PADDR + 10*(1 << 20) + 2 + .long PCI_PADDR + 11*(1 << 20) + 2 + .long PCI_PADDR + 12*(1 << 20) + 2 + .long PCI_PADDR + 13*(1 << 20) + 2 + .long PCI_PADDR + 14*(1 << 20) + 2 + .long PCI_PADDR + 15*(1 << 20) + 2 +#else + .rept 16 + .long 0 + .endr +#endif + .long hwmap_table_0 + 0x000 - KERNEL_BASE + 1 + .long hwmap_table_0 + 0x400 - KERNEL_BASE + 1 + .long hwmap_table_0 + 0x800 - KERNEL_BASE + 1 + .long hwmap_table_0 + 0xC00 - KERNEL_BASE + 1 + .rept 0xFF8 - 0xF00 - 16 - 4 + .long 0 + .endr + @ Page fractals + .long kernel_table1_map + 0x000 - KERNEL_BASE + 1 + .long kernel_table1_map + 0x400 - KERNEL_BASE + 1 + .long kernel_table1_map + 0x800 - KERNEL_BASE + 1 + .long kernel_table1_map + 0xC00 - KERNEL_BASE + 1 + @ Top level fractals + .long 0 @ removed for alignment constraints, using the KERNEL_BASE identity mapping instead + .rept 0x1000 - 0xFF8 - 5 + .long 0 + .endr + +.globl kernel_table1_map +kernel_table1_map: @ Size = 4KiB + .rept 0xF00/4 + .long 0 + .endr + .long hwmap_table_0 - KERNEL_BASE + (1 << 4) + 3 + .rept 0xFF8/4 - 0xF00/4 - 1 + .long 0 + .endr + .long kernel_table1_map - KERNEL_BASE + (1 << 4) + 3 + .long 0 + +@ Hardware mappings +.globl hwmap_table_0 +hwmap_table_0: + .long UART0_PADDR + (1 << 4) + 3 @ UART0 + .rept 1024 - 1 + .long 0 + .endr + diff --git a/Kernel/arch/armv7/time.c b/Kernel/arch/armv7/time.c new file mode 100644 index 00000000..d4ae4fa6 --- /dev/null +++ b/Kernel/arch/armv7/time.c @@ -0,0 +1,16 @@ +/* + * Acess2 + * + * ARM7 Time code + * arch/arm7/time.c + */ +#include + +// === GLOBALS === +tTime giTimestamp; + +// === CODE === +tTime now(void) +{ + return giTimestamp; +}