From 36ee9f5c625f4d16cd61636148f3e8591b5f66a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Fri, 25 Jul 2008 00:25:27 +0000 Subject: [PATCH] - use a physical page for natfeat debug output for now - add 040 cpu and mmu stuff - use leftover from the page root table to put interrupt vector table to set VBR to git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26627 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/arch/m68k/arch_kernel_args.h | 3 + src/system/boot/platform/atari_m68k/mmu.cpp | 12 +++ .../boot/platform/atari_m68k/mmu_040.cpp | 2 +- src/system/kernel/arch/m68k/Jamfile | 6 +- src/system/kernel/arch/m68k/arch_030_asm.S | 2 +- src/system/kernel/arch/m68k/arch_040_asm.S | 30 +++++++ src/system/kernel/arch/m68k/arch_040_cpu.cpp | 90 +++++++++++++++++++ src/system/kernel/arch/m68k/arch_040_mmu.cpp | 46 ++++++++++ src/system/kernel/arch/m68k/arch_cpu.cpp | 10 ++- src/system/kernel/arch/m68k/arch_int.cpp | 10 ++- .../arch/m68k/arch_vm_translation_map.cpp | 4 +- .../m68k/arch_vm_translation_map_impl.cpp | 12 ++- .../kernel/platform/atari_m68k/platform.cpp | 37 +++++++- 13 files changed, 248 insertions(+), 16 deletions(-) create mode 100644 src/system/kernel/arch/m68k/arch_040_asm.S create mode 100644 src/system/kernel/arch/m68k/arch_040_cpu.cpp create mode 100644 src/system/kernel/arch/m68k/arch_040_mmu.cpp diff --git a/headers/private/kernel/arch/m68k/arch_kernel_args.h b/headers/private/kernel/arch/m68k/arch_kernel_args.h index 15d42349c8..8f532881c6 100644 --- a/headers/private/kernel/arch/m68k/arch_kernel_args.h +++ b/headers/private/kernel/arch/m68k/arch_kernel_args.h @@ -29,6 +29,9 @@ typedef struct { // page root table uint32 phys_pgroot; uint32 vir_pgroot; + // interrupt vector table (VBR) + uint32 phys_vbr; + uint32 vir_vbr; //XXX: addr_range page_table; // virtual address and size of the page table addr_range exception_handlers; diff --git a/src/system/boot/platform/atari_m68k/mmu.cpp b/src/system/boot/platform/atari_m68k/mmu.cpp index b1849ecc1f..728ec17d92 100644 --- a/src/system/boot/platform/atari_m68k/mmu.cpp +++ b/src/system/boot/platform/atari_m68k/mmu.cpp @@ -49,6 +49,8 @@ * 0x0800 - 0x10000 supervisor mode stack (1) XXX: more ? x86 starts at 500 * 0x10000 - ? code (up to ~500 kB) * 0x100000 or FAST_RAM_BASE if any: + * ... page root directory + * ... interrupt vectors (VBR) * ... page directory * ... boot loader heap (32 kB) * ... free physical memory @@ -75,6 +77,11 @@ # define TRACE(x) ; #endif + +// since the page root directory doesn't take a full page (1k) +// we stuff some other stuff after it, like the interrupt vectors (1k) +#define VBR_PAGE_OFFSET 1024 + static const uint32 kDefaultPageTableFlags = 0x07; // present, user, R/W static const size_t kMaxKernelSize = 0x100000; // 1 MB for the kernel @@ -259,6 +266,7 @@ init_page_directory(void) // allocate a new pg root dir gPageRoot = get_next_physical_page(); gKernelArgs.arch_args.phys_pgroot = (uint32)gPageRoot; + gKernelArgs.arch_args.phys_vbr = (uint32)gPageRoot + VBR_PAGE_OFFSET; // set the root pointers gMMUOps->load_rp(gPageRoot); @@ -598,6 +606,10 @@ mmu_init(void) gKernelArgs.arch_args.vir_pgroot = get_next_virtual_page(); map_page(gKernelArgs.arch_args.vir_pgroot, (uint32)gPageRoot, kDefaultPageFlags); + // set virtual addr for interrupt vector table + gKernelArgs.arch_args.vir_vbr = gKernelArgs.arch_args.vir_pgroot + + VBR_PAGE_OFFSET; + // map in a kernel stack gKernelArgs.cpu_kstack[0].start = (addr_t)mmu_allocate(NULL, KERNEL_STACK_SIZE); gKernelArgs.cpu_kstack[0].size = KERNEL_STACK_SIZE; diff --git a/src/system/boot/platform/atari_m68k/mmu_040.cpp b/src/system/boot/platform/atari_m68k/mmu_040.cpp index 5f68477e17..c939fa9120 100644 --- a/src/system/boot/platform/atari_m68k/mmu_040.cpp +++ b/src/system/boot/platform/atari_m68k/mmu_040.cpp @@ -148,7 +148,7 @@ add_page_table(addr_t virtualAddress) page_root_entry *apr = &pr[aindex + i]; apr->addr = TA_TO_PREA(tbl); apr->type = DT_ROOT; - //TRACE(("inserting tbl @ %p as %08x entry %08x\n", tbl, TA_TO_PREA(tbl), *(uint32 *)apr)); + //TRACE(("inserting tbl @ %p as %08x pr[%d] %08x\n", tbl, TA_TO_PREA(tbl), aindex + i, *(uint32 *)apr)); // clear the table //TRACE(("clearing table[%d]\n", i)); pd = (page_directory_entry *)tbl; diff --git a/src/system/kernel/arch/m68k/Jamfile b/src/system/kernel/arch/m68k/Jamfile index b609d65639..96de4816d1 100644 --- a/src/system/kernel/arch/m68k/Jamfile +++ b/src/system/kernel/arch/m68k/Jamfile @@ -14,7 +14,9 @@ KernelMergeObject arch_m68k_030.o : ; KernelMergeObject arch_m68k_040.o : - arch_040.cpp + arch_040_cpu.cpp + arch_040_mmu.cpp + arch_040_asm.S : $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused -m68040 ; @@ -50,7 +52,7 @@ KernelMergeObject kernel_arch_m68k.o : $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused : arch_m68k_030.o -# arch_m68k_040.a + arch_m68k_040.o # arch_m68k_060.a ; diff --git a/src/system/kernel/arch/m68k/arch_030_asm.S b/src/system/kernel/arch/m68k/arch_030_asm.S index 3ac764ec58..ceeb0e3696 100644 --- a/src/system/kernel/arch/m68k/arch_030_asm.S +++ b/src/system/kernel/arch/m68k/arch_030_asm.S @@ -14,7 +14,7 @@ FUNCTION(flush_atc_all_030): pflusha rts - /* flush all ATC entries */ + /* flush ATC entries for given address */ FUNCTION(flush_atc_addr_030): move.l (4,%a7),%a0 pflush #0,#0,(%a0) diff --git a/src/system/kernel/arch/m68k/arch_040_asm.S b/src/system/kernel/arch/m68k/arch_040_asm.S new file mode 100644 index 0000000000..c2f5cd1c24 --- /dev/null +++ b/src/system/kernel/arch/m68k/arch_040_asm.S @@ -0,0 +1,30 @@ + +#define FUNCTION(x) .global x; .type x,@function; x + +.text + /* gas doesn't seem to get the -m arg... */ + .cpu 68040 + + /* that one can be inlined */ +FUNCTION(flush_insn_pipeline_040): + nop + rts + + /* flush all ATC entries */ +FUNCTION(flush_atc_all_040): + pflusha + rts + + /* flush all user (non-global) ATC entries */ +FUNCTION(flush_atc_user_040): + pflushan + rts + + /* flush ATC entries for given address */ +FUNCTION(flush_atc_addr_040): + move.l (4,%a7),%a0 + pflush (%a0) + rts + + + diff --git a/src/system/kernel/arch/m68k/arch_040_cpu.cpp b/src/system/kernel/arch/m68k/arch_040_cpu.cpp new file mode 100644 index 0000000000..cf18eb8bff --- /dev/null +++ b/src/system/kernel/arch/m68k/arch_040_cpu.cpp @@ -0,0 +1,90 @@ +/* + * Copyright 2003-2008, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * François Revol + */ + +#include + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* from arch_040_asm.S */ +extern void flush_insn_pipeline_040(void); +extern void flush_atc_all_040(void); +extern void flush_atc_user_040(void); +extern void flush_atc_addr_040(addr_t addr); + +#ifdef __cplusplus +} +#endif + + + +#define CACHELINE 16 + +static void +sync_icache_040(addr_t address, size_t len) +{ + int l, off; + char *p; + + off = (unsigned int)address & (CACHELINE - 1); + len += off; + + l = len; + p = (char *)address - off; + asm volatile ("nop"); + +#warning M68K: 040: use CPUSHP on pages when possible for speed. + do { + asm volatile ( \ + "cpushl %%ic,(%0)\n" \ + :: "a"(p)); + p += CACHELINE; + } while ((l -= CACHELINE) > 0); + asm volatile ("nop"); +} + + +static void +sync_dcache_040(addr_t address, size_t len) +{ + int l, off; + char *p; + + off = (unsigned int)address & (CACHELINE - 1); + len += off; + + l = len; + p = (char *)address - off; + asm volatile ("nop"); + +#warning M68K: 040: use CPUSHP on pages when possible for speed. + do { + asm volatile ( \ + "cpushl %%dc,(%0)\n" \ + :: "a"(p)); + p += CACHELINE; + } while ((l -= CACHELINE) > 0); + asm volatile ("nop"); +} + + +struct m68k_cpu_ops cpu_ops_040 = { + &flush_insn_pipeline_040, + &flush_atc_all_040, + &flush_atc_user_040, + &flush_atc_addr_040, + &sync_dcache_040, + &sync_icache_040, + NULL // idle +}; diff --git a/src/system/kernel/arch/m68k/arch_040_mmu.cpp b/src/system/kernel/arch/m68k/arch_040_mmu.cpp new file mode 100644 index 0000000000..4cc4691f6b --- /dev/null +++ b/src/system/kernel/arch/m68k/arch_040_mmu.cpp @@ -0,0 +1,46 @@ +/* + * Copyright 2007, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * François Revol + */ + +#include + +#include + +#define ARCH_M68K_MMU_TYPE 68040 + +#include "arch_vm_translation_map_impl.cpp" + +static void +set_pgdir(void *rt) +{ + uint32 rp; + rp = (uint32)rt & ~((1 << 9) - 1); + + asm volatile( \ + "movec %0,%%srp\n" \ + "movec %0,%%urp\n" \ + : : "d"(rp)); + +} + + +struct m68k_vm_ops m68040_vm_ops = { + _m68k_translation_map_get_pgdir, + m68k_vm_translation_map_init_map, + m68k_vm_translation_map_init_kernel_map_post_sem, + m68k_vm_translation_map_init, + m68k_vm_translation_map_init_post_area, + m68k_vm_translation_map_init_post_sem, + m68k_vm_translation_map_early_map, + /*m68k_vm_translation_map_*/early_query, + set_pgdir, +#if 0 + m68k_map_address_range, + m68k_unmap_address_range, + m68k_remap_address_range +#endif +}; diff --git a/src/system/kernel/arch/m68k/arch_cpu.cpp b/src/system/kernel/arch/m68k/arch_cpu.cpp index 34b6eefc46..1c92853c5f 100644 --- a/src/system/kernel/arch/m68k/arch_cpu.cpp +++ b/src/system/kernel/arch/m68k/arch_cpu.cpp @@ -64,6 +64,8 @@ arch_cpu_init(kernel_args *args) switch (arch_cpu_type) { case 68020: case 68030: + memcpy(&cpu_ops, &cpu_ops_030, sizeof(cpu_ops)); + /* cpu_ops.flush_insn_pipeline = cpu_ops_030.flush_insn_pipeline; cpu_ops.flush_atc_all = cpu_ops_030.flush_atc_all; cpu_ops.flush_atc_user = cpu_ops_030.flush_atc_user; @@ -71,9 +73,12 @@ arch_cpu_init(kernel_args *args) cpu_ops.flush_dcache = cpu_ops_030.flush_dcache; cpu_ops.flush_icache = cpu_ops_030.flush_icache; cpu_ops.idle = cpu_ops_030.idle; // NULL + */ break; -#ifdef SUPPORTS_040 +//#ifdef SUPPORTS_040 case 68040: + memcpy(&cpu_ops, &cpu_ops_030, sizeof(cpu_ops)); + /* cpu_ops.flush_insn_pipeline = cpu_ops_040.flush_insn_pipeline; cpu_ops.flush_atc_all = cpu_ops_040.flush_atc_all; cpu_ops.flush_atc_user = cpu_ops_040.flush_atc_user; @@ -81,8 +86,9 @@ arch_cpu_init(kernel_args *args) cpu_ops.flush_dcache = cpu_ops_040.flush_dcache; cpu_ops.flush_icache = cpu_ops_040.flush_icache; cpu_ops.idle = cpu_ops_040.idle; // NULL + */ break; -#endif +//#endif #ifdef SUPPORTS_060 case 68060: cpu_ops.flush_insn_pipeline = cpu_ops_060.flush_insn_pipeline; diff --git a/src/system/kernel/arch/m68k/arch_int.cpp b/src/system/kernel/arch/m68k/arch_int.cpp index 2b725b427f..9dff90e1e9 100644 --- a/src/system/kernel/arch/m68k/arch_int.cpp +++ b/src/system/kernel/arch/m68k/arch_int.cpp @@ -43,7 +43,8 @@ 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[M68K_EXCEPTION_VECTOR_COUNT]; +m68k_exception_handler *gExceptionVectors; // defined in arch_exceptions.S extern "C" void __m68k_exception_noop(void); @@ -296,9 +297,12 @@ arch_int_init(kernel_args *args) 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; +#if 0 /* get the physical address */ err = arch_vm_translation_map_early_query( (addr_t)gExceptionVectors, &vbr); @@ -306,8 +310,10 @@ arch_int_init(kernel_args *args) 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,%%cacr" : : "r"(vbr):); + asm volatile ("movec %0,%%vbr" : : "r"(vbr):); return B_OK; } 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 6add81e01f..f70753b22d 100644 --- a/src/system/kernel/arch/m68k/arch_vm_translation_map.cpp +++ b/src/system/kernel/arch/m68k/arch_vm_translation_map.cpp @@ -32,7 +32,7 @@ //extern struct m68k_vm_ops m68851_vm_ops; extern struct m68k_vm_ops m68030_vm_ops; -//extern struct m68k_vm_ops m68040_vm_ops; +extern struct m68k_vm_ops m68040_vm_ops; // 060 should be identical to 040 except for copyback issue //extern struct m68k_vm_ops m68060_vm_ops; @@ -49,7 +49,7 @@ m68k_vm_ops *get_vm_ops() case 68030: return &m68030_vm_ops; case 68040: - //return &m68040_vm_ops; + return &m68040_vm_ops; case 68060: //return &m68060_vm_ops; panic("Unimplemented yet (mmu)"); diff --git a/src/system/kernel/arch/m68k/arch_vm_translation_map_impl.cpp b/src/system/kernel/arch/m68k/arch_vm_translation_map_impl.cpp index 7afad224e8..8560d680c9 100644 --- a/src/system/kernel/arch/m68k/arch_vm_translation_map_impl.cpp +++ b/src/system/kernel/arch/m68k/arch_vm_translation_map_impl.cpp @@ -58,7 +58,7 @@ -//#define TRACE_VM_TMAP +#define TRACE_VM_TMAP #ifdef TRACE_VM_TMAP # define TRACE(x) dprintf x #else @@ -229,8 +229,10 @@ early_query(addr_t va, addr_t *_physicalAddress) addr_t pa; int32 index; status_t err = B_ERROR; // no pagetable here - + TRACE(("%s(%p,)", __FUNCTION__, va)); + index = VADDR_TO_PRENT(va); + TRACE(("%s: pr[%d].type %d\n", __FUNCTION__, index, pr[index].type)); if (pr && pr[index].type == DT_ROOT) { pa = PRE_TO_TA(pr[index]); // pa == va when in TT @@ -238,11 +240,15 @@ early_query(addr_t va, addr_t *_physicalAddress) pd = (page_directory_entry *)pa; index = VADDR_TO_PDENT(va); + TRACE(("%s: pd[%d].type %d\n", __FUNCTION__, index, + pd?(pd[index].type):-1)); if (pd && pd[index].type == DT_DIR) { pa = PDE_TO_TA(pd[index]); pt = (page_table_entry *)pa; index = VADDR_TO_PTENT(va); + TRACE(("%s: pt[%d].type %d\n", __FUNCTION__, index, + pt?(pt[index].type):-1)); if (pt && pt[index].type == DT_INDIRECT) { pi = (page_indirect_entry *)pt; pa = PIE_TO_TA(pi[index]); @@ -335,7 +341,7 @@ destroy_tmap(vm_translation_map *map) if (map->arch_data->rtdir_virt != NULL) { // cycle through and free all of the user space pgtables - // since the size of tables don't match B_PAEG_SIZE, + // since the size of tables don't match B_PAGE_SIZE, // we alloc several at once, based on modulos, // we make sure they are either all in the tree or none. for (i = VADDR_TO_PRENT(USER_BASE); i <= VADDR_TO_PRENT(USER_BASE + (USER_SIZE - 1)); i++) { diff --git a/src/system/kernel/platform/atari_m68k/platform.cpp b/src/system/kernel/platform/atari_m68k/platform.cpp index 82a614a4f7..61c31aef44 100644 --- a/src/system/kernel/platform/atari_m68k/platform.cpp +++ b/src/system/kernel/platform/atari_m68k/platform.cpp @@ -46,6 +46,12 @@ public: private: int fRTC; + // native features (ARAnyM emulator) + uint32 (*nfGetID)(const char *name); + int32 (*nfCall)(uint32 ID, ...); + char *nfPage; + uint32 nfDebugPrintfID; + }; @@ -71,7 +77,13 @@ M68KAtari::~M68KAtari() status_t M68KAtari::Init(struct kernel_args *kernelArgs) { - return B_NO_INIT; + nfGetID = + kernelArgs->arch_args.plat_args.atari.nat_feat.nf_get_id; + nfCall = + kernelArgs->arch_args.plat_args.atari.nat_feat.nf_call; + nfPage = (char *) + kernelArgs->arch_args.plat_args.atari.nat_feat.nf_page; + return B_OK; } @@ -79,7 +91,11 @@ M68KAtari::Init(struct kernel_args *kernelArgs) status_t M68KAtari::InitSerialDebug(struct kernel_args *kernelArgs) { - return B_NO_INIT; + nfDebugPrintfID = + kernelArgs->arch_args.plat_args.atari.nat_feat.nf_dprintf_id; + +#warning M68K: add real serial debug output someday + return B_OK; } @@ -137,7 +153,21 @@ M68KAtari::SerialDebugGetChar() void M68KAtari::SerialDebugPutChar(char c) { - panic("WRITEME"); + if (nfCall && nfDebugPrintfID) { +#if 0 + static char buffer[2] = { '\0', '\0' }; + buffer[0] = c; + + nfCall(nfDebugPrintfID /*| 0*/, buffer); +#endif + nfPage[0] = c; + nfPage[1] = '\0'; + nfCall(nfDebugPrintfID /*| 0*/, nfPage); + } + +#warning M68K: WRITEME + // real serial + //panic("WRITEME"); } @@ -169,6 +199,7 @@ M68KAtari::ClearHardwareTimer(void) void M68KAtari::ShutDown(bool reboot) { + panic("Bombs!"); panic("WRITEME"); }