Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
/* put core_id in edi */
movl LAPIC_VADDR+0x20, %edi
shrl $24, %edi
/* Switch to kernel stack */
movq kstack(, %rdi, 8), %rsp
I've never been happy with this method of a core discovering its id. Especially since lapic ids are not guaranteed to be numbered continuously from 0 to n-1. A lot of my code is happier if the cores are numbered sequentially. I've wanted to separate coreid from lapic id.
I think I just realised a better way of storing the core id within the core itself that allows numbering the cores as I like. Each core already has its own TSS and thus each core loads a different selector into its TR like this
If a core needs to know its id it can read its own TR, subtract 0x70 and right shift 4 bits. No memory access required. If I rearranged my GDT, I could get rid of the subtract so that core id would be TR>>4.
Does this seem like a good idea ?
- gerryg400
If a trainstation is where trains stop, what is a workstation ?
I use the same trick here, primarily because half the machines I test on do not have an enabled APIC. So yes, it works
Note that neither approach accesses memory - STR gets the TR via a bunch of micro-ops, and APIC accesses are caught before they enter the system bus.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Are you looking to avoid memory accesses in general or just the lapic? If it's just the LAPIC either using the kernel based GS offset on an x86-64 or a processor specific data segment with a static selector would work well. You could also store the kernel stack offset in such a structure and avoid any other additional calculations.
If you're simply looking for the Processor's ID the method you described should work just fine, though I don't know that you can guarantee continuous id's if processors are disabled for some reason. Still as long as you're generating the TSS descriptors with a consistent algorithm it should be fine. Overall though I've found a known data segment or using the kernel based GS offset to offer a lot more flexibility implementation wise.
Thanks both of you. I'm not really trying to avoid memory access. My original goal was to be able to give each core an id as it is woken by the BP. This all came about because one of my test machines has lapic ids 0, 2, 4, and 6. I still wanted to call the cores 0, 1, 2 and 3.
I really like the idea of storing the core specific stuff in the GS seg. I've only been in 64bit land for a few weeks and am revisiting (and breaking!) all my old and pretty stable 32bit code. Guess there are lots of neat tricks to learn.
- gerryg400
If a trainstation is where trains stop, what is a workstation ?