Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include	"u.h"
2
#include	"../port/lib.h"
3
#include	"mem.h"
4
#include	"dat.h"
5
#include	"fns.h"
6
#include	"io.h"
7
#include	"ureg.h"
8
#include	"../port/error.h"
9
 
10
/*
11
 * Back the processor into real mode to run a BIOS call,
12
 * then return.  This must be used carefully, since it 
13
 * completely disables hardware interrupts (e.g., the i8259)
14
 * while running.  It is *not* using VM86 mode. 
15
 * Maybe that's really the right answer, but real mode
16
 * is fine for now.  We don't expect to use this very much --
17
 * just for BIOS INT 13 disk i/o.
18
 */
19
 
20
void realmode0(void);		/* in realmode0.s */
21
void realmodeintrinst(void);	/* in realmode0.s */
22
void realmodeend(void);		/* in realmode0.s */
23
 
24
extern ushort rmseg;		/* in realmode0.s */
25
 
26
static Ureg rmu;
27
static QLock rmlock;
28
static int beenhere;
29
 
30
void
31
realmode(Ureg *ureg)
32
{
33
	int s, sz;
34
	ulong cr3;
35
	uchar *ip;
36
 
37
	qlock(&rmlock);
38
	if (!beenhere)
39
		iprint("into bios in real mode...");
40
	*(Ureg *)RMUADDR = *ureg;
41
 
42
	/*
43
	 * in pxe-loaded bootstraps, the l.s real-mode code is already
44
	 * below 64K, but for pbs-loaded bootstraps, we need to copy it there.
45
	 */
46
	ip = (void *)realmodeintrinst;		/* the INT instruction */
47
	ip[1] = ureg->trap;			/* insert INT number */
48
	coherence();
49
	if ((uintptr)KTZERO == KZERO+PXEBASE)	/* pxe-loaded? */
50
		rmseg = 0;			/* into JMPFAR instr. */
51
	else {
52
		/* copy l.s so that it can be run from 16-bit mode */
53
		sz = (char *)realmodeend - (char *)KTZERO;
54
		if (sz > RMSIZE)
55
			panic("real mode code %d bytes > %d", sz, RMSIZE);
56
		rmseg = (RMCODE - KZERO) >> 4;	/* into JMPFAR instr. */
57
		memmove((void*)RMCODE, (void*)KTZERO, sz);
58
	}
59
	coherence();
60
 
61
	s = splhi();
62
	m->pdb[PDX(0)] = m->pdb[PDX(KZERO)];	/* identity map low */
63
	cr3 = getcr3();
64
	putcr3(PADDR(m->pdb));
65
	if (arch)
66
		arch->introff();
67
	else
68
		i8259off();
69
 
70
	realmode0();
71
	splhi();				/* who knows what the bios did */
72
 
73
	if(m->tss){
74
		/*
75
		 * Called from memory.c before initialization of mmu.
76
		 * Don't turn interrupts on before the kernel is ready!
77
		 */
78
		if (arch)
79
			arch->intron();
80
		else
81
			i8259on();
82
	}
83
	m->pdb[PDX(0)] = 0;	/* remove low mapping */
84
	putcr3(cr3);
85
	splx(s);
86
 
87
	*ureg = *(Ureg *)RMUADDR;
88
	if (!beenhere) {
89
		beenhere = 1;
90
		iprint("and back\n");
91
	}
92
	qunlock(&rmlock);
93
}