+++ /dev/null
-#
-# 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)
-
+++ /dev/null
-/**
- * Acess2
- * - By John Hodge (thePowersGang)
- *
- * arch/arm7/debug.c
- * - ARM7 Debug output
- * NOTE: Currently designed for the realview-pb-a8 emulated by Qemu
- */
-#include <acess.h>
-
-// === 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)
-{
-}
-
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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
-
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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
-
+++ /dev/null
-/*
- * Acess2 ARM7 Port
- *
- * lib.c - Library Functions
- */
-#include <acess.h>
-
-// === 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;
-}
+++ /dev/null
-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 = .;
-}
+++ /dev/null
-/*
- * Acess2
- *
- * ARM7 Entrypoint
- * arch/arm7/main.c
- */
-#include <acess.h>
-
-// === 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)
-{
-}
-
+++ /dev/null
-/*
- * Acess2
- *
- * ARM7 Physical Memory Manager
- * arch/arm7/mm_phys.c
- */
-#define DEBUG 0
-
-#include <acess.h>
-#include <mm_virt.h>
-
-#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 <tpl_mm_phys_bitmap.h>
-
-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
-}
+++ /dev/null
-/*
- * Acess2
- *
- * ARM7 Virtual Memory Manager
- * - arch/arm7/mm_virt.c
- */
-#define DEBUG 0
-#include <acess.h>
-#include <mm_virt.h>
-#include <hal_proc.h>
-
-#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)
-{
-
-}
-
+++ /dev/null
-/*
- *
- */
-#include <acess.h>
-
-// 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));
-}
+++ /dev/null
-/*
- * 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
-
+++ /dev/null
-/*
- * Acess2
- * - By John Hodge (thePowersGang)
- *
- * arch/arm7/proc.
- * - ARM7 Process Switching
- */
-#include <acess.h>
-#include <threads_int.h>
-#include <hal_proc.h>
-
-// === 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)
-{
-
-}
-
+++ /dev/null
-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
-
+++ /dev/null
-/*
- * Acess2
- *
- * ARM7 Time code
- * arch/arm7/time.c
- */
-#include <acess.h>
-
-// === GLOBALS ===
-tTime giTimestamp;
-
-// === CODE ===
-tTime now(void)
-{
- return giTimestamp;
-}
--- /dev/null
+#
+# 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)
+
--- /dev/null
+/**
+ * Acess2
+ * - By John Hodge (thePowersGang)
+ *
+ * arch/arm7/debug.c
+ * - ARM7 Debug output
+ * NOTE: Currently designed for the realview-pb-a8 emulated by Qemu
+ */
+#include <acess.h>
+
+// === 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)
+{
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * Acess2 ARM7 Port
+ *
+ * lib.c - Library Functions
+ */
+#include <acess.h>
+
+// === 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;
+}
--- /dev/null
+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 = .;
+}
--- /dev/null
+/*
+ * Acess2
+ *
+ * ARM7 Entrypoint
+ * arch/arm7/main.c
+ */
+#include <acess.h>
+
+// === 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)
+{
+}
+
--- /dev/null
+/*
+ * Acess2
+ *
+ * ARM7 Physical Memory Manager
+ * arch/arm7/mm_phys.c
+ */
+#define DEBUG 0
+
+#include <acess.h>
+#include <mm_virt.h>
+
+#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 <tpl_mm_phys_bitmap.h>
+
+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
+}
--- /dev/null
+/*
+ * Acess2
+ *
+ * ARM7 Virtual Memory Manager
+ * - arch/arm7/mm_virt.c
+ */
+#define DEBUG 0
+#include <acess.h>
+#include <mm_virt.h>
+#include <hal_proc.h>
+
+#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)
+{
+
+}
+
--- /dev/null
+/*
+ *
+ */
+#include <acess.h>
+
+// 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));
+}
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * Acess2
+ * - By John Hodge (thePowersGang)
+ *
+ * arch/arm7/proc.
+ * - ARM7 Process Switching
+ */
+#include <acess.h>
+#include <threads_int.h>
+#include <hal_proc.h>
+
+// === 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)
+{
+
+}
+
--- /dev/null
+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
+
--- /dev/null
+/*
+ * Acess2
+ *
+ * ARM7 Time code
+ * arch/arm7/time.c
+ */
+#include <acess.h>
+
+// === GLOBALS ===
+tTime giTimestamp;
+
+// === CODE ===
+tTime now(void)
+{
+ return giTimestamp;
+}