void kmain (void) { cpu = &cpus[0]; uart_init (P2V(UART0)); init_vmm (); kpt_freerange (align_up(&end, PT_SZ), P2V_WO(INIT_KERNMAP)); paging_init (INIT_KERNMAP, PHYSTOP); kmem_init (); kmem_init2(P2V(INIT_KERNMAP), P2V(PHYSTOP)); trap_init (); // vector table and stacks for models gic_init(P2V(VIC_BASE)); // arm v2 gic init uart_enable_rx (); // interrupt for uart consoleinit (); // console pinit (); // process (locks) binit (); // buffer cache fileinit (); // file table iinit (); // inode cache ideinit (); // ide (memory block device) #ifdef INCLUDE_REMOVED timer_init (HZ); // the timer (ticker) #endif sti (); userinit(); // first user process scheduler(); // start running processes }
// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { monitor_clear (); // Print basic system information. cprintf ("Ensidia\n\n"); cprintf ("Copyright (c) 2013-2014 Fotis Koutoulakis\n"); cprintf ("Based on xv6 by Russ Cox et al, at MIT CSAIL\n"); kinit1(end, P2V(4*1024*1024)); // phys page allocator kvmalloc(); // kernel page table mpinit(); // collect info about this machine lapicinit(); seginit(); // set up segments cprintf("\ncpu%d: starting xng kernel\n\n", cpu->id); picinit(); // interrupt controller ioapicinit(); // another interrupt controller consoleinit(); // I/O devices & their interrupts uartinit(); // serial port pinit(); // process table tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table iinit(); // inode cache ideinit(); // disk if(!ismp) timerinit(); // uniprocessor timer startothers(); // start other processors kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() userinit(); // first user process // Finish setting up this processor in mpmain. mpmain(); }
// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { kinit1(end, P2V(4*1024*1024)); // phys page allocator kvmalloc(); // kernel page table mpinit(); // detect other processors lapicinit(); // interrupt controller seginit(); // segment descriptors cprintf("\ncpu%d: starting xv6\n\n", cpunum()); picinit(); // another interrupt controller ioapicinit(); // another interrupt controller consoleinit(); // console hardware uartinit(); // serial port pinit(); // process table tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table ideinit(); // disk if(!ismp) timerinit(); // uniprocessor timer startothers(); // start other processors kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() userinit(); // first user process mpmain(); // finish this processor's setup init_semaphores_on_boot(); }
// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { kinit1(end, P2V(4*1024*1024)); // phys page allocator // kmem. freelist added cprintf("%x \n", end); kvmalloc(); // kernel page table #ifdef CONFIG_MULTI_PROCESS mpinit(); // collect info about this machine #endif lapicinit(); seginit(); // set up segments picinit(); // interrupt controller: Programmable Interrupt Controller #ifdef CONFIG_MULTI_PROCESS ioapicinit(); // another interrupt controller #endif consoleinit(); // I/O devices & their interrupts uartinit(); // serial port pinit(); // process table tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table iinit(); // inode cache ideinit(); // disk if(!ismp) timerinit(); // uniprocessor timer #ifdef CONFIG_MULTI_PROCESS startothers(); // start other processors kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() #endif userinit(); // first user process // Finish setting up this processor in mpmain. mpmain(); }
// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { unsigned char FB[]="MESSAGE WRITTEN THROUGH FRAMEBUFFER!!"; fb_init(); // initialize framebuffer device (2015.11.02) cprintf("\nUsing Framebuffer still presents some problems :(\n\n"); cprintf("\nSuggestion: review the way it is used in console.c\n\n"); fb_write(FB, sizeof(FB)); // Framebuffer maybe could be used before this moment (2015.11.02) see_mylock(MYLOCK); kinit1(end, P2V(4*1024*1024)); // phys page allocator kvmalloc(); // kernel page table mpinit(); // collect info about this machine lapicinit(); seginit(); // set up segments cprintf("\ncpu%d: starting xv6\n\n", cpu->id); picinit(); // interrupt controller ioapicinit(); // another interrupt controller consoleinit(); // I/O devices & their interrupts uartinit(); // serial port pinit(); // process table tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table ideinit(); // disk if(!ismp) timerinit(); // uniprocessor timer startothers(); // start other processors kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() userinit(); // first user process // Finish setting up this processor in mpmain. mpmain(); }
/*int main(void){*/ void kmain(void){ // vga_init(); // puts((uint8_t*)"Hello kernel world!\n"); /*do some work here, like initialize timer or paging*/ kinit1(end, P2V(4*1024*1024)); // phys page allocator kvmalloc(); // kernel page table mpinit(); // collect info about this machine lapicinit(); // gdt_descriptor(); // puts((uint8_t*)"GDT initialized...\n"); // idt_descriptor(); // puts((uint8_t*)"IDT initialized...\n"); // cprintf("IDT initialized...\n"); seginit(); // set up segments cprintf("\ncpu%d: starting xv6\n\n", cpu->id); picinit(); // interrupt controller ioapicinit(); // another interrupt controller consoleinit(); // I/O devices & their interrupts uartinit(); // serial port pinit(); // process table tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table ideinit(); // disk if(!ismp) timerinit(); // uniprocessor timer startothers(); // start other processors kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() userinit(); // first user process // Finish setting up this processor in mpmain. mpmain(); }
// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { kinit1(end, P2V(4*1024*1024)); // phys page allocator kvmalloc(); // kernel page table mpinit(); // collect info about this machine lapicinit(); seginit(); // set up segments cprintf("\ncpu%d: starting xv6\n\n", cpu->id); picinit(); // interrupt controller ioapicinit(); // another interrupt controller consoleinit(); // I/O devices & their interrupts uartinit(); // serial port pinit(); // process table tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table ideinit(); // disk if(!ismp) timerinit(); // uniprocessor timer startothers(); // start other processors kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() userinit(); // first user process mpmain(); }
// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { kinit1(end, P2V(4*1024*1024)); // phys page allocator kvmalloc(); // kernel page table mpinit(); // collect info about this machine lapicinit(); seginit(); // set up segments cprintf("\ncpu%d: starting xv6\n\n", cpu->id); picinit(); // interrupt controller ioapicinit(); // another interrupt controller consoleinit(); // I/O devices & their interrupts uartinit(); // serial port initGraphMode(); initDom(); tryOnce(); toggleOn(); pinit(); // process table toggleOn(); tvinit(); // trap vectors toggleOn(); binit(); // buffer cache toggleOn(); fileinit(); // file table toggleOn(); iinit(); // inode cache toggleOn(); ideinit(); // disk toggleOn(); if(!ismp) timerinit(); // uniprocessor timer toggleOn(); startothers(); // start other processors toggleOn(); kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() toggleOn(); txt_initLock(); mouseEnable(); initProcessMsgMap(); userinit(); // first user process toggleOn(); endToggle(); // Finish setting up this processor in mpmain. mpmain(); }
// Start the non-boot (AP) processors. static void startothers(void) { extern uchar _binary_entryother_start[], _binary_entryother_size[]; uchar *code; struct cpu *c; char *stack; // Write entry code to unused memory at 0x7000. // The linker has placed the image of entryother.S in // _binary_entryother_start. code = P2V(0x7000); memmove(code, _binary_entryother_start, (uint)_binary_entryother_size); for(c = cpus; c < cpus+ncpu; c++){ if(c == cpus+cpunum()) // We've started already. continue; // Tell entryother.S what stack to use, where to enter, and what // pgdir to use. We cannot use kpgdir yet, because the AP processor // is running in low memory, so we use entrypgdir for the APs too. stack = kalloc(); *(void**)(code-4) = stack + KSTACKSIZE; *(void**)(code-8) = mpenter; *(int**)(code-12) = (void *) V2P(entrypgdir); lapicstartap(c->apicid, V2P(code)); // wait for cpu to finish mpmain() while(c->started == 0) ; } }
// Start additional processor running entry code at addr. // See Appendix B of MultiProcessor Specification. void lapicstartap(uchar apicid, uint addr) { int i; ushort *wrv; // "The BSP must initialize CMOS shutdown code to 0AH // and the warm reset vector (DWORD based at 40:67) to point at // the AP startup code prior to the [universal startup algorithm]." outb(CMOS_PORT, 0xF); // offset 0xF is shutdown code outb(CMOS_PORT+1, 0x0A); wrv = (ushort*)P2V((0x40<<4 | 0x67)); // Warm reset vector wrv[0] = 0; wrv[1] = addr >> 4; // "Universal startup algorithm." // Send INIT (level-triggered) interrupt to reset other CPU. lapicw(ICRHI, apicid<<24); lapicw(ICRLO, INIT | LEVEL | ASSERT); microdelay(200); lapicw(ICRLO, INIT | LEVEL); microdelay(100); // should be 10ms, but too slow in Bochs! // Send startup IPI (twice!) to enter code. // Regular hardware is supposed to only accept a STARTUP // when it is in the halted state due to an INIT. So the second // should be ignored, but it is part of the official Intel algorithm. // Bochs complains about the second one. Too bad for Bochs. for(i = 0; i < 2; i++){ lapicw(ICRHI, apicid<<24); lapicw(ICRLO, STARTUP | (addr>>12)); microdelay(200); } }
size_t frame_alloc_mult_contig(uintptr_t* frames, size_t num) { /* Iterate over all the frames */ for(uint32_t i = 0; i < 131072; ++i) { if(frame_get(i * 0x1000) == 0) { uint8_t enough = TRUE; for(uint32_t j = 0; j < num; ++j) { if(frame_get(i + j * 0x1000) == 1) { enough = FALSE; break; } } if(enough == TRUE) { for(uint32_t j = 0; j < num; ++j) { frame_set(i + j * 0x1000, 1); frames[j] = P2V(i + j * 0x1000); } return num; } } } return 0; }
// Given a parent process's page table, create a copy // of it for a child. pde_t* copyuvm(pde_t *pgdir, uint sz) { pde_t *d; pte_t *pte; uint pa, i, flags; char *mem; if((d = setupkvm()) == 0) return 0; for(i = 0; i < sz; i += PGSIZE){ if((pte = walkpgdir(pgdir, (void *) i, 0)) == 0) panic("copyuvm: pte should exist"); if(!(*pte & PTE_P)) panic("copyuvm: page not present"); pa = PTE_ADDR(*pte); flags = PTE_FLAGS(*pte); if((mem = kalloc()) == 0) goto bad; memmove(mem, (char*)P2V(pa), PGSIZE); if(mappages(d, (void*)i, PGSIZE, V2P(mem), flags) < 0) goto bad; } return d; bad: freevm(d); return 0; }
// Deallocate user pages to bring the process size from oldsz to // newsz. oldsz and newsz need not be page-aligned, nor does newsz // need to be less than oldsz. oldsz can be larger than the actual // process size. Returns the new process size. int deallocuvm(pde_t *pgdir, uint oldsz, uint newsz) { pte_t *pte; uint a, pa; if(newsz >= oldsz) return oldsz; a = PGROUNDUP(newsz); for(; a < oldsz; a += PGSIZE){ pte = walkpgdir(pgdir, (char*)a, 0); if(!pte) a += (NPTENTRIES - 1) * PGSIZE; else if((*pte & PTE_P) != 0){ pa = PTE_ADDR(*pte); if(pa == 0) panic("kfree"); char *v = P2V(pa); kfree(v); *pte = 0; } } return newsz; }
// Os procedimentos de inicialização começam a executar o // código .C a partir daqui. // Aloca uma pilha real e troca para ela, primeiro fazendo // algumas configurações necessárias par o alocador de memória funcionar. int main(void) { kinit1(end, P2V(4*1024*1024)); // alocador de páginas de memória física kvmalloc(); // tabela de páginas do kernel mpinit(); // detecta outros processadores lapicinit(); // controlador de interrupções seginit(); // descritores de segmentos picinit(); // desabilita pic ioapicinit(); // outro controlador de interrupções consoleinit(); // console hardware uartinit(); // porta serial pinit(); // tabela de processos tvinit(); // vetores trap binit(); // buffer cache fileinit(); // tabela de arquivo ideinit(); // disco startothers(); // inicia outros processadores kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // deve vir após startothers() userinit(); // primeiro processo no modo usuário mpmain(); // encerra esta configuração de processadores }
static void kpt_free (char *v) { if (v >= (char*)P2V(INIT_KERNMAP)) { kfree(v, PT_ORDER); return; } acquire(&kpt_mem.lock); _kpt_free (v); release(&kpt_mem.lock); }
//PAGEBREAK! // Map user virtual address to kernel address. char* uva2ka(pde_t *pgdir, char *uva) { pte_t *pte; pte = walkpgdir(pgdir, uva, 0); if((*pte & PTE_P) == 0) return 0; if((*pte & PTE_U) == 0) return 0; return (char*)P2V(PTE_ADDR(*pte)); }
// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { kinit1(end, P2V(4*1024*1024)); // phys page allocator kvmalloc(); // kernel page table mpinit(); // detect other processors lapicinit(); // interrupt controller seginit(); // segment descriptors picinit(); // disable pic ioapicinit(); // another interrupt controller consoleinit(); // console hardware uartinit(); // serial port pinit(); // process table shminit(); // shared memory tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table ideinit(); // disk startothers(); // start other processors kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() userinit(); // first user process mpmain(); // finish this processor's setup }
// Free a page table and all the physical memory pages // in the user part. void freevm(pde_t *pgdir) { uint i; if(pgdir == 0) panic("freevm: no pgdir"); deallocuvm(pgdir, KERNBASE, 0); for(i = 0; i < NPDENTRIES; i++){ if(pgdir[i] & PTE_P){ char * v = P2V(PTE_ADDR(pgdir[i])); kfree(v); } } kfree((char*)pgdir); }
// Allocate one 4096-byte page of physical memory. // Returns a pointer that the kernel can use. // Returns 0 if the memory cannot be allocated. char* kalloc(void) { struct run *r; char *rv; if(kmem.use_lock) acquire(&kmem.lock); r = kmem.freelist; if(r) kmem.freelist = r->next; if(kmem.use_lock) release(&kmem.lock); rv = P2V((r - kmem.runs) * PGSIZE); return rv; }
// Set up kernel part of a page table. pde_t* setupkvm(void) { pde_t *pgdir; struct kmap *k; if((pgdir = (pde_t*)kalloc()) == 0) return 0; memset(pgdir, 0, PGSIZE); if(P2V(PHYSTOP) > (void*)DEVSPACE) panic("setupkvm: PHYSTOP too high"); for(k = kmap; k < &kmap[NELEM(kmap)]; k++) if(mappages(pgdir, k->virt, k->phys_end - k->phys_start, (uint)k->phys_start, k->perm) < 0) return 0; return pgdir; }
void e1000_received(struct e1000 *e) { struct sockbuf *sb; uint16_t old_cur; while((e->rx_descs[e->rx_cur]->status & 0x1)) { uint8_t *buf = (void *)(uintptr_t)P2V(e->rx_descs[e->rx_cur]->addr); uint16_t len = e->rx_descs[e->rx_cur]->length; sb = sockbuf_alloc(e->dev, len); kmemcpy(sb->data, buf, len); network_received(sb); e->rx_descs[e->rx_cur]->status = 0; old_cur = e->rx_cur; e->rx_cur = (e->rx_cur + 1) % NUM_RX_DESC; e1000_outl(e, REG_RXDESCTAIL, old_cur ) ; } }
// Search for the MP Floating Pointer Structure, which according to the // spec is in one of the following three locations: // 1) in the first KB of the EBDA; // 2) in the last KB of system base memory; // 3) in the BIOS ROM between 0xE0000 and 0xFFFFF. static struct mp* mpsearch(void) { uchar *bda; uint p; struct mp *mp; bda = (uchar *) P2V(0x400); if((p = ((bda[0x0F]<<8)| bda[0x0E]) << 4)){ if((mp = mpsearch1(p, 1024))) return mp; } else { p = ((bda[0x14]<<8)|bda[0x13])*1024; if((mp = mpsearch1(p-1024, 1024))) return mp; } return mpsearch1(0xF0000, 0x10000); }
struct network_dev * rtl8139_init() { struct network_dev *device = kmalloc(sizeof(*device)); struct rtl8139 *rtl = (struct rtl8139 *)kmalloc(sizeof(*rtl)); global = rtl; device->device = rtl; rtl->dev = device; rtl->pci = pci_get_device(RTL8139_VEND, RTL8139_DEV); rtl->rx_buffer = pallocn(2);//kmalloc(RX_BUF_LEN + RX_BUF_PAD); //FIXME: Wat Wat Wat rtl->tx_buffers = (void *)P2V(0x3380000);//kmalloc((8192+16+1500)*4); if(rtl->pci != NULL) { rtl->pci_hdr = rtl->pci->header; rtl->io_base = pci_get_bar(rtl->pci, PCI_BAR_IO) & ~1; rtl->mem_base = (uint8_t *)(pci_get_bar(rtl->pci, PCI_BAR_MEM) & ~3); rtl8139_start(rtl); rtl8139_getmac(rtl,(char *)&device->mac); device->send = rtl8139_send; printf("Realtek 8139 Ethernet adapter Rev %i found\t", rtl->pci_hdr->rev); printf("io base %x ",rtl->io_base); printf("mem base %x\n",rtl->mem_base); // device->receive = rtl8139_receive; print_mac((char *)&device->mac); printf("%X\n",rtl->dev); } else { kfree(rtl->rx_buffer); kfree(rtl); rtl = NULL; device = NULL; } return device; }
// Return the address of the PTE in page table pgdir // that corresponds to virtual address va. If alloc!=0, // create any required page table pages. static pte_t * walkpgdir(pde_t *pgdir, const void *va, int alloc) { pde_t *pde; pte_t *pgtab; pde = &pgdir[PDX(va)]; if(*pde & PTE_P){ pgtab = (pte_t*)P2V(PTE_ADDR(*pde)); } else { if(!alloc || (pgtab = (pte_t*)kalloc()) == 0) return 0; // Make sure all those PTE_P bits are zero. memset(pgtab, 0, PGSIZE); // The permissions here are overly generous, but they can // be further restricted by the permissions in the page table // entries, if necessary. *pde = V2P(pgtab) | PTE_P | PTE_W | PTE_U; } return &pgtab[PTX(va)]; }
// Load a program segment into pgdir. addr must be page-aligned // and the pages from addr to addr+sz must already be mapped. int loaduvm(pde_t *pgdir, char *addr, struct inode *ip, uint offset, uint sz) { uint i, pa, n; pte_t *pte; if((uint) addr % PGSIZE != 0) panic("loaduvm: addr must be page aligned"); for(i = 0; i < sz; i += PGSIZE){ if((pte = walkpgdir(pgdir, addr+i, 0)) == 0) panic("loaduvm: address should exist"); pa = PTE_ADDR(*pte); if(sz - i < PGSIZE) n = sz - i; else n = PGSIZE; if(readi(ip, P2V(pa), offset+i, n) != n) return -1; } return 0; }
int8_t frame_alloc_aligned(uintptr_t* frame, uint32_t alignment) { uint32_t mask = alignment - 1; /* Iterate over all the frames */ for(uint32_t i = 0; i < 4096; ++i) { if(frames_bitmap[i] ^ 0xFFFFFFFF) { /* There's a free frame here */ /* For each bit in this part of the bitmap */ for(uintptr_t f = i * 32 * 0x1000; f < (i+1) * 32 * 0x1000; f += 0x1000) { /* If the frame is free */ if(0 == frame_get(f) && (f & mask) == 0) { frame_set(f, 1); *frame = P2V(f); return 0; } } } } return -ENOMEM; }
int display_vga() { // set processor to vga mode struct regs16 regs = { .ax = 0x13}; pushcli(); pte_t original = biosmap(); int32(0x10, ®s); #if MODE_UNCHAINED display_unchained(); #endif biosunmap(original); popcli(); return 0; } int display_draw() { static int page = 0; char* page_addr = (char *)P2V(0xA0000 + page*FRAME_PIX); // move current buffer to non-visible page #if MODE_UNCHAINED int i; outb(SC_INDEX, MAP_MASK); for (i = 0; i < 4; i++) { outb(SC_DATA, 1 << i); memmove(page_addr, frame_buffer[i], FRAME_PIX); } short flip_addr = page*FRAME_PIX; // flip pages short high_addr = HIGH_ADDRESS | (flip_addr & 0xff00); short low_addr = LOW_ADDRESS | (flip_addr << 8); #ifdef VERTICAL_RETRACE while ((inb(INPUT_STATUS_1) & DISPLAY_ENABLE)); #endif outw(CRTC_INDEX, high_addr); outw(CRTC_INDEX, low_addr); #ifdef VERTICAL_RETRACE while (!(inb(INPUT_STATUS_1) & VRETRACE)); #endif // use the other page next time page = (page+1)%2; #else memmove(page_addr, frame_buffer, SCREEN_PIX); #endif return 0; } int display_text() { // set processor to text mode struct regs16 regs = { .ax = 0x03}; pushcli(); pte_t original = biosmap(); int32(0x10, ®s); biosunmap(original); popcli(); return 0; }
/* * map_ioctl: * process the supported ioctls */ static int map_ioctl(RP rp) { PARAM far *p = (PARAM far*)IOPARAM(rp); DATA far *d; int idx; ULONG addr, lock, temp; ULONG far *ud; /* only accept class XFREE86_PMAP */ if (IOCAT(rp) != XFREE86_PMAP) return RP_EBAD; switch (IOFUNC(rp)) { case PMAP_MAP: /* test: Parameter packet is readable and has correct size * get a free slot */ if (Verify(p,sizeof(PARAM),0)==0 && (idx = find_empty()) != -1) { /* map the requested region */ addr = Pmap(p->u.physaddr,p->size); /* was okay? */ if (addr) { /* get the return packet of ioctl */ d = (DATA far*)IODATA(rp); /* writable ? */ if (Verify(d,sizeof(DATA),1)==0) { /* set the mapping address in * process address space */ d->addr = addr; d->sel = 0; /* registrate stuff in mapping table */ maps[idx].phys = p->u.physaddr; maps[idx].vmaddr = addr; maps[idx].sfnum = IOSFN(rp); maps[idx].lockhan = 0; return RPDONE; } } } /* come here for error condition */ break; case PMAP_UNMAP: /* test: parameter packet readable and correct size * entry found in table * unmapping okay? */ if (Verify(p,sizeof(PARAM),0)==0 && (idx = find_map(IOSFN(rp),p->u.vmaddr)) != -1 && Punmap(p->u.vmaddr)==0) { /* get the return packet of ioctl */ ud = (ULONG far*)IODATA(rp); /* writable ? */ if (Verify(d,sizeof(ULONG),1)==0) { /* set the vmaddress just invalidated * into data packet */ *ud = maps[idx].vmaddr; /* remove entry from table */ maps[idx].phys = 0; maps[idx].vmaddr = 0; maps[idx].sfnum = -1; maps[idx].lockhan = 0; return RPDONE; } } /* arrive here for error condition */ break; case PMAP_UNMAP2: /* test: parameter packet readable and correct size * entry found in table * unmapping okay? */ if (Verify(p,sizeof(PARAM),0)==0 && (idx = find_mapphys(IOSFN(rp),p->u.physaddr,p->size)) != -1 && Punmap(maps[idx].vmaddr)==0) { /* remove entry from table */ maps[idx].phys = 0; maps[idx].vmaddr = 0; maps[idx].sfnum = -1; maps[idx].lockhan = 0; return RPDONE; } /* arrive here for error condition */ break; case PMAP_NAME: if (Verify(d,14,1) == 0) { bmove((char far*)d,"\\dev\\pmap$\0",11); return RPDONE; } break; case PMAP_DRVID: return drvid(d,IODLEN(rp),PMAPDRV_ID); case PMAP_READROM: /* testcfg.sys replacement function */ if (Verify(p,sizeof(ROMPARAM),0) == 0) { ROMPARAM far *p1 = (ROMPARAM*)p; USHORT n = p1->numbytes; ULONG ad = p1->physaddr + n; if (p1->command == 0 && p1->physaddr >= 0xc0000 && p1->physaddr <= 0xfffff && ad >= 0xc0000 && ad <= 0xfffff) { char far *d1 = (char far*)IODATA(rp); if (Verify(d1,n,1) == 0) { char far *addr; if (P2V(p1->physaddr,n,&addr)==0) { bmove(d1,addr,n); /*UnPhysToVirt == NOOP in OS/2 2.x */ return RPDONE; } } } } break; case PMAP_LOCKBUF: /* test: Parameter packet is readable and has correct size * */ lock = 0; if (Verify(p,sizeof(PARAM),0)==0 && (idx = find_empty()) != -1) { /* lock the requested region */ lock = Vlock(p->u.vmaddr,p->size); temp = (p->u.vmaddr << 3) | 0x070000; /* Make sel */ /* was okay? */ if ((lock) && (Verify((FPVOID)temp, (USHORT)p->size, 0) ==0)) { /* get the return packet of ioctl */ d = (DATA far*)IODATA(rp); /* writable ? */ if (Verify(d,sizeof(DATA),1)==0) { /* set the mapping address in * process address space */ /* This is where things crash: VtoP does not like our addr */ d->addr = VtoP(p->u.vmaddr); d->sel = 0; maps[idx].phys = addr; maps[idx].vmaddr = p->u.vmaddr; maps[idx].sfnum = IOSFN(rp); maps[idx].lockhan = lock; return RPDONE; } } if(lock) Vunlock(lock); /* In case Verify failed */ } /* come here for error condition */ break; default: return RP_EBAD; } /* break from case */ return RP_EINVAL; }
getcallerpcs(&s, pcs); for(i=0; i<10; i++) cprintf(" %p", pcs[i]); panicked = 1; // freeze other CPU for(;;) ; } //PAGEBREAK: 50 #define BACKSPACE 0x100 #define CRTPORT 0x3d4 #define KEY_LF 0xE4 #define KEY_RT 0xE5 #define KEY_UP 0xE2 #define KEY_DN 0xE3 static ushort *crt = (ushort*)P2V(0xb8000); // CGA memory static void cgaputc(int c) { int pos; // Cursor position: col + 80*row. outb(CRTPORT, 14); pos = inb(CRTPORT+1) << 8; outb(CRTPORT, 15); pos |= inb(CRTPORT+1); if(c == '\n') pos += 80 - pos%80; else if(c==KEY_RT)
void uart_send(const char c) { __REG(P2V(UART0)) = c; if(c == '\n') __REG(P2V(UART0)) = '\r'; }