diff --git a/benchmark/benchmark.c b/benchmark/benchmark.c index 16e730c03..92bd24e13 100644 --- a/benchmark/benchmark.c +++ b/benchmark/benchmark.c @@ -93,8 +93,7 @@ static void benchmark_print_IPC_data(uint64_t *buffer, uint32_t id) number_schedules = buffer[BENCHMARK_TCB_NUMBER_SCHEDULES]; kernel = buffer[BENCHMARK_TCB_KERNEL_UTILISATION]; entries = buffer[BENCHMARK_TCB_NUMBER_KERNEL_ENTRIES]; - sddf_printf("Utilisation details for PD: %s (%x)\n", - pd_id_to_name(id), id); + sddf_printf("Utilisation details for PD: %s (%x)\n", pd_id_to_name(id), id); } sddf_printf("{\nKernelUtilisation: %lx\nKernelEntries: " "%lx\nNumberSchedules: %lx\nTotalUtilisation: %lx\n}\n", @@ -219,9 +218,9 @@ void notified(microkit_channel ch) void init(void) { - serial_cli_queue_init_sys(microkit_name, NULL, NULL, NULL, - &serial_tx_queue_handle, serial_tx_queue, - serial_tx_data); + uint32_t serial_tx_data_capacity; + serial_cli_data_capacity(microkit_name, NULL, &serial_tx_data_capacity); + serial_queue_init(&serial_tx_queue_handle, serial_tx_queue, serial_tx_data_capacity, serial_tx_data); serial_putchar_init(SERIAL_TX_CH, &serial_tx_queue_handle); bench_core_config_info(microkit_name, &core_config); @@ -263,20 +262,18 @@ seL4_Bool fault(microkit_child id, microkit_msginfo msginfo, microkit_msginfo *r sddf_printf("BENCH|LOG: Faulting PD %s (%x)\n", pd_id_to_name(id), id); seL4_UserContext regs; - seL4_TCB_ReadRegisters(BASE_TCB_CAP + id, false, 0, - sizeof(seL4_UserContext) / sizeof(seL4_Word), ®s); + seL4_TCB_ReadRegisters(BASE_TCB_CAP + id, false, 0, sizeof(seL4_UserContext) / sizeof(seL4_Word), ®s); sddf_printf("Registers: \npc : %lx\nspsr : %lx\nx0 : %lx\nx1 : %lx\n" "x2 : %lx\nx3 : %lx\nx4 : %lx\nx5 : %lx\nx6 : %lx\nx7 : %lx\n", - regs.pc, regs.spsr, regs.x0, regs.x1, regs.x2, regs.x3, - regs.x4, regs.x5, regs.x6, regs.x7); + regs.pc, regs.spsr, regs.x0, regs.x1, regs.x2, regs.x3, regs.x4, regs.x5, regs.x6, regs.x7); switch (microkit_msginfo_get_label(msginfo)) { case seL4_Fault_CapFault: { uint64_t ip = seL4_GetMR(seL4_CapFault_IP); uint64_t fault_addr = seL4_GetMR(seL4_CapFault_Addr); uint64_t in_recv_phase = seL4_GetMR(seL4_CapFault_InRecvPhase); - sddf_printf("CapFault: ip=%lx fault_addr=%lx in_recv_phase=%s\n", - ip, fault_addr, (in_recv_phase == 0 ? "false" : "true")); + sddf_printf("CapFault: ip=%lx fault_addr=%lx in_recv_phase=%s\n", ip, fault_addr, + (in_recv_phase == 0 ? "false" : "true")); break; } case seL4_Fault_UserException: { @@ -288,8 +285,7 @@ seL4_Bool fault(microkit_child id, microkit_msginfo msginfo, microkit_msginfo *r uint64_t fault_addr = seL4_GetMR(seL4_VMFault_Addr); uint64_t is_instruction = seL4_GetMR(seL4_VMFault_PrefetchFault); uint64_t fsr = seL4_GetMR(seL4_VMFault_FSR); - sddf_printf("VMFault: ip=%lx fault_addr=%lx fsr=%lx %s\n", - ip, fault_addr, fsr, + sddf_printf("VMFault: ip=%lx fault_addr=%lx fsr=%lx %s\n", ip, fault_addr, fsr, (is_instruction ? "(instruction fault)" : "(data fault)")); break; } diff --git a/examples/echo_server/include/serial_config/serial_config.h b/examples/echo_server/include/serial_config/serial_config.h index ebe4626a1..d49d7c424 100644 --- a/examples/echo_server/include/serial_config/serial_config.h +++ b/examples/echo_server/include/serial_config/serial_config.h @@ -11,7 +11,7 @@ #include /* Number of clients that can be connected to the serial server. */ -#define SERIAL_NUM_CLIENTS 3 +#define NUM_SERIAL_CLIENTS 3 /* Only support transmission and not receive. */ #define SERIAL_TX_ONLY 1 @@ -41,47 +41,63 @@ #define SERIAL_TX_DATA_REGION_CAPACITY_CLI1 SERIAL_DATA_REGION_CAPACITY #define SERIAL_TX_DATA_REGION_CAPACITY_CLI2 SERIAL_DATA_REGION_CAPACITY +/* To avoid deadlocks caused when the virtualiser adds colour codes to the + start and end of strings, driver data region must be larger than any + client data region. */ #define SERIAL_MAX_CLIENT_TX_DATA_CAPACITY MAX(SERIAL_TX_DATA_REGION_CAPACITY_CLI2, MAX(SERIAL_TX_DATA_REGION_CAPACITY_CLI0, SERIAL_TX_DATA_REGION_CAPACITY_CLI1)) #if SERIAL_WITH_COLOUR _Static_assert(SERIAL_TX_DATA_REGION_CAPACITY_DRIV > SERIAL_MAX_CLIENT_TX_DATA_CAPACITY, "Driver TX data region must be larger than all client data regions in SERIAL_WITH_COLOUR mode."); #endif +/* Ensure the entire data region can be assigned a unique index by a 32 bit + unsigned. */ #define SERIAL_MAX_DATA_CAPACITY MAX(SERIAL_TX_DATA_REGION_CAPACITY_DRIV, SERIAL_MAX_CLIENT_TX_DATA_CAPACITY) _Static_assert(SERIAL_MAX_DATA_CAPACITY < UINT32_MAX, "Data regions must be smaller than UINT32 max to correctly use queue data structure."); -static inline void serial_cli_queue_init_sys(char *pd_name, serial_queue_handle_t *rx_queue_handle, - serial_queue_t *rx_queue, - char *rx_data, serial_queue_handle_t *tx_queue_handle, serial_queue_t *tx_queue, char *tx_data) +static inline void serial_cli_data_capacity(char *pd_name, uint32_t *rx_data_capacity, uint32_t *tx_data_capacity) { if (!sddf_strcmp(pd_name, SERIAL_CLI0_NAME)) { - serial_queue_init(tx_queue_handle, tx_queue, SERIAL_TX_DATA_REGION_CAPACITY_CLI0, tx_data); + *tx_data_capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI0; } else if (!sddf_strcmp(pd_name, SERIAL_CLI1_NAME)) { - serial_queue_init(tx_queue_handle, tx_queue, SERIAL_TX_DATA_REGION_CAPACITY_CLI1, tx_data); + *tx_data_capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI1; } else if (!sddf_strcmp(pd_name, SERIAL_CLI2_NAME)) { - serial_queue_init(tx_queue_handle, tx_queue, SERIAL_TX_DATA_REGION_CAPACITY_CLI2, tx_data); + *tx_data_capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI2; } } -static inline void serial_virt_queue_init_sys(char *pd_name, serial_queue_handle_t *cli_queue_handle, - serial_queue_t *cli_queue, char *cli_data) +typedef struct serial_queue_info { + serial_queue_t *cli_queue; + char *cli_data; + uint32_t capacity; +} serial_queue_info_t; + +static inline void serial_virt_queue_info(char *pd_name, serial_queue_t *cli_queue, char *cli_data, + serial_queue_info_t ret[NUM_SERIAL_CLIENTS]) { if (!sddf_strcmp(pd_name, SERIAL_VIRT_TX_NAME)) { - serial_queue_init(cli_queue_handle, cli_queue, SERIAL_TX_DATA_REGION_CAPACITY_CLI0, cli_data); - serial_queue_init(&cli_queue_handle[1], (serial_queue_t *)((uintptr_t)cli_queue + SERIAL_QUEUE_SIZE), - SERIAL_TX_DATA_REGION_CAPACITY_CLI1, cli_data + SERIAL_TX_DATA_REGION_CAPACITY_CLI0); - serial_queue_init(&cli_queue_handle[2], (serial_queue_t *)((uintptr_t)cli_queue + 2 * SERIAL_QUEUE_SIZE), - SERIAL_TX_DATA_REGION_CAPACITY_CLI2, - cli_data + SERIAL_TX_DATA_REGION_CAPACITY_CLI0 + SERIAL_TX_DATA_REGION_CAPACITY_CLI1); + ret[0] = (serial_queue_info_t) { .cli_queue = cli_queue, + .cli_data = cli_data, + .capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI0 }; + ret[1] = + (serial_queue_info_t) { .cli_queue = (serial_queue_t *)((uintptr_t)ret[0].cli_queue + SERIAL_QUEUE_SIZE), + .cli_data = ret[0].cli_data + ret[0].capacity, + .capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI1 }; + ret[2] = + (serial_queue_info_t) { .cli_queue = (serial_queue_t *)((uintptr_t)ret[1].cli_queue + SERIAL_QUEUE_SIZE), + .cli_data = ret[1].cli_data + ret[1].capacity, + .capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI2 }; } } #if SERIAL_WITH_COLOUR -static inline void serial_channel_names_init(char **client_names) +static inline void serial_channel_names_init(char *pd_name, char *client_names[NUM_SERIAL_CLIENTS]) { - client_names[0] = SERIAL_CLI0_NAME; - client_names[1] = SERIAL_CLI1_NAME; - client_names[2] = SERIAL_CLI2_NAME; + if (!sddf_strcmp(pd_name, SERIAL_VIRT_TX_NAME)) { + client_names[0] = SERIAL_CLI0_NAME; + client_names[1] = SERIAL_CLI1_NAME; + client_names[2] = SERIAL_CLI2_NAME; + } } #endif diff --git a/examples/echo_server/include/serial_config_smp/serial_config.h b/examples/echo_server/include/serial_config_smp/serial_config.h index 2a498e530..98df83bfd 100644 --- a/examples/echo_server/include/serial_config_smp/serial_config.h +++ b/examples/echo_server/include/serial_config_smp/serial_config.h @@ -11,7 +11,7 @@ #include /* Number of clients that can be connected to the serial server. */ -#define SERIAL_NUM_CLIENTS 6 +#define NUM_SERIAL_CLIENTS 6 /* Only support transmission and not receive. */ #define SERIAL_TX_ONLY 1 @@ -62,60 +62,69 @@ _Static_assert(SERIAL_TX_DATA_REGION_CAPACITY_DRIV > SERIAL_MAX_CLIENT_TX_DATA_C _Static_assert(SERIAL_MAX_DATA_CAPACITY < UINT32_MAX, "Data regions must be smaller than UINT32 max to correctly use queue data structure."); -static inline void serial_cli_queue_init_sys(char *pd_name, serial_queue_handle_t *rx_queue_handle, - serial_queue_t *rx_queue, char *rx_data, - serial_queue_handle_t *tx_queue_handle, serial_queue_t *tx_queue, - char *tx_data) +static inline void serial_cli_data_capacity(char *pd_name, uint32_t *rx_data_capacity, uint32_t *tx_data_capacity) { if (!sddf_strcmp(pd_name, SERIAL_CLI0_NAME)) { - serial_queue_init(tx_queue_handle, tx_queue, SERIAL_TX_DATA_REGION_CAPACITY_CLI0, tx_data); + *tx_data_capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI0; } else if (!sddf_strcmp(pd_name, SERIAL_CLI1_NAME)) { - serial_queue_init(tx_queue_handle, tx_queue, SERIAL_TX_DATA_REGION_CAPACITY_CLI1, tx_data); + *tx_data_capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI1; } else if (!sddf_strcmp(pd_name, SERIAL_CLI2_NAME)) { - serial_queue_init(tx_queue_handle, tx_queue, SERIAL_TX_DATA_REGION_CAPACITY_CLI2, tx_data); + *tx_data_capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI2; } else if (!sddf_strcmp(pd_name, SERIAL_CLI3_NAME)) { - serial_queue_init(tx_queue_handle, tx_queue, SERIAL_TX_DATA_REGION_CAPACITY_CLI3, tx_data); + *tx_data_capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI3; } else if (!sddf_strcmp(pd_name, SERIAL_CLI4_NAME)) { - serial_queue_init(tx_queue_handle, tx_queue, SERIAL_TX_DATA_REGION_CAPACITY_CLI4, tx_data); + *tx_data_capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI4; } else if (!sddf_strcmp(pd_name, SERIAL_CLI5_NAME)) { - serial_queue_init(tx_queue_handle, tx_queue, SERIAL_TX_DATA_REGION_CAPACITY_CLI5, tx_data); + *tx_data_capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI5; } } -static inline void serial_virt_queue_init_sys(char *pd_name, serial_queue_handle_t *cli_queue_handle, - serial_queue_t *cli_queue, char *cli_data) +typedef struct serial_queue_info { + serial_queue_t *cli_queue; + char *cli_data; + uint32_t capacity; +} serial_queue_info_t; + +static inline void serial_virt_queue_info(char *pd_name, serial_queue_t *cli_queue, char *cli_data, + serial_queue_info_t ret[NUM_SERIAL_CLIENTS]) { if (!sddf_strcmp(pd_name, SERIAL_VIRT_TX_NAME)) { - serial_queue_init(cli_queue_handle, cli_queue, SERIAL_TX_DATA_REGION_CAPACITY_CLI0, cli_data); - serial_queue_init(&cli_queue_handle[1], (serial_queue_t *)((uintptr_t)cli_queue + SERIAL_QUEUE_SIZE), - SERIAL_TX_DATA_REGION_CAPACITY_CLI1, cli_data + SERIAL_TX_DATA_REGION_CAPACITY_CLI0); - serial_queue_init(&cli_queue_handle[2], (serial_queue_t *)((uintptr_t)cli_queue + 2 * SERIAL_QUEUE_SIZE), - SERIAL_TX_DATA_REGION_CAPACITY_CLI2, - cli_data + SERIAL_TX_DATA_REGION_CAPACITY_CLI0 + SERIAL_TX_DATA_REGION_CAPACITY_CLI1); - serial_queue_init(&cli_queue_handle[3], (serial_queue_t *)((uintptr_t)cli_queue + 3 * SERIAL_QUEUE_SIZE), - SERIAL_TX_DATA_REGION_CAPACITY_CLI3, - cli_data + SERIAL_TX_DATA_REGION_CAPACITY_CLI0 + SERIAL_TX_DATA_REGION_CAPACITY_CLI1 - + SERIAL_TX_DATA_REGION_CAPACITY_CLI2); - serial_queue_init(&cli_queue_handle[4], (serial_queue_t *)((uintptr_t)cli_queue + 4 * SERIAL_QUEUE_SIZE), - SERIAL_TX_DATA_REGION_CAPACITY_CLI4, - cli_data + SERIAL_TX_DATA_REGION_CAPACITY_CLI0 + SERIAL_TX_DATA_REGION_CAPACITY_CLI1 - + SERIAL_TX_DATA_REGION_CAPACITY_CLI2 + SERIAL_TX_DATA_REGION_CAPACITY_CLI3); - serial_queue_init(&cli_queue_handle[5], (serial_queue_t *)((uintptr_t)cli_queue + 5 * SERIAL_QUEUE_SIZE), - SERIAL_TX_DATA_REGION_CAPACITY_CLI5, - cli_data + SERIAL_TX_DATA_REGION_CAPACITY_CLI0 + SERIAL_TX_DATA_REGION_CAPACITY_CLI1 - + SERIAL_TX_DATA_REGION_CAPACITY_CLI2 + SERIAL_TX_DATA_REGION_CAPACITY_CLI3 - + SERIAL_TX_DATA_REGION_CAPACITY_CLI4); + ret[0] = (serial_queue_info_t) { .cli_queue = cli_queue, + .cli_data = cli_data, + .capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI0 }; + ret[1] = + (serial_queue_info_t) { .cli_queue = (serial_queue_t *)((uintptr_t)ret[0].cli_queue + SERIAL_QUEUE_SIZE), + .cli_data = ret[0].cli_data + ret[0].capacity, + .capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI1 }; + ret[2] = + (serial_queue_info_t) { .cli_queue = (serial_queue_t *)((uintptr_t)ret[1].cli_queue + SERIAL_QUEUE_SIZE), + .cli_data = ret[1].cli_data + ret[1].capacity, + .capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI2 }; + ret[3] = + (serial_queue_info_t) { .cli_queue = (serial_queue_t *)((uintptr_t)ret[2].cli_queue + SERIAL_QUEUE_SIZE), + .cli_data = ret[2].cli_data + ret[2].capacity, + .capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI3 }; + ret[4] = + (serial_queue_info_t) { .cli_queue = (serial_queue_t *)((uintptr_t)ret[3].cli_queue + SERIAL_QUEUE_SIZE), + .cli_data = ret[3].cli_data + ret[3].capacity, + .capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI4 }; + ret[5] = + (serial_queue_info_t) { .cli_queue = (serial_queue_t *)((uintptr_t)ret[4].cli_queue + SERIAL_QUEUE_SIZE), + .cli_data = ret[4].cli_data + ret[4].capacity, + .capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI5 }; } } #if SERIAL_WITH_COLOUR -static inline void serial_channel_names_init(char **client_names) +static inline void serial_channel_names_init(char *pd_name, char *client_names[NUM_SERIAL_CLIENTS]) { - client_names[0] = SERIAL_CLI0_NAME; - client_names[1] = SERIAL_CLI1_NAME; - client_names[2] = SERIAL_CLI2_NAME; - client_names[3] = SERIAL_CLI3_NAME; - client_names[4] = SERIAL_CLI4_NAME; - client_names[5] = SERIAL_CLI5_NAME; + if (!sddf_strcmp(pd_name, SERIAL_VIRT_TX_NAME)) { + client_names[0] = SERIAL_CLI0_NAME; + client_names[1] = SERIAL_CLI1_NAME; + client_names[2] = SERIAL_CLI2_NAME; + client_names[3] = SERIAL_CLI3_NAME; + client_names[4] = SERIAL_CLI4_NAME; + client_names[5] = SERIAL_CLI5_NAME; + } } #endif diff --git a/examples/echo_server/lwip.c b/examples/echo_server/lwip.c index 54bfe0b29..119369a7b 100644 --- a/examples/echo_server/lwip.c +++ b/examples/echo_server/lwip.c @@ -286,13 +286,15 @@ static void netif_status_callback(struct netif *netif) void init(void) { - serial_cli_queue_init_sys(microkit_name, NULL, NULL, NULL, &serial_tx_queue_handle, serial_tx_queue, serial_tx_data); + uint32_t serial_tx_data_capacity; + serial_cli_data_capacity(microkit_name, NULL, &serial_tx_data_capacity); + serial_queue_init(&serial_tx_queue_handle, serial_tx_queue, serial_tx_data_capacity, serial_tx_data); serial_putchar_init(SERIAL_TX_CH, &serial_tx_queue_handle); - size_t rx_capacity, tx_capacity; - net_cli_queue_capacity(microkit_name, &rx_capacity, &tx_capacity); - net_queue_init(&state.rx_queue, rx_free, rx_active, rx_capacity); - net_queue_init(&state.tx_queue, tx_free, tx_active, tx_capacity); + size_t net_rx_capacity, net_tx_capacity; + net_cli_queue_capacity(microkit_name, &net_rx_capacity, &net_tx_capacity); + net_queue_init(&state.rx_queue, rx_free, rx_active, net_rx_capacity); + net_queue_init(&state.tx_queue, tx_free, tx_active, net_tx_capacity); net_buffers_init(&state.tx_queue, 0); lwip_init(); diff --git a/examples/serial/README.md b/examples/serial/README.md index 027a1e10c..b11db6471 100644 --- a/examples/serial/README.md +++ b/examples/serial/README.md @@ -86,7 +86,7 @@ system file including client names and queue sizes, as well as updated initialis for clients and virtualisers. * **Makefile** You must include directories for **SERIAL_COMPONENTS**, the **UART_DRIVER** and your -**SERIAL_CONFIG_INCLUDE**. You must also supply **SERIAL_NUM_CLIENTS**. You must add the uart +**SERIAL_CONFIG_INCLUDE**. You must also supply **NUM_SERIAL_CLIENTS**. You must add the uart driver, transmit virtualiser and optionally the receive virtualiser to your image list. You must add your serial include directory to your cflags, and finally you must include the uart driver and serial_components make files. For each component you wish to have access to the serial @@ -117,4 +117,4 @@ completed, and waits for input. When a character is received, each client will r character using `sddf_putchar_unbuffered` which flushes the character to the device immediately. Every tenth character each client will print a string containing their name using `sddf_printf` which calls the serial `_sddf_putchar`, flushing characters to the device only when a `\n` is -encountered. \ No newline at end of file +encountered. diff --git a/examples/serial/include/serial_config/serial_config.h b/examples/serial/include/serial_config/serial_config.h index eeb1f8a7b..77cabf5b4 100644 --- a/examples/serial/include/serial_config/serial_config.h +++ b/examples/serial/include/serial_config/serial_config.h @@ -10,7 +10,8 @@ #include #include -#define SERIAL_NUM_CLIENTS 2 +/* Number of clients that can be connected to the serial server. */ +#define NUM_SERIAL_CLIENTS 2 /* Only support transmission and not receive. */ #define SERIAL_TX_ONLY 0 @@ -47,49 +48,68 @@ #define SERIAL_RX_DATA_REGION_CAPACITY_CLI0 SERIAL_DATA_REGION_CAPACITY #define SERIAL_RX_DATA_REGION_CAPACITY_CLI1 SERIAL_DATA_REGION_CAPACITY +/* To avoid deadlocks caused when the virtualiser adds colour codes to the + start and end of strings, driver data region must be larger than any + client data region. */ #define SERIAL_MAX_CLIENT_TX_DATA_CAPACITY MAX(SERIAL_TX_DATA_REGION_CAPACITY_CLI0, SERIAL_TX_DATA_REGION_CAPACITY_CLI1) #if SERIAL_WITH_COLOUR _Static_assert(SERIAL_TX_DATA_REGION_CAPACITY_DRIV > SERIAL_MAX_CLIENT_TX_DATA_CAPACITY, "Driver TX data region must be larger than all client data regions in SERIAL_WITH_COLOUR mode."); #endif +/* Ensure the entire data region can be assigned a unique index by a 32 bit + unsigned. */ #define SERIAL_MAX_TX_DATA_CAPACITY MAX(SERIAL_TX_DATA_REGION_CAPACITY_DRIV, SERIAL_MAX_CLIENT_TX_DATA_CAPACITY) #define SERIAL_MAX_RX_DATA_CAPACITY MAX(SERIAL_RX_DATA_REGION_CAPACITY_DRIV, MAX(SERIAL_RX_DATA_REGION_CAPACITY_CLI0, SERIAL_RX_DATA_REGION_CAPACITY_CLI1)) #define SERIAL_MAX_DATA_CAPACITY MAX(SERIAL_MAX_TX_DATA_CAPACITY, SERIAL_MAX_RX_DATA_CAPACITY) _Static_assert(SERIAL_MAX_DATA_CAPACITY < UINT32_MAX, "Data regions must be smaller than UINT32 max to correctly use queue data structure."); -static inline void serial_cli_queue_init_sys(char *pd_name, serial_queue_handle_t *rx_queue_handle, - serial_queue_t *rx_queue, - char *rx_data, serial_queue_handle_t *tx_queue_handle, serial_queue_t *tx_queue, char *tx_data) +static inline void serial_cli_data_capacity(char *pd_name, uint32_t *rx_data_capacity, uint32_t *tx_data_capacity) { if (!sddf_strcmp(pd_name, SERIAL_CLI0_NAME)) { - serial_queue_init(rx_queue_handle, rx_queue, SERIAL_RX_DATA_REGION_CAPACITY_CLI0, rx_data); - serial_queue_init(tx_queue_handle, tx_queue, SERIAL_TX_DATA_REGION_CAPACITY_CLI0, tx_data); + *tx_data_capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI0; + *rx_data_capacity = SERIAL_RX_DATA_REGION_CAPACITY_CLI0; } else if (!sddf_strcmp(pd_name, SERIAL_CLI1_NAME)) { - serial_queue_init(rx_queue_handle, rx_queue, SERIAL_RX_DATA_REGION_CAPACITY_CLI1, rx_data); - serial_queue_init(tx_queue_handle, tx_queue, SERIAL_TX_DATA_REGION_CAPACITY_CLI1, tx_data); + *tx_data_capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI1; + *rx_data_capacity = SERIAL_RX_DATA_REGION_CAPACITY_CLI1; } } -static inline void serial_virt_queue_init_sys(char *pd_name, serial_queue_handle_t *cli_queue_handle, - serial_queue_t *cli_queue, char *cli_data) +typedef struct serial_queue_info { + serial_queue_t *cli_queue; + char *cli_data; + uint32_t capacity; +} serial_queue_info_t; + +static inline void serial_virt_queue_info(char *pd_name, serial_queue_t *cli_queue, char *cli_data, + serial_queue_info_t ret[NUM_SERIAL_CLIENTS]) { - if (!sddf_strcmp(pd_name, SERIAL_VIRT_RX_NAME)) { - serial_queue_init(cli_queue_handle, cli_queue, SERIAL_RX_DATA_REGION_CAPACITY_CLI0, cli_data); - serial_queue_init(&cli_queue_handle[1], (serial_queue_t *)((uintptr_t)cli_queue + SERIAL_QUEUE_SIZE), - SERIAL_RX_DATA_REGION_CAPACITY_CLI1, cli_data + SERIAL_RX_DATA_REGION_CAPACITY_CLI0); - } else if (!sddf_strcmp(pd_name, SERIAL_VIRT_TX_NAME)) { - serial_queue_init(cli_queue_handle, cli_queue, SERIAL_TX_DATA_REGION_CAPACITY_CLI0, cli_data); - serial_queue_init(&cli_queue_handle[1], (serial_queue_t *)((uintptr_t)cli_queue + SERIAL_QUEUE_SIZE), - SERIAL_TX_DATA_REGION_CAPACITY_CLI1, cli_data + SERIAL_TX_DATA_REGION_CAPACITY_CLI0); + if (!sddf_strcmp(pd_name, SERIAL_VIRT_TX_NAME)) { + ret[0] = (serial_queue_info_t) { .cli_queue = cli_queue, + .cli_data = cli_data, + .capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI0 }; + ret[1] = + (serial_queue_info_t) { .cli_queue = (serial_queue_t *)((uintptr_t)ret[0].cli_queue + SERIAL_QUEUE_SIZE), + .cli_data = ret[0].cli_data + ret[0].capacity, + .capacity = SERIAL_TX_DATA_REGION_CAPACITY_CLI1 }; + } else if (!sddf_strcmp(pd_name, SERIAL_VIRT_RX_NAME)) { + ret[0] = (serial_queue_info_t) { .cli_queue = cli_queue, + .cli_data = cli_data, + .capacity = SERIAL_RX_DATA_REGION_CAPACITY_CLI0 }; + ret[1] = + (serial_queue_info_t) { .cli_queue = (serial_queue_t *)((uintptr_t)ret[0].cli_queue + SERIAL_QUEUE_SIZE), + .cli_data = ret[0].cli_data + ret[0].capacity, + .capacity = SERIAL_RX_DATA_REGION_CAPACITY_CLI1 }; } } #if SERIAL_WITH_COLOUR -static inline void serial_channel_names_init(char **client_names) +static inline void serial_channel_names_init(char *pd_name, char *client_names[NUM_SERIAL_CLIENTS]) { - client_names[0] = SERIAL_CLI0_NAME; - client_names[1] = SERIAL_CLI1_NAME; + if (!sddf_strcmp(pd_name, SERIAL_VIRT_TX_NAME)) { + client_names[0] = SERIAL_CLI0_NAME; + client_names[1] = SERIAL_CLI1_NAME; + } } #endif diff --git a/examples/serial/serial_server.c b/examples/serial/serial_server.c index 2a49f2b3d..84d49d35a 100644 --- a/examples/serial/serial_server.c +++ b/examples/serial/serial_server.c @@ -24,7 +24,10 @@ uint32_t local_head; void init(void) { - serial_cli_queue_init_sys(microkit_name, &rx_queue_handle, rx_queue, rx_data, &tx_queue_handle, tx_queue, tx_data); + uint32_t rx_data_capacity, tx_data_capacity; + serial_cli_data_capacity(microkit_name, &rx_data_capacity, &tx_data_capacity); + serial_queue_init(&rx_queue_handle, rx_queue, rx_data_capacity, rx_data); + serial_queue_init(&tx_queue_handle, tx_queue, tx_data_capacity, tx_data); serial_putchar_init(TX_CH, &tx_queue_handle); sddf_printf("Hello world! I am %s.\nPlease give me character!\n", microkit_name); } diff --git a/serial/components/virt_rx.c b/serial/components/virt_rx.c index 4d107d1b5..c103fdc56 100644 --- a/serial/components/virt_rx.c +++ b/serial/components/virt_rx.c @@ -21,7 +21,7 @@ char *rx_data_drv; char *rx_data_cli0; serial_queue_handle_t rx_queue_handle_drv; -serial_queue_handle_t rx_queue_handle_cli[SERIAL_NUM_CLIENTS]; +serial_queue_handle_t rx_queue_handle_cli[NUM_SERIAL_CLIENTS]; #define MAX_CLI_BASE_10 4 typedef enum mode {normal, switched, number} mode_t; @@ -78,7 +78,7 @@ void rx_return(void) default: if (c == SERIAL_TERMINATE_NUM) { int input_number = sddf_atoi(next_client); - if (input_number >= 0 && input_number < SERIAL_NUM_CLIENTS) { + if (input_number >= 0 && input_number < NUM_SERIAL_CLIENTS) { if (transferred && serial_require_producer_signal(&rx_queue_handle_cli[current_client])) { serial_update_visible_tail(&rx_queue_handle_cli[current_client], local_tail); serial_cancel_producer_signal(&rx_queue_handle_cli[current_client]); @@ -129,7 +129,13 @@ void rx_return(void) void init(void) { serial_queue_init(&rx_queue_handle_drv, rx_queue_drv, SERIAL_RX_DATA_REGION_CAPACITY_DRIV, rx_data_drv); - serial_virt_queue_init_sys(microkit_name, rx_queue_handle_cli, rx_queue_cli0, rx_data_cli0); + + serial_queue_info_t queue_info[NUM_SERIAL_CLIENTS] = { 0 }; + serial_virt_queue_info(microkit_name, rx_queue_cli0, rx_data_cli0, queue_info); + for (int i = 0; i < NUM_SERIAL_CLIENTS; i++) { + serial_queue_init(&rx_queue_handle_cli[i], queue_info[i].cli_queue, queue_info[i].capacity, + queue_info[i].cli_data); + } } void notified(microkit_channel ch) diff --git a/serial/components/virt_tx.c b/serial/components/virt_tx.c index b57200771..46b82b062 100644 --- a/serial/components/virt_tx.c +++ b/serial/components/virt_tx.c @@ -41,17 +41,17 @@ const char *colours[] = { #define COLOUR_END "\x1b[0m" #define COLOUR_END_LEN 4 -char *client_names[SERIAL_NUM_CLIENTS]; +char *client_names[NUM_SERIAL_CLIENTS]; #endif serial_queue_handle_t tx_queue_handle_drv; -serial_queue_handle_t tx_queue_handle_cli[SERIAL_NUM_CLIENTS]; +serial_queue_handle_t tx_queue_handle_cli[NUM_SERIAL_CLIENTS]; -#define TX_PENDING_LEN (SERIAL_NUM_CLIENTS + 1) +#define TX_PENDING_LEN (NUM_SERIAL_CLIENTS + 1) typedef struct tx_pending { uint32_t queue[TX_PENDING_LEN]; - bool clients_pending[SERIAL_NUM_CLIENTS]; + bool clients_pending[NUM_SERIAL_CLIENTS]; uint32_t head; uint32_t tail; } tx_pending_t; @@ -71,7 +71,7 @@ static void tx_pending_push(uint32_t client) } /* Ensure the pending queue is not already full */ - assert(tx_pending_length() < SERIAL_NUM_CLIENTS); + assert(tx_pending_length() < NUM_SERIAL_CLIENTS); tx_pending.queue[tx_pending.tail] = client; tx_pending.clients_pending[client] = true; @@ -134,7 +134,7 @@ void tx_return(void) } uint32_t client; - bool notify_client[SERIAL_NUM_CLIENTS] = {false}; + bool notify_client[NUM_SERIAL_CLIENTS] = { false }; bool transferred = false; for (uint32_t req = 0; req < num_pending_tx; req++) { tx_pending_pop(&client); @@ -160,7 +160,7 @@ void tx_return(void) microkit_notify(DRIVER_CH); } - for (uint32_t client = 0; client < SERIAL_NUM_CLIENTS; client++) { + for (uint32_t client = 0; client < NUM_SERIAL_CLIENTS; client++) { if (notify_client[client] && serial_require_consumer_signal(&tx_queue_handle_cli[client])) { serial_cancel_consumer_signal(&tx_queue_handle_cli[client]); microkit_notify(client + CLIENT_OFFSET); @@ -170,7 +170,7 @@ void tx_return(void) void tx_provide(microkit_channel ch) { - if (ch > SERIAL_NUM_CLIENTS) { + if (ch > NUM_SERIAL_CLIENTS) { sddf_dprintf("VIRT_TX|LOG: Received notification from unknown channel %u\n", ch); return; } @@ -204,7 +204,13 @@ void tx_provide(microkit_channel ch) void init(void) { serial_queue_init(&tx_queue_handle_drv, tx_queue_drv, SERIAL_TX_DATA_REGION_CAPACITY_DRIV, tx_data_drv); - serial_virt_queue_init_sys(microkit_name, tx_queue_handle_cli, tx_queue_cli0, tx_data_cli0); + + serial_queue_info_t queue_info[NUM_SERIAL_CLIENTS] = { 0 }; + serial_virt_queue_info(microkit_name, tx_queue_cli0, tx_data_cli0, queue_info); + for (int i = 0; i < NUM_SERIAL_CLIENTS; i++) { + serial_queue_init(&tx_queue_handle_cli[i], queue_info[i].cli_queue, queue_info[i].capacity, + queue_info[i].cli_data); + } #if !SERIAL_TX_ONLY /* Print a deterministic string to allow console input to begin */ @@ -214,8 +220,8 @@ void init(void) #endif #if SERIAL_WITH_COLOUR - serial_channel_names_init(client_names); - for (uint32_t i = 0; i < SERIAL_NUM_CLIENTS; i++) { + serial_channel_names_init(microkit_name, client_names); + for (uint32_t i = 0; i < NUM_SERIAL_CLIENTS; i++) { sddf_dprintf("%s'%s' is client %u%s\n", colours[i % ARRAY_SIZE(colours)], client_names[i], i, COLOUR_END); } #endif