#include <cpus.h>
#include <debug.h>
#include <mach_kgdb.h>
#include <mach_vm_debug.h>
#include <kern/thread.h>
#include <mach/vm_attributes.h>
#include <mach/vm_param.h>
#include <vm/vm_kern.h>
#include <vm/vm_map.h>
#include <vm/vm_page.h>
#include <mach/ppc/thread_status.h>
#include <kern/spl.h>
#include <kern/simple_lock.h>
#include <kern/misc_protos.h>
#include <ppc/misc_protos.h>
#include <ppc/proc_reg.h>
#include <ppc/mem.h>
#include <ppc/pmap.h>
#include <ppc/pmap_internals.h>
#include <ppc/Firmware.h>
#include <ppc/mappings.h>
#include <ppc/exception.h>
#include <ppc/savearea.h>
#include <ddb/db_output.h>
extern struct Saveanchor saveanchor;
unsigned int debsave0 = 0;
unsigned int backchain = 0;
struct savearea *save_alloc(void) {
kern_return_t retr;
savectl *sctl;
vm_offset_t vaddr, paddr;
struct savearea *newbaby;
if(saveanchor.savecount <= (saveanchor.saveneed - saveanchor.saveneghyst)) {
while(saveanchor.savecount < saveanchor.saveneed) {
retr = kmem_alloc_wired(kernel_map, &vaddr, PAGE_SIZE);
if(retr != KERN_SUCCESS) {
panic("Whoops... Not a bit of wired memory left for saveareas\n");
}
paddr = pmap_extract(kernel_pmap, vaddr);
bzero((void *)vaddr, PAGE_SIZE);
sctl = (savectl *)(vaddr+PAGE_SIZE-sizeof(savectl));
sctl->sac_alloc = sac_empty;
sctl->sac_vrswap = (unsigned int)vaddr ^ (unsigned int)paddr;
sctl->sac_flags |= 0x0000EE00;
if(!save_queue(paddr)) {
panic("Arrgghhhh, time out trying to lock the savearea anchor during upward adjustment\n");
}
}
}
if (saveanchor.savecount > saveanchor.savemaxcount)
saveanchor.savemaxcount = saveanchor.savecount;
newbaby = save_get();
if(!((unsigned int)newbaby & 0xFFFFF000)) {
panic("No saveareas?!?!?! No way! Can't happen! Nuh-uh... I'm dead, done for, kaput...\n");
}
return newbaby;
}
void save_release(struct savearea *save) {
savectl *csave;
save_ret(save);
if(saveanchor.savecount > (saveanchor.saveneed + saveanchor.saveposhyst)) {
csave = (savectl *)42;
while((unsigned int)csave && (saveanchor.savecount > saveanchor.saveneed)) {
csave = save_dequeue();
if((unsigned int)csave & 1) {
panic("Arrgghhhh, time out trying to lock the savearea anchor during downward adjustment\n");
return;
}
if((unsigned int)csave) kmem_free(kernel_map, (vm_offset_t) csave, PAGE_SIZE);
}
}
return;
}
save_fake_zone_info(int *count, vm_size_t *cur_size, vm_size_t *max_size, vm_size_t *elem_size,
vm_size_t *alloc_size, int *collectable, int *exhaustable)
{
*count = saveanchor.saveinuse;
*cur_size = saveanchor.savecount * (PAGE_SIZE / 2);
*max_size = saveanchor.savemaxcount * (PAGE_SIZE / 2);
*elem_size = PAGE_SIZE / 2;
*alloc_size = PAGE_SIZE;
*collectable = 1;
*exhaustable = 0;
}
void save_free_dump(void) {
unsigned int *dsv, omsr;
savectl *dsc;
dsv = save_deb(&omsr);
while(dsv) {
dsc=(savectl *)((unsigned int)dsv+4096-sizeof(savectl));
dsv=(unsigned int *)(((unsigned int) dsc->sac_next)^(dsc->sac_vrswap));
}
__asm__ volatile ("mtmsr %0" : : "r" (omsr));
return;
}
void DumpTheSave(struct savearea *save) {
unsigned int *r;
printf("savearea at %08X\n", save);
printf(" srrs: %08X %08X\n", save->save_srr0, save->save_srr1);
printf(" cr, xer, lr: %08X %08X %08X\n", save->save_cr, save->save_xer, save->save_lr);
printf("ctr, dar, dsisr: %08X %08X %08X\n", save->save_ctr, save->save_dar, save->save_dsisr);
printf(" space, copyin: %08X %08X\n", save->save_space, save->save_sr_copyin);
r=&save->save_r0;
printf(" regs: %08X %08X %08X %08X %08X %08X %08X %08X\n", r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]);
printf(" %08X %08X %08X %08X %08X %08X %08X %08X\n", r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]);
printf(" %08X %08X %08X %08X %08X %08X %08X %08X\n", r[16], r[17], r[18], r[19], r[20], r[21], r[22], r[23]);
printf(" %08X %08X %08X %08X %08X %08X %08X %08X\n", r[24], r[25], r[29], r[27], r[28], r[29], r[30], r[31]);
r=(unsigned int *)&save->save_fp0;
printf(" floats: %08X%08X %08X%08X %08X%08X %08X%08X\n", r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]);
printf(" %08X%08X %08X%08X %08X%08X %08X%08X\n", r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]);
printf(" %08X%08X %08X%08X %08X%08X %08X%08X\n", r[16], r[17], r[18], r[19], r[20], r[21], r[22], r[23]);
printf(" %08X%08X %08X%08X %08X%08X %08X%08X\n", r[24], r[25], r[29], r[27], r[28], r[29], r[30], r[31]);
printf(" %08X%08X %08X%08X %08X%08X %08X%08X\n", r[32], r[33], r[34], r[35], r[36], r[37], r[38], r[39]);
printf(" %08X%08X %08X%08X %08X%08X %08X%08X\n", r[40], r[41], r[42], r[43], r[44], r[45], r[46], r[47]);
printf(" %08X%08X %08X%08X %08X%08X %08X%08X\n", r[48], r[49], r[50], r[51], r[52], r[53], r[54], r[55]);
printf(" %08X%08X %08X%08X %08X%08X %08X%08X\n", r[56], r[57], r[58], r[59], r[60], r[61], r[62], r[63]);
r=&save->save_sr0;
printf(" srs: %08X %08X %08X %08X %08X %08X %08X %08X\n", r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]);
printf(" %08X %08X %08X %08X %08X %08X %08X %08X\n", r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]);
printf("prev, phys, act: %08X %08X %08X\n", save->save_prev, save->save_phys, save->save_act);
printf(" flags: %08X\n", save->save_flags);
return;
}
void DumpBackChain(struct savearea *save) {
unsigned int *r;
savearea *sv;
if(!backchain) return;
printf("Proceeding back from savearea at %08X:\n", save);
sv=save;
while(sv) {
printf(" curr=%08X; prev=%08X; stack=%08X\n", sv, sv->save_prev, sv->save_r1);
sv=sv->save_prev;
}
return;
}