- 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:
parent
3f59678453
commit
36ee9f5c62
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
;
|
||||
|
@ -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)
|
||||
|
30
src/system/kernel/arch/m68k/arch_040_asm.S
Normal file
30
src/system/kernel/arch/m68k/arch_040_asm.S
Normal 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
|
||||
|
||||
|
||||
|
90
src/system/kernel/arch/m68k/arch_040_cpu.cpp
Normal file
90
src/system/kernel/arch/m68k/arch_040_cpu.cpp
Normal 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
|
||||
};
|
46
src/system/kernel/arch/m68k/arch_040_mmu.cpp
Normal file
46
src/system/kernel/arch/m68k/arch_040_mmu.cpp
Normal 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
|
||||
};
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)");
|
||||
|
@ -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++) {
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user