Skip to content

Conversation

@niklarm
Copy link
Contributor

@niklarm niklarm commented Nov 1, 2016

This moves the export table at the beginning of the uVisor binary and allows the application to just call a uVisor function, which then executes a thunk inside uVisor binary which does the SVC with the right ID.

Benchmark API is also removed.

TODO: Porting guide needs to be updated to reflect an additional load:

ldr r0, =uvisor_api
ldr r0, [r0, #8]
blx r0

cc @AlessandroA @Patater @meriac

api/src/api.c Outdated
/******************************** page heap ********************************/
int uvisor_page_malloc(UvisorPageTable * const table)
{
return uvisor_api.page.malloc(table);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this level of indirection? There are 2 important design requirements which I'm not sure we can satisfy at the same time with this approach:

  1. All entry points in one file.
  2. The one file shows immediately which API will be run in P, NP, S, NS mode.

1. is satisfied here, but then the check on "where are you coming from" will be scattered throughout the other several files, compromising 2..

Also, we already discussed this: By using this level of indirection the boundary P/NP is shifted. It is more natural that the uvisor-lib runs the very last instruction that is executed in NP. The uvisor-core instead would run the very first instruction which is executed in P mode. In that sense the svc should be called from here (lib) and not from the core.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A benefit of uVisor core doing the transition is that interface between uVisor core and all other software is just a simple table of functions that are callable via the ordinary AAPCS. uVisor core is then able to later decide how the transitions should work and when, which is of benefit when we are still trying out different models of transitioning.

Also note that not all entry points into uVisor core will perform a transition: pool queue code is shared between uVisor core and other software, but lives in the uVisor core binary because uVisor core also runs the code and we want all code that runs privileged to live in the uVisor core binary.

2 sounds like a "nice to have" and not a "must have", but I don't see the basic approach we are taking here as antithetical to 2; we could still do 2, but where an API runs is platform dependent (v7 vs v8) and awkward to annotate at this level of abstraction.

@niklarm niklarm force-pushed the feature/capi branch 3 times, most recently from 81519bc to dabd5fa Compare November 2, 2016 16:34
}

/* Use this one weird trick to map functions to SVC IDs. */
#define UVISOR_SVC_ID_debug_register_driver UVISOR_SVC_ID_DEBUG_REGISTER_BOX
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just define the IDs out of the function names? See my old commit:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason why I didn't do that was that if you change the function name, you also have to change the SVC IDs in many places and that would spam this PR a little.
Would you like me to add this as a separate commit though?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes please!

"svc %[svc_id] \n" \
"bx lr \n" \
:: [svc_id] "I" (UVISOR_SVC_ID_ ## fn_name & 0xFF) \
:: [svc_id] "I" UVISOR_SVC_ID_GET(fn_target) \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you re-add the parentheses here?

@mazimkhan
Copy link

The uvisor build and test jobs are misleading. The batch script that does uvisor build does not make Jenkins realise that make has failed. Will fix it soon.

13:46:50 ./platform/beetle/debug/configuration_beetle_cortex_m3_0x20000000_0x140.linker:8: nonconstant expression for origin
13:46:50 collect2.exe: error: ld returned 1 exit status
13:46:50 make[3]: *** [platform/beetle/debug/configuration_beetle_cortex_m3_0x20000000_0x140.elf] Error 1
13:46:50 make[3]: Leaving directory `c:/jsbld/ws/mbed-os/uvisor-pr-test-pipeline@2/mbed-os/features/FEATURE_UVISOR/importer/TARGET_IGNORE/uvisor'
13:46:50 make[2]: *** [CONFIGURATION_BEETLE_CORTEX_M3_0x20000000_0x140] Error 2
13:46:50 make[2]: Leaving directory `c:/jsbld/ws/mbed-os/uvisor-pr-test-pipeline@2/mbed-os/features/FEATURE_UVISOR/importer/TARGET_IGNORE/uvisor'
13:46:50 make[1]: *** [platform-beetle] Error 2
13:46:50 make[1]: Leaving directory `c:/jsbld/ws/mbed-os/uvisor-pr-test-pipeline@2/mbed-os/features/FEATURE_UVISOR/importer/TARGET_IGNORE/uvisor'
13:46:50 make: *** [uvisor-compile] Error 2
13:46:50 make: Leaving directory `c:/jsbld/ws/mbed-os/uvisor-pr-test-pipeline@2/mbed-os/features/FEATURE_UVISOR/importer'

LENGTH = UVISOR_SRAM_LENGTH_USED - STACK_SIZE
STACK (rw) : ORIGIN = (SRAM_ORIGIN + SRAM_OFFSET + UVISOR_SRAM_LENGTH_USED - STACK_SIZE),
LENGTH = STACK_SIZE
LENGTH = UVISOR_SRAM_LENGTH_USED - STACK_SIZE - STACK_GUARD_BAND
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to group changes to the STACK_GUARD_BAND in this commit, which is otherwise focused on replacing export_table.c with api.c?

LENGTH = STACK_SIZE
LENGTH = UVISOR_SRAM_LENGTH_USED - STACK_SIZE - STACK_GUARD_BAND
STACK (rw) : ORIGIN = ORIGIN(RAM) + LENGTH(RAM),
LENGTH = UVISOR_SRAM_LENGTH_PROTECTED - LENGTH(RAM)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes also seem to want grouping into a separate commit that has a commit description that explains these changes more explicitly.

The only changes to the linker script that makes sense to be grouped with the export_table.c to api.c transition commit are the ones involved in replacing the export_table with uvisor_api; otherwise, the diff is noisy.

The moving of the stack into its own section is certainly a logical change deserving of its own separate commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved into separate commit.

Copy link
Contributor

@Patater Patater left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have verified that each commit of this PR builds individually.

@niklarm niklarm force-pushed the feature/capi branch 2 times, most recently from f3405be to 6354ac9 Compare November 7, 2016 11:54
For clarity, this moves the functions in export_table.c into three
separate files.
Cleanup unused sections and use better section size computation.
Instead of calling SVCs in the application directly, the API function in
the uvisor_api table is called, which jumps into uVisors binary and
performs the SVC. This way no synchronization of SVC IDs between uVisor
and the application needs to be performed.

Note that this also speeds up calling the pool queue APIs, since the
position of the export table needs not be manually computed anymore.
@meriac meriac merged commit b6efa6b into ARMmbed:master Nov 8, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants