* Copyright 2007, FranΓ§ois Revol, revol@free.fr.
* Distributed under the terms of the MIT License.
*
* Copyright 2003-2005, Axel DΓΆrfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
* Distributed under the terms of the NewOS License.
*/
#include <KernelExport.h>
#include <arch_platform.h>
#include <arch_thread.h>
#include <arch/cpu.h>
#include <boot/kernel_args.h>
#include <commpage.h>
#include <elf.h>
extern struct m68k_cpu_ops cpu_ops_030;
extern struct m68k_cpu_ops cpu_ops_040;
extern struct m68k_cpu_ops cpu_ops_060;
struct m68k_cpu_ops cpu_ops;
int arch_cpu_type;
int arch_fpu_type;
int arch_mmu_type;
int arch_platform;
status_t
arch_cpu_preboot_init_percpu(kernel_args *args, int curr_cpu)
{
arch_thread_set_current_thread(NULL);
return B_OK;
}
status_t
arch_cpu_init_percpu(kernel_args *args, int curr_cpu)
{
return 0;
}
status_t
arch_cpu_init(kernel_args *args)
{
arch_cpu_type = args->arch_args.cpu_type;
arch_fpu_type = args->arch_args.fpu_type;
arch_mmu_type = args->arch_args.mmu_type;
arch_platform = args->arch_args.platform;
arch_platform = args->arch_args.machine;
switch (arch_cpu_type) {
case 68020:
case 68030:
memcpy(&cpu_ops, &cpu_ops_030, sizeof(cpu_ops));
break;
case 68040:
memcpy(&cpu_ops, &cpu_ops_040, sizeof(cpu_ops));
break;
#ifdef SUPPORTS_060
case 68060:
memcpy(&cpu_ops, &cpu_ops_060, sizeof(cpu_ops));
break;
#endif
default:
panic("unknown cpu_type %d\n", arch_cpu_type);
}
return B_OK;
}
status_t
arch_cpu_init_post_vm(kernel_args *args)
{
return B_OK;
}
status_t
arch_cpu_init_post_modules(kernel_args *args)
{
image_id image = get_commpage_image();
return B_OK;
}
void
arch_cpu_sync_icache(void *address, size_t len)
{
cpu_ops.flush_icache((addr_t)address, len);
}
void
arch_cpu_memory_read_barrier(void)
{
asm volatile ("nop;" : : : "memory");
#warning M68k: check arch_cpu_memory_read_barrier (FNOP ?)
}
void
arch_cpu_memory_write_barrier(void)
{
asm volatile ("nop;" : : : "memory");
#warning M68k: check arch_cpu_memory_write_barrier (FNOP ?)
}
void
arch_cpu_invalidate_TLB_range(addr_t start, addr_t end)
{
int32 num_pages = end / B_PAGE_SIZE - start / B_PAGE_SIZE;
cpu_ops.flush_insn_pipeline();
while (num_pages-- >= 0) {
cpu_ops.flush_atc_addr(start);
cpu_ops.flush_insn_pipeline();
start += B_PAGE_SIZE;
}
cpu_ops.flush_insn_pipeline();
}
void
arch_cpu_invalidate_TLB_list(addr_t pages[], int num_pages)
{
int i;
cpu_ops.flush_insn_pipeline();
for (i = 0; i < num_pages; i++) {
cpu_ops.flush_atc_addr(pages[i]);
cpu_ops.flush_insn_pipeline();
}
cpu_ops.flush_insn_pipeline();
}
void
arch_cpu_global_TLB_invalidate(void)
{
cpu_ops.flush_insn_pipeline();
cpu_ops.flush_atc_all();
cpu_ops.flush_insn_pipeline();
}
void
arch_cpu_user_TLB_invalidate(void)
{
cpu_ops.flush_insn_pipeline();
cpu_ops.flush_atc_user();
cpu_ops.flush_insn_pipeline();
}
status_t
arch_cpu_shutdown(bool reboot)
{
M68KPlatform::Default()->ShutDown(reboot);
return B_ERROR;
}
bool
m68k_set_fault_handler(addr_t *handlerLocation, addr_t handler)
{
*handlerLocation = handler;
return false;
}