View unanswered posts | View active topics It is currently Fri Mar 29, 2024 8:08 am



Reply to topic  [ 108 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7, 8  Next
 CS01 
Author Message

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Finally got text output on-screen that verifies that the I/O interface works. The program just writes directly to the text screen from user mode. Previously the software had been calling a video routine to output a character. The issue with this was when called from user mode the video routine didn’t have access to the correct physical memory locations for the cursor position and character attributes. The memory map is different between user and machine modes.
For some reason on an ecall instruction the return address isn’t being updated properly. This causes a return to a previous ecall instruction rather than the current one. This forms a loop then. The loop was found while verifying the text output. It’s maddening because the ecall instruction works several times in a row, then fails in this instance. It’s looking like a hardware issue of some sort.

_________________
Robert Finch http://www.finitron.ca


Sat Feb 15, 2020 4:05 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Today’s issue was the scheduler. The scheduler is called from the time slice ISR. It can take hundreds of cycles to schedule the next task, so it’s desired to run the scheduling with interrupts enabled where possible. However, it’s been called from an ISR. That means the ISR’s could nest. IF things take too long then perhaps the time slice ISR would run again. That’d be bad because it’s already running. So, a flag is needed to indicate when the scheduler is already running. If already busy then calling the scheduler returns immediately. But a flag where? To keep things fast and simple a flag CSR was added. The csr instruction can read and set the flag in one operation.
The start of the scheduler looks like this:
Code:
FMTK_SchedulerIRQ:
   csrrs   $v0,#$792,#1               ; check and set semaphore
   and      $v0,$v0,#1
   beqz   $v0,.doSchedule            ; do scheduling only if semaphore clear
   ret
.doSchedule:
   csrrs   $x0,#$300,#1               ; enable ints

_________________
Robert Finch http://www.finitron.ca


Sun Feb 16, 2020 3:36 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Forgot to code for the case of the status register update with the CSRRS, CSRRC instructions. This led to inability to control when interrupts were enabled or disabled.
Missed clearing the invalid instruction flag for the WFI instruction leading it to cause an illegal instruction trap. The core has a very simple mechanism for detecting illegal instructions. At the start of an instruction fetch a flag is set indicating the instruction is illegal. Then as instructions are decoded or executed the flag is cleared. Anything left over won’t clear the flag and hence it’ll be detected as an illegal instruction. This amounts to a very wide or gate into the illegal instruction ff.

_________________
Robert Finch http://www.finitron.ca


Mon Feb 17, 2020 3:43 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
The system is getting hung up because of a bad stack address. It gets through initialization then when it gets to the app (a sprite demo) it hangs. The memory mapping appears to be not working in the manner expected. It’s returning a page number of zero, which means the page wasn’t allocated. But there are no errors during the allocation of the stack page. There’re only a few possibilities. The map could be getting zeroed out at some point, or the wrong map is being referenced, or the hardware isn’t working. I finally managed to get an on-screen hex number dump working so that helps a bit.
Updated the system random number generator to 64-bits from 32.
Got a good pic of the wait-for-interrupt instruction in action. Everything is stalled with the clock gated off until an interrupt occurs (the ucpu1_i_... signal). It looks like the via6522 timer must be working to some degree as the interrupt occurs and can be shut off as expected.
Attachment:
File comment: Pic of WFI in action
WFI.png
WFI.png [ 27.07 KiB | Viewed 3305 times ]

_________________
Robert Finch http://www.finitron.ca


Wed Feb 19, 2020 3:46 am
Profile WWW

Joined: Mon Oct 07, 2019 2:41 am
Posts: 585
Are interupts valid for a modern CPU? IRQ #2A42 USB service:the crap in the throne did not flush.
In the later 70's some machines had I/O switching and IRQ's at the microcode level. This model might
be valid today to handle the basic machine, that would have the outer layer a virtual machine, with
the inner layer (the internal logic) able to handle a static memory model so you have a more robust design.A easy to virtualize design might be better, even if the I/O logic is a few more cycles longer
being indirect addressing. The old ATLAS computer comes to mind.
Good luck in finding what sounds like a race logic problem. A C64 can crash on sprite,but we expect better todays era.


Wed Feb 19, 2020 5:30 am
Profile

Joined: Mon Oct 07, 2019 2:41 am
Posts: 585
I got reading about the ALTAS and it is too old of a model to use.
Time sharing was the main reason for virtual memory, that ended that
era of computing with UNIX about 1980. IRQ sevice was ok for then,
with 2400 baud terminals and 100 megabyte hard drives.
You got painful ALGOL and useless memory management before that.
Then a few labs came out with the mouse and windows, remember the $100 mouse.
Now we have C and pop up widows every where. Niklaus Wirth has I feel the best GUI
interface out there and newer langauge http://www.projectoberon.com/
You might want to split the internal design into 4 parts, alu ,hardware message movement,
and video data movement and real virtual memory. The AMGIA comes to mind here for the some of the design.Two models of virtual memory kernal and large. Kernal is a small fixed size,but will not page fault.
Large is your regular virtual memory.
(ignore any spelling errors, from the guy grumbling that new software will not run in 800x600 16 colors)
I want to read text, not play click the icon game.
Good luck with the error.


Wed Feb 19, 2020 5:18 pm
Profile

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Quote:
Are interupts valid for a modern CPU? I
Good question. I think it depends on the purpose of the cpu. I added the pfi (poll for interrupt) custom instruction to allow for a modern OS that runs with interrupts disabled. Modified the compiler to spit out pfi instruction every so often in code.

Found the bug.
Found out the mapping logic was working correctly by inspecting the timing output more carefully. I noted that the correct address does actually appear on the address bus, it was just a cycle or two later than expected. An intermediate address value appeared on the bus sooner.
Added fast access mode for memory access that doesn’t require mapped output. Since the mapping logic adds two clock cycles to memory access when it’s not needed the fast access trims two clocks off every memory access. That means system modes are substantially faster than user mode code.

Wrote a mutex component having a WISHBONE interface. Also had a look at the vendor’s mutex component which uses the AXI bus. Thinking I might use some AXI components in the future I added an AXI bus interface to the core. The OS software now uses a hardware mutex to gate access to system variables.
Also updated the semaphoric memory component. The semaphore component is interesting because it makes use of the address bus as a data bus to update the memory during both read and write cycles. Reading a semaphore needs to decrement the count, so part of the address bus is used to indicate the decrement. Since a read operation works this way, it is also supported for write operations.

_________________
Robert Finch http://www.finitron.ca


Thu Feb 20, 2020 4:07 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Quote:
and video data movement and real virtual memory. The AMGIA comes to mind here for the some of the design.Two models of virtual memory kernal and large. Kernal is a small fixed size,but will not page fault.
Large is your regular virtual memory.

The OS kernel is in rom at the moment. It's small enough that it fits easily. There are two mode of operation which have different memory. The OS sees a flat address space, the user app sees a segmented and paged address space. Nothing can swap to disk because there's no disk to swap pages with. When the system runs out of memory its out of memory. The virtual memory system is pretty simple, but hopefully powerful enough. The OS doesn't handle page faults. It's assumed that enough memory is allocated at task startup.

I've been wondering why modern memory systems just don't limit the number of pages per memory map, rather than having huge multi-level paged lookups. The system limit per task for this system is 4096 pages, which may be reduced in future. All the page tables are fit into block ram in the FPGA and there's no TLB. There's about 350kB worth of tables required to cover 512MB ram. It's the $0.99 intro to virtual memory as opposed to a big complex system.

_________________
Robert Finch http://www.finitron.ca


Thu Feb 20, 2020 4:23 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Mainly software debugging today. The system works a little bit better all the time. The OS now uses hardware mutexes rather than disabling / enabling interrupts, so it should work in a multi-processor environment. Interrupts are disabled all the time now, and software interrupt poll instructions (pfi) inserted all over the place.
Changed the register file to use block ram rather than distributed LUTs. This allows for more register sets. Register sets are now tied to the HART id. So, the core has a range of 32 HART id’s, one for each register set.
Thinking of implementing a watchdog timer of some sort in case the program doesn't use interrupt polling often enough. It's conceivable that program is written with an infinite loop. If such a thing happens it shouldn't cause everything to lock up.

_________________
Robert Finch http://www.finitron.ca


Fri Feb 21, 2020 4:50 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
The number of memory maps available may be reduced to 32 from 64 in order to match the number of register sets available. This may make it easier to manage the resource, if a register set also corresponds to a memory map. The register sets and memory maps correspond now and are tied to the hardware thread id (HARTID).
Implemented the watchdog timer on the PFI instruction. Whenever a PFI instruction executes the watchdog timer is reset to zero, otherwise it counts every clock cycle. When the counter reaches 2048 a non-maskable interrupt is generated.
For some reason memory mapping which was working has now stopped working. It appears to be the mvmap instruction that’s failing. Unfortunately, the system can’t be simulated. The simulator just hangs.
Integer registers are no longer saved and restored on task switches. There’s simply a separate set of integer registers for each task, so there’s no need to save and restore.
The mutex component didn’t work after a reset. The old values were being retained in the mutex.

_________________
Robert Finch http://www.finitron.ca


Sat Feb 22, 2020 4:09 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Uncovered the bug with paged memory. With the register file switched to block ram it delayed the register output by an additional cycle compared to the previous version. This added a cycle to read of the page map ram, which is also block ram, so the value wasn’t available soon enough. I added a couple of wait states for a specific instruction between the regfetch stage and execute to get it to work. The extra clock cycles aren’t a big deal as the instruction that is delayed isn’t used very often. Here is a photo of a map dump.
Attachment:
File comment: photo of memory map dump
mmap.JPG
mmap.JPG [ 1.26 MiB | Viewed 3209 times ]

The blue square in the top right corner of the display is the IRQ live indicator, it’s actually flashing different colors / characters. The square at the bottom left is the cursor. The sixteen colored stripes are 64 sprites which are defaulted to appear on-screen in those locations. The numbers along the left-hand side of the screen indicate page mappings. The eight digits at the left are four digits for the task number followed by four digits for the virtual page number. There is then a space and the physical page number that is mapped to the virtual page. A page number of zero indicates no mapping. The numbers go in sequence for task #1 as 0,1,2,5,6. Pages 3,4 got mapped for task #0 which has scrolled off-screen. Only the first 16 of 4096 entries were dumped.

_________________
Robert Finch http://www.finitron.ca


Sun Feb 23, 2020 8:10 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Working on task switching tonight. This comes from investigation into why the system doesn’t run the first task as expected. The StartTask() function seems to work, but when tasks are switched a whole bunch of additional invalid tasks are added to the ready list. This must be coming from the InsertIntoReadyList() function in the scheduler. The system then gets messed up when it tries to switch to one of the invalid tasks. I believe the invalid tasks are coming from the way that the timeout list is checked during scheduling. It simply loops through every possible task looking for timed-out tasks. Timed-out tasks get inserted back into the ready list. It goes according to the task status. But the task status for tasks not yet started is undefined. So, the OS initialization routine needs to be modified to define the task status for all possible tasks. I believe random data in the task status may be causing the scheduler to think tasks are valid for timeouts.
I have the OS setup now so that it can assign tasks to either processor. A task affinity still needs to be setup. Once a task has been assigned to a processor it can’t switch processors. The task id contains the processor number.

_________________
Robert Finch http://www.finitron.ca


Mon Feb 24, 2020 5:33 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Getting a little bit further all the time. The issue now is a return address is bad because the value loaded is off by one stack entry. Sounds like a simple issue to resolve, just find out where the stack pointer isn’t being adjusted properly. Well I triple checked all the stack adjustments for different control flow paths and there doesn’t seem to be anything amiss. Also, the issue is in a routine that works most of the time. If it were a stack pointer adjustment, things should go wrong all the time. Time to run a ramtest routine, it’s more likely the ram controller returning data out of wack.
Running the ramtest routine it eventually failed and started spitting out “Illegal Instruction” messages after running for about five minutes. So, I tried changing the timing on the ack signal. Which made things worse, failed after about 200,000 memory cycles. So, now I’m trying a delay on the ack signal so that data shows up a cycle or two before ack does. It’s a synchronous design and the tools are supposed to have worked out all the timing so it shouldn’t matter in theory if data and ack show up at the same time.

I found out that mutexes weren’t being unlocked causing the system to hang. This is probably due to bus timing issues. So, the unlock command is now sent twice. That seems to have cleared up that issue.

_________________
Robert Finch http://www.finitron.ca


Wed Feb 26, 2020 3:51 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Playing with the ethernet today. Setup the ethmac controller from opencores.org in the Petajon SoC. It was easier to do than I thought it would be. The PHY is MII compatible so it can interface directly to the ethmac. I had thought a MII<->RMII converter would be needed.
Wrote some code to read from the board’s eeprom which has a unique id to set the MAC address.
Altered the dram input data path slightly. The dram ack signal was being used to enable dram data onto the bus, this was switched to the dram circuit select signal. This change should allow the data to be latched before ack is signalled, rather than at the same time.

_________________
Robert Finch http://www.finitron.ca


Thu Feb 27, 2020 4:16 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Debugging the eeprom interface was the order of the day. An I2C realtime clock interface was also added. Both these interfaces are not working. Attempting a read cycle results in all zeros for the value read. It supposed to be a MAC address for the eeprom and date/time info from the rtc. The I2C interface is a core available at opencores.org. I’ve had it working in the past so I know it can be done.

_________________
Robert Finch http://www.finitron.ca


Fri Feb 28, 2020 7:42 am
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 108 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7, 8  Next

Who is online

Users browsing this forum: No registered users and 15 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

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software