Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IPM console #27804

Merged
merged 10 commits into from
Sep 4, 2020
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@
/drivers/clock_control/*esp32* @extremegtx
/drivers/clock_control/*npcx* @MulinChao
/drivers/counter/ @nordic-krch
/drivers/console/ipm_console.c @finikorg
/drivers/console/semihost_console.c @luozhongyao
/drivers/counter/counter_cmos.c @andrewboie
/drivers/counter/maxim_ds3231.c @pabigot
Expand Down
66 changes: 66 additions & 0 deletions boards/xtensa/up_squared_adsp/tools/mbterm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env python3
#
# Copyright (c) 2020 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0

from time import sleep
from mmap import mmap, ACCESS_COPY
from ctypes import c_uint8

from lib.device import Device
import lib.registers as regs

MBOX = 0x91281000
LENGTH = 0x1000

with open("/dev/mem", "rb") as f:
mem_map = mmap(f.fileno(), LENGTH, access=ACCESS_COPY, offset=MBOX)
mem = (c_uint8 * LENGTH).from_buffer(mem_map)

def mailbox_poll_mem(dev):
while True:
if dev.dsp_hipct.value & regs.ADSP_IPC_HIPCT_BUSY:

# Use only id for passing character
line_len = dev.dsp_hipct.value & regs.ADSP_IPC_HIPCT_MSG

# Mask out internal bits
line_len &= 0x10FFFF

if line_len:
print(bytes(mem[:line_len]).decode())

# Clear interrupt
dev.dsp_hipct.value |= regs.ADSP_IPC_HIPCT_BUSY
else:
sleep(0.005)

# Character passed in mailbox ID field
def mailbox_poll_char(dev):
while True:
if dev.dsp_hipct.value & regs.ADSP_IPC_HIPCT_BUSY:

# Use only id for passing character
character = dev.dsp_hipct.value & regs.ADSP_IPC_HIPCT_MSG

# Get readable character
character &= 0x10FFFF

print('{}'.format(chr(character)), end='')

# Clear interrupt
dev.dsp_hipct.value |= regs.ADSP_IPC_HIPCT_BUSY
else:
sleep(0.005)


if __name__ == "__main__":
# Clear Done if needed
#dev.dsp_hipct.value |= regs.ADSP_IPC_HIPCT_BUSY

# Use Device library for controlling registers
device = Device()
device.open_device()

mailbox_poll_mem(device)
1 change: 1 addition & 0 deletions boards/xtensa/up_squared_adsp/up_squared_adsp.dts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@

chosen {
zephyr,sram = &sram0;
zephyr,console = &ipm_console;
};
};
1 change: 1 addition & 0 deletions drivers/console/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ zephyr_sources_ifdef(CONFIG_RAM_CONSOLE ram_console.c)
zephyr_sources_ifdef(CONFIG_RTT_CONSOLE rtt_console.c)
zephyr_sources_ifdef(CONFIG_IPM_CONSOLE_RECEIVER ipm_console_receiver.c)
zephyr_sources_ifdef(CONFIG_IPM_CONSOLE_SENDER ipm_console_sender.c)
zephyr_sources_ifdef(CONFIG_IPM_CONSOLE ipm_console.c)
zephyr_sources_ifdef(CONFIG_UART_MCUMGR uart_mcumgr.c)
zephyr_sources_ifdef(CONFIG_UART_PIPE uart_pipe.c)
zephyr_sources_ifdef(CONFIG_XTENSA_SIM_CONSOLE xtensa_sim_console.c)
Expand Down
26 changes: 26 additions & 0 deletions drivers/console/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,32 @@ config IPM_CONSOLE_STACK_SIZE
thread to print out incoming messages from the remote CPU. Specify the
stack size for these threads here.

config IPM_CONSOLE
bool "Inter-processor Mailbox console"
depends on IPM
select CONSOLE_HAS_DRIVER
help
Enable console over Inter-processor Mailbox.

# Workaround for not being able to have commas in macro arguments
DT_CHOSEN_Z_IPM_CONSOLE := zephyr,console

config IPM_CONSOLE_ON_DEV_NAME
string "IPM device name used by console"
default "$(dt_chosen_label,$(DT_CHOSEN_Z_IPM_CONSOLE))" if HAS_DTS
default "IPM_0"
finikorg marked this conversation as resolved.
Show resolved Hide resolved
depends on IPM_CONSOLE
help
IPM device name used by IPM console driver.

config IPM_CONSOLE_LINE_BUF_LEN
int "IPM console line buffer length"
default 128
depends on IPM_CONSOLE
help
IPM console line buffer length specify amount of the buffer
where characters are stored before sending the whole line.

config UART_PIPE
bool "Enable pipe UART driver"
select UART_INTERRUPT_DRIVEN
Expand Down
91 changes: 91 additions & 0 deletions drivers/console/ipm_console.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2020 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <kernel.h>
#include <device.h>
#include <init.h>
#include <drivers/ipm.h>

#include <logging/log.h>
LOG_MODULE_REGISTER(ipm_console, CONFIG_IPM_LOG_LEVEL);

struct device *ipm_dev;

static int console_out(int c)
{
static char buf[CONFIG_IPM_CONSOLE_LINE_BUF_LEN];
static size_t len;
int ret;

if (c != '\n' && len < sizeof(buf)) {
buf[len++] = c;
return c;
}
finikorg marked this conversation as resolved.
Show resolved Hide resolved

ret = ipm_send(ipm_dev, 1, len, buf, len);
if (ret) {
LOG_ERR("Error sending character %c over IPM, ret %d", c, ret);
}

memset(buf, 0, sizeof(buf));
len = 0;

/* After buffer is full start a new one */
if (c != '\n') {
buf[len++] = c;
}

