Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changes in / [b86d436:3c081d0e] in mainline


Ignore:
Files:
10 added
60 deleted
26 edited

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    rb86d436 r3c081d0e  
    7676@ "us" UltraSPARC I-II subarchitecture
    7777@ "us3" UltraSPARC III-IV subarchitecture
    78 @ "sun4v" Niagara (sun4v)
    7978! [PLATFORM=sparc64&MACHINE=generic] PROCESSOR (choice)
    8079
     
    428427
    429428% Serial line input module
    430 ! [CONFIG_DSRLNIN=y|(PLATFORM=ia64&MACHINE=i460GX&CONFIG_NS16550=y)|(PLATFORM=ia64&MACHINE=ski)|(PLATFORM=sparc64&MACHINE=serengeti&CONFIG_SGCN_KBD=y)|(PLATFORM=sparc64&PROCESSOR=sun4v)] CONFIG_SRLN (y)
     429! [CONFIG_DSRLNIN=y|(PLATFORM=ia64&MACHINE=i460GX&CONFIG_NS16550=y)|(PLATFORM=ia64&MACHINE=ski)|(PLATFORM=sparc64&MACHINE=serengeti&CONFIG_SGCN_KBD=y)] CONFIG_SRLN (y)
    431430
    432431% EGA support
  • boot/arch/sparc64/loader/asm.S

    rb86d436 r3c081d0e  
    115115         */
    116116       
    117 #if defined (SUN4U)
    118117        /*
    119118         * US3 processors have a write-invalidate cache, so explicitly
     
    129128                call icache_flush
    130129                nop
    131 #endif 
     130       
    132131        1:
    133132                membar #StoreStore
  • boot/arch/sparc64/loader/main.c

    rb86d436 r3c081d0e  
    5757#endif
    5858
    59 /** UltraSPARC subarchitecture - 1 for US, 3 for US3, 0 for other */
    60 static uint8_t subarchitecture = 0;
     59/** UltraSPARC subarchitecture - 1 for US, 3 for US3 */
     60static uint8_t subarchitecture;
    6161
    6262/**
     
    6969static void version_print(void)
    7070{
    71        
    7271        printf("HelenOS SPARC64 Bootloader\nRelease %s%s%s\n"
    7372            "Copyright (c) 2006 HelenOS project\n",
     
    8483#define US_IIIi_CODE   0x15
    8584
    86 /* max. length of the "compatible" property of the root node */
    87 #define COMPATIBLE_PROP_MAXLEN  64
    88 
    89 /*
    90  * HelenOS bootloader will use these constants to distinguish particular
    91  * UltraSPARC architectures
    92  */
    93 #define COMPATIBLE_SUN4U        10
    94 #define COMPATIBLE_SUN4V        20
    95 
    96 /** US architecture. COMPATIBLE_SUN4U for sun4v, COMPATIBLE_SUN4V for sun4u */
    97 static uint8_t architecture;
    98 
    9985/**
    100  * Detects the UltraSPARC architecture (sun4u and sun4v currently supported)
    101  * by inspecting the property called "compatible" in the OBP root node.
    102  */
    103 static void detect_architecture(void)
    104 {
    105         phandle root = ofw_find_device("/");
    106         char compatible[COMPATIBLE_PROP_MAXLEN];
    107 
    108         if (ofw_get_property(root, "compatible", compatible,
    109                         COMPATIBLE_PROP_MAXLEN) <= 0) {
    110                 printf("Unable to determine architecture, default: sun4u.\n");
    111                 architecture = COMPATIBLE_SUN4U;
    112                 return;
    113         }
    114 
    115         if (strcmp(compatible, "sun4v") == 0) {
    116                 architecture = COMPATIBLE_SUN4V;
    117         } else {
    118                 /*
    119                  * As not all sun4u machines have "sun4u" in their "compatible"
    120                  * OBP property (e.g. Serengeti's OBP "compatible" property is
    121                  * "SUNW,Serengeti"), we will by default fallback to sun4u if
    122                  * an unknown value of the "compatible" property is encountered.
    123                  */
    124                 architecture = COMPATIBLE_SUN4U;
    125         }
    126 }
    127 
    128 
    129 /**
    130  * Detects the subarchitecture (US, US3) of the sun4u
    131  * processor. Sets the global variables "subarchitecture" and "mid_mask" to
     86 * Sets the global variables "subarchitecture" and "mid_mask" to
    13287 * correct values.
    13388 */
     
    154109}
    155110
    156 /**
    157  * Performs sun4u-specific initialization. The components are expected
    158  * to be already copied and boot allocator initialized.
    159  *
    160  * @param base  kernel base virtual address
    161  * @param top   virtual address above which the boot allocator
    162  *              can make allocations
    163  */
    164 static void bootstrap_sun4u(void *base, unsigned int top)
    165 {
    166         void *balloc_base;
    167         /*
    168          * Claim and map the physical memory for the boot allocator.
    169          * Initialize the boot allocator.
    170          */
    171         balloc_base = base + ALIGN_UP(top, PAGE_SIZE);
    172         (void) ofw_claim_phys(bootinfo.physmem_start + balloc_base,
    173             BALLOC_MAX_SIZE);
    174         (void) ofw_map(bootinfo.physmem_start + balloc_base, balloc_base,
    175             BALLOC_MAX_SIZE, -1);
    176         balloc_init(&bootinfo.ballocs, (uintptr_t) balloc_base,
    177             (uintptr_t) balloc_base);
    178        
    179         printf("Setting up screens...");
    180         ofw_setup_screens();
    181         printf("done.\n");
    182        
    183         printf("Canonizing OpenFirmware device tree...");
    184         bootinfo.ofw_root = ofw_tree_build();
    185         printf("done.\n");
    186        
    187 #ifdef CONFIG_AP
    188         printf("Checking for secondary processors...");
    189         if (!ofw_cpu(mid_mask, bootinfo.physmem_start))
    190                 printf("Error: unable to get CPU properties\n");
    191         printf("done.\n");
    192 #endif
    193 
    194 }
    195 
    196 /**
    197  *  * Performs sun4v-specific initialization. The components are expected
    198  *   * to be already copied and boot allocator initialized.
    199  *    */
    200 static void bootstrap_sun4v(void)
    201 {
    202         /*
    203          * When SILO booted, the OBP had established a virtual to physical
    204          * memory mapping. This mapping is not an identity (because the
    205          * physical memory starts on non-zero address) - this is not
    206          * surprising. But! The mapping even does not map virtual address
    207          * 0 onto the starting address of the physical memory, but onto an
    208          * address which is 0x400000 bytes higher. The reason is that the
    209          * OBP had already used the memory just at the beginning of the
    210          * physical memory, so that memory cannot be used by SILO (nor
    211          * bootloader). As for now, we solve it by a nasty workaround:
    212          * we pretend that the physical memory starts 0x400000 bytes further
    213          * than it actually does (and hence pretend that the physical memory
    214          * is 0x400000 bytes smaller). Of course, the value 0x400000 will most
    215          * probably depend on the machine and OBP version (the workaround now
    216          * works on Simics). A solution would be to inspect the "available"
    217          * property of the "/memory" node to find out which parts of memory
    218          * are used by OBP and redesign the algorithm of copying
    219          * kernel/init tasks/ramdisk from the bootable image to memory
    220          * (which we must do anyway because of issues with claiming the memory
    221          * on Serengeti).
    222          */
    223         bootinfo.physmem_start += 0x400000;
    224         bootinfo.memmap.zones[0].start += 0x400000;
    225         bootinfo.memmap.zones[0].size -= 0x400000;
    226         printf("The sun4v init finished.");
    227 }
    228 
    229 
    230111void bootstrap(void)
    231112{
    232113        void *base = (void *) KERNEL_VIRTUAL_ADDRESS;
     114        void *balloc_base;
    233115        unsigned int top = 0;
    234116        unsigned int i;
    235117        unsigned int j;
    236118       
    237         detect_architecture();
     119        version_print();
     120       
     121        detect_subarchitecture();
    238122        init_components(components);
    239123       
     
    376260        printf("done.\n");
    377261       
    378         /* perform architecture-specific initialization */
    379         if (architecture == COMPATIBLE_SUN4U) {
    380                 bootstrap_sun4u(base, top);
    381         } else if (architecture == COMPATIBLE_SUN4V) {
    382                 bootstrap_sun4v();
    383         } else {
    384                 printf("Unknown architecture.\n");
    385                 halt();
    386         }
     262        /*
     263         * Claim and map the physical memory for the boot allocator.
     264         * Initialize the boot allocator.
     265         */
     266        balloc_base = base + ALIGN_UP(top, PAGE_SIZE);
     267        (void) ofw_claim_phys(bootinfo.physmem_start + balloc_base,
     268            BALLOC_MAX_SIZE);
     269        (void) ofw_map(bootinfo.physmem_start + balloc_base, balloc_base,
     270            BALLOC_MAX_SIZE, -1);
     271        balloc_init(&bootinfo.ballocs, (uintptr_t) balloc_base,
     272            (uintptr_t) balloc_base);
     273       
     274        printf("Setting up screens...");
     275        ofw_setup_screens();
     276        printf("done.\n");
     277       
     278        printf("Canonizing OpenFirmware device tree...");
     279        bootinfo.ofw_root = ofw_tree_build();
     280        printf("done.\n");
     281       
     282#ifdef CONFIG_AP
     283        printf("Checking for secondary processors...");
     284        if (!ofw_cpu(mid_mask, bootinfo.physmem_start))
     285                printf("Error: unable to get CPU properties\n");
     286        printf("done.\n");
     287#endif
    387288       
    388289        printf("Booting the kernel...\n");
  • kernel/arch/sparc64/Makefile.inc

    rb86d436 r3c081d0e  
    4646ifeq ($(PROCESSOR),us)
    4747        DEFS += -DUS
    48         DEFS += -DSUN4U
    49         USARCH = sun4u
    5048endif
    5149
    5250ifeq ($(PROCESSOR),us3)
    5351        DEFS += -DUS3
    54         DEFS += -DSUN4U
    55         USARCH = sun4u
    56 endif
    57 
    58 ifeq ($(PROCESSOR),sun4v)
    59         DEFS += -DSUN4V
    60         USARCH = sun4v
    61 #MH
    62         DEFS += -DUS
    6352endif
    6453
    6554ARCH_SOURCES = \
    66         arch/$(KARCH)/src/cpu/$(USARCH)/cpu.c \
     55        arch/$(KARCH)/src/cpu/cpu.c \
    6756        arch/$(KARCH)/src/debug/stacktrace.c \
    6857        arch/$(KARCH)/src/debug/stacktrace_asm.S \
    6958        arch/$(KARCH)/src/asm.S \
    70         arch/$(KARCH)/src/$(USARCH)/asm.S \
    7159        arch/$(KARCH)/src/panic.S \
    7260        arch/$(KARCH)/src/console.c \
     
    7462        arch/$(KARCH)/src/fpu_context.c \
    7563        arch/$(KARCH)/src/dummy.s \
    76         arch/$(KARCH)/src/mm/$(USARCH)/as.c \
     64        arch/$(KARCH)/src/mm/as.c \
    7765        arch/$(KARCH)/src/mm/cache.S \
    78         arch/$(KARCH)/src/mm/$(USARCH)/frame.c \
     66        arch/$(KARCH)/src/mm/frame.c \
    7967        arch/$(KARCH)/src/mm/page.c \
    80         arch/$(KARCH)/src/mm/$(USARCH)/tlb.c \
    81         arch/$(KARCH)/src/$(USARCH)/sparc64.c \
    82         arch/$(KARCH)/src/$(USARCH)/start.S \
    83         arch/$(KARCH)/src/proc/$(USARCH)/scheduler.c \
     68        arch/$(KARCH)/src/mm/tlb.c \
     69        arch/$(KARCH)/src/sparc64.c \
     70        arch/$(KARCH)/src/start.S \
     71        arch/$(KARCH)/src/proc/scheduler.c \
    8472        arch/$(KARCH)/src/proc/thread.c \
    85         arch/$(KARCH)/src/trap/$(USARCH)/mmu.S \
    86         arch/$(KARCH)/src/trap/$(USARCH)/trap_table.S \
     73        arch/$(KARCH)/src/trap/mmu.S \
     74        arch/$(KARCH)/src/trap/trap_table.S \
    8775        arch/$(KARCH)/src/trap/trap.c \
    8876        arch/$(KARCH)/src/trap/exception.c \
     
    9482        arch/$(KARCH)/src/drivers/pci.c \
    9583        arch/$(KARCH)/src/drivers/fhc.c
    96 
    97 ifeq ($(USARCH),sun4v)
    98         ARCH_SOURCES += \
    99                 arch/$(KARCH)/src/drivers/niagara.c \
    100                 arch/$(KARCH)/src/sun4v/md.c
    101 endif
    10284
    10385ifeq ($(CONFIG_FB),y)
     
    11496ifeq ($(CONFIG_TSB),y)
    11597        ARCH_SOURCES += \
    116                 arch/$(KARCH)/src/mm/$(USARCH)/tsb.c
     98                arch/$(KARCH)/src/mm/tsb.c
    11799endif
  • kernel/arch/sparc64/include/arch.h

    rb86d436 r3c081d0e  
    3838#define KERN_sparc64_ARCH_H_
    3939
    40 #if defined (SUN4U)
    41 #include <arch/sun4u/arch.h>
    42 #elif defined (SUN4V)
    43 #include <arch/sun4v/arch.h>
    44 #endif
    45 
    4640#define ASI_AIUP                0x10    /** Access to primary context with user privileges. */
    4741#define ASI_AIUS                0x11    /** Access to secondary context with user privileges. */
     42#define ASI_NUCLEUS_QUAD_LDD    0x24    /** ASI for 16-byte atomic loads. */
     43#define ASI_DCACHE_TAG          0x47    /** ASI D-Cache Tag. */
     44#define ASI_ICBUS_CONFIG                0x4a    /** ASI of the UPA_CONFIG/FIREPLANE_CONFIG register. */
    4845
    4946#define NWINDOWS                8       /** Number of register window sets. */
     
    5552#endif /* __ASM__ */
    5653
    57 
    5854#endif
    5955
  • kernel/arch/sparc64/include/cpu.h

    rb86d436 r3c081d0e  
    6464#endif
    6565
     66typedef struct {
     67        uint32_t mid;                   /**< Processor ID as read from
     68                                             UPA_CONFIG/FIREPLANE_CONFIG. */
     69        ver_reg_t ver;
     70        uint32_t clock_frequency;       /**< Processor frequency in Hz. */
     71        uint64_t next_tick_cmpr;        /**< Next clock interrupt should be
     72                                             generated when the TICK register
     73                                             matches this value. */
     74} cpu_arch_t;
    6675
    67 #if defined (SUN4U)
    68 #include <arch/sun4u/cpu.h>
    69 #elif defined (SUN4V)
    70 #include <arch/sun4v/cpu.h>
     76
     77/**
     78 * Reads the module ID (agent ID/CPUID) of the current CPU.
     79 */
     80static inline uint32_t read_mid(void)
     81{
     82        uint64_t icbus_config = asi_u64_read(ASI_ICBUS_CONFIG, 0);
     83        icbus_config = icbus_config >> ICBUS_CONFIG_MID_SHIFT;
     84#if defined (US)
     85        return icbus_config & 0x1f;
     86#elif defined (US3)
     87        if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIII_I)
     88                return icbus_config & 0x1f;
     89        else
     90                return icbus_config & 0x3ff;
    7191#endif
    72 
     92}
    7393
    7494#endif 
  • kernel/arch/sparc64/include/drivers/tick.h

    rb86d436 r3c081d0e  
    3636#define KERN_sparc64_TICK_H_
    3737
    38 #include <arch/asm.h>
    3938#include <arch/interrupt.h>
    40 
    41 /* mask of the "counter" field of the Tick register */
    42 #define TICK_COUNTER_MASK       (~(1l << 63))
    4339
    4440extern void tick_init(void);
    4541extern void tick_interrupt(int n, istate_t *istate);
    46 
    47 /**
    48  * Reads the Tick register counter.
    49  */
    50 static inline uint64_t tick_counter_read(void)
    51 {
    52         return TICK_COUNTER_MASK & tick_read();
    53 }
    5442
    5543#endif
  • kernel/arch/sparc64/include/mm/frame.h

    rb86d436 r3c081d0e  
    3636#define KERN_sparc64_FRAME_H_
    3737
    38 #if defined (SUN4U)
    39 #include <arch/mm/sun4u/frame.h>
    40 #elif defined (SUN4V)
    41 #include <arch/mm/sun4v/frame.h>
     38/*
     39 * Page size supported by the MMU.
     40 * For 8K there is the nasty illegal virtual aliasing problem.
     41 * Therefore, the kernel uses 8K only internally on the TLB and TSB levels.
     42 */
     43#define MMU_FRAME_WIDTH         13      /* 8K */
     44#define MMU_FRAME_SIZE          (1 << MMU_FRAME_WIDTH)
     45
     46/*
     47 * Page size exported to the generic memory management subsystems.
     48 * This page size is not directly supported by the MMU, but we can emulate
     49 * each 16K page with a pair of adjacent 8K pages.
     50 */
     51#define FRAME_WIDTH             14      /* 16K */
     52#define FRAME_SIZE              (1 << FRAME_WIDTH)
     53
     54#ifdef KERNEL
     55#ifndef __ASM__
     56
     57#include <arch/types.h>
     58
     59union frame_address {
     60        uintptr_t address;
     61        struct {
     62#if defined (US)
     63                unsigned : 23;
     64                uint64_t pfn : 28;              /**< Physical Frame Number. */
     65#elif defined (US3)
     66                unsigned : 21;
     67                uint64_t pfn : 30;              /**< Physical Frame Number. */
     68#endif
     69                unsigned offset : 13;           /**< Offset. */
     70        } __attribute__ ((packed));
     71};
     72
     73typedef union frame_address frame_address_t;
     74
     75extern uintptr_t last_frame;
     76extern uintptr_t end_of_identity;
     77
     78extern void frame_arch_init(void);
     79#define physmem_print()
     80
     81#endif
    4282#endif
    4383
  • kernel/arch/sparc64/include/mm/mmu.h

    rb86d436 r3c081d0e  
    3636#define KERN_sparc64_MMU_H_
    3737
    38 #if defined (SUN4U)
    39 #include <arch/mm/sun4u/mmu.h>
    40 #elif defined (SUN4V)
    41 #include <arch/mm/sun4v/mmu.h>
     38#if defined(US)
     39/* LSU Control Register ASI. */
     40#define ASI_LSU_CONTROL_REG             0x45    /**< Load/Store Unit Control Register. */
    4241#endif
    4342
     43/* I-MMU ASIs. */
     44#define ASI_IMMU                        0x50
     45#define ASI_IMMU_TSB_8KB_PTR_REG        0x51   
     46#define ASI_IMMU_TSB_64KB_PTR_REG       0x52
     47#define ASI_ITLB_DATA_IN_REG            0x54
     48#define ASI_ITLB_DATA_ACCESS_REG        0x55
     49#define ASI_ITLB_TAG_READ_REG           0x56
     50#define ASI_IMMU_DEMAP                  0x57
     51
     52/* Virtual Addresses within ASI_IMMU. */
     53#define VA_IMMU_TSB_TAG_TARGET          0x0     /**< IMMU TSB tag target register. */
     54#define VA_IMMU_SFSR                    0x18    /**< IMMU sync fault status register. */
     55#define VA_IMMU_TSB_BASE                0x28    /**< IMMU TSB base register. */
     56#define VA_IMMU_TAG_ACCESS              0x30    /**< IMMU TLB tag access register. */
     57#if defined (US3)
     58#define VA_IMMU_PRIMARY_EXTENSION       0x48    /**< IMMU TSB primary extension register */
     59#define VA_IMMU_NUCLEUS_EXTENSION       0x58    /**< IMMU TSB nucleus extension register */
     60#endif
     61
     62
     63/* D-MMU ASIs. */
     64#define ASI_DMMU                        0x58
     65#define ASI_DMMU_TSB_8KB_PTR_REG        0x59   
     66#define ASI_DMMU_TSB_64KB_PTR_REG       0x5a
     67#define ASI_DMMU_TSB_DIRECT_PTR_REG     0x5b
     68#define ASI_DTLB_DATA_IN_REG            0x5c
     69#define ASI_DTLB_DATA_ACCESS_REG        0x5d
     70#define ASI_DTLB_TAG_READ_REG           0x5e
     71#define ASI_DMMU_DEMAP                  0x5f
     72
     73/* Virtual Addresses within ASI_DMMU. */
     74#define VA_DMMU_TSB_TAG_TARGET          0x0     /**< DMMU TSB tag target register. */
     75#define VA_PRIMARY_CONTEXT_REG          0x8     /**< DMMU primary context register. */
     76#define VA_SECONDARY_CONTEXT_REG        0x10    /**< DMMU secondary context register. */
     77#define VA_DMMU_SFSR                    0x18    /**< DMMU sync fault status register. */
     78#define VA_DMMU_SFAR                    0x20    /**< DMMU sync fault address register. */
     79#define VA_DMMU_TSB_BASE                0x28    /**< DMMU TSB base register. */
     80#define VA_DMMU_TAG_ACCESS              0x30    /**< DMMU TLB tag access register. */
     81#define VA_DMMU_VA_WATCHPOINT_REG       0x38    /**< DMMU VA data watchpoint register. */
     82#define VA_DMMU_PA_WATCHPOINT_REG       0x40    /**< DMMU PA data watchpoint register. */
     83#if defined (US3)
     84#define VA_DMMU_PRIMARY_EXTENSION       0x48    /**< DMMU TSB primary extension register */
     85#define VA_DMMU_SECONDARY_EXTENSION     0x50    /**< DMMU TSB secondary extension register */
     86#define VA_DMMU_NUCLEUS_EXTENSION       0x58    /**< DMMU TSB nucleus extension register */
     87#endif
     88
     89#ifndef __ASM__
     90
     91#include <arch/asm.h>
     92#include <arch/barrier.h>
     93#include <arch/types.h>
     94
     95#if defined(US)
     96/** LSU Control Register. */
     97typedef union {
     98        uint64_t value;
     99        struct {
     100                unsigned : 23;
     101                unsigned pm : 8;
     102                unsigned vm : 8;
     103                unsigned pr : 1;
     104                unsigned pw : 1;
     105                unsigned vr : 1;
     106                unsigned vw : 1;
     107                unsigned : 1;
     108                unsigned fm : 16;       
     109                unsigned dm : 1;        /**< D-MMU enable. */
     110                unsigned im : 1;        /**< I-MMU enable. */
     111                unsigned dc : 1;        /**< D-Cache enable. */
     112                unsigned ic : 1;        /**< I-Cache enable. */
     113               
     114        } __attribute__ ((packed));
     115} lsu_cr_reg_t;
     116#endif /* US */
     117
     118#endif /* !def __ASM__ */
    44119
    45120#endif
  • kernel/arch/sparc64/include/mm/tlb.h

    rb86d436 r3c081d0e  
    3636#define KERN_sparc64_TLB_H_
    3737
    38 #if defined (SUN4U)
    39 #include <arch/mm/sun4u/tlb.h>
    40 #elif defined (SUN4V)
    41 #include <arch/mm/sun4v/tlb.h>
    42 #endif
     38#if defined (US)
     39#define ITLB_ENTRY_COUNT                64
     40#define DTLB_ENTRY_COUNT                64
     41#define DTLB_MAX_LOCKED_ENTRIES         DTLB_ENTRY_COUNT
     42#endif
     43
     44/** TLB_DSMALL is the only of the three DMMUs that can hold locked entries. */
     45#if defined (US3)
     46#define DTLB_MAX_LOCKED_ENTRIES         16
     47#endif
     48
     49#define MEM_CONTEXT_KERNEL              0
     50#define MEM_CONTEXT_TEMP                1
     51
     52/** Page sizes. */
     53#define PAGESIZE_8K     0
     54#define PAGESIZE_64K    1
     55#define PAGESIZE_512K   2
     56#define PAGESIZE_4M     3
     57
     58/** Bit width of the TLB-locked portion of kernel address space. */
     59#define KERNEL_PAGE_WIDTH       22      /* 4M */
     60
     61/* TLB Demap Operation types. */
     62#define TLB_DEMAP_PAGE          0
     63#define TLB_DEMAP_CONTEXT       1
     64#if defined (US3)
     65#define TLB_DEMAP_ALL           2
     66#endif
     67
     68#define TLB_DEMAP_TYPE_SHIFT    6
     69
     70/* TLB Demap Operation Context register encodings. */
     71#define TLB_DEMAP_PRIMARY       0
     72#define TLB_DEMAP_SECONDARY     1
     73#define TLB_DEMAP_NUCLEUS       2
     74
     75/* There are more TLBs in one MMU in US3, their codes are defined here. */
     76#if defined (US3)
     77/* D-MMU: one small (16-entry) TLB and two big (512-entry) TLBs */
     78#define TLB_DSMALL      0
     79#define TLB_DBIG_0      2
     80#define TLB_DBIG_1      3
     81       
     82/* I-MMU: one small (16-entry) TLB and one big TLB */
     83#define TLB_ISMALL      0
     84#define TLB_IBIG        2
     85#endif
     86
     87#define TLB_DEMAP_CONTEXT_SHIFT 4
     88
     89/* TLB Tag Access shifts */
     90#define TLB_TAG_ACCESS_CONTEXT_SHIFT    0
     91#define TLB_TAG_ACCESS_CONTEXT_MASK     ((1 << 13) - 1)
     92#define TLB_TAG_ACCESS_VPN_SHIFT        13
     93
     94#ifndef __ASM__
     95
     96#include <arch/mm/tte.h>
     97#include <arch/mm/mmu.h>
     98#include <arch/mm/page.h>
     99#include <arch/asm.h>
     100#include <arch/barrier.h>
     101#include <arch/types.h>
     102#include <arch/register.h>
     103#include <arch/cpu.h>
     104
     105union tlb_context_reg {
     106        uint64_t v;
     107        struct {
     108                unsigned long : 51;
     109                unsigned context : 13;          /**< Context/ASID. */
     110        } __attribute__ ((packed));
     111};
     112typedef union tlb_context_reg tlb_context_reg_t;
     113
     114/** I-/D-TLB Data In/Access Register type. */
     115typedef tte_data_t tlb_data_t;
     116
     117/** I-/D-TLB Data Access Address in Alternate Space. */
     118
     119#if defined (US)
     120
     121union tlb_data_access_addr {
     122        uint64_t value;
     123        struct {
     124                uint64_t : 55;
     125                unsigned tlb_entry : 6;
     126                unsigned : 3;
     127        } __attribute__ ((packed));
     128};
     129typedef union tlb_data_access_addr dtlb_data_access_addr_t;
     130typedef union tlb_data_access_addr dtlb_tag_read_addr_t;
     131typedef union tlb_data_access_addr itlb_data_access_addr_t;
     132typedef union tlb_data_access_addr itlb_tag_read_addr_t;
     133
     134#elif defined (US3)
     135
     136/*
     137 * In US3, I-MMU and D-MMU have different formats of the data
     138 * access register virtual address. In the corresponding
     139 * structures the member variable for the entry number is
     140 * called "local_tlb_entry" - it contrasts with the "tlb_entry"
     141 * for the US data access register VA structure. The rationale
     142 * behind this is to prevent careless mistakes in the code
     143 * caused by setting only the entry number and not the TLB
     144 * number in the US3 code (when taking the code from US).
     145 */
     146
     147union dtlb_data_access_addr {
     148        uint64_t value;
     149        struct {
     150                uint64_t : 45;
     151                unsigned : 1;
     152                unsigned tlb_number : 2;
     153                unsigned : 4;
     154                unsigned local_tlb_entry : 9;
     155                unsigned : 3;
     156        } __attribute__ ((packed));
     157};
     158typedef union dtlb_data_access_addr dtlb_data_access_addr_t;
     159typedef union dtlb_data_access_addr dtlb_tag_read_addr_t;
     160
     161union itlb_data_access_addr {
     162        uint64_t value;
     163        struct {
     164                uint64_t : 45;
     165                unsigned : 1;
     166                unsigned tlb_number : 2;
     167                unsigned : 6;
     168                unsigned local_tlb_entry : 7;
     169                unsigned : 3;
     170        } __attribute__ ((packed));
     171};
     172typedef union itlb_data_access_addr itlb_data_access_addr_t;
     173typedef union itlb_data_access_addr itlb_tag_read_addr_t;
     174
     175#endif
     176
     177/** I-/D-TLB Tag Read Register. */
     178union tlb_tag_read_reg {
     179        uint64_t value;
     180        struct {
     181                uint64_t vpn : 51;      /**< Virtual Address bits 63:13. */
     182                unsigned context : 13;  /**< Context identifier. */
     183        } __attribute__ ((packed));
     184};
     185typedef union tlb_tag_read_reg tlb_tag_read_reg_t;
     186typedef union tlb_tag_read_reg tlb_tag_access_reg_t;
     187
     188
     189/** TLB Demap Operation Address. */
     190union tlb_demap_addr {
     191        uint64_t value;
     192        struct {
     193                uint64_t vpn: 51;       /**< Virtual Address bits 63:13. */
     194#if defined (US)
     195                unsigned : 6;           /**< Ignored. */
     196                unsigned type : 1;      /**< The type of demap operation. */
     197#elif defined (US3)
     198                unsigned : 5;           /**< Ignored. */
     199                unsigned type: 2;       /**< The type of demap operation. */
     200#endif
     201                unsigned context : 2;   /**< Context register selection. */
     202                unsigned : 4;           /**< Zero. */
     203        } __attribute__ ((packed));
     204};
     205typedef union tlb_demap_addr tlb_demap_addr_t;
     206
     207/** TLB Synchronous Fault Status Register. */
     208union tlb_sfsr_reg {
     209        uint64_t value;
     210        struct {
     211#if defined (US)
     212                unsigned long : 40;     /**< Implementation dependent. */
     213                unsigned asi : 8;       /**< ASI. */
     214                unsigned : 2;
     215                unsigned ft : 7;        /**< Fault type. */
     216#elif defined (US3)
     217                unsigned long : 39;     /**< Implementation dependent. */
     218                unsigned nf : 1;        /**< Non-faulting load. */
     219                unsigned asi : 8;       /**< ASI. */
     220                unsigned tm : 1;        /**< I-TLB miss. */
     221                unsigned : 3;           /**< Reserved. */
     222                unsigned ft : 5;        /**< Fault type. */
     223#endif
     224                unsigned e : 1;         /**< Side-effect bit. */
     225                unsigned ct : 2;        /**< Context Register selection. */
     226                unsigned pr : 1;        /**< Privilege bit. */
     227                unsigned w : 1;         /**< Write bit. */
     228                unsigned ow : 1;        /**< Overwrite bit. */
     229                unsigned fv : 1;        /**< Fault Valid bit. */
     230        } __attribute__ ((packed));
     231};
     232typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
     233
     234#if defined (US3)
     235
     236/*
     237 * Functions for determining the number of entries in TLBs. They either return
     238 * a constant value or a value based on the CPU autodetection.
     239 */
     240
     241/**
     242 * Determine the number of entries in the DMMU's small TLB.
     243 */
     244static inline uint16_t tlb_dsmall_size(void)
     245{
     246        return 16;
     247}
     248
     249/**
     250 * Determine the number of entries in each DMMU's big TLB.
     251 */
     252static inline uint16_t tlb_dbig_size(void)
     253{
     254        return 512;
     255}
     256
     257/**
     258 * Determine the number of entries in the IMMU's small TLB.
     259 */
     260static inline uint16_t tlb_ismall_size(void)
     261{
     262        return 16;
     263}
     264
     265/**
     266 * Determine the number of entries in the IMMU's big TLB.
     267 */
     268static inline uint16_t tlb_ibig_size(void)
     269{
     270        if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIV_PLUS)
     271                return 512;
     272        else
     273                return 128;
     274}
     275
     276#endif
     277
     278/** Read MMU Primary Context Register.
     279 *
     280 * @return              Current value of Primary Context Register.
     281 */
     282static inline uint64_t mmu_primary_context_read(void)
     283{
     284        return asi_u64_read(ASI_DMMU, VA_PRIMARY_CONTEXT_REG);
     285}
     286
     287/** Write MMU Primary Context Register.
     288 *
     289 * @param v             New value of Primary Context Register.
     290 */
     291static inline void mmu_primary_context_write(uint64_t v)
     292{
     293        asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
     294        flush_pipeline();
     295}
     296
     297/** Read MMU Secondary Context Register.
     298 *
     299 * @return              Current value of Secondary Context Register.
     300 */
     301static inline uint64_t mmu_secondary_context_read(void)
     302{
     303        return asi_u64_read(ASI_DMMU, VA_SECONDARY_CONTEXT_REG);
     304}
     305
     306/** Write MMU Primary Context Register.
     307 *
     308 * @param v             New value of Primary Context Register.
     309 */
     310static inline void mmu_secondary_context_write(uint64_t v)
     311{
     312        asi_u64_write(ASI_DMMU, VA_SECONDARY_CONTEXT_REG, v);
     313        flush_pipeline();
     314}
     315
     316#if defined (US)
     317
     318/** Read IMMU TLB Data Access Register.
     319 *
     320 * @param entry         TLB Entry index.
     321 *
     322 * @return              Current value of specified IMMU TLB Data Access
     323 *                      Register.
     324 */
     325static inline uint64_t itlb_data_access_read(size_t entry)
     326{
     327        itlb_data_access_addr_t reg;
     328       
     329        reg.value = 0;
     330        reg.tlb_entry = entry;
     331        return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
     332}
     333
     334/** Write IMMU TLB Data Access Register.
     335 *
     336 * @param entry         TLB Entry index.
     337 * @param value         Value to be written.
     338 */
     339static inline void itlb_data_access_write(size_t entry, uint64_t value)
     340{
     341        itlb_data_access_addr_t reg;
     342       
     343        reg.value = 0;
     344        reg.tlb_entry = entry;
     345        asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
     346        flush_pipeline();
     347}
     348
     349/** Read DMMU TLB Data Access Register.
     350 *
     351 * @param entry         TLB Entry index.
     352 *
     353 * @return              Current value of specified DMMU TLB Data Access
     354 *                      Register.
     355 */
     356static inline uint64_t dtlb_data_access_read(size_t entry)
     357{
     358        dtlb_data_access_addr_t reg;
     359       
     360        reg.value = 0;
     361        reg.tlb_entry = entry;
     362        return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
     363}
     364
     365/** Write DMMU TLB Data Access Register.
     366 *
     367 * @param entry         TLB Entry index.
     368 * @param value         Value to be written.
     369 */
     370static inline void dtlb_data_access_write(size_t entry, uint64_t value)
     371{
     372        dtlb_data_access_addr_t reg;
     373       
     374        reg.value = 0;
     375        reg.tlb_entry = entry;
     376        asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
     377        membar();
     378}
     379
     380/** Read IMMU TLB Tag Read Register.
     381 *
     382 * @param entry         TLB Entry index.
     383 *
     384 * @return              Current value of specified IMMU TLB Tag Read Register.
     385 */
     386static inline uint64_t itlb_tag_read_read(size_t entry)
     387{
     388        itlb_tag_read_addr_t tag;
     389
     390        tag.value = 0;
     391        tag.tlb_entry = entry;
     392        return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
     393}
     394
     395/** Read DMMU TLB Tag Read Register.
     396 *
     397 * @param entry         TLB Entry index.
     398 *
     399 * @return              Current value of specified DMMU TLB Tag Read Register.
     400 */
     401static inline uint64_t dtlb_tag_read_read(size_t entry)
     402{
     403        dtlb_tag_read_addr_t tag;
     404
     405        tag.value = 0;
     406        tag.tlb_entry = entry;
     407        return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
     408}
     409
     410#elif defined (US3)
     411
     412
     413/** Read IMMU TLB Data Access Register.
     414 *
     415 * @param tlb           TLB number (one of TLB_ISMALL or TLB_IBIG)
     416 * @param entry         TLB Entry index.
     417 *
     418 * @return              Current value of specified IMMU TLB Data Access
     419 *                      Register.
     420 */
     421static inline uint64_t itlb_data_access_read(int tlb, size_t entry)
     422{
     423        itlb_data_access_addr_t reg;
     424       
     425        reg.value = 0;
     426        reg.tlb_number = tlb;
     427        reg.local_tlb_entry = entry;
     428        return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
     429}
     430
     431/** Write IMMU TLB Data Access Register.
     432 * @param tlb           TLB number (one of TLB_ISMALL or TLB_IBIG)
     433 * @param entry         TLB Entry index.
     434 * @param value         Value to be written.
     435 */
     436static inline void itlb_data_access_write(int tlb, size_t entry,
     437        uint64_t value)
     438{
     439        itlb_data_access_addr_t reg;
     440       
     441        reg.value = 0;
     442        reg.tlb_number = tlb;
     443        reg.local_tlb_entry = entry;
     444        asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
     445        flush_pipeline();
     446}
     447
     448/** Read DMMU TLB Data Access Register.
     449 *
     450 * @param tlb           TLB number (one of TLB_DSMALL, TLB_DBIG, TLB_DBIG)
     451 * @param entry         TLB Entry index.
     452 *
     453 * @return              Current value of specified DMMU TLB Data Access
     454 *                      Register.
     455 */
     456static inline uint64_t dtlb_data_access_read(int tlb, size_t entry)
     457{
     458        dtlb_data_access_addr_t reg;
     459       
     460        reg.value = 0;
     461        reg.tlb_number = tlb;
     462        reg.local_tlb_entry = entry;
     463        return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
     464}
     465
     466/** Write DMMU TLB Data Access Register.
     467 *
     468 * @param tlb           TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1) 
     469 * @param entry         TLB Entry index.
     470 * @param value         Value to be written.
     471 */
     472static inline void dtlb_data_access_write(int tlb, size_t entry,
     473        uint64_t value)
     474{
     475        dtlb_data_access_addr_t reg;
     476       
     477        reg.value = 0;
     478        reg.tlb_number = tlb;
     479        reg.local_tlb_entry = entry;
     480        asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
     481        membar();
     482}
     483
     484/** Read IMMU TLB Tag Read Register.
     485 *
     486 * @param tlb           TLB number (one of TLB_ISMALL or TLB_IBIG)
     487 * @param entry         TLB Entry index.
     488 *
     489 * @return              Current value of specified IMMU TLB Tag Read Register.
     490 */
     491static inline uint64_t itlb_tag_read_read(int tlb, size_t entry)
     492{
     493        itlb_tag_read_addr_t tag;
     494
     495        tag.value = 0;
     496        tag.tlb_number = tlb;
     497        tag.local_tlb_entry = entry;
     498        return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
     499}
     500
     501/** Read DMMU TLB Tag Read Register.
     502 *
     503 * @param tlb           TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1)
     504 * @param entry         TLB Entry index.
     505 *
     506 * @return              Current value of specified DMMU TLB Tag Read Register.
     507 */
     508static inline uint64_t dtlb_tag_read_read(int tlb, size_t entry)
     509{
     510        dtlb_tag_read_addr_t tag;
     511
     512        tag.value = 0;
     513        tag.tlb_number = tlb;
     514        tag.local_tlb_entry = entry;
     515        return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
     516}
     517
     518#endif
     519
     520
     521/** Write IMMU TLB Tag Access Register.
     522 *
     523 * @param v             Value to be written.
     524 */
     525static inline void itlb_tag_access_write(uint64_t v)
     526{
     527        asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v);
     528        flush_pipeline();
     529}
     530
     531/** Read IMMU TLB Tag Access Register.
     532 *
     533 * @return              Current value of IMMU TLB Tag Access Register.
     534 */
     535static inline uint64_t itlb_tag_access_read(void)
     536{
     537        return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS);
     538}
     539
     540/** Write DMMU TLB Tag Access Register.
     541 *
     542 * @param v             Value to be written.
     543 */
     544static inline void dtlb_tag_access_write(uint64_t v)
     545{
     546        asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v);
     547        membar();
     548}
     549
     550/** Read DMMU TLB Tag Access Register.
     551 *
     552 * @return              Current value of DMMU TLB Tag Access Register.
     553 */
     554static inline uint64_t dtlb_tag_access_read(void)
     555{
     556        return asi_u64_read(ASI_DMMU, VA_DMMU_TAG_ACCESS);
     557}
     558
     559
     560/** Write IMMU TLB Data in Register.
     561 *
     562 * @param v             Value to be written.
     563 */
     564static inline void itlb_data_in_write(uint64_t v)
     565{
     566        asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v);
     567        flush_pipeline();
     568}
     569
     570/** Write DMMU TLB Data in Register.
     571 *
     572 * @param v             Value to be written.
     573 */
     574static inline void dtlb_data_in_write(uint64_t v)
     575{
     576        asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v);
     577        membar();
     578}
     579
     580/** Read ITLB Synchronous Fault Status Register.
     581 *
     582 * @return              Current content of I-SFSR register.
     583 */
     584static inline uint64_t itlb_sfsr_read(void)
     585{
     586        return asi_u64_read(ASI_IMMU, VA_IMMU_SFSR);
     587}
     588
     589/** Write ITLB Synchronous Fault Status Register.
     590 *
     591 * @param v             New value of I-SFSR register.
     592 */
     593static inline void itlb_sfsr_write(uint64_t v)
     594{
     595        asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v);
     596        flush_pipeline();
     597}
     598
     599/** Read DTLB Synchronous Fault Status Register.
     600 *
     601 * @return              Current content of D-SFSR register.
     602 */
     603static inline uint64_t dtlb_sfsr_read(void)
     604{
     605        return asi_u64_read(ASI_DMMU, VA_DMMU_SFSR);
     606}
     607
     608/** Write DTLB Synchronous Fault Status Register.
     609 *
     610 * @param v             New value of D-SFSR register.
     611 */
     612static inline void dtlb_sfsr_write(uint64_t v)
     613{
     614        asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
     615        membar();
     616}
     617
     618/** Read DTLB Synchronous Fault Address Register.
     619 *
     620 * @return              Current content of D-SFAR register.
     621 */
     622static inline uint64_t dtlb_sfar_read(void)
     623{
     624        return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR);
     625}
     626
     627/** Perform IMMU TLB Demap Operation.
     628 *
     629 * @param type          Selects between context and page demap (and entire MMU
     630 *                      demap on US3).
     631 * @param context_encoding Specifies which Context register has Context ID for
     632 *                      demap.
     633 * @param page          Address which is on the page to be demapped.
     634 */
     635static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
     636{
     637        tlb_demap_addr_t da;
     638        page_address_t pg;
     639       
     640        da.value = 0;
     641        pg.address = page;
     642       
     643        da.type = type;
     644        da.context = context_encoding;
     645        da.vpn = pg.vpn;
     646       
     647        /* da.value is the address within the ASI */
     648        asi_u64_write(ASI_IMMU_DEMAP, da.value, 0);
     649
     650        flush_pipeline();
     651}
     652
     653/** Perform DMMU TLB Demap Operation.
     654 *
     655 * @param type          Selects between context and page demap (and entire MMU
     656 *                      demap on US3).
     657 * @param context_encoding Specifies which Context register has Context ID for
     658 *                      demap.
     659 * @param page          Address which is on the page to be demapped.
     660 */
     661static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
     662{
     663        tlb_demap_addr_t da;
     664        page_address_t pg;
     665       
     666        da.value = 0;
     667        pg.address = page;
     668       
     669        da.type = type;
     670        da.context = context_encoding;
     671        da.vpn = pg.vpn;
     672       
     673        /* da.value is the address within the ASI */
     674        asi_u64_write(ASI_DMMU_DEMAP, da.value, 0);
     675
     676        membar();
     677}
     678
     679extern void fast_instruction_access_mmu_miss(unative_t, istate_t *);
     680extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t, istate_t *);
     681extern void fast_data_access_protection(tlb_tag_access_reg_t , istate_t *);
     682
     683extern void dtlb_insert_mapping(uintptr_t, uintptr_t, int, bool, bool);
     684
     685extern void dump_sfsr_and_sfar(void);
     686
     687#endif /* !def __ASM__ */
    43688
    44689#endif
  • kernel/arch/sparc64/include/mm/tte.h

    rb86d436 r3c081d0e  
    3636#define KERN_sparc64_TTE_H_
    3737
    38 #if defined (SUN4U)
    39 #include <arch/mm/sun4u/tte.h>
    40 #elif defined (SUN4V)
    41 #include <arch/mm/sun4v/tte.h>
     38#define TTE_G           (1 << 0)
     39#define TTE_W           (1 << 1)
     40#define TTE_P           (1 << 2)
     41#define TTE_E           (1 << 3)
     42#define TTE_CV          (1 << 4)
     43#define TTE_CP          (1 << 5)
     44#define TTE_L           (1 << 6)
     45
     46#define TTE_V_SHIFT     63
     47#define TTE_SIZE_SHIFT  61
     48
     49#ifndef __ASM__
     50
     51#include <arch/types.h>
     52
     53/* TTE tag's VA_tag field contains bits <63:VA_TAG_PAGE_SHIFT> of the VA */
     54#define VA_TAG_PAGE_SHIFT       22
     55
     56/** Translation Table Entry - Tag. */
     57union tte_tag {
     58        uint64_t value;
     59        struct {
     60                unsigned g : 1;         /**< Global. */
     61                unsigned : 2;           /**< Reserved. */
     62                unsigned context : 13;  /**< Context identifier. */
     63                unsigned : 6;           /**< Reserved. */
     64                uint64_t va_tag : 42;   /**< Virtual Address Tag, bits 63:22. */
     65        } __attribute__ ((packed));
     66};
     67
     68typedef union tte_tag tte_tag_t;
     69
     70/** Translation Table Entry - Data. */
     71union tte_data {
     72        uint64_t value;
     73        struct {
     74                unsigned v : 1;         /**< Valid. */
     75                unsigned size : 2;      /**< Page size of this entry. */
     76                unsigned nfo : 1;       /**< No-Fault-Only. */
     77                unsigned ie : 1;        /**< Invert Endianness. */
     78                unsigned soft2 : 9;     /**< Software defined field. */
     79#if defined (US)
     80                unsigned diag : 9;      /**< Diagnostic data. */
     81                unsigned pfn : 28;      /**< Physical Address bits, bits 40:13. */
     82#elif defined (US3)
     83                unsigned : 7;           /**< Reserved. */
     84                unsigned pfn : 30;      /**< Physical Address bits, bits 42:13 */
    4285#endif
     86                unsigned soft : 6;      /**< Software defined field. */
     87                unsigned l : 1;         /**< Lock. */
     88                unsigned cp : 1;        /**< Cacheable in physically indexed cache. */
     89                unsigned cv : 1;        /**< Cacheable in virtually indexed cache. */
     90                unsigned e : 1;         /**< Side-effect. */
     91                unsigned p : 1;         /**< Privileged. */
     92                unsigned w : 1;         /**< Writable. */
     93                unsigned g : 1;         /**< Global. */
     94        } __attribute__ ((packed));
     95};
     96
     97typedef union tte_data tte_data_t;
     98
     99#endif /* !def __ASM__ */
    43100
    44101#endif
  • kernel/arch/sparc64/include/trap/mmu.h

    rb86d436 r3c081d0e  
    3838#define KERN_sparc64_MMU_TRAP_H_
    3939
    40 #if defined (SUN4U)
    41 #include <arch/trap/sun4u/mmu.h>
    42 #elif defined (SUN4V)
    43 #include <arch/trap/sun4v/mmu.h>
     40#include <arch/stack.h>
     41#include <arch/regdef.h>
     42#include <arch/mm/tlb.h>
     43#include <arch/mm/mmu.h>
     44#include <arch/mm/tte.h>
     45#include <arch/trap/regwin.h>
     46
     47#ifdef CONFIG_TSB
     48#include <arch/mm/tsb.h>
    4449#endif
     50
     51#define TT_FAST_INSTRUCTION_ACCESS_MMU_MISS     0x64
     52#define TT_FAST_DATA_ACCESS_MMU_MISS            0x68
     53#define TT_FAST_DATA_ACCESS_PROTECTION          0x6c
     54
     55#define FAST_MMU_HANDLER_SIZE                   128
     56
     57#ifdef __ASM__
     58
     59.macro FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
     60        /*
     61         * First, try to refill TLB from TSB.
     62         */
     63#ifdef CONFIG_TSB
     64        ldxa [%g0] ASI_IMMU, %g1                        ! read TSB Tag Target Register
     65        ldxa [%g0] ASI_IMMU_TSB_8KB_PTR_REG, %g2        ! read TSB 8K Pointer
     66        ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %g4            ! 16-byte atomic load into %g4 and %g5
     67        cmp %g1, %g4                                    ! is this the entry we are looking for?
     68        bne,pn %xcc, 0f
     69        nop
     70        stxa %g5, [%g0] ASI_ITLB_DATA_IN_REG            ! copy mapping from ITSB to ITLB
     71        retry
     72#endif
     73
     740:
     75        wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
     76        PREEMPTIBLE_HANDLER fast_instruction_access_mmu_miss
     77.endm
     78
     79.macro FAST_DATA_ACCESS_MMU_MISS_HANDLER tl
     80        /*
     81         * First, try to refill TLB from TSB.
     82         */
     83
     84#ifdef CONFIG_TSB
     85        ldxa [%g0] ASI_DMMU, %g1                        ! read TSB Tag Target Register
     86        srlx %g1, TSB_TAG_TARGET_CONTEXT_SHIFT, %g2     ! is this a kernel miss?
     87        brz,pn %g2, 0f
     88        ldxa [%g0] ASI_DMMU_TSB_8KB_PTR_REG, %g3        ! read TSB 8K Pointer
     89        ldda [%g3] ASI_NUCLEUS_QUAD_LDD, %g4            ! 16-byte atomic load into %g4 and %g5
     90        cmp %g1, %g4                                    ! is this the entry we are looking for?
     91        bne,pn %xcc, 0f
     92        nop
     93        stxa %g5, [%g0] ASI_DTLB_DATA_IN_REG            ! copy mapping from DTSB to DTLB
     94        retry
     95#endif
     96
     97        /*
     98         * Second, test if it is the portion of the kernel address space
     99         * which is faulting. If that is the case, immediately create
     100         * identity mapping for that page in DTLB. VPN 0 is excluded from
     101         * this treatment.
     102         *
     103         * Note that branch-delay slots are used in order to save space.
     104         */
     1050:
     106        sethi %hi(fast_data_access_mmu_miss_data_hi), %g7
     107        wr %g0, ASI_DMMU, %asi
     108        ldxa [VA_DMMU_TAG_ACCESS] %asi, %g1             ! read the faulting Context and VPN
     109        set TLB_TAG_ACCESS_CONTEXT_MASK, %g2
     110        andcc %g1, %g2, %g3                             ! get Context
     111        bnz %xcc, 0f                                    ! Context is non-zero
     112        andncc %g1, %g2, %g3                            ! get page address into %g3
     113        bz  %xcc, 0f                                    ! page address is zero
     114        ldx [%g7 + %lo(end_of_identity)], %g4
     115        cmp %g3, %g4
     116        bgeu %xcc, 0f
     117
     118        ldx [%g7 + %lo(kernel_8k_tlb_data_template)], %g2
     119        add %g3, %g2, %g2
     120        stxa %g2, [%g0] ASI_DTLB_DATA_IN_REG            ! identity map the kernel page
     121        retry
     122
     123        /*
     124         * Third, catch and handle special cases when the trap is caused by
     125         * the userspace register window spill or fill handler. In case
     126         * one of these two traps caused this trap, we just lower the trap
     127         * level and service the DTLB miss. In the end, we restart
     128         * the offending SAVE or RESTORE.
     129         */
     1300:
     131.if (\tl > 0)
     132        wrpr %g0, 1, %tl
     133.endif
     134
     135        /*
     136         * Switch from the MM globals.
     137         */
     138        wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
     139
     140        /*
     141         * Read the Tag Access register for the higher-level handler.
     142         * This is necessary to survive nested DTLB misses.
     143         */     
     144        ldxa [VA_DMMU_TAG_ACCESS] %asi, %g2
     145
     146        /*
     147         * g2 will be passed as an argument to fast_data_access_mmu_miss().
     148         */
     149        PREEMPTIBLE_HANDLER fast_data_access_mmu_miss
     150.endm
     151
     152.macro FAST_DATA_ACCESS_PROTECTION_HANDLER tl
     153        /*
     154         * The same special case as in FAST_DATA_ACCESS_MMU_MISS_HANDLER.
     155         */
     156
     157.if (\tl > 0)
     158        wrpr %g0, 1, %tl
     159.endif
     160
     161        /*
     162         * Switch from the MM globals.
     163         */
     164        wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
     165
     166        /*
     167         * Read the Tag Access register for the higher-level handler.
     168         * This is necessary to survive nested DTLB misses.
     169         */     
     170        mov VA_DMMU_TAG_ACCESS, %g2
     171        ldxa [%g2] ASI_DMMU, %g2
     172
     173        /*
     174         * g2 will be passed as an argument to fast_data_access_mmu_miss().
     175         */
     176        PREEMPTIBLE_HANDLER fast_data_access_protection
     177.endm
     178
     179#endif /* __ASM__ */
    45180
    46181#endif
  • kernel/arch/sparc64/include/trap/regwin.h

    rb86d436 r3c081d0e  
    131131
    132132/*
     133 * Macro used to spill userspace window to userspace window buffer.
     134 * It can be either triggered from preemptible_handler doing SAVE
     135 * at (TL=1) or from normal kernel code doing SAVE when OTHERWIN>0
     136 * at (TL=0).
     137 */
     138.macro SPILL_TO_USPACE_WINDOW_BUFFER
     139        stx %l0, [%g7 + L0_OFFSET]     
     140        stx %l1, [%g7 + L1_OFFSET]
     141        stx %l2, [%g7 + L2_OFFSET]
     142        stx %l3, [%g7 + L3_OFFSET]
     143        stx %l4, [%g7 + L4_OFFSET]
     144        stx %l5, [%g7 + L5_OFFSET]
     145        stx %l6, [%g7 + L6_OFFSET]
     146        stx %l7, [%g7 + L7_OFFSET]
     147        stx %i0, [%g7 + I0_OFFSET]
     148        stx %i1, [%g7 + I1_OFFSET]
     149        stx %i2, [%g7 + I2_OFFSET]
     150        stx %i3, [%g7 + I3_OFFSET]
     151        stx %i4, [%g7 + I4_OFFSET]
     152        stx %i5, [%g7 + I5_OFFSET]
     153        stx %i6, [%g7 + I6_OFFSET]
     154        stx %i7, [%g7 + I7_OFFSET]
     155        add %g7, STACK_WINDOW_SAVE_AREA_SIZE, %g7
     156        saved
     157        retry
     158.endm
     159
     160
     161/*
    133162 * Macro used by the nucleus and the primary context 0 during normal fills.
    134163 */
     
    203232#endif /* __ASM__ */
    204233
    205 #if defined (SUN4U)
    206 #include <arch/trap/sun4u/regwin.h>
    207 #elif defined (SUN4V)
    208 #include <arch/trap/sun4v/regwin.h>
    209234#endif
    210235
    211 #endif
    212 
    213236/** @}
    214237 */
  • kernel/arch/sparc64/src/asm.S

    rb86d436 r3c081d0e  
    2929#include <arch/arch.h>
    3030#include <arch/stack.h>
     31#include <arch/regdef.h>
     32#include <arch/mm/mmu.h>
    3133
    3234.text
     
    232234        nop
    233235
     236
     237.macro WRITE_ALTERNATE_REGISTER reg, bit
     238        rdpr %pstate, %g1                               ! save PSTATE.PEF
     239        wrpr %g0, (\bit | PSTATE_PRIV_BIT), %pstate
     240        mov %o0, \reg
     241        wrpr %g0, PSTATE_PRIV_BIT, %pstate
     242        retl
     243        wrpr %g1, 0, %pstate                            ! restore PSTATE.PEF
     244.endm
     245
     246.macro READ_ALTERNATE_REGISTER reg, bit
     247        rdpr %pstate, %g1                               ! save PSTATE.PEF
     248        wrpr %g0, (\bit | PSTATE_PRIV_BIT), %pstate
     249        mov \reg, %o0
     250        wrpr %g0, PSTATE_PRIV_BIT, %pstate
     251        retl
     252        wrpr %g1, 0, %pstate                            ! restore PSTATE.PEF
     253.endm
     254
     255.global write_to_ag_g6
     256write_to_ag_g6:
     257        WRITE_ALTERNATE_REGISTER %g6, PSTATE_AG_BIT
     258
     259.global write_to_ag_g7
     260write_to_ag_g7:
     261        WRITE_ALTERNATE_REGISTER %g7, PSTATE_AG_BIT
     262
     263.global write_to_ig_g6
     264write_to_ig_g6:
     265        WRITE_ALTERNATE_REGISTER %g6, PSTATE_IG_BIT
     266
     267.global read_from_ag_g7
     268read_from_ag_g7:
     269        READ_ALTERNATE_REGISTER %g7, PSTATE_AG_BIT
     270
     271
     272/** Switch to userspace.
     273 *
     274 * %o0  Userspace entry address.
     275 * %o1  Userspace stack pointer address.
     276 * %o2  Userspace address of uarg structure.
     277 */
     278.global switch_to_userspace
     279switch_to_userspace:
     280        save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
     281        flushw
     282        wrpr %g0, 0, %cleanwin          ! avoid information leak
     283
     284        mov %i2, %o0                    ! uarg
     285        xor %o1, %o1, %o1               ! %o1 is defined to hold pcb_ptr
     286                                        ! set it to 0
     287
     288        clr %i2
     289        clr %i3
     290        clr %i4
     291        clr %i5
     292        clr %i6
     293
     294        wrpr %g0, 1, %tl                ! enforce mapping via nucleus
     295
     296        rdpr %cwp, %g1
     297        wrpr %g1, TSTATE_IE_BIT, %tstate
     298        wrpr %i0, 0, %tnpc
     299       
     300        /*
     301         * Set primary context according to secondary context.
     302         * Secondary context has been already installed by
     303         * higher-level functions.
     304         */
     305        wr %g0, ASI_DMMU, %asi
     306        ldxa [VA_SECONDARY_CONTEXT_REG] %asi, %g1
     307        stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi
     308        flush %i7
     309
     310        /*
     311         * Spills and fills will be handled by the userspace handlers.
     312         */
     313        wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(1), %wstate
     314       
     315        done                            ! jump to userspace
     316
  • kernel/arch/sparc64/src/drivers/kbd.c

    rb86d436 r3c081d0e  
    3939#include <console/console.h>
    4040#include <ddi/irq.h>
    41 #include <mm/page.h>
    4241#include <arch/mm/page.h>
    4342#include <arch/types.h>
  • kernel/arch/sparc64/src/drivers/tick.c

    rb86d436 r3c081d0e  
    5454        interrupt_register(14, "tick_int", tick_interrupt);
    5555        compare.int_dis = false;
    56         compare.tick_cmpr = tick_counter_read() +
    57                 CPU->arch.clock_frequency / HZ;
     56        compare.tick_cmpr = CPU->arch.clock_frequency / HZ;
    5857        CPU->arch.next_tick_cmpr = compare.tick_cmpr;
    5958        tick_compare_write(compare.value);
     59        tick_write(0);
    6060
    61 #if defined (US3) || defined (SUN4V)
     61#if defined (US3)
    6262        /* disable STICK interrupts and clear any pending ones */
    6363        tick_compare_reg_t stick_compare;
     
    111111         * overflow only in 146 years.
    112112         */
    113         drift = tick_counter_read() - CPU->arch.next_tick_cmpr;
     113        drift = tick_read() - CPU->arch.next_tick_cmpr;
    114114        while (drift > CPU->arch.clock_frequency / HZ) {
    115115                drift -= CPU->arch.clock_frequency / HZ;
    116116                CPU->missed_clock_ticks++;
    117117        }
    118         CPU->arch.next_tick_cmpr = tick_counter_read() +
     118        CPU->arch.next_tick_cmpr = tick_read() +
    119119            (CPU->arch.clock_frequency / HZ) - drift;
    120120        tick_compare_write(CPU->arch.next_tick_cmpr);
  • kernel/arch/sparc64/src/mm/page.c

    rb86d436 r3c081d0e  
    3333 */
    3434
    35 #include <mm/page.h>
    3635#include <arch/mm/page.h>
    3736#include <arch/mm/tlb.h>
  • kernel/arch/sparc64/src/trap/exception.c

    rb86d436 r3c081d0e  
    162162        fault_if_from_uspace(istate, "%s.", __func__);
    163163        dump_istate(istate);
    164 //MH
    165 //      dump_sfsr_and_sfar();
     164        dump_sfsr_and_sfar();
    166165        panic("%s.", __func__);
    167166}
  • kernel/generic/include/errno.h

    rb86d436 r3c081d0e  
    5757#define EADDRNOTAVAIL   -12     /* Address not available. */
    5858#define ETIMEOUT        -13     /* Timeout expired */
    59 //MH
    60 #ifndef EINVAL
    6159#define EINVAL          -14     /* Invalid value */
    62 #endif
    63 #ifndef EBUSY
    6460#define EBUSY           -15     /* Resource is busy */
    65 #endif
    6661#define EOVERFLOW       -16     /* The result does not fit its size. */
    6762#define EINTR           -17     /* Operation was interrupted. */
  • kernel/generic/src/main/kinit.c

    rb86d436 r3c081d0e  
    9494void kinit(void *arg)
    9595{
     96
    9697#if defined(CONFIG_SMP) || defined(CONFIG_KCONSOLE)
    9798        thread_t *thread;
     
    216217                }
    217218        }
    218 
     219       
    219220        /*
    220221         * Run user tasks.
     
    224225                        program_ready(&programs[i]);
    225226        }
    226 
     227       
    227228#ifdef CONFIG_KCONSOLE
    228229        if (!stdin) {
  • uspace/lib/libc/arch/sparc64/Makefile.inc

    rb86d436 r3c081d0e  
    4444BFD_NAME = elf64-sparc
    4545BFD_ARCH = sparc
    46 
    47 ifeq ($(PROCESSOR),us)
    48         DEFS += -DSUN4U
    49 endif
    50 
    51 ifeq ($(PROCESSOR),us3)
    52         DEFS += -DSUN4U
    53 endif
    54 
    55 ifeq ($(PROCESSOR),sun4v)
    56         DEFS += -DSUN4V
    57 endif
  • uspace/lib/libc/arch/sparc64/include/config.h

    rb86d436 r3c081d0e  
    3636#define LIBC_sparc64_CONFIG_H_
    3737
    38 #if defined (SUN4U)
    3938#define PAGE_WIDTH      14
    40 #elif defined(SUN4V)
    41 #define PAGE_WIDTH      13
    42 #endif
    43 
    4439#define PAGE_SIZE       (1 << PAGE_WIDTH)
    4540
  • uspace/lib/libc/arch/sparc64/src/thread_entry.s

    rb86d436 r3c081d0e  
    3838        # Create the first stack frame.
    3939        #
    40 
    41         #save %sp, -176, %sp
    42         #flushw
    43         #add %g0, -0x7ff, %fp
     40        save %sp, -176, %sp
     41        flushw
     42        add %g0, -0x7ff, %fp
    4443
    4544        sethi %hi(_gp), %l7
  • uspace/srv/hid/fb/Makefile.build

    rb86d436 r3c081d0e  
    7272
    7373ifeq ($(UARCH),sparc64)
    74         ifeq ($(PROCESSOR), sun4v)
    75                 SOURCES += niagara.c \
    76                         serial_console.c
    77                 CFLAGS += -DNIAGARA_ENABLED
    78         endif
    79 
    80         ifeq ($(MACHINE), serengeti)
    81                 SOURCES += sgcn.c \
    82                         serial_console.c
    83                 CFLAGS += -DSGCN_ENABLED
    84         endif
     74        SOURCES += sgcn.c \
     75                serial_console.c
     76        CFLAGS += -DSGCN_ENABLED
    8577endif
    8678
  • uspace/srv/hid/fb/main.c

    rb86d436 r3c081d0e  
    4141#include "ski.h"
    4242#include "sgcn.h"
    43 #include "niagara.h"
    4443#include "main.h"
    4544
     
    8988        }
    9089#endif
    91 #ifdef NIAGARA_ENABLED
    92         if ((!initialized) && (sysinfo_value("fb.kind") == 5)) {
    93                 if (niagara_init() == 0)
    94                         initialized = true;
    95         }
    96 #endif
    9790#ifdef SKI_ENABLED
    9891        if ((!initialized) && (sysinfo_value("fb") != true)) {
  • uspace/srv/hid/kbd/Makefile.build

    rb86d436 r3c081d0e  
    130130
    131131ifeq ($(UARCH),sparc64)
    132         ifeq ($(PROCESSOR),sun4u)
    133                 ifeq ($(MACHINE),serengeti)
    134                         SOURCES += \
    135                                 port/sgcn.c \
    136                                 ctl/stty.c
    137                 endif
    138                 ifeq ($(MACHINE),generic)
    139                         SOURCES += \
     132        ifeq ($(MACHINE),serengeti)
     133                SOURCES += \
     134                        port/sgcn.c \
     135                        ctl/stty.c
     136        else
     137                SOURCES += \
    140138                        port/sun.c \
    141139                        port/z8530.c \
    142140                        port/ns16550.c \
    143141                        ctl/sun.c
    144                 endif
    145         endif
    146         ifeq ($(PROCESSOR),sun4v)
    147                 SOURCES += \
    148                         port/niagara.c \
    149                         ctl/stty.c
    150142        endif
    151143endif
Note: See TracChangeset for help on using the changeset viewer.