From 60b11851d49669095452371787cdf21357d9733a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Fri, 25 Jul 2008 15:05:52 +0000 Subject: [PATCH] partial support for 68901 MFP chip as interrupt controller, untested. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26633 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../private/kernel/arch/m68k/arch_platform.h | 4 + .../private/kernel/platform/atari_m68k/MFP.h | 25 +++ src/system/boot/platform/atari_m68k/start.c | 16 +- src/system/kernel/arch/m68k/arch_int.cpp | 55 +++--- .../kernel/platform/atari_m68k/platform.cpp | 158 ++++++++++++++++++ 5 files changed, 229 insertions(+), 29 deletions(-) create mode 100644 headers/private/kernel/platform/atari_m68k/MFP.h diff --git a/headers/private/kernel/arch/m68k/arch_platform.h b/headers/private/kernel/arch/m68k/arch_platform.h index 4b2cc120f4..685e08c668 100644 --- a/headers/private/kernel/arch/m68k/arch_platform.h +++ b/headers/private/kernel/arch/m68k/arch_platform.h @@ -42,6 +42,10 @@ public: virtual char SerialDebugGetChar() = 0; virtual void SerialDebugPutChar(char c) = 0; + virtual void EnableIOInterrupt(int irq); + virtual void DisableIOInterrupt(int irq); + virtual void AcknowledgeIOInterrupt(int irq); + virtual void SetHardwareRTC(uint32 seconds) = 0; virtual uint32 GetHardwareRTC() = 0; diff --git a/headers/private/kernel/platform/atari_m68k/MFP.h b/headers/private/kernel/platform/atari_m68k/MFP.h new file mode 100644 index 0000000000..342a84016b --- /dev/null +++ b/headers/private/kernel/platform/atari_m68k/MFP.h @@ -0,0 +1,25 @@ +#ifndef _MFP_H +#define _MFP_H + +#define MFP_GPDR 0x01 +#define MFP_AER 0x03 +#define MFP_DDR 0x05 +#define MFP_IERA 0x07 +#define MFP_IERB 0x09 +#define MFP_IPRA 0x0b +#define MFP_IPRB 0x0d +#define MFP_ISRA 0x0f +#define MFP_ISRB 0x11 +#define MFP_IMRA 0x13 +#define MFP_IMRB 0x15 +#define MFP_VR 0x17 +#define MFP_TACR 0x19 +#define MFP_TBCR 0x1b +#define MFP_TCDCR 0x1d +#define MFP_TADR 0x1f +#define MFP_TBDR 0x21 +#define MFP_TCDR 0x23 +#define MFP_TDDR 0x25 +//XXX + +#endif /* _MFP_H */ diff --git a/src/system/boot/platform/atari_m68k/start.c b/src/system/boot/platform/atari_m68k/start.c index 32972edf98..cf6b345fb8 100644 --- a/src/system/boot/platform/atari_m68k/start.c +++ b/src/system/boot/platform/atari_m68k/start.c @@ -81,16 +81,28 @@ platform_start_kernel(void) dprintf("kernel entry at %lx\n", gKernelArgs.kernel_image.elf_header.e_entry); - asm("move.l %0, %%sp; " // move stack out of way + asm volatile ( + "move.l %0, %%sp; " // move stack out of way : : "m" (stackTop)); - asm("move.l #0x0,-(%%sp); " // we're the BSP cpu (0) + + asm volatile ( + "ori #0x0700,%%sr; "); // disable interrupts + + asm volatile ( + "move.l #0x0,-(%%sp); " // we're the BSP cpu (0) "move.l %0,-(%%sp); " // kernel args "move.l #0x0,-(%%sp);" // dummy retval for call to main "move.l %1,-(%%sp); " // this is the start address "rts; " // jump. : : "g" (args), "g" (gKernelArgs.kernel_image.elf_header.e_entry)); + // Huston, we have a problem! + + asm volatile ( + "andi #0xf8ff,%%sr; "); // reenable interrupts + panic("kernel returned!\n"); + } diff --git a/src/system/kernel/arch/m68k/arch_int.cpp b/src/system/kernel/arch/m68k/arch_int.cpp index 9dff90e1e9..10f6c01419 100644 --- a/src/system/kernel/arch/m68k/arch_int.cpp +++ b/src/system/kernel/arch/m68k/arch_int.cpp @@ -15,6 +15,7 @@ #include +#include #include #include #include @@ -64,28 +65,30 @@ 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; +//static struct interrupt_controller_module_info *sPIC; +//static void *sPICCookie; void arch_int_enable_io_interrupt(int irq) { - if (!sPIC) - return; + //if (!sPIC) + // return; // TODO: I have no idea, what IRQ type is appropriate. - sPIC->enable_io_interrupt(sPICCookie, irq, IRQ_TYPE_LEVEL); + //sPIC->enable_io_interrupt(sPICCookie, irq, IRQ_TYPE_LEVEL); + M68KPlatform::Default()->EnableIOInterrupt(irq); } void arch_int_disable_io_interrupt(int irq) { - if (!sPIC) - return; + //if (!sPIC) + // return; - sPIC->disable_io_interrupt(sPICCookie, irq); + //sPIC->disable_io_interrupt(sPICCookie, irq); + M68KPlatform::Default()->DisableIOInterrupt(irq); } @@ -243,28 +246,36 @@ m68k_exception_entry(struct iframe *iframe) case 30: // autovector interrupt case 31: // autovector interrupt { +#if 0 if (!sPIC) { panic("m68k_exception_entry(): external interrupt although we " "don't have a PIC driver!"); ret = B_HANDLED_INTERRUPT; break; } +#endif + M68KPlatform::Default()->AcknowledgeIOInterrupt(vector); dprintf("handling I/O interrupts...\n"); - int irq; + ret = int_io_interrupt_handler(vector, true); +#if 0 while ((irq = sPIC->acknowledge_io_interrupt(sPICCookie)) >= 0) { // TODO: correctly pass level-triggered vs. edge-triggered to the handler! ret = int_io_interrupt_handler(irq, true); } +#endif dprintf("handling I/O interrupts done\n"); break; } - case 0x1700: // thermal management exception - panic("thermal management exception: unimplemented\n"); - break; case 9: // trace default: + // vectors >= 64 are user defined vectors, used for IRQ + if (vector >= 64) { + M68KPlatform::Default()->AcknowledgeIOInterrupt(irq); + ret = int_io_interrupt_handler(vector, true); + break; + } dprintf("unhandled exception type 0x%x\n", vector); print_iframe(iframe); panic("unhandled exception type\n"); @@ -286,10 +297,6 @@ 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) { @@ -302,15 +309,7 @@ arch_int_init(kernel_args *args) /* fill in the vector table */ for (i = 0; i < M68K_EXCEPTION_VECTOR_COUNT; i++) gExceptionVectors[i] = &__m68k_exception_common; -#if 0 - /* 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; - } -#endif + vbr = args->arch_args.phys_vbr; /* point VBR to the new table */ asm volatile ("movec %0,%%vbr" : : "r"(vbr):); @@ -482,7 +481,9 @@ probe_pic_device(device_node_handle node, PICModuleList &picModules) status_t arch_int_init_post_device_manager(struct kernel_args *args) { -#warning M68K: init PIC from M68KPlatform:: + status_t err; + err = M68KPlatform::Default()->InitPIC(args); + return err; #if 0 /* PIC modules */ // get the interrupt controller driver modules PICModuleList picModules; @@ -541,7 +542,7 @@ arch_int_init_post_device_manager(struct kernel_args *args) } -#if 0 +#if 0//PPC // #pragma mark - struct m68k_cpu_exception_context * diff --git a/src/system/kernel/platform/atari_m68k/platform.cpp b/src/system/kernel/platform/atari_m68k/platform.cpp index 61c31aef44..a93ffd7c89 100644 --- a/src/system/kernel/platform/atari_m68k/platform.cpp +++ b/src/system/kernel/platform/atari_m68k/platform.cpp @@ -10,9 +10,23 @@ #include //#include +#include #include #include +#define MFP0_BASE 0xFFFFFA00 +#define MFP1_BASE 0xFFFFFA80 + +#define MFP0_VECTOR_BASE 64 +#define MFP1_VECTOR_BASE (MFP0_VECTOR_BASE+16) +// ? +#define SCC_C0_VECTOR_BASE (MFP1_VECTOR_BASE+16) +// ?? +#define SCC_C1_VECTOR_BASE (0x1BC/4) + +#define inb(a) (*(volatile uint8 *)(a)) +#define outb(a, v) (*(volatile uint8 *)(a) = v) + namespace BPrivate { @@ -20,7 +34,26 @@ namespace BPrivate { // #pragma mark - Atari (Falcon) + class M68KAtari : public M68KPlatform { + + class MFP { + public: + MFP(uint32 base, int vector); + ~MFP(); + + uint32 Base() const { return fBase; }; + int Vector() const { return fVector; }; + + void EnableIOInterrupt(int irq); + void DisableIOInterrupt(int irq); + void AcknowledgeIOInterrupt(int irq); + + private: + uint32 fBase; + int fVector; + }; + public: M68KAtari(); virtual ~M68KAtari(); @@ -36,6 +69,10 @@ public: virtual char SerialDebugGetChar(); virtual void SerialDebugPutChar(char c); + virtual void EnableIOInterrupt(int irq); + virtual void DisableIOInterrupt(int irq); + virtual void AcknowledgeIOInterrupt(int irq); + virtual void SetHardwareRTC(uint32 seconds); virtual uint32 GetHardwareRTC(); @@ -45,7 +82,11 @@ public: virtual void ShutDown(bool reboot); private: + MFP *MFPForIrq(int irq); int fRTC; + + MFP *fMFP[2]; + // native features (ARAnyM emulator) uint32 (*nfGetID)(const char *name); int32 (*nfCall)(uint32 ID, ...); @@ -60,6 +101,71 @@ private: using BPrivate::M68KAtari; +// #pragma mark - M68KAtari::MFP + + +static char sMFP0Buffer[sizeof(M68KAtari::MFP)]; +static char sMFP1Buffer[sizeof(M68KAtari::MFP)]; + +// constructor +MFP::MFP(uint32 base, int vector) +{ + fBase = base; + fVector = vector; +} + + +MFP::~MFP() +{ +} + +#warning M68K: use enable or mark register ? + +void +MFP::EnableIOInterrupt(int irq) +{ + uint8 bit = 1 << (irq % 8); + // I*B[0] is vector+0, I*A[0] is vector+8 + uint32 reg = Base() + ((irq > 8) ? (MFP_IERA) : (MFP_IERB)); + uint8 val = inb(reg); + if (val & bit == 0) { + val |= bit; + outb(reg, val); + } +} + + +void +MFP::DisableIOInterrupt(int irq) +{ + uint8 bit = 1 << (irq % 8); + // I*B[0] is vector+0, I*A[0] is vector+8 + uint32 reg = Base() + ((irq > 8) ? (MFP_IERA) : (MFP_IERB)); + uint8 val = inb(reg); + if (val & bit) { + val &= ~bit; + outb(reg, val); + } +} + + +void +MFP::AcknowledgeIOInterrupt(int irq) +{ + uint8 bit = 1 << (irq % 8); + // I*B[0] is vector+0, I*A[0] is vector+8 + uint32 reg = Base() + ((irq > 8) ? (MFP_ISRA) : (MFP_ISRB)); + uint8 val = inb(reg); + if (val & bit) { + val &= ~bit; + outb(reg, val); + } +} + + +// #pragma mark - M68KAtari + + // constructor M68KAtari::M68KAtari() : M68KPlatform(B_ATARI_PLATFORM, M68K_PLATFORM_ATARI), @@ -77,6 +183,9 @@ M68KAtari::~M68KAtari() status_t M68KAtari::Init(struct kernel_args *kernelArgs) { + fMFP[0] = NULL; + fMFP[1] = NULL; + nfGetID = kernelArgs->arch_args.plat_args.atari.nat_feat.nf_get_id; nfCall = @@ -119,6 +228,10 @@ status_t M68KAtari::InitPIC(struct kernel_args *kernelArgs) { panic("WRITEME"); + fMFP[0] = new(sMFP0Buffer) M68KAtari::MFP(MFP0_BASE, MFP0_VECTOR_BASE); + //if (kernelArgs->arch_args.machine == /*TT*/) { + fMFP[1] = new(sMFP1Buffer) M68KAtari::MFP(MFP1_BASE, MFP1_VECTOR_BASE); + //} return B_NO_INIT; } @@ -171,6 +284,35 @@ M68KAtari::SerialDebugPutChar(char c) } +void +M68KAtari::EnableIOInterrupt(int irq) +{ + MFP *mfp = MFPForIrq(irq); + + if (mfp) + mfp->EnableIOInterrupt(irq - mfp->Vector()); +} + + +void +M68KAtari::DisableIOInterrupt(int irq) +{ + MFP *mfp = MFPForIrq(irq); + + if (mfp) + mfp->DisableIOInterrupt(irq - mfp->Vector()); +} + + +void +M68KAtari::AcknowledgeIOInterrupt(int irq) +{ + MFP *mfp = MFPForIrq(irq); + + if (mfp) + mfp->AcknowledgeIOInterrupt(irq - mfp->Vector()); +} + void M68KAtari::SetHardwareRTC(uint32 seconds) { @@ -203,6 +345,22 @@ M68KAtari::ShutDown(bool reboot) panic("WRITEME"); } + +MFP * +M68KAtari::MFPForIrq(int irq) +{ + int i; + + for (i = 0; i < 2; i++) { + if (fMFP[i]) { + if (irq >= fMFP[i]->Vector() && irq < fMFP[i]->Vector() + 16) + return &fMFP[i]; + } + } + return NULL; +} + + // static buffer for constructing the actual M68KPlatform static char *sM68KPlatformBuffer[sizeof(M68KAtari)]; #warning PTR HERE ???