CS452 F23 Lecture Notes
Lecture 05 - 21 Sep 2023
1. Assignment Advice
- data structures: encapsulate, start simple, improve later
- use assertions generously
- some examples of mixed C/assembly programming in CasmDemo
- main.c, adder.c: basic arg passing using registers
- adder10.c: passing more than 8 args
- main.c, asmadder.S: manual assembler function with C caller
- asm.c - embed assembler in C code, exchange data with local vars
- recommendations:
- use embedded assembler only for short code sequences that do not access stack pointer
- use assembler routine linked as C routine for context-switch code
2. System Call Return
- context we saved when the
svc
instruction occured- X0-X30
- spel0 (the user program’s stack pointer)
- elrel1 (the user program’s program counter)
- spsrel1 (the user program’s processor state)
- when kernel has finished handling the interrupt and wants to return to a user task
- it needs to save kernel state (possibly)
- restore
- spel0, elrel1, spsrel1 from saved state
- finally, execute
eret
(exception return) instruction (eret
cannot be used from EL0)eret
restores PC from ELREL1, PSTATE from SPSREL1- returns to EL0 exception level
3. Kernel Initialization
- will initially be running boot.S:
- sets up EL1 stack pointer, masks interrupts, jumps to kmain
- what else needs to happen?
- need to initialize exception vector
- need to initialize any kernel data structures
- need to create an initial task, and context switch to it
- initial task will need to run some user-level function, at some priority
- you write the function, hard code function pointer into kernel
- set up task decriptor for intial task (see below)
- initial task will need to run some user-level function, at some priority
- how to context switch to the initial task
- set up saved task context to be the desired initial context for the user program
- return from exception (restore user context, the
eret
)
4. Task Descriptors
- task Id, parent Id, Priority, State (ready?, blocked?, running?)
- links?
- saved EL0 context (so you can context switch back to this task)
5. Passing Parameters
- see Chapter 9 of the Programmers Guide, and the Procedure Call Standard
- ABI (application binary interface) specifies register roles during procedure calls
- X0-X18 are “caller saved”
- X0-X7 are used for argument passing and return values
- first parameter in R0, second in R1, etc.
- X8 is indirect result location register
- for large results that cannot be placed in a register
- X9-X15 are temporary registers
- X16-X17: intra-procedure call temp register (otherwise - temp register)
- X18: platform register (otherwise - temp register)
- X0-X7 are used for argument passing and return values
- X19-X29: are “callee-saved”
- subroutine must save values before using registers, restore them on return
- caller expects values in these registers will be preserved across subroutine calls
- R29 - frame pointer
- R30 - link register
- holds return address, placed there by BL instruction used to invoke the subroutine
- Stack pointer alignment must be 16
- X0-X18 are “caller saved”
5.1. System Call Parameters
- example: int Create(int priority, void (*function)())
- how does the kernel receive the two parameters?
- how does it return the int?
- simple answer: can use the same arg/return conventions established by the ABI
- user program puts params into X0 and X1 before
svc
- kernel exception handler saves application context
- it can inspect saved X0 and X1 to find parameters
- kernel overwrites saved X0 with return value before
eret
- after
eret
, user program looks in X0 to find result
- user program puts params into X0 and X1 before
- system call stubs
- suppose we create a user-level function corresponding to each system call
int Create(int priority, void (*function)()) { --> svc N }
- Compiler will have placed params in x0 and x1 prior to branching to Create
- Compiler expects return value in x0 on
ret
from Create