[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:
parent
818ef0e501
commit
23eafdaf31
@ -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) ]
|
||||
|
42
src/system/kernel/arch/arm/Jamfile
Normal file
42
src/system/kernel/arch/arm/Jamfile
Normal 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 ;
|
||||
|
56
src/system/kernel/arch/arm/arch_asm.S
Normal file
56
src/system/kernel/arch/arm/arch_asm.S
Normal 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)
|
||||
|
||||
|
36
src/system/kernel/arch/arm/arch_commpage.cpp
Normal file
36
src/system/kernel/arch/arm/arch_commpage.cpp
Normal 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;
|
||||
}
|
||||
|
293
src/system/kernel/arch/arm/arch_cpu.cpp
Normal file
293
src/system/kernel/arch/arm/arch_cpu.cpp
Normal 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;
|
||||
}*/
|
394
src/system/kernel/arch/arm/arch_debug.cpp
Normal file
394
src/system/kernel/arch/arm/arch_debug.cpp
Normal 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!
|
||||
}
|
||||
|
||||
|
104
src/system/kernel/arch/arm/arch_debug_console.cpp
Normal file
104
src/system/kernel/arch/arm/arch_debug_console.cpp
Normal 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;
|
||||
}
|
||||
|
363
src/system/kernel/arch/arm/arch_elf.cpp
Normal file
363
src/system/kernel/arch/arm/arch_elf.cpp
Normal 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;
|
||||
}
|
||||
|
158
src/system/kernel/arch/arm/arch_int.cpp
Normal file
158
src/system/kernel/arch/arm/arch_int.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
70
src/system/kernel/arch/arm/arch_platform.cpp
Normal file
70
src/system/kernel/arch/arm/arch_platform.cpp
Normal 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;
|
||||
}
|
250
src/system/kernel/arch/arm/arch_real_time_clock.cpp
Normal file
250
src/system/kernel/arch/arm/arch_real_time_clock.cpp
Normal 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;
|
||||
}
|
46
src/system/kernel/arch/arm/arch_smp.c
Normal file
46
src/system/kernel/arch/arm/arch_smp.c
Normal 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");
|
||||
}
|
||||
|
54
src/system/kernel/arch/arm/arch_system_info.cpp
Normal file
54
src/system/kernel/arch/arm/arch_system_info.cpp
Normal 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;
|
||||
}
|
209
src/system/kernel/arch/arm/arch_thread.c
Normal file
209
src/system/kernel/arch/arm/arch_thread.c
Normal 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)
|
||||
{
|
||||
}
|
||||
|
47
src/system/kernel/arch/arm/arch_timer.cpp
Normal file
47
src/system/kernel/arch/arm/arch_timer.cpp
Normal 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);
|
||||
}
|
||||
|
101
src/system/kernel/arch/arm/arch_user_debugger.cpp
Normal file
101
src/system/kernel/arch/arm/arch_user_debugger.cpp
Normal 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;
|
||||
}
|
103
src/system/kernel/arch/arm/arch_vm.cpp
Normal file
103
src/system/kernel/arch/arm/arch_vm.cpp
Normal 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;
|
||||
}
|
119
src/system/kernel/arch/arm/arch_vm_translation_map.cpp
Normal file
119
src/system/kernel/arch/arm/arch_vm_translation_map.cpp
Normal 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);
|
||||
}
|
||||
|
||||
|
51
src/tools/gensyscalls/arch/arm/arch_gensyscalls.h
Normal file
51
src/tools/gensyscalls/arch/arm/arch_gensyscalls.h
Normal 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);
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user