- move atari platform subclass to platform/atari_m68k/

- fix exception handling, at least it builds now.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26089 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol 2008-06-23 00:16:23 +00:00
parent c21157b9cb
commit 30629f410c
8 changed files with 286 additions and 308 deletions

View File

@ -13,7 +13,8 @@
#endif // !_ASSEMBLER
#define SR_IP_MASK 0x0700
#define SR_S 0x2000
#ifndef _ASSEMBLER
@ -193,6 +194,7 @@ struct mc680x0_frame {
};
struct mc680x0_type_0_frame type_0;
struct mc680x0_type_1_frame type_1;
struct mc680x0_type_3_frame type_3;
struct mc680x0_type_2_frame type_2;
struct mc68040_type_7_frame type_7;
struct mc680x0_type_9_frame type_9;

View File

@ -18,6 +18,8 @@ enum m68k_platform_type {
namespace BPrivate {
// implemented in src/system/kernel/arch/m68k/arch_platform.cpp
class M68KPlatform {
public:
M68KPlatform(m68k_platform_type platformType);
@ -30,6 +32,7 @@ public:
virtual status_t Init(struct kernel_args *kernelArgs) = 0;
virtual status_t InitSerialDebug(struct kernel_args *kernelArgs) = 0;
virtual status_t InitPostVM(struct kernel_args *kernelArgs) = 0;
virtual status_t InitPIC(struct kernel_args *kernelArgs) = 0;
virtual status_t InitRTC(struct kernel_args *kernelArgs,
struct real_time_data *data) = 0;
virtual status_t InitTimer(struct kernel_args *kernelArgs) = 0;
@ -49,6 +52,44 @@ private:
m68k_platform_type fPlatformType;
};
// #pragma mark - Amiga
// #pragma mark - Atari (Falcon)
// implemented in src/system/kernel/platform/atari_m68k/platform.cpp
class M68KAtari : public M68KPlatform {
public:
M68KAtari();
virtual ~M68KAtari();
virtual status_t Init(struct kernel_args *kernelArgs);
virtual status_t InitSerialDebug(struct kernel_args *kernelArgs);
virtual status_t InitPostVM(struct kernel_args *kernelArgs);
virtual status_t InitPIC(struct kernel_args *kernelArgs);
virtual status_t InitRTC(struct kernel_args *kernelArgs,
struct real_time_data *data);
virtual status_t InitTimer(struct kernel_args *kernelArgs);
virtual char SerialDebugGetChar();
virtual void SerialDebugPutChar(char c);
virtual void SetHardwareRTC(uint32 seconds);
virtual uint32 GetHardwareRTC();
virtual void SetHardwareTimer(bigtime_t timeout);
virtual void ClearHardwareTimer(void);
virtual void ShutDown(bool reboot);
private:
int fRTC;
};
// #pragma mark - Mac
} // namespace BPrivate
using BPrivate::M68KPlatform;

View File

@ -37,7 +37,7 @@ KernelMergeObject kernel_arch_m68k.o :
arch_smp.c
arch_system_info.c
arch_thread.c
arch_timer.c
arch_timer.cpp
arch_user_debugger.cpp
arch_vm.cpp
arch_vm_translation_map.cpp

View File

@ -42,6 +42,7 @@
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];
// defined in arch_exceptions.S
@ -53,6 +54,8 @@ 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.
@ -104,7 +107,7 @@ print_iframe(struct iframe *frame)
/*kprintf(" pc 0x%08lx ccr 0x%02x\n",
frame->pc, frame->ccr);*/
kprintf(" pc 0x%08lx sr 0x%04x\n",
frame->pc, frame->sr);
frame->cpu.pc, frame->cpu.sr);
#if 0
dprintf("r0-r3: 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n", frame->d0, frame->d1, frame->d2, frame->d3);
dprintf("r4-r7: 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n", frame->d4, frame->d5, frame->d6, frame->d7);
@ -114,6 +117,46 @@ print_iframe(struct iframe *frame)
#endif
}
static addr_t
fault_address(struct iframe *iframe)
{
switch (iframe->cpu.type) {
case 0x0:
case 0x1:
return 0;
case 0x2:
return iframe->cpu.type_2.instruction_address;
case 0x3:
return iframe->cpu.type_3.effective_address;
case 0x7:
return iframe->cpu.type_7.effective_address;
case 0x9:
return iframe->cpu.type_9.instruction_address;
case 0xa:
return iframe->cpu.type_a.fault_address;
case 0xb:
return iframe->cpu.type_b.fault_address;
default:
return 0;
}
}
static bool
fault_was_write(struct iframe *iframe)
{
switch (iframe->cpu.type) {
case 0x7:
return !iframe->cpu.type_7.ssw.rw;
case 0xa:
return !iframe->cpu.type_a.ssw.rw;
case 0xb:
return !iframe->cpu.type_b.ssw.rw;
default:
panic("can't determine r/w from iframe type %d\n",
iframe->cpu.type);
return false;
}
}
extern "C" void m68k_exception_entry(struct iframe *iframe);
void
@ -147,42 +190,43 @@ m68k_exception_entry(struct iframe *iframe)
if (kernelDebugger) {
// if this thread has a fault handler, we're allowed to be here
struct thread *thread = thread_get_current_thread();
if (thread && thread->fault_handler != NULL) {
iframe->srr0 = thread->fault_handler;
if (thread && thread->fault_handler != 0) {
iframe->cpu.pc = thread->fault_handler;
break;
}
// otherwise, not really
panic("page fault in debugger without fault handler! Touching "
"address %p from ip %p\n", (void *)iframe->dar,
(void *)iframe->srr0);
"address %p from ip %p\n", (void *)fault_address(iframe),
(void *)iframe->cpu.pc);
break;
} else if ((iframe->srr1 & MSR_EXCEPTIONS_ENABLED) == 0) {
} else if ((iframe->cpu.sr & SR_IP_MASK) != 0) {
// if the interrupts were disabled, and we are not running the
// kernel startup the page fault was not allowed to happen and
// we must panic
panic("page fault, but interrupts were disabled. Touching "
"address %p from ip %p\n", (void *)iframe->dar,
(void *)iframe->srr0);
"address %p from ip %p\n", (void *)fault_address(iframe),
(void *)iframe->cpu.pc);
break;
} else if (thread != NULL && thread->page_faults_allowed < 1) {
panic("page fault not allowed at this place. Touching address "
"%p from ip %p\n", (void *)iframe->dar,
(void *)iframe->srr0);
"%p from ip %p\n", (void *)fault_address(iframe),
(void *)iframe->cpu.pc);
}
enable_interrupts();
addr_t newip;
ret = vm_page_fault(iframe->dar, iframe->srr0,
iframe->dsisr & (1 << 25), // store or load
iframe->srr1 & (1 << 14), // was the system in user or supervisor
ret = vm_page_fault(fault_address(iframe), iframe->cpu.pc,
fault_was_write(iframe), // store or load
iframe->cpu.sr & SR_S, // was the system in user or supervisor
&newip);
if (newip != 0) {
// the page fault handler wants us to modify the iframe to set the
// IP the cpu will return to to be this ip
iframe->srr0 = newip;
iframe->cpu.pc = newip;
}
break;
}
@ -241,9 +285,29 @@ dprintf("handling I/O interrupts done\n");
}
#warning M68K: WTF do I need that here ?
extern status_t
arch_vm_translation_map_early_query(addr_t va, addr_t *out_physical);
status_t
arch_int_init(kernel_args *args)
{
status_t err;
addr_t vbr;
int i;
/* fill in the vector table */
for (i = 0; i < M68K_EXCEPTION_VECTOR_COUNT; i++)
gExceptionVectors[i] = &__m68k_exception_common;
/* get the physical address */
err = arch_vm_translation_map_early_query(
(addr_t)gExceptionVectors, &vbr);
if (err < B_OK) {
panic("can't query phys for vbr");
return err;
}
/* point VBR to the new table */
asm volatile ("movec %0,%%cacr" : : "r"(vbr):);
return B_OK;
}
@ -251,52 +315,11 @@ arch_int_init(kernel_args *args)
status_t
arch_int_init_post_vm(kernel_args *args)
{
void *handlers = (void *)args->arch_args.exception_handlers.start;
// We may need to remap the exception handler area into the kernel address
// space.
if (!IS_KERNEL_ADDRESS(handlers)) {
addr_t address = (addr_t)handlers;
status_t error = m68k_remap_address_range(&address,
args->arch_args.exception_handlers.size, true);
if (error != B_OK) {
panic("arch_int_init_post_vm(): Failed to remap the exception "
"handler area!");
return error;
}
handlers = (void*)(address);
}
// create a region to map the irq vector code into (physical address 0x0)
area_id exceptionArea = create_area("exception_handlers",
&handlers, B_EXACT_ADDRESS, args->arch_args.exception_handlers.size,
B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
if (exceptionArea < B_OK)
panic("arch_int_init2: could not create exception handler region\n");
dprintf("exception handlers at %p\n", handlers);
// copy the handlers into this area
memcpy(handlers, &__irqvec_start, args->arch_args.exception_handlers.size);
arch_cpu_sync_icache(handlers, args->arch_args.exception_handlers.size);
// init the CPU exception contexts
int cpuCount = smp_get_num_cpus();
for (int i = 0; i < cpuCount; i++) {
m68k_cpu_exception_context *context = m68k_get_cpu_exception_context(i);
context->kernel_handle_exception = (void*)&m68k_exception_tail;
context->exception_context = context;
// kernel_stack is set when the current thread changes. At this point
// we don't have threads yet.
}
// set the exception context for this CPU
m68k_set_current_cpu_exception_context(m68k_get_cpu_exception_context(0));
return B_OK;
}
#if 0 /* PIC modules */
template<typename ModuleInfo>
struct Module : DoublyLinkedListLinkImpl<Module<ModuleInfo> > {
Module(ModuleInfo *module)
@ -448,11 +471,13 @@ probe_pic_device(device_node_handle node, PICModuleList &picModules)
return false;
}
#endif /* PIC modules */
status_t
arch_int_init_post_device_manager(struct kernel_args *args)
{
#warning M68K: init PIC from M68KPlatform::
#if 0 /* PIC modules */
// get the interrupt controller driver modules
PICModuleList picModules;
get_interrupt_controller_modules(picModules);
@ -501,6 +526,8 @@ arch_int_init_post_device_manager(struct kernel_args *args)
}
}
#endif /* PIC modules */
// no PIC found
panic("arch_int_init_post_device_manager(): Found no supported PIC!");
@ -508,6 +535,7 @@ arch_int_init_post_device_manager(struct kernel_args *args)
}
#if 0
// #pragma mark -
struct m68k_cpu_exception_context *
@ -534,3 +562,4 @@ m68k_set_current_cpu_exception_context(struct m68k_cpu_exception_context *contex
asm volatile("mtsprg0 %0" : : "r"(physicalPage + inPageOffset));
}
#endif

