Given that the P II has no interrupts of traps there is no way to generate page faults so catching memory accesses to inappropriate addresses is not possible. Ergo no MMU/MPU. I have not heard of any plans to put MMU/MPU hardware into the PII and I suspect it's an idea that would be soundly rejected as not being appropriate in an MCU anyway.
I actually don't see how any other memory protection can be done in software using hubexec. How can it work with no hardware address translation or traps?
One could of course fall back too the old PI style LMM technique to execute code from HUB. A little fetch/execute loop in software. That LMM loop could be made to do all the checks on memory accesses and perform the necessary translations and detect page faults. That is basically what the Z80 emulators, ZiCog and qz80 do when running z80 code from external RAM devices attached to the PI.
That of course will slow down execution speed tremendously.
In the end I think that whilst getting Minix running on the PII might be an interesting idea to pursue for fun, like getting CP/M running on the PI was, it will not have a practical value.
Hmm.. Heater, I think you just identified the one place where interrupts actually make sense.. for trapping page faults. In that case you *want* to interrupt the main task.
So putting the P2 aside for a moment, what about P1V?
You potentially have a lot more control over cogs and data streams, could achieve interrupt-like mechanisms easily
And more hub ram available too
I'm happy it's not sensible to virtualise on the Prop. That inevitability leads to bloat because, as per typical general computing, the excess of bulk RAM and single tasking speed has resulted in some truly fat libs. None more so than with GUIs.
Admittedly, the rate of increase in said bloat has levelled off along with the current CPU speed limits. And refinements in supporting hardware within the CPU and some decent RAM speed and subsystem improvements means the overall performance has made the bloat seem to go away. But it hasn't, today's best PCs are a requirement to lift such heavy burdens.
Tor,
I have this deeply disturbing feeling that you might be right. I can't think of a way to handle page faults without an interrupt like mechanism and a handler that does the required memory juggling. Unless we cast this functionality into silicon and the software never knows anything about what is happening to the memory beneath it.
Luckily nobody wants an MMU in a micro-controller
That makes sense to me, and maybe P3 can include some basic capabilities in hardware, or be made to operate with an external HUB memory, making it a CPU full on, not a micro-controller.
hehehe... Although I do agree that an MMU would be completely useless in embedded applications, which is the P2's target application, an MMU *does* have a place in education.
For example, the spinneret web server. On a practical level it is probably the worst possible web server, imo, since it is (comparatively) slow, easily DoS'd, and basically a free 10-year-old beige computer would be a far better server. So why would anyone buy the spinneret? Easy: for its educational value. No other device on the market lets you code on the bare metal something that remotely acts like a web server. (Try programming your own webserver in x86 assembly for a beige box, let me know how many years it takes :P).
So the propeller is basically aimed at two different markets: education and embedded. It needs to find a balance between them. And although an MMU would be useless in a robot or any other embedded application, the fact is an MMU is a requirement for any "real" OS, which, like the spinneret, would be great for the education market.
Now, I'm not saying there's going to be a huge demand for an MMU, the P2 will sell well as an advanced (compared to the Basic Stamp) learning platform regardless of whether it can run an OS or not. However, being able to run an OS won't be a useless feature. Like the spinneret was for basic web serving, I would love to see an OS learning platform. TBH that's why I want an MMU; I'm wanting to learn myself about OS programming. And there will be others. That's why the Minix book has been continuously in print since 1987 :P
Instead of an MMU, couldn't you just have a compiler that emits code that does bounds-checking when it suspects something could go wrong and explicitly inserts calls to page swapper functions when necessary?
m00tykins,
There seems to be some confusion over the terms "embedded" or "embedded system". It's just a label for a computer that is incorporated into some other system such that the users of that system don't have to know there is a computer in there. It just does whatever the system should do. Think Primary Flight Computers of a Fly By Wire aircraft, or even a Point of sale terminal. "embedded" does not mean small or real-time. An embedded system could well be a full up PC class machine with virtual memory and a serious OS line Windows or Linux (Well, Linux anyway )
Are you saying that the spinneret enables you to create an entire web server in PASM on a Propeller? I very much doubt it.
Years ago I created a simple Win32 app in x86 assembler, just for fun. I'm sure using the Windows socket API in assembler is about as easy. If we are "thinking OS learning platforms" and things like Minix there are so many better alternatives to the Propeller for that. There is a ton of ARM, MIPS and other cheap micros out there.
The Prop is not targeted at that kind of OS. With good reason.
Electrodude,
Yes a compiler can insert memory safety checks. That has to happen on every memory access. That kills performance. Languages like Ada do that when you switch the feature on.
It's even worse. Normally a compiler assumes a flat memory space for whatever it want's to do. How can it know what is the actual layout of memory when the programs it has compiled are run?
That is why we need an MMU to doll out memory when a machine is running many programs that come and go as users come and go, threads and processes are created and destroyed.
As I said, such an MMU function can be put into the fetch execute loop of an LMM kernel. But again we have killed performance.
Electrodude,
Yes a compiler can insert memory safety checks. That has to happen on every memory access. That kills performance. Languages like Ada do that when you switch the feature on.
It's even worse. Normally a compiler assumes a flat memory space for whatever it want's to do. How can it know what is the actual layout of memory when the programs it has compiled are run?
That is why we need an MMU to doll out memory when a machine is running many programs that come and go as users come and go, threads and processes are created and destroyed.
As I said, such an MMU function can be put into the fetch execute loop of an LMM kernel. But again we have killed performance.
I think I got mixed up when I wrote that post. What I think I wanted to say is, can't you have a compiler that makes sure that bad things will never happen, such as by complaining about a bad array index in a loop that loops one too many times, or about a place where a pointer is free'd but not set to NULL, or about a possible code path that might result in something being uninitialized? Of course, the compiler isn't going to be able to prove and catch everything, in which cases it can emit safety checks (and possibly emit a warning about it). If the programmer can prove something the compiler can't, he can put a hint with a #pragma or something promising that some specified condition will be true, sort of like an assert that the compiler should blindly accept as true instead of checking, that might help the compiler.
They have programs that check things like this - why aren't they part of the compiler? That way it would only have to be parsed once, although compiler checking definitely should be optional in cases like when you're compiling code that's known to work or where you're just that good of a programmer and want your compiler to finish before next year.
I'm not saying MMUs are bad - virtual memory is one of my favorite inventions (even though I rarely use it myself). I'm mainly complaining that compilers are stupid and don't check things they should, leaving many bugs undiscovered until a nice segfault comes around.
I wouldn't mind an MMU on the P3, but the main feature I want right now for the P2 is for it to exist in real silicon. But even without an MMU on the P2, it should still be possible to emulate one fairly efficiently with a smart enough compiler.
I've begun to notice that most of my complaints about computers these days are actually problems that mainly exist in C and C++ compilers. Maybe I should try a higher level language than C++, like Haskell or Ocaml or even just D. But then someone would have to port that new language to the Propeller.
I should get to work on my extended spin compiler so I can get an idea of how hard writing good compilers that prove everything and magically show you all your bugs actually is, then I'll stop complaining.
...can't you have a compiler that makes sure that bad things will never happen,..
Indeed you can. Pascal inserts runtime array bounds checks. It's also very fussy about data types in assignments, parameter passing and so on. The Ada language carries this to extreme which is why people like to use it of safety critical systems. Even C and C++ do a little type checking.
Some of the correctness checks can be done at "compile time" while the compiler is analysing your source and generating code. Others are done at run time by checks that are built into the resulting executable.
I'm mainly complaining that compilers are stupid and don't check things they should,
"Stupid" may be putting a bit hard. Programming languages are designed with particular uses in mind and are tailored to work well for those uses. For example C was created as a low level but portable systems programming language, some say one step up from assembler. As such it allows you do pretty much anything you can do in assembler, including make all those errors, with the power comes the risk. Ada on the other hand was designed to be much higher level with a great emphasis on correctness.
These are statically typed language that produce a static executable. But what about languages with dynamic typing? Javascript for example allows any type to be stored in any variable at any time. Writing to a non-existent array element is OK, the array just gets stretched to fit. Functions can be created and destroyed at run time. Everything is dynamic.
I used to think that anything that was not strictly, statically typed with a bunch of compile time checks was stupid too. In recent years I have changed my mind. My reasoning goes like this:
1) Having dynamic, probably interpreted, language means there is no waiting for the compiler, just edit code and see what it does. Much easier and quicker development.
2) Source code without all the type specifications in it is much easier to write and read.
3) If you are serious about your program working you will have a lot of tests in place, unit tests, integration test, etc. Those tests will show up problems due to type miss-matches, writing to the wrong place in an array, forgetting function parameters, etc, etc Well, given that you are serious and do have those tests there is no point in having he compiler check everything.
4) Putting those run time checks into an embedded system is pretty pointless. Sure it will raise an
exception when an array is overstepped or whatever but then what? Generally it means your program has arrived at a bad state that cannot be recovered from, the only thing to do is halt or reset. At this point the breaks fail, the plane crashes, the nuclear power station melts down! Such checks are useful during development though.
5) Ultimately, as you say, a compiler cannot check everything.
m00tykins,
There seems to be some confusion over the terms "embedded" or "embedded system". It's just a label for a computer that is incorporated into some other system such that the users of that system don't have to know there is a computer in there. It just does whatever the system should do. Think Primary Flight Computers of a Fly By Wire aircraft, or even a Point of sale terminal. "embedded" does not mean small or real-time. An embedded system could well be a full up PC class machine with virtual memory and a serious OS line Windows or Linux (Well, Linux anyway )Right, but small or real-time usually *does* mean embedded, that's why I said the propeller is meant for embedded applications.
Are you saying that the spinneret enables you to create an entire web server in PASM on a Propeller? I very much doubt it.
Actually, yes, that is what I'm saying. A web server is just a machine that is contacted over the internet to provide a service, as opposed to a client. That's why the spinneret product page says "Spinneret Web Server" :P.
Now, I'm thinking there actually *is* a way to run a full featured OS without a MMU or a performance penalty, so long as some requirements are met. The OS would need to be a microkernel, and would need to run the file system as a user space process. Then, programs would need to use capability-based addressing (see here), and therefore can only talk to the physical storage media through the kernel, since data structures like pointers would be illegal. In a way, it's like implementing the LMM on top of the kernel (since the kernel is privileged anyway) instead of underneath it.
It's all confused now a days. I would say that getting audio and video to play nicely on my PC is a real-time task, however my PC is not an embedded system. Modern phones an tabs are small but not generally referred to as "embedded systems". We have millions of web developers who no use the term "real-time" to describe chat notifications and the like being pushed to browsers.
I agree the Propeller is intended for embedded applications.
The Spinneret is certainly a web server. But how much of that web serving is happening in PASM? WIZnet is doing all the TCP/IP stack. I suspect the HTTP stuff is done in Spin. I have never looked.
The Spinneret is certainly a web server. But how much of that web serving is happening in PASM? WIZnet is doing all the TCP/IP stack. I suspect the HTTP stuff is done in Spin. I have never looked.
Are you saying that the spinneret enables you to create an entire web server in PASM on a Propeller? I very much doubt it.
I said yes, it enables you to make it in PASM. You could do it in spin if you want.
Nitpicking about totally irrelevant stuff aside, I think an MMU, or at least some sort of ability to code an MMU (which would just need interrupts) would be a great feature, and would allow the P2 to step into the OS-design educational market (high-school/college).
Although it would have to compete with ARM/MIPS/etc.... What student can, let alone want to, program in ARM or MIPS assembly? ALL OS's require at least some assembly in them (that's what prevents windows from running on powerpc, for example), and the fact that the propeller is perhaps an order of magnitude simpler than an ARM/MIPS is a huge bonus.
There is the dilemma in my mind. If you add an MMU to the Prop. And hence interrupts, and hence probably stack handling, oh and what about index registers and so on, so as to make such a general purpose OS and applications practical then what have you done?
Basically you have converted a Prop into a regular processor, like an ARM or MIPS or Power PC or whatever.
Well, my observation is that Parallax can never compete in that space. There are so many such machines already. No point in doing it.
At the same time you have made the Prop as complex as those other guys, thus destroying it's attraction to the markets it has. This is not only "no point" it's detrimental to the Props future.
I'm not sure of the complexity of the MIPS instruction set you claim. Whilst it is more to handle than PASM I have helped a few CS undergraduates with their assignments that involved MIPS assembler programming and it seemed pretty straight forward and regular to me. Unlike Intel x86 say.
I'm not sure you are right about Windows on Power PC. There was such a beast back in the day. But if MS decides to not to support building Windows for whatever architecture then that is the end of that.
In recent times MS has produced some kind of Windows for ARM.
Realtime.. the Norsk Data ND-100 16-bit minicomputers were as realtime as any computer could be (the OS was realtime, the time-sharing part was simply letting user programs be managed by a realtime task manipulating a priority table). But there was definitely nothing embedded about that mini!
I don't really see how addition of a feature would destroy its attraction to its current markets. If you don't need all eight cogs, just use seven. Same with any other added feature, no?
The additional complexity for the hardware depends on how much you're willing to offload to software. I think just adding interrupts is really enough. Even something as massive as Linux doesn't need a full-blown MMU if you can find a way to handle physical memory locations in software. Just an MPU. And even an MPU isn't necessary, just a way to send an interrupt if a seg fault occurs.
---
Here's what I'm proposing: add interrupt support. That way, a cog could be programmed as an MMU, and send the interrupts if necessary. No huge integrated MMU, no MPU, no other additional features really, just interrupts. That way you can make an MMU if you want, AND it's an additional feature in the target embedded market anyway.
Would anyone else like to see interrupt support? Or is everyone really satisfied with polling?
Would anyone else like to see interrupt support? Or is everyone really satisfied with polling?
Not sure how easy it is to find old discussions on this new forum, but this topic has been beat to death, repeatedly, as in over and over and over, ad infinitum, ground hog day...
C.W.
Polling isn't the only option to interrupts, it's not even popular. A cog can simply wait for an event, no polling needed. And that rarely means that you run out of cogs either. Adding interrupts adds lots of extra baggage, there's a definite cost. If you look up some older threads (you don't have to go back far) this has been discussed and detailed several times.I used to be in the "interrupts are easy, what's the problem?" camp in the past (I have coded for interrupts for decades), but I have changed my mind now. Although that particular case Heater came up with is a special case. Implementing an MMU.. would be nice. But adding interrupt support *does* have a cost. For the MMU case I suspect there are other solutions lurking.
An MMU is a complex piece of hardware, particularly on a pipelined processor. At any memory access, read or write, you can get a memory fault and have to unwind (or save) the state of what has been done so far. For the Propeller, this involves two read and one write access per instruction (plus the fetch read accesses for the pipeline. Some instructions might involve an uninterruptable read/write cycle (LOCKxxx). You'd have to define the result of one cog changing the MMU registers while another does a LOCKxxx instruction ... makes my head ache! You don't have to guarantee that it would work properly, but you'd have to at least explicitly define those cases as "not allowed". If you want to have an MMU per cog, that avoids the possibility of changing the MMU registers in parallel with execution, but adds the size and complexity of managing memory for each cog that is using an MMU.
Interrupts (as mentioned many times before) are also complex in a pipelined multiprocessor such as the P2. The interrupt processing is usually deferred to the inter-instruction time. Are prefetched instructions thrown away? How about prefetched operands? Some processors just throw everything away when an interrupt occurs. When execution is resumed, they just start over again. That's simple, but slows down execution if there are a lot of interrupts.
Me, I'm very happy with polling on a multiprocessor. I don't want the complexity (hardware and software) of interrupt support. It's not necessary.
XMOS provides interrupts, primarily for use with legacy code, but I don't think that anyone uses them. I found this stuff on how to use them: https://www.xcore.com/wiki/index.php/Interrupts
Not sure how easy it is to find old discussions on this new forum, but this topic has been beat to death, repeatedly, as in over and over and over, ad infinitum, ground hog day...
C.W.
Ah, sorry then. Does anyone have a link to a main thread, if there is one, regarding interrupts on the P2?
And Mike Green, Tor, thank you very much for explaining. Once I have a P2 (and the time lol) I would like to start a project to get some sort of MMU functionality on it, and I'd love to have your ideas on it. I'm thinking there must be some sort of workaround too, I'm just not sure what it is yet.... But I do have a feeling haha. I'll start a thread when I start coding.
Here's what I'm proposing: add interrupt support. That way, a cog could be programmed as an MMU, and send the interrupts if necessary. No huge integrated MMU, no MPU, no other additional features really, just interrupts. That way you can make an MMU if you want, AND it's an additional feature in the target embedded market anyway.
Please elaborate. What situations/events are you suggesting are signaled by those interrupts?
I can't imagine what you are suggesting. How does one make a MMU in software with only the help of an interrupt or two. Seems to me software address translation and/or rage checking on every memory access is going to make things run really slowly.
This debate about interrupts has been recurring for years. I wish there was a page somewhere where all the reasons the Prop does not have interrupts are laid out. I'd make one myself but I'm weary of it all.
If you checkout my ZiCog and Pullmolls qz80 Z80 emulators for the Prop projects you will see that they did at least have access to 64K or more of memory via and external memory driver with caches. That kind of idea could probably be extended into a more complex MMU. It's OK if you don't mind running slowly It's not clear that adding interrupts to those systems would have helped the emulator performance much.
Would anyone else like to see interrupt support? Or is everyone really satisfied with polling?
This comes down to semantics, and what interrupt support actually means.
Full classic interrupt has PUSH and POP and a stack.Small MCUs even have priority levels on interrupts, allowing higher priority interrupts to break into lower priority ones. Some have register bank switching for speed.That level of interrupt support is pretty much outside the scope of a P2.
However, there is a case for a hardware vector jump, but that has no stack and no PUSH or POP.Essentially, it is just a hardware triggered JMPRET.I would avoid calling that an interrupt, lest readers think it is something more.
@jmg - at a minimum, you'd need a hardware vector jump with an interrupt enable / disable, disabled by default and when an interrupt is accepted (interrupt input and enabled). All the state saving and restoring (flags at a minimum) has to be done in software. If the interrupt routine doesn't use a flag, it doesn't have to be saved and restored. Usually when interrupts are enabled, the actual enabling is either done by a special JMPRET (RETURN) or delayed to allow the JMPRET (RETURN) to finish executing (to allow the interrupt routine to actually exit).
We had 'full classic interrupts" without a stack or push/pop instructions. Univac 1100 series architecture, had 2 sets of registers to easily isolate user from executive space and also captured the P address and passed it to you at the time of the interrupt. It's been a long time since I worked with it but we did well without stacks. You just save the state you need to save when your interrupt routine gets control and everybody follows the same set of rules and conventions. Cool stuff!
I believe Mr, Green remembers working on these beauties!!
..... All the state saving and restoring (flags at a minimum) has to be done in software. If the interrupt routine doesn't use a flag, it doesn't have to be saved and restored. Usually when interrupts are enabled, the actual enabling is either done by a special JMPRET (RETURN) or delayed to allow the JMPRET (RETURN) to finish executing (to allow the interrupt routine to actually exit).
Yes, I did not include flags, but those could be saved in HW, which costs only a very few bits, vs the register cost to save/restore in SW.
The flags-save can be managed by the same tiny state engine that disables other INT sources from interrupting the current active INT.
mindrobots wrote:
We had 'full classic interrupts" without a stack or push/pop instructions. Univac 1100 series architecture, had 2 sets of registers to easily isolate user from executive space and also captured the P address and passed it to you at the time of the interrupt. It's been a long time since I worked with it but we did well without stacks.
Hmmm...interesting...let me cast that in Propeller terms:
On the Propeller we have the equivalent of "full classic interrupts" without a stack or push/pop instructions. The Propeller architecture has 8(16) sets of registers to easily isolate tasks form each other and allow low latency, deterministic response to events. We all work with it a lot and we do very well without stacks.
Of course that means we don't need classic interrupts either
The Norsk Data NORD-10 had 16 full sets of registers (including status registers and some of the internal registers). An interrupt switched register sets and continued from there. No explicit saving of state (or push/pop) was necessary for the interrupt itself. An interrupt could interrupt an interrupt, that's what all the levels were for. An interrupt could be handled in 1.2us back then in 1969, which was pretty good for the time.
Comments
Given that the P II has no interrupts of traps there is no way to generate page faults so catching memory accesses to inappropriate addresses is not possible. Ergo no MMU/MPU. I have not heard of any plans to put MMU/MPU hardware into the PII and I suspect it's an idea that would be soundly rejected as not being appropriate in an MCU anyway.
I actually don't see how any other memory protection can be done in software using hubexec. How can it work with no hardware address translation or traps?
One could of course fall back too the old PI style LMM technique to execute code from HUB. A little fetch/execute loop in software. That LMM loop could be made to do all the checks on memory accesses and perform the necessary translations and detect page faults. That is basically what the Z80 emulators, ZiCog and qz80 do when running z80 code from external RAM devices attached to the PI.
That of course will slow down execution speed tremendously.
In the end I think that whilst getting Minix running on the PII might be an interesting idea to pursue for fun, like getting CP/M running on the PI was, it will not have a practical value.
You potentially have a lot more control over cogs and data streams, could achieve interrupt-like mechanisms easily
And more hub ram available too
Admittedly, the rate of increase in said bloat has levelled off along with the current CPU speed limits. And refinements in supporting hardware within the CPU and some decent RAM speed and subsystem improvements means the overall performance has made the bloat seem to go away. But it hasn't, today's best PCs are a requirement to lift such heavy burdens.
I have this deeply disturbing feeling that you might be right. I can't think of a way to handle page faults without an interrupt like mechanism and a handler that does the required memory juggling. Unless we cast this functionality into silicon and the software never knows anything about what is happening to the memory beneath it.
Luckily nobody wants an MMU in a micro-controller
hehehe... Although I do agree that an MMU would be completely useless in embedded applications, which is the P2's target application, an MMU *does* have a place in education.
For example, the spinneret web server. On a practical level it is probably the worst possible web server, imo, since it is (comparatively) slow, easily DoS'd, and basically a free 10-year-old beige computer would be a far better server. So why would anyone buy the spinneret? Easy: for its educational value. No other device on the market lets you code on the bare metal something that remotely acts like a web server. (Try programming your own webserver in x86 assembly for a beige box, let me know how many years it takes :P).
So the propeller is basically aimed at two different markets: education and embedded. It needs to find a balance between them. And although an MMU would be useless in a robot or any other embedded application, the fact is an MMU is a requirement for any "real" OS, which, like the spinneret, would be great for the education market.
Now, I'm not saying there's going to be a huge demand for an MMU, the P2 will sell well as an advanced (compared to the Basic Stamp) learning platform regardless of whether it can run an OS or not. However, being able to run an OS won't be a useless feature. Like the spinneret was for basic web serving, I would love to see an OS learning platform. TBH that's why I want an MMU; I'm wanting to learn myself about OS programming. And there will be others. That's why the Minix book has been continuously in print since 1987 :P
There seems to be some confusion over the terms "embedded" or "embedded system". It's just a label for a computer that is incorporated into some other system such that the users of that system don't have to know there is a computer in there. It just does whatever the system should do. Think Primary Flight Computers of a Fly By Wire aircraft, or even a Point of sale terminal. "embedded" does not mean small or real-time. An embedded system could well be a full up PC class machine with virtual memory and a serious OS line Windows or Linux (Well, Linux anyway )
Are you saying that the spinneret enables you to create an entire web server in PASM on a Propeller? I very much doubt it.
Years ago I created a simple Win32 app in x86 assembler, just for fun. I'm sure using the Windows socket API in assembler is about as easy. If we are "thinking OS learning platforms" and things like Minix there are so many better alternatives to the Propeller for that. There is a ton of ARM, MIPS and other cheap micros out there.
The Prop is not targeted at that kind of OS. With good reason.
Yes a compiler can insert memory safety checks. That has to happen on every memory access. That kills performance. Languages like Ada do that when you switch the feature on.
It's even worse. Normally a compiler assumes a flat memory space for whatever it want's to do. How can it know what is the actual layout of memory when the programs it has compiled are run?
That is why we need an MMU to doll out memory when a machine is running many programs that come and go as users come and go, threads and processes are created and destroyed.
As I said, such an MMU function can be put into the fetch execute loop of an LMM kernel. But again we have killed performance.
Yes a compiler can insert memory safety checks. That has to happen on every memory access. That kills performance. Languages like Ada do that when you switch the feature on.
It's even worse. Normally a compiler assumes a flat memory space for whatever it want's to do. How can it know what is the actual layout of memory when the programs it has compiled are run?
That is why we need an MMU to doll out memory when a machine is running many programs that come and go as users come and go, threads and processes are created and destroyed.
As I said, such an MMU function can be put into the fetch execute loop of an LMM kernel. But again we have killed performance.
I think I got mixed up when I wrote that post. What I think I wanted to say is, can't you have a compiler that makes sure that bad things will never happen, such as by complaining about a bad array index in a loop that loops one too many times, or about a place where a pointer is free'd but not set to NULL, or about a possible code path that might result in something being uninitialized? Of course, the compiler isn't going to be able to prove and catch everything, in which cases it can emit safety checks (and possibly emit a warning about it). If the programmer can prove something the compiler can't, he can put a hint with a #pragma or something promising that some specified condition will be true, sort of like an assert that the compiler should blindly accept as true instead of checking, that might help the compiler.
They have programs that check things like this - why aren't they part of the compiler? That way it would only have to be parsed once, although compiler checking definitely should be optional in cases like when you're compiling code that's known to work or where you're just that good of a programmer and want your compiler to finish before next year.
I'm not saying MMUs are bad - virtual memory is one of my favorite inventions (even though I rarely use it myself). I'm mainly complaining that compilers are stupid and don't check things they should, leaving many bugs undiscovered until a nice segfault comes around.
I wouldn't mind an MMU on the P3, but the main feature I want right now for the P2 is for it to exist in real silicon. But even without an MMU on the P2, it should still be possible to emulate one fairly efficiently with a smart enough compiler.
I've begun to notice that most of my complaints about computers these days are actually problems that mainly exist in C and C++ compilers. Maybe I should try a higher level language than C++, like Haskell or Ocaml or even just D. But then someone would have to port that new language to the Propeller.
I should get to work on my extended spin compiler so I can get an idea of how hard writing good compilers that prove everything and magically show you all your bugs actually is, then I'll stop complaining.
...can't you have a compiler that makes sure that bad things will never happen,..
Indeed you can. Pascal inserts runtime array bounds checks. It's also very fussy about data types in assignments, parameter passing and so on. The Ada language carries this to extreme which is why people like to use it of safety critical systems. Even C and C++ do a little type checking.
Some of the correctness checks can be done at "compile time" while the compiler is analysing your source and generating code. Others are done at run time by checks that are built into the resulting executable.
I'm mainly complaining that compilers are stupid and don't check things they should,
"Stupid" may be putting a bit hard. Programming languages are designed with particular uses in mind and are tailored to work well for those uses. For example C was created as a low level but portable systems programming language, some say one step up from assembler. As such it allows you do pretty much anything you can do in assembler, including make all those errors, with the power comes the risk. Ada on the other hand was designed to be much higher level with a great emphasis on correctness.
These are statically typed language that produce a static executable. But what about languages with dynamic typing? Javascript for example allows any type to be stored in any variable at any time. Writing to a non-existent array element is OK, the array just gets stretched to fit. Functions can be created and destroyed at run time. Everything is dynamic.
I used to think that anything that was not strictly, statically typed with a bunch of compile time checks was stupid too. In recent years I have changed my mind. My reasoning goes like this:
1) Having dynamic, probably interpreted, language means there is no waiting for the compiler, just edit code and see what it does. Much easier and quicker development.
2) Source code without all the type specifications in it is much easier to write and read.
3) If you are serious about your program working you will have a lot of tests in place, unit tests, integration test, etc. Those tests will show up problems due to type miss-matches, writing to the wrong place in an array, forgetting function parameters, etc, etc Well, given that you are serious and do have those tests there is no point in having he compiler check everything.
4) Putting those run time checks into an embedded system is pretty pointless. Sure it will raise an
exception when an array is overstepped or whatever but then what? Generally it means your program has arrived at a bad state that cannot be recovered from, the only thing to do is halt or reset. At this point the breaks fail, the plane crashes, the nuclear power station melts down! Such checks are useful during development though.
5) Ultimately, as you say, a compiler cannot check everything.
There seems to be some confusion over the terms "embedded" or "embedded system". It's just a label for a computer that is incorporated into some other system such that the users of that system don't have to know there is a computer in there. It just does whatever the system should do. Think Primary Flight Computers of a Fly By Wire aircraft, or even a Point of sale terminal. "embedded" does not mean small or real-time. An embedded system could well be a full up PC class machine with virtual memory and a serious OS line Windows or Linux (Well, Linux anyway )Right, but small or real-time usually *does* mean embedded, that's why I said the propeller is meant for embedded applications.
Are you saying that the spinneret enables you to create an entire web server in PASM on a Propeller? I very much doubt it.
Actually, yes, that is what I'm saying. A web server is just a machine that is contacted over the internet to provide a service, as opposed to a client. That's why the spinneret product page says "Spinneret Web Server" :P.
Now, I'm thinking there actually *is* a way to run a full featured OS without a MMU or a performance penalty, so long as some requirements are met. The OS would need to be a microkernel, and would need to run the file system as a user space process. Then, programs would need to use capability-based addressing (see here), and therefore can only talk to the physical storage media through the kernel, since data structures like pointers would be illegal. In a way, it's like implementing the LMM on top of the kernel (since the kernel is privileged anyway) instead of underneath it.
I agree the Propeller is intended for embedded applications.
The Spinneret is certainly a web server. But how much of that web serving is happening in PASM? WIZnet is doing all the TCP/IP stack. I suspect the HTTP stuff is done in Spin. I have never looked.
Are you saying that the spinneret enables you to create an entire web server in PASM on a Propeller? I very much doubt it.
I said yes, it enables you to make it in PASM. You could do it in spin if you want.
Nitpicking about totally irrelevant stuff aside, I think an MMU, or at least some sort of ability to code an MMU (which would just need interrupts) would be a great feature, and would allow the P2 to step into the OS-design educational market (high-school/college).
Although it would have to compete with ARM/MIPS/etc.... What student can, let alone want to, program in ARM or MIPS assembly? ALL OS's require at least some assembly in them (that's what prevents windows from running on powerpc, for example), and the fact that the propeller is perhaps an order of magnitude simpler than an ARM/MIPS is a huge bonus.
Basically you have converted a Prop into a regular processor, like an ARM or MIPS or Power PC or whatever.
Well, my observation is that Parallax can never compete in that space. There are so many such machines already. No point in doing it.
At the same time you have made the Prop as complex as those other guys, thus destroying it's attraction to the markets it has. This is not only "no point" it's detrimental to the Props future.
I'm not sure of the complexity of the MIPS instruction set you claim. Whilst it is more to handle than PASM I have helped a few CS undergraduates with their assignments that involved MIPS assembler programming and it seemed pretty straight forward and regular to me. Unlike Intel x86 say.
I'm not sure you are right about Windows on Power PC. There was such a beast back in the day. But if MS decides to not to support building Windows for whatever architecture then that is the end of that.
In recent times MS has produced some kind of Windows for ARM.
I don't really see how addition of a feature would destroy its attraction to its current markets. If you don't need all eight cogs, just use seven. Same with any other added feature, no?
The additional complexity for the hardware depends on how much you're willing to offload to software. I think just adding interrupts is really enough. Even something as massive as Linux doesn't need a full-blown MMU if you can find a way to handle physical memory locations in software. Just an MPU. And even an MPU isn't necessary, just a way to send an interrupt if a seg fault occurs.
---
Here's what I'm proposing: add interrupt support. That way, a cog could be programmed as an MMU, and send the interrupts if necessary. No huge integrated MMU, no MPU, no other additional features really, just interrupts. That way you can make an MMU if you want, AND it's an additional feature in the target embedded market anyway.
Would anyone else like to see interrupt support? Or is everyone really satisfied with polling?
Not sure how easy it is to find old discussions on this new forum, but this topic has been beat to death, repeatedly, as in over and over and over, ad infinitum, ground hog day...
C.W.
Interrupts (as mentioned many times before) are also complex in a pipelined multiprocessor such as the P2. The interrupt processing is usually deferred to the inter-instruction time. Are prefetched instructions thrown away? How about prefetched operands? Some processors just throw everything away when an interrupt occurs. When execution is resumed, they just start over again. That's simple, but slows down execution if there are a lot of interrupts.
Me, I'm very happy with polling on a multiprocessor. I don't want the complexity (hardware and software) of interrupt support. It's not necessary.
Not sure how easy it is to find old discussions on this new forum, but this topic has been beat to death, repeatedly, as in over and over and over, ad infinitum, ground hog day...
C.W.
Ah, sorry then. Does anyone have a link to a main thread, if there is one, regarding interrupts on the P2?
And Mike Green, Tor, thank you very much for explaining. Once I have a P2 (and the time lol) I would like to start a project to get some sort of MMU functionality on it, and I'd love to have your ideas on it. I'm thinking there must be some sort of workaround too, I'm just not sure what it is yet.... But I do have a feeling haha. I'll start a thread when I start coding.
Here's what I'm proposing: add interrupt support. That way, a cog could be programmed as an MMU, and send the interrupts if necessary. No huge integrated MMU, no MPU, no other additional features really, just interrupts. That way you can make an MMU if you want, AND it's an additional feature in the target embedded market anyway.
Please elaborate. What situations/events are you suggesting are signaled by those interrupts?
I can't imagine what you are suggesting. How does one make a MMU in software with only the help of an interrupt or two. Seems to me software address translation and/or rage checking on every memory access is going to make things run really slowly.
This debate about interrupts has been recurring for years. I wish there was a page somewhere where all the reasons the Prop does not have interrupts are laid out. I'd make one myself but I'm weary of it all.
If you checkout my ZiCog and Pullmolls qz80 Z80 emulators for the Prop projects you will see that they did at least have access to 64K or more of memory via and external memory driver with caches. That kind of idea could probably be extended into a more complex MMU. It's OK if you don't mind running slowly It's not clear that adding interrupts to those systems would have helped the emulator performance much.
Would anyone else like to see interrupt support? Or is everyone really satisfied with polling?
This comes down to semantics, and what interrupt support actually means.
Full classic interrupt has PUSH and POP and a stack.Small MCUs even have priority levels on interrupts, allowing higher priority interrupts to break into lower priority ones. Some have register bank switching for speed.That level of interrupt support is pretty much outside the scope of a P2.
However, there is a case for a hardware vector jump, but that has no stack and no PUSH or POP.Essentially, it is just a hardware triggered JMPRET.I would avoid calling that an interrupt, lest readers think it is something more.
I believe Mr, Green remembers working on these beauties!!
Yes, I did not include flags, but those could be saved in HW, which costs only a very few bits, vs the register cost to save/restore in SW.
The flags-save can be managed by the same tiny state engine that disables other INT sources from interrupting the current active INT.
mindrobots wrote:
We had 'full classic interrupts" without a stack or push/pop instructions. Univac 1100 series architecture, had 2 sets of registers to easily isolate user from executive space and also captured the P address and passed it to you at the time of the interrupt. It's been a long time since I worked with it but we did well without stacks.
Hmmm...interesting...let me cast that in Propeller terms:
On the Propeller we have the equivalent of "full classic interrupts" without a stack or push/pop instructions. The Propeller architecture has 8(16) sets of registers to easily isolate tasks form each other and allow low latency, deterministic response to events. We all work with it a lot and we do very well without stacks.
Of course that means we don't need classic interrupts either