diff --git a/src/system/boot/arch/arm/Jamfile b/src/system/boot/arch/arm/Jamfile index c24ccde2be..43506aad36 100644 --- a/src/system/boot/arch/arm/Jamfile +++ b/src/system/boot/arch/arm/Jamfile @@ -24,7 +24,7 @@ KernelMergeObject boot_arch_$(TARGET_ARCH).o : $(kernelLibArchObjects) ; -SEARCH on [ FGristFiles arch_elf.cpp ] +SEARCH on [ FGristFiles arch_elf.cpp uart.c ] = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_ARCH) ] ; SEARCH on [ FGristFiles $(librootArchObjects) ] diff --git a/src/system/kernel/arch/arm/Jamfile b/src/system/kernel/arch/arm/Jamfile new file mode 100644 index 0000000000..c85efd0f68 --- /dev/null +++ b/src/system/kernel/arch/arm/Jamfile @@ -0,0 +1,42 @@ +SubDir HAIKU_TOP src system kernel arch arm ; + +SubDirHdrs $(SUBDIR) $(DOTDOT) generic ; +UsePrivateKernelHeaders ; +UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) board $(TARGET_BOOT_BOARD) ] ; + + +SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ; + + +KernelMergeObject kernel_arch_arm.o : +# arch_atomic.c + arch_commpage.cpp + arch_cpu.cpp +# arch_cpu_asm.S + arch_debug_console.cpp + arch_debug.cpp + arch_elf.cpp +# arch_exceptions.S + arch_int.cpp + arch_platform.cpp + arch_real_time_clock.cpp + arch_smp.c + arch_system_info.cpp + arch_thread.c + arch_timer.cpp + arch_user_debugger.cpp + arch_vm.cpp + arch_vm_translation_map.cpp + arch_asm.S + uart.c + generic_vm_physical_page_mapper.cpp + generic_vm_physical_page_ops.cpp +# + : + $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused + : + +; + +CreateAsmStructOffsetsHeader asm_offsets.h : asm_offsets.cpp ; + diff --git a/src/system/kernel/arch/arm/arch_asm.S b/src/system/kernel/arch/arm/arch_asm.S new file mode 100644 index 0000000000..07fd53326f --- /dev/null +++ b/src/system/kernel/arch/arm/arch_asm.S @@ -0,0 +1,56 @@ +/* + * Copyright 2009, Wischert, johanneswi@gmail.com. + * All rights reserved. Distributed under the terms of the MIT License. + * + * Copyright 2003, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + +#include + +#include + +.text + + + +/* void arch_int_enable_interrupts(void) */ +FUNCTION(arch_int_enable_interrupts): + mrs r0, cpsr + bic r0, r0, #(1<<7) /* clear the I bit */ + msr cpsr_c, r0 + bx lr +FUNCTION_END(arch_int_enable_interrupts) + + +/* int arch_int_disable_interrupts(void) + */ +FUNCTION(arch_int_disable_interrupts): + mrs r0, cpsr + orr r0, r0, #(1<<7) + msr cpsr_c, r0 + bx lr +FUNCTION_END(arch_int_disable_interrupts) + + +/* void arch_int_restore_interrupts(int oldState) + */ +FUNCTION(arch_int_restore_interrupts): + mrs r1, cpsr + orr r0,r0, #(1<<7) + bic r1, r1,#(1<<7) + orr r1, r1, r0 + msr cpsr_c, r1 + bx lr +FUNCTION_END(arch_int_restore_interrupts) + + +/* bool arch_int_are_interrupts_enabled(void) */ +FUNCTION(arch_int_are_interrupts_enabled): + mrs r0, cpsr + and r0, r0, #(1<<7) /*read the I bit*/ + mvn r0, r0 /*negate it since 1 means disabled interrupts*/ + bx lr +FUNCTION_END(arch_int_are_interrupts_enabled) + + diff --git a/src/system/kernel/arch/arm/arch_commpage.cpp b/src/system/kernel/arch/arm/arch_commpage.cpp new file mode 100644 index 0000000000..f23962aecb --- /dev/null +++ b/src/system/kernel/arch/arm/arch_commpage.cpp @@ -0,0 +1,36 @@ +/* + * Copyright 2009, Johannes Wischert, johanneswi@gmail.com. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include + +#include + +#include +#include +#include + + +status_t +arch_commpage_init(void) +{ + /* no optimized memcpy or anything yet */ + /* we don't use it for syscall yet either */ + // add syscall to the commpage image +// image_id image = get_commpage_image(); +#warning ARM:IMPLEMENTME + return B_OK; +} + + +status_t +arch_commpage_init_post_cpus(void) +{ +#warning ARM:IMPLEMENTME + return B_OK; +} + diff --git a/src/system/kernel/arch/arm/arch_cpu.cpp b/src/system/kernel/arch/arm/arch_cpu.cpp new file mode 100644 index 0000000000..35b9ca4a40 --- /dev/null +++ b/src/system/kernel/arch/arm/arch_cpu.cpp @@ -0,0 +1,293 @@ +/* + * Copyright 2007, François Revol, revol@free.fr. + * Distributed under the terms of the MIT License. + * + * Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + * + * Copyright 2001, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + + +#include + +//#include +#include +#include +#include +#include +#include + + +int arch_cpu_type; +int arch_fpu_type; +int arch_mmu_type; +int arch_platform; + +status_t +arch_cpu_preboot_init_percpu(kernel_args *args, int curr_cpu) +{ + // enable FPU + //ppc:set_msr(get_msr() | MSR_FP_AVAILABLE); + + // The current thread must be NULL for all CPUs till we have threads. + // Some boot code relies on this. + arch_thread_set_current_thread(NULL); + + return B_OK; +} + + +status_t +arch_cpu_init_percpu(kernel_args *args, int curr_cpu) +{ + //detect_cpu(curr_cpu); + + // we only support one anyway... + return 0; +} + + +status_t +arch_cpu_init(kernel_args *args) +{ + arch_cpu_type = args->arch_args.cpu_type; + arch_fpu_type = args->arch_args.fpu_type; + arch_mmu_type = args->arch_args.mmu_type; + arch_platform = args->arch_args.platform; + arch_platform = args->arch_args.machine; +#warning TODO arch_cpu_init + return B_OK; +} + + +status_t +arch_cpu_init_post_vm(kernel_args *args) +{ + return B_OK; +} + +status_t +arch_cpu_init_post_modules(kernel_args *args) +{ + // add the functions to the commpage image + image_id image = get_commpage_image(); + + return B_OK; +} + + +void +arch_cpu_sync_icache(void *address, size_t len) +{ +#warning ARM arch_cpu_sync_icache + +// cpu_ops.flush_icache((addr_t)address, len); +} + + +void +arch_cpu_memory_read_barrier(void) +{ + asm volatile ("nop;" : : : "memory"); +#warning M68k: check arch_cpu_memory_read_barrier (FNOP ?) +} + + +void +arch_cpu_memory_write_barrier(void) +{ + asm volatile ("nop;" : : : "memory"); +#warning M68k: check arch_cpu_memory_write_barrier (FNOP ?) +} + + +void +arch_cpu_invalidate_TLB_range(addr_t start, addr_t end) +{ +/* int32 num_pages = end / B_PAGE_SIZE - start / B_PAGE_SIZE; + cpu_ops.flush_insn_pipeline(); + while (num_pages-- >= 0) { + cpu_ops.flush_atc_addr(start); + cpu_ops.flush_insn_pipeline(); + start += B_PAGE_SIZE; + } + cpu_ops.flush_insn_pipeline(); +*/ +#warning WRITEME arch_cpu_invalidate_TLB_range +} + + +void +arch_cpu_invalidate_TLB_list(addr_t pages[], int num_pages) +{ +/* + int i; + + cpu_ops.flush_insn_pipeline(); + for (i = 0; i < num_pages; i++) { + cpu_ops.flush_atc_addr(pages[i]); + cpu_ops.flush_insn_pipeline(); + } + cpu_ops.flush_insn_pipeline(); +*/ +#warning WRITEME arch_cpu_invalidate_TLB_lis +} + + +void +arch_cpu_global_TLB_invalidate(void) +{ +/* cpu_ops.flush_insn_pipeline(); + cpu_ops.flush_atc_all(); + cpu_ops.flush_insn_pipeline(); +*/ +#warning WRITEME arch_cpu_global_TLB_invalidate +} + + +void +arch_cpu_user_TLB_invalidate(void) +{/* + cpu_ops.flush_insn_pipeline(); + cpu_ops.flush_atc_user(); + cpu_ops.flush_insn_pipeline(); +*/ +#warning WRITEME + +} + + +status_t +arch_cpu_user_memcpy(void *to, const void *from, size_t size, + addr_t *faultHandler) +{ +#warning WRITEME +/* + char *tmp = (char *)to; + char *s = (char *)from; + addr_t oldFaultHandler = *faultHandler; + + if (m68k_set_fault_handler(faultHandler, (addr_t)&&error)) + goto error; + + while (size--) + *tmp++ = *s++; + + *faultHandler = oldFaultHandler; + return 0; + +error: + *faultHandler = oldFaultHandler;*/ + return B_BAD_ADDRESS; +} + + +/** \brief Copies at most (\a size - 1) characters from the string in \a from to + * the string in \a to, NULL-terminating the result. + * + * \param to Pointer to the destination C-string. + * \param from Pointer to the source C-string. + * \param size Size in bytes of the string buffer pointed to by \a to. + * + * \return strlen(\a from). + */ + +ssize_t +arch_cpu_user_strlcpy(char *to, const char *from, size_t size, addr_t *faultHandler) +{ +#warning WRITEME +/* + int from_length = 0; + addr_t oldFaultHandler = *faultHandler; + + if (m68k_set_fault_handler(faultHandler, (addr_t)&&error)) + goto error; + + if (size > 0) { + to[--size] = '\0'; + // copy + for ( ; size; size--, from_length++, to++, from++) { + if ((*to = *from) == '\0') + break; + } + } + // count any leftover from chars + while (*from++ != '\0') + from_length++; + + *faultHandler = oldFaultHandler; + return from_length; + +error: + *faultHandler = oldFaultHandler;*/ + return B_BAD_ADDRESS; +} + + +status_t +arch_cpu_user_memset(void *s, char c, size_t count, addr_t *faultHandler) +{ +#warning WRITEME + +/* + char *xs = (char *)s; + addr_t oldFaultHandler = *faultHandler; + + if (m68k_set_fault_handler(faultHandler, (addr_t)&&error)) + goto error; + + while (count--) + *xs++ = c; + + *faultHandler = oldFaultHandler; + return 0; + +error: + *faultHandler = oldFaultHandler;*/ + + return B_BAD_ADDRESS; +} + + +status_t +arch_cpu_shutdown(bool reboot) +{ +#warning WRITEME +// M68KPlatform::Default()->ShutDown(reboot); + return B_ERROR; +} + + +void +arch_cpu_idle(void) +{ +#warning WRITEME + +// if (cpu_ops.idle) +// cpu_ops.idle(); +//#warning M68K: use LPSTOP ? + //asm volatile ("lpstop"); +} + + +// The purpose of this function is to trick the compiler. When setting the +// page_handler to a label that is obviously (to the compiler) never used, +// it may reorganize the control flow, so that the labeled part is optimized +// away. +// By invoking the function like this +// +// if (m68k_set_fault_handler(faultHandler, (addr_t)&&error)) +// goto error; +// +// the compiler has to keep the labeled code, since it can't guess the return +// value of this (non-inlinable) function. At least in my tests it worked that +// way, and I hope it will continue to work like this in the future. +// +/*bool +m68k_set_fault_handler(addr_t *handlerLocation, addr_t handler) +{ + *handlerLocation = handler; + return false; +}*/ diff --git a/src/system/kernel/arch/arm/arch_debug.cpp b/src/system/kernel/arch/arm/arch_debug.cpp new file mode 100644 index 0000000000..81f494ee12 --- /dev/null +++ b/src/system/kernel/arch/arm/arch_debug.cpp @@ -0,0 +1,394 @@ +/* + * Copyright 2003-2008, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler + * Ingo Weinhold + * François Revol + */ + + +#include + +#include +#include +#include +#include +#include +#include + + +struct stack_frame { + struct stack_frame *previous; + addr_t return_address; +}; + +#define NUM_PREVIOUS_LOCATIONS 32 + +extern struct iframe_stack gBootFrameStack; +/* + +static bool +already_visited(uint32 *visited, int32 *_last, int32 *_num, uint32 framePointer) +{ + int32 last = *_last; + int32 num = *_num; + int32 i; + + for (i = 0; i < num; i++) { + if (visited[(NUM_PREVIOUS_LOCATIONS + last - i) + % NUM_PREVIOUS_LOCATIONS] == framePointer) { + return true; + } + } + + *_last = last = (last + 1) % NUM_PREVIOUS_LOCATIONS; + visited[last] = framePointer; + + if (num < NUM_PREVIOUS_LOCATIONS) + *_num = num + 1; + + return false; +} + + +static inline stack_frame * +get_current_stack_frame() +{ + stack_frame *frame; + asm volatile("move.l %%fp,%0" : "=r"(frame)); + return frame; +} + + +static status_t +get_next_frame(addr_t framePointer, addr_t *next, addr_t *ip) +{ + struct thread *thread = thread_get_current_thread(); + addr_t oldFaultHandler = thread->fault_handler; + + // set fault handler, so that we can safely access user stacks + if (thread) { + if (m68k_set_fault_handler(&thread->fault_handler, (addr_t)&&error)) + goto error; + } + + *ip = ((struct stack_frame *)framePointer)->return_address; + *next = (addr_t)((struct stack_frame *)framePointer)->previous; + + if (thread) + thread->fault_handler = oldFaultHandler; + return B_OK; + +error: + thread->fault_handler = oldFaultHandler; + return B_BAD_ADDRESS; +} + + +static void +print_stack_frame(struct thread *thread, addr_t ip, addr_t framePointer, + addr_t nextFramePointer) +{ + addr_t diff = nextFramePointer - framePointer; + + // kernel space/user space switch + if (diff & 0x80000000) + diff = 0; + + // lookup symbol + const char *symbol, *image; + addr_t baseAddress; + bool exactMatch; + status_t status = elf_debug_lookup_symbol_address(ip, &baseAddress, &symbol, + &image, &exactMatch); + if (status != B_OK && !IS_KERNEL_ADDRESS(ip) && thread) { + // try to locate the image in the images loaded into user space + status = image_debug_lookup_user_symbol_address(thread->team, ip, + &baseAddress, &symbol, &image, &exactMatch); + } + if (status == B_OK) { + if (symbol != NULL) { + kprintf("%08lx (+%4ld) %08lx <%s>:%s + 0x%04lx%s\n", framePointer, + diff, ip, image, symbol, ip - baseAddress, + (exactMatch ? "" : " (nearest)")); + } else { + kprintf("%08lx (+%4ld) %08lx <%s@%p>:unknown + 0x%04lx\n", + framePointer, diff, ip, image, (void *)baseAddress, + ip - baseAddress); + } + } else + kprintf("%08lx (+%4ld) %08lx\n", framePointer, diff, ip); +} + + +static int +stack_trace(int argc, char **argv) +{ + uint32 previousLocations[NUM_PREVIOUS_LOCATIONS]; + struct iframe_stack *frameStack; + struct thread *thread; + addr_t framePointer; + int32 i, num = 0, last = 0; + + if (argc < 2) { + thread = thread_get_current_thread(); + framePointer = (addr_t)get_current_stack_frame(); + } else { +kprintf("Stack traces of other threads not supported yet!\n"); +return 0; + } + + // We don't have a thread pointer early in the boot process + if (thread != NULL) + frameStack = &thread->arch_info.iframes; + else + frameStack = &gBootFrameStack; + + for (i = 0; i < frameStack->index; i++) { + kprintf("iframe %p (end = %p)\n", + frameStack->frames[i], frameStack->frames[i] + 1); + } + + if (thread != NULL) { + kprintf("stack trace for thread 0x%lx \"%s\"\n", thread->id, + thread->name); + + kprintf(" kernel stack: %p to %p\n", + (void *)thread->kernel_stack_base, + (void *)(thread->kernel_stack_top)); + if (thread->user_stack_base != 0) { + kprintf(" user stack: %p to %p\n", + (void *)thread->user_stack_base, + (void *)(thread->user_stack_base + thread->user_stack_size)); + } + } + + kprintf("frame caller :function + offset\n"); + + for (;;) { + // see if the frame pointer matches the iframe + struct iframe *frame = NULL; + for (i = 0; i < frameStack->index; i++) { + if (framePointer == (addr_t)frameStack->frames[i]) { + // it's an iframe + frame = frameStack->frames[i]; + break; + } + } + + if (frame) { + kprintf("iframe at %p\n", frame); + kprintf(" d0 0x%08lx d1 0x%08lx d2 0x%08lx d3 0x%08lx\n", + frame->d[0], frame->d[1], frame->d[2], frame->d[3]); + kprintf(" d4 0x%08lx d5 0x%08lx d6 0x%08lx d7 0x%08lx\n", + frame->d[4], frame->d[5], frame->d[6], frame->d[7]); + kprintf(" a0 0x%08lx a1 0x%08lx a2 0x%08lx a3 0x%08lx\n", + frame->a[0], frame->a[1], frame->a[2], frame->a[3]); + kprintf(" a4 0x%08lx a5 0x%08lx a6 0x%08lx a7 0x%08lx (sp)\n", +#warning M68K: a7 in iframe ?? + frame->a[4], frame->a[5], frame->a[6], -1L); + kprintf(" pc 0x%08lx sr 0x%04x\n", + frame->cpu.pc, frame->cpu.sr); +#warning M68K: missing regs + + print_stack_frame(thread, frame->cpu.pc, framePointer, frame->a[6]); + framePointer = frame->a[6]; + } else { + addr_t ip, nextFramePointer; + + if (get_next_frame(framePointer, &nextFramePointer, &ip) != B_OK) { + kprintf("%08lx -- read fault\n", framePointer); + break; + } + + if (ip == 0 || framePointer == 0) + break; + + print_stack_frame(thread, ip, framePointer, nextFramePointer); + framePointer = nextFramePointer; + } + + if (already_visited(previousLocations, &last, &num, framePointer)) { + kprintf("circular stack frame: %p!\n", (void *)framePointer); + break; + } + if (framePointer == 0) + break; + } + + + return 0; +} + +*/ + +// #pragma mark - + + +void +arch_debug_save_registers(int *regs) +{ +} + + +bool +arch_debug_contains_call(struct thread *thread, const char *symbol, + addr_t start, addr_t end) +{ + return false; +} + + +void * +arch_debug_get_caller(void) +{ +#warning ARM:IMPLEMENT + // TODO: implement me + //return __builtin_frame_address(1); +// struct stack_frame *frame; + //frame = __builtin_frame_address(0); +// frame = get_current_stack_frame(); +// return (void *)frame->previous->return_address; + return NULL; +} + + +/*! Captures a stack trace (the return addresses) of the current thread. + \param returnAddresses The array the return address shall be written to. + \param maxCount The maximum number of return addresses to be captured. + \param skipIframes The number of interrupt frames that shall be skipped. If + greater than 0, \a skipFrames is ignored. + \param skipFrames The number of stack frames that shall be skipped. + \param userOnly If \c true, only userland return addresses are captured. + \return The number of return addresses written to the given array. +*/ +int32 +arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount, + int32 skipIframes, int32 skipFrames, bool userOnly) +{ +/* struct iframe_stack *frameStack; + addr_t framePointer; + int32 count = 0; + int32 i, num = 0, last = 0; + + // Keep skipping normal stack frames until we've skipped the iframes we're + // supposed to skip. + if (skipIframes > 0) { + skipFrames = INT_MAX; + } else { + // always skip our own frame + skipFrames++; + } + + struct thread* thread = thread_get_current_thread(); + framePointer = (addr_t)get_current_stack_frame(); + + // We don't have a thread pointer early in the boot process + if (thread != NULL) + frameStack = &thread->arch_info.iframes; + else + frameStack = &gBootFrameStack; + + while (framePointer != 0 && count < maxCount) { + // see if the frame pointer matches the iframe + struct iframe *frame = NULL; + for (i = 0; i < frameStack->index; i++) { + if (framePointer == (addr_t)frameStack->frames[i]) { + // it's an iframe + frame = frameStack->frames[i]; + break; + } + } + + addr_t ip; + addr_t nextFrame; + + if (frame) { + ip = frame->cpu.pc; + nextFrame = frame->a[6]; + + if (skipIframes > 0) { + if (--skipIframes == 0) + skipFrames = 0; + } + } else { + if (get_next_frame(framePointer, &nextFrame, &ip) != B_OK) + break; + } + + if (skipFrames <= 0 && (!userOnly || IS_USER_ADDRESS(framePointer))) + returnAddresses[count++] = ip; + else + skipFrames--; + + framePointer = nextFrame; + } + + return count;*/ +#warning ARM:IMPLEMENT + + return 0; +} + + +void* +arch_debug_get_interrupt_pc(bool* _isSyscall) +{ + // TODO: Implement! + return NULL; +} + + +bool +arch_is_debug_variable_defined(const char* variableName) +{ + // TODO: Implement! + return false; +} + + +status_t +arch_set_debug_variable(const char* variableName, uint64 value) +{ + // TODO: Implement! + return B_ENTRY_NOT_FOUND; +} + + +status_t +arch_get_debug_variable(const char* variableName, uint64* value) +{ + // TODO: Implement! + return B_ENTRY_NOT_FOUND; +} + + +status_t +arch_debug_init(kernel_args *args) +{ +// add_debugger_command("where", &stack_trace, "Same as \"sc\""); +// add_debugger_command("bt", &stack_trace, "Same as \"sc\" (as in gdb)"); +// add_debugger_command("sc", &stack_trace, "Stack crawl for current thread"); +#warning ARM:IMPLEMENT + + return B_NO_ERROR; +} + +void +arch_debug_call_with_fault_handler(cpu_ent* cpu, jmp_buf jumpBuffer, + void (*function)(void*), void* parameter) +{ + // TODO: Implement! Most likely in assembly. + longjmp(jumpBuffer, 1); +} + + +void +arch_debug_unset_current_thread(void) +{ + // TODO: Implement! +} + + diff --git a/src/system/kernel/arch/arm/arch_debug_console.cpp b/src/system/kernel/arch/arm/arch_debug_console.cpp new file mode 100644 index 0000000000..c11b8b9019 --- /dev/null +++ b/src/system/kernel/arch/arm/arch_debug_console.cpp @@ -0,0 +1,104 @@ +/* + * Copyright 2007, François Revol, revol@free.fr. + * Distributed under the terms of the MIT License. + * + * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + * + * Copyright 2001, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + + +//#include +#include +#include +#include +#include +#include +#include + + +void +arch_debug_remove_interrupt_handler(uint32 line) +{ +} + + +void +arch_debug_install_interrupt_handlers(void) +{ +} + + +char +arch_debug_blue_screen_getchar(void) +{ +#warning ARM WRITEME + return 0; +//M68KPlatform::Default()->BlueScreenGetChar(); +} + + +char +arch_debug_serial_getchar(void) +{ +#warning ARM WRITEME +return uart_getc(0,FALSE); +// return 0; +//M68KPlatform::Default()->SerialDebugGetChar(); +} + + +void +arch_debug_serial_putchar(const char c) +{ +//uart_putc(0,c); +//uart_putc(1,c); +uart_putc(0,c); +#warning ARM WRITEME + +// return 0; +//M68KPlatform::Default()->SerialDebugPutChar(c); +} + + +void +arch_debug_serial_puts(const char *s) +{ + while (*s != '\0') { + arch_debug_serial_putchar(*s); + s++; + } +} + + +void +arch_debug_serial_early_boot_message(const char *string) +{ + // this function will only be called in fatal situations +} + + +status_t +arch_debug_console_init(kernel_args *args) +{ + +uart_init_early(); +uart_init();//todo +uart_init_port(0,9600); +uart_init_port(1,9600); +uart_init_port(2,9600); +#warning ARM WRITEME + + return 0; +//M68KPlatform::Default()->InitSerialDebug(args); +} + + +status_t +arch_debug_console_init_settings(kernel_args *args) +{ + return B_OK; +} + diff --git a/src/system/kernel/arch/arm/arch_elf.cpp b/src/system/kernel/arch/arm/arch_elf.cpp new file mode 100644 index 0000000000..52e338e2cb --- /dev/null +++ b/src/system/kernel/arch/arm/arch_elf.cpp @@ -0,0 +1,363 @@ +/* + * Copyright 2009, Johannes Wischert, johanneswi@gmail.com. + * All rights reserved. Distributed under the terms of the MIT License. + * + * Copyright 2005, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + * + * Copyright 2002, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + +#ifdef _BOOT_MODE +#include +#endif + +#include + +#include +#include + + +#define TRACE_ARCH_ELF +#ifdef TRACE_ARCH_ELF +# define TRACE(x) dprintf x +# define CHATTY 1 +#else +# define TRACE(x) ; +# define CHATTY 0 +#endif + + +#ifdef TRACE_ARCH_ELF +static const char *kRelocations[] = { +"R_ARM_NONE", //0 Static Miscellaneous +"R_ARM_PC24", //1 Deprecated ARM ((S + A) | T) ? P +"R_ARM_ABS32", //2 Static Data (S + A) | T +"R_ARM_REL32", //3 Static Data ((S + A) | T) ? P +"R_ARM_LDR_PC_G0", //4 Static ARM S + A ? P +"R_ARM_ABS16", //5 Static Data S + A +"R_ARM_ABS12", //6 Static ARM S + A +"R_ARM_THM_ABS5", //7 Static Thumb16 S + A +"R_ARM_ABS8", //8 Static Data S + A +"R_ARM_SBREL32", //9 Static Data ((S + A) | T) ? B(S) +"R_ARM_THM_CALL", //10 Static Thumb32 ((S + A) | T) ? P +"R_ARM_THM_PC8", //11 Static Thumb16 S + A ? Pa +"R_ARM_BREL_ADJ", //12 Dynamic Data ?B(S) + A +"R_ARM_TLS_DESC", //13 Dynamic Data +"R_ARM_THM_SWI8", //14 Obsolete +"R_ARM_XPC25", //15 Obsolete +"R_ARM_THM_XPC22", //16 Obsolete Encodings reserved for future Dynamic relocations +"R_ARM_TLS_DTPMOD32", //17 Dynamic Data Module[S] +"R_ARM_TLS_DTPOFF32", //18 Dynamic Data S + A ? TLS +"R_ARM_TLS_TPOFF32", //19 Dynamic Data S + A ? tp +"R_ARM_COPY", //20 Dynamic Miscellaneous +"R_ARM_GLOB_DAT", //21 Dynamic Data (S + A) | T +"R_ARM_JUMP_SLOT", //22 Dynamic Data (S + A) | T +"R_ARM_RELATIVE", //23 Dynamic Data B(S) + A [Note: see Table 4-16] +"R_ARM_GOTOFF32", //24 Static Data ((S + A) | T) ? GOT_ORG +"R_ARM_BASE_PREL", //25 Static Data B(S) + A ? P +"R_ARM_GOT_BREL", //26 Static Data GOT(S) + A ? GOT_ORG +"R_ARM_PLT32", //27 Deprecated ARM ((S + A) | T) ? P +"R_ARM_CALL", //28 Static ARM ((S + A) | T) ? P +"R_ARM_JUMP24", //29 Static ARM ((S + A) | T) ? P +"R_ARM_THM_JUMP24", //30 Static Thumb32 ((S + A) | T) ? P +"R_ARM_BASE_ABS", //31 Static Data B(S) + A +"R_ARM_ALU_PCREL_7_0", //32 Obsolete +"R_ARM_ALU_PCREL_15_8", //33 Obsolete +"R_ARM_ALU_PCREL_23_15", //34 Obsolete Note ? Legacy (ARM ELF B02) names have been retained for these obsolete relocations. +"R_ARM_LDR_SBREL_11_0_NC", //35 Deprecated ARM S + A ? B(S) +"R_ARM_ALU_SBREL_19_12_NC", //36 Deprecated ARM S + A ? B(S) +"R_ARM_ALU_SBREL_27_20_CK", //37 Deprecated ARM S + A ? B(S) +"R_ARM_TARGET1", //38 Static Miscellaneous (S + A) | T or ((S + A) | T) ? P +"R_ARM_SBREL31", //39 Deprecated Data ((S + A) | T) ? B(S) +"R_ARM_V4BX", //40 Static Miscellaneous +"R_ARM_TARGET2", //41 Static Miscellaneous +"R_ARM_PREL31", //42 Static Data ((S + A) | T) ? P +"R_ARM_MOVW_ABS_NC", //43 Static ARM (S + A) | T +"R_ARM_MOVT_ABS", //44 Static ARM S + A +"R_ARM_MOVW_PREL_NC", //45 Static ARM ((S + A) | T) ? P +"R_ARM_MOVT_PREL", //46 Static ARM S + A ? P +"R_ARM_THM_MOVW_ABS_NC", //47 Static Thumb32 (S + A) | T +"R_ARM_THM_MOVT_ABS", //48 Static Thumb32 S + A +"R_ARM_THM_MOVW_PREL_NC", //49 Static Thumb32 ((S + A) | T) ? P +"R_ARM_THM_MOVT_PREL", //50 Static Thumb32 S + A ? P +"R_ARM_THM_JUMP19", //51 Static Thumb32 ((S + A) | T) ? P +"R_ARM_THM_JUMP6", //52 Static Thumb16 S + A ? P +"R_ARM_THM_ALU_PREL_11_0", //53 Static Thumb32 ((S + A) | T) ? Pa +"R_ARM_THM_PC12", //54 Static Thumb32 S + A ? Pa +"R_ARM_ABS32_NOI", //55 Static Data S + A +"R_ARM_REL32_NOI", //56 Static Data S + A ? P +"R_ARM_ALU_PC_G0_NC", //57 Static ARM ((S + A) | T) ? P +"R_ARM_ALU_PC_G0", //58 Static ARM ((S + A) | T) ? P +"R_ARM_ALU_PC_G1_NC", //59 Static ARM ((S + A) | T) ? P +"R_ARM_ALU_PC_G1", //60 Static ARM ((S + A) | T) ? P +"R_ARM_ALU_PC_G2", //61 Static ARM ((S + A) | T) ? P +"R_ARM_LDR_PC_G1", //62 Static ARM S + A ? P +"R_ARM_LDR_PC_G2", //63 Static ARM S + A ? P +"R_ARM_LDRS_PC_G0", //64 Static ARM S + A ? P +"R_ARM_LDRS_PC_G1", //65 Static ARM S + A ? P +"R_ARM_LDRS_PC_G2", //66 Static ARM S + A ? P +"R_ARM_LDC_PC_G0", //67 Static ARM S + A ? P +"R_ARM_LDC_PC_G1", //68 Static ARM S + A ? P +"R_ARM_LDC_PC_G2", //69 Static ARM S + A ? P +"R_ARM_ALU_SB_G0_NC", //70 Static ARM ((S + A) | T) ? B(S) +"R_ARM_ALU_SB_G0", //71 Static ARM ((S + A) | T) ? B(S) +"R_ARM_ALU_SB_G1_NC", //72 Static ARM ((S + A) | T) ? B(S) +"R_ARM_ALU_SB_G1", //73 Static ARM ((S + A) | T) ? B(S) +"R_ARM_ALU_SB_G2", //74 Static ARM ((S + A) | T) ? B(S) +"R_ARM_LDR_SB_G0", //75 Static ARM S + A ? B(S) +"R_ARM_LDR_SB_G1", //76 Static ARM S + A ? B(S) +"R_ARM_LDR_SB_G2", //77 Static ARM S + A ? B(S) +"R_ARM_LDRS_SB_G0", //78 Static ARM S + A ? B(S) +"R_ARM_LDRS_SB_G1", //79 Static ARM S + A ? B(S) +"R_ARM_LDRS_SB_G2", //80 Static ARM S + A ? B(S) +"R_ARM_LDC_SB_G0", //81 Static ARM S + A ? B(S) +"R_ARM_LDC_SB_G1", //82 Static ARM S + A ? B(S) +"R_ARM_LDC_SB_G2", //83 Static ARM S + A ? B(S) +"R_ARM_MOVW_BREL_NC", //84 Static ARM ((S + A) | T) ? B(S) +"R_ARM_MOVT_BREL", //85 Static ARM S + A ? B(S) +"R_ARM_MOVW_BREL", //86 Static ARM ((S + A) | T) ? B(S) +"R_ARM_THM_MOVW_BREL_NC", //87 Static Thumb32 ((S + A) | T) ? B(S) +"R_ARM_THM_MOVT_BREL", //88 Static Thumb32 S + A ? B(S) +"R_ARM_THM_MOVW_BREL", //89 Static Thumb32 ((S + A) | T) ? B(S) +"R_ARM_TLS_GOTDESC", //90 Static Data +"R_ARM_TLS_CALL", //91 Static ARM +"R_ARM_TLS_DESCSEQ", //92 Static ARM TLS relaxation +"R_ARM_THM_TLS_CALL", //93 Static Thumb32 +"R_ARM_PLT32_ABS", //94 Static Data PLT(S) + A +"R_ARM_GOT_ABS", //95 Static Data GOT(S) + A +"R_ARM_GOT_PREL", //96 Static Data GOT(S) + A ? P +"R_ARM_GOT_BREL12", //97 Static ARM GOT(S) + A ? GOT_ORG +"R_ARM_GOTOFF12", //98 Static ARM S + A ? GOT_ORG +"R_ARM_GOTRELAX", //99 Static Miscellaneous +"R_ARM_GNU_VTENTRY", //100 Deprecated Data ??? +"R_ARM_GNU_VTINHERIT", //101 Deprecated Data ??? +"R_ARM_THM_JUMP11", //102 Static Thumb16 S + A ? P +"R_ARM_THM_JUMP8", //103 Static Thumb16 S + A ? P +"R_ARM_TLS_GD32", //104 Static Data GOT(S) + A ? P +"R_ARM_TLS_LDM32", //105 Static Data GOT(S) + A ? P +"R_ARM_TLS_LDO32", //106 Static Data S + A ? TLS +"R_ARM_TLS_IE32", //107 Static Data GOT(S) + A ? P +"R_ARM_TLS_LE32", //108 Static Data S + A ? tp +"R_ARM_TLS_LDO12", //109 Static ARM S + A ? TLS +"R_ARM_TLS_LE12", //110 Static ARM S + A ? tp +"R_ARM_TLS_IE12GP", //111 Static ARM GOT(S) + A ? GOT_ORG +}; +#endif + +#ifdef _BOOT_MODE +status_t +boot_arch_elf_relocate_rel(struct preloaded_image *image, + struct Elf32_Rel *rel, int rel_len) +#else +int +arch_elf_relocate_rel(struct elf_image_info *image, + struct elf_image_info *resolve_image, struct Elf32_Rel *rel, int rel_len) +#endif +{ + // there are no rel entries in M68K elf + return B_NO_ERROR; +} + + +static inline void +write_32(addr_t P, Elf32_Word value) +{ + *(Elf32_Word*)P = value; +} + + +static inline void +write_16(addr_t P, Elf32_Word value) +{ + // bits 16:29 + *(Elf32_Half*)P = (Elf32_Half)value; +} + + +static inline bool +write_16_check(addr_t P, Elf32_Word value) +{ + // bits 15:0 + if ((value & 0xffff0000) && (~value & 0xffff8000)) + return false; + *(Elf32_Half*)P = (Elf32_Half)value; + return true; +} + + +static inline bool +write_8(addr_t P, Elf32_Word value) +{ + // bits 7:0 + *(uint8 *)P = (uint8)value; + return true; +} + + +static inline bool +write_8_check(addr_t P, Elf32_Word value) +{ + // bits 7:0 + if ((value & 0xffffff00) && (~value & 0xffffff80)) + return false; + *(uint8 *)P = (uint8)value; + return true; +} + + +#ifdef _BOOT_MODE +status_t +boot_arch_elf_relocate_rela(struct preloaded_image *image, + struct Elf32_Rela *rel, int rel_len) +#else +int +arch_elf_relocate_rela(struct elf_image_info *image, + struct elf_image_info *resolve_image, struct Elf32_Rela *rel, int rel_len) +#endif +{ + int i; + struct Elf32_Sym *sym; + int vlErr; + addr_t S = 0; // symbol address + addr_t R = 0; // section relative symbol address + + addr_t G = 0; // GOT address + addr_t L = 0; // PLT address + + #define P ((addr_t)(image->text_region.delta + rel[i].r_offset)) + #define A ((addr_t)rel[i].r_addend) + #define B (image->text_region.delta) +#warning ARM:define T correctly for thumb!!! + #define T 0 + + // TODO: Get the GOT address! + #define REQUIRE_GOT \ + if (G == 0) { \ + dprintf("arch_elf_relocate_rela(): Failed to get GOT address!\n"); \ + return B_ERROR; \ + } + + // TODO: Get the PLT address! + #define REQUIRE_PLT \ + if (L == 0) { \ + dprintf("arch_elf_relocate_rela(): Failed to get PLT address!\n"); \ + return B_ERROR; \ + } + + for (i = 0; i * (int)sizeof(struct Elf32_Rela) < rel_len; i++) { +#if CHATTY + dprintf("looking at rel type %d, offset 0x%lx, sym 0x%lx, addend 0x%lx\n", + ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, ELF32_R_SYM(rel[i].r_info), rel[i].r_addend); +#endif + switch (ELF32_R_TYPE(rel[i].r_info)) { +#warning ARM:ADDOTHERREL + case R_ARM_GLOB_DAT: + sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); + +#ifdef _BOOT_MODE + vlErr = boot_elf_resolve_symbol(image, sym, &S); +#else + vlErr = elf_resolve_symbol(image, sym, resolve_image, &S); +#endif + if (vlErr < 0) { + dprintf("%s(): Failed to relocate " + "entry index %d, rel type %d, offset 0x%lx, sym 0x%lx, " + "addend 0x%lx\n", __FUNCTION__, i, ELF32_R_TYPE(rel[i].r_info), + rel[i].r_offset, ELF32_R_SYM(rel[i].r_info), + rel[i].r_addend); + return vlErr; + } + break; + } + + +#warning ARM:ADDOTHERREL + + + switch (ELF32_R_TYPE(rel[i].r_info)) { +// case R_ARM_BREL_ADJ: +// ?B(S) + A +/* case R_ARM_TLS_DESC: + + case R_ARM_THM_XPC22 reserved for future Dynamic relocations: + + case R_ARM_TLS_DTPMOD32: +Module[S] + case R_ARM_TLS_DTPOFF32: +S + A ? TLS + case R_ARM_TLS_TPOFF32: +S + A ? tp +*/ + case R_ARM_GLOB_DAT: + write_32(P,(S + A) | T); + break; +/* case R_ARM_JUMP_SLOT: +(S + A) | T + case R_ARM_RELATIVE: +B(S) + A [Note: see Table 4-16] + +*/ + + + + + + + + case R_ARM_NONE: + break; + + case R_ARM_COPY: + // TODO: Implement! + dprintf("arch_elf_relocate_rela(): R_68K_COPY not yet " + "supported!\n"); + return B_ERROR; +/* + case R_68K_32: + case R_68K_GLOB_DAT: + write_32(P, S + A); + break; + + case R_68K_16: + if (write_16_check(P, S + A)) + break; +dprintf("R_68K_16 overflow\n"); + return B_BAD_DATA; + + case R_68K_8: + if (write_8_check(P, S + A)) + break; +dprintf("R_68K_8 overflow\n"); + return B_BAD_DATA; + + case R_68K_PC32: + write_32(P, (S + A - P)); + break; + + case R_68K_PC16: + if (write_16_check(P, (S + A - P))) + break; +dprintf("R_68K_PC16 overflow\n"); + return B_BAD_DATA; + + case R_68K_PC8: + if (write_8(P, (S + A - P))) + break; +dprintf("R_68K_PC8 overflow\n"); + return B_BAD_DATA; + + case R_68K_GOT32: + REQUIRE_GOT; + write_32(P, (G + A - P)); + break; +*/ + + + } +} +#warning ARM: FIXME!!!!!!! + return B_NO_ERROR; +} + diff --git a/src/system/kernel/arch/arm/arch_int.cpp b/src/system/kernel/arch/arm/arch_int.cpp new file mode 100644 index 0000000000..f649327e6a --- /dev/null +++ b/src/system/kernel/arch/arm/arch_int.cpp @@ -0,0 +1,158 @@ +/* + * Copyright 2003-2006, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler + * Ingo Weinhold + * François Revol + * Distributed under the terms of the MIT License. + * + * + * Copyright 2001, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + +#include + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#warning M68K: writeme! + + +//#define TRACE_ARCH_INT +#ifdef TRACE_ARCH_INT +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + +/*typedef void (*m68k_exception_handler)(void); +#define M68K_EXCEPTION_VECTOR_COUNT 256 +#warning M68K: align on 4 ? +//m68k_exception_handler gExceptionVectors[M68K_EXCEPTION_VECTOR_COUNT]; +m68k_exception_handler *gExceptionVectors; + +// defined in arch_exceptions.S +extern "C" void __m68k_exception_noop(void); +extern "C" void __m68k_exception_common(void); +*/ +extern int __irqvec_start; +extern int __irqvec_end; + +//extern"C" void m68k_exception_tail(void); + +// current fault handler +addr_t gFaultHandler; + +// An iframe stack used in the early boot process when we don't have +// threads yet. +struct iframe_stack gBootFrameStack; + +// interrupt controller interface (initialized +// in arch_int_init_post_device_manager()) +//static struct interrupt_controller_module_info *sPIC; +//static void *sPICCookie; + + +void +arch_int_enable_io_interrupt(int irq) +{ +#warning ARM WRITEME + //if (!sPIC) + // return; + + // TODO: I have no idea, what IRQ type is appropriate. + //sPIC->enable_io_interrupt(sPICCookie, irq, IRQ_TYPE_LEVEL); +// M68KPlatform::Default()->EnableIOInterrupt(irq); +} + + +void +arch_int_disable_io_interrupt(int irq) +{ +#warning ARM WRITEME + + //if (!sPIC) + // return; + + //sPIC->disable_io_interrupt(sPICCookie, irq); +// M68KPlatform::Default()->DisableIOInterrupt(irq); +} + + +/* arch_int_*_interrupts() and friends are in arch_asm.S */ + + +static void +print_iframe(struct iframe *frame) +{ +/* + dprintf("r0-r3: 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n", frame->r0, frame->r1, frame->r2, frame->r3); + dprintf("r4-r7: 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n", frame->r4, frame->r5, frame->r6, frame->r7); + dprintf("r8-r11: 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n", frame->r8, frame->r9, frame->r10, frame->r11); + dprintf("r12-r15: 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n", frame->r12, frame->r13, frame->a6, frame->a7); + dprintf(" pc 0x%08lx sr 0x%08lx\n", frame->pc, frame->sr); +*/ + +#warning ARM WRITEME +} + +status_t +arch_int_init(kernel_args *args) +{ + status_t err; + addr_t vbr; + int i; + +// gExceptionVectors = (m68k_exception_handler *)args->arch_args.vir_vbr; + + /* fill in the vector table */ +// for (i = 0; i < M68K_EXCEPTION_VECTOR_COUNT; i++) +// gExceptionVectors[i] = &__m68k_exception_common; + +// vbr = args->arch_args.phys_vbr; + /* point VBR to the new table */ +// asm volatile ("movec %0,%%vbr" : : "r"(vbr):); +#warning ARM WRITEME + + return B_OK; +} + + +status_t +arch_int_init_post_vm(kernel_args *args) +{ + status_t err; +// err = M68KPlatform::Default()->InitPIC(args); +#warning ARM WRITEME + + return err; +} + + + +status_t +arch_int_init_post_device_manager(struct kernel_args *args) +{ + // no PIC found + panic("arch_int_init_post_device_manager(): Found no supported PIC!"); + + return B_ENTRY_NOT_FOUND; +} + + diff --git a/src/system/kernel/arch/arm/arch_platform.cpp b/src/system/kernel/arch/arm/arch_platform.cpp new file mode 100644 index 0000000000..8e971dc4fe --- /dev/null +++ b/src/system/kernel/arch/arm/arch_platform.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 2007, François Revol, revol@free.fr. + * Distributed under the terms of the MIT License. + * + * Copyright 2006, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +//#include + +#include + +#include +#include +#include +//#include +#include +#include + +/* +static M68KPlatform *sM68KPlatform; + + +// constructor +M68KPlatform::M68KPlatform(platform_type platformType, + m68k_platform_type m68kPlatformType) + : fPlatformType(platformType), + fM68KPlatformType(m68kPlatformType) +{ +} + +// destructor +M68KPlatform::~M68KPlatform() +{ +} + +// Default +M68KPlatform * +M68KPlatform::Default() +{ + return sM68KPlatform; +} + + +// # pragma mark - +*/ + +status_t +arch_platform_init(struct kernel_args *kernelArgs) +{ +#warning ARM:WRITEME + + return B_OK; +} + + +status_t +arch_platform_init_post_vm(struct kernel_args *kernelArgs) +{ + return B_OK; +#warning ARM:WRITEME +//sM68KPlatform->InitPostVM(kernelArgs); +} + + +status_t +arch_platform_init_post_thread(struct kernel_args *kernelArgs) +{ + return B_OK; +} diff --git a/src/system/kernel/arch/arm/arch_real_time_clock.cpp b/src/system/kernel/arch/arm/arch_real_time_clock.cpp new file mode 100644 index 0000000000..c2cef4ac4a --- /dev/null +++ b/src/system/kernel/arch/arm/arch_real_time_clock.cpp @@ -0,0 +1,250 @@ +/* + * Copyright 2007, François Revol, revol@free.fr. + * Copyright 2006, Ingo Weinhold . All rights reserved. + * Copyright 2005-2007, Axel Dörfler, axeld@pinc-software.de + * Copyright 2003, Jeff Ward, jeff@r2d2.stcloudstate.edu. All rights reserved. + * + * Distributed under the terms of the MIT License. + */ + +#include + +//#include +#include +#include +#include +/* +typedef struct { + uint8 second; + uint8 minute; + uint8 hour; + uint8 day; + uint8 month; + uint8 year; + uint8 century; +} cmos_time; + + +static uint32 +bcd_to_int(uint8 bcd) +{ + uint32 numl; + uint32 numh; + + numl = bcd & 0x0f; + numh = (bcd & 0xf0) >> 4; + + return numh * 10 + numl; +} + + +static uint8 +int_to_bcd(uint32 number) +{ + uint8 low; + uint8 high; + + if (number > 99) + return 0; + + high = number / 10; + low = number % 10; + + return (high << 4) | low; +} + + +static int +same_time(const cmos_time *time1, const cmos_time *time2) +{ + return time1->second == time2->second + && time1->minute == time2->minute + && time1->hour == time2->hour + && time1->day == time2->day + && time1->month == time2->month + && time1->year == time2->year + && time1->century == time2->century; +} + + +static uint8 +cmos_read(uint8 addr) +{ + return M68KPlatform::Default()->ReadRTCReg(addr); +} + + +static void +cmos_write(uint8 addr, uint8 data) +{ + M68KPlatform::Default()->WriteRTCReg(addr, data); +} + + +static void +set_24_hour_mode(void) +{ + uint8 status_b; + + status_b = cmos_read(0x0b); + status_b |= 0x02; + cmos_write(0x0b, status_b); +} + + +static void +read_cmos_clock(cmos_time *cmos) +{ + set_24_hour_mode(); + + cmos->century = cmos_read(0x32); + cmos->year = cmos_read(0x09); + cmos->month = cmos_read(0x08); + cmos->day = cmos_read(0x07); + cmos->hour = cmos_read(0x04); + cmos->minute = cmos_read(0x02); + cmos->second = cmos_read(0x00); +} + + +static void +write_cmos_clock(cmos_time *cmos) +{ + set_24_hour_mode(); + + cmos_write(0x32, cmos->century); + cmos_write(0x09, cmos->year); + cmos_write(0x08, cmos->month); + cmos_write(0x07, cmos->day); + cmos_write(0x04, cmos->hour); + cmos_write(0x02, cmos->minute); + cmos_write(0x00, cmos->second); +} + + +static uint32 +cmos_to_secs(const cmos_time *cmos) +{ + struct tm t; + t.tm_year = bcd_to_int(cmos->century) * 100 + bcd_to_int(cmos->year) + - RTC_EPOCH_BASE_YEAR; + t.tm_mon = bcd_to_int(cmos->month) - 1; + t.tm_mday = bcd_to_int(cmos->day); + t.tm_hour = bcd_to_int(cmos->hour); + t.tm_min = bcd_to_int(cmos->minute); + t.tm_sec = bcd_to_int(cmos->second); + + return rtc_tm_to_secs(&t); +} + + +static void +secs_to_cmos(uint32 seconds, cmos_time *cmos) +{ + int wholeYear; + + struct tm t; + rtc_secs_to_tm(seconds, &t); + + wholeYear = t.tm_year + RTC_EPOCH_BASE_YEAR; + + cmos->century = int_to_bcd(wholeYear / 100); + cmos->year = int_to_bcd(wholeYear % 100); + cmos->month = int_to_bcd(t.tm_mon + 1); + cmos->day = int_to_bcd(t.tm_mday); + cmos->hour = int_to_bcd(t.tm_hour); + cmos->minute = int_to_bcd(t.tm_min); + cmos->second = int_to_bcd(t.tm_sec); +} + + +// #pragma mark - + + + +static spinlock sSetArchDataLock; +*/ +status_t +arch_rtc_init(kernel_args *args, struct real_time_data *data) +{ +/* + // init the platform RTC service + status_t error = M68KPlatform::Default()->InitRTC(args, data); + if (error != B_OK) + return error; + + // init the arch specific part of the real_time_data + data->arch_data.data[0].system_time_offset = 0; + // cvFactor = 2^32 * 1000000 / tbFreq + // => (tb * cvFactor) >> 32 = (tb * 2^32 * 1000000 / tbFreq) >> 32 + // = tb / tbFreq * 1000000 = time in us + data->arch_data.system_time_conversion_factor + = uint32((uint64(1) << 32) * 1000000 + / args->arch_args.time_base_frequency); + data->arch_data.version = 0; + + // init spinlock + sSetArchDataLock = 0; + + // init system_time() conversion factor + __m68k_setup_system_time(&data->arch_data.system_time_conversion_factor); +*/ +#warning ARM:WRITEME + return B_OK; +} + + +uint32 +arch_rtc_get_hw_time(void) +{ +#warning ARM:WRITEME + + return 0; +//M68KPlatform::Default()->GetHardwareRTC(); +} + + +void +arch_rtc_set_hw_time(uint32 seconds) +{ +#warning ARM:WRITEME + +// M68KPlatform::Default()->SetHardwareRTC(seconds); +} + + +void +arch_rtc_set_system_time_offset(struct real_time_data *data, bigtime_t offset) +{ +/* + cpu_status state = disable_interrupts(); + acquire_spinlock(&sSetArchDataLock); + + int32 version = data->arch_data.version + 1; + data->arch_data.data[version % 2].system_time_offset = offset; + data->arch_data.version = version; + + release_spinlock(&sSetArchDataLock); + restore_interrupts(state); +*/ +#warning ARM:WRITEME + +} + + +bigtime_t +arch_rtc_get_system_time_offset(struct real_time_data *data) +{ +#warning ARM:WRITEME +/* + int32 version; + bigtime_t offset; + do { + version = data->arch_data.version; + offset = data->arch_data.data[version % 2].system_time_offset; + } while (version != data->arch_data.version); + + return offset; +*/ +return 0; +} diff --git a/src/system/kernel/arch/arm/arch_smp.c b/src/system/kernel/arch/arm/arch_smp.c new file mode 100644 index 0000000000..3a14e963d1 --- /dev/null +++ b/src/system/kernel/arch/arm/arch_smp.c @@ -0,0 +1,46 @@ +/* + * Copyright 2007, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * François Revol + * + * Copyright 2004, Axel Dörfler, axeld@pinc-software.de + * Distributed under the terms of the OpenBeOS License. + */ + + +#include + +#include +#include +#include + + +status_t +arch_smp_init(kernel_args *args) +{ + return B_OK; +} + + +status_t +arch_smp_per_cpu_init(kernel_args *args, int32 cpu) +{ + return B_OK; +} + + +void +arch_smp_send_ici(int32 target_cpu) +{ + panic("called arch_smp_send_ici!\n"); +} + + +void +arch_smp_send_broadcast_ici() +{ + panic("called arch_smp_send_broadcast_ici\n"); +} + diff --git a/src/system/kernel/arch/arm/arch_system_info.cpp b/src/system/kernel/arch/arm/arch_system_info.cpp new file mode 100644 index 0000000000..e73d1c857c --- /dev/null +++ b/src/system/kernel/arch/arm/arch_system_info.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2007, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * François Revol + * + * Copyright 2006, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include + +#include +//#include +#include +#include + + +static uint64 sCPUClockFrequency; +static uint64 sBusClockFrequency; +static enum cpu_types sCPUType; +static uint16 sCPURevision; + +status_t +arch_get_system_info(system_info *info, size_t size) +{ + info->cpu_type = sCPUType; + info->cpu_revision = sCPURevision; + + info->cpu_clock_speed = sCPUClockFrequency; + info->bus_clock_speed = sBusClockFrequency; + +// info->platform_type = M68KPlatform::Default()->PlatformType(); + + return B_OK; +} + + +status_t +arch_system_info_init(struct kernel_args *args) +{ + + int i; + + sCPUClockFrequency = args->arch_args.cpu_frequency; + sBusClockFrequency = args->arch_args.bus_frequency; + + sCPURevision = args->arch_args.cpu_type; //XXX +#warning ARM:WRITEME +// sCPUType = B_CPU_M68K; + + return B_OK; +} diff --git a/src/system/kernel/arch/arm/arch_thread.c b/src/system/kernel/arch/arm/arch_thread.c new file mode 100644 index 0000000000..92d0b75469 --- /dev/null +++ b/src/system/kernel/arch/arm/arch_thread.c @@ -0,0 +1,209 @@ +/* + * Copyright 2003-2007, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler + * Ingo Weinhold + * François Revol + * + * Copyright 2001, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +//#include + +#include + +#warning M68K: writeme! +// Valid initial arch_thread state. We just memcpy() it when initializing +// a new thread structure. +static struct arch_thread sInitialState; + +struct thread *gCurrentThread; + + +status_t +arch_thread_init(struct kernel_args *args) +{ + // Initialize the static initial arch_thread state (sInitialState). + // Currently nothing to do, i.e. zero initialized is just fine. + + return B_OK; +} + + +status_t +arch_team_init_team_struct(struct team *team, bool kernel) +{ + // Nothing to do. The structure is empty. + return B_OK; +} + + +status_t +arch_thread_init_thread_struct(struct thread *thread) +{ + // set up an initial state (stack & fpu) + memcpy(&thread->arch_info, &sInitialState, sizeof(struct arch_thread)); + + return B_OK; +} + + +status_t +arch_thread_init_kthread_stack(struct thread *t, int (*start_func)(void), + void (*entry_func)(void), void (*exit_func)(void)) +{ +/* addr_t *kstack = (addr_t *)t->kernel_stack_base; + addr_t *kstackTop = (addr_t *)t->kernel_stack_base; + + // clear the kernel stack +#ifdef DEBUG_KERNEL_STACKS +# ifdef STACK_GROWS_DOWNWARDS + memset((void *)((addr_t)kstack + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE), 0, + KERNEL_STACK_SIZE); +# else + memset(kstack, 0, KERNEL_STACK_SIZE); +# endif +#else + memset(kstack, 0, KERNEL_STACK_SIZE); +#endif + + // space for frame pointer and return address, and stack frames must be + // 16 byte aligned + kstackTop -= 2; + kstackTop = (addr_t*)((addr_t)kstackTop & ~0xf); + + // LR, CR, r2, r13-r31, f13-f31, as pushed by m68k_context_switch() + kstackTop -= 22 + 2 * 19; + + // let LR point to m68k_kernel_thread_root() + kstackTop[0] = (addr_t)&m68k_kernel_thread_root; + + // the arguments of m68k_kernel_thread_root() are the functions to call, + // provided in registers r13-r15 + kstackTop[3] = (addr_t)entry_func; + kstackTop[4] = (addr_t)start_func; + kstackTop[5] = (addr_t)exit_func; + + // save this stack position + t->arch_info.sp = (void *)kstackTop; +*/ +#warning ARM:WRITEME + return B_OK; +} + + +status_t +arch_thread_init_tls(struct thread *thread) +{ + // TODO: Implement! + return B_OK; +} + + +void +arch_thread_switch_kstack_and_call(struct thread *t, addr_t newKstack, + void (*func)(void *), void *arg) +{ +#warning ARM:WRITEME +// m68k_switch_stack_and_call(newKstack, func, arg); +} + + +void +arch_thread_context_switch(struct thread *from, struct thread *to) +{ +/* addr_t newPageDirectory; + + newPageDirectory = (addr_t)m68k_next_page_directory(from, to); + + if ((newPageDirectory % B_PAGE_SIZE) != 0) + panic("arch_thread_context_switch: bad pgdir 0x%lx\n", newPageDirectory); +#warning M68K: export from arch_vm.c + m68k_set_pgdir(newPageDirectory); + m68k_context_switch(&from->arch_info.sp, to->arch_info.sp);*/ +#warning ARM:WRITEME + +} + + +void +arch_thread_dump_info(void *info) +{ + struct arch_thread *at = (struct arch_thread *)info; + + dprintf("\tsp: %p\n", at->sp); +} + + +status_t +arch_thread_enter_userspace(struct thread *thread, addr_t entry, void *arg1, void *arg2) +{ + panic("arch_thread_enter_uspace(): not yet implemented\n"); + return B_ERROR; +} + + +bool +arch_on_signal_stack(struct thread *thread) +{ + return false; +} + + +status_t +arch_setup_signal_frame(struct thread *thread, struct sigaction *sa, int sig, int sigMask) +{ + return B_ERROR; +} + + +int64 +arch_restore_signal_frame(void) +{ + return 0; +} + + +void +arch_check_syscall_restart(struct thread *thread) +{ +} + + +/** Saves everything needed to restore the frame in the child fork in the + * arch_fork_arg structure to be passed to arch_restore_fork_frame(). + * Also makes sure to return the right value. + */ + +void +arch_store_fork_frame(struct arch_fork_arg *arg) +{ +} + + +/** Restores the frame from a forked team as specified by the provided + * arch_fork_arg structure. + * Needs to be called from within the child team, ie. instead of + * arch_thread_enter_uspace() as thread "starter". + * This function does not return to the caller, but will enter userland + * in the child team at the same position where the parent team left of. + */ + +void +arch_restore_fork_frame(struct arch_fork_arg *arg) +{ +} + diff --git a/src/system/kernel/arch/arm/arch_timer.cpp b/src/system/kernel/arch/arm/arch_timer.cpp new file mode 100644 index 0000000000..5ef99fbff7 --- /dev/null +++ b/src/system/kernel/arch/arm/arch_timer.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2007, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * François Revol + * + * Copyright 2001, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + + +#include +#include +#include + +#include +#include +//#include + + +void +arch_timer_set_hardware_timer(bigtime_t timeout) +{ +#warning ARM:WRITEME + +// M68KPlatform::Default()->SetHardwareTimer(timeout); +} + + +void +arch_timer_clear_hardware_timer() +{ +#warning ARM:WRITEME +// M68KPlatform::Default()->ClearHardwareTimer(); +} + + +int +arch_init_timer(kernel_args *args) +{ +#warning ARM:WRITEME + + return 0; +//M68KPlatform::Default()->InitTimer(args); +} + diff --git a/src/system/kernel/arch/arm/arch_user_debugger.cpp b/src/system/kernel/arch/arm/arch_user_debugger.cpp new file mode 100644 index 0000000000..4fceffabdd --- /dev/null +++ b/src/system/kernel/arch/arm/arch_user_debugger.cpp @@ -0,0 +1,101 @@ +/* + * Copyright 2007, François Revol, revol@free.fr. + * Distributed under the terms of the MIT License. + * + * Copyright 2005, Axel Dörfler, axeld@pinc-softare.de + * Distributed under the terms of the MIT License. + */ + + +#include +#include +#include +#include + + +#warning ARM: WRITEME +void +arch_clear_team_debug_info(struct arch_team_debug_info *info) +{ +} + + +void +arch_destroy_team_debug_info(struct arch_team_debug_info *info) +{ + arch_clear_team_debug_info(info); +} + + +void +arch_clear_thread_debug_info(struct arch_thread_debug_info *info) +{ +} + + +void +arch_destroy_thread_debug_info(struct arch_thread_debug_info *info) +{ + arch_clear_thread_debug_info(info); +} + + +void +arch_update_thread_single_step() +{ +} + + +void +arch_set_debug_cpu_state(const debug_cpu_state *cpuState) +{ +} + + +void +arch_get_debug_cpu_state(debug_cpu_state *cpuState) +{ +} + + +status_t +arch_get_thread_debug_cpu_state(struct thread *thread, + debug_cpu_state *cpuState) +{ + return B_ERROR; +} + + + +status_t +arch_set_breakpoint(void *address) +{ + return B_ERROR; +} + + +status_t +arch_clear_breakpoint(void *address) +{ + return B_ERROR; +} + + +status_t +arch_set_watchpoint(void *address, uint32 type, int32 length) +{ + return B_ERROR; +} + + +status_t +arch_clear_watchpoint(void *address) +{ + return B_ERROR; +} + +bool +arch_has_breakpoints(struct arch_team_debug_info *info) +{ + return false; +} diff --git a/src/system/kernel/arch/arm/arch_vm.cpp b/src/system/kernel/arch/arm/arch_vm.cpp new file mode 100644 index 0000000000..a20531d929 --- /dev/null +++ b/src/system/kernel/arch/arm/arch_vm.cpp @@ -0,0 +1,103 @@ +/* + * Copyright 2007, François Revol, revol@free.fr. + * Distributed under the terms of the MIT License. + * + * Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + * + * Copyright 2001, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + +#include + +#include +#include + +#include +#include +#include +//#include + + +//#define TRACE_ARCH_VM +#ifdef TRACE_ARCH_VM +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + +#warning M68K: WRITEME + +status_t +arch_vm_init(kernel_args *args) +{ + return B_OK; +} + + +status_t +arch_vm_init2(kernel_args *args) +{ +// int bats[8]; +// int i; + + /**/ +#warning M68K: disable TT0 and TT1, set up pmmu + + return B_OK; +} + + +status_t +arch_vm_init_post_area(kernel_args *args) +{ + return B_OK; +} + + +status_t +arch_vm_init_end(kernel_args *args) +{ + +#warning M68K: unset TT0 now + return B_OK; +} + + +status_t +arch_vm_init_post_modules(kernel_args *args) +{ + return B_OK; +} + + +void +arch_vm_aspace_swap(struct vm_address_space *from, struct vm_address_space *to) +{ +#warning ARM:WRITEME +// m68k_set_pgdir(m68k_translation_map_get_pgdir(&to->translation_map)); +} + + +bool +arch_vm_supports_protection(uint32 protection) +{ + return true; +} + + +void +arch_vm_unset_memory_type(vm_area *area) +{ +} + + +status_t +arch_vm_set_memory_type(vm_area *area, addr_t physicalBase, uint32 type) +{ + if (type == 0) + return B_OK; + + return B_ERROR; +} diff --git a/src/system/kernel/arch/arm/arch_vm_translation_map.cpp b/src/system/kernel/arch/arm/arch_vm_translation_map.cpp new file mode 100644 index 0000000000..2c4f32664c --- /dev/null +++ b/src/system/kernel/arch/arm/arch_vm_translation_map.cpp @@ -0,0 +1,119 @@ +/* + * Copyright 1007, François Revol, revol@free.fr. + * Distributed under the terms of the MIT License. + * + * Copyright 2003-2007, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + * + * Copyright 2001, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include + +#include "generic_vm_physical_page_mapper.h" + + + +void * +m68k_translation_map_get_pgdir(vm_translation_map *map) +{ + return NULL; +#warning ARM:WRITEME +//get_vm_ops()->m68k_translation_map_get_pgdir(map); +} + +// #pragma mark - +// VM API + + +status_t +arch_vm_translation_map_init_map(vm_translation_map *map, bool kernel) +{ + return NULL; +#warning ARM:WRITEME + +//get_vm_ops()->arch_vm_translation_map_init_map(map, kernel); +} + + +status_t +arch_vm_translation_map_init_kernel_map_post_sem(vm_translation_map *map) +{ + return NULL; +#warning ARM:WRITEME + +//get_vm_ops()->arch_vm_translation_map_init_kernel_map_post_sem(map); +} + + +status_t +arch_vm_translation_map_init(kernel_args *args) +{ + return NULL; +#warning ARM:WRITEME + +//get_vm_ops()->arch_vm_translation_map_init(args); +} + + +status_t +arch_vm_translation_map_init_post_area(kernel_args *args) +{ + return NULL; +#warning ARM:WRITEME + +//get_vm_ops()->arch_vm_translation_map_init_post_area(args); +} + + +status_t +arch_vm_translation_map_init_post_sem(kernel_args *args) +{ + return NULL; +#warning ARM:WRITEME + +//get_vm_ops()->arch_vm_translation_map_init_post_sem(args); +} + + +/** Directly maps a page without having knowledge of any kernel structures. + * Used only during VM setup. + * It currently ignores the "attributes" parameter and sets all pages + * read/write. + */ + +status_t +arch_vm_translation_map_early_map(kernel_args *ka, addr_t virtualAddress, addr_t physicalAddress, + uint8 attributes, addr_t (*get_free_page)(kernel_args *)) +{ + return NULL; +#warning ARM:WRITEME + +//get_vm_ops()->arch_vm_translation_map_early_map(ka, virtualAddress, physicalAddress, +// attributes, get_free_page); +} + + +// XXX currently assumes this translation map is active + +status_t +arch_vm_translation_map_early_query(addr_t va, addr_t *out_physical) +{ + return NULL; +#warning ARM:WRITEME + +//get_vm_ops()->arch_vm_translation_map_early_query(va, out_physical); +} + + diff --git a/src/system/boot/arch/arm/uart.c b/src/system/kernel/arch/arm/uart.c similarity index 100% rename from src/system/boot/arch/arm/uart.c rename to src/system/kernel/arch/arm/uart.c diff --git a/src/tools/gensyscalls/arch/arm/arch_gensyscalls.h b/src/tools/gensyscalls/arch/arm/arch_gensyscalls.h new file mode 100644 index 0000000000..28f51bea95 --- /dev/null +++ b/src/tools/gensyscalls/arch/arm/arch_gensyscalls.h @@ -0,0 +1,51 @@ +// Included by gensyscalls. + +typedef int AlignmentType; +static const char* kAlignmentType = "int"; +static const int kAlignment = sizeof(AlignmentType); + +// ReturnTypeCreator +template +class ReturnTypeCreator { +public: + static void Create(Syscall* syscall, const char* name) + { + int size = sizeof(T); + int usedSize = align_to_type(size); + const char* alignmentType + = (size != usedSize && size < kAlignment ? kAlignmentType : 0); + + syscall->SetReturnType(name, size, usedSize, alignmentType); + } +}; + +template<> +class ReturnTypeCreator { +public: + static void Create(Syscall* syscall, const char* name) + { + syscall->SetReturnType(name, 0, 0, 0); + } +}; + +// ParameterCreator +template +class ParameterCreator { +public: + static void Create(Syscall* syscall, const char* typeName, + const char* parameterName) + { + // compute offset + int offset = 0; + if (Parameter* previous = syscall->LastParameter()) + offset = previous->Offset() + previous->UsedSize(); + + int size = sizeof(T); + int usedSize = align_to_type(size); + const char* alignmentType + = (size != usedSize && size < kAlignment ? kAlignmentType : 0); + + syscall->AddParameter(typeName, parameterName, size, usedSize, offset, + alignmentType); + } +};