return c;
}

#if defined(CONFIG_STDOUT_CONSOLE)
extern void __stdout_hook_install(int (*hook)(int));
#else
#define __stdout_hook_install(x) \
do { /* nothing */ \
} while ((0))
#endif

#if defined(CONFIG_PRINTK)
extern void __printk_hook_install(int (*fn)(int));
#else
#define __printk_hook_install(x) \
do { /* nothing */ \
} while ((0))
#endif

/* Install printk/stdout hooks */
static void ipm_console_hook_install(void)
{
__stdout_hook_install(console_out);
__printk_hook_install(console_out);
}

static int ipm_console_init(struct device *dev)
{
ARG_UNUSED(dev);

LOG_DBG("IPM console initialization");

ipm_dev = device_get_binding(CONFIG_IPM_CONSOLE_ON_DEV_NAME);
if (!ipm_dev) {
LOG_ERR("Cannot get %s", CONFIG_IPM_CONSOLE_ON_DEV_NAME);
return -ENODEV;
}

if (ipm_max_id_val_get(ipm_dev) < CONFIG_IPM_CONSOLE_LINE_BUF_LEN) {
LOG_ERR("IPM driver does not support buffer length %d",
CONFIG_IPM_CONSOLE_LINE_BUF_LEN);
return -ENOTSUP;
}

ipm_console_hook_install();

return 0;
}

/* Need to be initialized after IPM */
SYS_INIT(ipm_console_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
12 changes: 12 additions & 0 deletions dts/bindings/ipm/zephyr,ipm-console.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright (c) 2020 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

description: IPM console

compatible: "zephyr,ipm-console"

include: uart-device.yaml

properties:
label:
required: true
5 changes: 5 additions & 0 deletions dts/xtensa/intel/intel_apl_adsp.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,10 @@
interrupt-parent = <&cavs0>;
label = "IPM_0";
};

ipm_console: ipm_console {
compatible = "zephyr,ipm-console";
label="IPM_0";
};
};
};
2 changes: 1 addition & 1 deletion scripts/sanity_chk/sanitylib.py
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ def handle(self):
master, slave = pty.openpty()

try:
ser_pty_process = subprocess.Popen(serial_pty, stdout=master, stdin=master, stderr=master)
ser_pty_process = subprocess.Popen(re.split(',| ', serial_pty), stdout=master, stdin=master, stderr=master)
except subprocess.CalledProcessError as error:
logger.error("Failed to run subprocess {}, error {}".format(serial_pty, error.output))
return
Expand Down
13 changes: 11 additions & 2 deletions soc/xtensa/intel_apl_adsp/Kconfig.defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ config TEST_LOGGING_DEFAULTS

if LOG

# When console is enabled printk should go through it
config LOG_PRINTK
default y
default y if !CONSOLE

config LOG_BACKEND_RB
default y
Expand All @@ -57,7 +58,6 @@ config LOG_BACKEND_RB_MEM_SIZE

endif # LOG


if SMP

config MP_NUM_CPUS
Expand All @@ -80,4 +80,13 @@ config SCHED_IPI_SUPPORTED

endif

config IPM_INTEL_ADSP
default y
depends on IPM

config IPM_CONSOLE
default y
depends on CONSOLE
depends on IPM

endif
3 changes: 2 additions & 1 deletion soc/xtensa/intel_apl_adsp/adsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,5 @@ static int adsp_init(struct device *dev)
return 0;
}

SYS_INIT(adsp_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
/* Init after IPM initialization and before logging (uses memory windows) */
SYS_INIT(adsp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);