Moving forward, there are two goals and both involve interrupts. One is that I want to get a 1000 Hz timer interrupt running. The other is to use interrupts in the serial driver. Without serial interrupts, the CPU will sit in a polling loop in the serial driver. Why is this bad you ask? Well for one thing the Kyu shell runs as the highest priority thread once the system is up and running. This means that it will hog the CPU -- and tests that get launched to run in lower priority threads (and they all so) will never execute.
Interrupts for the Zynq involve the ARM GIC (generic interrupt controller). I worked up a driver for this when working on the Orange Pi (Allwinner H3) and my hope is to be able to use that code here. I copy the file, anticipating the need to make changes. I do need to change the base addresses for the CPU and DIST section. It turns out that it just works!
I decide to start with the timer first and copy some code I wrote as part of my Ebaz bare metal experimentation. I work up a list of interrupt numbers (zynq_int.h) based on information in chapter 7 of the TRM -- then I adjust timer.c to fit in with the expectations in Kyu and it works! I have a printf in the timer handler, and it is printing endless messages on the console. I comment this out and add a print statement at the Kyu prompt that shows the timer count. A quick check suggests that it is indeed running at 1000 Hz.
SLCR is "system level control registers" and is somewhat stealthy in the TRM. The registers are enumerated in detail starting at page 1570 of Appendix B. We want PSS_RST_CTRL, which is at offset 0x200. The SLCR base is 0xF800_0000. This register has one active bit (the low bit). Set it to "1" and you reset the system. Sounds easy, but it doesn't work.
There is a trick. The SLCR registers need to be "unlocked" by writing a magic value to the register at offset 8. We could also lock them again, but that would be silly since the system is going to reboot anyway. We add the write to unlock the SLCR registers and we get the desired reset! No doubt U-Boot locked the registers before transfering control to us.
And it is easy. We only use interrupts for received characters. We don't mind polling to send characters as that will be brief. Now that we are using interrupts to receive, we can run the usual tests in the test menu and Kyu looks more or less functional.
Tom's Computer Info / [email protected]