Plan 9 from Bell Labs’s /usr/web/sources/xen/xen2/9/xenpc/xensystem.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"io.h"

#include "../xen/xen.h"
/* 
 * The use of 'barrier' in the following reflects their use as local-lock
 * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
 * critical operations are executed. All critical operatiosn must complete
 * /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
 * includes these barriers, for example.
 */

#define LOG(a) 

extern shared_info_t *HYPERVISOR_shared_info;

void
xendie() {
	panic("xendie called\n");
}

int
ipending(void) {
	extern unsigned long upcallcount;
	dp("ipending: @0x%llx mask 0x%ux, pending 0x%ux, pending_sel 0x%ux\n", 
		HYPERVISOR_shared_info->system_time,
		HYPERVISOR_shared_info->evtchn_mask[0],
		HYPERVISOR_shared_info->evtchn_pending[0],
		HYPERVISOR_shared_info->evtchn_pending_sel);
			
	dp("ipending: vcpu same 0x%ux, 0x%ux upcallcount 0x%lux\n", 
		HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask,
		HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_pending, 
		upcallcount);	
	return HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_pending;
}

int XENCLI(void)
{
	unsigned long s = islo();
//	LOG(dp("XENCLI enter shared info is %p\n", HYPERVISOR_shared_info));
    HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
//	LOG(dp("XENCLI done\n"));
//	LOG(dp("splhi\n"));
	return s;
}

int XENSTI(void)
 {
	void evtchn_do_upcall(Ureg *regs);
	shared_info_t *_shared = HYPERVISOR_shared_info;
	unsigned long realpfn(void *va);
	int s = islo();
	
	do {
 		 _shared->vcpu_data[0].evtchn_upcall_mask = 0;

    		if (_shared->vcpu_data[0].evtchn_upcall_pending) {
			LOG(dp("S\n"));
        			evtchn_do_upcall(0);
			LOG(dp("s\n"));
		}
	} while (_shared->vcpu_data[0].evtchn_upcall_pending);
	LOG(dp("SS%x\n", _shared->evtchn_mask[0]));

	_shared->vcpu_data[0].evtchn_upcall_mask = 0;
/*	dp("spllo _shared %p mask val 0x%lx pfn 0x%lx\n", _shared, 
			_shared->vcpu_data[0].evtchn_upcall_mask, 
		realpfn(_shared)	);*/
	return s;
}

unsigned long
getcr0() {
	LOG(dp("GETCR0 ... return 0 ...\n"));
	return 0;
}

unsigned long
getcr1() {
	LOG(dp("GETCR1 ... return 0 ...\n"));
	return 0;
}

unsigned long
getcr2() {
	LOG(dp("GETCR2 ... return 0 ...\n"));
	return 0;
}

/*
unsigned long
getcr3() {
	LOG(dp("GETCR3 ... return 0 ...\n"));
	return 0;
}

*/
unsigned long
getcr4() {
	LOG(dp("GETCR4 ... return 0 ...\n"));
	return 0;
}


void
putcr4() {
	LOG(dp("putTCR4 ... NOOP ...\n"));
}


int islo(void) {
	int retval;
	shared_info_t *_shared = HYPERVISOR_shared_info;
	retval = (_shared->vcpu_data[0].evtchn_upcall_mask == 0) ? 0x200 : 0;
	return retval;
}

int
uartgetc(void) {
	return -1;
}

void fpoff(void){
	LOG(dp("fpoff. What to do?\n"));
}

void fpinit(void){
}

extern unsigned long *mfn;

