mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-11-16 12:34:45 +00:00
Compare commits
10 Commits
18b2ce8e81
...
5.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61ccb9c05d | ||
|
|
7661402bc2 | ||
|
|
5284e812e2 | ||
|
|
e95c00a79e | ||
|
|
95036a4591 | ||
|
|
534f9dbe13 | ||
|
|
4a2ac5ef8d | ||
|
|
5eb0773159 | ||
|
|
849d741832 | ||
|
|
a1f9265c03 |
@@ -24,44 +24,85 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @brief The SC16IS752 device context.
|
||||
*
|
||||
* All members are private to the device driver.
|
||||
*/
|
||||
typedef struct {
|
||||
sc16is752_spi_context base;
|
||||
Pin irq_pin;
|
||||
rtems_interrupt_server_entry irqs_entry; /* Internal. Don't touch. */
|
||||
rtems_interrupt_server_action irqs_action; /* Internal. Don't touch. */
|
||||
rtems_interrupt_server_entry irqs_entry;
|
||||
rtems_interrupt_server_action irqs_action;
|
||||
uint32_t irqs_index;
|
||||
} atsam_sc16is752_spi_context;
|
||||
|
||||
/**
|
||||
* @brief The SC16IS752 device configuration.
|
||||
*
|
||||
* @see atsam_sc16is752_spi_create().
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief The device file path for the new device.
|
||||
*/
|
||||
const char *device_path;
|
||||
|
||||
/**
|
||||
* @brief The SC16IS752 mode.
|
||||
*/
|
||||
sc16is752_mode mode;
|
||||
|
||||
/**
|
||||
* @brief The input frequency in Hertz of the SC16IS752 chip. See XTAL1 and
|
||||
* XTAL2 pins.
|
||||
*/
|
||||
uint32_t input_frequency;
|
||||
|
||||
/**
|
||||
* @brief The SPI bus device path.
|
||||
*/
|
||||
const char *spi_path;
|
||||
|
||||
/**
|
||||
* @brief The SPI chip select (starts with 0, the SPI driver uses
|
||||
* SPI_ChipSelect(1 << spi_chip_select)).
|
||||
*/
|
||||
uint8_t spi_chip_select;
|
||||
|
||||
/**
|
||||
* @brief The SPI bus speed in Hertz.
|
||||
*/
|
||||
uint32_t spi_speed_hz;
|
||||
|
||||
/**
|
||||
* @brief The interrupt pin, e.g. { PIO_PD28, PIOD, ID_PIOD, PIO_INPUT,
|
||||
* PIO_IT_LOW_LEVEL }.
|
||||
*/
|
||||
const Pin irq_pin;
|
||||
|
||||
/**
|
||||
* @brief The index to identify the interrupt server used for interrupt
|
||||
* processing.
|
||||
*/
|
||||
uint32_t server_index;
|
||||
} atsam_sc16is752_spi_config;
|
||||
|
||||
/**
|
||||
* @brief Creates an SPI connected SC16IS752 device.
|
||||
*
|
||||
* This devices uses the interrupt server, see
|
||||
* rtems_interrupt_server_initialize().
|
||||
* This devices uses the interrupt server, see rtems_interrupt_server_create().
|
||||
*
|
||||
* The device claims the interrupt of the PIO block.
|
||||
*
|
||||
* @param[in] ctx The device context. May have an arbitrary content.
|
||||
* @param[in] device_path The device file path for the new device.
|
||||
* @param[in] mode The SC16IS752 mode.
|
||||
* @param[in] input_frequency The input frequency in Hertz of the SC16IS752
|
||||
* chip. See XTAL1 and XTAL2 pins.
|
||||
* @param[in] spi_path The SPI bus device path.
|
||||
* @param[in] spi_chip_select The SPI chip select (starts with 0, the SPI
|
||||
* driver uses SPI_ChipSelect(1 << spi_chip_select)).
|
||||
* @param[in] spi_speed_hz The SPI bus speed in Hertz.
|
||||
* @param[in] irq_pin The interrupt pin, e.g. { PIO_PD28, PIOD, ID_PIOD,
|
||||
* PIO_INPUT, PIO_IT_LOW_LEVEL }.
|
||||
* @param[out] ctx is the device context. It may have an arbitrary content.
|
||||
* @param config is the device configuration.
|
||||
*
|
||||
* @return See sc16is752_spi_create().
|
||||
*/
|
||||
int atsam_sc16is752_spi_create(
|
||||
atsam_sc16is752_spi_context *ctx,
|
||||
const char *device_path,
|
||||
sc16is752_mode mode,
|
||||
uint32_t input_frequency,
|
||||
const char *spi_path,
|
||||
uint8_t spi_chip_select,
|
||||
uint32_t spi_speed_hz,
|
||||
const Pin *irq_pin
|
||||
const atsam_sc16is752_spi_config *config
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -41,7 +41,7 @@ static bool atsam_sc16is752_install_interrupt(sc16is752_context *base)
|
||||
rtems_status_code sc;
|
||||
uint8_t rv;
|
||||
|
||||
sc = rtems_interrupt_server_entry_initialize(RTEMS_INTERRUPT_SERVER_DEFAULT,
|
||||
sc = rtems_interrupt_server_entry_initialize(ctx->irqs_index,
|
||||
&ctx->irqs_entry);
|
||||
rtems_interrupt_server_action_prepend(&ctx->irqs_entry,
|
||||
&ctx->irqs_action, atsam_sc16i752_irqs_handler, ctx);
|
||||
@@ -65,23 +65,18 @@ static void atsam_sc16is752_remove_interrupt(sc16is752_context *base)
|
||||
|
||||
int atsam_sc16is752_spi_create(
|
||||
atsam_sc16is752_spi_context *ctx,
|
||||
const char *device_path,
|
||||
sc16is752_mode mode,
|
||||
uint32_t input_frequency,
|
||||
const char *spi_path,
|
||||
uint8_t spi_chip_select,
|
||||
uint32_t spi_speed_hz,
|
||||
const Pin *irq_pin
|
||||
const atsam_sc16is752_spi_config *config
|
||||
)
|
||||
{
|
||||
ctx->base.base.mode = mode;
|
||||
ctx->base.base.input_frequency = input_frequency;
|
||||
ctx->base.base.mode = config->mode;
|
||||
ctx->base.base.input_frequency = config->input_frequency;
|
||||
ctx->base.base.install_irq = atsam_sc16is752_install_interrupt;
|
||||
ctx->base.base.remove_irq = atsam_sc16is752_remove_interrupt;
|
||||
ctx->base.spi_path = spi_path;
|
||||
ctx->base.cs = spi_chip_select;
|
||||
ctx->base.speed_hz = spi_speed_hz;
|
||||
ctx->irq_pin = *irq_pin;
|
||||
ctx->base.spi_path = config->spi_path;
|
||||
ctx->base.cs = config->spi_chip_select;
|
||||
ctx->base.speed_hz = config->spi_speed_hz;
|
||||
ctx->irq_pin = config->irq_pin;
|
||||
ctx->irqs_index = config->server_index;
|
||||
|
||||
return sc16is752_spi_create(&ctx->base, device_path);
|
||||
return sc16is752_spi_create(&ctx->base, config->device_path);
|
||||
}
|
||||
|
||||
@@ -122,6 +122,8 @@ void zynq_uart_initialize(rtems_termios_device_context *base)
|
||||
uint32_t brgr = 0x3e;
|
||||
uint32_t bauddiv = 0x6;
|
||||
|
||||
zynq_uart_reset_tx_flush(ctx);
|
||||
|
||||
zynq_cal_baud_rate(ZYNQ_UART_DEFAULT_BAUD, &brgr, &bauddiv, regs->mode);
|
||||
|
||||
regs->control &= ~(ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN);
|
||||
|
||||
@@ -226,9 +226,11 @@ get_checksum(unsigned start, int length)
|
||||
int
|
||||
send_ipi(unsigned int dst, unsigned int v)
|
||||
{
|
||||
int to, send_status;
|
||||
int to, send_status, apicid;
|
||||
|
||||
IMPS_LAPIC_WRITE(LAPIC_ICR+0x10, (dst << 24));
|
||||
apicid = imps_cpu_apic_map[dst];
|
||||
|
||||
IMPS_LAPIC_WRITE(LAPIC_ICR+0x10, (apicid << 24));
|
||||
IMPS_LAPIC_WRITE(LAPIC_ICR, v);
|
||||
|
||||
/* Wait for send to finish */
|
||||
@@ -251,9 +253,11 @@ static int
|
||||
boot_cpu(imps_processor *proc)
|
||||
{
|
||||
int apicid = proc->apic_id, success = 1;
|
||||
int cpuid;
|
||||
unsigned bootaddr;
|
||||
unsigned bios_reset_vector = PHYS_TO_VIRTUAL(BIOS_RESET_VECTOR);
|
||||
|
||||
cpuid = imps_apic_cpu_map[apicid];
|
||||
/*
|
||||
* Copy boot code for secondary CPUs here. Find it in between
|
||||
* "patch_code_start" and "patch_code_end" symbols. The other CPUs
|
||||
@@ -276,7 +280,7 @@ boot_cpu(imps_processor *proc)
|
||||
/* Pass start function, stack region and gdtdescr to AP
|
||||
* see startAP.S for location */
|
||||
reset[1] = (uint32_t)secondary_cpu_initialize;
|
||||
reset[2] = (uint32_t)_Per_CPU_Get_by_index(apicid)->interrupt_stack_high;
|
||||
reset[2] = (uint32_t)_Per_CPU_Get_by_index(cpuid)->interrupt_stack_high;
|
||||
memcpy(
|
||||
(char*) &reset[3],
|
||||
&gdtdesc,
|
||||
@@ -295,13 +299,13 @@ boot_cpu(imps_processor *proc)
|
||||
|
||||
/* assert INIT IPI */
|
||||
send_ipi(
|
||||
apicid,
|
||||
cpuid,
|
||||
LAPIC_ICR_TM_LEVEL | LAPIC_ICR_LEVELASSERT | LAPIC_ICR_DM_INIT
|
||||
);
|
||||
UDELAY(10000);
|
||||
|
||||
/* de-assert INIT IPI */
|
||||
send_ipi(apicid, LAPIC_ICR_TM_LEVEL | LAPIC_ICR_DM_INIT);
|
||||
send_ipi(cpuid, LAPIC_ICR_TM_LEVEL | LAPIC_ICR_DM_INIT);
|
||||
|
||||
UDELAY(10000);
|
||||
|
||||
@@ -312,7 +316,7 @@ boot_cpu(imps_processor *proc)
|
||||
if (proc->apic_ver >= APIC_VER_NEW) {
|
||||
int i;
|
||||
for (i = 1; i <= 2; i++) {
|
||||
send_ipi(apicid, LAPIC_ICR_DM_SIPI | ((bootaddr >> 12) & 0xFF));
|
||||
send_ipi(cpuid, LAPIC_ICR_DM_SIPI | ((bootaddr >> 12) & 0xFF));
|
||||
UDELAY(1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
* Acts as a barrier to ensure all previous I/O accesses have
|
||||
* completed before any further ones are issued.
|
||||
*/
|
||||
static inline void eieio(void)
|
||||
static inline void io_eieio(void)
|
||||
{
|
||||
__asm__ __volatile__ ("eieio");
|
||||
}
|
||||
@@ -59,9 +59,9 @@ static inline void eieio(void)
|
||||
/* Enforce in-order execution of data I/O.
|
||||
* No distinction between read/write on PPC; use eieio for all three.
|
||||
*/
|
||||
#define iobarrier_rw() eieio()
|
||||
#define iobarrier_r() eieio()
|
||||
#define iobarrier_w() eieio()
|
||||
#define iobarrier_rw() io_eieio()
|
||||
#define iobarrier_r() io_eieio()
|
||||
#define iobarrier_w() io_eieio()
|
||||
|
||||
/*
|
||||
* 8, 16 and 32 bit, big and little endian I/O operations, with barrier.
|
||||
|
||||
@@ -7,13 +7,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009, 2019 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
* Copyright (C) 2009, 2020 embedded brains GmbH (http://www.embedded-brains.de)
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
@@ -21,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/chain.h>
|
||||
@@ -30,54 +25,43 @@
|
||||
|
||||
#define BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR (BSP_INTERRUPT_VECTOR_MAX + 1)
|
||||
|
||||
typedef struct {
|
||||
RTEMS_INTERRUPT_LOCK_MEMBER(lock);
|
||||
rtems_chain_control entries;
|
||||
rtems_id server;
|
||||
unsigned errors;
|
||||
} bsp_interrupt_server_context;
|
||||
static rtems_interrupt_server_control bsp_interrupt_server_default;
|
||||
|
||||
#if defined(RTEMS_SMP)
|
||||
static bsp_interrupt_server_context *bsp_interrupt_server_instances;
|
||||
#else
|
||||
static bsp_interrupt_server_context bsp_interrupt_server_instance;
|
||||
#endif
|
||||
static rtems_chain_control bsp_interrupt_server_chain =
|
||||
RTEMS_CHAIN_INITIALIZER_EMPTY(bsp_interrupt_server_chain);
|
||||
|
||||
static bsp_interrupt_server_context *bsp_interrupt_server_get_context(
|
||||
static rtems_interrupt_server_control *bsp_interrupt_server_get_context(
|
||||
uint32_t server_index,
|
||||
rtems_status_code *sc
|
||||
)
|
||||
{
|
||||
#if defined(RTEMS_SMP)
|
||||
if (bsp_interrupt_server_instances == NULL) {
|
||||
*sc = RTEMS_INCORRECT_STATE;
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
if (bsp_interrupt_server_instance.server == RTEMS_ID_NONE) {
|
||||
*sc = RTEMS_INCORRECT_STATE;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
rtems_chain_node *node;
|
||||
|
||||
if (server_index >= rtems_scheduler_get_processor_maximum()) {
|
||||
bsp_interrupt_lock();
|
||||
node = rtems_chain_first(&bsp_interrupt_server_chain);
|
||||
|
||||
while (node != rtems_chain_tail(&bsp_interrupt_server_chain)) {
|
||||
rtems_interrupt_server_control *s;
|
||||
|
||||
s = RTEMS_CONTAINER_OF(node, rtems_interrupt_server_control, node);
|
||||
if (s->index == server_index) {
|
||||
bsp_interrupt_unlock();
|
||||
return s;
|
||||
}
|
||||
|
||||
node = rtems_chain_next(node);
|
||||
}
|
||||
|
||||
bsp_interrupt_unlock();
|
||||
*sc = RTEMS_INVALID_ID;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*sc = RTEMS_SUCCESSFUL;
|
||||
#if defined(RTEMS_SMP)
|
||||
return &bsp_interrupt_server_instances[server_index];
|
||||
#else
|
||||
return &bsp_interrupt_server_instance;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void bsp_interrupt_server_trigger(void *arg)
|
||||
{
|
||||
rtems_interrupt_lock_context lock_context;
|
||||
rtems_interrupt_server_entry *e = arg;
|
||||
bsp_interrupt_server_context *s = e->server;
|
||||
rtems_interrupt_server_control *s = e->server;
|
||||
|
||||
if (bsp_interrupt_is_valid_vector(e->vector)) {
|
||||
bsp_interrupt_vector_disable(e->vector);
|
||||
@@ -137,7 +121,7 @@ static rtems_interrupt_server_entry *bsp_interrupt_server_query_entry(
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
bsp_interrupt_server_context *server;
|
||||
rtems_interrupt_server_control *server;
|
||||
rtems_vector_number vector;
|
||||
rtems_option options;
|
||||
rtems_interrupt_handler handler;
|
||||
@@ -281,7 +265,7 @@ static void bsp_interrupt_server_remove_helper(void *arg)
|
||||
}
|
||||
|
||||
static rtems_status_code bsp_interrupt_server_call_helper(
|
||||
bsp_interrupt_server_context *s,
|
||||
rtems_interrupt_server_control *s,
|
||||
rtems_vector_number vector,
|
||||
rtems_option options,
|
||||
rtems_interrupt_handler handler,
|
||||
@@ -314,7 +298,7 @@ static rtems_status_code bsp_interrupt_server_call_helper(
|
||||
}
|
||||
|
||||
static rtems_interrupt_server_entry *bsp_interrupt_server_get_entry(
|
||||
bsp_interrupt_server_context *s
|
||||
rtems_interrupt_server_control *s
|
||||
)
|
||||
{
|
||||
rtems_interrupt_lock_context lock_context;
|
||||
@@ -337,7 +321,7 @@ static rtems_interrupt_server_entry *bsp_interrupt_server_get_entry(
|
||||
|
||||
static void bsp_interrupt_server_task(rtems_task_argument arg)
|
||||
{
|
||||
bsp_interrupt_server_context *s = (bsp_interrupt_server_context *) arg;
|
||||
rtems_interrupt_server_control *s = (rtems_interrupt_server_control *) arg;
|
||||
|
||||
while (true) {
|
||||
rtems_event_set events;
|
||||
@@ -377,7 +361,7 @@ rtems_status_code rtems_interrupt_server_handler_install(
|
||||
)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
bsp_interrupt_server_context *s;
|
||||
rtems_interrupt_server_control *s;
|
||||
|
||||
s = bsp_interrupt_server_get_context(server_index, &sc);
|
||||
if (s == NULL) {
|
||||
@@ -402,7 +386,7 @@ rtems_status_code rtems_interrupt_server_handler_remove(
|
||||
)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
bsp_interrupt_server_context *s;
|
||||
rtems_interrupt_server_control *s;
|
||||
|
||||
s = bsp_interrupt_server_get_context(server_index, &sc);
|
||||
if (s == NULL) {
|
||||
@@ -464,7 +448,7 @@ rtems_status_code rtems_interrupt_server_handler_iterate(
|
||||
{
|
||||
rtems_status_code sc;
|
||||
bsp_interrupt_server_handler_iterate_helper_data hihd;
|
||||
bsp_interrupt_server_context *s;
|
||||
rtems_interrupt_server_control *s;
|
||||
|
||||
s = bsp_interrupt_server_get_context(server_index, &sc);
|
||||
if (s == NULL) {
|
||||
@@ -487,36 +471,35 @@ rtems_status_code rtems_interrupt_server_handler_iterate(
|
||||
);
|
||||
}
|
||||
|
||||
rtems_status_code rtems_interrupt_server_initialize(
|
||||
/*
|
||||
* The default server is statically allocated. Just clear the structure so
|
||||
* that it can be re-initialized.
|
||||
*/
|
||||
static void bsp_interrupt_server_destroy_default(
|
||||
rtems_interrupt_server_control *s
|
||||
)
|
||||
{
|
||||
memset(s, 0, sizeof(*s));
|
||||
}
|
||||
|
||||
#if defined(RTEMS_SMP)
|
||||
static void bsp_interrupt_server_destroy_secondary(
|
||||
rtems_interrupt_server_control *s
|
||||
)
|
||||
{
|
||||
free(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
static rtems_status_code bsp_interrupt_server_create(
|
||||
rtems_interrupt_server_control *s,
|
||||
rtems_task_priority priority,
|
||||
size_t stack_size,
|
||||
rtems_mode modes,
|
||||
rtems_attribute attributes,
|
||||
uint32_t *server_count
|
||||
uint32_t cpu_index
|
||||
)
|
||||
{
|
||||
uint32_t cpu_index;
|
||||
uint32_t cpu_count;
|
||||
uint32_t dummy;
|
||||
bsp_interrupt_server_context *instances;
|
||||
|
||||
if (server_count == NULL) {
|
||||
server_count = &dummy;
|
||||
}
|
||||
|
||||
cpu_count = rtems_scheduler_get_processor_maximum();
|
||||
|
||||
#if defined(RTEMS_SMP)
|
||||
instances = calloc(cpu_count, sizeof(*instances));
|
||||
if (instances == NULL) {
|
||||
return RTEMS_NO_MEMORY;
|
||||
}
|
||||
#else
|
||||
instances = &bsp_interrupt_server_instance;
|
||||
#endif
|
||||
|
||||
for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
|
||||
bsp_interrupt_server_context *s = &instances[cpu_index];
|
||||
rtems_status_code sc;
|
||||
#if defined(RTEMS_SMP)
|
||||
rtems_id scheduler;
|
||||
@@ -535,25 +518,14 @@ rtems_status_code rtems_interrupt_server_initialize(
|
||||
&s->server
|
||||
);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
*server_count = cpu_index;
|
||||
|
||||
#if defined(RTEMS_SMP)
|
||||
if (cpu_index > 0) {
|
||||
bsp_interrupt_server_instances = instances;
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
free(instances);
|
||||
#endif
|
||||
|
||||
return RTEMS_TOO_MANY;
|
||||
return sc;
|
||||
}
|
||||
|
||||
#if defined(RTEMS_SMP)
|
||||
sc = rtems_scheduler_ident_by_processor(cpu_index, &scheduler);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
/* Do not start an interrupt server on a processor without a scheduler */
|
||||
continue;
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
sc = rtems_task_set_scheduler(s->server, scheduler, priority);
|
||||
@@ -563,27 +535,188 @@ rtems_status_code rtems_interrupt_server_initialize(
|
||||
CPU_ZERO(&cpu);
|
||||
CPU_SET(cpu_index, &cpu);
|
||||
(void) rtems_task_set_affinity(s->server, sizeof(cpu), &cpu);
|
||||
#else
|
||||
(void) cpu_index;
|
||||
#endif
|
||||
|
||||
rtems_chain_append_unprotected(&bsp_interrupt_server_chain, &s->node);
|
||||
|
||||
sc = rtems_task_start(
|
||||
s->server,
|
||||
bsp_interrupt_server_task,
|
||||
(rtems_task_argument) s
|
||||
);
|
||||
_Assert(sc == RTEMS_SUCCESSFUL);
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
rtems_status_code rtems_interrupt_server_initialize(
|
||||
rtems_task_priority priority,
|
||||
size_t stack_size,
|
||||
rtems_mode modes,
|
||||
rtems_attribute attributes,
|
||||
uint32_t *server_count
|
||||
)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
rtems_interrupt_server_control *s;
|
||||
uint32_t cpu_index;
|
||||
#if defined(RTEMS_SMP)
|
||||
uint32_t cpu_count;
|
||||
#endif
|
||||
|
||||
cpu_index = 0;
|
||||
s = &bsp_interrupt_server_default;
|
||||
|
||||
bsp_interrupt_lock();
|
||||
|
||||
if (s->server != 0) {
|
||||
sc = RTEMS_INCORRECT_STATE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
#if defined(RTEMS_SMP)
|
||||
bsp_interrupt_server_instances = instances;
|
||||
#endif
|
||||
*server_count = cpu_index;
|
||||
s->destroy = bsp_interrupt_server_destroy_default;
|
||||
sc = bsp_interrupt_server_create(
|
||||
s,
|
||||
priority,
|
||||
stack_size,
|
||||
modes,
|
||||
attributes,
|
||||
cpu_index
|
||||
);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
cpu_index = 1;
|
||||
|
||||
#if defined(RTEMS_SMP)
|
||||
cpu_count = rtems_scheduler_get_processor_maximum();
|
||||
|
||||
while (cpu_index < cpu_count) {
|
||||
s = calloc(1, sizeof(*s));
|
||||
|
||||
if (s == NULL) {
|
||||
sc = RTEMS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
s->destroy = bsp_interrupt_server_destroy_secondary;
|
||||
s->index = cpu_index;
|
||||
sc = bsp_interrupt_server_create(
|
||||
s,
|
||||
priority,
|
||||
stack_size,
|
||||
modes,
|
||||
attributes,
|
||||
cpu_index
|
||||
);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
++cpu_index;
|
||||
}
|
||||
#endif
|
||||
|
||||
done:
|
||||
bsp_interrupt_unlock();
|
||||
|
||||
if (server_count != NULL) {
|
||||
*server_count = cpu_index;
|
||||
}
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
rtems_status_code rtems_interrupt_server_create(
|
||||
rtems_interrupt_server_control *s,
|
||||
const rtems_interrupt_server_config *config,
|
||||
uint32_t *server_index
|
||||
)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
|
||||
sc = rtems_task_create(
|
||||
config->name,
|
||||
config->priority,
|
||||
config->storage_size,
|
||||
config->modes,
|
||||
config->attributes,
|
||||
&s->server
|
||||
);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
return sc;
|
||||
}
|
||||
|
||||
rtems_interrupt_lock_initialize(&s->lock, "Interrupt Server");
|
||||
rtems_chain_initialize_empty(&s->entries);
|
||||
s->destroy = config->destroy;
|
||||
s->index = rtems_object_id_get_index(s->server)
|
||||
+ rtems_scheduler_get_processor_maximum();
|
||||
*server_index = s->index;
|
||||
|
||||
bsp_interrupt_lock();
|
||||
rtems_chain_initialize_node(&s->node);
|
||||
rtems_chain_append_unprotected(&bsp_interrupt_server_chain, &s->node);
|
||||
bsp_interrupt_unlock();
|
||||
|
||||
sc = rtems_task_start(
|
||||
s->server,
|
||||
bsp_interrupt_server_task,
|
||||
(rtems_task_argument) s
|
||||
);
|
||||
_Assert(sc == RTEMS_SUCCESSFUL);
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
static void bsp_interrupt_server_destroy_helper(void *arg)
|
||||
{
|
||||
bsp_interrupt_server_helper_data *hd = arg;
|
||||
rtems_interrupt_server_control *s = hd->server;
|
||||
rtems_status_code sc;
|
||||
|
||||
bsp_interrupt_lock();
|
||||
rtems_chain_extract_unprotected(&s->node);
|
||||
bsp_interrupt_unlock();
|
||||
|
||||
if (s->destroy != NULL) {
|
||||
(*s->destroy)(s);
|
||||
}
|
||||
|
||||
sc = rtems_event_transient_send(hd->task);
|
||||
_Assert(sc == RTEMS_SUCCESSFUL);
|
||||
(void) sc;
|
||||
|
||||
rtems_task_exit();
|
||||
}
|
||||
|
||||
rtems_status_code rtems_interrupt_server_delete(uint32_t server_index)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
rtems_interrupt_server_control *s;
|
||||
|
||||
s = bsp_interrupt_server_get_context(server_index, &sc);
|
||||
if (s == NULL) {
|
||||
return sc;
|
||||
}
|
||||
|
||||
bsp_interrupt_server_call_helper(
|
||||
s,
|
||||
BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
bsp_interrupt_server_destroy_helper
|
||||
);
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static void bsp_interrupt_server_entry_initialize(
|
||||
rtems_interrupt_server_entry *entry,
|
||||
bsp_interrupt_server_context *s
|
||||
rtems_interrupt_server_control *s
|
||||
)
|
||||
{
|
||||
rtems_chain_set_off_chain(&entry->node);
|
||||
@@ -611,7 +744,7 @@ rtems_status_code rtems_interrupt_server_entry_initialize(
|
||||
)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
bsp_interrupt_server_context *s;
|
||||
rtems_interrupt_server_control *s;
|
||||
|
||||
s = bsp_interrupt_server_get_context(server_index, &sc);
|
||||
if (s == NULL) {
|
||||
@@ -645,7 +778,7 @@ rtems_status_code rtems_interrupt_server_entry_move(
|
||||
)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
bsp_interrupt_server_context *s;
|
||||
rtems_interrupt_server_control *s;
|
||||
|
||||
s = bsp_interrupt_server_get_context(destination_server_index, &sc);
|
||||
if (s == NULL) {
|
||||
@@ -667,7 +800,7 @@ void rtems_interrupt_server_entry_destroy(
|
||||
rtems_interrupt_server_entry *entry
|
||||
)
|
||||
{
|
||||
bsp_interrupt_server_context *s;
|
||||
rtems_interrupt_server_control *s;
|
||||
rtems_interrupt_lock_context lock_context;
|
||||
|
||||
s = entry->server;
|
||||
@@ -698,7 +831,7 @@ rtems_status_code rtems_interrupt_server_request_initialize(
|
||||
)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
bsp_interrupt_server_context *s;
|
||||
rtems_interrupt_server_control *s;
|
||||
|
||||
s = bsp_interrupt_server_get_context(server_index, &sc);
|
||||
if (s == NULL) {
|
||||
@@ -727,8 +860,8 @@ static void bsp_interrupt_server_handler_move_helper(void *arg)
|
||||
e = bsp_interrupt_server_query_entry(hd->vector, &trigger_options);
|
||||
if (e != NULL) {
|
||||
rtems_interrupt_lock_context lock_context;
|
||||
bsp_interrupt_server_context *src = e->server;
|
||||
bsp_interrupt_server_context *dst = hihd->arg;
|
||||
rtems_interrupt_server_control *src = e->server;
|
||||
rtems_interrupt_server_control *dst = hihd->arg;
|
||||
bool pending;
|
||||
|
||||
/* The source server is only used in SMP configurations for the lock */
|
||||
@@ -763,8 +896,8 @@ rtems_status_code rtems_interrupt_server_move(
|
||||
)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
bsp_interrupt_server_context *src;
|
||||
bsp_interrupt_server_context *dst;
|
||||
rtems_interrupt_server_control *src;
|
||||
rtems_interrupt_server_control *dst;
|
||||
bsp_interrupt_server_handler_iterate_helper_data hihd;
|
||||
|
||||
src = bsp_interrupt_server_get_context(source_server_index, &sc);
|
||||
@@ -810,7 +943,7 @@ static void bsp_interrupt_server_entry_suspend_helper(void *arg)
|
||||
rtems_status_code rtems_interrupt_server_suspend(uint32_t server_index)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
bsp_interrupt_server_context *s;
|
||||
rtems_interrupt_server_control *s;
|
||||
|
||||
s = bsp_interrupt_server_get_context(server_index, &sc);
|
||||
if (s == NULL) {
|
||||
@@ -831,7 +964,7 @@ rtems_status_code rtems_interrupt_server_suspend(uint32_t server_index)
|
||||
rtems_status_code rtems_interrupt_server_resume(uint32_t server_index)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
bsp_interrupt_server_context *s;
|
||||
rtems_interrupt_server_control *s;
|
||||
|
||||
s = bsp_interrupt_server_get_context(server_index, &sc);
|
||||
if (s == NULL) {
|
||||
@@ -858,7 +991,7 @@ rtems_status_code rtems_interrupt_server_set_affinity(
|
||||
)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
bsp_interrupt_server_context *s;
|
||||
rtems_interrupt_server_control *s;
|
||||
rtems_id scheduler;
|
||||
|
||||
s = bsp_interrupt_server_get_context(server_index, &sc);
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
* @ingroup RTEMSApplicationConfiguration
|
||||
*
|
||||
* @brief Evaluate MPCI Configuration Options
|
||||
*
|
||||
* This header file defines _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT for use by
|
||||
* other configuration header files.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -49,6 +46,8 @@
|
||||
|
||||
#ifdef CONFIGURE_MP_APPLICATION
|
||||
|
||||
#include <rtems/confdefs/threads.h>
|
||||
|
||||
#ifndef CONFIGURE_EXTRA_MPCI_RECEIVE_SERVER_STACK
|
||||
#define CONFIGURE_EXTRA_MPCI_RECEIVE_SERVER_STACK 0
|
||||
#endif
|
||||
@@ -83,8 +82,6 @@
|
||||
#error "CONFIGURE_MP_NODE_NUMBER must be less than or equal to CONFIGURE_MP_MAXIMUM_NODES"
|
||||
#endif
|
||||
|
||||
#define _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -126,10 +123,6 @@ RTEMS_SECTION( ".rtemsstack.mpci" );
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* CONFIGURE_MP_APPLICATION */
|
||||
|
||||
#define _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT 0
|
||||
|
||||
#endif /* CONFIGURE_MP_APPLICATION */
|
||||
|
||||
#else /* RTEMS_MULTIPROCESSING */
|
||||
@@ -138,8 +131,6 @@ RTEMS_SECTION( ".rtemsstack.mpci" );
|
||||
#error "CONFIGURE_MP_APPLICATION must not be defined if multiprocessing is disabled"
|
||||
#endif
|
||||
|
||||
#define _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT 0
|
||||
|
||||
#endif /* RTEMS_MULTIPROCESSING */
|
||||
|
||||
#endif /* CONFIGURE_INIT */
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
|
||||
#include <rtems/confdefs/bdbuf.h>
|
||||
#include <rtems/confdefs/extensions.h>
|
||||
#include <rtems/confdefs/mpci.h>
|
||||
#include <rtems/confdefs/percpu.h>
|
||||
#include <rtems/confdefs/scheduler.h>
|
||||
#include <rtems/confdefs/unlimited.h>
|
||||
@@ -197,6 +196,12 @@ const size_t _Thread_Initial_thread_count =
|
||||
rtems_resource_maximum_per_allocation( _CONFIGURE_TASKS ) +
|
||||
rtems_resource_maximum_per_allocation( CONFIGURE_MAXIMUM_POSIX_THREADS );
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING) && defined(CONFIGURE_MP_APPLICATION)
|
||||
#define _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT 1
|
||||
#else
|
||||
#define _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT 0
|
||||
#endif
|
||||
|
||||
THREAD_INFORMATION_DEFINE(
|
||||
_Thread,
|
||||
OBJECTS_INTERNAL_API,
|
||||
|
||||
@@ -214,6 +214,9 @@ typedef struct {
|
||||
/**
|
||||
* @brief Converter implementation for new file system instance.
|
||||
*
|
||||
* Note: If you pass a converter to mount, you have to destroy it yourself if
|
||||
* mount failed. In a good case it is destroyed at unmount.
|
||||
*
|
||||
* Before converters have been added to the RTEMS implementation of the FAT
|
||||
* file system, the implementation was:
|
||||
* - Short names were saved in code page format (as is still the case).
|
||||
@@ -270,6 +273,10 @@ typedef struct {
|
||||
* RTEMS_FILESYSTEM_READ_WRITE,
|
||||
* &mount_opts
|
||||
* );
|
||||
*
|
||||
* if (rv != 0) {
|
||||
* (*mount_opts.converter->handler->destroy)(mount_opts.converter);
|
||||
* }
|
||||
* } else {
|
||||
* rv = -1;
|
||||
* errno = ENOMEM;
|
||||
|
||||
@@ -9,13 +9,7 @@
|
||||
/*
|
||||
* Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
|
||||
*
|
||||
* Copyright (C) 2008, 2019 embedded brains GmbH
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
* Copyright (C) 2008, 2020 embedded brains GmbH (http://www.embedded-brains.de)
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
@@ -259,6 +253,76 @@ typedef struct rtems_interrupt_server_action {
|
||||
*/
|
||||
#define RTEMS_INTERRUPT_SERVER_DEFAULT 0
|
||||
|
||||
/**
|
||||
* @brief An interrupt server control.
|
||||
*
|
||||
* This structure must be treated as an opaque data type. Members must not be
|
||||
* accessed directly.
|
||||
*
|
||||
* @see rtems_interrupt_server_create()
|
||||
*/
|
||||
typedef struct rtems_interrupt_server_control {
|
||||
RTEMS_INTERRUPT_LOCK_MEMBER( lock )
|
||||
rtems_chain_control entries;
|
||||
rtems_id server;
|
||||
unsigned long errors;
|
||||
uint32_t index;
|
||||
rtems_chain_node node;
|
||||
void ( *destroy )( struct rtems_interrupt_server_control * );
|
||||
} rtems_interrupt_server_control;
|
||||
|
||||
/**
|
||||
* @brief An interrupt server configuration.
|
||||
*
|
||||
* @see rtems_interrupt_server_create()
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief The task name of the interrupt server.
|
||||
*/
|
||||
rtems_name name;
|
||||
|
||||
/**
|
||||
* @brief The initial task priority of the interrupt server.
|
||||
*/
|
||||
rtems_task_priority priority;
|
||||
|
||||
/**
|
||||
* @brief The task storage area of the interrupt server.
|
||||
*
|
||||
* It shall be NULL for interrupt servers created by
|
||||
* rtems_interrupt_server_create().
|
||||
*/
|
||||
void *storage_area;
|
||||
|
||||
/**
|
||||
* @brief The task storage size of the interrupt server.
|
||||
*
|
||||
* For interrupt servers created by rtems_interrupt_server_create() this is
|
||||
* the task stack size.
|
||||
*/
|
||||
size_t storage_size;
|
||||
|
||||
/**
|
||||
* @brief The initial task modes of the interrupt server.
|
||||
*/
|
||||
rtems_mode modes;
|
||||
|
||||
/**
|
||||
* @brief The task attributes of the interrupt server.
|
||||
*/
|
||||
rtems_attribute attributes;
|
||||
|
||||
/**
|
||||
* @brief An optional handler to destroy the interrupt server control handed
|
||||
* over to rtems_interrupt_server_create().
|
||||
*
|
||||
* This handler is called in the context of the interrupt server to be
|
||||
* deleted, see also rtems_interrupt_server_delete().
|
||||
*/
|
||||
void ( *destroy )( rtems_interrupt_server_control * );
|
||||
} rtems_interrupt_server_config;
|
||||
|
||||
/**
|
||||
* @brief An interrupt server entry.
|
||||
*
|
||||
@@ -309,16 +373,19 @@ typedef struct {
|
||||
*
|
||||
* The server count pointer @a server_count may be @a NULL.
|
||||
*
|
||||
* The task name of interrupt servers created by this function is
|
||||
* rtems_build_name( 'I', 'R', 'Q', 'S' ).
|
||||
*
|
||||
* This function may block.
|
||||
*
|
||||
* @see rtems_task_create().
|
||||
* @retval RTEMS_SUCCESSFUL The operation was successful.
|
||||
*
|
||||
* @retval RTEMS_SUCCESSFUL Successful operation.
|
||||
* @retval RTEMS_INCORRECT_STATE The interrupt servers are not initialized.
|
||||
* @retval RTEMS_NO_MEMORY Not enough memory.
|
||||
* @retval RTEMS_TOO_MANY No free task available to create at least one server task.
|
||||
* @retval RTEMS_UNSATISFIED Task stack size too large.
|
||||
* @retval RTEMS_INVALID_PRIORITY Invalid task priority.
|
||||
* @retval RTEMS_INCORRECT_STATE The interrupt servers were already initialized.
|
||||
*
|
||||
* @return The function uses rtems_task_create(). If this operation is not
|
||||
* successful, then its status code is returned.
|
||||
*
|
||||
* @see rtems_interrupt_server_create() and rtems_interrupt_server_delete().
|
||||
*/
|
||||
rtems_status_code rtems_interrupt_server_initialize(
|
||||
rtems_task_priority priority,
|
||||
@@ -328,6 +395,54 @@ rtems_status_code rtems_interrupt_server_initialize(
|
||||
uint32_t *server_count
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Creates an interrupt server.
|
||||
*
|
||||
* This function may block.
|
||||
*
|
||||
* @param[out] control is the interrupt server control. The ownership of this
|
||||
* structure is transferred from the caller of this function to the interrupt
|
||||
* server management.
|
||||
*
|
||||
* @param config is the interrupt server configuration.
|
||||
*
|
||||
* @param[out] server_index is the pointer to a server index variable. The
|
||||
* index of the built interrupt server will be stored in the referenced
|
||||
* variable if the operation was successful.
|
||||
*
|
||||
* @retval RTEMS_SUCCESSFUL The operation was successful.
|
||||
*
|
||||
* @return The function uses rtems_task_create(). If this operation is not
|
||||
* successful, then its status code is returned.
|
||||
*
|
||||
* @see rtems_interrupt_server_initialize() and
|
||||
* rtems_interrupt_server_delete().
|
||||
*/
|
||||
rtems_status_code rtems_interrupt_server_create(
|
||||
rtems_interrupt_server_control *control,
|
||||
const rtems_interrupt_server_config *config,
|
||||
uint32_t *server_index
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Destroys the interrupt server.
|
||||
*
|
||||
* This function may block.
|
||||
*
|
||||
* The interrupt server deletes itself, so after the return of the function the
|
||||
* interrupt server may be still in the termination process depending on the
|
||||
* task priorities of the system.
|
||||
*
|
||||
* @param server_index is the index of the interrupt server to destroy. Use
|
||||
* ::RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server.
|
||||
*
|
||||
* @retval RTEMS_SUCCESSFUL The operation was successful.
|
||||
* @retval RTEMS_INVALID_ID The interrupt server index was invalid.
|
||||
*
|
||||
* @see rtems_interrupt_server_create()
|
||||
*/
|
||||
rtems_status_code rtems_interrupt_server_delete( uint32_t server_index );
|
||||
|
||||
/**
|
||||
* @brief Installs the interrupt handler routine @a handler for the interrupt
|
||||
* vector with number @a vector on the server @a server.
|
||||
|
||||
@@ -504,6 +504,7 @@ static rtems_status_code mount_worker(
|
||||
if (rv != 0) {
|
||||
rmdir(mount_path);
|
||||
free(mount_path);
|
||||
(*mount_options.converter->handler->destroy)(mount_options.converter);
|
||||
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
|
||||
@@ -103,10 +103,12 @@ int rtems_dosfs_initialize(
|
||||
int rc = 0;
|
||||
const rtems_dosfs_mount_options *mount_options = data;
|
||||
rtems_dosfs_convert_control *converter;
|
||||
bool converter_created = false;
|
||||
|
||||
|
||||
if (mount_options == NULL || mount_options->converter == NULL) {
|
||||
converter = rtems_dosfs_create_default_converter();
|
||||
converter_created = true;
|
||||
} else {
|
||||
converter = mount_options->converter;
|
||||
}
|
||||
@@ -117,6 +119,9 @@ int rtems_dosfs_initialize(
|
||||
&msdos_file_handlers,
|
||||
&msdos_dir_handlers,
|
||||
converter);
|
||||
if (rc != 0 && converter_created) {
|
||||
(*converter->handler->destroy)(converter);
|
||||
}
|
||||
} else {
|
||||
errno = ENOMEM;
|
||||
rc = -1;
|
||||
|
||||
@@ -234,12 +234,16 @@ static void rtems_shell_clear_shell_env(void)
|
||||
eno = pthread_setspecific(rtems_shell_current_env_key, NULL);
|
||||
if (eno != 0)
|
||||
rtems_error(0, "pthread_setspecific(shell_current_env_key): clear");
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear stdin and stdout file pointers of they will be closed
|
||||
/*
|
||||
* Clear stdin, stdout and stderr file pointers so they will not be closed.
|
||||
*/
|
||||
static void rtems_shell_clear_shell_std_handles(void)
|
||||
{
|
||||
stdin = NULL;
|
||||
stdout = NULL;
|
||||
stderr = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -775,6 +779,7 @@ void rtems_shell_print_env(
|
||||
{
|
||||
if ( !shell_env ) {
|
||||
printk( "shell_env is NULL\n" );
|
||||
|
||||
return;
|
||||
}
|
||||
printk( "shell_env=%p\n"
|
||||
@@ -797,6 +802,7 @@ static rtems_task rtems_shell_task(rtems_task_argument task_argument)
|
||||
rtems_shell_env_t *shell_env = (rtems_shell_env_t*) task_argument;
|
||||
rtems_id wake_on_end = shell_env->wake_on_end;
|
||||
rtems_shell_main_loop( shell_env );
|
||||
rtems_shell_clear_shell_std_handles();
|
||||
if (wake_on_end != RTEMS_INVALID_ID)
|
||||
rtems_event_send (wake_on_end, RTEMS_EVENT_1);
|
||||
rtems_task_exit();
|
||||
@@ -872,6 +878,11 @@ bool rtems_shell_main_loop(
|
||||
else
|
||||
stdout = stderr;
|
||||
} else if (strcmp(shell_env->output, "/dev/null") == 0) {
|
||||
if (stdout == NULL) {
|
||||
fprintf(stderr, "shell: stdout is NULLs\n");
|
||||
rtems_shell_clear_shell_env();
|
||||
return false;
|
||||
}
|
||||
fclose (stdout);
|
||||
} else {
|
||||
FILE *output = fopen(shell_env->output,
|
||||
@@ -906,6 +917,13 @@ bool rtems_shell_main_loop(
|
||||
}
|
||||
|
||||
if (!input_file) {
|
||||
if (stdin == NULL) {
|
||||
fprintf(stderr, "shell: stdin is NULLs\n");
|
||||
if (stdoutToClose != NULL)
|
||||
fclose(stdoutToClose);
|
||||
rtems_shell_clear_shell_env();
|
||||
return false;
|
||||
}
|
||||
/* Make a raw terminal, Linux Manuals */
|
||||
if (tcgetattr(fileno(stdin), &previous_term) >= 0) {
|
||||
term = previous_term;
|
||||
@@ -967,7 +985,7 @@ bool rtems_shell_main_loop(
|
||||
* keep on trucking.
|
||||
*/
|
||||
if (shell_env->login_check != NULL) {
|
||||
result = rtems_shell_login(shell_env, stdin,stdout);
|
||||
result = rtems_shell_login(shell_env, stdin, stdout);
|
||||
} else {
|
||||
setuid(shell_env->uid);
|
||||
setgid(shell_env->gid);
|
||||
|
||||
@@ -29,17 +29,7 @@ int shm_unlink( const char *name )
|
||||
_Objects_Allocator_lock();
|
||||
|
||||
shm = _POSIX_Shm_Get_by_name( name, 0, &obj_err );
|
||||
switch ( obj_err ) {
|
||||
case OBJECTS_GET_BY_NAME_INVALID_NAME:
|
||||
err = ENOENT;
|
||||
break;
|
||||
|
||||
case OBJECTS_GET_BY_NAME_NAME_TOO_LONG:
|
||||
err = ENAMETOOLONG;
|
||||
break;
|
||||
|
||||
case OBJECTS_GET_BY_NAME_NO_OBJECT:
|
||||
default:
|
||||
if ( shm ) {
|
||||
_Objects_Namespace_remove_string(
|
||||
&_POSIX_Shm_Information,
|
||||
&shm->Object
|
||||
@@ -50,7 +40,18 @@ int shm_unlink( const char *name )
|
||||
* the shm object will be freed later in _POSIX_Shm_Attempt_delete */
|
||||
_POSIX_Shm_Free( shm );
|
||||
}
|
||||
} else {
|
||||
switch ( obj_err ) {
|
||||
case OBJECTS_GET_BY_NAME_NAME_TOO_LONG:
|
||||
err = ENAMETOOLONG;
|
||||
break;
|
||||
|
||||
case OBJECTS_GET_BY_NAME_INVALID_NAME:
|
||||
case OBJECTS_GET_BY_NAME_NO_OBJECT:
|
||||
default:
|
||||
err = ENOENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_Objects_Allocator_unlock();
|
||||
|
||||
@@ -83,9 +83,9 @@ SYM (_CPU_Context_switch):
|
||||
.L_restore:
|
||||
movl I386_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE(eax),ecx
|
||||
movl ecx,PER_CPU_ISR_DISPATCH_DISABLE(edx)
|
||||
movl REG_ESP(eax),esp /* restore stack pointer */
|
||||
pushl REG_EFLAGS(eax) /* push eflags */
|
||||
popf /* restore eflags */
|
||||
movl REG_ESP(eax),esp /* restore stack pointer */
|
||||
movl REG_EBP(eax),ebp /* restore base pointer */
|
||||
movl REG_EBX(eax),ebx /* restore ebx */
|
||||
movl REG_ESI(eax),esi /* restore source register */
|
||||
|
||||
Reference in New Issue
Block a user