Distinguish between onboard PCIe- and plug-in PCIe devices
Distinguish between onboard PCIe- and plug-in PCIe devices
Greetings Os-Dev members!
my first request on this forum; this is exciting My question is rather simple, yet complicated to answer (besides the answer is "no").
Is there any way to distinguish between PCI(e) devices that are soldered onto the motherboard (e.g. a 2nd onboard ethernet controller) and devices which have been plugged into an arbitrary PCI(e) slot?
- My first idea was to make a list of all PCI(e) devices and their bus/device/function-numbers in an unmodified state (no devices plugged in). But bus-numbers will definitely differ depending on the devices which are (likely) plugged in, in the lifecycle of my platforms.
- In my research I came across the term "ACPI". But as far as I know ACPI is mostly about power management? Does ACPI have tables of motherboard components? The specification does not state this explicitly.
Any other ideas / hints for me?
Best regards!
my first request on this forum; this is exciting My question is rather simple, yet complicated to answer (besides the answer is "no").
Is there any way to distinguish between PCI(e) devices that are soldered onto the motherboard (e.g. a 2nd onboard ethernet controller) and devices which have been plugged into an arbitrary PCI(e) slot?
- My first idea was to make a list of all PCI(e) devices and their bus/device/function-numbers in an unmodified state (no devices plugged in). But bus-numbers will definitely differ depending on the devices which are (likely) plugged in, in the lifecycle of my platforms.
- In my research I came across the term "ACPI". But as far as I know ACPI is mostly about power management? Does ACPI have tables of motherboard components? The specification does not state this explicitly.
Any other ideas / hints for me?
Best regards!
- dchapiesky
- Member
- Posts: 204
- Joined: Sun Dec 25, 2016 1:54 am
- Libera.chat IRC: dchapiesky
Re: Distinguish between onboard PCIe- and plug-in PCIe devic
The conventional pci spec called devices on the motherboard "planar" devices..... from the wikipedia
But it appears your issue confounded even IBM where they had to implement custom firmware lookup tables..... https://www.ibm.com/developerworks/aix/ ... ion-codes/ as well with pci-e https://www.ibm.com/support/knowledgece ... ations.htm
So the right place to look may be BIOS/UEFI....
Another place to look may be the PCI-e enclosure code
Your investigation of ACPI may be confusing the use of SMBUS as part of the PCI-e specification... SMBUS is a simple 2 wire network which is used by PCI-e devices for initial configuration... ACPI does use this same bus for power management of said devices.... but ACPI is not the only reason SMBUS is used...
see Pins 5-9 under pinout... https://en.wikipedia.org/wiki/PCI_Express
Finally an old post (here: https://www.osronline.com/showthread.cfm?link=186835 )
says this is a snipe hunt...
But it appears your issue confounded even IBM where they had to implement custom firmware lookup tables..... https://www.ibm.com/developerworks/aix/ ... ion-codes/ as well with pci-e https://www.ibm.com/support/knowledgece ... ations.htm
So the right place to look may be BIOS/UEFI....
Another place to look may be the PCI-e enclosure code
Your investigation of ACPI may be confusing the use of SMBUS as part of the PCI-e specification... SMBUS is a simple 2 wire network which is used by PCI-e devices for initial configuration... ACPI does use this same bus for power management of said devices.... but ACPI is not the only reason SMBUS is used...
see Pins 5-9 under pinout... https://en.wikipedia.org/wiki/PCI_Express
Finally an old post (here: https://www.osronline.com/showthread.cfm?link=186835 )
says this is a snipe hunt...
Don Burn wrote ... If you are thinking the Device Manager is reflecting something that is related to the ordering of the physical slots on the board you are sadly mistaken. There is no guarantee of a correlation between the data you can read from the controller and the slots on the board. ... Don's correct -- the "location" info that is reported in the DeviceManager can actually be set as part of the driver initialization, along with the UI number and Address. The OS builds it from the slot, bus and function number but those numbers have no real correlation to the actual backplane. I've done this dance with four companies so far, and spent considerable [billable, though!] time driving this point home: if you want to be able to specifically identify a particular card for an end user you need to a) put an EEPROM on the board that the driver can talk to and burn that EEPROM with a specific unique serial number and b) put an LED on that board that the driver can toggle on or off. There is just no other way to be able to specifically identify a particular card for an end user, and the HW boys are just going to have to go berserk over that one ...
Last edited by dchapiesky on Wed Feb 01, 2017 9:22 am, edited 1 time in total.
Plagiarize. Plagiarize. Let not one line escape thine eyes...
Re: Distinguish between onboard PCIe- and plug-in PCIe devic
Hi,
Cheers,
Brendan
In theory; (on "80x86 PC") you should be able to obtain this information from System Management BIOS. In practice; I wouldn't want to assume that any information provided by System Management BIOS is "100% guaranteed accurate" (firmware vendors tend to treat it as an afterthought).vollkorn wrote:Is there any way to distinguish between PCI(e) devices that are soldered onto the motherboard (e.g. a 2nd onboard ethernet controller) and devices which have been plugged into an arbitrary PCI(e) slot?
You might be able to use "chipset identification" (e.g. product ID of host bridge and LPC bridge) to infer the information; but that won't be complete (e.g. additional devices motherboard manufacturer added to the motherboard that aren't built directly into the chipset) and will involve maintaining a huge database of all possible motherboards.vollkorn wrote:- My first idea was to make a list of all PCI(e) devices and their bus/device/function-numbers in an unmodified state (no devices plugged in). But bus-numbers will definitely differ depending on the devices which are (likely) plugged in, in the lifecycle of my platforms.
ACPI is "Advanced Configuration" in addition to "Power Interface" (it's not just power management alone). I'm not sure; but I doubt ACPI has what you want.vollkorn wrote:- In my research I came across the term "ACPI". But as far as I know ACPI is mostly about power management? Does ACPI have tables of motherboard components? The specification does not state this explicitly.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: Distinguish between onboard PCIe- and plug-in PCIe devic
Hi again,
Cheers,
Brendan
Brendan wrote:In theory; (on "80x86 PC") you should be able to obtain this information from System Management BIOS. In practice; I wouldn't want to assume that any information provided by System Management BIOS is "100% guaranteed accurate" (firmware vendors tend to treat it as an afterthought).
Just wanted to point out that these would make a good combination. Specifically; you could use "chipset identification" (and a database of motherboard details) and then fall back to SMBIOS if there's no information in the motherboard database. That way, the database would only need details for computers where SMBIOS doesn't provide correct information (and wouldn't need to contain information for all motherboards); and you'd be "mostly immune" to SMBIOS problems.Brendan wrote:You might be able to use "chipset identification" (e.g. product ID of host bridge and LPC bridge) to infer the information; but that won't be complete (e.g. additional devices motherboard manufacturer added to the motherboard that aren't built directly into the chipset) and will involve maintaining a huge database of all possible motherboards.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
- dchapiesky
- Member
- Posts: 204
- Joined: Sun Dec 25, 2016 1:54 am
- Libera.chat IRC: dchapiesky
Re: Distinguish between onboard PCIe- and plug-in PCIe devic
It should be noted that PCI bus numbers are not a physical 1-1 relationship with slots...
Bus numbers are based on a counter in each bridge where as the bridge finds (via SMBUS) a valid device, it increments the counter and reports that device using the new value.
If a board is removed - ALL subsequent bus numbers (and bridge numbers - as they are PCI devices as well) will change.
Unless you have an authoritarian based work flow in your shop - human error will inevitably screw up your database of device locations.
Bus numbers are based on a counter in each bridge where as the bridge finds (via SMBUS) a valid device, it increments the counter and reports that device using the new value.
If a board is removed - ALL subsequent bus numbers (and bridge numbers - as they are PCI devices as well) will change.
Unless you have an authoritarian based work flow in your shop - human error will inevitably screw up your database of device locations.
Plagiarize. Plagiarize. Let not one line escape thine eyes...
Re: Distinguish between onboard PCIe- and plug-in PCIe devic
Thanks for your replies!
I just tested Brendans approach using the SMBIOS information via "dmidecode" utility. There is a structure which is call "Onboard Devices Extended Information (Type 41)". For one ethernet controller it looks like this:
The downside:
1. this information was not available on every board I tested.
2. the bus address (see above) was 0000:00:00.0. From this structure I known that there is one I210 controller onboard. I cannot distinguish between this onboard I210 controller and other I210 controllers. The actual bus number of this device is 0000:04:00.0.
I tried another utility "biosdecode" which gave me a interrupt routine table (see below). I assume that this is the $pir table (https://people.freebsd.org/~jhb/papers/ ... node5.html)
I just tested Brendans approach using the SMBIOS information via "dmidecode" utility. There is a structure which is call "Onboard Devices Extended Information (Type 41)". For one ethernet controller it looks like this:
Code: Select all
Handle 0x005A, DMI type 41, 11 bytes
Onboard Device
Reference Designation: Intel I210AT
Type: Ethernet
Status: Enabled
Type Instance: 1
Bus Address: 0000:00:00.0
1. this information was not available on every board I tested.
2. the bus address (see above) was 0000:00:00.0. From this structure I known that there is one I210 controller onboard. I cannot distinguish between this onboard I210 controller and other I210 controllers. The actual bus number of this device is 0000:04:00.0.
This is true, but I don't care about slot numbers (for now).It should be noted that PCI bus numbers are not a physical 1-1 relationship with slots...
I tried another utility "biosdecode" which gave me a interrupt routine table (see below). I assume that this is the $pir table (https://people.freebsd.org/~jhb/papers/ ... node5.html)
Again, this worked on one board. On another board this information was not quite logical.PCI Interrupt Routing 1.0 present.
Router ID: 00:1f.0
Exclusive IRQs: None
Compatible Router: 8086:27b8
Slot Entry 1: ID 00:1c, on-board
Slot Entry 2: ID 00:01, on-board
Slot Entry 3: ID 00:03, on-board
Slot Entry 4: ID 00:02, on-board
Slot Entry 5: ID 00:1f, on-board
Slot Entry 6: ID 00:14, on-board
Slot Entry 7: ID 00:1a, on-board
Slot Entry 8: ID 00:16, on-board
Slot Entry 9: ID 00:19, on-board <-- My i210 device
Slot Entry 10: ID 00:1b, on-board
Slot Entry 11: ID 00:1d, on-board
Slot Entry 12: ID 04:00, on-board
Slot Entry 13: ID 02:00, on-board
Slot Entry 14: ID 03:07, slot number 1
Slot Entry 15: ID 03:06, slot number 2
Slot Entry 16: ID 03:05, slot number 3
Slot Entry 17: ID 03:04, slot number 4
Slot Entry 18: ID 05:00, slot number 5
Slot Entry 19: ID 01:00, slot number 7
- Schol-R-LEA
- Member
- Posts: 1925
- Joined: Fri Oct 27, 2006 9:42 am
- Location: Athens, GA, USA
Re: Distinguish between onboard PCIe- and plug-in PCIe devic
I think you may have hit on a good idea by accident, actually.Brendan wrote:You might be able to use "chipset identification" (e.g. product ID of host bridge and LPC bridge) to infer the information; but that won't be complete (e.g. additional devices motherboard manufacturer added to the motherboard that aren't built directly into the chipset) and will involve maintaining a huge database of all possible motherboards.
Creating and, more crucially, maintaining and correcting such a database, would actually be an excellent project in and of itself, and not just for OS development. If nothing else, it would serve to consolidate knowledge currently scattered among less public databases at companies like Intel, Microsoft and Oracle, and among the configuration files of the *BSDs and various Linux distros.
However, it is not something that would be a part of a single hobby OS project, or even a single commercial OS project - it is the sort of massive operation that really would have to be done as a formal consortium, run by a small group of subject matter experts and supported by dozens of volunteers, with some doing the basic research and a separate group doing confirmation. It would probably also require at least a few good negotiators with at least basic domain knowledge who could work with the manufacturers to try and crowbar some additional information out of them where needed.
If they provided a common format for providing motherboard information - you know, what SMBIOS was supposed to have been from the start - as a supplemental report that developers could refer to, and as a downloadable data structure which installer programs and operating systems themselves could interrogate, it would save everyone a lot of wheel reinventing.
The problem, of course, is that no matter how good this idea might be, it would need someone to start it, a group of people to run it, and a raft of dosh to keep it running. Even running something like this on a shoestring would at least require paying for the hosting and other basic infrastructure. It's the sort of thing Patreon exists for, but the interest group is so small that it would be difficult to get enough support.
I am not the one to do this, for a number of reasons which should be obvious from my previous posts. Perhaps some other members would be able to, but I am not going to hold my breath. I hope someone does, but hoping wouldn't get it done. As a somewhat Machiavellian aside, perhaps some of the more... ah... OCD and/or AS members could be persuaded to divert attention from their OS work into this? It is the sort of thing that could benefit from obsessive attention to detail.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Re: Distinguish between onboard PCIe- and plug-in PCIe devic
Could you explain this idea in a little more detail?Schol-R-LEA wrote:I think you may have hit on a good idea by accident, actually.Brendan wrote:You might be able to use "chipset identification" (e.g. product ID of host bridge and LPC bridge) to infer the information; but that won't be complete (e.g. additional devices motherboard manufacturer added to the motherboard that aren't built directly into the chipset) and will involve maintaining a huge database of all possible motherboards.
Re: Distinguish between onboard PCIe- and plug-in PCIe devic
Hi,
However; a motherboard is more than a chipset; and there can be devices built into the motherboard that were not built into the chipset. By getting "system manufacturer, product name and version" from SMBIOS, and identifying the chipset, and combining all that information (and having some sort of firmware/ACPI table checksum scheme to ensure it's the right one) you can identify the motherboard. If you had a large database containing all information for all motherboards, then after identifying the motherboard you could use the database to determine all devices that were built into the motherboard.
Determining a "motherboard ID" isn't too hard. The problem is that a huge database containing all information for all motherboards doesn't really exist, and it would take a large number of people a lot of time to create one (and maintain it after its created), so in practice this isn't viable for a lone hobby OS developer.
If a large number of people (e.g. hobby OS developers) did spend a lot of time to create a database of motherboard information; then all hobby OS developers would be able to use it, and this could make the idea viable. This is what Schol-R-LEA is suggesting.
The alternative is to a partial/minimal database of motherboard information that only contains information that can't be obtained in other ways (e.g. that can't be obtained from SMBIOS because SMBIOS is buggy for that motherboard). In this case the database of motherboard information would be much smaller; which would make it more practical for a lone hobby OS developer. That is what I was suggesting.
Cheers,
Brendan
All PCI devices (including host bridges and LPC bridges) have a "vendor ID" and a "product ID" (in the device's PCI configuration space) to identify the specific device. The "vendor ID" and "product ID" of the PCI host bridge/s and PCI to LPC bridge can be used to identify the chipset. If you had a large database containing all information for all chipsets, then after identifying the chipset you could use the database to determine all devices that were built into that chipset.vollkorn wrote:Could you explain this idea in a little more detail?Schol-R-LEA wrote:I think you may have hit on a good idea by accident, actually.Brendan wrote:You might be able to use "chipset identification" (e.g. product ID of host bridge and LPC bridge) to infer the information; but that won't be complete (e.g. additional devices motherboard manufacturer added to the motherboard that aren't built directly into the chipset) and will involve maintaining a huge database of all possible motherboards.
However; a motherboard is more than a chipset; and there can be devices built into the motherboard that were not built into the chipset. By getting "system manufacturer, product name and version" from SMBIOS, and identifying the chipset, and combining all that information (and having some sort of firmware/ACPI table checksum scheme to ensure it's the right one) you can identify the motherboard. If you had a large database containing all information for all motherboards, then after identifying the motherboard you could use the database to determine all devices that were built into the motherboard.
Determining a "motherboard ID" isn't too hard. The problem is that a huge database containing all information for all motherboards doesn't really exist, and it would take a large number of people a lot of time to create one (and maintain it after its created), so in practice this isn't viable for a lone hobby OS developer.
If a large number of people (e.g. hobby OS developers) did spend a lot of time to create a database of motherboard information; then all hobby OS developers would be able to use it, and this could make the idea viable. This is what Schol-R-LEA is suggesting.
The alternative is to a partial/minimal database of motherboard information that only contains information that can't be obtained in other ways (e.g. that can't be obtained from SMBIOS because SMBIOS is buggy for that motherboard). In this case the database of motherboard information would be much smaller; which would make it more practical for a lone hobby OS developer. That is what I was suggesting.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: Distinguish between onboard PCIe- and plug-in PCIe devic
Hi,
For a "very random" example; for my OS project I want a 3D model/mesh of the motherboard so that (in conjunction with other models for other hardware - computer case, PCI devices, RAM modules, disk drives, etc) the OS is able to construct an accurate virtual model of the whole computer; which would be used for marketing (take a virtual tour inside a computer before you buy it), and showing the exact location of a faulty device that needs replacing, and used for planning upgrades (will this large video card fit in that PCI slot or will CPU cooler get in the way?); and potentially (with information from other sources - fan speed controllers, temperature sensors, disk activity, etc) used for real-time thermal modelling and real-time acoustic modelling.
Cheers,
Brendan
To achieve "critical mass" (to get enough people participating to make it useful) you'd need a lot of people to agree with contents and format; but everyone will have different ideas of what information it should/could contain and what format it should/could be in.Schol-R-LEA wrote:I think you may have hit on a good idea by accident, actually.Brendan wrote:You might be able to use "chipset identification" (e.g. product ID of host bridge and LPC bridge) to infer the information; but that won't be complete (e.g. additional devices motherboard manufacturer added to the motherboard that aren't built directly into the chipset) and will involve maintaining a huge database of all possible motherboards.
Creating and, more crucially, maintaining and correcting such a database, would actually be an excellent project in and of itself, and not just for OS development. If nothing else, it would serve to consolidate knowledge currently scattered among less public databases at companies like Intel, Microsoft and Oracle, and among the configuration files of the *BSDs and various Linux distros.
However, it is not something that would be a part of a single hobby OS project, or even a single commercial OS project - it is the sort of massive operation that really would have to be done as a formal consortium, run by a small group of subject matter experts and supported by dozens of volunteers, with some doing the basic research and a separate group doing confirmation. It would probably also require at least a few good negotiators with at least basic domain knowledge who could work with the manufacturers to try and crowbar some additional information out of them where needed.
If they provided a common format for providing motherboard information - you know, what SMBIOS was supposed to have been from the start - as a supplemental report that developers could refer to, and as a downloadable data structure which installer programs and operating systems themselves could interrogate, it would save everyone a lot of wheel reinventing.
The problem, of course, is that no matter how good this idea might be, it would need someone to start it, a group of people to run it, and a raft of dosh to keep it running. Even running something like this on a shoestring would at least require paying for the hosting and other basic infrastructure. It's the sort of thing Patreon exists for, but the interest group is so small that it would be difficult to get enough support.
I am not the one to do this, for a number of reasons which should be obvious from my previous posts. Perhaps some other members would be able to, but I am not going to hold my breath. I hope someone does, but hoping wouldn't get it done. As a somewhat Machiavellian aside, perhaps some of the more... ah... OCD and/or AS members could be persuaded to divert attention from their OS work into this? It is the sort of thing that could benefit from obsessive attention to detail.
For a "very random" example; for my OS project I want a 3D model/mesh of the motherboard so that (in conjunction with other models for other hardware - computer case, PCI devices, RAM modules, disk drives, etc) the OS is able to construct an accurate virtual model of the whole computer; which would be used for marketing (take a virtual tour inside a computer before you buy it), and showing the exact location of a faulty device that needs replacing, and used for planning upgrades (will this large video card fit in that PCI slot or will CPU cooler get in the way?); and potentially (with information from other sources - fan speed controllers, temperature sensors, disk activity, etc) used for real-time thermal modelling and real-time acoustic modelling.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
- dchapiesky
- Member
- Posts: 204
- Joined: Sun Dec 25, 2016 1:54 am
- Libera.chat IRC: dchapiesky
Re: Distinguish between onboard PCIe- and plug-in PCIe devic
As shown in the IBM links I provided, IBM at least maintains a database for certain systems in it's product line....
Maybe a Greyback OSDev Elder could post a message at intel or their developer website http://01.org asking if such a database exists for intel motherboards and would they make it available to the OSDev community as a whole.... (I suggest this route rather than just 1 person making the request for obvious reasons....)
If this succeeds then perhaps another message to Dell, (HP is so screwed organizationally right now I don't think they could find a light socket right now), and others you feel are popular brands.... ASUS comes to mind.
2 cents...
cheers
Maybe a Greyback OSDev Elder could post a message at intel or their developer website http://01.org asking if such a database exists for intel motherboards and would they make it available to the OSDev community as a whole.... (I suggest this route rather than just 1 person making the request for obvious reasons....)
If this succeeds then perhaps another message to Dell, (HP is so screwed organizationally right now I don't think they could find a light socket right now), and others you feel are popular brands.... ASUS comes to mind.
2 cents...
cheers
Plagiarize. Plagiarize. Let not one line escape thine eyes...
- Schol-R-LEA
- Member
- Posts: 1925
- Joined: Fri Oct 27, 2006 9:42 am
- Location: Athens, GA, USA
Re: Distinguish between onboard PCIe- and plug-in PCIe devic
@Brendan: This is a valid point, and one which, now that I see it, I can see as significant problem. I... well, I'm not sure if it a generally soluble one, in the abstract. Can a 90%+ solution be found? In the realm of OS development specifically... I dunno.
<aside type="Pointless (and not in the Haskell sense)">
I think there's even a name for this problem, probably several - it is something that pops up in the design of objects/data structures in general; it comes up in things related to satisficing, value weighting, and Pareto optimization in economics; hell, if you pardon a bit of fanciful woolgathering, in some ways is at the heart of our inability to reconcile macro and microscopic physical phenomena.
Why do I mention that analogy? Because it makes for an analogy to one (non-)solution: the Copenhagen Interpretation. Whose model is right? The one that gets the right answers in the current frame of reference, of course. But if we need to compare or convert between them, that's a problem, so... we need... I dunno, what would be the equivalent of the Lorenz transformation in data modeling even look like? No, wait, Lorenz is about frames of reference in spacetime, uhm... sum-over-histories transforms on a manifold matrix? No, dammit, I'm getting confused here, and even if it were a sensible analogy, without the measurable interaction constraints of actual masses to give limits, that would literally take infinite memory and/or infinite computation time to perform, even if it were decidable... *sigh* got nothin'.
Ah, sorry about this. Reading about or viewing videos on certain highly meta topics (e.g., modern physics, strange loops, etc.) does strange things to me.
</aside>
TL;DR: Stop that! It's silly.
<aside type="Pointless (and not in the Haskell sense)">
I think there's even a name for this problem, probably several - it is something that pops up in the design of objects/data structures in general; it comes up in things related to satisficing, value weighting, and Pareto optimization in economics; hell, if you pardon a bit of fanciful woolgathering, in some ways is at the heart of our inability to reconcile macro and microscopic physical phenomena.
Why do I mention that analogy? Because it makes for an analogy to one (non-)solution: the Copenhagen Interpretation. Whose model is right? The one that gets the right answers in the current frame of reference, of course. But if we need to compare or convert between them, that's a problem, so... we need... I dunno, what would be the equivalent of the Lorenz transformation in data modeling even look like? No, wait, Lorenz is about frames of reference in spacetime, uhm... sum-over-histories transforms on a manifold matrix? No, dammit, I'm getting confused here, and even if it were a sensible analogy, without the measurable interaction constraints of actual masses to give limits, that would literally take infinite memory and/or infinite computation time to perform, even if it were decidable... *sigh* got nothin'.
Ah, sorry about this. Reading about or viewing videos on certain highly meta topics (e.g., modern physics, strange loops, etc.) does strange things to me.
</aside>
TL;DR: Stop that! It's silly.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.