Last visit was: Sat Aug 02, 2025 12:28 pm
|
It is currently Sat Aug 02, 2025 12:28 pm
|
rf68000 - 68k similar core
Author |
Message |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2402 Location: Canada
|
Bug Fixes The trace flag was being reset by the TRAP instruction preventing tracing through traps. TRAPS were skipped over. This might be the behavior desired most of the time. In many cases one does not want to step through OS routines that are assumed working.
Crashes Stepping through code crashed when stepping through the keyboard routines. This crash will likely not be fixed. The keyboard routines are needed by single-step; it is pretty obvious they cannot be single-stepped at the same time they are being used. There should be an option to skip over subroutines. It is tempting to add the skip into the CPU hardware. The trap flag state could be stored as the LSB of a subroutine address on the stack when a subroutine call occurs. It could then be restored.
Mods Added rotating destination cores for interrupts to the interrupt controller. This was to support staggering of the timer interrupt. The idea is to prevent all cores from trying to manipulate system lists at the same time. The timer interrupt was adjusted to occur more often so that the interrupt period remains the same for each core.
_________________Robert Finch http://www.finitron.ca
|
Mon Jul 07, 2025 4:27 am |
|
 |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2402 Location: Canada
|
A lot of finagling trying to get the timer ISR running for FMTK. Not having much luck. The default tick interrupt works great, but the FMTK timer ISR is somewhat larger and more complex. It has a launchpad written in assembler, then the bulk of the ISR is C code. One thought was that perhaps it was consuming too much time, so I tried increasing the period of timer interrupts, setting them to 33 Hz instead of 100 Hz. The CPU is not particularly fast by today’s standards. No luck.
The timer ISR was modified to store registers in the task control block (TCB) instead of on the stack.
Added two instructions to the CPU using up two illegal opcodes. Store register list to task control block (sttcb), and load register list from task control block (ldtcb). Then got rid of the instructions. Storing to the TCB can mostly be done with a movem generic instruction.
Re-wrote the demo graphics routines in the boot program in C instead of assembler. Triggering the graphics routine demo causes a crash now. It is desired to move as much code as possible to ‘C’ instead of assembler. But the C routines seem to not work as reliably as the assembler code.
_________________Robert Finch http://www.finitron.ca
|
Tue Jul 08, 2025 7:00 am |
|
 |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2402 Location: Canada
|
The FMTK timer ISR appears to be working, but does not update the on-screen IRQ live indicator. The IRQ flag for the interpreter is being set, and the tick count is incrementing, viewed using the monitor’s memory dump command. On a hunch, the IRQ live indicator was re-written to load and store the screen value using a register intermediary. Previously it just did an ADD directly to memory. The difference is that the ADD to memory is a read-modify-write operation whereas using the register it is separate a read and write. It is uncertain whether read-modify-write operations make it through the bus bridge and the I/O device. Timer ISR is fixed now.
DRAM memory reads were busted for non-streaming reads. Generation of the ack signal was faulty.
Non-streaming reads are still broken. Spent some time tweaking the MPMC (multi-port memory controller) to fix reads. Managed to simplify some logic a tiny bit. Non-streamed reads now appear to work. Tens of KB of data were dumped from the DRAM without a crash. Previously it would crash after about 8kB.
Updated the memory controller with more support for cached reads. The controller now latches the read request until it is filled. Previously the cache was completely pipelined. In theory cached reads should now work. (Seemed to work in sim). Just testing now (turns out not to work). Cached reads are a bit convoluted. A read miss goes into a miss queue while the read is stalled until the miss gets a chance to update the cache. It could be some time before there is a response on a miss. There may be outstanding misses from other channels to process before the current miss. There may be some more work required on the LRU updates. It looked like it may be updating too many slots in sim. Having too many slots updated reduces the effective associativity of the cache.
_________________Robert Finch http://www.finitron.ca
|
Wed Jul 09, 2025 10:05 am |
|
 |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2402 Location: Canada
