#include <debug.h>
#include <mach_ldebug.h>
#include <mach_kdb.h>
#include <mach_kdp.h>
#include <kern/misc_protos.h>
#include <kern/thread.h>
#include <kern/processor.h>
#include <kern/startup.h>
#include <machine/machine_routines.h>
#include <ppc/boot.h>
#include <ppc/proc_reg.h>
#include <ppc/misc_protos.h>
#include <ppc/pmap.h>
#include <ppc/new_screen.h>
#include <ppc/exception.h>
#include <ppc/asm.h>
#include <ppc/Firmware.h>
#include <ppc/savearea.h>
#include <ppc/low_trace.h>
#include <ppc/Diagnostics.h>
#include <ppc/cpu_internal.h>
#include <ppc/mem.h>
#include <ppc/mappings.h>
#include <ppc/locks.h>
#include <kern/pms.h>
#include <ppc/rtclock.h>
#include <pexpert/pexpert.h>
extern unsigned int mckFlags;
extern vm_offset_t intstack;
extern vm_offset_t debstack;
extern unsigned int extPatchMCK;
extern unsigned int extPatch32;
extern unsigned int hwulckPatch_isync;
extern unsigned int hwulckPatch_eieio;
extern unsigned int hwulckbPatch_isync;
extern unsigned int hwulckbPatch_eieio;
extern unsigned int mulckPatch_isync;
extern unsigned int mulckPatch_eieio;
extern unsigned int mulckePatch_isync;
extern unsigned int mulckePatch_eieio;
extern unsigned int sulckPatch_isync;
extern unsigned int sulckPatch_eieio;
extern unsigned int rwlesPatch_isync;
extern unsigned int rwlesPatch_eieio;
extern unsigned int rwldPatch_isync;
extern unsigned int rwldPatch_eieio;
extern unsigned int bcopy_nop_if_32bit;
extern unsigned int bcopy_nc_nop_if_32bit;
extern unsigned int memcpy_nop_if_32bit;
extern unsigned int xsum_nop_if_32bit;
extern unsigned int uft_nop_if_32bit;
extern unsigned int uft_uaw_nop_if_32bit;
extern unsigned int uft_cuttrace;
int forcenap = 0;
int wcte = 0;
int debug_task;
patch_entry_t patch_table[] = {
{&extPatch32, 0x60000000, PATCH_FEATURE, PatchExt32},
{&extPatchMCK, 0x60000000, PATCH_PROCESSOR, CPU_SUBTYPE_POWERPC_970},
{&hwulckPatch_isync, 0x60000000, PATCH_FEATURE, PatchLwsync},
{&hwulckPatch_eieio, 0x7c2004ac, PATCH_FEATURE, PatchLwsync},
{&hwulckbPatch_isync, 0x60000000, PATCH_FEATURE, PatchLwsync},
{&hwulckbPatch_eieio, 0x7c2004ac, PATCH_FEATURE, PatchLwsync},
{&mulckPatch_isync, 0x60000000, PATCH_FEATURE, PatchLwsync},
{&mulckPatch_eieio, 0x7c2004ac, PATCH_FEATURE, PatchLwsync},
{&mulckePatch_isync, 0x60000000, PATCH_FEATURE, PatchLwsync},
{&mulckePatch_eieio, 0x7c2004ac, PATCH_FEATURE, PatchLwsync},
{&sulckPatch_isync, 0x60000000, PATCH_FEATURE, PatchLwsync},
{&sulckPatch_eieio, 0x7c2004ac, PATCH_FEATURE, PatchLwsync},
{&rwlesPatch_isync, 0x60000000, PATCH_FEATURE, PatchLwsync},
{&rwlesPatch_eieio, 0x7c2004ac, PATCH_FEATURE, PatchLwsync},
{&rwldPatch_isync, 0x60000000, PATCH_FEATURE, PatchLwsync},
{&rwldPatch_eieio, 0x7c2004ac, PATCH_FEATURE, PatchLwsync},
{&bcopy_nop_if_32bit, 0x60000000, PATCH_FEATURE, PatchExt32},
{&bcopy_nc_nop_if_32bit,0x60000000, PATCH_FEATURE, PatchExt32},
{&memcpy_nop_if_32bit, 0x60000000, PATCH_FEATURE, PatchExt32},
{&xsum_nop_if_32bit, 0x60000000, PATCH_FEATURE, PatchExt32},
{&uft_nop_if_32bit, 0x60000000, PATCH_FEATURE, PatchExt32},
{&uft_uaw_nop_if_32bit, 0x60000000, PATCH_FEATURE, PatchExt32},
{&uft_cuttrace, 0x60000000, PATCH_FEATURE, PatchExt32},
{NULL, 0x00000000, PATCH_END_OF_TABLE, 0}
};
void ppc_init(
boot_args *args);
void ppc_init_cpu(
struct per_proc_info *proc_info);
void
ppc_init(
boot_args *args)
{
unsigned int maxmem;
uint64_t xmaxmem;
uint64_t newhid;
unsigned int cputrace;
unsigned int novmx;
unsigned int mcksoft;
thread_t thread;
mapping_t *mp;
uint64_t scdata;
BootProcInfo.cpu_number = 0;
BootProcInfo.cpu_flags = 0;
BootProcInfo.istackptr = 0;
BootProcInfo.intstack_top_ss = (vm_offset_t)&intstack + INTSTACK_SIZE - FM_SIZE;
BootProcInfo.debstack_top_ss = (vm_offset_t)&debstack + KERNEL_STACK_SIZE - FM_SIZE;
BootProcInfo.debstackptr = BootProcInfo.debstack_top_ss;
BootProcInfo.interrupts_enabled = 0;
BootProcInfo.pending_ast = AST_NONE;
BootProcInfo.FPU_owner = NULL;
BootProcInfo.VMX_owner = NULL;
BootProcInfo.pp_cbfr = console_per_proc_alloc(TRUE);
BootProcInfo.rtcPop = EndOfAllTime;
BootProcInfo.pp2ndPage = (addr64_t)&BootProcInfo;
BootProcInfo.pms.pmsStamp = 0;
BootProcInfo.pms.pmsPop = EndOfAllTime;
BootProcInfo.pms.pmsState = pmsParked;
BootProcInfo.pms.pmsCSetCmd = pmsCInit;
mp = (mapping_t *)BootProcInfo.ppUMWmp;
mp->mpFlags = 0x01000000 | mpLinkage | mpPerm | 1;
mp->mpSpace = invalSpace;
pmsInit();
thread_bootstrap();
thread = current_thread();
thread->machine.curctx = &thread->machine.facctx;
thread->machine.facctx.facAct = thread;
thread->machine.umwSpace = invalSpace;
thread->machine.preemption_count = 1;
cpu_bootstrap();
cpu_init();
master_cpu = 0;
processor_bootstrap();
timer_start(&thread->system_timer, mach_absolute_time());
PROCESSOR_DATA(master_processor, kernel_timer) =
PROCESSOR_DATA(master_processor, thread_timer) = &thread->system_timer;
static_memory_end = round_page(args->topOfKernelData);;
PE_init_platform(FALSE, args);
if (!PE_parse_boot_arg("novmx", &novmx)) novmx=0;
if(novmx) {
BootProcInfo.pf.Available &= ~pfAltivec;
__asm__ volatile("mtsprg 2,%0" : : "r" (BootProcInfo.pf.Available));
}
if (!PE_parse_boot_arg("fn", &forcenap)) forcenap = 0;
else {
if(forcenap < 2) forcenap = forcenap + 1;
else forcenap = 0;
}
if (!PE_parse_boot_arg("pmsx", &pmsExperimental)) pmsExperimental = 0;
if (!PE_parse_boot_arg("lcks", &LcksOpts)) LcksOpts = 0;
if (!PE_parse_boot_arg("diag", &dgWork.dgFlags)) dgWork.dgFlags = 0;
if(dgWork.dgFlags & enaExpTrace) trcWork.traceMask = 0xFFFFFFFF;
if(PE_parse_boot_arg("ctrc", &cputrace)) {
trcWork.traceMask = (trcWork.traceMask & 0xFFFFFFF0) | (cputrace & 0xF);
}
if(!PE_parse_boot_arg("tb", &trcWork.traceSize)) {
#if DEBUG
trcWork.traceSize = 32;
#else
trcWork.traceSize = 8;
#endif
}
if(trcWork.traceSize < 1) trcWork.traceSize = 1;
if(trcWork.traceSize > 256) trcWork.traceSize = 256;
trcWork.traceSize = trcWork.traceSize * 4096;
if (!PE_parse_boot_arg("maxmem", &maxmem))
xmaxmem=0;
else
xmaxmem = (uint64_t)maxmem * (1024 * 1024);
if (!PE_parse_boot_arg("wcte", &wcte)) wcte = 0;
else wcte = (wcte != 0);
if (!PE_parse_boot_arg("mcklog", &mckFlags)) mckFlags = 0;
else if(mckFlags > 1) mckFlags = 0;
if (!PE_parse_boot_arg("ht_shift", &hash_table_shift))
hash_table_shift = 0;
ppc_vm_init(xmaxmem, args);
if(BootProcInfo.pf.Available & pf64Bit) {
if(!wcte) {
(void)ml_scom_read(GUSModeReg << 8, &scdata);
scdata = scdata | GUSMstgttoff;
(void)ml_scom_write(GUSModeReg << 8, scdata);
}
if(PE_parse_boot_arg("mcksoft", &mcksoft)) {
newhid = BootProcInfo.pf.pfHID5;
if(mcksoft < 2) {
newhid &= 0xFFFFFFFFFFFFDFFFULL;
newhid |= (mcksoft & 1) << 13;
BootProcInfo.pf.pfHID5 = newhid;
hid5set64(newhid);
}
}
}
machine_startup();
}
void
ppc_init_cpu(
struct per_proc_info *proc_info)
{
uint64_t scdata;
proc_info->cpu_flags &= ~SleepState;
if((BootProcInfo.pf.Available & pf64Bit) && !wcte) {
(void)ml_scom_read(GUSModeReg << 8, &scdata);
scdata = scdata | GUSMstgttoff;
(void)ml_scom_write(GUSModeReg << 8, scdata);
}
cpu_init();
slave_main();
}