Пример #1
0
Файл: proc.c Проект: npe9/harvey
void
kproc(char *name, void (*func)(void *), void *arg)
{
	Mach *m = machp();
	Proc *p;
	static Pgrp *kpgrp;

	p = newproc();
	p->psstate = 0;
	p->procmode = 0640;
	p->kp = 1;
	p->noswap = 1;

	p->scallnr = m->externup->scallnr;
	memmove(p->arg, m->externup->arg, sizeof(m->externup->arg));
	p->nerrlab = 0;
	p->slash = m->externup->slash;
	p->dot = m->externup->dot;
	if(p->dot)
		incref(p->dot);

	memmove(p->note, m->externup->note, sizeof(p->note));
	p->nnote = m->externup->nnote;
	p->notified = 0;
	p->lastnote = m->externup->lastnote;
	p->notify = m->externup->notify;
	p->ureg = 0;
	p->dbgreg = 0;

	procpriority(p, PriKproc, 0);

	kprocchild(p, func, arg);

	kstrdup(&p->user, eve);
	kstrdup(&p->text, name);
	if(kpgrp == 0)
		kpgrp = newpgrp();
	p->pgrp = kpgrp;
	incref(kpgrp);

	memset(p->time, 0, sizeof(p->time));
	p->time[TReal] = sys->ticks;
	ready(p);
	/*
	 *  since the bss/data segments are now shareable,
	 *  any mmu info about this process is now stale
	 *  and has to be discarded.
	 */
	p->newtlb = 1;
	mmuflush();
}
Пример #2
0
void
hzclock(Ureg *ur)
{
	Proc *up = externup();
	uintptr_t pc;

	machp()->ticks++;
	if(machp()->machno == 0)
		sys->ticks = machp()->ticks;

	pc = userpc(ur);
	if(machp()->proc)
		machp()->proc->pc = pc;

	if(machp()->mmuflush){
		if(up)
			mmuflush();
		machp()->mmuflush = 0;
	}

	accounttime();
	kmapinval();

	if(kproftimer != nil)
		kproftimer(pc);
	oprof_alarm_handler(ur);

	if(machp()->online == 0)
		return;

	if(active.exiting) {
		print("someone's exiting\n");
		exit(0);
	}

	if(machp()->machno == 0) {
		/* since sys->ticks is only updated if machp()->machno == 0 */
		checkalarms();
	}

	if(up && up->state == Running)
		hzsched();	/* in proc.c */
}
Пример #3
0
void init_lisa_mmu(void)
{
    uint32 i,j;

	start=1; segment1=0; segment2=0; context=0;
	mmudirty=0;
    mmudirty_all[0]=0;
    mmudirty_all[1]=0;
    mmudirty_all[2]=0;
    mmudirty_all[3]=0;
    mmudirty_all[4]=0;

    DEBUG_LOG(0,"Initializing... mmu_trans_all: %p mmu_all: %p",mmu_trans_all,mmu_all);

	for (i=0; i<32768; i++) // Initialize START mode (setup in hwg81) translation table
	{
     // First, zap all MMU contexts to bad pages.  This is to make sure that
     // we don't accidentally hit unused pages.  Alternatively, for debugging
     // purposes, we could uncomment this block and see if anything breaks.

		mmu_trans_all[1][i].address= 0;
		mmu_trans_all[1][i].readfn = bad_page;
		mmu_trans_all[1][i].writefn= bad_page;
        mmu_trans_all[1][i].table=NULL;

		mmu_trans_all[2][i].address= 0;
		mmu_trans_all[2][i].readfn = bad_page;
		mmu_trans_all[2][i].writefn= bad_page;
        mmu_trans_all[2][i].table=NULL;

		mmu_trans_all[3][i].address= 0;
		mmu_trans_all[3][i].readfn = bad_page;
		mmu_trans_all[3][i].writefn= bad_page;
        mmu_trans_all[3][i].table=NULL;

		mmu_trans_all[4][i].address= 0;
		mmu_trans_all[4][i].readfn = bad_page;
		mmu_trans_all[4][i].writefn= bad_page;
        mmu_trans_all[4][i].table=NULL;

        init_start_mode_segment(i);

        mmudirty=0;
        mmudirty_all[0]=0;
        mmudirty_all[1]=0xdec0de;
        mmudirty_all[2]=0xdec0de;
        mmudirty_all[3]=0xdec0de;
        mmudirty_all[4]=0xdec0de;
	}


	for (i=0; i<128; i++) // Initialize START mode fake mmu table
	{
        mmu_all[0][i].sor=0;
        mmu_all[0][i].slr=0xf00;
        mmu_all[0][i].changed=0;

        mmu_all[1][i].sor=0;                 mmu_all[3][i].sor=0;
        mmu_all[1][i].slr=0xc00;             mmu_all[3][i].slr=0xc00;
        mmu_all[1][i].changed=1;             mmu_all[3][i].changed=1;

        mmu_all[2][i].sor=0;                 mmu_all[4][i].sor=0;
        mmu_all[2][i].slr=0xc00;             mmu_all[4][i].slr=0xc00;
        mmu_all[2][i].changed=1;             mmu_all[4][i].changed=1;

	}


    // fill up memory
    for (j=0,i=(minlisaram>>9); i<(maxlisaram>>9); i+=((128*1024)>>9),j++)
    {
        mmu_all[1][j].sor=(i>>9);    mmu_all[1][j].slr=0x700;
    }

    // Setup I/O space in page 126/127 of our context 1 (lisa context 0)
    mmu_all[1][126].slr=0x900;       mmu_all[1][126].sor=0;
    mmu_all[1][127].slr=0xf00;       mmu_all[1][127].sor=0;


	// Initialize Lisa MMU Function Types
	// fn assignments
    for (i=0; i<MAX_LISA_MFN; i++)
    {
     mem68k_memptr[i]=lisa_mptr_OxERROR;
     mem68k_fetch_byte[i]=lisa_rb_OxERROR;
     mem68k_fetch_word[i]=lisa_rw_OxERROR;
     mem68k_fetch_long[i]=lisa_rl_OxERROR;
     mem68k_store_byte[i]=lisa_wb_OxERROR;
     mem68k_store_word[i]=lisa_ww_OxERROR;
     mem68k_store_long[i]=lisa_wl_OxERROR;
    }

	mem68k_memptr[OxUnused]=lisa_mptr_OxUnused;
	mem68k_fetch_byte[OxUnused]=lisa_rb_OxUnused;
	mem68k_fetch_word[OxUnused]=lisa_rw_OxUnused;
	mem68k_fetch_long[OxUnused]=lisa_rl_OxUnused;
	mem68k_store_byte[OxUnused]=lisa_wb_OxUnused;
	mem68k_store_word[OxUnused]=lisa_ww_OxUnused;
	mem68k_store_long[OxUnused]=lisa_wl_OxUnused;
                                  
	mem68k_memptr[    Ox0000_slot1]=lisa_mptr_Ox0000_slot1;
	mem68k_fetch_byte[Ox0000_slot1]=lisa_rb_Ox0000_slot1;
	mem68k_fetch_word[Ox0000_slot1]=lisa_rw_Ox0000_slot1;
	mem68k_fetch_long[Ox0000_slot1]=lisa_rl_Ox0000_slot1;
	mem68k_store_byte[Ox0000_slot1]=lisa_wb_Ox0000_slot1;
	mem68k_store_word[Ox0000_slot1]=lisa_ww_Ox0000_slot1;
	mem68k_store_long[Ox0000_slot1]=lisa_wl_Ox0000_slot1;
                                  
	mem68k_memptr[    Ox2000_slot1]=lisa_mptr_Ox2000_slot1;
	mem68k_fetch_byte[Ox2000_slot1]=lisa_rb_Ox2000_slot1;
	mem68k_fetch_word[Ox2000_slot1]=lisa_rw_Ox2000_slot1;
	mem68k_fetch_long[Ox2000_slot1]=lisa_rl_Ox2000_slot1;
	mem68k_store_byte[Ox2000_slot1]=lisa_wb_Ox2000_slot1;
	mem68k_store_word[Ox2000_slot1]=lisa_ww_Ox2000_slot1;
	mem68k_store_long[Ox2000_slot1]=lisa_wl_Ox2000_slot1;
                                  
	mem68k_memptr[    Ox4000_slot2]=lisa_mptr_Ox4000_slot2;
	mem68k_fetch_byte[Ox4000_slot2]=lisa_rb_Ox4000_slot2;
	mem68k_fetch_word[Ox4000_slot2]=lisa_rw_Ox4000_slot2;
	mem68k_fetch_long[Ox4000_slot2]=lisa_rl_Ox4000_slot2;
	mem68k_store_byte[Ox4000_slot2]=lisa_wb_Ox4000_slot2;
	mem68k_store_word[Ox4000_slot2]=lisa_ww_Ox4000_slot2;
	mem68k_store_long[Ox4000_slot2]=lisa_wl_Ox4000_slot2;
                                  
	mem68k_memptr[    Ox6000_slot2]=lisa_mptr_Ox6000_slot2;
	mem68k_fetch_byte[Ox6000_slot2]=lisa_rb_Ox6000_slot2;
	mem68k_fetch_word[Ox6000_slot2]=lisa_rw_Ox6000_slot2;
	mem68k_fetch_long[Ox6000_slot2]=lisa_rl_Ox6000_slot2;
	mem68k_store_byte[Ox6000_slot2]=lisa_wb_Ox6000_slot2;
	mem68k_store_word[Ox6000_slot2]=lisa_ww_Ox6000_slot2;
	mem68k_store_long[Ox6000_slot2]=lisa_wl_Ox6000_slot2;
                                  
	mem68k_memptr[    Ox8000_slot3]=lisa_mptr_Ox8000_slot3;
	mem68k_fetch_byte[Ox8000_slot3]=lisa_rb_Ox8000_slot3;
	mem68k_fetch_word[Ox8000_slot3]=lisa_rw_Ox8000_slot3;
	mem68k_fetch_long[Ox8000_slot3]=lisa_rl_Ox8000_slot3;
	mem68k_store_byte[Ox8000_slot3]=lisa_wb_Ox8000_slot3;
	mem68k_store_word[Ox8000_slot3]=lisa_ww_Ox8000_slot3;
	mem68k_store_long[Ox8000_slot3]=lisa_wl_Ox8000_slot3;
                                  
	mem68k_memptr[    Oxa000_slot3]=lisa_mptr_Oxa000_slot3;
	mem68k_fetch_byte[Oxa000_slot3]=lisa_rb_Oxa000_slot3;
	mem68k_fetch_word[Oxa000_slot3]=lisa_rw_Oxa000_slot3;
	mem68k_fetch_long[Oxa000_slot3]=lisa_rl_Oxa000_slot3;
	mem68k_store_byte[Oxa000_slot3]=lisa_wb_Oxa000_slot3;
	mem68k_store_word[Oxa000_slot3]=lisa_ww_Oxa000_slot3;
	mem68k_store_long[Oxa000_slot3]=lisa_wl_Oxa000_slot3;

	mem68k_memptr[Oxc000_flopmem]=lisa_mptr_Oxc000_flopmem;
	mem68k_fetch_byte[Oxc000_flopmem]=lisa_rb_Oxc000_flopmem;
	mem68k_fetch_word[Oxc000_flopmem]=lisa_rw_Oxc000_flopmem;
	mem68k_fetch_long[Oxc000_flopmem]=lisa_rl_Oxc000_flopmem;
	mem68k_store_byte[Oxc000_flopmem]=lisa_wb_Oxc000_flopmem;
	mem68k_store_word[Oxc000_flopmem]=lisa_ww_Oxc000_flopmem;
	mem68k_store_long[Oxc000_flopmem]=lisa_wl_Oxc000_flopmem;

    mem68k_memptr[Oxd200_sccz8530]=lisa_mptr_Oxd200_sccz8530;
	mem68k_fetch_byte[Oxd200_sccz8530]=lisa_rb_Oxd200_sccz8530;
	mem68k_fetch_word[Oxd200_sccz8530]=lisa_rw_Oxd200_sccz8530;
	mem68k_fetch_long[Oxd200_sccz8530]=lisa_rl_Oxd200_sccz8530;
	mem68k_store_byte[Oxd200_sccz8530]=lisa_wb_Oxd200_sccz8530;
	mem68k_store_word[Oxd200_sccz8530]=lisa_ww_Oxd200_sccz8530;
	mem68k_store_long[Oxd200_sccz8530]=lisa_wl_Oxd200_sccz8530;

	mem68k_memptr[Oxd800_par_via2]=lisa_mptr_Oxd800_par_via2;
	mem68k_fetch_byte[Oxd800_par_via2]=lisa_rb_Oxd800_par_via2;
	mem68k_fetch_word[Oxd800_par_via2]=lisa_rw_Oxd800_par_via2;
	mem68k_fetch_long[Oxd800_par_via2]=lisa_rl_Oxd800_par_via2;
	mem68k_store_byte[Oxd800_par_via2]=lisa_wb_Oxd800_par_via2;
	mem68k_store_word[Oxd800_par_via2]=lisa_ww_Oxd800_par_via2;
	mem68k_store_long[Oxd800_par_via2]=lisa_wl_Oxd800_par_via2;

	mem68k_memptr[Oxdc00_cops_via1]=lisa_mptr_Oxdc00_cops_via1;
	mem68k_fetch_byte[Oxdc00_cops_via1]=lisa_rb_Oxdc00_cops_via1;
	mem68k_fetch_word[Oxdc00_cops_via1]=lisa_rw_Oxdc00_cops_via1;
	mem68k_fetch_long[Oxdc00_cops_via1]=lisa_rl_Oxdc00_cops_via1;
	mem68k_store_byte[Oxdc00_cops_via1]=lisa_wb_Oxdc00_cops_via1;
	mem68k_store_word[Oxdc00_cops_via1]=lisa_ww_Oxdc00_cops_via1;
	mem68k_store_long[Oxdc00_cops_via1]=lisa_wl_Oxdc00_cops_via1;

	mem68k_memptr[Oxe000_latches]=lisa_mptr_Oxe000_latches;
	mem68k_fetch_byte[Oxe000_latches]=lisa_rb_Oxe000_latches;
	mem68k_fetch_word[Oxe000_latches]=lisa_rw_Oxe000_latches;
	mem68k_fetch_long[Oxe000_latches]=lisa_rl_Oxe000_latches;
	mem68k_store_byte[Oxe000_latches]=lisa_wb_Oxe000_latches;
	mem68k_store_word[Oxe000_latches]=lisa_ww_Oxe000_latches;
	mem68k_store_long[Oxe000_latches]=lisa_wl_Oxe000_latches;

	mem68k_memptr[Oxe800_videlatch]=lisa_mptr_Oxe800_videlatch;
	mem68k_fetch_byte[Oxe800_videlatch]=lisa_rb_Oxe800_videlatch;
	mem68k_fetch_word[Oxe800_videlatch]=lisa_rw_Oxe800_videlatch;
	mem68k_fetch_long[Oxe800_videlatch]=lisa_rl_Oxe800_videlatch;
	mem68k_store_byte[Oxe800_videlatch]=lisa_wb_Oxe800_videlatch;
	mem68k_store_word[Oxe800_videlatch]=lisa_ww_Oxe800_videlatch;
	mem68k_store_long[Oxe800_videlatch]=lisa_wl_Oxe800_videlatch;

	mem68k_memptr[Oxf000_memerror]=lisa_mptr_Oxf000_memerror;
	mem68k_fetch_byte[Oxf000_memerror]=lisa_rb_Oxf000_memerror;
	mem68k_fetch_word[Oxf000_memerror]=lisa_rw_Oxf000_memerror;
	mem68k_fetch_long[Oxf000_memerror]=lisa_rl_Oxf000_memerror;
	mem68k_store_byte[Oxf000_memerror]=lisa_wb_Oxf000_memerror;
	mem68k_store_word[Oxf000_memerror]=lisa_ww_Oxf000_memerror;
	mem68k_store_long[Oxf000_memerror]=lisa_wl_Oxf000_memerror;

	mem68k_memptr[Oxf800_statreg]=lisa_mptr_Oxf800_statreg;
	mem68k_fetch_byte[Oxf800_statreg]=lisa_rb_Oxf800_statreg;
	mem68k_fetch_word[Oxf800_statreg]=lisa_rw_Oxf800_statreg;
	mem68k_fetch_long[Oxf800_statreg]=lisa_rl_Oxf800_statreg;
	mem68k_store_byte[Oxf800_statreg]=lisa_wb_Oxf800_statreg;
	mem68k_store_word[Oxf800_statreg]=lisa_ww_Oxf800_statreg;
	mem68k_store_long[Oxf800_statreg]=lisa_wl_Oxf800_statreg;

	mem68k_memptr[ram]=lisa_mptr_ram;
	mem68k_fetch_byte[ram]=lisa_rb_ram;
	mem68k_fetch_word[ram]=lisa_rw_ram;
	mem68k_fetch_long[ram]=lisa_rl_ram;
	mem68k_store_byte[ram]=lisa_wb_ram;
	mem68k_store_word[ram]=lisa_ww_ram;
	mem68k_store_long[ram]=lisa_wl_ram;

	mem68k_memptr[ro_violn]=lisa_mptr_ro_violn;
	mem68k_fetch_byte[ro_violn]=lisa_rb_ro_violn;
	mem68k_fetch_word[ro_violn]=lisa_rw_ro_violn;
	mem68k_fetch_long[ro_violn]=lisa_rl_ro_violn;
	mem68k_store_byte[ro_violn]=lisa_wb_ro_violn;
	mem68k_store_word[ro_violn]=lisa_ww_ro_violn;
	mem68k_store_long[ro_violn]=lisa_wl_ro_violn;

	mem68k_memptr[bad_page]=lisa_mptr_bad_page;
	mem68k_fetch_byte[bad_page]=lisa_rb_bad_page;
	mem68k_fetch_word[bad_page]=lisa_rw_bad_page;
	mem68k_fetch_long[bad_page]=lisa_rl_bad_page;
	mem68k_store_byte[bad_page]=lisa_wb_bad_page;
	mem68k_store_word[bad_page]=lisa_ww_bad_page;
	mem68k_store_long[bad_page]=lisa_wl_bad_page;

	mem68k_memptr[sio_rom]=lisa_mptr_sio_rom;
	mem68k_fetch_byte[sio_rom]=lisa_rb_sio_rom;
	mem68k_fetch_word[sio_rom]=lisa_rw_sio_rom;
	mem68k_fetch_long[sio_rom]=lisa_rl_sio_rom;
	mem68k_store_byte[sio_rom]=lisa_wb_sio_rom;
	mem68k_store_word[sio_rom]=lisa_ww_sio_rom;
	mem68k_store_long[sio_rom]=lisa_wl_sio_rom;

	mem68k_memptr[sio_mrg]=lisa_mptr_sio_mrg;
	mem68k_fetch_byte[sio_mrg]=lisa_rb_sio_mrg;
	mem68k_fetch_word[sio_mrg]=lisa_rw_sio_mrg;
	mem68k_fetch_long[sio_mrg]=lisa_rl_sio_mrg;
	mem68k_store_byte[sio_mrg]=lisa_wb_sio_mrg;
	mem68k_store_word[sio_mrg]=lisa_ww_sio_mrg;
	mem68k_store_long[sio_mrg]=lisa_wl_sio_mrg;

	mem68k_memptr[sio_mmu]=lisa_mptr_sio_mmu;
	mem68k_fetch_byte[sio_mmu]=lisa_rb_sio_mmu;
	mem68k_fetch_word[sio_mmu]=lisa_rw_sio_mmu;
	mem68k_fetch_long[sio_mmu]=lisa_rl_sio_mmu;
	mem68k_store_byte[sio_mmu]=lisa_wb_sio_mmu;
	mem68k_store_word[sio_mmu]=lisa_ww_sio_mmu;
	mem68k_store_long[sio_mmu]=lisa_wl_sio_mmu;

	mem68k_memptr[vidram]=lisa_mptr_vidram;
	mem68k_fetch_byte[vidram]=lisa_rb_vidram;
	mem68k_fetch_word[vidram]=lisa_rw_vidram;
	mem68k_fetch_long[vidram]=lisa_rl_vidram;
	mem68k_store_byte[vidram]=lisa_wb_vidram;
	mem68k_store_word[vidram]=lisa_ww_vidram;
	mem68k_store_long[vidram]=lisa_wl_vidram;

	mem68k_memptr[io]=lisa_mptr_io;
	mem68k_fetch_byte[io]=lisa_rb_io;
	mem68k_fetch_word[io]=lisa_rw_io;
	mem68k_fetch_long[io]=lisa_rl_io;
	mem68k_store_byte[io]=lisa_wb_io;
	mem68k_store_word[io]=lisa_ww_io;
	mem68k_store_long[io]=lisa_wl_io;


    mem68k_memptr[Oxd400_amd9512]=lisa_mptr_Oxd400_amd9512;
    mem68k_fetch_byte[Oxd400_amd9512]=lisa_rb_Oxd400_amd9512;
    mem68k_fetch_word[Oxd400_amd9512]=lisa_rw_Oxd400_amd9512;
    mem68k_fetch_long[Oxd400_amd9512]=lisa_rl_Oxd400_amd9512;
    mem68k_store_byte[Oxd400_amd9512]=lisa_wb_Oxd400_amd9512;
    mem68k_store_word[Oxd400_amd9512]=lisa_ww_Oxd400_amd9512;
    mem68k_store_long[Oxd400_amd9512]=lisa_wl_Oxd400_amd9512;

        mem68k_memptr[Oxd000_ff_space]=lisa_mptr_Oxd000_ff_space;
    mem68k_fetch_byte[Oxd000_ff_space]=lisa_rb_Oxd000_ff_space;
    mem68k_fetch_word[Oxd000_ff_space]=lisa_rw_Oxd000_ff_space;
    mem68k_fetch_long[Oxd000_ff_space]=lisa_rl_Oxd000_ff_space;
    mem68k_store_byte[Oxd000_ff_space]=lisa_wb_Oxd000_ff_space;
    mem68k_store_word[Oxd000_ff_space]=lisa_ww_Oxd000_ff_space;
    mem68k_store_long[Oxd000_ff_space]=lisa_wl_Oxd000_ff_space;

    mem68k_memptr[OxVoid]=lisa_mptr_OxVoid;
    mem68k_fetch_byte[OxVoid]=lisa_rb_OxVoid;
    mem68k_fetch_word[OxVoid]=lisa_rw_OxVoid;
    mem68k_fetch_long[OxVoid]=lisa_rl_OxVoid;
    mem68k_store_byte[OxVoid]=lisa_wb_OxVoid;
    mem68k_store_word[OxVoid]=lisa_ww_OxVoid;
    mem68k_store_long[OxVoid]=lisa_wl_OxVoid;

    DEBUG_LOG(0,"mmu_trans_all: %p mmu_all: %p",mmu_trans_all,mmu_all);
    segment1=0; segment2=0; start=1; mmuflush(0);

    mmu0_checksum=get_mmu0_chk();

    DEBUG_LOG(0,"mmu_trans_all: %p mmu_all: %p",mmu_trans_all,mmu_all);
}
Пример #4
0
void
kforkexecac(Proc *p, int core, char *ufile, char **argv)
{
	Mach *m = machp();
	Khdr hdr;
	Tos *tos;
	Chan *chan;
	int argc, i, n, sno;
	char *a, *elem, *file, *args;
	int32_t hdrsz, magic, textsz, datasz, bsssz;
	uintptr_t textlim, datalim, bsslim, entry, tbase, tsize, dbase, dsize, bbase, bsize, sbase, ssize, stack;
	Mach *mp;
	//	static Pgrp *kpgrp;

	panic("kexec not done\n");
	// XXX: since this is kernel code we can't do attachimage,
	// we should be reading the file into kernel memory.
	// this only matters if we are using ufile.
	// YYY: look at dev reboot for help.

	file = nil;
	elem = nil;
	chan = nil;
	mp = nil;

	USED(chan);

	if(waserror()){
		DBG("kforkexecac: failing: %s\n", m->externup->errstr);
		if(file)
			free(file);
		if(elem)
			free(elem);
		if(chan)
			cclose(chan);
		if(core > 0 && mp != nil)
			mp->proc = nil;
		if(core != 0)
			p->ac = nil;
		nexterror();
	}

	if(core != 0)
		p->ac = getac(p, core);

	argc = 0;
	if(ufile != nil){
		panic("ufile not implemented yet");
		file = validnamedup(ufile, 1);
		DBG("kforkexecac: up %#p file %s\n", m->externup, file);
		chan = namec(file, Aopen, OEXEC, 0);
		kstrdup(&elem, m->externup->genbuf);

		hdrsz = chan->dev->read(chan, &hdr, sizeof(Khdr), 0);
		DBG("wrote ufile\n");

		if(hdrsz < 2)
			error(Ebadexec);
	}else{
		/* somebody already wrote in our text segment */
		for(sno = 0; sno < NSEG; sno++)
			if(p->seg[sno] != nil)
				if((p->seg[sno]->type & SG_EXEC) != 0)
					break;
		if(sno == NSEG)
			error("kforkexecac: no text segment!");
		hdr = *(Khdr*)p->seg[sno]->base;
		hdrsz = sizeof(Khdr);
	}

//	p = (char*)&hdr;
	magic = l2be(hdr.magic);
	DBG("badexec3\n");

	if(hdrsz != sizeof(Khdr) || magic != AOUT_MAGIC)
		error(Ebadexec);
	if(magic & HDR_MAGIC){
		entry = vl2be(hdr.hdr[0]);
		hdrsz = sizeof(Khdr);
	}
	else{
		entry = l2be(hdr.entry);
		hdrsz = sizeof(Exec);
	}

	textsz = l2be(hdr.text);
	datasz = l2be(hdr.data);
	bsssz = l2be(hdr.bss);

	panic("aki broke it before it even got working.");
/* TODO(aki): figure out what to do with this.
	tbase = p->seg[TSEG]->base;
	tsize = tbase - p->seg[TSEG]->top;
	dbase = p->seg[DSEG]->base;
	dsize = dbase - p->seg[DSEG]->top;
	bbase = p->seg[BSEG]->base;
	bsize = bbase - p->seg[BSEG]->top;
	sbase = p->seg[SSEG]->base;
	ssize = sbase - p->seg[SSEG]->top;
*/

	// XXX: we are no longer contiguous.
	textlim = ROUNDUP(hdrsz+textsz, BIGPGSZ);
	// XXX: we are going to be at least two pages here.
	datalim = BIGPGROUND(datasz);
	bsslim = BIGPGROUND(datalim+bsssz);

	// XXX: this is pretty fragile
	memmove((void*)dbase, (void*)(entry+textsz), datasz);
	DBG("writing data dbase %#p tbase %#p textsz %ld datasz %ld\n", dbase, tbase, textsz, datasz);
//	memmove((void*)dbase, (void*)"testing data", 13);
	/*
	 * Check the binary header for consistency,
	 * e.g. the entry point is within the text segment and
	 * the segments don't overlap each other.
	 */
	// XXX: max instruction size on amd64 is 15 bytes provide a check for consistency.
	DBG("kexec: entry %#p tbase %#p hdrsz %ld  textsz %ld\n", entry, tbase, hdrsz, textsz);
	if(entry < tbase+hdrsz || entry >= tbase+hdrsz+textsz)
		error(Ebadexec);
	// XXX: what about the kernel stack we are making here?
	DBG("kexec: testing if sizes overflow limits\n");
	if(textsz >= textlim || datasz > datalim || bsssz > bsslim)
		error(Ebadexec);
	DBG("kexec: do the top of the segments overflow limits?\n");
	if(textlim >= tbase+tsize || datalim >= dbase+dsize || bsslim >= bbase+bsize)
		error(Ebadexec);

	DBG("kexec: is bss below data?\n");
	if(bsslim < datalim)
		error(Ebadexec);
	/*
	Interesting thought, the previously allocated segments for
	data and text are shared and constant.  The BSS and the stack
	are not.  What you really want is the ability to make an
	executable text and data and then create child executables on
	top of that.  This will lower external fragmentation and allow
	a bunch of communicating shared memory processes (ie.  go) in
	kernel space.

	Fundamentally this means that the allocation of the text and
	the data should be separate from the bss and the stack.  This
	will require that you change the linkers as well to allow the
	separation of data and bss sections.
	*/

	/*
	 * Stack is a pointer into the temporary stack
	 * segment, and will move as items are pushed.
	 */

	 // need to work something out here with the stack.
	stack = sbase+ssize-sizeof(Tos);


	 /*
	  * XXX: When we are linking this how do we set the tos? We will need to change trap right?
	  */
	tos = (Tos*)stack;
	tos->cyclefreq = m->cyclefreq;
	cycles((uint64_t*)&tos->pcycles);
	tos->pcycles = -tos->pcycles;
	tos->kcycles = tos->pcycles;
	tos->clock = 0;

	DBG("kexec: argument processing\n");
	if(0)
	for(i = 0;; i++, argv++){
		a = *(char**)validaddr(argv, sizeof(char**), 0);
		if(a == nil)
			break;
		a = validaddr(a, 1, 0);
		n = ((char*)vmemchr(a, 0, 0x7fffffff) - a) + 1;

		if(argc > 0 && i == 0)
			continue;

		stack -= n;
		if(stack < sbase+ssize-4096)
			error(Enovmem);
		args = UINT2PTR(stack);
		memmove(args, a, n);
		args[n-1] = 0;
		argc++;
	}
	// DBG("kexec: ensuring we have argc\n");
	if(0)
	if(argc < 1)
		error(Ebadexec);

	a = args = UINT2PTR(stack);
	stack = sysexecstack(stack, argc);
	// XXX: look through math on this. look at ../../9/port/ exec.c
	// YYY: this looks like a Jimism for 9k.
	// DBG("kexec: ensuring the stack \n");
	if(0)
	if(stack-(argc+1)*sizeof(char**)-BIGPGSZ < sbase+ssize-4096)
		error(Ebadexec);

	argv = (char**)stack;
	*--argv = nil;
	// XXX: replace USTKTOP with a new variable representing the top of stack.
	if(0)
	for(i = 0; i < argc; i++){
		*--argv = args + (USTKTOP-sbase+ssize);
		args += strlen(args) + 1;
	}

	DBG("argsing\n");
	n = args - a;
	if(0)
	if(n <= 0)
		error(Egreg);
	if(n > 128)
		n = 128;
	DBG("kexec: allocating args\n");
	// XXX: hangs in smalloc, not sure why.
//	args = smalloc(n);
//	if(waserror()){
//		DBG("erroring\n");
//		free(args);
//		nexterror();
//	}
//	DBG("kexec: moving args\n");
//	memmove(args, a, n);
//	if(0)
//	while(n > 0 && (args[n-1] & 0xc0) == 0x80)
//		n--;
//	args[n-1] = '\0';

	kstrdup(&p->text, "kexecproc");
	p->args = nil;
	//elem;
//	elem = nil;
//	p->args = args;
//	p->nargs = n;
	poperror();				/* p (m->externup->args) */





/*
	qlock(&p->debug);

	sysprocsetup(p);
	qunlock(&p->debug);
*/

	// why is this sched and not ureg?
	p->sched.pc = entry;
	// the real question here is how do you set up the stack?
	p->sched.sp = PTR2UINT(stack-BY2SE);
	p->sched.sp = STACKALIGN(p->sched.sp);


	// XXX: what does it imply if you have a kproc that runs on an ac?
	if(core > 0){
		DBG("kexec: coring %d\n", core);
		mp = p->ac;
		mp->icc->flushtlb = 1;
		mp->icc->rc = ICCOK;

		DBG("kexec: exotic proc on cpu%d\n", mp->machno);
		qlock(&p->debug);
		if(waserror()){
			DBG("kexec: had error");
			qunlock(&p->debug);
			nexterror();
		}
		p->nicc++;
		p->state = Exotic;
		p->psstate = 0;
		DBG("kexec: unlocking");
		qunlock(&p->debug);
		poperror();
		mfence();
		mp->icc->fn = (void*)entry;
		sched();
	}else{
		DBG("kexec: readying\n");
		ready(p);
		p->newtlb = 1;
		mmuflush();
	}
	DBG("kforkexecac up %#p done\n"
		"textsz %lx datasz %lx bsssz %lx hdrsz %lx\n"
		"textlim %ullx datalim %ullx bsslim %ullx\n", m->externup,
		textsz, datasz, bsssz, hdrsz, textlim, datalim, bsslim);
}