extern int _bss, _bssend, _end;
+static unsigned long curmapped = 0xFFFFFFFF;
+
unsigned long v2p(void *virt)
{
unsigned long _virt = (unsigned long)virt;
return _virt;
if (_virt >= 0x200000 && _virt < 0x300000)
return _virt - 0x200000 + /* XXX */ 0x1FF82000;
+ if (_virt >= 0x1F0000 && _virt < 0x1F2000)
+ return _virt - 0x1F0000 + 0x1FF80000;
+ if ((_virt & ~0xFFF) == 0x4000)
+ return _virt - 0x4000 + curmapped;
+
outputf("WARNING: v2p(%08x)", _virt);
return 0xFFFFFFFF;
}
if (phys >= 0xA0000 && phys < 0xC0000)
return (void*)phys;
- if (phys >= 0x1FF80000 && phys < 0x20000000)
+ if (phys >= 0x1FF82000 && phys < 0x20000000)
return (void*)(phys - 0x1FF82000 + 0x200000);
- outputf("WARNING: p2v(%08x)", phys);
- return (void *)0xFFFFFFFF;
+ if (phys >= 0x1FF80000 && phys < 0x1FF82000)
+ return (void*)(phys - 0x1FF80000 + 0x1F0000);
+
+ if ((phys & ~0xFFF) != curmapped) /* If it's not mapped, map it in. */
+ {
+ curmapped = phys & ~0xFFF;
+ addmap(0x4000, curmapped);
+ asm volatile("invlpg 0x4000");
+ }
+ return (void*)(0x4000 + (phys & 0xFFF));
}
-
-inline int pt_addmap(unsigned long *pd, unsigned long vaddr, unsigned long paddr)
+int addmap(unsigned long vaddr, unsigned long paddr)
{
unsigned long pde = ((unsigned long *)p2v((unsigned long)pd))[PDE_FOR(vaddr)];
unsigned long *pt;
return 0;
}
-static void * pt_setup(int tseg_start, int tseg_size) {
+void *demap(unsigned long client_pd, unsigned long vaddr)
+{
+ unsigned long pde = ((unsigned long *)p2v(client_pd))[PDE_FOR(vaddr)];
+ unsigned long pte;
+
+ if (!(pde & PTE_PRESENT))
+ return (void*)0x0;
+ pte = ((unsigned long *)p2v(ADDR_12_MASK(pde)))[PTE_FOR(vaddr)];
+ if (!(pte & PTE_PRESENT))
+ return (void*)0x0;
+ return p2v((pte & ~0xFFF) + (vaddr & 0xFFF));
+}
+
+static void pt_setup(int tseg_start, int tseg_size) {
int i;
/* The page directory and page table live at TSEG and TSEG + 0x1000,
* respectively. */
unsigned long *pagedirectory = (unsigned long *) tseg_start;
unsigned long *pagetable = (unsigned long *) (tseg_start + 0x1000);
+
+ pd = pagedirectory;
/* Clear out the page directory except for one entry pointing to the
* page table, and clear the page table entirely. */
/* Map 0x0A0000:0x0BFFFF to itself. */
for (i = 0; i < 32; i++)
- pt_addmap(pagedirectory, 0xA0000 + i * 0x1000, 0xA0000 + i * 0x1000);
+ addmap(0xA0000 + i * 0x1000, 0xA0000 + i * 0x1000);
- /* Map 0x200000:0x300000 to TSEG */
+ /* Map 0x200000:0x300000 to TSEG data */
for (i = 0; i < 256; i++)
- pt_addmap(pagedirectory, 0x200000 + i * 0x1000, tseg_start + 0x2000 + i * 0x1000);
+ addmap(0x200000 + i * 0x1000, tseg_start + (i + 2) * 0x1000);
/* Map 0x300000:0x400000 to 0x200000, so we can copy our code out of
* RAM the first time around */
for (i = 0; i < 256; i++)
- pt_addmap(pagedirectory, 0x300000 + i * 0x1000, 0x200000 + i * 0x1000);
+ addmap(0x300000 + i * 0x1000, 0x200000 + i * 0x1000);
- return pagedirectory;
+ /* Map 0x1F0000:0x1F2000 to TSEG paging info */
+ for (i = 0; i < 2; i++)
+ addmap(0x1F0000 + i * 0x1000, tseg_start + i * 0x1000);
}
void c_entry(void)
outb(0x80, 0x01);
if (!initialized)
- pd = pt_setup(0x1FF80000, 0x80000);
+ pt_setup(0x1FF80000, 0x80000);
outb(0x80, 0x02);
/* Enable paging. */
#include "fsdata.h"
#include "fsdata.c"
#include <io.h>
+#include <minilib.h>
+#include <paging.h>
+#include <output.h>
/*-----------------------------------------------------------------------------------*/
file->len = strlen(buf)-1;
}
+void handle_backtrace(struct fs_file *file)
+{
+ static unsigned char buf[2048];
+ static unsigned char buf2[64];
+ int i = 10;
+ unsigned long *pebp, *peip;
+ unsigned long ebp;
+ unsigned long cr3;
+
+ strcpy(buf, "<html><head><title>Backtrace</title></head><body><tt><pre>");
+ ebp = *(unsigned long *)0xAFFE4;
+ cr3 = *(unsigned long *)0xAFFF8;
+
+ sprintf(buf2, "0x%08x, from\n", *(unsigned long*)0xAFFF0);
+ strcat(buf, buf2);
+
+ /* I never thought I'd do this again. */
+ while ((peip = demap(cr3, ebp+4)) != 0x0 && i--)
+ {
+ sprintf(buf2, "0x%08x, from\n", *peip);
+ strcat(buf, buf2);
+ pebp = demap(cr3, ebp);
+ if (!pebp)
+ {
+ strcat(buf, "<unreadable %ebp>\n");
+ break;
+ }
+ if (ebp >= *pebp && *pebp)
+ {
+ strcat(buf, "<recursive %ebp>\n");
+ break;
+ }
+ ebp = *pebp;
+ }
+ if (i == -1)
+ strcat(buf, "...\n");
+ else
+ strcat(buf, "<root>");
+ strcat(buf, "</pre></tt></body></html>");
+
+ file->data = buf;
+ file->len = strlen(buf)-1;
+}
+
void handle_reboot(struct fs_file *file)
{
outb(0xCF9, 0x4);
handle_regs(file);
return 1;
}
+ if (!strcmp(name, "/backtrace.html"))
+ {
+ handle_backtrace(file);
+ return 1;
+ }
if (!strcmp(name, "/reboot"))
{
handle_reboot(file);
static const unsigned char data_index_html[] =
"<html><head><title>NetWatch</title></head>"
- "<body><h1>NetWatch</h1><iframe src=\"registers.html\" height=100 width=600></iframe><form action=reboot type=post><input type=submit value=\"Reboot!\"></form></body>"
- "</html>";
+ "<body><h1>NetWatch</h1>"
+ "<iframe src=\"registers.html\" height=100 width=600></iframe><br>"
+ "<iframe src=\"backtrace.html\" height=250 width=150></iframe>"
+ "<form action=reboot type=post><input type=submit value=\"Reboot!\"></form>"
+ "</body></html>";
const struct fsdata_file file_404_html[] = {{NULL, "/404.html", data_404_html, sizeof(data_404_html)}};
const struct fsdata_file file_index_html[] = {{file_404_html, "/index.html", data_index_html, sizeof(data_index_html)}};