|
Added a timer component which supports up to 32 timers but is currently configured for 8. The timer component is used to generate the time-slice interrupt which was previously generated by discrete logic. This gives more flexibility to the system as the timer IRQ can now be varied via software.
First test with PIT added: system crashed, forgot to connect the PIT’s data bus and ack signals.
Second test: PIT showed up as a device with the device name characters scrambled, byte reverse logic was screwy. System crashed.
Third test: PIT device name correct. System locked. Not even keyboard interrupts working.
Fourth Test: Keyboard working now, no timer interrupts. Dumping the timer registers reveals they are not all set. The registers controlling the timer are not set, but the registers controlling overall operation (interrupt enables) are. This situation is going to require some more investigation.
The system has been operating with just a single core effectively enabled. The other cores are stuck executing a short infinite loop so they do not interfere with the first core (core #2). Enabling a second core caused the system to hang. It did get to processing a timer IRQ as the IRQ live indicator showed up. (This was prior to adding the timer component). So, rotating core numbers in the interrupt controller is probably working. Timer interrupts are given to cores in a round-robin fashion. The first core receives a timer interrupt, then the next timer interrupt goes to the next core. The time-slice interrupt is set to 10ms (or 100Hz).
_________________Robert Finch http://www.finitron.ca
|
Thu Jul 10, 2025 6:56 am |
|
 |
oldben
Joined: Mon Oct 07, 2019 2:41 am Posts: 817
|
Would a timer irq on video retrace be useful?
|
Thu Jul 10, 2025 12:19 pm |
|
 |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2402 Location: Canada
|
Quote: Would a timer irq on video retrace be useful? Yes, very useful. The frame buffer has a vertical blank output that could be used to trigger an IRQ but is not connected ATM. The system has a co-processor that can in theory take action at almost any point of the display. It is similar to the Amiga Copper. It has a WAIT instruction with the horizontal and vertical positions as parameters. Timer Test N: Dumping registers reveals they are being set now. The logic for register update was re-written. The current count register is decrementing ! But no interrupts are occurring. Left a couple of brackets off the interrupt logic. Turns out to be a typo in a signal name. Timer is working now, after about a dozen trials. Removed the address from the FTA bus response. It was not of much use. The idea was to allow syncing responses with requests, but that is mainly handled with the transaction id. Tweaked the memory controller some more. Removed a latch enable signal on the data read back from the MIG controller. The data is being strobed into registers by a write signal and latching should not be needed. Figured out a bug in the MMU that prevented having the bus registered for an extra cycle. The MMU was always active and trying to look-up address translations even though it was not enabled. Without tables properly setup it resulted in a crash.
_________________Robert Finch http://www.finitron.ca
|
Fri Jul 11, 2025 6:51 am |
|
 |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2402 Location: Canada
|
Trying to get threads running without having the whole OS present.
Restructured part of the OS for multi-core operation. There is a separate ready queue and timeout list now for each CPU. The ready queue and timeout list are now protected by masking interrupts when accessing the list instead of using semaphores. There is lower overhead with interrupt masking. Since only a single core is accessing these lists there is no need for semaphores.
Added timer callbacks to the OS. They are supported with a callback pid and function registers in the timer component.
_________________Robert Finch http://www.finitron.ca
|
Sun Jul 13, 2025 2:45 am |
|
 |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2402 Location: Canada
|
The free TCB (thread control block) list is not working correctly. The first Free TCB is reported as: 260Ah when it should be 1. It is initialized to 1 but somehow very quickly gets corrupted. 260Ah is an invalid handle, way beyond the number of TCBs available. <- turned out to be a bad function prototype for the number display. Added alarms to the OS. Alarms are sorted according to the soonest occurrence. One of the PIT (programmable interval timer) timers is used to time the alarms. Timing resolution down to about 100 ns hopefully. When an alarm occurs it may invoke a callback function and/or send a message to a mailbox. Partially re-wrote the semaphore lock and unlock functions. They now disable/enable interrupts in addition to locking/unlocking semaphores. Femtiki startup is currently hanging trying to start a thread. This bug has me stumped ATM. A NULL pointer is being returned as the address of the TCB array, and I cannot figure out why. It is the line of code marked with two ‘*’s. In the listing it shows the value zero being loaded into d0. However, this is prior to the code being patched up by the linker. After the code is patched by the linker the ‘0’s are translated to a 101000h (the correct address of the TCB array). If I dump the binary file, it can be seen that the address is patched up correctly. It is also correct in the .mem file used to load the FPGA BRAM. “C” code: Code: t = TCBHandleToPointer(ht); DisplayString("tcbs="); DisplayTetra((unsigned long)&tcbs[0]); freeTCB = t->next; DisplayString(" t="); DisplayTetra((unsigned long)t);
Listing file: Code: 00:00000A32 2F400026 1063: move.l d0,(26+l250,a7) 00:00000A36 43FA02D0 1064: lea l229,a1 00:00000A3A 4EB900000000 1065: jsr _DisplayString **00:00000A40 203C00000000 1066: move.l #_tcbs,d0 00:00000A46 2200 1067: move.l d0,d1 00:00000A48 4EB900000000 1068: jsr _DisplayTetra 00:00000A4E 206F0026 1069: move.l (26+l250,a7),a0 .Mem File: Code: 786C0000 10003C20** 00220010** 0000B94E
There is only a couple of things I can think of. 1) By coincidence the value is being zero’d out at run time. It just happens to zero out exactly the right place in machine code. 2) It is bad SRAM memory, that happens to have a zero right there.
_________________Robert Finch http://www.finitron.ca
|
Mon Jul 14, 2025 4:21 am |
|
 |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2402 Location: Canada
