pc: consolidate __const_udelay for linux drivers

Use common implementation used by wifi and (not merged) audio driver.
Avoid usage of lib/delay.c since lpj and loop_for_jiffies are not calibrated
for the ported drivers as done on native Linux during boot and leads to wrong
delays for usb and intel_fb.

Issue #4540
This commit is contained in:
Alexander Boettcher 2022-06-30 16:40:30 +02:00 committed by Christian Helmuth
parent 7b4556e546
commit 46b487c2f7
13 changed files with 87 additions and 29 deletions

View File

@ -26,7 +26,6 @@ unsigned long long sched_clock(void)
void time_init(void)
{
lx_emul_time_init(); /* replaces timer_probe() */
lpj_fine = 1000000 / HZ;
}

View File

@ -47,6 +47,7 @@ SRC_C += lx_emul/sched_core.c
SRC_C += lx_emul/slab_common.c
SRC_C += lx_emul/softirq.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/kernel/rcu/tiny.c

View File

@ -1,4 +1,3 @@
arch/x86/lib/delay.c
arch/x86/lib/hweight.S
arch/x86/pci/legacy.c
arch/x86/platform/intel/iosf_mbi.c

View File

@ -1,4 +1,3 @@
arch/x86/lib/delay.c
arch/x86/lib/hweight.S
arch/x86/lib/memcpy_64.S
arch/x86/lib/memmove_64.S

View File

@ -11,6 +11,7 @@ INC_DIR += $(REL_PRG_DIR)/shadow
SRC_CC += main.cc
SRC_CC += misc.cc
SRC_CC += emul.cc
SRC_CC += time.cc
SRC_CC += opregion_io_mem.cc
SRC_C += dummies.c
SRC_C += lx_emul.c

View File

@ -0,0 +1,25 @@
/*
* \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)) { ; }
}

View File

@ -1,4 +1,3 @@
arch/x86/lib/delay.c
arch/x86/lib/hweight.S
arch/x86/pci/legacy.c
drivers/base/bus.c

View File

@ -1,4 +1,3 @@
arch/x86/lib/delay.c
arch/x86/lib/hweight.S
arch/x86/pci/legacy.c
drivers/base/bus.c

View File

@ -8,6 +8,7 @@ LIBS := base pc_lx_emul jitterentropy
INC_DIR += $(REL_PRG_DIR)
SRC_CC += main.cc
SRC_CC += misc.cc
SRC_CC += time.cc
SRC_CC += lx_emul/shared_dma_buffer.cc
SRC_C += dummies.c
SRC_C += lx_emul.c

View File

@ -0,0 +1,25 @@
/*
* \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)) { ; }
}

View File

@ -47,11 +47,6 @@ const struct trace_print_flags pageflag_names[] = { {0,NULL}};
struct kernel_stat kstat;
#include <linux/delay.h>
/* support for arch/x86/lib/delay.c, normally defined in init/main.c */
unsigned long loops_per_jiffy = (1<<12);
#include <asm/processor.h>
@ -70,11 +65,6 @@ struct cpuinfo_x86 boot_cpu_data =
unsigned long init_stack[THREAD_SIZE / sizeof(unsigned long)];
#include <linux/delay.h>
unsigned long lpj_fine = 0;
/*
* Generate_dummies.c will otherwise pull in <linux/rcutree.h>
* that clashes with rcutiny.h.

View File

@ -0,0 +1,34 @@
/*
* \brief Supplement for emulation for linux/include/asm-generic/delay.h
* \author Josef Soentgen
* \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 <lx_emul.h>
void __const_udelay(unsigned long xloops)
{
unsigned long usecs = xloops / 0x10C7UL;
if (usecs < 100)
lx_emul_time_udelay(usecs);
else
usleep_range(usecs, usecs * 10);
}
void __udelay(unsigned long usecs)
{
lx_emul_time_udelay(usecs);
}

View File

@ -18,20 +18,6 @@
#include <lx_emul/alloc.h>
#include <lx_emul/io_mem.h>
#include <asm-generic/delay.h>
#include <linux/delay.h>
void __const_udelay(unsigned long xloops)
{
unsigned long usecs = xloops / 0x10C7UL;
if (usecs < 100)
lx_emul_time_udelay(usecs);
else
usleep_range(usecs, usecs * 10);
}
#include <linux/slab.h>
struct kmem_cache * kmem_cache_create_usercopy(const char * name,