| Skiboot overview |
| ================ |
| |
| Skiboot is firmware, loaded by the FSP. Along with loading the bootloader, |
| it provides some runtime services to the OS (typically Linux). |
| |
| Source layout |
| ------------- |
| |
| ========= =================================== |
| Directory Content |
| ========= =================================== |
| asm/ small amount, mainly entry points |
| ccan/ bits from CCAN |
| core/ common code among machines. |
| doc/ not enough here |
| external/ tools to run external of sapphire. |
| hdata/ all stuff going to/from FSP |
| hw/ drivers for things & fsp things. |
| include/ headers! |
| libc/ tiny libc, from SLOF |
| libfdt/ straight device tree lib |
| libpore/ to manipulate PORE engine. |
| ========= =================================== |
| |
| We have a spinlock implementation in asm/lock.S |
| Entry points are detailed in asm/head.S |
| The main C entry point is in core/init.c: main_cpu_entry() |
| |
| Binaries |
| -------- |
| The following binaries are built: |
| |
| =========== ============================================ |
| File Purpose |
| =========== ============================================ |
| skiboot.lid is the actual lid. objdump out |
| skiboot.elf is the elf binary of it, lid comes from this |
| skiboot.map plain map of symbols |
| =========== ============================================ |
| |
| Booting |
| ------- |
| |
| On boot, every thread of execution jumps to a single entry point in skiboot |
| so we need to do some magic to ensure we init things properly and don't stomp |
| on each other. We choose a master thread, putting everybody else into a |
| spinloop. |
| |
| Essentially, we do this by doing an atomic fetch and inc and whoever gets 0 |
| gets to be the master. |
| |
| When we enter skiboot we also get a memory location in a register which |
| is the location of a device tree for the system. We flatten out the device |
| tree, turning offsets into real pointers and manipulating it where needed. |
| We re-flatten the device tree before booting the OS (Linux). |
| |
| The main entry point is main_cpu_entry() in core/init.c, this is a carefully |
| ordered init of things. The sequence is relatively well documented there. |
| |
| OS interface |
| ------------ |
| |
| Skiboot maintains its own stack for each CPU. We do not have an ABI like |
| "may use X stack on OS stack", we entirely keep to our own stack space. |
| The OS (Linux) calling skiboot will never use any OS stack space and the OS |
| does not need to call skiboot with a valid stack. |
| |
| We define an array of stacks, one for each CPU. On entry to skiboot, |
| we can find out stack by multiplying our CPU number by the stack size and |
| adding that to the address of the stack area. |
| |
| At the bottom of each stack area is a per CPU data structure, which we |
| can get to by chopping off the LSBs of the stack pointer. |
| |
| The OPAL interface is a generic message queue. The Linux side of things |
| can be found in linux/arch/powerpc/platform/powernv/ |
| |
| Interrupts |
| ---------- |
| |
| We don't handle interrupts in skiboot. |
| |
| In the future we may have to change to process machine check interrupts |
| during boot. |
| |
| We do not have timer interrupts. |
| |
| |
| Memory |
| ------ |
| |
| We initially occupy a chunk of memory, "heap". We pass to the OS (Linux) |
| a reservation of what we occupy (including stacks). |
| |
| In the source file include/mem-map.h we include a memory map. This is |
| manually generated, not automatically generated. |
| |
| We use CCAN for a bunch of helper code, turning on things like DEBUG_LOCKS |
| and DEBUG_MALLOC as these are not a performance issue for us, and we like |
| to be careful. |
| |
| In include/config.h there are defines for turning on extra tracing. |
| OPAL is what we name the interface from skiboot to OS (Linux). |
| |
| Each CPU gets a 16k stack, which is probably more than enough. Stack |
| should be used sparingly though. |
| |
| Important memory locations: |
| |
| ============= ============================================================ |
| Location What's there |
| ============= ============================================================ |
| SKIBOOT_BASE where skiboot lives, of SKIBOOT_SIZE |
| HEAP_BASE Where skiboot heap starts, of HEAP_SIZE |
| ============= ============================================================ |
| |
| There is also SKIBOOT_SIZE (manually calculated) and DEVICE_TREE_MAX_SIZE, |
| which is largely historical. |
| |
| Skiboot log |
| ----------- |
| |
| There is a circular log buffer that skiboot maintains. This can be |
| accessed either from the FSP or through /dev/mem or through the sysfs |
| file /sys/firmware/opal/msglog. |