1
0
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:
Peter Wemm 2007-11-13 23:00:24 +00:00
parent bfbdccc1d1
commit 6dd3a6c06e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=173592
5 changed files with 25 additions and 141 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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! */
/*