/*1* Copyright (c) 20092* The President and Fellows of Harvard College.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12* 3. Neither the name of the University nor the names of its contributors13* may be used to endorse or promote products derived from this software14* without specific prior written permission.15*16* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND17* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE18* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE19* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE20* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL21* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS22* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)23* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT24* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY25* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF26* SUCH DAMAGE.27*/2829#ifndef _CPU_H_30#define _CPU_H_313233#include <spinlock.h>34#include <threadlist.h>35#include <machine/vm.h> /* for TLBSHOOTDOWN_MAX */363738/*39* Per-cpu structure40*41* Note: curcpu is defined by <current.h>.42*43* cpu->c_self should always be used when *using* the address of curcpu44* (as opposed to merely dereferencing it) in case curcpu is defined as45* a pointer with a fixed address and a per-cpu mapping in the MMU.46*/4748struct cpu {49/*50* Fixed after allocation.51*/52struct cpu *c_self; /* Canonical address of this struct */53unsigned c_number; /* This cpu's cpu number */54unsigned c_hardware_number; /* Hardware-defined cpu number */5556/*57* Accessed only by this cpu.58*/59struct thread *c_curthread; /* Current thread on cpu */60struct threadlist c_zombies; /* List of exited threads */61unsigned c_hardclocks; /* Counter of hardclock() calls */6263/**64* ASST3 related65*/66struct addrspace *c_lastas; /* last as loaded inside the tlb of this cpu */6768/*69* Accessed by other cpus.70* Protected by the runqueue lock.71*/72bool c_isidle; /* True if this cpu is idle */73struct threadlist c_runqueue; /* Run queue for this cpu */74struct spinlock c_runqueue_lock;7576/*77* Accessed by other cpus.78* Protected by the IPI lock.79*80* If c_numshootdown is -1 (TLBSHOOTDOWN_ALL), all mappings81* should be invalidated. This is used if more than82* TLBSHOOTDOWN_MAX mappings are going to be invalidated at83* once. TLBSHOOTDOWN_MAX is MD and chosen based on when it84* becomes more efficient just to flush the whole TLB.85*86* struct tlbshootdown is machine-dependent and might87* reasonably be either an address space and vaddr pair, or a88* paddr, or something else.89*/90uint32_t c_ipi_pending; /* One bit for each IPI number */91struct tlbshootdown c_shootdown[TLBSHOOTDOWN_MAX];92int c_numshootdown;93struct spinlock c_ipi_lock;94};9596#define TLBSHOOTDOWN_ALL (-1)9798/*99* Initialization functions.100*101* cpu_create creates a cpu; it is suitable for calling from driver-102* or bus-specific code that looks for secondary CPUs.103*104* cpu_create calls cpu_machdep_init.105*106* cpu_start_secondary is the platform-dependent assembly language107* entry point for new CPUs; it can be found in start.S. It calls108* cpu_hatch after having claimed the startup stack and thread created109* for the cpu.110*/111struct cpu *cpu_create(unsigned hardware_number);112void cpu_machdep_init(struct cpu *);113/*ASMLINKAGE*/ void cpu_start_secondary(void);114void cpu_hatch(unsigned software_number);115116/*117* Return a string describing the CPU type.118*/119const char *cpu_identify(void);120121/*122* Hardware-level interrupt on/off, for the current CPU.123*124* These should only be used by the spl code.125*/126void cpu_irqoff(void);127void cpu_irqon(void);128129/*130* Idle or shut down (respectively) the processor.131*132* cpu_idle() sits around (in a low-power state if possible) until it133* thinks something interesting may have happened, such as an134* interrupt. Then it returns. (It may be wrong, so it should always135* be called in a loop checking some other condition.) It must be136* called with interrupts off to avoid race conditions, although137* interrupts may be delivered before it returns.138*139* cpu_halt sits around (in a low-power state if possible) until the140* external reset is pushed. Interrupts should be disabled. It does141* not return. It should not allow interrupts to be delivered.142*/143void cpu_idle(void);144void cpu_halt(void);145146/*147* Interprocessor interrupts.148*149* From time to time it is necessary to poke another CPU. System150* boards of multiprocessor machines provide a way to do this.151*152* TLB shootdown is done by the VM system when more than one processor153* has (or may have) a page mapped in the MMU and it is being changed154* or otherwise needs to be invalidated across all CPUs.155*156* ipi_send sends an IPI to one CPU.157* ipi_broadcast sends an IPI to all CPUs except the current one.158* ipi_tlbshootdown is like ipi_send but carries TLB shootdown data.159*160* interprocessor_interrupt is called on the target CPU when an IPI is161* received.162*/163164/* IPI types */165#define IPI_PANIC 0 /* System has called panic() */166#define IPI_OFFLINE 1 /* CPU is requested to go offline */167#define IPI_UNIDLE 2 /* Runnable threads are available */168#define IPI_TLBSHOOTDOWN 3 /* MMU mapping(s) need invalidation */169170void ipi_send(struct cpu *target, int code);171void ipi_broadcast(int code);172void ipi_tlbshootdown(struct cpu *target, const struct tlbshootdown *mapping);173void interprocessor_interrupt(void);174175void ipi_tlbshootdown_by_num( unsigned, const struct tlbshootdown *);176#endif /* _CPU_H_ */177178179