RISC-V: Add kernel device functionalty

- Create device untypeds for platform devices that can be passed to user
space.
- Create kernel device mapping for devices required by the kernel.
Note that the current kernel device mapping is simply a 1GiB of page
physical memory as that contains all devices for all RISC-V platforms
that are currently supported.
This commit is contained in:
Siwei Zhuang 2019-05-22 20:56:52 +10:00 committed by Kent McLeod
parent 2865d6b61b
commit 4b24006678
7 changed files with 79 additions and 1 deletions

View file

@ -24,4 +24,19 @@ static p_region_t BOOT_DATA avail_p_regs[] = {
#endif
};
static const paddr_t BOOT_RODATA kernel_devices[] = {
/* Plic0 */
0x00000000,
};
static const p_region_t BOOT_RODATA dev_p_regs[] = {
{ 0x10010000, 0x10011000 }, /* UART0 */
{ 0x10011000, 0x10012000 }, /* UART1 */
{ 0x10020000, 0x10021000 }, /* PWM0 */
{ 0x10021000, 0x10022000 }, /* PWM1 */
{ 0x10060000, 0x10061000 }, /* GPIO */
{ 0x10090000, 0x10091000 }, /* ETH */
};
#endif

View file

@ -24,4 +24,8 @@ static p_region_t BOOT_DATA avail_p_regs[] = {
#endif
};
static const paddr_t BOOT_RODATA *kernel_devices = NULL;
static const p_region_t BOOT_RODATA *dev_p_regs = NULL;
#endif

View file

@ -20,4 +20,7 @@ static p_region_t BOOT_DATA avail_p_regs[] = {
{ /*.start = */ 0x0, /* .end = */ 0x10000000}
};
static const paddr_t BOOT_RODATA *kernel_devices = NULL;
static const p_region_t BOOT_RODATA *dev_p_regs = NULL;
#endif

View file

@ -62,6 +62,8 @@
int get_num_avail_p_regs(void);
p_region_t *get_avail_p_regs(void);
int get_num_dev_p_regs(void);
p_region_t get_dev_p_reg(word_t i);
void map_kernel_devices(void);
bool_t CONST isReservedIRQ(irq_t irq);

View file

@ -42,10 +42,22 @@ BOOT_CODE static bool_t create_untypeds(cap_t root_cnode_cap, region_t boot_mem_
{
seL4_SlotPos slot_pos_before;
seL4_SlotPos slot_pos_after;
region_t dev_reg;
slot_pos_before = ndks_boot.slot_pos_cur;
bool_t res = create_kernel_untypeds(root_cnode_cap, boot_mem_reuse_reg, slot_pos_before);
UNUSED paddr_t current_region_pos = 0;
for (int i = 0; i < get_num_dev_p_regs(); i++) {
assert(get_dev_p_reg(i).start >= current_region_pos);
current_region_pos = get_dev_p_reg(i).end;
dev_reg = paddr_to_pptr_reg(get_dev_p_reg(i));
if (!create_untypeds_for_region(root_cnode_cap, true,
dev_reg, slot_pos_before)) {
return false;
}
}
slot_pos_after = ndks_boot.slot_pos_cur;
ndks_boot.bi_frame->untyped = (seL4_SlotRegion) {
slot_pos_before, slot_pos_after

View file

@ -98,6 +98,12 @@ static pte_t pte_next(word_t phys_addr, bool_t is_leaf)
/* ==================== BOOT CODE STARTS HERE ==================== */
BOOT_CODE void map_kernel_frame(paddr_t paddr, pptr_t vaddr, vm_rights_t vm_rights)
{
assert((paddr % RISCV_GET_LVL_PGSIZE(1)) == 0);
kernel_root_pageTable[RISCV_GET_PT_INDEX(vaddr, 1)] = pte_next(paddr, true);
}
BOOT_CODE VISIBLE void map_kernel_window(void)
{
/* mapping of kernelBase (virtual address) to kernel's physBase */
@ -142,8 +148,9 @@ BOOT_CODE VISIBLE void map_kernel_window(void)
}
#endif
/* There should be 1GiB free where we will put device mapping some day */
/* There should be 1GiB free where we put device mapping */
assert(pptr == UINTPTR_MAX - RISCV_GET_LVL_PGSIZE(1) + 1);
map_kernel_devices();
}
BOOT_CODE void map_it_pt_cap(cap_t vspace_cap, cap_t pt_cap)

View file

@ -50,6 +50,41 @@ BOOT_CODE p_region_t *get_avail_p_regs(void)
return (p_region_t *) avail_p_regs;
}
BOOT_CODE int get_num_dev_p_regs(void)
{
if (dev_p_regs != NULL) {
return (sizeof(dev_p_regs) / sizeof(p_region_t));
} else {
return 0;
}
}
BOOT_CODE p_region_t get_dev_p_reg(word_t i)
{
/* We need this if guard as some RISC-V configurations don't declare any
* device regions and some compilers complain about indexing an empty array
* due to not being able to infer that get_dev_p_reg is only called if
* dev_p_regs contains entries.
*/
if (get_num_dev_p_regs() == 0) {
printf("%s: No devices present.\n", __func__);
halt();
}
return dev_p_regs[i];
}
BOOT_CODE void map_kernel_devices(void)
{
if (kernel_devices == NULL) {
return;
}
for (int i = 0; i < (sizeof(kernel_devices) / sizeof(paddr_t)); i++) {
map_kernel_frame(kernel_devices[i], PPTR_KDEV,
VMKernelOnly);
}
}
/**
DONT_TRANSLATE
*/