Commit cf8e8658 authored by Ard Biesheuvel's avatar Ard Biesheuvel
Browse files

arch: Remove Itanium (IA-64) architecture

The Itanium architecture is obsolete, and an informal survey [0] reveals
that any residual use of Itanium hardware in production is mostly HP-UX
or OpenVMS based. The use of Linux on Itanium appears to be limited to
enthusiasts that occasionally boot a fresh Linux kernel to see whether
things are still working as intended, and perhaps to churn out some
distro packages that are rarely used in practice.

None of the original companies behind Itanium still produce or support
any hardware or software for the architecture, and it is listed as
'Orphaned' in the MAINTAINERS file, as apparently, none of the engineers
that contributed on behalf of those companies (nor anyone else, for that
matter) have been willing to support or maintain the architecture
upstream or even be responsible for applying the odd fix. The Intel
firmware team removed all IA-64 support from the Tianocore/EDK2
reference implementation of EFI in 2018. (Itanium is the original
architecture for which EFI was developed, and the way Linux supports it
deviates significantly from other architectures.) Some distros, such as
Debian and Gentoo, still maintain [unofficial] ia64 ports, but many have
dropped support years ago.

While the argument is being made [1] that there is a 'for the common
good' angle to being able to build and run existing projects such as the
Grid Community Toolkit [2] on Itanium for interoperability testing, the
fact remains that none of those projects are known to be deployed on
Linux/ia64, and very few people actually have access to such a system in
the first place. Even if there were ways imaginable in which Linux/ia64
could be put to good use today, what matters is whether anyone is
actually doing that, and this does not appear to be the case.

There are no emulators widely available, and so boot testing Itanium is
generally infeasible for ordinary contributors. GCC still supports IA-64
but its compile farm [3] no longer has any IA-64 machines. GLIBC would
like to get rid of IA-64 [4] too because it would permit some overdue
code cleanups. In summary, the benefits to the ecosystem of having IA-64
be part of it are mostly theoretical, whereas the maintenance overhead
of keeping it supported is real.

So let's rip off the band aid, and remove the IA-64 arch code entirely.
This follows the timeline proposed by the Debian/ia64 maintainer [5],
which removes support in a controlled manner, leaving IA-64 in a known
good state in the most recent LTS release. Other projects will follow
once the kernel support is removed.

[0] https://lore.kernel.org/all/CAMj1kXFCMh_578jniKpUtx_j8ByHnt=s7S+yQ+vGbKt9ud7+kQ@mail.gmail.com/
[1] https://lore.kernel.org/all/0075883c-7c51-00f5-2c2d-5119c1820410@web.de/
[2] https://gridcf.org/gct-docs/latest/index.html
[3] https://cfarm.tetaneutral.net/machines/list/
[4] https://lore.kernel.org/all/87bkiilpc4.fsf@mid.deneb.enyo.de/
[5] https://lore.kernel.org/all/ff58a3e76e5102c94bb5946d99187b358def688a.camel@physik.fu-berlin.de/



Acked-by: default avatarTony Luck <tony.luck@intel.com>
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
parent a0334bf7
Loading
Loading
Loading
Loading
+0 −246
Original line number Diff line number Diff line
==================================
Memory Attribute Aliasing on IA-64
==================================

Bjorn Helgaas <bjorn.helgaas@hp.com>

May 4, 2006


Memory Attributes
=================

    Itanium supports several attributes for virtual memory references.
    The attribute is part of the virtual translation, i.e., it is
    contained in the TLB entry.  The ones of most interest to the Linux
    kernel are:

	==		======================
        WB		Write-back (cacheable)
	UC		Uncacheable
	WC		Write-coalescing
	==		======================

    System memory typically uses the WB attribute.  The UC attribute is
    used for memory-mapped I/O devices.  The WC attribute is uncacheable
    like UC is, but writes may be delayed and combined to increase
    performance for things like frame buffers.

    The Itanium architecture requires that we avoid accessing the same
    page with both a cacheable mapping and an uncacheable mapping[1].

    The design of the chipset determines which attributes are supported
    on which regions of the address space.  For example, some chipsets
    support either WB or UC access to main memory, while others support
    only WB access.

