mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 02:40:08 +00:00
lx_emul: unify udelay implementation
Implement udelay for all architectures within common lx_emul code, remove driver-specific version. Always do busy looping in udelay and use cpu_relax() like the original Linux code. Thereby, we profit from architecture specific instructions (cpu cool down), and jiffies are updated if irqs are on. Ref genodelabs/genode#4778
This commit is contained in:
parent
50541c68ec
commit
6a7a30ceaa
@ -37,6 +37,7 @@ SRC_C += lx_emul/shadow/kernel/sched/sched.c
|
||||
SRC_C += lx_emul/shadow/kernel/smp.c
|
||||
SRC_C += lx_emul/shadow/kernel/stop_machine.c
|
||||
SRC_C += lx_emul/shadow/lib/cpumask.c
|
||||
SRC_C += lx_emul/shadow/lib/delay.c
|
||||
SRC_C += lx_emul/shadow/mm/percpu.c
|
||||
SRC_C += lx_emul/shadow/mm/slab_common.c
|
||||
SRC_C += lx_emul/shadow/mm/slub.c
|
||||
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* \brief Shadows Linux kernel arch/arm/include/asm/delay.h
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2023-03-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_DELAY_H
|
||||
#define __ASM_DELAY_H
|
||||
|
||||
/*
|
||||
* We shadow the original arm variant and use the generic version instead,
|
||||
* like x86 and arm64. Thereby, we can simply use one and the same backend
|
||||
* function for udelay, which is part of our emulation codebase anyway.
|
||||
*/
|
||||
#include <asm-generic/delay.h>
|
||||
|
||||
#endif
|
||||
|
38
repos/dde_linux/src/lib/lx_emul/shadow/lib/delay.c
Normal file
38
repos/dde_linux/src/lib/lx_emul/shadow/lib/delay.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* \brief Supplement for emulation for arch-specific lib/delay.c
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2023-03-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
|
||||
#include <asm-generic/delay.h>
|
||||
#include <asm/vdso/processor.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <lx_emul.h>
|
||||
#include <lx_emul/time.h>
|
||||
|
||||
|
||||
void __const_udelay(unsigned long xloops)
|
||||
{
|
||||
unsigned long const usecs = xloops / 0x10C7UL;
|
||||
__udelay(usecs);
|
||||
}
|
||||
|
||||
|
||||
void __udelay(unsigned long usecs)
|
||||
{
|
||||
/*
|
||||
* if interrupts are open, jiffies get updated implicitely
|
||||
* by call of cpu_relax()
|
||||
*/
|
||||
unsigned long long end = lx_emul_time_counter() + usecs;
|
||||
while (lx_emul_time_counter() < end) cpu_relax();
|
||||
}
|
@ -48,7 +48,6 @@ SRC_C += lx_emul/mapping.c
|
||||
SRC_C += lx_emul/page_alloc.c
|
||||
SRC_C += lx_emul/sched_core.c
|
||||
SRC_C += lx_emul/vmalloc.c
|
||||
SRC_C += lx_emul/delay.c
|
||||
|
||||
SRC_C += lx_emul/shadow/fs/libfs.c
|
||||
SRC_C += lx_emul/shadow/lib/logic_iomem.c
|
||||
|
@ -12,7 +12,6 @@ SRC_CC += wlan.cc
|
||||
SRC_CC += firmware.cc
|
||||
SRC_CC += socket_call.cc
|
||||
SRC_CC += lx_emul/random.cc
|
||||
SRC_CC += time.cc
|
||||
|
||||
SRC_C += dummies.c
|
||||
SRC_C += lx_emul.c
|
||||
|
@ -26,8 +26,6 @@ extern "C" {
|
||||
struct dma_fence_work;
|
||||
struct dma_fence_work_ops;
|
||||
|
||||
void lx_emul_time_udelay(unsigned long usec);
|
||||
|
||||
void *emul_alloc_shmem_file_buffer(unsigned long);
|
||||
void emul_free_shmem_file_buffer(void *);
|
||||
|
||||
|
@ -9,7 +9,6 @@ INC_DIR += $(REL_PRG_DIR)
|
||||
|
||||
SRC_CC += main.cc
|
||||
SRC_CC += emul.cc
|
||||
SRC_CC += time.cc
|
||||
SRC_CC += opregion_io_mem.cc
|
||||
SRC_C += dummies.c
|
||||
SRC_C += pci.c
|
||||
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* \brief Lx_emul udelay function for very short delays
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2021-07-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <base/log.h>
|
||||
#include <lx_kit/env.h>
|
||||
|
||||
extern "C" void lx_emul_time_udelay(unsigned long usec);
|
||||
extern "C" void lx_emul_time_udelay(unsigned long usec)
|
||||
{
|
||||
if (usec > 100)
|
||||
Genode::error("Cannot delay that long ", usec, " microseconds");
|
||||
|
||||
unsigned long long start = Lx_kit::env().timer.curr_time().trunc_to_plain_us().value;
|
||||
while (Lx_kit::env().timer.curr_time().trunc_to_plain_us().value < (start + usec)) { ; }
|
||||
}
|
@ -19,13 +19,3 @@
|
||||
|
||||
/* fix for missing include in linux/dynamic_debug.h */
|
||||
#include <linux/compiler_attributes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void lx_emul_time_udelay(unsigned long usec);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -7,7 +7,6 @@ LIBS := base pc_lx_emul jitterentropy
|
||||
|
||||
INC_DIR += $(REL_PRG_DIR)
|
||||
SRC_CC += main.cc
|
||||
SRC_CC += time.cc
|
||||
SRC_CC += lx_emul/shared_dma_buffer.cc
|
||||
SRC_C += dummies.c
|
||||
SRC_C += lx_emul.c
|
||||
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* \brief Lx_emul udelay function for very short delays
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2021-07-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <base/log.h>
|
||||
#include <lx_kit/env.h>
|
||||
|
||||
extern "C" void lx_emul_time_udelay(unsigned long usec);
|
||||
extern "C" void lx_emul_time_udelay(unsigned long usec)
|
||||
{
|
||||
if (usec > 100)
|
||||
Genode::error("Cannot delay that long ", usec, " microseconds");
|
||||
|
||||
unsigned long long start = Lx_kit::env().timer.curr_time().trunc_to_plain_us().value;
|
||||
while (Lx_kit::env().timer.curr_time().trunc_to_plain_us().value < (start + usec)) { ; }
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* \brief Supplement for emulation for linux/include/asm-generic/delay.h
|
||||
* \author Josef Soentgen
|
||||
* \author Alexander Boettcher
|
||||
* \date 2022-05-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
|
||||
#include <asm-generic/delay.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
||||
#include <lx_emul.h>
|
||||
|
||||
|
||||
void __const_udelay(unsigned long xloops)
|
||||
{
|
||||
unsigned long const usecs = xloops / 0x10C7UL;
|
||||
__udelay(usecs);
|
||||
}
|
||||
|
||||
|
||||
void __udelay(unsigned long usecs)
|
||||
{
|
||||
/*
|
||||
* Account for delays summing up to equivalent of 1 jiffie during
|
||||
* jiffies_64 stays same. When 1 jiffie is reached in sum,
|
||||
* increase jiffie_64 to break endless loops, seen in
|
||||
* * intel_fb - cpu_relax(void) emulation used by
|
||||
* busy loop of slchi() in drivers/i2c/algos/i2c-algo-bit.c
|
||||
* * wifi_drv - net/wireless/intel/iwlwif* code during error code handling
|
||||
*/
|
||||
static uint64_t last_jiffie = 0;
|
||||
static unsigned long delayed_sum = 0;
|
||||
|
||||
if (jiffies_64 == last_jiffie) {
|
||||
delayed_sum += usecs;
|
||||
} else {
|
||||
last_jiffie = jiffies_64;
|
||||
delayed_sum = usecs;
|
||||
}
|
||||
|
||||
if (usecs < 100)
|
||||
lx_emul_time_udelay(usecs);
|
||||
else {
|
||||
unsigned long slept = 0;
|
||||
while (slept < usecs) {
|
||||
lx_emul_time_udelay(100);
|
||||
slept += 100;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* When delays sum up to the equivalent of 1 jiffie,
|
||||
* increase it to break endless loops.
|
||||
*/
|
||||
if (delayed_sum >= jiffies_to_usecs(1)) {
|
||||
jiffies_64 ++;
|
||||
delayed_sum = 0;
|
||||
}
|
||||
}
|
@ -24,8 +24,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void lx_emul_time_udelay(unsigned long usec);
|
||||
|
||||
int lx_emul_rfkill_get_any(void);
|
||||
void lx_emul_rfkill_switch_all(int blocked);
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* \brief Lx_emul udelay function for very short delays
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2021-07-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <base/log.h>
|
||||
#include <lx_kit/env.h>
|
||||
|
||||
extern "C" void lx_emul_time_udelay(unsigned long usec);
|
||||
extern "C" void lx_emul_time_udelay(unsigned long usec)
|
||||
{
|
||||
if (usec > 100)
|
||||
Genode::error("Cannot delay that long ", usec, " microseconds");
|
||||
|
||||
unsigned long long start = Lx_kit::env().timer.curr_time().trunc_to_plain_us().value;
|
||||
while (Lx_kit::env().timer.curr_time().trunc_to_plain_us().value < (start + usec)) { ; }
|
||||
}
|
@ -10,14 +10,3 @@
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void lx_emul_time_udelay(unsigned long usec);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -3,7 +3,7 @@ REQUIRES := x86_64
|
||||
TARGET := test-driver_time
|
||||
LIBS := base pc_lx_emul jitterentropy
|
||||
|
||||
SRC_CC += main.cc time.cc
|
||||
SRC_CC += main.cc
|
||||
SRC_C += lx_user.c
|
||||
SRC_C += dummies.c
|
||||
SRC_C += generated_dummies.c
|
||||
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* \brief Lx_emul udelay function for very short delays
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2021-07-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <base/log.h>
|
||||
#include <lx_kit/env.h>
|
||||
|
||||
extern "C" void lx_emul_time_udelay(unsigned long usec);
|
||||
extern "C" void lx_emul_time_udelay(unsigned long usec)
|
||||
{
|
||||
if (usec > 100)
|
||||
Genode::error("Cannot delay that long ", usec, " microseconds");
|
||||
|
||||
unsigned long long start = Lx_kit::env().timer.curr_time().trunc_to_plain_us().value;
|
||||
while (Lx_kit::env().timer.curr_time().trunc_to_plain_us().value < (start + usec)) { ; }
|
||||
}
|
Loading…
Reference in New Issue
Block a user