[GSoC] [ARM] Patch by Johannes Wischert.

- stubbed out many arch kernel functions (borrowed from other archs),
- partially implement ELF relocations code, enough to load the kernel,
- move uart.c to kernel sources and use the same one for the loader,
- default implementation for gensyscalls,
- assembler code functions for interrupt masking (enable/disable/restore/query).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32327 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol 2009-08-13 18:34:15 +00:00
parent 818ef0e501
commit 23eafdaf31
20 changed files with 2497 additions and 1 deletions

View File

@ -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) ]

View File

@ -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 ;

View File

@ -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 <arch/arm/arch_cpu.h>
#include <asm_defs.h>
.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)

View File

@ -0,0 +1,36 @@
/*
* Copyright 2009, Johannes Wischert, johanneswi@gmail.com.
* Distributed under the terms of the MIT License.
*/
#include <commpage.h>
#include <string.h>
#include <KernelExport.h>
#include <cpu.h>
#include <elf.h>
#include <smp.h>
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;
}

View File

@ -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 <KernelExport.h>
//#include <arch_platform.h>
#include <arch_thread.h>
#include <arch/cpu.h>
#include <boot/kernel_args.h>
#include <commpage.h>
#include <elf.h>
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;
}*/

View File

@ -0,0 +1,394 @@
/*
* Copyright 2003-2008, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler <axeld@pinc-software.de>
* Ingo Weinhold <bonefish@cs.tu-berlin.de>
* François Revol <revol@free.fr>
*/
#include <arch/debug.h>
#include <arch_cpu.h>
#include <debug.h>
#include <elf.h>
#include <kernel.h>
#include <kimage.h>
#include <thread.h>
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 <image>: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!
}

View File

@ -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 <arch_platform.h>
#include <arch/debug_console.h>
#include <boot/kernel_args.h>
#include <kernel.h>
#include <vm.h>
#include <arch/arm/uart.h>
#include <string.h>
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;
}

View File

@ -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 <bonefish@cs.tu-berlin.de>.
* 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 <boot/arch.h>
#endif
#include <KernelExport.h>
#include <elf_priv.h>
#include <arch/elf.h>
#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;
}

View File

@ -0,0 +1,158 @@
/*
* Copyright 2003-2006, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler <axeld@pinc-software.de>
* Ingo Weinhold <bonefish@cs.tu-berlin.de>
* François Revol <revol@free.fr>
* Distributed under the terms of the MIT License.
*
*
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
* Distributed under the terms of the NewOS License.
*/
#include <int.h>
//#include <arch_platform.h>
#include <arch/smp.h>
#include <boot/kernel_args.h>
#include <device_manager.h>
#include <kscheduler.h>
#include <interrupt_controller.h>
#include <smp.h>
#include <thread.h>
#include <timer.h>
#include <util/DoublyLinkedList.h>
#include <util/kernel_cpp.h>
#include <vm.h>
#include <vm_address_space.h>
#include <vm_priv.h>
#include <string.h>
#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;
}

View File

@ -0,0 +1,70 @@
/*
* Copyright 2007, François Revol, revol@free.fr.
* Distributed under the terms of the MIT License.
*
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
//#include <arch_platform.h>
#include <new>
#include <KernelExport.h>
#include <arch/platform.h>
#include <boot/kernel_args.h>
//#include <platform/openfirmware/openfirmware.h>
#include <real_time_clock.h>
#include <util/kernel_cpp.h>
/*
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;
}

View File

@ -0,0 +1,250 @@
/*
* Copyright 2007, François Revol, revol@free.fr.
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>. 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 <arch/real_time_clock.h>
//#include <arch_platform.h>
#include <real_time_clock.h>
#include <real_time_data.h>
#include <smp.h>
/*
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;
}

View File

@ -0,0 +1,46 @@
/*
* Copyright 2007, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* François Revol <revol@free.fr>
*
* Copyright 2004, Axel Dörfler, axeld@pinc-software.de
* Distributed under the terms of the OpenBeOS License.
*/
#include <KernelExport.h>
#include <boot/stage2.h>
#include <arch/smp.h>
#include <debug.h>
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");
}

View File

@ -0,0 +1,54 @@
/*
* Copyright 2007, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* François Revol <revol@free.fr>
*
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include <OS.h>
#include <arch_cpu.h>
//#include <arch_platform.h>
#include <arch/system_info.h>
#include <boot/kernel_args.h>
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;
}

View File

@ -0,0 +1,209 @@
/*
* Copyright 2003-2007, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler <axeld@pinc-software.de>
* Ingo Weinhold <bonefish@cs.tu-berlin.de>
* François Revol <revol@free.fr>
*
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
* Distributed under the terms of the NewOS License.
*/
#include <arch_thread.h>
#include <arch_cpu.h>
#include <arch/thread.h>
#include <boot/stage2.h>
#include <kernel.h>
#include <thread.h>
#include <vm_address_space.h>
#include <vm_types.h>
#include <arch_vm.h>
//#include <arch/vm_translation_map.h>
#include <string.h>
#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)
{
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2007, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* François Revol <revol@free.fr>
*
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
* Distributed under the terms of the NewOS License.
*/
#include <boot/stage2.h>
#include <kernel.h>
#include <debug.h>
#include <timer.h>
#include <arch/timer.h>
//#include <arch_platform.h>
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);
}

View File

@ -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 <debugger.h>
#include <int.h>
#include <thread.h>
#include <arch/user_debugger.h>
#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;
}

View File

@ -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 <KernelExport.h>
#include <kernel.h>
#include <boot/kernel_args.h>
#include <vm.h>
#include <vm_types.h>
#include <arch/vm.h>
//#include <arch_mmu.h>
//#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;
}

View File

@ -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 <KernelExport.h>
#include <kernel.h>
#include <vm.h>
#include <vm_address_space.h>
#include <vm_priv.h>
#include <int.h>
#include <boot/kernel_args.h>
#include <arch/vm_translation_map.h>
#include <arch/cpu.h>
//#include <arch_mmu.h>
#include <stdlib.h>
#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);
}

View File

@ -0,0 +1,51 @@
// Included by gensyscalls.
typedef int AlignmentType;
static const char* kAlignmentType = "int";
static const int kAlignment = sizeof(AlignmentType);
// ReturnTypeCreator
template<typename T>
class ReturnTypeCreator {
public:
static void Create(Syscall* syscall, const char* name)
{
int size = sizeof(T);
int usedSize = align_to_type<AlignmentType>(size);
const char* alignmentType
= (size != usedSize && size < kAlignment ? kAlignmentType : 0);
syscall->SetReturnType(name, size, usedSize, alignmentType);
}
};
template<>
class ReturnTypeCreator<void> {
public:
static void Create(Syscall* syscall, const char* name)
{
syscall->SetReturnType(name, 0, 0, 0);
}
};
// ParameterCreator
template<typename T>
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<AlignmentType>(size);
const char* alignmentType
= (size != usedSize && size < kAlignment ? kAlignmentType : 0);
syscall->AddParameter(typeName, parameterName, size, usedSize, offset,
alignmentType);
}
};