Remove the pre-ARMv6 and pre-INTRNG code.
ARM has required ARMV6+ and INTRNg for some time now, so remove always false #ifdefs and unconditionally do always true #ifdefs.
This commit is contained in:
@@ -62,10 +62,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include "opt_soc.h"
|
||||
#endif
|
||||
|
||||
#ifdef INTRNG
|
||||
#include "pic_if.h"
|
||||
#endif
|
||||
|
||||
#include "gpio_if.h"
|
||||
|
||||
#define AW_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
|
||||
@@ -257,7 +254,6 @@ struct clk_list {
|
||||
clk_t clk;
|
||||
};
|
||||
|
||||
#ifdef INTRNG
|
||||
struct gpio_irqsrc {
|
||||
struct intr_irqsrc isrc;
|
||||
u_int irq;
|
||||
@@ -269,7 +265,6 @@ struct gpio_irqsrc {
|
||||
uint32_t oldfunc;
|
||||
bool enabled;
|
||||
};
|
||||
#endif
|
||||
|
||||
#define AW_GPIO_MEMRES 0
|
||||
#define AW_GPIO_IRQRES 1
|
||||
@@ -286,10 +281,8 @@ struct aw_gpio_softc {
|
||||
struct aw_gpio_conf *conf;
|
||||
TAILQ_HEAD(, clk_list) clk_list;
|
||||
|
||||
#ifdef INTRNG
|
||||
struct gpio_irqsrc *gpio_pic_irqsrc;
|
||||
int nirqs;
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct resource_spec aw_gpio_res_spec[] = {
|
||||
@@ -1071,10 +1064,8 @@ aw_gpio_attach(device_t dev)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#ifdef INTRNG
|
||||
aw_gpio_register_isrcs(sc);
|
||||
intr_pic_register(dev, OF_xref_from_node(ofw_bus_get_node(dev)));
|
||||
#endif
|
||||
|
||||
sc->sc_busdev = gpiobus_attach_bus(dev);
|
||||
if (sc->sc_busdev == NULL)
|
||||
@@ -1451,7 +1442,6 @@ static device_method_t aw_gpio_methods[] = {
|
||||
DEVMETHOD(device_attach, aw_gpio_attach),
|
||||
DEVMETHOD(device_detach, aw_gpio_detach),
|
||||
|
||||
#ifdef INTRNG
|
||||
/* Interrupt controller interface */
|
||||
DEVMETHOD(pic_disable_intr, aw_gpio_pic_disable_intr),
|
||||
DEVMETHOD(pic_enable_intr, aw_gpio_pic_enable_intr),
|
||||
@@ -1461,7 +1451,6 @@ static device_method_t aw_gpio_methods[] = {
|
||||
DEVMETHOD(pic_post_filter, aw_gpio_pic_post_filter),
|
||||
DEVMETHOD(pic_post_ithread, aw_gpio_pic_post_ithread),
|
||||
DEVMETHOD(pic_pre_ithread, aw_gpio_pic_pre_ithread),
|
||||
#endif
|
||||
|
||||
/* GPIO protocol */
|
||||
DEVMETHOD(gpio_get_bus, aw_gpio_get_bus),
|
||||
|
||||
@@ -10,7 +10,7 @@ arm/allwinner/aw_if_dwc.c optional dwc
|
||||
arm/allwinner/aw_machdep.c standard
|
||||
arm/allwinner/aw_mmc.c optional mmc | mmccam
|
||||
arm/allwinner/aw_mp.c optional smp
|
||||
arm/allwinner/aw_nmi.c optional intrng
|
||||
arm/allwinner/aw_nmi.c standard
|
||||
arm/allwinner/aw_rsb.c optional rsb | p2wi
|
||||
arm/allwinner/aw_rtc.c optional aw_rtc
|
||||
arm/allwinner/aw_syscon.c optional ext_resources syscon
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
|
||||
* Copyright (c) 2015 Semihalf.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_platform.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
|
||||
#include <dev/fdt/fdt_common.h>
|
||||
#include <dev/ofw/openfirm.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/fdt.h>
|
||||
#include <machine/intr.h>
|
||||
|
||||
#ifndef INTRNG
|
||||
static int alpine_pic_decode_fdt(uint32_t iparent, uint32_t *intr,
|
||||
int *interrupt, int *trig, int *pol);
|
||||
|
||||
static int
|
||||
alpine_pic_decode_fdt(uint32_t iparent, uint32_t *intr, int *interrupt,
|
||||
int *trig, int *pol)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
rv = gic_decode_fdt(iparent, intr, interrupt, trig, pol);
|
||||
if (rv == 0) {
|
||||
/* This was recognized as our PIC and decoded. */
|
||||
interrupt = FDT_MAP_IRQ(iparent, interrupt);
|
||||
|
||||
/* Configure the interrupt if callback provided */
|
||||
if (arm_config_irq)
|
||||
(*arm_config_irq)(*interrupt, *trig, *pol);
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
|
||||
fdt_pic_decode_t fdt_pic_table[] = {
|
||||
&alpine_pic_decode_fdt,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
@@ -3,6 +3,5 @@
|
||||
arm/versatile/sp804.c standard
|
||||
dev/uart/uart_dev_ns8250.c optional uart
|
||||
|
||||
arm/annapurna/alpine/alpine_common.c standard
|
||||
arm/annapurna/alpine/alpine_machdep.c standard
|
||||
arm/annapurna/alpine/alpine_machdep_mp.c optional smp
|
||||
|
||||
@@ -54,18 +54,9 @@ __FBSDID("$FreeBSD$");
|
||||
.text
|
||||
.align 2
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
#define GET_PCB(tmp) \
|
||||
mrc p15, 0, tmp, c13, c0, 4; \
|
||||
add tmp, tmp, #(TD_PCB)
|
||||
#else
|
||||
.Lcurpcb:
|
||||
.word _C_LABEL(__pcpu) + PC_CURPCB
|
||||
|
||||
#define GET_PCB(tmp) \
|
||||
ldr tmp, .Lcurpcb
|
||||
#endif
|
||||
|
||||
|
||||
#define SAVE_REGS stmfd sp!, {r4-r11}; _SAVE({r4-r11})
|
||||
#define RESTORE_REGS ldmfd sp!, {r4-r11}
|
||||
|
||||
@@ -42,16 +42,9 @@ __FBSDID("$FreeBSD$");
|
||||
.text
|
||||
.align 2
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
#define GET_PCB(tmp) \
|
||||
mrc p15, 0, tmp, c13, c0, 4; \
|
||||
add tmp, tmp, #(TD_PCB)
|
||||
#else
|
||||
.Lcurpcb:
|
||||
.word _C_LABEL(__pcpu) + PC_CURPCB
|
||||
#define GET_PCB(tmp) \
|
||||
ldr tmp, .Lcurpcb
|
||||
#endif
|
||||
|
||||
/*
|
||||
* r0 = user space address
|
||||
|
||||
@@ -156,6 +156,3 @@ static struct bus_space arm_base_bus_space __aligned(CACHE_LINE_SIZE) = {
|
||||
bus_space_tag_t fdtbus_bs_tag = &arm_base_bus_space;
|
||||
#endif
|
||||
|
||||
#if __ARM_ARCH < 6
|
||||
bus_space_tag_t arm_base_bs_tag = &arm_base_bus_space;
|
||||
#endif
|
||||
|
||||
@@ -48,17 +48,9 @@ __FBSDID("$FreeBSD$");
|
||||
.text
|
||||
.align 2
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
#define GET_PCB(tmp) \
|
||||
mrc p15, 0, tmp, c13, c0, 4; \
|
||||
add tmp, tmp, #(TD_PCB)
|
||||
#else
|
||||
.Lpcb:
|
||||
.word _C_LABEL(__pcpu) + PC_CURPCB
|
||||
|
||||
#define GET_PCB(tmp) \
|
||||
ldr tmp, .Lpcb
|
||||
#endif
|
||||
|
||||
#define SAVE_REGS stmfd sp!, {r4-r6}
|
||||
#define RESTORE_REGS ldmfd sp!, {r4-r6}
|
||||
|
||||
@@ -40,12 +40,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/elf.h>
|
||||
#include <machine/md_var.h>
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
void reinit_mmu(uint32_t ttb, uint32_t aux_clr, uint32_t aux_set);
|
||||
|
||||
int disable_bp_hardening;
|
||||
int spectre_v2_safe = 1;
|
||||
#endif
|
||||
|
||||
struct cpuinfo cpuinfo =
|
||||
{
|
||||
@@ -83,9 +81,7 @@ SYSCTL_INT(_hw_cpu_quirks, OID_AUTO, actlr_set,
|
||||
void
|
||||
cpuinfo_init(void)
|
||||
{
|
||||
#if __ARM_ARCH >= 6
|
||||
uint32_t tmp;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prematurely fetch CPU quirks. Standard fetch for tunable
|
||||
@@ -130,16 +126,13 @@ cpuinfo_init(void)
|
||||
/* CP15 c0,c0 regs 0-7 exist on all CPUs (although aliased with MIDR) */
|
||||
cpuinfo.ctr = cp15_ctr_get();
|
||||
cpuinfo.tcmtr = cp15_tcmtr_get();
|
||||
#if __ARM_ARCH >= 6
|
||||
cpuinfo.tlbtr = cp15_tlbtr_get();
|
||||
cpuinfo.mpidr = cp15_mpidr_get();
|
||||
cpuinfo.revidr = cp15_revidr_get();
|
||||
#endif
|
||||
|
||||
/* if CPU is not v7 cpu id scheme */
|
||||
if (cpuinfo.architecture != 0xF)
|
||||
return;
|
||||
#if __ARM_ARCH >= 6
|
||||
cpuinfo.id_pfr0 = cp15_id_pfr0_get();
|
||||
cpuinfo.id_pfr1 = cp15_id_pfr1_get();
|
||||
cpuinfo.id_dfr0 = cp15_id_dfr0_get();
|
||||
@@ -240,10 +233,8 @@ cpuinfo_init(void)
|
||||
tmp = (cpuinfo.id_isar5 >> 16) & 0xF; /* CRC32 */
|
||||
if (tmp >= 1)
|
||||
elf_hwcap2 |= HWCAP2_CRC32;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
/*
|
||||
* Get bits that must be set or cleared in ACLR register.
|
||||
* Note: Bits in ACLR register are IMPLEMENTATION DEFINED.
|
||||
@@ -535,5 +526,3 @@ SYSCTL_PROC(_machdep, OID_AUTO, disable_bp_hardening,
|
||||
|
||||
SYSCTL_INT(_machdep, OID_AUTO, spectre_v2_safe, CTLFLAG_RD,
|
||||
&spectre_v2_safe, 0, "System is safe to Spectre Version 2 attacks");
|
||||
|
||||
#endif /* __ARM_ARCH >= 6 */
|
||||
|
||||
@@ -153,10 +153,9 @@ void
|
||||
db_show_mdpcpu(struct pcpu *pc)
|
||||
{
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
db_printf("curpmap = %p\n", pc->pc_curpmap);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
db_validate_address(vm_offset_t addr)
|
||||
{
|
||||
|
||||
@@ -257,7 +257,6 @@ kdb_cpu_pc_is_singlestep(db_addr_t pc)
|
||||
/*
|
||||
* XXX: If the platform fails to enable its debug arch.
|
||||
* there will be no stepping capabilities
|
||||
* (SOFTWARE_SSTEP is not defined for __ARM_ARCH >= 6).
|
||||
*/
|
||||
if (!dbg_capable())
|
||||
return (FALSE);
|
||||
|
||||
@@ -131,7 +131,6 @@ static const struct arm32_insn arm32_i[] = {
|
||||
{ 0x0c500000, 0x04100000, "ldr", "daW" },
|
||||
{ 0x0c500000, 0x04400000, "strb", "daW" },
|
||||
{ 0x0c500000, 0x04500000, "ldrb", "daW" },
|
||||
#if __ARM_ARCH >= 6
|
||||
{ 0x0fff0ff0, 0x06bf0fb0, "rev16", "dm" },
|
||||
{ 0xffffffff, 0xf57ff01f, "clrex", "c" },
|
||||
{ 0x0ff00ff0, 0x01800f90, "strex", "dmo" },
|
||||
@@ -142,7 +141,6 @@ static const struct arm32_insn arm32_i[] = {
|
||||
{ 0x0ff00fff, 0x01d00f9f, "ldrexb", "do" },
|
||||
{ 0x0ff00ff0, 0x01e00f90, "strexh", "dmo" },
|
||||
{ 0x0ff00fff, 0x01f00f9f, "ldrexh", "do" },
|
||||
#endif
|
||||
{ 0x0e1f0000, 0x080d0000, "stm", "YnWl" },/* separate out r13 base */
|
||||
{ 0x0e1f0000, 0x081d0000, "ldm", "YnWl" },/* separate out r13 base */
|
||||
{ 0x0e100000, 0x08000000, "stm", "XnWl" },
|
||||
|
||||
@@ -85,9 +85,7 @@ struct sysentvec elf32_freebsd_sysvec = {
|
||||
.sv_fixlimit = NULL,
|
||||
.sv_maxssiz = NULL,
|
||||
.sv_flags =
|
||||
#if __ARM_ARCH >= 6
|
||||
SV_ASLR | SV_SHP | SV_TIMEKEEP | SV_RNG_SEED_VER |
|
||||
#endif
|
||||
SV_ABI_FREEBSD | SV_ILP32 | SV_ASLR,
|
||||
.sv_set_syscall_retval = cpu_set_syscall_retval,
|
||||
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
|
||||
@@ -305,14 +303,8 @@ elf_cpu_load_file(linker_file_t lf)
|
||||
*/
|
||||
if (lf->id == 1)
|
||||
return (0);
|
||||
#if __ARM_ARCH >= 6
|
||||
dcache_wb_pou((vm_offset_t)lf->address, (vm_size_t)lf->size);
|
||||
icache_inv_all();
|
||||
#else
|
||||
cpu_dcache_wb_range((vm_offset_t)lf->address, (vm_size_t)lf->size);
|
||||
cpu_l2cache_wb_range((vm_offset_t)lf->address, (vm_size_t)lf->size);
|
||||
cpu_icache_sync_range((vm_offset_t)lf->address, (vm_size_t)lf->size);
|
||||
#endif
|
||||
|
||||
#if defined(DDB) || defined(KDTRACE_HOOKS) || defined(STACK)
|
||||
/*
|
||||
|
||||
@@ -77,27 +77,7 @@ _C_LABEL(dtrace_invop_jump_addr):
|
||||
/*
|
||||
* PUSHFRAME - macro to push a trap frame on the stack in the current mode
|
||||
* Since the current mode is used, the SVC lr field is not defined.
|
||||
*
|
||||
* NOTE: r13 and r14 are stored separately as a work around for the
|
||||
* SA110 rev 2 STM^ bug
|
||||
*/
|
||||
#if __ARM_ARCH < 6
|
||||
#define PUSHFRAME \
|
||||
sub sp, sp, #4; /* Align the stack */ \
|
||||
str lr, [sp, #-4]!; /* Push the return address */ \
|
||||
sub sp, sp, #(4*17); /* Adjust the stack pointer */ \
|
||||
stmia sp, {r0-r12}; /* Push the user mode registers */ \
|
||||
add r0, sp, #(4*13); /* Adjust the stack pointer */ \
|
||||
stmia r0, {r13-r14}^; /* Push the user mode registers */ \
|
||||
mov r0, r0; /* NOP for previous instruction */ \
|
||||
mrs r0, spsr; /* Put the SPSR on the stack */ \
|
||||
str r0, [sp, #-4]!; \
|
||||
ldr r0, =ARM_RAS_START; \
|
||||
mov r1, #0; \
|
||||
str r1, [r0]; \
|
||||
mov r1, #0xffffffff; \
|
||||
str r1, [r0, #4];
|
||||
#else
|
||||
#define PUSHFRAME \
|
||||
sub sp, sp, #4; /* Align the stack */ \
|
||||
str lr, [sp, #-4]!; /* Push the return address */ \
|
||||
@@ -108,23 +88,12 @@ _C_LABEL(dtrace_invop_jump_addr):
|
||||
mov r0, r0; /* NOP for previous instruction */ \
|
||||
mrs r0, spsr; /* Put the SPSR on the stack */ \
|
||||
str r0, [sp, #-4]!;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PULLFRAME - macro to pull a trap frame from the stack in the current mode
|
||||
* Since the current mode is used, the SVC lr field is ignored.
|
||||
*/
|
||||
|
||||
#if __ARM_ARCH < 6
|
||||
#define PULLFRAME \
|
||||
ldr r0, [sp], #4; /* Get the SPSR from stack */ \
|
||||
msr spsr_fsxc, r0; \
|
||||
ldmia sp, {r0-r14}^; /* Restore registers (usr mode) */ \
|
||||
mov r0, r0; /* NOP for previous instruction */ \
|
||||
add sp, sp, #(4*17); /* Adjust the stack pointer */ \
|
||||
ldr lr, [sp], #4; /* Pull the return address */ \
|
||||
add sp, sp, #4 /* Align the stack */
|
||||
#else
|
||||
#define PULLFRAME \
|
||||
ldr r0, [sp], #4 ; /* Get the SPSR from stack */ \
|
||||
msr spsr_fsxc, r0; \
|
||||
@@ -134,7 +103,6 @@ _C_LABEL(dtrace_invop_jump_addr):
|
||||
add sp, sp, #(4*17); /* Adjust the stack pointer */ \
|
||||
ldr lr, [sp], #4; /* Pull the return address */ \
|
||||
add sp, sp, #4 /* Align the stack */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PUSHFRAMEINSVC - macro to push a trap frame on the stack in SVC32 mode
|
||||
@@ -142,49 +110,7 @@ _C_LABEL(dtrace_invop_jump_addr):
|
||||
* mode. The processor mode is switched to SVC mode and the trap frame is
|
||||
* stored. The SVC lr field is used to store the previous value of
|
||||
* lr in SVC mode.
|
||||
*
|
||||
* NOTE: r13 and r14 are stored separately as a work around for the
|
||||
* SA110 rev 2 STM^ bug
|
||||
*/
|
||||
#if __ARM_ARCH < 6
|
||||
#define PUSHFRAMEINSVC \
|
||||
stmdb sp, {r0-r3}; /* Save 4 registers */ \
|
||||
mov r0, lr; /* Save xxx32 r14 */ \
|
||||
mov r1, sp; /* Save xxx32 sp */ \
|
||||
mrs r3, spsr; /* Save xxx32 spsr */ \
|
||||
mrs r2, cpsr; /* Get the CPSR */ \
|
||||
bic r2, r2, #(PSR_MODE); /* Fix for SVC mode */ \
|
||||
orr r2, r2, #(PSR_SVC32_MODE); \
|
||||
msr cpsr_c, r2; /* Punch into SVC mode */ \
|
||||
mov r2, sp; /* Save SVC sp */ \
|
||||
bic sp, sp, #7; /* Align sp to an 8-byte addrress */ \
|
||||
sub sp, sp, #(4 * 17); /* Pad trapframe to keep alignment */ \
|
||||
/* and for dtrace to emulate push/pop */ \
|
||||
str r0, [sp, #-4]!; /* Push return address */ \
|
||||
str lr, [sp, #-4]!; /* Push SVC lr */ \
|
||||
str r2, [sp, #-4]!; /* Push SVC sp */ \
|
||||
msr spsr_fsxc, r3; /* Restore correct spsr */ \
|
||||
ldmdb r1, {r0-r3}; /* Restore 4 regs from xxx mode */ \
|
||||
sub sp, sp, #(4*15); /* Adjust the stack pointer */ \
|
||||
stmia sp, {r0-r12}; /* Push the user mode registers */ \
|
||||
add r0, sp, #(4*13); /* Adjust the stack pointer */ \
|
||||
stmia r0, {r13-r14}^; /* Push the user mode registers */ \
|
||||
mov r0, r0; /* NOP for previous instruction */ \
|
||||
ldr r5, =ARM_RAS_START; /* Check if there's any RAS */ \
|
||||
ldr r4, [r5, #4]; /* reset it to point at the */ \
|
||||
cmp r4, #0xffffffff; /* end of memory if necessary; */ \
|
||||
movne r1, #0xffffffff; /* leave value in r4 for later */ \
|
||||
strne r1, [r5, #4]; /* comparison against PC. */ \
|
||||
ldr r3, [r5]; /* Retrieve global RAS_START */ \
|
||||
cmp r3, #0; /* and reset it if non-zero. */ \
|
||||
movne r1, #0; /* If non-zero RAS_START and */ \
|
||||
strne r1, [r5]; /* PC was lower than RAS_END, */ \
|
||||
ldrne r1, [r0, #16]; /* adjust the saved PC so that */ \
|
||||
cmpne r4, r1; /* execution later resumes at */ \
|
||||
strhi r3, [r0, #16]; /* the RAS_START location. */ \
|
||||
mrs r0, spsr; \
|
||||
str r0, [sp, #-4]!
|
||||
#else
|
||||
#define PUSHFRAMEINSVC \
|
||||
stmdb sp, {r0-r3}; /* Save 4 registers */ \
|
||||
mov r0, lr; /* Save xxx32 r14 */ \
|
||||
@@ -210,7 +136,6 @@ _C_LABEL(dtrace_invop_jump_addr):
|
||||
mov r0, r0; /* NOP for previous instruction */ \
|
||||
mrs r0, spsr; /* Put the SPSR on the stack */ \
|
||||
str r0, [sp, #-4]!
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PULLFRAMEFROMSVCANDEXIT - macro to pull a trap frame from the stack
|
||||
@@ -219,15 +144,6 @@ _C_LABEL(dtrace_invop_jump_addr):
|
||||
* exit.
|
||||
*/
|
||||
|
||||
#if __ARM_ARCH < 6
|
||||
#define PULLFRAMEFROMSVCANDEXIT \
|
||||
ldr r0, [sp], #4; /* Get the SPSR from stack */ \
|
||||
msr spsr_fsxc, r0; /* restore SPSR */ \
|
||||
ldmia sp, {r0-r14}^; /* Restore registers (usr mode) */ \
|
||||
mov r0, r0; /* NOP for previous instruction */ \
|
||||
add sp, sp, #(4*15); /* Adjust the stack pointer */ \
|
||||
ldmia sp, {sp, lr, pc}^ /* Restore lr and exit */
|
||||
#else
|
||||
#define PULLFRAMEFROMSVCANDEXIT \
|
||||
ldr r0, [sp], #4; /* Get the SPSR from stack */ \
|
||||
msr spsr_fsxc, r0; /* restore SPSR */ \
|
||||
@@ -236,7 +152,6 @@ _C_LABEL(dtrace_invop_jump_addr):
|
||||
mov r0, r0; /* NOP for previous instruction */ \
|
||||
add sp, sp, #(4*15); /* Adjust the stack pointer */ \
|
||||
ldmia sp, {sp, lr, pc}^ /* Restore lr and exit */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Unwind hints so we can unwind past functions that use
|
||||
|
||||
@@ -75,15 +75,7 @@ fiq_installhandler(void *func, size_t size)
|
||||
{
|
||||
const uint32_t fiqvector = 7 * sizeof(uint32_t);
|
||||
|
||||
#if __ARM_ARCH < 6 && !defined(__ARM_FIQ_INDIRECT)
|
||||
vector_page_setprot(VM_PROT_READ|VM_PROT_WRITE);
|
||||
#endif
|
||||
|
||||
memcpy((void *)(vector_page + fiqvector), func, size);
|
||||
|
||||
#if __ARM_ARCH < 6 && !defined(__ARM_FIQ_INDIRECT)
|
||||
vector_page_setprot(VM_PROT_READ);
|
||||
#endif
|
||||
icache_sync((vm_offset_t) fiqvector, size);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,16 +40,9 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
.syntax unified
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
#define GET_PCB(tmp) \
|
||||
mrc p15, 0, tmp, c13, c0, 4; \
|
||||
add tmp, tmp, #(TD_PCB)
|
||||
#else
|
||||
.Lcurpcb:
|
||||
.word _C_LABEL(__pcpu) + PC_CURPCB
|
||||
#define GET_PCB(tmp) \
|
||||
ldr tmp, .Lcurpcb
|
||||
#endif
|
||||
|
||||
/*
|
||||
* casueword32(volatile uint32_t *base, uint32_t oldval, uint32_t *oldvalp,
|
||||
@@ -77,22 +70,14 @@ EENTRY_NP(casueword32)
|
||||
adr r4, .Lcasuwordfault
|
||||
str r4, [r6, #PCB_ONFAULT]
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
mov r5, #1
|
||||
ldrex r4, [r0]
|
||||
cmp r4, r1
|
||||
strexeq r5, r3, [r0]
|
||||
#else
|
||||
ldrt r4, [r0]
|
||||
cmp r4, r1
|
||||
strteq r3, [r0]
|
||||
#endif
|
||||
str r4, [r2]
|
||||
mov r0, #0
|
||||
str r0, [r6, #PCB_ONFAULT]
|
||||
#if __ARM_ARCH >= 6
|
||||
mov r0, r5
|
||||
#endif
|
||||
1:
|
||||
ldmfd sp!, {r4, r5, r6}
|
||||
RET
|
||||
|
||||
@@ -62,18 +62,9 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
ASSYM(KERNBASE, KERNBASE);
|
||||
ASSYM(KERNVIRTADDR, KERNVIRTADDR);
|
||||
#if __ARM_ARCH >= 6
|
||||
ASSYM(CPU_ASID_KERNEL,CPU_ASID_KERNEL);
|
||||
#endif
|
||||
ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
|
||||
#if __ARM_ARCH < 6
|
||||
ASSYM(PCB_DACR, offsetof(struct pcb, pcb_dacr));
|
||||
#endif
|
||||
ASSYM(PCB_PAGEDIR, offsetof(struct pcb, pcb_pagedir));
|
||||
#if __ARM_ARCH < 6
|
||||
ASSYM(PCB_L1VEC, offsetof(struct pcb, pcb_l1vec));
|
||||
ASSYM(PCB_PL1VEC, offsetof(struct pcb, pcb_pl1vec));
|
||||
#endif
|
||||
ASSYM(PCB_R4, offsetof(struct pcb, pcb_regs.sf_r4));
|
||||
ASSYM(PCB_R5, offsetof(struct pcb, pcb_regs.sf_r5));
|
||||
ASSYM(PCB_R6, offsetof(struct pcb, pcb_regs.sf_r6));
|
||||
@@ -86,9 +77,7 @@ ASSYM(PCB_R12, offsetof(struct pcb, pcb_regs.sf_r12));
|
||||
ASSYM(PCB_SP, offsetof(struct pcb, pcb_regs.sf_sp));
|
||||
ASSYM(PCB_LR, offsetof(struct pcb, pcb_regs.sf_lr));
|
||||
ASSYM(PCB_PC, offsetof(struct pcb, pcb_regs.sf_pc));
|
||||
#if __ARM_ARCH >= 6
|
||||
ASSYM(PCB_TPIDRURW, offsetof(struct pcb, pcb_regs.sf_tpidrurw));
|
||||
#endif
|
||||
|
||||
ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
|
||||
ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
|
||||
@@ -97,24 +86,12 @@ ASSYM(M_DATA, offsetof(struct mbuf, m_data));
|
||||
ASSYM(M_NEXT, offsetof(struct mbuf, m_next));
|
||||
ASSYM(IP_SRC, offsetof(struct ip, ip_src));
|
||||
ASSYM(IP_DST, offsetof(struct ip, ip_dst));
|
||||
#if __ARM_ARCH < 6
|
||||
ASSYM(CF_CONTEXT_SWITCH, offsetof(struct cpu_functions, cf_context_switch));
|
||||
ASSYM(CF_DCACHE_WB_RANGE, offsetof(struct cpu_functions, cf_dcache_wb_range));
|
||||
ASSYM(CF_IDCACHE_WBINV_ALL, offsetof(struct cpu_functions, cf_idcache_wbinv_all));
|
||||
ASSYM(CF_L2CACHE_WBINV_ALL, offsetof(struct cpu_functions, cf_l2cache_wbinv_all));
|
||||
ASSYM(CF_TLB_FLUSHID_SE, offsetof(struct cpu_functions, cf_tlb_flushID_SE));
|
||||
#endif
|
||||
|
||||
ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
|
||||
ASSYM(TD_FLAGS, offsetof(struct thread, td_flags));
|
||||
ASSYM(TD_PROC, offsetof(struct thread, td_proc));
|
||||
ASSYM(TD_MD, offsetof(struct thread, td_md));
|
||||
ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
|
||||
#if __ARM_ARCH < 6
|
||||
ASSYM(MD_TP, offsetof(struct mdthread, md_tp));
|
||||
ASSYM(MD_RAS_START, offsetof(struct mdthread, md_ras_start));
|
||||
ASSYM(MD_RAS_END, offsetof(struct mdthread, md_ras_end));
|
||||
#endif
|
||||
|
||||
ASSYM(TF_SPSR, offsetof(struct trapframe, tf_spsr));
|
||||
ASSYM(TF_R0, offsetof(struct trapframe, tf_r0));
|
||||
@@ -125,28 +102,17 @@ ASSYM(P_FLAG, offsetof(struct proc, p_flag));
|
||||
|
||||
ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc));
|
||||
|
||||
#if __ARM_ARCH < 6
|
||||
ASSYM(ARM_TP_ADDRESS, ARM_TP_ADDRESS);
|
||||
ASSYM(ARM_RAS_START, ARM_RAS_START);
|
||||
ASSYM(ARM_RAS_END, ARM_RAS_END);
|
||||
#endif
|
||||
|
||||
#ifdef VFP
|
||||
ASSYM(PCB_VFPSTATE, offsetof(struct pcb, pcb_vfpstate));
|
||||
#endif
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
ASSYM(PC_CURPMAP, offsetof(struct pcpu, pc_curpmap));
|
||||
ASSYM(PC_BP_HARDEN_KIND, offsetof(struct pcpu, pc_bp_harden_kind));
|
||||
ASSYM(PCPU_BP_HARDEN_KIND_NONE, PCPU_BP_HARDEN_KIND_NONE);
|
||||
ASSYM(PCPU_BP_HARDEN_KIND_BPIALL, PCPU_BP_HARDEN_KIND_BPIALL);
|
||||
ASSYM(PCPU_BP_HARDEN_KIND_ICIALLU, PCPU_BP_HARDEN_KIND_ICIALLU);
|
||||
#endif
|
||||
|
||||
ASSYM(PAGE_SIZE, PAGE_SIZE);
|
||||
#if __ARM_ARCH < 6
|
||||
ASSYM(PMAP_DOMAIN_KERNEL, PMAP_DOMAIN_KERNEL);
|
||||
#endif
|
||||
#ifdef PMAP_INCLUDE_PTE_SYNC
|
||||
ASSYM(PMAP_INCLUDE_PTE_SYNC, 1);
|
||||
#endif
|
||||
|
||||
@@ -106,9 +106,6 @@ __FBSDID("$FreeBSD$");
|
||||
#error FreeBSD/arm doesn't provide compatibility with releases prior to 10
|
||||
#endif
|
||||
|
||||
#if __ARM_ARCH >= 6 && !defined(INTRNG)
|
||||
#error armv6 requires INTRNG
|
||||
#endif
|
||||
|
||||
#ifndef _ARM_ARCH_5E
|
||||
#error FreeBSD requires ARMv5 or later
|
||||
@@ -134,26 +131,10 @@ extern int *end;
|
||||
|
||||
#ifdef FDT
|
||||
vm_paddr_t pmap_pa;
|
||||
#if __ARM_ARCH >= 6
|
||||
vm_offset_t systempage;
|
||||
vm_offset_t irqstack;
|
||||
vm_offset_t undstack;
|
||||
vm_offset_t abtstack;
|
||||
#else
|
||||
/*
|
||||
* This is the number of L2 page tables required for covering max
|
||||
* (hypothetical) memsize of 4GB and all kernel mappings (vectors, msgbuf,
|
||||
* stacks etc.), uprounded to be divisible by 4.
|
||||
*/
|
||||
#define KERNEL_PT_MAX 78
|
||||
static struct pv_addr kernel_pt_table[KERNEL_PT_MAX];
|
||||
struct pv_addr systempage;
|
||||
static struct pv_addr msgbufpv;
|
||||
struct pv_addr irqstack;
|
||||
struct pv_addr undstack;
|
||||
struct pv_addr abtstack;
|
||||
static struct pv_addr kernelstack;
|
||||
#endif /* __ARM_ARCH >= 6 */
|
||||
#endif /* FDT */
|
||||
|
||||
#ifdef PLATFORM
|
||||
@@ -197,22 +178,6 @@ arm_vector_init(vm_offset_t va, int which)
|
||||
icache_sync(va, (ARM_NVEC * 2) * sizeof(u_int));
|
||||
|
||||
vector_page = va;
|
||||
#if __ARM_ARCH < 6
|
||||
if (va == ARM_VECTORS_HIGH) {
|
||||
/*
|
||||
* Enable high vectors in the system control reg (SCTLR).
|
||||
*
|
||||
* Assume the MD caller knows what it's doing here, and really
|
||||
* does want the vector page relocated.
|
||||
*
|
||||
* Note: This has to be done here (and not just in
|
||||
* cpu_setup()) because the vector page needs to be
|
||||
* accessible *before* cpu_startup() is called.
|
||||
* Think ddb(9) ...
|
||||
*/
|
||||
cpu_control(CPU_CONTROL_VECRELOC, CPU_CONTROL_VECRELOC);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -220,9 +185,6 @@ cpu_startup(void *dummy)
|
||||
{
|
||||
struct pcb *pcb = thread0.td_pcb;
|
||||
const unsigned int mbyte = 1024 * 1024;
|
||||
#if __ARM_ARCH < 6 && !defined(ARM_CACHE_LOCK_ENABLE)
|
||||
vm_page_t m;
|
||||
#endif
|
||||
|
||||
identify_arm_cpu();
|
||||
|
||||
@@ -247,19 +209,6 @@ cpu_startup(void *dummy)
|
||||
pcb->pcb_regs.sf_sp = (u_int)thread0.td_kstack +
|
||||
USPACE_SVC_STACK_TOP;
|
||||
pmap_set_pcb_pagedir(kernel_pmap, pcb);
|
||||
#if __ARM_ARCH < 6
|
||||
vector_page_setprot(VM_PROT_READ);
|
||||
pmap_postinit();
|
||||
#ifdef ARM_CACHE_LOCK_ENABLE
|
||||
pmap_kenter_user(ARM_TP_ADDRESS, ARM_TP_ADDRESS);
|
||||
arm_lock_cache_line(ARM_TP_ADDRESS);
|
||||
#else
|
||||
m = vm_page_alloc(NULL, 0, VM_ALLOC_NOOBJ | VM_ALLOC_ZERO);
|
||||
pmap_kenter_user(ARM_TP_ADDRESS, VM_PAGE_TO_PHYS(m));
|
||||
#endif
|
||||
*(uint32_t *)ARM_RAS_START = 0;
|
||||
*(uint32_t *)ARM_RAS_END = 0xffffffff;
|
||||
#endif
|
||||
}
|
||||
|
||||
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
|
||||
@@ -279,7 +228,6 @@ cpu_flush_dcache(void *ptr, size_t len)
|
||||
int
|
||||
cpu_est_clockrate(int cpu_id, uint64_t *rate)
|
||||
{
|
||||
#if __ARM_ARCH >= 6
|
||||
struct pcpu *pc;
|
||||
|
||||
pc = pcpu_find(cpu_id);
|
||||
@@ -292,9 +240,6 @@ cpu_est_clockrate(int cpu_id, uint64_t *rate)
|
||||
*rate = pc->pc_clock;
|
||||
|
||||
return (0);
|
||||
#else
|
||||
return (ENXIO);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -737,9 +682,7 @@ makectx(struct trapframe *tf, struct pcb *pcb)
|
||||
void
|
||||
pcpu0_init(void)
|
||||
{
|
||||
#if __ARM_ARCH >= 6
|
||||
set_curthread(&thread0);
|
||||
#endif
|
||||
pcpu_init(pcpup, 0, sizeof(struct pcpu));
|
||||
PCPU_SET(curthread, &thread0);
|
||||
}
|
||||
@@ -762,7 +705,6 @@ init_proc0(vm_offset_t kstack)
|
||||
pcpup->pc_curpcb = thread0.td_pcb;
|
||||
}
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
void
|
||||
set_stackptrs(int cpu)
|
||||
{
|
||||
@@ -774,19 +716,6 @@ set_stackptrs(int cpu)
|
||||
set_stackptr(PSR_UND32_MODE,
|
||||
undstack + ((UND_STACK_SIZE * PAGE_SIZE) * (cpu + 1)));
|
||||
}
|
||||
#else
|
||||
void
|
||||
set_stackptrs(int cpu)
|
||||
{
|
||||
|
||||
set_stackptr(PSR_IRQ32_MODE,
|
||||
irqstack.pv_va + ((IRQ_STACK_SIZE * PAGE_SIZE) * (cpu + 1)));
|
||||
set_stackptr(PSR_ABT32_MODE,
|
||||
abtstack.pv_va + ((ABT_STACK_SIZE * PAGE_SIZE) * (cpu + 1)));
|
||||
set_stackptr(PSR_UND32_MODE,
|
||||
undstack.pv_va + ((UND_STACK_SIZE * PAGE_SIZE) * (cpu + 1)));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
arm_kdb_init(void)
|
||||
@@ -800,286 +729,6 @@ arm_kdb_init(void)
|
||||
}
|
||||
|
||||
#ifdef FDT
|
||||
#if __ARM_ARCH < 6
|
||||
void *
|
||||
initarm(struct arm_boot_params *abp)
|
||||
{
|
||||
struct mem_region mem_regions[FDT_MEM_REGIONS];
|
||||
struct pv_addr kernel_l1pt;
|
||||
struct pv_addr dpcpu;
|
||||
vm_offset_t dtbp, freemempos, l2_start, lastaddr;
|
||||
uint64_t memsize;
|
||||
uint32_t l2size;
|
||||
char *env;
|
||||
void *kmdp;
|
||||
u_int l1pagetable;
|
||||
int i, j, err_devmap, mem_regions_sz;
|
||||
|
||||
lastaddr = parse_boot_param(abp);
|
||||
arm_physmem_kernaddr = abp->abp_physaddr;
|
||||
|
||||
memsize = 0;
|
||||
|
||||
cpuinfo_init();
|
||||
set_cpufuncs();
|
||||
|
||||
/*
|
||||
* Find the dtb passed in by the boot loader.
|
||||
*/
|
||||
kmdp = preload_search_by_type("elf kernel");
|
||||
if (kmdp != NULL)
|
||||
dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t);
|
||||
else
|
||||
dtbp = (vm_offset_t)NULL;
|
||||
|
||||
#if defined(FDT_DTB_STATIC)
|
||||
/*
|
||||
* In case the device tree blob was not retrieved (from metadata) try
|
||||
* to use the statically embedded one.
|
||||
*/
|
||||
if (dtbp == (vm_offset_t)NULL)
|
||||
dtbp = (vm_offset_t)&fdt_static_dtb;
|
||||
#endif
|
||||
|
||||
if (OF_install(OFW_FDT, 0) == FALSE)
|
||||
panic("Cannot install FDT");
|
||||
|
||||
if (OF_init((void *)dtbp) != 0)
|
||||
panic("OF_init failed with the found device tree");
|
||||
|
||||
/* Grab physical memory regions information from device tree. */
|
||||
if (fdt_get_mem_regions(mem_regions, &mem_regions_sz, &memsize) != 0)
|
||||
panic("Cannot get physical memory regions");
|
||||
physmem_hardware_regions(mem_regions, mem_regions_sz);
|
||||
|
||||
/* Grab reserved memory regions information from device tree. */
|
||||
if (fdt_get_reserved_regions(mem_regions, &mem_regions_sz) == 0)
|
||||
physmem_exclude_regions(mem_regions, mem_regions_sz,
|
||||
EXFLAG_NODUMP | EXFLAG_NOALLOC);
|
||||
|
||||
/* Platform-specific initialisation */
|
||||
platform_probe_and_attach();
|
||||
|
||||
pcpu0_init();
|
||||
|
||||
/* Do basic tuning, hz etc */
|
||||
init_param1();
|
||||
|
||||
/* Calculate number of L2 tables needed for mapping vm_page_array */
|
||||
l2size = (memsize / PAGE_SIZE) * sizeof(struct vm_page);
|
||||
l2size = (l2size >> L1_S_SHIFT) + 1;
|
||||
|
||||
/*
|
||||
* Add one table for end of kernel map, one for stacks, msgbuf and
|
||||
* L1 and L2 tables map, one for vectors map and two for
|
||||
* l2 structures from pmap_bootstrap.
|
||||
*/
|
||||
l2size += 5;
|
||||
|
||||
/* Make it divisible by 4 */
|
||||
l2size = (l2size + 3) & ~3;
|
||||
|
||||
freemempos = (lastaddr + PAGE_MASK) & ~PAGE_MASK;
|
||||
|
||||
/* Define a macro to simplify memory allocation */
|
||||
#define valloc_pages(var, np) \
|
||||
alloc_pages((var).pv_va, (np)); \
|
||||
(var).pv_pa = (var).pv_va + (abp->abp_physaddr - KERNVIRTADDR);
|
||||
|
||||
#define alloc_pages(var, np) \
|
||||
(var) = freemempos; \
|
||||
freemempos += (np * PAGE_SIZE); \
|
||||
memset((char *)(var), 0, ((np) * PAGE_SIZE));
|
||||
|
||||
while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
|
||||
freemempos += PAGE_SIZE;
|
||||
valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
|
||||
|
||||
for (i = 0, j = 0; i < l2size; ++i) {
|
||||
if (!(i % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
|
||||
valloc_pages(kernel_pt_table[i],
|
||||
L2_TABLE_SIZE / PAGE_SIZE);
|
||||
j = i;
|
||||
} else {
|
||||
kernel_pt_table[i].pv_va = kernel_pt_table[j].pv_va +
|
||||
L2_TABLE_SIZE_REAL * (i - j);
|
||||
kernel_pt_table[i].pv_pa =
|
||||
kernel_pt_table[i].pv_va - KERNVIRTADDR +
|
||||
abp->abp_physaddr;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Allocate a page for the system page mapped to 0x00000000
|
||||
* or 0xffff0000. This page will just contain the system vectors
|
||||
* and can be shared by all processes.
|
||||
*/
|
||||
valloc_pages(systempage, 1);
|
||||
|
||||
/* Allocate dynamic per-cpu area. */
|
||||
valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
|
||||
dpcpu_init((void *)dpcpu.pv_va, 0);
|
||||
|
||||
/* Allocate stacks for all modes */
|
||||
valloc_pages(irqstack, IRQ_STACK_SIZE * MAXCPU);
|
||||
valloc_pages(abtstack, ABT_STACK_SIZE * MAXCPU);
|
||||
valloc_pages(undstack, UND_STACK_SIZE * MAXCPU);
|
||||
valloc_pages(kernelstack, kstack_pages);
|
||||
valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
|
||||
|
||||
/*
|
||||
* Now we start construction of the L1 page table
|
||||
* We start by mapping the L2 page tables into the L1.
|
||||
* This means that we can replace L1 mappings later on if necessary
|
||||
*/
|
||||
l1pagetable = kernel_l1pt.pv_va;
|
||||
|
||||
/*
|
||||
* Try to map as much as possible of kernel text and data using
|
||||
* 1MB section mapping and for the rest of initial kernel address
|
||||
* space use L2 coarse tables.
|
||||
*
|
||||
* Link L2 tables for mapping remainder of kernel (modulo 1MB)
|
||||
* and kernel structures
|
||||
*/
|
||||
l2_start = lastaddr & ~(L1_S_OFFSET);
|
||||
for (i = 0 ; i < l2size - 1; i++)
|
||||
pmap_link_l2pt(l1pagetable, l2_start + i * L1_S_SIZE,
|
||||
&kernel_pt_table[i]);
|
||||
|
||||
pmap_curmaxkvaddr = l2_start + (l2size - 1) * L1_S_SIZE;
|
||||
|
||||
/* Map kernel code and data */
|
||||
pmap_map_chunk(l1pagetable, KERNVIRTADDR, abp->abp_physaddr,
|
||||
(((uint32_t)(lastaddr) - KERNVIRTADDR) + PAGE_MASK) & ~PAGE_MASK,
|
||||
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
|
||||
|
||||
/* Map L1 directory and allocated L2 page tables */
|
||||
pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
|
||||
L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
|
||||
|
||||
pmap_map_chunk(l1pagetable, kernel_pt_table[0].pv_va,
|
||||
kernel_pt_table[0].pv_pa,
|
||||
L2_TABLE_SIZE_REAL * l2size,
|
||||
VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
|
||||
|
||||
/* Map allocated DPCPU, stacks and msgbuf */
|
||||
pmap_map_chunk(l1pagetable, dpcpu.pv_va, dpcpu.pv_pa,
|
||||
freemempos - dpcpu.pv_va,
|
||||
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
|
||||
|
||||
/* Link and map the vector page */
|
||||
pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH,
|
||||
&kernel_pt_table[l2size - 1]);
|
||||
pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
|
||||
VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE, PTE_CACHE);
|
||||
|
||||
/* Establish static device mappings. */
|
||||
err_devmap = platform_devmap_init();
|
||||
devmap_bootstrap(l1pagetable, NULL);
|
||||
vm_max_kernel_address = platform_lastaddr();
|
||||
|
||||
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) | DOMAIN_CLIENT);
|
||||
pmap_pa = kernel_l1pt.pv_pa;
|
||||
cpu_setttb(kernel_l1pt.pv_pa);
|
||||
cpu_tlb_flushID();
|
||||
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2));
|
||||
|
||||
/*
|
||||
* Now that proper page tables are installed, call cpu_setup() to enable
|
||||
* instruction and data caches and other chip-specific features.
|
||||
*/
|
||||
cpu_setup();
|
||||
|
||||
/*
|
||||
* Only after the SOC registers block is mapped we can perform device
|
||||
* tree fixups, as they may attempt to read parameters from hardware.
|
||||
*/
|
||||
OF_interpret("perform-fixup", 0);
|
||||
|
||||
platform_gpio_init();
|
||||
|
||||
cninit();
|
||||
|
||||
debugf("initarm: console initialized\n");
|
||||
debugf(" arg1 kmdp = 0x%08x\n", (uint32_t)kmdp);
|
||||
debugf(" boothowto = 0x%08x\n", boothowto);
|
||||
debugf(" dtbp = 0x%08x\n", (uint32_t)dtbp);
|
||||
arm_print_kenv();
|
||||
|
||||
/*
|
||||
* Dump the boot metadata. We have to wait for cninit() since console
|
||||
* output is required. If it's grossly incorrect the kernel will never
|
||||
* make it this far.
|
||||
*/
|
||||
if (getenv_is_true("debug.dump_modinfo_at_boot"))
|
||||
preload_dump();
|
||||
|
||||
env = kern_getenv("kernelname");
|
||||
if (env != NULL) {
|
||||
strlcpy(kernelname, env, sizeof(kernelname));
|
||||
freeenv(env);
|
||||
}
|
||||
|
||||
if (err_devmap != 0)
|
||||
printf("WARNING: could not fully configure devmap, error=%d\n",
|
||||
err_devmap);
|
||||
|
||||
platform_late_init();
|
||||
|
||||
/*
|
||||
* Pages were allocated during the secondary bootstrap for the
|
||||
* stacks for different CPU modes.
|
||||
* We must now set the r13 registers in the different CPU modes to
|
||||
* point to these stacks.
|
||||
* Since the ARM stacks use STMFD etc. we must set r13 to the top end
|
||||
* of the stack memory.
|
||||
*/
|
||||
cpu_control(CPU_CONTROL_MMU_ENABLE, CPU_CONTROL_MMU_ENABLE);
|
||||
|
||||
set_stackptrs(0);
|
||||
|
||||
/*
|
||||
* We must now clean the cache again....
|
||||
* Cleaning may be done by reading new data to displace any
|
||||
* dirty data in the cache. This will have happened in cpu_setttb()
|
||||
* but since we are boot strapping the addresses used for the read
|
||||
* may have just been remapped and thus the cache could be out
|
||||
* of sync. A re-clean after the switch will cure this.
|
||||
* After booting there are no gross relocations of the kernel thus
|
||||
* this problem will not occur after initarm().
|
||||
*/
|
||||
cpu_idcache_wbinv_all();
|
||||
|
||||
undefined_init();
|
||||
|
||||
init_proc0(kernelstack.pv_va);
|
||||
|
||||
arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
|
||||
pmap_bootstrap(freemempos, &kernel_l1pt);
|
||||
msgbufp = (void *)msgbufpv.pv_va;
|
||||
msgbufinit(msgbufp, msgbufsize);
|
||||
mutex_init();
|
||||
|
||||
/*
|
||||
* Exclude the kernel (and all the things we allocated which immediately
|
||||
* follow the kernel) from the VM allocation pool but not from crash
|
||||
* dumps. virtual_avail is a global variable which tracks the kva we've
|
||||
* "allocated" while setting up pmaps.
|
||||
*
|
||||
* Prepare the list of physical memory available to the vm subsystem.
|
||||
*/
|
||||
physmem_exclude_region(abp->abp_physaddr,
|
||||
(virtual_avail - KERNVIRTADDR), EXFLAG_NOALLOC);
|
||||
physmem_init_kernel_globals();
|
||||
|
||||
init_param2(physmem);
|
||||
dbg_monitor_init();
|
||||
arm_kdb_init();
|
||||
|
||||
return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
|
||||
sizeof(struct pcb)));
|
||||
}
|
||||
#else /* __ARM_ARCH < 6 */
|
||||
void *
|
||||
initarm(struct arm_boot_params *abp)
|
||||
{
|
||||
@@ -1303,6 +952,4 @@ initarm(struct arm_boot_params *abp)
|
||||
return ((void *)STACKALIGN(thread0.td_pcb));
|
||||
|
||||
}
|
||||
|
||||
#endif /* __ARM_ARCH < 6 */
|
||||
#endif /* FDT */
|
||||
|
||||
@@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/smp.h>
|
||||
|
||||
#ifdef INTRNG
|
||||
#include "pic_if.h"
|
||||
|
||||
#ifdef SMP
|
||||
@@ -66,7 +65,6 @@ struct intr_ipi {
|
||||
|
||||
static struct intr_ipi ipi_sources[INTR_IPI_COUNT];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* arm_irq_memory_barrier()
|
||||
@@ -131,7 +129,6 @@ arm_irq_memory_barrier(uintptr_t irq)
|
||||
cpu_l2cache_drain_writebuf();
|
||||
}
|
||||
|
||||
#ifdef INTRNG
|
||||
#ifdef SMP
|
||||
static inline struct intr_ipi *
|
||||
intr_ipi_lookup(u_int ipi)
|
||||
@@ -229,4 +226,3 @@ intr_pic_ipi_setup(u_int ipi, const char *name, intr_ipi_handler_t *hand,
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -43,8 +43,6 @@ __FBSDID("$FreeBSD$");
|
||||
#ifdef DDB
|
||||
#include <ddb/ddb.h>
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
|
||||
DB_SHOW_COMMAND(cp15, db_show_cp15)
|
||||
{
|
||||
u_int reg;
|
||||
@@ -90,7 +88,6 @@ DB_SHOW_COMMAND(vtop, db_show_vtop)
|
||||
} else
|
||||
db_printf("show vtop <virt_addr>\n");
|
||||
}
|
||||
#endif /* __ARM_ARCH >= 6 */
|
||||
#endif /* DDB */
|
||||
|
||||
int
|
||||
|
||||
@@ -118,9 +118,7 @@ memrw(struct cdev *dev, struct uio *uio, int flags)
|
||||
return (EINVAL);
|
||||
sx_xlock(&tmppt_lock);
|
||||
pmap_kenter((vm_offset_t)_tmppt, v);
|
||||
#if __ARM_ARCH >= 6
|
||||
pmap_tlb_flush(kernel_pmap, (vm_offset_t)_tmppt);
|
||||
#endif
|
||||
o = (int)uio->uio_offset & PAGE_MASK;
|
||||
c = (u_int)(PAGE_SIZE - ((int)iov->iov_base & PAGE_MASK));
|
||||
c = min(c, (u_int)(PAGE_SIZE - o));
|
||||
|
||||
@@ -229,11 +229,7 @@ minidumpsys(struct dumperinfo *di)
|
||||
mdhdr.ptesize = ptesize;
|
||||
mdhdr.kernbase = KERNBASE;
|
||||
mdhdr.arch = __ARM_ARCH;
|
||||
#if __ARM_ARCH >= 6
|
||||
mdhdr.mmuformat = MINIDUMP_MMU_FORMAT_V6;
|
||||
#else
|
||||
mdhdr.mmuformat = MINIDUMP_MMU_FORMAT_V4;
|
||||
#endif
|
||||
mdhdr.dumpavailsize = round_page(sizeof(dump_avail));
|
||||
dump_init_header(di, &kdh, KERNELDUMPMAGIC, KERNELDUMP_ARM_VERSION,
|
||||
dumpsize);
|
||||
|
||||
@@ -163,7 +163,7 @@ init_secondary(int cpu)
|
||||
|
||||
pcpu_init(pc, cpu, sizeof(struct pcpu));
|
||||
dpcpu_init(dpcpu[cpu - 1], cpu);
|
||||
#if __ARM_ARCH >= 6 && defined(DDB)
|
||||
#if defined(DDB)
|
||||
dbg_monitor_init_secondary();
|
||||
#endif
|
||||
/* Signal our startup to BSP */
|
||||
|
||||
@@ -90,17 +90,13 @@ static int nexus_activate_resource(device_t, device_t, int, int,
|
||||
struct resource *);
|
||||
static bus_space_tag_t nexus_get_bus_tag(device_t, device_t);
|
||||
static bus_dma_tag_t nexus_get_dma_tag(device_t dev, device_t child);
|
||||
#ifdef INTRNG
|
||||
#ifdef SMP
|
||||
static int nexus_bind_intr(device_t, device_t, struct resource *, int);
|
||||
#endif
|
||||
#endif
|
||||
static int nexus_config_intr(device_t dev, int irq, enum intr_trigger trig,
|
||||
enum intr_polarity pol);
|
||||
#ifdef INTRNG
|
||||
static int nexus_describe_intr(device_t dev, device_t child,
|
||||
struct resource *irq, void *cookie, const char *descr);
|
||||
#endif
|
||||
static int nexus_deactivate_resource(device_t, device_t, int, int,
|
||||
struct resource *);
|
||||
static int nexus_release_resource(device_t, device_t, int, int,
|
||||
@@ -138,12 +134,10 @@ static device_method_t nexus_methods[] = {
|
||||
DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
|
||||
DEVMETHOD(bus_get_bus_tag, nexus_get_bus_tag),
|
||||
DEVMETHOD(bus_get_dma_tag, nexus_get_dma_tag),
|
||||
#ifdef INTRNG
|
||||
DEVMETHOD(bus_describe_intr, nexus_describe_intr),
|
||||
#ifdef SMP
|
||||
DEVMETHOD(bus_bind_intr, nexus_bind_intr),
|
||||
#endif
|
||||
#endif
|
||||
#ifdef FDT
|
||||
DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr),
|
||||
#endif
|
||||
@@ -305,13 +299,8 @@ nexus_config_intr(device_t dev, int irq, enum intr_trigger trig,
|
||||
{
|
||||
int ret = ENODEV;
|
||||
|
||||
#ifdef INTRNG
|
||||
device_printf(dev, "bus_config_intr is obsolete and not supported!\n");
|
||||
ret = EOPNOTSUPP;
|
||||
#else
|
||||
if (arm_config_irq)
|
||||
ret = (*arm_config_irq)(irq, trig, pol);
|
||||
#endif
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@@ -319,37 +308,20 @@ static int
|
||||
nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
|
||||
driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep)
|
||||
{
|
||||
#ifndef INTRNG
|
||||
int irq;
|
||||
#endif
|
||||
|
||||
if ((rman_get_flags(res) & RF_SHAREABLE) == 0)
|
||||
flags |= INTR_EXCL;
|
||||
|
||||
#ifdef INTRNG
|
||||
return(intr_setup_irq(child, res, filt, intr, arg, flags, cookiep));
|
||||
#else
|
||||
for (irq = rman_get_start(res); irq <= rman_get_end(res); irq++) {
|
||||
arm_setup_irqhandler(device_get_nameunit(child),
|
||||
filt, intr, arg, irq, flags, cookiep);
|
||||
arm_unmask_irq(irq);
|
||||
}
|
||||
return (0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih)
|
||||
{
|
||||
|
||||
#ifdef INTRNG
|
||||
return (intr_teardown_irq(child, r, ih));
|
||||
#else
|
||||
return (arm_remove_irqhandler(rman_get_start(r), ih));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef INTRNG
|
||||
static int
|
||||
nexus_describe_intr(device_t dev, device_t child, struct resource *irq,
|
||||
void *cookie, const char *descr)
|
||||
@@ -366,7 +338,6 @@ nexus_bind_intr(device_t dev, device_t child, struct resource *irq, int cpu)
|
||||
return (intr_bind_irq(child, irq, cpu));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int
|
||||
nexus_activate_resource(device_t bus, device_t child, int type, int rid,
|
||||
@@ -406,13 +377,11 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid,
|
||||
rman_set_bushandle(r, vaddr);
|
||||
return (0);
|
||||
} else if (type == SYS_RES_IRQ) {
|
||||
#ifdef INTRNG
|
||||
err = intr_activate_irq(child, r);
|
||||
if (err != 0) {
|
||||
rman_deactivate_resource(r);
|
||||
return (err);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
@@ -438,9 +407,7 @@ nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
|
||||
rman_set_bushandle(r, 0);
|
||||
}
|
||||
} else if (type == SYS_RES_IRQ) {
|
||||
#ifdef INTRNG
|
||||
intr_deactivate_irq(child, r);
|
||||
#endif
|
||||
}
|
||||
|
||||
return (rman_deactivate_resource(r));
|
||||
@@ -451,9 +418,6 @@ static int
|
||||
nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells,
|
||||
pcell_t *intr)
|
||||
{
|
||||
#ifndef INTRNG
|
||||
return (intr_fdt_map_irq(iparent, intr, icells));
|
||||
#else
|
||||
u_int irq;
|
||||
struct intr_map_data_fdt *fdt_data;
|
||||
size_t len;
|
||||
@@ -466,6 +430,5 @@ nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells,
|
||||
memcpy(fdt_data->cells, intr, icells * sizeof(pcell_t));
|
||||
irq = intr_map_irq(NULL, iparent, (struct intr_map_data *)fdt_data);
|
||||
return (irq);
|
||||
#endif /* INTRNG */
|
||||
}
|
||||
#endif /* FDT */
|
||||
|
||||
+1
-452
@@ -69,7 +69,7 @@ do_sync(void)
|
||||
|
||||
__asm volatile ("" : : : "memory");
|
||||
}
|
||||
#elif __ARM_ARCH >= 6
|
||||
#else
|
||||
static inline void
|
||||
do_sync(void)
|
||||
{
|
||||
@@ -78,255 +78,6 @@ do_sync(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__CLANG_ATOMICS) || defined(__GNUC_ATOMICS)
|
||||
|
||||
/*
|
||||
* New C11 __atomic_* API.
|
||||
*/
|
||||
|
||||
/* ARMv6+ systems should be supported by the compiler. */
|
||||
#if __ARM_ARCH <= 5
|
||||
|
||||
/* Clang doesn't allow us to reimplement builtins without this. */
|
||||
#ifdef __clang__
|
||||
#pragma redefine_extname __sync_synchronize_ext __sync_synchronize
|
||||
#define __sync_synchronize __sync_synchronize_ext
|
||||
#endif
|
||||
|
||||
void
|
||||
__sync_synchronize(void)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#ifdef SMP
|
||||
#error "On SMP systems we should have proper atomic operations."
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On uniprocessor systems, we can perform the atomic operations by
|
||||
* disabling interrupts.
|
||||
*/
|
||||
|
||||
#define EMIT_LOAD_N(N, uintN_t) \
|
||||
uintN_t \
|
||||
__atomic_load_##N(uintN_t *mem, int model __unused) \
|
||||
{ \
|
||||
uintN_t ret; \
|
||||
\
|
||||
WITHOUT_INTERRUPTS({ \
|
||||
ret = *mem; \
|
||||
}); \
|
||||
return (ret); \
|
||||
}
|
||||
|
||||
#define EMIT_STORE_N(N, uintN_t) \
|
||||
void \
|
||||
__atomic_store_##N(uintN_t *mem, uintN_t val, int model __unused) \
|
||||
{ \
|
||||
\
|
||||
WITHOUT_INTERRUPTS({ \
|
||||
*mem = val; \
|
||||
}); \
|
||||
}
|
||||
|
||||
#define EMIT_COMPARE_EXCHANGE_N(N, uintN_t) \
|
||||
_Bool \
|
||||
__atomic_compare_exchange_##N(uintN_t *mem, uintN_t *expected, \
|
||||
uintN_t desired, int success __unused, int failure __unused) \
|
||||
{ \
|
||||
_Bool ret; \
|
||||
\
|
||||
WITHOUT_INTERRUPTS({ \
|
||||
if (*mem == *expected) { \
|
||||
*mem = desired; \
|
||||
ret = 1; \
|
||||
} else { \
|
||||
*expected = *mem; \
|
||||
ret = 0; \
|
||||
} \
|
||||
}); \
|
||||
return (ret); \
|
||||
}
|
||||
|
||||
#define EMIT_FETCH_OP_N(N, uintN_t, name, op) \
|
||||
uintN_t \
|
||||
__atomic_##name##_##N(uintN_t *mem, uintN_t val, int model __unused) \
|
||||
{ \
|
||||
uintN_t ret; \
|
||||
\
|
||||
WITHOUT_INTERRUPTS({ \
|
||||
ret = *mem; \
|
||||
*mem op val; \
|
||||
}); \
|
||||
return (ret); \
|
||||
}
|
||||
|
||||
#define EMIT_ALL_OPS_N(N, uintN_t) \
|
||||
EMIT_LOAD_N(N, uintN_t) \
|
||||
EMIT_STORE_N(N, uintN_t) \
|
||||
EMIT_COMPARE_EXCHANGE_N(N, uintN_t) \
|
||||
EMIT_FETCH_OP_N(N, uintN_t, exchange, =) \
|
||||
EMIT_FETCH_OP_N(N, uintN_t, fetch_add, +=) \
|
||||
EMIT_FETCH_OP_N(N, uintN_t, fetch_and, &=) \
|
||||
EMIT_FETCH_OP_N(N, uintN_t, fetch_or, |=) \
|
||||
EMIT_FETCH_OP_N(N, uintN_t, fetch_sub, -=) \
|
||||
EMIT_FETCH_OP_N(N, uintN_t, fetch_xor, ^=)
|
||||
|
||||
EMIT_ALL_OPS_N(1, uint8_t)
|
||||
EMIT_ALL_OPS_N(2, uint16_t)
|
||||
EMIT_ALL_OPS_N(4, uint32_t)
|
||||
EMIT_ALL_OPS_N(8, uint64_t)
|
||||
#undef EMIT_ALL_OPS_N
|
||||
|
||||
#else /* !_KERNEL */
|
||||
|
||||
/*
|
||||
* For userspace on uniprocessor systems, we can implement the atomic
|
||||
* operations by using a Restartable Atomic Sequence. This makes the
|
||||
* kernel restart the code from the beginning when interrupted.
|
||||
*/
|
||||
|
||||
#define EMIT_LOAD_N(N, uintN_t) \
|
||||
uintN_t \
|
||||
__atomic_load_##N(uintN_t *mem, int model __unused) \
|
||||
{ \
|
||||
\
|
||||
return (*mem); \
|
||||
}
|
||||
|
||||
#define EMIT_STORE_N(N, uintN_t) \
|
||||
void \
|
||||
__atomic_store_##N(uintN_t *mem, uintN_t val, int model __unused) \
|
||||
{ \
|
||||
\
|
||||
*mem = val; \
|
||||
}
|
||||
|
||||
#define EMIT_EXCHANGE_N(N, uintN_t, ldr, str) \
|
||||
uintN_t \
|
||||
__atomic_exchange_##N(uintN_t *mem, uintN_t val, int model __unused) \
|
||||
{ \
|
||||
uint32_t old, temp, ras_start; \
|
||||
\
|
||||
ras_start = ARM_RAS_START; \
|
||||
__asm volatile ( \
|
||||
/* Set up Restartable Atomic Sequence. */ \
|
||||
"1:" \
|
||||
"\tadr %2, 1b\n" \
|
||||
"\tstr %2, [%5]\n" \
|
||||
"\tadr %2, 2f\n" \
|
||||
"\tstr %2, [%5, #4]\n" \
|
||||
\
|
||||
"\t"ldr" %0, %4\n" /* Load old value. */ \
|
||||
"\t"str" %3, %1\n" /* Store new value. */ \
|
||||
\
|
||||
/* Tear down Restartable Atomic Sequence. */ \
|
||||
"2:" \
|
||||
"\tmov %2, #0x00000000\n" \
|
||||
"\tstr %2, [%5]\n" \
|
||||
"\tmov %2, #0xffffffff\n" \
|
||||
"\tstr %2, [%5, #4]\n" \
|
||||
: "=&r" (old), "=m" (*mem), "=&r" (temp) \
|
||||
: "r" (val), "m" (*mem), "r" (ras_start)); \
|
||||
return (old); \
|
||||
}
|
||||
|
||||
#define EMIT_COMPARE_EXCHANGE_N(N, uintN_t, ldr, streq) \
|
||||
_Bool \
|
||||
__atomic_compare_exchange_##N(uintN_t *mem, uintN_t *pexpected, \
|
||||
uintN_t desired, int success __unused, int failure __unused) \
|
||||
{ \
|
||||
uint32_t expected, old, temp, ras_start; \
|
||||
\
|
||||
expected = *pexpected; \
|
||||
ras_start = ARM_RAS_START; \
|
||||
__asm volatile ( \
|
||||
/* Set up Restartable Atomic Sequence. */ \
|
||||
"1:" \
|
||||
"\tadr %2, 1b\n" \
|
||||
"\tstr %2, [%6]\n" \
|
||||
"\tadr %2, 2f\n" \
|
||||
"\tstr %2, [%6, #4]\n" \
|
||||
\
|
||||
"\t"ldr" %0, %5\n" /* Load old value. */ \
|
||||
"\tcmp %0, %3\n" /* Compare to expected value. */\
|
||||
"\t"streq" %4, %1\n" /* Store new value. */ \
|
||||
\
|
||||
/* Tear down Restartable Atomic Sequence. */ \
|
||||
"2:" \
|
||||
"\tmov %2, #0x00000000\n" \
|
||||
"\tstr %2, [%6]\n" \
|
||||
"\tmov %2, #0xffffffff\n" \
|
||||
"\tstr %2, [%6, #4]\n" \
|
||||
: "=&r" (old), "=m" (*mem), "=&r" (temp) \
|
||||
: "r" (expected), "r" (desired), "m" (*mem), \
|
||||
"r" (ras_start)); \
|
||||
if (old == expected) { \
|
||||
return (1); \
|
||||
} else { \
|
||||
*pexpected = old; \
|
||||
return (0); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define EMIT_FETCH_OP_N(N, uintN_t, ldr, str, name, op, ret) \
|
||||
uintN_t \
|
||||
__atomic_##name##_##N(uintN_t *mem, uintN_t val, int model __unused) \
|
||||
{ \
|
||||
uint32_t old, new, ras_start; \
|
||||
\
|
||||
ras_start = ARM_RAS_START; \
|
||||
__asm volatile ( \
|
||||
/* Set up Restartable Atomic Sequence. */ \
|
||||
"1:" \
|
||||
"\tadr %2, 1b\n" \
|
||||
"\tstr %2, [%5]\n" \
|
||||
"\tadr %2, 2f\n" \
|
||||
"\tstr %2, [%5, #4]\n" \
|
||||
\
|
||||
"\t"ldr" %0, %4\n" /* Load old value. */ \
|
||||
"\t"op" %2, %0, %3\n" /* Calculate new value. */ \
|
||||
"\t"str" %2, %1\n" /* Store new value. */ \
|
||||
\
|
||||
/* Tear down Restartable Atomic Sequence. */ \
|
||||
"2:" \
|
||||
"\tmov %2, #0x00000000\n" \
|
||||
"\tstr %2, [%5]\n" \
|
||||
"\tmov %2, #0xffffffff\n" \
|
||||
"\tstr %2, [%5, #4]\n" \
|
||||
: "=&r" (old), "=m" (*mem), "=&r" (new) \
|
||||
: "r" (val), "m" (*mem), "r" (ras_start)); \
|
||||
return (ret); \
|
||||
}
|
||||
|
||||
#define EMIT_ALL_OPS_N(N, uintN_t, ldr, str, streq) \
|
||||
EMIT_LOAD_N(N, uintN_t) \
|
||||
EMIT_STORE_N(N, uintN_t) \
|
||||
EMIT_EXCHANGE_N(N, uintN_t, ldr, str) \
|
||||
EMIT_COMPARE_EXCHANGE_N(N, uintN_t, ldr, streq) \
|
||||
EMIT_FETCH_OP_N(N, uintN_t, ldr, str, fetch_add, "add", old) \
|
||||
EMIT_FETCH_OP_N(N, uintN_t, ldr, str, fetch_and, "and", old) \
|
||||
EMIT_FETCH_OP_N(N, uintN_t, ldr, str, fetch_or, "orr", old) \
|
||||
EMIT_FETCH_OP_N(N, uintN_t, ldr, str, fetch_sub, "sub", old) \
|
||||
EMIT_FETCH_OP_N(N, uintN_t, ldr, str, fetch_xor, "eor", old) \
|
||||
EMIT_FETCH_OP_N(N, uintN_t, ldr, str, add_fetch, "add", new) \
|
||||
EMIT_FETCH_OP_N(N, uintN_t, ldr, str, and_fetch, "and", new) \
|
||||
EMIT_FETCH_OP_N(N, uintN_t, ldr, str, or_fetch, "orr", new) \
|
||||
EMIT_FETCH_OP_N(N, uintN_t, ldr, str, sub_fetch, "sub", new) \
|
||||
EMIT_FETCH_OP_N(N, uintN_t, ldr, str, xor_fetch, "eor", new)
|
||||
|
||||
EMIT_ALL_OPS_N(1, uint8_t, "ldrb", "strb", "strbeq")
|
||||
EMIT_ALL_OPS_N(2, uint16_t, "ldrh", "strh", "strheq")
|
||||
EMIT_ALL_OPS_N(4, uint32_t, "ldr", "str", "streq")
|
||||
#undef EMIT_ALL_OPS_N
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* __ARM_ARCH */
|
||||
|
||||
#endif /* __CLANG_ATOMICS || __GNUC_ATOMICS */
|
||||
|
||||
#if defined(__SYNC_ATOMICS) || defined(EMIT_SYNC_ATOMICS)
|
||||
|
||||
@@ -358,7 +109,6 @@ EMIT_ALL_OPS_N(4, uint32_t, "ldr", "str", "streq")
|
||||
* Old __sync_* API.
|
||||
*/
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
|
||||
/* Implementations for old GCC versions, lacking support for atomics. */
|
||||
|
||||
@@ -676,205 +426,4 @@ __strong_reference(__sync_fetch_and_xor_2_c, __sync_fetch_and_xor_2);
|
||||
__strong_reference(__sync_fetch_and_xor_4_c, __sync_fetch_and_xor_4);
|
||||
#endif
|
||||
|
||||
#else /* __ARM_ARCH < 6 */
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#ifdef SMP
|
||||
#error "On SMP systems we should have proper atomic operations."
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On uniprocessor systems, we can perform the atomic operations by
|
||||
* disabling interrupts.
|
||||
*/
|
||||
|
||||
#define EMIT_VAL_COMPARE_AND_SWAP_N(N, uintN_t) \
|
||||
uintN_t \
|
||||
__sync_val_compare_and_swap_##N(uintN_t *mem, uintN_t expected, \
|
||||
uintN_t desired) \
|
||||
{ \
|
||||
uintN_t ret; \
|
||||
\
|
||||
WITHOUT_INTERRUPTS({ \
|
||||
ret = *mem; \
|
||||
if (*mem == expected) \
|
||||
*mem = desired; \
|
||||
}); \
|
||||
return (ret); \
|
||||
}
|
||||
|
||||
#define EMIT_FETCH_AND_OP_N(N, uintN_t, name, op) \
|
||||
uintN_t \
|
||||
__sync_##name##_##N(uintN_t *mem, uintN_t val) \
|
||||
{ \
|
||||
uintN_t ret; \
|
||||
\
|
||||
WITHOUT_INTERRUPTS({ \
|
||||
ret = *mem; \
|
||||
*mem op val; \
|
||||
}); \
|
||||
return (ret); \
|
||||
}
|
||||
|
||||
#define EMIT_ALL_OPS_N(N, uintN_t) \
|
||||
EMIT_VAL_COMPARE_AND_SWAP_N(N, uintN_t) \
|
||||
EMIT_FETCH_AND_OP_N(N, uintN_t, lock_test_and_set, =) \
|
||||
EMIT_FETCH_AND_OP_N(N, uintN_t, fetch_and_add, +=) \
|
||||
EMIT_FETCH_AND_OP_N(N, uintN_t, fetch_and_and, &=) \
|
||||
EMIT_FETCH_AND_OP_N(N, uintN_t, fetch_and_or, |=) \
|
||||
EMIT_FETCH_AND_OP_N(N, uintN_t, fetch_and_sub, -=) \
|
||||
EMIT_FETCH_AND_OP_N(N, uintN_t, fetch_and_xor, ^=)
|
||||
|
||||
EMIT_ALL_OPS_N(1, uint8_t)
|
||||
EMIT_ALL_OPS_N(2, uint16_t)
|
||||
EMIT_ALL_OPS_N(4, uint32_t)
|
||||
EMIT_ALL_OPS_N(8, uint64_t)
|
||||
#undef EMIT_ALL_OPS_N
|
||||
|
||||
#else /* !_KERNEL */
|
||||
|
||||
/*
|
||||
* For userspace on uniprocessor systems, we can implement the atomic
|
||||
* operations by using a Restartable Atomic Sequence. This makes the
|
||||
* kernel restart the code from the beginning when interrupted.
|
||||
*/
|
||||
|
||||
#define EMIT_LOCK_TEST_AND_SET_N(N, uintN_t, ldr, str) \
|
||||
uintN_t \
|
||||
__sync_lock_test_and_set_##N##_c(uintN_t *mem, uintN_t val) \
|
||||
{ \
|
||||
uint32_t old, temp, ras_start; \
|
||||
\
|
||||
ras_start = ARM_RAS_START; \
|
||||
__asm volatile ( \
|
||||
/* Set up Restartable Atomic Sequence. */ \
|
||||
"1:" \
|
||||
"\tadr %2, 1b\n" \
|
||||
"\tstr %2, [%5]\n" \
|
||||
"\tadr %2, 2f\n" \
|
||||
"\tstr %2, [%5, #4]\n" \
|
||||
\
|
||||
"\t"ldr" %0, %4\n" /* Load old value. */ \
|
||||
"\t"str" %3, %1\n" /* Store new value. */ \
|
||||
\
|
||||
/* Tear down Restartable Atomic Sequence. */ \
|
||||
"2:" \
|
||||
"\tmov %2, #0x00000000\n" \
|
||||
"\tstr %2, [%5]\n" \
|
||||
"\tmov %2, #0xffffffff\n" \
|
||||
"\tstr %2, [%5, #4]\n" \
|
||||
: "=&r" (old), "=m" (*mem), "=&r" (temp) \
|
||||
: "r" (val), "m" (*mem), "r" (ras_start)); \
|
||||
return (old); \
|
||||
}
|
||||
|
||||
#define EMIT_VAL_COMPARE_AND_SWAP_N(N, uintN_t, ldr, streq) \
|
||||
uintN_t \
|
||||
__sync_val_compare_and_swap_##N##_c(uintN_t *mem, uintN_t expected, \
|
||||
uintN_t desired) \
|
||||
{ \
|
||||
uint32_t old, temp, ras_start; \
|
||||
\
|
||||
ras_start = ARM_RAS_START; \
|
||||
__asm volatile ( \
|
||||
/* Set up Restartable Atomic Sequence. */ \
|
||||
"1:" \
|
||||
"\tadr %2, 1b\n" \
|
||||
"\tstr %2, [%6]\n" \
|
||||
"\tadr %2, 2f\n" \
|
||||
"\tstr %2, [%6, #4]\n" \
|
||||
\
|
||||
"\t"ldr" %0, %5\n" /* Load old value. */ \
|
||||
"\tcmp %0, %3\n" /* Compare to expected value. */\
|
||||
"\t"streq" %4, %1\n" /* Store new value. */ \
|
||||
\
|
||||
/* Tear down Restartable Atomic Sequence. */ \
|
||||
"2:" \
|
||||
"\tmov %2, #0x00000000\n" \
|
||||
"\tstr %2, [%6]\n" \
|
||||
"\tmov %2, #0xffffffff\n" \
|
||||
"\tstr %2, [%6, #4]\n" \
|
||||
: "=&r" (old), "=m" (*mem), "=&r" (temp) \
|
||||
: "r" (expected), "r" (desired), "m" (*mem), \
|
||||
"r" (ras_start)); \
|
||||
return (old); \
|
||||
}
|
||||
|
||||
#define EMIT_FETCH_AND_OP_N(N, uintN_t, ldr, str, name, op) \
|
||||
uintN_t \
|
||||
__sync_##name##_##N##_c(uintN_t *mem, uintN_t val) \
|
||||
{ \
|
||||
uint32_t old, temp, ras_start; \
|
||||
\
|
||||
ras_start = ARM_RAS_START; \
|
||||
__asm volatile ( \
|
||||
/* Set up Restartable Atomic Sequence. */ \
|
||||
"1:" \
|
||||
"\tadr %2, 1b\n" \
|
||||
"\tstr %2, [%5]\n" \
|
||||
"\tadr %2, 2f\n" \
|
||||
"\tstr %2, [%5, #4]\n" \
|
||||
\
|
||||
"\t"ldr" %0, %4\n" /* Load old value. */ \
|
||||
"\t"op" %2, %0, %3\n" /* Calculate new value. */ \
|
||||
"\t"str" %2, %1\n" /* Store new value. */ \
|
||||
\
|
||||
/* Tear down Restartable Atomic Sequence. */ \
|
||||
"2:" \
|
||||
"\tmov %2, #0x00000000\n" \
|
||||
"\tstr %2, [%5]\n" \
|
||||
"\tmov %2, #0xffffffff\n" \
|
||||
"\tstr %2, [%5, #4]\n" \
|
||||
: "=&r" (old), "=m" (*mem), "=&r" (temp) \
|
||||
: "r" (val), "m" (*mem), "r" (ras_start)); \
|
||||
return (old); \
|
||||
}
|
||||
|
||||
#define EMIT_ALL_OPS_N(N, uintN_t, ldr, str, streq) \
|
||||
EMIT_LOCK_TEST_AND_SET_N(N, uintN_t, ldr, str) \
|
||||
EMIT_VAL_COMPARE_AND_SWAP_N(N, uintN_t, ldr, streq) \
|
||||
EMIT_FETCH_AND_OP_N(N, uintN_t, ldr, str, fetch_and_add, "add") \
|
||||
EMIT_FETCH_AND_OP_N(N, uintN_t, ldr, str, fetch_and_and, "and") \
|
||||
EMIT_FETCH_AND_OP_N(N, uintN_t, ldr, str, fetch_and_or, "orr") \
|
||||
EMIT_FETCH_AND_OP_N(N, uintN_t, ldr, str, fetch_and_sub, "sub") \
|
||||
EMIT_FETCH_AND_OP_N(N, uintN_t, ldr, str, fetch_and_xor, "eor")
|
||||
|
||||
#ifdef __clang__
|
||||
EMIT_ALL_OPS_N(1, uint8_t, "ldrb", "strb", "strbeq")
|
||||
EMIT_ALL_OPS_N(2, uint16_t, "ldrh", "strh", "strheq")
|
||||
#else
|
||||
EMIT_ALL_OPS_N(1, uint8_t, "ldrb", "strb", "streqb")
|
||||
EMIT_ALL_OPS_N(2, uint16_t, "ldrh", "strh", "streqh")
|
||||
#endif
|
||||
EMIT_ALL_OPS_N(4, uint32_t, "ldr", "str", "streq")
|
||||
|
||||
#ifndef __clang__
|
||||
__strong_reference(__sync_lock_test_and_set_1_c, __sync_lock_test_and_set_1);
|
||||
__strong_reference(__sync_lock_test_and_set_2_c, __sync_lock_test_and_set_2);
|
||||
__strong_reference(__sync_lock_test_and_set_4_c, __sync_lock_test_and_set_4);
|
||||
__strong_reference(__sync_val_compare_and_swap_1_c, __sync_val_compare_and_swap_1);
|
||||
__strong_reference(__sync_val_compare_and_swap_2_c, __sync_val_compare_and_swap_2);
|
||||
__strong_reference(__sync_val_compare_and_swap_4_c, __sync_val_compare_and_swap_4);
|
||||
__strong_reference(__sync_fetch_and_add_1_c, __sync_fetch_and_add_1);
|
||||
__strong_reference(__sync_fetch_and_add_2_c, __sync_fetch_and_add_2);
|
||||
__strong_reference(__sync_fetch_and_add_4_c, __sync_fetch_and_add_4);
|
||||
__strong_reference(__sync_fetch_and_and_1_c, __sync_fetch_and_and_1);
|
||||
__strong_reference(__sync_fetch_and_and_2_c, __sync_fetch_and_and_2);
|
||||
__strong_reference(__sync_fetch_and_and_4_c, __sync_fetch_and_and_4);
|
||||
__strong_reference(__sync_fetch_and_sub_1_c, __sync_fetch_and_sub_1);
|
||||
__strong_reference(__sync_fetch_and_sub_2_c, __sync_fetch_and_sub_2);
|
||||
__strong_reference(__sync_fetch_and_sub_4_c, __sync_fetch_and_sub_4);
|
||||
__strong_reference(__sync_fetch_and_or_1_c, __sync_fetch_and_or_1);
|
||||
__strong_reference(__sync_fetch_and_or_2_c, __sync_fetch_and_or_2);
|
||||
__strong_reference(__sync_fetch_and_or_4_c, __sync_fetch_and_or_4);
|
||||
__strong_reference(__sync_fetch_and_xor_1_c, __sync_fetch_and_xor_1);
|
||||
__strong_reference(__sync_fetch_and_xor_2_c, __sync_fetch_and_xor_2);
|
||||
__strong_reference(__sync_fetch_and_xor_4_c, __sync_fetch_and_xor_4);
|
||||
#endif /* __ARM_ARCH */
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __SYNC_ATOMICS */
|
||||
|
||||
@@ -62,7 +62,6 @@ struct sysarch_args {
|
||||
static int arm32_sync_icache (struct thread *, void *);
|
||||
static int arm32_drain_writebuf(struct thread *, void *);
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
static int
|
||||
sync_icache(uintptr_t addr, size_t len)
|
||||
{
|
||||
@@ -98,7 +97,6 @@ sync_icache(uintptr_t addr, size_t len)
|
||||
bpb_inv_all();
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
arm32_sync_icache(struct thread *td, void *args)
|
||||
@@ -106,9 +104,7 @@ arm32_sync_icache(struct thread *td, void *args)
|
||||
struct arm_sync_icache_args ua;
|
||||
int error;
|
||||
ksiginfo_t ksi;
|
||||
#if __ARM_ARCH >= 6
|
||||
vm_offset_t rv;
|
||||
#endif
|
||||
|
||||
if ((error = copyin(args, &ua, sizeof(ua))) != 0)
|
||||
return (error);
|
||||
@@ -132,7 +128,6 @@ arm32_sync_icache(struct thread *td, void *args)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
rv = sync_icache(ua.addr, ua.len);
|
||||
if (rv != 1) {
|
||||
ksiginfo_init_trap(&ksi);
|
||||
@@ -142,9 +137,6 @@ arm32_sync_icache(struct thread *td, void *args)
|
||||
trapsignal(td, &ksi);
|
||||
return (EINVAL);
|
||||
}
|
||||
#else
|
||||
cpu_icache_sync_range(ua.addr, ua.len);
|
||||
#endif
|
||||
|
||||
td->td_retval[0] = 0;
|
||||
return (0);
|
||||
@@ -155,12 +147,8 @@ arm32_drain_writebuf(struct thread *td, void *args)
|
||||
{
|
||||
/* No args. */
|
||||
|
||||
#if __ARM_ARCH < 6
|
||||
cpu_drain_writebuf();
|
||||
#else
|
||||
dsb();
|
||||
cpu_l2cache_drain_writebuf();
|
||||
#endif
|
||||
td->td_retval[0] = 0;
|
||||
return (0);
|
||||
}
|
||||
@@ -169,12 +157,7 @@ static int
|
||||
arm32_set_tp(struct thread *td, void *args)
|
||||
{
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
set_tls(args);
|
||||
#else
|
||||
td->td_md.md_tp = (register_t)args;
|
||||
*(register_t *)ARM_TP_ADDRESS = (register_t)args;
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -182,11 +165,7 @@ static int
|
||||
arm32_get_tp(struct thread *td, void *args)
|
||||
{
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
td->td_retval[0] = (register_t)get_tls();
|
||||
#else
|
||||
td->td_retval[0] = *(register_t *)ARM_TP_ADDRESS;
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@@ -136,9 +136,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
|
||||
pcb2->pcb_regs.sf_r5 = (register_t)td2;
|
||||
pcb2->pcb_regs.sf_lr = (register_t)fork_trampoline;
|
||||
pcb2->pcb_regs.sf_sp = STACKALIGN(td2->td_frame);
|
||||
#if __ARM_ARCH >= 6
|
||||
pcb2->pcb_regs.sf_tpidrurw = (register_t)get_tls();
|
||||
#endif
|
||||
|
||||
pcb2->pcb_vfpcpu = -1;
|
||||
pcb2->pcb_vfpstate.fpscr = initial_fpscr;
|
||||
@@ -151,9 +149,6 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
|
||||
/* Setup to release spin count in fork_exit(). */
|
||||
td2->td_md.md_spinlock_count = 1;
|
||||
td2->td_md.md_saved_cspr = PSR_SVC32_MODE;
|
||||
#if __ARM_ARCH < 6
|
||||
td2->td_md.md_tp = *(register_t *)ARM_TP_ADDRESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -272,18 +267,9 @@ int
|
||||
cpu_set_user_tls(struct thread *td, void *tls_base)
|
||||
{
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
td->td_pcb->pcb_regs.sf_tpidrurw = (register_t)tls_base;
|
||||
if (td == curthread)
|
||||
set_tls(tls_base);
|
||||
#else
|
||||
td->td_md.md_tp = (register_t)tls_base;
|
||||
if (td == curthread) {
|
||||
critical_enter();
|
||||
*(register_t *)ARM_TP_ADDRESS = (register_t)tls_base;
|
||||
critical_exit();
|
||||
}
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
# Init
|
||||
arm/freescale/imx/imx_common.c standard
|
||||
arm/freescale/imx/imx_machdep.c standard
|
||||
arm/freescale/imx/imx51_machdep.c optional soc_imx51
|
||||
arm/freescale/imx/imx53_machdep.c optional soc_imx53
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (C) 2008-2011 MARVELL INTERNATIONAL LTD.
|
||||
* Copyright (c) 2012, 2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by Semihalf.
|
||||
*
|
||||
* Portions of this software were developed by Oleksandr Rybalko
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of MARVELL nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <dev/fdt/fdt_common.h>
|
||||
#include <dev/ofw/openfirm.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/vmparam.h>
|
||||
|
||||
#ifndef INTRNG
|
||||
static int
|
||||
fdt_intc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
|
||||
int *pol)
|
||||
{
|
||||
|
||||
*interrupt = fdt32_to_cpu(intr[0]);
|
||||
*trig = INTR_TRIGGER_CONFORM;
|
||||
*pol = INTR_POLARITY_CONFORM;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
fdt_pic_decode_t fdt_pic_table[] = {
|
||||
&fdt_intc_decode_ic,
|
||||
NULL
|
||||
};
|
||||
#endif /* INTRNG */
|
||||
@@ -48,11 +48,7 @@
|
||||
* is sufficient for any data type, pointer or numeric. The resulting type
|
||||
* is equivelent to arm's uintptr_t (but is purposely spelled "unsigned" here).
|
||||
*/
|
||||
#if __ARM_ARCH >= 6
|
||||
#define _ALIGNBYTES (sizeof(int) - 1)
|
||||
#else
|
||||
#define _ALIGNBYTES (sizeof(long long) - 1)
|
||||
#endif
|
||||
#define _ALIGN(p) (((unsigned)(p) + _ALIGNBYTES) & ~_ALIGNBYTES)
|
||||
|
||||
#endif /* !_ARM_INCLUDE__ALIGN_H_ */
|
||||
|
||||
@@ -390,32 +390,6 @@
|
||||
/* Fault status register definitions */
|
||||
#define FAULT_USER 0x10
|
||||
|
||||
#if __ARM_ARCH < 6
|
||||
#define FAULT_TYPE_MASK 0x0f
|
||||
#define FAULT_WRTBUF_0 0x00 /* Vector Exception */
|
||||
#define FAULT_WRTBUF_1 0x02 /* Terminal Exception */
|
||||
#define FAULT_BUSERR_0 0x04 /* External Abort on Linefetch -- Section */
|
||||
#define FAULT_BUSERR_1 0x06 /* External Abort on Linefetch -- Page */
|
||||
#define FAULT_BUSERR_2 0x08 /* External Abort on Non-linefetch -- Section */
|
||||
#define FAULT_BUSERR_3 0x0a /* External Abort on Non-linefetch -- Page */
|
||||
#define FAULT_BUSTRNL1 0x0c /* External abort on Translation -- Level 1 */
|
||||
#define FAULT_BUSTRNL2 0x0e /* External abort on Translation -- Level 2 */
|
||||
#define FAULT_ALIGN_0 0x01 /* Alignment */
|
||||
#define FAULT_ALIGN_1 0x03 /* Alignment */
|
||||
#define FAULT_TRANS_S 0x05 /* Translation -- Section */
|
||||
#define FAULT_TRANS_F 0x06 /* Translation -- Flag */
|
||||
#define FAULT_TRANS_P 0x07 /* Translation -- Page */
|
||||
#define FAULT_DOMAIN_S 0x09 /* Domain -- Section */
|
||||
#define FAULT_DOMAIN_P 0x0b /* Domain -- Page */
|
||||
#define FAULT_PERM_S 0x0d /* Permission -- Section */
|
||||
#define FAULT_PERM_P 0x0f /* Permission -- Page */
|
||||
|
||||
#define FAULT_IMPRECISE 0x400 /* Imprecise exception (XSCALE) */
|
||||
#define FAULT_EXTERNAL 0x400 /* External abort (armv6+) */
|
||||
#define FAULT_WNR 0x800 /* Write-not-Read access (armv6+) */
|
||||
|
||||
#else /* __ARM_ARCH < 6 */
|
||||
|
||||
#define FAULT_ALIGN 0x001 /* Alignment Fault */
|
||||
#define FAULT_DEBUG 0x002 /* Debug Event */
|
||||
#define FAULT_ACCESS_L1 0x003 /* Access Bit (L1) */
|
||||
@@ -443,7 +417,6 @@
|
||||
#define FSR_WNR (1 << 11) /* Write-not-Read access */
|
||||
#define FSR_EXT (1 << 12) /* DECERR/SLVERR for external*/
|
||||
#define FSR_CM (1 << 13) /* Cache maintenance fault */
|
||||
#endif /* !__ARM_ARCH < 6 */
|
||||
|
||||
/*
|
||||
* Address of the vector page, low and high versions.
|
||||
|
||||
@@ -37,14 +37,8 @@
|
||||
|
||||
#ifdef LOCORE
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
#define GET_CURTHREAD_PTR(tmp) \
|
||||
mrc p15, 0, tmp, c13, c0, 4
|
||||
#else
|
||||
#define GET_CURTHREAD_PTR(tmp) \
|
||||
ldr tmp, =_C_LABEL(__pcpu);\
|
||||
ldr tmp, [tmp, #PC_CURTHREAD]
|
||||
#endif
|
||||
|
||||
#define ELFNOTE(section, type, vendor, desctype, descdata...) \
|
||||
.pushsection section ; \
|
||||
|
||||
@@ -47,12 +47,10 @@
|
||||
#define isb() __asm __volatile("isb" : : : "memory")
|
||||
#define dsb() __asm __volatile("dsb" : : : "memory")
|
||||
#define dmb() __asm __volatile("dmb" : : : "memory")
|
||||
#elif __ARM_ARCH >= 6
|
||||
#else
|
||||
#define isb() __asm __volatile("mcr p15, 0, %0, c7, c5, 4" : : "r" (0) : "memory")
|
||||
#define dsb() __asm __volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0) : "memory")
|
||||
#define dmb() __asm __volatile("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory")
|
||||
#else
|
||||
#error Only use this file with ARMv6 and later
|
||||
#endif
|
||||
|
||||
#define mb() dmb()
|
||||
|
||||
@@ -254,10 +254,6 @@ struct bus_space {
|
||||
bus_size_t, const uint64_t *, bus_size_t);
|
||||
};
|
||||
|
||||
#if __ARM_ARCH < 6
|
||||
extern bus_space_tag_t arm_base_bs_tag;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Utility macros; INTERNAL USE ONLY.
|
||||
*/
|
||||
|
||||
@@ -75,28 +75,4 @@
|
||||
|
||||
#define BUS_DMA_TAG_VALID(t) ((t) != (bus_dma_tag_t)0)
|
||||
|
||||
#if defined(_ARM32_BUS_DMA_PRIVATE) && __ARM_ARCH < 6
|
||||
/*
|
||||
* arm32_dma_range
|
||||
*
|
||||
* This structure describes a valid DMA range.
|
||||
*/
|
||||
struct arm32_dma_range {
|
||||
bus_addr_t dr_sysbase; /* system base address */
|
||||
bus_addr_t dr_busbase; /* appears here on bus */
|
||||
bus_size_t dr_len; /* length of range */
|
||||
};
|
||||
|
||||
/* _dm_buftype */
|
||||
#define ARM32_BUFTYPE_INVALID 0
|
||||
#define ARM32_BUFTYPE_LINEAR 1
|
||||
#define ARM32_BUFTYPE_MBUF 2
|
||||
#define ARM32_BUFTYPE_UIO 3
|
||||
#define ARM32_BUFTYPE_RAW 4
|
||||
|
||||
struct arm32_dma_range *bus_dma_get_range(void);
|
||||
int bus_dma_get_range_nb(void);
|
||||
|
||||
#endif /* _ARM32_BUS_DMA_PRIVATE */
|
||||
|
||||
#endif /* _ARM_BUS_DMA_H */
|
||||
|
||||
@@ -39,10 +39,6 @@
|
||||
#include <machine/cpuinfo.h>
|
||||
#include <machine/sysreg.h>
|
||||
|
||||
#if __ARM_ARCH < 6
|
||||
#error Only include this file for ARMv6
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Some kernel modules (dtrace all for example) are compiled
|
||||
* unconditionally with -DSMP. Although it looks like a bug,
|
||||
|
||||
@@ -59,87 +59,6 @@ breakpoint(void)
|
||||
|
||||
struct cpu_functions {
|
||||
/* CPU functions */
|
||||
#if __ARM_ARCH < 6
|
||||
void (*cf_cpwait) (void);
|
||||
|
||||
/* MMU functions */
|
||||
|
||||
u_int (*cf_control) (u_int bic, u_int eor);
|
||||
void (*cf_setttb) (u_int ttb);
|
||||
|
||||
/* TLB functions */
|
||||
|
||||
void (*cf_tlb_flushID) (void);
|
||||
void (*cf_tlb_flushID_SE) (u_int va);
|
||||
void (*cf_tlb_flushD) (void);
|
||||
void (*cf_tlb_flushD_SE) (u_int va);
|
||||
|
||||
/*
|
||||
* Cache operations:
|
||||
*
|
||||
* We define the following primitives:
|
||||
*
|
||||
* icache_sync_range Synchronize I-cache range
|
||||
*
|
||||
* dcache_wbinv_all Write-back and Invalidate D-cache
|
||||
* dcache_wbinv_range Write-back and Invalidate D-cache range
|
||||
* dcache_inv_range Invalidate D-cache range
|
||||
* dcache_wb_range Write-back D-cache range
|
||||
*
|
||||
* idcache_wbinv_all Write-back and Invalidate D-cache,
|
||||
* Invalidate I-cache
|
||||
* idcache_wbinv_range Write-back and Invalidate D-cache,
|
||||
* Invalidate I-cache range
|
||||
*
|
||||
* Note that the ARM term for "write-back" is "clean". We use
|
||||
* the term "write-back" since it's a more common way to describe
|
||||
* the operation.
|
||||
*
|
||||
* There are some rules that must be followed:
|
||||
*
|
||||
* ID-cache Invalidate All:
|
||||
* Unlike other functions, this one must never write back.
|
||||
* It is used to intialize the MMU when it is in an unknown
|
||||
* state (such as when it may have lines tagged as valid
|
||||
* that belong to a previous set of mappings).
|
||||
*
|
||||
* I-cache Sync range:
|
||||
* The goal is to synchronize the instruction stream,
|
||||
* so you may beed to write-back dirty D-cache blocks
|
||||
* first. If a range is requested, and you can't
|
||||
* synchronize just a range, you have to hit the whole
|
||||
* thing.
|
||||
*
|
||||
* D-cache Write-Back and Invalidate range:
|
||||
* If you can't WB-Inv a range, you must WB-Inv the
|
||||
* entire D-cache.
|
||||
*
|
||||
* D-cache Invalidate:
|
||||
* If you can't Inv the D-cache, you must Write-Back
|
||||
* and Invalidate. Code that uses this operation
|
||||
* MUST NOT assume that the D-cache will not be written
|
||||
* back to memory.
|
||||
*
|
||||
* D-cache Write-Back:
|
||||
* If you can't Write-back without doing an Inv,
|
||||
* that's fine. Then treat this as a WB-Inv.
|
||||
* Skipping the invalidate is merely an optimization.
|
||||
*
|
||||
* All operations:
|
||||
* Valid virtual addresses must be passed to each
|
||||
* cache operation.
|
||||
*/
|
||||
void (*cf_icache_sync_range) (vm_offset_t, vm_size_t);
|
||||
|
||||
void (*cf_dcache_wbinv_all) (void);
|
||||
void (*cf_dcache_wbinv_range) (vm_offset_t, vm_size_t);
|
||||
void (*cf_dcache_inv_range) (vm_offset_t, vm_size_t);
|
||||
void (*cf_dcache_wb_range) (vm_offset_t, vm_size_t);
|
||||
|
||||
void (*cf_idcache_inv_all) (void);
|
||||
void (*cf_idcache_wbinv_all) (void);
|
||||
void (*cf_idcache_wbinv_range) (vm_offset_t, vm_size_t);
|
||||
#endif
|
||||
void (*cf_l2cache_wbinv_all) (void);
|
||||
void (*cf_l2cache_wbinv_range) (vm_offset_t, vm_size_t);
|
||||
void (*cf_l2cache_inv_range) (vm_offset_t, vm_size_t);
|
||||
@@ -148,56 +67,20 @@ struct cpu_functions {
|
||||
|
||||
/* Other functions */
|
||||
|
||||
#if __ARM_ARCH < 6
|
||||
void (*cf_drain_writebuf) (void);
|
||||
#endif
|
||||
|
||||
void (*cf_sleep) (int mode);
|
||||
|
||||
#if __ARM_ARCH < 6
|
||||
/* Soft functions */
|
||||
|
||||
void (*cf_context_switch) (void);
|
||||
#endif
|
||||
|
||||
void (*cf_setup) (void);
|
||||
};
|
||||
|
||||
extern struct cpu_functions cpufuncs;
|
||||
extern u_int cputype;
|
||||
|
||||
#if __ARM_ARCH < 6
|
||||
#define cpu_cpwait() cpufuncs.cf_cpwait()
|
||||
|
||||
#define cpu_control(c, e) cpufuncs.cf_control(c, e)
|
||||
#define cpu_setttb(t) cpufuncs.cf_setttb(t)
|
||||
|
||||
#define cpu_tlb_flushID() cpufuncs.cf_tlb_flushID()
|
||||
#define cpu_tlb_flushID_SE(e) cpufuncs.cf_tlb_flushID_SE(e)
|
||||
#define cpu_tlb_flushD() cpufuncs.cf_tlb_flushD()
|
||||
#define cpu_tlb_flushD_SE(e) cpufuncs.cf_tlb_flushD_SE(e)
|
||||
|
||||
#define cpu_icache_sync_range(a, s) cpufuncs.cf_icache_sync_range((a), (s))
|
||||
|
||||
#define cpu_dcache_wbinv_all() cpufuncs.cf_dcache_wbinv_all()
|
||||
#define cpu_dcache_wbinv_range(a, s) cpufuncs.cf_dcache_wbinv_range((a), (s))
|
||||
#define cpu_dcache_inv_range(a, s) cpufuncs.cf_dcache_inv_range((a), (s))
|
||||
#define cpu_dcache_wb_range(a, s) cpufuncs.cf_dcache_wb_range((a), (s))
|
||||
|
||||
#define cpu_idcache_inv_all() cpufuncs.cf_idcache_inv_all()
|
||||
#define cpu_idcache_wbinv_all() cpufuncs.cf_idcache_wbinv_all()
|
||||
#define cpu_idcache_wbinv_range(a, s) cpufuncs.cf_idcache_wbinv_range((a), (s))
|
||||
#endif
|
||||
|
||||
#define cpu_l2cache_wbinv_all() cpufuncs.cf_l2cache_wbinv_all()
|
||||
#define cpu_l2cache_wb_range(a, s) cpufuncs.cf_l2cache_wb_range((a), (s))
|
||||
#define cpu_l2cache_inv_range(a, s) cpufuncs.cf_l2cache_inv_range((a), (s))
|
||||
#define cpu_l2cache_wbinv_range(a, s) cpufuncs.cf_l2cache_wbinv_range((a), (s))
|
||||
#define cpu_l2cache_drain_writebuf() cpufuncs.cf_l2cache_drain_writebuf()
|
||||
|
||||
#if __ARM_ARCH < 6
|
||||
#define cpu_drain_writebuf() cpufuncs.cf_drain_writebuf()
|
||||
#endif
|
||||
#define cpu_sleep(m) cpufuncs.cf_sleep(m)
|
||||
|
||||
#define cpu_setup() cpufuncs.cf_setup()
|
||||
@@ -263,11 +146,7 @@ void armv4_idcache_inv_all (void);
|
||||
/*
|
||||
* Macros for manipulating CPU interrupts
|
||||
*/
|
||||
#if __ARM_ARCH < 6
|
||||
#define __ARM_INTR_BITS (PSR_I | PSR_F)
|
||||
#else
|
||||
#define __ARM_INTR_BITS (PSR_I | PSR_F | PSR_A)
|
||||
#endif
|
||||
|
||||
static __inline uint32_t
|
||||
__set_cpsr(uint32_t bic, uint32_t eor)
|
||||
@@ -358,7 +237,6 @@ extern u_int arm_cache_level;
|
||||
extern u_int arm_cache_loc;
|
||||
extern u_int arm_cache_type[14];
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
#define HAVE_INLINE_FFS
|
||||
|
||||
static __inline __pure2 int
|
||||
@@ -415,7 +293,6 @@ flsll(long long mask)
|
||||
return (mask == 0 ? 0 :
|
||||
8 * sizeof(mask) - __builtin_clzll((unsigned long long)mask));
|
||||
}
|
||||
#endif
|
||||
#else /* !_KERNEL */
|
||||
|
||||
static __inline void
|
||||
|
||||
@@ -124,8 +124,6 @@ struct cpuinfo {
|
||||
extern struct cpuinfo cpuinfo;
|
||||
|
||||
void cpuinfo_init(void);
|
||||
#if __ARM_ARCH >= 6
|
||||
void cpuinfo_init_bp_hardening(void);
|
||||
void cpuinfo_reinit_mmu(uint32_t ttb);
|
||||
#endif
|
||||
#endif /* _MACHINE_CPUINFO_H_ */
|
||||
|
||||
@@ -49,13 +49,9 @@ typedef int db_expr_t;
|
||||
kdb_frame->tf_pc += BKPT_SIZE; \
|
||||
} while (0)
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
#define db_clear_single_step kdb_cpu_clear_singlestep
|
||||
#define db_set_single_step kdb_cpu_set_singlestep
|
||||
#define db_pc_is_singlestep kdb_cpu_pc_is_singlestep
|
||||
#else
|
||||
#define SOFTWARE_SSTEP 1
|
||||
#endif
|
||||
|
||||
#define IS_BREAKPOINT_TRAP(type, code) (type == T_BREAKPOINT)
|
||||
#define IS_WATCHPOINT_TRAP(type, code) (type == T_WATCHPOINT)
|
||||
|
||||
@@ -43,42 +43,12 @@ enum dbg_access_t {
|
||||
HW_WATCHPOINT_RW = HW_WATCHPOINT_R | HW_WATCHPOINT_W,
|
||||
};
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
void dbg_monitor_init(void);
|
||||
void dbg_monitor_init_secondary(void);
|
||||
void dbg_show_watchpoint(void);
|
||||
int dbg_setup_watchpoint(db_expr_t, db_expr_t, enum dbg_access_t);
|
||||
int dbg_remove_watchpoint(db_expr_t, db_expr_t);
|
||||
void dbg_resume_dbreg(void);
|
||||
#else /* __ARM_ARCH >= 6 */
|
||||
static __inline void
|
||||
dbg_show_watchpoint(void)
|
||||
{
|
||||
}
|
||||
static __inline int
|
||||
dbg_setup_watchpoint(db_expr_t addr __unused, db_expr_t size __unused,
|
||||
enum dbg_access_t access __unused)
|
||||
{
|
||||
return (ENXIO);
|
||||
}
|
||||
static __inline int
|
||||
dbg_remove_watchpoint(db_expr_t addr __unused, db_expr_t size __unused)
|
||||
{
|
||||
return (ENXIO);
|
||||
}
|
||||
static __inline void
|
||||
dbg_monitor_init(void)
|
||||
{
|
||||
}
|
||||
static __inline void
|
||||
dbg_monitor_init_secondary(void)
|
||||
{
|
||||
}
|
||||
static __inline void
|
||||
dbg_resume_dbreg(void)
|
||||
{
|
||||
}
|
||||
#endif /* __ARM_ARCH < 6 */
|
||||
|
||||
#else /* DDB */
|
||||
static __inline void
|
||||
|
||||
@@ -36,16 +36,6 @@
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#ifndef INTRNG
|
||||
|
||||
/* Max interrupt number */
|
||||
#define FDT_INTR_MAX NIRQ
|
||||
|
||||
/* Map phandle/intpin pair to global IRQ number */
|
||||
#define FDT_MAP_IRQ(node, pin) (pin)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Bus space tag. XXX endianess info needs to be derived from the blob.
|
||||
*/
|
||||
|
||||
@@ -118,10 +118,8 @@ struct switchframe
|
||||
register_t sf_sp;
|
||||
register_t sf_lr;
|
||||
register_t sf_pc;
|
||||
#if __ARM_ARCH >= 6
|
||||
register_t sf_tpidrurw;
|
||||
register_t sf_spare0;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -45,8 +45,6 @@
|
||||
#include <dev/ofw/openfirm.h>
|
||||
#endif
|
||||
|
||||
#ifdef INTRNG
|
||||
|
||||
#ifndef NIRQ
|
||||
#define NIRQ 1024 /* XXX - It should be an option. */
|
||||
#endif
|
||||
@@ -65,42 +63,6 @@ void intr_ipi_setup(u_int, const char *, intr_ipi_handler_t *, void *,
|
||||
|
||||
int intr_pic_ipi_setup(u_int, const char *, intr_ipi_handler_t *, void *);
|
||||
#endif
|
||||
#else /* INTRNG */
|
||||
|
||||
/* XXX move to std.* files? */
|
||||
#if defined(SOC_MV_DISCOVERY)
|
||||
#define NIRQ 96
|
||||
#elif defined(SOC_MV_KIRKWOOD)
|
||||
#define NIRQ 64
|
||||
#elif defined(CPU_CORTEXA)
|
||||
#define NIRQ 1020
|
||||
#elif defined(CPU_KRAIT)
|
||||
#define NIRQ 288
|
||||
#elif defined(CPU_ARM1176)
|
||||
#define NIRQ 128
|
||||
#else
|
||||
#define NIRQ 32
|
||||
#endif
|
||||
|
||||
int arm_get_next_irq(int);
|
||||
void arm_mask_irq(uintptr_t);
|
||||
void arm_unmask_irq(uintptr_t);
|
||||
void arm_intrnames_init(void);
|
||||
void arm_setup_irqhandler(const char *, int (*)(void*), void (*)(void*),
|
||||
void *, int, int, void **);
|
||||
int arm_remove_irqhandler(int, void *);
|
||||
extern void (*arm_post_filter)(void *);
|
||||
extern int (*arm_config_irq)(int irq, enum intr_trigger trig,
|
||||
enum intr_polarity pol);
|
||||
|
||||
void intr_pic_init_secondary(void);
|
||||
|
||||
#ifdef FDT
|
||||
int gic_decode_fdt(phandle_t, pcell_t *, int *, int *, int *);
|
||||
int intr_fdt_map_irq(phandle_t, pcell_t *, int);
|
||||
#endif
|
||||
|
||||
#endif /* INTRNG */
|
||||
|
||||
void arm_irq_memory_barrier(uintptr_t);
|
||||
|
||||
|
||||
@@ -38,21 +38,9 @@
|
||||
|
||||
#define KDB_STOPPEDPCB(pc) &stoppcbs[pc->pc_cpuid]
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
extern void kdb_cpu_clear_singlestep(void);
|
||||
extern void kdb_cpu_set_singlestep(void);
|
||||
boolean_t kdb_cpu_pc_is_singlestep(db_addr_t);
|
||||
#else
|
||||
static __inline void
|
||||
kdb_cpu_clear_singlestep(void)
|
||||
{
|
||||
}
|
||||
|
||||
static __inline void
|
||||
kdb_cpu_set_singlestep(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static __inline void
|
||||
kdb_cpu_sync_icache(unsigned char *addr, size_t size)
|
||||
|
||||
@@ -5,16 +5,9 @@
|
||||
#define _MACHDEP_BOOT_MACHDEP_H_
|
||||
|
||||
/* Structs that need to be initialised by initarm */
|
||||
#if __ARM_ARCH >= 6
|
||||
extern vm_offset_t irqstack;
|
||||
extern vm_offset_t undstack;
|
||||
extern vm_offset_t abtstack;
|
||||
#else
|
||||
struct pv_addr;
|
||||
extern struct pv_addr irqstack;
|
||||
extern struct pv_addr undstack;
|
||||
extern struct pv_addr abtstack;
|
||||
#endif
|
||||
|
||||
/* Define various stack sizes in pages */
|
||||
#define IRQ_STACK_SIZE 1
|
||||
|
||||
@@ -43,7 +43,6 @@ struct vmspace;
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
/* Branch predictor hardening method */
|
||||
#define PCPU_BP_HARDEN_KIND_NONE 0
|
||||
#define PCPU_BP_HARDEN_KIND_BPIALL 1
|
||||
@@ -67,10 +66,6 @@ struct vmspace;
|
||||
uint32_t pc_original_actlr; \
|
||||
uint64_t pc_clock; \
|
||||
char __pad[139]
|
||||
#else
|
||||
#define PCPU_MD_FIELDS \
|
||||
char __pad[93]
|
||||
#endif
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
@@ -82,7 +77,6 @@ struct pcpu;
|
||||
|
||||
extern struct pcpu *pcpup;
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
#define CPU_MASK (0xf)
|
||||
|
||||
#ifndef SMP
|
||||
@@ -138,9 +132,6 @@ set_tls(void *tls)
|
||||
|
||||
#define curthread get_curthread()
|
||||
|
||||
#else
|
||||
#define get_pcpu() pcpup
|
||||
#endif
|
||||
|
||||
#define PCPU_GET(member) (get_pcpu()->pc_ ## member)
|
||||
#define PCPU_ADD(member, value) (get_pcpu()->pc_ ## member += (value))
|
||||
|
||||
@@ -55,11 +55,6 @@ struct mdthread {
|
||||
int md_ptrace_addr;
|
||||
int md_ptrace_instr_alt;
|
||||
int md_ptrace_addr_alt;
|
||||
#if __ARM_ARCH < 6
|
||||
register_t md_tp;
|
||||
void *md_ras_start;
|
||||
void *md_ras_end;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct mdproc {
|
||||
|
||||
@@ -35,22 +35,14 @@ static inline void
|
||||
sf_buf_map(struct sf_buf *sf, int flags)
|
||||
{
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
pmap_qenter(sf->kva, &(sf->m), 1);
|
||||
#else
|
||||
pmap_kenter(sf->kva, VM_PAGE_TO_PHYS(sf->m));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int
|
||||
sf_buf_unmap(struct sf_buf *sf)
|
||||
{
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
pmap_qremove(sf->kva, 1);
|
||||
#else
|
||||
pmap_kremove(sf->kva);
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
#endif /* !_MACHINE_SF_BUF_H_ */
|
||||
|
||||
@@ -41,27 +41,6 @@
|
||||
|
||||
#include <machine/armreg.h>
|
||||
|
||||
/*
|
||||
* The ARM_TP_ADDRESS points to a special purpose page, which is used as local
|
||||
* store for the ARM per-thread data and Restartable Atomic Sequences support.
|
||||
* Put it just above the "high" vectors' page.
|
||||
* The cpu_switch() code assumes ARM_RAS_START is ARM_TP_ADDRESS + 4, and
|
||||
* ARM_RAS_END is ARM_TP_ADDRESS + 8, so if that ever changes, be sure to
|
||||
* update the cpu_switch() (and cpu_throw()) code as well.
|
||||
* In addition, code in arm/include/atomic.h and arm/arm/exception.S
|
||||
* assumes that ARM_RAS_END is at ARM_RAS_START+4, so be sure to update those
|
||||
* if ARM_RAS_END moves in relation to ARM_RAS_START (look for occurrences
|
||||
* of ldr/str rm,[rn, #4]).
|
||||
*/
|
||||
|
||||
/* ARM_TP_ADDRESS is needed for processors that don't support
|
||||
* the exclusive-access opcodes introduced with ARMv6K. */
|
||||
#if __ARM_ARCH <= 5
|
||||
#define ARM_TP_ADDRESS (ARM_VECTORS_HIGH + 0x1000)
|
||||
#define ARM_RAS_START (ARM_TP_ADDRESS + 4)
|
||||
#define ARM_RAS_END (ARM_TP_ADDRESS + 8)
|
||||
#endif
|
||||
|
||||
#ifndef LOCORE
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
|
||||
@@ -42,8 +42,6 @@
|
||||
/*
|
||||
* CP14 registers
|
||||
*/
|
||||
#if __ARM_ARCH >= 6
|
||||
|
||||
#define CP14_DBGDIDR(rr) p14, 0, rr, c0, c0, 0 /* Debug ID Register */
|
||||
#define CP14_DBGDSCRext_V6(rr) p14, 0, rr, c0, c1, 0 /* Debug Status and Ctrl Register v6 */
|
||||
#define CP14_DBGDSCRext_V7(rr) p14, 0, rr, c0, c2, 2 /* Debug Status and Ctrl Register v7 */
|
||||
@@ -55,8 +53,6 @@
|
||||
|
||||
#define CP14_DBGDSCRint(rr) CP14_DBGDSCRext_V6(rr) /* Debug Status and Ctrl internal view */
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* CP15 C0 registers
|
||||
*/
|
||||
@@ -131,10 +127,8 @@
|
||||
#define CP15_DFSR(rr) p15, 0, rr, c5, c0, 0 /* Data Fault Status Register */
|
||||
#define CP15_HSR(rr) p15, 4, rr, c5, c2, 0 /* Hyp Syndrome Register */
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
/* From ARMv6: */
|
||||
#define CP15_IFSR(rr) p15, 0, rr, c5, c0, 1 /* Instruction Fault Status Register */
|
||||
#endif
|
||||
#if __ARM_ARCH >= 7
|
||||
/* From ARMv7: */
|
||||
#define CP15_ADFSR(rr) p15, 0, rr, c5, c1, 0 /* Auxiliary Data Fault Status Register */
|
||||
@@ -149,10 +143,8 @@
|
||||
#define CP15_HIFAR(rr) p15, 4, rr, c6, c0, 2 /* Hyp Instruction Fault Address Register */
|
||||
#define CP15_HPFAR(rr) p15, 4, rr, c6, c0, 4 /* Hyp IPA Fault Address Register */
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
/* From ARMv6k: */
|
||||
#define CP15_IFAR(rr) p15, 0, rr, c6, c0, 2 /* Instruction Fault Address Register */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* CP15 C7 registers
|
||||
@@ -236,10 +228,8 @@
|
||||
|
||||
#define CP15_TLBIALLH(rr) p15, 4, rr, c8, c7, 0 /* Invalidate Entire Hyp Unified TLB */
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
/* From ARMv6: */
|
||||
#define CP15_TLBIMVAA(rr) p15, 0, rr, c8, c7, 3 /* Invalidate unified TLB by MVA, all ASID */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* CP15 C9 registers
|
||||
@@ -248,7 +238,7 @@
|
||||
#define CP15_PMUSERENR(rr) p15, 0, rr, c15, c9, 0 /* Access Validation Control Register */
|
||||
#define CP15_PMCR(rr) p15, 0, rr, c15, c12, 0 /* Performance Monitor Control Register */
|
||||
#define CP15_PMCCNTR(rr) p15, 0, rr, c15, c12, 1 /* PM Cycle Count Register */
|
||||
#elif __ARM_ARCH > 6
|
||||
#else
|
||||
#define CP15_L2CTLR(rr) p15, 1, rr, c9, c0, 2 /* L2 Control Register */
|
||||
#define CP15_PMCR(rr) p15, 0, rr, c9, c12, 0 /* Performance Monitor Control Register */
|
||||
#define CP15_PMCNTENSET(rr) p15, 0, rr, c9, c12, 1 /* PM Count Enable Set Register */
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#ifndef _MACHINE_VM_H_
|
||||
#define _MACHINE_VM_H_
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
#define VM_MEMATTR_WB_WA ((vm_memattr_t)0)
|
||||
#define VM_MEMATTR_NOCACHE ((vm_memattr_t)1)
|
||||
#define VM_MEMATTR_DEVICE ((vm_memattr_t)2)
|
||||
@@ -45,10 +44,5 @@
|
||||
#define VM_MEMATTR_WRITE_COMBINING VM_MEMATTR_WRITE_THROUGH /* for DRM */
|
||||
#define VM_MEMATTR_WRITE_BACK VM_MEMATTR_WB_WA /* for DRM */
|
||||
#endif
|
||||
#else
|
||||
/* Memory attribute configuration. */
|
||||
#define VM_MEMATTR_DEFAULT 0
|
||||
#define VM_MEMATTR_UNCACHEABLE 1
|
||||
#endif
|
||||
|
||||
#endif /* !_MACHINE_VM_H_ */
|
||||
|
||||
@@ -527,7 +527,6 @@ mv_gpio_exec_intr_handlers(device_t dev, uint32_t status, int high)
|
||||
static void
|
||||
mv_gpio_intr_handler(device_t dev, int pin)
|
||||
{
|
||||
#ifdef INTRNG
|
||||
struct intr_irqsrc isrc;
|
||||
struct mv_gpio_softc *sc;
|
||||
sc = (struct mv_gpio_softc *)device_get_softc(dev);
|
||||
@@ -544,7 +543,6 @@ mv_gpio_intr_handler(device_t dev, int pin)
|
||||
return;
|
||||
|
||||
intr_isrc_dispatch(&isrc, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -62,9 +62,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
#include <dev/fdt/fdt_common.h>
|
||||
|
||||
#ifdef INTRNG
|
||||
#include "pic_if.h"
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define debugf(fmt, args...) do { printf("%s(): ", __func__); \
|
||||
|
||||
@@ -259,10 +259,8 @@ struct decode_win_spec {
|
||||
win_read_t ddr_sz_read;
|
||||
win_write_t ddr_br_write;
|
||||
win_write_t ddr_sz_write;
|
||||
#if __ARM_ARCH >= 6
|
||||
get_t get_tclk;
|
||||
get_t get_cpu_freq;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct decode_win_spec *soc_decode_win_spec;
|
||||
@@ -287,10 +285,8 @@ static struct decode_win_spec decode_win_specs[] =
|
||||
&ddr_armv7_sz_read,
|
||||
&ddr_armv7_br_write,
|
||||
&ddr_armv7_sz_write,
|
||||
#if __ARM_ARCH >= 6
|
||||
&get_tclk_armada38x,
|
||||
&get_cpu_freq_armada38x,
|
||||
#endif
|
||||
},
|
||||
{
|
||||
&read_cpu_ctrl_armv7,
|
||||
@@ -310,10 +306,8 @@ static struct decode_win_spec decode_win_specs[] =
|
||||
&ddr_armv7_sz_read,
|
||||
&ddr_armv7_br_write,
|
||||
&ddr_armv7_sz_write,
|
||||
#if __ARM_ARCH >= 6
|
||||
&get_tclk_armadaxp,
|
||||
&get_cpu_freq_armadaxp,
|
||||
#endif
|
||||
},
|
||||
{
|
||||
&read_cpu_ctrl_armv5,
|
||||
@@ -333,10 +327,8 @@ static struct decode_win_spec decode_win_specs[] =
|
||||
&ddr_armv5_sz_read,
|
||||
&ddr_armv5_br_write,
|
||||
&ddr_armv5_sz_write,
|
||||
#if __ARM_ARCH >= 6
|
||||
NULL,
|
||||
NULL,
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2896,7 +2888,6 @@ struct fdt_fixup_entry fdt_fixup_table[] = {
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
uint32_t
|
||||
get_tclk(void)
|
||||
{
|
||||
@@ -2916,27 +2907,3 @@ get_cpu_freq(void)
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef INTRNG
|
||||
static int
|
||||
fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
|
||||
int *pol)
|
||||
{
|
||||
|
||||
if (!ofw_bus_node_is_compatible(node, "mrvl,pic") &&
|
||||
!ofw_bus_node_is_compatible(node, "mrvl,mpic"))
|
||||
return (ENXIO);
|
||||
|
||||
*interrupt = fdt32_to_cpu(intr[0]);
|
||||
*trig = INTR_TRIGGER_CONFORM;
|
||||
*pol = INTR_POLARITY_CONFORM;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
fdt_pic_decode_t fdt_pic_table[] = {
|
||||
&fdt_pic_decode_ic,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -466,9 +466,7 @@ mv_pcib_attach(device_t self)
|
||||
sc->sc_win_target = MV_WIN_PCIE_TARGET(port_id);
|
||||
sc->sc_mem_win_attr = MV_WIN_PCIE_MEM_ATTR(port_id);
|
||||
sc->sc_io_win_attr = MV_WIN_PCIE_IO_ATTR(port_id);
|
||||
#if __ARM_ARCH >= 6
|
||||
sc->sc_skip_enable_procedure = 1;
|
||||
#endif
|
||||
} else if (ofw_bus_node_is_compatible(parnode, "marvell,armada-370-pcie")) {
|
||||
sc->sc_type = MV_TYPE_PCIE;
|
||||
sc->sc_win_target = MV_WIN_PCIE_TARGET_ARMADA38X(port_id);
|
||||
@@ -1218,9 +1216,7 @@ mv_pcib_map_msi(device_t dev, device_t child, int irq, uint64_t *addr,
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
mv_msi_data(irq, addr, data);
|
||||
#endif
|
||||
|
||||
debugf("%s: irq: %d addr: %jx data: %x\n",
|
||||
__func__, irq, *addr, *data);
|
||||
|
||||
@@ -4,7 +4,6 @@ arm/versatile/pl050.c optional sc
|
||||
arm/versatile/sp804.c standard
|
||||
arm/versatile/versatile_machdep.c standard
|
||||
arm/versatile/versatile_clcd.c optional sc
|
||||
arm/versatile/versatile_common.c standard
|
||||
arm/versatile/versatile_pci.c optional pci
|
||||
arm/versatile/versatile_scm.c standard
|
||||
arm/versatile/versatile_sic.c standard
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (C) 2008-2011 MARVELL INTERNATIONAL LTD.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by Semihalf.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of MARVELL nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <dev/fdt/fdt_common.h>
|
||||
#include <dev/ofw/openfirm.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/vmparam.h>
|
||||
|
||||
#ifndef INTRNG
|
||||
static int
|
||||
fdt_intc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
|
||||
int *pol)
|
||||
{
|
||||
|
||||
if (!ofw_bus_node_is_compatible(node, "arm,versatile-vic"))
|
||||
return (ENXIO);
|
||||
|
||||
*interrupt = fdt32_to_cpu(intr[0]);
|
||||
*trig = INTR_TRIGGER_CONFORM;
|
||||
*pol = INTR_POLARITY_CONFORM;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
fdt_pic_decode_t fdt_pic_table[] = {
|
||||
&fdt_intc_decode_ic,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user