]> Joshua Wise's Git repositories - netwatch.git/blame - aseg-paging/pagingstub.c
Hit paging to clean it up a bit. Add a reboot button.
[netwatch.git] / aseg-paging / pagingstub.c
CommitLineData
9e2a82e4
JP
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>
e68cc768 7#include <serial.h>
923ea2c2 8#include <output.h>
ed22a699 9#include "traps.h"
9e2a82e4
JP
10#include "../net/net.h"
11#include "vga-overlay.h"
12
722e5aea 13extern void smi_init();
9e2a82e4 14#include "vm_flags.h"
9e2a82e4 15
923ea2c2 16extern void smi_entry();
9e2a82e4 17void set_cr0(unsigned int);
b908495a 18void ps_switch_stack (void (*call)(), int stack);
9e2a82e4 19
9e2a82e4
JP
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
923ea2c2
JW
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) {
9e2a82e4 87 int i;
9e2a82e4 88
923ea2c2
JW
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);
9e2a82e4
JP
93
94 /* Clear out the page directory except for one entry pointing to the
95 * page table, and clear the page table entirely. */
b908495a 96 pagedirectory[0] = (tseg_start + 0x1000) | PTE_PRESENT | PTE_READ_WRITE;
9e2a82e4 97 for (i = 1; i < 1024; i++)
9e2a82e4 98 pagedirectory[i] = 0;
9e2a82e4 99
9e2a82e4 100 for (i = 0; i < 1024; i++)
9e2a82e4 101 pagetable[i] = 0;
9e2a82e4 102
923ea2c2
JW
103 /* Map 0x0A0000:0x0BFFFF to itself. */
104 for (i = 0; i < 32; i++)
105 pt_addmap(pagedirectory, 0xA0000 + i * 0x1000, 0xA0000 + i * 0x1000);
9e2a82e4 106
923ea2c2
JW
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);
9e2a82e4 110
923ea2c2 111 /* Map 0x300000:0x400000 to 0x200000, so we can copy our code out of
9e2a82e4 112 * RAM the first time around */
923ea2c2
JW
113 for (i = 0; i < 256; i++)
114 pt_addmap(pagedirectory, 0x300000 + i * 0x1000, 0x200000 + i * 0x1000);
9e2a82e4 115
9e2a82e4
JP
116 return pagedirectory;
117}
118
119void c_entry(void)
120{
923ea2c2 121 paging_enb = 0;
9e2a82e4 122
923ea2c2
JW
123 outb(0x80, 0x01);
124 if (!initialized)
125 pd = pt_setup(0x1FF80000, 0x80000);
126 outb(0x80, 0x02);
113df320
JW
127
128 /* Enable paging. */
923ea2c2 129 set_cr3((unsigned long)pd);
9e2a82e4 130 set_cr0(get_cr0() | CR0_PG);
923ea2c2
JW
131 outb(0x80, 0x03);
132 paging_enb = 1;
ed22a699 133
923ea2c2
JW
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);
113df320 145
923ea2c2 146 /* Only now is it safe to call other functions. */
113df320 147 serial_init();
923ea2c2 148 dolog("Evacuation to TSEG complete.");
ed22a699 149 }
923ea2c2
JW
150
151 outb(0x80, 0x06);
ed22a699
JP
152
153 traps_install();
923ea2c2
JW
154
155 outb(0x80, 0x07);
ed22a699 156
923ea2c2
JW
157 if (!initialized)
158 {
159 smi_init(); /* Run the firstrun. */
160 outb(0x80, 0x08);
113df320 161
923ea2c2 162 initialized = 1;
9e2a82e4 163 }
923ea2c2
JW
164
165 outb(0x80, 0x09);
113df320 166 ps_switch_stack(smi_entry, 0x270000);
b908495a 167 outb(0x80, 0xFA);
9e2a82e4 168}
This page took 0.036965 seconds and 4 git commands to generate.