Comments (5)
I found out that the raspberry pi 4 uses the GIC-400 interrupt controller. I used the CoreLinkTM GIC-400 Generic Interrupt Controller Manual, ARM Generic Interrupt Controller Architecture Specification, and the BCM2711 ARM Peripherals Manual to get information about it.
To implement the timer interrupt we need the following information:
- The base address of the GIC-400
- The address for the Distributor Base
- The address for the CPU Base
- Enable the Interrupt Set-Enable Registers
- Allow us to forward the corresponding interrupt to the CPU interfaces.
- Interrupt Acknowledge Register
- Tell the processor which interrupt fired.
- End Of Interrupt Register
- Indicates to the Distributor that it can forward the new highest priority pending interrupt
- Interrupt Processor Targets Registers
- Tells the Distributor to which CPU interface it should forward the interrupt
- Time interrupt ID
- VideoCore interrupts start at the interrupt ID of 96 (see page 87 in the BCM2711 ARM Peripherals Manual). If you look at the table on page 86 of the BCM2711 ARM Peripherals Manual, we need the index 0, 1, 2, and 3. Which then corespondents to the IDs of 96, 97, 98, and 99.
The irq.h file would then look like this:
#ifndef _P_IRQ_H
#define _P_IRQ_H
#include <peripherals/base.h>
#define GIC_BASE 0xFF840000
#define GICD_DIST_BASE (GIC_BASE+0x00001000)
#define GICC_CPU_BASE (GIC_BASE+0x00002000)
#define GICD_ENABLE_IRQ_BASE (GICD_DIST_BASE+0x00000100)
#define GICC_IAR (GICC_CPU_BASE+0x0000000C)
#define GICC_EOIR (GICC_CPU_BASE+0x00000010)
#define GIC_IRQ_TARGET_BASE (GICD_DIST_BASE+0x00000800)
//VC (=VideoCore) starts at 96
#define SYSTEM_TIMER_IRQ_0 (0x60) //96
#define SYSTEM_TIMER_IRQ_1 (0x61) //97
#define SYSTEM_TIMER_IRQ_2 (0x62) //98
#define SYSTEM_TIMER_IRQ_3 (0x63) //99
#endif
The irq.c looks then as follows:
#include "utils.h"
#include "printf.h"
#include "timer.h"
#include "entry.h"
#include "peripherals/irq.h"
#include "arm/sysregs.h"
const char *entry_error_messages[] = {
"SYNC_INVALID_EL1t",
"IRQ_INVALID_EL1t",
"FIQ_INVALID_EL1t",
"ERROR_INVALID_EL1T",
"SYNC_INVALID_EL1h",
"IRQ_INVALID_EL1h",
"FIQ_INVALID_EL1h",
"ERROR_INVALID_EL1h",
"SYNC_INVALID_EL0_64",
"IRQ_INVALID_EL0_64",
"FIQ_INVALID_EL0_64",
"ERROR_INVALID_EL0_64",
"SYNC_INVALID_EL0_32",
"IRQ_INVALID_EL0_32",
"FIQ_INVALID_EL0_32",
"ERROR_INVALID_EL0_32"
};
void enable_interrupt(unsigned int irq) {
printf("%x\r\n", irq);
unsigned int n = irq / 32;
unsigned int offset = irq % 32;
unsigned int enableRegister = GICD_ENABLE_IRQ_BASE + (4*n);
printf("EnableRegister: %x\r\n", enableRegister);
put32(enableRegister, 1 << offset);
}
void assign_target(unsigned int irq, unsigned int cpu) {
unsigned int n = irq / 4;
unsigned int targetRegister = GIC_IRQ_TARGET_BASE + (4*n);
// Currently we only enter the target CPU 0
put32(targetRegister, get32(targetRegister) | (1 << 8));
}
void show_invalid_entry_message(int type, unsigned long esr, unsigned long address) {
printf("%s, ESR: %x, address, %x\r\n", entry_error_messages[type], esr, address);
}
void enable_interrupt_controller() {
assign_target(SYSTEM_TIMER_IRQ_1, 0);
enable_interrupt(SYSTEM_TIMER_IRQ_1);
}
void handle_irq(void) {
unsigned int irq_ack_reg = get32(GICC_IAR);
unsigned int irq = irq_ack_reg & 0x2FF;
switch (irq) {
case (SYSTEM_TIMER_IRQ_1):
handle_timer_irq();
put32(GICC_EOIR, irq_ack_reg);
break;
default:
printf("Unknown pending irq: %x\r\n", irq);
break;
}
}
from raspberry-pi-os.
hello past self, here's what I think is happening after some testing:
Low Level Devel doesn't need to configure the GIC because he used a custom armstub
to start the RPI4, which does not enable the GIC. The default armstub
probably sets up the GIC which causes the "ARMC" interrupt handling code to fail. An interesting point is that according to the rpi docs, the GIC is enabled by default, but once I remove the GIC enabling code in the armstub
, the ARMC code works again, I guess this means that the GIC needs to be explicitly enabled in the armstub
.
With all this, I think ARMC is a part of the legacy interrupt controller, but still I don't know what "ARMC" stands for.
A good reference for GIC enabling code can be found in raspberrypi/tools.
from raspberry-pi-os.
@rhythm16 I hope I can provide some answers to your questions.
- I think ARMC stands for ARM-Core, which is used to send interrupts to all cores and you can find the registers in Table 117. ARMC Interrupt Registers in the BCM2711 ARM Peripherals Manual
- As for my understanding, the ARMC does not support VC interrupts (see Table 117. ARMC Interrupt Registers in the BCM2711 ARM Peripherals Manual and page 83)
- I think you don't have to configure both since all interrupts go through the GIC (if I interpret the diagram on page 87 in the BCM2711 ARM Peripherals Manual correctly)
Please correct me if I'm wrong somewhere.
from raspberry-pi-os.
@maxstreitberger thanks for your effort, but do you know why doesn't Low Level Devel need to configure the GIC?
I (rpi4b) also followed the youtube video and everything works fine. By now I'm just confused. The bcm2711 peripheral datasheet doesn't explain clearly,
what are the ARMC registers?
why do the ARMC registers control the VC interrupts when on page 87 the VC interrupts are connected to the GIC?
why is ARMC also listed as an interrupt source?
should I configure both the ARMC registers and the GIC?
so many questions... I'd be very thankful if anyone can help.
from raspberry-pi-os.
Brilliant. I spent hours trying to figure out how to get timer interrupts working on my raspberry pi 4b. The GIC-400 initialization and interrupt setup code here is what I needed. Thanks!
from raspberry-pi-os.
Related Issues (20)
- Is it possible to boot up raspberry-pi-os from Uboot? HOT 2
- [Lesson05] RPi 4 system call not working HOT 3
- Connecting from Ubuntu to Raspberry Pi using USB to TTL, following linked guide just results in black bash windows on Ubuntu.
- [Lesson 1.4] Typo in `raspberry-pi-os/docs/lesson01/linux/kernel-startup.md` "childern" > "children" HOT 1
- Can i debug the raspberry pi os on the qemu and gdb? if it does, please tell me how to use it, thanks! HOT 2
- Has anyone gotten the MMU code to work on raspberry pi 4?
- Okay
- I connected waveshare screen to raspberry pi zero w and thereโs no option to rotate screen to right or left. What to do?
- [lesson5] after sys_write syscall exe, el0_sync happen
- lesson 01 set alt5 for gpio 14/15 HOT 4
- why not used c in utils.S HOT 1
- Exercice 1.1
- [exercises lesson06] after switch to user_process , it cannot response svc call HOT 1
- [Lesson04] Raspberry Pi 4 interrupts not working after first call to timer_tick() HOT 1
- How to find FUARTCLK in BCM2837 document HOT 1
- Filesyitem and drivers
- Possible missing of GPPUD control signal removal HOT 1
- Printf Long Support - issue in uli2a
- how does memzero works?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from raspberry-pi-os.