Memory Map
==========

    Platform firmware describes the physical memory map and the
    supported attributes for each region.  At boot-time, the kernel uses
    the EFI GetMemoryMap() interface.  ACPI can also describe memory
    devices and the attributes they support, but Linux/ia64 currently
    doesn't use this information.

    The kernel uses the efi_memmap table returned from GetMemoryMap() to
    learn the attributes supported by each region of physical address
    space.  Unfortunately, this table does not completely describe the
    address space because some machines omit some or all of the MMIO
    regions from the map.

    The kernel maintains another table, kern_memmap, which describes the
    memory Linux is actually using and the attribute for each region.
    This contains only system memory; it does not contain MMIO space.

    The kern_memmap table typically contains only a subset of the system
    memory described by the efi_memmap.  Linux/ia64 can't use all memory
    in the system because of constraints imposed by the identity mapping
    scheme.

    The efi_memmap table is preserved unmodified because the original
    boot-time information is required for kexec.

Kernel Identity Mappings
========================

    Linux/ia64 identity mappings are done with large pages, currently
    either 16MB or 64MB, referred to as "granules."  Cacheable mappings
    are speculative[2], so the processor can read any location in the
    page at any time, independent of the programmer's intentions.  This
    means that to avoid attribute aliasing, Linux can create a cacheable
    identity mapping only when the entire granule supports cacheable
    access.

    Therefore, kern_memmap contains only full granule-sized regions that
    can referenced safely by an identity mapping.

    Uncacheable mappings are not speculative, so the processor will
    generate UC accesses only to locations explicitly referenced by
    software.  This allows UC identity mappings to cover granules that
    are only partially populated, or populated with a combination of UC
    and WB regions.

User Mappings
=============

    User mappings are typically done with 16K or 64K pages.  The smaller
    page size allows more flexibility because only 16K or 64K has to be
    homogeneous with respect to memory attributes.

Potential Attribute Aliasing Cases
==================================

    There are several ways the kernel creates new mappings:

mmap of /dev/mem
----------------

	This uses remap_pfn_range(), which creates user mappings.  These
	mappings may be either WB or UC.  If the region being mapped
	happens to be in kern_memmap, meaning that it may also be mapped
	by a kernel identity mapping, the user mapping must use the same
	attribute as the kernel mapping.

	If the region is not in kern_memmap, the user mapping should use
	an attribute reported as being supported in the EFI memory map.

	Since the EFI memory map does not describe MMIO on some
	machines, this should use an uncacheable mapping as a fallback.

mmap of /sys/class/pci_bus/.../legacy_mem
-----------------------------------------

	This is very similar to mmap of /dev/mem, except that legacy_mem
	only allows mmap of the one megabyte "legacy MMIO" area for a
	specific PCI bus.  Typically this is the first megabyte of
	physical address space, but it may be different on machines with
	several VGA devices.

	"X" uses this to access VGA frame buffers.  Using legacy_mem
	rather than /dev/mem allows multiple instances of X to talk to
	different VGA cards.

	The /dev/mem mmap constraints apply.

mmap of /proc/bus/pci/.../??.?
------------------------------

	This is an MMIO mmap of PCI functions, which additionally may or
	may not be requested as using the WC attribute.

	If WC is requested, and the region in kern_memmap is either WC
	or UC, and the EFI memory map designates the region as WC, then
	the WC mapping is allowed.

	Otherwise, the user mapping must use the same attribute as the
	kernel mapping.

read/write of /dev/mem
----------------------

	This uses copy_from_user(), which implicitly uses a kernel
	identity mapping.  This is obviously safe for things in
	kern_memmap.

	There may be corner cases of things that are not in kern_memmap,
	but could be accessed this way.  For example, registers in MMIO
	space are not in kern_memmap, but could be accessed with a UC
	mapping.  This would not cause attribute aliasing.  But
	registers typically can be accessed only with four-byte or
	eight-byte accesses, and the copy_from_user() path doesn't allow
	any control over the access size, so this would be dangerous.