|
Big Fix Much to my disbelief, I found one issue: the flag testing for the BGT instruction in the CPU was messed up. There was a ‘not’ missing from the zero-flag test. This would cause BGT to act like a BEQ in many cases. You mean I have been using the CPU for a couple of years now, and just noticed BGT does not work? The CPU test program needs an obvious upgrade it failed to catch it. I have been doing most of the coding in assembler and did not make use of BGT. However, the compiled code does occasionally.
_________________Robert Finch http://www.finitron.ca
|
Mon Jul 14, 2025 5:50 am |
|
 |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2402 Location: Canada
|
Since fixing the BGT bug the flow of the startup code is different, leading to different software bugs. During the startup process interrupts are disabled, but somehow the timer interrupt is occurring. And that may mess things up. Milestone: Got the first successful dump of the thread list. Playing around with the idea of having loads of timers (LOT) as in thousands. The idea is to be able to use a timer without the OS having a list or priority queue of timers. Each timer would be able to notify a thread of the timeout. And each timer would have its own timer interrupt subroutine. For instance, with 256 timers available there would be 256 timer ISR routines. A program would open a timer device getting a handle, then fill out a small block of information needed to perform the timed operation. Info would include a mailbox handle, the desired timeout and an option to repeat. I sketched out a timer ISR macro which then calls a generic timer routine. Each timer ISR takes 24 bytes. For 256 timers that would be 6kB of code. Going to try it with 64 timers first. 64 is the number of timer blocks available by default in the MMURTL operating system. I have to code a timer though that is overloaded multiple times. There would be one timer with counts in SRAM. The timer ISRs look like: Code: macAlarmISR macro move.l #_FMTK_AlarmISRLaunchpad\@,REPTN*4+$300 bra.s _FMTK_NextAlarmISR\@ _FMTK_AlarmISRLaunchpad\@: move.w #$2700,sr ; disable interrupts move.l #REPTN,d0 jsr _FMTK_AlarmISR rte _FMTK_NextAlarmISR\@ endm
_SetupAlarmISRs: rept 64 macAlarmISR endr rts
They call this generic C code routine: Code: void FMTK_AlarmISR(__reg("d0") long ndx) { if (PIT[ndx].hMbx > 0) FMTK_PostMsg(PIT[ndx].hMbx,0xffffffff,0xffffffff,0xffffffff); }
Cannot get an ISR much shorter.
_________________Robert Finch http://www.finitron.ca
|
Tue Jul 15, 2025 7:18 am |
|
 |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2402 Location: Canada
|
Re-wrote the PIT component. The component was switched to 48-bit counts instead of 32-bit counts. 32-bit counts could not generate long enough intervals. Since it was being re-written anyway, RAM backed counts were used to create 256 timers in the component. Software had to be updated for the new register set. The timer component is a little larger than expected but not too bad. The 256 timers take up about 5,900 LUTs.
Added a second vector signal line to the CPU core. The second signal indicates that the interrupt responder is providing a full 32-bit address to the CPU instead of a vector number. With hundreds of timers available hundreds of vectors would be required and the 68k does not support it. Vectoring had to change somehow.
The system is getting stuck in an infinite loop when booting. It acts almost as if single stepping were enabled without waiting for the step command. The current line is disassembled, then the registers dumped, and the process repeated again. The screen scrolls like crazy until a key is pressed, at which point the system hangs. (It was doing this before the timer change). It is almost as if an interrupt routine does not work quite right.
_________________Robert Finch http://www.finitron.ca
|
Wed Jul 16, 2025 4:56 am |
|
 |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2402 Location: Canada