View File

@ -17,6 +17,11 @@
#include <real_time_clock.h>
#include <util/kernel_cpp.h>
using BPrivate::M68KAtari;
//using BPrivate::M68KAmiga;
//using BPrivate::M68KMac;
//using BPrivate::M68KNext;
static M68KPlatform *sM68KPlatform;
@ -40,236 +45,6 @@ M68KPlatform::Default()
}
// #pragma mark - Amiga
// #pragma mark - Apple
namespace BPrivate {
class M68KApple : public M68KPlatform {
public:
M68KApple();
virtual ~M68KApple();
virtual status_t Init(struct kernel_args *kernelArgs);
virtual status_t InitSerialDebug(struct kernel_args *kernelArgs);
virtual status_t InitPostVM(struct kernel_args *kernelArgs);
virtual status_t InitRTC(struct kernel_args *kernelArgs,
struct real_time_data *data);
virtual char SerialDebugGetChar();
virtual void SerialDebugPutChar(char c);
//virtual void SetHardwareRTC(uint32 seconds);
//virtual uint32 GetHardwareRTC();
virtual void ShutDown(bool reboot);
private:
int fRTC;
};
} // namespace BPrivate
using BPrivate::M68KApple;
// constructor
M68KApple::M68KApple()
: M68KPlatform(M68K_PLATFORM_MAC),
fRTC(-1)
{
}
// destructor
M68KApple::~M68KApple()
{
}
// Init
status_t
M68KApple::Init(struct kernel_args *kernelArgs)
{
return of_init(
(int(*)(void*))kernelArgs->platform_args.openfirmware_entry);
}
// InitSerialDebug
status_t
M68KApple::InitSerialDebug(struct kernel_args *kernelArgs)
{
return B_OK;
}
// InitPostVM
status_t
M68KApple::InitPostVM(struct kernel_args *kernelArgs)
{
return B_OK;
}
// InitRTC
status_t
M68KApple::InitRTC(struct kernel_args *kernelArgs,
struct real_time_data *data)
{
return B_OK;
}
// DebugSerialGetChar
char
M68KApple::SerialDebugGetChar()
{
int key;
return (char)key;
}
// DebugSerialPutChar
void
M68KApple::SerialDebugPutChar(char c)
{
}
// ShutDown
void
M68KApple::ShutDown(bool reboot)
{
#if 0
if (reboot) {
of_interpret("reset-all", 0, 0);
} else {
// not standardized, so it might fail
of_interpret("shut-down", 0, 0);
}
#endif
}
// #pragma mark - Atari (Falcon)
namespace BPrivate {
class M68KAtari : public M68KPlatform {
public:
M68KAtari();
virtual ~M68KAtari();
virtual status_t Init(struct kernel_args *kernelArgs);
virtual status_t InitSerialDebug(struct kernel_args *kernelArgs);
virtual status_t InitPostVM(struct kernel_args *kernelArgs);
virtual status_t InitRTC(struct kernel_args *kernelArgs,
struct real_time_data *data);
virtual char SerialDebugGetChar();
virtual void SerialDebugPutChar(char c);
//virtual void SetHardwareRTC(uint32 seconds);
//virtual uint32 GetHardwareRTC();
virtual void ShutDown(bool reboot);
private:
int fRTC;
};
} // namespace BPrivate
using BPrivate::M68KAtari;
// constructor
M68KAtari::M68KAtari()
: M68KPlatform(M68K_PLATFORM_OPEN_FIRMWARE),
fRTC(-1)
{
}
// destructor
M68KAtari::~M68KAtari()
{
}
// Init
status_t
M68KAtari::Init(struct kernel_args *kernelArgs)
{
return of_init(
(int(*)(void*))kernelArgs->platform_args.openfirmware_entry);
}
// InitSerialDebug
status_t
M68KAtari::InitSerialDebug(struct kernel_args *kernelArgs)
{
if (of_getprop(gChosen, "stdin", &fInput, sizeof(int)) == OF_FAILED)
return B_ERROR;
if (of_getprop(gChosen, "stdout", &fOutput, sizeof(int)) == OF_FAILED)
return B_ERROR;
return B_OK;
}
// InitPostVM
status_t
M68KAtari::InitPostVM(struct kernel_args *kernelArgs)
{
add_debugger_command("of_exit", &debug_command_of_exit,
"Exit to the Open Firmware prompt. No way to get back into the OS!");
add_debugger_command("of_enter", &debug_command_of_enter,
"Enter a subordinate Open Firmware interpreter. Quitting it returns "
"to KDL.");
return B_OK;
}
// InitRTC
status_t
M68KAtari::InitRTC(struct kernel_args *kernelArgs,
struct real_time_data *data)
{
// open RTC
fRTC = of_open(kernelArgs->platform_args.rtc_path);
if (fRTC == OF_FAILED) {
dprintf("M68KAtari::InitRTC(): Failed open RTC device!\n");
return B_ERROR;
}
return B_OK;
}
// DebugSerialGetChar
char
M68KAtari::SerialDebugGetChar()
{
int key;
if (of_interpret("key", 0, 1, &key) == OF_FAILED)
return 0;
return (char)key;
}
// DebugSerialPutChar
void
M68KAtari::SerialDebugPutChar(char c)
{
if (c == '\n')
of_write(fOutput, "\r\n", 2);
else
of_write(fOutput, &c, 1);
}
// ShutDown
void
M68KAtari::ShutDown(bool reboot)
{
if (reboot) {
of_interpret("reset-all", 0, 0);
} else {
// not standardized, so it might fail
of_interpret("shut-down", 0, 0);
}
}
// # pragma mark -
@ -281,21 +56,25 @@ arch_platform_init(struct kernel_args *kernelArgs)
{
#warning M68K: switch platform from kernel args
// only Atari supported for now
switch (args->arch_args.platform) {
switch (kernelArgs->arch_args.platform) {
#if 0
case M68K_PLATFORM_AMIGA:
sM68KPlatform = new(sM68KPlatformBuffer) M68KAmiga;
break;
#endif
case M68K_PLATFORM_ATARI:
sM68KPlatform = new(sM68KPlatformBuffer) M68KAtari;
break;
#if 0
case M68K_PLATFORM_MAC:
sM68KPlatform = new(sM68KPlatformBuffer) M68KApple;
break;
case M68K_PLATFORM_NEXT:
sM68KPlatform = new(sM68KPlatformBuffer) M68KNext;
break;
#endif
default:
panic("unknown platform d\n", args->arch_args.platform);
panic("unknown platform d\n", kernelArgs->arch_args.platform);
}
return sM68KPlatform->Init(kernelArgs);

View File

@ -16,28 +16,26 @@
#include <timer.h>
#include <arch/timer.h>
#include <arch_platform.h>
void
arch_timer_set_hardware_timer(bigtime_t timeout)
{
if(timeout < 1000)
timeout = 1000;
platform_timer_set_hardware_timer(timeout);
M68KPlatform::Default()->SetHardwareTimer(timeout);
}
void
arch_timer_clear_hardware_timer()
{
platform_timer_set_hardware_timer(timeout);
M68KPlatform::Default()->ClearHardwareTimer();
}
int
arch_init_timer(kernel_args *ka)
arch_init_timer(kernel_args *args)
{
return platform_init_timer(ka);
return M68KPlatform::Default()->InitTimer(args);
}

View File

@ -35,21 +35,18 @@ extern struct m68k_vm_ops m68030_vm_ops;
static m68k_vm_ops *get_vm_ops()
{
int cpu = arch_cpu_type;
cpu &= MMU_MASK;
switch (cpu) {
case MMU_NONE:
panic("Ugh, no mmu !?");
return NULL;
case MMU_68551:
int mmu = arch_mmu_type;
switch (mmu) {
case 68551:
panic("Unimplemented yet (mmu)");
//return &m68851_vm_ops;
return NULL;
case MMU_68030:
case 68030:
return &m68030_vm_ops;
case MMU_68040:
case 68040:
//return &m68040_vm_ops;
case MMU_68060:
case 68060:
//return &m68060_vm_ops;
panic("Unimplemented yet (mmu)");
return NULL;

View File

@ -1,3 +1,135 @@
/*
Just a dummy. No BIOS services are required in the kernel.
*/
#include <arch_platform.h>
#include <new>
#include <KernelExport.h>
#include <boot/kernel_args.h>
//#include <platform/openfirmware/openfirmware.h>
#include <real_time_clock.h>
#include <util/kernel_cpp.h>
using BPrivate::M68KAtari;
// constructor
M68KAtari::M68KAtari()
: M68KPlatform(M68K_PLATFORM_ATARI),
fRTC(-1)
{
}
// destructor
M68KAtari::~M68KAtari()
{
}
status_t
M68KAtari::Init(struct kernel_args *kernelArgs)
{
return B_NO_INIT;
return B_OK;
}
status_t
M68KAtari::InitSerialDebug(struct kernel_args *kernelArgs)
{
return B_NO_INIT;
return B_OK;
}
status_t
M68KAtari::InitPostVM(struct kernel_args *kernelArgs)
{
#if 0
add_debugger_command("of_exit", &debug_command_of_exit,
"Exit to the Open Firmware prompt. No way to get back into the OS!");
add_debugger_command("of_enter", &debug_command_of_enter,
"Enter a subordinate Open Firmware interpreter. Quitting it returns "
"to KDL.");
#endif
return B_NO_INIT;
return B_OK;
}
status_t
M68KAtari::InitPIC(struct kernel_args *kernelArgs)
{
panic("WRITEME");
return B_NO_INIT;
}
status_t
M68KAtari::InitRTC(struct kernel_args *kernelArgs,
struct real_time_data *data)
{
panic("WRITEME");
return B_NO_INIT;
return B_OK;
}
status_t
M68KAtari::InitTimer(struct kernel_args *kernelArgs)
{
panic("WRITEME");
return B_NO_INIT;
}
char
M68KAtari::SerialDebugGetChar()
{
panic("WRITEME");
return 0;
// return (char)key;
}
void
M68KAtari::SerialDebugPutChar(char c)
{
panic("WRITEME");
}
void
M68KAtari::SetHardwareRTC(uint32 seconds)
{
}
uint32
M68KAtari::GetHardwareRTC()
{
return 0;
}
void
M68KAtari::SetHardwareTimer(bigtime_t timeout)
{
}
void
M68KAtari::ClearHardwareTimer(void)
{
}
void
M68KAtari::ShutDown(bool reboot)
{
panic("WRITEME");
}