]> Joshua Wise's Git repositories - netwatch.git/blame_incremental - aseg-paging/pagingstub.c
Hit paging to clean it up a bit. Add a reboot button.
[netwatch.git] / aseg-paging / pagingstub.c
... / ...
CommitLineData
1#include <io.h>
2#include <smram.h>
3#include <video_defines.h>
4#include <minilib.h>
5#include <smi.h>
6#include <pci-bother.h>
7#include <serial.h>
8#include <output.h>
9#include "traps.h"
10#include "../net/net.h"
11#include "vga-overlay.h"
12
13extern void smi_init();
14#include "vm_flags.h"
15
16extern void smi_entry();
17void set_cr0(unsigned int);
18void ps_switch_stack (void (*call)(), int stack);
19
20#define get_cr0() \
21 ({ \
22 register unsigned int _temp__; \
23 asm volatile("mov %%cr0, %0" : "=r" (_temp__)); \
24 _temp__; \
25 })
26
27
28#define set_cr3(value) \
29 { \
30 register unsigned int _temp__ = (value); \
31 asm volatile("mov %0, %%cr3" : : "r" (_temp__)); \
32 }
33#define CR0_PG 0x80000000
34
35#define MAP_FLAGS (PTE_PRESENT | PTE_READ_WRITE)
36
37static int initialized = 0;
38static int paging_enb = 0;
39static unsigned long *pd;
40
41extern int _bss, _bssend, _end;
42
43unsigned long v2p(void *virt)
44{
45 unsigned long _virt = (unsigned long)virt;
46
47 if (!paging_enb)
48 return _virt;
49
50 if (_virt >= 0xA0000 && _virt < 0xC0000)
51 return _virt;
52 if (_virt >= 0x200000 && _virt < 0x300000)
53 return _virt - 0x200000 + /* XXX */ 0x1FF82000;
54 outputf("WARNING: v2p(%08x)", _virt);
55 return 0xFFFFFFFF;
56}
57
58void *p2v(unsigned long phys)
59{
60 if (!paging_enb)
61 return (void*)phys;
62
63 if (phys >= 0xA0000 && phys < 0xC0000)
64 return (void*)phys;
65 if (phys >= 0x1FF80000 && phys < 0x20000000)
66 return (void*)(phys - 0x1FF82000 + 0x200000);
67 outputf("WARNING: p2v(%08x)", phys);
68 return (void *)0xFFFFFFFF;
69}
70
71
72inline int pt_addmap(unsigned long *pd, unsigned long vaddr, unsigned long paddr)
73{
74 unsigned long pde = ((unsigned long *)p2v((unsigned long)pd))[PDE_FOR(vaddr)];
75 unsigned long *pt;
76
77 if (!(pde & PTE_PRESENT))
78 return -1;
79
80 pt = (unsigned long *)p2v(ADDR_12_MASK(pde));
81 pt[PTE_FOR(vaddr)] = paddr | PTE_PRESENT | PTE_READ_WRITE;
82
83 return 0;
84}
85
86static void * pt_setup(int tseg_start, int tseg_size) {
87 int i;
88
89 /* The page directory and page table live at TSEG and TSEG + 0x1000,
90 * respectively. */
91 unsigned long *pagedirectory = (unsigned long *) tseg_start;
92 unsigned long *pagetable = (unsigned long *) (tseg_start + 0x1000);
93
94 /* Clear out the page directory except for one entry pointing to the
95 * page table, and clear the page table entirely. */
96 pagedirectory[0] = (tseg_start + 0x1000) | PTE_PRESENT | PTE_READ_WRITE;
97 for (i = 1; i < 1024; i++)
98 pagedirectory[i] = 0;
99
100 for (i = 0; i < 1024; i++)
101 pagetable[i] = 0;
102
103 /* Map 0x0A0000:0x0BFFFF to itself. */
104 for (i = 0; i < 32; i++)
105 pt_addmap(pagedirectory, 0xA0000 + i * 0x1000, 0xA0000 + i * 0x1000);
106
107 /* Map 0x200000:0x300000 to TSEG */
108 for (i = 0; i < 256; i++)
109 pt_addmap(pagedirectory, 0x200000 + i * 0x1000, tseg_start + 0x2000 + i * 0x1000);
110
111 /* Map 0x300000:0x400000 to 0x200000, so we can copy our code out of
112 * RAM the first time around */
113 for (i = 0; i < 256; i++)
114 pt_addmap(pagedirectory, 0x300000 + i * 0x1000, 0x200000 + i * 0x1000);
115
116 return pagedirectory;
117}
118
119void c_entry(void)
120{
121 paging_enb = 0;
122
123 outb(0x80, 0x01);
124 if (!initialized)
125 pd = pt_setup(0x1FF80000, 0x80000);
126 outb(0x80, 0x02);
127
128 /* Enable paging. */
129 set_cr3((unsigned long)pd);
130 set_cr0(get_cr0() | CR0_PG);
131 outb(0x80, 0x03);
132 paging_enb = 1;
133
134 /* If this is the first goround, copy in data. */
135 if (!initialized)
136 {
137 unsigned char *p;
138
139 outb(0x80, 0x04);
140 for (p = (void *)0x200000; (void *)p < (void *)&_bss; p++)
141 *p = *(p + 0x100000);
142 for (p = (void *)&_bss; (void *)p < (void *)&_bssend; p++)
143 *p = 0;
144 outb(0x80, 0x05);
145
146 /* Only now is it safe to call other functions. */
147 serial_init();
148 dolog("Evacuation to TSEG complete.");
149 }
150
151 outb(0x80, 0x06);
152
153 traps_install();
154
155 outb(0x80, 0x07);
156
157 if (!initialized)
158 {
159 smi_init(); /* Run the firstrun. */
160 outb(0x80, 0x08);
161
162 initialized = 1;
163 }
164
165 outb(0x80, 0x09);
166 ps_switch_stack(smi_entry, 0x270000);
167 outb(0x80, 0xFA);
168}
This page took 0.024049 seconds and 4 git commands to generate.