Exemplo n.º 1
0
static void parse_initrd(Mbdata *mb)
{
	if(!mb->flags & (1<<3))
		kprintf("multiboot header has no modules\n");
	int i;
	struct Mbmod *mods = (struct Mbmod*)VADDR_DIRECT(mb->mods_addr);
	for(i=0;i<mb->mods_count;i++){
		kprintf("mbmod: %d %p %p\n", i, 
		  mods[i].start, mods[i].end);
	}
	if(mb->mods_count<1)
		return;
	initrd_begin = VADDR_DIRECT(mods[0].start);
	initrd_end = VADDR_DIRECT(mods[0].end);
}
Exemplo n.º 2
0
// Start additional processor running bootstrap code at addr.
// See Appendix B of MultiProcessor Specification.
void
lapic_ap_start(int apicid, uint32_t addr)
{
	int i;
	uint16_t *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(IO_RTC, 0xF);  // offset 0xF is shutdown code
	outb(IO_RTC+1, 0x0A);
	wrv = VADDR_DIRECT(0x40 << 4 | 0x67);
	wrv[0] = addr & 0xffff;
	wrv[1] = (addr ^ wrv[0]) >> 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 bootstrap 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);
	}
}
Exemplo n.º 3
0
void cpu_up(int id)
{
	extern char _bootother_start[];
	extern uint64_t _bootother_size;
	extern void (*apstart)(void);
	char *stack;

	unsigned char *code = (unsigned char*)VADDR_DIRECT(0x7000);
	struct cpu *c = per_cpu_ptr(cpus, id);
	assert(c->id != myid());
	assert(c->id == id);
	memcpy(code, _bootother_start, _bootother_size);

	stack = (char*)page2kva(alloc_pages_cpu(c, KSTACKPAGE));
	assert(stack != NULL);

	kprintf("LAPIC %d, CODE %p PA: %p, STACK: %p\n", c->hwid, code, PADDR_DIRECT(code), stack);
	warmreset(PADDR_DIRECT(code));

	*(uint32_t*)(code-4) = (uint32_t)PADDR_DIRECT(&apstart);
	*(uint64_t*)(code-12) = (uint64_t)stack + KSTACKSIZE;
	*(uint64_t*)(code-20) = (uint64_t)boot_cr3;
	// bootother.S sets this to 0x0a55face early on
	*(uint32_t*)(code-64) = 0;
	bcpuid = c->id;
	atomic_set(&bsync, 0);

	lapic_start_ap(c, PADDR_DIRECT(code));

	while(atomic_read(&bsync) == 0)
		nop_pause();
	rstrreset();
}
Exemplo n.º 4
0
static void rstrreset(void)
{
	volatile uint16_t *wrv;

	// Paranoid: set warm reset code and vector back to defaults
	outb(IO_RTC, 0xF);
	outb(IO_RTC+1, 0);
	wrv = (uint16_t*)VADDR_DIRECT(0x40<<4 | 0x67);
	wrv[0] = 0;
	wrv[1] = 0;
}
Exemplo n.º 5
0
pmd_t *
get_pmd(pgd_t *pgdir, uintptr_t la, bool create) {
#if PMXSHIFT == PUXSHIFT
	return get_pud(pgdir, la, create);
#else /* PMXSHIFT == PUXSHIFT */
    pud_t *pudp;
    if ((pudp = get_pud(pgdir, la, create)) == NULL) {
        return NULL;
    }
    if (!(*pudp & PTE_P)) {
        struct Page *page;
        if (!create || (page = alloc_page()) == NULL) {
            return NULL;
        }
        set_page_ref(page, 1);
        uintptr_t pa = page2pa(page);
        memset(VADDR_DIRECT(pa), 0, PGSIZE);
        *pudp = pa | PTE_U | PTE_W | PTE_P;
    }
    return &((pmd_t *)VADDR_DIRECT(PUD_ADDR(*pudp)))[PMX(la)];
#endif /* PMXSHIFT == PUXSHIFT */
}
Exemplo n.º 6
0
static void warmreset(uint32_t addr)
{
	volatile uint16_t *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(IO_RTC, 0xF);  // offset 0xF is shutdown code
	outb(IO_RTC+1, 0x0A);
	wrv = (uint16_t*)VADDR_DIRECT(0x40<<4 | 0x67);  // Warm reset vector
	wrv[0] = 0;
	wrv[1] = addr >> 4;
}
Exemplo n.º 7
0
static void mbmem2e820(Mbdata *mb)
{
	static struct e820map m;
	if(!(mb->flags & (1<<6)))
    		panic("multiboot header has no memory map");
	e820map_addr = &m;
  	uint8_t *p = (uint8_t*) VADDR_DIRECT(mb->mmap_addr);
  	uint8_t *ep = p + mb->mmap_length;
	int i = 0;
	while(p<ep){
		if(i>=E820MAX) break;
		struct Mbmem *mbmem = (Mbmem*)p;
		p += 4 + mbmem->size;
		m.map[i].addr = mbmem->base;
		m.map[i].size = mbmem->length;
		m.map[i].type = mbmem->type;
		i++;
	}
	m.nr_map = i;
}
Exemplo n.º 8
0
static uint32_t
lapicw(int index, uint32_t value)
{
	((volatile uint32_t *)VADDR_DIRECT(sysconf.lapic_phys))[index] = value;
	return ((volatile uint32_t *)VADDR_DIRECT(sysconf.lapic_phys))[ID];
}
Exemplo n.º 9
0
static uint32_t
lapicr(int index)
{
	return ((volatile uint32_t *)VADDR_DIRECT(sysconf.lapic_phys))[index];
}
Exemplo n.º 10
0
int kern_init(uint64_t mbmagic, uint64_t mbmem)
{
	extern char edata[], end[];
	memset(edata, 0, end - edata);

	/* percpu variable for CPU0 is preallocated */
	percpu_offsets[0] = __percpu_start;

	cons_init();		// init the console

	const char *message = "(THU.CST) os is loading ...";
	kprintf("%s\n\n", message);
	if(mbmagic == MULTIBOOT_BOOTLOADER_MAGIC){
		kprintf("Multiboot dectected: param %p\n", (void*)mbmem);
		mbmem2e820((Mbdata*)VADDR_DIRECT(mbmem));
		parse_initrd((Mbdata*)VADDR_DIRECT(mbmem));
	}

	print_kerninfo();

	/* get_cpu_var not available before tls_init() */
	hz_init();
	gdt_init(per_cpu_ptr(cpus, 0));
	tls_init(per_cpu_ptr(cpus, 0));
	acpitables_init();
	lapic_init();
	numa_init();

	pmm_init_numa();		// init physical memory management, numa awared
	/* map the lapic */
	lapic_init_late();

	//init the acpi stuff

	idt_init();		// init interrupt descriptor table
	pic_init();		// init interrupt controller

//	acpi_conf_init();


	percpu_init();
	cpus_init();
#ifdef UCONFIG_ENABLE_IPI
	ipi_init();
#endif

	refcache_init();

	vmm_init();		// init virtual memory management
	sched_init();		// init scheduler
	proc_init();		// init process table
	sync_init();		// init sync struct

	/* ext int */
	ioapic_init();
	acpi_init();

	ide_init();		// init ide devices
#ifdef UCONFIG_SWAP
	swap_init();		// init swap
#endif
	fs_init();		// init fs

	clock_init();		// init clock interrupt
	mod_init();

	trap_init();

	//XXX put here?
	bootaps();

	intr_enable();		// enable irq interrupt

#ifdef UCONFIG_HAVE_LINUX_DDE36_BASE
	dde_kit_init();
#endif

	/* do nothing */
	cpu_idle();		// run idle process
}