Don't use locations in .data to store exception temporaries, use decidicated

space in cpu_info instead.  This also moves undefined_handler_address into
cpu_info as well.
Use the new armreg* inlines for getting TPIDRPRW register.
Add MULTIPROCESSOR version of CPU_INFO_FOREACH
This commit is contained in:
matt 2012-08-29 23:10:31 +00:00
parent a9ceb00145
commit 72c1c71ead
5 changed files with 70 additions and 52 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: arm_machdep.c,v 1.34 2012/08/29 07:14:03 matt Exp $ */
/* $NetBSD: arm_machdep.c,v 1.35 2012/08/29 23:10:31 matt Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@ -78,7 +78,7 @@
#include <sys/param.h>
__KERNEL_RCSID(0, "$NetBSD: arm_machdep.c,v 1.34 2012/08/29 07:14:03 matt Exp $");
__KERNEL_RCSID(0, "$NetBSD: arm_machdep.c,v 1.35 2012/08/29 23:10:31 matt Exp $");
#include <sys/exec.h>
#include <sys/proc.h>
@ -100,12 +100,25 @@ __KERNEL_RCSID(0, "$NetBSD: arm_machdep.c,v 1.34 2012/08/29 07:14:03 matt Exp $"
char machine[] = MACHINE; /* from <machine/param.h> */
char machine_arch[] = MACHINE_ARCH; /* from <machine/param.h> */
#ifdef __PROG32
extern const uint32_t undefinedinstruction_bounce[];
#endif
/* Our exported CPU info; we can have only one. */
struct cpu_info cpu_info_store = {
.ci_cpl = IPL_HIGH,
.ci_curlwp = &lwp0,
#ifdef __PROG32
.ci_undefsave[2] = (register_t) undefinedinstruction_bounce,
#endif
};
#ifdef MULTIPROCESSOR
struct cpu_info *cpu_info[MAXCPUS] = {
[0] = &cpu_info_store
};
#endif
const pcu_ops_t * const pcu_ops_md_defs[PCU_UNIT_COUNT] = {
#if defined(FPU_VFP)
[PCU_FPU] = &arm_vfp_ops,

View File

@ -1,4 +1,4 @@
/* $NetBSD: exception.S,v 1.16 2008/04/27 18:58:44 matt Exp $ */
/* $NetBSD: exception.S,v 1.17 2012/08/29 23:10:31 matt Exp $ */
/*
* Copyright (c) 1994-1997 Mark Brinicombe.
@ -50,7 +50,7 @@
#include <machine/cpu.h>
#include <machine/frame.h>
RCSID("$NetBSD: exception.S,v 1.16 2008/04/27 18:58:44 matt Exp $")
RCSID("$NetBSD: exception.S,v 1.17 2012/08/29 23:10:31 matt Exp $")
.text
.align 0
@ -213,16 +213,13 @@ exception_exit:
*/
ASENTRY_NP(undefined_entry)
stmfd sp!, {r0, r1}
ldr r0, Lundefined_handler_indirection
GET_CURCPU(r0)
ldr r1, [sp], #0x0004
str r1, [r0, #0x0000]
str r1, [r0, #CI_UNDEFSAVE]!
ldr r1, [sp], #0x0004
str r1, [r0, #0x0004]
ldmia r0, {r0, r1, pc}
Lundefined_handler_indirection:
.word Lundefined_handler_indirection_data
/*
* assembly bounce code for calling the kernel
* undefined instruction handler. This uses
@ -236,20 +233,3 @@ ENTRY_NP(undefinedinstruction_bounce)
mov r0, sp
adr lr, exception_exit
b _C_LABEL(undefinedinstruction)
.data
.align 0
/*
* Indirection data
* 2 words use for preserving r0 and r1
* 3rd word contains the undefined handler address.
*/
Lundefined_handler_indirection_data:
.word 0
.word 0
.global _C_LABEL(undefined_handler_address)
_C_LABEL(undefined_handler_address):
.word _C_LABEL(undefinedinstruction_bounce)

View File

@ -1,4 +1,4 @@
# $NetBSD: genassym.cf,v 1.50 2012/08/29 07:09:12 matt Exp $
# $NetBSD: genassym.cf,v 1.51 2012/08/29 23:10:31 matt Exp $
# Copyright (c) 1982, 1990 The Regents of the University of California.
# All rights reserved.
@ -74,6 +74,7 @@ define KERNEL_BASE KERNEL_BASE
define VM_MIN_ADDRESS VM_MIN_ADDRESS
define VM_MAXUSER_ADDRESS VM_MAXUSER_ADDRESS
define PV_PA offsetof(pv_addr_t, pv_pa)
define PMAP_DOMAIN_KERNEL PMAP_DOMAIN_KERNEL
define DOMAIN_CLIENT DOMAIN_CLIENT
define L1_S_PROTO_generic L1_S_PROTO_generic
@ -163,12 +164,14 @@ define CI_ASTPENDING offsetof(struct cpu_info, ci_astpending)
define CI_WANT_RESCHED offsetof(struct cpu_info, ci_want_resched)
define CI_INTR_DEPTH offsetof(struct cpu_info, ci_intr_depth)
define CI_MTX_COUNT offsetof(struct cpu_info, ci_mtx_count)
define CI_UNDEFSAVE offsetof(struct cpu_info, ci_undefsave[0])
if defined(EXEC_AOUT)
define CI_CTRL offsetof(struct cpu_info, ci_ctrl)
endif
ifdef __HAVE_FAST_SOFTINTS
define CI_SOFTINTS offsetof(struct cpu_info, ci_softints)
endif
define CI_IDLELWP offsetof(struct cpu_info, ci_data.cpu_idlelwp)
define CI_CC_NTRAP offsetof(struct cpu_info, ci_data.cpu_ntrap)
define CI_CC_NINTR offsetof(struct cpu_info, ci_data.cpu_nintr)
define CI_CC_NSOFT offsetof(struct cpu_info, ci_data.cpu_nsoft)

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.h,v 1.12 2012/08/29 19:10:16 matt Exp $ */
/* $NetBSD: machdep.h,v 1.13 2012/08/29 23:10:31 matt Exp $ */
#ifndef _ARM32_BOOT_MACHDEP_H_
#define _ARM32_BOOT_MACHDEP_H_
@ -27,7 +27,8 @@ extern paddr_t cpu_reset_address_paddr;
extern u_int data_abort_handler_address;
extern u_int prefetch_abort_handler_address;
extern u_int undefined_handler_address;
//extern u_int undefined_handler_address;
#define undefined_handler_address (curcpu()->ci_undefsave[2])
extern char *booted_kernel;

View File

@ -90,7 +90,7 @@ extern int cpu_do_powersave;
#ifdef _LOCORE
#if defined(_ARM_ARCH_6)
#define IRQdisable cprid i
#define IRQdisable cpsid i
#define IRQenable cpsie i
#elif defined(__PROG32)
#define IRQdisable \
@ -219,13 +219,12 @@ void arm32_vector_init(vaddr_t, int);
*/
static inline int curcpl(void);
static inline void set_curcpl(int);
#ifdef __HAVE_FAST_SOFTINTS
static inline void cpu_dosoftints(void);
#endif
#include <sys/device_if.h>
#include <sys/evcnt.h>
#include <sys/cpu_data.h>
struct cpu_info {
struct cpu_data ci_data; /* MI per-cpu data */
device_t ci_dev; /* Device corresponding to this CPU */
@ -244,33 +243,31 @@ struct cpu_info {
volatile uint32_t ci_softints;
#endif
lwp_t *ci_curlwp; /* current lwp */
#ifdef _ARM_ARCH_6
uint32_t ci_ccnt_freq; /* cycle count frequency */
#endif
struct evcnt ci_arm700bugcount;
int32_t ci_mtx_count;
int ci_mtx_oldspl;
register_t ci_undefsave[3];
uint32_t ci_vfp_id;
#ifdef MULTIPROCESSOR
#if defined(_ARM_ARCH_7)
uint64_t ci_lastintr;
#endif
#if defined(MP_CPU_INFO_MEMBERS)
MP_CPU_INFO_MEMBERS
#endif
};
#ifndef MULTIPROCESSOR
extern struct cpu_info cpu_info_store;
#if defined(TPIDRPRW_IS_CURLWP)
static inline struct lwp *
_curlwp(void)
{
struct lwp *l;
__asm("mrc\tp15, 0, %0, c13, c0, 4" : "=r"(l));
return l;
return (struct lwp *) armreg_tpidrprw_read();
}
static inline void
_curlwp_set(struct lwp *l)
{
__asm("mcr\tp15, 0, %0, c13, c0, 4" : "=r"(l));
armreg_tpidrprw_write((uintptr_t)l);
}
#define curlwp (_curlwp())
@ -283,19 +280,35 @@ curcpu(void)
static inline struct cpu_info *
curcpu(void)
{
struct cpu_info *ci;
__asm("mrc\tp15, 0, %0, c13, c0, 4" : "=r"(ci));
return ci;
return (struct cpu_info *) armreg_tpidrprw_read();
}
#else
#elif !defined(MULTIPROCESSOR)
#define curcpu() (&cpu_info_store)
#else
#error MULTIPROCESSOR requires TPIDRPRW_IS_CURLWP or TPIDRPRW_IS_CURCPU
#endif /* !TPIDRPRW_IS_CURCPU && !TPIDRPRW_IS_CURLWP */
#ifndef curlwp
#define curlwp (curcpu()->ci_curlwp)
#endif
#define cpu_number() 0
#define CPU_INFO_ITERATOR int
#if defined(MULTIPROCESSOR)
extern struct cpu_info *cpu_info[];
#define cpu_number() (curcpu()->ci_cpuid)
void cpu_boot_secondary_processors(void);
#define CPU_IS_PRIMARY(ci) ((ci)->ci_cpuid == 0)
#define CPU_INFO_FOREACH(cii, ci) \
cii = 0, ci = cpu_info[0]; cii < ncpu && (ci = cpu_info[cii]) != NULL; cii++
#else
#define cpu_number() 0
#define CPU_IS_PRIMARY(ci) true
#define CPU_INFO_FOREACH(cii, ci) \
cii = 0, ci = curcpu(); ci != NULL; ci = NULL
#endif
#define LWP0_CPU_INFO (&cpu_info_store)
#endif /* !MULTIPROCESSOR */
static inline int
curcpl(void)
@ -309,16 +322,18 @@ set_curcpl(int pri)
curcpu()->ci_cpl = pri;
}
#ifdef __HAVE_FAST_SOFTINTS
void dosoftints(void);
static inline void
cpu_dosoftints(void)
{
#ifdef __HAVE_FAST_SOFTINTS
void dosoftints(void);
#ifndef __HAVE_PIC_FAST_SOFTINTS
struct cpu_info * const ci = curcpu();
if (ci->ci_intr_depth == 0 && (ci->ci_softints >> ci->ci_cpl) > 0)
dosoftints();
}
#endif
#endif
}
#ifdef __PROG32
void cpu_proc_fork(struct proc *, struct proc *);
@ -330,14 +345,14 @@ void cpu_proc_fork(struct proc *, struct proc *);
* Scheduling glue
*/
#define setsoftast() (curcpu()->ci_astpending = 1)
#define setsoftast() (curcpu()->ci_astpending = 1)
/*
* Notify the current process (p) that it has a signal pending,
* process as soon as possible.
*/
#define cpu_signotify(l) setsoftast()
#define cpu_signotify(l) setsoftast()
/*
* Give a profiling tick to the current process when the user profiling
@ -346,6 +361,12 @@ void cpu_proc_fork(struct proc *, struct proc *);
*/
#define cpu_need_proftick(l) ((l)->l_pflag |= LP_OWEUPC, setsoftast())
/*
* We've already preallocated the stack for the idlelwps for additional CPUs.
* This hook allows to return them.
*/
vaddr_t cpu_uarea_alloc_idlelwp(struct cpu_info *);
#ifndef acorn26
/*
* cpu device glue (belongs in cpuvar.h)