|
Found a bug in the keyboard routines when locking / unlocking semaphores. The semaphore lock / unlock routines were updated to record the status register value, but the keyboard routines were not updated to reflect new requirements. The status register was being set to some random value by the keyboard routines. This had weird effects like dropping into user mode, or turning on trace mode. With this fixed, the system no longer gets stuck in an infinite loop. Instead it crashes due to a bad timer interrupt.
The timer tick ISR is broken again. This time it is using the new hardware multiplexed timer. The multiplexed timer component is smaller than the previous component while supporting up to 64 timers. The PIT seems to be returning a vector number of zero, which causes the starting stack pointer to be loaded into the program counter, causing a crash. Why the vector is zero is yet to be determined.
_________________Robert Finch http://www.finitron.ca
|
Thu Jul 17, 2025 7:08 am |
|
 |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2402 Location: Canada
|
Bug Fixes Found a bug in the semaphore lock routine. The value of the status register was not being returned. This caused the semaphore un-lock to fail. The value ended up not being returned as the return register was popped off the stack by the trap routine used to call the semaphore lock. The return value needed to be placed in the stack instead of being set in a register.
The timer tick ISR is fixed again.
Mods Modified the CPU to not set the interrupt mask until the third instruction after a return from interrupt (RTE) occurs. The idea is to prevent infinite loops due to a stuck or unacknowledged interrupt signal. If an interrupt signal is stuck the ISR would be called again before the next instruction gets a chance to execute. Hopefully the delay will allow programs to progress although very slowly if there is a stuck interrupt.
Modified interrupt handlers to set the most significant bit of the thread register. The thread register is used when locking semaphores. The issue that could arise is that if the semaphore were locked by a thread and an interrupt occurred which also locked the same semaphore, the semaphore lock could succeed when it should have failed. While locking the same semaphore by the same thread would not necessarily create issues, it does at unlock time. This could also be alleviated using counting semaphores instead of straight binary semaphores. Setting the MSB of the thread for interrupts makes the thread different.
Milestones The system is starting up Femtiki now but does not get to the monitor prompt. It seems to be stuck in a loop somewhere. Interrupts are happening. If a key is pressed, then the keyboard interrupt goes nuts and the timer interrupt quits working. The thread list is being dumped as part of the startup and it contains the system thread and an idle thread started as part of the startup process.
<- System now gets to the monitor prompt, but as soon as a key is pressed it gets locked in keypress interrupt. This has me stumped as the keyboard IRQ is lower priority than the timer tick IRQ and the timer tick IRQ ceases to operate. <- figured this one out. The keyboard IRQ was connected to a higher line on the interrupt controller. Even though specified as a lower level interrupt, the interrupt controller quit checking for interrupts based on the first one it found starting with the highest input lines. The keyboard IRQ signal was moved to a lower input signal on the interrupt controller.
The keyboard semaphore seems not to work.
The system is closer to working with the Femtiki thread scheduler running. Timer interrupts are running, and keyboard interrupts are detected. But the command prompt is stalled trying to get a character. Believed to be due to semaphore locks not working correctly.
_________________Robert Finch http://www.finitron.ca
|
Sat Jul 19, 2025 2:32 am |
|
 |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2402 Location: Canada
|
Bug fixes Found another bug in the semaphore code. The semaphore number argument was inadvertently cleared causing all references to be to semaphore #0. Semaphores seem to be working now. Mods The message logic was modified to lock individual mailboxes instead of locking them all when a mailbox is modified. The number of hardware semaphores increased to accommodate the number of mailboxes. Milestones: A new piece of the OS was run, SendMsg() and WaitMsg(). The test was sending a message to a mailbox, which was then followed directly by waiting for a message. The STOP instruction of the processor finally got tested. It is used when Reschedule() is called to wait for an interrupt before proceeding. Issues The OS does not seem to be switching threads correctly. There are two threads defined, but only one is ever run.
_________________Robert Finch http://www.finitron.ca
|
Sun Jul 20, 2025 1:30 pm |
|
 |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2402 Location: Canada
|
Milestone: the OS is switching between two threads. <- this is busted now
Mods: Added a simple trace facility to the CPU core. It tracks the last 2048 PC addresses. When a button is pressed on the FPGA board, the trace buffer gets dumped and appears in the logic analyzer. The trace facility does not work as expected, it is dumping only a single address.
The serial port driver was finally fixed up for new semaphore operation.
The IRQ priorities were flipped around for the serial port and keyboard. Serial port is now number 5 and keyboard is number 3. This gives the serial port a higher priority.
_________________Robert Finch http://www.finitron.ca
|
Fri Jul 25, 2025 5:20 am |
|
Who is online |
Users browsing this forum: AhrefsBot, claudebot and 140 guests |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum
|
|