Page 1 of 1

Storing the core id in the TR

Posted: Wed May 05, 2010 3:52 pm
by gerryg400
For some time I've had a bit of code something like this at the entrance to my kernel for traps and interrupts.

Code: Select all

		/* 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

Code: Select all

		wr_tr(0x70+id*0x10);
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

Re: Storing the core id in the TR

Posted: Wed May 05, 2010 4:05 pm
by Combuster
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.

Re: Storing the core id in the TR

Posted: Wed May 05, 2010 4:30 pm
by gerryg400
Combuster, lapic accesses still go thru the paging mechanism don't they? Wouldn't that potentially require a memory access ?

- gerryg400

Re: Storing the core id in the TR

Posted: Wed May 05, 2010 5:13 pm
by Cognition
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.

Example:

Code: Select all

   //Core id
   mov %gs:0, %edi
   //Kernel stack
   mov %gs:8, %rsp
   //PID
   mov %gs:16, %rsi
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.

Re: Storing the core id in the TR

Posted: Wed May 05, 2010 6:22 pm
by gerryg400
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