Summary
On x86-64, an eXtensible Host Controller (xHC) is responsible to interact with USB from the operating-system. The operating-system writes at conventional positions in RAM to read and write the registers of the xHC. What these registers do is explained in the xHCI specification. The keyboard is polled by the xHC at a certain interval using the Periodic Transfer Ring. When a transfer occurs, the xHC triggers an interrupt. The operating-system will then look in RAM for any change. If any change is detected, the operating-system puts a message on the message queue of the application which currently has focus.
Long answer
I don't know much about ARM and how it interfaces to USB. I've been in the process of writing an x86-64 kernel which interacts with USB keyboards so I'll answer for x86-64. By the way, x86-64 is the CPU architecture you find in most desktop computers today.
x86 CPUs can't interact with USB directly. They need a PCI compliant device of which some registers are mapped into main memory (RAM). This PCI device is called today the eXtensible Host Controller (xHC). There once was other names but they were all provided as a way for x86 CPUs to interact with USB. The xHCI specification describes the functioning of the xHC (see https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/extensible-host-controler-interface-usb-xhci.pdf).
When the computer boots, there is some firmware on the motherboard which probably questions the different PCI devices for the position of their memory mapped registers (I don't have more information on how). It then informs the operating-system (OS) of where these registers will land using the ACPI tables which is a conventional representation of hardware. The position of these tables is stated in the ACPI convention.
When the computer boots, firmware hands over control to the OS. The OS will look at the ACPI tables to find the base address of the PCI configuration space for the computer. Most often it will be always the same address. It doesn't even need to be actual physical memory. It can be anywhere even outside memory. On QEMU virtual machines (with 128MB of memory by default), the PCI config space is often found above the actual physical memory.
The PCI config space is then scanned with a conventional approach to device addressing. 798
Basically, each function of each device gets a config space. There can be several buses onto which can be up to 32 devices onto which can be up to 8 functions (see https://wiki.osdev.org/PCI). To find the base address of one function you need to use a basic arithmetic formula specified in the PCI convention as such: UINT64 configSpacePhysAddr = pciConfigBaseAddr + ((bus - first_bus) << 20 | device << 15 | function << 12); The value pciConfigBaseAddr is often 0x80000000. It cannot be relied on so it must be retrieved in the MCFG ACPI table which is located using other tables. The first table of the ACPI table chain is the RSDP table (see https://wiki.osdev.org/RSDP). The RSDP table has a conventional location and it allows to find all the other tables.
The function is specific to one protocol. For example, on a PCI compliant device which is an WIFI card and a Bluetooth card at the same time, you'll find 2 functions. Each function does more or less a specific thing (a specific protocol). Another example is the xHC from Intel. The xHC will be a device with only one function (to interface with USB).
Every PCI function gets several IDs which allow to identify the device and what it does (or to load a proper driver for it).
The xHC will present a complex interface to software with memory mapped registers. The OS will write to these registers to set up the xHC. The xHC is compatible with MSI-X. MSI-X is a new mechanism which allows to get interrupts directly bypassing the IOAPIC of x86 computers. The interrupt acts similarly to an inter-processor interrupt (also used to bootstrap other processors from core 0 or to control other cores in general).
The xHC has event rings, transfer rings and one command ring. All rings lie in RAM. The event rings are used by the xHC to tell software something happened. Most events will be accompanied with an interrupt. The vector that will be triggered is chosen by the OS using the MSI-X table. There can be up to 2048 different interrupt vectors when using the MSI-X capability of the xHC. The transfer rings are used by software to transfer data to or from USB devices. The command ring is used by software to send commands to the xHC. 798