From da5542511463e28bbd2e6af8a4aed940e8d31e08 Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Wed, 9 Feb 2022 15:06:08 +0100 Subject: [PATCH] lx_emul: finalize support for x86_32 and x86_64 Original commit by Josef Soentgen. Fix genodelabs/genode#4411 --- .../spec/x86/lx_emul/shadow/asm/cpufeature.h | 12 ++ .../spec/x86/lx_emul/shadow/asm/debugreg.h | 9 + .../x86/lx_emul/shadow/asm/memory_model.h | 27 +++ .../spec/x86/lx_emul/shadow/asm/page.h | 74 +++++++ .../spec/x86/lx_emul/shadow/asm/pgtable.h | 49 +++++ .../spec/x86/lx_emul/shadow/asm/sections.h | 13 ++ .../spec/x86/lx_emul/shadow/asm/switch_to.h | 9 + .../spec/x86/lx_emul/shadow/asm/sync_core.h | 9 + .../spec/x86/lx_emul/shadow/asm/uaccess.h | 18 ++ .../x86/lx_emul/shadow/linux/compiler-gcc.h | 28 +++ .../spec/x86/lx_emul/shadow/linux/pci.h | 22 ++ .../spec/x86/lx_emul/shadow/linux/swapops.h | 9 + .../x86_32/lx_emul/shadow/asm/atomic64_32.h | 59 ++++++ .../x86_32/lx_emul/shadow/asm/string_32.h | 9 + .../src/lib/lx_emul/spec/x86/irqchip.c | 95 +++++++++ .../dde_linux/src/lib/lx_emul/spec/x86/pci.c | 194 ++++++++++++++++++ .../src/lib/lx_emul/spec/x86_32/atomic64_32.c | 25 +++ 17 files changed, 661 insertions(+) create mode 100644 repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/cpufeature.h create mode 100644 repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/debugreg.h create mode 100644 repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/memory_model.h create mode 100644 repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/page.h create mode 100644 repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/pgtable.h create mode 100644 repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/sections.h create mode 100644 repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/switch_to.h create mode 100644 repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/sync_core.h create mode 100644 repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/uaccess.h create mode 100644 repos/dde_linux/src/include/spec/x86/lx_emul/shadow/linux/compiler-gcc.h create mode 100644 repos/dde_linux/src/include/spec/x86/lx_emul/shadow/linux/pci.h create mode 100644 repos/dde_linux/src/include/spec/x86/lx_emul/shadow/linux/swapops.h create mode 100644 repos/dde_linux/src/include/spec/x86_32/lx_emul/shadow/asm/atomic64_32.h create mode 100644 repos/dde_linux/src/include/spec/x86_32/lx_emul/shadow/asm/string_32.h create mode 100644 repos/dde_linux/src/lib/lx_emul/spec/x86/irqchip.c create mode 100644 repos/dde_linux/src/lib/lx_emul/spec/x86/pci.c create mode 100644 repos/dde_linux/src/lib/lx_emul/spec/x86_32/atomic64_32.c diff --git a/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/cpufeature.h b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/cpufeature.h new file mode 100644 index 0000000000..34ccf560ed --- /dev/null +++ b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/cpufeature.h @@ -0,0 +1,12 @@ +/** + * \brief Shadow copy of asm/cpufeature.h + * \author Josef Soentgen + * \date 2022-01-14 + */ + +#ifndef _ASM__CPUFEATURE_H_ +#define _ASM__CPUFEATURE_H_ + +#define boot_cpu_has(bit) 0 + +#endif diff --git a/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/debugreg.h b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/debugreg.h new file mode 100644 index 0000000000..c18e12f0f1 --- /dev/null +++ b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/debugreg.h @@ -0,0 +1,9 @@ +/** + * \brief Shadow copy of asm/debugreg.h + * \author Josef Soentgen + * \date 2022-01-14 + */ + +#ifndef _ASM__DEBUGREG_H_ +#define _ASM__DEBUGREG_H_ +#endif diff --git a/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/memory_model.h b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/memory_model.h new file mode 100644 index 0000000000..65712b0c85 --- /dev/null +++ b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/memory_model.h @@ -0,0 +1,27 @@ +/* + * \brief Shadows Linux kernel asm-generic/memory_model.h + * \author Norman Feske + * \date 2021-06-25 + */ + +/* + * Copyright (C) 2021 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#ifndef __ASM_MEMORY_MODEL_H +#define __ASM_MEMORY_MODEL_H + +#include + +#ifndef __ASSEMBLY__ + +#define page_to_pfn(page) virt_to_pfn(page_to_virt(page)) +#define pfn_to_page(pfn) virt_to_page(pfn_to_virt(pfn)) + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASM_MEMORY_MODEL_H */ + diff --git a/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/page.h b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/page.h new file mode 100644 index 0000000000..4b623f65d9 --- /dev/null +++ b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/page.h @@ -0,0 +1,74 @@ +/* + * \brief Shadows Linux kernel asm-generic/page.h + * \author Norman Feske + * \date 2021-06-25 + */ + +/* + * Copyright (C) 2021 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#ifndef __ASM_GENERIC_PAGE_H +#define __ASM_GENERIC_PAGE_H + +#include + +#ifdef CONFIG_X86_64 +#include +#else +#include +#endif /* CONFIG_X86_64 */ + +/* + * The 'virtual' member of 'struct page' is needed by 'lx_emul_virt_to_phys' + * and 'page_to_virt'. + */ +#define WANT_PAGE_VIRTUAL + +#ifndef __ASSEMBLY__ + +#include +#include +#include + +struct page; + +#include +extern struct range pfn_mapped[]; +extern int nr_pfn_mapped; + +static inline void clear_user_page(void *page, unsigned long vaddr, + struct page *pg) +{ + clear_page(page); +} + +static inline void copy_user_page(void *to, void *from, unsigned long vaddr, + struct page *topage) +{ + copy_page(to, from); +} + +typedef struct page *pgtable_t; + +#define __va(x) ((void*)lx_emul_mem_virt_addr((void*)(x))) +#define __pa(x) lx_emul_mem_dma_addr((void *)(x)) + +#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) +#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) +#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) + +static inline struct page *virt_to_page(void const *v) { return lx_emul_virt_to_pages(v, 1U); } +#define page_to_virt(p) ((p)->virtual) + +#define virt_addr_valid(kaddr) ((unsigned long)kaddr != 0UL) + +#endif /* __ASSEMBLY__ */ + +#include +#include + +#endif /* __ASM_GENERIC_PAGE_H */ diff --git a/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/pgtable.h b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/pgtable.h new file mode 100644 index 0000000000..acd7aa5dcd --- /dev/null +++ b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/pgtable.h @@ -0,0 +1,49 @@ +/* + * \brief Shadows Linux kernel arch/x86/include/asm/pgtable.h + * \author Stefan Kalkowski + * \date 2022-01-25 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#ifndef _ASM__X86__PGTABLE_H +#define _ASM__X86__PGTABLE_H + +#include + +#include +#include + +#include + +static inline pte_t pte_mkwrite(pte_t pte) { return pte; } + +static inline bool __pkru_allows_pkey(u16 pkey, bool write) +{ + lx_emul_trace_and_stop(__func__); +} + +extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; + +#define ZERO_PAGE(vaddr) ((void)(vaddr),virt_to_page(empty_zero_page)) + +#ifdef CONFIG_X86_64 +static inline int p4d_none(p4d_t p4d) +{ + lx_emul_trace_and_stop(__func__); +} + +static inline int pud_none(pud_t pud) +{ + lx_emul_trace_and_stop(__func__); +} + +#endif + +#endif /*_ASM__X86__PGTABLE_H */ + diff --git a/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/sections.h b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/sections.h new file mode 100644 index 0000000000..f0d977becc --- /dev/null +++ b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/sections.h @@ -0,0 +1,13 @@ +/** + * \brief Shadow copy of asm/sections.h + * \author Josef Soentgen + * \date 2022-01-13 + */ + +#ifndef _ASM__SECTIONS_H_ +#define _ASM__SECTIONS_H_ + +#include +#include + +#endif diff --git a/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/switch_to.h b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/switch_to.h new file mode 100644 index 0000000000..15613fa1cc --- /dev/null +++ b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/switch_to.h @@ -0,0 +1,9 @@ +/** + * \brief Shadow copy of asm/switch_to.h + * \author Josef Soentgen + * \date 2022-01-14 + */ + +#ifndef _ASM__SWITCH_TO_H_ +#define _ASM__SWITCH_TO_H_ +#endif diff --git a/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/sync_core.h b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/sync_core.h new file mode 100644 index 0000000000..bf4441eb44 --- /dev/null +++ b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/sync_core.h @@ -0,0 +1,9 @@ +/** + * \brief Shadow copy of asm/sync_core.h + * \author Josef Soentgen + * \date 2022-01-14 + */ + +#ifndef _ASM__SYNC_CORE_H_ +#define _ASM__SYNC_CORE_H_ +#endif diff --git a/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/uaccess.h b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/uaccess.h new file mode 100644 index 0000000000..b1a9ab5cb7 --- /dev/null +++ b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/asm/uaccess.h @@ -0,0 +1,18 @@ +/** + * \brief Shadow copy of asm/uaccess.h + * \author Josef Soentgen + * \date 2022-01-14 + */ + +#ifndef _ASM__UACCESS_H_ +#define _ASM__UACCESS_H_ + +#include_next + +#undef put_user +#undef get_user + +#define get_user(x, ptr) ({ (x) = *(ptr); 0; }) +#define put_user(x, ptr) ({ *(ptr) = (x); 0; }) + +#endif diff --git a/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/linux/compiler-gcc.h b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/linux/compiler-gcc.h new file mode 100644 index 0000000000..486cf53d46 --- /dev/null +++ b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/linux/compiler-gcc.h @@ -0,0 +1,28 @@ +/* + * \brief Shadow copy of linux/compiler-gcc.h + * \author Stefan Kalkowski + * \date 2021-03-17 + */ + +/* + * Copyright (C) 2021 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#ifndef _LX_EMUL__SHADOW__LINUX__COMPILER_GCC_H_ +#define _LX_EMUL__SHADOW__LINUX__COMPILER_GCC_H_ + +#include_next + +/** + * We have to re-define `asm_volatile_goto`, because the original function + * uses `asm goto(...)`, which is a problem when building PIC code. + */ +#ifdef asm_volatile_goto +#undef asm_volatile_goto +#define asm_volatile_goto(x...) asm volatile("invalid use of asm_volatile_goto") +#endif + +#endif /* _LX_EMUL__SHADOW__LINUX__COMPILER_GCC_H_ */ diff --git a/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/linux/pci.h b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/linux/pci.h new file mode 100644 index 0000000000..c0e5b85356 --- /dev/null +++ b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/linux/pci.h @@ -0,0 +1,22 @@ +/** + * \brief Shadow copy of linux/pci.h + * \author Josef Soentgen + * \date 2022-01-14 + */ + +#ifndef _LINUX__PCI_H_ +#define _LINUX__PCI_H_ + +#include + +#include_next + +#undef DECLARE_PCI_FIXUP_CLASS_FINAL + +#define DECLARE_PCI_FIXUP_CLASS_FINAL(vendor, device, class, \ + class_shift, hook) \ +static void __pci_fixup_final_##hook(struct pci_dev *dev) __attribute__((constructor)); \ +static void __pci_fixup_final_##hook(struct pci_dev *dev) { \ + lx_emul_register_pci_fixup(hook, __func__); }; + +#endif /* _LINUX__PCI_H_ */ diff --git a/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/linux/swapops.h b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/linux/swapops.h new file mode 100644 index 0000000000..49d60cadb6 --- /dev/null +++ b/repos/dde_linux/src/include/spec/x86/lx_emul/shadow/linux/swapops.h @@ -0,0 +1,9 @@ +/** + * \brief Shadow copy of linux/swapops.h + * \author Josef Soentgen + * \date 2022-01-14 + */ + +#ifndef _LINUX__SWAPOPS_H_ +#define _LINUX__SWAPOPS_H_ +#endif diff --git a/repos/dde_linux/src/include/spec/x86_32/lx_emul/shadow/asm/atomic64_32.h b/repos/dde_linux/src/include/spec/x86_32/lx_emul/shadow/asm/atomic64_32.h new file mode 100644 index 0000000000..3f2e295e28 --- /dev/null +++ b/repos/dde_linux/src/include/spec/x86_32/lx_emul/shadow/asm/atomic64_32.h @@ -0,0 +1,59 @@ +/** + * \brief Shadow copy of asm/atomic64_32.h + * \author Josef Soentgen + * \date 2022-01-31 + * + * This header contains all declarations but only a handful are + * actually implemented. + */ + +#ifndef _ASM__ATOMIC64_32_H_ +#define _ASM__ATOMIC64_32_H_ + +#include + +typedef struct { + s64 __aligned(8) counter; +} atomic64_t; + +s64 arch_atomic64_add(s64 i, atomic64_t *v); +s64 arch_atomic64_add_return(s64 i, atomic64_t *v); +int arch_atomic64_add_unless(atomic64_t *v, s64 a, s64 u); +void arch_atomic64_and(s64 i, atomic64_t *v); +s64 arch_atomic64_cmpxchg(atomic64_t *v, s64 o, s64 n); +void arch_atomic64_dec(atomic64_t *v); +s64 arch_atomic64_dec_if_positive(atomic64_t *v); +s64 arch_atomic64_dec_return(atomic64_t *v); +s64 arch_atomic64_fetch_add(s64 i, atomic64_t *v); +s64 arch_atomic64_fetch_and(s64 i, atomic64_t *v); +s64 arch_atomic64_fetch_or(s64 i, atomic64_t *v); +s64 arch_atomic64_fetch_xor(s64 i, atomic64_t *v); +void arch_atomic64_inc(atomic64_t *v); +int arch_atomic64_inc_not_zero(atomic64_t *v); +s64 arch_atomic64_inc_return(atomic64_t *v); +void arch_atomic64_or(s64 i, atomic64_t *v); +s64 arch_atomic64_read(const atomic64_t *v); +void arch_atomic64_set(atomic64_t *v, s64 i); +s64 arch_atomic64_sub(s64 i, atomic64_t *v); +s64 arch_atomic64_sub_return(s64 i, atomic64_t *v); +s64 arch_atomic64_xchg(atomic64_t *v, s64 n); +void arch_atomic64_xor(s64 i, atomic64_t *v); + +#define arch_atomic64_cmpxchg arch_atomic64_cmpxchg +#define arch_atomic64_xchg arch_atomic64_xchg +#define arch_atomic64_add_return arch_atomic64_add_return +#define arch_atomic64_sub_return arch_atomic64_sub_return +#define arch_atomic64_inc_return arch_atomic64_inc_return +#define arch_atomic64_dec_return arch_atomic64_dec_return +#define arch_atomic64_inc arch_atomic64_inc +#define arch_atomic64_dec arch_atomic64_dec +#define arch_atomic64_add_unless arch_atomic64_add_unless +#define arch_atomic64_inc_not_zero arch_atomic64_inc_not_zero +#define arch_atomic64_dec_if_positive arch_atomic64_dec_if_positive +#define arch_atomic64_fetch_and arch_atomic64_fetch_and +#define arch_atomic64_fetch_or arch_atomic64_fetch_or +#define arch_atomic64_fetch_xor arch_atomic64_fetch_xor +#define arch_atomic64_fetch_add arch_atomic64_fetch_add +#define arch_atomic64_fetch_sub(i, v) arch_atomic64_fetch_add(-(i), (v)) + +#endif /* _ASM__ATOMIC64_32_H_ */ diff --git a/repos/dde_linux/src/include/spec/x86_32/lx_emul/shadow/asm/string_32.h b/repos/dde_linux/src/include/spec/x86_32/lx_emul/shadow/asm/string_32.h new file mode 100644 index 0000000000..91218d38f1 --- /dev/null +++ b/repos/dde_linux/src/include/spec/x86_32/lx_emul/shadow/asm/string_32.h @@ -0,0 +1,9 @@ +/** + * \brief Shadow copy of asm/string_32.h + * \author Josef Soentgen + * \date 2022-01-31 + */ + +#ifndef _ASM__STRING_32_H_ +#define _ASM__STRING_32_H_ +#endif /* _ASM__STRING_32_H_ */ diff --git a/repos/dde_linux/src/lib/lx_emul/spec/x86/irqchip.c b/repos/dde_linux/src/lib/lx_emul/spec/x86/irqchip.c new file mode 100644 index 0000000000..fd3cb9e570 --- /dev/null +++ b/repos/dde_linux/src/lib/lx_emul/spec/x86/irqchip.c @@ -0,0 +1,95 @@ +/* + * \brief Linux DDE x86 interrupt controller + * \author Josef Soentgen + * \date 2022-01-20 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include +#include +#include +#include +#include <../kernel/irq/internals.h> + + +static void dde_irq_unmask(struct irq_data *d) +{ + lx_emul_irq_unmask(d->hwirq); +} + + +static void dde_irq_mask(struct irq_data *d) +{ + lx_emul_irq_mask(d->hwirq); +} + + +struct irq_chip dde_irqchip_data_chip = { + .name = "dde-irqs", + .irq_mask = dde_irq_mask, + .irq_disable = dde_irq_mask, + .irq_unmask = dde_irq_unmask, + .irq_mask_ack = dde_irq_mask, +}; + + +int lx_emul_irq_task_function(void * data) +{ + int irq; + + for (;;) { + lx_emul_task_schedule(true); + + irq_enter(); + + irq = lx_emul_irq_last(); + + if (!irq) { + ack_bad_irq(irq); + WARN_ONCE(true, "Unexpected interrupt %d received!\n", + lx_emul_irq_last()); + } else { + generic_handle_irq(irq); + } + + irq_exit(); + } + + return 0; +} + + +struct task_struct irq_task = { + .__state = 0, + .usage = REFCOUNT_INIT(2), + .flags = PF_KTHREAD, + .prio = MAX_PRIO - 20, + .static_prio = MAX_PRIO - 20, + .normal_prio = MAX_PRIO - 20, + .policy = SCHED_NORMAL, + .cpus_ptr = &irq_task.cpus_mask, + .cpus_mask = CPU_MASK_ALL, + .nr_cpus_allowed = 1, + .mm = NULL, + .active_mm = NULL, + .tasks = LIST_HEAD_INIT(irq_task.tasks), + .real_parent = &irq_task, + .parent = &irq_task, + .children = LIST_HEAD_INIT(irq_task.children), + .sibling = LIST_HEAD_INIT(irq_task.sibling), + .group_leader = &irq_task, + .comm = "kirqd", + .thread = INIT_THREAD, + .pending = { + .list = LIST_HEAD_INIT(irq_task.pending.list), + .signal = {{0}} + }, + .blocked = {{0}}, +}; +void * lx_emul_irq_task_struct = &irq_task; diff --git a/repos/dde_linux/src/lib/lx_emul/spec/x86/pci.c b/repos/dde_linux/src/lib/lx_emul/spec/x86/pci.c new file mode 100644 index 0000000000..35d208d10d --- /dev/null +++ b/repos/dde_linux/src/lib/lx_emul/spec/x86/pci.c @@ -0,0 +1,194 @@ +/* + * \brief Linux kernel PCI + * \author Josef Soentgen + * \date 2022-01-14 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include +#include + + +#include + +int arch_probe_nr_irqs(void) +{ + return 16; +} + + +#include + +static int x86_init_pci_init(void) +{ + return 1; +} + + +static void x86_init_pci_init_irq(void) { } + + +struct x86_init_ops x86_init = { + .pci = { + .init = x86_init_pci_init, + .init_irq = x86_init_pci_init_irq, + }, +}; + + +#include + +#include +#include +#include + +static int pci_raw_ops_read(unsigned int domain, unsigned int bus, unsigned int devfn, + int reg, int len, u32 *val) +{ + return lx_emul_pci_read_config(bus, devfn, (unsigned)reg, (unsigned)len, val); +} + + +static int pci_raw_ops_write(unsigned int domain, unsigned int bus, unsigned int devfn, + int reg, int len, u32 val) +{ + return lx_emul_pci_write_config(bus, devfn, (unsigned)reg, (unsigned)len, val); +} + + +const struct pci_raw_ops genode_raw_pci_ops = { + .read = pci_raw_ops_read, + .write = pci_raw_ops_write, +}; + +const struct pci_raw_ops *raw_pci_ops = &genode_raw_pci_ops; + + +static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) +{ + return pci_raw_ops_read(0, bus->number, devfn, where, size, value); +} + + +static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) +{ + return pci_raw_ops_write(0, bus->number, devfn, where, size, value); +} + + +struct pci_ops pci_root_ops = { + .read = pci_read, + .write = pci_write, +}; + + +#include + +static struct resource _dummy_parent; + +void pcibios_scan_root(int busnum) +{ + struct pci_bus *bus; + struct pci_sysdata *sd; + struct pci_dev *dev; + + LIST_HEAD(resources); + + sd = kzalloc(sizeof(*sd), GFP_KERNEL); + if (!sd) { + return; + } + sd->node = NUMA_NO_NODE; + pci_add_resource(&resources, &ioport_resource); + pci_add_resource(&resources, &iomem_resource); + + bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources); + + if (!bus) { + pci_free_resource_list(&resources); + kfree(sd); + return; + } + pci_bus_add_devices(bus); + + /* handle early quirks */ + list_for_each_entry(dev, &bus->devices, bus_list) { + + /* + * As pci_enable_resources() is only going to check if + * the parent of the resource is set register the dummy. + */ + struct resource *r; + int i; + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + + r = &dev->resource[i]; + r->parent = &_dummy_parent; + } + + lx_emul_execute_pci_fixup(dev); + } +} + + +#include +#include + +extern struct irq_chip dde_irqchip_data_chip; + + +void pci_assign_irq(struct pci_dev * dev) +{ + struct irq_data *irq_data; + + /* + * Be lazy and treat irq as hwirq as this is used by the + * dde_irqchip_data_chip for (un-)masking. + */ + irq_data = irq_get_irq_data(dev->irq); + irq_data->hwirq = dev->irq; + + irq_set_chip_and_handler(dev->irq, &dde_irqchip_data_chip, + handle_level_irq); +} + + +#include + +unsigned long pci_mem_start = 0xaeedbabe; + +const struct attribute_group aspm_ctrl_attr_group[] = { 0 }; +const struct attribute_group pci_dev_vpd_attr_group = { }; + +struct pci_fixup __start_pci_fixups_early[] = { 0 }; +struct pci_fixup __end_pci_fixups_early[] = { 0 }; +struct pci_fixup __start_pci_fixups_header[] = { 0 }; +struct pci_fixup __end_pci_fixups_header[] = { 0 }; +struct pci_fixup __start_pci_fixups_final[] = { 0 }; +struct pci_fixup __end_pci_fixups_final[] = { 0 }; +struct pci_fixup __start_pci_fixups_enable[] = { 0 }; +struct pci_fixup __end_pci_fixups_enable[] = { 0 }; +struct pci_fixup __start_pci_fixups_resume[] = { 0 }; +struct pci_fixup __end_pci_fixups_resume[] = { 0 }; +struct pci_fixup __start_pci_fixups_resume_early[] = { 0 }; +struct pci_fixup __end_pci_fixups_resume_early[] = { 0 }; +struct pci_fixup __start_pci_fixups_suspend[] = { 0 }; +struct pci_fixup __end_pci_fixups_suspend[] = { 0 }; +struct pci_fixup __start_pci_fixups_suspend_late[] = { 0 }; +struct pci_fixup __end_pci_fixups_suspend_late[] = { 0 }; + +int pcibios_last_bus = -1; + + +extern int __init pcibios_init(void); +int __init pcibios_init(void) +{ + lx_emul_trace(__func__); + return 0; +} diff --git a/repos/dde_linux/src/lib/lx_emul/spec/x86_32/atomic64_32.c b/repos/dde_linux/src/lib/lx_emul/spec/x86_32/atomic64_32.c new file mode 100644 index 0000000000..ef58c0441d --- /dev/null +++ b/repos/dde_linux/src/lib/lx_emul/spec/x86_32/atomic64_32.c @@ -0,0 +1,25 @@ +#include + +/** + * This is not atomic on 32bit systems but this is not a problem + * because we will not be preempted. + */ + +s64 arch_atomic64_add(s64 i, atomic64_t *v) +{ + v->counter += i; + return v->counter; +} + + +s64 arch_atomic64_read(const atomic64_t *v) +{ + return v->counter; +} + + +s64 arch_atomic64_sub(s64 i, atomic64_t *v) +{ + v->counter -= i; + return v->counter; +}