mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-20 11:11:24 +00:00
Drastically simplify the i386 pcpu backend by merging parts of the
amd64 mechanism over. Instead of page table hackery that isn't actually needed, just use 'struct pcpu __pcpu[MAXCPU]' for backing like all the other platforms do. Get rid of 'struct privatespace' and a while mess of #ifdef SMP garbage that set it up. As a bonus, this returns the 4MB of KVA that we stole to implement it the old way. This also allows you to read the pcpu data for each cpu when reading a minidump. Background information: Originally, pcpu stuff was implemented as having per-cpu page tables and magic to make different data structures appear at the same actual address. In order to share page tables, we switched to using the GDT and %fs/%gs to access it. But we still did the evil magic to set it up for the old way. The "idle stacks" are not used for the idle process anymore and are just used for a few functions during bootup, then ignored. (excercise for reader: free these afterwards).
This commit is contained in:
parent
bfbdccc1d1
commit
6dd3a6c06e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=173592
@ -72,16 +72,6 @@
|
||||
.set PTD,PTmap + (PTDPTDI * PAGE_SIZE)
|
||||
.set PTDpde,PTD + (PTDPTDI * PDESIZE)
|
||||
|
||||
#ifdef SMP
|
||||
/*
|
||||
* Define layout of per-cpu address space.
|
||||
* This is "constructed" in locore.s on the BSP and in mp_machdep.c
|
||||
* for each AP. DO NOT REORDER THESE WITHOUT UPDATING THE REST!
|
||||
*/
|
||||
.globl SMP_prvspace
|
||||
.set SMP_prvspace,(MPPTDI << PDRSHIFT)
|
||||
#endif /* SMP */
|
||||
|
||||
/*
|
||||
* Compiled KERNBASE location and the kernel load address
|
||||
*/
|
||||
@ -106,16 +96,6 @@ bootinfo: .space BOOTINFO_SIZE /* bootinfo that we can handle */
|
||||
KERNend: .long 0 /* phys addr end of kernel (just after bss) */
|
||||
physfree: .long 0 /* phys addr of next free page */
|
||||
|
||||
#ifdef SMP
|
||||
.globl cpu0prvpage
|
||||
cpu0pp: .long 0 /* phys addr cpu0 private pg */
|
||||
cpu0prvpage: .long 0 /* relocated version */
|
||||
|
||||
.globl SMPpt
|
||||
SMPptpa: .long 0 /* phys addr SMP page table */
|
||||
SMPpt: .long 0 /* relocated version */
|
||||
#endif /* SMP */
|
||||
|
||||
.globl IdlePTD
|
||||
IdlePTD: .long 0 /* phys addr of kernel PTD */
|
||||
|
||||
@ -763,20 +743,6 @@ no_kernend:
|
||||
addl $KERNBASE, %esi
|
||||
movl %esi, R(vm86paddr)
|
||||
|
||||
#ifdef SMP
|
||||
/* Allocate cpu0's private data page */
|
||||
ALLOCPAGES(1)
|
||||
movl %esi,R(cpu0pp)
|
||||
addl $KERNBASE, %esi
|
||||
movl %esi, R(cpu0prvpage) /* relocated to KVM space */
|
||||
|
||||
/* Allocate SMP page table page */
|
||||
ALLOCPAGES(1)
|
||||
movl %esi,R(SMPptpa)
|
||||
addl $KERNBASE, %esi
|
||||
movl %esi, R(SMPpt) /* relocated to KVM space */
|
||||
#endif /* SMP */
|
||||
|
||||
/*
|
||||
* Enable PSE and PGE.
|
||||
*/
|
||||
@ -854,37 +820,6 @@ no_kernend:
|
||||
movl $ISA_HOLE_LENGTH>>PAGE_SHIFT, %ecx
|
||||
fillkpt(R(vm86pa), $PG_RW|PG_U)
|
||||
|
||||
#ifdef SMP
|
||||
/* Map cpu0's private page into global kmem (4K @ cpu0prvpage) */
|
||||
movl R(cpu0pp), %eax
|
||||
movl $1, %ecx
|
||||
fillkptphys($PG_RW)
|
||||
|
||||
/* Map SMP page table page into global kmem FWIW */
|
||||
movl R(SMPptpa), %eax
|
||||
movl $1, %ecx
|
||||
fillkptphys($PG_RW)
|
||||
|
||||
/* Map the private page into the SMP page table */
|
||||
movl R(cpu0pp), %eax
|
||||
movl $0, %ebx /* pte offset = 0 */
|
||||
movl $1, %ecx /* one private page coming right up */
|
||||
fillkpt(R(SMPptpa), $PG_RW)
|
||||
|
||||
/* ... and put the page table table in the pde. */
|
||||
movl R(SMPptpa), %eax
|
||||
movl $MPPTDI, %ebx
|
||||
movl $1, %ecx
|
||||
fillkpt(R(IdlePTD), $PG_RW)
|
||||
|
||||
/* Fakeup VA for the local apic to allow early traps. */
|
||||
ALLOCPAGES(1)
|
||||
movl %esi, %eax
|
||||
movl $(NPTEPG-1), %ebx /* pte offset = NTEPG-1 */
|
||||
movl $1, %ecx /* one private pt coming right up */
|
||||
fillkpt(R(SMPptpa), $PG_RW)
|
||||
#endif /* SMP */
|
||||
|
||||
/*
|
||||
* Create an identity mapping for low physical memory, including the kernel.
|
||||
* The part of this mapping that covers the first 1 MB of physical memory
|
||||
|
@ -127,7 +127,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/perfmon.h>
|
||||
#endif
|
||||
#ifdef SMP
|
||||
#include <machine/privatespace.h>
|
||||
#include <machine/smp.h>
|
||||
#endif
|
||||
|
||||
@ -207,9 +206,7 @@ vm_paddr_t dump_avail[PHYSMAP_SIZE + 2];
|
||||
struct kva_md_info kmi;
|
||||
|
||||
static struct trapframe proc0_tf;
|
||||
#ifndef SMP
|
||||
static struct pcpu __pcpu;
|
||||
#endif
|
||||
struct pcpu __pcpu[MAXCPU];
|
||||
|
||||
struct mtx icu_lock;
|
||||
|
||||
@ -2116,11 +2113,7 @@ init386(first)
|
||||
gdt_segs[GUFS_SEL].ssd_limit = atop(0 - 1);
|
||||
gdt_segs[GUGS_SEL].ssd_limit = atop(0 - 1);
|
||||
|
||||
#ifdef SMP
|
||||
pc = &SMP_prvspace[0].pcpu;
|
||||
#else
|
||||
pc = &__pcpu;
|
||||
#endif
|
||||
pc = &__pcpu[0];
|
||||
gdt_segs[GPRIV_SEL].ssd_limit = atop(0 - 1);
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) pc;
|
||||
gdt_segs[GPROC0_SEL].ssd_base = (int) &pc->pc_common_tss;
|
||||
|
@ -78,7 +78,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/psl.h>
|
||||
#include <machine/smp.h>
|
||||
#include <machine/specialreg.h>
|
||||
#include <machine/privatespace.h>
|
||||
|
||||
#define WARMBOOT_TARGET 0
|
||||
#define WARMBOOT_OFF (KERNBASE + 0x0467)
|
||||
@ -134,6 +133,8 @@ int mp_naps; /* # of Applications processors */
|
||||
int boot_cpu_id = -1; /* designated BSP */
|
||||
extern int nkpt;
|
||||
|
||||
extern struct pcpu __pcpu[];
|
||||
|
||||
/*
|
||||
* CPU topology map datastructures for HTT.
|
||||
*/
|
||||
@ -144,12 +145,12 @@ static struct cpu_top mp_top;
|
||||
char *bootSTK;
|
||||
static int bootAP;
|
||||
|
||||
/* Free these after use */
|
||||
void *bootstacks[MAXCPU];
|
||||
|
||||
/* Hotwire a 0->4MB V==P mapping */
|
||||
extern pt_entry_t *KPTphys;
|
||||
|
||||
/* SMP page table page */
|
||||
extern pt_entry_t *SMPpt;
|
||||
|
||||
struct pcb stoppcbs[MAXCPU];
|
||||
|
||||
/* Variables needed for SMP tlb shootdown. */
|
||||
@ -493,6 +494,7 @@ cpu_mp_announce(void)
|
||||
void
|
||||
init_secondary(void)
|
||||
{
|
||||
struct pcpu *pc;
|
||||
vm_offset_t addr;
|
||||
int gsel_tss;
|
||||
int x, myid;
|
||||
@ -500,11 +502,18 @@ init_secondary(void)
|
||||
|
||||
/* bootAP is set in start_ap() to our ID. */
|
||||
myid = bootAP;
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[myid];
|
||||
gdt_segs[GPROC0_SEL].ssd_base =
|
||||
(int) &SMP_prvspace[myid].pcpu.pc_common_tss;
|
||||
SMP_prvspace[myid].pcpu.pc_prvspace =
|
||||
&SMP_prvspace[myid].pcpu;
|
||||
|
||||
/* Get per-cpu data */
|
||||
pc = &__pcpu[myid];
|
||||
|
||||
/* prime data page for it to use */
|
||||
pcpu_init(pc, myid, sizeof(struct pcpu));
|
||||
pc->pc_apic_id = cpu_apic_ids[myid];
|
||||
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;
|
||||
|
||||
for (x = 0; x < NGDT; x++) {
|
||||
ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd);
|
||||
@ -587,7 +596,6 @@ init_secondary(void)
|
||||
printf("SMP: cpuid = %d\n", PCPU_GET(cpuid));
|
||||
printf("SMP: actual apic_id = %d\n", lapic_id());
|
||||
printf("SMP: correct apic_id = %d\n", PCPU_GET(apic_id));
|
||||
printf("PTD[MPPTDI] = %#jx\n", (uintmax_t)PTD[MPPTDI]);
|
||||
panic("cpuid mismatch! boom!!");
|
||||
}
|
||||
|
||||
@ -727,11 +735,9 @@ start_all_aps(void)
|
||||
#ifndef PC98
|
||||
u_char mpbiosreason;
|
||||
#endif
|
||||
struct pcpu *pc;
|
||||
char *stack;
|
||||
uintptr_t kptbase;
|
||||
u_int32_t mpbioswarmvec;
|
||||
int apic_id, cpu, i, pg;
|
||||
int apic_id, cpu, i;
|
||||
|
||||
mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);
|
||||
|
||||
@ -757,24 +763,8 @@ start_all_aps(void)
|
||||
for (cpu = 1; cpu < mp_ncpus; cpu++) {
|
||||
apic_id = cpu_apic_ids[cpu];
|
||||
|
||||
/* first page of AP's private space */
|
||||
pg = cpu * i386_btop(sizeof(struct privatespace));
|
||||
|
||||
/* allocate a new private data page */
|
||||
pc = (struct pcpu *)kmem_alloc(kernel_map, PAGE_SIZE);
|
||||
|
||||
/* wire it into the private page table page */
|
||||
SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(pc));
|
||||
|
||||
/* allocate and set up an idle stack data page */
|
||||
stack = (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE); /* XXXKSE */
|
||||
for (i = 0; i < KSTACK_PAGES; i++)
|
||||
SMPpt[pg + 1 + i] = (pt_entry_t)
|
||||
(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack));
|
||||
|
||||
/* prime data page for it to use */
|
||||
pcpu_init(pc, cpu, sizeof(struct pcpu));
|
||||
pc->pc_apic_id = apic_id;
|
||||
bootstacks[cpu] = (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE);
|
||||
|
||||
/* setup a vector to our boot code */
|
||||
*((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET;
|
||||
@ -784,8 +774,7 @@ start_all_aps(void)
|
||||
outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */
|
||||
#endif
|
||||
|
||||
bootSTK = &SMP_prvspace[cpu].idlekstack[KSTACK_PAGES *
|
||||
PAGE_SIZE];
|
||||
bootSTK = (char *)bootstacks[cpu] + KSTACK_PAGES * PAGE_SIZE - 4;
|
||||
bootAP = cpu;
|
||||
|
||||
/* attempt to start the Application Processor */
|
||||
@ -814,19 +803,7 @@ start_all_aps(void)
|
||||
outb(CMOS_DATA, mpbiosreason);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up the idle context for the BSP. Similar to above except
|
||||
* that some was done by locore, some by pmap.c and some is implicit
|
||||
* because the BSP is cpu#0 and the page is initially zero and also
|
||||
* because we can refer to variables by name on the BSP..
|
||||
*/
|
||||
|
||||
/* Allocate and setup BSP idle stack */
|
||||
stack = (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE);
|
||||
for (i = 0; i < KSTACK_PAGES; i++)
|
||||
SMPpt[1 + i] = (pt_entry_t)
|
||||
(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack));
|
||||
|
||||
/* Undo V==P hack from above */
|
||||
for (i = 0; i < NKPT; i++)
|
||||
PTD[i] = 0;
|
||||
pmap_invalidate_range(kernel_pmap, 0, NKPT * NBPDR - 1);
|
||||
|
@ -242,9 +242,6 @@ struct msgbuf *msgbufp = 0;
|
||||
*/
|
||||
static caddr_t crashdumpmap;
|
||||
|
||||
#ifdef SMP
|
||||
extern pt_entry_t *SMPpt;
|
||||
#endif
|
||||
static pt_entry_t *PMAP1 = 0, *PMAP2;
|
||||
static pt_entry_t *PADDR1 = 0, *PADDR2;
|
||||
#ifdef SMP
|
||||
@ -1305,11 +1302,7 @@ pmap_pinit(pmap_t pmap)
|
||||
LIST_INSERT_HEAD(&allpmaps, pmap, pm_list);
|
||||
mtx_unlock_spin(&allpmaps_lock);
|
||||
/* Wire in kernel global address entries. */
|
||||
/* XXX copies current process, does not fill in MPPTDI */
|
||||
bcopy(PTD + KPTDI, pmap->pm_pdir + KPTDI, nkpt * sizeof(pd_entry_t));
|
||||
#ifdef SMP
|
||||
pmap->pm_pdir[MPPTDI] = PTD[MPPTDI];
|
||||
#endif
|
||||
|
||||
/* install self-referential address mapping entry(s) */
|
||||
for (i = 0; i < NPGPTD; i++) {
|
||||
@ -1552,9 +1545,6 @@ pmap_release(pmap_t pmap)
|
||||
|
||||
bzero(pmap->pm_pdir + PTDPTDI, (nkpt + NPGPTD) *
|
||||
sizeof(*pmap->pm_pdir));
|
||||
#ifdef SMP
|
||||
pmap->pm_pdir[MPPTDI] = 0;
|
||||
#endif
|
||||
|
||||
pmap_qremove((vm_offset_t)pmap->pm_pdir, NPGPTD);
|
||||
|
||||
|
@ -121,27 +121,16 @@
|
||||
#endif
|
||||
|
||||
#ifndef NKPDE
|
||||
#ifdef SMP
|
||||
#define NKPDE (KVA_PAGES - 1) /* number of page tables/pde's */
|
||||
#else
|
||||
#define NKPDE (KVA_PAGES) /* number of page tables/pde's */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The *PTDI values control the layout of virtual memory
|
||||
*
|
||||
* XXX This works for now, but I am not real happy with it, I'll fix it
|
||||
* right after I fix locore.s and the magic 28K hole
|
||||
*
|
||||
* SMP_PRIVPAGES: The per-cpu address space is 0xff80000 -> 0xffbfffff
|
||||
*/
|
||||
#ifdef SMP
|
||||
#define MPPTDI (NPDEPTD-1) /* per cpu ptd entry */
|
||||
#define KPTDI (MPPTDI-NKPDE) /* start of kernel virtual pde's */
|
||||
#else
|
||||
#define KPTDI (NPDEPTD-NKPDE)/* start of kernel virtual pde's */
|
||||
#endif /* SMP */
|
||||
#define KPTDI (NPDEPTD-NKPDE) /* start of kernel virtual pde's */
|
||||
#define PTDPTDI (KPTDI-NPGPTD) /* ptd entry that points to ptd! */
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user