////////////////////////////////////////////////////////////////////// // KIRK functioon ////////////////////////////////////////////////////////////////////// int pspKirkProc(void *dst,u32 dsize,void *src,u32 ssize,u32 cmd) { u32 intval; u32 sts; // enable decrypter HW intval = irq_disable(); (*(vu32 *)0xbc100050) |= 0x80; irq_resume(intval); // clear cache // sceKernelDcacheWritebackInvalidateAll(); pspClearDcache(); #if 0 // memory address mask r2 = 0x1fffffff; r3 = r18 & r2; // arg1 r2 = r16 & r2; // arg3 #endif //Kprintf("irq_disable\n"); // intval = irq_disable(); // go KIRK *(u32 *)(0xbde00010) = (u32)cmd; *(u32 *)(0xbde0002c) = ((u32)src)&0x1fffffff; *(u32 *)(0xbde00030) = ((u32)dst)&0x1fffffff; #if 0 *(u32 *)(0xbde00020) = 0x33; // for IRQ mode #endif //Kprintf("go kirk\n"); *(u32 *)(0xbde0000c) = 0x01; // EXEXUTE // irq_resume(intval); //Kprintf("wait sts\n"); do { sts = *(vu32 *)0xbde0001c; }while( (sts & 0x11)==0); *(u32 *)(0xbde00028) = sts; if(sts & 0x10) { *(u32 *)(0xbde0000c) = 0x02; do { sts = *(vu32 *)0xbde0001c; }while( (sts & 0x02)==0); *(u32 *)(0xbde00028) = sts; asm("sync"::); return -1; }
/* HVM mode suspension. */ static void xctrl_suspend() { int suspend_cancelled; EVENTHANDLER_INVOKE(power_suspend); /* * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE * drivers need this. */ mtx_lock(&Giant); if (DEVICE_SUSPEND(root_bus) != 0) { mtx_unlock(&Giant); printf("%s: device_suspend failed\n", __func__); return; } mtx_unlock(&Giant); /* * Prevent any races with evtchn_interrupt() handler. */ disable_intr(); irq_suspend(); suspend_cancelled = HYPERVISOR_suspend(0); if (suspend_cancelled) irq_resume(); else xenpci_resume(); /* * Re-enable interrupts and put the scheduler back to normal. */ enable_intr(); /* * FreeBSD really needs to add DEVICE_SUSPEND_CANCEL or * similar. */ mtx_lock(&Giant); if (!suspend_cancelled) DEVICE_RESUME(root_bus); mtx_unlock(&Giant); EVENTHANDLER_INVOKE(power_resume); }
/* * Called very early in the resume sequence - reinitialise the various * bits of Xen machinery including the hypercall page and the shared * info page. */ void xenpci_resume() { device_t dev = devclass_get_device(xenpci_devclass, 0); struct xenpci_softc *scp = device_get_softc(dev); struct xen_add_to_physmap xatp; xenpci_resume_hypercall_stubs(dev, scp); xatp.domid = DOMID_SELF; xatp.idx = 0; xatp.space = XENMAPSPACE_shared_info; xatp.gpfn = shared_info_pa >> PAGE_SHIFT; if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) panic("HYPERVISOR_memory_op failed"); pmap_kenter((vm_offset_t) HYPERVISOR_shared_info, shared_info_pa); xenpci_set_callback(dev); gnttab_resume(); irq_resume(); }
static int __do_suspend(void *ignore) { int err; extern void time_resume(void); BUG_ON(smp_processor_id() != 0); BUG_ON(in_interrupt()); #if defined(__i386__) || defined(__x86_64__) if (xen_feature(XENFEAT_auto_translated_physmap)) { printk(KERN_WARNING "Cannot suspend in " "auto_translated_physmap mode.\n"); return -EOPNOTSUPP; } #endif err = smp_suspend(); if (err) return err; xenbus_suspend(); preempt_disable(); #ifdef __i386__ kmem_cache_shrink(pgd_cache); #endif mm_pin_all(); local_irq_disable(); preempt_enable(); gnttab_suspend(); pre_suspend(); /* * We'll stop somewhere inside this hypercall. When it returns, * we'll start resuming after the restore. */ HYPERVISOR_suspend(virt_to_mfn(xen_start_info)); shutting_down = SHUTDOWN_INVALID; post_suspend(); gnttab_resume(); irq_resume(); time_resume(); switch_idle_mm(); local_irq_enable(); xencons_resume(); xenbus_resume(); smp_resume(); return err; }
static int __do_suspend(void *ignore) { int i, j, k, fpp, err; extern unsigned long max_pfn; extern unsigned long *pfn_to_mfn_frame_list_list; extern unsigned long *pfn_to_mfn_frame_list[]; extern void time_resume(void); BUG_ON(smp_processor_id() != 0); BUG_ON(in_interrupt()); if (xen_feature(XENFEAT_auto_translated_physmap)) { printk(KERN_WARNING "Cannot suspend in " "auto_translated_physmap mode.\n"); return -EOPNOTSUPP; } err = smp_suspend(); if (err) return err; xenbus_suspend(); preempt_disable(); #ifdef __i386__ kmem_cache_shrink(pgd_cache); #endif mm_pin_all(); __cli(); preempt_enable(); gnttab_suspend(); HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page; clear_fixmap(FIX_SHARED_INFO); xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn); xen_start_info->console_mfn = mfn_to_pfn(xen_start_info->console_mfn); /* * We'll stop somewhere inside this hypercall. When it returns, * we'll start resuming after the restore. */ HYPERVISOR_suspend(virt_to_mfn(xen_start_info)); shutting_down = SHUTDOWN_INVALID; set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); memset(empty_zero_page, 0, PAGE_SIZE); HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = virt_to_mfn(pfn_to_mfn_frame_list_list); fpp = PAGE_SIZE/sizeof(unsigned long); for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) { if ((j % fpp) == 0) { k++; pfn_to_mfn_frame_list_list[k] = virt_to_mfn(pfn_to_mfn_frame_list[k]); j = 0; } pfn_to_mfn_frame_list[k][j] = virt_to_mfn(&phys_to_machine_mapping[i]); } HYPERVISOR_shared_info->arch.max_pfn = max_pfn; gnttab_resume(); irq_resume(); time_resume(); switch_idle_mm(); __sti(); xencons_resume(); xenbus_resume(); smp_resume(); return err; }
/* Full PV mode suspension. */ static void xctrl_suspend() { int i, j, k, fpp; unsigned long max_pfn, start_info_mfn; EVENTHANDLER_INVOKE(power_suspend); #ifdef SMP struct thread *td; cpuset_t map; u_int cpuid; /* * Bind us to CPU 0 and stop any other VCPUs. */ td = curthread; thread_lock(td); sched_bind(td, 0); thread_unlock(td); cpuid = PCPU_GET(cpuid); KASSERT(cpuid == 0, ("xen_suspend: not running on cpu 0")); map = all_cpus; CPU_CLR(cpuid, &map); CPU_NAND(&map, &stopped_cpus); if (!CPU_EMPTY(&map)) stop_cpus(map); #endif /* * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE * drivers need this. */ mtx_lock(&Giant); if (DEVICE_SUSPEND(root_bus) != 0) { mtx_unlock(&Giant); printf("%s: device_suspend failed\n", __func__); #ifdef SMP if (!CPU_EMPTY(&map)) restart_cpus(map); #endif return; } mtx_unlock(&Giant); local_irq_disable(); xencons_suspend(); gnttab_suspend(); max_pfn = HYPERVISOR_shared_info->arch.max_pfn; void *shared_info = HYPERVISOR_shared_info; HYPERVISOR_shared_info = NULL; pmap_kremove((vm_offset_t) shared_info); PT_UPDATES_FLUSH(); xen_start_info->store_mfn = MFNTOPFN(xen_start_info->store_mfn); xen_start_info->console.domU.mfn = MFNTOPFN(xen_start_info->console.domU.mfn); /* * We'll stop somewhere inside this hypercall. When it returns, * we'll start resuming after the restore. */ start_info_mfn = VTOMFN(xen_start_info); pmap_suspend(); HYPERVISOR_suspend(start_info_mfn); pmap_resume(); pmap_kenter_ma((vm_offset_t) shared_info, xen_start_info->shared_info); HYPERVISOR_shared_info = shared_info; HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = VTOMFN(xen_pfn_to_mfn_frame_list_list); fpp = PAGE_SIZE/sizeof(unsigned long); for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) { if ((j % fpp) == 0) { k++; xen_pfn_to_mfn_frame_list_list[k] = VTOMFN(xen_pfn_to_mfn_frame_list[k]); j = 0; } xen_pfn_to_mfn_frame_list[k][j] = VTOMFN(&xen_phys_machine[i]); } HYPERVISOR_shared_info->arch.max_pfn = max_pfn; gnttab_resume(); irq_resume(); local_irq_enable(); xencons_resume(); #ifdef CONFIG_SMP for_each_cpu(i) vcpu_prepare(i); #endif /* * Only resume xenbus /after/ we've prepared our VCPUs; otherwise * the VCPU hotplug callback can race with our vcpu_prepare */ mtx_lock(&Giant); DEVICE_RESUME(root_bus); mtx_unlock(&Giant); #ifdef SMP thread_lock(curthread); sched_unbind(curthread); thread_unlock(curthread); if (!CPU_EMPTY(&map)) restart_cpus(map); #endif EVENTHANDLER_INVOKE(power_resume); }