- 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
This commit is contained in:
François Revol 2008-07-25 00:25:27 +00:00
parent 3f59678453
commit 36ee9f5c62
13 changed files with 248 additions and 16 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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
;

View File

@ -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)

View File

@ -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

View File

@ -0,0 +1,90 @@
/*
* Copyright 2003-2008, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* François Revol <revol@free.fr>
*/
#include <KernelExport.h>
#include <arch_platform.h>
#include <arch_thread.h>
#include <arch/cpu.h>
#include <boot/kernel_args.h>
#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
};

View 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>
*/
#include <arch/cpu.h>
#include <arch_040_mmu.h>
#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
};

View File

@ -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;

View File

@ -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;
}

View File

@ -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)");

View File

@ -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++) {

View File

@ -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");
}