mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-01 02:03:31 +00:00
Some code churn:
o Eliminate IA64_PHYS_TO_RR6 and change all places where the macro is used by calling either bus_space_map() or pmap_mapdev(). o Implement bus_space_map() in terms of pmap_mapdev() and implement bus_space_unmap() in terms of pmap_unmapdev(). o Have ia64_pib hold the uncached virtual address of the processor interrupt block throughout the kernel's life and access the elements of the PIB through this structure pointer. This is a non-functional change with the exception of using ia64_ld1() and ia64_st8() to write to the PIB. We were still using assignments, for which the compiler generates semaphore reads -- which cause undefined behaviour for uncacheable memory. Note also that the memory barriers in ipi_send() are critical for proper functioning. With all the mapping of uncached memory done by pmap_mapdev(), we can keep track of the translations and wire them in the CPU. This then eliminates the need to reserve a whole region for uncached I/O and it eliminates translation traps for device I/O accesses.
This commit is contained in:
parent
12fefae25c
commit
26279767e4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=203883
@ -31,8 +31,6 @@
|
||||
|
||||
#include <machine/md_var.h>
|
||||
|
||||
extern u_int64_t ia64_lapic_address;
|
||||
|
||||
struct sapic *sapic_create(int, int, u_int64_t);
|
||||
|
||||
static void
|
||||
@ -150,7 +148,7 @@ ia64_probe_sapics(void)
|
||||
/* Save the address of the processor interrupt block. */
|
||||
if (bootverbose)
|
||||
printf("\tLocal APIC address=0x%x\n", table->Address);
|
||||
ia64_lapic_address = table->Address;
|
||||
ia64_lapic_addr = table->Address;
|
||||
|
||||
end = (char *)table + table->Header.Length;
|
||||
p = (char *)(table + 1);
|
||||
@ -172,7 +170,7 @@ ia64_probe_sapics(void)
|
||||
case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: {
|
||||
ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic =
|
||||
(ACPI_MADT_LOCAL_APIC_OVERRIDE *)entry;
|
||||
ia64_lapic_address = lapic->Address;
|
||||
ia64_lapic_addr = lapic->Address;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -29,12 +29,33 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <machine/bus.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
extern u_long ia64_port_base;
|
||||
|
||||
#define __PIO_ADDR(port) \
|
||||
(void *)(ia64_port_base | (((port) & 0xfffc) << 10) | ((port) & 0xFFF))
|
||||
|
||||
int
|
||||
bus_space_map(bus_space_tag_t bst, bus_addr_t addr, bus_size_t size,
|
||||
int flags __unused, bus_space_handle_t *bshp)
|
||||
{
|
||||
|
||||
*bshp = (__predict_false(bst == IA64_BUS_SPACE_IO))
|
||||
? addr : (uintptr_t)pmap_mapdev(addr, size);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bus_space_unmap(bus_space_tag_t bst __unused, bus_space_handle_t bsh,
|
||||
bus_size_t size)
|
||||
{
|
||||
|
||||
pmap_unmapdev(bsh, size);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
bus_space_read_io_1(u_long port)
|
||||
{
|
||||
|
@ -33,6 +33,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/bootinfo.h>
|
||||
#include <machine/efi.h>
|
||||
#include <machine/sal.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
extern uint64_t ia64_call_efi_physical(uint64_t, uint64_t, uint64_t, uint64_t,
|
||||
uint64_t, uint64_t);
|
||||
@ -123,8 +125,8 @@ efi_boot_minimal(uint64_t systbl)
|
||||
md->md_virt =
|
||||
(void *)IA64_PHYS_TO_RR7(md->md_phys);
|
||||
else if (md->md_attr & EFI_MD_ATTR_UC)
|
||||
md->md_virt =
|
||||
(void *)IA64_PHYS_TO_RR6(md->md_phys);
|
||||
md->md_virt = pmap_mapdev(md->md_phys,
|
||||
md->md_pages * EFI_PAGE_SIZE);
|
||||
}
|
||||
md = efi_md_next(md);
|
||||
}
|
||||
|
@ -106,7 +106,6 @@ void
|
||||
interrupt(struct trapframe *tf)
|
||||
{
|
||||
struct thread *td;
|
||||
volatile struct ia64_interrupt_block *ib = IA64_INTERRUPT_BLOCK;
|
||||
uint64_t adj, clk, itc;
|
||||
int64_t delta;
|
||||
u_int vector;
|
||||
@ -128,7 +127,7 @@ interrupt(struct trapframe *tf)
|
||||
*/
|
||||
if (vector == 0) {
|
||||
PCPU_INC(md.stats.pcs_nextints);
|
||||
inta = ib->ib_inta;
|
||||
inta = ia64_ld1(&ia64_pib->ib_inta);
|
||||
if (inta == 15) {
|
||||
PCPU_INC(md.stats.pcs_nstrays);
|
||||
__asm __volatile("mov cr.eoi = r0;; srlz.d");
|
||||
|
@ -85,6 +85,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/efi.h>
|
||||
#include <machine/elf.h>
|
||||
#include <machine/fpu.h>
|
||||
#include <machine/intr.h>
|
||||
#include <machine/mca.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/mutex.h>
|
||||
@ -134,6 +135,10 @@ struct fpswa_iface *fpswa_iface;
|
||||
u_int64_t ia64_pal_base;
|
||||
u_int64_t ia64_port_base;
|
||||
|
||||
u_int64_t ia64_lapic_addr = PAL_PIB_DEFAULT_ADDR;
|
||||
|
||||
struct ia64_pib *ia64_pib;
|
||||
|
||||
static int ia64_sync_icache_needed;
|
||||
|
||||
char machine[] = MACHINE;
|
||||
@ -308,6 +313,8 @@ cpu_startup(void *dummy)
|
||||
* information.
|
||||
*/
|
||||
ia64_probe_sapics();
|
||||
ia64_pib = pmap_mapdev(ia64_lapic_addr, sizeof(*ia64_pib));
|
||||
|
||||
ia64_mca_init();
|
||||
|
||||
/*
|
||||
@ -677,7 +684,8 @@ ia64_init(void)
|
||||
for (md = efi_md_first(); md != NULL; md = efi_md_next(md)) {
|
||||
switch (md->md_type) {
|
||||
case EFI_MD_TYPE_IOPORT:
|
||||
ia64_port_base = IA64_PHYS_TO_RR6(md->md_phys);
|
||||
ia64_port_base = (uintptr_t)pmap_mapdev(md->md_phys,
|
||||
md->md_pages * EFI_PAGE_SIZE);
|
||||
break;
|
||||
case EFI_MD_TYPE_PALCODE:
|
||||
ia64_pal_base = md->md_phys;
|
||||
|
@ -68,8 +68,9 @@ MALLOC_DEFINE(M_SMP, "SMP", "SMP related allocations");
|
||||
|
||||
void ia64_ap_startup(void);
|
||||
|
||||
#define LID_SAPIC_ID(x) ((int)((x) >> 24) & 0xff)
|
||||
#define LID_SAPIC_EID(x) ((int)((x) >> 16) & 0xff)
|
||||
#define LID_SAPIC(x) ((u_int)((x) >> 16))
|
||||
#define LID_SAPIC_ID(x) ((u_int)((x) >> 24) & 0xff)
|
||||
#define LID_SAPIC_EID(x) ((u_int)((x) >> 16) & 0xff)
|
||||
#define LID_SAPIC_SET(id,eid) (((id & 0xff) << 8 | (eid & 0xff)) << 16);
|
||||
#define LID_SAPIC_MASK 0xffff0000UL
|
||||
|
||||
@ -114,7 +115,6 @@ ia64_store_mca_state(void* arg)
|
||||
void
|
||||
ia64_ap_startup(void)
|
||||
{
|
||||
volatile struct ia64_interrupt_block *ib = IA64_INTERRUPT_BLOCK;
|
||||
uint64_t vhpt;
|
||||
int vector;
|
||||
|
||||
@ -153,7 +153,7 @@ ia64_ap_startup(void)
|
||||
while (vector != 15) {
|
||||
ia64_srlz_d();
|
||||
if (vector == 0)
|
||||
vector = (int)ib->ib_inta;
|
||||
vector = (int)ia64_ld1(&ia64_pib->ib_inta);
|
||||
ia64_set_eoi(0);
|
||||
ia64_srlz_d();
|
||||
vector = ia64_get_ivr();
|
||||
@ -363,16 +363,18 @@ ipi_all_but_self(int ipi)
|
||||
void
|
||||
ipi_send(struct pcpu *cpu, int ipi)
|
||||
{
|
||||
volatile uint64_t *pipi;
|
||||
uint64_t vector;
|
||||
u_int lid;
|
||||
uint8_t vector;
|
||||
|
||||
pipi = (void *)IA64_PHYS_TO_RR6(ia64_lapic_address |
|
||||
((cpu->pc_md.lid & LID_SAPIC_MASK) >> 12));
|
||||
vector = (uint64_t)(ipi_vector[ipi] & 0xff);
|
||||
lid = LID_SAPIC(cpu->pc_md.lid);
|
||||
vector = ipi_vector[ipi];
|
||||
KASSERT(vector != 0, ("IPI %d is not assigned a vector", ipi));
|
||||
*pipi = vector;
|
||||
CTR3(KTR_SMP, "ipi_send(%p, %ld), cpuid=%d", pipi, vector,
|
||||
PCPU_GET(cpuid));
|
||||
|
||||
ia64_mf();
|
||||
ia64_st8(&(ia64_pib->ib_ipi[lid][0]), vector);
|
||||
ia64_mf_a();
|
||||
CTR4(KTR_SMP, "ipi_send(%p, %ld): cpuid=%d, vector=%u", cpu, ipi,
|
||||
PCPU_GET(cpuid), vector);
|
||||
}
|
||||
|
||||
SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, cpu_mp_unleash, NULL);
|
||||
|
@ -2145,9 +2145,12 @@ pmap_remove_write(vm_page_t m)
|
||||
* NOT real memory.
|
||||
*/
|
||||
void *
|
||||
pmap_mapdev(vm_offset_t pa, vm_size_t size)
|
||||
pmap_mapdev(vm_paddr_t pa, vm_size_t size)
|
||||
{
|
||||
return (void*) IA64_PHYS_TO_RR6(pa);
|
||||
vm_offset_t va;
|
||||
|
||||
va = pa | IA64_RR_BASE(6);
|
||||
return ((void *)va);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2156,7 +2159,6 @@ pmap_mapdev(vm_offset_t pa, vm_size_t size)
|
||||
void
|
||||
pmap_unmapdev(vm_offset_t va, vm_size_t size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -42,6 +42,9 @@
|
||||
#include <machine/sapicreg.h>
|
||||
#include <machine/sapicvar.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
static MALLOC_DEFINE(M_SAPIC, "sapic", "I/O SAPIC devices");
|
||||
|
||||
static int sysctl_machdep_apic(SYSCTL_HANDLER_ARGS);
|
||||
@ -52,8 +55,6 @@ SYSCTL_OID(_machdep, OID_AUTO, apic, CTLTYPE_STRING|CTLFLAG_RD,
|
||||
struct sapic *ia64_sapics[16]; /* XXX make this resizable */
|
||||
int ia64_sapic_count;
|
||||
|
||||
u_int64_t ia64_lapic_address = PAL_PIB_DEFAULT_ADDR;
|
||||
|
||||
struct sapic_rte {
|
||||
u_int64_t rte_vector :8;
|
||||
u_int64_t rte_delivery_mode :3;
|
||||
@ -165,7 +166,7 @@ sapic_create(u_int id, u_int base, u_int64_t address)
|
||||
|
||||
sa->sa_id = id;
|
||||
sa->sa_base = base;
|
||||
sa->sa_registers = IA64_PHYS_TO_RR6(address);
|
||||
sa->sa_registers = (uintptr_t)pmap_mapdev(address, 1048576);
|
||||
|
||||
mtx_init(&sa->sa_mtx, "I/O SAPIC lock", NULL, MTX_SPIN);
|
||||
|
||||
|
@ -132,28 +132,14 @@
|
||||
|
||||
|
||||
/*
|
||||
* Map a region of device bus space into CPU virtual address space.
|
||||
* Map and unmap a region of device bus space into CPU virtual address space.
|
||||
*/
|
||||
static __inline int
|
||||
bus_space_map(bus_space_tag_t bst, bus_addr_t addr, bus_size_t size __unused,
|
||||
int flags __unused, bus_space_handle_t *bshp)
|
||||
{
|
||||
|
||||
*bshp = (__predict_false(bst == IA64_BUS_SPACE_IO))
|
||||
? addr : IA64_PHYS_TO_RR6(addr);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Unmap a region of device bus space.
|
||||
*/
|
||||
static __inline void
|
||||
bus_space_unmap(bus_space_tag_t bst __unused, bus_space_handle_t bsh __unused,
|
||||
bus_size_t size __unused)
|
||||
{
|
||||
}
|
||||
int
|
||||
bus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
|
||||
bus_space_handle_t *);
|
||||
|
||||
void
|
||||
bus_space_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t size);
|
||||
|
||||
/*
|
||||
* Get a new handle for a subregion of an already-mapped area of bus space.
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Marcel Moolenaar
|
||||
* Copyright (c) 1998 Doug Rabson
|
||||
* All rights reserved.
|
||||
*
|
||||
@ -27,26 +28,23 @@
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_INTR_H_
|
||||
#define _MACHINE_INTR_H_
|
||||
#define _MACHINE_INTR_H_
|
||||
|
||||
/*
|
||||
* Layout of the Processor Interrupt Block.
|
||||
*/
|
||||
struct ia64_interrupt_block
|
||||
struct ia64_pib
|
||||
{
|
||||
u_int64_t ib_ipi[0x20000]; /* 1Mb of IPI interrupts */
|
||||
u_int8_t ib_reserved1[0xe0000];
|
||||
u_int8_t ib_inta; /* Generate INTA cycle */
|
||||
u_int8_t ib_reserved2[7];
|
||||
u_int8_t ib_xtp; /* XTP cycle */
|
||||
u_int8_t ib_reserved3[7];
|
||||
u_int8_t ib_reserved4[0x1fff0];
|
||||
uint64_t ib_ipi[65536][2]; /* 64K-way IPIs (1MB area). */
|
||||
uint8_t _rsvd1[0xe0000];
|
||||
uint8_t ib_inta; /* Generate INTA cycle. */
|
||||
uint8_t _rsvd2[7];
|
||||
uint8_t ib_xtp; /* External Task Priority. */
|
||||
uint8_t _rsvd3[7];
|
||||
uint8_t _rsvd4[0x1fff0];
|
||||
};
|
||||
|
||||
extern u_int64_t ia64_lapic_address;
|
||||
|
||||
#define IA64_INTERRUPT_BLOCK \
|
||||
(struct ia64_interrupt_block *)IA64_PHYS_TO_RR6(ia64_lapic_address)
|
||||
extern struct ia64_pib *ia64_pib;
|
||||
|
||||
int ia64_setup_intr(const char *name, int irq, driver_filter_t filter,
|
||||
driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep);
|
||||
|
@ -49,7 +49,7 @@ struct ia64_fdesc {
|
||||
#define IA64_CFM_RRB_FR(x) (((x) >> 25) & 0x7f)
|
||||
#define IA64_CFM_RRB_PR(x) (((x) >> 32) & 0x3f)
|
||||
|
||||
/* Concenience function (inline) to adjust backingstore pointers. */
|
||||
/* Convenience function (inline) to adjust backingstore pointers. */
|
||||
static __inline uint64_t
|
||||
ia64_bsp_adjust(uint64_t bsp, int nslots)
|
||||
{
|
||||
@ -60,22 +60,22 @@ ia64_bsp_adjust(uint64_t bsp, int nslots)
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
extern char sigcode[];
|
||||
extern char esigcode[];
|
||||
extern int szsigcode;
|
||||
extern long Maxmem;
|
||||
|
||||
struct _special;
|
||||
struct fpreg;
|
||||
struct reg;
|
||||
struct thread;
|
||||
struct trapframe;
|
||||
|
||||
/*
|
||||
* Return value from ia64_init. Describes stack to switch to.
|
||||
*/
|
||||
struct ia64_init_return {
|
||||
uint64_t bspstore;
|
||||
uint64_t sp;
|
||||
};
|
||||
|
||||
extern uint64_t ia64_lapic_addr;
|
||||
|
||||
extern long Maxmem;
|
||||
|
||||
void busdma_swi(void);
|
||||
int copyout_regstack(struct thread *, uint64_t *, uint64_t *);
|
||||
void cpu_mp_add(u_int, u_int, u_int);
|
||||
|
@ -132,7 +132,7 @@ vm_paddr_t pmap_kextract(vm_offset_t va);
|
||||
void pmap_kremove(vm_offset_t);
|
||||
void pmap_setdevram(unsigned long long basea, vm_offset_t sizea);
|
||||
int pmap_uses_prom_console(void);
|
||||
void *pmap_mapdev(vm_offset_t, vm_size_t);
|
||||
void *pmap_mapdev(vm_paddr_t, vm_size_t);
|
||||
void pmap_unmapdev(vm_offset_t, vm_size_t);
|
||||
unsigned *pmap_pte(pmap_t, vm_offset_t) __pure2;
|
||||
void pmap_set_opt (unsigned *);
|
||||
|
@ -132,7 +132,6 @@
|
||||
#define IA64_RR_BASE(n) (((u_int64_t) (n)) << 61)
|
||||
#define IA64_RR_MASK(x) ((x) & ((1L << 61) - 1))
|
||||
|
||||
#define IA64_PHYS_TO_RR6(x) ((x) | IA64_RR_BASE(6))
|
||||
#define IA64_PHYS_TO_RR7(x) ((x) | IA64_RR_BASE(7))
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user