/* this is called with the VIRTUAL address of the pdb */
void
putcr3(unsigned long *pnewcr3) {	unsigned long *newcr3 = pnewcr3;
	static unsigned long *prevcr3 = 0;
	unsigned long realpfn;
	LOG(dp("putcr3: cr3 %p\n", newcr3));
	realpfn = mfn[PADDR(newcr3)>>PGSHIFT] << PGSHIFT;
	LOG(dp("realpfn is 0x%ulx\n", realpfn));
	USED(realpfn);
	/* if it's the same one no need to pin it */
	/* also, special case: first one was pinned */
	if (prevcr3 && (newcr3 != prevcr3)) {
		LOG(dp("INVAL %p, realpfn 0x%ulx\n", newcr3, realpfn));
/*		HYPERVISOR_update_va_mapping(((unsigned long) newcr3)>>PGSHIFT,
		(realpfn)|PTEVALID|PTERONLY, UVMF_INVLPG);
 */
		LOG(dp("PIN %p\n", newcr3));
//		queue_pgd_pin((ulong *)realpfn);
		queue_pgd_pin(newcr3);
	}
	queue_pt_switch(PADDR(newcr3));
	if (prevcr3 && (newcr3 != prevcr3)) {
		LOG(dp("UNPIN 0x%ulx\n", prevcr3));
//		queue_pgd_unpin((ulong *)(mfn[PADDR(prevcr3)>>PGSHIFT]<<PGSHIFT));
		queue_pgd_unpin(prevcr3);
	}
	prevcr3 = newcr3;
	LOG(dp("done q pt sw\n"));
	queue_tlb_flush();
	_flush_page_update_queue();
	LOG(dp("done flush\n"));
}

#ifdef NOT_IN_GUEST
#define PROBLEM dp
int
inb(int port) {
	PROBLEM("inb 0x%x\n", port);
	return 0;
}

void
insb(int port, void *v, int count) {
	PROBLEM("insb");
}

ushort
ins(int port) {
	PROBLEM("ins");
	return 0;
}

void
inss(int port, void *v, int count) {
	PROBLEM("inss");
}

ulong
inl( int port) {
	PROBLEM("inl");
	return 0;
}

void
insl (int port, void *v, int count) {
	PROBLEM("insl");
}


void
outb(int port, int byte) {
	PROBLEM("outb 0x%x 0x%x\n", port, byte);
}

void
outsb(int port, void *v, int count) {
	PROBLEM("outsb");
}

void
outs(int port, ushort s) {
	PROBLEM("outs");
}

void
outss(int port, void *v, int count) {
	PROBLEM("outss");
}

void
outl(int port, ulong l) {
	PROBLEM("outl");
}

void
outsl(int port, void *v, int count) {
	PROBLEM("outsl");
}

#endif
uvlong
xenmicroseconds(uvlong */*hz*/) {
	dp("xenmicroseconds: current is 0x%ux\n", 
			HYPERVISOR_shared_info->wc_usec);
	return HYPERVISOR_shared_info->wc_usec;
}

void halt(void) {
	extern int nrdy;
	LOG(dp("halt: nrdy %d, islo %d\n", nrdy, islo()));
	if (nrdy)
		return;
//	spllo();
	/* This is supposed to be HYPERVISOR_block(). 
	 * the reason is that with the yield, it just goes to 
	 * other domains, and if they're not busy, comes right 
	 * back to you. With block it does what you really want:
	 * blocks until interrupt. I've tested this and it works
	 * well, let me know if it is trouble. -- RGM
	 * HYPERVISOR_yield();
	 */
	HYPERVISOR_block();
}

#ifdef NOTYET

#define __save_flags(x)
do {
    (x) = HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask;
} while (0)

#define __restore_flags(x)
do {
    shared_info_t *_shared = HYPERVISOR_shared_info;
    barrier();
    if ( (_shared->vcpu_data[0].evtchn_upcall_mask = x) == 0 ) {
        barrier(); /* unmask then check (avoid races) */
        if ( unlikely(_shared->vcpu_data[0].evtchn_upcall_pending) )
            evtchn_do_upcall(NULL);
    }
} while (0)

#define __save_and_cli(x)
do {
    (x) = HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask;
    HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
    barrier();
} while (0)

#define __save_and_sti(x)
do {
    shared_info_t *_shared = HYPERVISOR_shared_info;
    barrier();
    (x) = _shared->vcpu_data[0].evtchn_upcall_mask;
    _shared->vcpu_data[0].evtchn_upcall_mask = 0;
    barrier(); /* unmask then check (avoid races) */
    if ( unlikely(_shared->vcpu_data[0].evtchn_upcall_pending) )
        evtchn_do_upcall(NULL);
} while (0)


#endif

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].