diff --git a/headers/private/kernel/arch/m68k/arch_cpu.h b/headers/private/kernel/arch/m68k/arch_cpu.h index bdf71d5e37..4f921f6ced 100644 --- a/headers/private/kernel/arch/m68k/arch_cpu.h +++ b/headers/private/kernel/arch/m68k/arch_cpu.h @@ -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; diff --git a/headers/private/kernel/arch/m68k/arch_platform.h b/headers/private/kernel/arch/m68k/arch_platform.h index 05bb739e56..d55fce00e4 100644 --- a/headers/private/kernel/arch/m68k/arch_platform.h +++ b/headers/private/kernel/arch/m68k/arch_platform.h @@ -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; diff --git a/src/system/kernel/arch/m68k/Jamfile b/src/system/kernel/arch/m68k/Jamfile index abb7046275..83957805f6 100644 --- a/src/system/kernel/arch/m68k/Jamfile +++ b/src/system/kernel/arch/m68k/Jamfile @@ -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 diff --git a/src/system/kernel/arch/m68k/arch_int.cpp b/src/system/kernel/arch/m68k/arch_int.cpp index ca2db30eb4..2b725b427f 100644 --- a/src/system/kernel/arch/m68k/arch_int.cpp +++ b/src/system/kernel/arch/m68k/arch_int.cpp @@ -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 struct Module : DoublyLinkedListLinkImpl > { 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 diff --git a/src/system/kernel/arch/m68k/arch_platform.cpp b/src/system/kernel/arch/m68k/arch_platform.cpp index 4c39028f8e..34c625f5fe 100644 --- a/src/system/kernel/arch/m68k/arch_platform.cpp +++ b/src/system/kernel/arch/m68k/arch_platform.cpp @@ -17,6 +17,11 @@ #include #include +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); diff --git a/src/system/kernel/arch/m68k/arch_timer.cpp b/src/system/kernel/arch/m68k/arch_timer.cpp index 72ab1204c8..e450727883 100644 --- a/src/system/kernel/arch/m68k/arch_timer.cpp +++ b/src/system/kernel/arch/m68k/arch_timer.cpp @@ -16,28 +16,26 @@ #include #include +#include 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); } diff --git a/src/system/kernel/arch/m68k/arch_vm_translation_map.cpp b/src/system/kernel/arch/m68k/arch_vm_translation_map.cpp index 2eab1dca47..24badfee0e 100644 --- a/src/system/kernel/arch/m68k/arch_vm_translation_map.cpp +++ b/src/system/kernel/arch/m68k/arch_vm_translation_map.cpp @@ -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; diff --git a/src/system/kernel/platform/atari_m68k/platform.cpp b/src/system/kernel/platform/atari_m68k/platform.cpp index c30c0cc959..1703ee7d55 100644 --- a/src/system/kernel/platform/atari_m68k/platform.cpp +++ b/src/system/kernel/platform/atari_m68k/platform.cpp @@ -1,3 +1,135 @@ /* Just a dummy. No BIOS services are required in the kernel. */ + +#include + +#include + +#include + +#include +//#include +#include +#include + +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"); +}