On amd64, arm64 and i386, we have the possibility to switch between TLS
areas in userspace. The nice thing about this is that it makes it easier
to do light-weight threading, if we ever feel like doing that. On armv6,
let's go into the same direction by making it possible to safely use the
TPIDRURW register, which is intended for this purpose.
Clean up the ARMv6 code to remove md_tp entirely. Simply add a dedicated
field to the PCB to hold the value of TPIDRURW across context switches,
like we do for any other register. As userspace currently uses the
read-only TPIDRURO register, simply ensure that we keep both values in
sync where possible. The system calls for modifying the read-only
register will simply write the intended value into both registers, so
that it lazily ends up in the PCB during the next context switch.
Reviewed by: https://reviews.freebsd.org/D7951
Approved by: andrew
Reviewed by: imp
Differential Revision: https://reviews.freebsd.org/D7951
Right now, userspace (fast) gettimeofday(2) on x86 only works for
RDTSC. For older machines, like Core2, where RDTSC is not C2/C3
invariant, and which fall to HPET hardware, this means that the call
has both the penalty of the syscall and of the uncached hw behind the
QPI or PCIe connection to the sought bridge. Nothing can me done
against the access latency, but the syscall overhead can be removed.
System already provides mappable /dev/hpetX devices, which gives
straight access to the HPET registers page.
Add yet another algorithm to the x86 'vdso' timehands. Libc is updated
to handle both RDTSC and HPET. For HPET, the index of the hpet device
to mmap is passed from kernel to userspace, index might be changed and
libc invalidates its mapping as needed.
Remove cpu_fill_vdso_timehands() KPI, instead require that
timecounters which can be used from userspace, to provide
tc_fill_vdso_timehands{,32}() methods. Merge i386 and amd64
libc/<arch>/sys/__vdso_gettc.c into one source file in the new
libc/x86/sys location. __vdso_gettc() internal interface is changed
to move timecounter algorithm detection into the MD code.
Measurements show that RDTSC even with the syscall overhead is faster
than userspace HPET access. But still, userspace HPET is three-four
times faster than syscall HPET on several Core2 and SandyBridge
machines.
Tested by: Howard Su <howard0su@gmail.com>
Sponsored by: The FreeBSD Foundation
MFC after: 1 month
Differential revision: https://reviews.freebsd.org/D7473
fully-pessimized implementation that requires a type to be aligned to
its natural size.
On armv6+ the compiler might generate load-/store-multiple instructions
which require 4-byte alignment even though the source code is only
accessing individual uint32_t values in a way that doesn't require any
particular alignment at all. The compiler apparently feels free to
combine multiple accesses into a single instruction that requires a
more-strict alignment, and no set of compiler flags seems to disable
this behavior (at least in clang 3.8).
This fixes alignment faults on arm systems using wifi adapters. The
wifi code uses ALIGNED_POINTER(p, uint32_t) to decide whether it needs
to copy-align tcp headers. Because clang is combining several uint32_t
accesses into a single ldm instruction, we need to say that accessing a
uint32_t requires 4-byte alignment.
Approved by: re(gjb)
are no longer natural-alignment strict, there are still some restrictions.
FreeBSD network code assumes data is naturally-aligned or is running
on a platform with no restrictions; pointers are not annotated to
indicate the data pointed to may be packed or unaligned. The clang
optimizer can sometimes combine the load or store of a pair of adjacent
32-bit values into a single doubleword load/store, and that operation
requires at least 4-byte alignment. __NO_STRICT_ALIGNMENT can lead
to tcp headers being only 2-byte aligned.
Note that alignment faults remain disabled on armv6, this change reverts
only the defining of the symbol which leads to some overly-agressive code
shortcuts when building common/shared drivers and network code for arm.
Approved by: re(kib)
the exact CPU we are running on to set the cpu functions. Relax the check
to ignore the CPU revision. Even so this may still be too specific.
Reviewed by: mmel
Sponsored by: ABT Systems Ltd
Differential Revision: https://reviews.freebsd.org/D6504
- Reset debug architecture and enable monitor for secondary
CPUs in init_secondary() rather than when configuring watchpoint, etc.
- Disable HW debugging capabilities when one of the CPU cores fails
to set up.
- Use dbg_capable() in a more atomic manner to avoid any mismatch
between CPUs.
Differential Revision: https://reviews.freebsd.org/D6009
to match the new state of affairs. The hardware we support has always been
able to do unaligned accesses, we've just never enabled it until now.
This brings FreeBSD into line with all the other major OSes, and should help
with the growing volume of 3rd-party software that assumes unaligned access
will just work on armv6 and armv7.
have ACLE support built in. The ACLE (ARM C Language Extensions) defines
a set of standardized symbols which indicate the architecture version and
features available. ACLE support is built in to modern compilers (both
clang and gcc), but absent from gcc prior to 4.4.
ARM (the company) provides the acle-compat.h header file to define the
right symbols for older versions of gcc. Basically, acle-compat.h does
for arm about the same thing cdefs.h does for freebsd: defines
standardized macros that work no matter which compiler you use. If ARM
hadn't provided this file we would have ended up with a big #ifdef __arm__
section in cdefs.h with our own compatibility shims.
Remove #include <machine/acle-compat.h> from the zillion other places (an
ever-growing list) that it appears. Since style(9) requires sys/types.h
or sys/param.h early in the include list, and both of those lead to
including cdefs.h, only a couple special cases still need to include
acle-compat.h directly.
Loves it: imp
where possible. In the places that doesn't work (multi-line inline asm,
and places where the old armv4 cpufuncs mechanism is used), annotate the
accesses with a comment that includes SCTLR. Now a grep -i sctlr can find
all the system control register manipulations.
No functional changes.
compilers can emit arm instructions that require 8-byte alignment. The
alignment-sensitive instructions were added in armv5, which has to be
supported by our combined v4/v5 kernels, so the value is set uncoditionally
for all arm architecture versions.
Also adjust the comment to explain in more detail why the macros have the
form and values they do.
Per advice from bde@, maintain the unsignedness of the value of _ALIGNBYTES
(but do so using his second choice of allowing sizeof() to supply the
unsignedness, rather than just hardcoding '8U', which in my mind would
require an even more verbose comment to explain why it's right). Also
explain in the comment that the resulting type of _ALIGN() is equivelent
to uinptr_t on arm (32-bit unsigned int), but it's purposely spelled as
"unsigned" to avoid problems with including other header files. Even
including machine/_types.h to allow use of __uintptr_t causes compilation
failures because of this header being included (indirectly) in asm code.
The discussion that led to this change (albeit at a glacial pace) is at
https://lists.freebsd.org/pipermail/svn-src-head/2014-November/064593.html
implementations. Early in the boot the kernel will use an approximate,
however after the timer has been probed it will switch to a more accurate
implementation.
Reviewed by: manu
Sponsored by: ABT Systems Ltd
Differential Revision: https://reviews.freebsd.org/D5762
and R/W emulation aborts under pmap lock.
There were two reasons for using of atomic operations:
(1) the pmap code is based on i386 one where they are used,
(2) there was an idea that access and R/W emulation aborts should be
handled as quick as possible, without pmap locking.
However, the atomic operations in i386 pmap code are used only because
page table entries may be modified by hardware. At the beginning, we
were not sure that it's the only reason. So even if arm hardware does
not modify them, we did not risk to not use them at that time. Further,
it turns out after some testing that using of pmap lock for access and
R/W emulation aborts does not bring any extra cost and there was no
measurable difference. Thus, we have decided finally to use pmap lock
for all operations on page table entries and so, there is no reason for
atomic operations on them. This makes the code cleaner and safer.
This decision introduce a question if it's safe to use pmap lock for
access and R/W emulation aborts. Anyhow, there may happen two cases in
general:
(A) Aborts while the pmap lock is locked already - this should not
happen as pmap lock is not recursive. However, under pmap lock only
internal kernel data should be accessed and such data should be mapped
with A bit set and NM bit cleared. If double abort happens, then
a mapping of data which has caused it must be fixed.
(B) Aborts while another lock(s) is/are locked - this already can
happen. There is no difference here if it's either access or R/W
emulation abort, or if it's some other abort.
Reviewed by: kib
(PL1) and unprivileged (PL0) read/write access. As cp15 virtual to
physical address translation operations are used, interrupts must be
disabled to get consistent result when they are called.
These functions should be used only in very specific occasions like
during abort handling or kernel debugging. One of them is going to be
used in pmap_fault(). However, complete function set is added. It cost
nothing, as they are inlined.
While here, fix comment of #endif.
Reviewed by: kib
universal.
(1) New struct intr_map_data is defined as a container for arbitrary
description of an interrupt used by a device. Typically, an interrupt
number and configuration relevant to an interrupt controller is encoded
in such description. However, any additional information may be encoded
too like a set of cpus on which an interrupt should be enabled or vendor
specific data needed for setup of an interrupt in controller. The struct
intr_map_data itself is meant to be opaque for INTRNG.
(2) An intr_map_irq() function is created which takes an interrupt
controller identification and struct intr_map_data as arguments and
returns global interrupt number which identifies an interrupt.
(3) A set of functions to be used by bus drivers is created as well as
a corresponding set of methods for interrupt controller drivers. These
sets take both struct resource and struct intr_map_data as one of the
arguments. There is a goal to keep struct intr_map_data in struct
resource, however, this way a final solution is not limited to that.
(4) Other small changes are done to reflect new situation.
This is only first step aiming to create stable interface for interrupt
controller drivers. Thus, some temporary solution is taken. Interrupt
descriptions for devices are stored in INTRNG and two specific mapping
function are created to be temporary used by bus drivers. That's why
the struct intr_map_data is not opaque for INTRNG now. This temporary
solution will be replaced by final one in next step.
Differential Revision: https://reviews.freebsd.org/D5730
- Don't convert atags address passed from U-Boot. It's real physical
address (and we have 1:1 mapping).
- Size of tags is encoded in words, not in bytes
This allow us to boot FreeBSD kernel (using uImage encapsulation) directly
from U-boot using 'bootm' command or by Android fastboot loader.
For now, kernel uImage must be marked as Linux, but we can add support for
FreeBSD into U-Boot later.
controller IPI provider.
New struct intr_ipi is defined which keeps all info about an IPI:
its name, counter, send and dispatch methods. Generic intr_ipi_setup(),
intr_ipi_send() and intr_ipi_dispatch() functions are implemented.
An IPI provider must implement two functions:
(1) an intr_ipi_send_t function which is able to send an IPI,
(2) a setup function which initializes itself for an IPI and
calls intr_ipi_setup() with appropriate arguments.
Differential Revision: https://reviews.freebsd.org/D5700
the interrupt framework is also going to be used by another (MIPS)
architecture. IPI implementations may vary much across different
architectures.
An IPI implementation should still define INTR_IPI_COUNT and use
intr_ipi_setup_counters() to setup IPI counters which are inside of
intrcnt[] and intrnames[] arrays. Those are used for sysctl and ddb.
Then, intr_ipi_increment_count() should be used to increment obtained
counter.
Reviewed by: imp
Differential Revision: https://reviews.freebsd.org/D5459
intr_pic_init_secondary. Replace them with a direct call. On BCM2836
and ARMADA XP we need to add this function, but it can be empty.
Reviewed by: ian, imp
Sponsored by: ABT Systems Ltd
Differential Revision: https://reviews.freebsd.org/D5460
slightly wrong on the others. We should just check if mp_ncpus is set to
more than one CPU as we may wish to run on a single core even when SMP is
available.
Reviewed by: ian
Sponsored by: ABT Systems Ltd
Differential Revision: https://reviews.freebsd.org/D5458
or pte-v6.h in files which needs it.
There are quite internal definitions in pte-v4.h and pte-v6.h headers
specific for corresponding pmap implementation. These headers should be
included only in very few files and an intention is to not hide for
which implementation such files are.
Further, sys/arm/arm/elf_trampoline.c is an example of file which
uses armv4 like pmap implementation for both armv4 and armv6 platforms.
This is another reason why pte.h which includes specific header
according to __ARM_ARCH is not created.
Create new pmap.h which includes specific header according to
__ARM_ARCH.
Note that <machine/pmap.h> is included from <vm/pmap.h> so one common
<machine/pmap.h> must exist.
are not utilized there. Only domain #0 is used and there is no reference
to it in the whole pmap-v6.c. Thus initialize domain access register in
locore-v6.c without reference too.
It turned out that devmap.c is not only file in which PTE_DEVICE
is used and simultaneously, built for both armv4 and armv6 platforms.
When I tried to build all arm kernels before r295168 commit, it was
hid by some other local changes in my tree. I hope that this is just
temporary workaround before VM_MEMATTR_DEVICE could be used instead of
PTE_DEVICE outside of pmap code for __ARM_ARCH < 6.
instead of hiding behind pmap_map_chunk(). It's not longer needed
after old pmap-v6 code was removed.
For compatibility with __ARM_ARCH < 6, define PTE_DEVICE in devmap.c
file. Certainly, it would be nice if VM_MEMATTR_DEVICE could be used
even for __ARM_ARCH < 6.
do not depend on pmap internals. This is a preparation for hiding
internal pmap definitions as much as possible from the rest of system.
Simultaneously, the protection argument evaluation is fixed. Happily,
it did not effect the mappings. And it's the reason why it was not fixed
earlier.
Use per-CPU structure to store HW watchpoints registers state
for each CPU present in the system. Those registers will be restored
upon wake up from the STOP state if requested by the debug_monitor
code. The method is similar to the one introduced to AMD64.
We store all possible 16 registers for HW watchpoints
(maximum allowed by the architecture).
HW breakpoints are not maintained since they are used for single
stepping only.
Pointed out by: kib
Reviewed by: wma
No strong objections from: kib
Submitted by: Zbigniew Bodek <zbb@semihalf.com>
Obtained from: Semihalf
Sponsored by: Juniper Networks Inc.
Differential Revision: https://reviews.freebsd.org/D4338
This allows, for example, UEFI pass a memory map with some ram in this
region, but for us to ignore it. This is the case when running under the
qemu virt machine type.
Sponsored by: ABT Systems Ltd
Allows for using hardware watchpoints for 1, 2, 4, 8 byte long addresses.
The default configuration of watchpoint is RW but code allows to select
RO or WO and X.
Since debugging registers are per-CPU (CP14) the watchpoint is set on
the CPU that was lucky (or not) to enter DDB.
HW breakpoints are used to perform single step in KDB.
When HW breakpoint is enabled all watchpoints are temporary disabled
to avoid recursive abort on both watchpoint and breakpoint.
In case of branch, the breakpoint is set to both - next instruction
and possible branch address. This requires at least 2 breakpoints
supported in the CPU however this is a must for ARMv6/v7 CPUs.
Reviewed by: imp
Submitted by: Zbigniew Bodek <zbb@semihalf.com>
Obtained from: Semihalf
Sponsored by: Juniper Networks Inc.
Differential Revision: https://reviews.freebsd.org/D4037
pmap implementations on ARM. This way minidump code can be used without
any platform specific modification.
Also, this is the last piece missing for ARM_NEW_PMAP.
Differential Revision: https://reviews.freebsd.org/D5023
into a new function that other platforms can share.
This creates a new ofw_reg_to_paddr() function (in a new ofw_subr.c file)
that contains most of the existing ppc implementation, mostly unchanged.
The ppc code now calls the new MI code from the MD code, then creates a
ppc-specific bus_space mapping from the results. The new arm implementation
does the same in an arm-specific way.
This also moves the declaration of OF_decode_addr() from ofw_machdep.h to
openfirm.h, except on sparc64 which uses a different function signature.
This will help all FDT platforms to set up early console access using
OF_decode_addr().
The ci20 port (by kan@) is going to reuse almost all of the intrng code
since the SoC in question looks suspiciously like someone took an ARM
SoC design and replaced the ARM core with a MIPS core.
* migrate out the code;
* rename ARM_ -> INTR_;
* rename arm_ -> intr_;
* move the interrupt flush routine from intr.c / intrng.c into
arm/machdep_intr.c - removing the code duplication and removing
the ARM specific bits from here.
Thanks to the Star Wars: The Force Awakens premiere line for allowing
me a couple hours of quiet time to finish the universe builds.
Tested:
* make universe
TODO:
* The structure definitions in subr_intr.c still includes machine/intr.h
which requires one duplicates all of the intrng definitions in
the platform code (which kan has done, and I think we don't have to.)
Instead I should break out the generic things (function declarations,
common intr structures, etc) into a separate header.
* Kan has requested I make the PIC based IPI stuff optional.
(1) The pmap argument passed to the function must be current pmap only.
(2) The process must be single threaded as the function is called either
when a process is exiting or from exec_new_vmspace().
Remove pmap_tlb_flush_ng() which is not used anywhere now.
Approved by: kib (mentor)
clock_gettime(2) on ARMv7 and ARMv8 systems which have architectural
generic timer hardware. It is similar how the RDTSC timer is used in
userspace on x86.
Fix a permission problem where generic timer access from EL0 (or
userspace on v7) was not properly initialized on APs.
For ARMv7, mark the stack non-executable. The shared page is added for
all arms (including ARMv8 64bit), and the signal trampoline code is
moved to the page.
Reviewed by: andrew
Discussed with: emaste, mmel
Sponsored by: The FreeBSD Foundation
Differential revision: https://reviews.freebsd.org/D4209
Boundary Trace to assembly to reduce the overhead of these checks.
Submitted by: Howard Su <howard0su@gmail.com>
Relnotes: Yes
Differential Revision: https://reviews.freebsd.org/D4266
- add new TEX class for WT cacheable memory
- export new TEX class to kernel as VM_MEMATTR_WT attribute
- add new aliases VM_MEMATTR_WRITE_COMBINING and
VM_MEMATTR_WRITE_BACK, it's used in DRM code
Note:
Only Cortex A8 supports WT caching in HW. On rest of Cortex CPUs,
WT requests is treated as uncacheable.
Approved by: kib (mentor)
Replace tlb_flush_local() by tlb_flush() as even not global mappings
could be fetched to TLB(s) on other cores by speculative table walk.
From OS point of view, it was not a problem as either such mappings
were not used anymore or they were flushed from TLB(s) when reused.
However, from hardware point of view, it was a problem. Not flushed
mappings could be a target for speculative reads or prefetches (which
might be quite aggresive on ARM cores). As speculative read can fill
cacheline, it can cause a real problem, when physical page is reused,
but mapped with different memory attributes.
Anyhow, it's good to have only valid mappings in TLB(s).
Approved by: kib (mentor)
This structure must be binary compatible regardless of PMAP
version being used. Create reserved section for NEW_PMAP to
make other variables be placed exactly in the same memory
addresses. This fixes kgdb/gdb behavoiur, which uses pcb.h stuctures.
The NEW_PMAP is kernel flag, so it does not propagate to the buildworld,
what makes the tools using pcb.h unable to parse PCB data.
Reviewed by: mmel, kib
Submitted by: Wojciech Macek <wma@semihalf.com>
Obtained from: Semihalf
Sponsored by: Juniper Networks Inc.
Differential Revision: https://reviews.freebsd.org/D4011
Allow manipulation with PSR_A bit on ARMv6+.
Remove declaration of unused functions.
This effectively enables asynchronous aborts on early bootstrap stage,
which previously was not enabled due to an error in enable_interrupts().
PR: 201434
Reported by: Gregory Soutade <soutade at gmail.com>
Approved by: kib (mentor)
function which checks an address for privileged (PL1) write access.
The function is inlined so it does not bring any cost, but makes
function set for checking privileged access complete.
Approved by: kib (mentor)
little-endian configuration for 64-bit variant is supported.
Reviewed by: mmel
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D4113
as of r288992 use it to manage the CCNT.
Use the CNNT for get_cyclecount() instead of binuptime() when device pmu
is compiled in; if it fails to attach, fall back to the former method.
Enable by default for the BeagleBoneBlack configuration.
Optained from: Cambridge/L41
Sponsored by: DARPA/AFRL
Reviewed by: andrew
Differential Revision: https://reviews.freebsd.org/D3837