rdos wrote:I use the ACPI APIC table to identify how the APIC should be configured and which cores are available and their IDs.
That would be the MADT I alluded to earlier. Indeed I do the same. To my knowledge, the only alternatives are to use the MP tables (which might no longer be present), or sending INIT and Startup IPIs to all cores excluding self. Which basically means firing a shotgun into a dark room. So yeah, the MADT is your only reasonable hope.
rdos wrote:This means that APs cannot be started until ACPI is started & the APIC is setup, which ocurs in the kernel and not in the boot-loader. I also fail to see the connection with EFI or BIOS boot. The ACPI table is available in both modes and in the same format.
Yeah, I remember now that bzt talked about BOOTBOOT having multicore support before. Essentially, BOOTBOOT will boot all available CPUs so you don't have to. The MADT requires no AML, so it is indeed reasonable for a bootloader to parse it.
rdos wrote:I also fail to see any reason why multiple cores should be started at the same time.
Because speed. Let's name the actors in this play the booter and the bootee. While the booter is waiting for signs of life from the bootee, it isn't doing anything productive. In most systems I have seen that use this mechanism, only the BSP will be a booter, an the APs will be blocked in the scheduler until something pushes tasks into the queue. That means, they aren't doing anything productive. As you can see from bzt's most recent reply, architecturally there is no reason why there can't be 65535 CPUs. If the BSP is starting all APs sequentially, and the APs don't do anything, they are going to be here a while.
Actually, 65535 is beyond my absolute task limit (32767), so the function creating the AP starter tasks should also be in its own task. Then it can block while waiting for a slot in the task queue to open up. I might have to revisit that design decision (having an absolute task limit) some time. Having more CPUs than tasks is probably not terribly sensible, so i might have to limit those.
rdos wrote:I boot them in turn, which is much simpler.
What, now you argue for simplicity and against performance? A week ago you argued the opposite position when discussing interrupt code. Make up your mind, please. In this case, I don't think it is much simpler. I have a block of memory I copy to an arbitrary location in low mem and then point the AP at. I don't have to hope a certain address is going to be free. I don't even have to run the starter code on the BSP, it can run on any core.
rdos wrote:I copy GDT, IDT, CR3, CR4 and other settings to low RAM at fixed locations, and then reference these from the bootstrap code.
I fail to see the point. Unless your goal is to keep running in 16-bit real mode, the GDT required as part of the trampoline will be different from the final GDT loaded in AP startup code, if for no other reason, by its address. The IDT makes no sense unless you are operating in the correct mode, but by that point, you will no longer need stuff to be in low memory to reference it. CR3, OK, that one is needed. CR4 less so, that can be done in the AP landing pad. It would also break encapsulation of the trampoline, since it is not the trampoline's place to tell you whether you should set, say, the WP bit. You should, but the trampoline is the wrong place to do it in. In 64-bit mode, you should also enable SYSCALL, yet the trampoline won't do that for you, either.