From 26279767e41f5f95bba899fae00f3652e4c17154 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sun, 14 Feb 2010 16:56:24 +0000 Subject: [PATCH] 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. --- sys/ia64/acpica/madt.c | 6 ++---- sys/ia64/ia64/bus_machdep.c | 21 +++++++++++++++++++++ sys/ia64/ia64/efi.c | 6 ++++-- sys/ia64/ia64/interrupt.c | 3 +-- sys/ia64/ia64/machdep.c | 10 +++++++++- sys/ia64/ia64/mp_machdep.c | 26 ++++++++++++++------------ sys/ia64/ia64/pmap.c | 8 +++++--- sys/ia64/ia64/sapic.c | 7 ++++--- sys/ia64/include/bus.h | 26 ++++++-------------------- sys/ia64/include/intr.h | 24 +++++++++++------------- sys/ia64/include/md_var.h | 16 ++++++++-------- sys/ia64/include/pmap.h | 2 +- sys/ia64/include/vmparam.h | 1 - 13 files changed, 86 insertions(+), 70 deletions(-) diff --git a/sys/ia64/acpica/madt.c b/sys/ia64/acpica/madt.c index 254308846b1e..51193fffcc80 100644 --- a/sys/ia64/acpica/madt.c +++ b/sys/ia64/acpica/madt.c @@ -31,8 +31,6 @@ #include -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; } diff --git a/sys/ia64/ia64/bus_machdep.c b/sys/ia64/ia64/bus_machdep.c index f9e019bfc642..cd9ebc8ce461 100644 --- a/sys/ia64/ia64/bus_machdep.c +++ b/sys/ia64/ia64/bus_machdep.c @@ -29,12 +29,33 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include 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) { diff --git a/sys/ia64/ia64/efi.c b/sys/ia64/ia64/efi.c index 7e6fdaa9ef83..d193f60c055a 100644 --- a/sys/ia64/ia64/efi.c +++ b/sys/ia64/ia64/efi.c @@ -33,6 +33,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include 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); } diff --git a/sys/ia64/ia64/interrupt.c b/sys/ia64/ia64/interrupt.c index 8a8cbb81a953..a90e8e8e4c6b 100644 --- a/sys/ia64/ia64/interrupt.c +++ b/sys/ia64/ia64/interrupt.c @@ -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"); diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index 8bebde2d5cc2..cddf6c0b8f96 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -85,6 +85,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -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; diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c index 9cbf7705df9a..c5ed48f501d6 100644 --- a/sys/ia64/ia64/mp_machdep.c +++ b/sys/ia64/ia64/mp_machdep.c @@ -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); diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c index 6a0e21498443..a2af574af57e 100644 --- a/sys/ia64/ia64/pmap.c +++ b/sys/ia64/ia64/pmap.c @@ -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; } /* diff --git a/sys/ia64/ia64/sapic.c b/sys/ia64/ia64/sapic.c index 00ef23490fcd..88bd01398728 100644 --- a/sys/ia64/ia64/sapic.c +++ b/sys/ia64/ia64/sapic.c @@ -42,6 +42,9 @@ #include #include +#include +#include + 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); diff --git a/sys/ia64/include/bus.h b/sys/ia64/include/bus.h index a2a02a09f5a8..bad4f85ac15f 100644 --- a/sys/ia64/include/bus.h +++ b/sys/ia64/include/bus.h @@ -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. diff --git a/sys/ia64/include/intr.h b/sys/ia64/include/intr.h index 7d59ef217d61..8651fdad110c 100644 --- a/sys/ia64/include/intr.h +++ b/sys/ia64/include/intr.h @@ -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); diff --git a/sys/ia64/include/md_var.h b/sys/ia64/include/md_var.h index 7fdcb2de5390..9a2f92a53b2c 100644 --- a/sys/ia64/include/md_var.h +++ b/sys/ia64/include/md_var.h @@ -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); diff --git a/sys/ia64/include/pmap.h b/sys/ia64/include/pmap.h index f878d279c5fc..e40d64766d18 100644 --- a/sys/ia64/include/pmap.h +++ b/sys/ia64/include/pmap.h @@ -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 *); diff --git a/sys/ia64/include/vmparam.h b/sys/ia64/include/vmparam.h index 9e65ea8fa2fd..e040e9af8d72 100644 --- a/sys/ia64/include/vmparam.h +++ b/sys/ia64/include/vmparam.h @@ -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)) /*