iotest passed
This commit is contained in:
parent
4c5aa629d4
commit
850fb5e3c1
8
am/am.h
8
am/am.h
|
@ -84,12 +84,12 @@ void _intr_write(int enable);
|
|||
|
||||
// =================== Protection Extension (PTE) ====================
|
||||
|
||||
int _pte_init(void *(*pgalloc)(int npages), void (*pgfree)(void *));
|
||||
void _prot_create(_Protect *p);
|
||||
int _pte_init(void *(*pgalloc)(size_t npages), void (*pgfree)(void *));
|
||||
int _prot_create(_Protect *p);
|
||||
void _prot_destroy(_Protect *p);
|
||||
void _prot_switch(_Protect *p);
|
||||
void _map(_Protect *p, void *va, void *pa);
|
||||
void _protect(_Protect *p, void *va, int len, int prot);
|
||||
int _map(_Protect *p, void *va, void *pa);
|
||||
int _protect(_Protect *p, void *va, int len, int prot);
|
||||
_RegSet *_umake(_Protect *p, _Area ustack, _Area kstack,
|
||||
void (*entry)(void *), void *args);
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#ifndef __AM_X86_H__
|
||||
#define __AM_X86_H__
|
||||
|
||||
extern "C" {
|
||||
|
||||
void lapic_eoi();
|
||||
void lapic_init();
|
||||
void ioapic_init();
|
||||
|
@ -10,7 +8,5 @@ void lapic_bootap(int cpu, uint32_t address);
|
|||
void ioapic_enable(int irq, int cpu);
|
||||
void smp_init();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -3,11 +3,8 @@
|
|||
#include <am-x86.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
extern "C" { int printk(const char *, ...); }
|
||||
static _RegSet* (*H)(_Event, _RegSet*) = NULL;
|
||||
|
||||
static _RegSet* (*H)(_Event, _RegSet*) = nullptr;
|
||||
|
||||
extern "C" {
|
||||
void irq0();
|
||||
void irq1();
|
||||
void irq14();
|
||||
|
@ -29,9 +26,9 @@ void vec14();
|
|||
void vecsys();
|
||||
void irqall();
|
||||
|
||||
extern TSS tss[];
|
||||
extern struct TSS tss[];
|
||||
|
||||
void irq_handle(TrapFrame *tf) {
|
||||
void irq_handle(struct TrapFrame *tf) {
|
||||
_RegSet regs = {
|
||||
.eax = tf->eax, .ebx = tf->ebx, .ecx = tf->ecx, .edx = tf->edx,
|
||||
.esi = tf->esi, .edi = tf->edi, .ebp = tf->ebp, .esp3 = 0,
|
||||
|
@ -84,7 +81,7 @@ void irq_handle(TrapFrame *tf) {
|
|||
_RegSet *ret = ®s;
|
||||
if (H) {
|
||||
_RegSet *next = H(ev, ®s);
|
||||
if (next != nullptr) {
|
||||
if (next != NULL) {
|
||||
ret = next;
|
||||
}
|
||||
}
|
||||
|
@ -175,9 +172,6 @@ void irq_handle(TrapFrame *tf) {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int _asye_init(_RegSet*(*handler)(_Event, _RegSet*)) {
|
||||
static GateDesc idt[NR_IRQ];
|
||||
smp_init();
|
||||
|
@ -217,9 +211,9 @@ int _asye_init(_RegSet*(*handler)(_Event, _RegSet*)) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
_RegSet *_make(_Area stack, void *entry, void *arg) {
|
||||
_RegSet *_make(_Area stack, void (*entry)(void *), void *arg) {
|
||||
_RegSet *regs = (_RegSet*)stack.start;
|
||||
regs->esp0 = reinterpret_cast<uint32_t>(stack.end);
|
||||
regs->esp0 = (uint32_t)stack.end;
|
||||
regs->cs = KSEL(SEG_KCODE);
|
||||
regs->ds = regs->es = regs->ss = KSEL(SEG_KDATA);
|
||||
regs->eip = (uint32_t)entry;
|
|
@ -2,10 +2,6 @@
|
|||
#include <amdev.h>
|
||||
#include <x86.h>
|
||||
|
||||
extern "C" { int printf(const char *, ...); }
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern void vga_init();
|
||||
extern void timer_init();
|
||||
|
||||
|
@ -69,8 +65,8 @@ size_t timer_read(uintptr_t reg, void *buf, size_t size);
|
|||
size_t input_read(uintptr_t reg, void *buf, size_t size);
|
||||
|
||||
static _Device x86_dev[] = {
|
||||
{_DEV_INPUT, "8279 Keyboard Controller", input_read, nullptr},
|
||||
{_DEV_TIMER, "RDTSC Timer", timer_read, nullptr},
|
||||
{_DEV_INPUT, "8279 Keyboard Controller", input_read, NULL},
|
||||
{_DEV_TIMER, "RDTSC Timer", timer_read, NULL},
|
||||
{_DEV_VIDEO, "Standard VGA Controller", video_read, video_write},
|
||||
{_DEV_PCICONF, "PCI Configuration", pciconf_read, pciconf_write},
|
||||
{_DEV_ATA0, "ATA Disk Controller 0", hd_read, hd_write},
|
||||
|
@ -81,8 +77,6 @@ _Device *_device(int n) {
|
|||
if (n >= 0 && (unsigned int)n < sizeof(x86_dev) / sizeof(x86_dev[0])) {
|
||||
return &x86_dev[n];
|
||||
} else {
|
||||
return nullptr;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -2,9 +2,7 @@
|
|||
#include <x86.h>
|
||||
#include <am-x86.h>
|
||||
|
||||
extern "C" {
|
||||
int current_cpu();
|
||||
}
|
||||
int current_cpu();
|
||||
|
||||
#define MP_PROC 0x00
|
||||
|
||||
|
@ -97,10 +95,10 @@ int _mpe_init(void (*entry)()) {
|
|||
|
||||
for (int cpu = 1; cpu < numcpu; cpu ++) {
|
||||
*(uint16_t*)(0x7c00 + 510) = 0x55aa;
|
||||
*reinterpret_cast<uint32_t*>(0x7000) = 0x007c00ea; // code for ljmp
|
||||
*reinterpret_cast<uint32_t*>(0x7004) = 0x00000000;
|
||||
*(uint32_t*)(0x7000) = 0x007c00ea; // code for ljmp
|
||||
*(uint32_t*)(0x7004) = 0x00000000;
|
||||
*(void**)(0x7010) = (void*)mp_entry;
|
||||
*reinterpret_cast<uint32_t*>(0x7020) += 1024; // 1KB bootstrap stack
|
||||
*(uint32_t*)(0x7020) += 1024; // 1KB bootstrap stack
|
||||
lapic_bootap(cpu, 0x7000);
|
||||
while (_atomic_xchg(&ap_boot, 0) != 1);
|
||||
}
|
|
@ -3,11 +3,11 @@
|
|||
|
||||
#define PG_ALIGN __attribute((aligned(PGSIZE)))
|
||||
|
||||
TSS tss[MAX_CPU];
|
||||
struct TSS tss[MAX_CPU];
|
||||
SegDesc gdts[MAX_CPU][NR_SEG];
|
||||
PDE kpdir[NR_PDE] PG_ALIGN;
|
||||
PDE kptab[NR_PDE * NR_PTE] PG_ALIGN;
|
||||
void* (*palloc_f)();
|
||||
void* (*palloc_f)(size_t);
|
||||
void (*pfree_f)(void*);
|
||||
|
||||
_Area segments[] = { // Kernel memory mappings
|
||||
|
@ -15,7 +15,7 @@ _Area segments[] = { // Kernel memory mappings
|
|||
{.start = (void*)0xf0000000, .end = (void*)(0)}, // High memory: APIC and VGA
|
||||
};
|
||||
|
||||
int _pte_init(void* (*palloc)(), void (*pfree)(void*)) {
|
||||
int _pte_init(void* (*palloc)(size_t), void (*pfree)(void*)) {
|
||||
palloc_f = palloc;
|
||||
pfree_f = pfree;
|
||||
SegDesc *gdt = gdts[_cpu()];
|
||||
|
@ -24,14 +24,15 @@ int _pte_init(void* (*palloc)(), void (*pfree)(void*)) {
|
|||
gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, DPL_KERN);
|
||||
gdt[SEG_UCODE] = SEG(STA_X | STA_R, 0, 0xffffffff, DPL_USER);
|
||||
gdt[SEG_UDATA] = SEG(STA_W, 0, 0xffffffff, DPL_USER);
|
||||
gdt[SEG_TSS] = SEG16(STS_T32A, &tss[_cpu()], sizeof(TSS)-1, DPL_KERN);
|
||||
gdt[SEG_TSS] = SEG16(STS_T32A, &tss[_cpu()], sizeof(struct TSS)-1, DPL_KERN);
|
||||
set_gdt(gdt, sizeof(SegDesc) * NR_SEG);
|
||||
set_tr(KSEL(SEG_TSS));
|
||||
|
||||
PDE *alloc = kptab;
|
||||
for (auto &seg: segments) {
|
||||
PTE *ptab = nullptr;
|
||||
for (uint32_t pa = reinterpret_cast<uint32_t>(seg.start); pa != reinterpret_cast<uint32_t>(seg.end); pa += PGSIZE) {
|
||||
for (int i = 0; i < sizeof(segments) / sizeof(segments[0]); i++) {
|
||||
_Area *seg = &segments[i];
|
||||
PTE *ptab = NULL;
|
||||
for (uint32_t pa = (uint32_t)seg->start; pa != (uint32_t)seg->end; pa += PGSIZE) {
|
||||
if (!(kpdir[PDX(pa)] & PTE_P)) {
|
||||
ptab = alloc;
|
||||
alloc += NR_PDE;
|
||||
|
@ -46,8 +47,8 @@ int _pte_init(void* (*palloc)(), void (*pfree)(void*)) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void _protect(_Protect *p) {
|
||||
PDE *updir = (PDE*)(palloc_f());
|
||||
int _prot_create(_Protect *p) {
|
||||
PDE *updir = (PDE*)(palloc_f(1));
|
||||
p->ptr = updir;
|
||||
// map kernel space
|
||||
for (int i = 0; i < 1024; i ++)
|
||||
|
@ -56,9 +57,9 @@ void _protect(_Protect *p) {
|
|||
// exact copy of kernel page table
|
||||
// no user memory is mapped
|
||||
|
||||
p->area.start = reinterpret_cast<void*>(0x40000000);
|
||||
p->area.end = reinterpret_cast<void*>(0xc0000000);
|
||||
// return [ULOW, UHIGH)
|
||||
p->area.start = (void*)0x40000000;
|
||||
p->area.end = (void*)0xc0000000;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _release(_Protect *p) {
|
||||
|
@ -69,17 +70,18 @@ void _switch(_Protect *p) {
|
|||
set_cr3(p->ptr);
|
||||
}
|
||||
|
||||
void _map(_Protect *p, void *va, void *pa, int prot) {
|
||||
int _map(_Protect *p, void *va, void *pa) {
|
||||
PDE *pt = (PDE*)p->ptr;
|
||||
PDE *pde = &pt[PDX(va)];
|
||||
uint32_t wflag = (prot & _PROT_WRITE) ? PTE_W : 0;
|
||||
uint32_t wflag = 0; // TODO: this should be not accessible
|
||||
if (!(*pde & PTE_P)) {
|
||||
*pde = PTE_P | wflag | PTE_U | reinterpret_cast<uint32_t>(palloc_f());
|
||||
*pde = PTE_P | wflag | PTE_U | (uint32_t)(palloc_f(1));
|
||||
}
|
||||
PTE *pte = &((PTE*)PTE_ADDR(*pde))[PTX(va)];
|
||||
if (!(*pte & PTE_P)) {
|
||||
*pte = PTE_P | wflag | PTE_U | reinterpret_cast<uint32_t>(pa);
|
||||
*pte = PTE_P | wflag | PTE_U | (uint32_t)(pa);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *_query(_Protect *p, void *va, int *prot) {
|
||||
|
@ -106,9 +108,9 @@ _RegSet *_umake(_Protect *p, _Area ustack, _Area kstack, void (*entry)(void *),
|
|||
_RegSet *regs = (_RegSet*)kstack.start;
|
||||
regs->cs = USEL(SEG_UCODE);
|
||||
regs->ds = regs->es = regs->ss = USEL(SEG_UDATA);
|
||||
regs->esp3 = reinterpret_cast<uint32_t>(ustack.end);
|
||||
regs->esp3 = (uint32_t)ustack.end;
|
||||
regs->ss0 = KSEL(SEG_KDATA);
|
||||
regs->esp0 = reinterpret_cast<uint32_t>(kstack.end);
|
||||
regs->esp0 = (uint32_t)kstack.end;
|
||||
regs->eip = (uint32_t)entry;
|
||||
regs->eflags = FL_IF;
|
||||
|
|
@ -2,8 +2,6 @@
|
|||
#include <am-x86.h>
|
||||
#include <am.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
int main();
|
||||
|
||||
_Area _heap;
|
||||
|
@ -18,8 +16,6 @@ void _start() {
|
|||
_halt(ret);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define SERIAL_PORT 0x3f8
|
||||
|
||||
static void serial_init() {
|
||||
|
@ -32,13 +28,12 @@ static void serial_init() {
|
|||
outb(SERIAL_PORT + 4, 0x0B);
|
||||
}
|
||||
|
||||
|
||||
static void memory_init() {
|
||||
extern char end;
|
||||
unsigned long st, ed;
|
||||
unsigned long step = 1L<<20; // 1 MB step
|
||||
st = ed = (((unsigned long)&end) & ~(step-1)) + step;
|
||||
while (true) {
|
||||
while (1) {
|
||||
volatile int *ptr = (int*)ed;
|
||||
*ptr = 0x5a5a5a5a;
|
||||
if (*ptr == 0x5a5a5a5a) {
|
||||
|
@ -47,8 +42,8 @@ static void memory_init() {
|
|||
break;
|
||||
}
|
||||
}
|
||||
_heap.start = reinterpret_cast<void*>(st);
|
||||
_heap.end = reinterpret_cast<void*>(ed);
|
||||
_heap.start = (void*)st;
|
||||
_heap.end = (void*)ed;
|
||||
}
|
||||
|
||||
void _trm_init() {
|
||||
|
@ -67,6 +62,7 @@ static void puts(const char *s) {
|
|||
_putc(*p);
|
||||
}
|
||||
}
|
||||
|
||||
void _halt(int code) {
|
||||
puts("Exited (");
|
||||
if (code == 0) _putc('0');
|
||||
|
@ -80,5 +76,3 @@ void _halt(int code) {
|
|||
puts(").\n");
|
||||
asm volatile("cli; hlt");
|
||||
}
|
||||
|
||||
|
|
@ -5,7 +5,9 @@
|
|||
_Device *pci;
|
||||
|
||||
uint32_t pci_conf_read(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) {
|
||||
return pci->read(_DEV_PCICONF_REG(bus, slot, func, offset), 4);
|
||||
uint32_t res;
|
||||
pci->read(_DEVREG_PCICONF(bus, slot, func, offset), &res, 4);
|
||||
return res;
|
||||
}
|
||||
|
||||
struct pcidev {
|
||||
|
@ -34,25 +36,44 @@ void pci_test(_Device *dev) {
|
|||
}
|
||||
|
||||
void timer_test(_Device *dev) {
|
||||
uint32_t t0 = dev->read(_DEV_TIMER_REG_UPTIME, 4);
|
||||
for (int volatile i = 0; i < 1000000; i ++) ;
|
||||
uint32_t t1 = dev->read(_DEV_TIMER_REG_UPTIME, 4);
|
||||
printk("Loop 10^6 time elapse: %d ms\n", t1 - t0);
|
||||
_UptimeReg uptime;
|
||||
dev->read(_DEVREG_TIMER_UPTIME, &uptime, sizeof(uptime));
|
||||
uint32_t t0 = uptime.lo;
|
||||
for (int volatile i = 0; i < 10000000; i ++) ;
|
||||
dev->read(_DEVREG_TIMER_UPTIME, &uptime, sizeof(uptime));
|
||||
uint32_t t1 = uptime.lo;
|
||||
printk("Loop 10^7 time elapse: %d ms\n", t1 - t0);
|
||||
}
|
||||
|
||||
static uint8_t readb(_Device *dev, uint32_t reg) {
|
||||
uint8_t res;
|
||||
dev->read(reg, &res, 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
static uint32_t readl(_Device *dev, uint32_t reg) {
|
||||
uint32_t res;
|
||||
dev->read(reg, &res, 4);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void writeb(_Device *dev, uint32_t reg, uint8_t res) {
|
||||
dev->write(reg, &res, 1);
|
||||
}
|
||||
|
||||
void ata_test(_Device *dev) {
|
||||
while ((dev->read(_DEV_ATA_REG_STATUS, 1) & 0xc0) != 0x40);
|
||||
while ((readb(dev, _DEVREG_ATA_STATUS) & 0xc0) != 0x40);
|
||||
int offset = 0;
|
||||
dev->write(_DEV_ATA_REG_NSECT, 1, 1);
|
||||
dev->write(_DEV_ATA_REG_SECT, 1, offset);
|
||||
dev->write(_DEV_ATA_REG_CYLOW, 1, offset >> 8);
|
||||
dev->write(_DEV_ATA_REG_CYHIGH, 1, offset >> 16);
|
||||
dev->write(_DEV_ATA_REG_DRIVE, 1, (offset >> 24) | 0xe0);
|
||||
dev->write(_DEV_ATA_REG_STATUS, 1, 0x20);
|
||||
while ((dev->read(7, 1) & 0xc0) != 0x40);
|
||||
writeb(dev, _DEVREG_ATA_NSECT, 1);
|
||||
writeb(dev, _DEVREG_ATA_SECT, offset);
|
||||
writeb(dev, _DEVREG_ATA_CYLOW, offset >> 8);
|
||||
writeb(dev, _DEVREG_ATA_CYHIGH, offset >> 16);
|
||||
writeb(dev, _DEVREG_ATA_DRIVE, (offset >> 24) | 0xe0);
|
||||
writeb(dev, _DEVREG_ATA_STATUS, 0x20);
|
||||
while ((readb(dev, _DEVREG_ATA_STATUS) & 0xc0) != 0x40);
|
||||
uint32_t buf[512 / 4];
|
||||
for (int i = 0; i < 512 / 4; i ++) {
|
||||
buf[i] = dev->read(_DEV_ATA_REG_DATA, 4);
|
||||
buf[i] = readl(dev, _DEVREG_ATA_DATA);
|
||||
}
|
||||
for (int i = 0; i < 512; i ++) {
|
||||
printf("%02x ", ((char*)buf)[i] & 0xff);
|
||||
|
@ -60,6 +81,7 @@ void ata_test(_Device *dev) {
|
|||
}
|
||||
|
||||
int main() {
|
||||
_ioe_init();
|
||||
for (int n = 1; ; n ++) {
|
||||
_Device *dev = _device(n);
|
||||
if (!dev) break;
|
||||
|
|
Loading…
Reference in New Issue