ioremap()
---------

	This returns a mapping for use inside the kernel.

	If the region is in kern_memmap, we should use the attribute
	specified there.

	If the EFI memory map reports that the entire granule supports
	WB, we should use that (granules that are partially reserved
	or occupied by firmware do not appear in kern_memmap).

	If the granule contains non-WB memory, but we can cover the
	region safely with kernel page table mappings, we can use
	ioremap_page_range() as most other architectures do.

	Failing all of the above, we have to fall back to a UC mapping.

Past Problem Cases
==================

mmap of various MMIO regions from /dev/mem by "X" on Intel platforms
--------------------------------------------------------------------

      The EFI memory map may not report these MMIO regions.

      These must be allowed so that X will work.  This means that
      when the EFI memory map is incomplete, every /dev/mem mmap must
      succeed.  It may create either WB or UC user mappings, depending
      on whether the region is in kern_memmap or the EFI memory map.

mmap of 0x0-0x9FFFF /dev/mem by "hwinfo" on HP sx1000 with VGA enabled
----------------------------------------------------------------------

      The EFI memory map reports the following attributes:

        =============== ======= ==================
        0x00000-0x9FFFF WB only
        0xA0000-0xBFFFF UC only (VGA frame buffer)
        0xC0000-0xFFFFF WB only
        =============== ======= ==================

      This mmap is done with user pages, not kernel identity mappings,
      so it is safe to use WB mappings.

      The kernel VGA driver may ioremap the VGA frame buffer at 0xA0000,
      which uses a granule-sized UC mapping.  This granule will cover some
      WB-only memory, but since UC is non-speculative, the processor will
      never generate an uncacheable reference to the WB-only areas unless
      the driver explicitly touches them.

mmap of 0x0-0xFFFFF legacy_mem by "X"
-------------------------------------

      If the EFI memory map reports that the entire range supports the
      same attributes, we can allow the mmap (and we will prefer WB if
      supported, as is the case with HP sx[12]000 machines with VGA
      disabled).

      If EFI reports the range as partly WB and partly UC (as on sx[12]000
      machines with VGA enabled), we must fail the mmap because there's no
      safe attribute to use.

      If EFI reports some of the range but not all (as on Intel firmware
      that doesn't report the VGA frame buffer at all), we should fail the
      mmap and force the user to map just the specific region of interest.

mmap of 0xA0000-0xBFFFF legacy_mem by "X" on HP sx1000 with VGA disabled
------------------------------------------------------------------------

      The EFI memory map reports the following attributes::

        0x00000-0xFFFFF WB only (no VGA MMIO hole)

      This is a special case of the previous case, and the mmap should
      fail for the same reason as above.

read of /sys/devices/.../rom
----------------------------

      For VGA devices, this may cause an ioremap() of 0xC0000.  This
      used to be done with a UC mapping, because the VGA frame buffer
      at 0xA0000 prevents use of a WB granule.  The UC mapping causes
      an MCA on HP sx[12]000 chipsets.

      We should use WB page table mappings to avoid covering the VGA
      frame buffer.

Notes
=====

    [1] SDM rev 2.2, vol 2, sec 4.4.1.
    [2] SDM rev 2.2, vol 2, sec 4.4.6.
+0 −144
Original line number Diff line number Diff line
==========================
EFI Real Time Clock driver
==========================

S. Eranian <eranian@hpl.hp.com>

March 2000

1. Introduction
===============

This document describes the efirtc.c driver has provided for
the IA-64 platform.

The purpose of this driver is to supply an API for kernel and user applications
to get access to the Time Service offered by EFI version 0.92.

EFI provides 4 calls one can make once the OS is booted: GetTime(),
SetTime(), GetWakeupTime(), SetWakeupTime() which are all supported by this
driver. We describe those calls as well the design of the driver in the
following sections.

2. Design Decisions
===================

The original ideas was to provide a very simple driver to get access to,
at first, the time of day service. This is required in order to access, in a
portable way, the CMOS clock. A program like /sbin/hwclock uses such a clock
to initialize the system view of the time during boot.

Because we wanted to minimize the impact on existing user-level apps using
the CMOS clock, we decided to expose an API that was very similar to the one
used today with the legacy RTC driver (driver/char/rtc.c). However, because
EFI provides a simpler services, not all ioctl() are available. Also
new ioctl()s have been introduced for things that EFI provides but not the
legacy.

EFI uses a slightly different way of representing the time, noticeably
the reference date is different. Year is the using the full 4-digit format.
The Epoch is January 1st 1998. For backward compatibility reasons we don't
expose this new way of representing time. Instead we use something very
similar to the struct tm, i.e. struct rtc_time, as used by hwclock.
One of the reasons for doing it this way is to allow for EFI to still evolve
without necessarily impacting any of the user applications. The decoupling
enables flexibility and permits writing wrapper code is ncase things change.

The driver exposes two interfaces, one via the device file and a set of
ioctl()s. The other is read-only via the /proc filesystem.

As of today we don't offer a /proc/sys interface.

To allow for a uniform interface between the legacy RTC and EFI time service,
we have created the include/linux/rtc.h header file to contain only the
"public" API of the two drivers.  The specifics of the legacy RTC are still
in include/linux/mc146818rtc.h.


3. Time of day service
======================

The part of the driver gives access to the time of day service of EFI.
Two ioctl()s, compatible with the legacy RTC calls:

	Read the CMOS clock::

		ioctl(d, RTC_RD_TIME, &rtc);

	Write the CMOS clock::

		ioctl(d, RTC_SET_TIME, &rtc);

The rtc is a pointer to a data structure defined in rtc.h which is close
to a struct tm::

  struct rtc_time {
          int tm_sec;
          int tm_min;
          int tm_hour;
          int tm_mday;
          int tm_mon;
          int tm_year;
          int tm_wday;
          int tm_yday;
          int tm_isdst;
  };

The driver takes care of converting back an forth between the EFI time and
this format.

Those two ioctl()s can be exercised with the hwclock command:

For reading::

	# /sbin/hwclock --show
	Mon Mar  6 15:32:32 2000  -0.910248 seconds

For setting::

	# /sbin/hwclock --systohc

Root privileges are required to be able to set the time of day.

4. Wakeup Alarm service
=======================

EFI provides an API by which one can program when a machine should wakeup,
i.e. reboot. This is very different from the alarm provided by the legacy
RTC which is some kind of interval timer alarm. For this reason we don't use
the same ioctl()s to get access to the service. Instead we have
introduced 2 news ioctl()s to the interface of an RTC.

We have added 2 new ioctl()s that are specific to the EFI driver:

	Read the current state of the alarm::

		ioctl(d, RTC_WKALM_RD, &wkt)

	Set the alarm or change its status::

		ioctl(d, RTC_WKALM_SET, &wkt)

The wkt structure encapsulates a struct rtc_time + 2 extra fields to get
status information::

  struct rtc_wkalrm {

          unsigned char enabled; /* =1 if alarm is enabled */
          unsigned char pending; /* =1 if alarm is pending  */

          struct rtc_time time;
  }

As of today, none of the existing user-level apps supports this feature.
However writing such a program should be hard by simply using those two
ioctl().

Root privileges are required to be able to set the alarm.

5. References
=============

Checkout the following Web site for more information on EFI:

http://developer.intel.com/technology/efi/
+0 −1067

File deleted.

Preview size limit exceeded, changes collapsed.

+0 −3
Original line number Diff line number Diff line
.. SPDX-License-Identifier: GPL-2.0

.. kernel-feat:: $srctree/Documentation/features ia64

Documentation/arch/ia64/fsys.rst

deleted100644 → 0
+0 −303

File deleted.

Preview size limit exceeded, changes collapsed.

Loading