1/*
2 * Copyright 2013, winocm. <winocm@icloud.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 *   Redistributions of source code must retain the above copyright notice, this
9 *   list of conditions and the following disclaimer.
10 *
11 *   Redistributions in binary form must reproduce the above copyright notice, this
12 *   list of conditions and the following disclaimer in the documentation and/or
13 *   other materials provided with the distribution.
14 *
15 *   If you are going to use this software in any form that does not involve
16 *   releasing the source to this project or improving it, let me know beforehand.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29/*
30 * ARM processor data
31 */
32
33#ifndef _ARM_CPU_DATA_H_
34#define _ARM_CPU_DATA_H_
35
36#include <mach_assert.h>
37
38#include <kern/assert.h>
39#include <kern/kern_types.h>
40#include <kern/queue.h>
41#include <kern/processor.h>
42#include <kern/pms.h>
43#include <pexpert/pexpert.h>
44#include <mach/arm/thread_status.h>
45#include <mach/arm/vm_param.h>
46
47/*
48 * The current thread is returned from an assembly routine.
49 */
50extern thread_t current_thread(void);
51
52/*
53 * The boot processor.
54 */
55extern struct processor BootProcessor;
56
57#ifndef offsetof
58#define offsetof(TYPE,MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
59#endif
60
61typedef enum {
62    TASK_MAP_32BIT,             /* 32-bit user, compatibility mode */
63} task_map_t;
64
65typedef struct rtclock_timer {
66    mpqueue_head_t queue;
67    uint64_t deadline;
68    uint64_t when_set;
69    boolean_t has_expired;
70} rtclock_timer_t;
71
72typedef uint16_t    asid_t;
73typedef uint8_t     asid_ref_t;
74
75/*
76 * The core processor data. This is also referred to as the processor
77 * control region block (PCRB) or processor control block (PCB). Use
78 * whatever terminology suits you on this fine day.
79 */
80typedef struct cpu_data {
81    struct cpu_data *cpu_this;  /* pointer to myself */
82    thread_t cpu_active_thread;
83    int cpu_preemption_level;
84    int cpu_number;             /* Logical CPU */
85    void *cpu_int_state;        /* interrupt state */
86    vm_offset_t cpu_active_stack;   /* kernel stack base */
87    vm_offset_t cpu_kernel_stack;   /* kernel stack top */
88    vm_offset_t cpu_int_stack_top;
89    int cpu_interrupt_level;
90    int cpu_phys_number;        /* Physical CPU */
91    cpu_id_t cpu_id;            /* Platform Expert */
92    int cpu_signals;            /* IPI events */
93    int cpu_prior_signals;      /* Last set of events, and debugging. */
94    int cpu_mcount_off;         /* mcount recursion */
95    int cpu_type;
96    int cpu_subtype;
97    int cpu_threadtype;
98    int cpu_running;
99    struct processor *cpu_processor;
100    uint64_t debugger_entry_time;
101    arm_saved_state_t *cpu_fatal_trap_state;
102    arm_saved_state_t *cpu_post_fatal_trap_state;
103    caddr_t cpu_onfault;        /* for alignment faults */
104    int cpu_pending_ast;
105    uint64_t interrupt_entry_time;
106    uint32_t interrupt_count[8];
107    uint32_t rtcPop;
108    struct pmap *user_pmap;
109    uint64_t absolute_time;
110    rtclock_timer_t rt_timer;
111    thread_t old_thread;
112    thread_t new_thread;
113
114    asid_t          cpu_active_asid;
115    asid_t          cpu_last_asid;
116    volatile asid_ref_t *cpu_pmap_asid_coherentp;
117    volatile asid_ref_t *cpu_pmap_asid_coherentp_kernel;
118#define PMAP_ASID_MAX_ASID      (0xFF)
119    asid_t          cpu_asid_free_hint;
120    asid_ref_t      cpu_asid_refcounts[PMAP_ASID_MAX_ASID];
121    pmap_t          cpu_asid_last_pmap_dispatched[PMAP_ASID_MAX_ASID];
122
123    uint32_t fleh_reset;
124    uint32_t fleh_undef;
125    uint32_t fleh_swi;
126    uint32_t fleh_prefabt;
127    uint32_t fleh_dataabt;
128    uint32_t fleh_dataexc;
129    uint32_t fleh_irq;
130
131    IOInterruptHandler handler;     /* for IOKit */
132    void* nub;
133    void* target;
134    void* refCon;
135
136} cpu_data_t;
137
138extern cpu_data_t *cpu_data_ptr[];
139extern cpu_data_t cpu_data_master;
140
141static inline cpu_data_t *cpu_datap(int cpu)
142{
143    return cpu_data_ptr[cpu];
144}
145
146#define disable_preemption              _disable_preemption
147#define enable_preemption               _enable_preemption
148#define enable_preemption_no_check        _enable_preemption_no_check
149#define mp_disable_preemption           _disable_preemption
150#define mp_enable_preemption            _enable_preemption
151#define mp_enable_preemption_no_check        _enable_preemption_no_check
152
153extern int get_preemption_level(void);
154extern void disable_preemption(void);
155extern void enable_preemption(void);
156extern void enable_preemption_no_check(void);
157extern void mp_disable_preemption(void);
158extern void mp_enable_preemption(void);
159extern void mp_enable_preemption_no_check(void);
160extern int get_simple_lock_count(void);
161
162int get_interrupt_level(void);
163int get_cpu_number(void);
164int get_cpu_phys_number(void);
165
166cpu_data_t *current_cpu_datap(void);
167
168#endif
169