Пример #1
0
/*
 * vm_contig_pg_kmap:
 *
 * Map previously allocated (vm_contig_pg_alloc) range of pages from
 * vm_page_array[] into the KVA.  Once mapped, the pages are part of
 * the Kernel, and are to free'ed with kmem_free(&kernel_map, addr, size).
 *
 * No requirements.
 */
static vm_offset_t
vm_contig_pg_kmap(int start, u_long size, vm_map_t map, int flags)
{
	vm_offset_t addr;
	vm_paddr_t pa;
	vm_page_t pga = vm_page_array;
	u_long offset;

	if (size == 0)
		panic("vm_contig_pg_kmap: size must not be 0");
	size = round_page(size);
	addr = kmem_alloc_pageable(&kernel_map, size, VM_SUBSYS_CONTIG);
	if (addr) {
		pa = VM_PAGE_TO_PHYS(&pga[start]);
		for (offset = 0; offset < size; offset += PAGE_SIZE)
			pmap_kenter_noinval(addr + offset, pa + offset);
		pmap_invalidate_range(&kernel_pmap, addr, addr + size);
		if (flags & M_ZERO)
			bzero((void *)addr, size);
	}
	return(addr);
}
Пример #2
0
int
start_all_aps(void)
{
	int x,apic_id, cpu;
	struct pcpu *pc;
	
	mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);

	/* set up temporary P==V mapping for AP boot */
	/* XXX this is a hack, we should boot the AP on its own stack/PTD */

	/* start each AP */
	for (cpu = 1; cpu < mp_ncpus; cpu++) {
		apic_id = cpu_apic_ids[cpu];


		bootAP = cpu;
		bootAPgdt = gdt + (512*cpu);

		/* Get per-cpu data */
		pc = &__pcpu[bootAP];
		pcpu_init(pc, bootAP, sizeof(struct pcpu));
		dpcpu_init((void *)kmem_alloc(kernel_map, DPCPU_SIZE), bootAP);
		pc->pc_apic_id = cpu_apic_ids[bootAP];
		pc->pc_prvspace = pc;
		pc->pc_curthread = 0;

		gdt_segs[GPRIV_SEL].ssd_base = (int) pc;
		gdt_segs[GPROC0_SEL].ssd_base = (int) &pc->pc_common_tss;
		
		PT_SET_MA(bootAPgdt, VTOM(bootAPgdt) | PG_V | PG_RW);
		bzero(bootAPgdt, PAGE_SIZE);
		for (x = 0; x < NGDT; x++)
			ssdtosd(&gdt_segs[x], &bootAPgdt[x].sd);
		PT_SET_MA(bootAPgdt, vtomach(bootAPgdt) | PG_V);
#ifdef notyet
		
                if (HYPERVISOR_vcpu_op(VCPUOP_get_physid, cpu, &cpu_id) == 0) { 
                        apicid = xen_vcpu_physid_to_x86_apicid(cpu_id.phys_id); 
                        acpiid = xen_vcpu_physid_to_x86_acpiid(cpu_id.phys_id); 
#ifdef CONFIG_ACPI 
                        if (acpiid != 0xff) 
                                x86_acpiid_to_apicid[acpiid] = apicid; 
#endif 
                } 
#endif
		
		/* attempt to start the Application Processor */
		if (!start_ap(cpu)) {
			printf("AP #%d (PHY# %d) failed!\n", cpu, apic_id);
			/* better panic as the AP may be running loose */
			printf("panic y/n? [y] ");
			if (cngetc() != 'n')
				panic("bye-bye");
		}

		CPU_SET(cpu, &all_cpus);	/* record AP in CPU map */
	}
	

	pmap_invalidate_range(kernel_pmap, 0, NKPT * NBPDR - 1);
	
	/* number of APs actually started */
	return mp_naps;
}