1. 18 Jan, 2023 3 commits
    • Jeffrey Lee's avatar
      Add a new OS_ClaimProcessorVector API · 1ea531dd
      Jeffrey Lee authored
      The original OS_ClaimProcessorVector API had several flaws, including:
      
      * The vector claim process is non-atomic. For single-core use this can
      countered by disabling IRQs around the SWI until you've saved the old
      handler address (and by hoping you don't accidentally trigger an
      exception somewhere in the middle), but for multi-core there's no real
      solution.
      * Releasing handlers has to be done in the correct order
      * When releasing a handler, there's no guarantee that any current
      invocation of the handler has finished by the time the release SWI call
      returns. Like the claim process, this is mostly an issue for multi-core
      (or multi-thread) systems, where the only way to guarantee that another
      thread/core isn't running a handler is to have an outside observer (the
      kernel) keep track of things.
      
      To solve these issues, the new API (aka NewCPV / cpv2) takes the
      following approach:
      
      * The kernel maintains a linked list of handlers for each processor
      vector
      * Each linked list is protected via a spinrw lock, to provide MP-safety
      and to guarantee that any handler which is being removed will be idle by
      the time the SWI returns
      
      Extra functionality has also been added in:
      
      * Instead of being called in a "virgin" state (i.e. registers on entry
      are expected to match the register state from when the CPU raised the
      exception), each handler now accepts a context pointer which contains
      the ARM register dump and any CP15 registers that are relevant to the
      exception type. This helps ensure handlers behave correctly if recursive
      aborts are triggered (especially since it may be hard for a handler to
      know if it's going to perform an action that triggers a recursive
      abort).
      * Handlers accept a workspace pointer in R12. This avoids the need for
      handlers to be stub routines in RAM which load their workspace pointer
      from a PC-relative location, greatly simplifying things. E.g. standard
      CMHG veneers can now be directly registered as handlers (although the
      large number of registers that are saved/restored in the CMHG veneer
      makes this a bit inefficient).
      * Because all the exception registers are provided (and returned) via
      the register dump, handlers are free to corrupt most ARM registers. This
      should provide a small speed boost by reducing stacking/unstacking
      within the handlers themselves (although the extra work which is going
      on in the kernel is likely to cancel out those gains)
      * Handlers can now return in four different states:
        1. Exception claimed: The kernel will restore the registers from the
      register dump and return from the exception
        2. Pass on to next handler
        3. Pass on with an error. Currently the kernel ignores this error, but
      a future improvement would be to log it somewhere.
        4. Fail with a serious error. For ABT, UND & IRQ this will result in
      the stacks being flattened, the abort details being recorded (in the
      exception dump area & OS_ReadSysInfo 7), and the error being raised,
      just like an unhandled exception. For SWI it'll be as if the SWI failed
      with that error. For IRQ it's currently ignored.
      
      The ability to return serious errors means that some components which
      previously had to flatten the stacks and raise the error manually
      (FPEmulator, VFPSupport) can now leave the kernel to perform those
      actions, making them more future-proof/compatible with alternate kernel
      implementations.
      
      The address of a routine for calling the new CPV handlers has been added
      to OS_ReadSysInfo 6, to allow the SMP module to invoke the handlers for
      exceptions which occur on other cores.
      1ea531dd
    • Jeffrey Lee's avatar
      Enable synclib · a0e9849c
      Jeffrey Lee authored
      SEH makes sure that use of synclib by AbortTrap is safe (assuming all
      other code in the system which flattens the stacks also uses SEH).
      
      Synclib will also be a critical component of the new
      OS_ClaimProcessorVector API.
      a0e9849c
    • Jeffrey Lee's avatar
      Add a system for C++-like exception handlers · 93c6e33d
      Jeffrey Lee authored
      This change adds support for "Stack-based exception handlers", aka
      "SEH". Each privileged mode stack can contain a linked list of special
      exception handler stack frames, with the pointer to the head node stored
      in one of the words near the base of the stack memory (i.e. next to the
      C relocation offsets).
      
      Each SEH node in the stack has a handler function associated with it.
      
      When the kernel (or other SEH-aware components) flatten a stack, the
      corresponding handler functions will be called, to allow the code to
      perform suitable recovery actions, such as unlocking any spinlocks that
      the aborted operation was holding.
      
      Currently there's no support for the handler to "catch" the exception
      and halt the stack flattening - the stack will be flattened, the only
      thing the SEH handlers can do is try and make sure the system isn't left
      in a broken state.
      
      AbortTrap has been modified to make use of SEH (to protect its use of
      synclib), and a new test (attest_err3) has been added to make sure that
      it's working correctly.
      
      TaskControl_ResetStacks has been updated to perform SEH unwinding before
      it flattens the stacks.
      
      SEH functions & values are exposed via OS_ReadSysInfo 6, to allow
      external code to push/pop nodes or to invoke the handlers before they
      flatten the stack(s).
      93c6e33d
  2. 14 Jan, 2023 13 commits
  3. 05 Jan, 2023 1 commit
  4. 01 Jun, 2022 2 commits
  5. 07 Aug, 2021 4 commits
    • Jeffrey Lee's avatar
      Fix AbortTrap's handling of LDA instruction for emulated AP1 · 322fd3a6
      Jeffrey Lee authored
      When AP1 memory is being emulated (long descriptor page tables are in
      use), the AbortTrap machinery is used to emulate usermode read access.
      This provides coverage for all read instructions except those that
      AbortTrap handles via MemMap requests - LDREX, LDA, LDAEX, LDF & LFM.
      
      LDREX & LDAEX request both read & write access, so are fine (the MemMap
      request will get passed through to the registered AbortTrap handlers).
      
      LDF & LFM are irrelevant, since they only exist on ARM7500FE (on other
      machines FPEmulator will translate them to regular LDR/LDM, which are
      handled correctly)
      
      LDA however, will generate a plain "memmap with usermode read" request.
      When AbortTrap looks at the permissions of emulated AP1 it doesn't take
      into account the fact that the usermode read permission is being
      emulated, so it thinks that everything is fine and claims the memmap
      was successful, causing the abort handler to retry the instruction
      without making any changes, resulting in an infinite abort loop.
      
      Deal with this by detecting the above situation and also requesting
      usermode execute access. This will avoid the kernel (and hopefully the
      registered AbortTrap handlers) from thinking that the emulated AP1 is
      acceptable, without adversely affecting the behaviour of other
      instructions or access privileges. If no handler is present or the
      memmap request is denied, the abort will get passed on to the next stage
      of the abort handler (i.e. you'll get a standard data abort from trying
      to LDA from arbitrary emulated AP1 memory)
      
      The new test program (Dev/AbortTrap/attest_ap1) will check that this
      edge case is dealt with correctly.
      
      Tested on Pi 4, for both long & short page tables
      
      Version 6.59. Tagged as 'Kernel-6_59'
      322fd3a6
    • Jeffrey Lee's avatar
      Add safety checks to s.CPUFeatures · e2e5a722
      Jeffrey Lee authored
      To avoid CallASWI's CPUFeatures implementation getting dangerously out
      of sync with the kernel, add extra asserts to both sets of sources to
      check try and make sure both sets of sources get updated when new flags
      are added.
      e2e5a722
    • Jeffrey Lee's avatar
      Allocate OS_PlatformFeatures 0 bit 22 · 305dc195
      Jeffrey Lee authored
      Pyromaniac doesn't allow low-level control or examination of the memory
      map; allocate an OS_PlatformFeatures bit to allow software to directly
      detect this limitation instead of having to rely on the affected SWIs
      erroring.
      
      https://www.riscosopen.org/forum/forums/3/topics/16609
      305dc195
    • Jeffrey Lee's avatar
      Fix a couple of comment typos · e565ad40
      Jeffrey Lee authored
      e565ad40
  6. 28 Jul, 2021 17 commits
    • Jeffrey Lee's avatar
      Make OS_Memory 24 report Abortable DAs · b98ccef2
      Jeffrey Lee authored
      Version 6.58. Tagged as 'Kernel-6_58'
      b98ccef2
    • Jeffrey Lee's avatar
      Add AP 1 emulation for long descriptor page tables · f93d930d
      Jeffrey Lee authored
      The long descriptor page table format doesn't support RISC OS access
      privilege 1 (user RX, privileged RWX). Previously we were downgrading
      this to AP 0 (user RWX, privielged RWX), which obviously weakens the
      security of the memory. However now that we have an AbortTrap
      implementation, we can map the memory as "user none, privileged RWX" and
      provide user read support via AbortTrap's instruction decode & execute
      logic.
      
      There's no support for executing usermode code from the memory, but the
      compatibility issues caused by that are likely to be minimal.
      f93d930d
    • Jeffrey Lee's avatar
      AbortTrap prefetch abort support · 84c73735
      Jeffrey Lee authored
      Also make lazy task swapping aborts to use IFAR where possible, to
      ensure any Thumb-2/Jazelle instructions which cross page boundaries are
      handled correctly.
      84c73735
    • Jeffrey Lee's avatar
      Fix OS_ReadSysInfo 7 to record prefetch abort details · 5266c864
      Jeffrey Lee authored
      OS_ReadSysInfo 7 is meant to record the details of the last data or
      prefetch abort that was passed to the environment handlers. This was
      implemented in Ursula, but the code for recording the prefetch abort
      details got lost somewhere during the 32 bit conversion process. Restore
      it.
      5266c864
    • Jeffrey Lee's avatar
      Add abortable DA support · fccd5e2f
      Jeffrey Lee authored
      This implementation should be compatible with RISCOS Ltd's
      implementation.
      fccd5e2f
    • Jeffrey Lee's avatar
      Use decgen cache files · 5b6c1710
      Jeffrey Lee authored
      Sadly we need one file per combination of action files, but by adding
      these pre-generated cache files to git we can speed up building the
      kernel from clean by a significant amount.
      5b6c1710
    • Jeffrey Lee's avatar
      Add OS_AbortTrap implementation · c199c178
      Jeffrey Lee authored
      This supports all the load/store instructions, including FPA & VFP/NEON.
      Most instructions are handled directly via the base version of the
      AbortTrap API that was first implemented in RISC OS Select. However, to
      properly cope with LDREX/STREX, and future support for prefetch aborts,
      the API has been extended to allow the kernel to request that a block of
      memory is mapped in with certain permissions. For LDREX/STREX the kernel
      will then rewind the PC so that the instruction can be retried directly.
      
      Test code in Dev/AbortTrap exists in order to allow checking of all
      major functionality, along with code for building the code in a
      softloadable module for easier/quicker testing.
      c199c178
    • Jeffrey Lee's avatar
      OS_PlatformFeatures 34: Report presence of some CP15 regs · 3d5802b0
      Jeffrey Lee authored
      Report whether:
      * DFAR & DFSR are writable
      * IFAR, IFSR, AIFSR, ADFSR are implemented
      3d5802b0
    • Jeffrey Lee's avatar
      Add extra ops to hdr/Copro15ops · 994013b4
      Jeffrey Lee authored
      More data & prefetch abort registers
      994013b4
    • Jeffrey Lee's avatar
      Split AMB_LazyFixUp in two · de4dfa14
      Jeffrey Lee authored
      If lazy task swapping is active, but it isn't a lazy task swapping
      abort, AMB_LazyFixUp will force all of application space to be mapped
      in, in order to protect the data/prefetech abort environment handlers
      from triggering unexpected recursive aborts (which could easily happen
      if the handlers make use of application space in any way). Recursive
      aborts generally aren't tolerated by these handlers because they're
      entered in ABT32 mode and may rely on the DFSR/DFAR registers being
      correct.
      
      To allow for more stages to be added to the abort handler inbetween lazy
      task swapping fixup & invoking the abort environment handler,
      AMB_LazyFixUp has now been split in two so that the code which maps in
      all of application space can be excuted at a more suitable time.
      de4dfa14
    • Jeffrey Lee's avatar
      Improve LibKern · 85f92e4f
      Jeffrey Lee authored
      Add kalloc (malloc with an error pointer), free, _kernel_irqs_disabled,
      _kernel_irqs_off, _kernel_irqs_on, and a simple memcpy implementation.
      
      Export the symbols so they're actually usable from other object files.
      85f92e4f
    • Jeffrey Lee's avatar
      bc963b02
    • Jeffrey Lee's avatar
      Add extra LTORG to s.HAL · e7152ebd
      Jeffrey Lee authored
      Needed to resolve some literal pool range issues when long descriptor
      page table support is enabled
      e7152ebd
    • Jeffrey Lee's avatar
      Tidy up data abort handling · 876079a4
      Jeffrey Lee authored
      There was some redundant code needlessly pushing & popping various
      registers to the stack, left behind from when we removed the code that
      dealt with 26-bit processor vector reads on StrongARM & processed the
      proto-OS_AbortTrap "abort indirection nodes".
      876079a4
    • Jeffrey Lee's avatar
      Allow RW/ZI sections to be used · 2b665896
      Jeffrey Lee authored
      * Instruct the linker to place any RW/ZI data sections in the last ~16MB
      of the memory map, starting from &ff000000 (with the current toolchain,
      giving it a fixed base address is much easier than giving it a variable
      base address)
      * The RW/ZI section is mapped as completely inaccessible to user mode
      * The initial content of the RW section is copied over shortly after MMU
      startup (in Continue_after_HALInit)
      * Since link's -bin option produces a file containing a copy of the
      (zero-initialised) ZI section, the kernel binary is now produced from a
      "binary with AIF header" AIF with the help of the new 'kstrip' tool.
      kstrip extracts just the RO and RW sections, ensuring the ROM doesn't
      contain a redundant block of zeros for the ZI section.
      
      This should make it easier to use C code & arbitrary libraries within
      the kernel, providing they're compiled with suitable settings (e.g.
      non-module, no FP, no stack checking, like HALs typically use)
      2b665896
    • Timothy E Baldwin's avatar
      Support multiple source files · 9bc4a580
      Timothy E Baldwin authored
      9bc4a580
    • Timothy E Baldwin's avatar
      Build kernel using relocatable AOF · 5835d7b0
      Timothy E Baldwin authored
      * Add KernelBaseA absolute symbol.
      * Use KernelBase - KernelBaseA to convert some expressions
        to/from AREA relative form.
      * Link to correct address.
      * Remove ORG directive
      * Move EndOfKernel to separate AREA
      5835d7b0